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