Use iterators for razor_set_diff() implementation.
13 #include <rpm/rpmlib.h>
14 #include <rpm/rpmdb.h>
17 /* Import a yum filelist as a razor package set. */
21 YUM_STATE_PACKAGE_NAME,
31 XML_Parser primary_parser;
32 XML_Parser filelists_parser;
33 XML_Parser current_parser;
35 struct razor_importer *importer;
36 struct import_property_context *current_property_context;
37 char name[256], buffer[512], *p;
43 yum_primary_start_element(void *data, const char *name, const char **atts)
45 struct yum_context *ctx = data;
46 const char *n, *version, *release;
50 if (strcmp(name, "name") == 0) {
51 ctx->state = YUM_STATE_PACKAGE_NAME;
53 } else if (strcmp(name, "version") == 0) {
56 for (i = 0; atts[i]; i += 2) {
57 if (strcmp(atts[i], "ver") == 0)
58 version = atts[i + 1];
59 else if (strcmp(atts[i], "rel") == 0)
60 release = atts[i + 1];
62 if (version == NULL || release == NULL) {
63 fprintf(stderr, "invalid version tag, "
64 "missing version or release attribute\n");
68 snprintf(buffer, sizeof buffer, "%s-%s", version, release);
69 razor_importer_begin_package(ctx->importer, ctx->name, buffer);
70 } else if (strcmp(name, "checksum") == 0) {
72 ctx->state = YUM_STATE_CHECKSUM;
73 } else if (strcmp(name, "rpm:requires") == 0) {
74 ctx->state = YUM_STATE_REQUIRES;
75 } else if (strcmp(name, "rpm:provides") == 0) {
76 ctx->state = YUM_STATE_PROVIDES;
77 } else if (strcmp(name, "rpm:obsoletes") == 0) {
78 ctx->state = YUM_STATE_OBSOLETES;
79 } else if (strcmp(name, "rpm:conflicts") == 0) {
80 ctx->state = YUM_STATE_CONFLICTS;
81 } else if (strcmp(name, "rpm:entry") == 0 &&
82 ctx->state != YUM_STATE_BEGIN) {
86 for (i = 0; atts[i]; i += 2) {
87 if (strcmp(atts[i], "name") == 0)
89 else if (strcmp(atts[i], "ver") == 0)
90 version = atts[i + 1];
91 else if (strcmp(atts[i], "rel") == 0)
92 release = atts[i + 1];
96 fprintf(stderr, "invalid rpm:entry, "
97 "missing name or version attributes\n");
101 if (version && release)
102 snprintf(buffer, sizeof buffer,
103 "%s-%s", version, release);
105 strcpy(buffer, version);
109 switch (ctx->state) {
110 case YUM_STATE_REQUIRES:
111 razor_importer_add_property(ctx->importer, n, buffer,
112 RAZOR_PROPERTY_REQUIRES);
114 case YUM_STATE_PROVIDES:
115 razor_importer_add_property(ctx->importer, n, buffer,
116 RAZOR_PROPERTY_PROVIDES);
118 case YUM_STATE_OBSOLETES:
119 razor_importer_add_property(ctx->importer, n, buffer,
120 RAZOR_PROPERTY_OBSOLETES);
122 case YUM_STATE_CONFLICTS:
123 razor_importer_add_property(ctx->importer, n, buffer,
124 RAZOR_PROPERTY_CONFLICTS);
131 yum_primary_end_element (void *data, const char *name)
133 struct yum_context *ctx = data;
135 switch (ctx->state) {
136 case YUM_STATE_PACKAGE_NAME:
137 case YUM_STATE_CHECKSUM:
139 ctx->state = YUM_STATE_BEGIN;
143 if (strcmp(name, "package") == 0) {
144 XML_StopParser(ctx->current_parser, XML_TRUE);
145 ctx->current_parser = ctx->filelists_parser;
150 yum_character_data (void *data, const XML_Char *s, int len)
152 struct yum_context *ctx = data;
154 switch (ctx->state) {
155 case YUM_STATE_PACKAGE_NAME:
156 case YUM_STATE_CHECKSUM:
158 memcpy(ctx->p, s, len);
166 yum_filelists_start_element(void *data, const char *name, const char **atts)
168 struct yum_context *ctx = data;
169 const char *pkg, *pkgid;
172 if (strcmp(name, "package") == 0) {
175 for (i = 0; atts[i]; i += 2) {
176 if (strcmp(atts[i], "name") == 0)
178 else if (strcmp(atts[i], "pkgid") == 0)
181 if (strcmp(pkgid, ctx->pkgid) != 0)
182 fprintf(stderr, "primary.xml and filelists.xml "
183 "mismatch for %s: %s vs %s",
184 pkg, pkgid, ctx->pkgid);
185 } else if (strcmp(name, "file") == 0) {
186 ctx->state = YUM_STATE_FILE;
187 ctx->p = ctx->buffer;
193 yum_filelists_end_element (void *data, const char *name)
195 struct yum_context *ctx = data;
197 ctx->state = YUM_STATE_BEGIN;
198 if (strcmp(name, "package") == 0) {
199 XML_StopParser(ctx->current_parser, XML_TRUE);
200 ctx->current_parser = ctx->primary_parser;
201 razor_importer_finish_package(ctx->importer);
202 } else if (strcmp(name, "file") == 0)
203 razor_importer_add_file(ctx->importer, ctx->buffer);
207 #define XML_BUFFER_SIZE 4096
210 razor_set_create_from_yum(void)
212 struct yum_context ctx;
215 gzFile primary, filelists;
216 XML_ParsingStatus status;
218 ctx.importer = razor_importer_new();
219 ctx.state = YUM_STATE_BEGIN;
221 ctx.primary_parser = XML_ParserCreate(NULL);
222 XML_SetUserData(ctx.primary_parser, &ctx);
223 XML_SetElementHandler(ctx.primary_parser,
224 yum_primary_start_element,
225 yum_primary_end_element);
226 XML_SetCharacterDataHandler(ctx.primary_parser,
229 ctx.filelists_parser = XML_ParserCreate(NULL);
230 XML_SetUserData(ctx.filelists_parser, &ctx);
231 XML_SetElementHandler(ctx.filelists_parser,
232 yum_filelists_start_element,
233 yum_filelists_end_element);
234 XML_SetCharacterDataHandler(ctx.filelists_parser,
237 primary = gzopen("primary.xml.gz", "rb");
240 filelists = gzopen("filelists.xml.gz", "rb");
241 if (filelists == NULL)
244 ctx.current_parser = ctx.primary_parser;
247 XML_GetParsingStatus(ctx.current_parser, &status);
248 switch (status.parsing) {
250 ret = XML_ResumeParser(ctx.current_parser);
253 case XML_INITIALIZED:
254 buf = XML_GetBuffer(ctx.current_parser,
256 if (ctx.current_parser == ctx.primary_parser)
257 len = gzread(primary, buf, XML_BUFFER_SIZE);
259 len = gzread(filelists, buf, XML_BUFFER_SIZE);
262 "couldn't read input: %s\n",
267 XML_ParseBuffer(ctx.current_parser, len, len == 0);
272 } while (status.parsing != XML_FINISHED);
275 XML_ParserFree(ctx.primary_parser);
276 XML_ParserFree(ctx.filelists_parser);
281 return razor_importer_finish(ctx.importer);
292 razor_set_create_from_rpmdb(void)
294 struct razor_importer *importer;
295 rpmdbMatchIterator iter;
297 int_32 type, count, i;
298 union rpm_entry name, version, release;
299 union rpm_entry property_names, property_versions, property_flags;
300 union rpm_entry basenames, dirnames, dirindexes;
301 char filename[PATH_MAX];
304 rpmReadConfigFiles(NULL, NULL);
306 if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
307 fprintf(stderr, "cannot open rpm database\n");
311 importer = razor_importer_new();
313 iter = rpmdbInitIterator(db, 0, NULL, 0);
314 while (h = rpmdbNextIterator(iter), h != NULL) {
315 headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
316 headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
317 headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
318 snprintf(filename, sizeof filename, "%s-%s",
319 version.string, release.string);
320 razor_importer_begin_package(importer, name.string, filename);
322 headerGetEntry(h, RPMTAG_REQUIRENAME, &type,
323 &property_names.p, &count);
324 headerGetEntry(h, RPMTAG_REQUIREVERSION, &type,
325 &property_versions.p, &count);
326 headerGetEntry(h, RPMTAG_REQUIREFLAGS, &type,
327 &property_flags.p, &count);
328 for (i = 0; i < count; i++)
329 razor_importer_add_property(importer,
330 property_names.list[i],
331 property_versions.list[i],
332 RAZOR_PROPERTY_REQUIRES);
334 headerGetEntry(h, RPMTAG_PROVIDENAME, &type,
335 &property_names.p, &count);
336 headerGetEntry(h, RPMTAG_PROVIDEVERSION, &type,
337 &property_versions.p, &count);
338 headerGetEntry(h, RPMTAG_PROVIDEFLAGS, &type,
339 &property_flags.p, &count);
340 for (i = 0; i < count; i++)
341 razor_importer_add_property(importer,
342 property_names.list[i],
343 property_versions.list[i],
344 RAZOR_PROPERTY_PROVIDES);
346 headerGetEntry(h, RPMTAG_OBSOLETENAME, &type,
347 &property_names.p, &count);
348 headerGetEntry(h, RPMTAG_OBSOLETEVERSION, &type,
349 &property_versions.p, &count);
350 headerGetEntry(h, RPMTAG_OBSOLETEFLAGS, &type,
351 &property_flags.p, &count);
352 for (i = 0; i < count; i++)
353 razor_importer_add_property(importer,
354 property_names.list[i],
355 property_versions.list[i],
356 RAZOR_PROPERTY_OBSOLETES);
358 headerGetEntry(h, RPMTAG_CONFLICTNAME, &type,
359 &property_names.p, &count);
360 headerGetEntry(h, RPMTAG_CONFLICTVERSION, &type,
361 &property_versions.p, &count);
362 headerGetEntry(h, RPMTAG_CONFLICTFLAGS, &type,
363 &property_flags.p, &count);
364 for (i = 0; i < count; i++)
365 razor_importer_add_property(importer,
366 property_names.list[i],
367 property_versions.list[i],
368 RAZOR_PROPERTY_CONFLICTS);
370 headerGetEntry(h, RPMTAG_BASENAMES, &type,
371 &basenames.p, &count);
372 headerGetEntry(h, RPMTAG_DIRNAMES, &type,
373 &dirnames.p, &count);
374 headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
375 &dirindexes.p, &count);
376 for (i = 0; i < count; i++) {
377 snprintf(filename, sizeof filename, "%s%s",
378 dirnames.list[dirindexes.flags[i]],
380 razor_importer_add_file(importer, filename);
383 razor_importer_finish_package(importer);
388 return razor_importer_finish(importer);