src/main.c
author J. Ali Harlow <ali@juiblex.co.uk>
Thu Feb 09 20:45:27 2012 +0000 (2012-02-09)
changeset 418 33b825d3128d
parent 412 810d9ba06afd
child 421 408c66ad463d
permissions -rw-r--r--
Add transaction barriers
These allow packages to be installed and removed which have scripts
that depend on each other when atomic transactions are involved.
Note that yum supports pre, but not other requires flags. post will
need similar support to the post scripts themselves pulling in the
requires flags from the rpms. Likewise preun and postun will need
similar handling to those scrips since the requires flags will need
to be stored in the razor database.
rhughes@241
     1
/*
rhughes@241
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
rhughes@241
     3
 * Copyright (C) 2008  Red Hat, Inc
ali@418
     4
 * Copyright (C) 2009, 2011-2012  J. Ali Harlow <ali@juiblex.co.uk>
rhughes@241
     5
 *
rhughes@241
     6
 * This program is free software; you can redistribute it and/or modify
rhughes@241
     7
 * it under the terms of the GNU General Public License as published by
rhughes@241
     8
 * the Free Software Foundation; either version 2 of the License, or
rhughes@241
     9
 * (at your option) any later version.
rhughes@241
    10
 *
rhughes@241
    11
 * This program is distributed in the hope that it will be useful,
rhughes@241
    12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rhughes@241
    13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
rhughes@241
    14
 * GNU General Public License for more details.
rhughes@241
    15
 *
rhughes@241
    16
 * You should have received a copy of the GNU General Public License along
rhughes@241
    17
 * with this program; if not, write to the Free Software Foundation, Inc.,
rhughes@241
    18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
rhughes@241
    19
 */
rhughes@241
    20
krh@305
    21
#define _GNU_SOURCE
krh@305
    22
ali@321
    23
#include "config.h"
ali@321
    24
rhughes@241
    25
#include <stdlib.h>
rhughes@241
    26
#include <stddef.h>
rhughes@241
    27
#include <stdio.h>
rhughes@241
    28
#include <stdint.h>
rhughes@241
    29
#include <string.h>
rhughes@241
    30
#include <sys/stat.h>
rhughes@241
    31
#include <unistd.h>
rhughes@241
    32
#include <fcntl.h>
rhughes@241
    33
#include <dirent.h>
ali@325
    34
#include <limits.h>
ali@321
    35
#ifdef HAVE_CURL
rhughes@241
    36
#include <curl/curl.h>
ali@321
    37
#endif
rhughes@241
    38
#include <fnmatch.h>
rhughes@241
    39
#include <errno.h>
rhughes@241
    40
#include "razor.h"
rhughes@241
    41
richard@310
    42
static const char system_repo_filename[] = "system.rzdb";
richard@310
    43
static const char next_repo_filename[] = "system-next.rzdb";
richard@310
    44
static const char rawhide_repo_filename[] = "rawhide.rzdb";
krh@317
    45
static const char *install_root = "";
rhughes@241
    46
static const char *repo_filename = system_repo_filename;
rhughes@241
    47
static const char *yum_url;
rhughes@241
    48
krh@271
    49
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
krh@271
    50
ali@363
    51
static int
ali@403
    52
update_packages(struct razor_transaction *trans,
ali@403
    53
		struct razor_install_iterator *ii, struct razor_set *system,
ali@403
    54
		struct razor_set *next, struct razor_atomic *atomic,
ali@403
    55
		struct razor_relocations *relocations,
ali@418
    56
		enum razor_stage_type stage);
ali@418
    57
static int
ali@418
    58
update_system(const char *install_root, struct razor_relocations *relocations,
ali@418
    59
	      struct razor_transaction *trans, struct razor_set *system,
ali@418
    60
	      struct razor_set *next, const char *verb);
ali@363
    61
krh@281
    62
static struct razor_package_iterator *
krh@281
    63
create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[])
rhughes@241
    64
{
krh@281
    65
	struct razor_package_query *query;
krh@281
    66
	struct razor_package_iterator *iter;
rhughes@241
    67
	struct razor_package *package;
richard@302
    68
	const char *name, *pattern;
krh@281
    69
	int i, count;
rhughes@241
    70
krh@281
    71
	if (argc == 0)
krh@281
    72
		return razor_package_iterator_create(set);
krh@281
    73
krh@281
    74
	query = razor_package_query_create(set);
krh@281
    75
krh@281
    76
	for (i = 0; i < argc; i++) {
krh@281
    77
		iter = razor_package_iterator_create(set);
krh@281
    78
		pattern = argv[i];
krh@281
    79
		count = 0;
richard@307
    80
		while (razor_package_iterator_next(iter, &package,
richard@307
    81
						   RAZOR_DETAIL_NAME, &name,
richard@307
    82
						   RAZOR_DETAIL_LAST)) {
krh@281
    83
			if (fnmatch(pattern, name, 0) != 0)
krh@281
    84
				continue;
krh@281
    85
krh@281
    86
			razor_package_query_add_package(query, package);
krh@281
    87
			count++;
krh@281
    88
		}
krh@281
    89
		razor_package_iterator_destroy(iter);
krh@281
    90
krh@281
    91
		if (count == 0)
krh@281
    92
			fprintf(stderr,
krh@281
    93
				"no package matches \"%s\"\n", pattern);
rhughes@241
    94
	}
rhughes@241
    95
krh@281
    96
	return razor_package_query_finish(query);
krh@281
    97
}
krh@281
    98
krh@281
    99
#define LIST_PACKAGES_ONLY_NAMES 0x01
krh@281
   100
krh@281
   101
static void
krh@281
   102
list_packages(struct razor_package_iterator *iter, uint32_t flags)
krh@281
   103
{
krh@281
   104
	struct razor_package *package;
krh@281
   105
	const char *name, *version, *arch;
krh@281
   106
krh@281
   107
	while (razor_package_iterator_next(iter, &package,
richard@302
   108
					   RAZOR_DETAIL_NAME, &name,
richard@302
   109
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   110
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   111
					   RAZOR_DETAIL_LAST)) {
krh@281
   112
		if (flags & LIST_PACKAGES_ONLY_NAMES)
rhughes@241
   113
			printf("%s\n", name);
rhughes@241
   114
		else
rhughes@241
   115
			printf("%s-%s.%s\n", name, version, arch);
rhughes@241
   116
	}
krh@281
   117
}
krh@281
   118
krh@281
   119
static int
krh@281
   120
command_list(int argc, const char *argv[])
krh@281
   121
{
krh@281
   122
	struct razor_package_iterator *pi;
ali@403
   123
	struct razor_atomic *atomic;
krh@281
   124
	struct razor_set *set;
krh@281
   125
	uint32_t flags = 0;
krh@281
   126
	int i = 0;
krh@281
   127
krh@281
   128
	if (i < argc && strcmp(argv[i], "--only-names") == 0) {
krh@281
   129
		flags |= LIST_PACKAGES_ONLY_NAMES;
krh@281
   130
		i++;
krh@281
   131
	}
krh@281
   132
ali@403
   133
	atomic = razor_atomic_open("List installed packages");
ali@403
   134
	set = razor_root_open_read_only(install_root, atomic);
ali@403
   135
	if (set == NULL) {
ali@403
   136
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   137
		razor_atomic_destroy(atomic);
krh@317
   138
		return 1;
ali@403
   139
	}
krh@317
   140
krh@281
   141
	pi = create_iterator_from_argv(set, argc - i, argv + i);
krh@281
   142
	list_packages(pi, flags);
rhughes@241
   143
	razor_package_iterator_destroy(pi);
ali@403
   144
	razor_set_unref(set);
ali@403
   145
	razor_atomic_destroy(atomic);
rhughes@241
   146
rhughes@241
   147
	return 0;
rhughes@241
   148
}
rhughes@241
   149
krh@306
   150
static void
krh@306
   151
list_package_properties(struct razor_set *set,
krh@306
   152
			struct razor_package *package, uint32_t type)
rhughes@241
   153
{
krh@306
   154
	struct razor_property_iterator *pi;
rhughes@241
   155
	struct razor_property *property;
rhughes@241
   156
	const char *name, *version;
krh@247
   157
	uint32_t flags;
rhughes@241
   158
rhughes@241
   159
	pi = razor_property_iterator_create(set, package);
rhughes@241
   160
	while (razor_property_iterator_next(pi, &property,
krh@247
   161
					    &name, &flags, &version)) {
krh@247
   162
		if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
rhughes@241
   163
			continue;
krh@247
   164
		printf("%s", name);
krh@247
   165
		if (version[0] != '\0')
krh@247
   166
			printf(" %s %s",
krh@247
   167
			       razor_property_relation_to_string(property),
krh@247
   168
			       version);
krh@247
   169
krh@247
   170
		if (flags & ~(RAZOR_PROPERTY_RELATION_MASK | RAZOR_PROPERTY_TYPE_MASK)) {
krh@247
   171
			printf(" [");
krh@247
   172
			if (flags & RAZOR_PROPERTY_PRE)
krh@247
   173
				printf(" pre");
krh@247
   174
			if (flags & RAZOR_PROPERTY_POST)
krh@247
   175
				printf(" post");
krh@247
   176
			if (flags & RAZOR_PROPERTY_PREUN)
krh@247
   177
				printf(" preun");
krh@247
   178
			if (flags & RAZOR_PROPERTY_POSTUN)
krh@247
   179
				printf(" postun");
krh@247
   180
			printf(" ]");
krh@247
   181
		}
krh@247
   182
		printf("\n");
rhughes@241
   183
	}
rhughes@241
   184
	razor_property_iterator_destroy(pi);
krh@306
   185
}
rhughes@241
   186
