# HG changeset patch # User Kristian H?gsberg # Date 1212600469 14400 # Node ID b97c130460a5cf24c5bc220e0fa95bf5c464cc3e # Parent 85381bba83dffc37b63ec76b421677d36a6c6f39 Flesh out the rpm -q part of the rpm command line wrapper. diff -r 85381bba83df -r b97c130460a5 Makefile --- a/Makefile Tue Jun 03 15:21:22 2008 -0400 +++ b/Makefile Wed Jun 04 13:27:49 2008 -0400 @@ -10,7 +10,7 @@ test-driver : razor.o types.o util.o test-driver.o -rpm-razor : rpm-razor.o +rpm-razor : rpm-razor.o razor.o types.o util.o test : test-driver ./test-driver test.xml diff -r 85381bba83df -r b97c130460a5 razor.c --- a/razor.c Tue Jun 03 15:21:22 2008 -0400 +++ b/razor.c Wed Jun 04 13:27:49 2008 -0400 @@ -810,6 +810,7 @@ struct razor_set *set; struct razor_package *package, *end; struct list *index; + int free_index; }; static struct razor_package_iterator * @@ -886,6 +887,9 @@ void razor_package_iterator_destroy(struct razor_package_iterator *pi) { + if (pi->free_index) + free(pi->index); + free(pi); } @@ -2993,3 +2997,78 @@ /* FIXME: free upstream if it was created as an empty set */ } + +struct razor_package_query { + struct razor_set *set; + char *vector; + int count; +}; + +struct razor_package_query * +razor_package_query_create(struct razor_set *set) +{ + struct razor_package_query *pq; + int count; + + pq = zalloc(sizeof *pq); + pq->set = set; + count = set->packages.size / sizeof(struct razor_package); + pq->vector = zalloc(count * sizeof(char)); + + return pq; +} + +void +razor_package_query_add_package(struct razor_package_query *pq, + struct razor_package *p) +{ + struct razor_package *packages; + + packages = pq->set->packages.data; + pq->count += pq->vector[p - packages] ^ 1; + pq->vector[p - packages] = 1; +} + +void +razor_package_query_add_iterator(struct razor_package_query *pq, + struct razor_package_iterator *pi) +{ + struct razor_package *packages, *p; + const char *name, *version, *arch; + + packages = pq->set->packages.data; + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) { + pq->count += pq->vector[p - packages] ^ 1; + pq->vector[p - packages] = 1; + } +} + +struct razor_package_iterator * +razor_package_query_finish(struct razor_package_query *pq) +{ + struct razor_package_iterator *pi; + struct razor_set *set; + struct list *index; + int i, j, count; + + set = pq->set; + count = set->packages.size / sizeof(struct razor_package); + index = zalloc(pq->count * sizeof *index); + + for (i = 0, j = 0; i < count; i++) { + if (!pq->vector[i]) + continue; + + index[j].data = i; + if (j == pq->count - 1) + index[j].flags = 0x80; + j++; + } + + free(pq); + + pi = razor_package_iterator_create_with_index(set, index); + pi->free_index = 1; + + return pi; +} diff -r 85381bba83df -r b97c130460a5 razor.h --- a/razor.h Tue Jun 03 15:21:22 2008 -0400 +++ b/razor.h Wed Jun 04 13:27:49 2008 -0400 @@ -68,6 +68,17 @@ const char **arch); void razor_package_iterator_destroy(struct razor_package_iterator *pi); +struct razor_package_query * +razor_package_query_create(struct razor_set *set); +void +razor_package_query_add_package(struct razor_package_query *pq, + struct razor_package *p); +void +razor_package_query_add_iterator(struct razor_package_query *pq, + struct razor_package_iterator *pi); +struct razor_package_iterator * +razor_package_query_finish(struct razor_package_query *pq); + struct razor_property_iterator; struct razor_property_iterator * razor_property_iterator_create(struct razor_set *set, diff -r 85381bba83df -r b97c130460a5 rpm-razor.c --- a/rpm-razor.c Tue Jun 03 15:21:22 2008 -0400 +++ b/rpm-razor.c Wed Jun 04 13:27:49 2008 -0400 @@ -38,7 +38,8 @@ void *data; }; -static int option_all; +static int option_all, option_whatrequires, option_whatprovides; + static const struct option query_options[] = { { OPTION_BOOL, "configfiles", 'c', NULL, "list all configuration files", NULL }, @@ -57,8 +58,8 @@ { OPTION_BOOL, "fileid", 0, NULL, "query/verify package(s) with file identifier", NULL }, { OPTION_BOOL, "specfile", 0, NULL, "query a spec file", NULL, }, { OPTION_BOOL, "triggeredby", 0, NULL, "query the package(s) triggered by the package", NULL }, - { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", NULL }, - { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", NULL }, + { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", &option_whatrequires }, + { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", &option_whatprovides }, { OPTION_BOOL, "nomanifest", 0, NULL, "do not process non-package files as manifests", NULL }, { } }; @@ -78,8 +79,8 @@ { OPTION_BOOL, "fileid", 0, NULL, "query/verify package(s) with file identifier", NULL }, { OPTION_BOOL, "specfile", 0, NULL, "query a spec file", NULL }, { OPTION_BOOL, "triggeredby", 0, NULL, "query the package(s) triggered by the package", NULL }, - { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", NULL }, - { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", NULL }, + { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", &option_whatrequires }, + { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", &option_whatprovides }, { OPTION_BOOL, "nomanifest", 0, NULL, "do not process non-package files as manifests", NULL }, { } }; @@ -169,14 +170,16 @@ { } }; +static int option_conflicts, option_obsoletes, option_requires, option_provides; + static const struct option alias_options[] = { { OPTION_BOOL, "scripts", 0, NULL, "list install/erase scriptlets from package(s)", NULL, }, { OPTION_BOOL, "setperms", 0, NULL, "set permissions of files in a package", NULL, }, { OPTION_BOOL, "setugids", 0, NULL, "set user/group ownership of files in a package", NULL, }, - { OPTION_BOOL, "conflicts", 0, NULL, "list capabilities this package conflicts with", NULL, }, - { OPTION_BOOL, "obsoletes", 0, NULL, "list other packages removed by installing this package", NULL, }, - { OPTION_BOOL, "provides", 0, NULL, "list capabilities that this package provides", NULL, }, - { OPTION_BOOL, "requires", 0, NULL, "list capabilities required by package(s)", NULL, }, + { OPTION_BOOL, "conflicts", 0, NULL, "list capabilities this package conflicts with", &option_conflicts, }, + { OPTION_BOOL, "obsoletes", 0, NULL, "list other packages removed by installing this package", &option_obsoletes, }, + { OPTION_BOOL, "provides", 0, NULL, "list capabilities that this package provides", &option_provides, }, + { OPTION_BOOL, "requires", 0, NULL, "list capabilities required by package(s)", &option_requires, }, { OPTION_BOOL, "info", 0, NULL, "list descriptive information from package(s)", NULL, }, { OPTION_BOOL, "changelog", 0, NULL, "list change logs for this package", NULL, }, { OPTION_BOOL, "xml", 0, NULL, "list metadata in xml", NULL, }, @@ -224,15 +227,168 @@ { } }; +static const char system_repo_filename[] = "system.repo"; +static const char *repo_filename = system_repo_filename; + +static struct razor_property * +add_property_packages(struct razor_set *set, + struct razor_package_query *query, + const char *ref_name, + const char *ref_version, + enum razor_property_type ref_type) +{ + struct razor_property *property; + struct razor_property_iterator *pi; + struct razor_package_iterator *pkgi; + const char *name, *version; + enum razor_property_type type; + enum razor_version_relation relation; + + pi = razor_property_iterator_create(set, NULL); + while (razor_property_iterator_next(pi, &property, &name, + &relation, &version, &type)) { + if (strcmp(ref_name, name) != 0) + continue; + if (ref_version && relation == RAZOR_VERSION_EQUAL && + strcmp(ref_version, version) != 0) + continue; + if (ref_type != type) + continue; + + pkgi = razor_package_iterator_create_for_property(set, + property); + razor_package_query_add_iterator(query, pkgi); + razor_package_iterator_destroy(pkgi); + } + razor_property_iterator_destroy(pi); + + return property; +} + +static int +strcmpp(const void *p1, const void *p2) +{ + return strcmp(*(char * const *) p1, *(char * const *) p2); +} + +static void +add_command_line_packages(struct razor_set *set, + struct razor_package_query *query, + int argc, const char **argv) +{ + struct razor_package *package; + struct razor_package_iterator *pi; + const char *name, *version, *arch; + int i, cmp; + + qsort(argv, argc, sizeof(*argv), strcmpp); + i = 0; + + pi = razor_package_iterator_create(set); + + while (razor_package_iterator_next(pi, &package, + &name, &version, &arch)) { + while (cmp = strcmp(argv[i], name), cmp < 0 && i < argc) { + printf("package %s is not installed\n", argv[i]); + i++; + } + + if (cmp == 0) { + razor_package_query_add_package(query, package); + i++; + } + } + + razor_package_iterator_destroy(pi); +} + +static void +print_package_properties(struct razor_set *set, + struct razor_package *package, + enum razor_property_type ref_type) +{ + struct razor_property *property; + struct razor_property_iterator *pi; + const char *name, *version; + enum razor_property_type type; + enum razor_version_relation relation; + + pi = razor_property_iterator_create(set, package); + while (razor_property_iterator_next(pi, &property, + &name, &relation, &version, + &type)) { + if (type != ref_type) + continue; + if (version[0] == '\0') + printf("%s\n", name); + else + printf("%s %s %s\n", name, + razor_version_relations[relation], version); + } + razor_property_iterator_destroy(pi); +} + static void command_query(int argc, const char *argv[]) { - if (argc == 0 && !option_all) { + struct razor_set *set; + struct razor_package_iterator *pi; + struct razor_package *package; + struct razor_package_query *query; + const char *name, *version, *arch; + + set = razor_set_open(repo_filename); + + if (option_all + option_whatprovides + option_whatrequires > 1) { + printf("only one type of query/verify " + "may be performed at a time\n"); + exit(1); + } + + query = razor_package_query_create(set); + if (option_all) { + pi = razor_package_iterator_create(set); + razor_package_query_add_iterator(query, pi); + razor_package_iterator_destroy(pi); + } else if (option_whatrequires) { + add_property_packages(set, query, + argv[0], NULL, RAZOR_PROPERTY_REQUIRES); + } else if (option_whatprovides) { + add_property_packages(set, query, + argv[0], NULL, RAZOR_PROPERTY_PROVIDES); + } else if (argc > 0) { + add_command_line_packages(set, query, argc, argv); + } else { printf("no arguments given for query\n"); exit(1); } - printf("command query - not implemented\n"); + pi = razor_package_query_finish(query); + + while (razor_package_iterator_next(pi, &package, + &name, &version, &arch)) { + if (option_conflicts) + print_package_properties(set, package, + RAZOR_PROPERTY_CONFLICTS); + if (option_obsoletes) + print_package_properties(set, package, + RAZOR_PROPERTY_OBSOLETES); + if (option_requires) + print_package_properties(set, package, + RAZOR_PROPERTY_REQUIRES); + if (option_provides) + print_package_properties(set, package, + RAZOR_PROPERTY_PROVIDES); + if (!option_conflicts && !option_obsoletes && + !option_requires && !option_provides) + printf("%s-%s.%s\n", name, version, arch); + } + + razor_package_iterator_destroy(pi); + + razor_set_destroy(set); + + return; } static void