src/main.c
author J. Ali Harlow <ali@juiblex.co.uk>
Wed Apr 29 17:00:01 2009 +0100 (2009-04-29)
changeset 361 2523d03a840e
parent 351 48b0adfe3059
child 363 c75a2d5caae9
permissions -rw-r--r--
Add support for preloading lua modules. This is useful both when
providing lua bindings to applications based on librazor and when
producing static binaries using librazor (where otherwise the lua
POSIX library would need to be included as an additional dynamic
object).
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@351
     4
 * Copyright (C) 2009  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";
richard@310
    45
static const char updated_repo_filename[] = "system-updated.rzdb";
krh@317
    46
static const char *install_root = "";
rhughes@241
    47
static const char *repo_filename = system_repo_filename;
rhughes@241
    48
static const char *yum_url;
rhughes@241
    49
krh@271
    50
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
krh@271
    51
krh@281
    52
static struct razor_package_iterator *
krh@281
    53
create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[])
rhughes@241
    54
{
krh@281
    55
	struct razor_package_query *query;
krh@281
    56
	struct razor_package_iterator *iter;
rhughes@241
    57
	struct razor_package *package;
richard@302
    58
	const char *name, *pattern;
krh@281
    59
	int i, count;
rhughes@241
    60
krh@281
    61
	if (argc == 0)
krh@281
    62
		return razor_package_iterator_create(set);
krh@281
    63
krh@281
    64
	query = razor_package_query_create(set);
krh@281
    65
krh@281
    66
	for (i = 0; i < argc; i++) {
krh@281
    67
		iter = razor_package_iterator_create(set);
krh@281
    68
		pattern = argv[i];
krh@281
    69
		count = 0;
richard@307
    70
		while (razor_package_iterator_next(iter, &package,
richard@307
    71
						   RAZOR_DETAIL_NAME, &name,
richard@307
    72
						   RAZOR_DETAIL_LAST)) {
krh@281
    73
			if (fnmatch(pattern, name, 0) != 0)
krh@281
    74
				continue;
krh@281
    75
krh@281
    76
			razor_package_query_add_package(query, package);
krh@281
    77
			count++;
krh@281
    78
		}
krh@281
    79
		razor_package_iterator_destroy(iter);
krh@281
    80
krh@281
    81
		if (count == 0)
krh@281
    82
			fprintf(stderr,
krh@281
    83
				"no package matches \"%s\"\n", pattern);
rhughes@241
    84
	}
rhughes@241
    85
krh@281
    86
	return razor_package_query_finish(query);
krh@281
    87
}
krh@281
    88
krh@281
    89
#define LIST_PACKAGES_ONLY_NAMES 0x01
krh@281
    90
krh@281
    91
static void
krh@281
    92
list_packages(struct razor_package_iterator *iter, uint32_t flags)
krh@281
    93
{
krh@281
    94
	struct razor_package *package;
krh@281
    95
	const char *name, *version, *arch;
krh@281
    96
krh@281
    97
	while (razor_package_iterator_next(iter, &package,
richard@302
    98
					   RAZOR_DETAIL_NAME, &name,
richard@302
    99
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   100
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   101
					   RAZOR_DETAIL_LAST)) {
krh@281
   102
		if (flags & LIST_PACKAGES_ONLY_NAMES)
rhughes@241
   103
			printf("%s\n", name);
rhughes@241
   104
		else
rhughes@241
   105
			printf("%s-%s.%s\n", name, version, arch);
rhughes@241
   106
	}
krh@281
   107
}
krh@281
   108
krh@281
   109
static int
krh@281
   110
command_list(int argc, const char *argv[])
krh@281
   111
{
krh@281
   112
	struct razor_package_iterator *pi;
krh@281
   113
	struct razor_set *set;
krh@281
   114
	uint32_t flags = 0;
krh@281
   115
	int i = 0;
krh@281
   116
krh@281
   117
	if (i < argc && strcmp(argv[i], "--only-names") == 0) {
krh@281
   118
		flags |= LIST_PACKAGES_ONLY_NAMES;
krh@281
   119
		i++;
krh@281
   120
	}
krh@281
   121
krh@317
   122
	set = razor_root_open_read_only(install_root);
krh@317
   123
	if (set == NULL)
krh@317
   124
		return 1;
krh@317
   125
krh@281
   126
	pi = create_iterator_from_argv(set, argc - i, argv + i);
krh@281
   127
	list_packages(pi, flags);
rhughes@241
   128
	razor_package_iterator_destroy(pi);
rhughes@241
   129
	razor_set_destroy(set);
rhughes@241
   130
rhughes@241
   131
	return 0;
rhughes@241
   132
}
rhughes@241
   133
krh@306
   134
static void
krh@306
   135
list_package_properties(struct razor_set *set,
krh@306
   136
			struct razor_package *package, uint32_t type)
rhughes@241
   137
{
krh@306
   138
	struct razor_property_iterator *pi;
rhughes@241
   139
	struct razor_property *property;
rhughes@241
   140
	const char *name, *version;
krh@247
   141
	uint32_t flags;
rhughes@241
   142
rhughes@241
   143
	pi = razor_property_iterator_create(set, package);
rhughes@241
   144
	while (razor_property_iterator_next(pi, &property,
krh@247
   145
					    &name, &flags, &version)) {
krh@247
   146
		if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
rhughes@241
   147
			continue;
krh@247
   148
		printf("%s", name);
krh@247
   149
		if (version[0] != '\0')
krh@247
   150
			printf(" %s %s",
krh@247
   151
			       razor_property_relation_to_string(property),
krh@247
   152
			       version);
krh@247
   153
krh@247
   154
		if (flags & ~(RAZOR_PROPERTY_RELATION_MASK | RAZOR_PROPERTY_TYPE_MASK)) {
krh@247
   155
			printf(" [");
krh@247
   156
			if (flags & RAZOR_PROPERTY_PRE)
krh@247
   157
				printf(" pre");
krh@247
   158
			if (flags & RAZOR_PROPERTY_POST)
krh@247
   159
				printf(" post");
krh@247
   160
			if (flags & RAZOR_PROPERTY_PREUN)
krh@247
   161
				printf(" preun");
krh@247
   162
			if (flags & RAZOR_PROPERTY_POSTUN)
krh@247
   163
				printf(" postun");
krh@247
   164
			printf(" ]");
krh@247
   165
		}
krh@247
   166
		printf("\n");
rhughes@241
   167
	}
rhughes@241
   168
	razor_property_iterator_destroy(pi);
krh@306
   169
}
rhughes@241
   170
krh@306
   171
static int
krh@306
   172
list_properties(int argc, const char *argv[], uint32_t type)
krh@306
   173
{
krh@306
   174
	struct razor_set *set;
krh@306
   175
	struct razor_package *package;
krh@306
   176
	struct razor_package_iterator *pi;
krh@306
   177
	const char *name, *version, *arch;
krh@306
   178
krh@317
   179
	set = razor_root_open_read_only(install_root);
krh@317
   180
	if (set == NULL)
krh@317
   181
		return 1;
krh@317
   182
krh@306
   183
	pi = create_iterator_from_argv(set, argc, argv);
krh@306
   184
	while (razor_package_iterator_next(pi, &package,
richard@307
   185
					   RAZOR_DETAIL_NAME, &name,
richard@307
   186
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   187
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   188
					   RAZOR_DETAIL_LAST))
krh@306
   189
		list_package_properties(set, package, type);
krh@306
   190
	razor_package_iterator_destroy(pi);
rhughes@241
   191
	razor_set_destroy(set);
rhughes@241
   192
rhughes@241
   193
	return 0;
rhughes@241
   194
}
rhughes@241
   195