krh@306
   187
static int
krh@306
   188
list_properties(int argc, const char *argv[], uint32_t type)
krh@306
   189
{
krh@306
   190
	struct razor_set *set;
ali@403
   191
	struct razor_atomic *atomic;
krh@306
   192
	struct razor_package *package;
krh@306
   193
	struct razor_package_iterator *pi;
krh@306
   194
	const char *name, *version, *arch;
krh@306
   195
ali@403
   196
	atomic = razor_atomic_open("List package properties");
ali@403
   197
	set = razor_root_open_read_only(install_root, atomic);
ali@403
   198
	if (set == NULL) {
ali@403
   199
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   200
		razor_atomic_destroy(atomic);
krh@317
   201
		return 1;
ali@403
   202
	}
krh@317
   203
krh@306
   204
	pi = create_iterator_from_argv(set, argc, argv);
krh@306
   205
	while (razor_package_iterator_next(pi, &package,
richard@307
   206
					   RAZOR_DETAIL_NAME, &name,
richard@307
   207
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   208
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   209
					   RAZOR_DETAIL_LAST))
krh@306
   210
		list_package_properties(set, package, type);
krh@306
   211
	razor_package_iterator_destroy(pi);
ali@403
   212
	razor_set_unref(set);
ali@403
   213
	razor_atomic_destroy(atomic);
rhughes@241
   214
rhughes@241
   215
	return 0;
rhughes@241
   216
}
rhughes@241
   217
rhughes@241
   218
static int
rhughes@241
   219
command_list_requires(int argc, const char *argv[])
rhughes@241
   220
{
krh@306
   221
	return list_properties(argc, argv, RAZOR_PROPERTY_REQUIRES);
rhughes@241
   222
}
rhughes@241
   223
rhughes@241
   224
static int
rhughes@241
   225
command_list_provides(int argc, const char *argv[])
rhughes@241
   226
{
krh@306
   227
	return list_properties(argc, argv, RAZOR_PROPERTY_PROVIDES);
rhughes@241
   228
}
rhughes@241
   229
rhughes@241
   230
static int
rhughes@241
   231
command_list_obsoletes(int argc, const char *argv[])
rhughes@241
   232
{
krh@306
   233
	return list_properties(argc, argv, RAZOR_PROPERTY_OBSOLETES);
rhughes@241
   234
}
rhughes@241
   235
rhughes@241
   236
static int
rhughes@241
   237
command_list_conflicts(int argc, const char *argv[])
rhughes@241
   238
{
krh@306
   239
	return list_properties(argc, argv, RAZOR_PROPERTY_CONFLICTS);
rhughes@241
   240
}
rhughes@241
   241
rhughes@241
   242
static int
ali@369
   243
command_list_scripts(int argc, const char *argv[])
ali@369
   244
{
ali@369
   245
	struct razor_set *set;
ali@403
   246
	struct razor_atomic *atomic;
ali@369
   247
	struct razor_package *package;
ali@369
   248
	struct razor_package_iterator *pi;
ali@369
   249
	const char *preunprog, *preun, *postunprog, *postun;
ali@369
   250
ali@403
   251
	atomic = razor_atomic_open("List package scripts");
ali@403
   252
	set = razor_root_open_read_only(install_root, atomic);
ali@403
   253
	if (set == NULL) {
ali@403
   254
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   255
		razor_atomic_destroy(atomic);
ali@369
   256
		return 1;
ali@403
   257
	}
ali@369
   258
ali@369
   259
	pi = create_iterator_from_argv(set, argc, argv);
ali@369
   260
	while (razor_package_iterator_next(pi, &package,
ali@369
   261
					   RAZOR_DETAIL_PREUNPROG, &preunprog,
ali@369
   262
					   RAZOR_DETAIL_PREUN, &preun,
ali@369
   263
					   RAZOR_DETAIL_POSTUNPROG, &postunprog,
ali@369
   264
					   RAZOR_DETAIL_POSTUN, &postun,
ali@369
   265
					   RAZOR_DETAIL_LAST)) {
ali@369
   266
		if (preun && *preun) {
ali@369
   267
			printf("preuninstall scriptlet");
ali@369
   268
			if (preunprog && *preunprog)
ali@369
   269
				printf(" (using %s)",preunprog);
ali@369
   270
			printf(":\n%s\n",preun);
ali@369
   271
		}
ali@369
   272
		if (postun && *postun) {
ali@369
   273
			printf("postuninstall scriptlet");
ali@369
   274
			if (postunprog && *postunprog)
ali@369
   275
				printf(" (using %s)",postunprog);
ali@369
   276
			printf(":\n%s\n",postun);
ali@369
   277
		}
ali@369
   278
	}
ali@369
   279
	razor_package_iterator_destroy(pi);
ali@403
   280
	razor_set_unref(set);
ali@403
   281
	razor_atomic_destroy(atomic);
ali@369
   282
ali@369
   283
	return 0;
ali@369
   284
}
ali@369
   285
ali@369
   286
static int
rhughes@241
   287
command_list_files(int argc, const char *argv[])
rhughes@241
   288
{
ali@403
   289
	struct razor_atomic *atomic;
rhughes@241
   290
	struct razor_set *set;
rhughes@241
   291
ali@403
   292
	atomic = razor_atomic_open("List package files");
ali@403
   293
	set = razor_root_open_read_only(install_root, atomic);
ali@403
   294
	if (set == NULL) {
ali@403
   295
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   296
		razor_atomic_destroy(atomic);
rhughes@241
   297
		return 1;
ali@403
   298
	}
krh@317
   299
rhughes@241
   300
	razor_set_list_files(set, argv[0]);
ali@403
   301
	razor_set_unref(set);
ali@403
   302
	razor_atomic_destroy(atomic);
rhughes@241
   303
rhughes@241
   304
	return 0;
rhughes@241
   305
}
rhughes@241
   306
rhughes@241
   307
static int
rhughes@241
   308
command_list_file_packages(int argc, const char *argv[])
rhughes@241
   309
{
ali@403
   310
	struct razor_atomic *atomic;
rhughes@241
   311
	struct razor_set *set;
rhughes@241
   312
	struct razor_package_iterator *pi;
rhughes@241
   313
ali@403
   314
	atomic = razor_atomic_open("List file packages");
ali@403
   315
	set = razor_root_open_read_only(install_root, atomic);
ali@403
   316
	if (set == NULL) {
ali@403
   317
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   318
		razor_atomic_destroy(atomic);
rhughes@241
   319
		return 1;
ali@403
   320
	}
rhughes@241
   321
rhughes@241
   322
	pi = razor_package_iterator_create_for_file(set, argv[0]);
krh@281
   323
	list_packages(pi, 0);
rhughes@241
   324
	razor_package_iterator_destroy(pi);
rhughes@241
   325
ali@403
   326
	razor_set_unref(set);
ali@403
   327
	razor_atomic_destroy(atomic);
rhughes@241
   328
rhughes@241
   329
	return 0;
rhughes@241
   330
}
rhughes@241
   331
rhughes@241
   332
static int
rhughes@241
   333
command_list_package_files(int argc, const char *argv[])
rhughes@241
   334
{
ali@403
   335
	struct razor_atomic *atomic;
rhughes@241
   336
	struct razor_set *set;
krh@306
   337
	struct razor_package_iterator *pi;
krh@306
   338
	struct razor_package *package;
krh@306
   339
	const char *name, *version, *arch;
rhughes@241
   340
ali@403
   341
	atomic = razor_atomic_open("List package files");
ali@403
   342
	set = razor_root_open_read_only(install_root, atomic);
ali@403
   343
	if (set == NULL) {
ali@403
   344
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   345
		razor_atomic_destroy(atomic);
rhughes@241
   346
		return 1;
ali@403
   347
	}
jbowes@288
   348
krh@306
   349
	pi = create_iterator_from_argv(set, argc, argv);
krh@306
   350
	while (razor_package_iterator_next(pi, &package,
richard@307
   351
					   RAZOR_DETAIL_NAME, &name,
richard@307
   352
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   353
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   354
					   RAZOR_DETAIL_LAST))
krh@306
   355
		razor_set_list_package_files(set, package);
krh@306
   356
	razor_package_iterator_destroy(pi);
krh@306
   357
ali@403
   358
	razor_set_unref(set);
ali@403
   359
	razor_atomic_destroy(atomic);
rhughes@241
   360
rhughes@241
   361
	return 0;
rhughes@241
   362
}
rhughes@241
   363
rhughes@241
   364
static int
rhughes@241
   365
list_property_packages(const char *ref_name,
rhughes@241
   366
		       const char *ref_version,
krh@247
   367
		       uint32_t type)
