1.1 --- a/src/main.c Mon Jul 04 10:48:18 2016 +0100
1.2 +++ b/src/main.c Fri Jul 08 17:52:27 2016 +0100
1.3 @@ -46,6 +46,7 @@
1.4 #include <errno.h>
1.5 #include <getopt.h>
1.6 #include "razor.h"
1.7 +#include "import.h"
1.8
1.9 static const char system_repo_filename[] = "system.rzdb";
1.10 static const char next_repo_filename[] = "system-next.rzdb";
1.11 @@ -614,140 +615,121 @@
1.12 RAZOR_PROPERTY_PROVIDES);
1.13 }
1.14
1.15 -#ifndef HAVE_CURL
1.16 -static int
1.17 -download_local(const char *url, const char *file)
1.18 +#ifdef HAVE_CURL
1.19 +struct get_contents_with_curl_baton {
1.20 + void *buf;
1.21 + size_t buflen;
1.22 +};
1.23 +
1.24 +static size_t
1.25 +get_contents_with_curl_callback(void *contents, size_t size, size_t nmemb,
1.26 + void *data)
1.27 {
1.28 - FILE *wfp, *rfp;
1.29 - char buffer[256], *ptr, *local;
1.30 - size_t nb, n;
1.31 - struct razor_error *error = NULL;
1.32 + size_t nb = size * nmemb;
1.33 + struct get_contents_with_curl_baton *baton = data;
1.34
1.35 - local = razor_path_from_uri(url, &error);
1.36 -
1.37 - if (local == NULL) {
1.38 - fprintf(stderr, "%s: %s\n", file, razor_error_get_msg(error));
1.39 - razor_error_free(error);
1.40 - return -1;
1.41 - } else {
1.42 - rfp = fopen(local, "rb");
1.43 - if (rfp == NULL) {
1.44 - perror(local);
1.45 - free(local);
1.46 - return -1;
1.47 - }
1.48 -
1.49 - wfp = fopen(file, "wb");
1.50 - if (wfp == NULL) {
1.51 - perror(file);
1.52 - fclose(rfp);
1.53 - free(local);
1.54 - return -1;
1.55 - }
1.56 -
1.57 - while((nb = fread(buffer, 1, sizeof(buffer), rfp)) > 0) {
1.58 - ptr = buffer;
1.59 - while (nb > 0 && (n = fwrite(ptr, 1, nb, wfp)) > 0) {
1.60 - ptr += n;
1.61 - nb -= n;
1.62 - }
1.63 -
1.64 - if (nb != 0) {
1.65 - perror(file);
1.66 - fclose(wfp);
1.67 - fclose(rfp);
1.68 - unlink(file);
1.69 - free(local);
1.70 - return -1;
1.71 - }
1.72 - }
1.73 -
1.74 - if (ferror(rfp)) {
1.75 - perror(local);
1.76 - fclose(wfp);
1.77 - fclose(rfp);
1.78 - unlink(file);
1.79 - free(local);
1.80 - return -1;
1.81 - }
1.82 -
1.83 - fclose(wfp);
1.84 - fclose(rfp);
1.85 - free(local);
1.86 + baton->buf = realloc(baton->buf, baton->buflen + nb);
1.87 + if (!baton->buf) {
1.88 + fprintf(stderr, "Not enough memory to read file\n");
1.89 return 0;
1.90 }
1.91 +
1.92 + memcpy((char *)baton->buf + baton->buflen, contents, nb);
1.93 + baton->buflen += nb;
1.94 +
1.95 + return nb;
1.96 }
1.97 -#endif /* !HAVE_CURL */
1.98
1.99 +static void *get_contents_with_curl(const char *uri, size_t *length,
1.100 + int private, struct razor_error **error)
1.101 +{
1.102 + CURL *curl;
1.103 + char errbuf[256];
1.104 + CURLcode res;
1.105 + struct get_contents_with_curl_baton baton = {0,};
1.106 +
1.107 + curl = curl_easy_init();
1.108 + if (!curl) {
1.109 + razor_set_error(error, RAZOR_GENERAL_ERROR,
1.110 + RAZOR_GENERAL_ERROR_FAILED, uri,
1.111 + "Failed to initialize libcurl");
1.112 + return NULL;
1.113 + }
1.114 +
1.115 + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
1.116 + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
1.117 + get_contents_with_curl_callback);
1.118 + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&baton);
1.119 + curl_easy_setopt(curl, CURLOPT_URL, uri);
1.120 + curl_easy_setopt(curl, CURLOPT_USERAGENT, "razor/" VERSION);
1.121 + res = curl_easy_perform(curl);
1.122 + curl_easy_cleanup(curl);
1.123 +
1.124 + if (res != CURLE_OK) {
1.125 + razor_set_error(error, RAZOR_GENERAL_ERROR,
1.126 + RAZOR_GENERAL_ERROR_FAILED, uri, errbuf);
1.127 + free(baton.buf);
1.128 + return NULL;
1.129 + }
1.130 +
1.131 + *length = baton.buflen;
1.132 + return baton.buf;
1.133 +}
1.134 +
1.135 +int free_contents_with_curl(void *addr, size_t length)
1.136 +{
1.137 + free(addr);
1.138 +}
1.139 +#endif
1.140 +
1.141 +void init_uri_handler(void)
1.142 +{
1.143 #ifdef HAVE_CURL
1.144 -static int
1.145 -show_progress(void *clientp,
1.146 - double dltotal, double dlnow, double ultotal, double ulnow)
1.147 -{
1.148 - const char *file = clientp;
1.149 -
1.150 - if (!dlnow < dltotal)
1.151 - fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
1.152 - file, (int) dlnow / 1024, (int) dltotal / 1024);
1.153 -
1.154 - return 0;
1.155 + struct razor_uri_vtable uri_vtable={0,};
1.156 + uri_vtable.structure_size=sizeof(uri_vtable);
1.157 + uri_vtable.get_contents=get_contents_with_curl;
1.158 + uri_vtable.free_contents=free_contents_with_curl;
1.159 + razor_uri_set_vtable(NULL, &uri_vtable, NULL);
1.160 +#endif
1.161 }
1.162
1.163 static int
1.164 -download_with_curl(const char *url, const char *file)
1.165 +download_if_missing(const char *uri, const char *file)
1.166 {
1.167 + int retval = 0;
1.168 + struct stat buf;
1.169 + void *contents;
1.170 + size_t length;
1.171 + struct razor_error *error = NULL;
1.172 FILE *fp;
1.173 - CURL *curl;
1.174 - char error[256];
1.175 - CURLcode res;
1.176 - long response;
1.177 -
1.178 - curl = curl_easy_init();
1.179 - if (curl == NULL) {
1.180 - fprintf(stderr,
1.181 - "%s: download manually (curl failed)\n", file);
1.182 - return -1;
1.183 - }
1.184 -
1.185 - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
1.186 - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
1.187 - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
1.188 - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
1.189 -
1.190 - fp = fopen(file, "wb");
1.191 - if (fp == NULL) {
1.192 - perror(file);
1.193 - return -1;
1.194 - }
1.195 - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
1.196 - curl_easy_setopt(curl, CURLOPT_URL, url);
1.197 - res = curl_easy_perform(curl);
1.198 - fclose(fp);
1.199 - putc('\n', stderr);
1.200 - if (res != CURLE_OK) {
1.201 - fprintf(stderr, "curl error: %s\n", error);
1.202 - unlink(file);
1.203 - return -1;
1.204 - }
1.205 - curl_easy_cleanup(curl);
1.206 -
1.207 - return 0;
1.208 -}
1.209 -#endif /* HAVE_CURL */
1.210 -
1.211 -static int
1.212 -download_if_missing(const char *url, const char *file)
1.213 -{
1.214 - struct stat buf;
1.215
1.216 if (stat(file, &buf) >= 0)
1.217 return 0;
1.218
1.219 -#ifndef HAVE_CURL
1.220 - return download_local(url, file);
1.221 -#else
1.222 - return download_with_curl(url, file);
1.223 -#endif
1.224 + contents = razor_uri_get_contents(uri, &length, 0, &error);
1.225 +
1.226 + if (!contents) {
1.227 + fprintf(stderr, "%s: %s\n", uri, razor_error_get_msg(error));
1.228 + razor_error_free(error);
1.229 + return -1;
1.230 + }
1.231 +
1.232 + fp = fopen(file, "wb");
1.233 + if (!fp) {
1.234 + perror(file);
1.235 + razor_uri_free_contents(contents, length);
1.236 + return -1;
1.237 + }
1.238 +
1.239 + if (fwrite(contents, 1, length, fp) != length) {
1.240 + perror(file);
1.241 + retval = -1;
1.242 + }
1.243 +
1.244 + fclose(fp);
1.245 + razor_uri_free_contents(contents, length);
1.246 +
1.247 + return retval;
1.248 }
1.249
1.250 #define YUM_URL "http://download.fedora.redhat.com" \
1.251 @@ -773,17 +755,9 @@
1.252 return 1;
1.253 }
1.254
1.255 - printf("downloading from '%s'.\n", yum_url);
1.256 - snprintf(buffer, sizeof buffer,
1.257 - "%s/repodata/primary.xml.gz", yum_url);
1.258 - if (download_if_missing(buffer, "primary.xml.gz") < 0)
1.259 - return -1;
1.260 - snprintf(buffer, sizeof buffer,
1.261 - "%s/repodata/filelists.xml.gz", yum_url);
1.262 - if (download_if_missing(buffer, "filelists.xml.gz") < 0)
1.263 - return -1;
1.264 + printf("importing from '%s'.\n", yum_url);
1.265
1.266 - set = razor_set_create_from_yum();
1.267 + set = razor_set_create_from_yum(yum_url);
1.268 if (set == NULL)
1.269 return 1;
1.270 atomic = razor_atomic_open("Yum import repository");
1.271 @@ -1097,48 +1071,6 @@
1.272 return razor_concat(name, "-", v, ".", arch, ".rpm", NULL);
1.273 }
1.274
1.275 -static int
1.276 -download_packages(struct razor_set *system, struct razor_set *next)
1.277 -{
1.278 - struct razor_install_iterator *ii;
1.279 - struct razor_package *package;
1.280 - enum razor_install_action action;
1.281 - const char *name, *version, *arch;
1.282 - char *file, *url, *s;
1.283 - int errors = 0, count;
1.284 -
1.285 - ii = razor_set_create_install_iterator(system, next);
1.286 - while (razor_install_iterator_next(ii, &package, &action, &count)) {
1.287 - if (action != RAZOR_INSTALL_ACTION_ADD)
1.288 - continue;
1.289 -
1.290 - razor_package_get_details(next, package,
1.291 - RAZOR_DETAIL_NAME, &name,
1.292 - RAZOR_DETAIL_VERSION, &version,
1.293 - RAZOR_DETAIL_ARCH, &arch,
1.294 - RAZOR_DETAIL_LAST);
1.295 -
1.296 - s = rpm_filename(name, version, arch);
1.297 - file = razor_concat("Packages/", s, NULL);
1.298 - url = razor_path_relative_to_uri(yum_url, file, NULL);
1.299 - free(file);
1.300 - file = razor_concat("rpms/", s, NULL);
1.301 - free(s);
1.302 - if (download_if_missing(url, file) < 0)
1.303 - errors++;
1.304 - free(file);
1.305 - free(url);
1.306 - }
1.307 - razor_install_iterator_destroy(ii);
1.308 -
1.309 - if (errors > 0) {
1.310 - fprintf(stderr, "failed to download %d packages\n", errors);
1.311 - return -1;
1.312 - }
1.313 -
1.314 - return 0;
1.315 -}
1.316 -
1.317 static struct razor_set *
1.318 relocate_packages(struct razor_set *set, struct razor_atomic *atomic,
1.319 struct razor_relocations *relocations)
1.320 @@ -1179,12 +1111,7 @@
1.321 s = razor_concat("Packages/", filename, NULL);
1.322 uri = razor_path_relative_to_uri(yum_url, s, NULL);
1.323 free(s);
1.324 - file = razor_concat("rpms/", filename, NULL);
1.325 free(filename);
1.326 - download_if_missing(uri, file);
1.327 - free(uri);
1.328 - uri = razor_path_to_uri(file);
1.329 - free(file);
1.330 rpm = razor_rpm_open(uri, &error);
1.331 free(uri);
1.332 if (rpm == NULL) {
1.333 @@ -1255,14 +1182,15 @@
1.334 RAZOR_DETAIL_ARCH, &arch,
1.335 RAZOR_DETAIL_LAST);
1.336
1.337 + s = rpm_filename(name, version, arch);
1.338 + file = razor_concat("Packages/", s, NULL);
1.339 + free(s);
1.340 + uri = razor_path_relative_to_uri(yum_url, file, NULL);
1.341 + free(file);
1.342 +
1.343 if (stage & RAZOR_STAGE_SCRIPTS_PRE)
1.344 - printf("install %s-%s\n", name, version);
1.345 + printf("install %s\n", uri);
1.346
1.347 - s = rpm_filename(name, version, arch);
1.348 - file = razor_concat("rpms/", s, NULL);
1.349 - free(s);
1.350 - uri = razor_path_to_uri(file);
1.351 - free(file);
1.352 rpm = razor_rpm_open(uri, &error);
1.353 free(uri);
1.354 if (rpm == NULL) {
1.355 @@ -1510,33 +1438,10 @@
1.356 }
1.357 }
1.358
1.359 - if (razor_atomic_create_dir(atomic, "file:rpms",
1.360 - S_IRWXU | S_IRWXG | S_IRWXO) ||
1.361 - razor_atomic_commit(atomic)) {
1.362 - fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
1.363 - razor_transaction_destroy(trans);
1.364 - razor_set_unref(upstream);
1.365 - razor_root_close(root);
1.366 - razor_atomic_destroy(atomic);
1.367 - if (relocations)
1.368 - razor_relocations_destroy(relocations);
1.369 - return 1;
1.370 - }
1.371 -
1.372 razor_atomic_destroy(atomic);
1.373
1.374 next = razor_transaction_commit(trans);
1.375
1.376 - if (download_packages(system, next) < 0) {
1.377 - razor_set_unref(next);
1.378 - razor_transaction_destroy(trans);
1.379 - razor_set_unref(upstream);
1.380 - razor_root_close(root);
1.381 - if (relocations)
1.382 - razor_relocations_destroy(relocations);
1.383 - return 1;
1.384 - }
1.385 -
1.386 retval = update_system(root, relocations, trans, next,
1.387 do_update ? "Update" : "Install");
1.388
1.389 @@ -1975,6 +1880,8 @@
1.390 return 1;
1.391 }
1.392
1.393 + init_uri_handler();
1.394 +
1.395 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1.396 if (strcmp(razor_commands[i].name, argv[main_optind]) == 0)
1.397 return razor_commands[i].func(argc - main_optind,