rhughes@241
   196
static int
rhughes@241
   197
command_list_requires(int argc, const char *argv[])
rhughes@241
   198
{
krh@306
   199
	return list_properties(argc, argv, RAZOR_PROPERTY_REQUIRES);
rhughes@241
   200
}
rhughes@241
   201
rhughes@241
   202
static int
rhughes@241
   203
command_list_provides(int argc, const char *argv[])
rhughes@241
   204
{
krh@306
   205
	return list_properties(argc, argv, RAZOR_PROPERTY_PROVIDES);
rhughes@241
   206
}
rhughes@241
   207
rhughes@241
   208
static int
rhughes@241
   209
command_list_obsoletes(int argc, const char *argv[])
rhughes@241
   210
{
krh@306
   211
	return list_properties(argc, argv, RAZOR_PROPERTY_OBSOLETES);
rhughes@241
   212
}
rhughes@241
   213
rhughes@241
   214
static int
rhughes@241
   215
command_list_conflicts(int argc, const char *argv[])
rhughes@241
   216
{
krh@306
   217
	return list_properties(argc, argv, RAZOR_PROPERTY_CONFLICTS);
rhughes@241
   218
}
rhughes@241
   219
rhughes@241
   220
static int
rhughes@241
   221
command_list_files(int argc, const char *argv[])
rhughes@241
   222
{
rhughes@241
   223
	struct razor_set *set;
rhughes@241
   224
krh@317
   225
	set = razor_root_open_read_only(install_root);
rhughes@241
   226
	if (set == NULL)
rhughes@241
   227
		return 1;
krh@317
   228
rhughes@241
   229
	razor_set_list_files(set, argv[0]);
rhughes@241
   230
	razor_set_destroy(set);
rhughes@241
   231
rhughes@241
   232
	return 0;
rhughes@241
   233
}
rhughes@241
   234
rhughes@241
   235
static int
rhughes@241
   236
command_list_file_packages(int argc, const char *argv[])
rhughes@241
   237
{
rhughes@241
   238
	struct razor_set *set;
rhughes@241
   239
	struct razor_package_iterator *pi;
rhughes@241
   240
krh@317
   241
	set = razor_root_open_read_only(install_root);
rhughes@241
   242
	if (set == NULL)
rhughes@241
   243
		return 1;
rhughes@241
   244
rhughes@241
   245
	pi = razor_package_iterator_create_for_file(set, argv[0]);
krh@281
   246
	list_packages(pi, 0);
rhughes@241
   247
	razor_package_iterator_destroy(pi);
rhughes@241
   248
rhughes@241
   249
	razor_set_destroy(set);
rhughes@241
   250
rhughes@241
   251
	return 0;
rhughes@241
   252
}
rhughes@241
   253
rhughes@241
   254
static int
rhughes@241
   255
command_list_package_files(int argc, const char *argv[])
rhughes@241
   256
{
rhughes@241
   257
	struct razor_set *set;
krh@306
   258
	struct razor_package_iterator *pi;
krh@306
   259
	struct razor_package *package;
krh@306
   260
	const char *name, *version, *arch;
rhughes@241
   261
krh@317
   262
	set = razor_root_open_read_only(install_root);
rhughes@241
   263
	if (set == NULL)
rhughes@241
   264
		return 1;
jbowes@288
   265
krh@306
   266
	pi = create_iterator_from_argv(set, argc, argv);
krh@306
   267
	while (razor_package_iterator_next(pi, &package,
richard@307
   268
					   RAZOR_DETAIL_NAME, &name,
richard@307
   269
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   270
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   271
					   RAZOR_DETAIL_LAST))
krh@306
   272
		razor_set_list_package_files(set, package);
krh@306
   273
	razor_package_iterator_destroy(pi);
krh@306
   274
rhughes@241
   275
	razor_set_destroy(set);
rhughes@241
   276
rhughes@241
   277
	return 0;
rhughes@241
   278
}
rhughes@241
   279
rhughes@241
   280
static int
rhughes@241
   281
list_property_packages(const char *ref_name,
rhughes@241
   282
		       const char *ref_version,
krh@247
   283
		       uint32_t type)
rhughes@241
   284
{
rhughes@241
   285
	struct razor_set *set;
rhughes@241
   286
	struct razor_property *property;
krh@281
   287
	struct razor_property_iterator *prop_iter;
krh@281
   288
	struct razor_package_iterator *pkg_iter;
rhughes@241
   289
	const char *name, *version;
krh@247
   290
	uint32_t flags;
rhughes@241
   291
rhughes@241
   292
	if (ref_name == NULL)
rhughes@241
   293
		return 0;
rhughes@241
   294
krh@317
   295
	set = razor_root_open_read_only(install_root);
rhughes@241
   296
	if (set == NULL)
rhughes@241
   297
		return 1;
rhughes@241
   298
krh@281
   299
	prop_iter = razor_property_iterator_create(set, NULL);
krh@281
   300
	while (razor_property_iterator_next(prop_iter, &property,
krh@247
   301
					    &name, &flags, &version)) {
rhughes@241
   302
		if (strcmp(ref_name, name) != 0)
rhughes@241
   303
			continue;
krh@247
   304
		if (ref_version &&
krh@247
   305
		    (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
rhughes@241
   306
		    strcmp(ref_version, version) != 0)
rhughes@241
   307
			continue;
krh@247
   308
		if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
rhughes@241
   309
			continue;
rhughes@241
   310
krh@281
   311
		pkg_iter =
krh@281
   312
			razor_package_iterator_create_for_property(set,
krh@281
   313
								   property);
krh@281
   314
		list_packages(pkg_iter, 0);
krh@281
   315
		razor_package_iterator_destroy(pkg_iter);
rhughes@241
   316
	}
krh@281
   317
	razor_property_iterator_destroy(prop_iter);
rhughes@241
   318
krh@317
   319
	razor_set_destroy(set);
krh@317
   320
rhughes@241
   321
	return 0;
rhughes@241
   322
}
rhughes@241
   323
rhughes@241
   324
static int
rhughes@241
   325
command_what_requires(int argc, const char *argv[])
rhughes@241
   326
{
rhughes@241
   327
	return list_property_packages(argv[0], argv[1],
rhughes@241
   328
				      RAZOR_PROPERTY_REQUIRES);
rhughes@241
   329
}
rhughes@241
   330
rhughes@241
   331
static int
rhughes@241
   332
command_what_provides(int argc, const char *argv[])
rhughes@241
   333
{
rhughes@241
   334
	return list_property_packages(argv[0], argv[1],
rhughes@241
   335
				      RAZOR_PROPERTY_PROVIDES);
rhughes@241
   336
}
rhughes@241
   337
rhughes@241
   338
static int
rhughes@241
   339
show_progress(void *clientp,
rhughes@241
   340
	      double dltotal, double dlnow, double ultotal, double ulnow)
rhughes@241
   341
{
rhughes@241
   342
	const char *file = clientp;
rhughes@241
   343
rhughes@241
   344
	if (!dlnow < dltotal)
rhughes@241
   345
		fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
rhughes@241
   346
			file, (int) dlnow / 1024, (int) dltotal / 1024);
rhughes@241
   347
rhughes@241
   348
	return 0;
rhughes@241
   349
}
rhughes@241
   350
