Fix package queries for empty sets.
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.
35 /* Import a yum filelist as a razor package set. */
39 YUM_STATE_PACKAGE_NAME,
40 YUM_STATE_PACKAGE_ARCH,
50 XML_Parser primary_parser;
51 XML_Parser filelists_parser;
52 XML_Parser current_parser;
54 struct razor_importer *importer;
55 struct import_property_context *current_property_context;
56 char name[256], arch[64], buffer[512], *p;
58 uint32_t property_type;
63 yum_to_razor_relation (const char *flags)
65 if (flags[0] == 'L') {
67 return RAZOR_PROPERTY_LESS;
69 return RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL;
70 } else if (flags[0] == 'G') {
72 return RAZOR_PROPERTY_GREATER;
74 return RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL;
76 return RAZOR_PROPERTY_EQUAL;
80 yum_primary_start_element(void *data, const char *name, const char **atts)
82 struct yum_context *ctx = data;
83 const char *n, *epoch, *version, *release;
85 uint32_t pre, relation, flags;
88 if (strcmp(name, "name") == 0) {
89 ctx->state = YUM_STATE_PACKAGE_NAME;
91 } else if (strcmp(name, "arch") == 0) {
92 ctx->state = YUM_STATE_PACKAGE_ARCH;
94 } else if (strcmp(name, "version") == 0) {
98 for (i = 0; atts[i]; i += 2) {
99 if (strcmp(atts[i], "epoch") == 0)
101 else if (strcmp(atts[i], "ver") == 0)
102 version = atts[i + 1];
103 else if (strcmp(atts[i], "rel") == 0)
104 release = atts[i + 1];
106 if (version == NULL || release == NULL) {
107 fprintf(stderr, "invalid version tag, "
108 "missing version or release attribute\n");
112 razor_build_evr(buffer, sizeof buffer, epoch, version, release);
113 razor_importer_begin_package(ctx->importer,
114 ctx->name, buffer, ctx->arch);
115 } else if (strcmp(name, "checksum") == 0) {
117 ctx->state = YUM_STATE_CHECKSUM;
118 } else if (strcmp(name, "rpm:requires") == 0) {
119 ctx->state = YUM_STATE_REQUIRES;
120 ctx->property_type = RAZOR_PROPERTY_REQUIRES;
121 } else if (strcmp(name, "rpm:provides") == 0) {
122 ctx->state = YUM_STATE_PROVIDES;
123 ctx->property_type = RAZOR_PROPERTY_PROVIDES;
124 } else if (strcmp(name, "rpm:obsoletes") == 0) {
125 ctx->state = YUM_STATE_OBSOLETES;
126 ctx->property_type = RAZOR_PROPERTY_OBSOLETES;
127 } else if (strcmp(name, "rpm:conflicts") == 0) {
128 ctx->state = YUM_STATE_CONFLICTS;
129 ctx->property_type = RAZOR_PROPERTY_CONFLICTS;
130 } else if (strcmp(name, "rpm:entry") == 0 &&
131 ctx->state != YUM_STATE_BEGIN) {
136 relation = RAZOR_PROPERTY_EQUAL;
138 for (i = 0; atts[i]; i += 2) {
139 if (strcmp(atts[i], "name") == 0)
141 else if (strcmp(atts[i], "epoch") == 0)
143 else if (strcmp(atts[i], "ver") == 0)
144 version = atts[i + 1];
145 else if (strcmp(atts[i], "rel") == 0)
146 release = atts[i + 1];
147 else if (strcmp(atts[i], "flags") == 0)
148 relation = yum_to_razor_relation(atts[i + 1]);
149 else if (strcmp(atts[i], "pre") == 0)
152 RAZOR_PROPERTY_POST |
153 RAZOR_PROPERTY_PREUN |
154 RAZOR_PROPERTY_POSTUN;
158 fprintf(stderr, "invalid rpm:entry, "
159 "missing name or version attributes\n");
163 razor_build_evr(buffer, sizeof buffer, epoch, version, release);
164 flags = ctx->property_type | relation | pre;
165 razor_importer_add_property(ctx->importer, n, flags, buffer);
170 yum_primary_end_element (void *data, const char *name)
172 struct yum_context *ctx = data;
174 switch (ctx->state) {
175 case YUM_STATE_PACKAGE_NAME:
176 case YUM_STATE_PACKAGE_ARCH:
177 case YUM_STATE_CHECKSUM:
179 ctx->state = YUM_STATE_BEGIN;
183 if (strcmp(name, "package") == 0) {
184 XML_StopParser(ctx->current_parser, XML_TRUE);
185 ctx->current_parser = ctx->filelists_parser;
190 yum_character_data (void *data, const XML_Char *s, int len)
192 struct yum_context *ctx = data;
194 switch (ctx->state) {
195 case YUM_STATE_PACKAGE_NAME:
196 case YUM_STATE_PACKAGE_ARCH:
197 case YUM_STATE_CHECKSUM:
199 memcpy(ctx->p, s, len);
207 yum_filelists_start_element(void *data, const char *name, const char **atts)
209 struct yum_context *ctx = data;
210 const char *pkg, *pkgid;
213 if (strcmp(name, "package") == 0) {
216 for (i = 0; atts[i]; i += 2) {
217 if (strcmp(atts[i], "name") == 0)
219 else if (strcmp(atts[i], "pkgid") == 0)
222 if (strcmp(pkgid, ctx->pkgid) != 0)
223 fprintf(stderr, "primary.xml and filelists.xml "
224 "mismatch for %s: %s vs %s",
225 pkg, pkgid, ctx->pkgid);
226 } else if (strcmp(name, "file") == 0) {
227 ctx->state = YUM_STATE_FILE;
228 ctx->p = ctx->buffer;
234 yum_filelists_end_element (void *data, const char *name)
236 struct yum_context *ctx = data;
238 ctx->state = YUM_STATE_BEGIN;
239 if (strcmp(name, "package") == 0) {
240 XML_StopParser(ctx->current_parser, XML_TRUE);
241 ctx->current_parser = ctx->primary_parser;
242 razor_importer_finish_package(ctx->importer);
243 } else if (strcmp(name, "file") == 0)
244 razor_importer_add_file(ctx->importer, ctx->buffer);
248 #define XML_BUFFER_SIZE 4096
251 razor_set_create_from_yum(void)
253 struct yum_context ctx;
256 gzFile primary, filelists;
257 XML_ParsingStatus status;
259 ctx.importer = razor_importer_create();
260 ctx.state = YUM_STATE_BEGIN;
262 ctx.primary_parser = XML_ParserCreate(NULL);
263 XML_SetUserData(ctx.primary_parser, &ctx);
264 XML_SetElementHandler(ctx.primary_parser,
265 yum_primary_start_element,
266 yum_primary_end_element);
267 XML_SetCharacterDataHandler(ctx.primary_parser,
270 ctx.filelists_parser = XML_ParserCreate(NULL);
271 XML_SetUserData(ctx.filelists_parser, &ctx);
272 XML_SetElementHandler(ctx.filelists_parser,
273 yum_filelists_start_element,
274 yum_filelists_end_element);
275 XML_SetCharacterDataHandler(ctx.filelists_parser,
278 primary = gzopen("primary.xml.gz", "rb");
281 filelists = gzopen("filelists.xml.gz", "rb");
282 if (filelists == NULL)
285 ctx.current_parser = ctx.primary_parser;
288 XML_GetParsingStatus(ctx.current_parser, &status);
289 switch (status.parsing) {
291 ret = XML_ResumeParser(ctx.current_parser);
294 case XML_INITIALIZED:
295 buf = XML_GetBuffer(ctx.current_parser,
297 if (ctx.current_parser == ctx.primary_parser)
298 len = gzread(primary, buf, XML_BUFFER_SIZE);
300 len = gzread(filelists, buf, XML_BUFFER_SIZE);
303 "couldn't read input: %s\n",
308 XML_ParseBuffer(ctx.current_parser, len, len == 0);
313 } while (status.parsing != XML_FINISHED);
316 XML_ParserFree(ctx.primary_parser);
317 XML_ParserFree(ctx.filelists_parser);
322 return razor_importer_finish(ctx.importer);