2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 /* Import a yum filelist as a razor package set. */
38 YUM_STATE_PACKAGE_NAME,
39 YUM_STATE_PACKAGE_ARCH,
41 YUM_STATE_DESCRIPTION,
53 XML_Parser primary_parser;
54 XML_Parser filelists_parser;
55 XML_Parser current_parser;
57 struct razor_importer *importer;
58 struct import_property_context *current_property_context;
59 char name[256], arch[64], summary[512], description[4096];
60 char url[256], license[64], buffer[512], *p;
65 static enum razor_version_relation
66 yum_to_razor_flags (const char *flags)
70 return RAZOR_VERSION_EQUAL;
72 if (flags[0] == 'L') {
74 return RAZOR_VERSION_LESS;
76 return RAZOR_VERSION_LESS_OR_EQUAL;
77 } else if (flags[0] == 'G') {
79 return RAZOR_VERSION_GREATER;
81 return RAZOR_VERSION_GREATER_OR_EQUAL;
83 return RAZOR_VERSION_EQUAL;
87 yum_primary_start_element(void *data, const char *name, const char **atts)
89 struct yum_context *ctx = data;
90 const char *n, *epoch, *version, *release, *flags;
94 if (strcmp(name, "name") == 0) {
95 ctx->state = YUM_STATE_PACKAGE_NAME;
97 } else if (strcmp(name, "arch") == 0) {
98 ctx->state = YUM_STATE_PACKAGE_ARCH;
100 } else if (strcmp(name, "version") == 0) {
104 for (i = 0; atts[i]; i += 2) {
105 if (strcmp(atts[i], "epoch") == 0)
107 else if (strcmp(atts[i], "ver") == 0)
108 version = atts[i + 1];
109 else if (strcmp(atts[i], "rel") == 0)
110 release = atts[i + 1];
112 if (version == NULL || release == NULL) {
113 fprintf(stderr, "invalid version tag, "
114 "missing version or release attribute\n");
118 razor_build_evr(buffer, sizeof buffer, epoch, version, release);
119 razor_importer_begin_package(ctx->importer,
120 ctx->name, buffer, ctx->arch);
121 } else if (strcmp(name, "summary") == 0) {
122 ctx->p = ctx->summary;
123 ctx->state = YUM_STATE_SUMMARY;
124 } else if (strcmp(name, "description") == 0) {
125 ctx->p = ctx->description;
126 ctx->state = YUM_STATE_DESCRIPTION;
127 } else if (strcmp(name, "url") == 0) {
129 ctx->state = YUM_STATE_URL;
130 } else if (strcmp(name, "checksum") == 0) {
132 ctx->state = YUM_STATE_CHECKSUM;
133 } else if (strcmp(name, "rpm:license") == 0) {
134 ctx->p = ctx->license;
135 ctx->state = YUM_STATE_LICENSE;
136 } else if (strcmp(name, "rpm:requires") == 0) {
137 ctx->state = YUM_STATE_REQUIRES;
138 } else if (strcmp(name, "rpm:provides") == 0) {
139 ctx->state = YUM_STATE_PROVIDES;
140 } else if (strcmp(name, "rpm:obsoletes") == 0) {
141 ctx->state = YUM_STATE_OBSOLETES;
142 } else if (strcmp(name, "rpm:conflicts") == 0) {
143 ctx->state = YUM_STATE_CONFLICTS;
144 } else if (strcmp(name, "rpm:entry") == 0 &&
145 ctx->state != YUM_STATE_BEGIN) {
151 for (i = 0; atts[i]; i += 2) {
152 if (strcmp(atts[i], "name") == 0)
154 else if (strcmp(atts[i], "epoch") == 0)
156 else if (strcmp(atts[i], "ver") == 0)
157 version = atts[i + 1];
158 else if (strcmp(atts[i], "rel") == 0)
159 release = atts[i + 1];
160 else if (strcmp(atts[i], "flags") == 0)
165 fprintf(stderr, "invalid rpm:entry, "
166 "missing name or version attributes\n");
170 razor_build_evr(buffer, sizeof buffer, epoch, version, release);
171 switch (ctx->state) {
172 case YUM_STATE_REQUIRES:
173 razor_importer_add_property(ctx->importer, n,
174 yum_to_razor_flags (flags),
176 RAZOR_PROPERTY_REQUIRES);
178 case YUM_STATE_PROVIDES:
179 razor_importer_add_property(ctx->importer, n,
180 yum_to_razor_flags (flags),
182 RAZOR_PROPERTY_PROVIDES);
184 case YUM_STATE_OBSOLETES:
185 razor_importer_add_property(ctx->importer, n,
186 yum_to_razor_flags (flags),
188 RAZOR_PROPERTY_OBSOLETES);
190 case YUM_STATE_CONFLICTS:
191 razor_importer_add_property(ctx->importer, n,
192 yum_to_razor_flags (flags),
194 RAZOR_PROPERTY_CONFLICTS);
201 yum_primary_end_element (void *data, const char *name)
203 struct yum_context *ctx = data;
205 switch (ctx->state) {
206 case YUM_STATE_PACKAGE_NAME:
207 case YUM_STATE_PACKAGE_ARCH:
208 case YUM_STATE_SUMMARY:
209 case YUM_STATE_DESCRIPTION:
211 case YUM_STATE_LICENSE:
212 case YUM_STATE_CHECKSUM:
214 ctx->state = YUM_STATE_BEGIN;
218 if (strcmp(name, "package") == 0) {
219 razor_importer_add_details(ctx->importer, ctx->summary,
220 ctx->description, ctx->url,
223 XML_StopParser(ctx->current_parser, XML_TRUE);
224 ctx->current_parser = ctx->filelists_parser;
229 yum_character_data (void *data, const XML_Char *s, int len)
231 struct yum_context *ctx = data;
233 switch (ctx->state) {
234 case YUM_STATE_PACKAGE_NAME:
235 case YUM_STATE_PACKAGE_ARCH:
236 case YUM_STATE_SUMMARY:
237 case YUM_STATE_DESCRIPTION:
239 case YUM_STATE_LICENSE:
240 case YUM_STATE_CHECKSUM:
242 memcpy(ctx->p, s, len);
250 yum_filelists_start_element(void *data, const char *name, const char **atts)
252 struct yum_context *ctx = data;
253 const char *pkg, *pkgid;
256 if (strcmp(name, "package") == 0) {
259 for (i = 0; atts[i]; i += 2) {
260 if (strcmp(atts[i], "name") == 0)
262 else if (strcmp(atts[i], "pkgid") == 0)
265 if (strcmp(pkgid, ctx->pkgid) != 0)
266 fprintf(stderr, "primary.xml and filelists.xml "
267 "mismatch for %s: %s vs %s",
268 pkg, pkgid, ctx->pkgid);
269 } else if (strcmp(name, "file") == 0) {
270 ctx->state = YUM_STATE_FILE;
271 ctx->p = ctx->buffer;
277 yum_filelists_end_element (void *data, const char *name)
279 struct yum_context *ctx = data;
281 ctx->state = YUM_STATE_BEGIN;
282 if (strcmp(name, "package") == 0) {
283 XML_StopParser(ctx->current_parser, XML_TRUE);
284 ctx->current_parser = ctx->primary_parser;
285 razor_importer_finish_package(ctx->importer);
286 } else if (strcmp(name, "file") == 0)
287 razor_importer_add_file(ctx->importer, ctx->buffer);
291 #define XML_BUFFER_SIZE 4096
294 razor_set_create_from_yum(void)
296 struct yum_context ctx;
299 gzFile primary, filelists;
300 XML_ParsingStatus status;
302 ctx.importer = razor_importer_new();
303 ctx.state = YUM_STATE_BEGIN;
305 ctx.primary_parser = XML_ParserCreate(NULL);
306 XML_SetUserData(ctx.primary_parser, &ctx);
307 XML_SetElementHandler(ctx.primary_parser,
308 yum_primary_start_element,
309 yum_primary_end_element);
310 XML_SetCharacterDataHandler(ctx.primary_parser,
313 ctx.filelists_parser = XML_ParserCreate(NULL);
314 XML_SetUserData(ctx.filelists_parser, &ctx);
315 XML_SetElementHandler(ctx.filelists_parser,
316 yum_filelists_start_element,
317 yum_filelists_end_element);
318 XML_SetCharacterDataHandler(ctx.filelists_parser,
321 primary = gzopen("primary.xml.gz", "rb");
324 filelists = gzopen("filelists.xml.gz", "rb");
325 if (filelists == NULL)
328 ctx.current_parser = ctx.primary_parser;
331 XML_GetParsingStatus(ctx.current_parser, &status);
332 switch (status.parsing) {
334 ret = XML_ResumeParser(ctx.current_parser);
337 case XML_INITIALIZED:
338 buf = XML_GetBuffer(ctx.current_parser,
340 if (ctx.current_parser == ctx.primary_parser)
341 len = gzread(primary, buf, XML_BUFFER_SIZE);
343 len = gzread(filelists, buf, XML_BUFFER_SIZE);
346 "couldn't read input: %s\n",
351 XML_ParseBuffer(ctx.current_parser, len, len == 0);
356 } while (status.parsing != XML_FINISHED);
359 XML_ParserFree(ctx.primary_parser);
360 XML_ParserFree(ctx.filelists_parser);
365 return razor_importer_finish(ctx.importer);