rhughes@241
   351
static int
rhughes@241
   352
download_if_missing(const char *url, const char *file)
rhughes@241
   353
{
ali@321
   354
#ifndef HAVE_CURL
ali@321
   355
	return 1;
ali@321
   356
#else
rhughes@241
   357
	CURL *curl;
rhughes@241
   358
	struct stat buf;
rhughes@241
   359
	char error[256];
rhughes@241
   360
	FILE *fp;
rhughes@241
   361
	CURLcode res;
rhughes@241
   362
	long response;
rhughes@241
   363
rhughes@241
   364
	curl = curl_easy_init();
rhughes@241
   365
	if (curl == NULL)
rhughes@241
   366
		return 1;
rhughes@241
   367
rhughes@241
   368
	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
rhughes@241
   369
	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
rhughes@241
   370
	curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
rhughes@241
   371
	curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
rhughes@241
   372
rhughes@241
   373
	if (stat(file, &buf) < 0) {
ali@345
   374
		fp = fopen(file, "wb");
rhughes@241
   375
		if (fp == NULL) {
rhughes@241
   376
			fprintf(stderr,
rhughes@241
   377
				"failed to open %s for writing\n", file);
rhughes@241
   378
			return -1;
rhughes@241
   379
		}
rhughes@241
   380
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
rhughes@241
   381
		curl_easy_setopt(curl, CURLOPT_URL, url);
rhughes@241
   382
		res = curl_easy_perform(curl);
rhughes@241
   383
		fclose(fp);
rhughes@241
   384
		if (res != CURLE_OK) {
rhughes@241
   385
			fprintf(stderr, "curl error: %s\n", error);
rhughes@241
   386
			unlink(file);
rhughes@241
   387
			return -1;
rhughes@241
   388
		}
rhughes@241
   389
		res = curl_easy_getinfo(curl,
rhughes@241
   390
					CURLINFO_RESPONSE_CODE, &response);
rhughes@241
   391
		if (res != CURLE_OK) {
rhughes@241
   392
			fprintf(stderr, "curl error: %s\n", error);
rhughes@241
   393
                        unlink(file);
rhughes@241
   394
                        return -1;
rhughes@241
   395
		}
rhughes@241
   396
		if (response != 200) {
rhughes@241
   397
			fprintf(stderr, " - failed %ld\n", response);
rhughes@241
   398
                        unlink(file);
rhughes@241
   399
                        return -1;
rhughes@241
   400
		}
rhughes@241
   401
		fprintf(stderr, "\n");
rhughes@241
   402
	}
rhughes@241
   403
rhughes@241
   404
	curl_easy_cleanup(curl);
rhughes@241
   405
rhughes@241
   406
	return 0;
ali@321
   407
#endif	/* HAVE_CURL */
rhughes@241
   408
}
rhughes@241
   409
rhughes@241
   410
#define YUM_URL "http://download.fedora.redhat.com" \
rhughes@241
   411
	"/pub/fedora/linux/development/i386/os"
rhughes@241
   412
rhughes@241
   413
static int
rhughes@241
   414
command_import_yum(int argc, const char *argv[])
rhughes@241
   415
{
rhughes@241
   416
	struct razor_set *set;
rhughes@241
   417
	char buffer[512];
rhughes@241
   418
rhughes@241
   419
	printf("downloading from %s.\n", yum_url);
rhughes@241
   420
	snprintf(buffer, sizeof buffer,
rhughes@241
   421
		 "%s/repodata/primary.xml.gz", yum_url);
rhughes@241
   422
	if (download_if_missing(buffer, "primary.xml.gz") < 0)
rhughes@241
   423
		return -1;
rhughes@241
   424
	snprintf(buffer, sizeof buffer,
rhughes@241
   425
		 "%s/repodata/filelists.xml.gz", yum_url);
rhughes@241
   426
	if (download_if_missing(buffer, "filelists.xml.gz") < 0)
rhughes@241
   427
		return -1;
rhughes@241
   428
rhughes@241
   429
	set = razor_set_create_from_yum();
rhughes@241
   430
	if (set == NULL)
rhughes@241
   431
		return 1;
ali@342
   432
	if (razor_set_write(set, rawhide_repo_filename, RAZOR_REPO_FILE_MAIN)) {
ali@342
   433
		perror(rawhide_repo_filename);
ali@342
   434
		return -1;
ali@342
   435
	}
ali@342
   436
	if (razor_set_write(set, "rawhide-details.rzdb",
ali@342
   437
	    RAZOR_REPO_FILE_DETAILS)) {
ali@342
   438
		perror("rawhide-details.rzdb");
ali@342
   439
		return -1;
ali@342
   440
	}
ali@342
   441
	if (razor_set_write(set, "rawhide-files.rzdb", RAZOR_REPO_FILE_FILES)) {
ali@342
   442
		perror("rawhide-files.rzdb");
ali@342
   443
		return -1;
ali@342
   444
	}
rhughes@241
   445
	razor_set_destroy(set);
rhughes@241
   446
	printf("wrote %s\n", rawhide_repo_filename);
rhughes@241
   447
rhughes@241
   448
	return 0;
rhughes@241
   449
}
rhughes@241
   450
ali@320
   451
#if HAVE_RPMLIB
rhughes@241
   452
static int
rhughes@241
   453
command_import_rpmdb(int argc, const char *argv[])
rhughes@241
   454
{
rhughes@241
   455
	struct razor_set *set;
krh@317
   456
	struct razor_root *root;
krh@317
   457
krh@317
   458
	root = razor_root_open(install_root);
krh@317
   459
	if (root == NULL)
krh@317
   460
		return 1;
rhughes@241
   461
rhughes@241
   462
	set = razor_set_create_from_rpmdb();
rhughes@241
   463
	if (set == NULL)
rhughes@241
   464
		return 1;
rhughes@241
   465
krh@317
   466
	razor_root_update(root, set);
krh@317
   467
krh@317
   468
	return razor_root_commit(root);
rhughes@241
   469
}
ali@320
   470
#endif
rhughes@241
   471
rhughes@241
   472
static int
rhughes@241
   473
mark_packages_for_update(struct razor_transaction *trans,
rhughes@241
   474
			 struct razor_set *set, const char *pattern)
rhughes@241
   475
{
rhughes@241
   476
	struct razor_package_iterator *pi;
rhughes@241
   477
	struct razor_package *package;
richard@302
   478
	const char *name;
rhughes@241
   479
	int matches = 0;
rhughes@241
   480
rhughes@241
   481
	pi = razor_package_iterator_create(set);
rhughes@241
   482
	while (razor_package_iterator_next(pi, &package,
richard@307
   483
					   RAZOR_DETAIL_NAME, &name,
richard@307
   484
					   RAZOR_DETAIL_LAST)) {
rhughes@241
   485
		if (pattern && fnmatch(pattern, name, 0) == 0) {
rhughes@241
   486
			razor_transaction_update_package(trans, package);
rhughes@241
   487
			matches++;
rhughes@241
   488
		}
rhughes@241
   489
	}
rhughes@241
   490
	razor_package_iterator_destroy(pi);
rhughes@241
   491
rhughes@241
   492
	return matches;
rhughes@241
   493
}
rhughes@241
   494
