src/main.c
author J. Ali Harlow <ali@juiblex.co.uk>
Mon Jul 11 16:50:21 2016 +0100 (2016-07-11)
changeset 490 9e2943af74fe
parent 476 48e45439fd9a
permissions -rw-r--r--
Release 0.6.3.105
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@475
     4
 * Copyright (C) 2009, 2011-2012, 2014, 2016  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@455
    35
#ifdef MSWIN_API
ali@455
    36
#include <windows.h>
ali@455
    37
#include <shlwapi.h>
ali@455
    38
#endif
ali@321
    39
#ifdef HAVE_CURL
rhughes@241
    40
#include <curl/curl.h>
ali@321
    41
#endif
ali@455
    42
#if !defined(HAVE_CURL) && !defined(MSWIN_API)
ali@455
    43
#include <ctype.h>
ali@455
    44
#endif
rhughes@241
    45
#include <fnmatch.h>
rhughes@241
    46
#include <errno.h>
ali@445
    47
#include <getopt.h>
rhughes@241
    48
#include "razor.h"
ali@476
    49
#include "import.h"
rhughes@241
    50
richard@310
    51
static const char system_repo_filename[] = "system.rzdb";
richard@310
    52
static const char next_repo_filename[] = "system-next.rzdb";
ali@475
    53
static const char rawhide_repo_uri[] = "file:rawhide.rzdb";
krh@317
    54
static const char *install_root = "";
rhughes@241
    55
static const char *repo_filename = system_repo_filename;
rhughes@241
    56
static const char *yum_url;
rhughes@241
    57
ali@445
    58
#ifndef FALSE
ali@445
    59
#define FALSE 0
ali@445
    60
#endif
ali@445
    61
ali@445
    62
#ifndef TRUE
ali@445
    63
#define TRUE (!FALSE)
ali@445
    64
#endif
ali@445
    65
krh@271
    66
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
krh@271
    67
ali@363
    68
static int
ali@403
    69
update_packages(struct razor_transaction *trans,
ali@403
    70
		struct razor_install_iterator *ii, struct razor_set *system,
ali@403
    71
		struct razor_set *next, struct razor_atomic *atomic,
ali@403
    72
		struct razor_relocations *relocations,
ali@418
    73
		enum razor_stage_type stage);
ali@418
    74
static int
ali@424
    75
update_system(struct razor_root *root, struct razor_relocations *relocations,
ali@424
    76
	      struct razor_transaction *trans, struct razor_set *next,
ali@424
    77
	      const char *verb);
ali@363
    78
ali@445
    79
static int command_help(int argc, char * const argv[]);
ali@445
    80
ali@445
    81
struct razor_option {
ali@445
    82
	char *name;
ali@445
    83
	int has_arg;
ali@445
    84
	int val;
ali@445
    85
	char *description;
ali@445
    86
	char *arg_description;
ali@445
    87
};
ali@445
    88
ali@445
    89
static void
ali@445
    90
razor_usage(const char *command, int n_options, struct razor_option *options,
ali@445
    91
	    const char *parameter_string)
ali@445
    92
{
ali@445
    93
	int i, help_printed = FALSE;
ali@445
    94
	char buf[19];
ali@445
    95
ali@445
    96
	printf("Usage: razor %s [options] %s\n", command, parameter_string);
ali@445
    97
	printf("(Specify the --help global option for a list of other "
ali@445
    98
	       "help options)\n");
ali@445
    99
	printf("\nOptions:\n");
ali@445
   100
ali@445
   101
	for(i = 0; i < n_options; i++) {
ali@445
   102
		if (!help_printed && strcmp(options[i].name, "help") > 0) {
ali@445
   103
			printf("  --help              "
ali@445
   104
			       "Show this help message and exit\n");
ali@445
   105
			help_printed = TRUE;
ali@445
   106
		}
ali@445
   107
ali@445
   108
		if (options[i].has_arg != no_argument)
ali@445
   109
			snprintf(buf, sizeof(buf), "%s=%s", options[i].name,
ali@445
   110
				 options[i].arg_description);
ali@445
   111
		else
ali@445
   112
			strncpy(buf, options[i].name, sizeof(buf));
ali@445
   113
		buf[18] = '\0';
ali@445
   114
ali@445
   115
		printf("  --%-18s%s\n", buf, options[i].description);
ali@445
   116
	}
ali@445
   117
ali@445
   118
	if (!help_printed)
ali@445
   119
		printf("  --help              "
ali@445
   120
		       "Show this help message and exit\n");
ali@445
   121
}
ali@445
   122
ali@445
   123
/**
ali@445
   124
 * razor_getopt:
ali@445
   125
 *
ali@445
   126
 *
ali@445
   127
 * Returns: The next option found or -2 on handled or -1 on error
ali@445
   128
 *          or 0 on end of option list.
ali@445
   129
 **/
ali@445
   130
static int
ali@445
   131
razor_getopt(int argc, char * const argv[], int n_options,
ali@445
   132
	     struct razor_option *options, const char *parameter_string,
ali@445
   133
	     const char **arg)
ali@445
   134
{
ali@445
   135
	int i, opt, do_help = 0, retval;
ali@445
   136
	struct option *longopts;
ali@445
   137
ali@445
   138
	longopts = calloc((n_options + 2), sizeof(*longopts));
ali@445
   139
ali@445
   140
	for(i = 0; i < n_options; i++) {
ali@445
   141
		longopts[i].name = options[i].name;
ali@445
   142
		longopts[i].has_arg = options[i].has_arg;
ali@445
   143
		longopts[i].flag = &retval;
ali@445
   144
		longopts[i].val = options[i].val;
ali@445
   145
	}
ali@445
   146
ali@445
   147
	longopts[i].name = "help";
ali@445
   148
	longopts[i].has_arg = no_argument;
ali@445
   149
	longopts[i].flag = &do_help;
ali@445
   150
	longopts[i].val = TRUE;
ali@445
   151
ali@445
   152
	opterr = 0;
ali@445
   153
ali@475
   154
	opt = getopt_long(argc, (char **)argv, "+", longopts, NULL);
ali@445
   155
ali@445
   156
	switch (opt)
ali@445
   157
	{
ali@445
   158
		case 0:
ali@445
   159
			if (do_help) {
ali@445
   160
				razor_usage(argv[0], n_options, options,
ali@445
   161
					    parameter_string);
ali@445
   162
				retval = -2;
ali@445
   163
			} else if (arg)
ali@445
   164
				*arg = optarg;
ali@445
   165
			break;
ali@445
   166
ali@445
   167
		case -1:
ali@445
   168
			retval = 0;
ali@445
   169
			break;
ali@445
   170
ali@445
   171
		default:
ali@445
   172
			razor_usage(argv[0], n_options, options,
ali@445
   173
				    parameter_string);
ali@445
   174
			retval = -1;
ali@445
   175
	}
ali@445
   176
ali@445
   177
	free(longopts);
ali@445
   178
	return retval;
ali@445
   179
}
ali@445
   180
krh@281
   181
static struct razor_package_iterator *
ali@445
   182
create_iterator_from_argv(struct razor_set *set, int argc, char * const argv[])
rhughes@241
   183
{
krh@281
   184
	struct razor_package_query *query;
krh@281
   185
	struct razor_package_iterator *iter;
rhughes@241
   186
	struct razor_package *package;
richard@302
   187
	const char *name, *pattern;
krh@281
   188
	int i, count;
rhughes@241
   189
krh@281
   190
	if (argc == 0)
krh@281
   191
		return razor_package_iterator_create(set);
krh@281
   192
krh@281
   193
	query = razor_package_query_create(set);
krh@281
   194
krh@281
   195
	for (i = 0; i < argc; i++) {
krh@281
   196
		iter = razor_package_iterator_create(set);
krh@281
   197
		pattern = argv[i];
krh@281
   198
		count = 0;
richard@307
   199
		while (razor_package_iterator_next(iter, &package,
richard@307
   200
						   RAZOR_DETAIL_NAME, &name,
richard@307
   201
						   RAZOR_DETAIL_LAST)) {
krh@281
   202
			if (fnmatch(pattern, name, 0) != 0)
krh@281
   203
				continue;
krh@281
   204
krh@281
   205
			razor_package_query_add_package(query, package);
krh@281
   206
			count++;
krh@281
   207
		}
krh@281
   208
		razor_package_iterator_destroy(iter);
krh@281
   209
krh@281
   210
		if (count == 0)
krh@281
   211
			fprintf(stderr,
krh@281
   212
				"no package matches \"%s\"\n", pattern);
rhughes@241
   213
	}
rhughes@241
   214
krh@281
   215
	return razor_package_query_finish(query);
krh@281
   216
}
krh@281
   217
krh@281
   218
#define LIST_PACKAGES_ONLY_NAMES 0x01
krh@281
   219
krh@281
   220
static void
krh@281
   221
list_packages(struct razor_package_iterator *iter, uint32_t flags)
krh@281
   222
{
krh@281
   223
	struct razor_package *package;
krh@281
   224
	const char *name, *version, *arch;
krh@281
   225
krh@281
   226
	while (razor_package_iterator_next(iter, &package,
richard@302
   227
					   RAZOR_DETAIL_NAME, &name,
richard@302
   228
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   229
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   230
					   RAZOR_DETAIL_LAST)) {
krh@281
   231
		if (flags & LIST_PACKAGES_ONLY_NAMES)
rhughes@241
   232
			printf("%s\n", name);
rhughes@241
   233
		else
rhughes@241
   234
			printf("%s-%s.%s\n", name, version, arch);
rhughes@241
   235
	}
krh@281
   236
}
krh@281
   237
krh@281
   238
static int
ali@445
   239
command_list(int argc, char * const argv[])
krh@281
   240
{
ali@445
   241
	int opt;
krh@281
   242
	struct razor_package_iterator *pi;
ali@424
   243
	struct razor_error *error = NULL;
krh@281
   244
	struct razor_set *set;
krh@281
   245
	uint32_t flags = 0;
ali@445
   246
	enum {
ali@445
   247
		opt_only_names = 1,
ali@445
   248
	};
ali@445
   249
	static struct razor_option options[] = {
ali@445
   250
		{ .name = "only-names", .has_arg = no_argument,
ali@445
   251
		  .val = opt_only_names,
ali@445
   252
		  .description = "Only list package names" },
ali@445
   253
	};
krh@281
   254
ali@445
   255
	do {
ali@445
   256
		opt = razor_getopt(argc, argv, ARRAY_SIZE(options), options,
ali@445
   257
				   "pattern ...", NULL);
ali@445
   258
		switch (opt) {
ali@445
   259
			case -2:
ali@445
   260
				return 0;
ali@445
   261
			case -1:
ali@445
   262
				return 1;
ali@445
   263
			case opt_only_names:
ali@445
   264
				flags |= LIST_PACKAGES_ONLY_NAMES;
ali@445
   265
				break;
ali@445
   266
		}
ali@445
   267
	} while (opt);
krh@281
   268
ali@424
   269
	set = razor_root_open_read_only(install_root, &error);
ali@403
   270
	if (set == NULL) {
ali@424
   271
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   272
		razor_error_free(error);
krh@317
   273
		return 1;
ali@403
   274
	}
krh@317
   275
ali@445
   276
	pi = create_iterator_from_argv(set, argc - optind, argv + optind);
krh@281
   277
	list_packages(pi, flags);
rhughes@241
   278
	razor_package_iterator_destroy(pi);
ali@403
   279
	razor_set_unref(set);
rhughes@241
   280
rhughes@241
   281
	return 0;
rhughes@241
   282
}
rhughes@241
   283