rhughes@241
   368
{
ali@403
   369
	struct razor_atomic *atomic;
rhughes@241
   370
	struct razor_set *set;
rhughes@241
   371
	struct razor_property *property;
krh@281
   372
	struct razor_property_iterator *prop_iter;
krh@281
   373
	struct razor_package_iterator *pkg_iter;
rhughes@241
   374
	const char *name, *version;
krh@247
   375
	uint32_t flags;
rhughes@241
   376
rhughes@241
   377
	if (ref_name == NULL)
rhughes@241
   378
		return 0;
rhughes@241
   379
ali@403
   380
	atomic = razor_atomic_open("List package properties");
ali@403
   381
	set = razor_root_open_read_only(install_root, atomic);
ali@403
   382
	if (set == NULL) {
ali@403
   383
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   384
		razor_atomic_destroy(atomic);
rhughes@241
   385
		return 1;
ali@403
   386
	}
rhughes@241
   387
krh@281
   388
	prop_iter = razor_property_iterator_create(set, NULL);
krh@281
   389
	while (razor_property_iterator_next(prop_iter, &property,
krh@247
   390
					    &name, &flags, &version)) {
rhughes@241
   391
		if (strcmp(ref_name, name) != 0)
rhughes@241
   392
			continue;
krh@247
   393
		if (ref_version &&
krh@247
   394
		    (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
rhughes@241
   395
		    strcmp(ref_version, version) != 0)
rhughes@241
   396
			continue;
krh@247
   397
		if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
rhughes@241
   398
			continue;
rhughes@241
   399
krh@281
   400
		pkg_iter =
krh@281
   401
			razor_package_iterator_create_for_property(set,
krh@281
   402
								   property);
krh@281
   403
		list_packages(pkg_iter, 0);
krh@281
   404
		razor_package_iterator_destroy(pkg_iter);
rhughes@241
   405
	}
krh@281
   406
	razor_property_iterator_destroy(prop_iter);
rhughes@241
   407
ali@403
   408
	razor_set_unref(set);
ali@403
   409
	razor_atomic_destroy(atomic);
krh@317
   410
rhughes@241
   411
	return 0;
rhughes@241
   412
}
rhughes@241
   413
rhughes@241
   414
static int
rhughes@241
   415
command_what_requires(int argc, const char *argv[])
rhughes@241
   416
{
rhughes@241
   417
	return list_property_packages(argv[0], argv[1],
rhughes@241
   418
				      RAZOR_PROPERTY_REQUIRES);
rhughes@241
   419
}
rhughes@241
   420
rhughes@241
   421
static int
rhughes@241
   422
command_what_provides(int argc, const char *argv[])
rhughes@241
   423
{
rhughes@241
   424
	return list_property_packages(argv[0], argv[1],
rhughes@241
   425
				      RAZOR_PROPERTY_PROVIDES);
rhughes@241
   426
}
rhughes@241
   427
rhughes@241
   428
static int
rhughes@241
   429
show_progress(void *clientp,
rhughes@241
   430
	      double dltotal, double dlnow, double ultotal, double ulnow)
rhughes@241
   431
{
rhughes@241
   432
	const char *file = clientp;
rhughes@241
   433
rhughes@241
   434
	if (!dlnow < dltotal)
rhughes@241
   435
		fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
rhughes@241
   436
			file, (int) dlnow / 1024, (int) dltotal / 1024);
rhughes@241
   437
rhughes@241
   438
	return 0;
rhughes@241
   439
}
rhughes@241
   440
rhughes@241
   441
static int
rhughes@241
   442
download_if_missing(const char *url, const char *file)
rhughes@241
   443
{
ali@321
   444
#ifndef HAVE_CURL
ali@321
   445
	return 1;
ali@321
   446
#else
rhughes@241
   447
	CURL *curl;
rhughes@241
   448
	struct stat buf;
rhughes@241
   449
	char error[256];
rhughes@241
   450
	FILE *fp;
rhughes@241
   451
	CURLcode res;
rhughes@241
   452
	long response;
rhughes@241
   453
rhughes@241
   454
	curl = curl_easy_init();
rhughes@241
   455
	if (curl == NULL)
rhughes@241
   456
		return 1;
rhughes@241
   457
rhughes@241
   458
	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
rhughes@241
   459
	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
rhughes@241
   460
	curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
rhughes@241
   461
	curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
rhughes@241
   462
rhughes@241
   463
	if (stat(file, &buf) < 0) {
ali@345
   464
		fp = fopen(file, "wb");
rhughes@241
   465
		if (fp == NULL) {
rhughes@241
   466
			fprintf(stderr,
rhughes@241
   467
				"failed to open %s for writing\n", file);
rhughes@241
   468
			return -1;
rhughes@241
   469
		}
rhughes@241
   470
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
rhughes@241
   471
		curl_easy_setopt(curl, CURLOPT_URL, url);
rhughes@241
   472
		res = curl_easy_perform(curl);
rhughes@241
   473
		fclose(fp);
rhughes@241
   474
		if (res != CURLE_OK) {
rhughes@241
   475
			fprintf(stderr, "curl error: %s\n", error);
rhughes@241
   476
			unlink(file);
rhughes@241
   477
			return -1;
rhughes@241
   478
		}
rhughes@241
   479
		res = curl_easy_getinfo(curl,
rhughes@241
   480
					CURLINFO_RESPONSE_CODE, &response);
rhughes@241
   481
		if (res != CURLE_OK) {
rhughes@241
   482
			fprintf(stderr, "curl error: %s\n", error);
rhughes@241
   483
                        unlink(file);
rhughes@241
   484
                        return -1;
rhughes@241
   485
		}
rhughes@241
   486
		if (response != 200) {
rhughes@241
   487
			fprintf(stderr, " - failed %ld\n", response);
rhughes@241
   488
                        unlink(file);
rhughes@241
   489
                        return -1;
rhughes@241
   490
		}
rhughes@241
   491
		fprintf(stderr, "\n");
rhughes@241
   492
	}
rhughes@241
   493
rhughes@241
   494
	curl_easy_cleanup(curl);
rhughes@241
   495
rhughes@241
   496
	return 0;
ali@321
   497
#endif	/* HAVE_CURL */
rhughes@241
   498
}
rhughes@241
   499
rhughes@241
   500
#define YUM_URL "http://download.fedora.redhat.com" \
rhughes@241
   501
	"/pub/fedora/linux/development/i386/os"
rhughes@241
   502
rhughes@241
   503
static int
rhughes@241
   504
command_import_yum(int argc, const char *argv[])
rhughes@241
   505
{
ali@403
   506
	int retval;
rhughes@241
   507
	struct razor_set *set;
ali@403
   508
	struct razor_atomic *atomic;
rhughes@241
   509
	char buffer[512];
rhughes@241
   510
rhughes@241
   511
	printf("downloading from %s.\n", yum_url);
rhughes@241
   512
	snprintf(buffer, sizeof buffer,
rhughes@241
   513
		 "%s/repodata/primary.xml.gz", yum_url);
rhughes@241
   514
	if (download_if_missing(buffer, "primary.xml.gz") < 0)
rhughes@241
   515
		return -1;
rhughes@241
   516
	snprintf(buffer, sizeof buffer,
rhughes@241
   517
		 "%s/repodata/filelists.xml.gz", yum_url);
rhughes@241
   518
	if (download_if_missing(buffer, "filelists.xml.gz") < 0)
rhughes@241
   519
		return -1;
rhughes@241
   520
rhughes@241
   521
	set = razor_set_create_from_yum();
rhughes@241
   522
	if (set == NULL)
rhughes@241
   523
		return 1;
ali@403
   524
	atomic = razor_atomic_open("Yum import repository");
ali@403
   525
	razor_set_write(set, atomic, rawhide_repo_filename, RAZOR_SECTION_ALL);
ali@403
   526
	retval = razor_atomic_commit(atomic);
ali@403
   527
	razor_set_unref(set);
ali@403
   528
	if (retval)
ali@403
   529
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   530
	else
ali@403
   531
		printf("wrote %s\n", rawhide_repo_filename);
ali@403
   532
	razor_atomic_destroy(atomic);
rhughes@241
   533
ali@403
   534
	return retval;
rhughes@241
   535
}
rhughes@241
   536
ali@320
   537
#if HAVE_RPMLIB
rhughes@241
   538
static int
rhughes@241
   539
command_import_rpmdb(int argc, const char *argv[])
rhughes@241
   540
{
rhughes@241
   541
	struct razor_set *set;
krh@317
   542
	struct razor_root *root;
ali@403
   543
	struct razor_atomic *atomic;
ali@403
   544
	int retval;
krh@317
   545
ali@403
   546
	atomic = razor_atomic_open("Import RPM database");
ali@403
   547
ali@403
   548
	root = razor_root_open(install_root, atomic);
ali@403
   549
	if (root == NULL) {
ali@403
   550
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   551
		razor_atomic_destroy(atomic);
krh@317
   552
		return 1;
ali@403
   553
	}
rhughes@241
   554
rhughes@241
   555
	set = razor_set_create_from_rpmdb();
rhughes@241
   556
	if (set == NULL)
rhughes@241
   557
		return 1;
rhughes@241
   558
krh@317
   559
	razor_root_update(root, set);
krh@317
   560
ali@403
   561
	retval = razor_root_commit(root);
ali@403
   562
	if (retval)
ali@403
   563
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   564
ali@403
   565
	razor_atomic_destroy(atomic);
ali@403
   566
ali@403
   567
	return retval;
rhughes@241
   568
}
ali@320
   569
#endif
rhughes@241
   570
rhughes@241
   571