rhughes@241
   495
static int
rhughes@241
   496
mark_packages_for_removal(struct razor_transaction *trans,
rhughes@241
   497
			  struct razor_set *set, const char *pattern)
rhughes@241
   498
{
rhughes@241
   499
	struct razor_package_iterator *pi;
rhughes@241
   500
	struct razor_package *package;
richard@302
   501
	const char *name;
rhughes@241
   502
	int matches = 0;
rhughes@241
   503
rhughes@241
   504
	pi = razor_package_iterator_create(set);
richard@307
   505
	while (razor_package_iterator_next(pi, &package,
richard@307
   506
					   RAZOR_DETAIL_NAME, &name,
richard@307
   507
					   RAZOR_DETAIL_LAST)) {
rhughes@241
   508
		if (pattern && fnmatch(pattern, name, 0) == 0) {
rhughes@241
   509
			razor_transaction_remove_package(trans, package);
rhughes@241
   510
			matches++;
rhughes@241
   511
		}
rhughes@241
   512
	}
rhughes@241
   513
	razor_package_iterator_destroy(pi);
rhughes@241
   514
rhughes@241
   515
	return matches;
rhughes@241
   516
}
rhughes@241
   517
rhughes@241
   518
static int
rhughes@241
   519
command_update(int argc, const char *argv[])
rhughes@241
   520
{
rhughes@241
   521
	struct razor_set *set, *upstream;
rhughes@241
   522
	struct razor_transaction *trans;
rhughes@241
   523
	int i, errors;
rhughes@241
   524
krh@317
   525
	set = razor_root_open_read_only(install_root);
krh@317
   526
	if (set == NULL)
krh@315
   527
		return 1;
krh@315
   528
rhughes@241
   529
	upstream = razor_set_open(rawhide_repo_filename);
krh@315
   530
	if (upstream == NULL ||
krh@315
   531
	    razor_set_open_details(upstream, "rawhide-details.rzdb") ||
krh@315
   532
	    razor_set_open_files(upstream, "rawhide-files.rzdb"))
rhughes@241
   533
		return 1;
rhughes@241
   534
rhughes@241
   535
	trans = razor_transaction_create(set, upstream);
rhughes@241
   536
	if (argc == 0)
rhughes@241
   537
		razor_transaction_update_all(trans);
rhughes@241
   538
	for (i = 0; i < argc; i++) {
rhughes@241
   539
		if (mark_packages_for_update(trans, set, argv[i]) == 0) {
rhughes@241
   540
			fprintf(stderr, "no match for %s\n", argv[i]);
rhughes@241
   541
			return 1;
rhughes@241
   542
		}
rhughes@241
   543
	}
rhughes@241
   544
krh@252
   545
	razor_transaction_resolve(trans);
krh@252
   546
	errors = razor_transaction_describe(trans);
krh@252
   547
	if (errors) {
krh@252
   548
		fprintf(stderr, "unresolved dependencies\n");
rhughes@241
   549
		return 1;
krh@252
   550
	}
rhughes@241
   551
rhughes@241
   552
	set = razor_transaction_finish(trans);
jbowes@258
   553
	razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN);
rhughes@241
   554
	razor_set_destroy(set);
rhughes@241
   555
	razor_set_destroy(upstream);
richard@310
   556
	printf("wrote system-updated.rzdb\n");
rhughes@241
   557
rhughes@241
   558
	return 0;
rhughes@241
   559
}
rhughes@241
   560
rhughes@241
   561
static int
rhughes@241
   562
command_remove(int argc, const char *argv[])
rhughes@241
   563
{
rhughes@241
   564
	struct razor_set *set, *upstream;
rhughes@241
   565
	struct razor_transaction *trans;
rhughes@241
   566
	int i, errors;
rhughes@241
   567
krh@317
   568
	set = razor_root_open_read_only(install_root);
rhughes@241
   569
	if (set == NULL)
rhughes@241
   570
		return 1;
rhughes@241
   571
rhughes@241
   572
	upstream = razor_set_create();
rhughes@241
   573
	trans = razor_transaction_create(set, upstream);
rhughes@241
   574
	for (i = 0; i < argc; i++) {
rhughes@241
   575
		if (mark_packages_for_removal(trans, set, argv[i]) == 0) {
rhughes@241
   576
			fprintf(stderr, "no match for %s\n", argv[i]);
rhughes@241
   577
			return 1;
rhughes@241
   578
		}
rhughes@241
   579
	}
rhughes@241
   580
ali@350
   581
	razor_transaction_resolve(trans);
ali@350
   582
	errors = razor_transaction_describe(trans);
rhughes@241
   583
	if (errors)
rhughes@241
   584
		return 1;
rhughes@241
   585
rhughes@241
   586
	set = razor_transaction_finish(trans);
jbowes@258
   587
	razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN);
rhughes@241
   588
	razor_set_destroy(set);
rhughes@241
   589
	razor_set_destroy(upstream);
richard@310
   590
	printf("wrote system-updated.rzdb\n");
rhughes@241
   591
rhughes@241
   592
	return 0;
rhughes@241
   593
}
rhughes@241
   594
rhughes@241
   595
static void
krh@253
   596
print_diff(enum razor_diff_action action,
krh@253
   597
	   struct razor_package *package,
krh@253
   598
	   const char *name,
krh@253
   599
	   const char *version,
krh@253
   600
	   const char *arch,
rhughes@241
   601
	   void *data)
rhughes@241
   602
{
krh@253
   603
	if (action == RAZOR_DIFF_ACTION_ADD)
krh@253
   604
		printf("install %s-%s.%s\n", name, version, arch);
krh@253
   605
	if (action == RAZOR_DIFF_ACTION_REMOVE)
krh@253
   606
		printf("remove %s-%s.%s\n", name, version, arch);
rhughes@241
   607
}
rhughes@241
   608
rhughes@241
   609
static int
rhughes@241
   610
command_diff(int argc, const char *argv[])
rhughes@241
   611
{
rhughes@241
   612
	struct razor_set *set, *updated;
rhughes@241
   613
krh@317
   614
	set = razor_root_open_read_only(install_root);
rhughes@241
   615
	updated = razor_set_open(updated_repo_filename);
rhughes@241
   616
	if (set == NULL || updated == NULL)
rhughes@241
   617
		return 1;
rhughes@241
   618
rhughes@241
   619
	razor_set_diff(set, updated, print_diff, NULL);
rhughes@241
   620
rhughes@241
   621
	razor_set_destroy(set);
rhughes@241
   622
	razor_set_destroy(updated);
rhughes@241
   623
rhughes@241
   624
	return 0;
rhughes@241
   625
}
rhughes@241
   626
rhughes@241
   627
static int
rhughes@241
   628