krh@306
   284
static void
krh@306
   285
list_package_properties(struct razor_set *set,
krh@306
   286
			struct razor_package *package, uint32_t type)
rhughes@241
   287
{
krh@306
   288
	struct razor_property_iterator *pi;
rhughes@241
   289
	struct razor_property *property;
rhughes@241
   290
	const char *name, *version;
krh@247
   291
	uint32_t flags;
rhughes@241
   292
rhughes@241
   293
	pi = razor_property_iterator_create(set, package);
rhughes@241
   294
	while (razor_property_iterator_next(pi, &property,
krh@247
   295
					    &name, &flags, &version)) {
krh@247
   296
		if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
rhughes@241
   297
			continue;
krh@247
   298
		printf("%s", name);
krh@247
   299
		if (version[0] != '\0')
krh@247
   300
			printf(" %s %s",
krh@247
   301
			       razor_property_relation_to_string(property),
krh@247
   302
			       version);
krh@247
   303
krh@247
   304
		if (flags & ~(RAZOR_PROPERTY_RELATION_MASK | RAZOR_PROPERTY_TYPE_MASK)) {
krh@247
   305
			printf(" [");
krh@247
   306
			if (flags & RAZOR_PROPERTY_PRE)
krh@247
   307
				printf(" pre");
krh@247
   308
			if (flags & RAZOR_PROPERTY_POST)
krh@247
   309
				printf(" post");
krh@247
   310
			if (flags & RAZOR_PROPERTY_PREUN)
krh@247
   311
				printf(" preun");
krh@247
   312
			if (flags & RAZOR_PROPERTY_POSTUN)
krh@247
   313
				printf(" postun");
krh@247
   314
			printf(" ]");
krh@247
   315
		}
krh@247
   316
		printf("\n");
rhughes@241
   317
	}
rhughes@241
   318
	razor_property_iterator_destroy(pi);
krh@306
   319
}
rhughes@241
   320
krh@306
   321
static int
ali@445
   322
list_properties(int argc, char * const argv[], uint32_t type)
krh@306
   323
{
krh@306
   324
	struct razor_set *set;
ali@424
   325
	struct razor_error *error = NULL;
krh@306
   326
	struct razor_package *package;
krh@306
   327
	struct razor_package_iterator *pi;
krh@306
   328
	const char *name, *version, *arch;
krh@306
   329
ali@445
   330
	switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
ali@445
   331
		case -2:
ali@445
   332
			return 0;
ali@445
   333
		case -1:
ali@445
   334
			return 1;
ali@445
   335
	}
ali@445
   336
ali@424
   337
	set = razor_root_open_read_only(install_root, &error);
ali@403
   338
	if (set == NULL) {
ali@424
   339
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   340
		razor_error_free(error);
krh@317
   341
		return 1;
ali@403
   342
	}
krh@317
   343
ali@445
   344
	pi = create_iterator_from_argv(set, argc - optind, argv + optind);
krh@306
   345
	while (razor_package_iterator_next(pi, &package,
richard@307
   346
					   RAZOR_DETAIL_NAME, &name,
richard@307
   347
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   348
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   349
					   RAZOR_DETAIL_LAST))
krh@306
   350
		list_package_properties(set, package, type);
krh@306
   351
	razor_package_iterator_destroy(pi);
ali@403
   352
	razor_set_unref(set);
rhughes@241
   353
rhughes@241
   354
	return 0;
rhughes@241
   355
}
rhughes@241
   356
rhughes@241
   357
static int
ali@445
   358
command_list_requires(int argc, char * const argv[])
rhughes@241
   359
{
krh@306
   360
	return list_properties(argc, argv, RAZOR_PROPERTY_REQUIRES);
rhughes@241
   361
}
rhughes@241
   362
rhughes@241
   363
static int
ali@445
   364
command_list_provides(int argc, char * const argv[])
rhughes@241
   365
{
krh@306
   366
	return list_properties(argc, argv, RAZOR_PROPERTY_PROVIDES);
rhughes@241
   367
}
rhughes@241
   368
rhughes@241
   369
static int
ali@445
   370
command_list_obsoletes(int argc, char * const argv[])
rhughes@241
   371
{
krh@306
   372
	return list_properties(argc, argv, RAZOR_PROPERTY_OBSOLETES);
rhughes@241
   373
}
rhughes@241
   374
rhughes@241
   375
static int
ali@445
   376
command_list_conflicts(int argc, char * const argv[])
rhughes@241
   377
{
krh@306
   378
	return list_properties(argc, argv, RAZOR_PROPERTY_CONFLICTS);
rhughes@241
   379
}
rhughes@241
   380
rhughes@241
   381
static int
ali@445
   382
command_list_scripts(int argc, char * const argv[])
ali@369
   383
{
ali@369
   384
	struct razor_set *set;
ali@424
   385
	struct razor_error *error = NULL;
ali@369
   386
	struct razor_package *package;
ali@369
   387
	struct razor_package_iterator *pi;
ali@369
   388
	const char *preunprog, *preun, *postunprog, *postun;
ali@369
   389
ali@445
   390
	switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
ali@445
   391
		case -2:
ali@445
   392
			return 0;
ali@445
   393
		case -1:
ali@445
   394
			return 1;
ali@445
   395
	}
ali@445
   396
ali@424
   397
	set = razor_root_open_read_only(install_root, &error);
ali@403
   398
	if (set == NULL) {
ali@424
   399
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   400
		razor_error_free(error);
ali@369
   401
		return 1;
ali@403
   402
	}
ali@369
   403
ali@445
   404
	pi = create_iterator_from_argv(set, argc - optind, argv + optind);
ali@369
   405
	while (razor_package_iterator_next(pi, &package,
ali@369
   406
					   RAZOR_DETAIL_PREUNPROG, &preunprog,
ali@369
   407
					   RAZOR_DETAIL_PREUN, &preun,
ali@369
   408
					   RAZOR_DETAIL_POSTUNPROG, &postunprog,
ali@369
   409
					   RAZOR_DETAIL_POSTUN, &postun,
ali@369
   410
					   RAZOR_DETAIL_LAST)) {
ali@369
   411
		if (preun && *preun) {
ali@369
   412
			printf("preuninstall scriptlet");
ali@369
   413
			if (preunprog && *preunprog)
ali@369
   414
				printf(" (using %s)",preunprog);
ali@369
   415
			printf(":\n%s\n",preun);
ali@369
   416
		}
ali@369
   417
		if (postun && *postun) {
ali@369
   418
			printf("postuninstall scriptlet");
ali@369
   419
			if (postunprog && *postunprog)
ali@369
   420
				printf(" (using %s)",postunprog);
ali@369
   421
			printf(":\n%s\n",postun);
ali@369
   422
		}
ali@369
   423
	}
ali@369
   424
	razor_package_iterator_destroy(pi);
ali@403
   425
	razor_set_unref(set);
ali@369
   426
ali@369
   427
	return 0;
ali@369
   428
}
ali@369
   429
ali@369
   430
static int
ali@445
   431
command_list_files(int argc, char * const argv[])
rhughes@241
   432
{
ali@424
   433
	struct razor_error *error = NULL;
rhughes@241
   434
	struct razor_set *set;
rhughes@241
   435
ali@445
   436
	switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
ali@445
   437
		case -2:
ali@445
   438
			return 0;
ali@445
   439
		case -1:
ali@445
   440
			return 1;
ali@445
   441
	}
ali@445
   442
ali@445
   443
	if (argc - optind > 1) {
ali@445
   444
		razor_usage(argv[0], 0, NULL, "[pattern]");
ali@445
   445
		return 1;
ali@445
   446
	}
ali@445
   447
ali@424
   448
	set = razor_root_open_read_only(install_root, &error);
ali@403
   449
	if (set == NULL) {
ali@424
   450
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   451
		razor_error_free(error);
rhughes@241
   452
		return 1;
ali@403
   453
	}
krh@317
   454
ali@445
   455
	razor_set_list_files(set, argv[optind]);
ali@403
   456
	razor_set_unref(set);
rhughes@241
   457
rhughes@241
   458
	return 0;
rhughes@241
   459
}
rhughes@241
   460
rhughes@241
   461
static int
ali@445
   462
command_list_file_packages(int argc, char * const argv[])
rhughes@241
   463
{
ali@424
   464
	struct razor_error *error = NULL;
rhughes@241
   465
	struct razor_set *set;
rhughes@241
   466
	struct razor_package_iterator *pi;
rhughes@241
   467
ali@445
   468
	switch (razor_getopt(argc, argv, 0, NULL, "pattern", NULL)) {
ali@445
   469
		case -2:
ali@445
   470
			return 0;
ali@445
   471
		case -1:
ali@445
   472
			return 1;
ali@445
   473
	}
ali@445
   474
ali@445
   475
	if (argc - optind != 1) {
ali@445
   476
		razor_usage(argv[0], 0, NULL, "pattern");
ali@445
   477
		return 1;
ali@445
   478
	}
ali@445
   479
ali@424
   480
	set = razor_root_open_read_only(install_root, &error);
ali@403
   481
	if (set == NULL) {
ali@424
   482
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   483
		razor_error_free(error);
rhughes@241
   484
		return 1;
ali@403
   485
	}
rhughes@241
   486
ali@445
   487
	pi = razor_package_iterator_create_for_file(set, argv[optind]);
krh@281
   488
	list_packages(pi, 0);
rhughes@241
   489
	razor_package_iterator_destroy(pi);
rhughes@241
   490
ali@403
   491
	razor_set_unref(set);
rhughes@241
   492
rhughes@241
   493
	return 0;
rhughes@241
   494
}
rhughes@241
   495
rhughes@241
   496
static int
ali@445
   497
command_list_package_files(int argc, char * const argv[])
rhughes@241
   498
{
ali@424
   499
	struct razor_error *error = NULL;
rhughes@241
   500
	struct razor_set *set;
krh@306
   501
	struct razor_package_iterator *pi;
krh@306
   502
	struct razor_package *package;
krh@306
   503
	const char *name, *version, *arch;
rhughes@241
   504
ali@445
   505
	switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
ali@445
   506
		case -2:
ali@445
   507
			return 0;
ali@445
   508
		case -1:
ali@445
   509
			return 1;
ali@445
   510
	}
ali@445
   511
ali@424
   512
	set = razor_root_open_read_only(install_root, &error);
ali@403
   513
	if (set == NULL) {
ali@424
   514
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   515
		razor_error_free(error);
rhughes@241
   516
		return 1;
ali@403
   517
	}
jbowes@288
   518
ali@445
   519
	pi = create_iterator_from_argv(set, argc - optind, argv + optind);
krh@306
   520
	while (razor_package_iterator_next(pi, &package,
richard@307
   521
					   RAZOR_DETAIL_NAME, &name,
richard@307
   522
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   523
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   524
					   RAZOR_DETAIL_LAST))
krh@306
   525
		razor_set_list_package_files(set, package);