static int
rhughes@241
   572
mark_packages_for_update(struct razor_transaction *trans,
rhughes@241
   573
			 struct razor_set *set, const char *pattern)
rhughes@241
   574
{
rhughes@241
   575
	struct razor_package_iterator *pi;
rhughes@241
   576
	struct razor_package *package;
richard@302
   577
	const char *name;
rhughes@241
   578
	int matches = 0;
rhughes@241
   579
rhughes@241
   580
	pi = razor_package_iterator_create(set);
rhughes@241
   581
	while (razor_package_iterator_next(pi, &package,
richard@307
   582
					   RAZOR_DETAIL_NAME, &name,
richard@307
   583
					   RAZOR_DETAIL_LAST)) {
rhughes@241
   584
		if (pattern && fnmatch(pattern, name, 0) == 0) {
rhughes@241
   585
			razor_transaction_update_package(trans, package);
rhughes@241
   586
			matches++;
rhughes@241
   587
		}
rhughes@241
   588
	}
rhughes@241
   589
	razor_package_iterator_destroy(pi);
rhughes@241
   590
rhughes@241
   591
	return matches;
rhughes@241
   592
}
rhughes@241
   593
rhughes@241
   594
static int
rhughes@241
   595
mark_packages_for_removal(struct razor_transaction *trans,
rhughes@241
   596
			  struct razor_set *set, const char *pattern)
rhughes@241
   597
{
rhughes@241
   598
	struct razor_package_iterator *pi;
rhughes@241
   599
	struct razor_package *package;
richard@302
   600
	const char *name;
rhughes@241
   601
	int matches = 0;
rhughes@241
   602
rhughes@241
   603
	pi = razor_package_iterator_create(set);
richard@307
   604
	while (razor_package_iterator_next(pi, &package,
richard@307
   605
					   RAZOR_DETAIL_NAME, &name,
richard@307
   606
					   RAZOR_DETAIL_LAST)) {
rhughes@241
   607
		if (pattern && fnmatch(pattern, name, 0) == 0) {
rhughes@241
   608
			razor_transaction_remove_package(trans, package);
rhughes@241
   609
			matches++;
rhughes@241
   610
		}
rhughes@241
   611
	}
rhughes@241
   612
	razor_package_iterator_destroy(pi);
rhughes@241
   613
rhughes@241
   614
	return matches;
rhughes@241
   615
}
rhughes@241
   616
rhughes@241
   617
static int
rhughes@241
   618
command_remove(int argc, const char *argv[])
rhughes@241
   619
{
ali@363
   620
	struct razor_set *system, *upstream, *next;
rhughes@241
   621
	struct razor_transaction *trans;
ali@403
   622
	struct razor_atomic *atomic;
ali@403
   623
	int i, retval;
rhughes@241
   624
ali@403
   625
	atomic = razor_atomic_open("Remove packages");
ali@403
   626
ali@418
   627
	system = razor_root_open_read_only(install_root, atomic);
ali@363
   628
	if (system == NULL) {
ali@403
   629
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   630
		razor_atomic_destroy(atomic);
rhughes@241
   631
		return 1;
ali@363
   632
	}
rhughes@241
   633
ali@418
   634
	razor_atomic_destroy(atomic);
ali@418
   635
ali@363
   636
	upstream = razor_set_create_without_root();
ali@363
   637
	trans = razor_transaction_create(system, upstream);
ali@403
   638
	razor_set_unref(upstream);
rhughes@241
   639
	for (i = 0; i < argc; i++) {
ali@363
   640
		if (mark_packages_for_removal(trans, system, argv[i]) == 0) {
rhughes@241
   641
			fprintf(stderr, "no match for %s\n", argv[i]);
ali@363
   642
			razor_transaction_destroy(trans);
ali@403
   643
			razor_set_unref(system);
rhughes@241
   644
			return 1;
rhughes@241
   645
		}
rhughes@241
   646
	}
rhughes@241
   647
ali@350
   648
	razor_transaction_resolve(trans);
ali@403
   649
	retval = razor_transaction_describe(trans);
ali@403
   650
	if (retval) {
ali@363
   651
		razor_transaction_destroy(trans);
ali@403
   652
		razor_set_unref(system);
rhughes@241
   653
		return 1;
ali@363
   654
	}
rhughes@241
   655
ali@369
   656
	next = razor_transaction_commit(trans);
ali@403
   657
ali@418
   658
	retval = update_system(install_root, NULL, trans, system, next,
ali@418
   659
			       "Remove");
ali@363
   660
ali@369
   661
	razor_transaction_destroy(trans);
ali@403
   662
	razor_set_unref(system);
ali@403
   663
	razor_set_unref(next);
rhughes@241
   664
ali@403
   665
	return retval;
rhughes@241
   666
}
rhughes@241
   667
rhughes@241
   668
static void
krh@253
   669
print_diff(enum razor_diff_action action,
krh@253
   670
	   struct razor_package *package,
krh@253
   671
	   const char *name,
krh@253
   672
	   const char *version,
krh@253
   673
	   const char *arch,
rhughes@241
   674
	   void *data)
rhughes@241
   675
{
krh@253
   676
	if (action == RAZOR_DIFF_ACTION_ADD)
krh@253
   677
		printf("install %s-%s.%s\n", name, version, arch);
krh@253
   678
	if (action == RAZOR_DIFF_ACTION_REMOVE)
krh@253
   679
		printf("remove %s-%s.%s\n", name, version, arch);
rhughes@241
   680
}
rhughes@241
   681
rhughes@241
   682
static int
rhughes@241
   683
command_diff(int argc, const char *argv[])
rhughes@241
   684
{
ali@403
   685
	struct razor_atomic *atomic;
rhughes@241
   686
	struct razor_set *set, *updated;
rhughes@241
   687
ali@403
   688
	atomic = razor_atomic_open("Show package differences");
ali@403
   689
	set = razor_root_open_read_only(install_root, atomic);
ali@403
   690
	updated = razor_set_open(rawhide_repo_filename, atomic);
ali@403
   691
	if (set == NULL || updated == NULL) {
ali@403
   692
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   693
		razor_atomic_destroy(atomic);
rhughes@241
   694
		return 1;
ali@403
   695
	}
rhughes@241
   696
rhughes@241
   697
	razor_set_diff(set, updated, print_diff, NULL);
rhughes@241
   698
ali@403
   699
	razor_set_unref(set);
ali@403
   700
	razor_set_unref(updated);
ali@403
   701
	razor_atomic_destroy(atomic);
rhughes@241
   702
rhughes@241
   703
	return 0;
rhughes@241
   704
}
rhughes@241
   705
rhughes@241
   706
static int
rhughes@241
   707
command_import_rpms(int argc, const char *argv[])
rhughes@241
   708
{
rhughes@241
   709
	DIR *dir;
rhughes@241
   710
	struct dirent *de;
rhughes@241
   711
	struct razor_importer *importer;
rhughes@241
   712
	struct razor_set *set;
rhughes@241
   713
	struct razor_rpm *rpm;
ali@403
   714
	struct razor_atomic *atomic;
jbowes@263
   715
	int len, imported_count = 0;
rhughes@241
   716
	char filename[256];
rhughes@241
   717
	const char *dirname = argv[0];
ali@403
   718
	int retval;
rhughes@241
   719
rhughes@241
   720
	if (dirname == NULL) {
rhughes@241
   721
		fprintf(stderr, "usage: razor import-rpms DIR\n");
rhughes@241
   722
		return -1;
rhughes@241
   723
	}
rhughes@241
   724
rhughes@241
   725
	dir = opendir(dirname);
rhughes@241
   726
	if (dir == NULL) {
rhughes@241
   727
		fprintf(stderr, "couldn't read dir %s\n", dirname);
rhughes@241
   728
		return -1;
rhughes@241
   729
	}
rhughes@241
   730
krh@249
   731
	importer = razor_importer_create();
rhughes@241
   732
rhughes@241
   733
	while (de = readdir(dir), de != NULL) {
rhughes@241
   734
		len = strlen(de->d_name);
rhughes@241
   735
		if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
ali@403
   736
			continue;
rhughes@241
   737
		snprintf(filename, sizeof filename,
rhughes@241
   738
			 "%s/%s", dirname, de->d_name);
ali@403
   739
		atomic = razor_atomic_open("Read RPM");
ali@403
   740
		rpm = razor_rpm_open(filename, atomic);
ali@403
   741
		if (rpm == NULL)
ali@403
   742
			fprintf(stderr, "%s\n",
ali@403
   743
				razor_atomic_get_error_msg(atomic));
ali@403
   744
		razor_atomic_destroy(atomic);
ali@403
   745
		if (rpm == NULL)
rhughes@241
   746
			continue;
rhughes@241
   747
		if (razor_importer_add_rpm(importer, rpm)) {
rhughes@241
   748
			fprintf(stderr, "couldn't import %s\n", filename);
rhughes@241
   749
			break;
rhughes@241
   750
		}
rhughes@241
   751
		razor_rpm_close(rpm);
jbowes@263
   752
jbowes@263
   753
		printf("\rimporting %d", ++imported_count);
jbowes@263
   754
		fflush(stdout);
rhughes@241
   755
	}
rhughes@241
   756
rhughes@241
   757
	if (de != NULL) {
rhughes@241
   758
		razor_importer_destroy(importer);
rhughes@241
   759
		return -1;
rhughes@241
   760
	}
rhughes@241
   761
jbowes@263
   762
	printf("\nsaving\n");
rhughes@241
   763
	set = razor_importer_finish(importer);
rhughes@241
   764
ali@403
   765
	atomic = razor_atomic_open("Update system database");
ali@403
   766
	razor_set_write(set, atomic, repo_filename, RAZOR_SECTION_ALL);
ali@403
   767
	razor_set_unref(set);
ali@403
   768
	retval = razor_atomic_commit(atomic);
ali@403
   769
	if (retval)
ali@403
   770
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   771
	else
ali@403
   772
		printf("wrote %s\n", repo_filename);
ali@403
   773
	razor_atomic_destroy(atomic);
rhughes@241
   774
ali@403
   775
	return retval;
rhughes@241
   776
}
rhughes@241
   777
