Implement property (requires/provides) to package mapping.
22 array_init(struct array *array)
24 memset(array, 0, sizeof *array);
28 array_release(struct array *array)
34 array_add(struct array *array, int size)
44 while (alloc < array->size + size)
47 if (array->alloc < alloc) {
48 data = realloc(array->data, alloc);
55 p = array->data + array->size;
62 write_to_fd(int fd, void *p, size_t size)
68 len = write(fd, p, rest);
78 write_to_file(const char *filename, void *p, size_t size)
82 fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
85 err = write_to_fd(fd, p, size);
102 struct razor_set_header {
104 unsigned int version;
105 struct { unsigned int type, offset, size; } sections[0];
108 #define RAZOR_MAGIC 0x7a7a7a7a
109 #define RAZOR_VERSION 1
111 #define RAZOR_BUCKETS 1
112 #define RAZOR_STRINGS 2
113 #define RAZOR_PACKAGES 3
114 #define RAZOR_REQUIRES 4
115 #define RAZOR_PROVIDES 5
116 #define RAZOR_PROPERTIES 6
118 struct razor_package {
120 unsigned long version;
121 unsigned long requires;
122 unsigned long provides;
125 struct razor_property {
127 unsigned long version;
128 unsigned long packages;
132 struct array buckets;
133 struct array string_pool;
134 struct array property_pool;
135 struct array packages;
136 struct array requires;
137 struct array provides;
138 struct razor_set_header *header;
142 razor_set_create(void)
144 return zalloc(sizeof(struct razor_set));
148 razor_set_open(const char *filename)
150 struct razor_set *set;
152 unsigned int size, offset;
155 set = zalloc(sizeof *set);
156 fd = open(filename, O_RDONLY);
157 if (fstat(fd, &stat) < 0)
159 set->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
160 if (set->header == MAP_FAILED) {
165 for (i = 0; i < set->header->sections[i].type; i++) {
166 offset = set->header->sections[i].offset;
167 size = set->header->sections[i].size;
169 switch (set->header->sections[i].type) {
171 set->string_pool.data = (void *) set->header + offset;
172 set->string_pool.size = size;
173 set->string_pool.alloc = size;
176 set->packages.data = (void *) set->header + offset;
177 set->packages.size = size;
178 set->packages.size = size;
181 set->requires.data = (void *) set->header + offset;
182 set->requires.size = size;
183 set->requires.size = size;
186 set->provides.data = (void *) set->header + offset;
187 set->provides.size = size;
188 set->provides.size = size;
190 case RAZOR_PROPERTIES:
191 set->property_pool.data = (void *) set->header + offset;
192 set->property_pool.size = size;
193 set->property_pool.size = size;
203 razor_set_destroy(struct razor_set *set)
209 for (i = 0; set->header->sections[i].type; i++)
211 size = set->header->sections[i].type;
212 munmap(set->header, size);
213 free(set->buckets.data);
215 free(set->buckets.data);
216 free(set->string_pool.data);
217 free(set->packages.data);
218 free(set->requires.data);
219 free(set->provides.data);
220 free(set->property_pool.data);
227 razor_set_write(struct razor_set *set, const char *filename)
230 struct razor_set_header *header = (struct razor_set_header *) data;
231 unsigned long offset;
233 struct { int type; struct array *array; } sections[] = {
234 { RAZOR_STRINGS, &set->string_pool },
235 { RAZOR_PACKAGES, &set->packages },
236 { RAZOR_REQUIRES, &set->requires },
237 { RAZOR_PROVIDES, &set->provides },
238 { RAZOR_PROPERTIES, &set->property_pool },
242 memset(data, 0, sizeof data);
243 header->magic = RAZOR_MAGIC;
244 header->version = RAZOR_VERSION;
245 offset = sizeof data;
247 for (i = 0; sections[i].type != 0; i++) {
248 header->sections[i].type = sections[i].type;
249 header->sections[i].offset = offset;
250 header->sections[i].size = sections[i].array->size;
251 offset += (sections[i].array->size + 4095) & ~4095;
254 header->sections[i].type = 0;
255 header->sections[i].offset = 0;
256 header->sections[i].size = 0;
258 fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
262 write_to_fd(fd, data, sizeof data);
263 for (i = 0; sections[i].type != 0; i++)
264 write_to_fd(fd, sections[i].array->data,
265 (sections[i].array->size + 4095) & ~4095);
273 hash_string(const char *key)
276 unsigned int hash = 0;
278 for (p = key; *p; p++)
279 hash = (hash * 617) ^ *p;
285 razor_set_lookup(struct razor_set *set, const char *key)
287 unsigned int mask, start, i;
291 pool = set->string_pool.data;
292 mask = set->buckets.alloc - 1;
293 start = hash_string(key) * sizeof(unsigned long);
295 for (i = 0; i < set->buckets.alloc; i += sizeof *b) {
296 b = set->buckets.data + ((start + i) & mask);
301 if (strcmp(key, &pool[*b]) == 0)
309 add_to_string_pool(struct razor_set *set, const char *key)
314 len = strlen(key) + 1;
315 p = array_add(&set->string_pool, len);
318 return p - (char *) set->string_pool.data;
322 add_to_property_pool(struct razor_set *set, struct array *properties)
326 p = array_add(properties, sizeof *p);
328 p = array_add(&set->property_pool, properties->size);
329 memcpy(p, properties->data, properties->size);
331 return p - (unsigned long *) set->property_pool.data;
335 do_insert(struct razor_set *set, unsigned long value)
337 unsigned int mask, start, i;
341 key = (char *) set->string_pool.data + value;
342 mask = set->buckets.alloc - 1;
343 start = hash_string(key) * sizeof(unsigned long);
345 for (i = 0; i < set->buckets.alloc; i += sizeof *b) {
346 b = set->buckets.data + ((start + i) & mask);
355 razor_set_insert(struct razor_set *set, const char *key)
357 unsigned long value, *buckets, *b, *end;
360 alloc = set->buckets.alloc;
361 array_add(&set->buckets, 4 * sizeof *buckets);
362 if (alloc != set->buckets.alloc) {
363 end = set->buckets.data + alloc;
364 memset(end, 0, set->buckets.alloc - alloc);
365 for (b = set->buckets.data; b < end; b++) {
369 do_insert(set, value);
374 value = add_to_string_pool(set, key);
375 do_insert (set, value);
381 razor_set_tokenize(struct razor_set *set, const char *string)
386 return razor_set_tokenize(set, "");
388 token = razor_set_lookup(set, string);
392 return razor_set_insert(set, string);
395 struct import_property_context {
397 struct array package;
400 struct import_context {
401 struct razor_set *set;
402 struct import_property_context requires;
403 struct import_property_context provides;
404 struct array packages;
405 struct import_package *package;
406 unsigned long *requires_map;
407 unsigned long *provides_map;
410 struct import_package {
412 unsigned long version;
413 unsigned long requires;
414 unsigned long provides;
418 struct import_property {
420 unsigned long version;
421 unsigned long package;
423 unsigned long unique_index;
427 import_context_add_package(struct import_context *ctx,
428 const char *name, const char *version)
430 struct import_package *p;
432 p = array_add(&ctx->packages, sizeof *p);
433 p->name = razor_set_tokenize(ctx->set, name);
434 p->version = razor_set_tokenize(ctx->set, version);
435 p->index = p - (struct import_package *) ctx->packages.data;
438 array_init(&ctx->requires.package);
439 array_init(&ctx->provides.package);
443 import_context_finish_package(struct import_context *ctx)
445 struct import_package *p;
448 p->requires = add_to_property_pool(ctx->set, &ctx->requires.package);
449 p->provides = add_to_property_pool(ctx->set, &ctx->provides.package);
451 array_release(&ctx->requires.package);
452 array_release(&ctx->provides.package);
456 import_context_add_property(struct import_context *ctx,
457 struct import_property_context *pctx,
458 const char *name, const char *version)
460 struct import_property *p;
463 p = array_add(&pctx->all, sizeof *p);
464 p->name = razor_set_tokenize(ctx->set, name);
465 p->version = razor_set_tokenize(ctx->set, version);
466 p->package = ctx->package->index;
467 p->index = p - (struct import_property *) pctx->all.data;
469 r = array_add(&pctx->package, sizeof *r);
474 parse_package(struct import_context *ctx, const char **atts, void *data)
476 const char *name = NULL, *version = NULL;
479 for (i = 0; atts[i]; i += 2) {
480 if (strcmp(atts[i], "name") == 0)
482 else if (strcmp(atts[i], "version") == 0)
483 version = atts[i + 1];
486 if (name == NULL || version == NULL) {
487 fprintf(stderr, "invalid package tag, "
488 "missing name or version attributes\n");
492 import_context_add_package(ctx, name, version);
496 parse_property(struct import_context *ctx, const char **atts, void *data)
498 const char *name = NULL, *version = NULL;
501 for (i = 0; atts[i]; i += 2) {
502 if (strcmp(atts[i], "name") == 0)
504 if (strcmp(atts[i], "version") == 0)
505 version = atts[i + 1];
509 fprintf(stderr, "invalid tag, missing name attribute\n");
513 import_context_add_property(ctx, data, name, version);
517 start_element(void *data, const char *name, const char **atts)
519 struct import_context *ctx = data;
521 if (strcmp(name, "package") == 0)
522 parse_package(ctx, atts, NULL);
523 else if (strcmp(name, "requires") == 0)
524 parse_property(ctx, atts, &ctx->requires);
525 else if (strcmp(name, "provides") == 0)
526 parse_property(ctx, atts, &ctx->provides);
530 end_element (void *data, const char *name)
532 struct import_context *ctx = data;
534 if (strcmp(name, "package") == 0)
535 import_context_finish_package(ctx);
539 sha1_to_hex(const unsigned char *sha1)
542 static char hexbuffer[4][50];
543 static const char hex[] = "0123456789abcdef";
544 char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
547 for (i = 0; i < 20; i++) {
548 unsigned int val = *sha1++;
549 *buf++ = hex[val >> 4];
550 *buf++ = hex[val & 0xf];
558 razor_prepare_import(struct import_context *ctx)
560 memset(ctx, 0, sizeof *ctx);
561 ctx->set = razor_set_create();
565 razor_import(struct import_context *ctx, const char *filename)
573 unsigned char hash[20];
575 fd = open(filename, O_RDONLY);
576 if (fstat(fd, &stat) < 0)
578 p = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
582 parser = XML_ParserCreate(NULL);
583 XML_SetUserData(parser, ctx);
584 XML_SetElementHandler(parser, start_element, end_element);
585 if (XML_Parse(parser, p, stat.st_size, 1) == XML_STATUS_ERROR) {
587 "%s at line %d, %s\n",
588 XML_ErrorString(XML_GetErrorCode(parser)),
589 XML_GetCurrentLineNumber(parser),
594 XML_ParserFree(parser);
597 SHA1_Update(&sha1, p, stat.st_size);
598 SHA1_Final(hash, &sha1);
602 snprintf(buf, sizeof buf, "set/%s", sha1_to_hex(hash));
603 if (write_to_file(buf, p, stat.st_size) < 0)
605 munmap(p, stat.st_size);
610 static struct razor_set *qsort_set;
613 compare_packages(const void *p1, const void *p2)
615 const struct import_package *pkg1 = p1, *pkg2 = p2;
616 char *pool = qsort_set->string_pool.data;
618 return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
622 compare_properties(const void *p1, const void *p2)
624 const struct import_property *prop1 = p1, *prop2 = p2;
625 char *pool = qsort_set->string_pool.data;
628 result = strcmp(&pool[prop1->name], &pool[prop2->name]);
630 return strcmp(&pool[prop1->version], &pool[prop2->version]);
635 static unsigned long *
636 uniqueify_properties(struct razor_set *set,
637 struct array *in, struct array *out)
639 struct import_property *ip, *end;
640 struct razor_property *rp, *rp_end;
641 struct array *pkgs, *p;
642 unsigned long *map, *r;
643 int i, count, unique;
645 count = in->size / sizeof(struct import_property);
646 qsort(in->data, count,
647 sizeof(struct import_property), compare_properties);
650 end = in->data + in->size;
651 for (ip = in->data; ip < end; ip++) {
653 ip->name != rp->name || ip->version != rp->version) {
654 rp = array_add(out, sizeof *rp);
656 rp->version = ip->version;
658 ip->unique_index = rp - (struct razor_property *) out->data;
661 map = malloc(count * sizeof (unsigned long));
663 for (i = 0; i < count; i++)
664 map[ip[i].index] = ip[i].unique_index;
666 unique = out->size / sizeof(*rp);
667 pkgs = zalloc(unique * sizeof *pkgs);
668 for (ip = in->data; ip < end; ip++) {
669 r = array_add(&pkgs[ip->unique_index], sizeof *r);
673 rp_end = out->data + out->size;
674 for (rp = out->data, p = pkgs; rp < rp_end; rp++, p++)
675 rp->packages = add_to_property_pool(set, p);
683 remap_package_links(struct import_context *ctx)
685 struct import_package *p, *end;
686 unsigned long *pool, *r;
688 pool = ctx->set->property_pool.data;
689 end = ctx->packages.data + ctx->packages.size;
690 for (p = ctx->packages.data; p < end; p++) {
691 for (r = &pool[p->requires]; ~*r; r++)
692 *r = ctx->requires_map[*r];
693 for (r = &pool[p->provides]; ~*r; r++)
694 *r = ctx->provides_map[*r];
699 remap_property_links(struct import_context *ctx)
701 struct razor_property *p, *end;
702 struct import_package *ip;
703 unsigned long *map, *pool, *r;
706 pool = ctx->set->property_pool.data;
707 count = ctx->packages.size / sizeof(struct import_package);
708 map = malloc(count * sizeof *map);
709 ip = ctx->packages.data;
710 for (i = 0; i < count; i++)
711 map[ip[i].index] = i;
713 /* FIXME: This will break if we implement package list sharing
714 * for all properties, since we'll remap those lists more than
715 * once. We should just have a separate pool for property
716 * lists and a separate pool for package lists and remap it as
717 * a flat pool. Right now, as property lists and package
718 * lists are mixed, we can't do that. */
720 end = ctx->set->requires.data + ctx->set->requires.size;
721 for (p = ctx->set->requires.data; p < end; p++)
722 for (r = &pool[p->packages]; ~*r; r++)
725 end = ctx->set->provides.data + ctx->set->provides.size;
726 for (p = ctx->set->provides.data; p < end; p++)
727 for (r = &pool[p->packages]; ~*r; r++)
733 static struct razor_set *
734 razor_finish_import(struct import_context *ctx)
736 struct import_package *ip;
737 struct razor_package *rp;
740 qsort_set = ctx->set;
743 uniqueify_properties(ctx->set,
745 &ctx->set->requires);
747 uniqueify_properties(ctx->set,
749 &ctx->set->provides);
751 remap_package_links(ctx);
753 count = ctx->packages.size / sizeof(struct import_package);
754 qsort(ctx->packages.data, count,
755 sizeof(struct import_package), compare_packages);
757 ip = ctx->packages.data;
758 for (i = 0; i < count; i++, ip++, rp++) {
759 rp = array_add(&ctx->set->packages, sizeof *rp);
761 rp->version = ip->version;
762 rp->requires = ip->requires;
763 rp->provides = ip->provides;
766 remap_property_links(ctx);
768 free(ctx->requires.all.data);
769 free(ctx->provides.all.data);
770 free(ctx->requires_map);
771 free(ctx->provides_map);
773 fprintf(stderr, "parsed %d requires, %d unique\n",
774 ctx->requires.all.size / sizeof(struct import_property),
775 ctx->set->requires.size / sizeof(struct razor_property));
776 fprintf(stderr, "parsed %d provides, %d unique\n",
777 ctx->provides.all.size / sizeof(struct import_property),
778 ctx->set->provides.size / sizeof(struct razor_property));
783 /* Import a yum filelist as a razor package set. */
787 YUM_STATE_PACKAGE_NAME
791 struct import_context ctx;
792 struct import_property_context *current_property_context;
798 yum_start_element(void *data, const char *name, const char **atts)
800 struct yum_context *ctx = data;
801 const char *n, *version;
804 if (strcmp(name, "name") == 0) {
805 ctx->state = YUM_STATE_PACKAGE_NAME;
806 } else if (strcmp(name, "version") == 0) {
807 for (i = 0; atts[i]; i += 2) {
808 if (strcmp(atts[i], "ver") == 0)
809 version = atts[i + 1];
811 import_context_add_package(&ctx->ctx, ctx->name, version);
812 } else if (strcmp(name, "rpm:requires") == 0) {
813 ctx->current_property_context = &ctx->ctx.requires;
814 } else if (strcmp(name, "rpm:provides") == 0) {
815 ctx->current_property_context = &ctx->ctx.provides;
816 } else if (strcmp(name, "rpm:entry") == 0 &&
817 ctx->current_property_context != NULL) {
820 for (i = 0; atts[i]; i += 2) {
821 if (strcmp(atts[i], "name") == 0)
823 else if (strcmp(atts[i], "ver") == 0)
824 version = atts[i + 1];
828 fprintf(stderr, "invalid rpm:entry, "
829 "missing name or version attributes\n");
833 import_context_add_property(&ctx->ctx,
834 ctx->current_property_context,
840 yum_end_element (void *data, const char *name)
842 struct yum_context *ctx = data;
844 if (strcmp(name, "package") == 0) {
846 import_context_finish_package(&ctx->ctx);
847 } else if (strcmp(name, "name") == 0) {
849 } else if (strcmp(name, "rpm:requires") == 0) {
850 ctx->current_property_context = NULL;
851 } else if (strcmp(name, "rpm:provides") == 0) {
852 ctx->current_property_context = NULL;
857 yum_character_data (void *data, const XML_Char *s, int len)
859 struct yum_context *ctx = data;
861 if (ctx->state == YUM_STATE_PACKAGE_NAME)
862 ctx->name = strndup(s, len);
865 static struct razor_set *
866 razor_set_create_from_yum_filelist(int fd)
868 struct yum_context ctx;
873 razor_prepare_import(&ctx.ctx);
875 parser = XML_ParserCreate(NULL);
876 XML_SetUserData(parser, &ctx);
877 XML_SetElementHandler(parser, yum_start_element, yum_end_element);
878 XML_SetCharacterDataHandler(parser, yum_character_data);
881 len = read(fd, buf, sizeof buf);
884 "couldn't read input: %s\n", strerror(errno));
889 if (XML_Parse(parser, buf, len, 0) == XML_STATUS_ERROR) {
892 XML_ErrorString(XML_GetErrorCode(parser)),
893 XML_GetCurrentLineNumber(parser));
898 XML_ParserFree(parser);
900 return razor_finish_import(&ctx.ctx);
904 razor_set_list(struct razor_set *set)
906 struct razor_package *p, *end;
909 pool = set->string_pool.data;
910 end = set->packages.data + set->packages.size;
911 for (p = set->packages.data; p < end; p++)
912 printf("%s %s\n", &pool[p->name], &pool[p->version]);
915 struct razor_set *bsearch_set;
918 compare_package_name(const void *key, const void *data)
920 const struct razor_package *p = data;
923 pool = bsearch_set->string_pool.data;
925 return strcmp(key, &pool[p->name]);
928 struct razor_package *
929 razor_set_get_package(struct razor_set *set, const char *package)
932 return bsearch(package, set->packages.data,
933 set->packages.size / sizeof(struct razor_package),
934 sizeof(struct razor_package), compare_package_name);
938 compare_property_name(const void *key, const void *data)
940 const struct razor_property *p = data;
943 pool = bsearch_set->string_pool.data;
945 return strcmp(key, &pool[p->name]);
948 struct razor_property *
949 razor_set_get_property(struct razor_set *set,
950 struct array *properties,
951 const char *property)
953 struct razor_property *p, *start;
956 p = bsearch(property, properties->data,
957 properties->size / sizeof(struct razor_property),
958 sizeof(struct razor_property), compare_property_name);
960 start = properties->data;
961 while (p > start && (p - 1)->name == p->name)
968 razor_set_list_all_properties(struct razor_set *set, struct array *properties)
970 struct razor_property *p, *end;
973 pool = set->string_pool.data;
974 end = properties->data + properties->size;
975 for (p = properties->data; p < end; p++)
976 printf("%s %s\n", &pool[p->name], &pool[p->version]);
980 razor_set_list_requires(struct razor_set *set, const char *name)
982 struct razor_property *p, *requires;
983 struct razor_package *package;
988 package = razor_set_get_package(set, name);
989 r = (unsigned long *) set->property_pool.data +
991 requires = set->requires.data;
992 pool = set->string_pool.data;
995 printf("%s %s\n", &pool[p->name], &pool[p->version]);
998 razor_set_list_all_properties(set, &set->requires);
1002 razor_set_list_provides(struct razor_set *set, const char *name)
1004 struct razor_property *p, *provides;
1005 struct razor_package *package;
1010 package = razor_set_get_package(set, name);
1011 r = (unsigned long *) set->property_pool.data +
1013 provides = set->provides.data;
1014 pool = set->string_pool.data;
1016 p = &provides[*r++];
1017 printf("%s %s\n", &pool[p->name], &pool[p->version]);
1020 razor_set_list_all_properties(set, &set->provides);
1024 razor_set_list_property_packages(struct razor_set *set,
1025 struct array *properties,
1028 struct razor_property *property, *end;
1029 struct razor_package *p, *packages;
1036 property = razor_set_get_property(set, properties, name);
1037 packages = set->packages.data;
1038 pool = set->string_pool.data;
1039 end = properties->data + properties->size;
1040 while (property < end && strcmp(name, &pool[property->name]) == 0) {
1041 r = (unsigned long *)
1042 set->property_pool.data + property->packages;
1044 p = &packages[*r++];
1046 &pool[p->name], &pool[p->version]);
1053 razor_set_info(struct razor_set *set)
1055 unsigned int offset, size;
1058 for (i = 0; i < set->header->sections[i].type; i++) {
1059 offset = set->header->sections[i].offset;
1060 size = set->header->sections[i].size;
1062 switch (set->header->sections[i].type) {
1064 printf("string pool:\t\t%dkb\n", size / 1024);
1066 case RAZOR_PACKAGES:
1067 printf("package section:\t%dkb\n", size / 1024);
1069 case RAZOR_REQUIRES:
1070 printf("requires section:\t%dkb\n", size / 1024);
1072 case RAZOR_PROVIDES:
1073 printf("provides section:\t%dkb\n", size / 1024);
1075 case RAZOR_PROPERTIES:
1076 printf("properties section:\t%dkb\n", size / 1024);
1085 printf("usage: razor [ import FILES | lookup <key> | "
1086 "list | list-requires | list-provides | eat-yum | info ]\n");
1090 static const char *repo_filename = "system.repo";
1091 static const char rawhide_repo_filename[] = "rawhide.repo";
1094 main(int argc, char *argv[])
1097 struct razor_set *set;
1098 struct stat statbuf;
1099 struct import_context ctx;
1102 repo = getenv("RAZOR_REPO");
1104 repo_filename = repo;
1108 } else if (strcmp(argv[1], "import") == 0) {
1109 if (stat("set", &statbuf) && mkdir("set", 0777)) {
1110 fprintf(stderr, "could not create directory 'set'\n");
1114 razor_prepare_import(&ctx);
1116 for (i = 2; i < argc; i++) {
1117 if (razor_import(&ctx, argv[i]) < 0) {
1118 fprintf(stderr, "failed to import %s\n",
1124 set = razor_finish_import(&ctx);
1126 printf("bucket allocation: %d\n", set->buckets.alloc);
1127 printf("pool size: %d\n", set->string_pool.size);
1128 printf("pool allocation: %d\n", set->string_pool.alloc);
1129 printf("packages: %d\n",
1130 set->packages.size / sizeof(struct razor_package));
1131 printf("requires: %d\n",
1132 set->requires.size / sizeof(struct razor_property));
1133 printf("provides: %d\n",
1134 set->provides.size / sizeof(struct razor_property));
1136 razor_set_write(set, repo_filename);
1138 razor_set_destroy(set);
1139 } else if (strcmp(argv[1], "lookup") == 0) {
1140 set = razor_set_open(repo_filename);
1141 printf("%s is %lu\n", argv[2],
1142 razor_set_lookup(set, argv[2]));
1143 razor_set_destroy(set);
1144 } else if (strcmp(argv[1], "list") == 0) {
1145 set = razor_set_open(repo_filename);
1146 razor_set_list(set);
1147 razor_set_destroy(set);
1148 } else if (strcmp(argv[1], "list-requires") == 0) {
1149 set = razor_set_open(repo_filename);
1150 razor_set_list_requires(set, argv[2]);
1151 razor_set_destroy(set);
1152 } else if (strcmp(argv[1], "list-provides") == 0) {
1153 set = razor_set_open(repo_filename);
1154 razor_set_list_provides(set, argv[2]);
1155 razor_set_destroy(set);
1156 } else if (strcmp(argv[1], "what-requires") == 0) {
1157 set = razor_set_open(repo_filename);
1158 razor_set_list_property_packages(set, &set->requires, argv[2]);
1159 razor_set_destroy(set);
1160 } else if (strcmp(argv[1], "what-provides") == 0) {
1161 set = razor_set_open(repo_filename);
1162 razor_set_list_property_packages(set, &set->provides, argv[2]);
1163 razor_set_destroy(set);
1164 } else if (strcmp(argv[1], "info") == 0) {
1165 set = razor_set_open(repo_filename);
1166 razor_set_info(set);
1167 razor_set_destroy(set);
1168 } else if (strcmp(argv[1], "eat-yum") == 0) {
1169 set = razor_set_create_from_yum_filelist(STDIN_FILENO);
1172 razor_set_write(set, rawhide_repo_filename);
1173 razor_set_destroy(set);
1174 printf("wrote %s\n", rawhide_repo_filename);