rhughes@241: /* rhughes@241: * Copyright (C) 2008 Kristian Høgsberg rhughes@241: * Copyright (C) 2008 Red Hat, Inc ali@403: * Copyright (C) 2009, 2011 J. Ali Harlow rhughes@241: * rhughes@241: * This program is free software; you can redistribute it and/or modify rhughes@241: * it under the terms of the GNU General Public License as published by rhughes@241: * the Free Software Foundation; either version 2 of the License, or rhughes@241: * (at your option) any later version. rhughes@241: * rhughes@241: * This program is distributed in the hope that it will be useful, rhughes@241: * but WITHOUT ANY WARRANTY; without even the implied warranty of rhughes@241: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the rhughes@241: * GNU General Public License for more details. rhughes@241: * rhughes@241: * You should have received a copy of the GNU General Public License along rhughes@241: * with this program; if not, write to the Free Software Foundation, Inc., rhughes@241: * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. rhughes@241: */ rhughes@241: krh@305: #define _GNU_SOURCE krh@305: ali@321: #include "config.h" ali@321: rhughes@241: #include rhughes@241: #include rhughes@241: #include rhughes@241: #include rhughes@241: #include rhughes@241: #include rhughes@241: #include rhughes@241: #include rhughes@241: #include ali@325: #include ali@321: #ifdef HAVE_CURL rhughes@241: #include ali@321: #endif rhughes@241: #include rhughes@241: #include rhughes@241: #include "razor.h" rhughes@241: richard@310: static const char system_repo_filename[] = "system.rzdb"; richard@310: static const char next_repo_filename[] = "system-next.rzdb"; richard@310: static const char rawhide_repo_filename[] = "rawhide.rzdb"; krh@317: static const char *install_root = ""; rhughes@241: static const char *repo_filename = system_repo_filename; rhughes@241: static const char *yum_url; rhughes@241: krh@271: #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) krh@271: ali@363: static int ali@403: update_packages(struct razor_transaction *trans, ali@403: struct razor_install_iterator *ii, struct razor_set *system, ali@403: struct razor_set *next, struct razor_atomic *atomic, ali@403: struct razor_relocations *relocations, ali@403: enum razor_stage_type stage); ali@363: krh@281: static struct razor_package_iterator * krh@281: create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[]) rhughes@241: { krh@281: struct razor_package_query *query; krh@281: struct razor_package_iterator *iter; rhughes@241: struct razor_package *package; richard@302: const char *name, *pattern; krh@281: int i, count; rhughes@241: krh@281: if (argc == 0) krh@281: return razor_package_iterator_create(set); krh@281: krh@281: query = razor_package_query_create(set); krh@281: krh@281: for (i = 0; i < argc; i++) { krh@281: iter = razor_package_iterator_create(set); krh@281: pattern = argv[i]; krh@281: count = 0; richard@307: while (razor_package_iterator_next(iter, &package, richard@307: RAZOR_DETAIL_NAME, &name, richard@307: RAZOR_DETAIL_LAST)) { krh@281: if (fnmatch(pattern, name, 0) != 0) krh@281: continue; krh@281: krh@281: razor_package_query_add_package(query, package); krh@281: count++; krh@281: } krh@281: razor_package_iterator_destroy(iter); krh@281: krh@281: if (count == 0) krh@281: fprintf(stderr, krh@281: "no package matches \"%s\"\n", pattern); rhughes@241: } rhughes@241: krh@281: return razor_package_query_finish(query); krh@281: } krh@281: krh@281: #define LIST_PACKAGES_ONLY_NAMES 0x01 krh@281: krh@281: static void krh@281: list_packages(struct razor_package_iterator *iter, uint32_t flags) krh@281: { krh@281: struct razor_package *package; krh@281: const char *name, *version, *arch; krh@281: krh@281: while (razor_package_iterator_next(iter, &package, richard@302: RAZOR_DETAIL_NAME, &name, richard@302: RAZOR_DETAIL_VERSION, &version, richard@307: RAZOR_DETAIL_ARCH, &arch, richard@307: RAZOR_DETAIL_LAST)) { krh@281: if (flags & LIST_PACKAGES_ONLY_NAMES) rhughes@241: printf("%s\n", name); rhughes@241: else rhughes@241: printf("%s-%s.%s\n", name, version, arch); rhughes@241: } krh@281: } krh@281: krh@281: static int krh@281: command_list(int argc, const char *argv[]) krh@281: { krh@281: struct razor_package_iterator *pi; ali@403: struct razor_atomic *atomic; krh@281: struct razor_set *set; krh@281: uint32_t flags = 0; krh@281: int i = 0; krh@281: krh@281: if (i < argc && strcmp(argv[i], "--only-names") == 0) { krh@281: flags |= LIST_PACKAGES_ONLY_NAMES; krh@281: i++; krh@281: } krh@281: ali@403: atomic = razor_atomic_open("List installed packages"); ali@403: set = razor_root_open_read_only(install_root, atomic); ali@403: if (set == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); krh@317: return 1; ali@403: } krh@317: krh@281: pi = create_iterator_from_argv(set, argc - i, argv + i); krh@281: list_packages(pi, flags); rhughes@241: razor_package_iterator_destroy(pi); ali@403: razor_set_unref(set); ali@403: razor_atomic_destroy(atomic); rhughes@241: rhughes@241: return 0; rhughes@241: } rhughes@241: krh@306: static void krh@306: list_package_properties(struct razor_set *set, krh@306: struct razor_package *package, uint32_t type) rhughes@241: { krh@306: struct razor_property_iterator *pi; rhughes@241: struct razor_property *property; rhughes@241: const char *name, *version; krh@247: uint32_t flags; rhughes@241: rhughes@241: pi = razor_property_iterator_create(set, package); rhughes@241: while (razor_property_iterator_next(pi, &property, krh@247: &name, &flags, &version)) { krh@247: if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type) rhughes@241: continue; krh@247: printf("%s", name); krh@247: if (version[0] != '\0') krh@247: printf(" %s %s", krh@247: razor_property_relation_to_string(property), krh@247: version); krh@247: krh@247: if (flags & ~(RAZOR_PROPERTY_RELATION_MASK | RAZOR_PROPERTY_TYPE_MASK)) { krh@247: printf(" ["); krh@247: if (flags & RAZOR_PROPERTY_PRE) krh@247: printf(" pre"); krh@247: if (flags & RAZOR_PROPERTY_POST) krh@247: printf(" post"); krh@247: if (flags & RAZOR_PROPERTY_PREUN) krh@247: printf(" preun"); krh@247: if (flags & RAZOR_PROPERTY_POSTUN) krh@247: printf(" postun"); krh@247: printf(" ]"); krh@247: } krh@247: printf("\n"); rhughes@241: } rhughes@241: razor_property_iterator_destroy(pi); krh@306: } rhughes@241: krh@306: static int krh@306: list_properties(int argc, const char *argv[], uint32_t type) krh@306: { krh@306: struct razor_set *set; ali@403: struct razor_atomic *atomic; krh@306: struct razor_package *package; krh@306: struct razor_package_iterator *pi; krh@306: const char *name, *version, *arch; krh@306: ali@403: atomic = razor_atomic_open("List package properties"); ali@403: set = razor_root_open_read_only(install_root, atomic); ali@403: if (set == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); krh@317: return 1; ali@403: } krh@317: krh@306: pi = create_iterator_from_argv(set, argc, argv); krh@306: while (razor_package_iterator_next(pi, &package, richard@307: RAZOR_DETAIL_NAME, &name, richard@307: RAZOR_DETAIL_VERSION, &version, richard@307: RAZOR_DETAIL_ARCH, &arch, richard@307: RAZOR_DETAIL_LAST)) krh@306: list_package_properties(set, package, type); krh@306: razor_package_iterator_destroy(pi); ali@403: razor_set_unref(set); ali@403: razor_atomic_destroy(atomic); rhughes@241: rhughes@241: return 0; rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_list_requires(int argc, const char *argv[]) rhughes@241: { krh@306: return list_properties(argc, argv, RAZOR_PROPERTY_REQUIRES); rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_list_provides(int argc, const char *argv[]) rhughes@241: { krh@306: return list_properties(argc, argv, RAZOR_PROPERTY_PROVIDES); rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_list_obsoletes(int argc, const char *argv[]) rhughes@241: { krh@306: return list_properties(argc, argv, RAZOR_PROPERTY_OBSOLETES); rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_list_conflicts(int argc, const char *argv[]) rhughes@241: { krh@306: return list_properties(argc, argv, RAZOR_PROPERTY_CONFLICTS); rhughes@241: } rhughes@241: rhughes@241: static int ali@369: command_list_scripts(int argc, const char *argv[]) ali@369: { ali@369: struct razor_set *set; ali@403: struct razor_atomic *atomic; ali@369: struct razor_package *package; ali@369: struct razor_package_iterator *pi; ali@369: const char *preunprog, *preun, *postunprog, *postun; ali@369: ali@403: atomic = razor_atomic_open("List package scripts"); ali@403: set = razor_root_open_read_only(install_root, atomic); ali@403: if (set == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); ali@369: return 1; ali@403: } ali@369: ali@369: pi = create_iterator_from_argv(set, argc, argv); ali@369: while (razor_package_iterator_next(pi, &package, ali@369: RAZOR_DETAIL_PREUNPROG, &preunprog, ali@369: RAZOR_DETAIL_PREUN, &preun, ali@369: RAZOR_DETAIL_POSTUNPROG, &postunprog, ali@369: RAZOR_DETAIL_POSTUN, &postun, ali@369: RAZOR_DETAIL_LAST)) { ali@369: if (preun && *preun) { ali@369: printf("preuninstall scriptlet"); ali@369: if (preunprog && *preunprog) ali@369: printf(" (using %s)",preunprog); ali@369: printf(":\n%s\n",preun); ali@369: } ali@369: if (postun && *postun) { ali@369: printf("postuninstall scriptlet"); ali@369: if (postunprog && *postunprog) ali@369: printf(" (using %s)",postunprog); ali@369: printf(":\n%s\n",postun); ali@369: } ali@369: } ali@369: razor_package_iterator_destroy(pi); ali@403: razor_set_unref(set); ali@403: razor_atomic_destroy(atomic); ali@369: ali@369: return 0; ali@369: } ali@369: ali@369: static int rhughes@241: command_list_files(int argc, const char *argv[]) rhughes@241: { ali@403: struct razor_atomic *atomic; rhughes@241: struct razor_set *set; rhughes@241: ali@403: atomic = razor_atomic_open("List package files"); ali@403: set = razor_root_open_read_only(install_root, atomic); ali@403: if (set == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; ali@403: } krh@317: rhughes@241: razor_set_list_files(set, argv[0]); ali@403: razor_set_unref(set); ali@403: razor_atomic_destroy(atomic); rhughes@241: rhughes@241: return 0; rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_list_file_packages(int argc, const char *argv[]) rhughes@241: { ali@403: struct razor_atomic *atomic; rhughes@241: struct razor_set *set; rhughes@241: struct razor_package_iterator *pi; rhughes@241: ali@403: atomic = razor_atomic_open("List file packages"); ali@403: set = razor_root_open_read_only(install_root, atomic); ali@403: if (set == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; ali@403: } rhughes@241: rhughes@241: pi = razor_package_iterator_create_for_file(set, argv[0]); krh@281: list_packages(pi, 0); rhughes@241: razor_package_iterator_destroy(pi); rhughes@241: ali@403: razor_set_unref(set); ali@403: razor_atomic_destroy(atomic); rhughes@241: rhughes@241: return 0; rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_list_package_files(int argc, const char *argv[]) rhughes@241: { ali@403: struct razor_atomic *atomic; rhughes@241: struct razor_set *set; krh@306: struct razor_package_iterator *pi; krh@306: struct razor_package *package; krh@306: const char *name, *version, *arch; rhughes@241: ali@403: atomic = razor_atomic_open("List package files"); ali@403: set = razor_root_open_read_only(install_root, atomic); ali@403: if (set == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; ali@403: } jbowes@288: krh@306: pi = create_iterator_from_argv(set, argc, argv); krh@306: while (razor_package_iterator_next(pi, &package, richard@307: RAZOR_DETAIL_NAME, &name, richard@307: RAZOR_DETAIL_VERSION, &version, richard@307: RAZOR_DETAIL_ARCH, &arch, richard@307: RAZOR_DETAIL_LAST)) krh@306: razor_set_list_package_files(set, package); krh@306: razor_package_iterator_destroy(pi); krh@306: ali@403: razor_set_unref(set); ali@403: razor_atomic_destroy(atomic); rhughes@241: rhughes@241: return 0; rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: list_property_packages(const char *ref_name, rhughes@241: const char *ref_version, krh@247: uint32_t type) rhughes@241: { ali@403: struct razor_atomic *atomic; rhughes@241: struct razor_set *set; rhughes@241: struct razor_property *property; krh@281: struct razor_property_iterator *prop_iter; krh@281: struct razor_package_iterator *pkg_iter; rhughes@241: const char *name, *version; krh@247: uint32_t flags; rhughes@241: rhughes@241: if (ref_name == NULL) rhughes@241: return 0; rhughes@241: ali@403: atomic = razor_atomic_open("List package properties"); ali@403: set = razor_root_open_read_only(install_root, atomic); ali@403: if (set == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; ali@403: } rhughes@241: krh@281: prop_iter = razor_property_iterator_create(set, NULL); krh@281: while (razor_property_iterator_next(prop_iter, &property, krh@247: &name, &flags, &version)) { rhughes@241: if (strcmp(ref_name, name) != 0) rhughes@241: continue; krh@247: if (ref_version && krh@247: (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL && rhughes@241: strcmp(ref_version, version) != 0) rhughes@241: continue; krh@247: if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type) rhughes@241: continue; rhughes@241: krh@281: pkg_iter = krh@281: razor_package_iterator_create_for_property(set, krh@281: property); krh@281: list_packages(pkg_iter, 0); krh@281: razor_package_iterator_destroy(pkg_iter); rhughes@241: } krh@281: razor_property_iterator_destroy(prop_iter); rhughes@241: ali@403: razor_set_unref(set); ali@403: razor_atomic_destroy(atomic); krh@317: rhughes@241: return 0; rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_what_requires(int argc, const char *argv[]) rhughes@241: { rhughes@241: return list_property_packages(argv[0], argv[1], rhughes@241: RAZOR_PROPERTY_REQUIRES); rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_what_provides(int argc, const char *argv[]) rhughes@241: { rhughes@241: return list_property_packages(argv[0], argv[1], rhughes@241: RAZOR_PROPERTY_PROVIDES); rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: show_progress(void *clientp, rhughes@241: double dltotal, double dlnow, double ultotal, double ulnow) rhughes@241: { rhughes@241: const char *file = clientp; rhughes@241: rhughes@241: if (!dlnow < dltotal) rhughes@241: fprintf(stderr, "\rdownloading %s, %dkB/%dkB", rhughes@241: file, (int) dlnow / 1024, (int) dltotal / 1024); rhughes@241: rhughes@241: return 0; rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: download_if_missing(const char *url, const char *file) rhughes@241: { ali@321: #ifndef HAVE_CURL ali@321: return 1; ali@321: #else rhughes@241: CURL *curl; rhughes@241: struct stat buf; rhughes@241: char error[256]; rhughes@241: FILE *fp; rhughes@241: CURLcode res; rhughes@241: long response; rhughes@241: rhughes@241: curl = curl_easy_init(); rhughes@241: if (curl == NULL) rhughes@241: return 1; rhughes@241: rhughes@241: curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error); rhughes@241: curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); rhughes@241: curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress); rhughes@241: curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file); rhughes@241: rhughes@241: if (stat(file, &buf) < 0) { ali@345: fp = fopen(file, "wb"); rhughes@241: if (fp == NULL) { rhughes@241: fprintf(stderr, rhughes@241: "failed to open %s for writing\n", file); rhughes@241: return -1; rhughes@241: } rhughes@241: curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); rhughes@241: curl_easy_setopt(curl, CURLOPT_URL, url); rhughes@241: res = curl_easy_perform(curl); rhughes@241: fclose(fp); rhughes@241: if (res != CURLE_OK) { rhughes@241: fprintf(stderr, "curl error: %s\n", error); rhughes@241: unlink(file); rhughes@241: return -1; rhughes@241: } rhughes@241: res = curl_easy_getinfo(curl, rhughes@241: CURLINFO_RESPONSE_CODE, &response); rhughes@241: if (res != CURLE_OK) { rhughes@241: fprintf(stderr, "curl error: %s\n", error); rhughes@241: unlink(file); rhughes@241: return -1; rhughes@241: } rhughes@241: if (response != 200) { rhughes@241: fprintf(stderr, " - failed %ld\n", response); rhughes@241: unlink(file); rhughes@241: return -1; rhughes@241: } rhughes@241: fprintf(stderr, "\n"); rhughes@241: } rhughes@241: rhughes@241: curl_easy_cleanup(curl); rhughes@241: rhughes@241: return 0; ali@321: #endif /* HAVE_CURL */ rhughes@241: } rhughes@241: rhughes@241: #define YUM_URL "http://download.fedora.redhat.com" \ rhughes@241: "/pub/fedora/linux/development/i386/os" rhughes@241: rhughes@241: static int rhughes@241: command_import_yum(int argc, const char *argv[]) rhughes@241: { ali@403: int retval; rhughes@241: struct razor_set *set; ali@403: struct razor_atomic *atomic; rhughes@241: char buffer[512]; rhughes@241: rhughes@241: printf("downloading from %s.\n", yum_url); rhughes@241: snprintf(buffer, sizeof buffer, rhughes@241: "%s/repodata/primary.xml.gz", yum_url); rhughes@241: if (download_if_missing(buffer, "primary.xml.gz") < 0) rhughes@241: return -1; rhughes@241: snprintf(buffer, sizeof buffer, rhughes@241: "%s/repodata/filelists.xml.gz", yum_url); rhughes@241: if (download_if_missing(buffer, "filelists.xml.gz") < 0) rhughes@241: return -1; rhughes@241: rhughes@241: set = razor_set_create_from_yum(); rhughes@241: if (set == NULL) rhughes@241: return 1; ali@403: atomic = razor_atomic_open("Yum import repository"); ali@403: razor_set_write(set, atomic, rawhide_repo_filename, RAZOR_SECTION_ALL); ali@403: retval = razor_atomic_commit(atomic); ali@403: razor_set_unref(set); ali@403: if (retval) ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: else ali@403: printf("wrote %s\n", rawhide_repo_filename); ali@403: razor_atomic_destroy(atomic); rhughes@241: ali@403: return retval; rhughes@241: } rhughes@241: ali@320: #if HAVE_RPMLIB rhughes@241: static int rhughes@241: command_import_rpmdb(int argc, const char *argv[]) rhughes@241: { rhughes@241: struct razor_set *set; krh@317: struct razor_root *root; ali@403: struct razor_atomic *atomic; ali@403: int retval; krh@317: ali@403: atomic = razor_atomic_open("Import RPM database"); ali@403: ali@403: root = razor_root_open(install_root, atomic); ali@403: if (root == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); krh@317: return 1; ali@403: } rhughes@241: rhughes@241: set = razor_set_create_from_rpmdb(); rhughes@241: if (set == NULL) rhughes@241: return 1; rhughes@241: krh@317: razor_root_update(root, set); krh@317: ali@403: retval = razor_root_commit(root); ali@403: if (retval) ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: ali@403: razor_atomic_destroy(atomic); ali@403: ali@403: return retval; rhughes@241: } ali@320: #endif rhughes@241: rhughes@241: static int rhughes@241: mark_packages_for_update(struct razor_transaction *trans, rhughes@241: struct razor_set *set, const char *pattern) rhughes@241: { rhughes@241: struct razor_package_iterator *pi; rhughes@241: struct razor_package *package; richard@302: const char *name; rhughes@241: int matches = 0; rhughes@241: rhughes@241: pi = razor_package_iterator_create(set); rhughes@241: while (razor_package_iterator_next(pi, &package, richard@307: RAZOR_DETAIL_NAME, &name, richard@307: RAZOR_DETAIL_LAST)) { rhughes@241: if (pattern && fnmatch(pattern, name, 0) == 0) { rhughes@241: razor_transaction_update_package(trans, package); rhughes@241: matches++; rhughes@241: } rhughes@241: } rhughes@241: razor_package_iterator_destroy(pi); rhughes@241: rhughes@241: return matches; rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: mark_packages_for_removal(struct razor_transaction *trans, rhughes@241: struct razor_set *set, const char *pattern) rhughes@241: { rhughes@241: struct razor_package_iterator *pi; rhughes@241: struct razor_package *package; richard@302: const char *name; rhughes@241: int matches = 0; rhughes@241: rhughes@241: pi = razor_package_iterator_create(set); richard@307: while (razor_package_iterator_next(pi, &package, richard@307: RAZOR_DETAIL_NAME, &name, richard@307: RAZOR_DETAIL_LAST)) { rhughes@241: if (pattern && fnmatch(pattern, name, 0) == 0) { rhughes@241: razor_transaction_remove_package(trans, package); rhughes@241: matches++; rhughes@241: } rhughes@241: } rhughes@241: razor_package_iterator_destroy(pi); rhughes@241: rhughes@241: return matches; rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_remove(int argc, const char *argv[]) rhughes@241: { ali@363: struct razor_root *root; ali@363: struct razor_set *system, *upstream, *next; rhughes@241: struct razor_transaction *trans; ali@403: struct razor_atomic *atomic; ali@403: struct razor_install_iterator *ii; ali@403: int i, retval; rhughes@241: ali@403: atomic = razor_atomic_open("Remove packages"); ali@403: ali@403: root = razor_root_open(install_root, atomic); ali@403: system = razor_set_ref(razor_root_get_system_set(root)); ali@363: if (system == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@363: razor_root_close(root); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; ali@363: } rhughes@241: ali@363: upstream = razor_set_create_without_root(); ali@363: trans = razor_transaction_create(system, upstream); ali@403: razor_set_unref(upstream); rhughes@241: for (i = 0; i < argc; i++) { ali@363: if (mark_packages_for_removal(trans, system, argv[i]) == 0) { rhughes@241: fprintf(stderr, "no match for %s\n", argv[i]); ali@363: razor_transaction_destroy(trans); ali@403: razor_set_unref(system); ali@363: razor_root_close(root); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; rhughes@241: } rhughes@241: } rhughes@241: ali@350: razor_transaction_resolve(trans); ali@403: retval = razor_transaction_describe(trans); ali@403: if (retval) { ali@363: razor_transaction_destroy(trans); ali@403: razor_set_unref(system); ali@363: razor_root_close(root); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; ali@363: } rhughes@241: ali@369: next = razor_transaction_commit(trans); ali@403: ii = razor_set_create_install_iterator(system, next); ali@403: update_packages(trans, ii, system, next, atomic, NULL, ali@403: RAZOR_STAGE_SCRIPTS_PRE); ali@403: update_packages(trans, ii, system, next, atomic, NULL, ali@403: RAZOR_STAGE_FILES); ali@403: ali@363: razor_root_update(root, next); ali@363: ali@403: (void)razor_root_commit(root); ali@403: retval = razor_atomic_commit(atomic); ali@403: if (retval) ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: else ali@403: update_packages(trans, ii, system, next, atomic, NULL, ali@403: RAZOR_STAGE_SCRIPTS_POST); ali@403: razor_install_iterator_destroy(ii); ali@403: ali@369: razor_transaction_destroy(trans); ali@403: razor_atomic_destroy(atomic); ali@403: razor_set_unref(system); ali@403: razor_set_unref(next); rhughes@241: ali@403: return retval; rhughes@241: } rhughes@241: rhughes@241: static void krh@253: print_diff(enum razor_diff_action action, krh@253: struct razor_package *package, krh@253: const char *name, krh@253: const char *version, krh@253: const char *arch, rhughes@241: void *data) rhughes@241: { krh@253: if (action == RAZOR_DIFF_ACTION_ADD) krh@253: printf("install %s-%s.%s\n", name, version, arch); krh@253: if (action == RAZOR_DIFF_ACTION_REMOVE) krh@253: printf("remove %s-%s.%s\n", name, version, arch); rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_diff(int argc, const char *argv[]) rhughes@241: { ali@403: struct razor_atomic *atomic; rhughes@241: struct razor_set *set, *updated; rhughes@241: ali@403: atomic = razor_atomic_open("Show package differences"); ali@403: set = razor_root_open_read_only(install_root, atomic); ali@403: updated = razor_set_open(rawhide_repo_filename, atomic); ali@403: if (set == NULL || updated == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; ali@403: } rhughes@241: rhughes@241: razor_set_diff(set, updated, print_diff, NULL); rhughes@241: ali@403: razor_set_unref(set); ali@403: razor_set_unref(updated); ali@403: razor_atomic_destroy(atomic); rhughes@241: rhughes@241: return 0; rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_import_rpms(int argc, const char *argv[]) rhughes@241: { rhughes@241: DIR *dir; rhughes@241: struct dirent *de; rhughes@241: struct razor_importer *importer; rhughes@241: struct razor_set *set; rhughes@241: struct razor_rpm *rpm; ali@403: struct razor_atomic *atomic; jbowes@263: int len, imported_count = 0; rhughes@241: char filename[256]; rhughes@241: const char *dirname = argv[0]; ali@403: int retval; rhughes@241: rhughes@241: if (dirname == NULL) { rhughes@241: fprintf(stderr, "usage: razor import-rpms DIR\n"); rhughes@241: return -1; rhughes@241: } rhughes@241: rhughes@241: dir = opendir(dirname); rhughes@241: if (dir == NULL) { rhughes@241: fprintf(stderr, "couldn't read dir %s\n", dirname); rhughes@241: return -1; rhughes@241: } rhughes@241: krh@249: importer = razor_importer_create(); rhughes@241: rhughes@241: while (de = readdir(dir), de != NULL) { rhughes@241: len = strlen(de->d_name); rhughes@241: if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0) ali@403: continue; rhughes@241: snprintf(filename, sizeof filename, rhughes@241: "%s/%s", dirname, de->d_name); ali@403: atomic = razor_atomic_open("Read RPM"); ali@403: rpm = razor_rpm_open(filename, atomic); ali@403: if (rpm == NULL) ali@403: fprintf(stderr, "%s\n", ali@403: razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); ali@403: if (rpm == NULL) rhughes@241: continue; rhughes@241: if (razor_importer_add_rpm(importer, rpm)) { rhughes@241: fprintf(stderr, "couldn't import %s\n", filename); rhughes@241: break; rhughes@241: } rhughes@241: razor_rpm_close(rpm); jbowes@263: jbowes@263: printf("\rimporting %d", ++imported_count); jbowes@263: fflush(stdout); rhughes@241: } rhughes@241: rhughes@241: if (de != NULL) { rhughes@241: razor_importer_destroy(importer); rhughes@241: return -1; rhughes@241: } rhughes@241: jbowes@263: printf("\nsaving\n"); rhughes@241: set = razor_importer_finish(importer); rhughes@241: ali@403: atomic = razor_atomic_open("Update system database"); ali@403: razor_set_write(set, atomic, repo_filename, RAZOR_SECTION_ALL); ali@403: razor_set_unref(set); ali@403: retval = razor_atomic_commit(atomic); ali@403: if (retval) ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: else ali@403: printf("wrote %s\n", repo_filename); ali@403: razor_atomic_destroy(atomic); rhughes@241: ali@403: return retval; rhughes@241: } rhughes@241: ali@403: static char * krh@254: rpm_filename(const char *name, const char *version, const char *arch) rhughes@241: { krh@254: const char *v; krh@254: krh@254: /* Skip epoch */ krh@253: v = strchr(version, ':'); krh@254: if (v != NULL) krh@254: v = v + 1; krh@254: else krh@253: v = version; rhughes@241: ali@403: return razor_concat(name, "-", v, ".", arch, ".rpm", NULL); rhughes@241: } rhughes@241: krh@254: static int krh@254: download_packages(struct razor_set *system, struct razor_set *next) rhughes@241: { krh@316: struct razor_install_iterator *ii; krh@254: struct razor_package *package; krh@316: enum razor_install_action action; krh@254: const char *name, *version, *arch; ali@403: char *file, *url, *s; krh@316: int errors = 0, count; krh@316: krh@316: ii = razor_set_create_install_iterator(system, next); ali@382: while (razor_install_iterator_next(ii, &package, &action, &count)) { krh@316: if (action == RAZOR_INSTALL_ACTION_REMOVE) krh@316: continue; krh@316: ali@382: razor_package_get_details(next, package, krh@316: RAZOR_DETAIL_NAME, &name, krh@316: RAZOR_DETAIL_VERSION, &version, krh@316: RAZOR_DETAIL_ARCH, &arch, krh@316: RAZOR_DETAIL_LAST); krh@316: ali@403: s = rpm_filename(name, version, arch); ali@403: url = razor_concat(yum_url, "/Packages/", s, NULL); ali@403: file = razor_concat("rpms/", s, NULL); ali@403: free(s); krh@254: if (download_if_missing(url, file) < 0) krh@254: errors++; ali@403: free(file); ali@403: free(url); krh@254: } krh@316: razor_install_iterator_destroy(ii); krh@254: krh@254: if (errors > 0) { krh@254: fprintf(stderr, "failed to download %d packages\n", errors); krh@254: return -1; krh@254: } krh@254: krh@254: return 0; krh@254: } krh@254: ali@351: static struct razor_set * ali@403: relocate_packages(struct razor_set *set, struct razor_atomic *atomic, ali@403: struct razor_relocations *relocations) ali@351: { ali@372: int i; ali@351: struct razor_importer *importer; ali@351: struct razor_property_iterator *prop_iter; ali@351: struct razor_package_iterator *pkg_iter; ali@351: struct razor_file_iterator *file_iter; ali@351: struct razor_package *package; ali@351: struct razor_property *property; ali@351: struct razor_rpm *rpm; ali@351: const char *name, *version, *arch, *summary, *desc, *url, *license; ali@369: const char *preunprog, *preun, *postunprog, *postun; ali@372: const char *install_prefix; ali@372: const char *const *prefixes; ali@403: char *file, *s; ali@351: uint32_t flags; ali@351: ali@351: importer = razor_importer_create(); ali@351: pkg_iter = razor_package_iterator_create(set); ali@351: ali@351: while (razor_package_iterator_next(pkg_iter, &package, ali@351: RAZOR_DETAIL_NAME, &name, ali@351: RAZOR_DETAIL_VERSION, &version, ali@351: RAZOR_DETAIL_ARCH, &arch, ali@351: RAZOR_DETAIL_SUMMARY, &summary, ali@351: RAZOR_DETAIL_DESCRIPTION, &desc, ali@351: RAZOR_DETAIL_URL, &url, ali@351: RAZOR_DETAIL_LICENSE, &license, ali@369: RAZOR_DETAIL_PREUNPROG, &preunprog, ali@369: RAZOR_DETAIL_PREUN, &preun, ali@369: RAZOR_DETAIL_POSTUNPROG, &postunprog, ali@369: RAZOR_DETAIL_POSTUN, &postun, ali@351: RAZOR_DETAIL_LAST)) { ali@403: s = rpm_filename(name, version, arch); ali@403: file = razor_concat("rpms/", s, NULL); ali@403: free(s); ali@403: rpm = razor_rpm_open(file, atomic); ali@403: free(file); ali@351: if (rpm == NULL) { ali@351: razor_package_iterator_destroy(pkg_iter); ali@351: razor_importer_destroy(importer); ali@351: return NULL; ali@351: } ali@351: ali@351: razor_relocations_set_rpm(relocations, rpm); ali@351: ali@351: razor_importer_begin_package(importer, name, version, arch); ali@351: razor_importer_add_details(importer, ali@351: summary, desc, url, license); ali@351: ali@372: razor_rpm_get_details(rpm, RAZOR_DETAIL_PREFIXES, &prefixes, ali@372: RAZOR_DETAIL_LAST); ali@372: for (i = 0; prefixes && prefixes[i]; i++) { ali@372: install_prefix = razor_relocations_apply(relocations, ali@372: prefixes[i]); ali@372: razor_importer_add_install_prefix(importer, ali@372: install_prefix); ali@372: } ali@372: ali@372: razor_rpm_close(rpm); ali@372: ali@351: prop_iter = razor_property_iterator_create(set, package); ali@351: while (razor_property_iterator_next(prop_iter, &property, ali@351: &name, &flags, &version)) ali@351: razor_importer_add_property(importer, ali@351: name, flags, version); ali@351: razor_property_iterator_destroy(prop_iter); ali@351: ali@377: file_iter = razor_file_iterator_create(set, package, 0); ali@351: while (razor_file_iterator_next(file_iter, &name)) { ali@351: name = razor_relocations_apply(relocations, name); ali@351: razor_importer_add_file(importer, name); ali@351: } ali@351: razor_file_iterator_destroy(file_iter); ali@351: ali@369: razor_importer_add_script(importer, RAZOR_PROPERTY_PREUN, ali@369: preunprog, preun); ali@369: razor_importer_add_script(importer, RAZOR_PROPERTY_POSTUN, ali@369: postunprog, postun); ali@369: ali@351: razor_importer_finish_package(importer); ali@351: } ali@351: ali@351: razor_package_iterator_destroy(pkg_iter); ali@351: return razor_importer_finish(importer); ali@351: } ali@351: krh@254: static int ali@369: install_package(struct razor_transaction *trans, struct razor_set *set, ali@403: struct razor_atomic *atomic, struct razor_package *package, ali@403: struct razor_relocations *relocations, int install_count, ali@403: enum razor_stage_type stage) ali@363: { ali@363: int retval; ali@363: const char *name, *version, *arch; ali@403: char *file, *s; ali@363: struct razor_rpm *rpm; ali@363: ali@363: razor_package_get_details(set, package, ali@363: RAZOR_DETAIL_NAME, &name, ali@363: RAZOR_DETAIL_VERSION, &version, ali@363: RAZOR_DETAIL_ARCH, &arch, ali@363: RAZOR_DETAIL_LAST); ali@363: ali@403: if (stage & RAZOR_STAGE_SCRIPTS_PRE) ali@403: printf("install %s-%s\n", name, version); ali@363: ali@403: s = rpm_filename(name, version, arch); ali@403: file = razor_concat("rpms/", s, NULL); ali@403: free(s); ali@403: rpm = razor_rpm_open(file, atomic); ali@403: free(file); ali@363: if (rpm == NULL) { ali@403: fprintf(stderr, "%s\n", ali@403: razor_atomic_get_error_msg(atomic)); ali@363: return -1; ali@363: } ali@363: if (relocations) ali@363: razor_rpm_set_relocations(rpm, relocations); ali@369: razor_transaction_fixup_package(trans, package, rpm); ali@403: retval = razor_rpm_install(rpm, atomic, install_root, install_count, ali@403: stage); ali@403: if (retval < 0) { ali@403: s = rpm_filename(name, version, arch); ali@403: fprintf(stderr, "%s: %s\n", s, ali@403: razor_atomic_get_error_msg(atomic)); ali@403: free(s); ali@403: } ali@363: razor_rpm_close(rpm); ali@363: return retval; ali@363: } ali@363: ali@363: static int ali@403: update_packages(struct razor_transaction *trans, ali@403: struct razor_install_iterator *ii, struct razor_set *system, ali@403: struct razor_set *next, struct razor_atomic *atomic, ali@403: struct razor_relocations *relocations, ali@403: enum razor_stage_type stage) krh@254: { krh@254: struct razor_package *package; krh@316: enum razor_install_action action; ali@363: int retval = 0, count; rhughes@241: ali@403: razor_install_iterator_rewind(ii); ali@403: ali@382: while (!retval && razor_install_iterator_next(ii, &package, ali@363: &action, &count)) { ali@363: if (action == RAZOR_INSTALL_ACTION_ADD) ali@403: retval = install_package(trans, next, atomic, package, ali@403: relocations, count, stage); ali@363: else if (action == RAZOR_INSTALL_ACTION_REMOVE) ali@403: retval = razor_package_remove(system, next, atomic, ali@403: package, install_root, ali@403: count, stage); rhughes@241: } rhughes@241: ali@363: return retval; rhughes@241: } rhughes@241: rhughes@241: static int ali@382: command_install_or_update(int argc, const char *argv[], int do_update) rhughes@241: { rhughes@241: struct razor_root *root; ali@351: struct razor_relocations *relocations=NULL; ali@351: struct razor_set *system, *upstream, *next, *set; rhughes@241: struct razor_transaction *trans; ali@403: struct razor_atomic *atomic; ali@403: struct razor_install_iterator *ii; ali@403: int i, retval, len, dependencies = 1; ali@351: char *oldpath; rhughes@241: ali@403: if (do_update) ali@403: atomic = razor_atomic_open("Update packages"); ali@403: else ali@403: atomic = razor_atomic_open("Install packages"); ali@403: ali@403: root = razor_root_open(install_root, atomic); ali@403: if (root == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); krh@255: return 1; ali@403: } krh@255: ali@351: for (i = 0; i < argc; i++) { ali@351: if (strcmp(argv[i], "--no-dependencies") == 0) ali@351: dependencies = 0; ali@351: else if (strcmp(argv[i], "--relocate") == 0) { ali@351: i++; ali@351: if (i >= argc || strchr(argv[i], '=') == NULL) { ali@351: fprintf(stderr, ali@382: "Usage: razor %s [OPTION...] RPM\n", ali@382: do_update ? "update" : "install"); ali@351: fprintf(stderr, "Options:\n"); ali@351: fprintf(stderr, " [--no-dependencies]\n"); ali@351: fprintf(stderr, ali@351: " [--relocate OLDPATH=NEWPATH] RPM\n"); ali@351: return -1; ali@351: } ali@351: len = strchr(argv[i], '=') - argv[i]; ali@351: oldpath = malloc(len + 1); ali@351: strncpy(oldpath, argv[i], len); ali@351: oldpath[len] = '\0'; ali@351: if (!relocations) ali@351: relocations = razor_relocations_create(); ali@351: razor_relocations_add(relocations, oldpath, ali@351: argv[i] + len + 1); ali@351: free(oldpath); ali@351: } else ali@351: break; ali@351: } ali@351: ali@403: upstream = razor_set_open(rawhide_repo_filename, atomic); krh@373: if (upstream == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); krh@373: razor_root_close(root); ali@403: razor_atomic_destroy(atomic); krh@373: return 1; ali@382: } krh@315: ali@351: if (relocations) { ali@403: set = relocate_packages(upstream, atomic, relocations); ali@403: if (set == NULL) { ali@403: fprintf(stderr, "%s\n", ali@403: razor_atomic_get_error_msg(atomic)); ali@403: razor_root_close(root); ali@403: razor_atomic_destroy(atomic); ali@403: razor_set_unref(upstream); ali@403: return 1; ali@403: } ali@403: razor_set_unref(upstream); ali@351: upstream = set; ali@351: } ali@351: ali@403: system = razor_set_ref(razor_root_get_system_set(root)); ali@403: krh@250: trans = razor_transaction_create(system, upstream); rhughes@241: ali@382: if (i == argc && do_update) ali@382: razor_transaction_update_all(trans); rhughes@241: for (; i < argc; i++) { ali@389: if (do_update && ali@389: mark_packages_for_update(trans, system, argv[i])) ali@389: continue; rhughes@241: if (mark_packages_for_update(trans, upstream, argv[i]) == 0) { rhughes@241: fprintf(stderr, "no package matched %s\n", argv[i]); ali@369: razor_transaction_destroy(trans); ali@403: razor_set_unref(upstream); ali@403: razor_set_unref(system); rhughes@241: razor_root_close(root); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; rhughes@241: } rhughes@241: } rhughes@241: rhughes@241: if (dependencies) { krh@245: razor_transaction_resolve(trans); krh@245: if (razor_transaction_describe(trans) > 0) { ali@369: razor_transaction_destroy(trans); ali@403: razor_set_unref(upstream); ali@403: razor_set_unref(system); rhughes@241: razor_root_close(root); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; rhughes@241: } rhughes@241: } rhughes@241: ali@403: if (razor_atomic_create_dir(atomic, "rpms", ali@403: S_IRWXU | S_IRWXG | S_IRWXO)) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@369: razor_transaction_destroy(trans); ali@403: razor_set_unref(upstream); ali@403: razor_set_unref(system); rhughes@241: razor_root_close(root); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; rhughes@241: } rhughes@241: ali@382: next = razor_transaction_commit(trans); ali@382: krh@254: if (download_packages(system, next) < 0) { ali@403: razor_set_unref(next); ali@369: razor_transaction_destroy(trans); ali@403: razor_set_unref(upstream); ali@403: razor_set_unref(system); rhughes@241: razor_root_close(root); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; rhughes@241: } rhughes@241: ali@403: ii = razor_set_create_install_iterator(system, next); ali@403: ali@403: update_packages(trans, ii, system, next, atomic, relocations, ali@403: RAZOR_STAGE_SCRIPTS_PRE); ali@403: update_packages(trans, ii, system, next, atomic, relocations, ali@403: RAZOR_STAGE_FILES); rhughes@241: ali@369: razor_root_update(root, next); ali@369: ali@403: razor_set_unref(upstream); ali@403: ali@403: (void)razor_root_commit(root); ali@403: retval = razor_atomic_commit(atomic); ali@403: if (retval) ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: else ali@403: update_packages(trans, ii, system, next, atomic, relocations, ali@403: RAZOR_STAGE_SCRIPTS_POST); ali@403: ali@369: razor_transaction_destroy(trans); ali@351: if (relocations) ali@351: razor_relocations_destroy(relocations); ali@403: razor_install_iterator_destroy(ii); rhughes@241: ali@403: razor_atomic_destroy(atomic); ali@403: ali@403: razor_set_unref(next); ali@403: razor_set_unref(system); ali@403: ali@403: return retval; rhughes@241: } rhughes@241: rhughes@241: static int ali@382: command_update(int argc, const char *argv[]) ali@382: { ali@382: return command_install_or_update(argc, argv, 1); ali@382: } ali@382: ali@382: static int ali@382: command_install(int argc, const char *argv[]) ali@382: { ali@382: return command_install_or_update(argc, argv, 0); ali@382: } ali@382: ali@382: static int rhughes@241: command_init(int argc, const char *argv[]) rhughes@241: { rhughes@241: return razor_root_create(install_root); rhughes@241: } rhughes@241: rhughes@241: static int rhughes@241: command_download(int argc, const char *argv[]) rhughes@241: { ali@403: struct razor_atomic *atomic; rhughes@241: struct razor_set *set; rhughes@241: struct razor_package_iterator *pi; rhughes@241: struct razor_package *package; rhughes@241: const char *pattern = argv[0], *name, *version, *arch; rhughes@241: char url[256], file[256]; rhughes@241: int matches = 0; rhughes@241: ali@403: atomic = razor_atomic_open("Download packages"); ali@403: ali@403: if (razor_atomic_create_dir(atomic, "rpms", ali@403: S_IRWXU | S_IRWXG | S_IRWXO)) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); rhughes@241: return 1; rhughes@241: } rhughes@241: ali@403: set = razor_set_open(rawhide_repo_filename, atomic); ali@403: ali@403: if (razor_atomic_commit(atomic)) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); ali@403: return 1; ali@403: } ali@403: razor_atomic_destroy(atomic); ali@403: rhughes@241: pi = razor_package_iterator_create(set); rhughes@241: while (razor_package_iterator_next(pi, &package, richard@302: RAZOR_DETAIL_NAME, &name, richard@302: RAZOR_DETAIL_VERSION, &version, richard@307: RAZOR_DETAIL_ARCH, &arch, richard@307: RAZOR_DETAIL_LAST)) { rhughes@241: if (pattern && fnmatch(pattern, name, 0) != 0) rhughes@241: continue; rhughes@241: rhughes@241: matches++; rhughes@241: snprintf(url, sizeof url, rhughes@241: "%s/Packages/%s-%s.%s.rpm", rhughes@241: yum_url, name, version, arch); rhughes@241: snprintf(file, sizeof file, rhughes@241: "rpms/%s-%s.%s.rpm", name, version, arch); rhughes@241: download_if_missing(url, file); rhughes@241: } rhughes@241: razor_package_iterator_destroy(pi); ali@403: razor_set_unref(set); rhughes@241: rhughes@241: if (matches == 0) rhughes@241: fprintf(stderr, "no packages matched \"%s\"\n", pattern); rhughes@241: else if (matches == 1) rhughes@241: fprintf(stderr, "downloaded 1 package\n"); rhughes@241: else rhughes@241: fprintf(stderr, "downloaded %d packages\n", matches); rhughes@241: rhughes@241: return 0; rhughes@241: } rhughes@241: jbowes@258: static int jbowes@258: command_info(int argc, const char *argv[]) jbowes@258: { ali@403: struct razor_atomic *atomic; jbowes@258: struct razor_set *set; jbowes@258: struct razor_package_iterator *pi; jbowes@258: struct razor_package *package; jbowes@258: const char *pattern = argv[0], *name, *version, *arch; jbowes@258: const char *summary, *description, *url, *license; jbowes@258: ali@403: atomic = razor_atomic_open("Package info"); ali@403: set = razor_root_open_read_only(install_root, atomic); ali@403: if (set == NULL) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); jbowes@288: return 1; ali@403: } krh@317: jbowes@258: pi = razor_package_iterator_create(set); jbowes@258: while (razor_package_iterator_next(pi, &package, richard@302: RAZOR_DETAIL_NAME, &name, richard@302: RAZOR_DETAIL_VERSION, &version, richard@307: RAZOR_DETAIL_ARCH, &arch, richard@307: RAZOR_DETAIL_LAST)) { jbowes@258: if (pattern && fnmatch(pattern, name, 0) != 0) jbowes@258: continue; jbowes@258: richard@302: razor_package_get_details (set, package, richard@302: RAZOR_DETAIL_SUMMARY, &summary, richard@302: RAZOR_DETAIL_DESCRIPTION, &description, richard@302: RAZOR_DETAIL_URL, &url, richard@302: RAZOR_DETAIL_LICENSE, &license, richard@307: RAZOR_DETAIL_LAST); jbowes@258: jbowes@258: printf ("Name: %s\n", name); jbowes@258: printf ("Arch: %s\n", arch); jbowes@258: printf ("Version: %s\n", version); jbowes@258: printf ("URL: %s\n", url); jbowes@258: printf ("License: %s\n", license); jbowes@258: printf ("Summary: %s\n", summary); jbowes@258: printf ("Description:\n"); jbowes@258: printf ("%s\n", description); jbowes@258: printf ("\n"); jbowes@258: } jbowes@258: razor_package_iterator_destroy(pi); ali@403: razor_set_unref(set); ali@403: razor_atomic_destroy(atomic); jbowes@258: jbowes@258: return 0; jbowes@258: } jbowes@258: jbowes@292: #define SEARCH_MAX 256 jbowes@292: jbowes@292: static int jbowes@292: command_search(int argc, const char *argv[]) jbowes@292: { ali@403: struct razor_atomic *atomic; jbowes@292: struct razor_set *set; jbowes@292: struct razor_package_iterator *pi; jbowes@292: struct razor_package *package; jbowes@292: char pattern[SEARCH_MAX]; jbowes@292: const char *name, *version, *arch; jbowes@292: const char *summary, *description, *url, *license; jbowes@292: jbowes@292: if (!argv[0]) { jbowes@292: fprintf(stderr, "must specify a search term\n"); jbowes@292: return 1; jbowes@292: } jbowes@292: krh@294: snprintf(pattern, sizeof pattern, "*%s*", argv[0]); jbowes@292: ali@403: atomic = razor_atomic_open("Search packages"); ali@403: set = razor_set_open(rawhide_repo_filename, atomic); ali@403: if (set == NULL || razor_atomic_commit(atomic)) { ali@403: fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); ali@403: razor_atomic_destroy(atomic); jbowes@292: return 1; ali@403: } ali@403: razor_atomic_destroy(atomic); richard@310: jbowes@292: pi = razor_package_iterator_create(set); jbowes@292: while (razor_package_iterator_next(pi, &package, richard@304: RAZOR_DETAIL_NAME, &name, richard@304: RAZOR_DETAIL_VERSION, &version, krh@305: RAZOR_DETAIL_ARCH, &arch, krh@305: RAZOR_DETAIL_SUMMARY, &summary, krh@305: RAZOR_DETAIL_DESCRIPTION, &description, krh@305: RAZOR_DETAIL_URL, &url, krh@305: RAZOR_DETAIL_LICENSE, &license, richard@307: RAZOR_DETAIL_LAST)) { krh@305: if (!fnmatch(pattern, name, FNM_CASEFOLD) || krh@305: !fnmatch(pattern, url, FNM_CASEFOLD) || krh@305: !fnmatch(pattern, summary, FNM_CASEFOLD) || krh@305: !fnmatch(pattern, description, FNM_CASEFOLD)) krh@305: printf("%s-%s.%s: %s\n", name, version, arch, summary); jbowes@292: } jbowes@292: razor_package_iterator_destroy(pi); ali@403: razor_set_unref(set); jbowes@292: jbowes@292: return 0; jbowes@292: } jbowes@292: rhughes@241: static struct { rhughes@241: const char *name; rhughes@241: const char *description; rhughes@241: int (*func)(int argc, const char *argv[]); rhughes@241: } razor_commands[] = { rhughes@241: { "list", "list all packages", command_list }, rhughes@241: { "list-requires", "list all requires for the given package", command_list_requires }, rhughes@241: { "list-provides", "list all provides for the given package", command_list_provides }, rhughes@241: { "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes }, rhughes@241: { "list-conflicts", "list all conflicts for the given package", command_list_conflicts }, ali@369: { "list-scripts", "list all scripts for the given package", command_list_scripts }, rhughes@241: { "list-files", "list files for package set", command_list_files }, rhughes@241: { "list-file-packages", "list packages owning file", command_list_file_packages }, rhughes@241: { "list-package-files", "list files in package", command_list_package_files }, rhughes@241: { "what-requires", "list the packages that have the given requires", command_what_requires }, rhughes@241: { "what-provides", "list the packages that have the given provides", command_what_provides }, rhughes@241: { "import-yum", "import yum metadata files", command_import_yum }, ali@320: #if HAVE_RPMLIB rhughes@241: { "import-rpmdb", "import the system rpm database", command_import_rpmdb }, ali@320: #endif rhughes@241: { "import-rpms", "import rpms from the given directory", command_import_rpms }, rhughes@241: { "update", "update all or specified packages", command_update }, rhughes@241: { "remove", "remove specified packages", command_remove }, rhughes@241: { "diff", "show diff between two package sets", command_diff }, rhughes@241: { "install", "install rpm", command_install }, rhughes@241: { "init", "init razor root", command_init }, jbowes@258: { "download", "download packages", command_download }, jbowes@292: { "info", "display package details", command_info }, jbowes@292: { "search", "search package details", command_search } rhughes@241: }; rhughes@241: rhughes@241: static int rhughes@241: usage(void) rhughes@241: { rhughes@241: int i; rhughes@241: rhughes@241: printf("usage:\n"); rhughes@241: for (i = 0; i < ARRAY_SIZE(razor_commands); i++) rhughes@241: printf(" %-20s%s\n", rhughes@241: razor_commands[i].name, razor_commands[i].description); rhughes@241: rhughes@241: return 1; rhughes@241: } rhughes@241: rhughes@241: int rhughes@241: main(int argc, const char *argv[]) rhughes@241: { krh@317: char *repo, *root; rhughes@241: int i; rhughes@241: rhughes@241: repo = getenv("RAZOR_REPO"); rhughes@241: if (repo != NULL) rhughes@241: repo_filename = repo; rhughes@241: krh@317: root = getenv("RAZOR_ROOT"); krh@317: if (root != NULL) krh@317: install_root = root; krh@317: rhughes@241: yum_url = getenv("YUM_URL"); rhughes@241: if (yum_url == NULL) rhughes@241: yum_url = YUM_URL; rhughes@241: ali@359: if (getenv("RAZOR_NO_ROOT_NAME_CHECKS")) ali@359: razor_disable_root_name_checks(1); ali@359: rhughes@241: if (argc < 2) rhughes@241: return usage(); rhughes@241: rhughes@241: for (i = 0; i < ARRAY_SIZE(razor_commands); i++) rhughes@241: if (strcmp(razor_commands[i].name, argv[1]) == 0) rhughes@241: return razor_commands[i].func(argc - 2, argv + 2); rhughes@241: rhughes@241: return usage(); rhughes@241: }