command_import_rpms(int argc, const char *argv[])
rhughes@241
   629
{
rhughes@241
   630
	DIR *dir;
rhughes@241
   631
	struct dirent *de;
rhughes@241
   632
	struct razor_importer *importer;
rhughes@241
   633
	struct razor_set *set;
rhughes@241
   634
	struct razor_rpm *rpm;
jbowes@263
   635
	int len, imported_count = 0;
rhughes@241
   636
	char filename[256];
rhughes@241
   637
	const char *dirname = argv[0];
rhughes@241
   638
rhughes@241
   639
	if (dirname == NULL) {
rhughes@241
   640
		fprintf(stderr, "usage: razor import-rpms DIR\n");
rhughes@241
   641
		return -1;
rhughes@241
   642
	}
rhughes@241
   643
rhughes@241
   644
	dir = opendir(dirname);
rhughes@241
   645
	if (dir == NULL) {
rhughes@241
   646
		fprintf(stderr, "couldn't read dir %s\n", dirname);
rhughes@241
   647
		return -1;
rhughes@241
   648
	}
rhughes@241
   649
krh@249
   650
	importer = razor_importer_create();
rhughes@241
   651
rhughes@241
   652
	while (de = readdir(dir), de != NULL) {
rhughes@241
   653
		len = strlen(de->d_name);
rhughes@241
   654
		if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
rhughes@241
   655
		    continue;
rhughes@241
   656
		snprintf(filename, sizeof filename,
rhughes@241
   657
			 "%s/%s", dirname, de->d_name);
rhughes@241
   658
		rpm = razor_rpm_open(filename);
rhughes@241
   659
		if (rpm == NULL) {
rhughes@241
   660
			fprintf(stderr,
rhughes@241
   661
				"failed to open rpm \"%s\"\n", filename);
rhughes@241
   662
			continue;
rhughes@241
   663
		}
rhughes@241
   664
		if (razor_importer_add_rpm(importer, rpm)) {
rhughes@241
   665
			fprintf(stderr, "couldn't import %s\n", filename);
rhughes@241
   666
			break;
rhughes@241
   667
		}
rhughes@241
   668
		razor_rpm_close(rpm);
jbowes@263
   669
jbowes@263
   670
		printf("\rimporting %d", ++imported_count);
jbowes@263
   671
		fflush(stdout);
rhughes@241
   672
	}
rhughes@241
   673
rhughes@241
   674
	if (de != NULL) {
rhughes@241
   675
		razor_importer_destroy(importer);
rhughes@241
   676
		return -1;
rhughes@241
   677
	}
rhughes@241
   678
jbowes@263
   679
	printf("\nsaving\n");
rhughes@241
   680
	set = razor_importer_finish(importer);
rhughes@241
   681
jbowes@258
   682
	razor_set_write(set, repo_filename, RAZOR_REPO_FILE_MAIN);
richard@310
   683
	razor_set_write(set, "system-details.rzdb", RAZOR_REPO_FILE_DETAILS);
richard@310
   684
	razor_set_write(set, "system-files.rzdb", RAZOR_REPO_FILE_FILES);
rhughes@241
   685
	razor_set_destroy(set);
rhughes@241
   686
	printf("wrote %s\n", repo_filename);
rhughes@241
   687
rhughes@241
   688
	return 0;
rhughes@241
   689
}
rhughes@241
   690
krh@254
   691
static const char *
krh@254
   692
rpm_filename(const char *name, const char *version, const char *arch)
rhughes@241
   693
{
krh@254
   694
	static char file[PATH_MAX];
krh@254
   695
 	const char *v;
krh@254
   696
 
krh@254
   697
 	/* Skip epoch */
krh@253
   698
	v = strchr(version, ':');
krh@254
   699
 	if (v != NULL)
krh@254
   700
 		v = v + 1;
krh@254
   701
 	else
krh@253
   702
		v = version;
rhughes@241
   703
krh@254
   704
	snprintf(file, sizeof file, "%s-%s.%s.rpm", name, v, arch);
rhughes@241
   705
krh@254
   706
	return file;
rhughes@241
   707
}
rhughes@241
   708
krh@254
   709
static int
krh@254
   710
download_packages(struct razor_set *system, struct razor_set *next)
rhughes@241
   711
{
krh@316
   712
	struct razor_install_iterator *ii;
krh@254
   713
	struct razor_package *package;
krh@316
   714
	struct razor_set *set;
krh@316
   715
	enum razor_install_action action;
krh@254
   716
	const char *name, *version, *arch;
krh@254
   717
	char file[PATH_MAX], url[256];
krh@316
   718
	int errors = 0, count;
krh@316
   719
krh@316
   720
	ii = razor_set_create_install_iterator(system, next);
krh@316
   721
	while (razor_install_iterator_next(ii, &set, &package,
krh@316
   722
					   &action, &count)) {
krh@316
   723
		if (action == RAZOR_INSTALL_ACTION_REMOVE)
krh@316
   724
			continue;
krh@316
   725
krh@316
   726
		razor_package_get_details(set, package,
krh@316
   727
					  RAZOR_DETAIL_NAME, &name,
krh@316
   728
					  RAZOR_DETAIL_VERSION, &version,
krh@316
   729
					  RAZOR_DETAIL_ARCH, &arch,
krh@316
   730
					  RAZOR_DETAIL_LAST);
krh@316
   731
		
krh@254
   732
		snprintf(url, sizeof url,
krh@254
   733
			 "%s/Packages/%s",
krh@254
   734
			 yum_url, rpm_filename(name, version, arch));
krh@254
   735
		snprintf(file, sizeof file,
krh@254
   736
			 "rpms/%s", rpm_filename(name, version, arch));
krh@254
   737
		if (download_if_missing(url, file) < 0)
krh@254
   738
			errors++;
krh@254
   739
	}
krh@316
   740
	razor_install_iterator_destroy(ii);
krh@254
   741
krh@254
   742
	if (errors > 0) {
krh@254
   743
		fprintf(stderr, "failed to download %d packages\n", errors);
krh@254
   744
                return -1;
krh@254
   745
        }
krh@254
   746
krh@254
   747
	return 0;
krh@254
   748
}
krh@254
   749
ali@351
   750
static struct razor_set *
ali@351
   751
