2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009, 2011-2012, 2014, 2016 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_uri[] = "file: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, (char **)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;
624 struct razor_error *error = NULL;
626 local = razor_path_from_uri(url, &error);
629 fprintf(stderr, "%s: %s\n", file, razor_error_get_msg(error));
630 razor_error_free(error);
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);
727 if (res != CURLE_OK) {
728 fprintf(stderr, "curl error: %s\n", error);
732 curl_easy_cleanup(curl);
736 #endif /* HAVE_CURL */
739 download_if_missing(const char *url, const char *file)
743 if (stat(file, &buf) >= 0)
747 return download_local(url, file);
749 return download_with_curl(url, file);
753 #define YUM_URL "http://download.fedora.redhat.com" \
754 "/pub/fedora/linux/development/i386/os"
757 command_import_yum(int argc, char * const argv[])
760 struct razor_set *set;
761 struct razor_atomic *atomic;
764 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
771 if (argc - optind > 0) {
772 razor_usage(argv[0], 0, NULL, "");
776 printf("downloading from '%s'.\n", yum_url);
777 snprintf(buffer, sizeof buffer,
778 "%s/repodata/primary.xml.gz", yum_url);
779 if (download_if_missing(buffer, "primary.xml.gz") < 0)
781 snprintf(buffer, sizeof buffer,
782 "%s/repodata/filelists.xml.gz", yum_url);
783 if (download_if_missing(buffer, "filelists.xml.gz") < 0)
786 set = razor_set_create_from_yum();
789 atomic = razor_atomic_open("Yum import repository");
790 razor_set_write(set, atomic, rawhide_repo_uri, RAZOR_SECTION_ALL);
791 retval = razor_atomic_commit(atomic);
792 razor_set_unref(set);
794 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
796 printf("wrote %s\n", rawhide_repo_uri);
797 razor_atomic_destroy(atomic);
804 command_import_rpmdb(int argc, char * const argv[])
806 struct razor_set *set;
807 struct razor_root *root;
808 struct razor_error *error = NULL;
809 struct razor_atomic *atomic;
812 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
819 if (argc - optind > 0) {
820 razor_usage(argv[0], 0, NULL, "");
824 root = razor_root_open(install_root, &error);
826 fprintf(stderr, "%s\n", razor_error_get_msg(error));
827 razor_error_free(error);
831 set = razor_set_create_from_rpmdb();
835 atomic = razor_atomic_open("Import RPM database");
837 retval = razor_root_update(root, set, atomic);
840 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
842 razor_atomic_destroy(atomic);
844 razor_root_close(root);
851 mark_packages_for_update(struct razor_transaction *trans,
852 struct razor_set *set, const char *pattern)
854 struct razor_package_iterator *pi;
855 struct razor_package *package;
859 pi = razor_package_iterator_create(set);
860 while (razor_package_iterator_next(pi, &package,
861 RAZOR_DETAIL_NAME, &name,
862 RAZOR_DETAIL_LAST)) {
863 if (pattern && fnmatch(pattern, name, 0) == 0) {
864 razor_transaction_update_package(trans, package);
868 razor_package_iterator_destroy(pi);
874 mark_packages_for_removal(struct razor_transaction *trans,
875 struct razor_set *set, const char *pattern)
877 struct razor_package_iterator *pi;
878 struct razor_package *package;
882 pi = razor_package_iterator_create(set);
883 while (razor_package_iterator_next(pi, &package,
884 RAZOR_DETAIL_NAME, &name,
885 RAZOR_DETAIL_LAST)) {
886 if (pattern && fnmatch(pattern, name, 0) == 0) {
887 razor_transaction_remove_package(trans, package);
891 razor_package_iterator_destroy(pi);
897 command_remove(int argc, char * const argv[])
899 struct razor_set *system, *upstream, *next;
900 struct razor_transaction *trans;
901 struct razor_error *error = NULL;
902 struct razor_root *root;
905 switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
912 root = razor_root_open(install_root, &error);
914 fprintf(stderr, "%s\n", razor_error_get_msg(error));
915 razor_error_free(error);
919 system = razor_root_get_system_set(root);
920 upstream = razor_set_create_without_root();
921 trans = razor_transaction_create(system, upstream);
922 razor_set_unref(upstream);
923 for (i = optind; i < argc; i++) {
924 if (mark_packages_for_removal(trans, system, argv[i]) == 0) {
925 fprintf(stderr, "no match for %s\n", argv[i]);
926 razor_transaction_destroy(trans);
927 razor_root_close(root);
932 razor_transaction_resolve(trans);
933 retval = razor_transaction_describe(trans);
935 razor_transaction_destroy(trans);
936 razor_root_close(root);
940 next = razor_transaction_commit(trans);
942 retval = update_system(root, NULL, trans, next, "Remove");
944 razor_transaction_destroy(trans);
945 razor_root_close(root);
946 razor_set_unref(next);
952 print_diff(enum razor_diff_action action,
953 struct razor_package *package,
959 if (action == RAZOR_DIFF_ACTION_ADD)
960 printf("install %s-%s.%s\n", name, version, arch);
961 if (action == RAZOR_DIFF_ACTION_REMOVE)
962 printf("remove %s-%s.%s\n", name, version, arch);
966 command_diff(int argc, char * const argv[])
968 struct razor_error *error = NULL;
969 struct razor_set *set, *updated;
971 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
978 if (argc - optind > 0) {
979 razor_usage(argv[0], 0, NULL, "");
983 set = razor_root_open_read_only(install_root, &error);
985 updated = razor_set_open(rawhide_repo_uri, 0, &error);
988 if (updated == NULL) {
989 fprintf(stderr, "%s\n", razor_error_get_msg(error));
990 razor_error_free(error);
992 razor_set_unref(set);
996 razor_set_diff(set, updated, print_diff, NULL);
998 razor_set_unref(set);
999 razor_set_unref(updated);
1005 command_import_rpms(int argc, char * const argv[])
1009 struct razor_importer *importer;
1010 struct razor_set *set;
1011 struct razor_rpm *rpm;
1012 struct razor_error *error=NULL;
1013 struct razor_atomic *atomic;
1014 int len, imported_count = 0;
1016 const char *dirname;
1019 switch (razor_getopt(argc, argv, 0, NULL, "dir", NULL)) {
1026 if (argc - optind != 1) {
1027 razor_usage(argv[0], 0, NULL, "dir");
1031 dirname = argv[optind];
1033 dir = opendir(dirname);
1035 fprintf(stderr, "couldn't read dir %s\n", dirname);
1039 importer = razor_importer_create();
1041 while (de = readdir(dir), de != NULL) {
1042 len = strlen(de->d_name);
1043 if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
1045 snprintf(filename, sizeof filename,
1046 "%s/%s", dirname, de->d_name);
1047 rpm = razor_rpm_open(filename, &error);
1049 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1050 razor_error_free(error);
1054 if (razor_importer_add_rpm(importer, rpm)) {
1055 fprintf(stderr, "couldn't import %s\n", filename);
1058 razor_rpm_close(rpm);
1060 printf("\rimporting %d", ++imported_count);
1065 razor_importer_destroy(importer);
1069 printf("\nsaving\n");
1070 set = razor_importer_finish(importer);
1072 atomic = razor_atomic_open("Update system database");
1073 razor_set_write(set, atomic, repo_filename, RAZOR_SECTION_ALL);
1074 razor_set_unref(set);
1075 retval = razor_atomic_commit(atomic);
1077 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1079 printf("wrote %s\n", repo_filename);
1080 razor_atomic_destroy(atomic);
1086 rpm_filename(const char *name, const char *version, const char *arch)
1091 v = strchr(version, ':');
1097 return razor_concat(name, "-", v, ".", arch, ".rpm", NULL);
1101 download_packages(struct razor_set *system, struct razor_set *next)
1103 struct razor_install_iterator *ii;
1104 struct razor_package *package;
1105 enum razor_install_action action;
1106 const char *name, *version, *arch;
1107 char *file, *url, *s;
1108 int errors = 0, count;
1110 ii = razor_set_create_install_iterator(system, next);
1111 while (razor_install_iterator_next(ii, &package, &action, &count)) {
1112 if (action != RAZOR_INSTALL_ACTION_ADD)
1115 razor_package_get_details(next, package,
1116 RAZOR_DETAIL_NAME, &name,
1117 RAZOR_DETAIL_VERSION, &version,
1118 RAZOR_DETAIL_ARCH, &arch,
1121 s = rpm_filename(name, version, arch);
1122 file = razor_concat("Packages/", s, NULL);
1123 url = razor_path_relative_to_uri(yum_url, file, NULL);
1125 file = razor_concat("rpms/", s, NULL);
1127 if (download_if_missing(url, file) < 0)
1132 razor_install_iterator_destroy(ii);
1135 fprintf(stderr, "failed to download %d packages\n", errors);
1142 static struct razor_set *
1143 relocate_packages(struct razor_set *set, struct razor_atomic *atomic,
1144 struct razor_relocations *relocations)
1147 struct razor_importer *importer;
1148 struct razor_property_iterator *prop_iter;
1149 struct razor_package_iterator *pkg_iter;
1150 struct razor_file_iterator *file_iter;
1151 struct razor_package *package;
1152 struct razor_property *property;
1153 struct razor_rpm *rpm;
1154 struct razor_error *error=NULL;
1155 const char *name, *version, *arch, *summary, *desc, *url, *license;
1156 const char *preunprog, *preun, *postunprog, *postun;
1157 const char *install_prefix;
1158 const char *const *prefixes;
1159 char *file, *s, *uri, *filename;
1162 importer = razor_importer_create();
1163 pkg_iter = razor_package_iterator_create(set);
1165 while (razor_package_iterator_next(pkg_iter, &package,
1166 RAZOR_DETAIL_NAME, &name,
1167 RAZOR_DETAIL_VERSION, &version,
1168 RAZOR_DETAIL_ARCH, &arch,
1169 RAZOR_DETAIL_SUMMARY, &summary,
1170 RAZOR_DETAIL_DESCRIPTION, &desc,
1171 RAZOR_DETAIL_URL, &url,
1172 RAZOR_DETAIL_LICENSE, &license,
1173 RAZOR_DETAIL_PREUNPROG, &preunprog,
1174 RAZOR_DETAIL_PREUN, &preun,
1175 RAZOR_DETAIL_POSTUNPROG, &postunprog,
1176 RAZOR_DETAIL_POSTUN, &postun,
1177 RAZOR_DETAIL_LAST)) {
1178 filename = rpm_filename(name, version, arch);
1179 s = razor_concat("Packages/", filename, NULL);
1180 uri = razor_path_relative_to_uri(yum_url, s, NULL);
1182 file = razor_concat("rpms/", filename, NULL);
1184 download_if_missing(uri, file);
1186 uri = razor_path_to_uri(file);
1188 rpm = razor_rpm_open(uri, &error);
1191 razor_atomic_propagate_error(atomic, error, NULL);
1192 razor_package_iterator_destroy(pkg_iter);
1193 razor_importer_destroy(importer);
1197 razor_relocations_set_rpm(relocations, rpm);
1199 razor_importer_begin_package(importer, name, version, arch);
1200 razor_importer_add_details(importer,
1201 summary, desc, url, license);
1203 razor_rpm_get_details(rpm, RAZOR_DETAIL_PREFIXES, &prefixes,
1205 for (i = 0; prefixes && prefixes[i]; i++) {
1206 install_prefix = razor_relocations_apply(relocations,
1208 razor_importer_add_install_prefix(importer,
1212 razor_rpm_close(rpm);
1214 prop_iter = razor_property_iterator_create(set, package);
1215 while (razor_property_iterator_next(prop_iter, &property,
1216 &name, &flags, &version))
1217 razor_importer_add_property(importer,
1218 name, flags, version);
1219 razor_property_iterator_destroy(prop_iter);
1221 file_iter = razor_file_iterator_create(set, package, 0);
1222 while (razor_file_iterator_next(file_iter, &name)) {
1223 name = razor_relocations_apply(relocations, name);
1224 razor_importer_add_file(importer, name);
1226 razor_file_iterator_destroy(file_iter);
1228 razor_importer_add_script(importer, RAZOR_PROPERTY_PREUN,
1230 razor_importer_add_script(importer, RAZOR_PROPERTY_POSTUN,
1231 postunprog, postun);
1233 razor_importer_finish_package(importer);
1236 razor_package_iterator_destroy(pkg_iter);
1237 return razor_importer_finish(importer);
1241 install_package(struct razor_transaction *trans, struct razor_set *set,
1242 struct razor_atomic *atomic, struct razor_package *package,
1243 struct razor_relocations *relocations, int install_count,
1244 enum razor_stage_type stage)
1247 const char *name, *version, *arch;
1248 char *file, *s, *uri;
1249 struct razor_rpm *rpm;
1250 struct razor_error *error=NULL;
1252 razor_package_get_details(set, package,
1253 RAZOR_DETAIL_NAME, &name,
1254 RAZOR_DETAIL_VERSION, &version,
1255 RAZOR_DETAIL_ARCH, &arch,
1258 if (stage & RAZOR_STAGE_SCRIPTS_PRE)
1259 printf("install %s-%s\n", name, version);
1261 s = rpm_filename(name, version, arch);
1262 file = razor_concat("rpms/", s, NULL);
1264 uri = razor_path_to_uri(file);
1266 rpm = razor_rpm_open(uri, &error);
1269 razor_atomic_propagate_error(atomic, error, NULL);
1270 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1274 razor_rpm_set_relocations(rpm, relocations);
1275 razor_transaction_fixup_package(trans, package, rpm);
1276 retval = razor_rpm_install(rpm, atomic, install_root, install_count,
1279 s = rpm_filename(name, version, arch);
1280 fprintf(stderr, "%s: %s\n", s,
1281 razor_atomic_get_error_msg(atomic));
1284 razor_rpm_close(rpm);
1289 * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT
1290 * is met (in which case the action is consumed).
1293 update_packages(struct razor_transaction *trans,
1294 struct razor_install_iterator *ii, struct razor_set *system,
1295 struct razor_set *next, struct razor_atomic *atomic,
1296 struct razor_relocations *relocations,
1297 enum razor_stage_type stage)
1299 struct razor_package *package;
1300 enum razor_install_action action;
1301 int retval = 0, count;
1303 while (!retval && razor_install_iterator_next(ii, &package, &action,
1305 if (action == RAZOR_INSTALL_ACTION_ADD) {
1306 if (install_package(trans, next, atomic, package,
1307 relocations, count, stage))
1309 } else if (action == RAZOR_INSTALL_ACTION_REMOVE) {
1310 if (razor_package_remove(system, next, atomic, package,
1311 install_root, count, stage))
1313 } else if (action == RAZOR_INSTALL_ACTION_COMMIT)
1321 update_system(struct razor_root *root, struct razor_relocations *relocations,
1322 struct razor_transaction *trans, struct razor_set *next,
1325 struct razor_set *system, *set;
1326 struct razor_atomic *atomic;
1327 struct razor_install_iterator *ii;
1332 description = razor_concat(verb, " packages", NULL);
1334 system = razor_set_ref(razor_root_get_system_set(root));
1336 ii = razor_set_create_install_iterator(system, next);
1339 pos = razor_install_iterator_tell(ii);
1341 atomic = razor_atomic_open(description);
1343 r = update_packages(trans, ii, system, next, atomic,
1344 relocations, RAZOR_STAGE_SCRIPTS_PRE);
1346 fprintf(stderr, "%s aborted\n", verb);
1349 razor_install_iterator_seek(ii, pos);
1350 r = update_packages(trans, ii, system, next, atomic,
1351 relocations, RAZOR_STAGE_FILES);
1354 set = razor_install_iterator_commit_set(ii);
1355 razor_root_update(root, set, atomic);
1356 razor_set_unref(set);
1358 razor_root_update(root, next, atomic);
1360 retval = razor_atomic_commit(atomic);
1362 fprintf(stderr, "%s\n",
1363 razor_atomic_get_error_msg(atomic));
1365 razor_install_iterator_seek(ii, pos);
1366 update_packages(trans, ii, system, next,
1367 atomic, relocations,
1368 RAZOR_STAGE_SCRIPTS_POST);
1372 razor_atomic_destroy(atomic);
1373 } while(!retval && r == 1);
1375 razor_install_iterator_destroy(ii);
1377 razor_set_unref(system);
1385 command_install_or_update(int argc, char * const argv[], int do_update)
1387 struct razor_relocations *relocations = NULL;
1388 struct razor_set *system, *upstream, *next, *set;
1389 struct razor_transaction *trans;
1390 struct razor_error *error = NULL;
1391 struct razor_atomic *atomic;
1392 struct razor_root *root;
1393 int opt, i, retval = 0, len, dependencies = 1;
1397 opt_no_dependencies = 1,
1400 static struct razor_option options[] = {
1401 { .name = "no-dependencies", .has_arg = no_argument,
1402 .val = opt_no_dependencies,
1403 .description = "Do not verify package dependencies" },
1404 { .name = "relocate", .has_arg = required_argument,
1405 .val = opt_relocate,
1406 .description = "Relocate files from path OLD to NEW",
1407 .arg_description = "OLD=NEW" },
1411 opt = razor_getopt(argc, argv, ARRAY_SIZE(options), options,
1418 case opt_no_dependencies:
1422 if (strchr(arg, '=') == NULL) {
1423 razor_usage(argv[0],
1424 ARRAY_SIZE(options),
1425 options, "rpm ...");
1428 len = strchr(arg, '=') - arg;
1429 oldpath = malloc(len + 1);
1430 strncpy(oldpath, arg, len);
1431 oldpath[len] = '\0';
1433 relocations = razor_relocations_create();
1434 razor_relocations_add(relocations, oldpath,
1441 upstream = razor_set_open(rawhide_repo_uri, 0, &error);
1442 if (upstream == NULL) {
1443 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1444 razor_error_free(error);
1446 razor_relocations_destroy(relocations);
1451 atomic = razor_atomic_open("Update packages");
1453 atomic = razor_atomic_open("Install packages");
1456 set = relocate_packages(upstream, atomic, relocations);
1458 fprintf(stderr, "%s\n",
1459 razor_atomic_get_error_msg(atomic));
1460 razor_atomic_destroy(atomic);
1461 razor_set_unref(upstream);
1464 razor_set_unref(upstream);
1468 root = razor_root_open(install_root, &error);
1470 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1471 razor_error_free(error);
1472 razor_atomic_destroy(atomic);
1473 razor_set_unref(upstream);
1475 razor_relocations_destroy(relocations);
1479 system = razor_root_get_system_set(root);
1480 trans = razor_transaction_create(system, upstream);
1482 if (optind == argc && do_update)
1483 razor_transaction_update_all(trans);
1484 for (i = optind; i < argc; i++) {
1486 mark_packages_for_update(trans, system, argv[i]))
1488 if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
1489 fprintf(stderr, "no package matched %s\n", argv[i]);
1490 razor_transaction_destroy(trans);
1491 razor_root_close(root);
1492 razor_set_unref(upstream);
1493 razor_atomic_destroy(atomic);
1495 razor_relocations_destroy(relocations);
1501 razor_transaction_resolve(trans);
1502 if (razor_transaction_describe(trans) > 0) {
1503 razor_transaction_destroy(trans);
1504 razor_set_unref(upstream);
1505 razor_root_close(root);
1506 razor_atomic_destroy(atomic);
1508 razor_relocations_destroy(relocations);
1513 if (razor_atomic_create_dir(atomic, "file:rpms",
1514 S_IRWXU | S_IRWXG | S_IRWXO) ||
1515 razor_atomic_commit(atomic)) {
1516 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1517 razor_transaction_destroy(trans);
1518 razor_set_unref(upstream);
1519 razor_root_close(root);
1520 razor_atomic_destroy(atomic);
1522 razor_relocations_destroy(relocations);
1526 razor_atomic_destroy(atomic);
1528 next = razor_transaction_commit(trans);
1530 if (download_packages(system, next) < 0) {
1531 razor_set_unref(next);
1532 razor_transaction_destroy(trans);
1533 razor_set_unref(upstream);
1534 razor_root_close(root);
1536 razor_relocations_destroy(relocations);
1540 retval = update_system(root, relocations, trans, next,
1541 do_update ? "Update" : "Install");
1543 razor_set_unref(upstream);
1544 razor_root_close(root);
1546 razor_transaction_destroy(trans);
1548 razor_relocations_destroy(relocations);
1550 razor_set_unref(next);
1556 command_update(int argc, char * const argv[])
1558 return command_install_or_update(argc, argv, 1);
1562 command_install(int argc, char * const argv[])
1564 return command_install_or_update(argc, argv, 0);
1568 command_init(int argc, char * const argv[])
1571 struct razor_error *error = NULL;
1573 switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
1580 if (argc - optind > 0) {
1581 razor_usage(argv[0], 0, NULL, "");
1585 retval = razor_root_create(install_root, &error);
1587 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1588 razor_error_free(error);
1590 printf("Created install root\n");
1596 command_download(int argc, char * const argv[])
1598 struct razor_error *error = NULL;
1599 struct razor_atomic *atomic;
1600 struct razor_set *set;
1601 struct razor_package_iterator *pi;
1602 struct razor_package *package;
1603 const char *pattern, *name, *version, *arch;
1604 char *url, *file, *s, filename[256];
1607 switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
1614 if (argc - optind > 1) {
1615 razor_usage(argv[0], 0, NULL, "[pattern]");
1619 pattern = argv[optind];
1621 set = razor_set_open(rawhide_repo_uri, 0, &error);
1623 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1624 razor_error_free(error);
1628 atomic = razor_atomic_open("Download packages");
1630 if (razor_atomic_create_dir(atomic, "file:rpms",
1631 S_IRWXU | S_IRWXG | S_IRWXO)) {
1632 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1633 razor_atomic_destroy(atomic);
1637 if (razor_atomic_commit(atomic)) {
1638 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1639 razor_atomic_destroy(atomic);
1642 razor_atomic_destroy(atomic);
1644 pi = razor_package_iterator_create(set);
1645 while (razor_package_iterator_next(pi, &package,
1646 RAZOR_DETAIL_NAME, &name,
1647 RAZOR_DETAIL_VERSION, &version,
1648 RAZOR_DETAIL_ARCH, &arch,
1649 RAZOR_DETAIL_LAST)) {
1650 if (pattern && fnmatch(pattern, name, 0) != 0)
1654 snprintf(filename, sizeof filename,
1655 "%s-%s.%s.rpm", name, version, arch);
1656 s = razor_concat("Packages/", filename, NULL);
1657 url = razor_path_relative_to_uri(yum_url, s, NULL);
1659 file = razor_concat("rpms/", filename, NULL);
1660 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 struct razor_string_iterator *si;
1714 const char *pattern, *name, *version, *arch;
1715 const char *summary, *description, *url, *license;
1718 switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
1725 if (argc - optind > 1) {
1726 razor_usage(argv[0], 0, NULL, "[pattern]");
1730 pattern = argv[optind];
1732 set = razor_root_open_read_only(install_root, &error);
1734 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1735 razor_error_free(error);
1739 pi = razor_package_iterator_create(set);
1740 while (razor_package_iterator_next(pi, &package,
1741 RAZOR_DETAIL_NAME, &name,
1742 RAZOR_DETAIL_VERSION, &version,
1743 RAZOR_DETAIL_ARCH, &arch,
1744 RAZOR_DETAIL_LAST)) {
1745 if (pattern && fnmatch(pattern, name, 0) != 0)
1748 printf ("Name: %s\n", name);
1749 printf ("Arch: %s\n", arch);
1750 printf ("Version: %s\n", version);
1752 si = razor_install_prefix_iterator_create(set, package);
1753 if (razor_string_iterator_next(si, &prefix)) {
1754 printf ("Relocations: %s\n", prefix);
1755 while (razor_string_iterator_next(si, &prefix))
1756 printf (" : %s\n", prefix);
1758 razor_string_iterator_destroy(si);
1760 razor_package_get_details (set, package,
1761 RAZOR_DETAIL_SUMMARY, &summary,
1762 RAZOR_DETAIL_DESCRIPTION, &description,
1763 RAZOR_DETAIL_URL, &url,
1764 RAZOR_DETAIL_LICENSE, &license,
1767 printf ("URL: %s\n", url);
1768 printf ("License: %s\n", license);
1769 printf ("Summary: %s\n", summary);
1770 printf ("Description:\n");
1771 printf ("%s\n", description);
1774 razor_package_iterator_destroy(pi);
1775 razor_set_unref(set);
1780 #define SEARCH_MAX 256
1783 command_search(int argc, char * const argv[])
1785 struct razor_error *error = NULL;
1786 struct razor_set *set;
1787 struct razor_package_iterator *pi;
1788 struct razor_package *package;
1789 char pattern[SEARCH_MAX];
1790 const char *name, *version, *arch;
1791 const char *summary, *description, *url, *license;
1793 switch (razor_getopt(argc, argv, 0, NULL, "pattern", NULL)) {
1801 razor_usage(argv[0], 0, NULL, "pattern");
1805 snprintf(pattern, sizeof pattern, "*%s*", argv[1]);
1807 set = razor_set_open(rawhide_repo_uri, 0, &error);
1809 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1810 razor_error_free(error);
1814 pi = razor_package_iterator_create(set);
1815 while (razor_package_iterator_next(pi, &package,
1816 RAZOR_DETAIL_NAME, &name,
1817 RAZOR_DETAIL_VERSION, &version,
1818 RAZOR_DETAIL_ARCH, &arch,
1819 RAZOR_DETAIL_SUMMARY, &summary,
1820 RAZOR_DETAIL_DESCRIPTION, &description,
1821 RAZOR_DETAIL_URL, &url,
1822 RAZOR_DETAIL_LICENSE, &license,
1823 RAZOR_DETAIL_LAST)) {
1824 if (!fnmatch(pattern, name, FNM_CASEFOLD) ||
1825 !fnmatch(pattern, url, FNM_CASEFOLD) ||
1826 !fnmatch(pattern, summary, FNM_CASEFOLD) ||
1827 !fnmatch(pattern, description, FNM_CASEFOLD))
1828 printf("%s-%s.%s: %s\n", name, version, arch, summary);
1830 razor_package_iterator_destroy(pi);
1831 razor_set_unref(set);
1838 const char *description;
1839 int (*func)(int argc, char * const argv[]);
1840 } razor_commands[] = {
1841 { "diff", "Show diff between two package sets", command_diff },
1842 { "download", "Download packages", command_download },
1843 { "dump", "Low-level database dump (for debugging)", command_dump },
1844 { "help", "List available commands", command_help },
1846 { "import-rpmdb", "Import the system rpm database",
1847 command_import_rpmdb },
1849 { "import-rpms", "Import rpms from the given directory",
1850 command_import_rpms },
1851 { "import-yum", "Import yum metadata files", command_import_yum },
1852 { "info", "Display package details", command_info },
1853 { "init", "Init razor root", command_init },
1854 { "install", "Install rpm", command_install },
1855 { "list", "List all packages", command_list },
1856 { "list-conflicts", "List all conflicts for the given package",
1857 command_list_conflicts },
1858 { "list-file-packages", "List packages owning file",
1859 command_list_file_packages },
1860 { "list-files", "List files for package set", command_list_files },
1861 { "list-obsoletes", "List all obsoletes for the given package",
1862 command_list_obsoletes },
1863 { "list-package-files", "List files in package",
1864 command_list_package_files },
1865 { "list-provides", "List all provides for the given package",
1866 command_list_provides },
1867 { "list-requires", "List all requires for the given package",
1868 command_list_requires },
1869 { "list-scripts", "List all scripts for the given package",
1870 command_list_scripts },
1871 { "remove", "Remove specified packages", command_remove },
1872 { "search", "Search package details", command_search },
1873 { "update", "Update all or specified packages", command_update },
1874 { "what-provides", "List the packages that have the given provides",
1875 command_what_provides },
1876 { "what-requires", "List the packages that have the given requires",
1877 command_what_requires },
1881 command_help(int argc, char * const argv[])
1885 printf("Available commands:\n");
1886 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1887 printf(" %-20s%s\n",
1888 razor_commands[i].name, razor_commands[i].description);
1889 printf("\nType \"razor --help\" for help about global options\n"
1890 "or \"razor <command> --help\" for help about a particular "
1891 "command's options.\n");
1897 main(int argc, char *argv[])
1900 int i, opt, main_optind;
1901 int do_help_commands = 0;
1909 struct option options[] = {
1910 { .name = "database", .has_arg = required_argument,
1911 .val = opt_database },
1912 { .name = "help", .has_arg = no_argument, .val = opt_help },
1913 { .name = "help-commands", .has_arg = no_argument,
1914 .flag = &do_help_commands, .val = TRUE },
1915 { .name = "root", .has_arg = required_argument,
1917 { .name = "url", .has_arg = required_argument, .val = opt_url },
1921 repo = getenv("RAZOR_REPO");
1923 repo_filename = repo;
1925 root = getenv("RAZOR_ROOT");
1927 install_root = root;
1929 yum_url = getenv("YUM_URL");
1930 if (yum_url == NULL)
1933 if (getenv("RAZOR_NO_ROOT_NAME_CHECKS"))
1934 razor_disable_root_name_checks(1);
1939 while ((opt = getopt_long(argc, argv, "+", options, NULL)) != -1) {
1942 razor_set_database_uri(optarg);
1946 printf("Usage: razor [global-options] command "
1947 "[command-options-and-arguments]\n\n");
1948 printf("Options:\n");
1950 "Show this help message and exit\n");
1951 printf(" --help-commands List commands\n");
1952 printf(" --database=URI "
1953 "Use alternative database\n");
1954 printf(" --root=URI "
1955 "Use URI as top level directory\n");
1956 printf(" --url=URI "
1957 "Use URI as upstream repository\n");
1958 return opt != opt_help;
1960 install_root = optarg;
1970 main_optind = optind;
1973 if (do_help_commands || argc - main_optind < 1) {
1974 command_help(argc - main_optind, argv + main_optind);
1978 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1979 if (strcmp(razor_commands[i].name, argv[main_optind]) == 0)
1980 return razor_commands[i].func(argc - main_optind,
1981 argv + main_optind);
1983 command_help(argc - main_optind, argv + main_optind);