TODO: Add pipelined download and install idea.
12 #include <rpm/rpmlib.h>
13 #include <rpm/rpmdb.h>
18 parse_package(struct razor_importer *importer, const char **atts, void *data)
20 const char *name = NULL, *version = NULL;
23 for (i = 0; atts[i]; i += 2) {
24 if (strcmp(atts[i], "name") == 0)
26 else if (strcmp(atts[i], "version") == 0)
27 version = atts[i + 1];
30 if (name == NULL || version == NULL) {
31 fprintf(stderr, "invalid package tag, "
32 "missing name or version attributes\n");
36 razor_importer_begin_package(importer, name, version);
40 RZR_REQUIRES, RZR_PROVIDES
44 parse_property(struct razor_importer *importer, const char **atts, void *data)
46 const char *name = NULL, *version = NULL;
49 for (i = 0; atts[i]; i += 2) {
50 if (strcmp(atts[i], "name") == 0)
52 if (strcmp(atts[i], "version") == 0)
53 version = atts[i + 1];
57 fprintf(stderr, "invalid tag, missing name attribute\n");
63 razor_importer_add_requires(importer, name, version);
66 razor_importer_add_provides(importer, name, version);
72 start_element(void *data, const char *name, const char **atts)
74 struct razor_importer *importer = data;
76 if (strcmp(name, "package") == 0)
77 parse_package(importer, atts, NULL);
78 else if (strcmp(name, "requires") == 0)
79 parse_property(importer, atts, (void *) RZR_REQUIRES);
80 else if (strcmp(name, "provides") == 0)
81 parse_property(importer, atts, (void*) RZR_PROVIDES);
85 end_element (void *data, const char *name)
87 struct razor_importer *importer = data;
89 if (strcmp(name, "package") == 0)
90 razor_importer_finish_package(importer);
94 import_rzr_file(struct razor_importer *importer, const char *filename)
101 unsigned char hash[20];
103 fd = open(filename, O_RDONLY);
104 if (fstat(fd, &stat) < 0)
106 p = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
110 parser = XML_ParserCreate(NULL);
111 XML_SetUserData(parser, importer);
112 XML_SetElementHandler(parser, start_element, end_element);
113 if (XML_Parse(parser, p, stat.st_size, 1) == XML_STATUS_ERROR) {
115 "%s at line %ld, %s\n",
116 XML_ErrorString(XML_GetErrorCode(parser)),
117 XML_GetCurrentLineNumber(parser),
122 XML_ParserFree(parser);
125 SHA1_Update(&sha1, p, stat.st_size);
126 SHA1_Final(hash, &sha1);
130 munmap(p, stat.st_size);
136 razor_import_rzr_files(int count, const char *files[])
138 struct razor_importer *importer;
141 importer = razor_importer_new();
143 for (i = 0; i < count; i++) {
144 if (import_rzr_file(importer, files[i]) < 0) {
145 fprintf(stderr, "failed to import %s\n", files[i]);
150 return razor_importer_finish(importer);
153 /* Import a yum filelist as a razor package set. */
157 YUM_STATE_PACKAGE_NAME,
164 struct razor_importer *importer;
165 struct import_property_context *current_property_context;
166 char name[256], buffer[512], *p;
171 yum_start_element(void *data, const char *name, const char **atts)
173 struct yum_context *ctx = data;
174 const char *n, *version;
177 if (strcmp(name, "name") == 0) {
178 ctx->state = YUM_STATE_PACKAGE_NAME;
180 } else if (strcmp(name, "version") == 0) {
182 for (i = 0; atts[i]; i += 2) {
183 if (strcmp(atts[i], "ver") == 0)
184 version = atts[i + 1];
186 razor_importer_begin_package(ctx->importer, ctx->name, version);
187 } else if (strcmp(name, "rpm:requires") == 0) {
188 ctx->state = YUM_STATE_REQUIRES;
189 } else if (strcmp(name, "rpm:provides") == 0) {
190 ctx->state = YUM_STATE_PROVIDES;
191 } else if (strcmp(name, "rpm:entry") == 0 &&
192 ctx->state != YUM_STATE_BEGIN) {
195 for (i = 0; atts[i]; i += 2) {
196 if (strcmp(atts[i], "name") == 0)
198 else if (strcmp(atts[i], "ver") == 0)
199 version = atts[i + 1];
203 fprintf(stderr, "invalid rpm:entry, "
204 "missing name or version attributes\n");
208 switch (ctx->state) {
209 case YUM_STATE_REQUIRES:
210 razor_importer_add_requires(ctx->importer, n, version);
212 case YUM_STATE_PROVIDES:
213 razor_importer_add_provides(ctx->importer, n, version);
216 } else if (strcmp(name, "file") == 0) {
217 ctx->state = YUM_STATE_FILE;
218 ctx->p = ctx->buffer;
223 yum_end_element (void *data, const char *name)
225 struct yum_context *ctx = data;
227 ctx->state = YUM_STATE_BEGIN;
228 if (strcmp(name, "package") == 0)
229 razor_importer_finish_package(ctx->importer);
230 else if (strcmp(name, "file") == 0)
231 razor_importer_add_file(ctx->importer, ctx->buffer);
235 yum_character_data (void *data, const XML_Char *s, int len)
237 struct yum_context *ctx = data;
239 switch (ctx->state) {
240 case YUM_STATE_PACKAGE_NAME:
242 memcpy(ctx->p, s, len);
250 razor_set_create_from_yum_filelist(int fd)
252 struct yum_context ctx;
257 ctx.importer = razor_importer_new();
259 parser = XML_ParserCreate(NULL);
260 XML_SetUserData(parser, &ctx);
261 XML_SetElementHandler(parser, yum_start_element, yum_end_element);
262 XML_SetCharacterDataHandler(parser, yum_character_data);
265 len = read(fd, buf, sizeof buf);
268 "couldn't read input: %s\n", strerror(errno));
273 if (XML_Parse(parser, buf, len, 0) == XML_STATUS_ERROR) {
276 XML_ErrorString(XML_GetErrorCode(parser)),
277 XML_GetCurrentLineNumber(parser));
282 XML_ParserFree(parser);
284 return razor_importer_finish(ctx.importer);
295 razor_set_create_from_rpmdb(void)
297 struct razor_importer *importer;
298 rpmdbMatchIterator iter;
300 int_32 type, count, i;
301 union rpm_entry name, version, release;
302 union rpm_entry property_names, property_versions, property_flags;
303 union rpm_entry basenames, dirnames, dirindexes;
304 char filename[PATH_MAX];
307 rpmReadConfigFiles(NULL, NULL);
309 if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
310 fprintf(stderr, "cannot open rpm database\n");
314 importer = razor_importer_new();
316 iter = rpmdbInitIterator(db, 0, NULL, 0);
317 while (h = rpmdbNextIterator(iter), h != NULL) {
318 headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
319 headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
320 headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
321 razor_importer_begin_package(importer,
322 name.string, version.string);
324 headerGetEntry(h, RPMTAG_REQUIRENAME, &type,
325 &property_names.p, &count);
326 headerGetEntry(h, RPMTAG_REQUIREVERSION, &type,
327 &property_versions.p, &count);
328 headerGetEntry(h, RPMTAG_REQUIREFLAGS, &type,
329 &property_flags.p, &count);
330 for (i = 0; i < count; i++)
331 razor_importer_add_requires(importer,
332 property_names.list[i],
333 property_versions.list[i]);
335 headerGetEntry(h, RPMTAG_PROVIDENAME, &type,
336 &property_names.p, &count);
337 headerGetEntry(h, RPMTAG_PROVIDEVERSION, &type,
338 &property_versions.p, &count);
339 for (i = 0; i < count; i++)
340 razor_importer_add_provides(importer,
341 property_names.list[i],
342 property_versions.list[i]);
344 headerGetEntry(h, RPMTAG_BASENAMES, &type,
345 &basenames.p, &count);
346 headerGetEntry(h, RPMTAG_DIRNAMES, &type,
347 &dirnames.p, &count);
348 headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
349 &dirindexes.p, &count);
350 for (i = 0; i < count; i++) {
351 snprintf(filename, sizeof filename, "%s%s",
352 dirnames.list[dirindexes.flags[i]],
354 razor_importer_add_file(importer, filename);
357 razor_importer_finish_package(importer);
362 return razor_importer_finish(importer);