2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009, 2011-2012, 2014 J. Ali Harlow <ali@juiblex.co.uk>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 #include <curl/curl.h>
43 static const char system_repo_filename[] = "system.rzdb";
44 static const char next_repo_filename[] = "system-next.rzdb";
45 static const char rawhide_repo_filename[] = "rawhide.rzdb";
46 static const char *install_root = "";
47 static const char *repo_filename = system_repo_filename;
48 static const char *yum_url;
58 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
61 update_packages(struct razor_transaction *trans,
62 struct razor_install_iterator *ii, struct razor_set *system,
63 struct razor_set *next, struct razor_atomic *atomic,
64 struct razor_relocations *relocations,
65 enum razor_stage_type stage);
67 update_system(struct razor_root *root, struct razor_relocations *relocations,
68 struct razor_transaction *trans, struct razor_set *next,
71 static int command_help(int argc, char * const argv[]);
78 char *arg_description;
82 razor_usage(const char *command, int n_options, struct razor_option *options,
83 const char *parameter_string)
85 int i, help_printed = FALSE;
88 printf("Usage: razor %s [options] %s\n", command, parameter_string);
89 printf("(Specify the --help global option for a list of other "
91 printf("\nOptions:\n");
93 for(i = 0; i < n_options; i++) {
94 if (!help_printed && strcmp(options[i].name, "help") > 0) {
96 "Show this help message and exit\n");
100 if (options[i].has_arg != no_argument)
101 snprintf(buf, sizeof(buf), "%s=%s", options[i].name,
102 options[i].arg_description);
104 strncpy(buf, options[i].name, sizeof(buf));
107 printf(" --%-18s%s\n", buf, options[i].description);
112 "Show this help message and exit\n");
119 * Returns: The next option found or -2 on handled or -1 on error
120 * or 0 on end of option list.
123 razor_getopt(int argc, char * const argv[], int n_options,
124 struct razor_option *options, const char *parameter_string,
127 int i, opt, do_help = 0, retval;
128 struct option *longopts;
130 longopts = calloc((n_options + 2), sizeof(*longopts));
132 for(i = 0; i < n_options; i++) {
133 longopts[i].name = options[i].name;
134 longopts[i].has_arg = options[i].has_arg;
135 longopts[i].flag = &retval;
136 longopts[i].val = options[i].val;
139 longopts[i].name = "help";
140 longopts[i].has_arg = no_argument;
141 longopts[i].flag = &do_help;
142 longopts[i].val = TRUE;
146 opt = getopt_long(argc, argv, "+", longopts, NULL);
152 razor_usage(argv[0], n_options, options,
164 razor_usage(argv[0], n_options, options,
173 static struct razor_package_iterator *
174 create_iterator_from_argv(struct razor_set *set, int argc, char * const argv[])
176 struct razor_package_query *query;
177 struct razor_package_iterator *iter;
178 struct razor_package *package;
179 const char *name, *pattern;
183 return razor_package_iterator_create(set);
185 query = razor_package_query_create(set);
187 for (i = 0; i < argc; i++) {
188 iter = razor_package_iterator_create(set);
191 while (razor_package_iterator_next(iter, &package,
192 RAZOR_DETAIL_NAME, &name,
193 RAZOR_DETAIL_LAST)) {
194 if (fnmatch(pattern, name, 0) != 0)
197 razor_package_query_add_package(query, package);
200 razor_package_iterator_destroy(iter);
204 "no package matches \"%s\"\n", pattern);
207 return razor_package_query_finish(query);
210 #define LIST_PACKAGES_ONLY_NAMES 0x01
213 list_packages(struct razor_package_iterator *iter, uint32_t flags)
215 struct razor_package *package;
216 const char *name, *version, *arch;
218 while (razor_package_iterator_next(iter, &package,
219 RAZOR_DETAIL_NAME, &name,
220 RAZOR_DETAIL_VERSION, &version,
221 RAZOR_DETAIL_ARCH, &arch,
222 RAZOR_DETAIL_LAST)) {
223 if (flags & LIST_PACKAGES_ONLY_NAMES)
224 printf("%s\n", name);
226 printf("%s-%s.%s\n", name, version, arch);
231 command_list(int argc, char * const argv[])
234 struct razor_package_iterator *pi;
235 struct razor_error *error = NULL;
236 struct razor_set *set;
241 static struct razor_option options[] = {
242 { .name = "only-names", .has_arg = no_argument,
243 .val = opt_only_names,
244 .description = "Only list package names" },
248 opt = razor_getopt(argc, argv, ARRAY_SIZE(options), options,
249 "pattern ...", NULL);
256 flags |= LIST_PACKAGES_ONLY_NAMES;
261 set = razor_root_open_read_only(install_root, &error);
263 fprintf(stderr, "%s\n", razor_error_get_msg(error));
264 razor_error_free(error);
268 pi = create_iterator_from_argv(set, argc - optind, argv + optind);
269 list_packages(pi, flags);
270 razor_package_iterator_destroy(pi);
271 razor_set_unref(set);
277 list_package_properties(struct razor_set *set,
278 struct razor_package *package, uint32_t type)
280 struct razor_property_iterator *pi;
281 struct razor_property *property;
282 const char *name, *version;
285 pi = razor_property_iterator_create(set, package);
286 while (razor_property_iterator_next(pi, &property,
287 &name, &flags, &version)) {
288 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
291 if (version[0] != '\0')
293 razor_property_relation_to_string(property),
296 if (flags & ~(RAZOR_PROPERTY_RELATION_MASK | RAZOR_PROPERTY_TYPE_MASK)) {
298 if (flags & RAZOR_PROPERTY_PRE)
300 if (flags & RAZOR_PROPERTY_POST)
302 if (flags & RAZOR_PROPERTY_PREUN)
304 if (flags & RAZOR_PROPERTY_POSTUN)
310 razor_property_iterator_destroy(pi);
314 list_properties(int argc, char * const argv[], uint32_t type)
316 struct razor_set *set;
317 struct razor_error *error = NULL;
318 struct razor_package *package;
319 struct razor_package_iterator *pi;
320 const char *name, *version, *arch;
322 switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
329 set = razor_root_open_read_only(install_root, &error);
331 fprintf(stderr, "%s\n", razor_error_get_msg(error));
332 razor_error_free(error);
336 pi = create_iterator_from_argv(set, argc - optind, argv + optind);
337 while (razor_package_iterator_next(pi, &package,
338 RAZOR_DETAIL_NAME, &name,
339 RAZOR_DETAIL_VERSION, &version,
340 RAZOR_DETAIL_ARCH, &arch,
342 list_package_properties(set, package, type);
343 razor_package_iterator_destroy(pi);
344 razor_set_unref(set);
350 command_list_requires(int argc, char * const argv[])
352 return list_properties(argc, argv, RAZOR_PROPERTY_REQUIRES);
356 command_list_provides(int argc, char * const argv[])
358 return list_properties(argc, argv, RAZOR_PROPERTY_PROVIDES);
362 command_list_obsoletes(int argc, char * const argv[])
364 return list_properties(argc, argv, RAZOR_PROPERTY_OBSOLETES);
368 command_list_conflicts(int argc, char * const argv[])
370 return list_properties(argc, argv, RAZOR_PROPERTY_CONFLICTS);
374 command_list_scripts(int argc, char * const argv[])
376 struct razor_set *set;
377 struct razor_error *error = NULL;
378 struct razor_package *package;
379 struct razor_package_iterator *pi;
380 const char *preunprog, *preun, *postunprog, *postun;
382 switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
389 set = razor_root_open_read_only(install_root, &error);
391 fprintf(stderr, "%s\n", razor_error_get_msg(error));
392 razor_error_free(error);
396 pi = create_iterator_from_argv(set, argc - optind, argv + optind);
397 while (razor_package_iterator_next(pi, &package,
398 RAZOR_DETAIL_PREUNPROG, &preunprog,
399 RAZOR_DETAIL_PREUN, &preun,
400 RAZOR_DETAIL_POSTUNPROG, &postunprog,
401 RAZOR_DETAIL_POSTUN, &postun,
402 RAZOR_DETAIL_LAST)) {
403 if (preun && *preun) {
404 printf("preuninstall scriptlet");
405 if (preunprog && *preunprog)
406 printf(" (using %s)",preunprog);
407 printf(":\n%s\n",preun);
409 if (postun && *postun) {
410 printf("postuninstall scriptlet");
411 if (postunprog && *postunprog)
412 printf(" (using %s)",postunprog);
413 printf(":\n%s\n",postun);
416 razor_package_iterator_destroy(pi);
417 razor_set_unref(set);
423 command_list_files(int argc, char * const argv[])
425 struct razor_error *error = NULL;
426 struct razor_set *set;
428 switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
435 if (argc - optind > 1) {
436 razor_usage(argv[0], 0, NULL, "[pattern]");
440 set = razor_root_open_read_only(install_root, &error);
442 fprintf(stderr, "%s\n", razor_error_get_msg(error));
443 razor_error_free(error);
447 razor_set_list_files(set, argv[optind]);
448 razor_set_unref(set);
454 command_list_file_packages(int argc, char * const argv[])
456 struct razor_error *error = NULL;
457 struct razor_set *set;
458 struct razor_package_iterator *pi;
460 switch (razor_getopt(argc, argv, 0, NULL, "pattern", NULL)) {
467 if (argc - optind != 1) {
468 razor_usage(argv[0], 0, NULL, "pattern");
472 set = razor_root_open_read_only(install_root, &error);
474 fprintf(stderr, "%s\n", razor_error_get_msg(error));
475 razor_error_free(error);
479 pi = razor_package_iterator_create_for_file(set, argv[optind]);
480 list_packages(pi, 0);
481 razor_package_iterator_destroy(pi);
483 razor_set_unref(set);
489 command_list_package_files(int argc, char * const argv[])
491 struct razor_error *error = NULL;
492 struct razor_set *set;
493 struct razor_package_iterator *pi;
494 struct razor_package *package;
495 const char *name, *version, *arch;
497 switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
504 set = razor_root_open_read_only(install_root, &error);
506 fprintf(stderr, "%s\n", razor_error_get_msg(error));
507 razor_error_free(error);
511 pi = create_iterator_from_argv(set, argc - optind, argv + optind);
512 while (razor_package_iterator_next(pi, &package,
513 RAZOR_DETAIL_NAME, &name,
514 RAZOR_DETAIL_VERSION, &version,
515 RAZOR_DETAIL_ARCH, &arch,
517 razor_set_list_package_files(set, package);
518 razor_package_iterator_destroy(pi);
520 razor_set_unref(set);
526 list_property_packages(const char *ref_name,
527 const char *ref_version,
530 struct razor_error *error = NULL;
531 struct razor_set *set;
532 struct razor_property *property;
533 struct razor_property_iterator *prop_iter;
534 struct razor_package_iterator *pkg_iter;
535 const char *name, *version;
538 set = razor_root_open_read_only(install_root, &error);
540 fprintf(stderr, "%s\n", razor_error_get_msg(error));
541 razor_error_free(error);
545 prop_iter = razor_property_iterator_create(set, NULL);
546 while (razor_property_iterator_next(prop_iter, &property,
547 &name, &flags, &version)) {
548 if (strcmp(ref_name, name) != 0)
551 (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
552 strcmp(ref_version, version) != 0)
554 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
558 razor_package_iterator_create_for_property(set,
560 list_packages(pkg_iter, 0);
561 razor_package_iterator_destroy(pkg_iter);
563 razor_property_iterator_destroy(prop_iter);
565 razor_set_unref(set);
571 command_what_requires(int argc, char * const argv[])
573 switch (razor_getopt(argc, argv, 0, NULL, "name [version-release]",
581 if (argc - optind < 1 || argc - optind > 2) {
582 razor_usage(argv[0], 0, NULL, "name [version-release]");
586 return list_property_packages(argv[optind], argv[optind + 1],
587 RAZOR_PROPERTY_REQUIRES);
591 command_what_provides(int argc, char * const argv[])
593 switch (razor_getopt(argc, argv, 0, NULL, "name [version-release]",
601 if (argc - optind < 1 || argc - optind > 2) {
602 razor_usage(argv[0], 0, NULL, "name [version-release]");
606 return list_property_packages(argv[optind], argv[optind + 1],
607 RAZOR_PROPERTY_PROVIDES);
612 show_progress(void *clientp,
613 double dltotal, double dlnow, double ultotal, double ulnow)
615 const char *file = clientp;
617 if (!dlnow < dltotal)
618 fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
619 file, (int) dlnow / 1024, (int) dltotal / 1024);
623 #endif /* HAVE_CURL */
626 download_if_missing(const char *url, const char *file)
638 curl = curl_easy_init();
642 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
643 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
644 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
645 curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
647 if (stat(file, &buf) < 0) {
648 fp = fopen(file, "wb");
651 "failed to open %s for writing\n", file);
654 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
655 curl_easy_setopt(curl, CURLOPT_URL, url);
656 res = curl_easy_perform(curl);
658 if (res != CURLE_OK) {
659 fprintf(stderr, "curl error: %s\n", error);
663 res = curl_easy_getinfo(curl,
664 CURLINFO_RESPONSE_CODE, &response);
665 if (res != CURLE_OK) {
666 fprintf(stderr, "curl error: %s\n", error);
670 if (response != 200) {
671 fprintf(stderr, " - failed %ld\n", response);
675 fprintf(stderr, "\n");
678 curl_easy_cleanup(curl);
681 #endif /* HAVE_CURL */
684 #define YUM_URL "http://download.fedora.redhat.com" \
685 "/pub/fedora/linux/development/i386/os"
688 command_import_yum(int argc, char * const argv[])
691 struct razor_set *set;
692 struct razor_atomic *atomic;
695 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
702 if (argc - optind > 0) {
703 razor_usage(argv[0], 0, NULL, "");
707 printf("downloading from %s.\n", yum_url);
708 snprintf(buffer, sizeof buffer,
709 "%s/repodata/primary.xml.gz", yum_url);
710 if (download_if_missing(buffer, "primary.xml.gz") < 0)
712 snprintf(buffer, sizeof buffer,
713 "%s/repodata/filelists.xml.gz", yum_url);
714 if (download_if_missing(buffer, "filelists.xml.gz") < 0)
717 set = razor_set_create_from_yum();
720 atomic = razor_atomic_open("Yum import repository");
721 razor_set_write(set, atomic, rawhide_repo_filename, RAZOR_SECTION_ALL);
722 retval = razor_atomic_commit(atomic);
723 razor_set_unref(set);
725 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
727 printf("wrote %s\n", rawhide_repo_filename);
728 razor_atomic_destroy(atomic);
735 command_import_rpmdb(int argc, char * const argv[])
737 struct razor_set *set;
738 struct razor_root *root;
739 struct razor_error *error = NULL;
740 struct razor_atomic *atomic;
743 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
750 if (argc - optind > 0) {
751 razor_usage(argv[0], 0, NULL, "");
755 root = razor_root_open(install_root, &error);
757 fprintf(stderr, "%s\n", razor_error_get_msg(error));
758 razor_error_free(error);
762 set = razor_set_create_from_rpmdb();
766 atomic = razor_atomic_open("Import RPM database");
768 retval = razor_root_update(root, set, atomic);
771 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
773 razor_atomic_destroy(atomic);
775 razor_root_close(root);
782 mark_packages_for_update(struct razor_transaction *trans,
783 struct razor_set *set, const char *pattern)
785 struct razor_package_iterator *pi;
786 struct razor_package *package;
790 pi = razor_package_iterator_create(set);
791 while (razor_package_iterator_next(pi, &package,
792 RAZOR_DETAIL_NAME, &name,
793 RAZOR_DETAIL_LAST)) {
794 if (pattern && fnmatch(pattern, name, 0) == 0) {
795 razor_transaction_update_package(trans, package);
799 razor_package_iterator_destroy(pi);
805 mark_packages_for_removal(struct razor_transaction *trans,
806 struct razor_set *set, const char *pattern)
808 struct razor_package_iterator *pi;
809 struct razor_package *package;
813 pi = razor_package_iterator_create(set);
814 while (razor_package_iterator_next(pi, &package,
815 RAZOR_DETAIL_NAME, &name,
816 RAZOR_DETAIL_LAST)) {
817 if (pattern && fnmatch(pattern, name, 0) == 0) {
818 razor_transaction_remove_package(trans, package);
822 razor_package_iterator_destroy(pi);
828 command_remove(int argc, char * const argv[])
830 struct razor_set *system, *upstream, *next;
831 struct razor_transaction *trans;
832 struct razor_error *error = NULL;
833 struct razor_root *root;
836 switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
843 root = razor_root_open(install_root, &error);
845 fprintf(stderr, "%s\n", razor_error_get_msg(error));
846 razor_error_free(error);
850 system = razor_root_get_system_set(root);
851 upstream = razor_set_create_without_root();
852 trans = razor_transaction_create(system, upstream);
853 razor_set_unref(upstream);
854 for (i = optind; i < argc; i++) {
855 if (mark_packages_for_removal(trans, system, argv[i]) == 0) {
856 fprintf(stderr, "no match for %s\n", argv[i]);
857 razor_transaction_destroy(trans);
858 razor_root_close(root);
863 razor_transaction_resolve(trans);
864 retval = razor_transaction_describe(trans);
866 razor_transaction_destroy(trans);
867 razor_root_close(root);
871 next = razor_transaction_commit(trans);
873 retval = update_system(root, NULL, trans, next, "Remove");
875 razor_transaction_destroy(trans);
876 razor_root_close(root);
877 razor_set_unref(next);
883 print_diff(enum razor_diff_action action,
884 struct razor_package *package,
890 if (action == RAZOR_DIFF_ACTION_ADD)
891 printf("install %s-%s.%s\n", name, version, arch);
892 if (action == RAZOR_DIFF_ACTION_REMOVE)
893 printf("remove %s-%s.%s\n", name, version, arch);
897 command_diff(int argc, char * const argv[])
899 struct razor_error *error = NULL;
900 struct razor_set *set, *updated;
902 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
909 if (argc - optind > 0) {
910 razor_usage(argv[0], 0, NULL, "");
914 set = razor_root_open_read_only(install_root, &error);
916 updated = razor_set_open(rawhide_repo_filename, 0, &error);
919 if (updated == NULL) {
920 fprintf(stderr, "%s\n", razor_error_get_msg(error));
921 razor_error_free(error);
923 razor_set_unref(set);
927 razor_set_diff(set, updated, print_diff, NULL);
929 razor_set_unref(set);
930 razor_set_unref(updated);
936 command_import_rpms(int argc, char * const argv[])
940 struct razor_importer *importer;
941 struct razor_set *set;
942 struct razor_rpm *rpm;
943 struct razor_error *error=NULL;
944 struct razor_atomic *atomic;
945 int len, imported_count = 0;
950 switch (razor_getopt(argc, argv, 0, NULL, "dir", NULL)) {
957 if (argc - optind != 1) {
958 razor_usage(argv[0], 0, NULL, "dir");
962 dirname = argv[optind];
964 dir = opendir(dirname);
966 fprintf(stderr, "couldn't read dir %s\n", dirname);
970 importer = razor_importer_create();
972 while (de = readdir(dir), de != NULL) {
973 len = strlen(de->d_name);
974 if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
976 snprintf(filename, sizeof filename,
977 "%s/%s", dirname, de->d_name);
978 rpm = razor_rpm_open(filename, &error);
980 fprintf(stderr, "%s\n", razor_error_get_msg(error));
981 razor_error_free(error);
985 if (razor_importer_add_rpm(importer, rpm)) {
986 fprintf(stderr, "couldn't import %s\n", filename);
989 razor_rpm_close(rpm);
991 printf("\rimporting %d", ++imported_count);
996 razor_importer_destroy(importer);
1000 printf("\nsaving\n");
1001 set = razor_importer_finish(importer);
1003 atomic = razor_atomic_open("Update system database");
1004 razor_set_write(set, atomic, repo_filename, RAZOR_SECTION_ALL);
1005 razor_set_unref(set);
1006 retval = razor_atomic_commit(atomic);
1008 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1010 printf("wrote %s\n", repo_filename);
1011 razor_atomic_destroy(atomic);
1017 rpm_filename(const char *name, const char *version, const char *arch)
1022 v = strchr(version, ':');
1028 return razor_concat(name, "-", v, ".", arch, ".rpm", NULL);
1032 download_packages(struct razor_set *system, struct razor_set *next)
1034 struct razor_install_iterator *ii;
1035 struct razor_package *package;
1036 enum razor_install_action action;
1037 const char *name, *version, *arch;
1038 char *file, *url, *s;
1039 int errors = 0, count;
1041 ii = razor_set_create_install_iterator(system, next);
1042 while (razor_install_iterator_next(ii, &package, &action, &count)) {
1043 if (action != RAZOR_INSTALL_ACTION_ADD)
1046 razor_package_get_details(next, package,
1047 RAZOR_DETAIL_NAME, &name,
1048 RAZOR_DETAIL_VERSION, &version,
1049 RAZOR_DETAIL_ARCH, &arch,
1052 s = rpm_filename(name, version, arch);
1053 url = razor_concat(yum_url, "/Packages/", s, NULL);
1054 file = razor_concat("rpms/", s, NULL);
1056 if (download_if_missing(url, file) < 0)
1061 razor_install_iterator_destroy(ii);
1064 fprintf(stderr, "failed to download %d packages\n", errors);
1071 static struct razor_set *
1072 relocate_packages(struct razor_set *set, struct razor_atomic *atomic,
1073 struct razor_relocations *relocations)
1076 struct razor_importer *importer;
1077 struct razor_property_iterator *prop_iter;
1078 struct razor_package_iterator *pkg_iter;
1079 struct razor_file_iterator *file_iter;
1080 struct razor_package *package;
1081 struct razor_property *property;
1082 struct razor_rpm *rpm;
1083 struct razor_error *error=NULL;
1084 const char *name, *version, *arch, *summary, *desc, *url, *license;
1085 const char *preunprog, *preun, *postunprog, *postun;
1086 const char *install_prefix;
1087 const char *const *prefixes;
1091 importer = razor_importer_create();
1092 pkg_iter = razor_package_iterator_create(set);
1094 while (razor_package_iterator_next(pkg_iter, &package,
1095 RAZOR_DETAIL_NAME, &name,
1096 RAZOR_DETAIL_VERSION, &version,
1097 RAZOR_DETAIL_ARCH, &arch,
1098 RAZOR_DETAIL_SUMMARY, &summary,
1099 RAZOR_DETAIL_DESCRIPTION, &desc,
1100 RAZOR_DETAIL_URL, &url,
1101 RAZOR_DETAIL_LICENSE, &license,
1102 RAZOR_DETAIL_PREUNPROG, &preunprog,
1103 RAZOR_DETAIL_PREUN, &preun,
1104 RAZOR_DETAIL_POSTUNPROG, &postunprog,
1105 RAZOR_DETAIL_POSTUN, &postun,
1106 RAZOR_DETAIL_LAST)) {
1107 s = rpm_filename(name, version, arch);
1108 file = razor_concat("rpms/", s, NULL);
1110 rpm = razor_rpm_open(file, &error);
1113 razor_atomic_propagate_error(atomic, error, NULL);
1114 razor_error_free(error);
1115 razor_package_iterator_destroy(pkg_iter);
1116 razor_importer_destroy(importer);
1120 razor_relocations_set_rpm(relocations, rpm);
1122 razor_importer_begin_package(importer, name, version, arch);
1123 razor_importer_add_details(importer,
1124 summary, desc, url, license);
1126 razor_rpm_get_details(rpm, RAZOR_DETAIL_PREFIXES, &prefixes,
1128 for (i = 0; prefixes && prefixes[i]; i++) {
1129 install_prefix = razor_relocations_apply(relocations,
1131 razor_importer_add_install_prefix(importer,
1135 razor_rpm_close(rpm);
1137 prop_iter = razor_property_iterator_create(set, package);
1138 while (razor_property_iterator_next(prop_iter, &property,
1139 &name, &flags, &version))
1140 razor_importer_add_property(importer,
1141 name, flags, version);
1142 razor_property_iterator_destroy(prop_iter);
1144 file_iter = razor_file_iterator_create(set, package, 0);
1145 while (razor_file_iterator_next(file_iter, &name)) {
1146 name = razor_relocations_apply(relocations, name);
1147 razor_importer_add_file(importer, name);
1149 razor_file_iterator_destroy(file_iter);
1151 razor_importer_add_script(importer, RAZOR_PROPERTY_PREUN,
1153 razor_importer_add_script(importer, RAZOR_PROPERTY_POSTUN,
1154 postunprog, postun);
1156 razor_importer_finish_package(importer);
1159 razor_package_iterator_destroy(pkg_iter);
1160 return razor_importer_finish(importer);
1164 install_package(struct razor_transaction *trans, struct razor_set *set,
1165 struct razor_atomic *atomic, struct razor_package *package,
1166 struct razor_relocations *relocations, int install_count,
1167 enum razor_stage_type stage)
1170 const char *name, *version, *arch;
1172 struct razor_rpm *rpm;
1173 struct razor_error *error=NULL;
1175 razor_package_get_details(set, package,
1176 RAZOR_DETAIL_NAME, &name,
1177 RAZOR_DETAIL_VERSION, &version,
1178 RAZOR_DETAIL_ARCH, &arch,
1181 if (stage & RAZOR_STAGE_SCRIPTS_PRE)
1182 printf("install %s-%s\n", name, version);
1184 s = rpm_filename(name, version, arch);
1185 file = razor_concat("rpms/", s, NULL);
1187 rpm = razor_rpm_open(file, &error);
1190 razor_atomic_propagate_error(atomic, error, NULL);
1191 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1192 razor_error_free(error);
1196 razor_rpm_set_relocations(rpm, relocations);
1197 razor_transaction_fixup_package(trans, package, rpm);
1198 retval = razor_rpm_install(rpm, atomic, install_root, install_count,
1201 s = rpm_filename(name, version, arch);
1202 fprintf(stderr, "%s: %s\n", s,
1203 razor_atomic_get_error_msg(atomic));
1206 razor_rpm_close(rpm);
1211 * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT
1212 * is met (in which case the action is consumed).
1215 update_packages(struct razor_transaction *trans,
1216 struct razor_install_iterator *ii, struct razor_set *system,
1217 struct razor_set *next, struct razor_atomic *atomic,
1218 struct razor_relocations *relocations,
1219 enum razor_stage_type stage)
1221 struct razor_package *package;
1222 enum razor_install_action action;
1223 int retval = 0, count;
1225 while (!retval && razor_install_iterator_next(ii, &package, &action,
1227 if (action == RAZOR_INSTALL_ACTION_ADD) {
1228 if (install_package(trans, next, atomic, package,
1229 relocations, count, stage))
1231 } else if (action == RAZOR_INSTALL_ACTION_REMOVE) {
1232 if (razor_package_remove(system, next, atomic, package,
1233 install_root, count, stage))
1235 } else if (action == RAZOR_INSTALL_ACTION_COMMIT)
1243 update_system(struct razor_root *root, struct razor_relocations *relocations,
1244 struct razor_transaction *trans, struct razor_set *next,
1247 struct razor_set *system, *set;
1248 struct razor_atomic *atomic;
1249 struct razor_install_iterator *ii;
1254 description = razor_concat(verb, " packages", NULL);
1256 system = razor_set_ref(razor_root_get_system_set(root));
1258 ii = razor_set_create_install_iterator(system, next);
1261 pos = razor_install_iterator_tell(ii);
1263 atomic = razor_atomic_open(description);
1265 r = update_packages(trans, ii, system, next, atomic,
1266 relocations, RAZOR_STAGE_SCRIPTS_PRE);
1268 fprintf(stderr, "%s aborted\n", verb);
1271 razor_install_iterator_seek(ii, pos);
1272 r = update_packages(trans, ii, system, next, atomic,
1273 relocations, RAZOR_STAGE_FILES);
1276 set = razor_install_iterator_commit_set(ii);
1277 razor_root_update(root, set, atomic);
1278 razor_set_unref(set);
1280 razor_root_update(root, next, atomic);
1282 retval = razor_atomic_commit(atomic);
1284 fprintf(stderr, "%s\n",
1285 razor_atomic_get_error_msg(atomic));
1287 razor_install_iterator_seek(ii, pos);
1288 update_packages(trans, ii, system, next,
1289 atomic, relocations,
1290 RAZOR_STAGE_SCRIPTS_POST);
1294 razor_atomic_destroy(atomic);
1295 } while(!retval && r == 1);
1297 razor_set_unref(system);
1305 command_install_or_update(int argc, char * const argv[], int do_update)
1307 struct razor_relocations *relocations = NULL;
1308 struct razor_set *system, *upstream, *next, *set;
1309 struct razor_transaction *trans;
1310 struct razor_error *error = NULL;
1311 struct razor_atomic *atomic;
1312 struct razor_root *root;
1313 int opt, i, retval = 0, len, dependencies = 1;
1317 opt_no_dependencies = 1,
1320 static struct razor_option options[] = {
1321 { .name = "no-dependencies", .has_arg = no_argument,
1322 .val = opt_no_dependencies,
1323 .description = "Do not verify package dependencies" },
1324 { .name = "relocate", .has_arg = required_argument,
1325 .val = opt_relocate,
1326 .description = "Relocate files from path OLD to NEW",
1327 .arg_description = "OLD=NEW" },
1331 opt = razor_getopt(argc, argv, ARRAY_SIZE(options), options,
1338 case opt_no_dependencies:
1342 if (strchr(arg, '=') == NULL) {
1343 razor_usage(argv[0],
1344 ARRAY_SIZE(options),
1345 options, "rpm ...");
1348 len = strchr(arg, '=') - arg;
1349 oldpath = malloc(len + 1);
1350 strncpy(oldpath, arg, len);
1351 oldpath[len] = '\0';
1353 relocations = razor_relocations_create();
1354 razor_relocations_add(relocations, oldpath,
1361 upstream = razor_set_open(rawhide_repo_filename, 0, &error);
1362 if (upstream == NULL) {
1363 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1364 razor_error_free(error);
1369 atomic = razor_atomic_open("Update packages");
1371 atomic = razor_atomic_open("Install packages");
1374 set = relocate_packages(upstream, atomic, relocations);
1376 fprintf(stderr, "%s\n",
1377 razor_atomic_get_error_msg(atomic));
1378 razor_atomic_destroy(atomic);
1379 razor_set_unref(upstream);
1382 razor_set_unref(upstream);
1386 root = razor_root_open(install_root, &error);
1388 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1389 razor_error_free(error);
1390 razor_atomic_destroy(atomic);
1391 razor_set_unref(upstream);
1393 razor_relocations_destroy(relocations);
1397 system = razor_root_get_system_set(root);
1398 trans = razor_transaction_create(system, upstream);
1400 if (optind == argc && do_update)
1401 razor_transaction_update_all(trans);
1402 for (i = optind; i < argc; i++) {
1404 mark_packages_for_update(trans, system, argv[i]))
1406 if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
1407 fprintf(stderr, "no package matched %s\n", argv[i]);
1408 razor_transaction_destroy(trans);
1409 razor_root_close(root);
1410 razor_set_unref(upstream);
1411 razor_atomic_destroy(atomic);
1413 razor_relocations_destroy(relocations);
1419 razor_transaction_resolve(trans);
1420 if (razor_transaction_describe(trans) > 0) {
1421 razor_transaction_destroy(trans);
1422 razor_set_unref(upstream);
1423 razor_root_close(root);
1424 razor_atomic_destroy(atomic);
1426 razor_relocations_destroy(relocations);
1431 if (razor_atomic_create_dir(atomic, "rpms",
1432 S_IRWXU | S_IRWXG | S_IRWXO) ||
1433 razor_atomic_commit(atomic)) {
1434 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1435 razor_transaction_destroy(trans);
1436 razor_set_unref(upstream);
1437 razor_root_close(root);
1438 razor_atomic_destroy(atomic);
1440 razor_relocations_destroy(relocations);
1444 razor_atomic_destroy(atomic);
1446 next = razor_transaction_commit(trans);
1448 if (download_packages(system, next) < 0) {
1449 razor_set_unref(next);
1450 razor_transaction_destroy(trans);
1451 razor_set_unref(upstream);
1452 razor_root_close(root);
1453 razor_atomic_destroy(atomic);
1455 razor_relocations_destroy(relocations);
1459 retval = update_system(root, relocations, trans, next,
1460 do_update ? "Update" : "Install");
1462 razor_set_unref(upstream);
1463 razor_root_close(root);
1465 razor_transaction_destroy(trans);
1467 razor_relocations_destroy(relocations);
1469 razor_set_unref(next);
1475 command_update(int argc, char * const argv[])
1477 return command_install_or_update(argc, argv, 1);
1481 command_install(int argc, char * const argv[])
1483 return command_install_or_update(argc, argv, 0);
1487 command_init(int argc, char * const argv[])
1490 struct razor_error *error = NULL;
1492 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
1499 if (argc - optind > 0) {
1500 razor_usage(argv[0], 0, NULL, "");
1504 retval = razor_root_create(install_root, &error);
1506 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1507 razor_error_free(error);
1509 printf("Created install root\n");
1515 command_download(int argc, char * const argv[])
1517 struct razor_error *error = NULL;
1518 struct razor_atomic *atomic;
1519 struct razor_set *set;
1520 struct razor_package_iterator *pi;
1521 struct razor_package *package;
1522 const char *pattern, *name, *version, *arch;
1523 char url[256], file[256];
1526 switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
1533 if (argc - optind > 1) {
1534 razor_usage(argv[0], 0, NULL, "[pattern]");
1538 pattern = argv[optind];
1540 set = razor_set_open(rawhide_repo_filename, 0, &error);
1542 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1543 razor_error_free(error);
1547 atomic = razor_atomic_open("Download packages");
1549 if (razor_atomic_create_dir(atomic, "rpms",
1550 S_IRWXU | S_IRWXG | S_IRWXO)) {
1551 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1552 razor_atomic_destroy(atomic);
1556 if (razor_atomic_commit(atomic)) {
1557 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1558 razor_atomic_destroy(atomic);
1561 razor_atomic_destroy(atomic);
1563 pi = razor_package_iterator_create(set);
1564 while (razor_package_iterator_next(pi, &package,
1565 RAZOR_DETAIL_NAME, &name,
1566 RAZOR_DETAIL_VERSION, &version,
1567 RAZOR_DETAIL_ARCH, &arch,
1568 RAZOR_DETAIL_LAST)) {
1569 if (pattern && fnmatch(pattern, name, 0) != 0)
1573 snprintf(url, sizeof url,
1574 "%s/Packages/%s-%s.%s.rpm",
1575 yum_url, name, version, arch);
1576 snprintf(file, sizeof file,
1577 "rpms/%s-%s.%s.rpm", name, version, arch);
1578 download_if_missing(url, file);
1580 razor_package_iterator_destroy(pi);
1581 razor_set_unref(set);
1584 fprintf(stderr, "no packages matched \"%s\"\n", pattern);
1585 else if (matches == 1)
1586 fprintf(stderr, "downloaded 1 package\n");
1588 fprintf(stderr, "downloaded %d packages\n", matches);
1594 command_info(int argc, char * const argv[])
1596 struct razor_error *error = NULL;
1597 struct razor_set *set;
1598 struct razor_package_iterator *pi;
1599 struct razor_package *package;
1600 const char *pattern, *name, *version, *arch;
1601 const char *summary, *description, *url, *license;
1603 switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
1610 if (argc - optind > 1) {
1611 razor_usage(argv[0], 0, NULL, "[pattern]");
1615 pattern = argv[optind];
1617 set = razor_root_open_read_only(install_root, &error);
1619 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1620 razor_error_free(error);
1624 pi = razor_package_iterator_create(set);
1625 while (razor_package_iterator_next(pi, &package,
1626 RAZOR_DETAIL_NAME, &name,
1627 RAZOR_DETAIL_VERSION, &version,
1628 RAZOR_DETAIL_ARCH, &arch,
1629 RAZOR_DETAIL_LAST)) {
1630 if (pattern && fnmatch(pattern, name, 0) != 0)
1633 razor_package_get_details (set, package,
1634 RAZOR_DETAIL_SUMMARY, &summary,
1635 RAZOR_DETAIL_DESCRIPTION, &description,
1636 RAZOR_DETAIL_URL, &url,
1637 RAZOR_DETAIL_LICENSE, &license,
1640 printf ("Name: %s\n", name);
1641 printf ("Arch: %s\n", arch);
1642 printf ("Version: %s\n", version);
1643 printf ("URL: %s\n", url);
1644 printf ("License: %s\n", license);
1645 printf ("Summary: %s\n", summary);
1646 printf ("Description:\n");
1647 printf ("%s\n", description);
1650 razor_package_iterator_destroy(pi);
1651 razor_set_unref(set);
1656 #define SEARCH_MAX 256
1659 command_search(int argc, char * const argv[])
1661 struct razor_error *error = NULL;
1662 struct razor_set *set;
1663 struct razor_package_iterator *pi;
1664 struct razor_package *package;
1665 char pattern[SEARCH_MAX];
1666 const char *name, *version, *arch;
1667 const char *summary, *description, *url, *license;
1669 switch (razor_getopt(argc, argv, 0, NULL, "pattern", NULL)) {
1677 razor_usage(argv[0], 0, NULL, "pattern");
1681 snprintf(pattern, sizeof pattern, "*%s*", argv[1]);
1683 set = razor_set_open(rawhide_repo_filename, 0, &error);
1685 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1686 razor_error_free(error);
1690 pi = razor_package_iterator_create(set);
1691 while (razor_package_iterator_next(pi, &package,
1692 RAZOR_DETAIL_NAME, &name,
1693 RAZOR_DETAIL_VERSION, &version,
1694 RAZOR_DETAIL_ARCH, &arch,
1695 RAZOR_DETAIL_SUMMARY, &summary,
1696 RAZOR_DETAIL_DESCRIPTION, &description,
1697 RAZOR_DETAIL_URL, &url,
1698 RAZOR_DETAIL_LICENSE, &license,
1699 RAZOR_DETAIL_LAST)) {
1700 if (!fnmatch(pattern, name, FNM_CASEFOLD) ||
1701 !fnmatch(pattern, url, FNM_CASEFOLD) ||
1702 !fnmatch(pattern, summary, FNM_CASEFOLD) ||
1703 !fnmatch(pattern, description, FNM_CASEFOLD))
1704 printf("%s-%s.%s: %s\n", name, version, arch, summary);
1706 razor_package_iterator_destroy(pi);
1707 razor_set_unref(set);
1714 const char *description;
1715 int (*func)(int argc, char * const argv[]);
1716 } razor_commands[] = {
1717 { "diff", "Show diff between two package sets", command_diff },
1718 { "download", "Download packages", command_download },
1719 { "help", "List available commands", command_help },
1721 { "import-rpmdb", "Import the system rpm database",
1722 command_import_rpmdb },
1724 { "import-rpms", "Import rpms from the given directory",
1725 command_import_rpms },
1726 { "import-yum", "Import yum metadata files", command_import_yum },
1727 { "info", "Display package details", command_info },
1728 { "init", "Init razor root", command_init },
1729 { "install", "Install rpm", command_install },
1730 { "list", "List all packages", command_list },
1731 { "list-conflicts", "List all conflicts for the given package",
1732 command_list_conflicts },
1733 { "list-file-packages", "List packages owning file",
1734 command_list_file_packages },
1735 { "list-files", "List files for package set", command_list_files },
1736 { "list-obsoletes", "List all obsoletes for the given package",
1737 command_list_obsoletes },
1738 { "list-package-files", "List files in package",
1739 command_list_package_files },
1740 { "list-provides", "List all provides for the given package",
1741 command_list_provides },
1742 { "list-requires", "List all requires for the given package",
1743 command_list_requires },
1744 { "list-scripts", "List all scripts for the given package",
1745 command_list_scripts },
1746 { "remove", "Remove specified packages", command_remove },
1747 { "search", "Search package details", command_search },
1748 { "update", "Update all or specified packages", command_update },
1749 { "what-provides", "List the packages that have the given provides",
1750 command_what_provides },
1751 { "what-requires", "List the packages that have the given requires",
1752 command_what_requires },
1756 command_help(int argc, char * const argv[])
1760 printf("Available commands:\n");
1761 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1762 printf(" %-20s%s\n",
1763 razor_commands[i].name, razor_commands[i].description);
1764 printf("\nType \"razor --help\" for help about global options\n"
1765 "or \"razor <command> --help\" for help about a particular "
1766 "command's options.\n");
1772 main(int argc, char *argv[])
1775 int i, opt, main_optind;
1776 int do_help_commands = 0;
1784 struct option options[] = {
1785 { .name = "database", .has_arg = required_argument,
1786 .val = opt_database },
1787 { .name = "help", .has_arg = no_argument, .val = opt_help },
1788 { .name = "help-commands", .has_arg = no_argument,
1789 .flag = &do_help_commands, .val = TRUE },
1790 { .name = "root", .has_arg = required_argument,
1792 { .name = "url", .has_arg = required_argument, .val = opt_url },
1796 repo = getenv("RAZOR_REPO");
1798 repo_filename = repo;
1800 root = getenv("RAZOR_ROOT");
1802 install_root = root;
1804 yum_url = getenv("YUM_URL");
1805 if (yum_url == NULL)
1808 if (getenv("RAZOR_NO_ROOT_NAME_CHECKS"))
1809 razor_disable_root_name_checks(1);
1814 while ((opt = getopt_long(argc, argv, "+", options, NULL)) != -1) {
1817 razor_set_database_path(optarg);
1821 printf("Usage: razor [global-options] command "
1822 "[command-options-and-arguments]\n\n");
1823 printf("Options:\n");
1825 "Show this help message and exit\n");
1826 printf(" --help-commands List commands\n");
1827 printf(" --database=PATH "
1828 "Use alternative database\n");
1829 printf(" --root=ROOT "
1830 "Use ROOT as top level directory\n");
1831 printf(" --url=URL "
1832 "Use URL as upstream repository\n");
1833 return opt != opt_help;
1835 install_root = optarg;
1845 main_optind = optind;
1848 if (do_help_commands || argc - main_optind < 1) {
1849 command_help(argc - main_optind, argv + main_optind);
1853 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1854 if (strcmp(razor_commands[i].name, argv[main_optind]) == 0)
1855 return razor_commands[i].func(argc - main_optind,
1856 argv + main_optind);
1858 command_help(argc - main_optind, argv + main_optind);