krh@306
   526
	razor_package_iterator_destroy(pi);
krh@306
   527
ali@403
   528
	razor_set_unref(set);
rhughes@241
   529
rhughes@241
   530
	return 0;
rhughes@241
   531
}
rhughes@241
   532
rhughes@241
   533
static int
rhughes@241
   534
list_property_packages(const char *ref_name,
rhughes@241
   535
		       const char *ref_version,
krh@247
   536
		       uint32_t type)
rhughes@241
   537
{
ali@424
   538
	struct razor_error *error = NULL;
rhughes@241
   539
	struct razor_set *set;
rhughes@241
   540
	struct razor_property *property;
krh@281
   541
	struct razor_property_iterator *prop_iter;
krh@281
   542
	struct razor_package_iterator *pkg_iter;
rhughes@241
   543
	const char *name, *version;
krh@247
   544
	uint32_t flags;
rhughes@241
   545
ali@424
   546
	set = razor_root_open_read_only(install_root, &error);
ali@403
   547
	if (set == NULL) {
ali@424
   548
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   549
		razor_error_free(error);
rhughes@241
   550
		return 1;
ali@403
   551
	}
rhughes@241
   552
krh@281
   553
	prop_iter = razor_property_iterator_create(set, NULL);
krh@281
   554
	while (razor_property_iterator_next(prop_iter, &property,
krh@247
   555
					    &name, &flags, &version)) {
rhughes@241
   556
		if (strcmp(ref_name, name) != 0)
rhughes@241
   557
			continue;
krh@247
   558
		if (ref_version &&
krh@247
   559
		    (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
rhughes@241
   560
		    strcmp(ref_version, version) != 0)
rhughes@241
   561
			continue;
krh@247
   562
		if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
rhughes@241
   563
			continue;
rhughes@241
   564
krh@281
   565
		pkg_iter =
krh@281
   566
			razor_package_iterator_create_for_property(set,
krh@281
   567
								   property);
krh@281
   568
		list_packages(pkg_iter, 0);
krh@281
   569
		razor_package_iterator_destroy(pkg_iter);
rhughes@241
   570
	}
krh@281
   571
	razor_property_iterator_destroy(prop_iter);
rhughes@241
   572
ali@403
   573
	razor_set_unref(set);
krh@317
   574
rhughes@241
   575
	return 0;
rhughes@241
   576
}
rhughes@241
   577
rhughes@241
   578
static int
ali@445
   579
command_what_requires(int argc, char * const argv[])
rhughes@241
   580
{
ali@445
   581
	switch (razor_getopt(argc, argv, 0, NULL, "name [version-release]",
ali@445
   582
			     NULL)) {
ali@445
   583
		case -2:
ali@445
   584
			return 0;
ali@445
   585
		case -1:
ali@445
   586
			return 1;
ali@445
   587
	}
ali@445
   588
ali@445
   589
	if (argc - optind < 1 || argc - optind > 2) {
ali@445
   590
		razor_usage(argv[0], 0, NULL, "name [version-release]");
ali@445
   591
		return 1;
ali@445
   592
	}
ali@445
   593
ali@445
   594
	return list_property_packages(argv[optind], argv[optind + 1],
rhughes@241
   595
				      RAZOR_PROPERTY_REQUIRES);
rhughes@241
   596
}
rhughes@241
   597
rhughes@241
   598
static int
ali@445
   599
command_what_provides(int argc, char * const argv[])
rhughes@241
   600
{
ali@445
   601
	switch (razor_getopt(argc, argv, 0, NULL, "name [version-release]",
ali@445
   602
			     NULL)) {
ali@445
   603
		case -2:
ali@445
   604
			return 0;
ali@445
   605
		case -1:
ali@445
   606
			return 1;
ali@445
   607
	}
ali@445
   608
ali@445
   609
	if (argc - optind < 1 || argc - optind > 2) {
ali@445
   610
		razor_usage(argv[0], 0, NULL, "name [version-release]");
ali@445
   611
		return 1;
ali@445
   612
	}
ali@445
   613
ali@445
   614
	return list_property_packages(argv[optind], argv[optind + 1],
rhughes@241
   615
				      RAZOR_PROPERTY_PROVIDES);
rhughes@241
   616
}
rhughes@241
   617
ali@476
   618
#ifdef HAVE_CURL
ali@476
   619
struct get_contents_with_curl_baton {
ali@476
   620
	void *buf;
ali@476
   621
	size_t buflen;
ali@476
   622
};
ali@476
   623
ali@476
   624
static size_t
ali@476
   625
get_contents_with_curl_callback(void *contents, size_t size, size_t nmemb,
ali@476
   626
				void *data)
ali@455
   627
{
ali@476
   628
	size_t nb = size * nmemb;
ali@476
   629
	struct get_contents_with_curl_baton *baton = data;
ali@455
   630
ali@476
   631
	baton->buf = realloc(baton->buf, baton->buflen + nb);
ali@476
   632
	if (!baton->buf) {
ali@476
   633
		fprintf(stderr, "Not enough memory to read file\n");
ali@455
   634
		return 0;
ali@455
   635
	}
ali@476
   636
			 
ali@476
   637
	memcpy((char *)baton->buf + baton->buflen, contents, nb);
ali@476
   638
	baton->buflen += nb;
ali@476
   639
ali@476
   640
	return nb;
ali@455
   641
}
ali@455
   642
ali@476
   643
static void *get_contents_with_curl(const char *uri, size_t *length,
ali@476
   644
				    int private, struct razor_error **error)
ali@476
   645
{
ali@476
   646
	CURL *curl;
ali@476
   647
	char errbuf[256];
ali@476
   648
	CURLcode res;
ali@476
   649
	struct get_contents_with_curl_baton baton = {0,};
ali@476
   650
ali@476
   651
	curl = curl_easy_init();
ali@476
   652
	if (!curl) {
ali@476
   653
		razor_set_error(error, RAZOR_GENERAL_ERROR,
ali@476
   654
				RAZOR_GENERAL_ERROR_FAILED, uri,
ali@476
   655
				"Failed to initialize libcurl");
ali@476
   656
		return NULL;
ali@476
   657
	}
ali@476
   658
ali@476
   659
	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
ali@476
   660
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
ali@476
   661
			 get_contents_with_curl_callback);
ali@476
   662
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&baton);
ali@476
   663
	curl_easy_setopt(curl, CURLOPT_URL, uri);
ali@476
   664
	curl_easy_setopt(curl, CURLOPT_USERAGENT, "razor/" VERSION);
ali@476
   665
	res = curl_easy_perform(curl);
ali@476
   666
	curl_easy_cleanup(curl);
ali@476
   667
ali@476
   668
	if (res != CURLE_OK) {
ali@476
   669
		razor_set_error(error, RAZOR_GENERAL_ERROR,
ali@476
   670
				RAZOR_GENERAL_ERROR_FAILED, uri, errbuf);
ali@476
   671
		free(baton.buf);
ali@476
   672
		return NULL;
ali@476
   673
	}
ali@476
   674
ali@476
   675
	*length = baton.buflen;
ali@476
   676
	return baton.buf;
ali@476
   677
}
ali@476
   678
ali@476
   679
int free_contents_with_curl(void *addr, size_t length)
ali@476
   680
{
ali@476
   681
	free(addr);
ali@476
   682
}
ali@476
   683
#endif
ali@476
   684
ali@489
   685
static void init_uri_handler(void)
ali@476
   686
{
ali@442
   687
#ifdef HAVE_CURL
ali@476
   688
	struct razor_uri_vtable uri_vtable={0,};
ali@476
   689
	uri_vtable.structure_size=sizeof(uri_vtable);
ali@476
   690
	uri_vtable.get_contents=get_contents_with_curl;
ali@476
   691
	uri_vtable.free_contents=free_contents_with_curl;
ali@476
   692
	razor_uri_set_vtable(NULL, &uri_vtable, NULL);
ali@476
   693
#endif
rhughes@241
   694
}
rhughes@241
   695
rhughes@241
   696
static int
ali@476
   697
download_if_missing(const char *uri, const char *file)
rhughes@241
   698
{
ali@476
   699
	int retval = 0;
ali@476
   700
	struct stat buf;
ali@476
   701
	void *contents;
ali@476
   702
	size_t length;
ali@476
   703
	struct razor_error *error = NULL;
ali@455
   704
	FILE *fp;
ali@455
   705
ali@455
   706
	if (stat(file, &buf) >= 0)
ali@455
   707
		return 0;
ali@455
   708
ali@476
   709
	contents = razor_uri_get_contents(uri, &length, 0, &error);
ali@476
   710
ali@476
   711
	if (!contents) {
ali@476
   712
		fprintf(stderr, "%s: %s\n", uri, razor_error_get_msg(error));
ali@476
   713
		razor_error_free(error);
ali@476
   714
		return -1;
ali@476
   715
	}
ali@476
   716
ali@476
   717
	fp = fopen(file, "wb");
ali@476
   718
	if (!fp) {
ali@476
   719
		perror(file);
ali@476
   720
		razor_uri_free_contents(contents, length);
ali@476
   721
		return -1;
ali@476
   722
	}
ali@476
   723
ali@476
   724
	if (fwrite(contents, 1, length, fp) != length) {
ali@476
   725
		perror(file);
ali@476
   726
		retval = -1;
ali@476
   727
	}
ali@476
   728
ali@476
   729
	fclose(fp);
ali@476
   730
	razor_uri_free_contents(contents, length);
ali@476
   731
ali@476
   732
	return retval;
rhughes@241
   733
}
rhughes@241
   734
rhughes@241
   735
#define YUM_URL "http://download.fedora.redhat.com" \
rhughes@241
   736
	"/pub/fedora/linux/development/i386/os"
rhughes@241
   737
rhughes@241
   738
static int
ali@445
   739
command_import_yum(int argc, char * const argv[])
rhughes@241
   740
{
ali@403
   741
	int retval;
rhughes@241
   742
	struct razor_set *set;
ali@403
   743
	struct razor_atomic *atomic;
rhughes@241
   744
ali@445
   745
	switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
ali@445
   746
		case -2:
ali@445
   747
			return 0;
ali@445
   748
		case -1:
ali@445
   749
			return 1;
ali@445
   750
	}
ali@445
   751
ali@445
   752
	if (argc - optind > 0) {
ali@445
   753
		razor_usage(argv[0], 0, NULL, "");
ali@445
   754
		return 1;
ali@445
   755
	}
ali@445
   756
ali@476
   757
	printf("importing from '%s'.\n", yum_url);
rhughes@241
   758
ali@476
   759
	set = razor_set_create_from_yum(yum_url);
rhughes@241
   760
	if (set == NULL)
rhughes@241
   761
		return 1;
ali@403
   762
	atomic = razor_atomic_open("Yum import repository");
ali@475
   763
	razor_set_write(set, atomic, rawhide_repo_uri, RAZOR_SECTION_ALL);
ali@403
   764
	retval = razor_atomic_commit(atomic);
ali@403
   765
	razor_set_unref(set);
ali@403
   766
	if (retval)
ali@403
   767
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   768
	else
ali@475
   769
		printf("wrote %s\n", rawhide_repo_uri);
ali@403
   770
	razor_atomic_destroy(atomic);
rhughes@241
   771
