main.c
changeset 258 29d5002bd17f
parent 229 cae6308aa5b1
parent 248 057933050c42
child 259 5b0601d184ed
     1.1 --- a/main.c	Sun Jun 15 18:16:20 2008 -0400
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,915 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     1.6 - * Copyright (C) 2008  Red Hat, Inc
     1.7 - *
     1.8 - * This program is free software; you can redistribute it and/or modify
     1.9 - * it under the terms of the GNU General Public License as published by
    1.10 - * the Free Software Foundation; either version 2 of the License, or
    1.11 - * (at your option) any later version.
    1.12 - *
    1.13 - * This program is distributed in the hope that it will be useful,
    1.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.16 - * GNU General Public License for more details.
    1.17 - *
    1.18 - * You should have received a copy of the GNU General Public License along
    1.19 - * with this program; if not, write to the Free Software Foundation, Inc.,
    1.20 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 - */
    1.22 -
    1.23 -#include <stdlib.h>
    1.24 -#include <stddef.h>
    1.25 -#include <stdio.h>
    1.26 -#include <stdint.h>
    1.27 -#include <string.h>
    1.28 -#include <sys/stat.h>
    1.29 -#include <unistd.h>
    1.30 -#include <fcntl.h>
    1.31 -#include <dirent.h>
    1.32 -#include <curl/curl.h>
    1.33 -#include <fnmatch.h>
    1.34 -#include <errno.h>
    1.35 -#include "razor.h"
    1.36 -#include "razor-internal.h"
    1.37 -
    1.38 -static const char system_repo_filename[] = "system.repo";
    1.39 -static const char next_repo_filename[] = "system-next.repo";
    1.40 -static const char rawhide_repo_filename[] = "rawhide.repo";
    1.41 -static const char updated_repo_filename[] = "system-updated.repo";
    1.42 -static const char razor_root_path[] = "/var/lib/razor";
    1.43 -static const char root[] = "install";
    1.44 -static const char *repo_filename = system_repo_filename;
    1.45 -
    1.46 -static int
    1.47 -command_list(int argc, const char *argv[])
    1.48 -{
    1.49 -	struct razor_set *set;
    1.50 -	struct razor_package_iterator *pi;
    1.51 -	struct razor_package *package;
    1.52 -	const char *pattern, *name, *version, *arch;
    1.53 -	int only_names = 0, i = 0;
    1.54 -
    1.55 -	if (i < argc && strcmp(argv[i], "--only-names") == 0) {
    1.56 -		only_names = 1;
    1.57 -		i++;
    1.58 -	}
    1.59 -
    1.60 -	pattern = argv[i];
    1.61 -	set = razor_set_open(repo_filename);
    1.62 -	pi = razor_package_iterator_create(set);
    1.63 -	while (razor_package_iterator_next(pi, &package,
    1.64 -					   &name, &version, &arch)) {
    1.65 -		if (pattern && fnmatch(pattern, name, 0) != 0)
    1.66 -			continue;
    1.67 -
    1.68 -		if (only_names)
    1.69 -			printf("%s\n", name);
    1.70 -		else
    1.71 -			printf("%s-%s.%s\n", name, version, arch);
    1.72 -	}
    1.73 -	razor_package_iterator_destroy(pi);
    1.74 -	razor_set_destroy(set);
    1.75 -
    1.76 -	return 0;
    1.77 -}
    1.78 -
    1.79 -static int
    1.80 -list_properties(const char *package_name,
    1.81 -		enum razor_property_type required_type)
    1.82 -{
    1.83 -	struct razor_set *set;
    1.84 -	struct razor_property *property;
    1.85 -	struct razor_package *package;
    1.86 -	struct razor_property_iterator *pi;
    1.87 -	const char *name, *version;
    1.88 -	enum razor_property_type type;
    1.89 -	enum razor_version_relation relation;
    1.90 -
    1.91 -	set = razor_set_open(repo_filename);
    1.92 -	if (package_name)
    1.93 -		package = razor_set_get_package(set, package_name);
    1.94 -	else
    1.95 -		package = NULL;
    1.96 -
    1.97 -	pi = razor_property_iterator_create(set, package);
    1.98 -	while (razor_property_iterator_next(pi, &property,
    1.99 -					    &name, &relation, &version,
   1.100 -					    &type)) {
   1.101 -		if (type != required_type)
   1.102 -			continue;
   1.103 -		if (version[0] == '\0')
   1.104 -			printf("%s\n", name);
   1.105 -		else
   1.106 -			printf("%s %s %s\n", name,
   1.107 -			       razor_version_relations[relation], version);
   1.108 -	}
   1.109 -	razor_property_iterator_destroy(pi);
   1.110 -
   1.111 -	razor_set_destroy(set);
   1.112 -
   1.113 -	return 0;
   1.114 -}
   1.115 -
   1.116 -static int
   1.117 -command_list_requires(int argc, const char *argv[])
   1.118 -{
   1.119 -	return list_properties(argv[0], RAZOR_PROPERTY_REQUIRES);
   1.120 -}
   1.121 -
   1.122 -static int
   1.123 -command_list_provides(int argc, const char *argv[])
   1.124 -{
   1.125 -	return list_properties(argv[0], RAZOR_PROPERTY_PROVIDES);
   1.126 -}
   1.127 -
   1.128 -static int
   1.129 -command_list_obsoletes(int argc, const char *argv[])
   1.130 -{
   1.131 -	return list_properties(argv[0], RAZOR_PROPERTY_OBSOLETES);
   1.132 -}
   1.133 -
   1.134 -static int
   1.135 -command_list_conflicts(int argc, const char *argv[])
   1.136 -{
   1.137 -	return list_properties(argv[0], RAZOR_PROPERTY_CONFLICTS);
   1.138 -}
   1.139 -
   1.140 -static int
   1.141 -command_list_files(int argc, const char *argv[])
   1.142 -{
   1.143 -	struct razor_set *set;
   1.144 -
   1.145 -	set = razor_set_open(repo_filename);
   1.146 -	razor_set_open_files(set, "system-files.repo");
   1.147 -	if (set == NULL)
   1.148 -		return 1;
   1.149 -	razor_set_list_files(set, argv[0]);
   1.150 -	razor_set_destroy(set);
   1.151 -
   1.152 -	return 0;
   1.153 -}
   1.154 -
   1.155 -static int
   1.156 -command_list_file_packages(int argc, const char *argv[])
   1.157 -{
   1.158 -	struct razor_set *set;
   1.159 -	struct razor_package_iterator *pi;
   1.160 -	struct razor_package *package;
   1.161 -	const char *name, *version, *arch;
   1.162 -
   1.163 -	set = razor_set_open(repo_filename);
   1.164 -	razor_set_open_files(set, "system-files.repo");
   1.165 -	if (set == NULL)
   1.166 -		return 1;
   1.167 -
   1.168 -	pi = razor_package_iterator_create_for_file(set, argv[0]);
   1.169 -	while (razor_package_iterator_next(pi, &package,
   1.170 -					   &name, &version, &arch))
   1.171 -		printf("%s-%s\n", name, version);
   1.172 -	razor_package_iterator_destroy(pi);
   1.173 -
   1.174 -	razor_set_destroy(set);
   1.175 -
   1.176 -	return 0;
   1.177 -}
   1.178 -
   1.179 -static int
   1.180 -command_list_package_files(int argc, const char *argv[])
   1.181 -{
   1.182 -	struct razor_set *set;
   1.183 -
   1.184 -	set = razor_set_open(repo_filename);
   1.185 -	razor_set_open_files(set, "system-files.repo");
   1.186 -	if (set == NULL)
   1.187 -		return 1;
   1.188 -	razor_set_list_package_files(set, argv[0]);
   1.189 -	razor_set_destroy(set);
   1.190 -
   1.191 -	return 0;
   1.192 -}
   1.193 -
   1.194 -static void
   1.195 -list_packages_for_property(struct razor_set *set,
   1.196 -			   struct razor_property *property)
   1.197 -{
   1.198 -	struct razor_package_iterator *pi;
   1.199 -	struct razor_package *package;
   1.200 -	const char *name, *version, *arch;
   1.201 -
   1.202 -	pi = razor_package_iterator_create_for_property(set, property);
   1.203 -	while (razor_package_iterator_next(pi, &package,
   1.204 -					   &name, &version, &arch))
   1.205 -		printf("%s-%s.%s\n", name, version, arch);
   1.206 -	razor_package_iterator_destroy(pi);
   1.207 -}
   1.208 -
   1.209 -static int
   1.210 -list_property_packages(const char *ref_name,
   1.211 -		       const char *ref_version,
   1.212 -		       enum razor_property_type ref_type)
   1.213 -{
   1.214 -	struct razor_set *set;
   1.215 -	struct razor_property *property;
   1.216 -	struct razor_property_iterator *pi;
   1.217 -	const char *name, *version;
   1.218 -	enum razor_property_type type;
   1.219 -	enum razor_version_relation relation;
   1.220 -
   1.221 -	if (ref_name == NULL)
   1.222 -		return 0;
   1.223 -
   1.224 -	set = razor_set_open(repo_filename);
   1.225 -	if (set == NULL)
   1.226 -		return 1;
   1.227 -
   1.228 -	pi = razor_property_iterator_create(set, NULL);
   1.229 -	while (razor_property_iterator_next(pi, &property,
   1.230 -					    &name, &relation, &version,
   1.231 -					    &type)) {
   1.232 -		if (strcmp(ref_name, name) != 0)
   1.233 -			continue;
   1.234 -		if (ref_version && relation == RAZOR_VERSION_EQUAL &&
   1.235 -		    strcmp(ref_version, version) != 0)
   1.236 -			continue;
   1.237 -		if (ref_type != type)
   1.238 -			continue;
   1.239 -
   1.240 -		list_packages_for_property(set, property);
   1.241 -	}
   1.242 -	razor_property_iterator_destroy(pi);
   1.243 -
   1.244 -	return 0;
   1.245 -}
   1.246 -
   1.247 -static int
   1.248 -command_what_requires(int argc, const char *argv[])
   1.249 -{
   1.250 -	return list_property_packages(argv[0], argv[1],
   1.251 -				      RAZOR_PROPERTY_REQUIRES);
   1.252 -}
   1.253 -
   1.254 -static int
   1.255 -command_what_provides(int argc, const char *argv[])
   1.256 -{
   1.257 -	return list_property_packages(argv[0], argv[1],
   1.258 -				      RAZOR_PROPERTY_PROVIDES);
   1.259 -}
   1.260 -
   1.261 -static int
   1.262 -show_progress(void *clientp,
   1.263 -	      double dltotal, double dlnow, double ultotal, double ulnow)
   1.264 -{
   1.265 -	const char *file = clientp;
   1.266 -
   1.267 -	if (!dlnow < dltotal)
   1.268 -		fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
   1.269 -			file, (int) dlnow / 1024, (int) dltotal / 1024);
   1.270 -
   1.271 -	return 0;
   1.272 -}
   1.273 -
   1.274 -static int
   1.275 -download_if_missing(const char *url, const char *file)
   1.276 -{
   1.277 -	CURL *curl;
   1.278 -	struct stat buf;
   1.279 -	char error[256];
   1.280 -	FILE *fp;
   1.281 -	CURLcode res;
   1.282 -	long response;
   1.283 -
   1.284 -	curl = curl_easy_init();
   1.285 -	if (curl == NULL)
   1.286 -		return 1;
   1.287 -
   1.288 -	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
   1.289 -	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
   1.290 -	curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
   1.291 -	curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
   1.292 -
   1.293 -	if (stat(file, &buf) < 0) {
   1.294 -		fp = fopen(file, "w");
   1.295 -		if (fp == NULL) {
   1.296 -			fprintf(stderr,
   1.297 -				"failed to open %s for writing\n", file);
   1.298 -			return -1;
   1.299 -		}
   1.300 -		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
   1.301 -		curl_easy_setopt(curl, CURLOPT_URL, url);
   1.302 -		res = curl_easy_perform(curl);
   1.303 -		fclose(fp);
   1.304 -		if (res != CURLE_OK) {
   1.305 -			fprintf(stderr, "curl error: %s\n", error);
   1.306 -			unlink(file);
   1.307 -			return -1;
   1.308 -		}
   1.309 -		res = curl_easy_getinfo(curl,
   1.310 -					CURLINFO_RESPONSE_CODE, &response);
   1.311 -		if (res != CURLE_OK) {
   1.312 -			fprintf(stderr, "curl error: %s\n", error);
   1.313 -                        unlink(file);
   1.314 -                        return -1;
   1.315 -		}
   1.316 -		if (response != 200) {
   1.317 -			fprintf(stderr, " - failed %ld\n", response);
   1.318 -                        unlink(file);
   1.319 -                        return -1;
   1.320 -		}
   1.321 -		fprintf(stderr, "\n");
   1.322 -	}
   1.323 -
   1.324 -	curl_easy_cleanup(curl);
   1.325 -
   1.326 -	return 0;
   1.327 -}
   1.328 -
   1.329 -#define REPO_URL "http://download.fedora.redhat.com" \
   1.330 -	"/pub/fedora/linux/development/i386/os"
   1.331 -
   1.332 -static int
   1.333 -command_import_yum(int argc, const char *argv[])
   1.334 -{
   1.335 -	struct razor_set *set;
   1.336 -
   1.337 -	if (download_if_missing(REPO_URL "/repodata/primary.xml.gz",
   1.338 -				"primary.xml.gz") < 0)
   1.339 -		return -1;
   1.340 -	if (download_if_missing(REPO_URL "/repodata/filelists.xml.gz",
   1.341 -				"filelists.xml.gz") < 0)
   1.342 -		return -1;
   1.343 -
   1.344 -	set = razor_set_create_from_yum();
   1.345 -	if (set == NULL)
   1.346 -		return 1;
   1.347 -	razor_set_write(set, rawhide_repo_filename, RAZOR_REPO_FILE_MAIN);
   1.348 -	razor_set_write(set, "rawhide-details.repo", RAZOR_REPO_FILE_DETAILS);
   1.349 -	razor_set_write(set, "rawhide-files.repo", RAZOR_REPO_FILE_FILES);
   1.350 -	razor_set_destroy(set);
   1.351 -	printf("wrote %s\n", rawhide_repo_filename);
   1.352 -
   1.353 -	return 0;
   1.354 -}
   1.355 -
   1.356 -static int
   1.357 -command_import_rpmdb(int argc, const char *argv[])
   1.358 -{
   1.359 -	struct razor_set *set;
   1.360 -
   1.361 -	set = razor_set_create_from_rpmdb();
   1.362 -	if (set == NULL)
   1.363 -		return 1;
   1.364 -	razor_set_write(set, repo_filename, RAZOR_REPO_FILE_MAIN);
   1.365 -	razor_set_write(set, "system-details.repo", RAZOR_REPO_FILE_DETAILS);
   1.366 -	razor_set_write(set, "system-files.repo", RAZOR_REPO_FILE_FILES);
   1.367 -	razor_set_destroy(set);
   1.368 -	printf("wrote %s\n", repo_filename);
   1.369 -
   1.370 -	return 0;
   1.371 -}
   1.372 -
   1.373 -static int
   1.374 -command_validate(int argc, const char *argv[])
   1.375 -{
   1.376 -	struct razor_set *set;
   1.377 -
   1.378 -	set = razor_set_open(repo_filename);
   1.379 -	if (set == NULL)
   1.380 -		return 1;
   1.381 -	razor_set_list_unsatisfied(set);
   1.382 -	razor_set_destroy(set);
   1.383 -
   1.384 -	return 0;
   1.385 -}
   1.386 -
   1.387 -static int
   1.388 -mark_packages_for_update(struct razor_transaction *trans,
   1.389 -			 struct razor_set *set, const char *pattern)
   1.390 -{
   1.391 -	struct razor_package_iterator *pi;
   1.392 -	struct razor_package *package;
   1.393 -	const char *name, *version, *arch;
   1.394 -	int matches = 0;
   1.395 -
   1.396 -	pi = razor_package_iterator_create(set);
   1.397 -	while (razor_package_iterator_next(pi, &package,
   1.398 -					   &name, &version, &arch)) {
   1.399 -		if (pattern && fnmatch(pattern, name, 0) == 0) {
   1.400 -			razor_transaction_install_package(trans, package);
   1.401 -			matches++;
   1.402 -		}
   1.403 -	}
   1.404 -	razor_package_iterator_destroy(pi);
   1.405 -
   1.406 -	return matches;
   1.407 -}
   1.408 -
   1.409 -static int
   1.410 -mark_packages_for_removal(struct razor_transaction *trans,
   1.411 -			  struct razor_set *set, const char *pattern)
   1.412 -{
   1.413 -	struct razor_package_iterator *pi;
   1.414 -	struct razor_package *package;
   1.415 -	const char *name, *version, *arch;
   1.416 -	int matches = 0;
   1.417 -
   1.418 -	pi = razor_package_iterator_create(set);
   1.419 -	while (razor_package_iterator_next(pi, &package,
   1.420 -					   &name, &version, &arch)) {
   1.421 -		if (pattern && fnmatch(pattern, name, 0) == 0) {
   1.422 -			razor_transaction_remove_package(trans, package);
   1.423 -			matches++;
   1.424 -		}
   1.425 -	}
   1.426 -	razor_package_iterator_destroy(pi);
   1.427 -
   1.428 -	return matches;
   1.429 -}
   1.430 -
   1.431 -static int
   1.432 -command_update(int argc, const char *argv[])
   1.433 -{
   1.434 -	struct razor_set *set, *upstream;
   1.435 -	struct razor_transaction *trans;
   1.436 -	int i, errors;
   1.437 -
   1.438 -	set = razor_set_open(repo_filename);
   1.439 -	upstream = razor_set_open(rawhide_repo_filename);
   1.440 -	if (set == NULL || upstream == NULL)
   1.441 -		return 1;
   1.442 -
   1.443 -	trans = razor_transaction_create(set, upstream);
   1.444 -	if (argc == 0)
   1.445 -		razor_transaction_update_all(trans);
   1.446 -	for (i = 0; i < argc; i++) {
   1.447 -		if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
   1.448 -			fprintf(stderr, "no match for %s\n", argv[i]);
   1.449 -			return 1;
   1.450 -		}
   1.451 -	}
   1.452 -		
   1.453 -	errors = razor_transaction_resolve(trans);
   1.454 -	if (errors)
   1.455 -		return 1;
   1.456 -
   1.457 -	set = razor_transaction_finish(trans);
   1.458 -	razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN);
   1.459 -	razor_set_destroy(set);
   1.460 -	razor_set_destroy(upstream);
   1.461 -	printf("wrote system-updated.repo\n");
   1.462 -
   1.463 -	return 0;
   1.464 -}
   1.465 -
   1.466 -static int
   1.467 -command_remove(int argc, const char *argv[])
   1.468 -{
   1.469 -	struct razor_set *set;
   1.470 -	struct razor_transaction *trans;
   1.471 -	int i, errors;
   1.472 -
   1.473 -	set = razor_set_open(repo_filename);
   1.474 -	if (set == NULL)
   1.475 -		return 1;
   1.476 -
   1.477 -	trans = razor_transaction_create(set, NULL);
   1.478 -	for (i = 0; i < argc; i++) {
   1.479 -		if (mark_packages_for_removal(trans, set, argv[i]) == 0) {
   1.480 -			fprintf(stderr, "no match for %s\n", argv[i]);
   1.481 -			return 1;
   1.482 -		}
   1.483 -	}
   1.484 -
   1.485 -	errors = razor_transaction_resolve(trans);
   1.486 -	if (errors)
   1.487 -		return 1;
   1.488 -
   1.489 -	set = razor_transaction_finish(trans);
   1.490 -	razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN);
   1.491 -	razor_set_destroy(set);
   1.492 -	printf("wrote system-updated.repo\n");
   1.493 -
   1.494 -	return 0;
   1.495 -}
   1.496 -
   1.497 -static void
   1.498 -print_diff(const char *name,
   1.499 -	   const char *old_version, const char *new_version, const char *arch,
   1.500 -	   void *data)
   1.501 -{
   1.502 -	if (old_version)
   1.503 -		printf("removing %s %s\n", name, old_version);
   1.504 -	else
   1.505 -		printf("install %s %s\n", name, new_version);
   1.506 -}
   1.507 -
   1.508 -static int
   1.509 -command_diff(int argc, const char *argv[])
   1.510 -{
   1.511 -	struct razor_set *set, *updated;
   1.512 -
   1.513 -	set = razor_set_open(repo_filename);
   1.514 -	updated = razor_set_open(updated_repo_filename);
   1.515 -	if (set == NULL || updated == NULL)
   1.516 -		return 1;
   1.517 -
   1.518 -	razor_set_diff(set, updated, print_diff, NULL);	
   1.519 -
   1.520 -	razor_set_destroy(set);
   1.521 -	razor_set_destroy(updated);
   1.522 -
   1.523 -	return 0;
   1.524 -}
   1.525 -
   1.526 -static int
   1.527 -command_import_rpms(int argc, const char *argv[])
   1.528 -{
   1.529 -	DIR *dir;
   1.530 -	struct dirent *de;
   1.531 -	struct razor_importer *importer;
   1.532 -	struct razor_set *set;
   1.533 -	struct razor_rpm *rpm;
   1.534 -	int len;
   1.535 -	char filename[256];
   1.536 -	const char *dirname = argv[0];
   1.537 -
   1.538 -	if (dirname == NULL) {
   1.539 -		fprintf(stderr, "usage: razor import-rpms DIR\n");
   1.540 -		return -1;
   1.541 -	}
   1.542 -
   1.543 -	dir = opendir(dirname);
   1.544 -	if (dir == NULL) {
   1.545 -		fprintf(stderr, "couldn't read dir %s\n", dirname);
   1.546 -		return -1;
   1.547 -	}
   1.548 -
   1.549 -	importer = razor_importer_new();
   1.550 -
   1.551 -	while (de = readdir(dir), de != NULL) {
   1.552 -		len = strlen(de->d_name);
   1.553 -		if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
   1.554 -		    continue;
   1.555 -		snprintf(filename, sizeof filename,
   1.556 -			 "%s/%s", dirname, de->d_name);
   1.557 -		rpm = razor_rpm_open(filename);
   1.558 -		if (rpm == NULL) {
   1.559 -			fprintf(stderr,
   1.560 -				"failed to open rpm \"%s\"\n", filename);
   1.561 -			continue;
   1.562 -		}
   1.563 -		if (razor_importer_add_rpm(importer, rpm)) {
   1.564 -			fprintf(stderr, "couldn't import %s\n", filename);
   1.565 -			break;
   1.566 -		}
   1.567 -		razor_rpm_close(rpm);
   1.568 -	}
   1.569 -
   1.570 -	if (de != NULL) {
   1.571 -		razor_importer_destroy(importer);
   1.572 -		return -1;
   1.573 -	}
   1.574 -
   1.575 -	set = razor_importer_finish(importer);
   1.576 -
   1.577 -	razor_set_write(set, repo_filename, RAZOR_REPO_FILE_MAIN);
   1.578 -	razor_set_destroy(set);
   1.579 -	printf("wrote %s\n", repo_filename);
   1.580 -
   1.581 -	return 0;
   1.582 -}
   1.583 -
   1.584 -static void
   1.585 -download_package(const char *name,
   1.586 -		 const char *old_version,
   1.587 -		 const char *new_version,
   1.588 -		 const char *arch,
   1.589 -		 void *data)
   1.590 -{
   1.591 -	char file[PATH_MAX], url[256];
   1.592 -	const char *v;
   1.593 -	int *errors = data;
   1.594 -
   1.595 -	if (old_version)
   1.596 -		return;
   1.597 -
   1.598 -	/* Skip epoch */
   1.599 -	v = strchr(new_version, ':');
   1.600 -	if (v != NULL)
   1.601 -		v = v + 1;
   1.602 -	else
   1.603 -		v = new_version;
   1.604 -
   1.605 -	snprintf(url, sizeof url,
   1.606 -		 REPO_URL "/Packages/%s-%s.%s.rpm", name, v, arch);
   1.607 -	snprintf(file, sizeof file,
   1.608 -		 "rpms/%s-%s.%s.rpm", name, v, arch);
   1.609 -	if (download_if_missing(url, file) < 0)
   1.610 -		(*errors)++;
   1.611 -}
   1.612 -
   1.613 -static void
   1.614 -install_package(const char *name,
   1.615 -		const char *old_version,
   1.616 -		const char *new_version,
   1.617 -		const char *arch,
   1.618 -		void *data)
   1.619 -{
   1.620 -	const char *v, *root = data;
   1.621 -	char file[PATH_MAX];
   1.622 -	struct razor_rpm *rpm;
   1.623 -
   1.624 -	if (old_version) {
   1.625 -		printf("removing %s %s not handled\n", name, old_version);
   1.626 -		return;
   1.627 -	}
   1.628 -
   1.629 -	/* Skip epoch */
   1.630 -	v = strchr(new_version, ':');
   1.631 -	if (v != NULL)
   1.632 -		v = v + 1;
   1.633 -	else
   1.634 -		v = new_version;
   1.635 -
   1.636 -	printf("install %s %s\n", name, v);
   1.637 -	snprintf(file, sizeof file, "rpms/%s-%s.%s.rpm", name, v, arch);
   1.638 -
   1.639 - 	rpm = razor_rpm_open(file);
   1.640 -	if (rpm == NULL) {
   1.641 -		fprintf(stderr, "failed to open rpm %s\n", file);
   1.642 -		return;
   1.643 -	}
   1.644 -	if (razor_rpm_install(rpm, root) < 0) {
   1.645 -		fprintf(stderr,
   1.646 -			"failed to install rpm %s\n", file);
   1.647 -		return;
   1.648 -	}
   1.649 -	razor_rpm_close(rpm);
   1.650 -}
   1.651 -
   1.652 -static int
   1.653 -command_install(int argc, const char *argv[])
   1.654 -{
   1.655 -	struct razor_set *system, *upstream, *next;
   1.656 -	struct razor_transaction *trans;
   1.657 -	char path[PATH_MAX], new_path[PATH_MAX];
   1.658 -	int i = 0, errors, fd, dependencies = 1;
   1.659 -
   1.660 -	if (i < argc && strcmp(argv[i], "--no-dependencies") == 0) {
   1.661 -		dependencies = 0;
   1.662 -		i++;
   1.663 -	}
   1.664 -
   1.665 -	/* Create the new next repo file up front to ensure exclusive
   1.666 -	 * access. */
   1.667 -	snprintf(new_path, sizeof new_path,
   1.668 -		 "%s%s/%s", root, razor_root_path, next_repo_filename);
   1.669 -	fd = open(new_path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666);
   1.670 -	if (fd < 0) {
   1.671 -		fprintf(stderr, "failed to get lock file, "
   1.672 -			"maybe previous operation crashed?\n");
   1.673 -
   1.674 -		/* FIXME: Use fcntl advisory locking to figure out
   1.675 -		 * whether previous operation crashed or is still in
   1.676 -		 * progress. */
   1.677 -
   1.678 -		return -1;
   1.679 -	}
   1.680 -
   1.681 -	upstream = razor_set_open(rawhide_repo_filename);
   1.682 -	snprintf(path, sizeof path,
   1.683 -		 "%s%s/%s", root, razor_root_path, system_repo_filename);
   1.684 -	system = razor_set_open(path);
   1.685 -	if (system == NULL || upstream == NULL) {
   1.686 -		unlink(new_path);
   1.687 -		return 1;
   1.688 -	}
   1.689 -	trans = razor_transaction_create(system, upstream);
   1.690 -	for (; i < argc; i++) {
   1.691 -		if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
   1.692 -			fprintf(stderr, "no package matched %s\n", argv[i]);
   1.693 -			unlink(new_path);
   1.694 -			return 1;
   1.695 -		}
   1.696 -	}
   1.697 -
   1.698 -	if (dependencies) {
   1.699 -		errors = razor_transaction_resolve(trans);
   1.700 -		if (errors) {
   1.701 -			unlink(new_path);
   1.702 -			return 1;
   1.703 -		}
   1.704 -	}
   1.705 -
   1.706 -	next = razor_transaction_finish(trans);
   1.707 -
   1.708 -	razor_set_write_to_fd(next, fd, RAZOR_REPO_FILE_MAIN);
   1.709 -	printf("wrote %s\n", new_path);
   1.710 -
   1.711 -	if (mkdir("rpms", 0777) && errno != EEXIST) {
   1.712 -		fprintf(stderr, "failed to create rpms directory.\n");
   1.713 -		return 1;
   1.714 -	}
   1.715 -
   1.716 -	razor_set_diff(system, next, download_package, &errors);
   1.717 -	if (errors > 0) {
   1.718 -		fprintf(stderr, "failed to download %d packages\n", errors);
   1.719 -		unlink(new_path);
   1.720 -                return 1;
   1.721 -        }
   1.722 -
   1.723 -	/* FIXME: We need to figure out the right install order here,
   1.724 -	 * so the post and pre scripts can run. */
   1.725 -	razor_set_diff(system, next, install_package, (void *) root);
   1.726 -
   1.727 -	razor_set_destroy(next);
   1.728 -	razor_set_destroy(system);
   1.729 -	razor_set_destroy(upstream);
   1.730 -
   1.731 -	/* Make it so. */
   1.732 -	rename(new_path, path);
   1.733 -	printf("renamed %s to %s\n", new_path, path);
   1.734 -
   1.735 -	return 0;
   1.736 -}
   1.737 -
   1.738 -static int
   1.739 -command_init(int argc, const char *argv[])
   1.740 -{
   1.741 -	struct stat buf;
   1.742 -	struct razor_set *set;
   1.743 -	char path[PATH_MAX];
   1.744 -
   1.745 -	if (stat(root, &buf) < 0) {
   1.746 -		if (mkdir(root, 0777) < 0) {
   1.747 -			fprintf(stderr,
   1.748 -				"could not create install root \"%s\"\n",
   1.749 -				root);
   1.750 -			return -1;
   1.751 -		}
   1.752 -		fprintf(stderr, "created install root \"%s\"\n", root);
   1.753 -	} else if (!S_ISDIR(buf.st_mode)) {
   1.754 -		fprintf(stderr,
   1.755 -			"install root \"%s\" exists, but is not a directory\n",
   1.756 -			root);
   1.757 -		return -1;
   1.758 -	}
   1.759 -
   1.760 -	snprintf(path, sizeof path, "%s/%s",
   1.761 -		 razor_root_path, system_repo_filename);
   1.762 -	if (razor_create_dir(root, path) < 0) {
   1.763 -		fprintf(stderr, "could not create %s%s\n",
   1.764 -			root, razor_root_path);
   1.765 -		return -1;
   1.766 -	}
   1.767 -
   1.768 -	set = razor_set_create();
   1.769 -	snprintf(path, sizeof path, "%s%s/%s",
   1.770 -		 root, razor_root_path, system_repo_filename);
   1.771 -	if (razor_set_write(set, path, RAZOR_REPO_FILE_MAIN) < 0) {
   1.772 -		fprintf(stderr, "could not write initial package set\n");
   1.773 -		return -1;
   1.774 -	}
   1.775 -	razor_set_destroy(set);
   1.776 -
   1.777 -	return 0;
   1.778 -}
   1.779 -
   1.780 -static int
   1.781 -command_download(int argc, const char *argv[])
   1.782 -{
   1.783 -	struct razor_set *set;
   1.784 -	struct razor_package_iterator *pi;
   1.785 -	struct razor_package *package;
   1.786 -	const char *pattern = argv[0], *name, *version, *arch;
   1.787 -	char url[256], file[256];
   1.788 -	int matches = 0;
   1.789 -
   1.790 -	if (mkdir("rpms", 0777) && errno != EEXIST) {
   1.791 -		fprintf(stderr, "failed to create rpms directory.\n");
   1.792 -		return 1;
   1.793 -	}
   1.794 -
   1.795 -	set = razor_set_open(rawhide_repo_filename);
   1.796 -	pi = razor_package_iterator_create(set);
   1.797 -	while (razor_package_iterator_next(pi, &package,
   1.798 -					   &name, &version, &arch)) {
   1.799 -		if (pattern && fnmatch(pattern, name, 0) != 0)
   1.800 -			continue;
   1.801 -
   1.802 -		matches++;
   1.803 -		snprintf(url, sizeof url,
   1.804 -			 REPO_URL "/Packages/%s-%s.%s.rpm",
   1.805 -			 name, version, arch);
   1.806 -		snprintf(file, sizeof file,
   1.807 -			 "rpms/%s-%s.%s.rpm", name, version, arch);
   1.808 -		download_if_missing(url, file);
   1.809 -	}
   1.810 -	razor_package_iterator_destroy(pi);
   1.811 -	razor_set_destroy(set);
   1.812 -
   1.813 -	if (matches == 0)
   1.814 -		fprintf(stderr, "no packages matched \"%s\"\n", pattern);
   1.815 -	else if (matches == 1)
   1.816 -		fprintf(stderr, "downloaded 1 package\n");
   1.817 -	else
   1.818 -		fprintf(stderr, "downloaded %d packages\n", matches);
   1.819 -
   1.820 -	return 0;
   1.821 -}
   1.822 -
   1.823 -static int
   1.824 -command_info(int argc, const char *argv[])
   1.825 -{
   1.826 -	struct razor_set *set;
   1.827 -	struct razor_package_iterator *pi;
   1.828 -	struct razor_package *package;
   1.829 -	const char *pattern = argv[0], *name, *version, *arch;
   1.830 -	const char *summary, *description, *url, *license;
   1.831 -
   1.832 -	set = razor_set_open(repo_filename);
   1.833 -	razor_set_open_details(set, "system-details.repo");
   1.834 -	pi = razor_package_iterator_create(set);
   1.835 -	while (razor_package_iterator_next(pi, &package,
   1.836 -					   &name, &version, &arch)) {
   1.837 -		if (pattern && fnmatch(pattern, name, 0) != 0)
   1.838 -			continue;
   1.839 -
   1.840 -		razor_package_get_details (set, package, &summary, &description,
   1.841 -					   &url, &license);
   1.842 -
   1.843 -		printf ("Name:        %s\n", name);
   1.844 -		printf ("Arch:        %s\n", arch);
   1.845 -		printf ("Version:     %s\n", version);
   1.846 -		printf ("URL:         %s\n", url);
   1.847 -		printf ("License:     %s\n", license);
   1.848 -		printf ("Summary:     %s\n", summary);
   1.849 -		printf ("Description:\n");
   1.850 -		printf ("%s\n", description);
   1.851 -		printf ("\n");
   1.852 -	}
   1.853 -	razor_package_iterator_destroy(pi);
   1.854 -	razor_set_destroy(set);
   1.855 -
   1.856 -	return 0;
   1.857 -}
   1.858 -
   1.859 -static struct {
   1.860 -	const char *name;
   1.861 -	const char *description;
   1.862 -	int (*func)(int argc, const char *argv[]);
   1.863 -} razor_commands[] = {
   1.864 -	{ "list", "list all packages", command_list },
   1.865 -	{ "list-requires", "list all requires for the given package", command_list_requires },
   1.866 -	{ "list-provides", "list all provides for the given package", command_list_provides },
   1.867 -	{ "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
   1.868 -	{ "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
   1.869 -	{ "list-files", "list files for package set", command_list_files },
   1.870 -	{ "list-file-packages", "list packages owning file", command_list_file_packages },
   1.871 -	{ "list-package-files", "list files in package", command_list_package_files },
   1.872 -	{ "what-requires", "list the packages that have the given requires", command_what_requires },
   1.873 -	{ "what-provides", "list the packages that have the given provides", command_what_provides },
   1.874 -	{ "import-yum", "import yum metadata files", command_import_yum },
   1.875 -	{ "import-rpmdb", "import the system rpm database", command_import_rpmdb },
   1.876 -	{ "import-rpms", "import rpms from the given directory", command_import_rpms },
   1.877 -	{ "validate", "validate a package set", command_validate },
   1.878 -	{ "update", "update all or specified packages", command_update },
   1.879 -	{ "remove", "remove specified packages", command_remove },
   1.880 -	{ "diff", "show diff between two package sets", command_diff },
   1.881 -	{ "install", "install rpm", command_install },
   1.882 -	{ "init", "init razor root", command_init },
   1.883 -	{ "download", "download packages", command_download },
   1.884 -	{ "info", "display package details", command_info }
   1.885 -};
   1.886 -
   1.887 -static int
   1.888 -usage(void)
   1.889 -{
   1.890 -	int i;
   1.891 -
   1.892 -	printf("usage:\n");
   1.893 -	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
   1.894 -		printf("  %-20s%s\n",
   1.895 -		       razor_commands[i].name, razor_commands[i].description);
   1.896 -
   1.897 -	return 1;
   1.898 -}
   1.899 -
   1.900 -int
   1.901 -main(int argc, const char *argv[])
   1.902 -{
   1.903 -	char *repo;
   1.904 -	int i;
   1.905 -
   1.906 -	repo = getenv("RAZOR_REPO");
   1.907 -	if (repo != NULL)
   1.908 -		repo_filename = repo;
   1.909 -
   1.910 -	if (argc < 2)
   1.911 -		return usage();
   1.912 -
   1.913 -	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
   1.914 -		if (strcmp(razor_commands[i].name, argv[1]) == 0)
   1.915 -			return razor_commands[i].func(argc - 2, argv + 2);
   1.916 -
   1.917 -	return usage();
   1.918 -}