1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/main.c Mon Jun 16 15:40:30 2008 -0400
1.3 @@ -0,0 +1,804 @@
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 +
1.37 +static const char system_repo_filename[] = "system.repo";
1.38 +static const char next_repo_filename[] = "system-next.repo";
1.39 +static const char rawhide_repo_filename[] = "rawhide.repo";
1.40 +static const char updated_repo_filename[] = "system-updated.repo";
1.41 +static const char install_root[] = "install";
1.42 +static const char *repo_filename = system_repo_filename;
1.43 +static const char *yum_url;
1.44 +
1.45 +static int
1.46 +command_list(int argc, const char *argv[])
1.47 +{
1.48 + struct razor_set *set;
1.49 + struct razor_package_iterator *pi;
1.50 + struct razor_package *package;
1.51 + const char *pattern, *name, *version, *arch;
1.52 + int only_names = 0, i = 0;
1.53 +
1.54 + if (i < argc && strcmp(argv[i], "--only-names") == 0) {
1.55 + only_names = 1;
1.56 + i++;
1.57 + }
1.58 +
1.59 + pattern = argv[i];
1.60 + set = razor_set_open(repo_filename);
1.61 + pi = razor_package_iterator_create(set);
1.62 + while (razor_package_iterator_next(pi, &package,
1.63 + &name, &version, &arch)) {
1.64 + if (pattern && fnmatch(pattern, name, 0) != 0)
1.65 + continue;
1.66 +
1.67 + if (only_names)
1.68 + printf("%s\n", name);
1.69 + else
1.70 + printf("%s-%s.%s\n", name, version, arch);
1.71 + }
1.72 + razor_package_iterator_destroy(pi);
1.73 + razor_set_destroy(set);
1.74 +
1.75 + return 0;
1.76 +}
1.77 +
1.78 +static int
1.79 +list_properties(const char *package_name,
1.80 + enum razor_property_type required_type)
1.81 +{
1.82 + static const char *relation_string[] = { "<", "<=", "=", ">=", ">" };
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 + relation_string[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 + if (set == NULL)
1.147 + return 1;
1.148 + razor_set_list_files(set, argv[0]);
1.149 + razor_set_destroy(set);
1.150 +
1.151 + return 0;
1.152 +}
1.153 +
1.154 +static int
1.155 +command_list_file_packages(int argc, const char *argv[])
1.156 +{
1.157 + struct razor_set *set;
1.158 + struct razor_package_iterator *pi;
1.159 + struct razor_package *package;
1.160 + const char *name, *version, *arch;
1.161 +
1.162 + set = razor_set_open(repo_filename);
1.163 + if (set == NULL)
1.164 + return 1;
1.165 +
1.166 + pi = razor_package_iterator_create_for_file(set, argv[0]);
1.167 + while (razor_package_iterator_next(pi, &package,
1.168 + &name, &version, &arch))
1.169 + printf("%s-%s\n", name, version);
1.170 + razor_package_iterator_destroy(pi);
1.171 +
1.172 + razor_set_destroy(set);
1.173 +
1.174 + return 0;
1.175 +}
1.176 +
1.177 +static int
1.178 +command_list_package_files(int argc, const char *argv[])
1.179 +{
1.180 + struct razor_set *set;
1.181 +
1.182 + set = razor_set_open(repo_filename);
1.183 + if (set == NULL)
1.184 + return 1;
1.185 + razor_set_list_package_files(set, argv[0]);
1.186 + razor_set_destroy(set);
1.187 +
1.188 + return 0;
1.189 +}
1.190 +
1.191 +static void
1.192 +list_packages_for_property(struct razor_set *set,
1.193 + struct razor_property *property)
1.194 +{
1.195 + struct razor_package_iterator *pi;
1.196 + struct razor_package *package;
1.197 + const char *name, *version, *arch;
1.198 +
1.199 + pi = razor_package_iterator_create_for_property(set, property);
1.200 + while (razor_package_iterator_next(pi, &package,
1.201 + &name, &version, &arch))
1.202 + printf("%s-%s.%s\n", name, version, arch);
1.203 + razor_package_iterator_destroy(pi);
1.204 +}
1.205 +
1.206 +static int
1.207 +list_property_packages(const char *ref_name,
1.208 + const char *ref_version,
1.209 + enum razor_property_type ref_type)
1.210 +{
1.211 + struct razor_set *set;
1.212 + struct razor_property *property;
1.213 + struct razor_property_iterator *pi;
1.214 + const char *name, *version;
1.215 + enum razor_property_type type;
1.216 + enum razor_version_relation relation;
1.217 +
1.218 + if (ref_name == NULL)
1.219 + return 0;
1.220 +
1.221 + set = razor_set_open(repo_filename);
1.222 + if (set == NULL)
1.223 + return 1;
1.224 +
1.225 + pi = razor_property_iterator_create(set, NULL);
1.226 + while (razor_property_iterator_next(pi, &property,
1.227 + &name, &relation, &version,
1.228 + &type)) {
1.229 + if (strcmp(ref_name, name) != 0)
1.230 + continue;
1.231 + if (ref_version && relation == RAZOR_VERSION_EQUAL &&
1.232 + strcmp(ref_version, version) != 0)
1.233 + continue;
1.234 + if (ref_type != type)
1.235 + continue;
1.236 +
1.237 + list_packages_for_property(set, property);
1.238 + }
1.239 + razor_property_iterator_destroy(pi);
1.240 +
1.241 + return 0;
1.242 +}
1.243 +
1.244 +static int
1.245 +command_what_requires(int argc, const char *argv[])
1.246 +{
1.247 + return list_property_packages(argv[0], argv[1],
1.248 + RAZOR_PROPERTY_REQUIRES);
1.249 +}
1.250 +
1.251 +static int
1.252 +command_what_provides(int argc, const char *argv[])
1.253 +{
1.254 + return list_property_packages(argv[0], argv[1],
1.255 + RAZOR_PROPERTY_PROVIDES);
1.256 +}
1.257 +
1.258 +static int
1.259 +show_progress(void *clientp,
1.260 + double dltotal, double dlnow, double ultotal, double ulnow)
1.261 +{
1.262 + const char *file = clientp;
1.263 +
1.264 + if (!dlnow < dltotal)
1.265 + fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
1.266 + file, (int) dlnow / 1024, (int) dltotal / 1024);
1.267 +
1.268 + return 0;
1.269 +}
1.270 +
1.271 +static int
1.272 +download_if_missing(const char *url, const char *file)
1.273 +{
1.274 + CURL *curl;
1.275 + struct stat buf;
1.276 + char error[256];
1.277 + FILE *fp;
1.278 + CURLcode res;
1.279 + long response;
1.280 +
1.281 + curl = curl_easy_init();
1.282 + if (curl == NULL)
1.283 + return 1;
1.284 +
1.285 + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
1.286 + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
1.287 + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
1.288 + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
1.289 +
1.290 + if (stat(file, &buf) < 0) {
1.291 + fp = fopen(file, "w");
1.292 + if (fp == NULL) {
1.293 + fprintf(stderr,
1.294 + "failed to open %s for writing\n", file);
1.295 + return -1;
1.296 + }
1.297 + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
1.298 + curl_easy_setopt(curl, CURLOPT_URL, url);
1.299 + res = curl_easy_perform(curl);
1.300 + fclose(fp);
1.301 + if (res != CURLE_OK) {
1.302 + fprintf(stderr, "curl error: %s\n", error);
1.303 + unlink(file);
1.304 + return -1;
1.305 + }
1.306 + res = curl_easy_getinfo(curl,
1.307 + CURLINFO_RESPONSE_CODE, &response);
1.308 + if (res != CURLE_OK) {
1.309 + fprintf(stderr, "curl error: %s\n", error);
1.310 + unlink(file);
1.311 + return -1;
1.312 + }
1.313 + if (response != 200) {
1.314 + fprintf(stderr, " - failed %ld\n", response);
1.315 + unlink(file);
1.316 + return -1;
1.317 + }
1.318 + fprintf(stderr, "\n");
1.319 + }
1.320 +
1.321 + curl_easy_cleanup(curl);
1.322 +
1.323 + return 0;
1.324 +}
1.325 +
1.326 +#define YUM_URL "http://download.fedora.redhat.com" \
1.327 + "/pub/fedora/linux/development/i386/os"
1.328 +
1.329 +static int
1.330 +command_import_yum(int argc, const char *argv[])
1.331 +{
1.332 + struct razor_set *set;
1.333 + char buffer[512];
1.334 +
1.335 + printf("downloading from %s.\n", yum_url);
1.336 + snprintf(buffer, sizeof buffer,
1.337 + "%s/repodata/primary.xml.gz", yum_url);
1.338 + if (download_if_missing(buffer, "primary.xml.gz") < 0)
1.339 + return -1;
1.340 + snprintf(buffer, sizeof buffer,
1.341 + "%s/repodata/filelists.xml.gz", yum_url);
1.342 + if (download_if_missing(buffer, "filelists.xml.gz") < 0)
1.343 + return -1;
1.344 +
1.345 + set = razor_set_create_from_yum();
1.346 + if (set == NULL)
1.347 + return 1;
1.348 + razor_set_write(set, rawhide_repo_filename);
1.349 + razor_set_destroy(set);
1.350 + printf("wrote %s\n", rawhide_repo_filename);
1.351 +
1.352 + return 0;
1.353 +}
1.354 +
1.355 +static int
1.356 +command_import_rpmdb(int argc, const char *argv[])
1.357 +{
1.358 + struct razor_set *set;
1.359 +
1.360 + set = razor_set_create_from_rpmdb();
1.361 + if (set == NULL)
1.362 + return 1;
1.363 + razor_set_write(set, repo_filename);
1.364 + razor_set_destroy(set);
1.365 + printf("wrote %s\n", repo_filename);
1.366 +
1.367 + return 0;
1.368 +}
1.369 +
1.370 +static int
1.371 +mark_packages_for_update(struct razor_transaction *trans,
1.372 + struct razor_set *set, const char *pattern)
1.373 +{
1.374 + struct razor_package_iterator *pi;
1.375 + struct razor_package *package;
1.376 + const char *name, *version, *arch;
1.377 + int matches = 0;
1.378 +
1.379 + pi = razor_package_iterator_create(set);
1.380 + while (razor_package_iterator_next(pi, &package,
1.381 + &name, &version, &arch)) {
1.382 + if (pattern && fnmatch(pattern, name, 0) == 0) {
1.383 + razor_transaction_update_package(trans, package);
1.384 + matches++;
1.385 + }
1.386 + }
1.387 + razor_package_iterator_destroy(pi);
1.388 +
1.389 + return matches;
1.390 +}
1.391 +
1.392 +static int
1.393 +mark_packages_for_removal(struct razor_transaction *trans,
1.394 + struct razor_set *set, const char *pattern)
1.395 +{
1.396 + struct razor_package_iterator *pi;
1.397 + struct razor_package *package;
1.398 + const char *name, *version, *arch;
1.399 + int matches = 0;
1.400 +
1.401 + pi = razor_package_iterator_create(set);
1.402 + while (razor_package_iterator_next(pi, &package,
1.403 + &name, &version, &arch)) {
1.404 + if (pattern && fnmatch(pattern, name, 0) == 0) {
1.405 + razor_transaction_remove_package(trans, package);
1.406 + matches++;
1.407 + }
1.408 + }
1.409 + razor_package_iterator_destroy(pi);
1.410 +
1.411 + return matches;
1.412 +}
1.413 +
1.414 +static int
1.415 +command_update(int argc, const char *argv[])
1.416 +{
1.417 + struct razor_set *set, *upstream;
1.418 + struct razor_transaction *trans;
1.419 + int i, errors;
1.420 +
1.421 + set = razor_set_open(repo_filename);
1.422 + upstream = razor_set_open(rawhide_repo_filename);
1.423 + if (set == NULL || upstream == NULL)
1.424 + return 1;
1.425 +
1.426 + trans = razor_transaction_create(set, upstream);
1.427 + if (argc == 0)
1.428 + razor_transaction_update_all(trans);
1.429 + for (i = 0; i < argc; i++) {
1.430 + if (mark_packages_for_update(trans, set, argv[i]) == 0) {
1.431 + fprintf(stderr, "no match for %s\n", argv[i]);
1.432 + return 1;
1.433 + }
1.434 + }
1.435 +
1.436 + errors = razor_transaction_resolve(trans);
1.437 + if (errors)
1.438 + return 1;
1.439 +
1.440 + set = razor_transaction_finish(trans);
1.441 + razor_set_write(set, updated_repo_filename);
1.442 + razor_set_destroy(set);
1.443 + razor_set_destroy(upstream);
1.444 + printf("wrote system-updated.repo\n");
1.445 +
1.446 + return 0;
1.447 +}
1.448 +
1.449 +static int
1.450 +command_remove(int argc, const char *argv[])
1.451 +{
1.452 + struct razor_set *set, *upstream;
1.453 + struct razor_transaction *trans;
1.454 + int i, errors;
1.455 +
1.456 + set = razor_set_open(repo_filename);
1.457 + if (set == NULL)
1.458 + return 1;
1.459 +
1.460 + upstream = razor_set_create();
1.461 + trans = razor_transaction_create(set, upstream);
1.462 + for (i = 0; i < argc; i++) {
1.463 + if (mark_packages_for_removal(trans, set, argv[i]) == 0) {
1.464 + fprintf(stderr, "no match for %s\n", argv[i]);
1.465 + return 1;
1.466 + }
1.467 + }
1.468 +
1.469 + errors = razor_transaction_resolve(trans);
1.470 + if (errors)
1.471 + return 1;
1.472 +
1.473 + set = razor_transaction_finish(trans);
1.474 + razor_set_write(set, updated_repo_filename);
1.475 + razor_set_destroy(set);
1.476 + razor_set_destroy(upstream);
1.477 + printf("wrote system-updated.repo\n");
1.478 +
1.479 + return 0;
1.480 +}
1.481 +
1.482 +static void
1.483 +print_diff(const char *name,
1.484 + const char *old_version, const char *new_version, const char *arch,
1.485 + void *data)
1.486 +{
1.487 + if (old_version)
1.488 + printf("removing %s %s\n", name, old_version);
1.489 + else
1.490 + printf("install %s %s\n", name, new_version);
1.491 +}
1.492 +
1.493 +static int
1.494 +command_diff(int argc, const char *argv[])
1.495 +{
1.496 + struct razor_set *set, *updated;
1.497 +
1.498 + set = razor_set_open(repo_filename);
1.499 + updated = razor_set_open(updated_repo_filename);
1.500 + if (set == NULL || updated == NULL)
1.501 + return 1;
1.502 +
1.503 + razor_set_diff(set, updated, print_diff, NULL);
1.504 +
1.505 + razor_set_destroy(set);
1.506 + razor_set_destroy(updated);
1.507 +
1.508 + return 0;
1.509 +}
1.510 +
1.511 +static int
1.512 +command_import_rpms(int argc, const char *argv[])
1.513 +{
1.514 + DIR *dir;
1.515 + struct dirent *de;
1.516 + struct razor_importer *importer;
1.517 + struct razor_set *set;
1.518 + struct razor_rpm *rpm;
1.519 + int len;
1.520 + char filename[256];
1.521 + const char *dirname = argv[0];
1.522 +
1.523 + if (dirname == NULL) {
1.524 + fprintf(stderr, "usage: razor import-rpms DIR\n");
1.525 + return -1;
1.526 + }
1.527 +
1.528 + dir = opendir(dirname);
1.529 + if (dir == NULL) {
1.530 + fprintf(stderr, "couldn't read dir %s\n", dirname);
1.531 + return -1;
1.532 + }
1.533 +
1.534 + importer = razor_importer_new();
1.535 +
1.536 + while (de = readdir(dir), de != NULL) {
1.537 + len = strlen(de->d_name);
1.538 + if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
1.539 + continue;
1.540 + snprintf(filename, sizeof filename,
1.541 + "%s/%s", dirname, de->d_name);
1.542 + rpm = razor_rpm_open(filename);
1.543 + if (rpm == NULL) {
1.544 + fprintf(stderr,
1.545 + "failed to open rpm \"%s\"\n", filename);
1.546 + continue;
1.547 + }
1.548 + if (razor_importer_add_rpm(importer, rpm)) {
1.549 + fprintf(stderr, "couldn't import %s\n", filename);
1.550 + break;
1.551 + }
1.552 + razor_rpm_close(rpm);
1.553 + }
1.554 +
1.555 + if (de != NULL) {
1.556 + razor_importer_destroy(importer);
1.557 + return -1;
1.558 + }
1.559 +
1.560 + set = razor_importer_finish(importer);
1.561 +
1.562 + razor_set_write(set, repo_filename);
1.563 + razor_set_destroy(set);
1.564 + printf("wrote %s\n", repo_filename);
1.565 +
1.566 + return 0;
1.567 +}
1.568 +
1.569 +static void
1.570 +download_package(const char *name,
1.571 + const char *old_version,
1.572 + const char *new_version,
1.573 + const char *arch,
1.574 + void *data)
1.575 +{
1.576 + char file[PATH_MAX], url[256];
1.577 + const char *v;
1.578 + int *errors = data;
1.579 +
1.580 + if (old_version)
1.581 + return;
1.582 +
1.583 + /* Skip epoch */
1.584 + v = strchr(new_version, ':');
1.585 + if (v != NULL)
1.586 + v = v + 1;
1.587 + else
1.588 + v = new_version;
1.589 +
1.590 + snprintf(url, sizeof url,
1.591 + "%s/Packages/%s-%s.%s.rpm", yum_url, name, v, arch);
1.592 + snprintf(file, sizeof file,
1.593 + "rpms/%s-%s.%s.rpm", name, v, arch);
1.594 + if (download_if_missing(url, file) < 0)
1.595 + (*errors)++;
1.596 +}
1.597 +
1.598 +static void
1.599 +install_package(const char *name,
1.600 + const char *old_version,
1.601 + const char *new_version,
1.602 + const char *arch,
1.603 + void *data)
1.604 +{
1.605 + const char *v, *root = data;
1.606 + char file[PATH_MAX];
1.607 + struct razor_rpm *rpm;
1.608 +
1.609 + if (old_version) {
1.610 + printf("removing %s %s not handled\n", name, old_version);
1.611 + return;
1.612 + }
1.613 +
1.614 + /* Skip epoch */
1.615 + v = strchr(new_version, ':');
1.616 + if (v != NULL)
1.617 + v = v + 1;
1.618 + else
1.619 + v = new_version;
1.620 +
1.621 + printf("install %s %s\n", name, v);
1.622 + snprintf(file, sizeof file, "rpms/%s-%s.%s.rpm", name, v, arch);
1.623 +
1.624 + rpm = razor_rpm_open(file);
1.625 + if (rpm == NULL) {
1.626 + fprintf(stderr, "failed to open rpm %s\n", file);
1.627 + return;
1.628 + }
1.629 + if (razor_rpm_install(rpm, root) < 0) {
1.630 + fprintf(stderr,
1.631 + "failed to install rpm %s\n", file);
1.632 + return;
1.633 + }
1.634 + razor_rpm_close(rpm);
1.635 +}
1.636 +
1.637 +static int
1.638 +command_install(int argc, const char *argv[])
1.639 +{
1.640 + struct razor_root *root;
1.641 + struct razor_set *upstream, *next;
1.642 + struct razor_transaction *trans;
1.643 + int i = 0, errors, dependencies = 1;
1.644 +
1.645 + if (i < argc && strcmp(argv[i], "--no-dependencies") == 0) {
1.646 + dependencies = 0;
1.647 + i++;
1.648 + }
1.649 +
1.650 + root = razor_root_open(install_root, RAZOR_ROOT_OPEN_WRITE);
1.651 + upstream = razor_set_open(rawhide_repo_filename);
1.652 + trans = razor_root_create_transaction(root, upstream);
1.653 +
1.654 + for (; i < argc; i++) {
1.655 + if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
1.656 + fprintf(stderr, "no package matched %s\n", argv[i]);
1.657 + razor_root_close(root);
1.658 + return 1;
1.659 + }
1.660 + }
1.661 +
1.662 + if (dependencies) {
1.663 + errors = razor_transaction_resolve(trans);
1.664 + if (errors) {
1.665 + razor_root_close(root);
1.666 + return 1;
1.667 + }
1.668 + }
1.669 +
1.670 + next = razor_transaction_finish(trans);
1.671 +
1.672 + razor_root_update(root, next);
1.673 +
1.674 + if (mkdir("rpms", 0777) && errno != EEXIST) {
1.675 + fprintf(stderr, "failed to create rpms directory.\n");
1.676 + razor_root_close(root);
1.677 + return 1;
1.678 + }
1.679 +
1.680 + razor_root_diff(root, download_package, &errors);
1.681 + if (errors > 0) {
1.682 + fprintf(stderr, "failed to download %d packages\n", errors);
1.683 + razor_root_close(root);
1.684 + return 1;
1.685 + }
1.686 +
1.687 + /* FIXME: We need to figure out the right install order here,
1.688 + * so the post and pre scripts can run. */
1.689 + razor_root_diff(root, install_package, (void *) root);
1.690 +
1.691 + razor_set_destroy(next);
1.692 + razor_set_destroy(upstream);
1.693 +
1.694 + return razor_root_commit(root);
1.695 +}
1.696 +
1.697 +static int
1.698 +command_init(int argc, const char *argv[])
1.699 +{
1.700 + return razor_root_create(install_root);
1.701 +}
1.702 +
1.703 +static int
1.704 +command_download(int argc, const char *argv[])
1.705 +{
1.706 + struct razor_set *set;
1.707 + struct razor_package_iterator *pi;
1.708 + struct razor_package *package;
1.709 + const char *pattern = argv[0], *name, *version, *arch;
1.710 + char url[256], file[256];
1.711 + int matches = 0;
1.712 +
1.713 + if (mkdir("rpms", 0777) && errno != EEXIST) {
1.714 + fprintf(stderr, "failed to create rpms directory.\n");
1.715 + return 1;
1.716 + }
1.717 +
1.718 + set = razor_set_open(rawhide_repo_filename);
1.719 + pi = razor_package_iterator_create(set);
1.720 + while (razor_package_iterator_next(pi, &package,
1.721 + &name, &version, &arch)) {
1.722 + if (pattern && fnmatch(pattern, name, 0) != 0)
1.723 + continue;
1.724 +
1.725 + matches++;
1.726 + snprintf(url, sizeof url,
1.727 + "%s/Packages/%s-%s.%s.rpm",
1.728 + yum_url, name, version, arch);
1.729 + snprintf(file, sizeof file,
1.730 + "rpms/%s-%s.%s.rpm", name, version, arch);
1.731 + download_if_missing(url, file);
1.732 + }
1.733 + razor_package_iterator_destroy(pi);
1.734 + razor_set_destroy(set);
1.735 +
1.736 + if (matches == 0)
1.737 + fprintf(stderr, "no packages matched \"%s\"\n", pattern);
1.738 + else if (matches == 1)
1.739 + fprintf(stderr, "downloaded 1 package\n");
1.740 + else
1.741 + fprintf(stderr, "downloaded %d packages\n", matches);
1.742 +
1.743 + return 0;
1.744 +}
1.745 +
1.746 +static struct {
1.747 + const char *name;
1.748 + const char *description;
1.749 + int (*func)(int argc, const char *argv[]);
1.750 +} razor_commands[] = {
1.751 + { "list", "list all packages", command_list },
1.752 + { "list-requires", "list all requires for the given package", command_list_requires },
1.753 + { "list-provides", "list all provides for the given package", command_list_provides },
1.754 + { "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
1.755 + { "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
1.756 + { "list-files", "list files for package set", command_list_files },
1.757 + { "list-file-packages", "list packages owning file", command_list_file_packages },
1.758 + { "list-package-files", "list files in package", command_list_package_files },
1.759 + { "what-requires", "list the packages that have the given requires", command_what_requires },
1.760 + { "what-provides", "list the packages that have the given provides", command_what_provides },
1.761 + { "import-yum", "import yum metadata files", command_import_yum },
1.762 + { "import-rpmdb", "import the system rpm database", command_import_rpmdb },
1.763 + { "import-rpms", "import rpms from the given directory", command_import_rpms },
1.764 + { "update", "update all or specified packages", command_update },
1.765 + { "remove", "remove specified packages", command_remove },
1.766 + { "diff", "show diff between two package sets", command_diff },
1.767 + { "install", "install rpm", command_install },
1.768 + { "init", "init razor root", command_init },
1.769 + { "download", "download packages", command_download }
1.770 +};
1.771 +
1.772 +static int
1.773 +usage(void)
1.774 +{
1.775 + int i;
1.776 +
1.777 + printf("usage:\n");
1.778 + for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1.779 + printf(" %-20s%s\n",
1.780 + razor_commands[i].name, razor_commands[i].description);
1.781 +
1.782 + return 1;
1.783 +}
1.784 +
1.785 +int
1.786 +main(int argc, const char *argv[])
1.787 +{
1.788 + char *repo;
1.789 + int i;
1.790 +
1.791 + repo = getenv("RAZOR_REPO");
1.792 + if (repo != NULL)
1.793 + repo_filename = repo;
1.794 +
1.795 + yum_url = getenv("YUM_URL");
1.796 + if (yum_url == NULL)
1.797 + yum_url = YUM_URL;
1.798 +
1.799 + if (argc < 2)
1.800 + return usage();
1.801 +
1.802 + for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
1.803 + if (strcmp(razor_commands[i].name, argv[1]) == 0)
1.804 + return razor_commands[i].func(argc - 2, argv + 2);
1.805 +
1.806 + return usage();
1.807 +}