ali@403
   778
static char *
krh@254
   779
rpm_filename(const char *name, const char *version, const char *arch)
rhughes@241
   780
{
krh@254
   781
 	const char *v;
krh@254
   782
 
krh@254
   783
 	/* Skip epoch */
krh@253
   784
	v = strchr(version, ':');
krh@254
   785
 	if (v != NULL)
krh@254
   786
 		v = v + 1;
krh@254
   787
 	else
krh@253
   788
		v = version;
rhughes@241
   789
ali@403
   790
	return razor_concat(name, "-", v, ".", arch, ".rpm", NULL);
rhughes@241
   791
}
rhughes@241
   792
krh@254
   793
static int
krh@254
   794
download_packages(struct razor_set *system, struct razor_set *next)
rhughes@241
   795
{
krh@316
   796
	struct razor_install_iterator *ii;
krh@254
   797
	struct razor_package *package;
krh@316
   798
	enum razor_install_action action;
krh@254
   799
	const char *name, *version, *arch;
ali@403
   800
	char *file, *url, *s;
krh@316
   801
	int errors = 0, count;
krh@316
   802
krh@316
   803
	ii = razor_set_create_install_iterator(system, next);
ali@382
   804
	while (razor_install_iterator_next(ii, &package, &action, &count)) {
ali@418
   805
		if (action != RAZOR_INSTALL_ACTION_ADD)
krh@316
   806
			continue;
krh@316
   807
ali@382
   808
		razor_package_get_details(next, package,
krh@316
   809
					  RAZOR_DETAIL_NAME, &name,
krh@316
   810
					  RAZOR_DETAIL_VERSION, &version,
krh@316
   811
					  RAZOR_DETAIL_ARCH, &arch,
krh@316
   812
					  RAZOR_DETAIL_LAST);
krh@316
   813
		
ali@403
   814
		s = rpm_filename(name, version, arch);
ali@403
   815
		url = razor_concat(yum_url, "/Packages/", s, NULL);
ali@403
   816
		file = razor_concat("rpms/", s, NULL);
ali@403
   817
		free(s);
krh@254
   818
		if (download_if_missing(url, file) < 0)
krh@254
   819
			errors++;
ali@403
   820
		free(file);
ali@403
   821
		free(url);
krh@254
   822
	}
krh@316
   823
	razor_install_iterator_destroy(ii);
krh@254
   824
krh@254
   825
	if (errors > 0) {
krh@254
   826
		fprintf(stderr, "failed to download %d packages\n", errors);
krh@254
   827
                return -1;
krh@254
   828
        }
krh@254
   829
krh@254
   830
	return 0;
krh@254
   831
}
krh@254
   832
ali@351
   833
static struct razor_set *
ali@403
   834
relocate_packages(struct razor_set *set, struct razor_atomic *atomic,
ali@403
   835
		  struct razor_relocations *relocations)
ali@351
   836
{
ali@372
   837
	int i;
ali@351
   838
	struct razor_importer *importer;
ali@351
   839
	struct razor_property_iterator *prop_iter;
ali@351
   840
	struct razor_package_iterator *pkg_iter;
ali@351
   841
 	struct razor_file_iterator *file_iter;
ali@351
   842
 	struct razor_package *package;
ali@351
   843
	struct razor_property *property;
ali@351
   844
	struct razor_rpm *rpm;
ali@351
   845
	const char *name, *version, *arch, *summary, *desc, *url, *license;
ali@369
   846
	const char *preunprog, *preun, *postunprog, *postun;
ali@372
   847
	const char *install_prefix;
ali@372
   848
	const char *const *prefixes;
ali@403
   849
	char *file, *s;
ali@351
   850
	uint32_t flags;
ali@351
   851
ali@351
   852
	importer = razor_importer_create();
ali@351
   853
	pkg_iter = razor_package_iterator_create(set);
ali@351
   854
ali@351
   855
	while (razor_package_iterator_next(pkg_iter, &package,
ali@351
   856
					   RAZOR_DETAIL_NAME, &name,
ali@351
   857
					   RAZOR_DETAIL_VERSION, &version,
ali@351
   858
					   RAZOR_DETAIL_ARCH, &arch,
ali@351
   859
					   RAZOR_DETAIL_SUMMARY, &summary,
ali@351
   860
					   RAZOR_DETAIL_DESCRIPTION, &desc,
ali@351
   861
					   RAZOR_DETAIL_URL, &url,
ali@351
   862
					   RAZOR_DETAIL_LICENSE, &license,
ali@369
   863
					   RAZOR_DETAIL_PREUNPROG, &preunprog,
ali@369
   864
					   RAZOR_DETAIL_PREUN, &preun,
ali@369
   865
					   RAZOR_DETAIL_POSTUNPROG, &postunprog,
ali@369
   866
					   RAZOR_DETAIL_POSTUN, &postun,
ali@351
   867
					   RAZOR_DETAIL_LAST)) {
ali@403
   868
		s = rpm_filename(name, version, arch);
ali@403
   869
		file = razor_concat("rpms/", s, NULL);
ali@403
   870
		free(s);
ali@403
   871
		rpm = razor_rpm_open(file, atomic);
ali@403
   872
		free(file);
ali@351
   873
		if (rpm == NULL) {
ali@351
   874
			razor_package_iterator_destroy(pkg_iter);
ali@351
   875
			razor_importer_destroy(importer);
ali@351
   876
			return NULL;
ali@351
   877
		}
ali@351
   878
ali@351
   879
		razor_relocations_set_rpm(relocations, rpm);
ali@351
   880
ali@351
   881
		razor_importer_begin_package(importer, name, version, arch);
ali@351
   882
		razor_importer_add_details(importer,
ali@351
   883
					   summary, desc, url, license);
ali@351
   884
ali@372
   885
		razor_rpm_get_details(rpm, RAZOR_DETAIL_PREFIXES, &prefixes,
ali@372
   886
				      RAZOR_DETAIL_LAST);
ali@372
   887
		for (i = 0; prefixes && prefixes[i]; i++) {
ali@372
   888
			install_prefix = razor_relocations_apply(relocations,
ali@372
   889
								 prefixes[i]);
ali@372
   890
			razor_importer_add_install_prefix(importer,
ali@372
   891
							  install_prefix);
ali@372
   892
		}
ali@372
   893
ali@372
   894
		razor_rpm_close(rpm);
ali@372
   895
ali@351
   896
		prop_iter = razor_property_iterator_create(set, package);
ali@351
   897
		while (razor_property_iterator_next(prop_iter, &property,
ali@351
   898
						    &name, &flags, &version))
ali@351
   899
			razor_importer_add_property(importer,
ali@351
   900
						    name, flags, version);
ali@351
   901
		razor_property_iterator_destroy(prop_iter);
ali@351
   902
ali@377
   903
		file_iter = razor_file_iterator_create(set, package, 0);
ali@351
   904
		while (razor_file_iterator_next(file_iter, &name)) {
ali@351
   905
			name = razor_relocations_apply(relocations, name);
ali@351
   906
			razor_importer_add_file(importer, name);
ali@351
   907
		}
ali@351
   908
		razor_file_iterator_destroy(file_iter);
ali@351
   909
ali@369
   910
		razor_importer_add_script(importer, RAZOR_PROPERTY_PREUN,
ali@369
   911
					  preunprog, preun);
ali@369
   912
		razor_importer_add_script(importer, RAZOR_PROPERTY_POSTUN,
ali@369
   913
					  postunprog, postun);
ali@369
   914
ali@351
   915
		razor_importer_finish_package(importer);
ali@351
   916
	}
ali@351
   917
ali@351
   918
	razor_package_iterator_destroy(pkg_iter);
ali@351
   919
	return razor_importer_finish(importer);
ali@351
   920
}
ali@351
   921
krh@254
   922
static int
ali@369
   923
install_package(struct razor_transaction *trans, struct razor_set *set,
ali@403
   924
		struct razor_atomic *atomic, struct razor_package *package,
ali@403
   925
		struct razor_relocations *relocations, int install_count,
ali@403
   926
		enum razor_stage_type stage)