ali@403
   772
	return retval;
rhughes@241
   773
}
rhughes@241
   774
ali@320
   775
#if HAVE_RPMLIB
rhughes@241
   776
static int
ali@445
   777
command_import_rpmdb(int argc, char * const argv[])
rhughes@241
   778
{
rhughes@241
   779
	struct razor_set *set;
krh@317
   780
	struct razor_root *root;
ali@424
   781
	struct razor_error *error = NULL;
ali@403
   782
	struct razor_atomic *atomic;
ali@403
   783
	int retval;
krh@317
   784
ali@445
   785
	switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
ali@445
   786
		case -2:
ali@445
   787
			return 0;
ali@445
   788
		case -1:
ali@445
   789
			return 1;
ali@445
   790
	}
ali@445
   791
ali@445
   792
	if (argc - optind > 0) {
ali@445
   793
		razor_usage(argv[0], 0, NULL, "");
ali@445
   794
		return 1;
ali@445
   795
	}
ali@445
   796
ali@424
   797
	root = razor_root_open(install_root, &error);
ali@403
   798
	if (root == NULL) {
ali@424
   799
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   800
		razor_error_free(error);
krh@317
   801
		return 1;
ali@403
   802
	}
rhughes@241
   803
rhughes@241
   804
	set = razor_set_create_from_rpmdb();
rhughes@241
   805
	if (set == NULL)
rhughes@241
   806
		return 1;
rhughes@241
   807
ali@424
   808
	atomic = razor_atomic_open("Import RPM database");
krh@317
   809
ali@424
   810
	retval = razor_root_update(root, set, atomic);
ali@424
   811
ali@403
   812
	if (retval)
ali@403
   813
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
   814
ali@403
   815
	razor_atomic_destroy(atomic);
ali@403
   816
ali@424
   817
	razor_root_close(root);
ali@424
   818
ali@403
   819
	return retval;
rhughes@241
   820
}
ali@320
   821
#endif
rhughes@241
   822
rhughes@241
   823
static int
rhughes@241
   824
mark_packages_for_update(struct razor_transaction *trans,
rhughes@241
   825
			 struct razor_set *set, const char *pattern)
rhughes@241
   826
{
rhughes@241
   827
	struct razor_package_iterator *pi;
rhughes@241
   828
	struct razor_package *package;
richard@302
   829
	const char *name;
rhughes@241
   830
	int matches = 0;
rhughes@241
   831
rhughes@241
   832
	pi = razor_package_iterator_create(set);
rhughes@241
   833
	while (razor_package_iterator_next(pi, &package,
richard@307
   834
					   RAZOR_DETAIL_NAME, &name,
richard@307
   835
					   RAZOR_DETAIL_LAST)) {
rhughes@241
   836
		if (pattern && fnmatch(pattern, name, 0) == 0) {
rhughes@241
   837
			razor_transaction_update_package(trans, package);
rhughes@241
   838
			matches++;
rhughes@241
   839
		}
rhughes@241
   840
	}
rhughes@241
   841
	razor_package_iterator_destroy(pi);
rhughes@241
   842
rhughes@241
   843
	return matches;
rhughes@241
   844
}
rhughes@241
   845
rhughes@241
   846
static int
rhughes@241
   847
mark_packages_for_removal(struct razor_transaction *trans,
rhughes@241
   848
			  struct razor_set *set, const char *pattern)
rhughes@241
   849
{
rhughes@241
   850
	struct razor_package_iterator *pi;
rhughes@241
   851
	struct razor_package *package;
richard@302
   852
	const char *name;
rhughes@241
   853
	int matches = 0;
rhughes@241
   854
rhughes@241
   855
	pi = razor_package_iterator_create(set);
richard@307
   856
	while (razor_package_iterator_next(pi, &package,
richard@307
   857
					   RAZOR_DETAIL_NAME, &name,
richard@307
   858
					   RAZOR_DETAIL_LAST)) {
rhughes@241
   859
		if (pattern && fnmatch(pattern, name, 0) == 0) {
rhughes@241
   860
			razor_transaction_remove_package(trans, package);
rhughes@241
   861
			matches++;
rhughes@241
   862
		}
rhughes@241
   863
	}
rhughes@241
   864
	razor_package_iterator_destroy(pi);
rhughes@241
   865
rhughes@241
   866
	return matches;
rhughes@241
   867
}
rhughes@241
   868
rhughes@241
   869
static int
ali@445
   870
command_remove(int argc, char * const argv[])
rhughes@241
   871
{
ali@363
   872
	struct razor_set *system, *upstream, *next;
rhughes@241
   873
	struct razor_transaction *trans;
ali@424
   874
	struct razor_error *error = NULL;
ali@424
   875
	struct razor_root *root;
ali@403
   876
	int i, retval;
rhughes@241
   877
ali@445
   878
	switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
ali@445
   879
		case -2:
ali@445
   880
			return 0;
ali@445
   881
		case -1:
ali@445
   882
			return 1;
ali@445
   883
	}
ali@445
   884
ali@424
   885
	root = razor_root_open(install_root, &error);
ali@424
   886
	if (root == NULL) {
ali@424
   887
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   888
		razor_error_free(error);
rhughes@241
   889
		return 1;
ali@363
   890
	}
rhughes@241
   891
ali@424
   892
	system = razor_root_get_system_set(root);
ali@363
   893
	upstream = razor_set_create_without_root();
ali@363
   894
	trans = razor_transaction_create(system, upstream);
ali@403
   895
	razor_set_unref(upstream);
ali@445
   896
	for (i = optind; i < argc; i++) {
ali@363
   897
		if (mark_packages_for_removal(trans, system, argv[i]) == 0) {
rhughes@241
   898
			fprintf(stderr, "no match for %s\n", argv[i]);
ali@363
   899
			razor_transaction_destroy(trans);
ali@424
   900
			razor_root_close(root);
rhughes@241
   901
			return 1;
rhughes@241
   902
		}
rhughes@241
   903
	}
rhughes@241
   904
ali@350
   905
	razor_transaction_resolve(trans);
ali@403
   906
	retval = razor_transaction_describe(trans);
ali@403
   907
	if (retval) {
ali@363
   908
		razor_transaction_destroy(trans);
ali@424
   909
		razor_root_close(root);
rhughes@241
   910
		return 1;
ali@363
   911
	}
rhughes@241
   912
ali@369
   913
	next = razor_transaction_commit(trans);
ali@403
   914
ali@424
   915
	retval = update_system(root, NULL, trans, next, "Remove");
ali@363
   916
ali@369
   917
	razor_transaction_destroy(trans);
ali@424
   918
	razor_root_close(root);
ali@403
   919
	razor_set_unref(next);
rhughes@241
   920
ali@403
   921
	return retval;
rhughes@241
   922
}
rhughes@241
   923
rhughes@241
   924
static void
krh@253
   925
print_diff(enum razor_diff_action action,
krh@253
   926
	   struct razor_package *package,
krh@253
   927
	   const char *name,
krh@253
   928
	   const char *version,
krh@253
   929
	   const char *arch,
rhughes@241
   930
	   void *data)
rhughes@241
   931
{
krh@253
   932
	if (action == RAZOR_DIFF_ACTION_ADD)
krh@253
   933
		printf("install %s-%s.%s\n", name, version, arch);
krh@253
   934
	if (action == RAZOR_DIFF_ACTION_REMOVE)
krh@253
   935
		printf("remove %s-%s.%s\n", name, version, arch);
rhughes@241
   936
}
rhughes@241
   937
rhughes@241
   938
static int
ali@445
   939
command_diff(int argc, char * const argv[])
rhughes@241
   940
{
ali@424
   941
	struct razor_error *error = NULL;
rhughes@241
   942
	struct razor_set *set, *updated;
rhughes@241
   943
ali@445
   944
	switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
ali@445
   945
		case -2:
ali@445
   946
			return 0;
ali@445
   947
		case -1:
ali@445
   948
			return 1;
ali@445
   949
	}
ali@445
   950
ali@445
   951
	if (argc - optind > 0) {
ali@445
   952
		razor_usage(argv[0], 0, NULL, "");
ali@445
   953
		return 1;
ali@445
   954
	}
ali@445
   955
ali@424
   956
	set = razor_root_open_read_only(install_root, &error);
ali@424
   957
	if (set)
ali@475
   958
		updated = razor_set_open(rawhide_repo_uri, 0, &error);
ali@424
   959
	else
ali@424
   960
		updated = NULL;
ali@424
   961
	if (updated == NULL) {
ali@424
   962
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
   963
		razor_error_free(error);
ali@424
   964
		if (set)
ali@424
   965
			razor_set_unref(set);
rhughes@241
   966
		return 1;
ali@403
   967
	}
rhughes@241
   968
rhughes@241
   969
	razor_set_diff(set, updated, print_diff, NULL);
rhughes@241
   970
ali@403
   971
	razor_set_unref(set);
ali@403
   972
	razor_set_unref(updated);
rhughes@241
   973
rhughes@241
   974
	return 0;
rhughes@241
   975
}
rhughes@241
   976
rhughes@241
   977
static int
ali@445
   978
command_import_rpms(int argc, char * const argv[])
rhughes@241
   979
{
rhughes@241
   980
	DIR *dir;
rhughes@241
   981
	struct dirent *de;
rhughes@241
   982
	struct razor_importer *importer;
rhughes@241
   983
	struct razor_set *set;
rhughes@241
   984
	struct razor_rpm *rpm;
ali@426
   985
	struct razor_error *error=NULL;
ali@403
   986
	struct razor_atomic *atomic;
jbowes@263
   987
	int len, imported_count = 0;
rhughes@241
   988
	char filename[256];
ali@445
   989
	const char *dirname;
ali@403
   990
	int retval;
rhughes@241
   991
ali@445
   992
	switch (razor_getopt(argc, argv, 0, NULL, "dir", NULL)) {
ali@445
   993
		case -2:
ali@445
   994
			return 0;
ali@445
   995
		case -1:
ali@445
   996
			return 1;
rhughes@241
   997
	}
rhughes@241
   998
ali@445
   999
	if (argc - optind != 1) {
ali@445
  1000
		razor_usage(argv[0], 0, NULL, "dir");
ali@445
  1001
		return 1;
ali@445
  1002
	}
ali@445
  1003
ali@445
  1004
	dirname = argv[optind];
ali@445
  1005
rhughes@241
  1006
	dir = opendir(dirname);
rhughes@241
  1007
	if (dir == NULL) {
rhughes@241
  1008
		fprintf(stderr, "couldn't read dir %s\n", dirname);
rhughes@241
  1009
		return -1;
rhughes@241
  1010
	}
rhughes@241
  1011
krh@249
  1012
	importer = razor_importer_create();
rhughes@241
  1013
rhughes@241
  1014
	while (de = readdir(dir), de != NULL) {
rhughes@241
  1015
		len = strlen(de->d_name);
rhughes@241
  1016
		if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
ali@403
  1017
			continue;
rhughes@241
  1018
		snprintf(filename, sizeof filename,
rhughes@241
  1019
			 "%s/%s", dirname, de->d_name);
ali@426
  1020
		rpm = razor_rpm_open(filename, &error);
ali@426
  1021
		if (rpm == NULL) {
ali@426
  1022
			fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@426
  1023
			razor_error_free(error);
ali@426
  1024
			error=NULL;
rhughes@241
  1025
			continue;
ali@426
  1026
		}
rhughes@241
  1027
		if (razor_importer_add_rpm(importer, rpm)) {
rhughes@241
  1028
			fprintf(stderr, "couldn't import %s\n", filename);
rhughes@241
  1029
			break;
rhughes@241
  1030
		}
rhughes@241
  1031
		razor_rpm_close(rpm);
jbowes@263
  1032
jbowes@263
  1033
		printf("\rimporting %d", ++imported_count);
jbowes@263
  1034
		fflush(stdout);
rhughes@241
  1035
	}
rhughes@241
  1036
rhughes@241
  1037
	if (de != NULL) {
rhughes@241
  1038
		razor_importer_destroy(importer);
rhughes@241
  1039
		return -1;
rhughes@241
  1040
	}
rhughes@241
  1041
jbowes@263
  1042
	printf("\nsaving\n");
rhughes@241
  1043
	set = razor_importer_finish(importer);
rhughes@241
  1044
ali@403
  1045
	atomic = razor_atomic_open("Update system database");
ali@403
  1046
	razor_set_write(set, atomic, repo_filename, RAZOR_SECTION_ALL);
ali@403
  1047
	razor_set_unref(set);
ali@403
  1048
	retval = razor_atomic_commit(atomic);
ali@403
  1049
	if (retval)
ali@403
  1050
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
  1051
	else
ali@403
  1052
		printf("wrote %s\n", repo_filename);
ali@403
  1053
	razor_atomic_destroy(atomic);
rhughes@241
  1054
ali@403
  1055
	return retval;
rhughes@241
  1056
}
rhughes@241
  1057
