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 add_properties(struct razor_importer *importer,
293 enum razor_property_type property_type,
294 Header h, int_32 name_tag, int_32 version_tag, int_32 flags_tag)
296 union rpm_entry names, versions, flags;
297 int_32 i, type, count;
299 headerGetEntry(h, name_tag, &type, &names.p, &count);
300 headerGetEntry(h, version_tag, &type, &versions.p, &count);
301 headerGetEntry(h, flags_tag, &type, &flags.p, &count);
303 for (i = 0; i < count; i++)
304 razor_importer_add_property(importer,
311 razor_set_create_from_rpmdb(void)
313 struct razor_importer *importer;
314 rpmdbMatchIterator iter;
316 int_32 type, count, i;
317 union rpm_entry name, version, release;
318 union rpm_entry basenames, dirnames, dirindexes;
319 char filename[PATH_MAX];
322 rpmReadConfigFiles(NULL, NULL);
324 if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
325 fprintf(stderr, "cannot open rpm database\n");
329 importer = razor_importer_new();
331 iter = rpmdbInitIterator(db, 0, NULL, 0);
332 while (h = rpmdbNextIterator(iter), h != NULL) {
333 headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
334 headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
335 headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
336 snprintf(filename, sizeof filename, "%s-%s",
337 version.string, release.string);
338 razor_importer_begin_package(importer, name.string, filename);
340 add_properties(importer, RAZOR_PROPERTY_REQUIRES, h,
342 RPMTAG_REQUIREVERSION,
343 RPMTAG_REQUIREFLAGS);
345 add_properties(importer, RAZOR_PROPERTY_PROVIDES, h,
347 RPMTAG_PROVIDEVERSION,
348 RPMTAG_PROVIDEFLAGS);
350 add_properties(importer, RAZOR_PROPERTY_OBSOLETES, h,
352 RPMTAG_OBSOLETEVERSION,
353 RPMTAG_OBSOLETEFLAGS);
355 add_properties(importer, RAZOR_PROPERTY_CONFLICTS, h,
357 RPMTAG_CONFLICTVERSION,
358 RPMTAG_CONFLICTFLAGS);
360 headerGetEntry(h, RPMTAG_BASENAMES, &type,
361 &basenames.p, &count);
362 headerGetEntry(h, RPMTAG_DIRNAMES, &type,
363 &dirnames.p, &count);
364 headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
365 &dirindexes.p, &count);
366 for (i = 0; i < count; i++) {
367 snprintf(filename, sizeof filename, "%s%s",
368 dirnames.list[dirindexes.flags[i]],
370 razor_importer_add_file(importer, filename);
373 razor_importer_finish_package(importer);
378 return razor_importer_finish(importer);