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 | |
| parent | d8f5f9f8cfc5a780f7e95b178e919ac2b20fda93 (diff) | |
[MTD] UBI: Adaptations to new driver, reworked frontend
Diffstat (limited to 'ubi-utils')
| -rw-r--r-- | ubi-utils/src/config.h | 4 | ||||
| -rw-r--r-- | ubi-utils/src/libubi.c | 31 | ||||
| -rw-r--r-- | ubi-utils/src/libubi_int.h | 8 | ||||
| -rw-r--r-- | ubi-utils/src/ubimkvol.c | 405 | ||||
| -rw-r--r-- | ubi-utils/src/ubirmvol.c | 267 | ||||
| -rw-r--r-- | ubi-utils/src/ubiupdatevol.c | 50 | 
6 files changed, 456 insertions, 309 deletions
| diff --git a/ubi-utils/src/config.h b/ubi-utils/src/config.h index 746fa3c..b5bbd5b 100644 --- a/ubi-utils/src/config.h +++ b/ubi-utils/src/config.h @@ -20,8 +20,8 @@   * Author: Frank Haverkamp   */ -#define PACKAGE_VERSION     "1.0" -#define PACKAGE_BUGREPORT   "dedekind@oktetlabs.ru, haver@vnet.ibm.com, or tglx@linutronix.de" +#define PACKAGE_VERSION     "1.1" +#define PACKAGE_BUGREPORT   "haver@vnet.ibm.com, dedekind@linutronix.de, or tglx@linutronix.de"  #define __unused __attribute__((unused)) diff --git a/ubi-utils/src/libubi.c b/ubi-utils/src/libubi.c index 9b9a793..979f157 100644 --- a/ubi-utils/src/libubi.c +++ b/ubi-utils/src/libubi.c @@ -34,6 +34,7 @@  #include <sys/ioctl.h>  #include <stdint.h>  #include <mtd/ubi-user.h> +#include <mtd/ubi-header.h>  #include "libubi.h"  #include "libubi_int.h" @@ -47,7 +48,6 @@   * @sysfs_root	    sysfs root directory   * @ubi_root	    UBI root directory in sysfs   * - * @nlen_max	    full path to the "maximum volume name length" sysfs file   * @version	    full path to the "UBI version" sysfs file   *   * @cdev_path	    path pattern to UBI character devices @@ -85,7 +85,6 @@ struct ubi_lib  	char *sysfs_root;  	char *ubi_root; -	char *nlen_max;  	char *version;  	char *cdev_path;  	int  cdev_path_len; @@ -147,10 +146,6 @@ get_ubi_info(ubi_lib_t desc, struct ubi_info *ubi)  	if (err)  		return -1; -	err = sysfs_read_int(desc->nlen_max, (int*) &ubi->nlen_max); -	if (err) -		return -1; -  	/* Calculate number of UBI devices */  	do {  		char dir[20]; @@ -186,7 +181,6 @@ ubi_dump_handler(ubi_lib_t desc)  	ubi_lib_t d = desc;  	printf(	"UBI Library Descriptor:\n"  		"ubi_root:	 %s\n" -		"nlen_max:	 %s\n"  		"version:	 %s\n"  		"cdev_path:	 %s\n"  		"udev_path:	 %s\n" @@ -204,12 +198,12 @@ ubi_dump_handler(ubi_lib_t desc)  		"vol_type_path:	 %s\n"  		"vol_name_path:	 %s\n"  		"cdev_path_len:	 %d\n\n", -	       d->ubi_root, d->nlen_max, d->version, d->cdev_path, -	       d->udev_path, d->wear_path, d->vol_count_path, -	       d->tot_ebs_path, d->avail_ebs_path, d->eb_size_path, -	       d->nums_path, d->vol_cdev_path, d->vdev_path, -	       d->vol_nums_path, d->vol_bytes_path, d->vol_ebs_path, -	       d->vol_type_path, d->vol_name_path, d->cdev_path_len); +	       d->ubi_root, d->version, d->cdev_path, d->udev_path, +	       d->wear_path, d->vol_count_path, d->tot_ebs_path, +	       d->avail_ebs_path, d->eb_size_path, d->nums_path, +	       d->vol_cdev_path, d->vdev_path, d->vol_nums_path, +	       d->vol_bytes_path, d->vol_ebs_path, d->vol_type_path, +	       d->vol_name_path, d->cdev_path_len);  }  int @@ -281,11 +275,7 @@ ubi_open(ubi_lib_t *desc)  	if (!res->ubi_root)  		goto error; -	res->nlen_max = mkpath(res->ubi_root, UBI_NLEN_MAX); -	if (!res->nlen_max) -		goto error; - -	res->version =	mkpath(res->ubi_root, UBI_VERSION); +	res->version =	mkpath(res->ubi_root, UBI_VER);  	if (!res->version)  		goto error; @@ -394,7 +384,6 @@ ubi_close(ubi_lib_t *desc)  	free(tmp->udev_path);  	free(tmp->cdev_path);  	free(tmp->version); -	free(tmp->nlen_max);  	free(tmp->ubi_root);  	free(tmp->sysfs_root);  	free(tmp); @@ -486,7 +475,7 @@ ubi_get_vol_info(ubi_lib_t desc, unsigned int devn, unsigned int vol_id,  	int err;  	int len;  	char buf1[10]; -	char buf2[desc->ubi.nlen_max]; +	char buf2[UBI_MAX_VOLUME_NAME];  	err = sysfs_read_dev_subst(desc->vol_nums_path, &req->major,  				   &req->minor, 2, devn, vol_id); @@ -523,7 +512,7 @@ ubi_get_vol_info(ubi_lib_t desc, unsigned int devn, unsigned int vol_id,  	}  	len = sysfs_read_data_subst(desc->vol_name_path, &buf2[0], -				    desc->ubi.nlen_max, 2,  devn, vol_id); +				    UBI_MAX_VOLUME_NAME, 2,  devn, vol_id);  	if (len == -1)  		return -1; diff --git a/ubi-utils/src/libubi_int.h b/ubi-utils/src/libubi_int.h index ab387f5..830a682 100644 --- a/ubi-utils/src/libubi_int.h +++ b/ubi-utils/src/libubi_int.h @@ -1,5 +1,3 @@ -#ifndef __UBI_INT_H__ -#define __UBI_INT_H__  /*   * Copyright (c) International Business Machines Corp., 2006   * @@ -24,6 +22,8 @@   * Author: Artem B. Bityutskiy   */ +#ifndef __UBI_INT_H__ +#define __UBI_INT_H__  /*   * Enable/disable UBI library debugging messages.   */ @@ -58,7 +58,7 @@   * @def UBI_NLEN_MAX   *	@brief Name of syfs file containing the maximum UBI volume name length.   * - * @def UBI_VERSION + * @def UBI_VER   *      @brief Name of sysfs file containing UBI version.   *   * @def UBI_WEAR @@ -98,7 +98,7 @@   **/  #define UBI_ROOT	"ubi"  #define UBI_NLEN_MAX	"volume_name_max" -#define UBI_VERSION	"version" +#define UBI_VER		"version"  #define UBI_WEAR	"wear"  #define UBI_VOL_COUNT	"volumes_count"  #define UBI_TOT_EBS	"total_eraseblocks" diff --git a/ubi-utils/src/ubimkvol.c b/ubi-utils/src/ubimkvol.c index 30c569c..d35d2f3 100644 --- a/ubi-utils/src/ubimkvol.c +++ b/ubi-utils/src/ubimkvol.c @@ -19,13 +19,16 @@  /*   * An utility to create UBI volumes.   * - * Author: Artem B. Bityutskiy <dedekind@oktetlabs.ru> + * Author: Artem B. Bityutskiy <dedekind@linutronix.de> + *         Frank Haverkamp <haver@vnet.ibm.com>   *   * 1.0 Initial release   * 1.1 Does not support erase blocks anymore. This is replaced by   *     the number of bytes. + * 1.2 Reworked the user-interface to use argp.   */ +#include <argp.h>  #include <stdio.h>  #include <stdint.h>  #include <getopt.h> @@ -33,178 +36,229 @@  #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.2"  /* - * The variables below  are set by command line arguments. + * The variables below	are set by command line arguments.   */ -static int vol_type = UBI_DYNAMIC_VOLUME; -static int devn = -1; -static long long bytes = 0; -static int alignment = 1; -static int vol_id = UBI_VOL_NUM_AUTO; -static char *name = NULL; -static int nlen = 0; +struct args { +	int devn; +	int vol_id; +	int vol_type; +	long long bytes; +	int alignment; +	char *name; +	int nlen; -int main(int argc, char * const argv[]) -{ -	int err; -	ubi_lib_t lib; +	/* special stuff needed to get additional arguments */ +	char *arg1; +	char **options;		/* [STRING...] */ +}; -	err = parse_options(argc, argv); -	if (err) { -		fprintf(stderr, "Wrong options ...\n"); -		return err == 1 ? 0 : -1; -	} +static struct args myargs = { +	.vol_type = UBI_DYNAMIC_VOLUME, +	.devn = -1, +	.bytes = 0, +	.alignment = 1, +	.vol_id = UBI_VOL_NUM_AUTO, +	.name = NULL, +	.nlen = 0, +}; -	if (devn == -1) { -		fprintf(stderr, "Device number was not specified\n"); -		fprintf(stderr, "Use -h option for help\n"); -		return -1; -	} +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; -	err = ubi_open(&lib); -	if (err) { -		perror("Cannot open libubi"); -		return -1; -	} +static char doc[] = "\nVersion: " VERSION "\n\t" +	BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" +	"\nMake UBI Volume.\n"; -	err = param_sanity_check(lib); -	if (err) { -		perror("Input parameters check"); -		fprintf(stderr, "Use -h option for help\n"); -		goto out_libubi; -	} +static struct argp_option options[] = { +	{ .name = "devn", +	  .key = 'd', +	  .arg = "<devn>", +	  .flags = 0, +	  .doc = "UBI device", +	  .group = OPTION_ARG_OPTIONAL }, -	err = ubi_mkvol(lib, devn, vol_id, vol_type, bytes, alignment, name); -	if (err < 0) { -		perror("Cannot create volume"); -		fprintf(stderr, "  err=%d\n", err); -		goto out_libubi; -	} +	{ .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 }, -	/* printf("Created volume %d, %lld bytes, type %s, name %s\n", -	   vol_id, bytes, vol_type == UBI_DYNAMIC_VOLUME ? -	   "dynamic" : "static", name); */ +	{ .name = "type", +	  .key = 't', +	  .arg = "<static|dynamic>", +	  .flags = 0, +	  .doc = "volume type (dynamic, static), default is dynamic", +	  .group = OPTION_ARG_OPTIONAL }, -	vol_id = err; -	ubi_close(&lib); -	return 0; +	{ .name = "size", +	  .key = 's', +	  .arg = "<bytes>", +	  .flags = 0, +	  .doc = "volume size volume size in bytes, " +	  "kilobytes (KiB) or megabytes (MiB)", +	  .group = OPTION_ARG_OPTIONAL }, -out_libubi: -	ubi_close(&lib); -	return -1; -} +	{ .name = "name", +	  .key = 'N', +	  .arg = "<name>", +	  .flags = 0, +	  .doc = "volume name", +	  .group = OPTION_ARG_OPTIONAL }, + +	{ .name = "alignment", +	  .key = 'a', +	  .arg = "<alignment>", +	  .flags = 0, +	  .doc = "volume alignment (default is 1)", +	  .group = OPTION_ARG_OPTIONAL }, -/* 'getopt()' option string */ -static const char *optstring = "ht:s:n:N:d:a:"; +	{ .name = NULL, .key = 0, .arg = NULL, .flags = 0, +	  .doc = NULL, .group = 0 }, +}; -static int parse_options(int argc, char * const argv[]) +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)  { -	int opt = 0; - -	while (opt != -1) { -		char *endp; - -		opt = getopt(argc, argv, optstring); - -		switch (opt) { -		case 'h': -			usage(); -			return 1; -		case 't': -			if (!strcmp(optarg, "dynamic")) -				vol_type = UBI_DYNAMIC_VOLUME; -			else if (!strcmp(optarg, "static")) -				vol_type = UBI_STATIC_VOLUME; -			else { -				fprintf(stderr, "Bad volume type: \"%s\"\n", -					optarg); -				goto out; -			} -			break; -		case 's': -			bytes = strtoull(optarg, &endp, 0); -			if (endp == optarg || bytes < 0) { -				fprintf(stderr, "Bad volume size: \"%s\"\n", -					optarg); -				goto out; -			} -			if (endp != '\0') { -				if (strcmp(endp, "KiB") == 0) -					bytes *= 1024; -				else if (strcmp(endp, "MiB") == 0) -					bytes *= 1024*1024; -			} -			break; -		case 'a': -			alignment = strtoul(optarg, &endp, 0); -			if (*endp != '\0' || endp == optarg || -			    alignment <= 0) { -				fprintf(stderr, "Bad volume alignment: " -					"\"%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 'n': -			vol_id = strtoul(optarg, &endp, 0); -			if (*endp != '\0' || endp == optarg || -			    (vol_id < 0 && vol_id != UBI_DYNAMIC_VOLUME)) { -				fprintf(stderr, "Bad volume ID: " -					"\"%s\"\n", optarg); -				goto out; -			} -			break; -		case 'N': -			name = optarg; -			nlen = strlen(name); -			break; - -		case ':': -			fprintf(stderr, "Parameter is missing\n"); +	char *endp; +	struct args *args = state->input; + +	switch (key) { +	case 't': +		if (!strcmp(optarg, "dynamic")) +			args->vol_type = UBI_DYNAMIC_VOLUME; +		else if (!strcmp(optarg, "static")) +			args->vol_type = UBI_STATIC_VOLUME; +		else { +			fprintf(stderr, "Bad volume type: \"%s\"\n", +				optarg);  			goto out; -		case '?': -			fprintf(stderr, "Unknown parameter\n"); +		} +		break; +	case 's': +		args->bytes = strtoull(optarg, &endp, 0); +		if (endp == optarg || args->bytes < 0) { +			fprintf(stderr, "Bad volume size: \"%s\"\n", +				optarg);  			goto out; -		case -1: -			break; -		default: -			fprintf(stderr, "Internal error\n"); +		} +		if (endp != '\0') { +			if (strcmp(endp, "KiB") == 0) +				args->bytes *= 1024; +			else if (strcmp(endp, "MiB") == 0) +				args->bytes *= 1024*1024; +		} +		break; +	case 'a': +		args->alignment = strtoul(optarg, &endp, 0); +		if (*endp != '\0' || endp == optarg || +		    args->alignment <= 0) { +			fprintf(stderr, "Bad volume alignment: " +				"\"%s\"\n", optarg);  			goto out;  		} +		break; +	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 'N': +		args->name = optarg; +		args->nlen = strlen(args->name); +		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: -	errno = EINVAL; -	return -1; +	return(ARGP_ERR_UNKNOWN);  } -static int param_sanity_check(ubi_lib_t lib) +static int param_sanity_check(struct args *args, ubi_lib_t lib)  {  	int err, len;  	struct ubi_info ubi; -	if (bytes == 0) { +	if (args->bytes == 0) {  		fprintf(stderr, "Volume size was not specified\n");  		goto out;  	} -	if (name == NULL) { +	if (args->name == NULL) {  		fprintf(stderr, "Volume name was not specified\n");  		goto out;  	} @@ -213,39 +267,72 @@ static int param_sanity_check(ubi_lib_t lib)  	if (err)  		return -1; -	if (devn >= (int)ubi.dev_count) { -		fprintf(stderr, "Device %d does not exist\n", devn); +	if (args->devn >= (int)ubi.dev_count) { +		fprintf(stderr, "Device %d does not exist\n", args->devn);  		goto out;  	} -	len = strlen(name); -	if (len > (int)ubi.nlen_max) { +	len = strlen(args->name); +	if (len > UBI_MAX_VOLUME_NAME) {  		fprintf(stderr, "Too long name (%d symbols), max is %d\n", -			len, ubi.nlen_max); +			len, UBI_MAX_VOLUME_NAME);  		goto out;  	}  	return 0; -  out:  	errno = EINVAL;  	return -1;  } -static void usage(void) +int main(int argc, char * const argv[])  { -	printf("Usage: ubi_mkvol OPTIONS\n" -	       "Version: " PACKAGE_VERSION "\n" -	       "The command line options:\n" -	       "\t-h - this help message\n" -	       "\t-d - UBI device number\n" -	       "\t-t TYPE  - volume type (dynamic, static) " -	       "(default is dynamic)\n" -	       "\t-n VOLID - volume ID to assign to the new volume. If not" -	       "specified, \n" -	       "\t           the volume ID will be assigned automatically\n" -	       "\t-s BYTES - volume size in bytes, " -	       "kilobytes (KiB) or megabytes (MiB)\n" -	       "\t-N NAME  - volume name\n" -	       "\t-a ALIGNMENT - volume alignment (default is 1)\n"); +	int err; +	ubi_lib_t lib; + +	err = argp_parse(&argp, argc, (char **)argv, ARGP_IN_ORDER, 0, +			 &myargs); +	if (err) { +		fprintf(stderr, "Wrong options ...\n"); +		return err == 1 ? 0 : -1; +	} + +	if (myargs.devn == -1) { +		fprintf(stderr, "Device number was not specified\n"); +		fprintf(stderr, "Use -h option for help\n"); +		return -1; +	} + +	err = ubi_open(&lib); +	if (err) { +		perror("Cannot open libubi"); +		return -1; +	} + +	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_mkvol(lib, myargs.devn, myargs.vol_id, myargs.vol_type, +			myargs.bytes, myargs.alignment, myargs.name); +	if (err < 0) { +		perror("Cannot create volume"); +		fprintf(stderr, "  err=%d\n", err); +		goto out_libubi; +	} + +	/* printf("Created volume %d, %lld bytes, type %s, name %s\n", +	   vol_id, bytes, vol_type == UBI_DYNAMIC_VOLUME ? +	   "dynamic" : "static", name); */ + +	myargs.vol_id = err; +	ubi_close(&lib); +	return 0; + +out_libubi: +	ubi_close(&lib); +	return -1;  } 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"); -} diff --git a/ubi-utils/src/ubiupdatevol.c b/ubi-utils/src/ubiupdatevol.c index 28e1e8f..fd68dd8 100644 --- a/ubi-utils/src/ubiupdatevol.c +++ b/ubi-utils/src/ubiupdatevol.c @@ -14,14 +14,16 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to update UBI volumes.   *   * Author: Frank Haverkamp   * - * An utility to update UBI volumes. + * 1.0 Reworked the userinterface to use argp.   */ -#include <config.h> -  #include <argp.h>  #include <errno.h>  #include <fcntl.h> @@ -36,15 +38,18 @@  #include <sys/stat.h>  #include <sys/types.h> +#include <config.h>  #include <libubi.h> +#define VERSION "1.0" +  #define MAXPATH		1024  #define BUFSIZE		128 * 1024  #define MIN(x,y)	((x)<(y)?(x):(y))  struct args { -	int device; -	int volume; +	int devn; +	int vol_id;  	int truncate;  	int broken_update;  	int bufsize; @@ -55,8 +60,8 @@ struct args {  };  static struct args myargs = { -	.device = -1, -	.volume = -1, +	.devn = -1, +	.vol_id = -1,  	.truncate = 0,  	.broken_update = 0,  	.bufsize = BUFSIZE, @@ -64,25 +69,24 @@ static struct args myargs = {  	.options = NULL,  }; -static int verbose = 0; -  static error_t parse_opt (int key, char *arg, struct argp_state *state); +static int verbose = 0;  const char *argp_program_bug_address = PACKAGE_BUGREPORT; -static char doc[] = "\nVersion: " PACKAGE_VERSION "\n\t" +static char doc[] = "\nVersion: " VERSION "\n\t"  	BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n"  	"\nWrite to UBI Volume.\n";  static struct argp_option options[] = { -	{ .name = "device", +	{ .name = "devn",  	  .key = 'd', -	  .arg = "<device number>", +	  .arg = "<devn>",  	  .flags = 0,  	  .doc = "UBI device",  	  .group = OPTION_ARG_OPTIONAL }, -	{ .name = "volume", +	{ .name = "vol_id",  	  .key = 'n',  	  .arg = "<volume id>",  	  .flags = 0, @@ -139,8 +143,12 @@ parse_opt(int key, char *arg, struct argp_state *state)  		verbose = strtoul(arg, (char **)NULL, 0);  		break; -	case 'd': /* --device=<device number> */ -		args->device = strtol(arg, (char **)NULL, 0); +	case 'n': /* --vol_id=<volume id> */ +		args->vol_id = strtol(arg, (char **)NULL, 0); +		break; + +	case 'd': /* --devn=<device number> */ +		args->devn = strtol(arg, (char **)NULL, 0);  		break;  	case 'b': /* --bufsize=<bufsize> */ @@ -157,10 +165,6 @@ parse_opt(int key, char *arg, struct argp_state *state)  		args->broken_update = 1;  		break; -	case 'n': /* --volume=<volume id> */ -		args->volume = strtol(arg, (char **)NULL, 0); -		break; -  	case ARGP_KEY_NO_ARGS:  		/* argp_usage(state); */  		break; @@ -175,8 +179,8 @@ parse_opt(int key, char *arg, struct argp_state *state)                     arguments->strings.                     _In addition_, by setting `state->next' to the end -                   of the arguments, we can force argp to stop parsing here and -                   return. */ +                   of the arguments, we can force argp to stop parsing +                   here and return. */  		args->options = &state->argv[state->next];  		state->next = state->argc; @@ -205,7 +209,7 @@ ubi_truncate_volume(struct args *args, int64_t bytes)  	char path[MAXPATH];  	int old_errno; -	snprintf(path, MAXPATH-1, "/dev/ubi%d_%d", args->device, args->volume); +	snprintf(path, MAXPATH-1, "/dev/ubi%d_%d", args->devn, args->vol_id);  	path[MAXPATH-1] = '\0';  	ofd = open(path, O_RDWR); @@ -279,7 +283,7 @@ ubi_update_volume(struct args *args)  	if (!ifp)  		exit(EXIT_FAILURE); -	snprintf(path, MAXPATH-1, "/dev/ubi%d_%d", args->device, args->volume); +	snprintf(path, MAXPATH-1, "/dev/ubi%d_%d", args->devn, args->vol_id);  	path[MAXPATH-1] = '\0';  	ofd = open(path, O_RDWR); | 