ali@403
  1058
static char *
krh@254
  1059
rpm_filename(const char *name, const char *version, const char *arch)
rhughes@241
  1060
{
krh@254
  1061
 	const char *v;
krh@254
  1062
 
krh@254
  1063
 	/* Skip epoch */
krh@253
  1064
	v = strchr(version, ':');
krh@254
  1065
 	if (v != NULL)
krh@254
  1066
 		v = v + 1;
krh@254
  1067
 	else
krh@253
  1068
		v = version;
rhughes@241
  1069
ali@403
  1070
	return razor_concat(name, "-", v, ".", arch, ".rpm", NULL);
rhughes@241
  1071
}
rhughes@241
  1072
ali@351
  1073
static struct razor_set *
ali@403
  1074
relocate_packages(struct razor_set *set, struct razor_atomic *atomic,
ali@403
  1075
		  struct razor_relocations *relocations)
ali@351
  1076
{
ali@372
  1077
	int i;
ali@351
  1078
	struct razor_importer *importer;
ali@351
  1079
	struct razor_property_iterator *prop_iter;
ali@351
  1080
	struct razor_package_iterator *pkg_iter;
ali@351
  1081
 	struct razor_file_iterator *file_iter;
ali@351
  1082
 	struct razor_package *package;
ali@351
  1083
	struct razor_property *property;
ali@351
  1084
	struct razor_rpm *rpm;
ali@426
  1085
	struct razor_error *error=NULL;
ali@351
  1086
	const char *name, *version, *arch, *summary, *desc, *url, *license;
ali@369
  1087
	const char *preunprog, *preun, *postunprog, *postun;
ali@372
  1088
	const char *install_prefix;
ali@372
  1089
	const char *const *prefixes;
ali@489
  1090
	char *s, *uri, *filename;
ali@351
  1091
	uint32_t flags;
ali@351
  1092
ali@351
  1093
	importer = razor_importer_create();
ali@351
  1094
	pkg_iter = razor_package_iterator_create(set);
ali@351
  1095
ali@351
  1096
	while (razor_package_iterator_next(pkg_iter, &package,
ali@351
  1097
					   RAZOR_DETAIL_NAME, &name,
ali@351
  1098
					   RAZOR_DETAIL_VERSION, &version,
ali@351
  1099
					   RAZOR_DETAIL_ARCH, &arch,
ali@351
  1100
					   RAZOR_DETAIL_SUMMARY, &summary,
ali@351
  1101
					   RAZOR_DETAIL_DESCRIPTION, &desc,
ali@351
  1102
					   RAZOR_DETAIL_URL, &url,
ali@351
  1103
					   RAZOR_DETAIL_LICENSE, &license,
ali@369
  1104
					   RAZOR_DETAIL_PREUNPROG, &preunprog,
ali@369
  1105
					   RAZOR_DETAIL_PREUN, &preun,
ali@369
  1106
					   RAZOR_DETAIL_POSTUNPROG, &postunprog,
ali@369
  1107
					   RAZOR_DETAIL_POSTUN, &postun,
ali@351
  1108
					   RAZOR_DETAIL_LAST)) {
ali@475
  1109
		filename = rpm_filename(name, version, arch);
ali@475
  1110
		s = razor_concat("Packages/", filename, NULL);
ali@475
  1111
		uri = razor_path_relative_to_uri(yum_url, s, NULL);
ali@403
  1112
		free(s);
ali@475
  1113
		free(filename);
ali@475
  1114
		rpm = razor_rpm_open(uri, &error);
ali@475
  1115
		free(uri);
ali@351
  1116
		if (rpm == NULL) {
ali@447
  1117
			razor_atomic_propagate_error(atomic, error, NULL);
ali@351
  1118
			razor_package_iterator_destroy(pkg_iter);
ali@351
  1119
			razor_importer_destroy(importer);
ali@351
  1120
			return NULL;
ali@351
  1121
		}
ali@351
  1122
ali@351
  1123
		razor_relocations_set_rpm(relocations, rpm);
ali@351
  1124
ali@351
  1125
		razor_importer_begin_package(importer, name, version, arch);
ali@351
  1126
		razor_importer_add_details(importer,
ali@351
  1127
					   summary, desc, url, license);
ali@351
  1128
ali@372
  1129
		razor_rpm_get_details(rpm, RAZOR_DETAIL_PREFIXES, &prefixes,
ali@372
  1130
				      RAZOR_DETAIL_LAST);
ali@372
  1131
		for (i = 0; prefixes && prefixes[i]; i++) {
ali@372
  1132
			install_prefix = razor_relocations_apply(relocations,
ali@372
  1133
								 prefixes[i]);
ali@372
  1134
			razor_importer_add_install_prefix(importer,
ali@372
  1135
							  install_prefix);
ali@372
  1136
		}
ali@372
  1137
ali@372
  1138
		razor_rpm_close(rpm);
ali@372
  1139
ali@351
  1140
		prop_iter = razor_property_iterator_create(set, package);
ali@351
  1141
		while (razor_property_iterator_next(prop_iter, &property,
ali@351
  1142
						    &name, &flags, &version))
ali@351
  1143
			razor_importer_add_property(importer,
ali@351
  1144
						    name, flags, version);
ali@351
  1145
		razor_property_iterator_destroy(prop_iter);
ali@351
  1146
ali@377
  1147
		file_iter = razor_file_iterator_create(set, package, 0);
ali@351
  1148
		while (razor_file_iterator_next(file_iter, &name)) {
ali@351
  1149
			name = razor_relocations_apply(relocations, name);
ali@351
  1150
			razor_importer_add_file(importer, name);
ali@351
  1151
		}
ali@351
  1152
		razor_file_iterator_destroy(file_iter);
ali@351
  1153
ali@369
  1154
		razor_importer_add_script(importer, RAZOR_PROPERTY_PREUN,
ali@369
  1155
					  preunprog, preun);
ali@369
  1156
		razor_importer_add_script(importer, RAZOR_PROPERTY_POSTUN,
ali@369
  1157
					  postunprog, postun);
ali@369
  1158
ali@351
  1159
		razor_importer_finish_package(importer);
ali@351
  1160
	}
ali@351
  1161
ali@351
  1162
	razor_package_iterator_destroy(pkg_iter);
ali@351
  1163
	return razor_importer_finish(importer);
ali@351
  1164
}
ali@351
  1165
krh@254
  1166
static int
ali@369
  1167
install_package(struct razor_transaction *trans, struct razor_set *set,
ali@403
  1168
		struct razor_atomic *atomic, struct razor_package *package,
ali@403
  1169
		struct razor_relocations *relocations, int install_count,
ali@403
  1170
		enum razor_stage_type stage)
ali@363
  1171
{
ali@363
  1172
	int retval;
ali@363
  1173
	const char *name, *version, *arch;
ali@475
  1174
	char *file, *s, *uri;
ali@363
  1175
	struct razor_rpm *rpm;
ali@426
  1176
	struct razor_error *error=NULL;
ali@363
  1177
ali@363
  1178
	razor_package_get_details(set, package,
ali@363
  1179
				  RAZOR_DETAIL_NAME, &name,
ali@363
  1180
				  RAZOR_DETAIL_VERSION, &version,
ali@363
  1181
				  RAZOR_DETAIL_ARCH, &arch,
ali@363
  1182
				  RAZOR_DETAIL_LAST);
ali@363
  1183
ali@476
  1184
	s = rpm_filename(name, version, arch);
ali@476
  1185
	file = razor_concat("Packages/", s, NULL);
ali@476
  1186
	free(s);
ali@476
  1187
	uri = razor_path_relative_to_uri(yum_url, file, NULL);
ali@476
  1188
	free(file);
ali@476
  1189
ali@403
  1190
	if (stage & RAZOR_STAGE_SCRIPTS_PRE)
ali@476
  1191
		printf("install %s\n", uri);
ali@363
  1192
ali@475
  1193
	rpm = razor_rpm_open(uri, &error);
ali@475
  1194
	free(uri);
ali@363
  1195
	if (rpm == NULL) {
ali@447
  1196
		razor_atomic_propagate_error(atomic, error, NULL);
ali@426
  1197
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@363
  1198
		return -1;
ali@363
  1199
	}
ali@363
  1200
	if (relocations)
ali@363
  1201
		razor_rpm_set_relocations(rpm, relocations);
ali@369
  1202
	razor_transaction_fixup_package(trans, package, rpm);
ali@403
  1203
	retval = razor_rpm_install(rpm, atomic, install_root, install_count,
ali@403
  1204
				   stage);
ali@403
  1205
	if (retval < 0) {
ali@403
  1206
		s = rpm_filename(name, version, arch);
ali@403
  1207
		fprintf(stderr, "%s: %s\n", s,
ali@403
  1208
			razor_atomic_get_error_msg(atomic));
ali@403
  1209
		free(s);
ali@403
  1210
	}
ali@363
  1211
	razor_rpm_close(rpm);
ali@363
  1212
	return retval;
ali@363
  1213
}
ali@363
  1214
ali@412
  1215
/*
ali@418
  1216
 * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT
ali@418
  1217
 * is met (in which case the action is consumed).
ali@412
  1218
 */
ali@363
  1219
static int
ali@403
  1220
update_packages(struct razor_transaction *trans,
ali@403
  1221
		struct razor_install_iterator *ii, struct razor_set *system,
ali@403
  1222
		struct razor_set *next, struct razor_atomic *atomic,
ali@403
  1223
		struct razor_relocations *relocations,
ali@418
  1224
		enum razor_stage_type stage)