ali@363
   927
{
ali@363
   928
	int retval;
ali@363
   929
	const char *name, *version, *arch;
ali@403
   930
	char *file, *s;
ali@363
   931
	struct razor_rpm *rpm;
ali@363
   932
ali@363
   933
	razor_package_get_details(set, package,
ali@363
   934
				  RAZOR_DETAIL_NAME, &name,
ali@363
   935
				  RAZOR_DETAIL_VERSION, &version,
ali@363
   936
				  RAZOR_DETAIL_ARCH, &arch,
ali@363
   937
				  RAZOR_DETAIL_LAST);
ali@363
   938
ali@403
   939
	if (stage & RAZOR_STAGE_SCRIPTS_PRE)
ali@403
   940
		printf("install %s-%s\n", name, version);
ali@363
   941
ali@403
   942
	s = rpm_filename(name, version, arch);
ali@403
   943
	file = razor_concat("rpms/", s, NULL);
ali@403
   944
	free(s);
ali@403
   945
	rpm = razor_rpm_open(file, atomic);
ali@403
   946
	free(file);
ali@363
   947
	if (rpm == NULL) {
ali@403
   948
		fprintf(stderr, "%s\n",
ali@403
   949
			razor_atomic_get_error_msg(atomic));
ali@363
   950
		return -1;
ali@363
   951
	}
ali@363
   952
	if (relocations)
ali@363
   953
		razor_rpm_set_relocations(rpm, relocations);
ali@369
   954
	razor_transaction_fixup_package(trans, package, rpm);
ali@403
   955
	retval = razor_rpm_install(rpm, atomic, install_root, install_count,
ali@403
   956
				   stage);
ali@403
   957
	if (retval < 0) {
ali@403
   958
		s = rpm_filename(name, version, arch);
ali@403
   959
		fprintf(stderr, "%s: %s\n", s,
ali@403
   960
			razor_atomic_get_error_msg(atomic));
ali@403
   961
		free(s);
ali@403
   962
	}
ali@363
   963
	razor_rpm_close(rpm);
ali@363
   964
	return retval;
ali@363
   965
}
ali@363
   966
ali@412
   967
/*
ali@418
   968
 * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT
ali@418
   969
 * is met (in which case the action is consumed).
ali@412
   970
 */
ali@363
   971
static int
ali@403
   972
update_packages(struct razor_transaction *trans,
ali@403
   973
		struct razor_install_iterator *ii, struct razor_set *system,
ali@403
   974
		struct razor_set *next, struct razor_atomic *atomic,
ali@403
   975
		struct razor_relocations *relocations,
ali@418
   976
		enum razor_stage_type stage)
krh@254
   977
{
krh@254
   978
	struct razor_package *package;
krh@316
   979
	enum razor_install_action action;
ali@363
   980
	int retval = 0, count;
ali@403
   981
ali@412
   982
	while (!retval && razor_install_iterator_next(ii, &package, &action,
ali@412
   983
						      &count)) {
ali@418
   984
		if (action == RAZOR_INSTALL_ACTION_ADD) {
ali@418
   985
			if (install_package(trans, next, atomic, package,
ali@418
   986
					    relocations, count, stage))
ali@418
   987
				retval = -1;
ali@418
   988
		} else if (action == RAZOR_INSTALL_ACTION_REMOVE) {
ali@418
   989
			if (razor_package_remove(system, next, atomic, package,
ali@418
   990
						 install_root, count, stage))
ali@418
   991
				retval = -1;
ali@418
   992
		} else if (action == RAZOR_INSTALL_ACTION_COMMIT)
ali@418
   993
				retval = 1;
rhughes@241
   994
	}
rhughes@241
   995
ali@363
   996
	return retval;
rhughes@241
   997
}
rhughes@241
   998
rhughes@241
   999
static int
ali@418
  1000
update_system(const char *install_root, struct razor_relocations *relocations,
ali@418
  1001
	      struct razor_transaction *trans, struct razor_set *system,
ali@418
  1002
	      struct razor_set *next, const char *verb)
ali@418
  1003
{
ali@418
  1004
	struct razor_root *root;
ali@418
  1005
	struct razor_set *set;
ali@418
  1006
	struct razor_atomic *atomic;
ali@418
  1007
	struct razor_install_iterator *ii;
ali@418
  1008
	int r, retval = 0;
ali@418
  1009
	char *description;
ali@418
  1010
	size_t pos;
ali@418
  1011
ali@418
  1012
	description = razor_concat(verb, " packages", NULL);
ali@418
  1013
ali@418
  1014
	ii = razor_set_create_install_iterator(system, next);
ali@418
  1015
ali@418
  1016
	do {
ali@418
  1017
		pos = razor_install_iterator_tell(ii);
ali@418
  1018
ali@418
  1019
		atomic = razor_atomic_open(description);
ali@418
  1020
ali@418
  1021
		root = razor_root_open(install_root, atomic);
ali@418
  1022
		if (root == NULL) {
ali@418
  1023
			fprintf(stderr, "%s\n",
ali@418
  1024
				razor_atomic_get_error_msg(atomic));
ali@418
  1025
			razor_atomic_destroy(atomic);
ali@418
  1026
			retval = 1;
ali@418
  1027
			break;
ali@418
  1028
		}
ali@418
  1029
ali@418
  1030
		r = update_packages(trans, ii, system, next, atomic,
ali@418
  1031
				    relocations, RAZOR_STAGE_SCRIPTS_PRE);
ali@418
  1032
		if (r < 0) {
ali@418
  1033
			fprintf(stderr, "%s aborted\n", verb);
ali@418
  1034
			razor_atomic_destroy(atomic);
ali@418
  1035
			retval = r;
ali@418
  1036
		} else {
ali@418
  1037
			razor_install_iterator_seek(ii, pos);
ali@418
  1038
			r = update_packages(trans, ii, system, next, atomic,
ali@418
  1039
					    relocations, RAZOR_STAGE_FILES);
ali@418
  1040
ali@418
  1041
			if (r == 1) {
ali@418
  1042
				set = razor_install_iterator_commit_set(ii);
ali@418
  1043
				razor_root_update(root, set);
ali@418
  1044
				razor_set_unref(set);
ali@418
  1045
			} else if (r == 0)
ali@418
  1046
				razor_root_update(root, next);
ali@418
  1047
ali@418
  1048
			(void)razor_root_commit(root);
ali@418
  1049
			retval = razor_atomic_commit(atomic);
ali@418
  1050
			if (retval) {
ali@418
  1051
				fprintf(stderr, "%s\n",
ali@418
  1052
					razor_atomic_get_error_msg(atomic));
ali@418
  1053
				razor_atomic_destroy(atomic);
ali@418
  1054
			} else {
ali@418
  1055
				razor_install_iterator_seek(ii, pos);
ali@418
  1056
				update_packages(trans, ii, system, next,
ali@418
  1057
						atomic, relocations,
ali@418
  1058
						RAZOR_STAGE_SCRIPTS_POST);
ali@418
  1059
			}
ali@418
  1060
		}
ali@418
  1061
ali@418
  1062
		razor_atomic_destroy(atomic);
ali@418
  1063
	} while(!retval && r == 1);
ali@418
  1064
ali@418
  1065
	free(description);
ali@418
  1066
ali@418
  1067
	return retval;
ali@418
  1068
}
ali@418
  1069
ali@418
  1070
static int
ali@382
  1071
command_install_or_update(int argc, const char *argv[], int do_update)
rhughes@241
  1072
{
ali@351
  1073
	struct razor_relocations *relocations=NULL;
ali@351
  1074
	struct razor_set *system, *upstream, *next, *set;
rhughes@241
  1075
	struct razor_transaction *trans;
ali@403
  1076
	struct razor_atomic *atomic;
ali@403
  1077
	int i, retval, len, dependencies = 1;
ali@351
  1078
	char *oldpath;
rhughes@241
  1079
ali@351
  1080
	for (i = 0; i < argc; i++) {
ali@351
  1081
		if (strcmp(argv[i], "--no-dependencies") == 0)
ali@351
  1082
			dependencies = 0;
ali@351
  1083
		else if (strcmp(argv[i], "--relocate") == 0) {
ali@351
  1084
			i++;
ali@351
  1085
			if (i >= argc || strchr(argv[i], '=') == NULL) {
ali@351
  1086
				fprintf(stderr,
ali@382
  1087
				    "Usage: razor %s [OPTION...] RPM\n",
ali@382
  1088
				    do_update ? "update" : "install");
ali@351
  1089
				fprintf(stderr, "Options:\n");
ali@351
  1090
				fprintf(stderr, "    [--no-dependencies]\n");
ali@351
  1091
				fprintf(stderr,
ali@351
  1092
				    "    [--relocate OLDPATH=NEWPATH] RPM\n");
ali@351
  1093
				return -1;
ali@351
  1094
			}
ali@351
  1095
			len = strchr(argv[i], '=') - argv[i];
ali@351
  1096
			oldpath = malloc(len + 1);
ali@351
  1097
			strncpy(oldpath, argv[i], len);
ali@351
  1098
			oldpath[len] = '\0';
ali@351
  1099
			if (!relocations)
ali@351
  1100
			       relocations = razor_relocations_create();
ali@351
  1101
			razor_relocations_add(relocations, oldpath,
ali@351
  1102
					      argv[i] + len + 1);
ali@351
  1103
			free(oldpath);
ali@351
  1104
		} else
ali@351
  1105
			break;
ali@351
  1106
	}
ali@351
  1107
ali@418
  1108
	if (do_update)
ali@418
  1109
		atomic = razor_atomic_open("Update packages");
ali@418
  1110
	else
ali@418
  1111
		atomic = razor_atomic_open("Install packages");
ali@418
  1112
ali@403
  1113
	upstream = razor_set_open(rawhide_repo_filename, atomic);
krh@373
  1114
	if (upstream == NULL) {
ali@403
  1115
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
  1116
		razor_atomic_destroy(atomic);
krh@373
  1117
		return 1;
ali@382
  1118
	}
krh@315
  1119
ali@351
  1120
	if (relocations) {
ali@403
  1121
		set = relocate_packages(upstream, atomic, relocations);
ali@403
  1122
		if (set == NULL) {
ali@403
  1123
			fprintf(stderr, "%s\n",
ali@403
  1124
				razor_atomic_get_error_msg(atomic));
ali@403
  1125
			razor_atomic_destroy(atomic);
ali@403
  1126
			razor_set_unref(upstream);
ali@403
  1127
			return 1;
ali@403
  1128
		}
ali@403
  1129
		razor_set_unref(upstream);
ali@351
  1130
		upstream = set;
ali@351
  1131
	}
ali@351
  1132
ali@418
  1133
	system = razor_root_open_read_only(install_root, atomic);
ali@403
  1134
krh@250
  1135
	trans = razor_transaction_create(system, upstream);
rhughes@241
  1136
ali@382
  1137
	if (i == argc && do_update)
ali@382
  1138
		razor_transaction_update_all(trans);
rhughes@241
  1139
	for (; i < argc; i++) {
ali@389
  1140
		if (do_update &&
ali@389
  1141
		    mark_packages_for_update(trans, system, argv[i]))
ali@389
  1142
			continue;
rhughes@241
  1143
		if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
rhughes@241
  1144
			fprintf(stderr, "no package matched %s\n", argv[i]);
ali@369
  1145
			razor_transaction_destroy(trans);
ali@403
  1146
			razor_set_unref(upstream);
ali@403
  1147
			razor_set_unref(system);
ali@403
  1148
			razor_atomic_destroy(atomic);
rhughes@241
  1149
			return 1;
rhughes@241
  1150
		}
rhughes@241
  1151
	}
