diff options
author | dedekind@linutronix.de <dedekind@linutronix.de> | 2006-06-30 14:05:25 +0200 |
---|---|---|
committer | Frank Haverkamp <haver@vnet.ibm.com> | 2006-10-31 15:06:07 +0100 |
commit | faa7699bf15b9a08b1b2658745314ae8f63878a2 (patch) | |
tree | 5891164486ba5b4436c06209a31e1fa1244d23d0 /ubi-utils/src/ubirmvol.c | |
parent | d8f5f9f8cfc5a780f7e95b178e919ac2b20fda93 (diff) |
[MTD] UBI: Adaptations to new driver, reworked frontend
Diffstat (limited to 'ubi-utils/src/ubirmvol.c')
-rw-r--r-- | ubi-utils/src/ubirmvol.c | 267 |
1 files changed, 167 insertions, 100 deletions
diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c index cb47b6c..f810263 100644 --- a/ubi-utils/src/ubirmvol.c +++ b/ubi-utils/src/ubirmvol.c @@ -17,11 +17,15 @@ */ /* - * An utility to create UBI volumes. + * An utility to remove UBI volumes. * - * Autor: Artem B. Bityutskiy <dedekind@oktetlabs.ru> + * Author: Artem B. Bityutskiy <dedekind@linutronix.de> + * Frank Haverkamp <haver@vnet.ibm.com> + * + * 1.1 Reworked the userinterface to use argp. */ +#include <argp.h> #include <stdio.h> #include <stdint.h> #include <getopt.h> @@ -29,29 +33,180 @@ #include <string.h> #include <errno.h> -#include "config.h" +#include <config.h> #include <libubi.h> -static void usage(void); -static int param_sanity_check(ubi_lib_t lib); -static int parse_options(int argc, char * const argv[]); +#define VERSION "1.1" /* * The below variables are set by command line options. */ -static int vol_id = -1; -static int devn = -1; +struct args { + int devn; + int vol_id; + + /* special stuff needed to get additional arguments */ + char *arg1; + char **options; /* [STRING...] */ +}; + +static struct args myargs = { + .devn = -1, + .vol_id = -1, + + .arg1 = NULL, + .options = NULL, +}; + +static int param_sanity_check(struct args *args, ubi_lib_t lib); +static error_t parse_opt(int key, char *optarg, struct argp_state *state); +const char *argp_program_bug_address = PACKAGE_BUGREPORT; + +static char doc[] = "\nVersion: " VERSION "\n\t" + BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" + "\nMake UBI Volume.\n"; + +static struct argp_option options[] = { + { .name = "devn", + .key = 'd', + .arg = "<devn>", + .flags = 0, + .doc = "UBI device", + .group = OPTION_ARG_OPTIONAL }, + + { .name = "vol_id", + .key = 'n', + .arg = "<volume id>", + .flags = 0, + .doc = "UBI volume id, if not specified, the volume ID will be " + "assigned automatically", + .group = OPTION_ARG_OPTIONAL }, + + { .name = NULL, .key = 0, .arg = NULL, .flags = 0, + .doc = NULL, .group = 0 }, +}; + +static struct argp argp = { + .options = options, + .parser = parse_opt, + .args_doc = 0, + .doc = doc, + .children = NULL, + .help_filter = NULL, + .argp_domain = NULL, +}; + +/* + * @brief Parse the arguments passed into the test case. + * + * @param key The parameter. + * @param arg Argument passed to parameter. + * @param state Location to put information on parameters. + * + * @return error + * + * Get the `input' argument from `argp_parse', which we know is a + * pointer to our arguments structure. + */ +static error_t +parse_opt(int key, char *optarg, struct argp_state *state) +{ + char *endp; + struct args *args = state->input; + + switch (key) { + case 'd': /* --devn=<device number> */ + args->devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args->devn < 0) { + fprintf(stderr, "Bad UBI device number: " + "\"%s\"\n", optarg); + goto out; + } + break; + case 'n': /* --volid=<volume id> */ + args->vol_id = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || + (args->vol_id < 0 && args->vol_id != UBI_DYNAMIC_VOLUME)) { + fprintf(stderr, "Bad volume ID: " + "\"%s\"\n", optarg); + goto out; + } + break; + case ':': + fprintf(stderr, "Parameter is missing\n"); + goto out; + + case ARGP_KEY_NO_ARGS: + /* argp_usage(state); */ + break; + + case ARGP_KEY_ARG: + args->arg1 = optarg; + /* Now we consume all the rest of the arguments. + `state->next' is the index in `state->argv' of the + next argument to be parsed, which is the first STRING + we're interested in, so we can just use + `&state->argv[state->next]' as the value for + arguments->strings. + + _In addition_, by setting `state->next' to the end + of the arguments, we can force argp to stop parsing + here and return. */ + + args->options = &state->argv[state->next]; + state->next = state->argc; + break; + + case ARGP_KEY_END: + /* argp_usage(state); */ + break; + + default: + return(ARGP_ERR_UNKNOWN); + } + + return 0; + out: + return(ARGP_ERR_UNKNOWN); +} + +static int param_sanity_check(struct args *args, ubi_lib_t lib) +{ + int err; + struct ubi_info ubi; + + if (args->vol_id == -1) { + fprintf(stderr, "Volume ID was not specified\n"); + goto out; + } + + err = ubi_get_info(lib, &ubi); + if (err) + return -1; + + if (args->devn >= (int)ubi.dev_count) { + fprintf(stderr, "Device %d does not exist\n", args->devn); + goto out; + } + + return 0; + +out: + errno = EINVAL; + return -1; +} int main(int argc, char * const argv[]) { int err, old_errno; ubi_lib_t lib; - err = parse_options(argc, argv); + err = argp_parse(&argp, argc, (char **)argv, ARGP_IN_ORDER, 0, + &myargs); if (err) return err == 1 ? 0 : -1; - if (devn == -1) { + if (myargs.devn == -1) { fprintf(stderr, "Device number was not specified\n"); fprintf(stderr, "Use -h option for help\n"); return -1; @@ -63,14 +218,14 @@ int main(int argc, char * const argv[]) return -1; } - err = param_sanity_check(lib); + err = param_sanity_check(&myargs, lib); if (err) { perror("Input parameters check"); fprintf(stderr, "Use -h option for help\n"); goto out_libubi; } - err = ubi_rmvol(lib, devn, vol_id); + err = ubi_rmvol(lib, myargs.devn, myargs.vol_id); old_errno = errno; if (err < 0) { perror("Cannot remove volume"); @@ -84,91 +239,3 @@ out_libubi: ubi_close(&lib); return -1; } - -/* 'getopt()' option string */ -static const char *optstring = "hd:n:"; - -static int parse_options(int argc, char * const argv[]) -{ - int opt = 0; - - while (opt != -1) { - char *endp; - - opt = getopt(argc, argv, optstring); - - switch (opt) { - case 'h': - usage(); - return 1; - case 'n': - vol_id = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || vol_id < 0) { - fprintf(stderr, "Bad volume " - "number: \"%s\"\n", optarg); - goto out; - } - break; - case 'd': - devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || devn < 0) { - fprintf(stderr, "Bad UBI device " - "number: \"%s\"\n", optarg); - goto out; - } - break; - case ':': - fprintf(stderr, "Parameter is missing\n"); - goto out; - case '?': - fprintf(stderr, "Unknown parameter\n"); - goto out; - case -1: - break; - default: - fprintf(stderr, "Internal error\n"); - goto out; - } - } - - return 0; - -out: - errno = EINVAL; - return -1; -} - -static int param_sanity_check(ubi_lib_t lib) -{ - int err; - struct ubi_info ubi; - - if (vol_id == -1) { - fprintf(stderr, "Volume ID was not specified\n"); - goto out; - } - - err = ubi_get_info(lib, &ubi); - if (err) - return -1; - - if (devn >= (int)ubi.dev_count) { - fprintf(stderr, "Device %d does not exist\n", devn); - goto out; - } - - return 0; - -out: - errno = EINVAL; - return -1; -} - -static void usage(void) -{ - printf("Usage: ubi_rmvol OPTIONS\n" - "Command line options:\n" - "\t-h - this help message\n" - "\t-d - UBI device number\n" - "\t-n VOLNUM - volume number to remove\n"); -} |