Add an error object.
This is intended to dis-entangle the two roles that the atomic
object has evolved into so that atomic need only be used where
atomic actions are actually being undertaken.
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(const char *install_root, struct razor_relocations *relocations,
59 struct razor_transaction *trans, struct razor_set *system,
60 struct razor_set *next, const char *verb);
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_atomic *atomic;
124 struct razor_set *set;
128 if (i < argc && strcmp(argv[i], "--only-names") == 0) {
129 flags |= LIST_PACKAGES_ONLY_NAMES;
133 atomic = razor_atomic_open("List installed packages");
134 set = razor_root_open_read_only(install_root, atomic);
136 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
137 razor_atomic_destroy(atomic);
141 pi = create_iterator_from_argv(set, argc - i, argv + i);
142 list_packages(pi, flags);
143 razor_package_iterator_destroy(pi);
144 razor_set_unref(set);
145 razor_atomic_destroy(atomic);
151 list_package_properties(struct razor_set *set,
152 struct razor_package *package, uint32_t type)
154 struct razor_property_iterator *pi;
155 struct razor_property *property;
156 const char *name, *version;
159 pi = razor_property_iterator_create(set, package);
160 while (razor_property_iterator_next(pi, &property,
161 &name, &flags, &version)) {
162 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
165 if (version[0] != '\0')
167 razor_property_relation_to_string(property),
170 if (flags & ~(RAZOR_PROPERTY_RELATION_MASK | RAZOR_PROPERTY_TYPE_MASK)) {
172 if (flags & RAZOR_PROPERTY_PRE)
174 if (flags & RAZOR_PROPERTY_POST)
176 if (flags & RAZOR_PROPERTY_PREUN)
178 if (flags & RAZOR_PROPERTY_POSTUN)
184 razor_property_iterator_destroy(pi);
188 list_properties(int argc, const char *argv[], uint32_t type)
190 struct razor_set *set;
191 struct razor_atomic *atomic;
192 struct razor_package *package;
193 struct razor_package_iterator *pi;
194 const char *name, *version, *arch;
196 atomic = razor_atomic_open("List package properties");
197 set = razor_root_open_read_only(install_root, atomic);
199 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
200 razor_atomic_destroy(atomic);
204 pi = create_iterator_from_argv(set, argc, argv);
205 while (razor_package_iterator_next(pi, &package,
206 RAZOR_DETAIL_NAME, &name,
207 RAZOR_DETAIL_VERSION, &version,
208 RAZOR_DETAIL_ARCH, &arch,
210 list_package_properties(set, package, type);
211 razor_package_iterator_destroy(pi);
212 razor_set_unref(set);
213 razor_atomic_destroy(atomic);
219 command_list_requires(int argc, const char *argv[])
221 return list_properties(argc, argv, RAZOR_PROPERTY_REQUIRES);
225 command_list_provides(int argc, const char *argv[])
227 return list_properties(argc, argv, RAZOR_PROPERTY_PROVIDES);
231 command_list_obsoletes(int argc, const char *argv[])
233 return list_properties(argc, argv, RAZOR_PROPERTY_OBSOLETES);
237 command_list_conflicts(int argc, const char *argv[])
239 return list_properties(argc, argv, RAZOR_PROPERTY_CONFLICTS);
243 command_list_scripts(int argc, const char *argv[])
245 struct razor_set *set;
246 struct razor_atomic *atomic;
247 struct razor_package *package;
248 struct razor_package_iterator *pi;
249 const char *preunprog, *preun, *postunprog, *postun;
251 atomic = razor_atomic_open("List package scripts");
252 set = razor_root_open_read_only(install_root, atomic);
254 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
255 razor_atomic_destroy(atomic);
259 pi = create_iterator_from_argv(set, argc, argv);
260 while (razor_package_iterator_next(pi, &package,
261 RAZOR_DETAIL_PREUNPROG, &preunprog,
262 RAZOR_DETAIL_PREUN, &preun,
263 RAZOR_DETAIL_POSTUNPROG, &postunprog,
264 RAZOR_DETAIL_POSTUN, &postun,
265 RAZOR_DETAIL_LAST)) {
266 if (preun && *preun) {
267 printf("preuninstall scriptlet");
268 if (preunprog && *preunprog)
269 printf(" (using %s)",preunprog);
270 printf(":\n%s\n",preun);
272 if (postun && *postun) {
273 printf("postuninstall scriptlet");
274 if (postunprog && *postunprog)
275 printf(" (using %s)",postunprog);
276 printf(":\n%s\n",postun);
279 razor_package_iterator_destroy(pi);
280 razor_set_unref(set);
281 razor_atomic_destroy(atomic);
287 command_list_files(int argc, const char *argv[])
289 struct razor_atomic *atomic;
290 struct razor_set *set;
292 atomic = razor_atomic_open("List package files");
293 set = razor_root_open_read_only(install_root, atomic);
295 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
296 razor_atomic_destroy(atomic);
300 razor_set_list_files(set, argv[0]);
301 razor_set_unref(set);
302 razor_atomic_destroy(atomic);
308 command_list_file_packages(int argc, const char *argv[])
310 struct razor_atomic *atomic;
311 struct razor_set *set;
312 struct razor_package_iterator *pi;
314 atomic = razor_atomic_open("List file packages");
315 set = razor_root_open_read_only(install_root, atomic);
317 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
318 razor_atomic_destroy(atomic);
322 pi = razor_package_iterator_create_for_file(set, argv[0]);
323 list_packages(pi, 0);
324 razor_package_iterator_destroy(pi);
326 razor_set_unref(set);
327 razor_atomic_destroy(atomic);
333 command_list_package_files(int argc, const char *argv[])
335 struct razor_atomic *atomic;
336 struct razor_set *set;
337 struct razor_package_iterator *pi;
338 struct razor_package *package;
339 const char *name, *version, *arch;
341 atomic = razor_atomic_open("List package files");
342 set = razor_root_open_read_only(install_root, atomic);
344 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
345 razor_atomic_destroy(atomic);
349 pi = create_iterator_from_argv(set, argc, argv);
350 while (razor_package_iterator_next(pi, &package,
351 RAZOR_DETAIL_NAME, &name,
352 RAZOR_DETAIL_VERSION, &version,
353 RAZOR_DETAIL_ARCH, &arch,
355 razor_set_list_package_files(set, package);
356 razor_package_iterator_destroy(pi);
358 razor_set_unref(set);
359 razor_atomic_destroy(atomic);
365 list_property_packages(const char *ref_name,
366 const char *ref_version,
369 struct razor_atomic *atomic;
370 struct razor_set *set;
371 struct razor_property *property;
372 struct razor_property_iterator *prop_iter;
373 struct razor_package_iterator *pkg_iter;
374 const char *name, *version;
377 if (ref_name == NULL)
380 atomic = razor_atomic_open("List package properties");
381 set = razor_root_open_read_only(install_root, atomic);
383 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
384 razor_atomic_destroy(atomic);
388 prop_iter = razor_property_iterator_create(set, NULL);
389 while (razor_property_iterator_next(prop_iter, &property,
390 &name, &flags, &version)) {
391 if (strcmp(ref_name, name) != 0)
394 (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
395 strcmp(ref_version, version) != 0)
397 if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
401 razor_package_iterator_create_for_property(set,
403 list_packages(pkg_iter, 0);
404 razor_package_iterator_destroy(pkg_iter);
406 razor_property_iterator_destroy(prop_iter);
408 razor_set_unref(set);
409 razor_atomic_destroy(atomic);
415 command_what_requires(int argc, const char *argv[])
417 return list_property_packages(argv[0], argv[1],
418 RAZOR_PROPERTY_REQUIRES);
422 command_what_provides(int argc, const char *argv[])
424 return list_property_packages(argv[0], argv[1],
425 RAZOR_PROPERTY_PROVIDES);
429 show_progress(void *clientp,
430 double dltotal, double dlnow, double ultotal, double ulnow)
432 const char *file = clientp;
434 if (!dlnow < dltotal)
435 fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
436 file, (int) dlnow / 1024, (int) dltotal / 1024);
442 download_if_missing(const char *url, const char *file)
454 curl = curl_easy_init();
458 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
459 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
460 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
461 curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
463 if (stat(file, &buf) < 0) {
464 fp = fopen(file, "wb");
467 "failed to open %s for writing\n", file);
470 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
471 curl_easy_setopt(curl, CURLOPT_URL, url);
472 res = curl_easy_perform(curl);
474 if (res != CURLE_OK) {
475 fprintf(stderr, "curl error: %s\n", error);
479 res = curl_easy_getinfo(curl,
480 CURLINFO_RESPONSE_CODE, &response);
481 if (res != CURLE_OK) {
482 fprintf(stderr, "curl error: %s\n", error);
486 if (response != 200) {
487 fprintf(stderr, " - failed %ld\n", response);
491 fprintf(stderr, "\n");
494 curl_easy_cleanup(curl);
497 #endif /* HAVE_CURL */
500 #define YUM_URL "http://download.fedora.redhat.com" \
501 "/pub/fedora/linux/development/i386/os"
504 command_import_yum(int argc, const char *argv[])
507 struct razor_set *set;
508 struct razor_atomic *atomic;
511 printf("downloading from %s.\n", yum_url);
512 snprintf(buffer, sizeof buffer,
513 "%s/repodata/primary.xml.gz", yum_url);
514 if (download_if_missing(buffer, "primary.xml.gz") < 0)
516 snprintf(buffer, sizeof buffer,
517 "%s/repodata/filelists.xml.gz", yum_url);
518 if (download_if_missing(buffer, "filelists.xml.gz") < 0)
521 set = razor_set_create_from_yum();
524 atomic = razor_atomic_open("Yum import repository");
525 razor_set_write(set, atomic, rawhide_repo_filename, RAZOR_SECTION_ALL);
526 retval = razor_atomic_commit(atomic);
527 razor_set_unref(set);
529 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
531 printf("wrote %s\n", rawhide_repo_filename);
532 razor_atomic_destroy(atomic);
539 command_import_rpmdb(int argc, const char *argv[])
541 struct razor_set *set;
542 struct razor_root *root;
543 struct razor_atomic *atomic;
546 atomic = razor_atomic_open("Import RPM database");
548 root = razor_root_open(install_root, atomic);
550 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
551 razor_atomic_destroy(atomic);
555 set = razor_set_create_from_rpmdb();
559 razor_root_update(root, set);
561 retval = razor_root_commit(root);
563 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
565 razor_atomic_destroy(atomic);
572 mark_packages_for_update(struct razor_transaction *trans,
573 struct razor_set *set, const char *pattern)
575 struct razor_package_iterator *pi;
576 struct razor_package *package;
580 pi = razor_package_iterator_create(set);
581 while (razor_package_iterator_next(pi, &package,
582 RAZOR_DETAIL_NAME, &name,
583 RAZOR_DETAIL_LAST)) {
584 if (pattern && fnmatch(pattern, name, 0) == 0) {
585 razor_transaction_update_package(trans, package);
589 razor_package_iterator_destroy(pi);
595 mark_packages_for_removal(struct razor_transaction *trans,
596 struct razor_set *set, const char *pattern)
598 struct razor_package_iterator *pi;
599 struct razor_package *package;
603 pi = razor_package_iterator_create(set);
604 while (razor_package_iterator_next(pi, &package,
605 RAZOR_DETAIL_NAME, &name,
606 RAZOR_DETAIL_LAST)) {
607 if (pattern && fnmatch(pattern, name, 0) == 0) {
608 razor_transaction_remove_package(trans, package);
612 razor_package_iterator_destroy(pi);
618 command_remove(int argc, const char *argv[])
620 struct razor_set *system, *upstream, *next;
621 struct razor_transaction *trans;
622 struct razor_atomic *atomic;
625 atomic = razor_atomic_open("Remove packages");
627 system = razor_root_open_read_only(install_root, atomic);
628 if (system == NULL) {
629 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
630 razor_atomic_destroy(atomic);
634 razor_atomic_destroy(atomic);
636 upstream = razor_set_create_without_root();
637 trans = razor_transaction_create(system, upstream);
638 razor_set_unref(upstream);
639 for (i = 0; i < argc; i++) {
640 if (mark_packages_for_removal(trans, system, argv[i]) == 0) {
641 fprintf(stderr, "no match for %s\n", argv[i]);
642 razor_transaction_destroy(trans);
643 razor_set_unref(system);
648 razor_transaction_resolve(trans);
649 retval = razor_transaction_describe(trans);
651 razor_transaction_destroy(trans);
652 razor_set_unref(system);
656 next = razor_transaction_commit(trans);
658 retval = update_system(install_root, NULL, trans, system, next,
661 razor_transaction_destroy(trans);
662 razor_set_unref(system);
663 razor_set_unref(next);
669 print_diff(enum razor_diff_action action,
670 struct razor_package *package,
676 if (action == RAZOR_DIFF_ACTION_ADD)
677 printf("install %s-%s.%s\n", name, version, arch);
678 if (action == RAZOR_DIFF_ACTION_REMOVE)
679 printf("remove %s-%s.%s\n", name, version, arch);
683 command_diff(int argc, const char *argv[])
685 struct razor_atomic *atomic;
686 struct razor_set *set, *updated;
688 atomic = razor_atomic_open("Show package differences");
689 set = razor_root_open_read_only(install_root, atomic);
690 updated = razor_set_open(rawhide_repo_filename, atomic);
691 if (set == NULL || updated == NULL) {
692 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
693 razor_atomic_destroy(atomic);
697 razor_set_diff(set, updated, print_diff, NULL);
699 razor_set_unref(set);
700 razor_set_unref(updated);
701 razor_atomic_destroy(atomic);
707 command_import_rpms(int argc, const char *argv[])
711 struct razor_importer *importer;
712 struct razor_set *set;
713 struct razor_rpm *rpm;
714 struct razor_atomic *atomic;
715 int len, imported_count = 0;
717 const char *dirname = argv[0];
720 if (dirname == NULL) {
721 fprintf(stderr, "usage: razor import-rpms DIR\n");
725 dir = opendir(dirname);
727 fprintf(stderr, "couldn't read dir %s\n", dirname);
731 importer = razor_importer_create();
733 while (de = readdir(dir), de != NULL) {
734 len = strlen(de->d_name);
735 if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
737 snprintf(filename, sizeof filename,
738 "%s/%s", dirname, de->d_name);
739 atomic = razor_atomic_open("Read RPM");
740 rpm = razor_rpm_open(filename, atomic);
742 fprintf(stderr, "%s\n",
743 razor_atomic_get_error_msg(atomic));
744 razor_atomic_destroy(atomic);
747 if (razor_importer_add_rpm(importer, rpm)) {
748 fprintf(stderr, "couldn't import %s\n", filename);
751 razor_rpm_close(rpm);
753 printf("\rimporting %d", ++imported_count);
758 razor_importer_destroy(importer);
762 printf("\nsaving\n");
763 set = razor_importer_finish(importer);
765 atomic = razor_atomic_open("Update system database");
766 razor_set_write(set, atomic, repo_filename, RAZOR_SECTION_ALL);
767 razor_set_unref(set);
768 retval = razor_atomic_commit(atomic);
770 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
772 printf("wrote %s\n", repo_filename);
773 razor_atomic_destroy(atomic);
779 rpm_filename(const char *name, const char *version, const char *arch)
784 v = strchr(version, ':');
790 return razor_concat(name, "-", v, ".", arch, ".rpm", NULL);
794 download_packages(struct razor_set *system, struct razor_set *next)
796 struct razor_install_iterator *ii;
797 struct razor_package *package;
798 enum razor_install_action action;
799 const char *name, *version, *arch;
800 char *file, *url, *s;
801 int errors = 0, count;
803 ii = razor_set_create_install_iterator(system, next);
804 while (razor_install_iterator_next(ii, &package, &action, &count)) {
805 if (action != RAZOR_INSTALL_ACTION_ADD)
808 razor_package_get_details(next, package,
809 RAZOR_DETAIL_NAME, &name,
810 RAZOR_DETAIL_VERSION, &version,
811 RAZOR_DETAIL_ARCH, &arch,
814 s = rpm_filename(name, version, arch);
815 url = razor_concat(yum_url, "/Packages/", s, NULL);
816 file = razor_concat("rpms/", s, NULL);
818 if (download_if_missing(url, file) < 0)
823 razor_install_iterator_destroy(ii);
826 fprintf(stderr, "failed to download %d packages\n", errors);
833 static struct razor_set *
834 relocate_packages(struct razor_set *set, struct razor_atomic *atomic,
835 struct razor_relocations *relocations)
838 struct razor_importer *importer;
839 struct razor_property_iterator *prop_iter;
840 struct razor_package_iterator *pkg_iter;
841 struct razor_file_iterator *file_iter;
842 struct razor_package *package;
843 struct razor_property *property;
844 struct razor_rpm *rpm;
845 const char *name, *version, *arch, *summary, *desc, *url, *license;
846 const char *preunprog, *preun, *postunprog, *postun;
847 const char *install_prefix;
848 const char *const *prefixes;
852 importer = razor_importer_create();
853 pkg_iter = razor_package_iterator_create(set);
855 while (razor_package_iterator_next(pkg_iter, &package,
856 RAZOR_DETAIL_NAME, &name,
857 RAZOR_DETAIL_VERSION, &version,
858 RAZOR_DETAIL_ARCH, &arch,
859 RAZOR_DETAIL_SUMMARY, &summary,
860 RAZOR_DETAIL_DESCRIPTION, &desc,
861 RAZOR_DETAIL_URL, &url,
862 RAZOR_DETAIL_LICENSE, &license,
863 RAZOR_DETAIL_PREUNPROG, &preunprog,
864 RAZOR_DETAIL_PREUN, &preun,
865 RAZOR_DETAIL_POSTUNPROG, &postunprog,
866 RAZOR_DETAIL_POSTUN, &postun,
867 RAZOR_DETAIL_LAST)) {
868 s = rpm_filename(name, version, arch);
869 file = razor_concat("rpms/", s, NULL);
871 rpm = razor_rpm_open(file, atomic);
874 razor_package_iterator_destroy(pkg_iter);
875 razor_importer_destroy(importer);
879 razor_relocations_set_rpm(relocations, rpm);
881 razor_importer_begin_package(importer, name, version, arch);
882 razor_importer_add_details(importer,
883 summary, desc, url, license);
885 razor_rpm_get_details(rpm, RAZOR_DETAIL_PREFIXES, &prefixes,
887 for (i = 0; prefixes && prefixes[i]; i++) {
888 install_prefix = razor_relocations_apply(relocations,
890 razor_importer_add_install_prefix(importer,
894 razor_rpm_close(rpm);
896 prop_iter = razor_property_iterator_create(set, package);
897 while (razor_property_iterator_next(prop_iter, &property,
898 &name, &flags, &version))
899 razor_importer_add_property(importer,
900 name, flags, version);
901 razor_property_iterator_destroy(prop_iter);
903 file_iter = razor_file_iterator_create(set, package, 0);
904 while (razor_file_iterator_next(file_iter, &name)) {
905 name = razor_relocations_apply(relocations, name);
906 razor_importer_add_file(importer, name);
908 razor_file_iterator_destroy(file_iter);
910 razor_importer_add_script(importer, RAZOR_PROPERTY_PREUN,
912 razor_importer_add_script(importer, RAZOR_PROPERTY_POSTUN,
915 razor_importer_finish_package(importer);
918 razor_package_iterator_destroy(pkg_iter);
919 return razor_importer_finish(importer);
923 install_package(struct razor_transaction *trans, struct razor_set *set,
924 struct razor_atomic *atomic, struct razor_package *package,
925 struct razor_relocations *relocations, int install_count,
926 enum razor_stage_type stage)
929 const char *name, *version, *arch;
931 struct razor_rpm *rpm;
933 razor_package_get_details(set, package,
934 RAZOR_DETAIL_NAME, &name,
935 RAZOR_DETAIL_VERSION, &version,
936 RAZOR_DETAIL_ARCH, &arch,
939 if (stage & RAZOR_STAGE_SCRIPTS_PRE)
940 printf("install %s-%s\n", name, version);
942 s = rpm_filename(name, version, arch);
943 file = razor_concat("rpms/", s, NULL);
945 rpm = razor_rpm_open(file, atomic);
948 fprintf(stderr, "%s\n",
949 razor_atomic_get_error_msg(atomic));
953 razor_rpm_set_relocations(rpm, relocations);
954 razor_transaction_fixup_package(trans, package, rpm);
955 retval = razor_rpm_install(rpm, atomic, install_root, install_count,
958 s = rpm_filename(name, version, arch);
959 fprintf(stderr, "%s: %s\n", s,
960 razor_atomic_get_error_msg(atomic));
963 razor_rpm_close(rpm);
968 * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT
969 * is met (in which case the action is consumed).
972 update_packages(struct razor_transaction *trans,
973 struct razor_install_iterator *ii, struct razor_set *system,
974 struct razor_set *next, struct razor_atomic *atomic,
975 struct razor_relocations *relocations,
976 enum razor_stage_type stage)
978 struct razor_package *package;
979 enum razor_install_action action;
980 int retval = 0, count;
982 while (!retval && razor_install_iterator_next(ii, &package, &action,
984 if (action == RAZOR_INSTALL_ACTION_ADD) {
985 if (install_package(trans, next, atomic, package,
986 relocations, count, stage))
988 } else if (action == RAZOR_INSTALL_ACTION_REMOVE) {
989 if (razor_package_remove(system, next, atomic, package,
990 install_root, count, stage))
992 } else if (action == RAZOR_INSTALL_ACTION_COMMIT)
1000 update_system(const char *install_root, struct razor_relocations *relocations,
1001 struct razor_transaction *trans, struct razor_set *system,
1002 struct razor_set *next, const char *verb)
1004 struct razor_root *root;
1005 struct razor_set *set;
1006 struct razor_atomic *atomic;
1007 struct razor_install_iterator *ii;
1012 description = razor_concat(verb, " packages", NULL);
1014 ii = razor_set_create_install_iterator(system, next);
1017 pos = razor_install_iterator_tell(ii);
1019 atomic = razor_atomic_open(description);
1021 root = razor_root_open(install_root, atomic);
1023 fprintf(stderr, "%s\n",
1024 razor_atomic_get_error_msg(atomic));
1025 razor_atomic_destroy(atomic);
1030 r = update_packages(trans, ii, system, next, atomic,
1031 relocations, RAZOR_STAGE_SCRIPTS_PRE);
1033 fprintf(stderr, "%s aborted\n", verb);
1034 razor_root_close(root);
1037 razor_install_iterator_seek(ii, pos);
1038 r = update_packages(trans, ii, system, next, atomic,
1039 relocations, RAZOR_STAGE_FILES);
1042 set = razor_install_iterator_commit_set(ii);
1043 razor_root_update(root, set);
1044 razor_set_unref(set);
1046 razor_root_update(root, next);
1048 (void)razor_root_commit(root);
1049 retval = razor_atomic_commit(atomic);
1051 fprintf(stderr, "%s\n",
1052 razor_atomic_get_error_msg(atomic));
1054 razor_install_iterator_seek(ii, pos);
1055 update_packages(trans, ii, system, next,
1056 atomic, relocations,
1057 RAZOR_STAGE_SCRIPTS_POST);
1061 razor_atomic_destroy(atomic);
1062 } while(!retval && r == 1);
1070 command_install_or_update(int argc, const char *argv[], int do_update)
1072 struct razor_relocations *relocations=NULL;
1073 struct razor_set *system, *upstream, *next, *set;
1074 struct razor_transaction *trans;
1075 struct razor_atomic *atomic;
1076 int i, retval, len, dependencies = 1;
1079 for (i = 0; i < argc; i++) {
1080 if (strcmp(argv[i], "--no-dependencies") == 0)
1082 else if (strcmp(argv[i], "--relocate") == 0) {
1084 if (i >= argc || strchr(argv[i], '=') == NULL) {
1086 "Usage: razor %s [OPTION...] RPM\n",
1087 do_update ? "update" : "install");
1088 fprintf(stderr, "Options:\n");
1089 fprintf(stderr, " [--no-dependencies]\n");
1091 " [--relocate OLDPATH=NEWPATH] RPM\n");
1094 len = strchr(argv[i], '=') - argv[i];
1095 oldpath = malloc(len + 1);
1096 strncpy(oldpath, argv[i], len);
1097 oldpath[len] = '\0';
1099 relocations = razor_relocations_create();
1100 razor_relocations_add(relocations, oldpath,
1108 atomic = razor_atomic_open("Update packages");
1110 atomic = razor_atomic_open("Install packages");
1112 upstream = razor_set_open(rawhide_repo_filename, atomic);
1113 if (upstream == NULL) {
1114 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1115 razor_atomic_destroy(atomic);
1120 set = relocate_packages(upstream, atomic, relocations);
1122 fprintf(stderr, "%s\n",
1123 razor_atomic_get_error_msg(atomic));
1124 razor_atomic_destroy(atomic);
1125 razor_set_unref(upstream);
1128 razor_set_unref(upstream);
1132 system = razor_root_open_read_only(install_root, atomic);
1134 trans = razor_transaction_create(system, upstream);
1136 if (i == argc && do_update)
1137 razor_transaction_update_all(trans);
1138 for (; i < argc; i++) {
1140 mark_packages_for_update(trans, system, argv[i]))
1142 if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
1143 fprintf(stderr, "no package matched %s\n", argv[i]);
1144 razor_transaction_destroy(trans);
1145 razor_set_unref(upstream);
1146 razor_set_unref(system);
1147 razor_atomic_destroy(atomic);
1153 razor_transaction_resolve(trans);
1154 if (razor_transaction_describe(trans) > 0) {
1155 razor_transaction_destroy(trans);
1156 razor_set_unref(upstream);
1157 razor_set_unref(system);
1158 razor_atomic_destroy(atomic);
1163 if (razor_atomic_create_dir(atomic, "rpms",
1164 S_IRWXU | S_IRWXG | S_IRWXO) ||
1165 razor_atomic_commit(atomic)) {
1166 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1167 razor_transaction_destroy(trans);
1168 razor_set_unref(upstream);
1169 razor_set_unref(system);
1170 razor_atomic_destroy(atomic);
1174 razor_atomic_destroy(atomic);
1176 next = razor_transaction_commit(trans);
1178 if (download_packages(system, next) < 0) {
1179 razor_set_unref(next);
1180 razor_transaction_destroy(trans);
1181 razor_set_unref(upstream);
1182 razor_set_unref(system);
1183 razor_atomic_destroy(atomic);
1187 retval = update_system(install_root, relocations, trans, system, next,
1188 do_update ? "Update" : "Install");
1190 razor_set_unref(upstream);
1192 razor_transaction_destroy(trans);
1194 razor_relocations_destroy(relocations);
1196 razor_set_unref(next);
1197 razor_set_unref(system);
1203 command_update(int argc, const char *argv[])
1205 return command_install_or_update(argc, argv, 1);
1209 command_install(int argc, const char *argv[])
1211 return command_install_or_update(argc, argv, 0);
1215 command_init(int argc, const char *argv[])
1217 return razor_root_create(install_root);
1221 command_download(int argc, const char *argv[])
1223 struct razor_atomic *atomic;
1224 struct razor_set *set;
1225 struct razor_package_iterator *pi;
1226 struct razor_package *package;
1227 const char *pattern = argv[0], *name, *version, *arch;
1228 char url[256], file[256];
1231 atomic = razor_atomic_open("Download packages");
1233 if (razor_atomic_create_dir(atomic, "rpms",
1234 S_IRWXU | S_IRWXG | S_IRWXO)) {
1235 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1236 razor_atomic_destroy(atomic);
1240 set = razor_set_open(rawhide_repo_filename, atomic);
1242 if (razor_atomic_commit(atomic)) {
1243 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1244 razor_atomic_destroy(atomic);
1247 razor_atomic_destroy(atomic);
1249 pi = razor_package_iterator_create(set);
1250 while (razor_package_iterator_next(pi, &package,
1251 RAZOR_DETAIL_NAME, &name,
1252 RAZOR_DETAIL_VERSION, &version,
1253 RAZOR_DETAIL_ARCH, &arch,
1254 RAZOR_DETAIL_LAST)) {
1255 if (pattern && fnmatch(pattern, name, 0) != 0)
1259 snprintf(url, sizeof url,
1260 "%s/Packages/%s-%s.%s.rpm",
1261 yum_url, name, version, arch);
1262 snprintf(file, sizeof file,
1263 "rpms/%s-%s.%s.rpm", name, version, arch);
1264 download_if_missing(url, file);
1266 razor_package_iterator_destroy(pi);
1267 razor_set_unref(set);
1270 fprintf(stderr, "no packages matched \"%s\"\n", pattern);
1271 else if (matches == 1)
1272 fprintf(stderr, "downloaded 1 package\n");
1274 fprintf(stderr, "downloaded %d packages\n", matches);
1280 command_info(int argc, const char *argv[])
1282 struct razor_atomic *atomic;
1283 struct razor_set *set;
1284 struct razor_package_iterator *pi;
1285 struct razor_package *package;
1286 const char *pattern = argv[0], *name, *version, *arch;
1287 const char *summary, *description, *url, *license;
1289 atomic = razor_atomic_open("Package info");
1290 set = razor_root_open_read_only(install_root, atomic);
1292 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1293 razor_atomic_destroy(atomic);
1297 pi = razor_package_iterator_create(set);
1298 while (razor_package_iterator_next(pi, &package,
1299 RAZOR_DETAIL_NAME, &name,
1300 RAZOR_DETAIL_VERSION, &version,
1301 RAZOR_DETAIL_ARCH, &arch,
1302 RAZOR_DETAIL_LAST)) {
1303 if (pattern && fnmatch(pattern, name, 0) != 0)
1306 razor_package_get_details (set, package,
1307 RAZOR_DETAIL_SUMMARY, &summary,
1308 RAZOR_DETAIL_DESCRIPTION, &description,
1309 RAZOR_DETAIL_URL, &url,
1310 RAZOR_DETAIL_LICENSE, &license,
1313 printf ("Name: %s\n", name);
1314 printf ("Arch: %s\n", arch);
1315 printf ("Version: %s\n", version);
1316 printf ("URL: %s\n", url);
1317 printf ("License: %s\n", license);
1318 printf ("Summary: %s\n", summary);
1319 printf ("Description:\n");
1320 printf ("%s\n", description);
1323 razor_package_iterator_destroy(pi);
1324 razor_set_unref(set);
1325 razor_atomic_destroy(atomic);
1330 #define SEARCH_MAX 256
1333 command_search(int argc, const char *argv[])
1335 struct razor_atomic *atomic;
1336 struct razor_set *set;
1337 struct razor_package_iterator *pi;
1338 struct razor_package *package;
1339 char pattern[SEARCH_MAX];
1340 const char *name, *version, *arch;
1341 const char *summary, *description, *url, *license;
1344 fprintf(stderr, "must specify a search term\n");
1348 snprintf(pattern, sizeof pattern, "*%s*", argv[0]);
1350 atomic = razor_atomic_open("Search packages");
1351 set = razor_set_open(rawhide_repo_filename, atomic);
1352 if (set == NULL || razor_atomic_commit(atomic)) {
1353 fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1354 razor_atomic_destroy(atomic);
1357 razor_atomic_destroy(atomic);
1359 pi = razor_package_iterator_create(set);
1360 while (razor_package_iterator_next(pi, &package,
1361 RAZOR_DETAIL_NAME, &name,
1362 RAZOR_DETAIL_VERSION, &version,
1363 RAZOR_DETAIL_ARCH, &arch,
1364 RAZOR_DETAIL_SUMMARY, &summary,
1365 RAZOR_DETAIL_DESCRIPTION, &description,
1366 RAZOR_DETAIL_URL, &url,
1367 RAZOR_DETAIL_LICENSE, &license,
1368 RAZOR_DETAIL_LAST)) {
1369 if (!fnmatch(pattern, name, FNM_CASEFOLD) ||
1370 !fnmatch(pattern, url, FNM_CASEFOLD) ||
1371 !fnmatch(pattern, summary, FNM_CASEFOLD) ||
1372 !fnmatch(pattern, description, FNM_CASEFOLD))
1373 printf("%s-%s.%s: %s\n", name, version, arch, summary);
1375 razor_package_iterator_destroy(pi);
1376 razor_set_unref(set);
1383 const char *description;
1384 int (*func)(int argc, const char *argv[]);
1385 } razor_commands[] = {
1386 { "list", "list all packages", command_list },
1387 { "list-requires", "list all requires for the given package", command_list_requires },
1388 { "list-provides", "list all provides for the given package", command_list_provides },
1389 { "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
1390 { "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
1391 { "list-scripts", "list all scripts for the given package", command_list_scripts },
1392 { "list-files", "list files for package set", command_list_files },
1393 { "list-file-packages", "list packages owning file", command_list_file_packages },
1394 { "list-package-files", "list files in package", command_list_package_files },
1395 { "what-requires", "list the packages that have the given requires", command_what_requires },
1396 { "what-provides", "list the packages that have the given provides", command_what_provides },
1397 { "import-yum", "import yum metadata files", command_import_yum },
1399 { "import-rpmdb", "import the system rpm database", command_import_rpmdb },
1401 { "import-rpms", "import rpms from the given directory", command_import_rpms },
1402 { "update", "update all or specified packages", command_update },
1403 { "remove", "remove specified packages", command_remove },
1404 { "diff", "show diff between two package sets", command_diff },
1405 { "install", "install rpm", command_install },
1406 { "init", "init razor root", command_init },
1407 { "download", "download packages", command_download },
1408 { "info", "display package details", command_info },
1409 { "search", "search package details", command_search }
1418 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1419 printf(" %-20s%s\n",
1420 razor_commands[i].name, razor_commands[i].description);
1426 main(int argc, const char *argv[])
1431 repo = getenv("RAZOR_REPO");
1433 repo_filename = repo;
1435 root = getenv("RAZOR_ROOT");
1437 install_root = root;
1439 yum_url = getenv("YUM_URL");
1440 if (yum_url == NULL)
1443 if (getenv("RAZOR_NO_ROOT_NAME_CHECKS"))
1444 razor_disable_root_name_checks(1);
1449 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1450 if (strcmp(razor_commands[i].name, argv[1]) == 0)
1451 return razor_commands[i].func(argc - 2, argv + 2);