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.
40 #include <curl/curl.h>
42 #if !defined(HAVE_CURL) && !defined(MSWIN_API)
50 static const char system_repo_filename[] = "system.rzdb";
51 static const char next_repo_filename[] = "system-next.rzdb";
52 static const char rawhide_repo_filename[] = "rawhide.rzdb";
53 static const char *install_root = "";
54 static const char *repo_filename = system_repo_filename;
55 static const char *yum_url;
65 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
68 update_packages(struct razor_transaction *trans,
69 struct razor_install_iterator *ii, struct razor_set *system,
70 struct razor_set *next, struct razor_atomic *atomic,
71 struct razor_relocations *relocations,
72 enum razor_stage_type stage);
74 update_system(struct razor_root *root, struct razor_relocations *relocations,
75 struct razor_transaction *trans, struct razor_set *next,
78 static int command_help(int argc, char * const argv[]);
85 char *arg_description;
89 razor_usage(const char *command, int n_options, struct razor_option *options,
90 const char *parameter_string)
92 int i, help_printed = FALSE;
95 printf("Usage: razor %s [options] %s\n", command, parameter_string);
96 printf("(Specify the --help global option for a list of other "
98 printf("\nOptions:\n");
100 for(i = 0; i < n_options; i++) {
101 if (!help_printed && strcmp(options[i].name, "help") > 0) {
103 "Show this help message and exit\n");
107 if (options[i].has_arg != no_argument)
108 snprintf(buf, sizeof(buf), "%s=%s", options[i].name,
109 options[i].arg_description);
111 strncpy(buf, options[i].name, sizeof(buf));
114 printf(" --%-18s%s\n", buf, options[i].description);
119 "Show this help message and exit\n");
126 * Returns: The next option found or -2 on handled or -1 on error
127 * or 0 on end of option list.
130 razor_getopt(int argc, char * const argv[], int n_options,
131 struct razor_option *options, const char *parameter_string,
134 int i, opt, do_help = 0, retval;
135 struct option *longopts;
137 longopts = calloc((n_options + 2), sizeof(*longopts));
139 for(i = 0; i < n_options; i++) {
140 longopts[i].name = options[i].name;
141 longopts[i].has_arg = options[i].has_arg;
142 longopts[i].flag = &retval;
143 longopts[i].val = options[i].val;
146 longopts[i].name = "help";
147 longopts[i].has_arg = no_argument;
148 longopts[i].flag = &do_help;
149 longopts[i].val = TRUE;
153 opt = getopt_long(argc, argv, "+", longopts, NULL);
159 razor_usage(argv[0], n_options, options,
171 razor_usage(argv[0], n_options, options,
180 static struct razor_package_iterator *
181 create_iterator_from_argv(struct razor_set *set, int argc, char * const argv[])
183 struct razor_package_query *query;
184 struct razor_package_iterator *iter;
185 struct razor_package *package;
186 const char *name, *pattern;
190 return razor_package_iterator_create(set);
192 query = razor_package_query_create(set);
194 for (i = 0; i < argc; i++) {
195 iter = razor_package_iterator_create(set);
198 while (razor_package_iterator_next(iter, &package,
199 RAZOR_DETAIL_NAME, &name,
200 RAZOR_DETAIL_LAST)) {
201 if (fnmatch(pattern, name, 0) != 0)
204 razor_package_query_add_package(query, package);
207 razor_package_iterator_destroy(iter);
211 "no package matches \"%s\"\n", pattern);
214 return razor_package_query_finish(query);
217 #define LIST_PACKAGES_ONLY_NAMES 0x01
220 list_packages(struct razor_package_iterator *iter, uint32_t flags)
222 struct razor_package *package;
223 const char *name, *version, *arch;
225 while (razor_package_iterator_next(iter, &package,
226 RAZOR_DETAIL_NAME, &name,
227 RAZOR_DETAIL_VERSION, &version,
228 RAZOR_DETAIL_ARCH, &arch,
229 RAZOR_DETAIL_LAST)) {
230 if (flags & LIST_PACKAGES_ONLY_NAMES)
231 printf("%s\n", name);
233 printf("%s-%s.%s\n", name, version, arch);
238 command_list(int argc, char * const argv[])
241 struct razor_package_iterator *pi;
242 struct razor_error *error = NULL;
243 struct razor_set *set;
248 static struct razor_option options[] = {
249 { .name = "only-names", .has_arg = no_argument,
250 .val = opt_only_names,
251 .description = "Only list package names" },
255 opt = razor_getopt(argc, argv, ARRAY_SIZE(options), options,
256 "pattern ...", NULL);
263 flags |= LIST_PACKAGES_ONLY_NAMES;
268 set = razor_root_open_read_only(install_root, &error);
270 fprintf(stderr, "%s\n", razor_error_get_msg(error));
271 razor_error_free(error);
275 pi = create_iterator_from_argv(set, argc - optind, argv + optind);
276 list_packages(pi, flags);
277 razor_package_iterator_destroy(pi);
278 razor_set_unref(set);
284 list_package_properties(struct razor_set *set,
285 struct razor_package *package, uint32_t type)
287 struct razor_property_iterator *pi;
288 struct razor_property *property;
289 const char *name, *version;
292 pi = razor_property_iterator_create(set, package);
293 while (razor_property_iterator_next(pi, &property,
294 &name, &flags, &version)) {
295 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
298 if (version[0] != '\0')
300 razor_property_relation_to_string(property),
303 if (flags & ~(RAZOR_PROPERTY_RELATION_MASK | RAZOR_PROPERTY_TYPE_MASK)) {
305 if (flags & RAZOR_PROPERTY_PRE)
307 if (flags & RAZOR_PROPERTY_POST)
309 if (flags & RAZOR_PROPERTY_PREUN)
311 if (flags & RAZOR_PROPERTY_POSTUN)
317 razor_property_iterator_destroy(pi);
321 list_properties(int argc, char * const argv[], uint32_t type)
323 struct razor_set *set;
324 struct razor_error *error = NULL;
325 struct razor_package *package;
326 struct razor_package_iterator *pi;
327 const char *name, *version, *arch;
329 switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
336 set = razor_root_open_read_only(install_root, &error);
338 fprintf(stderr, "%s\n", razor_error_get_msg(error));
339 razor_error_free(error);
343 pi = create_iterator_from_argv(set, argc - optind, argv + optind);
344 while (razor_package_iterator_next(pi, &package,
345 RAZOR_DETAIL_NAME, &name,
346 RAZOR_DETAIL_VERSION, &version,
347 RAZOR_DETAIL_ARCH, &arch,
349 list_package_properties(set, package, type);
350 razor_package_iterator_destroy(pi);
351 razor_set_unref(set);
357 command_list_requires(int argc, char * const argv[])
359 return list_properties(argc, argv, RAZOR_PROPERTY_REQUIRES);
363 command_list_provides(int argc, char * const argv[])
365 return list_properties(argc, argv, RAZOR_PROPERTY_PROVIDES);
369 command_list_obsoletes(int argc, char * const argv[])
371 return list_properties(argc, argv, RAZOR_PROPERTY_OBSOLETES);
375 command_list_conflicts(int argc, char * const argv[])
377 return list_properties(argc, argv, RAZOR_PROPERTY_CONFLICTS);
381 command_list_scripts(int argc, char * const argv[])
383 struct razor_set *set;
384 struct razor_error *error = NULL;
385 struct razor_package *package;
386 struct razor_package_iterator *pi;
387 const char *preunprog, *preun, *postunprog, *postun;
389 switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
396 set = razor_root_open_read_only(install_root, &error);
398 fprintf(stderr, "%s\n", razor_error_get_msg(error));
399 razor_error_free(error);
403 pi = create_iterator_from_argv(set, argc - optind, argv + optind);
404 while (razor_package_iterator_next(pi, &package,
405 RAZOR_DETAIL_PREUNPROG, &preunprog,
406 RAZOR_DETAIL_PREUN, &preun,
407 RAZOR_DETAIL_POSTUNPROG, &postunprog,
408 RAZOR_DETAIL_POSTUN, &postun,
409 RAZOR_DETAIL_LAST)) {
410 if (preun && *preun) {
411 printf("preuninstall scriptlet");
412 if (preunprog && *preunprog)
413 printf(" (using %s)",preunprog);
414 printf(":\n%s\n",preun);
416 if (postun && *postun) {
417 printf("postuninstall scriptlet");
418 if (postunprog && *postunprog)
419 printf(" (using %s)",postunprog);
420 printf(":\n%s\n",postun);
423 razor_package_iterator_destroy(pi);
424 razor_set_unref(set);
430 command_list_files(int argc, char * const argv[])
432 struct razor_error *error = NULL;
433 struct razor_set *set;
435 switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
442 if (argc - optind > 1) {
443 razor_usage(argv[0], 0, NULL, "[pattern]");
447 set = razor_root_open_read_only(install_root, &error);
449 fprintf(stderr, "%s\n", razor_error_get_msg(error));
450 razor_error_free(error);
454 razor_set_list_files(set, argv[optind]);
455 razor_set_unref(set);
461 command_list_file_packages(int argc, char * const argv[])
463 struct razor_error *error = NULL;
464 struct razor_set *set;
465 struct razor_package_iterator *pi;
467 switch (razor_getopt(argc, argv, 0, NULL, "pattern", NULL)) {
474 if (argc - optind != 1) {
475 razor_usage(argv[0], 0, NULL, "pattern");
479 set = razor_root_open_read_only(install_root, &error);
481 fprintf(stderr, "%s\n", razor_error_get_msg(error));
482 razor_error_free(error);
486 pi = razor_package_iterator_create_for_file(set, argv[optind]);
487 list_packages(pi, 0);
488 razor_package_iterator_destroy(pi);
490 razor_set_unref(set);
496 command_list_package_files(int argc, char * const argv[])
498 struct razor_error *error = NULL;
499 struct razor_set *set;
500 struct razor_package_iterator *pi;
501 struct razor_package *package;
502 const char *name, *version, *arch;
504 switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
511 set = razor_root_open_read_only(install_root, &error);
513 fprintf(stderr, "%s\n", razor_error_get_msg(error));
514 razor_error_free(error);
518 pi = create_iterator_from_argv(set, argc - optind, argv + optind);
519 while (razor_package_iterator_next(pi, &package,
520 RAZOR_DETAIL_NAME, &name,
521 RAZOR_DETAIL_VERSION, &version,
522 RAZOR_DETAIL_ARCH, &arch,
524 razor_set_list_package_files(set, package);
525 razor_package_iterator_destroy(pi);
527 razor_set_unref(set);
533 list_property_packages(const char *ref_name,
534 const char *ref_version,
537 struct razor_error *error = NULL;
538 struct razor_set *set;
539 struct razor_property *property;
540 struct razor_property_iterator *prop_iter;
541 struct razor_package_iterator *pkg_iter;
542 const char *name, *version;
545 set = razor_root_open_read_only(install_root, &error);
547 fprintf(stderr, "%s\n", razor_error_get_msg(error));
548 razor_error_free(error);
552 prop_iter = razor_property_iterator_create(set, NULL);
553 while (razor_property_iterator_next(prop_iter, &property,
554 &name, &flags, &version)) {
555 if (strcmp(ref_name, name) != 0)
558 (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
559 strcmp(ref_version, version) != 0)
561 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
565 razor_package_iterator_create_for_property(set,
567 list_packages(pkg_iter, 0);
568 razor_package_iterator_destroy(pkg_iter);
570 razor_property_iterator_destroy(prop_iter);
572 razor_set_unref(set);
578 command_what_requires(int argc, char * const argv[])
580 switch (razor_getopt(argc, argv, 0, NULL, "name [version-release]",
588 if (argc - optind < 1 || argc - optind > 2) {
589 razor_usage(argv[0], 0, NULL, "name [version-release]");
593 return list_property_packages(argv[optind], argv[optind + 1],
594 RAZOR_PROPERTY_REQUIRES);
598 command_what_provides(int argc, char * const argv[])
600 switch (razor_getopt(argc, argv, 0, NULL, "name [version-release]",
608 if (argc - optind < 1 || argc - optind > 2) {
609 razor_usage(argv[0], 0, NULL, "name [version-release]");
613 return list_property_packages(argv[optind], argv[optind + 1],
614 RAZOR_PROPERTY_PROVIDES);
619 download_local(const char *url, const char *file)
622 char buffer[256], *ptr, *local;
625 local = razor_path_from_url(url);
629 "%s: download manually (curl not available)\n",
633 rfp = fopen(local, "rb");
640 wfp = fopen(file, "wb");
648 while((nb = fread(buffer, 1, sizeof(buffer), rfp)) > 0) {
650 while (nb > 0 && (n = fwrite(ptr, 1, nb, wfp)) > 0) {
680 #endif /* !HAVE_CURL */
684 show_progress(void *clientp,
685 double dltotal, double dlnow, double ultotal, double ulnow)
687 const char *file = clientp;
689 if (!dlnow < dltotal)
690 fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
691 file, (int) dlnow / 1024, (int) dltotal / 1024);
697 download_with_curl(const char *url, const char *file)
705 curl = curl_easy_init();
708 "%s: download manually (curl failed)\n", file);
712 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
713 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
714 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
715 curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
717 fp = fopen(file, "wb");
722 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
723 curl_easy_setopt(curl, CURLOPT_URL, url);
724 res = curl_easy_perform(curl);
726 if (res != CURLE_OK) {
727 fprintf(stderr, "curl error: %s\n", error);
731 res = curl_easy_getinfo(curl,
732 CURLINFO_RESPONSE_CODE, &response);
733 if (res != CURLE_OK) {
734 fprintf(stderr, "curl error: %s\n", error);
738 if (response != 200) {
739 fprintf(stderr, " - failed %ld\n", response);
743 fprintf(stderr, "\n");
744 curl_easy_cleanup(curl);
748 #endif /* HAVE_CURL */
751 download_if_missing(const char *url, const char *file)
755 if (stat(file, &buf) >= 0)
759 return download_local(url, file);
761 return download_with_curl(url, file);
765 #define YUM_URL "http://download.fedora.redhat.com" \
766 "/pub/fedora/linux/development/i386/os"
769 command_import_yum(int argc, char * const argv[])
772 struct razor_set *set;
773 struct razor_atomic *atomic;
776 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
783 if (argc - optind > 0) {
784 razor_usage(argv[0], 0, NULL, "");
788 printf("downloading from '%s'.\n", yum_url);
789 snprintf(buffer, sizeof buffer,
790 "%s/repodata/primary.xml.gz", yum_url);
791 if (download_if_missing(buffer, "primary.xml.gz") < 0)
793 snprintf(buffer, sizeof buffer,
794 "%s/repodata/filelists.xml.gz", yum_url);
795 if (download_if_missing(buffer, "filelists.xml.gz") < 0)
798 set = razor_set_create_from_yum();
801 atomic = razor_atomic_open("Yum import repository");
802 razor_set_write(set, atomic, rawhide_repo_filename, RAZOR_SECTION_ALL);
803 retval = razor_atomic_commit(atomic);
804 razor_set_unref(set);
806 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
808 printf("wrote %s\n", rawhide_repo_filename);
809 razor_atomic_destroy(atomic);
816 command_import_rpmdb(int argc, char * const argv[])
818 struct razor_set *set;
819 struct razor_root *root;
820 struct razor_error *error = NULL;
821 struct razor_atomic *atomic;
824 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
831 if (argc - optind > 0) {
832 razor_usage(argv[0], 0, NULL, "");
836 root = razor_root_open(install_root, &error);
838 fprintf(stderr, "%s\n", razor_error_get_msg(error));
839 razor_error_free(error);
843 set = razor_set_create_from_rpmdb();
847 atomic = razor_atomic_open("Import RPM database");
849 retval = razor_root_update(root, set, atomic);
852 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
854 razor_atomic_destroy(atomic);
856 razor_root_close(root);
863 mark_packages_for_update(struct razor_transaction *trans,
864 struct razor_set *set, const char *pattern)
866 struct razor_package_iterator *pi;
867 struct razor_package *package;
871 pi = razor_package_iterator_create(set);
872 while (razor_package_iterator_next(pi, &package,
873 RAZOR_DETAIL_NAME, &name,
874 RAZOR_DETAIL_LAST)) {
875 if (pattern && fnmatch(pattern, name, 0) == 0) {
876 razor_transaction_update_package(trans, package);
880 razor_package_iterator_destroy(pi);
886 mark_packages_for_removal(struct razor_transaction *trans,
887 struct razor_set *set, const char *pattern)
889 struct razor_package_iterator *pi;
890 struct razor_package *package;
894 pi = razor_package_iterator_create(set);
895 while (razor_package_iterator_next(pi, &package,
896 RAZOR_DETAIL_NAME, &name,
897 RAZOR_DETAIL_LAST)) {
898 if (pattern && fnmatch(pattern, name, 0) == 0) {
899 razor_transaction_remove_package(trans, package);
903 razor_package_iterator_destroy(pi);
909 command_remove(int argc, char * const argv[])
911 struct razor_set *system, *upstream, *next;
912 struct razor_transaction *trans;
913 struct razor_error *error = NULL;
914 struct razor_root *root;
917 switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
924 root = razor_root_open(install_root, &error);
926 fprintf(stderr, "%s\n", razor_error_get_msg(error));
927 razor_error_free(error);
931 system = razor_root_get_system_set(root);
932 upstream = razor_set_create_without_root();
933 trans = razor_transaction_create(system, upstream);
934 razor_set_unref(upstream);
935 for (i = optind; i < argc; i++) {
936 if (mark_packages_for_removal(trans, system, argv[i]) == 0) {
937 fprintf(stderr, "no match for %s\n", argv[i]);
938 razor_transaction_destroy(trans);
939 razor_root_close(root);
944 razor_transaction_resolve(trans);
945 retval = razor_transaction_describe(trans);
947 razor_transaction_destroy(trans);
948 razor_root_close(root);
952 next = razor_transaction_commit(trans);
954 retval = update_system(root, NULL, trans, next, "Remove");
956 razor_transaction_destroy(trans);
957 razor_root_close(root);
958 razor_set_unref(next);
964 print_diff(enum razor_diff_action action,
965 struct razor_package *package,
971 if (action == RAZOR_DIFF_ACTION_ADD)
972 printf("install %s-%s.%s\n", name, version, arch);
973 if (action == RAZOR_DIFF_ACTION_REMOVE)
974 printf("remove %s-%s.%s\n", name, version, arch);
978 command_diff(int argc, char * const argv[])
980 struct razor_error *error = NULL;
981 struct razor_set *set, *updated;
983 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
990 if (argc - optind > 0) {
991 razor_usage(argv[0], 0, NULL, "");
995 set = razor_root_open_read_only(install_root, &error);
997 updated = razor_set_open(rawhide_repo_filename, 0, &error);
1000 if (updated == NULL) {
1001 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1002 razor_error_free(error);
1004 razor_set_unref(set);
1008 razor_set_diff(set, updated, print_diff, NULL);
1010 razor_set_unref(set);
1011 razor_set_unref(updated);
1017 command_import_rpms(int argc, char * const argv[])
1021 struct razor_importer *importer;
1022 struct razor_set *set;
1023 struct razor_rpm *rpm;
1024 struct razor_error *error=NULL;
1025 struct razor_atomic *atomic;
1026 int len, imported_count = 0;
1028 const char *dirname;
1031 switch (razor_getopt(argc, argv, 0, NULL, "dir", NULL)) {
1038 if (argc - optind != 1) {
1039 razor_usage(argv[0], 0, NULL, "dir");
1043 dirname = argv[optind];
1045 dir = opendir(dirname);
1047 fprintf(stderr, "couldn't read dir %s\n", dirname);
1051 importer = razor_importer_create();
1053 while (de = readdir(dir), de != NULL) {
1054 len = strlen(de->d_name);
1055 if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
1057 snprintf(filename, sizeof filename,
1058 "%s/%s", dirname, de->d_name);
1059 rpm = razor_rpm_open(filename, &error);
1061 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1062 razor_error_free(error);
1066 if (razor_importer_add_rpm(importer, rpm)) {
1067 fprintf(stderr, "couldn't import %s\n", filename);
1070 razor_rpm_close(rpm);
1072 printf("\rimporting %d", ++imported_count);
1077 razor_importer_destroy(importer);
1081 printf("\nsaving\n");
1082 set = razor_importer_finish(importer);
1084 atomic = razor_atomic_open("Update system database");
1085 razor_set_write(set, atomic, repo_filename, RAZOR_SECTION_ALL);
1086 razor_set_unref(set);
1087 retval = razor_atomic_commit(atomic);
1089 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1091 printf("wrote %s\n", repo_filename);
1092 razor_atomic_destroy(atomic);
1098 rpm_filename(const char *name, const char *version, const char *arch)
1103 v = strchr(version, ':');
1109 return razor_concat(name, "-", v, ".", arch, ".rpm", NULL);
1113 download_packages(struct razor_set *system, struct razor_set *next)
1115 struct razor_install_iterator *ii;
1116 struct razor_package *package;
1117 enum razor_install_action action;
1118 const char *name, *version, *arch;
1119 char *file, *url, *s;
1120 int errors = 0, count;
1122 ii = razor_set_create_install_iterator(system, next);
1123 while (razor_install_iterator_next(ii, &package, &action, &count)) {
1124 if (action != RAZOR_INSTALL_ACTION_ADD)
1127 razor_package_get_details(next, package,
1128 RAZOR_DETAIL_NAME, &name,
1129 RAZOR_DETAIL_VERSION, &version,
1130 RAZOR_DETAIL_ARCH, &arch,
1133 s = rpm_filename(name, version, arch);
1134 url = razor_concat(yum_url, "/Packages/", s, NULL);
1135 file = razor_concat("rpms/", s, NULL);
1137 if (download_if_missing(url, file) < 0)
1142 razor_install_iterator_destroy(ii);
1145 fprintf(stderr, "failed to download %d packages\n", errors);
1152 static struct razor_set *
1153 relocate_packages(struct razor_set *set, struct razor_atomic *atomic,
1154 struct razor_relocations *relocations)
1157 struct razor_importer *importer;
1158 struct razor_property_iterator *prop_iter;
1159 struct razor_package_iterator *pkg_iter;
1160 struct razor_file_iterator *file_iter;
1161 struct razor_package *package;
1162 struct razor_property *property;
1163 struct razor_rpm *rpm;
1164 struct razor_error *error=NULL;
1165 const char *name, *version, *arch, *summary, *desc, *url, *license;
1166 const char *preunprog, *preun, *postunprog, *postun;
1167 const char *install_prefix;
1168 const char *const *prefixes;
1172 importer = razor_importer_create();
1173 pkg_iter = razor_package_iterator_create(set);
1175 while (razor_package_iterator_next(pkg_iter, &package,
1176 RAZOR_DETAIL_NAME, &name,
1177 RAZOR_DETAIL_VERSION, &version,
1178 RAZOR_DETAIL_ARCH, &arch,
1179 RAZOR_DETAIL_SUMMARY, &summary,
1180 RAZOR_DETAIL_DESCRIPTION, &desc,
1181 RAZOR_DETAIL_URL, &url,
1182 RAZOR_DETAIL_LICENSE, &license,
1183 RAZOR_DETAIL_PREUNPROG, &preunprog,
1184 RAZOR_DETAIL_PREUN, &preun,
1185 RAZOR_DETAIL_POSTUNPROG, &postunprog,
1186 RAZOR_DETAIL_POSTUN, &postun,
1187 RAZOR_DETAIL_LAST)) {
1188 s = rpm_filename(name, version, arch);
1189 file = razor_concat("rpms/", s, NULL);
1191 rpm = razor_rpm_open(file, &error);
1194 razor_atomic_propagate_error(atomic, error, NULL);
1195 razor_error_free(error);
1196 razor_package_iterator_destroy(pkg_iter);
1197 razor_importer_destroy(importer);
1201 razor_relocations_set_rpm(relocations, rpm);
1203 razor_importer_begin_package(importer, name, version, arch);
1204 razor_importer_add_details(importer,
1205 summary, desc, url, license);
1207 razor_rpm_get_details(rpm, RAZOR_DETAIL_PREFIXES, &prefixes,
1209 for (i = 0; prefixes && prefixes[i]; i++) {
1210 install_prefix = razor_relocations_apply(relocations,
1212 razor_importer_add_install_prefix(importer,
1216 razor_rpm_close(rpm);
1218 prop_iter = razor_property_iterator_create(set, package);
1219 while (razor_property_iterator_next(prop_iter, &property,
1220 &name, &flags, &version))
1221 razor_importer_add_property(importer,
1222 name, flags, version);
1223 razor_property_iterator_destroy(prop_iter);
1225 file_iter = razor_file_iterator_create(set, package, 0);
1226 while (razor_file_iterator_next(file_iter, &name)) {
1227 name = razor_relocations_apply(relocations, name);
1228 razor_importer_add_file(importer, name);
1230 razor_file_iterator_destroy(file_iter);
1232 razor_importer_add_script(importer, RAZOR_PROPERTY_PREUN,
1234 razor_importer_add_script(importer, RAZOR_PROPERTY_POSTUN,
1235 postunprog, postun);
1237 razor_importer_finish_package(importer);
1240 razor_package_iterator_destroy(pkg_iter);
1241 return razor_importer_finish(importer);
1245 install_package(struct razor_transaction *trans, struct razor_set *set,
1246 struct razor_atomic *atomic, struct razor_package *package,
1247 struct razor_relocations *relocations, int install_count,
1248 enum razor_stage_type stage)
1251 const char *name, *version, *arch;
1253 struct razor_rpm *rpm;
1254 struct razor_error *error=NULL;
1256 razor_package_get_details(set, package,
1257 RAZOR_DETAIL_NAME, &name,
1258 RAZOR_DETAIL_VERSION, &version,
1259 RAZOR_DETAIL_ARCH, &arch,
1262 if (stage & RAZOR_STAGE_SCRIPTS_PRE)
1263 printf("install %s-%s\n", name, version);
1265 s = rpm_filename(name, version, arch);
1266 file = razor_concat("rpms/", s, NULL);
1268 rpm = razor_rpm_open(file, &error);
1271 razor_atomic_propagate_error(atomic, error, NULL);
1272 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1273 razor_error_free(error);
1277 razor_rpm_set_relocations(rpm, relocations);
1278 razor_transaction_fixup_package(trans, package, rpm);
1279 retval = razor_rpm_install(rpm, atomic, install_root, install_count,
1282 s = rpm_filename(name, version, arch);
1283 fprintf(stderr, "%s: %s\n", s,
1284 razor_atomic_get_error_msg(atomic));
1287 razor_rpm_close(rpm);
1292 * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT
1293 * is met (in which case the action is consumed).
1296 update_packages(struct razor_transaction *trans,
1297 struct razor_install_iterator *ii, struct razor_set *system,
1298 struct razor_set *next, struct razor_atomic *atomic,
1299 struct razor_relocations *relocations,
1300 enum razor_stage_type stage)
1302 struct razor_package *package;
1303 enum razor_install_action action;
1304 int retval = 0, count;
1306 while (!retval && razor_install_iterator_next(ii, &package, &action,
1308 if (action == RAZOR_INSTALL_ACTION_ADD) {
1309 if (install_package(trans, next, atomic, package,
1310 relocations, count, stage))
1312 } else if (action == RAZOR_INSTALL_ACTION_REMOVE) {
1313 if (razor_package_remove(system, next, atomic, package,
1314 install_root, count, stage))
1316 } else if (action == RAZOR_INSTALL_ACTION_COMMIT)
1324 update_system(struct razor_root *root, struct razor_relocations *relocations,
1325 struct razor_transaction *trans, struct razor_set *next,
1328 struct razor_set *system, *set;
1329 struct razor_atomic *atomic;
1330 struct razor_install_iterator *ii;
1335 description = razor_concat(verb, " packages", NULL);
1337 system = razor_set_ref(razor_root_get_system_set(root));
1339 ii = razor_set_create_install_iterator(system, next);
1342 pos = razor_install_iterator_tell(ii);
1344 atomic = razor_atomic_open(description);
1346 r = update_packages(trans, ii, system, next, atomic,
1347 relocations, RAZOR_STAGE_SCRIPTS_PRE);
1349 fprintf(stderr, "%s aborted\n", verb);
1352 razor_install_iterator_seek(ii, pos);
1353 r = update_packages(trans, ii, system, next, atomic,
1354 relocations, RAZOR_STAGE_FILES);
1357 set = razor_install_iterator_commit_set(ii);
1358 razor_root_update(root, set, atomic);
1359 razor_set_unref(set);
1361 razor_root_update(root, next, atomic);
1363 retval = razor_atomic_commit(atomic);
1365 fprintf(stderr, "%s\n",
1366 razor_atomic_get_error_msg(atomic));
1368 razor_install_iterator_seek(ii, pos);
1369 update_packages(trans, ii, system, next,
1370 atomic, relocations,
1371 RAZOR_STAGE_SCRIPTS_POST);
1375 razor_atomic_destroy(atomic);
1376 } while(!retval && r == 1);
1378 razor_install_iterator_destroy(ii);
1380 razor_set_unref(system);
1388 command_install_or_update(int argc, char * const argv[], int do_update)
1390 struct razor_relocations *relocations = NULL;
1391 struct razor_set *system, *upstream, *next, *set;
1392 struct razor_transaction *trans;
1393 struct razor_error *error = NULL;
1394 struct razor_atomic *atomic;
1395 struct razor_root *root;
1396 int opt, i, retval = 0, len, dependencies = 1;
1400 opt_no_dependencies = 1,
1403 static struct razor_option options[] = {
1404 { .name = "no-dependencies", .has_arg = no_argument,
1405 .val = opt_no_dependencies,
1406 .description = "Do not verify package dependencies" },
1407 { .name = "relocate", .has_arg = required_argument,
1408 .val = opt_relocate,
1409 .description = "Relocate files from path OLD to NEW",
1410 .arg_description = "OLD=NEW" },
1414 opt = razor_getopt(argc, argv, ARRAY_SIZE(options), options,
1421 case opt_no_dependencies:
1425 if (strchr(arg, '=') == NULL) {
1426 razor_usage(argv[0],
1427 ARRAY_SIZE(options),
1428 options, "rpm ...");
1431 len = strchr(arg, '=') - arg;
1432 oldpath = malloc(len + 1);
1433 strncpy(oldpath, arg, len);
1434 oldpath[len] = '\0';
1436 relocations = razor_relocations_create();
1437 razor_relocations_add(relocations, oldpath,
1444 upstream = razor_set_open(rawhide_repo_filename, 0, &error);
1445 if (upstream == NULL) {
1446 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1447 razor_error_free(error);
1449 razor_relocations_destroy(relocations);
1454 atomic = razor_atomic_open("Update packages");
1456 atomic = razor_atomic_open("Install packages");
1459 set = relocate_packages(upstream, atomic, relocations);
1461 fprintf(stderr, "%s\n",
1462 razor_atomic_get_error_msg(atomic));
1463 razor_atomic_destroy(atomic);
1464 razor_set_unref(upstream);
1467 razor_set_unref(upstream);
1471 root = razor_root_open(install_root, &error);
1473 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1474 razor_error_free(error);
1475 razor_atomic_destroy(atomic);
1476 razor_set_unref(upstream);
1478 razor_relocations_destroy(relocations);
1482 system = razor_root_get_system_set(root);
1483 trans = razor_transaction_create(system, upstream);
1485 if (optind == argc && do_update)
1486 razor_transaction_update_all(trans);
1487 for (i = optind; i < argc; i++) {
1489 mark_packages_for_update(trans, system, argv[i]))
1491 if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
1492 fprintf(stderr, "no package matched %s\n", argv[i]);
1493 razor_transaction_destroy(trans);
1494 razor_root_close(root);
1495 razor_set_unref(upstream);
1496 razor_atomic_destroy(atomic);
1498 razor_relocations_destroy(relocations);
1504 razor_transaction_resolve(trans);
1505 if (razor_transaction_describe(trans) > 0) {
1506 razor_transaction_destroy(trans);
1507 razor_set_unref(upstream);
1508 razor_root_close(root);
1509 razor_atomic_destroy(atomic);
1511 razor_relocations_destroy(relocations);
1516 if (razor_atomic_create_dir(atomic, "rpms",
1517 S_IRWXU | S_IRWXG | S_IRWXO) ||
1518 razor_atomic_commit(atomic)) {
1519 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1520 razor_transaction_destroy(trans);
1521 razor_set_unref(upstream);
1522 razor_root_close(root);
1523 razor_atomic_destroy(atomic);
1525 razor_relocations_destroy(relocations);
1529 razor_atomic_destroy(atomic);
1531 next = razor_transaction_commit(trans);
1533 if (download_packages(system, next) < 0) {
1534 razor_set_unref(next);
1535 razor_transaction_destroy(trans);
1536 razor_set_unref(upstream);
1537 razor_root_close(root);
1539 razor_relocations_destroy(relocations);
1543 retval = update_system(root, relocations, trans, next,
1544 do_update ? "Update" : "Install");
1546 razor_set_unref(upstream);
1547 razor_root_close(root);
1549 razor_transaction_destroy(trans);
1551 razor_relocations_destroy(relocations);
1553 razor_set_unref(next);
1559 command_update(int argc, char * const argv[])
1561 return command_install_or_update(argc, argv, 1);
1565 command_install(int argc, char * const argv[])
1567 return command_install_or_update(argc, argv, 0);
1571 command_init(int argc, char * const argv[])
1574 struct razor_error *error = NULL;
1576 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
1583 if (argc - optind > 0) {
1584 razor_usage(argv[0], 0, NULL, "");
1588 retval = razor_root_create(install_root, &error);
1590 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1591 razor_error_free(error);
1593 printf("Created install root\n");
1599 command_download(int argc, char * const argv[])
1601 struct razor_error *error = NULL;
1602 struct razor_atomic *atomic;
1603 struct razor_set *set;
1604 struct razor_package_iterator *pi;
1605 struct razor_package *package;
1606 const char *pattern, *name, *version, *arch;
1607 char url[256], file[256];
1610 switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
1617 if (argc - optind > 1) {
1618 razor_usage(argv[0], 0, NULL, "[pattern]");
1622 pattern = argv[optind];
1624 set = razor_set_open(rawhide_repo_filename, 0, &error);
1626 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1627 razor_error_free(error);
1631 atomic = razor_atomic_open("Download packages");
1633 if (razor_atomic_create_dir(atomic, "rpms",
1634 S_IRWXU | S_IRWXG | S_IRWXO)) {
1635 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1636 razor_atomic_destroy(atomic);
1640 if (razor_atomic_commit(atomic)) {
1641 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1642 razor_atomic_destroy(atomic);
1645 razor_atomic_destroy(atomic);
1647 pi = razor_package_iterator_create(set);
1648 while (razor_package_iterator_next(pi, &package,
1649 RAZOR_DETAIL_NAME, &name,
1650 RAZOR_DETAIL_VERSION, &version,
1651 RAZOR_DETAIL_ARCH, &arch,
1652 RAZOR_DETAIL_LAST)) {
1653 if (pattern && fnmatch(pattern, name, 0) != 0)
1657 snprintf(url, sizeof url,
1658 "%s/Packages/%s-%s.%s.rpm",
1659 yum_url, name, version, arch);
1660 snprintf(file, sizeof file,
1661 "rpms/%s-%s.%s.rpm", name, version, arch);
1662 download_if_missing(url, file);
1664 razor_package_iterator_destroy(pi);
1665 razor_set_unref(set);
1668 fprintf(stderr, "no packages matched \"%s\"\n", pattern);
1669 else if (matches == 1)
1670 fprintf(stderr, "downloaded 1 package\n");
1672 fprintf(stderr, "downloaded %d packages\n", matches);
1678 command_dump(int argc, char * const argv[])
1680 struct razor_error *error = NULL;
1681 const char *filename;
1683 switch (razor_getopt(argc, argv, 0, NULL, "[filename]", NULL)) {
1690 if (argc - optind > 1) {
1691 razor_usage(argv[0], 0, NULL, "[filename]");
1695 filename = argv[optind];
1697 if (razor_dump_database(stdout, install_root, filename, &error)) {
1698 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1699 razor_error_free(error);
1707 command_info(int argc, char * const argv[])
1709 struct razor_error *error = NULL;
1710 struct razor_set *set;
1711 struct razor_package_iterator *pi;
1712 struct razor_package *package;
1713 const char *pattern, *name, *version, *arch;
1714 const char *summary, *description, *url, *license;
1716 switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
1723 if (argc - optind > 1) {
1724 razor_usage(argv[0], 0, NULL, "[pattern]");
1728 pattern = argv[optind];
1730 set = razor_root_open_read_only(install_root, &error);
1732 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1733 razor_error_free(error);
1737 pi = razor_package_iterator_create(set);
1738 while (razor_package_iterator_next(pi, &package,
1739 RAZOR_DETAIL_NAME, &name,
1740 RAZOR_DETAIL_VERSION, &version,
1741 RAZOR_DETAIL_ARCH, &arch,
1742 RAZOR_DETAIL_LAST)) {
1743 if (pattern && fnmatch(pattern, name, 0) != 0)
1746 razor_package_get_details (set, package,
1747 RAZOR_DETAIL_SUMMARY, &summary,
1748 RAZOR_DETAIL_DESCRIPTION, &description,
1749 RAZOR_DETAIL_URL, &url,
1750 RAZOR_DETAIL_LICENSE, &license,
1753 printf ("Name: %s\n", name);
1754 printf ("Arch: %s\n", arch);
1755 printf ("Version: %s\n", version);
1756 printf ("URL: %s\n", url);
1757 printf ("License: %s\n", license);
1758 printf ("Summary: %s\n", summary);
1759 printf ("Description:\n");
1760 printf ("%s\n", description);
1763 razor_package_iterator_destroy(pi);
1764 razor_set_unref(set);
1769 #define SEARCH_MAX 256
1772 command_search(int argc, char * const argv[])
1774 struct razor_error *error = NULL;
1775 struct razor_set *set;
1776 struct razor_package_iterator *pi;
1777 struct razor_package *package;
1778 char pattern[SEARCH_MAX];
1779 const char *name, *version, *arch;
1780 const char *summary, *description, *url, *license;
1782 switch (razor_getopt(argc, argv, 0, NULL, "pattern", NULL)) {
1790 razor_usage(argv[0], 0, NULL, "pattern");
1794 snprintf(pattern, sizeof pattern, "*%s*", argv[1]);
1796 set = razor_set_open(rawhide_repo_filename, 0, &error);
1798 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1799 razor_error_free(error);
1803 pi = razor_package_iterator_create(set);
1804 while (razor_package_iterator_next(pi, &package,
1805 RAZOR_DETAIL_NAME, &name,
1806 RAZOR_DETAIL_VERSION, &version,
1807 RAZOR_DETAIL_ARCH, &arch,
1808 RAZOR_DETAIL_SUMMARY, &summary,
1809 RAZOR_DETAIL_DESCRIPTION, &description,
1810 RAZOR_DETAIL_URL, &url,
1811 RAZOR_DETAIL_LICENSE, &license,
1812 RAZOR_DETAIL_LAST)) {
1813 if (!fnmatch(pattern, name, FNM_CASEFOLD) ||
1814 !fnmatch(pattern, url, FNM_CASEFOLD) ||
1815 !fnmatch(pattern, summary, FNM_CASEFOLD) ||
1816 !fnmatch(pattern, description, FNM_CASEFOLD))
1817 printf("%s-%s.%s: %s\n", name, version, arch, summary);
1819 razor_package_iterator_destroy(pi);
1820 razor_set_unref(set);
1827 const char *description;
1828 int (*func)(int argc, char * const argv[]);
1829 } razor_commands[] = {
1830 { "diff", "Show diff between two package sets", command_diff },
1831 { "download", "Download packages", command_download },
1832 { "dump", "Low-level database dump (for debugging)", command_dump },
1833 { "help", "List available commands", command_help },
1835 { "import-rpmdb", "Import the system rpm database",
1836 command_import_rpmdb },
1838 { "import-rpms", "Import rpms from the given directory",
1839 command_import_rpms },
1840 { "import-yum", "Import yum metadata files", command_import_yum },
1841 { "info", "Display package details", command_info },
1842 { "init", "Init razor root", command_init },
1843 { "install", "Install rpm", command_install },
1844 { "list", "List all packages", command_list },
1845 { "list-conflicts", "List all conflicts for the given package",
1846 command_list_conflicts },
1847 { "list-file-packages", "List packages owning file",
1848 command_list_file_packages },
1849 { "list-files", "List files for package set", command_list_files },
1850 { "list-obsoletes", "List all obsoletes for the given package",
1851 command_list_obsoletes },
1852 { "list-package-files", "List files in package",
1853 command_list_package_files },
1854 { "list-provides", "List all provides for the given package",
1855 command_list_provides },
1856 { "list-requires", "List all requires for the given package",
1857 command_list_requires },
1858 { "list-scripts", "List all scripts for the given package",
1859 command_list_scripts },
1860 { "remove", "Remove specified packages", command_remove },
1861 { "search", "Search package details", command_search },
1862 { "update", "Update all or specified packages", command_update },
1863 { "what-provides", "List the packages that have the given provides",
1864 command_what_provides },
1865 { "what-requires", "List the packages that have the given requires",
1866 command_what_requires },
1870 command_help(int argc, char * const argv[])
1874 printf("Available commands:\n");
1875 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1876 printf(" %-20s%s\n",
1877 razor_commands[i].name, razor_commands[i].description);
1878 printf("\nType \"razor --help\" for help about global options\n"
1879 "or \"razor <command> --help\" for help about a particular "
1880 "command's options.\n");
1886 main(int argc, char *argv[])
1889 int i, opt, main_optind;
1890 int do_help_commands = 0;
1898 struct option options[] = {
1899 { .name = "database", .has_arg = required_argument,
1900 .val = opt_database },
1901 { .name = "help", .has_arg = no_argument, .val = opt_help },
1902 { .name = "help-commands", .has_arg = no_argument,
1903 .flag = &do_help_commands, .val = TRUE },
1904 { .name = "root", .has_arg = required_argument,
1906 { .name = "url", .has_arg = required_argument, .val = opt_url },
1910 repo = getenv("RAZOR_REPO");
1912 repo_filename = repo;
1914 root = getenv("RAZOR_ROOT");
1916 install_root = root;
1918 yum_url = getenv("YUM_URL");
1919 if (yum_url == NULL)
1922 if (getenv("RAZOR_NO_ROOT_NAME_CHECKS"))
1923 razor_disable_root_name_checks(1);
1928 while ((opt = getopt_long(argc, argv, "+", options, NULL)) != -1) {
1931 razor_set_database_path(optarg);
1935 printf("Usage: razor [global-options] command "
1936 "[command-options-and-arguments]\n\n");
1937 printf("Options:\n");
1939 "Show this help message and exit\n");
1940 printf(" --help-commands List commands\n");
1941 printf(" --database=PATH "
1942 "Use alternative database\n");
1943 printf(" --root=ROOT "
1944 "Use ROOT as top level directory\n");
1945 printf(" --url=URL "
1946 "Use URL as upstream repository\n");
1947 return opt != opt_help;
1949 install_root = optarg;
1959 main_optind = optind;
1962 if (do_help_commands || argc - main_optind < 1) {
1963 command_help(argc - main_optind, argv + main_optind);
1967 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1968 if (strcmp(razor_commands[i].name, argv[main_optind]) == 0)
1969 return razor_commands[i].func(argc - main_optind,
1970 argv + main_optind);
1972 command_help(argc - main_optind, argv + main_optind);