diff -r 008c75a5e08d -r 4204db81cdbc src/main.c --- a/src/main.c Mon Jul 04 10:48:18 2016 +0100 +++ b/src/main.c Thu Jul 07 15:17:29 2016 +0100 @@ -46,6 +46,7 @@ #include #include #include "razor.h" +#include "import.h" static const char system_repo_filename[] = "system.rzdb"; static const char next_repo_filename[] = "system-next.rzdb"; @@ -614,140 +615,121 @@ RAZOR_PROPERTY_PROVIDES); } -#ifndef HAVE_CURL -static int -download_local(const char *url, const char *file) +#ifdef HAVE_CURL +struct get_contents_with_curl_baton { + void *buf; + size_t buflen; +}; + +static size_t +get_contents_with_curl_callback(void *contents, size_t size, size_t nmemb, + void *data) { - FILE *wfp, *rfp; - char buffer[256], *ptr, *local; - size_t nb, n; - struct razor_error *error = NULL; + size_t nb = size * nmemb; + struct get_contents_with_curl_baton *baton = data; - local = razor_path_from_uri(url, &error); - - if (local == NULL) { - fprintf(stderr, "%s: %s\n", file, razor_error_get_msg(error)); - razor_error_free(error); - return -1; - } else { - rfp = fopen(local, "rb"); - if (rfp == NULL) { - perror(local); - free(local); - return -1; - } - - wfp = fopen(file, "wb"); - if (wfp == NULL) { - perror(file); - fclose(rfp); - free(local); - return -1; - } - - while((nb = fread(buffer, 1, sizeof(buffer), rfp)) > 0) { - ptr = buffer; - while (nb > 0 && (n = fwrite(ptr, 1, nb, wfp)) > 0) { - ptr += n; - nb -= n; - } - - if (nb != 0) { - perror(file); - fclose(wfp); - fclose(rfp); - unlink(file); - free(local); - return -1; - } - } - - if (ferror(rfp)) { - perror(local); - fclose(wfp); - fclose(rfp); - unlink(file); - free(local); - return -1; - } - - fclose(wfp); - fclose(rfp); - free(local); + baton->buf = realloc(baton->buf, baton->buflen + nb); + if (!baton->buf) { + fprintf(stderr, "Not enough memory to read file\n"); return 0; } + + memcpy((char *)baton->buf + baton->buflen, contents, nb); + baton->buflen += nb; + + return nb; } -#endif /* !HAVE_CURL */ +static void *get_contents_with_curl(const char *uri, size_t *length, + int private, struct razor_error **error) +{ + CURL *curl; + char errbuf[256]; + CURLcode res; + struct get_contents_with_curl_baton baton = {0,}; + + curl = curl_easy_init(); + if (!curl) { + razor_set_error(error, RAZOR_GENERAL_ERROR, + RAZOR_GENERAL_ERROR_FAILED, uri, + "Failed to initialize libcurl"); + return NULL; + } + + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, + get_contents_with_curl_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&baton); + curl_easy_setopt(curl, CURLOPT_URL, uri); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "razor/" VERSION); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + + if (res != CURLE_OK) { + razor_set_error(error, RAZOR_GENERAL_ERROR, + RAZOR_GENERAL_ERROR_FAILED, uri, errbuf); + free(baton.buf); + return NULL; + } + + *length = baton.buflen; + return baton.buf; +} + +int free_contents_with_curl(void *addr, size_t length) +{ + free(addr); +} +#endif + +void init_uri_handler(void) +{ #ifdef HAVE_CURL -static int -show_progress(void *clientp, - double dltotal, double dlnow, double ultotal, double ulnow) -{ - const char *file = clientp; - - if (!dlnow < dltotal) - fprintf(stderr, "\rdownloading %s, %dkB/%dkB", - file, (int) dlnow / 1024, (int) dltotal / 1024); - - return 0; + struct razor_uri_vtable uri_vtable={0,}; + uri_vtable.structure_size=sizeof(uri_vtable); + uri_vtable.get_contents=get_contents_with_curl; + uri_vtable.free_contents=free_contents_with_curl; + razor_uri_set_vtable(NULL, &uri_vtable, NULL); +#endif } static int -download_with_curl(const char *url, const char *file) +download_if_missing(const char *uri, const char *file) { + int retval = 0; + struct stat buf; + void *contents; + size_t length; + struct razor_error *error = NULL; FILE *fp; - CURL *curl; - char error[256]; - CURLcode res; - long response; - - curl = curl_easy_init(); - if (curl == NULL) { - fprintf(stderr, - "%s: download manually (curl failed)\n", file); - return -1; - } - - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file); - - fp = fopen(file, "wb"); - if (fp == NULL) { - perror(file); - return -1; - } - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - fclose(fp); - putc('\n', stderr); - if (res != CURLE_OK) { - fprintf(stderr, "curl error: %s\n", error); - unlink(file); - return -1; - } - curl_easy_cleanup(curl); - - return 0; -} -#endif /* HAVE_CURL */ - -static int -download_if_missing(const char *url, const char *file) -{ - struct stat buf; if (stat(file, &buf) >= 0) return 0; -#ifndef HAVE_CURL - return download_local(url, file); -#else - return download_with_curl(url, file); -#endif + contents = razor_uri_get_contents(uri, &length, 0, &error); + + if (!contents) { + fprintf(stderr, "%s: %s\n", uri, razor_error_get_msg(error)); + razor_error_free(error); + return -1; + } + + fp = fopen(file, "wb"); + if (!fp) { + perror(file); + razor_uri_free_contents(contents, length); + return -1; + } + + if (fwrite(contents, 1, length, fp) != length) { + perror(file); + retval = -1; + } + + fclose(fp); + razor_uri_free_contents(contents, length); + + return retval; } #define YUM_URL "http://download.fedora.redhat.com" \ @@ -773,17 +755,9 @@ return 1; } - printf("downloading from '%s'.\n", yum_url); - snprintf(buffer, sizeof buffer, - "%s/repodata/primary.xml.gz", yum_url); - if (download_if_missing(buffer, "primary.xml.gz") < 0) - return -1; - snprintf(buffer, sizeof buffer, - "%s/repodata/filelists.xml.gz", yum_url); - if (download_if_missing(buffer, "filelists.xml.gz") < 0) - return -1; + printf("importing from '%s'.\n", yum_url); - set = razor_set_create_from_yum(); + set = razor_set_create_from_yum(yum_url); if (set == NULL) return 1; atomic = razor_atomic_open("Yum import repository"); @@ -1097,48 +1071,6 @@ return razor_concat(name, "-", v, ".", arch, ".rpm", NULL); } -static int -download_packages(struct razor_set *system, struct razor_set *next) -{ - struct razor_install_iterator *ii; - struct razor_package *package; - enum razor_install_action action; - const char *name, *version, *arch; - char *file, *url, *s; - int errors = 0, count; - - ii = razor_set_create_install_iterator(system, next); - while (razor_install_iterator_next(ii, &package, &action, &count)) { - if (action != RAZOR_INSTALL_ACTION_ADD) - continue; - - razor_package_get_details(next, package, - RAZOR_DETAIL_NAME, &name, - RAZOR_DETAIL_VERSION, &version, - RAZOR_DETAIL_ARCH, &arch, - RAZOR_DETAIL_LAST); - - s = rpm_filename(name, version, arch); - file = razor_concat("Packages/", s, NULL); - url = razor_path_relative_to_uri(yum_url, file, NULL); - free(file); - file = razor_concat("rpms/", s, NULL); - free(s); - if (download_if_missing(url, file) < 0) - errors++; - free(file); - free(url); - } - razor_install_iterator_destroy(ii); - - if (errors > 0) { - fprintf(stderr, "failed to download %d packages\n", errors); - return -1; - } - - return 0; -} - static struct razor_set * relocate_packages(struct razor_set *set, struct razor_atomic *atomic, struct razor_relocations *relocations) @@ -1179,12 +1111,7 @@ s = razor_concat("Packages/", filename, NULL); uri = razor_path_relative_to_uri(yum_url, s, NULL); free(s); - file = razor_concat("rpms/", filename, NULL); free(filename); - download_if_missing(uri, file); - free(uri); - uri = razor_path_to_uri(file); - free(file); rpm = razor_rpm_open(uri, &error); free(uri); if (rpm == NULL) { @@ -1255,14 +1182,15 @@ RAZOR_DETAIL_ARCH, &arch, RAZOR_DETAIL_LAST); + s = rpm_filename(name, version, arch); + file = razor_concat("Packages/", s, NULL); + free(s); + uri = razor_path_relative_to_uri(yum_url, file, NULL); + free(file); + if (stage & RAZOR_STAGE_SCRIPTS_PRE) - printf("install %s-%s\n", name, version); + printf("install %s\n", uri); - s = rpm_filename(name, version, arch); - file = razor_concat("rpms/", s, NULL); - free(s); - uri = razor_path_to_uri(file); - free(file); rpm = razor_rpm_open(uri, &error); free(uri); if (rpm == NULL) { @@ -1510,33 +1438,10 @@ } } - if (razor_atomic_create_dir(atomic, "file:rpms", - S_IRWXU | S_IRWXG | S_IRWXO) || - razor_atomic_commit(atomic)) { - fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); - razor_transaction_destroy(trans); - razor_set_unref(upstream); - razor_root_close(root); - razor_atomic_destroy(atomic); - if (relocations) - razor_relocations_destroy(relocations); - return 1; - } - razor_atomic_destroy(atomic); next = razor_transaction_commit(trans); - if (download_packages(system, next) < 0) { - razor_set_unref(next); - razor_transaction_destroy(trans); - razor_set_unref(upstream); - razor_root_close(root); - if (relocations) - razor_relocations_destroy(relocations); - return 1; - } - retval = update_system(root, relocations, trans, next, do_update ? "Update" : "Install"); @@ -1975,6 +1880,8 @@ return 1; } + init_uri_handler(); + for (i = 0; i < ARRAY_SIZE(razor_commands); i++) if (strcmp(razor_commands[i].name, argv[main_optind]) == 0) return razor_commands[i].func(argc - main_optind,