|
danw@109
|
1 |
#define _GNU_SOURCE
|
|
danw@109
|
2 |
|
|
danw@109
|
3 |
#include <string.h>
|
|
danw@109
|
4 |
#include <stdio.h>
|
|
danw@109
|
5 |
#include <sys/stat.h>
|
|
danw@109
|
6 |
#include <sys/mman.h>
|
|
danw@109
|
7 |
#include <unistd.h>
|
|
danw@109
|
8 |
#include <fcntl.h>
|
|
danw@109
|
9 |
#include <errno.h>
|
|
danw@109
|
10 |
|
|
danw@109
|
11 |
#include <expat.h>
|
|
danw@109
|
12 |
#include <zlib.h>
|
|
danw@109
|
13 |
#include "razor.h"
|
|
danw@109
|
14 |
|
|
danw@109
|
15 |
/* Import a yum filelist as a razor package set. */
|
|
danw@109
|
16 |
|
|
danw@109
|
17 |
enum {
|
|
danw@109
|
18 |
YUM_STATE_BEGIN,
|
|
danw@109
|
19 |
YUM_STATE_PACKAGE_NAME,
|
|
danw@109
|
20 |
YUM_STATE_CHECKSUM,
|
|
danw@109
|
21 |
YUM_STATE_REQUIRES,
|
|
danw@109
|
22 |
YUM_STATE_PROVIDES,
|
|
danw@109
|
23 |
YUM_STATE_OBSOLETES,
|
|
danw@109
|
24 |
YUM_STATE_CONFLICTS,
|
|
danw@109
|
25 |
YUM_STATE_FILE
|
|
danw@109
|
26 |
};
|
|
danw@109
|
27 |
|
|
danw@109
|
28 |
struct yum_context {
|
|
danw@109
|
29 |
XML_Parser primary_parser;
|
|
danw@109
|
30 |
XML_Parser filelists_parser;
|
|
danw@109
|
31 |
XML_Parser current_parser;
|
|
danw@109
|
32 |
|
|
danw@109
|
33 |
struct razor_importer *importer;
|
|
danw@109
|
34 |
struct import_property_context *current_property_context;
|
|
danw@109
|
35 |
char name[256], buffer[512], *p;
|
|
danw@109
|
36 |
char pkgid[128];
|
|
danw@109
|
37 |
int state;
|
|
danw@109
|
38 |
};
|
|
danw@109
|
39 |
|
|
danw@109
|
40 |
static enum razor_version_relation
|
|
danw@109
|
41 |
yum_to_razor_flags (const char *flags)
|
|
danw@109
|
42 |
{
|
|
danw@109
|
43 |
/* FIXME? */
|
|
danw@109
|
44 |
if (!flags)
|
|
danw@109
|
45 |
return RAZOR_VERSION_EQUAL;
|
|
danw@109
|
46 |
|
|
danw@109
|
47 |
if (flags[0] == 'L') {
|
|
danw@109
|
48 |
if (flags[1] == 'T')
|
|
danw@109
|
49 |
return RAZOR_VERSION_LESS;
|
|
danw@109
|
50 |
else
|
|
danw@109
|
51 |
return RAZOR_VERSION_LESS_OR_EQUAL;
|
|
danw@109
|
52 |
} else if (flags[0] == 'G') {
|
|
danw@109
|
53 |
if (flags[1] == 'T')
|
|
danw@109
|
54 |
return RAZOR_VERSION_GREATER;
|
|
danw@109
|
55 |
else
|
|
danw@109
|
56 |
return RAZOR_VERSION_GREATER_OR_EQUAL;
|
|
danw@109
|
57 |
} else
|
|
danw@109
|
58 |
return RAZOR_VERSION_EQUAL;
|
|
danw@109
|
59 |
}
|
|
danw@109
|
60 |
|
|
danw@109
|
61 |
static void
|
|
danw@109
|
62 |
yum_primary_start_element(void *data, const char *name, const char **atts)
|
|
danw@109
|
63 |
{
|
|
danw@109
|
64 |
struct yum_context *ctx = data;
|
|
danw@109
|
65 |
const char *n, *version, *release, *flags;
|
|
danw@109
|
66 |
char buffer[128];
|
|
danw@109
|
67 |
int i;
|
|
danw@109
|
68 |
|
|
danw@109
|
69 |
if (strcmp(name, "name") == 0) {
|
|
danw@109
|
70 |
ctx->state = YUM_STATE_PACKAGE_NAME;
|
|
danw@109
|
71 |
ctx->p = ctx->name;
|
|
danw@109
|
72 |
} else if (strcmp(name, "version") == 0) {
|
|
danw@109
|
73 |
version = NULL;
|
|
danw@109
|
74 |
release = NULL;
|
|
danw@109
|
75 |
for (i = 0; atts[i]; i += 2) {
|
|
danw@109
|
76 |
if (strcmp(atts[i], "ver") == 0)
|
|
danw@109
|
77 |
version = atts[i + 1];
|
|
danw@109
|
78 |
else if (strcmp(atts[i], "rel") == 0)
|
|
danw@109
|
79 |
release = atts[i + 1];
|
|
danw@109
|
80 |
}
|
|
danw@109
|
81 |
if (version == NULL || release == NULL) {
|
|
danw@109
|
82 |
fprintf(stderr, "invalid version tag, "
|
|
danw@109
|
83 |
"missing version or release attribute\n");
|
|
danw@109
|
84 |
return;
|
|
danw@109
|
85 |
}
|
|
danw@109
|
86 |
|
|
danw@109
|
87 |
snprintf(buffer, sizeof buffer, "%s-%s", version, release);
|
|
danw@109
|
88 |
razor_importer_begin_package(ctx->importer, ctx->name, buffer);
|
|
danw@109
|
89 |
} else if (strcmp(name, "checksum") == 0) {
|
|
danw@109
|
90 |
ctx->p = ctx->pkgid;
|
|
danw@109
|
91 |
ctx->state = YUM_STATE_CHECKSUM;
|
|
danw@109
|
92 |
} else if (strcmp(name, "rpm:requires") == 0) {
|
|
danw@109
|
93 |
ctx->state = YUM_STATE_REQUIRES;
|
|
danw@109
|
94 |
} else if (strcmp(name, "rpm:provides") == 0) {
|
|
danw@109
|
95 |
ctx->state = YUM_STATE_PROVIDES;
|
|
danw@109
|
96 |
} else if (strcmp(name, "rpm:obsoletes") == 0) {
|
|
danw@109
|
97 |
ctx->state = YUM_STATE_OBSOLETES;
|
|
danw@109
|
98 |
} else if (strcmp(name, "rpm:conflicts") == 0) {
|
|
danw@109
|
99 |
ctx->state = YUM_STATE_CONFLICTS;
|
|
danw@109
|
100 |
} else if (strcmp(name, "rpm:entry") == 0 &&
|
|
danw@109
|
101 |
ctx->state != YUM_STATE_BEGIN) {
|
|
danw@109
|
102 |
n = NULL;
|
|
danw@109
|
103 |
version = NULL;
|
|
danw@109
|
104 |
release = NULL;
|
|
danw@109
|
105 |
flags = NULL;
|
|
danw@109
|
106 |
for (i = 0; atts[i]; i += 2) {
|
|
danw@109
|
107 |
if (strcmp(atts[i], "name") == 0)
|
|
danw@109
|
108 |
n = atts[i + 1];
|
|
danw@109
|
109 |
else if (strcmp(atts[i], "ver") == 0)
|
|
danw@109
|
110 |
version = atts[i + 1];
|
|
danw@109
|
111 |
else if (strcmp(atts[i], "rel") == 0)
|
|
danw@109
|
112 |
release = atts[i + 1];
|
|
danw@109
|
113 |
else if (strcmp(atts[i], "flags") == 0)
|
|
danw@109
|
114 |
flags = atts[i + 1];
|
|
danw@109
|
115 |
}
|
|
danw@109
|
116 |
|
|
danw@109
|
117 |
if (n == NULL) {
|
|
danw@109
|
118 |
fprintf(stderr, "invalid rpm:entry, "
|
|
danw@109
|
119 |
"missing name or version attributes\n");
|
|
danw@109
|
120 |
return;
|
|
danw@109
|
121 |
}
|
|
danw@109
|
122 |
|
|
danw@109
|
123 |
if (version && release)
|
|
danw@109
|
124 |
snprintf(buffer, sizeof buffer,
|
|
danw@109
|
125 |
"%s-%s", version, release);
|
|
danw@109
|
126 |
else if (version)
|
|
danw@109
|
127 |
strcpy(buffer, version);
|
|
danw@109
|
128 |
else
|
|
danw@109
|
129 |
buffer[0] = '\0';
|
|
danw@109
|
130 |
|
|
danw@109
|
131 |
switch (ctx->state) {
|
|
danw@109
|
132 |
case YUM_STATE_REQUIRES:
|
|
danw@109
|
133 |
razor_importer_add_property(ctx->importer, n,
|
|
danw@109
|
134 |
yum_to_razor_flags (flags),
|
|
danw@109
|
135 |
buffer,
|
|
danw@109
|
136 |
RAZOR_PROPERTY_REQUIRES);
|
|
danw@109
|
137 |
break;
|
|
danw@109
|
138 |
case YUM_STATE_PROVIDES:
|
|
danw@109
|
139 |
razor_importer_add_property(ctx->importer, n,
|
|
danw@109
|
140 |
yum_to_razor_flags (flags),
|
|
danw@109
|
141 |
buffer,
|
|
danw@109
|
142 |
RAZOR_PROPERTY_PROVIDES);
|
|
danw@109
|
143 |
break;
|
|
danw@109
|
144 |
case YUM_STATE_OBSOLETES:
|
|
danw@109
|
145 |
razor_importer_add_property(ctx->importer, n,
|
|
danw@109
|
146 |
yum_to_razor_flags (flags),
|
|
danw@109
|
147 |
buffer,
|
|
danw@109
|
148 |
RAZOR_PROPERTY_OBSOLETES);
|
|
danw@109
|
149 |
break;
|
|
danw@109
|
150 |
case YUM_STATE_CONFLICTS:
|
|
danw@109
|
151 |
razor_importer_add_property(ctx->importer, n,
|
|
danw@109
|
152 |
yum_to_razor_flags (flags),
|
|
danw@109
|
153 |
buffer,
|
|
danw@109
|
154 |
RAZOR_PROPERTY_CONFLICTS);
|
|
danw@109
|
155 |
break;
|
|
danw@109
|
156 |
}
|
|
danw@109
|
157 |
}
|
|
danw@109
|
158 |
}
|
|
danw@109
|
159 |
|
|
danw@109
|
160 |
static void
|
|
danw@109
|
161 |
yum_primary_end_element (void *data, const char *name)
|
|
danw@109
|
162 |
{
|
|
danw@109
|
163 |
struct yum_context *ctx = data;
|
|
danw@109
|
164 |
|
|
danw@109
|
165 |
switch (ctx->state) {
|
|
danw@109
|
166 |
case YUM_STATE_PACKAGE_NAME:
|
|
danw@109
|
167 |
case YUM_STATE_CHECKSUM:
|
|
danw@109
|
168 |
case YUM_STATE_FILE:
|
|
danw@109
|
169 |
ctx->state = YUM_STATE_BEGIN;
|
|
danw@109
|
170 |
break;
|
|
danw@109
|
171 |
}
|
|
danw@109
|
172 |
|
|
danw@109
|
173 |
if (strcmp(name, "package") == 0) {
|
|
danw@109
|
174 |
XML_StopParser(ctx->current_parser, XML_TRUE);
|
|
danw@109
|
175 |
ctx->current_parser = ctx->filelists_parser;
|
|
danw@109
|
176 |
}
|
|
danw@109
|
177 |
}
|
|
danw@109
|
178 |
|
|
danw@109
|
179 |
static void
|
|
danw@109
|
180 |
yum_character_data (void *data, const XML_Char *s, int len)
|
|
danw@109
|
181 |
{
|
|
danw@109
|
182 |
struct yum_context *ctx = data;
|
|
danw@109
|
183 |
|
|
danw@109
|
184 |
switch (ctx->state) {
|
|
danw@109
|
185 |
case YUM_STATE_PACKAGE_NAME:
|
|
danw@109
|
186 |
case YUM_STATE_CHECKSUM:
|
|
danw@109
|
187 |
case YUM_STATE_FILE:
|
|
danw@109
|
188 |
memcpy(ctx->p, s, len);
|
|
danw@109
|
189 |
ctx->p += len;
|
|
danw@109
|
190 |
*ctx->p = '\0';
|
|
danw@109
|
191 |
break;
|
|
danw@109
|
192 |
}
|
|
danw@109
|
193 |
}
|
|
danw@109
|
194 |
|
|
danw@109
|
195 |
static void
|
|
danw@109
|
196 |
yum_filelists_start_element(void *data, const char *name, const char **atts)
|
|
danw@109
|
197 |
{
|
|
danw@109
|
198 |
struct yum_context *ctx = data;
|
|
danw@109
|
199 |
const char *pkg, *pkgid;
|
|
danw@109
|
200 |
int i;
|
|
danw@109
|
201 |
|
|
danw@109
|
202 |
if (strcmp(name, "package") == 0) {
|
|
danw@109
|
203 |
pkg = NULL;
|
|
danw@109
|
204 |
pkgid = NULL;
|
|
danw@109
|
205 |
for (i = 0; atts[i]; i += 2) {
|
|
danw@109
|
206 |
if (strcmp(atts[i], "name") == 0)
|
|
danw@109
|
207 |
pkg = atts[i + 1];
|
|
danw@109
|
208 |
else if (strcmp(atts[i], "pkgid") == 0)
|
|
danw@109
|
209 |
pkgid = atts[i + 1];
|
|
danw@109
|
210 |
}
|
|
danw@109
|
211 |
if (strcmp(pkgid, ctx->pkgid) != 0)
|
|
danw@109
|
212 |
fprintf(stderr, "primary.xml and filelists.xml "
|
|
danw@109
|
213 |
"mismatch for %s: %s vs %s",
|
|
danw@109
|
214 |
pkg, pkgid, ctx->pkgid);
|
|
danw@109
|
215 |
} else if (strcmp(name, "file") == 0) {
|
|
danw@109
|
216 |
ctx->state = YUM_STATE_FILE;
|
|
danw@109
|
217 |
ctx->p = ctx->buffer;
|
|
danw@109
|
218 |
}
|
|
danw@109
|
219 |
}
|
|
danw@109
|
220 |
|
|
danw@109
|
221 |
|
|
danw@109
|
222 |
static void
|
|
danw@109
|
223 |
yum_filelists_end_element (void *data, const char *name)
|
|
danw@109
|
224 |
{
|
|
danw@109
|
225 |
struct yum_context *ctx = data;
|
|
danw@109
|
226 |
|
|
danw@109
|
227 |
ctx->state = YUM_STATE_BEGIN;
|
|
danw@109
|
228 |
if (strcmp(name, "package") == 0) {
|
|
danw@109
|
229 |
XML_StopParser(ctx->current_parser, XML_TRUE);
|
|
danw@109
|
230 |
ctx->current_parser = ctx->primary_parser;
|
|
danw@109
|
231 |
razor_importer_finish_package(ctx->importer);
|
|
danw@109
|
232 |
} else if (strcmp(name, "file") == 0)
|
|
danw@109
|
233 |
razor_importer_add_file(ctx->importer, ctx->buffer);
|
|
danw@109
|
234 |
|
|
danw@109
|
235 |
}
|
|
danw@109
|
236 |
|
|
danw@109
|
237 |
#define XML_BUFFER_SIZE 4096
|
|
danw@109
|
238 |
|
|
danw@109
|
239 |
struct razor_set *
|
|
danw@109
|
240 |
razor_set_create_from_yum(void)
|
|
danw@109
|
241 |
{
|
|
danw@109
|
242 |
struct yum_context ctx;
|
|
danw@109
|
243 |
void *buf;
|
|
danw@109
|
244 |
int len, ret;
|
|
danw@109
|
245 |
gzFile primary, filelists;
|
|
danw@109
|
246 |
XML_ParsingStatus status;
|
|
danw@109
|
247 |
|
|
danw@109
|
248 |
ctx.importer = razor_importer_new();
|
|
danw@109
|
249 |
ctx.state = YUM_STATE_BEGIN;
|
|
danw@109
|
250 |
|
|
danw@109
|
251 |
ctx.primary_parser = XML_ParserCreate(NULL);
|
|
danw@109
|
252 |
XML_SetUserData(ctx.primary_parser, &ctx);
|
|
danw@109
|
253 |
XML_SetElementHandler(ctx.primary_parser,
|
|
danw@109
|
254 |
yum_primary_start_element,
|
|
danw@109
|
255 |
yum_primary_end_element);
|
|
danw@109
|
256 |
XML_SetCharacterDataHandler(ctx.primary_parser,
|
|
danw@109
|
257 |
yum_character_data);
|
|
danw@109
|
258 |
|
|
danw@109
|
259 |
ctx.filelists_parser = XML_ParserCreate(NULL);
|
|
danw@109
|
260 |
XML_SetUserData(ctx.filelists_parser, &ctx);
|
|
danw@109
|
261 |
XML_SetElementHandler(ctx.filelists_parser,
|
|
danw@109
|
262 |
yum_filelists_start_element,
|
|
danw@109
|
263 |
yum_filelists_end_element);
|
|
danw@109
|
264 |
XML_SetCharacterDataHandler(ctx.filelists_parser,
|
|
danw@109
|
265 |
yum_character_data);
|
|
danw@109
|
266 |
|
|
danw@109
|
267 |
primary = gzopen("primary.xml.gz", "rb");
|
|
danw@109
|
268 |
if (primary == NULL)
|
|
danw@109
|
269 |
return NULL;
|
|
danw@109
|
270 |
filelists = gzopen("filelists.xml.gz", "rb");
|
|
danw@109
|
271 |
if (filelists == NULL)
|
|
danw@109
|
272 |
return NULL;
|
|
danw@109
|
273 |
|
|
danw@109
|
274 |
ctx.current_parser = ctx.primary_parser;
|
|
danw@109
|
275 |
|
|
danw@109
|
276 |
do {
|
|
danw@109
|
277 |
XML_GetParsingStatus(ctx.current_parser, &status);
|
|
danw@109
|
278 |
switch (status.parsing) {
|
|
danw@109
|
279 |
case XML_SUSPENDED:
|
|
danw@109
|
280 |
ret = XML_ResumeParser(ctx.current_parser);
|
|
danw@109
|
281 |
break;
|
|
danw@109
|
282 |
case XML_PARSING:
|
|
danw@109
|
283 |
case XML_INITIALIZED:
|
|
danw@109
|
284 |
buf = XML_GetBuffer(ctx.current_parser,
|
|
danw@109
|
285 |
XML_BUFFER_SIZE);
|
|
danw@109
|
286 |
if (ctx.current_parser == ctx.primary_parser)
|
|
danw@109
|
287 |
len = gzread(primary, buf, XML_BUFFER_SIZE);
|
|
danw@109
|
288 |
else
|
|
danw@109
|
289 |
len = gzread(filelists, buf, XML_BUFFER_SIZE);
|
|
danw@109
|
290 |
if (len < 0) {
|
|
danw@109
|
291 |
fprintf(stderr,
|
|
danw@109
|
292 |
"couldn't read input: %s\n",
|
|
danw@109
|
293 |
strerror(errno));
|
|
danw@109
|
294 |
return NULL;
|
|
danw@109
|
295 |
}
|
|
danw@109
|
296 |
|
|
danw@109
|
297 |
XML_ParseBuffer(ctx.current_parser, len, len == 0);
|
|
danw@109
|
298 |
break;
|
|
danw@109
|
299 |
case XML_FINISHED:
|
|
danw@109
|
300 |
break;
|
|
danw@109
|
301 |
}
|
|
danw@109
|
302 |
} while (status.parsing != XML_FINISHED);
|
|
danw@109
|
303 |
|
|
danw@109
|
304 |
|
|
danw@109
|
305 |
XML_ParserFree(ctx.primary_parser);
|
|
danw@109
|
306 |
XML_ParserFree(ctx.filelists_parser);
|
|
danw@109
|
307 |
|
|
danw@109
|
308 |
gzclose(primary);
|
|
danw@109
|
309 |
gzclose(filelists);
|
|
danw@109
|
310 |
|
|
danw@109
|
311 |
return razor_importer_finish(ctx.importer);
|
|
danw@109
|
312 |
}
|