2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009, 2011-2012 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>
42 static const char system_repo_filename[] = "system.rzdb";
43 static const char next_repo_filename[] = "system-next.rzdb";
44 static const char rawhide_repo_filename[] = "rawhide.rzdb";
45 static const char *install_root = "";
46 static const char *repo_filename = system_repo_filename;
47 static const char *yum_url;
49 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
52 update_packages(struct razor_transaction *trans,
53 struct razor_install_iterator *ii, struct razor_set *system,
54 struct razor_set *next, struct razor_atomic *atomic,
55 struct razor_relocations *relocations,
56 enum razor_stage_type stage);
58 update_system(struct razor_root *root, struct razor_relocations *relocations,
59 struct razor_transaction *trans, struct razor_set *next,
62 static struct razor_package_iterator *
63 create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[])
65 struct razor_package_query *query;
66 struct razor_package_iterator *iter;
67 struct razor_package *package;
68 const char *name, *pattern;
72 return razor_package_iterator_create(set);
74 query = razor_package_query_create(set);
76 for (i = 0; i < argc; i++) {
77 iter = razor_package_iterator_create(set);
80 while (razor_package_iterator_next(iter, &package,
81 RAZOR_DETAIL_NAME, &name,
83 if (fnmatch(pattern, name, 0) != 0)
86 razor_package_query_add_package(query, package);
89 razor_package_iterator_destroy(iter);
93 "no package matches \"%s\"\n", pattern);
96 return razor_package_query_finish(query);
99 #define LIST_PACKAGES_ONLY_NAMES 0x01
102 list_packages(struct razor_package_iterator *iter, uint32_t flags)
104 struct razor_package *package;
105 const char *name, *version, *arch;
107 while (razor_package_iterator_next(iter, &package,
108 RAZOR_DETAIL_NAME, &name,
109 RAZOR_DETAIL_VERSION, &version,
110 RAZOR_DETAIL_ARCH, &arch,
111 RAZOR_DETAIL_LAST)) {
112 if (flags & LIST_PACKAGES_ONLY_NAMES)
113 printf("%s\n", name);
115 printf("%s-%s.%s\n", name, version, arch);
120 command_list(int argc, const char *argv[])
122 struct razor_package_iterator *pi;
123 struct razor_error *error = NULL;
124 struct razor_set *set;
128 if (i < argc && strcmp(argv[i], "--only-names") == 0) {
129 flags |= LIST_PACKAGES_ONLY_NAMES;
133 set = razor_root_open_read_only(install_root, &error);
135 fprintf(stderr, "%s\n", razor_error_get_msg(error));
136 razor_error_free(error);
140 pi = create_iterator_from_argv(set, argc - i, argv + i);
141 list_packages(pi, flags);
142 razor_package_iterator_destroy(pi);
143 razor_set_unref(set);
149 list_package_properties(struct razor_set *set,
150 struct razor_package *package, uint32_t type)
152 struct razor_property_iterator *pi;
153 struct razor_property *property;
154 const char *name, *version;
157 pi = razor_property_iterator_create(set, package);
158 while (razor_property_iterator_next(pi, &property,
159 &name, &flags, &version)) {
160 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
163 if (version[0] != '\0')
165 razor_property_relation_to_string(property),
168 if (flags & ~(RAZOR_PROPERTY_RELATION_MASK | RAZOR_PROPERTY_TYPE_MASK)) {
170 if (flags & RAZOR_PROPERTY_PRE)
172 if (flags & RAZOR_PROPERTY_POST)
174 if (flags & RAZOR_PROPERTY_PREUN)
176 if (flags & RAZOR_PROPERTY_POSTUN)
182 razor_property_iterator_destroy(pi);
186 list_properties(int argc, const char *argv[], uint32_t type)
188 struct razor_set *set;
189 struct razor_error *error = NULL;
190 struct razor_package *package;
191 struct razor_package_iterator *pi;
192 const char *name, *version, *arch;
194 set = razor_root_open_read_only(install_root, &error);
196 fprintf(stderr, "%s\n", razor_error_get_msg(error));
197 razor_error_free(error);
201 pi = create_iterator_from_argv(set, argc, argv);
202 while (razor_package_iterator_next(pi, &package,
203 RAZOR_DETAIL_NAME, &name,
204 RAZOR_DETAIL_VERSION, &version,
205 RAZOR_DETAIL_ARCH, &arch,
207 list_package_properties(set, package, type);
208 razor_package_iterator_destroy(pi);
209 razor_set_unref(set);
215 command_list_requires(int argc, const char *argv[])
217 return list_properties(argc, argv, RAZOR_PROPERTY_REQUIRES);
221 command_list_provides(int argc, const char *argv[])
223 return list_properties(argc, argv, RAZOR_PROPERTY_PROVIDES);
227 command_list_obsoletes(int argc, const char *argv[])
229 return list_properties(argc, argv, RAZOR_PROPERTY_OBSOLETES);
233 command_list_conflicts(int argc, const char *argv[])
235 return list_properties(argc, argv, RAZOR_PROPERTY_CONFLICTS);
239 command_list_scripts(int argc, const char *argv[])
241 struct razor_set *set;
242 struct razor_error *error = NULL;
243 struct razor_package *package;
244 struct razor_package_iterator *pi;
245 const char *preunprog, *preun, *postunprog, *postun;
247 set = razor_root_open_read_only(install_root, &error);
249 fprintf(stderr, "%s\n", razor_error_get_msg(error));
250 razor_error_free(error);
254 pi = create_iterator_from_argv(set, argc, argv);
255 while (razor_package_iterator_next(pi, &package,
256 RAZOR_DETAIL_PREUNPROG, &preunprog,
257 RAZOR_DETAIL_PREUN, &preun,
258 RAZOR_DETAIL_POSTUNPROG, &postunprog,
259 RAZOR_DETAIL_POSTUN, &postun,
260 RAZOR_DETAIL_LAST)) {
261 if (preun && *preun) {
262 printf("preuninstall scriptlet");
263 if (preunprog && *preunprog)
264 printf(" (using %s)",preunprog);
265 printf(":\n%s\n",preun);
267 if (postun && *postun) {
268 printf("postuninstall scriptlet");
269 if (postunprog && *postunprog)
270 printf(" (using %s)",postunprog);
271 printf(":\n%s\n",postun);
274 razor_package_iterator_destroy(pi);
275 razor_set_unref(set);
281 command_list_files(int argc, const char *argv[])
283 struct razor_error *error = NULL;
284 struct razor_set *set;
286 set = razor_root_open_read_only(install_root, &error);
288 fprintf(stderr, "%s\n", razor_error_get_msg(error));
289 razor_error_free(error);
293 razor_set_list_files(set, argv[0]);
294 razor_set_unref(set);
300 command_list_file_packages(int argc, const char *argv[])
302 struct razor_error *error = NULL;
303 struct razor_set *set;
304 struct razor_package_iterator *pi;
306 set = razor_root_open_read_only(install_root, &error);
308 fprintf(stderr, "%s\n", razor_error_get_msg(error));
309 razor_error_free(error);
313 pi = razor_package_iterator_create_for_file(set, argv[0]);
314 list_packages(pi, 0);
315 razor_package_iterator_destroy(pi);
317 razor_set_unref(set);
323 command_list_package_files(int argc, const char *argv[])
325 struct razor_error *error = NULL;
326 struct razor_set *set;
327 struct razor_package_iterator *pi;
328 struct razor_package *package;
329 const char *name, *version, *arch;
331 set = razor_root_open_read_only(install_root, &error);
333 fprintf(stderr, "%s\n", razor_error_get_msg(error));
334 razor_error_free(error);
338 pi = create_iterator_from_argv(set, argc, argv);
339 while (razor_package_iterator_next(pi, &package,
340 RAZOR_DETAIL_NAME, &name,
341 RAZOR_DETAIL_VERSION, &version,
342 RAZOR_DETAIL_ARCH, &arch,
344 razor_set_list_package_files(set, package);
345 razor_package_iterator_destroy(pi);
347 razor_set_unref(set);
353 list_property_packages(const char *ref_name,
354 const char *ref_version,
357 struct razor_error *error = NULL;
358 struct razor_set *set;
359 struct razor_property *property;
360 struct razor_property_iterator *prop_iter;
361 struct razor_package_iterator *pkg_iter;
362 const char *name, *version;
365 if (ref_name == NULL)
368 set = razor_root_open_read_only(install_root, &error);
370 fprintf(stderr, "%s\n", razor_error_get_msg(error));
371 razor_error_free(error);
375 prop_iter = razor_property_iterator_create(set, NULL);
376 while (razor_property_iterator_next(prop_iter, &property,
377 &name, &flags, &version)) {
378 if (strcmp(ref_name, name) != 0)
381 (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
382 strcmp(ref_version, version) != 0)
384 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
388 razor_package_iterator_create_for_property(set,
390 list_packages(pkg_iter, 0);
391 razor_package_iterator_destroy(pkg_iter);
393 razor_property_iterator_destroy(prop_iter);
395 razor_set_unref(set);
401 command_what_requires(int argc, const char *argv[])
403 return list_property_packages(argv[0], argv[1],
404 RAZOR_PROPERTY_REQUIRES);
408 command_what_provides(int argc, const char *argv[])
410 return list_property_packages(argv[0], argv[1],
411 RAZOR_PROPERTY_PROVIDES);
416 show_progress(void *clientp,
417 double dltotal, double dlnow, double ultotal, double ulnow)
419 const char *file = clientp;
421 if (!dlnow < dltotal)
422 fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
423 file, (int) dlnow / 1024, (int) dltotal / 1024);
427 #endif /* HAVE_CURL */
430 download_if_missing(const char *url, const char *file)
442 curl = curl_easy_init();
446 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
447 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
448 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
449 curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
451 if (stat(file, &buf) < 0) {
452 fp = fopen(file, "wb");
455 "failed to open %s for writing\n", file);
458 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
459 curl_easy_setopt(curl, CURLOPT_URL, url);
460 res = curl_easy_perform(curl);
462 if (res != CURLE_OK) {
463 fprintf(stderr, "curl error: %s\n", error);
467 res = curl_easy_getinfo(curl,
468 CURLINFO_RESPONSE_CODE, &response);
469 if (res != CURLE_OK) {
470 fprintf(stderr, "curl error: %s\n", error);
474 if (response != 200) {
475 fprintf(stderr, " - failed %ld\n", response);
479 fprintf(stderr, "\n");
482 curl_easy_cleanup(curl);
485 #endif /* HAVE_CURL */
488 #define YUM_URL "http://download.fedora.redhat.com" \
489 "/pub/fedora/linux/development/i386/os"
492 command_import_yum(int argc, const char *argv[])
495 struct razor_set *set;
496 struct razor_atomic *atomic;
499 printf("downloading from %s.\n", yum_url);
500 snprintf(buffer, sizeof buffer,
501 "%s/repodata/primary.xml.gz", yum_url);
502 if (download_if_missing(buffer, "primary.xml.gz") < 0)
504 snprintf(buffer, sizeof buffer,
505 "%s/repodata/filelists.xml.gz", yum_url);
506 if (download_if_missing(buffer, "filelists.xml.gz") < 0)
509 set = razor_set_create_from_yum();
512 atomic = razor_atomic_open("Yum import repository");
513 razor_set_write(set, atomic, rawhide_repo_filename, RAZOR_SECTION_ALL);
514 retval = razor_atomic_commit(atomic);
515 razor_set_unref(set);
517 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
519 printf("wrote %s\n", rawhide_repo_filename);
520 razor_atomic_destroy(atomic);
527 command_import_rpmdb(int argc, const char *argv[])
529 struct razor_set *set;
530 struct razor_root *root;
531 struct razor_error *error = NULL;
532 struct razor_atomic *atomic;
535 root = razor_root_open(install_root, &error);
537 fprintf(stderr, "%s\n", razor_error_get_msg(error));
538 razor_error_free(error);
542 set = razor_set_create_from_rpmdb();
546 atomic = razor_atomic_open("Import RPM database");
548 retval = razor_root_update(root, set, atomic);
551 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
553 razor_atomic_destroy(atomic);
555 razor_root_close(root);
562 mark_packages_for_update(struct razor_transaction *trans,
563 struct razor_set *set, const char *pattern)
565 struct razor_package_iterator *pi;
566 struct razor_package *package;
570 pi = razor_package_iterator_create(set);
571 while (razor_package_iterator_next(pi, &package,
572 RAZOR_DETAIL_NAME, &name,
573 RAZOR_DETAIL_LAST)) {
574 if (pattern && fnmatch(pattern, name, 0) == 0) {
575 razor_transaction_update_package(trans, package);
579 razor_package_iterator_destroy(pi);
585 mark_packages_for_removal(struct razor_transaction *trans,
586 struct razor_set *set, const char *pattern)
588 struct razor_package_iterator *pi;
589 struct razor_package *package;
593 pi = razor_package_iterator_create(set);
594 while (razor_package_iterator_next(pi, &package,
595 RAZOR_DETAIL_NAME, &name,
596 RAZOR_DETAIL_LAST)) {
597 if (pattern && fnmatch(pattern, name, 0) == 0) {
598 razor_transaction_remove_package(trans, package);
602 razor_package_iterator_destroy(pi);
608 command_remove(int argc, const char *argv[])
610 struct razor_set *system, *upstream, *next;
611 struct razor_transaction *trans;
612 struct razor_error *error = NULL;
613 struct razor_root *root;
616 root = razor_root_open(install_root, &error);
618 fprintf(stderr, "%s\n", razor_error_get_msg(error));
619 razor_error_free(error);
623 system = razor_root_get_system_set(root);
624 upstream = razor_set_create_without_root();
625 trans = razor_transaction_create(system, upstream);
626 razor_set_unref(upstream);
627 for (i = 0; i < argc; i++) {
628 if (mark_packages_for_removal(trans, system, argv[i]) == 0) {
629 fprintf(stderr, "no match for %s\n", argv[i]);
630 razor_transaction_destroy(trans);
631 razor_root_close(root);
636 razor_transaction_resolve(trans);
637 retval = razor_transaction_describe(trans);
639 razor_transaction_destroy(trans);
640 razor_root_close(root);
644 next = razor_transaction_commit(trans);
646 retval = update_system(root, NULL, trans, next, "Remove");
648 razor_transaction_destroy(trans);
649 razor_root_close(root);
650 razor_set_unref(next);
656 print_diff(enum razor_diff_action action,
657 struct razor_package *package,
663 if (action == RAZOR_DIFF_ACTION_ADD)
664 printf("install %s-%s.%s\n", name, version, arch);
665 if (action == RAZOR_DIFF_ACTION_REMOVE)
666 printf("remove %s-%s.%s\n", name, version, arch);
670 command_diff(int argc, const char *argv[])
672 struct razor_error *error = NULL;
673 struct razor_set *set, *updated;
675 set = razor_root_open_read_only(install_root, &error);
677 updated = razor_set_open(rawhide_repo_filename, 0, &error);
680 if (updated == NULL) {
681 fprintf(stderr, "%s\n", razor_error_get_msg(error));
682 razor_error_free(error);
684 razor_set_unref(set);
688 razor_set_diff(set, updated, print_diff, NULL);
690 razor_set_unref(set);
691 razor_set_unref(updated);
697 command_import_rpms(int argc, const char *argv[])
701 struct razor_importer *importer;
702 struct razor_set *set;
703 struct razor_rpm *rpm;
704 struct razor_error *error=NULL;
705 struct razor_atomic *atomic;
706 int len, imported_count = 0;
708 const char *dirname = argv[0];
711 if (dirname == NULL) {
712 fprintf(stderr, "usage: razor import-rpms DIR\n");
716 dir = opendir(dirname);
718 fprintf(stderr, "couldn't read dir %s\n", dirname);
722 importer = razor_importer_create();
724 while (de = readdir(dir), de != NULL) {
725 len = strlen(de->d_name);
726 if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
728 snprintf(filename, sizeof filename,
729 "%s/%s", dirname, de->d_name);
730 rpm = razor_rpm_open(filename, &error);
732 fprintf(stderr, "%s\n", razor_error_get_msg(error));
733 razor_error_free(error);
737 if (razor_importer_add_rpm(importer, rpm)) {
738 fprintf(stderr, "couldn't import %s\n", filename);
741 razor_rpm_close(rpm);
743 printf("\rimporting %d", ++imported_count);
748 razor_importer_destroy(importer);
752 printf("\nsaving\n");
753 set = razor_importer_finish(importer);
755 atomic = razor_atomic_open("Update system database");
756 razor_set_write(set, atomic, repo_filename, RAZOR_SECTION_ALL);
757 razor_set_unref(set);
758 retval = razor_atomic_commit(atomic);
760 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
762 printf("wrote %s\n", repo_filename);
763 razor_atomic_destroy(atomic);
769 rpm_filename(const char *name, const char *version, const char *arch)
774 v = strchr(version, ':');
780 return razor_concat(name, "-", v, ".", arch, ".rpm", NULL);
784 download_packages(struct razor_set *system, struct razor_set *next)
786 struct razor_install_iterator *ii;
787 struct razor_package *package;
788 enum razor_install_action action;
789 const char *name, *version, *arch;
790 char *file, *url, *s;
791 int errors = 0, count;
793 ii = razor_set_create_install_iterator(system, next);
794 while (razor_install_iterator_next(ii, &package, &action, &count)) {
795 if (action != RAZOR_INSTALL_ACTION_ADD)
798 razor_package_get_details(next, package,
799 RAZOR_DETAIL_NAME, &name,
800 RAZOR_DETAIL_VERSION, &version,
801 RAZOR_DETAIL_ARCH, &arch,
804 s = rpm_filename(name, version, arch);
805 url = razor_concat(yum_url, "/Packages/", s, NULL);
806 file = razor_concat("rpms/", s, NULL);
808 if (download_if_missing(url, file) < 0)
813 razor_install_iterator_destroy(ii);
816 fprintf(stderr, "failed to download %d packages\n", errors);
823 static struct razor_set *
824 relocate_packages(struct razor_set *set, struct razor_atomic *atomic,
825 struct razor_relocations *relocations)
828 struct razor_importer *importer;
829 struct razor_property_iterator *prop_iter;
830 struct razor_package_iterator *pkg_iter;
831 struct razor_file_iterator *file_iter;
832 struct razor_package *package;
833 struct razor_property *property;
834 struct razor_rpm *rpm;
835 struct razor_error *error=NULL;
836 const char *name, *version, *arch, *summary, *desc, *url, *license;
837 const char *preunprog, *preun, *postunprog, *postun;
838 const char *install_prefix;
839 const char *const *prefixes;
843 importer = razor_importer_create();
844 pkg_iter = razor_package_iterator_create(set);
846 while (razor_package_iterator_next(pkg_iter, &package,
847 RAZOR_DETAIL_NAME, &name,
848 RAZOR_DETAIL_VERSION, &version,
849 RAZOR_DETAIL_ARCH, &arch,
850 RAZOR_DETAIL_SUMMARY, &summary,
851 RAZOR_DETAIL_DESCRIPTION, &desc,
852 RAZOR_DETAIL_URL, &url,
853 RAZOR_DETAIL_LICENSE, &license,
854 RAZOR_DETAIL_PREUNPROG, &preunprog,
855 RAZOR_DETAIL_PREUN, &preun,
856 RAZOR_DETAIL_POSTUNPROG, &postunprog,
857 RAZOR_DETAIL_POSTUN, &postun,
858 RAZOR_DETAIL_LAST)) {
859 s = rpm_filename(name, version, arch);
860 file = razor_concat("rpms/", s, NULL);
862 rpm = razor_rpm_open(file, &error);
865 razor_atomic_abort(atomic, razor_error_get_msg(error));
866 razor_error_free(error);
867 razor_package_iterator_destroy(pkg_iter);
868 razor_importer_destroy(importer);
872 razor_relocations_set_rpm(relocations, rpm);
874 razor_importer_begin_package(importer, name, version, arch);
875 razor_importer_add_details(importer,
876 summary, desc, url, license);
878 razor_rpm_get_details(rpm, RAZOR_DETAIL_PREFIXES, &prefixes,
880 for (i = 0; prefixes && prefixes[i]; i++) {
881 install_prefix = razor_relocations_apply(relocations,
883 razor_importer_add_install_prefix(importer,
887 razor_rpm_close(rpm);
889 prop_iter = razor_property_iterator_create(set, package);
890 while (razor_property_iterator_next(prop_iter, &property,
891 &name, &flags, &version))
892 razor_importer_add_property(importer,
893 name, flags, version);
894 razor_property_iterator_destroy(prop_iter);
896 file_iter = razor_file_iterator_create(set, package, 0);
897 while (razor_file_iterator_next(file_iter, &name)) {
898 name = razor_relocations_apply(relocations, name);
899 razor_importer_add_file(importer, name);
901 razor_file_iterator_destroy(file_iter);
903 razor_importer_add_script(importer, RAZOR_PROPERTY_PREUN,
905 razor_importer_add_script(importer, RAZOR_PROPERTY_POSTUN,
908 razor_importer_finish_package(importer);
911 razor_package_iterator_destroy(pkg_iter);
912 return razor_importer_finish(importer);
916 install_package(struct razor_transaction *trans, struct razor_set *set,
917 struct razor_atomic *atomic, struct razor_package *package,
918 struct razor_relocations *relocations, int install_count,
919 enum razor_stage_type stage)
922 const char *name, *version, *arch;
924 struct razor_rpm *rpm;
925 struct razor_error *error=NULL;
927 razor_package_get_details(set, package,
928 RAZOR_DETAIL_NAME, &name,
929 RAZOR_DETAIL_VERSION, &version,
930 RAZOR_DETAIL_ARCH, &arch,
933 if (stage & RAZOR_STAGE_SCRIPTS_PRE)
934 printf("install %s-%s\n", name, version);
936 s = rpm_filename(name, version, arch);
937 file = razor_concat("rpms/", s, NULL);
939 rpm = razor_rpm_open(file, &error);
942 razor_atomic_abort(atomic, razor_error_get_msg(error));
943 fprintf(stderr, "%s\n", razor_error_get_msg(error));
944 razor_error_free(error);
948 razor_rpm_set_relocations(rpm, relocations);
949 razor_transaction_fixup_package(trans, package, rpm);
950 retval = razor_rpm_install(rpm, atomic, install_root, install_count,
953 s = rpm_filename(name, version, arch);
954 fprintf(stderr, "%s: %s\n", s,
955 razor_atomic_get_error_msg(atomic));
958 razor_rpm_close(rpm);
963 * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT
964 * is met (in which case the action is consumed).
967 update_packages(struct razor_transaction *trans,
968 struct razor_install_iterator *ii, struct razor_set *system,
969 struct razor_set *next, struct razor_atomic *atomic,
970 struct razor_relocations *relocations,
971 enum razor_stage_type stage)
973 struct razor_package *package;
974 enum razor_install_action action;
975 int retval = 0, count;
977 while (!retval && razor_install_iterator_next(ii, &package, &action,
979 if (action == RAZOR_INSTALL_ACTION_ADD) {
980 if (install_package(trans, next, atomic, package,
981 relocations, count, stage))
983 } else if (action == RAZOR_INSTALL_ACTION_REMOVE) {
984 if (razor_package_remove(system, next, atomic, package,
985 install_root, count, stage))
987 } else if (action == RAZOR_INSTALL_ACTION_COMMIT)
995 update_system(struct razor_root *root, struct razor_relocations *relocations,
996 struct razor_transaction *trans, struct razor_set *next,
999 struct razor_set *system, *set;
1000 struct razor_atomic *atomic;
1001 struct razor_install_iterator *ii;
1006 description = razor_concat(verb, " packages", NULL);
1008 system = razor_set_ref(razor_root_get_system_set(root));
1010 ii = razor_set_create_install_iterator(system, next);
1013 pos = razor_install_iterator_tell(ii);
1015 atomic = razor_atomic_open(description);
1017 r = update_packages(trans, ii, system, next, atomic,
1018 relocations, RAZOR_STAGE_SCRIPTS_PRE);
1020 fprintf(stderr, "%s aborted\n", verb);
1023 razor_install_iterator_seek(ii, pos);
1024 r = update_packages(trans, ii, system, next, atomic,
1025 relocations, RAZOR_STAGE_FILES);
1028 set = razor_install_iterator_commit_set(ii);
1029 razor_root_update(root, set, atomic);
1030 razor_set_unref(set);
1032 razor_root_update(root, next, atomic);
1034 retval = razor_atomic_commit(atomic);
1036 fprintf(stderr, "%s\n",
1037 razor_atomic_get_error_msg(atomic));
1039 razor_install_iterator_seek(ii, pos);
1040 update_packages(trans, ii, system, next,
1041 atomic, relocations,
1042 RAZOR_STAGE_SCRIPTS_POST);
1046 razor_atomic_destroy(atomic);
1047 } while(!retval && r == 1);
1049 razor_set_unref(system);
1057 command_install_or_update(int argc, const char *argv[], int do_update)
1059 struct razor_relocations *relocations = NULL;
1060 struct razor_set *system, *upstream, *next, *set;
1061 struct razor_transaction *trans;
1062 struct razor_error *error = NULL;
1063 struct razor_atomic *atomic;
1064 struct razor_root *root;
1065 int i, retval, len, dependencies = 1;
1068 for (i = 0; i < argc; i++) {
1069 if (strcmp(argv[i], "--no-dependencies") == 0)
1071 else if (strcmp(argv[i], "--relocate") == 0) {
1073 if (i >= argc || strchr(argv[i], '=') == NULL) {
1075 "Usage: razor %s [OPTION...] RPM\n",
1076 do_update ? "update" : "install");
1077 fprintf(stderr, "Options:\n");
1078 fprintf(stderr, " [--no-dependencies]\n");
1080 " [--relocate OLDPATH=NEWPATH] RPM\n");
1083 len = strchr(argv[i], '=') - argv[i];
1084 oldpath = malloc(len + 1);
1085 strncpy(oldpath, argv[i], len);
1086 oldpath[len] = '\0';
1088 relocations = razor_relocations_create();
1089 razor_relocations_add(relocations, oldpath,
1096 upstream = razor_set_open(rawhide_repo_filename, 0, &error);
1097 if (upstream == NULL) {
1098 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1099 razor_error_free(error);
1104 atomic = razor_atomic_open("Update packages");
1106 atomic = razor_atomic_open("Install packages");
1109 set = relocate_packages(upstream, atomic, relocations);
1111 fprintf(stderr, "%s\n",
1112 razor_atomic_get_error_msg(atomic));
1113 razor_atomic_destroy(atomic);
1114 razor_set_unref(upstream);
1117 razor_set_unref(upstream);
1121 root = razor_root_open(install_root, &error);
1123 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1124 razor_error_free(error);
1125 razor_atomic_destroy(atomic);
1126 razor_set_unref(upstream);
1128 razor_relocations_destroy(relocations);
1132 system = razor_root_get_system_set(root);
1133 trans = razor_transaction_create(system, upstream);
1135 if (i == argc && do_update)
1136 razor_transaction_update_all(trans);
1137 for (; i < argc; i++) {
1139 mark_packages_for_update(trans, system, argv[i]))
1141 if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
1142 fprintf(stderr, "no package matched %s\n", argv[i]);
1143 razor_transaction_destroy(trans);
1144 razor_root_close(root);
1145 razor_set_unref(upstream);
1146 razor_atomic_destroy(atomic);
1148 razor_relocations_destroy(relocations);
1154 razor_transaction_resolve(trans);
1155 if (razor_transaction_describe(trans) > 0) {
1156 razor_transaction_destroy(trans);
1157 razor_set_unref(upstream);
1158 razor_root_close(root);
1159 razor_atomic_destroy(atomic);
1161 razor_relocations_destroy(relocations);
1166 if (razor_atomic_create_dir(atomic, "rpms",
1167 S_IRWXU | S_IRWXG | S_IRWXO) ||
1168 razor_atomic_commit(atomic)) {
1169 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1170 razor_transaction_destroy(trans);
1171 razor_set_unref(upstream);
1172 razor_root_close(root);
1173 razor_atomic_destroy(atomic);
1175 razor_relocations_destroy(relocations);
1179 razor_atomic_destroy(atomic);
1181 next = razor_transaction_commit(trans);
1183 if (download_packages(system, next) < 0) {
1184 razor_set_unref(next);
1185 razor_transaction_destroy(trans);
1186 razor_set_unref(upstream);
1187 razor_root_close(root);
1188 razor_atomic_destroy(atomic);
1190 razor_relocations_destroy(relocations);
1194 retval = update_system(root, relocations, trans, next,
1195 do_update ? "Update" : "Install");
1197 razor_set_unref(upstream);
1198 razor_root_close(root);
1200 razor_transaction_destroy(trans);
1202 razor_relocations_destroy(relocations);
1204 razor_set_unref(next);
1210 command_update(int argc, const char *argv[])
1212 return command_install_or_update(argc, argv, 1);
1216 command_install(int argc, const char *argv[])
1218 return command_install_or_update(argc, argv, 0);
1222 command_init(int argc, const char *argv[])
1225 struct razor_error *error = NULL;
1227 retval = razor_root_create(install_root, &error);
1229 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1230 razor_error_free(error);
1232 printf("Created install root\n");
1238 command_download(int argc, const char *argv[])
1240 struct razor_error *error = NULL;
1241 struct razor_atomic *atomic;
1242 struct razor_set *set;
1243 struct razor_package_iterator *pi;
1244 struct razor_package *package;
1245 const char *pattern = argv[0], *name, *version, *arch;
1246 char url[256], file[256];
1249 set = razor_set_open(rawhide_repo_filename, 0, &error);
1251 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1252 razor_error_free(error);
1256 atomic = razor_atomic_open("Download packages");
1258 if (razor_atomic_create_dir(atomic, "rpms",
1259 S_IRWXU | S_IRWXG | S_IRWXO)) {
1260 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1261 razor_atomic_destroy(atomic);
1265 if (razor_atomic_commit(atomic)) {
1266 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1267 razor_atomic_destroy(atomic);
1270 razor_atomic_destroy(atomic);
1272 pi = razor_package_iterator_create(set);
1273 while (razor_package_iterator_next(pi, &package,
1274 RAZOR_DETAIL_NAME, &name,
1275 RAZOR_DETAIL_VERSION, &version,
1276 RAZOR_DETAIL_ARCH, &arch,
1277 RAZOR_DETAIL_LAST)) {
1278 if (pattern && fnmatch(pattern, name, 0) != 0)
1282 snprintf(url, sizeof url,
1283 "%s/Packages/%s-%s.%s.rpm",
1284 yum_url, name, version, arch);
1285 snprintf(file, sizeof file,
1286 "rpms/%s-%s.%s.rpm", name, version, arch);
1287 download_if_missing(url, file);
1289 razor_package_iterator_destroy(pi);
1290 razor_set_unref(set);
1293 fprintf(stderr, "no packages matched \"%s\"\n", pattern);
1294 else if (matches == 1)
1295 fprintf(stderr, "downloaded 1 package\n");
1297 fprintf(stderr, "downloaded %d packages\n", matches);
1303 command_info(int argc, const char *argv[])
1305 struct razor_error *error = NULL;
1306 struct razor_set *set;
1307 struct razor_package_iterator *pi;
1308 struct razor_package *package;
1309 const char *pattern = argv[0], *name, *version, *arch;
1310 const char *summary, *description, *url, *license;
1312 set = razor_root_open_read_only(install_root, &error);
1314 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1315 razor_error_free(error);
1319 pi = razor_package_iterator_create(set);
1320 while (razor_package_iterator_next(pi, &package,
1321 RAZOR_DETAIL_NAME, &name,
1322 RAZOR_DETAIL_VERSION, &version,
1323 RAZOR_DETAIL_ARCH, &arch,
1324 RAZOR_DETAIL_LAST)) {
1325 if (pattern && fnmatch(pattern, name, 0) != 0)
1328 razor_package_get_details (set, package,
1329 RAZOR_DETAIL_SUMMARY, &summary,
1330 RAZOR_DETAIL_DESCRIPTION, &description,
1331 RAZOR_DETAIL_URL, &url,
1332 RAZOR_DETAIL_LICENSE, &license,
1335 printf ("Name: %s\n", name);
1336 printf ("Arch: %s\n", arch);
1337 printf ("Version: %s\n", version);
1338 printf ("URL: %s\n", url);
1339 printf ("License: %s\n", license);
1340 printf ("Summary: %s\n", summary);
1341 printf ("Description:\n");
1342 printf ("%s\n", description);
1345 razor_package_iterator_destroy(pi);
1346 razor_set_unref(set);
1351 #define SEARCH_MAX 256
1354 command_search(int argc, const char *argv[])
1356 struct razor_error *error = NULL;
1357 struct razor_set *set;
1358 struct razor_package_iterator *pi;
1359 struct razor_package *package;
1360 char pattern[SEARCH_MAX];
1361 const char *name, *version, *arch;
1362 const char *summary, *description, *url, *license;
1365 fprintf(stderr, "must specify a search term\n");
1369 snprintf(pattern, sizeof pattern, "*%s*", argv[0]);
1371 set = razor_set_open(rawhide_repo_filename, 0, &error);
1373 fprintf(stderr, "%s\n", razor_error_get_msg(error));
1374 razor_error_free(error);
1378 pi = razor_package_iterator_create(set);
1379 while (razor_package_iterator_next(pi, &package,
1380 RAZOR_DETAIL_NAME, &name,
1381 RAZOR_DETAIL_VERSION, &version,
1382 RAZOR_DETAIL_ARCH, &arch,
1383 RAZOR_DETAIL_SUMMARY, &summary,
1384 RAZOR_DETAIL_DESCRIPTION, &description,
1385 RAZOR_DETAIL_URL, &url,
1386 RAZOR_DETAIL_LICENSE, &license,
1387 RAZOR_DETAIL_LAST)) {
1388 if (!fnmatch(pattern, name, FNM_CASEFOLD) ||
1389 !fnmatch(pattern, url, FNM_CASEFOLD) ||
1390 !fnmatch(pattern, summary, FNM_CASEFOLD) ||
1391 !fnmatch(pattern, description, FNM_CASEFOLD))
1392 printf("%s-%s.%s: %s\n", name, version, arch, summary);
1394 razor_package_iterator_destroy(pi);
1395 razor_set_unref(set);
1402 const char *description;
1403 int (*func)(int argc, const char *argv[]);
1404 } razor_commands[] = {
1405 { "list", "list all packages", command_list },
1406 { "list-requires", "list all requires for the given package", command_list_requires },
1407 { "list-provides", "list all provides for the given package", command_list_provides },
1408 { "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
1409 { "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
1410 { "list-scripts", "list all scripts for the given package", command_list_scripts },
1411 { "list-files", "list files for package set", command_list_files },
1412 { "list-file-packages", "list packages owning file", command_list_file_packages },
1413 { "list-package-files", "list files in package", command_list_package_files },
1414 { "what-requires", "list the packages that have the given requires", command_what_requires },
1415 { "what-provides", "list the packages that have the given provides", command_what_provides },
1416 { "import-yum", "import yum metadata files", command_import_yum },
1418 { "import-rpmdb", "import the system rpm database", command_import_rpmdb },
1420 { "import-rpms", "import rpms from the given directory", command_import_rpms },
1421 { "update", "update all or specified packages", command_update },
1422 { "remove", "remove specified packages", command_remove },
1423 { "diff", "show diff between two package sets", command_diff },
1424 { "install", "install rpm", command_install },
1425 { "init", "init razor root", command_init },
1426 { "download", "download packages", command_download },
1427 { "info", "display package details", command_info },
1428 { "search", "search package details", command_search }
1437 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1438 printf(" %-20s%s\n",
1439 razor_commands[i].name, razor_commands[i].description);
1445 main(int argc, const char *argv[])
1450 repo = getenv("RAZOR_REPO");
1452 repo_filename = repo;
1454 root = getenv("RAZOR_ROOT");
1456 install_root = root;
1458 yum_url = getenv("YUM_URL");
1459 if (yum_url == NULL)
1462 if (getenv("RAZOR_NO_ROOT_NAME_CHECKS"))
1463 razor_disable_root_name_checks(1);
1468 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1469 if (strcmp(razor_commands[i].name, argv[1]) == 0)
1470 return razor_commands[i].func(argc - 2, argv + 2);