src/main.c
changeset 483 8087224f30c4
parent 475 008c75a5e08d
child 489 9d0a04089d22
     1.1 --- a/src/main.c	Mon Jul 04 10:48:18 2016 +0100
     1.2 +++ b/src/main.c	Fri Jul 08 17:12:16 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,