krh@254
  1225
{
krh@254
  1226
	struct razor_package *package;
krh@316
  1227
	enum razor_install_action action;
ali@363
  1228
	int retval = 0, count;
ali@403
  1229
ali@412
  1230
	while (!retval && razor_install_iterator_next(ii, &package, &action,
ali@412
  1231
						      &count)) {
ali@418
  1232
		if (action == RAZOR_INSTALL_ACTION_ADD) {
ali@418
  1233
			if (install_package(trans, next, atomic, package,
ali@418
  1234
					    relocations, count, stage))
ali@418
  1235
				retval = -1;
ali@418
  1236
		} else if (action == RAZOR_INSTALL_ACTION_REMOVE) {
ali@418
  1237
			if (razor_package_remove(system, next, atomic, package,
ali@418
  1238
						 install_root, count, stage))
ali@418
  1239
				retval = -1;
ali@418
  1240
		} else if (action == RAZOR_INSTALL_ACTION_COMMIT)
ali@418
  1241
				retval = 1;
rhughes@241
  1242
	}
rhughes@241
  1243
ali@363
  1244
	return retval;
rhughes@241
  1245
}
rhughes@241
  1246
rhughes@241
  1247
static int
ali@424
  1248
update_system(struct razor_root *root, struct razor_relocations *relocations,
ali@424
  1249
	      struct razor_transaction *trans, struct razor_set *next,
ali@424
  1250
	      const char *verb)
ali@418
  1251
{
ali@424
  1252
	struct razor_set *system, *set;
ali@418
  1253
	struct razor_atomic *atomic;
ali@418
  1254
	struct razor_install_iterator *ii;
ali@418
  1255
	int r, retval = 0;
ali@418
  1256
	char *description;
ali@418
  1257
	size_t pos;
ali@418
  1258
ali@418
  1259
	description = razor_concat(verb, " packages", NULL);
ali@418
  1260
ali@424
  1261
	system = razor_set_ref(razor_root_get_system_set(root));
ali@424
  1262
ali@418
  1263
	ii = razor_set_create_install_iterator(system, next);
ali@418
  1264
ali@418
  1265
	do {
ali@418
  1266
		pos = razor_install_iterator_tell(ii);
ali@418
  1267
ali@418
  1268
		atomic = razor_atomic_open(description);
ali@418
  1269
ali@418
  1270
		r = update_packages(trans, ii, system, next, atomic,
ali@418
  1271
				    relocations, RAZOR_STAGE_SCRIPTS_PRE);
ali@418
  1272
		if (r < 0) {
ali@418
  1273
			fprintf(stderr, "%s aborted\n", verb);
ali@418
  1274
			retval = r;
ali@418
  1275
		} else {
ali@418
  1276
			razor_install_iterator_seek(ii, pos);
ali@418
  1277
			r = update_packages(trans, ii, system, next, atomic,
ali@418
  1278
					    relocations, RAZOR_STAGE_FILES);
ali@418
  1279
ali@418
  1280
			if (r == 1) {
ali@418
  1281
				set = razor_install_iterator_commit_set(ii);
ali@424
  1282
				razor_root_update(root, set, atomic);
ali@418
  1283
				razor_set_unref(set);
ali@418
  1284
			} else if (r == 0)
ali@424
  1285
				razor_root_update(root, next, atomic);
ali@418
  1286
ali@418
  1287
			retval = razor_atomic_commit(atomic);
ali@421
  1288
			if (retval)
ali@418
  1289
				fprintf(stderr, "%s\n",
ali@418
  1290
					razor_atomic_get_error_msg(atomic));
ali@421
  1291
			else {
ali@418
  1292
				razor_install_iterator_seek(ii, pos);
ali@418
  1293
				update_packages(trans, ii, system, next,
ali@418
  1294
						atomic, relocations,
ali@418
  1295
						RAZOR_STAGE_SCRIPTS_POST);
ali@418
  1296
			}
ali@418
  1297
		}
ali@418
  1298
ali@418
  1299
		razor_atomic_destroy(atomic);
ali@418
  1300
	} while(!retval && r == 1);
ali@418
  1301
ali@458
  1302
	razor_install_iterator_destroy(ii);
ali@458
  1303
ali@424
  1304
	razor_set_unref(system);
ali@424
  1305
ali@418
  1306
	free(description);
ali@418
  1307
ali@418
  1308
	return retval;
ali@418
  1309
}
ali@418
  1310
ali@418
  1311
static int
ali@445
  1312
command_install_or_update(int argc, char * const argv[], int do_update)
rhughes@241
  1313
{
ali@424
  1314
	struct razor_relocations *relocations = NULL;
ali@351
  1315
	struct razor_set *system, *upstream, *next, *set;
rhughes@241
  1316
	struct razor_transaction *trans;
ali@424
  1317
	struct razor_error *error = NULL;
ali@403
  1318
	struct razor_atomic *atomic;
ali@424
  1319
	struct razor_root *root;
ali@445
  1320
	int opt, i, retval = 0, len, dependencies = 1;
ali@351
  1321
	char *oldpath;
ali@445
  1322
	const char *arg;
ali@445
  1323
	enum {
ali@445
  1324
		opt_no_dependencies = 1,
ali@445
  1325
		opt_relocate = 2,
ali@445
  1326
	};
ali@445
  1327
	static struct razor_option options[] = {
ali@445
  1328
		{ .name = "no-dependencies", .has_arg = no_argument,
ali@445
  1329
		  .val = opt_no_dependencies,
ali@445
  1330
		  .description = "Do not verify package dependencies" },
ali@445
  1331
		{ .name = "relocate", .has_arg = required_argument,
ali@445
  1332
		  .val = opt_relocate,
ali@445
  1333
		  .description = "Relocate files from path OLD to NEW",
ali@445
  1334
		  .arg_description = "OLD=NEW" },
ali@445
  1335
	};
rhughes@241
  1336
ali@445
  1337
	do {
ali@445
  1338
		opt = razor_getopt(argc, argv, ARRAY_SIZE(options), options,
ali@445
  1339
				   "rpm ...", &arg);
ali@445
  1340
		switch (opt) {
ali@445
  1341
			case -2:
ali@445
  1342
				return 0;
ali@445
  1343
			case -1:
ali@445
  1344
				return 1;
ali@445
  1345
			case opt_no_dependencies:
ali@445
  1346
				dependencies = 0;
ali@445
  1347
				break;
ali@445
  1348
			case opt_relocate:
ali@445
  1349
				if (strchr(arg, '=') == NULL) {
ali@445
  1350
					razor_usage(argv[0],
ali@445
  1351
						    ARRAY_SIZE(options),
ali@445
  1352
						    options, "rpm ...");
ali@445
  1353
					return 1;
ali@445
  1354
				}
ali@445
  1355
				len = strchr(arg, '=') - arg;
ali@445
  1356
				oldpath = malloc(len + 1);
ali@445
  1357
				strncpy(oldpath, arg, len);
ali@445
  1358
				oldpath[len] = '\0';
ali@445
  1359
				if (!relocations)
ali@445
  1360
				       relocations = razor_relocations_create();
ali@445
  1361
				razor_relocations_add(relocations, oldpath,
ali@445
  1362
						      arg + len + 1);
ali@445
  1363
				free(oldpath);
ali@445
  1364
				break;
ali@445
  1365
		}
ali@445
  1366
	} while (opt);
ali@351
  1367
ali@475
  1368
	upstream = razor_set_open(rawhide_repo_uri, 0, &error);
ali@424
  1369
	if (upstream == NULL) {
ali@424
  1370
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
  1371
		razor_error_free(error);
ali@458
  1372
		if (relocations)
ali@458
  1373
			razor_relocations_destroy(relocations);
ali@424
  1374
		return 1;
ali@424
  1375
	}
ali@424
  1376
ali@418
  1377
	if (do_update)
ali@418
  1378
		atomic = razor_atomic_open("Update packages");
ali@418
  1379
	else
ali@418
  1380
		atomic = razor_atomic_open("Install packages");
ali@418
  1381
ali@351
  1382
	if (relocations) {
ali@403
  1383
		set = relocate_packages(upstream, atomic, relocations);
ali@403
  1384
		if (set == NULL) {
ali@403
  1385
			fprintf(stderr, "%s\n",
ali@403
  1386
				razor_atomic_get_error_msg(atomic));
ali@403
  1387
			razor_atomic_destroy(atomic);
ali@403
  1388
			razor_set_unref(upstream);
ali@403
  1389
			return 1;
ali@403
  1390
		}
ali@403
  1391
		razor_set_unref(upstream);
ali@351
  1392
		upstream = set;
ali@351
  1393
	}
ali@351
  1394
ali@424
  1395
	root = razor_root_open(install_root, &error);
ali@424
  1396
	if (root == NULL) {
ali@424
  1397
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
  1398
		razor_error_free(error);
ali@424
  1399
		razor_atomic_destroy(atomic);
ali@424
  1400
		razor_set_unref(upstream);
ali@424
  1401
		if (relocations)
ali@424
  1402
			razor_relocations_destroy(relocations);
ali@424
  1403
		return 1;
ali@424
  1404
	}
ali@403
  1405
ali@424
  1406
	system = razor_root_get_system_set(root);
krh@250
  1407
	trans = razor_transaction_create(system, upstream);
rhughes@241
  1408
ali@445
  1409
	if (optind == argc && do_update)
ali@382
  1410
		razor_transaction_update_all(trans);
ali@445
  1411
	for (i = optind; i < argc; i++) {
ali@389
  1412
		if (do_update &&
ali@389
  1413
		    mark_packages_for_update(trans, system, argv[i]))
ali@389
  1414
			continue;
rhughes@241
  1415
		if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
rhughes@241
  1416
			fprintf(stderr, "no package matched %s\n", argv[i]);
ali@369
  1417
			razor_transaction_destroy(trans);
ali@424
  1418
			razor_root_close(root);
ali@403
  1419
			razor_set_unref(upstream);
ali@403
  1420
			razor_atomic_destroy(atomic);
ali@424
  1421
			if (relocations)
ali@424
  1422
				razor_relocations_destroy(relocations);
rhughes@241
  1423
			return 1;
rhughes@241
  1424
		}
rhughes@241
  1425
	}
rhughes@241
  1426
rhughes@241
  1427
	if (dependencies) {
krh@245
  1428
		razor_transaction_resolve(trans);
krh@245
  1429
		if (razor_transaction_describe(trans) > 0) {
ali@369
  1430
			razor_transaction_destroy(trans);
ali@403
  1431
			razor_set_unref(upstream);
ali@424
  1432
			razor_root_close(root);
ali@403
  1433
			razor_atomic_destroy(atomic);
ali@424
  1434
			if (relocations)
ali@424
  1435
				razor_relocations_destroy(relocations);
rhughes@241
  1436
			return 1;
rhughes@241
  1437
		}
rhughes@241
  1438
	}
rhughes@241
  1439
ali@418
  1440
	razor_atomic_destroy(atomic);
ali@418
  1441
ali@382
  1442
	next = razor_transaction_commit(trans);
ali@382
  1443
ali@424
  1444
	retval = update_system(root, relocations, trans, next,
ali@418
  1445
			       do_update ? "Update" : "Install");
ali@403
  1446
ali@418
  1447
	razor_set_unref(upstream);
