Add control over database location
authorJ. Ali Harlow <ali@juiblex.co.uk>
Mon Sep 08 10:26:39 2014 +0100 (2014-09-08)
changeset 445aada48958b92
parent 444 a2908416b7cc
child 446 4277359896dc
Add control over database location
gl/.gitignore
gl/m4/.gitignore
gl/m4/gnulib-cache.m4
librazor/razor.h
librazor/root.c
src/main.c
     1.1 --- a/gl/.gitignore	Mon Sep 01 12:19:32 2014 +0100
     1.2 +++ b/gl/.gitignore	Mon Sep 08 10:26:39 2014 +0100
     1.3 @@ -74,3 +74,7 @@
     1.4  /sys_types.in.h
     1.5  /unistd.c
     1.6  /wctype-h.c
     1.7 +/getopt.c
     1.8 +/getopt.in.h
     1.9 +/getopt1.c
    1.10 +/getopt_int.h
     2.1 --- a/gl/m4/.gitignore	Mon Sep 01 12:19:32 2014 +0100
     2.2 +++ b/gl/m4/.gitignore	Mon Sep 08 10:26:39 2014 +0100
     2.3 @@ -71,3 +71,5 @@
     2.4  /ssize_t.m4
     2.5  /sys_socket_h.m4
     2.6  /sys_types_h.m4
     2.7 +/getopt.m4
     2.8 +/nocrash.m4
     3.1 --- a/gl/m4/gnulib-cache.m4	Mon Sep 01 12:19:32 2014 +0100
     3.2 +++ b/gl/m4/gnulib-cache.m4	Mon Sep 08 10:26:39 2014 +0100
     3.3 @@ -27,7 +27,7 @@
     3.4  
     3.5  
     3.6  # Specification in the form of a command-line invocation:
     3.7 -#   gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=. --no-conditional-dependencies --libtool --macro-prefix=gl fnmatch fnmatch-posix fsync mkdir mkdtemp
     3.8 +#   gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=. --no-conditional-dependencies --libtool --macro-prefix=gl fnmatch fnmatch-posix fsync getopt-gnu mkdir mkdtemp
     3.9  
    3.10  # Specification in the form of a few gnulib-tool.m4 macro invocations:
    3.11  gl_LOCAL_DIR([])
    3.12 @@ -35,6 +35,7 @@
    3.13    fnmatch
    3.14    fnmatch-posix
    3.15    fsync
    3.16 +  getopt-gnu
    3.17    mkdir
    3.18    mkdtemp
    3.19  ])
     4.1 --- a/librazor/razor.h	Mon Sep 01 12:19:32 2014 +0100
     4.2 +++ b/librazor/razor.h	Mon Sep 08 10:26:39 2014 +0100
     4.3 @@ -555,6 +555,8 @@
     4.4   **/
     4.5  struct razor_root;
     4.6  
     4.7 +const char *razor_get_database_path();
     4.8 +void razor_set_database_path(const char *database_path);
     4.9  int razor_root_create(const char *root, struct razor_error **error);
    4.10  struct razor_root *
    4.11  razor_root_open(const char *root, struct razor_error **error);
     5.1 --- a/librazor/root.c	Mon Sep 01 12:19:32 2014 +0100
     5.2 +++ b/librazor/root.c	Mon Sep 08 10:26:39 2014 +0100
     5.3 @@ -1,7 +1,7 @@
     5.4  /*
     5.5   * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     5.6   * Copyright (C) 2008  Red Hat, Inc
     5.7 - * Copyright (C) 2009, 2011, 2012  J. Ali Harlow <ali@juiblex.co.uk>
     5.8 + * Copyright (C) 2009, 2011, 2012, 2014  J. Ali Harlow <ali@juiblex.co.uk>
     5.9   *
    5.10   * This program is free software; you can redistribute it and/or modify
    5.11   * it under the terms of the GNU General Public License as published by
    5.12 @@ -41,6 +41,14 @@
    5.13  #define O_BINARY	0
    5.14  #endif
    5.15  
    5.16 +#ifndef FALSE
    5.17 +#define FALSE 0
    5.18 +#endif
    5.19 +
    5.20 +#ifndef TRUE
    5.21 +#define TRUE (!FALSE)
    5.22 +#endif
    5.23 +
    5.24  static const char system_repo_filename[] = "system.rzdb";
    5.25  /*
    5.26   * system_lock_filename is chosen to be the same as the pre v0.3
    5.27 @@ -50,11 +58,12 @@
    5.28   */
    5.29  static const char system_lock_filename[] = "system-next.rzdb";
    5.30  #ifdef MSWIN_API
    5.31 -#define RAZOR_ROOT_PATH	NULL
    5.32 +#define RAZOR_DATABASE_PATH	NULL
    5.33  #else
    5.34 -#define RAZOR_ROOT_PATH	"/var/lib/razor"
    5.35 +#define RAZOR_DATABASE_PATH	"/var/lib/razor"
    5.36  #endif
    5.37 -static const char *razor_root_path = RAZOR_ROOT_PATH;
    5.38 +static char *razor_database_path = RAZOR_DATABASE_PATH;
    5.39 +static int razor_database_path_alloced = FALSE;
    5.40  
    5.41  struct razor_root {
    5.42  	struct razor_set *system;
    5.43 @@ -65,17 +74,41 @@
    5.44  razor_root_init(void)
    5.45  {
    5.46  #ifdef MSWIN_API
    5.47 -	static char root_path[MAX_PATH];
    5.48 -	if (!razor_root_path) {
    5.49 +	static char database_path[MAX_PATH];
    5.50 +	if (!razor_database_path) {
    5.51  		SHGetFolderPath(NULL,
    5.52  			CSIDL_COMMON_APPDATA | CSIDL_FLAG_DONT_VERIFY, NULL, 0,
    5.53 -			root_path);
    5.54 -		strcat(root_path, "\\Razor");
    5.55 -		razor_root_path = root_path;
    5.56 +			database_path);
    5.57 +		strcat(database_path, "\\Razor");
    5.58 +		razor_database_path = database_path;
    5.59 +		razor_database_path_alloced = FALSE;
    5.60  	}
    5.61  #endif
    5.62  }
    5.63  
    5.64 +RAZOR_EXPORT const char *
    5.65 +razor_get_database_path()
    5.66 +{
    5.67 +	razor_root_init();
    5.68 +
    5.69 +	return razor_database_path;
    5.70 +}
    5.71 +
    5.72 +RAZOR_EXPORT void
    5.73 +razor_set_database_path(const char *database_path)
    5.74 +{
    5.75 +	if (razor_database_path_alloced)
    5.76 +		free(razor_database_path);
    5.77 +
    5.78 +	if (database_path) {
    5.79 +		razor_database_path = strdup(database_path);
    5.80 +		razor_database_path_alloced = TRUE;
    5.81 +	} else {
    5.82 +		razor_database_path = RAZOR_DATABASE_PATH;
    5.83 +		razor_database_path_alloced = FALSE;
    5.84 +	}
    5.85 +}
    5.86 +
    5.87  RAZOR_EXPORT int
    5.88  razor_root_create(const char *root, struct razor_error **error)
    5.89  {
    5.90 @@ -101,7 +134,8 @@
    5.91  		return -1;
    5.92  	}
    5.93  
    5.94 -	file = razor_concat(razor_root_path, "/", system_repo_filename, NULL);
    5.95 +	file = razor_concat(razor_database_path, "/", system_repo_filename,
    5.96 +			    NULL);
    5.97  	path = razor_path_add_root(file, root);
    5.98  	retval = !stat(path, &buf);
    5.99  	if (retval) {
   5.100 @@ -152,7 +186,7 @@
   5.101  		return NULL;
   5.102  	}
   5.103  
   5.104 -	s = razor_concat(razor_root_path, "/", system_lock_filename, NULL);
   5.105 +	s = razor_concat(razor_database_path, "/", system_lock_filename, NULL);
   5.106  	lock_path = razor_path_add_root(s, root);
   5.107  	free(s);
   5.108  
   5.109 @@ -168,7 +202,7 @@
   5.110  		return NULL;
   5.111  	}
   5.112  
   5.113 -	s = razor_concat(razor_root_path, "/", system_repo_filename, NULL);
   5.114 +	s = razor_concat(razor_database_path, "/", system_repo_filename, NULL);
   5.115  	image->path = razor_path_add_root(s, root);
   5.116  	free(s);
   5.117  
   5.118 @@ -198,7 +232,7 @@
   5.119  		return NULL;
   5.120  	}
   5.121  
   5.122 -	s = razor_concat(razor_root_path, "/", system_lock_filename, NULL);
   5.123 +	s = razor_concat(razor_database_path, "/", system_lock_filename, NULL);
   5.124  	path = razor_path_add_root(s, root);
   5.125  	free(s);
   5.126  
   5.127 @@ -212,7 +246,7 @@
   5.128  
   5.129  	free(path);
   5.130  
   5.131 -	s = razor_concat(razor_root_path, "/", system_repo_filename, NULL);
   5.132 +	s = razor_concat(razor_database_path, "/", system_repo_filename, NULL);
   5.133  	path = razor_path_add_root(s, root);
   5.134  	free(s);
   5.135  
     6.1 --- a/src/main.c	Mon Sep 01 12:19:32 2014 +0100
     6.2 +++ b/src/main.c	Mon Sep 08 10:26:39 2014 +0100
     6.3 @@ -1,7 +1,7 @@
     6.4  /*
     6.5   * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     6.6   * Copyright (C) 2008  Red Hat, Inc
     6.7 - * Copyright (C) 2009, 2011-2012  J. Ali Harlow <ali@juiblex.co.uk>
     6.8 + * Copyright (C) 2009, 2011-2012, 2014  J. Ali Harlow <ali@juiblex.co.uk>
     6.9   *
    6.10   * This program is free software; you can redistribute it and/or modify
    6.11   * it under the terms of the GNU General Public License as published by
    6.12 @@ -37,6 +37,7 @@
    6.13  #endif
    6.14  #include <fnmatch.h>
    6.15  #include <errno.h>
    6.16 +#include <getopt.h>
    6.17  #include "razor.h"
    6.18  
    6.19  static const char system_repo_filename[] = "system.rzdb";
    6.20 @@ -46,6 +47,14 @@
    6.21  static const char *repo_filename = system_repo_filename;
    6.22  static const char *yum_url;
    6.23  
    6.24 +#ifndef FALSE
    6.25 +#define FALSE 0
    6.26 +#endif
    6.27 +
    6.28 +#ifndef TRUE
    6.29 +#define TRUE (!FALSE)
    6.30 +#endif
    6.31 +
    6.32  #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
    6.33  
    6.34  static int
    6.35 @@ -59,8 +68,110 @@
    6.36  	      struct razor_transaction *trans, struct razor_set *next,
    6.37  	      const char *verb);
    6.38  
    6.39 +static int command_help(int argc, char * const argv[]);
    6.40 +
    6.41 +struct razor_option {
    6.42 +	char *name;
    6.43 +	int has_arg;
    6.44 +	int val;
    6.45 +	char *description;
    6.46 +	char *arg_description;
    6.47 +};
    6.48 +
    6.49 +static void
    6.50 +razor_usage(const char *command, int n_options, struct razor_option *options,
    6.51 +	    const char *parameter_string)
    6.52 +{
    6.53 +	int i, help_printed = FALSE;
    6.54 +	char buf[19];
    6.55 +
    6.56 +	printf("Usage: razor %s [options] %s\n", command, parameter_string);
    6.57 +	printf("(Specify the --help global option for a list of other "
    6.58 +	       "help options)\n");
    6.59 +	printf("\nOptions:\n");
    6.60 +
    6.61 +	for(i = 0; i < n_options; i++) {
    6.62 +		if (!help_printed && strcmp(options[i].name, "help") > 0) {
    6.63 +			printf("  --help              "
    6.64 +			       "Show this help message and exit\n");
    6.65 +			help_printed = TRUE;
    6.66 +		}
    6.67 +
    6.68 +		if (options[i].has_arg != no_argument)
    6.69 +			snprintf(buf, sizeof(buf), "%s=%s", options[i].name,
    6.70 +				 options[i].arg_description);
    6.71 +		else
    6.72 +			strncpy(buf, options[i].name, sizeof(buf));
    6.73 +		buf[18] = '\0';
    6.74 +
    6.75 +		printf("  --%-18s%s\n", buf, options[i].description);
    6.76 +	}
    6.77 +
    6.78 +	if (!help_printed)
    6.79 +		printf("  --help              "
    6.80 +		       "Show this help message and exit\n");
    6.81 +}
    6.82 +
    6.83 +/**
    6.84 + * razor_getopt:
    6.85 + *
    6.86 + *
    6.87 + * Returns: The next option found or -2 on handled or -1 on error
    6.88 + *          or 0 on end of option list.
    6.89 + **/
    6.90 +static int
    6.91 +razor_getopt(int argc, char * const argv[], int n_options,
    6.92 +	     struct razor_option *options, const char *parameter_string,
    6.93 +	     const char **arg)
    6.94 +{
    6.95 +	int i, opt, do_help = 0, retval;
    6.96 +	struct option *longopts;
    6.97 +
    6.98 +	longopts = calloc((n_options + 2), sizeof(*longopts));
    6.99 +
   6.100 +	for(i = 0; i < n_options; i++) {
   6.101 +		longopts[i].name = options[i].name;
   6.102 +		longopts[i].has_arg = options[i].has_arg;
   6.103 +		longopts[i].flag = &retval;
   6.104 +		longopts[i].val = options[i].val;
   6.105 +	}
   6.106 +
   6.107 +	longopts[i].name = "help";
   6.108 +	longopts[i].has_arg = no_argument;
   6.109 +	longopts[i].flag = &do_help;
   6.110 +	longopts[i].val = TRUE;
   6.111 +
   6.112 +	opterr = 0;
   6.113 +
   6.114 +	opt = getopt_long(argc, argv, "+", longopts, NULL);
   6.115 +
   6.116 +	switch (opt)
   6.117 +	{
   6.118 +		case 0:
   6.119 +			if (do_help) {
   6.120 +				razor_usage(argv[0], n_options, options,
   6.121 +					    parameter_string);
   6.122 +				retval = -2;
   6.123 +			} else if (arg)
   6.124 +				*arg = optarg;
   6.125 +			break;
   6.126 +
   6.127 +		case -1:
   6.128 +			retval = 0;
   6.129 +			break;
   6.130 +
   6.131 +		default:
   6.132 +			razor_usage(argv[0], n_options, options,
   6.133 +				    parameter_string);
   6.134 +			retval = -1;
   6.135 +	}
   6.136 +
   6.137 +	free(longopts);
   6.138 +	return retval;
   6.139 +}
   6.140 +
   6.141  static struct razor_package_iterator *
   6.142 -create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[])
   6.143 +create_iterator_from_argv(struct razor_set *set, int argc, char * const argv[])
   6.144  {
   6.145  	struct razor_package_query *query;
   6.146  	struct razor_package_iterator *iter;
   6.147 @@ -117,18 +228,35 @@
   6.148  }
   6.149  
   6.150  static int
   6.151 -command_list(int argc, const char *argv[])
   6.152 +command_list(int argc, char * const argv[])
   6.153  {
   6.154 +	int opt;
   6.155  	struct razor_package_iterator *pi;
   6.156  	struct razor_error *error = NULL;
   6.157  	struct razor_set *set;
   6.158  	uint32_t flags = 0;
   6.159 -	int i = 0;
   6.160 +	enum {
   6.161 +		opt_only_names = 1,
   6.162 +	};
   6.163 +	static struct razor_option options[] = {
   6.164 +		{ .name = "only-names", .has_arg = no_argument,
   6.165 +		  .val = opt_only_names,
   6.166 +		  .description = "Only list package names" },
   6.167 +	};
   6.168  
   6.169 -	if (i < argc && strcmp(argv[i], "--only-names") == 0) {
   6.170 -		flags |= LIST_PACKAGES_ONLY_NAMES;
   6.171 -		i++;
   6.172 -	}
   6.173 +	do {
   6.174 +		opt = razor_getopt(argc, argv, ARRAY_SIZE(options), options,
   6.175 +				   "pattern ...", NULL);
   6.176 +		switch (opt) {
   6.177 +			case -2:
   6.178 +				return 0;
   6.179 +			case -1:
   6.180 +				return 1;
   6.181 +			case opt_only_names:
   6.182 +				flags |= LIST_PACKAGES_ONLY_NAMES;
   6.183 +				break;
   6.184 +		}
   6.185 +	} while (opt);
   6.186  
   6.187  	set = razor_root_open_read_only(install_root, &error);
   6.188  	if (set == NULL) {
   6.189 @@ -137,7 +265,7 @@
   6.190  		return 1;
   6.191  	}
   6.192  
   6.193 -	pi = create_iterator_from_argv(set, argc - i, argv + i);
   6.194 +	pi = create_iterator_from_argv(set, argc - optind, argv + optind);
   6.195  	list_packages(pi, flags);
   6.196  	razor_package_iterator_destroy(pi);
   6.197  	razor_set_unref(set);
   6.198 @@ -183,7 +311,7 @@
   6.199  }
   6.200  
   6.201  static int
   6.202 -list_properties(int argc, const char *argv[], uint32_t type)
   6.203 +list_properties(int argc, char * const argv[], uint32_t type)
   6.204  {
   6.205  	struct razor_set *set;
   6.206  	struct razor_error *error = NULL;
   6.207 @@ -191,6 +319,13 @@
   6.208  	struct razor_package_iterator *pi;
   6.209  	const char *name, *version, *arch;
   6.210  
   6.211 +	switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
   6.212 +		case -2:
   6.213 +			return 0;
   6.214 +		case -1:
   6.215 +			return 1;
   6.216 +	}
   6.217 +
   6.218  	set = razor_root_open_read_only(install_root, &error);
   6.219  	if (set == NULL) {
   6.220  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.221 @@ -198,7 +333,7 @@
   6.222  		return 1;
   6.223  	}
   6.224  
   6.225 -	pi = create_iterator_from_argv(set, argc, argv);
   6.226 +	pi = create_iterator_from_argv(set, argc - optind, argv + optind);
   6.227  	while (razor_package_iterator_next(pi, &package,
   6.228  					   RAZOR_DETAIL_NAME, &name,
   6.229  					   RAZOR_DETAIL_VERSION, &version,
   6.230 @@ -212,31 +347,31 @@
   6.231  }
   6.232  
   6.233  static int
   6.234 -command_list_requires(int argc, const char *argv[])
   6.235 +command_list_requires(int argc, char * const argv[])
   6.236  {
   6.237  	return list_properties(argc, argv, RAZOR_PROPERTY_REQUIRES);
   6.238  }
   6.239  
   6.240  static int
   6.241 -command_list_provides(int argc, const char *argv[])
   6.242 +command_list_provides(int argc, char * const argv[])
   6.243  {
   6.244  	return list_properties(argc, argv, RAZOR_PROPERTY_PROVIDES);
   6.245  }
   6.246  
   6.247  static int
   6.248 -command_list_obsoletes(int argc, const char *argv[])
   6.249 +command_list_obsoletes(int argc, char * const argv[])
   6.250  {
   6.251  	return list_properties(argc, argv, RAZOR_PROPERTY_OBSOLETES);
   6.252  }
   6.253  
   6.254  static int
   6.255 -command_list_conflicts(int argc, const char *argv[])
   6.256 +command_list_conflicts(int argc, char * const argv[])
   6.257  {
   6.258  	return list_properties(argc, argv, RAZOR_PROPERTY_CONFLICTS);
   6.259  }
   6.260  
   6.261  static int
   6.262 -command_list_scripts(int argc, const char *argv[])
   6.263 +command_list_scripts(int argc, char * const argv[])
   6.264  {
   6.265  	struct razor_set *set;
   6.266  	struct razor_error *error = NULL;
   6.267 @@ -244,6 +379,13 @@
   6.268  	struct razor_package_iterator *pi;
   6.269  	const char *preunprog, *preun, *postunprog, *postun;
   6.270  
   6.271 +	switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
   6.272 +		case -2:
   6.273 +			return 0;
   6.274 +		case -1:
   6.275 +			return 1;
   6.276 +	}
   6.277 +
   6.278  	set = razor_root_open_read_only(install_root, &error);
   6.279  	if (set == NULL) {
   6.280  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.281 @@ -251,7 +393,7 @@
   6.282  		return 1;
   6.283  	}
   6.284  
   6.285 -	pi = create_iterator_from_argv(set, argc, argv);
   6.286 +	pi = create_iterator_from_argv(set, argc - optind, argv + optind);
   6.287  	while (razor_package_iterator_next(pi, &package,
   6.288  					   RAZOR_DETAIL_PREUNPROG, &preunprog,
   6.289  					   RAZOR_DETAIL_PREUN, &preun,
   6.290 @@ -278,11 +420,23 @@
   6.291  }
   6.292  
   6.293  static int
   6.294 -command_list_files(int argc, const char *argv[])
   6.295 +command_list_files(int argc, char * const argv[])
   6.296  {
   6.297  	struct razor_error *error = NULL;
   6.298  	struct razor_set *set;
   6.299  
   6.300 +	switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
   6.301 +		case -2:
   6.302 +			return 0;
   6.303 +		case -1:
   6.304 +			return 1;
   6.305 +	}
   6.306 +
   6.307 +	if (argc - optind > 1) {
   6.308 +		razor_usage(argv[0], 0, NULL, "[pattern]");
   6.309 +		return 1;
   6.310 +	}
   6.311 +
   6.312  	set = razor_root_open_read_only(install_root, &error);
   6.313  	if (set == NULL) {
   6.314  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.315 @@ -290,19 +444,31 @@
   6.316  		return 1;
   6.317  	}
   6.318  
   6.319 -	razor_set_list_files(set, argv[0]);
   6.320 +	razor_set_list_files(set, argv[optind]);
   6.321  	razor_set_unref(set);
   6.322  
   6.323  	return 0;
   6.324  }
   6.325  
   6.326  static int
   6.327 -command_list_file_packages(int argc, const char *argv[])
   6.328 +command_list_file_packages(int argc, char * const argv[])
   6.329  {
   6.330  	struct razor_error *error = NULL;
   6.331  	struct razor_set *set;
   6.332  	struct razor_package_iterator *pi;
   6.333  
   6.334 +	switch (razor_getopt(argc, argv, 0, NULL, "pattern", NULL)) {
   6.335 +		case -2:
   6.336 +			return 0;
   6.337 +		case -1:
   6.338 +			return 1;
   6.339 +	}
   6.340 +
   6.341 +	if (argc - optind != 1) {
   6.342 +		razor_usage(argv[0], 0, NULL, "pattern");
   6.343 +		return 1;
   6.344 +	}
   6.345 +
   6.346  	set = razor_root_open_read_only(install_root, &error);
   6.347  	if (set == NULL) {
   6.348  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.349 @@ -310,7 +476,7 @@
   6.350  		return 1;
   6.351  	}
   6.352  
   6.353 -	pi = razor_package_iterator_create_for_file(set, argv[0]);
   6.354 +	pi = razor_package_iterator_create_for_file(set, argv[optind]);
   6.355  	list_packages(pi, 0);
   6.356  	razor_package_iterator_destroy(pi);
   6.357  
   6.358 @@ -320,7 +486,7 @@
   6.359  }
   6.360  
   6.361  static int
   6.362 -command_list_package_files(int argc, const char *argv[])
   6.363 +command_list_package_files(int argc, char * const argv[])
   6.364  {
   6.365  	struct razor_error *error = NULL;
   6.366  	struct razor_set *set;
   6.367 @@ -328,6 +494,13 @@
   6.368  	struct razor_package *package;
   6.369  	const char *name, *version, *arch;
   6.370  
   6.371 +	switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
   6.372 +		case -2:
   6.373 +			return 0;
   6.374 +		case -1:
   6.375 +			return 1;
   6.376 +	}
   6.377 +
   6.378  	set = razor_root_open_read_only(install_root, &error);
   6.379  	if (set == NULL) {
   6.380  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.381 @@ -335,7 +508,7 @@
   6.382  		return 1;
   6.383  	}
   6.384  
   6.385 -	pi = create_iterator_from_argv(set, argc, argv);
   6.386 +	pi = create_iterator_from_argv(set, argc - optind, argv + optind);
   6.387  	while (razor_package_iterator_next(pi, &package,
   6.388  					   RAZOR_DETAIL_NAME, &name,
   6.389  					   RAZOR_DETAIL_VERSION, &version,
   6.390 @@ -362,9 +535,6 @@
   6.391  	const char *name, *version;
   6.392  	uint32_t flags;
   6.393  
   6.394 -	if (ref_name == NULL)
   6.395 -		return 0;
   6.396 -
   6.397  	set = razor_root_open_read_only(install_root, &error);
   6.398  	if (set == NULL) {
   6.399  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.400 @@ -398,16 +568,42 @@
   6.401  }
   6.402  
   6.403  static int
   6.404 -command_what_requires(int argc, const char *argv[])
   6.405 +command_what_requires(int argc, char * const argv[])
   6.406  {
   6.407 -	return list_property_packages(argv[0], argv[1],
   6.408 +	switch (razor_getopt(argc, argv, 0, NULL, "name [version-release]",
   6.409 +			     NULL)) {
   6.410 +		case -2:
   6.411 +			return 0;
   6.412 +		case -1:
   6.413 +			return 1;
   6.414 +	}
   6.415 +
   6.416 +	if (argc - optind < 1 || argc - optind > 2) {
   6.417 +		razor_usage(argv[0], 0, NULL, "name [version-release]");
   6.418 +		return 1;
   6.419 +	}
   6.420 +
   6.421 +	return list_property_packages(argv[optind], argv[optind + 1],
   6.422  				      RAZOR_PROPERTY_REQUIRES);
   6.423  }
   6.424  
   6.425  static int
   6.426 -command_what_provides(int argc, const char *argv[])
   6.427 +command_what_provides(int argc, char * const argv[])
   6.428  {
   6.429 -	return list_property_packages(argv[0], argv[1],
   6.430 +	switch (razor_getopt(argc, argv, 0, NULL, "name [version-release]",
   6.431 +			     NULL)) {
   6.432 +		case -2:
   6.433 +			return 0;
   6.434 +		case -1:
   6.435 +			return 1;
   6.436 +	}
   6.437 +
   6.438 +	if (argc - optind < 1 || argc - optind > 2) {
   6.439 +		razor_usage(argv[0], 0, NULL, "name [version-release]");
   6.440 +		return 1;
   6.441 +	}
   6.442 +
   6.443 +	return list_property_packages(argv[optind], argv[optind + 1],
   6.444  				      RAZOR_PROPERTY_PROVIDES);
   6.445  }
   6.446  
   6.447 @@ -489,13 +685,25 @@
   6.448  	"/pub/fedora/linux/development/i386/os"
   6.449  
   6.450  static int
   6.451 -command_import_yum(int argc, const char *argv[])
   6.452 +command_import_yum(int argc, char * const argv[])
   6.453  {
   6.454  	int retval;
   6.455  	struct razor_set *set;
   6.456  	struct razor_atomic *atomic;
   6.457  	char buffer[512];
   6.458  
   6.459 +	switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
   6.460 +		case -2:
   6.461 +			return 0;
   6.462 +		case -1:
   6.463 +			return 1;
   6.464 +	}
   6.465 +
   6.466 +	if (argc - optind > 0) {
   6.467 +		razor_usage(argv[0], 0, NULL, "");
   6.468 +		return 1;
   6.469 +	}
   6.470 +
   6.471  	printf("downloading from %s.\n", yum_url);
   6.472  	snprintf(buffer, sizeof buffer,
   6.473  		 "%s/repodata/primary.xml.gz", yum_url);
   6.474 @@ -524,7 +732,7 @@
   6.475  
   6.476  #if HAVE_RPMLIB
   6.477  static int
   6.478 -command_import_rpmdb(int argc, const char *argv[])
   6.479 +command_import_rpmdb(int argc, char * const argv[])
   6.480  {
   6.481  	struct razor_set *set;
   6.482  	struct razor_root *root;
   6.483 @@ -532,6 +740,18 @@
   6.484  	struct razor_atomic *atomic;
   6.485  	int retval;
   6.486  
   6.487 +	switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
   6.488 +		case -2:
   6.489 +			return 0;
   6.490 +		case -1:
   6.491 +			return 1;
   6.492 +	}
   6.493 +
   6.494 +	if (argc - optind > 0) {
   6.495 +		razor_usage(argv[0], 0, NULL, "");
   6.496 +		return 1;
   6.497 +	}
   6.498 +
   6.499  	root = razor_root_open(install_root, &error);
   6.500  	if (root == NULL) {
   6.501  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.502 @@ -605,7 +825,7 @@
   6.503  }
   6.504  
   6.505  static int
   6.506 -command_remove(int argc, const char *argv[])
   6.507 +command_remove(int argc, char * const argv[])
   6.508  {
   6.509  	struct razor_set *system, *upstream, *next;
   6.510  	struct razor_transaction *trans;
   6.511 @@ -613,6 +833,13 @@
   6.512  	struct razor_root *root;
   6.513  	int i, retval;
   6.514  
   6.515 +	switch (razor_getopt(argc, argv, 0, NULL, "pattern ...", NULL)) {
   6.516 +		case -2:
   6.517 +			return 0;
   6.518 +		case -1:
   6.519 +			return 1;
   6.520 +	}
   6.521 +
   6.522  	root = razor_root_open(install_root, &error);
   6.523  	if (root == NULL) {
   6.524  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.525 @@ -624,7 +851,7 @@
   6.526  	upstream = razor_set_create_without_root();
   6.527  	trans = razor_transaction_create(system, upstream);
   6.528  	razor_set_unref(upstream);
   6.529 -	for (i = 0; i < argc; i++) {
   6.530 +	for (i = optind; i < argc; i++) {
   6.531  		if (mark_packages_for_removal(trans, system, argv[i]) == 0) {
   6.532  			fprintf(stderr, "no match for %s\n", argv[i]);
   6.533  			razor_transaction_destroy(trans);
   6.534 @@ -667,11 +894,23 @@
   6.535  }
   6.536  
   6.537  static int
   6.538 -command_diff(int argc, const char *argv[])
   6.539 +command_diff(int argc, char * const argv[])
   6.540  {
   6.541  	struct razor_error *error = NULL;
   6.542  	struct razor_set *set, *updated;
   6.543  
   6.544 +	switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
   6.545 +		case -2:
   6.546 +			return 0;
   6.547 +		case -1:
   6.548 +			return 1;
   6.549 +	}
   6.550 +
   6.551 +	if (argc - optind > 0) {
   6.552 +		razor_usage(argv[0], 0, NULL, "");
   6.553 +		return 1;
   6.554 +	}
   6.555 +
   6.556  	set = razor_root_open_read_only(install_root, &error);
   6.557  	if (set)
   6.558  		updated = razor_set_open(rawhide_repo_filename, 0, &error);
   6.559 @@ -694,7 +933,7 @@
   6.560  }
   6.561  
   6.562  static int
   6.563 -command_import_rpms(int argc, const char *argv[])
   6.564 +command_import_rpms(int argc, char * const argv[])
   6.565  {
   6.566  	DIR *dir;
   6.567  	struct dirent *de;
   6.568 @@ -705,14 +944,23 @@
   6.569  	struct razor_atomic *atomic;
   6.570  	int len, imported_count = 0;
   6.571  	char filename[256];
   6.572 -	const char *dirname = argv[0];
   6.573 +	const char *dirname;
   6.574  	int retval;
   6.575  
   6.576 -	if (dirname == NULL) {
   6.577 -		fprintf(stderr, "usage: razor import-rpms DIR\n");
   6.578 -		return -1;
   6.579 +	switch (razor_getopt(argc, argv, 0, NULL, "dir", NULL)) {
   6.580 +		case -2:
   6.581 +			return 0;
   6.582 +		case -1:
   6.583 +			return 1;
   6.584  	}
   6.585  
   6.586 +	if (argc - optind != 1) {
   6.587 +		razor_usage(argv[0], 0, NULL, "dir");
   6.588 +		return 1;
   6.589 +	}
   6.590 +
   6.591 +	dirname = argv[optind];
   6.592 +
   6.593  	dir = opendir(dirname);
   6.594  	if (dir == NULL) {
   6.595  		fprintf(stderr, "couldn't read dir %s\n", dirname);
   6.596 @@ -1054,7 +1302,7 @@
   6.597  }
   6.598  
   6.599  static int
   6.600 -command_install_or_update(int argc, const char *argv[], int do_update)
   6.601 +command_install_or_update(int argc, char * const argv[], int do_update)
   6.602  {
   6.603  	struct razor_relocations *relocations = NULL;
   6.604  	struct razor_set *system, *upstream, *next, *set;
   6.605 @@ -1062,36 +1310,53 @@
   6.606  	struct razor_error *error = NULL;
   6.607  	struct razor_atomic *atomic;
   6.608  	struct razor_root *root;
   6.609 -	int i, retval, len, dependencies = 1;
   6.610 +	int opt, i, retval = 0, len, dependencies = 1;
   6.611  	char *oldpath;
   6.612 +	const char *arg;
   6.613 +	enum {
   6.614 +		opt_no_dependencies = 1,
   6.615 +		opt_relocate = 2,
   6.616 +	};
   6.617 +	static struct razor_option options[] = {
   6.618 +		{ .name = "no-dependencies", .has_arg = no_argument,
   6.619 +		  .val = opt_no_dependencies,
   6.620 +		  .description = "Do not verify package dependencies" },
   6.621 +		{ .name = "relocate", .has_arg = required_argument,
   6.622 +		  .val = opt_relocate,
   6.623 +		  .description = "Relocate files from path OLD to NEW",
   6.624 +		  .arg_description = "OLD=NEW" },
   6.625 +	};
   6.626  
   6.627 -	for (i = 0; i < argc; i++) {
   6.628 -		if (strcmp(argv[i], "--no-dependencies") == 0)
   6.629 -			dependencies = 0;
   6.630 -		else if (strcmp(argv[i], "--relocate") == 0) {
   6.631 -			i++;
   6.632 -			if (i >= argc || strchr(argv[i], '=') == NULL) {
   6.633 -				fprintf(stderr,
   6.634 -				    "Usage: razor %s [OPTION...] RPM\n",
   6.635 -				    do_update ? "update" : "install");
   6.636 -				fprintf(stderr, "Options:\n");
   6.637 -				fprintf(stderr, "    [--no-dependencies]\n");
   6.638 -				fprintf(stderr,
   6.639 -				    "    [--relocate OLDPATH=NEWPATH] RPM\n");
   6.640 -				return -1;
   6.641 -			}
   6.642 -			len = strchr(argv[i], '=') - argv[i];
   6.643 -			oldpath = malloc(len + 1);
   6.644 -			strncpy(oldpath, argv[i], len);
   6.645 -			oldpath[len] = '\0';
   6.646 -			if (!relocations)
   6.647 -			       relocations = razor_relocations_create();
   6.648 -			razor_relocations_add(relocations, oldpath,
   6.649 -					      argv[i] + len + 1);
   6.650 -			free(oldpath);
   6.651 -		} else
   6.652 -			break;
   6.653 -	}
   6.654 +	do {
   6.655 +		opt = razor_getopt(argc, argv, ARRAY_SIZE(options), options,
   6.656 +				   "rpm ...", &arg);
   6.657 +		switch (opt) {
   6.658 +			case -2:
   6.659 +				return 0;
   6.660 +			case -1:
   6.661 +				return 1;
   6.662 +			case opt_no_dependencies:
   6.663 +				dependencies = 0;
   6.664 +				break;
   6.665 +			case opt_relocate:
   6.666 +				if (strchr(arg, '=') == NULL) {
   6.667 +					razor_usage(argv[0],
   6.668 +						    ARRAY_SIZE(options),
   6.669 +						    options, "rpm ...");
   6.670 +					return 1;
   6.671 +				}
   6.672 +				len = strchr(arg, '=') - arg;
   6.673 +				oldpath = malloc(len + 1);
   6.674 +				strncpy(oldpath, arg, len);
   6.675 +				oldpath[len] = '\0';
   6.676 +				if (!relocations)
   6.677 +				       relocations = razor_relocations_create();
   6.678 +				razor_relocations_add(relocations, oldpath,
   6.679 +						      arg + len + 1);
   6.680 +				free(oldpath);
   6.681 +				break;
   6.682 +		}
   6.683 +	} while (opt);
   6.684  
   6.685  	upstream = razor_set_open(rawhide_repo_filename, 0, &error);
   6.686  	if (upstream == NULL) {
   6.687 @@ -1132,9 +1397,9 @@
   6.688  	system = razor_root_get_system_set(root);
   6.689  	trans = razor_transaction_create(system, upstream);
   6.690  
   6.691 -	if (i == argc && do_update)
   6.692 +	if (optind == argc && do_update)
   6.693  		razor_transaction_update_all(trans);
   6.694 -	for (; i < argc; i++) {
   6.695 +	for (i = optind; i < argc; i++) {
   6.696  		if (do_update &&
   6.697  		    mark_packages_for_update(trans, system, argv[i]))
   6.698  			continue;
   6.699 @@ -1207,23 +1472,35 @@
   6.700  }
   6.701  
   6.702  static int
   6.703 -command_update(int argc, const char *argv[])
   6.704 +command_update(int argc, char * const argv[])
   6.705  {
   6.706  	return command_install_or_update(argc, argv, 1);
   6.707  }
   6.708  
   6.709  static int
   6.710 -command_install(int argc, const char *argv[])
   6.711 +command_install(int argc, char * const argv[])
   6.712  {
   6.713  	return command_install_or_update(argc, argv, 0);
   6.714  }
   6.715  
   6.716  static int
   6.717 -command_init(int argc, const char *argv[])
   6.718 +command_init(int argc, char * const argv[])
   6.719  {
   6.720  	int retval;
   6.721  	struct razor_error *error = NULL;
   6.722  
   6.723 +	switch (razor_getopt(argc, argv, 0, NULL, "", NULL)) {
   6.724 +		case -2:
   6.725 +			return 0;
   6.726 +		case -1:
   6.727 +			return 1;
   6.728 +	}
   6.729 +
   6.730 +	if (argc - optind > 0) {
   6.731 +		razor_usage(argv[0], 0, NULL, "");
   6.732 +		return 1;
   6.733 +	}
   6.734 +
   6.735  	retval = razor_root_create(install_root, &error);
   6.736  	if (retval) {
   6.737  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.738 @@ -1235,17 +1512,31 @@
   6.739  }
   6.740  
   6.741  static int
   6.742 -command_download(int argc, const char *argv[])
   6.743 +command_download(int argc, char * const argv[])
   6.744  {
   6.745  	struct razor_error *error = NULL;
   6.746  	struct razor_atomic *atomic;
   6.747  	struct razor_set *set;
   6.748  	struct razor_package_iterator *pi;
   6.749  	struct razor_package *package;
   6.750 -	const char *pattern = argv[0], *name, *version, *arch;
   6.751 +	const char *pattern, *name, *version, *arch;
   6.752  	char url[256], file[256];
   6.753  	int matches = 0;
   6.754  
   6.755 +	switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
   6.756 +		case -2:
   6.757 +			return 0;
   6.758 +		case -1:
   6.759 +			return 1;
   6.760 +	}
   6.761 +
   6.762 +	if (argc - optind > 1) {
   6.763 +		razor_usage(argv[0], 0, NULL, "[pattern]");
   6.764 +		return 1;
   6.765 +	}
   6.766 +
   6.767 +	pattern = argv[optind];
   6.768 +
   6.769  	set = razor_set_open(rawhide_repo_filename, 0, &error);
   6.770  	if (set == NULL) {
   6.771  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.772 @@ -1300,15 +1591,29 @@
   6.773  }
   6.774  
   6.775  static int
   6.776 -command_info(int argc, const char *argv[])
   6.777 +command_info(int argc, char * const argv[])
   6.778  {
   6.779  	struct razor_error *error = NULL;
   6.780  	struct razor_set *set;
   6.781  	struct razor_package_iterator *pi;
   6.782  	struct razor_package *package;
   6.783 -	const char *pattern = argv[0], *name, *version, *arch;
   6.784 +	const char *pattern, *name, *version, *arch;
   6.785  	const char *summary, *description, *url, *license;
   6.786  
   6.787 +	switch (razor_getopt(argc, argv, 0, NULL, "[pattern]", NULL)) {
   6.788 +		case -2:
   6.789 +			return 0;
   6.790 +		case -1:
   6.791 +			return 1;
   6.792 +	}
   6.793 +
   6.794 +	if (argc - optind > 1) {
   6.795 +		razor_usage(argv[0], 0, NULL, "[pattern]");
   6.796 +		return 1;
   6.797 +	}
   6.798 +
   6.799 +	pattern = argv[optind];
   6.800 +
   6.801  	set = razor_root_open_read_only(install_root, &error);
   6.802  	if (set == NULL) {
   6.803  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   6.804 @@ -1351,7 +1656,7 @@
   6.805  #define SEARCH_MAX 256
   6.806  
   6.807  static int
   6.808 -command_search(int argc, const char *argv[])
   6.809 +command_search(int argc, char * const argv[])
   6.810  {
   6.811  	struct razor_error *error = NULL;
   6.812  	struct razor_set *set;
   6.813 @@ -1361,12 +1666,19 @@
   6.814  	const char *name, *version, *arch;
   6.815  	const char *summary, *description, *url, *license;
   6.816  
   6.817 -	if (!argv[0]) {
   6.818 -		fprintf(stderr, "must specify a search term\n");
   6.819 +	switch (razor_getopt(argc, argv, 0, NULL, "pattern", NULL)) {
   6.820 +		case -2:
   6.821 +			return 0;
   6.822 +		case -1:
   6.823 +			return 1;
   6.824 +	}
   6.825 +
   6.826 +	if (argc != 2) {
   6.827 +		razor_usage(argv[0], 0, NULL, "pattern");
   6.828  		return 1;
   6.829  	}
   6.830  
   6.831 -	snprintf(pattern, sizeof pattern, "*%s*", argv[0]);
   6.832 +	snprintf(pattern, sizeof pattern, "*%s*", argv[1]);
   6.833  
   6.834  	set = razor_set_open(rawhide_repo_filename, 0, &error);
   6.835  	if (set == NULL) {
   6.836 @@ -1400,52 +1712,86 @@
   6.837  static struct {
   6.838  	const char *name;
   6.839  	const char *description;
   6.840 -	int (*func)(int argc, const char *argv[]);
   6.841 +	int (*func)(int argc, char * const argv[]);
   6.842  } razor_commands[] = {
   6.843 -	{ "list", "list all packages", command_list },
   6.844 -	{ "list-requires", "list all requires for the given package", command_list_requires },
   6.845 -	{ "list-provides", "list all provides for the given package", command_list_provides },
   6.846 -	{ "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
   6.847 -	{ "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
   6.848 -	{ "list-scripts", "list all scripts for the given package", command_list_scripts },
   6.849 -	{ "list-files", "list files for package set", command_list_files },
   6.850 -	{ "list-file-packages", "list packages owning file", command_list_file_packages },
   6.851 -	{ "list-package-files", "list files in package", command_list_package_files },
   6.852 -	{ "what-requires", "list the packages that have the given requires", command_what_requires },
   6.853 -	{ "what-provides", "list the packages that have the given provides", command_what_provides },
   6.854 -	{ "import-yum", "import yum metadata files", command_import_yum },
   6.855 +	{ "diff", "Show diff between two package sets", command_diff },
   6.856 +	{ "download", "Download packages", command_download },
   6.857 +	{ "help", "List available commands", command_help },
   6.858  #if HAVE_RPMLIB
   6.859 -	{ "import-rpmdb", "import the system rpm database", command_import_rpmdb },
   6.860 +	{ "import-rpmdb", "Import the system rpm database",
   6.861 +	  command_import_rpmdb },
   6.862  #endif
   6.863 -	{ "import-rpms", "import rpms from the given directory", command_import_rpms },
   6.864 -	{ "update", "update all or specified packages", command_update },
   6.865 -	{ "remove", "remove specified packages", command_remove },
   6.866 -	{ "diff", "show diff between two package sets", command_diff },
   6.867 -	{ "install", "install rpm", command_install },
   6.868 -	{ "init", "init razor root", command_init },
   6.869 -	{ "download", "download packages", command_download },
   6.870 -	{ "info", "display package details", command_info },
   6.871 -	{ "search", "search package details", command_search }
   6.872 +	{ "import-rpms", "Import rpms from the given directory",
   6.873 +	  command_import_rpms },
   6.874 +	{ "import-yum", "Import yum metadata files", command_import_yum },
   6.875 +	{ "info", "Display package details", command_info },
   6.876 +	{ "init", "Init razor root", command_init },
   6.877 +	{ "install", "Install rpm", command_install },
   6.878 +	{ "list", "List all packages", command_list },
   6.879 +	{ "list-conflicts", "List all conflicts for the given package",
   6.880 +	  command_list_conflicts },
   6.881 +	{ "list-file-packages", "List packages owning file",
   6.882 +	  command_list_file_packages },
   6.883 +	{ "list-files", "List files for package set", command_list_files },
   6.884 +	{ "list-obsoletes", "List all obsoletes for the given package",
   6.885 +	  command_list_obsoletes },
   6.886 +	{ "list-package-files", "List files in package",
   6.887 +	  command_list_package_files },
   6.888 +	{ "list-provides", "List all provides for the given package",
   6.889 +	  command_list_provides },
   6.890 +	{ "list-requires", "List all requires for the given package",
   6.891 +	  command_list_requires },
   6.892 +	{ "list-scripts", "List all scripts for the given package",
   6.893 +	  command_list_scripts },
   6.894 +	{ "remove", "Remove specified packages", command_remove },
   6.895 +	{ "search", "Search package details", command_search },
   6.896 +	{ "update", "Update all or specified packages", command_update },
   6.897 +	{ "what-provides", "List the packages that have the given provides",
   6.898 +	  command_what_provides },
   6.899 +	{ "what-requires", "List the packages that have the given requires",
   6.900 +	  command_what_requires },
   6.901  };
   6.902  
   6.903  static int
   6.904 -usage(void)
   6.905 +command_help(int argc, char * const argv[])
   6.906  {
   6.907  	int i;
   6.908  
   6.909 -	printf("usage:\n");
   6.910 +	printf("Available commands:\n");
   6.911  	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
   6.912  		printf("  %-20s%s\n",
   6.913  		       razor_commands[i].name, razor_commands[i].description);
   6.914 +	printf("\nType \"razor --help\" for help about global options\n"
   6.915 +	       "or \"razor <command> --help\" for help about a particular "
   6.916 +	       "command's options.\n");
   6.917  
   6.918 -	return 1;
   6.919 +	return 0;
   6.920  }
   6.921  
   6.922  int
   6.923 -main(int argc, const char *argv[])
   6.924 +main(int argc, char *argv[])
   6.925  {
   6.926  	char *repo, *root;
   6.927 -	int i;
   6.928 +	int i, opt, main_optind;
   6.929 +	int do_help_commands = 0;
   6.930 +	enum {
   6.931 +		opt_database = 1,
   6.932 +		opt_help,
   6.933 +		opt_help_commands,
   6.934 +		opt_root,
   6.935 +		opt_url,
   6.936 +	};
   6.937 +	struct option options[] = {
   6.938 +		{ .name = "database", .has_arg = required_argument,
   6.939 +		  .val = opt_database },
   6.940 +		{ .name = "help", .has_arg = no_argument, .val = opt_help },
   6.941 +		{ .name = "help-commands", .has_arg = no_argument,
   6.942 +		  .flag = &do_help_commands, .val = TRUE },
   6.943 +		{ .name = "root", .has_arg = required_argument,
   6.944 +		  .val = opt_root },
   6.945 +		{ .name = "url", .has_arg = required_argument, .val = opt_url },
   6.946 +		{ 0, }
   6.947 +	};
   6.948  
   6.949  	repo = getenv("RAZOR_REPO");
   6.950  	if (repo != NULL)
   6.951 @@ -1462,12 +1808,53 @@
   6.952  	if (getenv("RAZOR_NO_ROOT_NAME_CHECKS"))
   6.953  		razor_disable_root_name_checks(1);
   6.954  
   6.955 -	if (argc < 2)
   6.956 -		return usage();
   6.957 +	optind = 1;
   6.958 +	opterr = 0;
   6.959 +
   6.960 +	while ((opt = getopt_long(argc, argv, "+", options, NULL)) != -1) {
   6.961 +		switch (opt) {
   6.962 +			case opt_database:
   6.963 +				razor_set_database_path(optarg);
   6.964 +				break;
   6.965 +			case opt_help:
   6.966 +			default:
   6.967 +				printf("Usage: razor [global-options] command "
   6.968 +				       "[command-options-and-arguments]\n\n");
   6.969 +				printf("Options:\n");
   6.970 +				printf("  --help              "
   6.971 +				       "Show this help message and exit\n");
   6.972 +				printf("  --help-commands     List commands\n");
   6.973 +				printf("  --database=PATH     "
   6.974 +				       "Use alternative database\n");
   6.975 +				printf("  --root=ROOT         "
   6.976 +				       "Use ROOT as top level directory\n");
   6.977 +				printf("  --url=URL           "
   6.978 +				       "Use URL as upstream repository\n");
   6.979 +				return opt != opt_help;
   6.980 +			case opt_root:
   6.981 +				install_root = optarg;
   6.982 +				break;
   6.983 +			case opt_url:
   6.984 +				yum_url = optarg;
   6.985 +				break;
   6.986 +			case 0:
   6.987 +				break;
   6.988 +		}
   6.989 +	}
   6.990 +
   6.991 +	main_optind = optind;
   6.992 +	optind = 1;
   6.993 +
   6.994 +	if (do_help_commands || argc - main_optind < 1) {
   6.995 +		command_help(argc - main_optind, argv + main_optind);
   6.996 +		return 1;
   6.997 +	}
   6.998  
   6.999  	for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
  6.1000 -		if (strcmp(razor_commands[i].name, argv[1]) == 0)
  6.1001 -			return razor_commands[i].func(argc - 2, argv + 2);
  6.1002 +		if (strcmp(razor_commands[i].name, argv[main_optind]) == 0)
  6.1003 +			return razor_commands[i].func(argc - main_optind,
  6.1004 +						      argv + main_optind);
  6.1005  
  6.1006 -	return usage();
  6.1007 +	command_help(argc - main_optind, argv + main_optind);
  6.1008 +	return 1;
  6.1009  }