relocate_packages(struct razor_set *set, struct razor_relocations *relocations)
ali@351
   752
{
ali@351
   753
	struct razor_importer *importer;
ali@351
   754
	struct razor_property_iterator *prop_iter;
ali@351
   755
	struct razor_package_iterator *pkg_iter;
ali@351
   756
 	struct razor_file_iterator *file_iter;
ali@351
   757
 	struct razor_package *package;
ali@351
   758
	struct razor_property *property;
ali@351
   759
	struct razor_rpm *rpm;
ali@351
   760
	const char *name, *version, *arch, *summary, *desc, *url, *license;
ali@351
   761
	char file[PATH_MAX];
ali@351
   762
	uint32_t flags;
ali@351
   763
ali@351
   764
	importer = razor_importer_create();
ali@351
   765
	pkg_iter = razor_package_iterator_create(set);
ali@351
   766
ali@351
   767
	while (razor_package_iterator_next(pkg_iter, &package,
ali@351
   768
					   RAZOR_DETAIL_NAME, &name,
ali@351
   769
					   RAZOR_DETAIL_VERSION, &version,
ali@351
   770
					   RAZOR_DETAIL_ARCH, &arch,
ali@351
   771
					   RAZOR_DETAIL_SUMMARY, &summary,
ali@351
   772
					   RAZOR_DETAIL_DESCRIPTION, &desc,
ali@351
   773
					   RAZOR_DETAIL_URL, &url,
ali@351
   774
					   RAZOR_DETAIL_LICENSE, &license,
ali@351
   775
					   RAZOR_DETAIL_LAST)) {
ali@351
   776
		snprintf(file, sizeof file,
ali@351
   777
			 "rpms/%s", rpm_filename(name, version, arch));
ali@351
   778
		rpm = razor_rpm_open(file);
ali@351
   779
		if (rpm == NULL) {
ali@351
   780
			fprintf(stderr, "failed to open rpm %s\n", file);
ali@351
   781
			razor_package_iterator_destroy(pkg_iter);
ali@351
   782
			razor_importer_destroy(importer);
ali@351
   783
			return NULL;
ali@351
   784
		}
ali@351
   785
ali@351
   786
		razor_relocations_set_rpm(relocations, rpm);
ali@351
   787
		razor_rpm_close(rpm);
ali@351
   788
ali@351
   789
		razor_importer_begin_package(importer, name, version, arch);
ali@351
   790
		razor_importer_add_details(importer,
ali@351
   791
					   summary, desc, url, license);
ali@351
   792
ali@351
   793
		prop_iter = razor_property_iterator_create(set, package);
ali@351
   794
		while (razor_property_iterator_next(prop_iter, &property,
ali@351
   795
						    &name, &flags, &version))
ali@351
   796
			razor_importer_add_property(importer,
ali@351
   797
						    name, flags, version);
ali@351
   798
		razor_property_iterator_destroy(prop_iter);
ali@351
   799
ali@351
   800
		file_iter = razor_file_iterator_create(set, package);
ali@351
   801
		while (razor_file_iterator_next(file_iter, &name)) {
ali@351
   802
			name = razor_relocations_apply(relocations, name);
ali@351
   803
			razor_importer_add_file(importer, name);
ali@351
   804
		}
ali@351
   805
		razor_file_iterator_destroy(file_iter);
ali@351
   806
ali@351
   807
		razor_importer_finish_package(importer);
ali@351
   808
	}
ali@351
   809
ali@351
   810
	razor_package_iterator_destroy(pkg_iter);
ali@351
   811
	return razor_importer_finish(importer);
ali@351
   812
}
ali@351
   813
krh@254
   814
static int
ali@351
   815
install_packages(struct razor_set *system, struct razor_set *next,
ali@351
   816
		 struct razor_relocations *relocations)
krh@254
   817
{
krh@316
   818
	struct razor_install_iterator *ii;
krh@254
   819
	struct razor_package *package;
krh@316
   820
	struct razor_set *set;
krh@316
   821
	enum razor_install_action action;
krh@254
   822
	struct razor_rpm *rpm;
krh@254
   823
	const char *name, *version, *arch;
rhughes@241
   824
	char file[PATH_MAX];
krh@316
   825
	int count;
rhughes@241
   826
krh@316
   827
	ii = razor_set_create_install_iterator(system, next);
krh@316
   828
	while (razor_install_iterator_next(ii, &set, &package,
krh@316
   829
					   &action, &count)) {
krh@316
   830
		if (action == RAZOR_INSTALL_ACTION_REMOVE)
krh@316
   831
			continue;
krh@316
   832
krh@316
   833
		razor_package_get_details(set, package,
krh@316
   834
					  RAZOR_DETAIL_NAME, &name,
krh@316
   835
					  RAZOR_DETAIL_VERSION, &version,
krh@316
   836
					  RAZOR_DETAIL_ARCH, &arch,
krh@316
   837
					  RAZOR_DETAIL_LAST);
krh@316
   838
krh@254
   839
		printf("install %s-%s\n", name, version);
krh@254
   840
krh@254
   841
		snprintf(file, sizeof file,
krh@254
   842
			 "rpms/%s", rpm_filename(name, version, arch));
krh@254
   843
		rpm = razor_rpm_open(file);
krh@254
   844
		if (rpm == NULL) {
krh@254
   845
			fprintf(stderr, "failed to open rpm %s\n", file);
krh@254
   846
			return -1;
krh@254
   847
		}
ali@351
   848
		if (relocations)
ali@351
   849
			razor_rpm_set_relocations(rpm, relocations);
krh@254
   850
		if (razor_rpm_install(rpm, install_root) < 0) {
krh@254
   851
			fprintf(stderr,
krh@254
   852
				"failed to install rpm %s\n", file);
krh@254
   853
			return -1;
krh@254
   854
		}
krh@254
   855
		razor_rpm_close(rpm);
rhughes@241
   856
	}
krh@316
   857
	razor_install_iterator_destroy(ii);
rhughes@241
   858
krh@254
   859
	return 0;
rhughes@241
   860
}
rhughes@241
   861
rhughes@241
   862
static int
rhughes@241
   863
command_install(int argc, const char *argv[])
rhughes@241
   864
{
rhughes@241
   865
	struct razor_root *root;
ali@351
   866
	struct razor_relocations *relocations=NULL;
ali@351
   867
	struct razor_set *system, *upstream, *next, *set;
rhughes@241
   868
	struct razor_transaction *trans;
ali@351
   869
	int i, len, dependencies = 1;
ali@351
   870
	char *oldpath;
rhughes@241
   871
krh@250
   872
	root = razor_root_open(install_root);
krh@255
   873
	if (root == NULL)
krh@255
   874
		return 1;
krh@255
   875
ali@351
   876
	for (i = 0; i < argc; i++) {
ali@351
   877
		if (strcmp(argv[i], "--no-dependencies") == 0)
ali@351
   878
			dependencies = 0;
ali@351
   879
		else if (strcmp(argv[i], "--relocate") == 0) {
ali@351
   880
			i++;
ali@351
   881
			if (i >= argc || strchr(argv[i], '=') == NULL) {
ali@351
   882
				fprintf(stderr,
ali@351
   883
				    "Usage: razor install [OPTION...] RPM\n");
ali@351
   884
				fprintf(stderr, "Options:\n");
ali@351
   885
				fprintf(stderr, "    [--no-dependencies]\n");
ali@351
   886
				fprintf(stderr,
ali@351
   887
				    "    [--relocate OLDPATH=NEWPATH] RPM\n");
ali@351
   888
				return -1;
ali@351
   889
			}
ali@351
   890
			len = strchr(argv[i], '=') - argv[i];
ali@351
   891
			oldpath = malloc(len + 1);
ali@351
   892
			strncpy(oldpath, argv[i], len);
ali@351
   893
			oldpath[len] = '\0';
ali@351
   894
			if (!relocations)
ali@351
   895
			       relocations = razor_relocations_create();
ali@351
   896
			razor_relocations_add(relocations, oldpath,
ali@351
   897
					      argv[i] + len + 1);
ali@351
   898
			free(oldpath);
ali@351
   899
		} else
ali@351
   900
			break;
ali@351
   901
	}
ali@351
   902
krh@250
   903
	system = razor_root_get_system_set(root);
rhughes@241
   904
	upstream = razor_set_open(rawhide_repo_filename);
krh@315
   905
	if (upstream == NULL ||
krh@315
   906
	    razor_set_open_details(upstream, "rawhide-details.rzdb") ||
krh@315
   907
	    razor_set_open_files(upstream, "rawhide-files.rzdb")) {
krh@315
   908
			fprintf(stderr, "couldn't open rawhide repo\n");
krh@315
   909
			razor_root_close(root);
krh@315
   910
			return 1;
krh@315
   911
	}		
krh@315
   912
ali@351
   913
	if (relocations) {
ali@351
   914
		set = relocate_packages(upstream, relocations);
ali@351
   915
		razor_set_destroy(upstream);
ali@351
   916
		upstream = set;
ali@351
   917
	}
ali@351
   918
krh@250
   919
	trans = razor_transaction_create(system, upstream);
rhughes@241
   920
rhughes@241
   921
	for (; i < argc; i++) {
rhughes@241
   922
		if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
rhughes@241
   923
			fprintf(stderr, "no package matched %s\n", argv[i]);
rhughes@241
   924
			razor_root_close(root);
rhughes@241
   925
			return 1;
rhughes@241
   926
		}
rhughes@241
   927
	}