ali@424
  1448
	razor_root_close(root);
ali@403
  1449
ali@369
  1450
	razor_transaction_destroy(trans);
ali@351
  1451
	if (relocations)
ali@351
  1452
		razor_relocations_destroy(relocations);
ali@403
  1453
ali@403
  1454
	razor_set_unref(next);
ali@403
  1455
ali@403
  1456
	return retval;
rhughes@241
  1457
}
rhughes@241
  1458
rhughes@241
  1459
static int
ali@445
  1460
command_update(int argc, char * const argv[])
ali@382
  1461
{
ali@382
  1462
	return command_install_or_update(argc, argv, 1);
ali@382
  1463
}
ali@382
  1464
ali@382
  1465
static int
ali@445
  1466
command_install(int argc, char * const argv[])
ali@382
  1467
{
ali@382
  1468
	return command_install_or_update(argc, argv, 0);
ali@382
  1469
}
ali@382
  1470
ali@382
  1471
static int
ali@445
  1472
command_init(int argc, char * const argv[])
rhughes@241
  1473
{
ali@425
  1474
	int retval;
ali@425
  1475
	struct razor_error *error = NULL;
ali@425
  1476
ali@445
  1477
	switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
ali@445
  1478
		case -2:
ali@445
  1479
			return 0;
ali@445
  1480
		case -1:
ali@445
  1481
			return 1;
ali@445
  1482
	}
ali@445
  1483
ali@445
  1484
	if (argc - optind > 0) {
ali@445
  1485
		razor_usage(argv[0], 0, NULL, "");
ali@445
  1486
		return 1;
ali@445
  1487
	}
ali@445
  1488
ali@425
  1489
	retval = razor_root_create(install_root, &error);
ali@425
  1490
	if (retval) {
ali@425
  1491
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@425
  1492
		razor_error_free(error);
ali@425
  1493
	} else
ali@425
  1494
		printf("Created install root\n");
ali@425
  1495
ali@425
  1496
	return retval;
rhughes@241
  1497
}
rhughes@241
  1498
rhughes@241
  1499
static int
ali@445
  1500
command_download(int argc, char * const argv[])
rhughes@241
  1501
{
ali@424
  1502
	struct razor_error *error = NULL;
ali@403
  1503
	struct razor_atomic *atomic;
rhughes@241
  1504
	struct razor_set *set;
rhughes@241
  1505
	struct razor_package_iterator *pi;
rhughes@241
  1506
	struct razor_package *package;
ali@445
  1507
	const char *pattern, *name, *version, *arch;
ali@475
  1508
	char *url, *file, *s, filename[256];
rhughes@241
  1509
	int matches = 0;
rhughes@241
  1510
ali@445
  1511
	switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
ali@445
  1512
		case -2:
ali@445
  1513
			return 0;
ali@445
  1514
		case -1:
ali@445
  1515
			return 1;
ali@445
  1516
	}
ali@445
  1517
ali@445
  1518
	if (argc - optind > 1) {
ali@445
  1519
		razor_usage(argv[0], 0, NULL, "[pattern]");
ali@445
  1520
		return 1;
ali@445
  1521
	}
ali@445
  1522
ali@445
  1523
	pattern = argv[optind];
ali@445
  1524
ali@475
  1525
	set = razor_set_open(rawhide_repo_uri, 0, &error);
ali@424
  1526
	if (set == NULL) {
ali@424
  1527
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
  1528
		razor_error_free(error);
ali@424
  1529
		return 1;
ali@424
  1530
	}
ali@424
  1531
ali@403
  1532
	atomic = razor_atomic_open("Download packages");
ali@403
  1533
ali@475
  1534
	if (razor_atomic_create_dir(atomic, "file:rpms", 
ali@403
  1535
				    S_IRWXU | S_IRWXG | S_IRWXO)) {
ali@403
  1536
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
  1537
		razor_atomic_destroy(atomic);
rhughes@241
  1538
		return 1;
rhughes@241
  1539
	}
rhughes@241
  1540
ali@403
  1541
	if (razor_atomic_commit(atomic)) {
ali@403
  1542
		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
ali@403
  1543
		razor_atomic_destroy(atomic);
ali@403
  1544
		return 1;
ali@403
  1545
	}
ali@403
  1546
	razor_atomic_destroy(atomic);
ali@403
  1547
rhughes@241
  1548
	pi = razor_package_iterator_create(set);
rhughes@241
  1549
	while (razor_package_iterator_next(pi, &package,
richard@302
  1550
					   RAZOR_DETAIL_NAME, &name,
richard@302
  1551
					   RAZOR_DETAIL_VERSION, &version,
richard@307
  1552
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
  1553
					   RAZOR_DETAIL_LAST)) {
rhughes@241
  1554
		if (pattern && fnmatch(pattern, name, 0) != 0)
rhughes@241
  1555
			continue;
rhughes@241
  1556
rhughes@241
  1557
		matches++;
ali@475
  1558
		snprintf(filename, sizeof filename,
ali@475
  1559
			 "%s-%s.%s.rpm", name, version, arch);
ali@475
  1560
		s = razor_concat("Packages/", filename, NULL);
ali@475
  1561
		url = razor_path_relative_to_uri(yum_url, s, NULL);
ali@475
  1562
		free(s);
ali@475
  1563
		file = razor_concat("rpms/", filename, NULL);
rhughes@241
  1564
		download_if_missing(url, file);
ali@475
  1565
		free(url);
ali@475
  1566
		free(file);
rhughes@241
  1567
	}
rhughes@241
  1568
	razor_package_iterator_destroy(pi);
ali@403
  1569
	razor_set_unref(set);
rhughes@241
  1570
rhughes@241
  1571
	if (matches == 0)
rhughes@241
  1572
		fprintf(stderr, "no packages matched \"%s\"\n", pattern);
rhughes@241
  1573
	else if (matches == 1)
rhughes@241
  1574
		fprintf(stderr, "downloaded 1 package\n");
rhughes@241
  1575
	else
rhughes@241
  1576
		fprintf(stderr, "downloaded %d packages\n", matches);
rhughes@241
  1577
rhughes@241
  1578
	return 0;
rhughes@241
  1579
}
rhughes@241
  1580
jbowes@258
  1581
static int
ali@457
  1582
command_dump(int argc, char * const argv[])
ali@457
  1583
{
ali@457
  1584
	struct razor_error *error = NULL;
ali@457
  1585
	const char *filename;
ali@457
  1586
ali@457
  1587
	switch (razor_getopt(argc, argv, 0, NULL, "[filename]", NULL)) {
ali@457
  1588
		case -2:
ali@457
  1589
			return 0;
ali@457
  1590
		case -1:
ali@457
  1591
			return 1;
ali@457
  1592
	}
ali@457
  1593
ali@457
  1594
	if (argc - optind > 1) {
ali@457
  1595
		razor_usage(argv[0], 0, NULL, "[filename]");
ali@457
  1596
		return 1;
ali@457
  1597
	}
ali@457
  1598
ali@457
  1599
	filename = argv[optind];
ali@457
  1600
ali@457
  1601
	if (razor_dump_database(stdout, install_root, filename, &error)) {
ali@457
  1602
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@457
  1603
		razor_error_free(error);
ali@457
  1604
		return 1;
ali@457
  1605
	}
ali@457
  1606
ali@457
  1607
	return 0;
ali@457
  1608
}
ali@457
  1609
ali@457
  1610
static int
ali@445
  1611
command_info(int argc, char * const argv[])
jbowes@258
  1612
{
ali@424
  1613
	struct razor_error *error = NULL;
jbowes@258
  1614
	struct razor_set *set;
jbowes@258
  1615
	struct razor_package_iterator *pi;
jbowes@258
  1616
	struct razor_package *package;
ali@462
  1617
	struct razor_string_iterator *si;
ali@445
  1618
	const char *pattern, *name, *version, *arch;
jbowes@258
  1619
	const char *summary, *description, *url, *license;
ali@462
  1620
	const char *prefix;
jbowes@258
  1621
ali@445
  1622
	switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
ali@445
  1623
		case -2:
ali@445
  1624
			return 0;
ali@445
  1625
		case -1:
ali@445
  1626
			return 1;
ali@445
  1627
	}
ali@445
  1628
ali@445
  1629
	if (argc - optind > 1) {
ali@445
  1630
		razor_usage(argv[0], 0, NULL, "[pattern]");
ali@445
  1631
		return 1;
ali@445
  1632
	}
ali@445
  1633
ali@445
  1634
	pattern = argv[optind];
ali@445
  1635
ali@424
  1636
	set = razor_root_open_read_only(install_root, &error);
ali@403
  1637
	if (set == NULL) {
ali@424
  1638
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
  1639
		razor_error_free(error);
jbowes@288
  1640
		return 1;
ali@403
  1641
	}
krh@317
  1642
jbowes@258
  1643
	pi = razor_package_iterator_create(set);
jbowes@258
  1644
	while (razor_package_iterator_next(pi, &package,
richard@302
  1645
					   RAZOR_DETAIL_NAME, &name,
richard@302
  1646
					   RAZOR_DETAIL_VERSION, &version,
richard@307
  1647
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
  1648
					   RAZOR_DETAIL_LAST)) {
jbowes@258
  1649
		if (pattern && fnmatch(pattern, name, 0) != 0)
jbowes@258
  1650
			continue;
jbowes@258
  1651
ali@462
  1652
		printf ("Name:        %s\n", name);
ali@462
  1653
		printf ("Arch:        %s\n", arch);
ali@462
  1654
		printf ("Version:     %s\n", version);
ali@462
  1655
ali@462
  1656
		si = razor_install_prefix_iterator_create(set, package);
ali@462
  1657
		if (razor_string_iterator_next(si, &prefix)) {
ali@462
  1658
			printf ("Relocations: %s\n", prefix);
ali@462
  1659
			while (razor_string_iterator_next(si, &prefix))
ali@462
  1660
				printf ("           : %s\n", prefix);
ali@462
  1661
		}
ali@462
  1662
		razor_string_iterator_destroy(si);
ali@462
  1663
richard@302
  1664
		razor_package_get_details (set, package,
richard@302
  1665
					   RAZOR_DETAIL_SUMMARY, &summary,
richard@302
  1666
					   RAZOR_DETAIL_DESCRIPTION, &description,
richard@302
  1667
					   RAZOR_DETAIL_URL, &url,
richard@302
  1668
					   RAZOR_DETAIL_LICENSE, &license,
richard@307
  1669
					   RAZOR_DETAIL_LAST);
jbowes@258
  1670
jbowes@258
  1671
		printf ("URL:         %s\n", url);
jbowes@258
  1672
		printf ("License:     %s\n", license);
jbowes@258
  1673
		printf ("Summary:     %s\n", summary);
jbowes@258
  1674
		printf ("Description:\n");
jbowes@258
  1675
		printf ("%s\n", description);
jbowes@258
  1676
		printf ("\n");
jbowes@258
  1677
	}
jbowes@258
  1678
	razor_package_iterator_destroy(pi);
ali@403
  1679
	razor_set_unref(set);
jbowes@258
  1680
jbowes@258
  1681
	return 0;
jbowes@258
  1682
}
jbowes@258
  1683
jbowes@292
  1684
#define SEARCH_MAX 256
jbowes@292
  1685