rhughes@241
  1152
rhughes@241
  1153
	if (dependencies) {
krh@245
  1154
		razor_transaction_resolve(trans);
krh@245
  1155
		if (razor_transaction_describe(trans) > 0) {
ali@369
  1156
			razor_transaction_destroy(trans);
ali@403
  1157
			razor_set_unref(upstream);
ali@403
  1158
			razor_set_unref(system);
ali@403
  1159
			razor_atomic_destroy(atomic);
rhughes@241
  1160
			return 1;
rhughes@241
  1161
		}
rhughes@241
  1162
	}
rhughes@241
  1163
ali@403
  1164
	if (razor_atomic_create_dir(atomic, "rpms",
ali@418
  1165
				    S_IRWXU | S_IRWXG | S_IRWXO) ||
ali@418
  1166
	    razor_atomic_commit(atomic)) {
ali@403
  1167
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@369
  1168
		razor_transaction_destroy(trans);
ali@403
  1169
		razor_set_unref(upstream);
ali@403
  1170
		razor_set_unref(system);
ali@403
  1171
		razor_atomic_destroy(atomic);
rhughes@241
  1172
		return 1;
rhughes@241
  1173
	}
rhughes@241
  1174
ali@418
  1175
	razor_atomic_destroy(atomic);
ali@418
  1176
ali@382
  1177
	next = razor_transaction_commit(trans);
ali@382
  1178
krh@254
  1179
	if (download_packages(system, next) < 0) {
ali@403
  1180
		razor_set_unref(next);
ali@369
  1181
		razor_transaction_destroy(trans);
ali@403
  1182
		razor_set_unref(upstream);
ali@403
  1183
		razor_set_unref(system);
ali@403
  1184
		razor_atomic_destroy(atomic);
rhughes@241
  1185
                return 1;
rhughes@241
  1186
        }
rhughes@241
  1187
ali@418
  1188
	retval = update_system(install_root, relocations, trans, system, next,
ali@418
  1189
			       do_update ? "Update" : "Install");
ali@403
  1190
ali@418
  1191
	razor_set_unref(upstream);
ali@403
  1192
ali@369
  1193
	razor_transaction_destroy(trans);
ali@351
  1194
	if (relocations)
ali@351
  1195
		razor_relocations_destroy(relocations);
ali@403
  1196
ali@403
  1197
	razor_set_unref(next);
ali@403
  1198
	razor_set_unref(system);
ali@403
  1199
ali@403
  1200
	return retval;
rhughes@241
  1201
}
rhughes@241
  1202
rhughes@241
  1203
static int
ali@382
  1204
command_update(int argc, const char *argv[])
ali@382
  1205
{
ali@382
  1206
	return command_install_or_update(argc, argv, 1);
ali@382
  1207
}
ali@382
  1208
ali@382
  1209
static int
ali@382
  1210
command_install(int argc, const char *argv[])
ali@382
  1211
{
ali@382
  1212
	return command_install_or_update(argc, argv, 0);
ali@382
  1213
}
ali@382
  1214
ali@382
  1215
static int
rhughes@241
  1216
command_init(int argc, const char *argv[])
rhughes@241
  1217
{
rhughes@241
  1218
	return razor_root_create(install_root);
rhughes@241
  1219
}
rhughes@241
  1220
rhughes@241
  1221
static int
rhughes@241
  1222
command_download(int argc, const char *argv[])
rhughes@241
  1223
{
ali@403
  1224
	struct razor_atomic *atomic;
rhughes@241
  1225
	struct razor_set *set;
rhughes@241
  1226
	struct razor_package_iterator *pi;
rhughes@241
  1227
	struct razor_package *package;
rhughes@241
  1228
	const char *pattern = argv[0], *name, *version, *arch;
rhughes@241
  1229
	char url[256], file[256];
rhughes@241
  1230
	int matches = 0;
rhughes@241
  1231
ali@403
  1232
	atomic = razor_atomic_open("Download packages");
ali@403
  1233
ali@403
  1234
	if (razor_atomic_create_dir(atomic, "rpms", 
ali@403
  1235
				    S_IRWXU | S_IRWXG | S_IRWXO)) {
ali@403
  1236
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
  1237
		razor_atomic_destroy(atomic);
rhughes@241
  1238
		return 1;
rhughes@241
  1239
	}
rhughes@241
  1240
ali@403
  1241
	set = razor_set_open(rawhide_repo_filename, atomic);
ali@403
  1242
ali@403
  1243
	if (razor_atomic_commit(atomic)) {
ali@403
  1244
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
  1245
		razor_atomic_destroy(atomic);
ali@403
  1246
		return 1;
ali@403
  1247
	}
ali@403
  1248
	razor_atomic_destroy(atomic);
ali@403
  1249
rhughes@241
  1250
	pi = razor_package_iterator_create(set);
rhughes@241
  1251
	while (razor_package_iterator_next(pi, &package,
richard@302
  1252
					   RAZOR_DETAIL_NAME, &name,
richard@302
  1253
					   RAZOR_DETAIL_VERSION, &version,
richard@307
  1254
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
  1255
					   RAZOR_DETAIL_LAST)) {
rhughes@241
  1256
		if (pattern && fnmatch(pattern, name, 0) != 0)
rhughes@241
  1257
			continue;
rhughes@241
  1258
rhughes@241
  1259
		matches++;
rhughes@241
  1260
		snprintf(url, sizeof url,
rhughes@241
  1261
			 "%s/Packages/%s-%s.%s.rpm",
rhughes@241
  1262
			 yum_url, name, version, arch);
rhughes@241
  1263
		snprintf(file, sizeof file,
rhughes@241
  1264
			 "rpms/%s-%s.%s.rpm", name, version, arch);
rhughes@241
  1265
		download_if_missing(url, file);
rhughes@241
  1266
	}
rhughes@241
  1267
	razor_package_iterator_destroy(pi);
ali@403
  1268
	razor_set_unref(set);
rhughes@241
  1269
rhughes@241
  1270
	if (matches == 0)
rhughes@241
  1271
		fprintf(stderr, "no packages matched \"%s\"\n", pattern);
rhughes@241
  1272
	else if (matches == 1)
rhughes@241
  1273
		fprintf(stderr, "downloaded 1 package\n");
rhughes@241
  1274
	else
rhughes@241
  1275
		fprintf(stderr, "downloaded %d packages\n", matches);
rhughes@241
  1276
rhughes@241
  1277
	return 0;
rhughes@241
  1278
}
rhughes@241
  1279
jbowes@258
  1280
static int
jbowes@258
  1281
