When uniquifying properties, also sort them on the owning package.
This ensures that whenever two packages provide or (or require, obsolete
or conflict) the same property, they appear in the same order in the
propertys list of packages.
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 enum option_type type;
39 const char *description;
43 /* A note about all these options: rpm allows options to mean
44 * different things depending on what other options are present on the
45 * command line. For example, if -q or --query is present, -i no
46 * longer means install, but info. The way we handle this is by
47 * setting all the options that may match (ie if -i is given we set
48 * install and info), and then look at the relevent one depending on
49 * what else in on the command line. */
51 static int option_all, option_whatrequires, option_whatprovides;
52 static int option_package;
54 static const struct option query_options[] = {
55 { OPTION_BOOL, "configfiles", 'c', NULL, "list all configuration files", NULL },
56 { OPTION_BOOL, "docfiles", 'd', NULL, "list all documentation files", NULL },
57 { OPTION_BOOL, "dump", 0, NULL, "dump basic file information", NULL },
58 { OPTION_BOOL, "list", 0, NULL, "list files in package", NULL },
59 { OPTION_STRING, "queryformat", 0, "QUERYFORMAT", "use the following query format", NULL },
60 { OPTION_BOOL, "state", 's', NULL, "display the states of the listed files", NULL },
61 { OPTION_BOOL, "all", 'a', NULL, "query/verify all packages", &option_all },
62 { OPTION_BOOL, "file", 'f', NULL, "query/verify package(s) owning file", NULL },
63 { OPTION_BOOL, "group", 'g', NULL, "query/verify package(s) in group", NULL },
64 { OPTION_BOOL, "package", 'p', NULL, "query/verify a package file", &option_package },
65 { OPTION_BOOL, "ftswalk", 'W', NULL, "query/verify package(s) from TOP file tree walk", NULL },
66 { OPTION_BOOL, "pkgid", 0, NULL, "query/verify package(s) with package identifier", NULL },
67 { OPTION_BOOL, "hdrid", 0, NULL, "query/verify package(s) with header identifier", NULL },
68 { OPTION_BOOL, "fileid", 0, NULL, "query/verify package(s) with file identifier", NULL },
69 { OPTION_BOOL, "specfile", 0, NULL, "query a spec file", NULL, },
70 { OPTION_BOOL, "triggeredby", 0, NULL, "query the package(s) triggered by the package", NULL },
71 { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", &option_whatrequires },
72 { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", &option_whatprovides },
73 { OPTION_BOOL, "nomanifest", 0, NULL, "do not process non-package files as manifests", NULL },
77 static int option_nodeps;
79 static const struct option verify_options[] = {
80 { OPTION_BOOL, "nomd5", 0, NULL, "don't verify MD5 digest of files", NULL },
81 { OPTION_BOOL, "nofiles", 0, NULL, "don't verify files in package", NULL },
82 { OPTION_BOOL, "nodeps", 0, NULL, "don't verify package dependencies", &option_nodeps },
83 { OPTION_BOOL, "noscript", 0, NULL, "don't execute verify script(s)", NULL, },
84 { OPTION_BOOL, "all", 'a', NULL, "query/verify all packages", &option_all },
85 { OPTION_BOOL, "file", 'f', NULL, "query/verify package(s) owning file", NULL },
86 { OPTION_BOOL, "group", 'g', NULL, "query/verify package(s) in group", NULL },
87 { OPTION_BOOL, "package", 'p', NULL, "query/verify a package file", &option_package },
88 { OPTION_BOOL, "ftswalk", 'W', NULL, "query/verify package(s) from TOP file tree walk", NULL },
89 { OPTION_BOOL, "pkgid", 0, NULL, "query/verify package(s) with package identifier", NULL },
90 { OPTION_BOOL, "hdrid", 0, NULL, "query/verify package(s) with header identifier", NULL },
91 { OPTION_BOOL, "fileid", 0, NULL, "query/verify package(s) with file identifier", NULL },
92 { OPTION_BOOL, "specfile", 0, NULL, "query a spec file", NULL },
93 { OPTION_BOOL, "triggeredby", 0, NULL, "query the package(s) triggered by the package", NULL },
94 { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", &option_whatrequires },
95 { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", &option_whatprovides },
96 { OPTION_BOOL, "nomanifest", 0, NULL, "do not process non-package files as manifests", NULL },
100 static const struct option ftw_options[] = {
101 { OPTION_BOOL, "comfollow", 0, NULL, "FTS_COMFOLLOW: follow command line symlinks", NULL },
102 { OPTION_BOOL, "logical", 0, NULL, "FTS_LOGICAL: logical walk", NULL },
103 { OPTION_BOOL, "nochdir", 0, NULL, "FTS_NOCHDIR: don't change directories", NULL },
104 { OPTION_BOOL, "nostat", 0, NULL, "FTS_NOSTAT: don't get stat info", NULL },
105 { OPTION_BOOL, "physical", 0, NULL, "FTS_PHYSICAL: physical walk", NULL },
106 { OPTION_BOOL, "seedot", 0, NULL, "FTS_SEEDOT: return dot and dot-dot", NULL },
107 { OPTION_BOOL, "xdev", 0, NULL, "FTS_XDEV: don't cross devices", NULL },
108 { OPTION_BOOL, "whiteout", 0, NULL, "FTS_WHITEOUT: return whiteout information", NULL },
112 static const struct option signature_options[] = {
113 { OPTION_BOOL, "addsign", 0, NULL, "sign package(s) (identical to --resign)", NULL, },
114 { OPTION_BOOL, "checksig", 'K', NULL, "verify package signature(s)", NULL, },
115 { OPTION_BOOL, "delsign", 0, NULL, "delete package signatures", NULL, },
116 { OPTION_BOOL, "import", 0, NULL, "import an armored public key", NULL, },
117 { OPTION_BOOL, "resign", 0, NULL, "sign package(s) (identical to --addsign)", NULL, },
118 { OPTION_BOOL, "nodigest", 0, NULL, "don't verify package digest(s)", NULL, },
119 { OPTION_BOOL, "nosignature", 0, NULL, "don't verify package signature(s)", NULL },
123 static int option_initdb;
125 static const struct option database_options[] = {
126 { OPTION_BOOL, "initdb", 0, NULL, "initialize database", &option_initdb },
127 { OPTION_BOOL, "rebuilddb", 0, NULL, "rebuild database inverted lists from installed package headers", NULL },
131 static int option_erase, option_install, option_upgrade, option_justdb;
132 static int option_test;
134 static const struct option install_options[] = {
135 { OPTION_BOOL, "aid", 0, NULL, "add suggested packages to transaction", NULL, },
136 { OPTION_BOOL, "allfiles", 0, NULL, "install all files, even configurations which might otherwise be skipped", NULL, },
137 { OPTION_BOOL, "allmatches", 0, NULL, "remove all packages which match <package> (normally an error is generated if <package> specified multiple packages)", NULL, },
138 { OPTION_BOOL, "badreloc", 0, NULL, "relocate files in non-relocatable package", NULL },
139 { OPTION_BOOL, "erase", 'e', "<package>", "erase (uninstall) package", &option_erase },
140 { OPTION_BOOL, "excludedocs", 0, NULL, "do not install documentation", NULL, },
141 { OPTION_BOOL, "excludepath", 0, "<path>", "skip files with leading component <path> ", NULL, },
142 { OPTION_BOOL, "fileconflicts", 0, NULL, "detect file conflicts between packages", NULL, },
143 { OPTION_BOOL, "force", 0, NULL, "short hand for --replacepkgs --replacefiles", NULL },
144 { OPTION_BOOL, "freshen", 'F', "<packagefile>+", "upgrade package(s) if already installed", NULL },
145 { OPTION_BOOL, "hash", 'h', NULL, "print hash marks as package installs (good with -v)", NULL },
146 { OPTION_BOOL, "ignorearch", 0, NULL, "don't verify package architecture", NULL, },
147 { OPTION_BOOL, "ignoreos", 0, NULL, "don't verify package operating system", NULL, },
148 { OPTION_BOOL, "ignoresize", 0, NULL, "don't check disk space before installing", NULL },
149 { OPTION_BOOL, "install", 'i', NULL, "install package(s)", &option_install },
150 { OPTION_BOOL, "justdb", 0, NULL, "update the database, but do not modify the filesystem", &option_justdb, },
151 { OPTION_BOOL, "nodeps", 0, NULL, "do not verify package dependencies", &option_nodeps, },
152 { OPTION_BOOL, "nomd5", 0, NULL, "don't verify MD5 digest of files", NULL, },
153 { OPTION_BOOL, "nocontexts", 0, NULL, "don't install file security contexts", NULL, },
154 { OPTION_BOOL, "noorder", 0, NULL, "do not reorder package installation to satisfy dependencies", NULL, },
155 { OPTION_BOOL, "nosuggest", 0, NULL, "do not suggest missing dependency resolution(s)", NULL, },
156 { OPTION_BOOL, "noscripts", 0, NULL, "do not execute package scriptlet(s)", NULL, },
157 { OPTION_BOOL, "notriggers", 0, NULL, "do not execute any scriptlet(s) triggered by this package", NULL, },
158 { OPTION_BOOL, "oldpackage", 0, NULL, "upgrade to an old version of the package (--force on upgrades does this automatically)", NULL },
159 { OPTION_BOOL, "percent", 0, NULL, "print percentages as package installs", NULL, },
160 { OPTION_STRING, "prefix", 0, "<dir>", "relocate the package to <dir>, if relocatable", NULL, },
161 { OPTION_STRING, "relocate", 0, "<old>=<new>", "relocate files from path <old> to <new>", NULL, },
162 { OPTION_BOOL, "repackage", 0, NULL, "save erased package files by repackaging", NULL, },
163 { OPTION_BOOL, "replacefiles", 0, NULL, "ignore file conflicts between packages", NULL, },
164 { OPTION_BOOL, "replacepkgs", 0, NULL, "reinstall if the package is already present", NULL, },
165 { OPTION_BOOL, "test", 0, NULL, "don't install, but tell if it would work or not", &option_test },
166 { OPTION_BOOL, "upgrade", 'U', "<packagefile>+", "upgrade package(s)", &option_upgrade },
170 static int option_version;
171 static const char *option_root = "install";
173 static const struct option common_options[] = {
174 { OPTION_STRING, "define", 'D', "MACRO EXPR", "define MACRO with value EXPR", NULL, },
175 { OPTION_STRING, "eval", 'E', "EXPR", "print macro expansion of EXPR", NULL },
176 { OPTION_STRING, "macros", 0, "<FILE:...>", "read <FILE:...> instead of default file(s)", NULL },
177 { OPTION_BOOL, "nodigest", 0, NULL, "don't verify package digest(s)", NULL, },
178 { OPTION_BOOL, "nosignature", 0, NULL, "don't verify package signature(s)", NULL, },
179 { OPTION_STRING, "rcfile", 0, "<FILE:...>", "read <FILE:...> instead of default file(s)", NULL },
180 { OPTION_STRING, "root", 'r', "ROOT", "use ROOT as top level directory (default: \"/\")", &option_root },
181 { OPTION_BOOL, "querytags", 0, NULL, "display known query tags", NULL, },
182 { OPTION_BOOL, "showrc", 0, NULL, "display final rpmrc and macro configuration", NULL, },
183 { OPTION_BOOL, "quiet", 0, NULL, "provide less detailed output", NULL },
184 { OPTION_BOOL, "verbose", 'v', NULL, "provide more detailed output", NULL },
185 { OPTION_BOOL, "version", 0, NULL, "print the version of rpm being used", &option_version },
189 static int option_conflicts, option_obsoletes, option_requires;
190 static int option_provides, option_info, option_changelog;
192 static const struct option alias_options[] = {
193 { OPTION_BOOL, "scripts", 0, NULL, "list install/erase scriptlets from package(s)", NULL, },
194 { OPTION_BOOL, "setperms", 0, NULL, "set permissions of files in a package", NULL, },
195 { OPTION_BOOL, "setugids", 0, NULL, "set user/group ownership of files in a package", NULL, },
196 { OPTION_BOOL, "conflicts", 0, NULL, "list capabilities this package conflicts with", &option_conflicts, },
197 { OPTION_BOOL, "obsoletes", 0, NULL, "list other packages removed by installing this package", &option_obsoletes, },
198 { OPTION_BOOL, "provides", 0, NULL, "list capabilities that this package provides", &option_provides, },
199 { OPTION_BOOL, "requires", 0, NULL, "list capabilities required by package(s)", &option_requires, },
200 { OPTION_BOOL, "info", 'i', NULL, "list descriptive information from package(s)", &option_info, },
201 { OPTION_BOOL, "changelog", 0, NULL, "list change logs for this package", &option_changelog, },
202 { OPTION_BOOL, "xml", 0, NULL, "list metadata in xml", NULL, },
203 { OPTION_BOOL, "triggers", 0, NULL, "list trigger scriptlets from package(s)", NULL, },
204 { OPTION_BOOL, "last", 0, NULL, "list package(s) by install time, most recent first", NULL, },
205 { OPTION_BOOL, "dupes", 0, NULL, "list duplicated packages", NULL, },
206 { OPTION_BOOL, "filesbypkg", 0, NULL, "list all files from each package", NULL, },
207 { OPTION_BOOL, "fileclass", 0, NULL, "list file names with classes", NULL, },
208 { OPTION_BOOL, "filecolor", 0, NULL, "list file names with colors", NULL, },
209 { OPTION_BOOL, "filecontext", 0, NULL, "list file names with security context from header", NULL, },
210 { OPTION_BOOL, "fscontext", 0, NULL, "list file names with security context from file system", NULL, },
211 { OPTION_BOOL, "recontext", 0, NULL, "list file names with security context from policy RE", NULL, },
212 { OPTION_BOOL, "fileprovide", 0, NULL, "list file names with provides", NULL, },
213 { OPTION_BOOL, "filerequire", 0, NULL, "list file names with requires", NULL, },
214 { OPTION_BOOL, "redhatprovides", 0, NULL, "find package name that contains a provided capability (needs rpmdb-redhat package installed)", NULL, },
215 { OPTION_BOOL, "redhatrequires", 0, NULL, "find package name that contains a required capability (needs rpmdb-redhat package installed)", NULL, },
216 { OPTION_STRING, "buildpolicy", 0, "<policy>", "set buildroot <policy> (e.g. compress man pages)", NULL, },
217 { OPTION_BOOL, "with", 0, "<option>", "enable configure <option> for build", NULL, },
218 { OPTION_BOOL, "without", 0, "<option>", "disable configure <option> for build", NULL },
222 static int option_help, option_usage;
224 static const struct option help_options[] = {
225 { OPTION_BOOL, "help", '?', NULL, "Show this help message", &option_help },
226 { OPTION_BOOL, "usage", 0, NULL, "Display brief usage message", &option_usage},
230 static int option_query, option_verify;
232 static const struct option rpm_options[] = {
233 { OPTION_BOOL, "query", 'q', NULL, "Query rpm database", &option_query },
234 { OPTION_BOOL, "verify", 'V', NULL, "Verify rpm database", &option_verify },
235 { OPTION_GROUP, NULL, 0, NULL, "Query options (with -q or --query):", &query_options },
236 { OPTION_GROUP, NULL, 0, NULL, "Verify options (with -V or --verify):", &verify_options },
237 { OPTION_GROUP, NULL, 0, NULL, "File tree walk options (with --ftswalk):", &ftw_options },
238 { OPTION_GROUP, NULL, 0, NULL, "Signature options:", &signature_options },
239 { OPTION_GROUP, NULL, 0, NULL, "Database options:", &database_options },
240 { OPTION_GROUP, NULL, 0, NULL, "Install/Upgrade/Erase options:", &install_options },
241 { OPTION_GROUP, NULL, 0, NULL, "Common options for all rpm modes and executables:", &common_options },
242 { OPTION_GROUP, NULL, 0, NULL, "Options implemented via popt alias/exec:", &alias_options },
243 { OPTION_GROUP, NULL, 0, NULL, "Help options", &help_options },
247 static const char system_repo_filename[] = "system.repo";
248 static const char *repo_filename = system_repo_filename;
251 command_initdb(int argc, const char *argv[])
253 razor_root_create(option_root);
256 static struct razor_property *
257 add_property_packages(struct razor_set *set,
258 struct razor_package_query *query,
259 const char *ref_name,
260 const char *ref_version,
263 struct razor_property *property;
264 struct razor_property_iterator *pi;
265 struct razor_package_iterator *pkgi;
266 const char *name, *version;
269 pi = razor_property_iterator_create(set, NULL);
270 while (razor_property_iterator_next(pi, &property, &name,
272 if (strcmp(ref_name, name) != 0)
275 (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
276 strcmp(ref_version, version) != 0)
278 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != ref_type)
281 pkgi = razor_package_iterator_create_for_property(set,
283 razor_package_query_add_iterator(query, pkgi);
284 razor_package_iterator_destroy(pkgi);
286 razor_property_iterator_destroy(pi);
292 strcmpp(const void *p1, const void *p2)
294 return strcmp(*(char * const *) p1, *(char * const *) p2);
298 add_command_line_packages(struct razor_set *set,
299 struct razor_package_query *query,
300 int argc, const char **argv)
302 struct razor_package *package;
303 struct razor_package_iterator *pi;
304 const char *name, *version, *arch;
307 qsort(argv, argc, sizeof(*argv), strcmpp);
311 pi = razor_package_iterator_create(set);
313 while (razor_package_iterator_next(pi, &package,
314 &name, &version, &arch)) {
315 while (cmp = strcmp(argv[i], name), cmp < 0 && i < argc) {
316 fprintf(stderr, "error: package %s is not installed\n",
323 razor_package_query_add_package(query, package);
328 razor_package_iterator_destroy(pi);
334 static struct razor_package_iterator *
335 get_query_packages(struct razor_set *set, int argc, const char *argv[])
337 struct razor_package_query *query;
338 struct razor_package_iterator *pi;
341 if (option_all + option_whatprovides + option_whatrequires > 1) {
342 printf("only one type of query/verify "
343 "may be performed at a time\n");
347 query = razor_package_query_create(set);
350 pi = razor_package_iterator_create(set);
351 razor_package_query_add_iterator(query, pi);
352 razor_package_iterator_destroy(pi);
353 } else if (option_whatrequires) {
354 for (i = 0; i < argc; i++)
355 add_property_packages(set, query,
357 RAZOR_PROPERTY_REQUIRES);
358 } else if (option_whatprovides) {
359 for (i = 0; i < argc; i++)
360 add_property_packages(set, query,
362 RAZOR_PROPERTY_PROVIDES);
363 } else if (argc > 0) {
364 add_command_line_packages(set, query, argc, argv);
366 printf("no arguments given for query/verify\n");
370 return razor_package_query_finish(query);
374 print_package_properties(struct razor_set *set,
375 struct razor_package *package,
378 struct razor_property *property;
379 struct razor_property_iterator *pi;
380 const char *name, *version;
383 pi = razor_property_iterator_create(set, package);
384 while (razor_property_iterator_next(pi, &property,
385 &name, &flags, &version)) {
386 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != ref_type)
388 if (version[0] == '\0')
389 printf("%s\n", name);
391 printf("%s %s %s\n", name,
392 razor_property_relation_to_string(property),
395 razor_property_iterator_destroy(pi);
399 print_package_info(struct razor_set *set, struct razor_package *package)
401 printf("FIXME: Package info not tracked.\n");
405 print_package_changelog(struct razor_set *set, struct razor_package *package)
407 printf("FIXME: Package changelog not tracked.\n");
410 static struct razor_set *
411 create_set_from_command_line(int argc, const char *argv[])
413 struct razor_importer *importer;
414 struct razor_rpm *rpm;
417 importer = razor_importer_create();
419 for (i = 0; i < argc; i++) {
420 rpm = razor_rpm_open(argv[i]);
423 if (razor_importer_add_rpm(importer, rpm))
424 printf("couldn't import %s\n", argv[i]);
426 razor_rpm_close(rpm);
429 return razor_importer_finish(importer);
433 command_query(int argc, const char *argv[])
435 struct razor_set *set;
436 struct razor_package_iterator *pi;
437 struct razor_package *package;
438 const char *name, *version, *arch;
440 if (option_package) {
441 set = create_set_from_command_line(argc, argv);
445 set = razor_root_open_read_only(option_root);
448 pi = get_query_packages(set, argc, argv);
450 while (razor_package_iterator_next(pi, &package,
451 &name, &version, &arch)) {
452 if (option_conflicts)
453 print_package_properties(set, package,
454 RAZOR_PROPERTY_CONFLICTS);
455 if (option_obsoletes)
456 print_package_properties(set, package,
457 RAZOR_PROPERTY_OBSOLETES);
459 print_package_properties(set, package,
460 RAZOR_PROPERTY_REQUIRES);
462 print_package_properties(set, package,
463 RAZOR_PROPERTY_PROVIDES);
465 print_package_info(set, package);
466 if (option_changelog)
467 print_package_changelog(set, package);
469 if (option_conflicts + option_obsoletes +
470 option_requires + option_provides +
471 option_info + option_changelog == 0)
472 printf("%s-%s.%s\n", name, version, arch);
475 razor_package_iterator_destroy(pi);
477 razor_set_destroy(set);
483 command_verify(int argc, const char *argv[])
485 struct razor_set *set;
486 struct razor_package_iterator *pi;
487 struct razor_package *package;
488 const char *name, *version, *arch;
490 if (option_package) {
491 set = create_set_from_command_line(argc, argv);
495 set = razor_root_open_read_only(option_root);
498 pi = get_query_packages(set, argc, argv);
500 while (razor_package_iterator_next(pi, &package,
501 &name, &version, &arch)) {
502 printf("verify %s-%s.%s - not implemented\n",
503 name, version, arch);
506 razor_package_iterator_destroy(pi);
510 update_package(enum razor_diff_action action,
511 struct razor_package *package,
517 if (action == RAZOR_DIFF_ACTION_ADD)
518 printf("install %s-%s.%s\n", name, version, arch);
519 if (action == RAZOR_DIFF_ACTION_REMOVE)
520 printf("remove %s-%s.%s\n", name, version, arch);
524 command_erase(int argc, const char *argv[])
526 struct razor_set *set, *upstream, *next;
527 struct razor_transaction *trans;
528 struct razor_package_query *query;
529 struct razor_package_iterator *pi;
530 struct razor_package *package;
531 const char *name, *version, *arch;
534 printf("no packages given for erase\n");
538 set = razor_set_open(repo_filename);
539 upstream = razor_set_create();
541 trans = razor_transaction_create(set, upstream);
543 query = razor_package_query_create(set);
544 add_command_line_packages(set, query, argc, argv);
546 pi = razor_package_query_finish(query);
547 while (razor_package_iterator_next(pi, &package,
548 &name, &version, &arch))
549 razor_transaction_remove_package(trans, package);
550 razor_package_iterator_destroy(pi);
552 if (!option_nodeps && razor_transaction_describe(trans) > 0) {
553 printf("unsatisfied dependencies.\n");
560 next = razor_transaction_finish(trans);
563 razor_set_diff(set, next, update_package, NULL);
565 razor_set_destroy(set);
566 razor_set_destroy(upstream);
568 razor_set_destroy(next);
572 command_install(int argc, const char *argv[])
574 struct razor_set *set, *upstream, *next;
575 struct razor_transaction *trans;
576 struct razor_package_iterator *pi;
577 struct razor_package *package;
578 const char *name, *version, *arch;
581 printf("no packages given for install\n");
585 set = razor_set_open(repo_filename);
586 upstream = create_set_from_command_line(argc, argv);
588 trans = razor_transaction_create(set, upstream);
590 pi = razor_package_iterator_create(upstream);
591 while (razor_package_iterator_next(pi, &package,
592 &name, &version, &arch))
593 razor_transaction_install_package(trans, package);
594 razor_package_iterator_destroy(pi);
596 if (!option_nodeps && razor_transaction_describe(trans) > 0) {
597 printf("unsatisfied dependencies.\n");
604 next = razor_transaction_finish(trans);
607 razor_set_diff(set, next, update_package, NULL);
609 razor_set_destroy(set);
610 razor_set_destroy(upstream);
612 razor_set_destroy(next);
616 command_update(int argc, const char *argv[])
618 struct razor_set *set, *upstream, *next;
619 struct razor_transaction *trans;
620 struct razor_package_iterator *pi;
621 struct razor_package *package;
622 const char *name, *version, *arch;
625 printf("no packages given for update\n");
629 set = razor_set_open(repo_filename);
630 upstream = create_set_from_command_line(argc, argv);
632 trans = razor_transaction_create(set, upstream);
634 pi = razor_package_iterator_create(upstream);
635 while (razor_package_iterator_next(pi, &package,
636 &name, &version, &arch))
637 razor_transaction_update_package(trans, package);
638 razor_package_iterator_destroy(pi);
640 if (!option_nodeps && razor_transaction_describe(trans) > 0) {
641 printf("unsatisfied dependencies.\n");
648 next = razor_transaction_finish(trans);
651 razor_set_diff(set, next, update_package, NULL);
653 razor_set_destroy(set);
654 razor_set_destroy(upstream);
656 razor_set_destroy(next);
660 for_each_option(const struct option *options,
661 const char *name, char short_name,
662 void (*fn)(const struct option *o,
663 const char *name, char short_name,
664 void *data), void *data)
668 for (i = 0; options[i].type != OPTION_LAST; i++) {
669 switch (options[i].type) {
671 count += for_each_option(options[i].data,
672 name, short_name, fn, data);
677 if (name && strcmp(options[i].name, name) == 0) {
678 fn(&options[i], name, 0, data);
684 short_name == options[i].short_name) {
685 fn(&options[i], NULL, short_name, data);
700 handle_option(const struct option *o,
701 const char *name, char short_name, void *data)
703 if (o->data == NULL) {
705 printf("option --%s not supported\n", name);
707 printf("option -%c not supported\n", short_name);
713 *(int *) o->data = 1;
717 *(const char **) o->data = name + strlen(o->name) + 1;
722 /* Shouldn't happen. */
728 parse_options(const struct option *options, int argc, const char **argv)
732 for (i = 1, j = 0; i < argc; i++) {
733 if (argv[i][0] != '-') {
738 if (argv[i][1] == '-') {
739 if (for_each_option(options, &argv[i][2], 0,
740 handle_option, NULL) == 0) {
741 printf("unknown option: %s\n", argv[i]);
747 for (k = 1; argv[i][k]; k++) {
748 if (for_each_option(options, NULL, argv[i][k],
749 handle_option, NULL) == 0) {
750 printf("unknown option: -%c\n", argv[i][k]);
760 print_options_help(const struct option *options)
764 for (i = 0; options[i].type != OPTION_LAST; i++) {
765 switch (options[i].type) {
767 printf("%s\n", options[i].description);
768 print_options_help(options[i].data);
775 if (options[i].short_name)
776 printf("-%c", options[i].short_name);
777 if (options[i].short_name && options[i].name)
780 printf("--%s", options[i].name);
781 if (options[i].arg_name)
782 printf("=%s", options[i].arg_name);
783 if (options[i].description)
784 printf("\t\t%s", options[i].description);
795 print_options_usage(const struct option *options)
799 for (i = 0; options[i].type != OPTION_LAST; i++) {
800 switch (options[i].type) {
802 print_options_usage(options[i].data);
807 if (options[i].short_name)
808 printf("-%c", options[i].short_name);
809 if (options[i].short_name && options[i].name)
812 printf("--%s", options[i].name);
818 if (options[i].short_name)
819 printf("-%c", options[i].short_name);
820 if (options[i].short_name && options[i].name)
823 printf("--%s", options[i].name);
824 if (options[i].arg_name)
825 printf("=%s", options[i].arg_name);
839 main(int argc, const char *argv[])
841 argc = parse_options(rpm_options, argc, argv);
843 if (option_version) {
844 printf("razor rpm version hoopla.\n");
849 printf("Usage: rpm [OPTION...]\n");
850 print_options_help(rpm_options);
855 printf("Usage: rpm [OPTION...]\n");
856 print_options_usage(rpm_options);
862 command_initdb(argc, argv);
863 } else if (option_verify) {
864 command_verify(argc, argv);
865 } else if (option_query) {
866 command_query(argc, argv);
867 } else if (option_install) {
868 command_install(argc, argv);
869 } else if (option_upgrade) {
870 command_update(argc, argv);
871 } else if (option_erase) {
872 command_erase(argc, argv);
874 print_options_usage(rpm_options);