rhughes@241
   928
rhughes@241
   929
	if (dependencies) {
krh@245
   930
		razor_transaction_resolve(trans);
krh@245
   931
		if (razor_transaction_describe(trans) > 0) {
rhughes@241
   932
			razor_root_close(root);
rhughes@241
   933
			return 1;
rhughes@241
   934
		}
rhughes@241
   935
	}
rhughes@241
   936
rhughes@241
   937
	next = razor_transaction_finish(trans);
rhughes@241
   938
rhughes@241
   939
	razor_root_update(root, next);
rhughes@241
   940
rhughes@241
   941
	if (mkdir("rpms", 0777) && errno != EEXIST) {
rhughes@241
   942
		fprintf(stderr, "failed to create rpms directory.\n");
rhughes@241
   943
		razor_root_close(root);
rhughes@241
   944
		return 1;
rhughes@241
   945
	}
rhughes@241
   946
krh@254
   947
	if (download_packages(system, next) < 0) {
rhughes@241
   948
		razor_root_close(root);
rhughes@241
   949
                return 1;
rhughes@241
   950
        }
rhughes@241
   951
ali@351
   952
	install_packages(system, next, relocations);
rhughes@241
   953
ali@351
   954
	if (relocations)
ali@351
   955
		razor_relocations_destroy(relocations);
rhughes@241
   956
	razor_set_destroy(next);
rhughes@241
   957
	razor_set_destroy(upstream);
rhughes@241
   958
rhughes@241
   959
	return razor_root_commit(root);
rhughes@241
   960
}
rhughes@241
   961
rhughes@241
   962
static int
rhughes@241
   963
command_init(int argc, const char *argv[])
rhughes@241
   964
{
rhughes@241
   965
	return razor_root_create(install_root);
rhughes@241
   966
}
rhughes@241
   967
rhughes@241
   968
static int
rhughes@241
   969
command_download(int argc, const char *argv[])
rhughes@241
   970
{
rhughes@241
   971
	struct razor_set *set;
rhughes@241
   972
	struct razor_package_iterator *pi;
rhughes@241
   973
	struct razor_package *package;
rhughes@241
   974
	const char *pattern = argv[0], *name, *version, *arch;
rhughes@241
   975
	char url[256], file[256];
rhughes@241
   976
	int matches = 0;
rhughes@241
   977
rhughes@241
   978
	if (mkdir("rpms", 0777) && errno != EEXIST) {
rhughes@241
   979
		fprintf(stderr, "failed to create rpms directory.\n");
rhughes@241
   980
		return 1;
rhughes@241
   981
	}
rhughes@241
   982
rhughes@241
   983
	set = razor_set_open(rawhide_repo_filename);
rhughes@241
   984
	pi = razor_package_iterator_create(set);
rhughes@241
   985
	while (razor_package_iterator_next(pi, &package,
richard@302
   986
					   RAZOR_DETAIL_NAME, &name,
richard@302
   987
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   988
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   989
					   RAZOR_DETAIL_LAST)) {
rhughes@241
   990
		if (pattern && fnmatch(pattern, name, 0) != 0)
rhughes@241
   991
			continue;
rhughes@241
   992
rhughes@241
   993
		matches++;
rhughes@241
   994
		snprintf(url, sizeof url,
rhughes@241
   995
			 "%s/Packages/%s-%s.%s.rpm",
rhughes@241
   996
			 yum_url, name, version, arch);
rhughes@241
   997
		snprintf(file, sizeof file,
rhughes@241
   998
			 "rpms/%s-%s.%s.rpm", name, version, arch);
rhughes@241
   999
		download_if_missing(url, file);
rhughes@241
  1000
	}
rhughes@241
  1001
	razor_package_iterator_destroy(pi);
rhughes@241
  1002
	razor_set_destroy(set);
rhughes@241
  1003
rhughes@241
  1004
	if (matches == 0)
rhughes@241
  1005
		fprintf(stderr, "no packages matched \"%s\"\n", pattern);
rhughes@241
  1006
	else if (matches == 1)
rhughes@241
  1007
		fprintf(stderr, "downloaded 1 package\n");
rhughes@241
  1008
	else
rhughes@241
  1009
		fprintf(stderr, "downloaded %d packages\n", matches);
rhughes@241
  1010
rhughes@241
  1011
	return 0;
rhughes@241
  1012
}
rhughes@241
  1013
jbowes@258
  1014
static int
jbowes@258
  1015
command_info(int argc, const char *argv[])
jbowes@258
  1016
{
jbowes@258
  1017
	struct razor_set *set;
jbowes@258
  1018
	struct razor_package_iterator *pi;
jbowes@258
  1019
	struct razor_package *package;
jbowes@258
  1020
	const char *pattern = argv[0], *name, *version, *arch;
jbowes@258
  1021
	const char *summary, *description, *url, *license;
jbowes@258
  1022
krh@317
  1023
	set = razor_root_open_read_only(install_root);
jbowes@288
  1024
	if (set == NULL)
jbowes@288
  1025
		return 1;
krh@317
  1026
jbowes@258
  1027
	pi = razor_package_iterator_create(set);
jbowes@258
  1028
	while (razor_package_iterator_next(pi, &package,
richard@302
  1029
					   RAZOR_DETAIL_NAME, &name,
richard@302
  1030
					   RAZOR_DETAIL_VERSION, &version,
richard@307
  1031
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
  1032
					   RAZOR_DETAIL_LAST)) {
jbowes@258
  1033
		if (pattern && fnmatch(pattern, name, 0) != 0)
jbowes@258
  1034
			continue;
jbowes@258
  1035
richard@302
  1036
		razor_package_get_details (set, package,
richard@302
  1037
					   RAZOR_DETAIL_SUMMARY, &summary,
richard@302
  1038
					   RAZOR_DETAIL_DESCRIPTION, &description,
richard@302
  1039
					   RAZOR_DETAIL_URL, &url,
richard@302
  1040
					   RAZOR_DETAIL_LICENSE, &license,
richard@307
  1041
					   RAZOR_DETAIL_LAST);
jbowes@258
  1042
jbowes@258
  1043
		printf ("Name:        %s\n", name);
jbowes@258
  1044
		printf ("Arch:        %s\n", arch);
jbowes@258
  1045
		printf ("Version:     %s\n", version);
jbowes@258
  1046
		printf ("URL:         %s\n", url);
jbowes@258
  1047
		printf ("License:     %s\n", license);
jbowes@258
  1048
		printf ("Summary:     %s\n", summary);
jbowes@258
  1049
		printf ("Description:\n");
jbowes@258
  1050
		printf ("%s\n", description);
jbowes@258
  1051
		printf ("\n");
jbowes@258
  1052
	}
jbowes@258
  1053
	razor_package_iterator_destroy(pi);
jbowes@258
  1054
	razor_set_destroy(set);
jbowes@258
  1055
jbowes@258
  1056
	return 0;
jbowes@258
  1057
}
jbowes@258
  1058