command_info(int argc, const char *argv[])
jbowes@258
  1282
{
ali@403
  1283
	struct razor_atomic *atomic;
jbowes@258
  1284
	struct razor_set *set;
jbowes@258
  1285
	struct razor_package_iterator *pi;
jbowes@258
  1286
	struct razor_package *package;
jbowes@258
  1287
	const char *pattern = argv[0], *name, *version, *arch;
jbowes@258
  1288
	const char *summary, *description, *url, *license;
jbowes@258
  1289
ali@403
  1290
	atomic = razor_atomic_open("Package info");
ali@403
  1291
	set = razor_root_open_read_only(install_root, atomic);
ali@403
  1292
	if (set == NULL) {
ali@403
  1293
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
  1294
		razor_atomic_destroy(atomic);
jbowes@288
  1295
		return 1;
ali@403
  1296
	}
krh@317
  1297
jbowes@258
  1298
	pi = razor_package_iterator_create(set);
jbowes@258
  1299
	while (razor_package_iterator_next(pi, &package,
richard@302
  1300
					   RAZOR_DETAIL_NAME, &name,
richard@302
  1301
					   RAZOR_DETAIL_VERSION, &version,
richard@307
  1302
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
  1303
					   RAZOR_DETAIL_LAST)) {
jbowes@258
  1304
		if (pattern && fnmatch(pattern, name, 0) != 0)
jbowes@258
  1305
			continue;
jbowes@258
  1306
richard@302
  1307
		razor_package_get_details (set, package,
richard@302
  1308
					   RAZOR_DETAIL_SUMMARY, &summary,
richard@302
  1309
					   RAZOR_DETAIL_DESCRIPTION, &description,
richard@302
  1310
					   RAZOR_DETAIL_URL, &url,
richard@302
  1311
					   RAZOR_DETAIL_LICENSE, &license,
richard@307
  1312
					   RAZOR_DETAIL_LAST);
jbowes@258
  1313
jbowes@258
  1314
		printf ("Name:        %s\n", name);
jbowes@258
  1315
		printf ("Arch:        %s\n", arch);
jbowes@258
  1316
		printf ("Version:     %s\n", version);
jbowes@258
  1317
		printf ("URL:         %s\n", url);
jbowes@258
  1318
		printf ("License:     %s\n", license);
jbowes@258
  1319
		printf ("Summary:     %s\n", summary);
jbowes@258
  1320
		printf ("Description:\n");
jbowes@258
  1321
		printf ("%s\n", description);
jbowes@258
  1322
		printf ("\n");
jbowes@258
  1323
	}
jbowes@258
  1324
	razor_package_iterator_destroy(pi);
ali@403
  1325
	razor_set_unref(set);
ali@403
  1326
	razor_atomic_destroy(atomic);
jbowes@258
  1327
jbowes@258
  1328
	return 0;
jbowes@258
  1329
}
jbowes@258
  1330
jbowes@292
  1331
#define SEARCH_MAX 256
jbowes@292
  1332
jbowes@292
  1333
static int
jbowes@292
  1334
command_search(int argc, const char *argv[])
jbowes@292
  1335
{
ali@403
  1336
	struct razor_atomic *atomic;
jbowes@292
  1337
	struct razor_set *set;
jbowes@292
  1338
	struct razor_package_iterator *pi;
jbowes@292
  1339
	struct razor_package *package;
jbowes@292
  1340
	char pattern[SEARCH_MAX];
jbowes@292
  1341
	const char *name, *version, *arch;
jbowes@292
  1342
	const char *summary, *description, *url, *license;
jbowes@292
  1343
jbowes@292
  1344
	if (!argv[0]) {
jbowes@292
  1345
		fprintf(stderr, "must specify a search term\n");
jbowes@292
  1346
		return 1;
jbowes@292
  1347
	}
jbowes@292
  1348
krh@294
  1349
	snprintf(pattern, sizeof pattern, "*%s*", argv[0]);
jbowes@292
  1350
ali@403
  1351
	atomic = razor_atomic_open("Search packages");
ali@403
  1352
	set = razor_set_open(rawhide_repo_filename, atomic);
ali@403
  1353
	if (set == NULL || razor_atomic_commit(atomic)) {
ali@403
  1354
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
  1355
		razor_atomic_destroy(atomic);
jbowes@292
  1356
		return 1;
ali@403
  1357
	}
ali@403
  1358
	razor_atomic_destroy(atomic);
richard@310
  1359
jbowes@292
  1360
	pi = razor_package_iterator_create(set);
jbowes@292
  1361
	while (razor_package_iterator_next(pi, &package,
richard@304
  1362
					   RAZOR_DETAIL_NAME, &name,
richard@304
  1363
					   RAZOR_DETAIL_VERSION, &version,
krh@305
  1364
					   RAZOR_DETAIL_ARCH, &arch,
krh@305
  1365
					   RAZOR_DETAIL_SUMMARY, &summary,
krh@305
  1366
					   RAZOR_DETAIL_DESCRIPTION, &description,
krh@305
  1367
					   RAZOR_DETAIL_URL, &url,
krh@305
  1368
					   RAZOR_DETAIL_LICENSE, &license,
richard@307
  1369
					   RAZOR_DETAIL_LAST)) {
krh@305
  1370
		if (!fnmatch(pattern, name, FNM_CASEFOLD) ||
krh@305
  1371
		    !fnmatch(pattern, url, FNM_CASEFOLD) ||
krh@305
  1372
		    !fnmatch(pattern, summary, FNM_CASEFOLD) ||
krh@305
  1373
		    !fnmatch(pattern, description, FNM_CASEFOLD))
krh@305
  1374
			printf("%s-%s.%s: %s\n", name, version, arch, summary);
jbowes@292
  1375
	}
jbowes@292
  1376
	razor_package_iterator_destroy(pi);
ali@403
  1377
	razor_set_unref(set);
jbowes@292
  1378
jbowes@292
  1379
	return 0;
jbowes@292
  1380
}
jbowes@292
  1381
rhughes@241
  1382
static struct {
rhughes@241
  1383
	const char *name;
rhughes@241
  1384
	const char *description;
rhughes@241
  1385
	int (*func)(int argc, const char *argv[]);
rhughes@241
  1386
} razor_commands[] = {
rhughes@241
  1387
	{ "list", "list all packages", command_list },
rhughes@241
  1388
	{ "list-requires", "list all requires for the given package", command_list_requires },
rhughes@241
  1389
	{ "list-provides", "list all provides for the given package", command_list_provides },
rhughes@241
  1390
	{ "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
rhughes@241
  1391
	{ "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
ali@369
  1392
	{ "list-scripts", "list all scripts for the given package", command_list_scripts },
rhughes@241
  1393
	{ "list-files", "list files for package set", command_list_files },
rhughes@241
  1394
	{ "list-file-packages", "list packages owning file", command_list_file_packages },
rhughes@241
  1395
	{ "list-package-files", "list files in package", command_list_package_files },
rhughes@241
  1396
	{ "what-requires", "list the packages that have the given requires", command_what_requires },
rhughes@241
  1397
	{ "what-provides", "list the packages that have the given provides", command_what_provides },
rhughes@241
  1398
	{ "import-yum", "import yum metadata files", command_import_yum },
ali@320
  1399
#if HAVE_RPMLIB
rhughes@241
  1400
	{ "import-rpmdb", "import the system rpm database", command_import_rpmdb },
ali@320
  1401
#endif
rhughes@241
  1402
	{ "import-rpms", "import rpms from the given directory", command_import_rpms },
rhughes@241
  1403
	{ "update", "update all or specified packages", command_update },
rhughes@241
  1404
	{ "remove", "remove specified packages", command_remove },
rhughes@241
  1405
	{ "diff", "show diff between two package sets", command_diff },
rhughes@241
  1406
	{ "install", "install rpm", command_install },
rhughes@241
  1407
	{ "init", "init razor root", command_init },
jbowes@258
  1408
	{ "download", "download packages", command_download },
jbowes@292
  1409
	{ "info", "display package details", command_info },
jbowes@292
  1410
	{ "search", "search package details", command_search }
rhughes@241
  1411
};
rhughes@241
  1412
rhughes@241
  1413
static int
rhughes@241
  1414
usage(void)
rhughes@241
  1415
{
rhughes@241
  1416
	int i;
rhughes@241
  1417
rhughes@241
  1418
	printf("usage:\n");
rhughes@241
  1419
	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
rhughes@241
  1420
		printf("  %-20s%s\n",
rhughes@241
  1421
		       razor_commands[i].name, razor_commands[i].description);
rhughes@241
  1422
rhughes@241
  1423
	return 1;
rhughes@241
  1424
}
rhughes@241
  1425
rhughes@241
  1426
int
rhughes@241
  1427
main(int argc, const char *argv[])
rhughes@241
  1428
{
krh@317
  1429
	char *repo, *root;
rhughes@241
  1430
	int i;
rhughes@241
  1431
rhughes@241
  1432
	repo = getenv("RAZOR_REPO");
rhughes@241
  1433
	if (repo != NULL)
rhughes@241
  1434
		repo_filename = repo;
rhughes@241
  1435
krh@317
  1436
	root = getenv("RAZOR_ROOT");
krh@317
  1437
	if (root != NULL)
krh@317
  1438
		install_root = root;
krh@317
  1439
rhughes@241
  1440
	yum_url = getenv("YUM_URL");
rhughes@241
  1441
	if (yum_url == NULL)
rhughes@241
  1442
		yum_url = YUM_URL;
rhughes@241
  1443
ali@359
  1444
	if (getenv("RAZOR_NO_ROOT_NAME_CHECKS"))
ali@359
  1445
		razor_disable_root_name_checks(1);
ali@359
  1446
rhughes@241
  1447
	if (argc < 2)
rhughes@241
  1448
		return usage();
rhughes@241
  1449
rhughes@241
  1450
	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
rhughes@241
  1451
		if (strcmp(razor_commands[i].name, argv[1]) == 0)
rhughes@241
  1452
			return razor_commands[i].func(argc - 2, argv + 2);
rhughes@241
  1453
rhughes@241
  1454
	return usage();
rhughes@241
  1455
}