jbowes@292
  1686
static int
ali@445
  1687
command_search(int argc, char * const argv[])
jbowes@292
  1688
{
ali@424
  1689
	struct razor_error *error = NULL;
jbowes@292
  1690
	struct razor_set *set;
jbowes@292
  1691
	struct razor_package_iterator *pi;
jbowes@292
  1692
	struct razor_package *package;
jbowes@292
  1693
	char pattern[SEARCH_MAX];
jbowes@292
  1694
	const char *name, *version, *arch;
jbowes@292
  1695
	const char *summary, *description, *url, *license;
jbowes@292
  1696
ali@445
  1697
	switch (razor_getopt(argc, argv, 0, NULL, "pattern", NULL)) {
ali@445
  1698
		case -2:
ali@445
  1699
			return 0;
ali@445
  1700
		case -1:
ali@445
  1701
			return 1;
ali@445
  1702
	}
ali@445
  1703
ali@445
  1704
	if (argc != 2) {
ali@445
  1705
		razor_usage(argv[0], 0, NULL, "pattern");
jbowes@292
  1706
		return 1;
jbowes@292
  1707
	}
jbowes@292
  1708
ali@445
  1709
	snprintf(pattern, sizeof pattern, "*%s*", argv[1]);
jbowes@292
  1710
ali@475
  1711
	set = razor_set_open(rawhide_repo_uri, 0, &error);
ali@424
  1712
	if (set == NULL) {
ali@424
  1713
		fprintf(stderr, "%s\n", razor_error_get_msg(error));
ali@424
  1714
		razor_error_free(error);
jbowes@292
  1715
		return 1;
ali@403
  1716
	}
richard@310
  1717
jbowes@292
  1718
	pi = razor_package_iterator_create(set);
jbowes@292
  1719
	while (razor_package_iterator_next(pi, &package,
richard@304
  1720
					   RAZOR_DETAIL_NAME, &name,
richard@304
  1721
					   RAZOR_DETAIL_VERSION, &version,
krh@305
  1722
					   RAZOR_DETAIL_ARCH, &arch,
krh@305
  1723
					   RAZOR_DETAIL_SUMMARY, &summary,
krh@305
  1724
					   RAZOR_DETAIL_DESCRIPTION, &description,
krh@305
  1725
					   RAZOR_DETAIL_URL, &url,
krh@305
  1726
					   RAZOR_DETAIL_LICENSE, &license,
richard@307
  1727
					   RAZOR_DETAIL_LAST)) {
krh@305
  1728
		if (!fnmatch(pattern, name, FNM_CASEFOLD) ||
krh@305
  1729
		    !fnmatch(pattern, url, FNM_CASEFOLD) ||
krh@305
  1730
		    !fnmatch(pattern, summary, FNM_CASEFOLD) ||
krh@305
  1731
		    !fnmatch(pattern, description, FNM_CASEFOLD))
krh@305
  1732
			printf("%s-%s.%s: %s\n", name, version, arch, summary);
jbowes@292
  1733
	}
jbowes@292
  1734
	razor_package_iterator_destroy(pi);
ali@403
  1735
	razor_set_unref(set);
jbowes@292
  1736
jbowes@292
  1737
	return 0;
jbowes@292
  1738
}
jbowes@292
  1739
rhughes@241
  1740
static struct {
rhughes@241
  1741
	const char *name;
rhughes@241
  1742
	const char *description;
ali@445
  1743
	int (*func)(int argc, char * const argv[]);
rhughes@241
  1744
} razor_commands[] = {
ali@445
  1745
	{ "diff", "Show diff between two package sets", command_diff },
ali@445
  1746
	{ "download", "Download packages", command_download },
ali@457
  1747
	{ "dump", "Low-level database dump (for debugging)", command_dump },
ali@445
  1748
	{ "help", "List available commands", command_help },
ali@320
  1749
#if HAVE_RPMLIB
ali@445
  1750
	{ "import-rpmdb", "Import the system rpm database",
ali@445
  1751
	  command_import_rpmdb },
ali@320
  1752
#endif
ali@445
  1753
	{ "import-rpms", "Import rpms from the given directory",
ali@445
  1754
	  command_import_rpms },
ali@445
  1755
	{ "import-yum", "Import yum metadata files", command_import_yum },
ali@445
  1756
	{ "info", "Display package details", command_info },
ali@445
  1757
	{ "init", "Init razor root", command_init },
ali@445
  1758
	{ "install", "Install rpm", command_install },
ali@445
  1759
	{ "list", "List all packages", command_list },
ali@445
  1760
	{ "list-conflicts", "List all conflicts for the given package",
ali@445
  1761
	  command_list_conflicts },
ali@445
  1762
	{ "list-file-packages", "List packages owning file",
ali@445
  1763
	  command_list_file_packages },
ali@445
  1764
	{ "list-files", "List files for package set", command_list_files },
ali@445
  1765
	{ "list-obsoletes", "List all obsoletes for the given package",
ali@445
  1766
	  command_list_obsoletes },
ali@445
  1767
	{ "list-package-files", "List files in package",
ali@445
  1768
	  command_list_package_files },
ali@445
  1769
	{ "list-provides", "List all provides for the given package",
ali@445
  1770
	  command_list_provides },
ali@445
  1771
	{ "list-requires", "List all requires for the given package",
ali@445
  1772
	  command_list_requires },
ali@445
  1773
	{ "list-scripts", "List all scripts for the given package",
ali@445
  1774
	  command_list_scripts },
ali@445
  1775
	{ "remove", "Remove specified packages", command_remove },
ali@445
  1776
	{ "search", "Search package details", command_search },
ali@445
  1777
	{ "update", "Update all or specified packages", command_update },
ali@445
  1778
	{ "what-provides", "List the packages that have the given provides",
ali@445
  1779
	  command_what_provides },
ali@445
  1780
	{ "what-requires", "List the packages that have the given requires",
ali@445
  1781
	  command_what_requires },
rhughes@241
  1782
};
rhughes@241
  1783
rhughes@241
  1784
static int
ali@445
  1785
command_help(int argc, char * const argv[])
rhughes@241
  1786
{
rhughes@241
  1787
	int i;
rhughes@241
  1788
ali@445
  1789
	printf("Available commands:\n");
rhughes@241
  1790
	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
rhughes@241
  1791
		printf("  %-20s%s\n",
rhughes@241
  1792
		       razor_commands[i].name, razor_commands[i].description);
ali@445
  1793
	printf("\nType \"razor --help\" for help about global options\n"
ali@445
  1794
	       "or \"razor <command> --help\" for help about a particular "
ali@445
  1795
	       "command's options.\n");
rhughes@241
  1796
ali@445
  1797
	return 0;
rhughes@241
  1798
}
rhughes@241
  1799
rhughes@241
  1800
int
ali@445
  1801
main(int argc, char *argv[])
rhughes@241
  1802
{
krh@317
  1803
	char *repo, *root;
ali@445
  1804
	int i, opt, main_optind;
ali@445
  1805
	int do_help_commands = 0;
ali@445
  1806
	enum {
ali@445
  1807
		opt_database = 1,
ali@445
  1808
		opt_help,
ali@445
  1809
		opt_help_commands,
ali@445
  1810
		opt_root,
ali@445
  1811
		opt_url,
ali@445
  1812
	};
ali@445
  1813
	struct option options[] = {
ali@445
  1814
		{ .name = "database", .has_arg = required_argument,
ali@445
  1815
		  .val = opt_database },
ali@445
  1816
		{ .name = "help", .has_arg = no_argument, .val = opt_help },
ali@445
  1817
		{ .name = "help-commands", .has_arg = no_argument,
ali@445
  1818
		  .flag = &do_help_commands, .val = TRUE },
ali@445
  1819
		{ .name = "root", .has_arg = required_argument,
ali@445
  1820
		  .val = opt_root },
ali@445
  1821
		{ .name = "url", .has_arg = required_argument, .val = opt_url },
ali@445
  1822
		{ 0, }
ali@445
  1823
	};
rhughes@241
  1824
rhughes@241
  1825
	repo = getenv("RAZOR_REPO");
rhughes@241
  1826
	if (repo != NULL)
rhughes@241
  1827
		repo_filename = repo;
rhughes@241
  1828
krh@317
  1829
	root = getenv("RAZOR_ROOT");
krh@317
  1830
	if (root != NULL)
krh@317
  1831
		install_root = root;
krh@317
  1832
rhughes@241
  1833
	yum_url = getenv("YUM_URL");
rhughes@241
  1834
	if (yum_url == NULL)
rhughes@241
  1835
		yum_url = YUM_URL;
rhughes@241
  1836
ali@359
  1837
	if (getenv("RAZOR_NO_ROOT_NAME_CHECKS"))
ali@359
  1838
		razor_disable_root_name_checks(1);
ali@359
  1839
ali@445
  1840
	optind = 1;
ali@445
  1841
	opterr = 0;
ali@445
  1842
ali@445
  1843
	while ((opt = getopt_long(argc, argv, "+", options, NULL)) != -1) {
ali@445
  1844
		switch (opt) {
ali@445
  1845
			case opt_database:
ali@475
  1846
				razor_set_database_uri(optarg);
ali@445
  1847
				break;
ali@445
  1848
			case opt_help:
ali@445
  1849
			default:
ali@445
  1850
				printf("Usage: razor [global-options] command "
ali@445
  1851
				       "[command-options-and-arguments]\n\n");
ali@445
  1852
				printf("Options:\n");
ali@445
  1853
				printf("  --help              "
ali@445
  1854
				       "Show this help message and exit\n");
ali@445
  1855
				printf("  --help-commands     List commands\n");
ali@475
  1856
				printf("  --database=URI      "
ali@445
  1857
				       "Use alternative database\n");
ali@475
  1858
				printf("  --root=URI          "
ali@475
  1859
				       "Use URI as top level directory\n");
ali@475
  1860
				printf("  --url=URI           "
ali@475
  1861
				       "Use URI as upstream repository\n");
ali@445
  1862
				return opt != opt_help;
ali@445
  1863
			case opt_root:
ali@445
  1864
				install_root = optarg;
ali@445
  1865
				break;
ali@445
  1866
			case opt_url:
ali@445
  1867
				yum_url = optarg;
ali@445
  1868
				break;
ali@445
  1869
			case 0:
ali@445
  1870
				break;
ali@445
  1871
		}
ali@445
  1872
	}
ali@445
  1873
ali@445
  1874
	main_optind = optind;
ali@445
  1875
	optind = 1;
ali@445
  1876
ali@445
  1877
	if (do_help_commands || argc - main_optind < 1) {
ali@445
  1878
		command_help(argc - main_optind, argv + main_optind);
ali@445
  1879
		return 1;
ali@445
  1880
	}
rhughes@241
  1881
ali@476
  1882
	init_uri_handler();
ali@476
  1883
rhughes@241
  1884
	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
ali@445
  1885
		if (strcmp(razor_commands[i].name, argv[main_optind]) == 0)
ali@445
  1886
			return razor_commands[i].func(argc - main_optind,
ali@445
  1887
						      argv + main_optind);
rhughes@241
  1888
ali@445
  1889
	command_help(argc - main_optind, argv + main_optind);
ali@445
  1890
	return 1;
rhughes@241
  1891
}