jbowes@292
  1059
#define SEARCH_MAX 256
jbowes@292
  1060
jbowes@292
  1061
static int
jbowes@292
  1062
command_search(int argc, const char *argv[])
jbowes@292
  1063
{
jbowes@292
  1064
	struct razor_set *set;
jbowes@292
  1065
	struct razor_package_iterator *pi;
jbowes@292
  1066
	struct razor_package *package;
jbowes@292
  1067
	char pattern[SEARCH_MAX];
jbowes@292
  1068
	const char *name, *version, *arch;
jbowes@292
  1069
	const char *summary, *description, *url, *license;
jbowes@292
  1070
jbowes@292
  1071
	if (!argv[0]) {
jbowes@292
  1072
		fprintf(stderr, "must specify a search term\n");
jbowes@292
  1073
		return 1;
jbowes@292
  1074
	}
jbowes@292
  1075
krh@294
  1076
	snprintf(pattern, sizeof pattern, "*%s*", argv[0]);
jbowes@292
  1077
krh@305
  1078
	set = razor_set_open(rawhide_repo_filename);
jbowes@292
  1079
	if (set == NULL)
jbowes@292
  1080
		return 1;
richard@310
  1081
richard@310
  1082
	if (razor_set_open_details(set, "rawhide-details.rzdb"))
jbowes@292
  1083
		return 1;
jbowes@292
  1084
jbowes@292
  1085
	pi = razor_package_iterator_create(set);
jbowes@292
  1086
	while (razor_package_iterator_next(pi, &package,
richard@304
  1087
					   RAZOR_DETAIL_NAME, &name,
richard@304
  1088
					   RAZOR_DETAIL_VERSION, &version,
krh@305
  1089
					   RAZOR_DETAIL_ARCH, &arch,
krh@305
  1090
					   RAZOR_DETAIL_SUMMARY, &summary,
krh@305
  1091
					   RAZOR_DETAIL_DESCRIPTION, &description,
krh@305
  1092
					   RAZOR_DETAIL_URL, &url,
krh@305
  1093
					   RAZOR_DETAIL_LICENSE, &license,
richard@307
  1094
					   RAZOR_DETAIL_LAST)) {
krh@305
  1095
		if (!fnmatch(pattern, name, FNM_CASEFOLD) ||
krh@305
  1096
		    !fnmatch(pattern, url, FNM_CASEFOLD) ||
krh@305
  1097
		    !fnmatch(pattern, summary, FNM_CASEFOLD) ||
krh@305
  1098
		    !fnmatch(pattern, description, FNM_CASEFOLD))
krh@305
  1099
			printf("%s-%s.%s: %s\n", name, version, arch, summary);
jbowes@292
  1100
	}
jbowes@292
  1101
	razor_package_iterator_destroy(pi);
jbowes@292
  1102
	razor_set_destroy(set);
jbowes@292
  1103
jbowes@292
  1104
	return 0;
jbowes@292
  1105
}
jbowes@292
  1106
rhughes@241
  1107
static struct {
rhughes@241
  1108
	const char *name;
rhughes@241
  1109
	const char *description;
rhughes@241
  1110
	int (*func)(int argc, const char *argv[]);
rhughes@241
  1111
} razor_commands[] = {
rhughes@241
  1112
	{ "list", "list all packages", command_list },
rhughes@241
  1113
	{ "list-requires", "list all requires for the given package", command_list_requires },
rhughes@241
  1114
	{ "list-provides", "list all provides for the given package", command_list_provides },
rhughes@241
  1115
	{ "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
rhughes@241
  1116
	{ "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
rhughes@241
  1117
	{ "list-files", "list files for package set", command_list_files },
rhughes@241
  1118
	{ "list-file-packages", "list packages owning file", command_list_file_packages },
rhughes@241
  1119
	{ "list-package-files", "list files in package", command_list_package_files },
rhughes@241
  1120
	{ "what-requires", "list the packages that have the given requires", command_what_requires },
rhughes@241
  1121
	{ "what-provides", "list the packages that have the given provides", command_what_provides },
rhughes@241
  1122
	{ "import-yum", "import yum metadata files", command_import_yum },
ali@320
  1123
#if HAVE_RPMLIB
rhughes@241
  1124
	{ "import-rpmdb", "import the system rpm database", command_import_rpmdb },
ali@320
  1125
#endif
rhughes@241
  1126
	{ "import-rpms", "import rpms from the given directory", command_import_rpms },
rhughes@241
  1127
	{ "update", "update all or specified packages", command_update },
rhughes@241
  1128
	{ "remove", "remove specified packages", command_remove },
rhughes@241
  1129
	{ "diff", "show diff between two package sets", command_diff },
rhughes@241
  1130
	{ "install", "install rpm", command_install },
rhughes@241
  1131
	{ "init", "init razor root", command_init },
jbowes@258
  1132
	{ "download", "download packages", command_download },
jbowes@292
  1133
	{ "info", "display package details", command_info },
jbowes@292
  1134
	{ "search", "search package details", command_search }
rhughes@241
  1135
};
rhughes@241
  1136
rhughes@241
  1137
static int
rhughes@241
  1138
usage(void)
rhughes@241
  1139
{
rhughes@241
  1140
	int i;
rhughes@241
  1141
rhughes@241
  1142
	printf("usage:\n");
rhughes@241
  1143
	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
rhughes@241
  1144
		printf("  %-20s%s\n",
rhughes@241
  1145
		       razor_commands[i].name, razor_commands[i].description);
rhughes@241
  1146
rhughes@241
  1147
	return 1;
rhughes@241
  1148
}
rhughes@241
  1149
rhughes@241
  1150
int
rhughes@241
  1151
main(int argc, const char *argv[])
rhughes@241
  1152
{
krh@317
  1153
	char *repo, *root;
rhughes@241
  1154
	int i;
rhughes@241
  1155
rhughes@241
  1156
	repo = getenv("RAZOR_REPO");
rhughes@241
  1157
	if (repo != NULL)
rhughes@241
  1158
		repo_filename = repo;
rhughes@241
  1159
krh@317
  1160
	root = getenv("RAZOR_ROOT");
krh@317
  1161
	if (root != NULL)
krh@317
  1162
		install_root = root;
krh@317
  1163
rhughes@241
  1164
	yum_url = getenv("YUM_URL");
rhughes@241
  1165
	if (yum_url == NULL)
rhughes@241
  1166
		yum_url = YUM_URL;
rhughes@241
  1167
ali@359
  1168
	if (getenv("RAZOR_NO_ROOT_NAME_CHECKS"))
ali@359
  1169
		razor_disable_root_name_checks(1);
ali@359
  1170
rhughes@241
  1171
	if (argc < 2)
rhughes@241
  1172
		return usage();
rhughes@241
  1173
rhughes@241
  1174
	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
rhughes@241
  1175
		if (strcmp(razor_commands[i].name, argv[1]) == 0)
rhughes@241
  1176
			return razor_commands[i].func(argc - 2, argv + 2);
rhughes@241
  1177
rhughes@241
  1178
	return usage();
rhughes@241
  1179
}