From 6ccd7242c4c1404dafb64cd937adc3c65ce02385 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 21 Jun 2006 14:26:02 +0200 Subject: [MTD] UBI: Removed automake, autoconf, added ubi userspace headers. Signed-off-by: Frank Haverkamp --- ubi-utils/src/ubirmvol.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 ubi-utils/src/ubirmvol.c (limited to 'ubi-utils/src/ubirmvol.c') diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c new file mode 100644 index 0000000..cb47b6c --- /dev/null +++ b/ubi-utils/src/ubirmvol.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * 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 create UBI volumes. + * + * Autor: Artem B. Bityutskiy + */ + +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include + +static void usage(void); +static int param_sanity_check(ubi_lib_t lib); +static int parse_options(int argc, char * const argv[]); + +/* + * The below variables are set by command line options. + */ +static int vol_id = -1; +static int devn = -1; + +int main(int argc, char * const argv[]) +{ + int err, old_errno; + ubi_lib_t lib; + + err = parse_options(argc, argv); + if (err) + return err == 1 ? 0 : -1; + + if (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(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); + old_errno = errno; + if (err < 0) { + perror("Cannot remove volume"); + fprintf(stderr, " err=%d errno=%d\n", err, old_errno); + goto out_libubi; + } + + return 0; + +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"); +} -- cgit v1.2.3 From faa7699bf15b9a08b1b2658745314ae8f63878a2 Mon Sep 17 00:00:00 2001 From: "dedekind@linutronix.de" Date: Fri, 30 Jun 2006 14:05:25 +0200 Subject: [MTD] UBI: Adaptations to new driver, reworked frontend --- include/mtd/ubi-header.h | 21 +-- include/mtd/ubi-user.h | 7 +- ubi-utils/src/config.h | 4 +- ubi-utils/src/libubi.c | 31 ++-- ubi-utils/src/libubi_int.h | 8 +- ubi-utils/src/ubimkvol.c | 405 ++++++++++++++++++++++++++----------------- ubi-utils/src/ubirmvol.c | 267 +++++++++++++++++----------- ubi-utils/src/ubiupdatevol.c | 50 +++--- 8 files changed, 470 insertions(+), 323 deletions(-) (limited to 'ubi-utils/src/ubirmvol.c') diff --git a/include/mtd/ubi-header.h b/include/mtd/ubi-header.h index 12ce1c9..ca96fc9 100644 --- a/include/mtd/ubi-header.h +++ b/include/mtd/ubi-header.h @@ -41,7 +41,7 @@ /* The initial CRC32 value used when calculating CRC checksums */ #define UBI_CRC32_INIT 0xFFFFFFFFU -/** +/* * Magic numbers of the UBI headers. * * @UBI_EC_HDR_MAGIC: erase counter header magic number (ASCII "UBI#") @@ -52,7 +52,7 @@ enum { UBI_VID_HDR_MAGIC = 0x55424921 }; -/** +/* * Molume type constants used in volume identifier headers. * * @UBI_VID_DYNAMIC: dynamic volume @@ -63,23 +63,19 @@ enum { UBI_VID_STATIC = 2 }; -/** +/* * Compatibility constants used by internal volumes. * * @UBI_COMPAT_DELETE: delete this internal volume before anything is written * to the flash * @UBI_COMPAT_RO: attach this device in read-only mode - * @UBI_COMPAT_IGNORE: ignore this internal volume, but the UBI wear-leveling - * unit may still move these logical eraseblocks to ensure wear-leveling * @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its - * physical eraseblocks, don't even allow the wear-leveling unit to move - * them + * physical eraseblocks, don't allow the wear-leveling unit to move them * @UBI_COMPAT_REJECT: reject this UBI image */ enum { UBI_COMPAT_DELETE = 1, UBI_COMPAT_RO = 2, - UBI_COMPAT_IGNORE = 3, UBI_COMPAT_PRESERVE = 4, UBI_COMPAT_REJECT = 5 }; @@ -281,7 +277,7 @@ struct ubi_vid_hdr { */ struct ubi_vid_hdr_upd_vol { ubi32_t vol_id; - uint8_t padding[UBI_VID_HDR_IVOL_DATA_SIZE - 4]; + uint8_t padding[UBI_VID_HDR_IVOL_DATA_SIZE-4]; } __attribute__ ((packed)); /* @@ -295,13 +291,13 @@ struct ubi_vid_hdr_upd_vol { */ #define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096) -/** +/* * enum ubi_internal_volume_numbers - volume IDs of internal UBI volumes. * * %UBI_LAYOUT_VOL_ID: volume ID of the layout volume * %UBI_UPDATE_VOL_ID: volume ID of the update volume */ -enum ubi_internal_volume_ids { +enum { UBI_LAYOUT_VOL_ID = UBI_INTERNAL_VOL_START, UBI_UPDATE_VOL_ID = UBI_INTERNAL_VOL_START + 1 }; @@ -351,6 +347,7 @@ enum ubi_internal_volume_ids { * @alignment: volume alignment * @data_pad: how many bytes are not used at the end of the eraseblocks to * satisfy the requested alignment + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) * @padding1: reserved, zeroes * @name_len: the volume name length * @name: the volume name @@ -382,7 +379,7 @@ struct ubi_vol_tbl_record { uint8_t vol_type; uint8_t padding1; ubi16_t name_len; - uint8_t name[UBI_VOL_NAME_MAX + 1]; + uint8_t name[UBI_VOL_NAME_MAX+1]; uint8_t padding2[24]; ubi32_t crc; } __attribute__ ((packed)); diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index 161f674..0eb1470 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -32,6 +32,9 @@ */ #define UBI_VOL_NUM_AUTO (-1) +/* Maximum volume name length */ +#define UBI_MAX_VOLUME_NAME 127 + /* * IOCTL commands of UBI character devices */ @@ -56,7 +59,7 @@ /* An eraseblock erasure command, used for debugging, disabled by dafault */ #define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 0, int32_t) -/** +/* * UBI volume type constants. * * @UBI_DYNAMIC_VOLUME: dynamic volume @@ -113,7 +116,7 @@ struct ubi_mkvol_req { * * @vol_id: ID of the volume to re-size * @bytes: new size of the volume in bytes - * + * * Re-sizing is possible for both dynamic and static volumes. But while dynamic * volumes may be re-sized arbitrarily, static volumes cannot be made to be * smaller then the number of bytes they bear. To arbitrarily shrink a static 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 #include #include +#include #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 + * Author: Artem B. Bityutskiy + * Frank Haverkamp * * 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 #include #include #include @@ -33,178 +36,229 @@ #include #include -#include "config.h" +#include #include -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 = "", + .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 = "", + .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 = "", + .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 = "", + .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 = "", + .flags = 0, + .doc = "volume name", + .group = OPTION_ARG_OPTIONAL }, + + { .name = "alignment", + .key = 'a', + .arg = "", + .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= */ + 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= */ + 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 + * Author: Artem B. Bityutskiy + * Frank Haverkamp + * + * 1.1 Reworked the userinterface to use argp. */ +#include #include #include #include @@ -29,29 +33,180 @@ #include #include -#include "config.h" +#include #include -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 = "", + .flags = 0, + .doc = "UBI device", + .group = OPTION_ARG_OPTIONAL }, + + { .name = "vol_id", + .key = 'n', + .arg = "", + .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= */ + 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= */ + 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 - #include #include #include @@ -36,15 +38,18 @@ #include #include +#include #include +#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 = "", + .arg = "", .flags = 0, .doc = "UBI device", .group = OPTION_ARG_OPTIONAL }, - { .name = "volume", + { .name = "vol_id", .key = 'n', .arg = "", .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= */ - args->device = strtol(arg, (char **)NULL, 0); + case 'n': /* --vol_id= */ + args->vol_id = strtol(arg, (char **)NULL, 0); + break; + + case 'd': /* --devn= */ + args->devn = strtol(arg, (char **)NULL, 0); break; case 'b': /* --bufsize= */ @@ -157,10 +165,6 @@ parse_opt(int key, char *arg, struct argp_state *state) args->broken_update = 1; break; - case 'n': /* --volume= */ - 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); -- cgit v1.2.3 From c474d44341b1ab9b1b39cf2bbf8686a610b54614 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Fri, 30 Jun 2006 14:28:31 +0200 Subject: [MTD] UBI: Fixed program versions --- ubi-utils/src/ubimkvol.c | 6 ++++-- ubi-utils/src/ubirmvol.c | 6 ++++-- ubi-utils/src/ubiupdatevol.c | 5 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'ubi-utils/src/ubirmvol.c') diff --git a/ubi-utils/src/ubimkvol.c b/ubi-utils/src/ubimkvol.c index d35d2f3..04b7fb5 100644 --- a/ubi-utils/src/ubimkvol.c +++ b/ubi-utils/src/ubimkvol.c @@ -39,7 +39,7 @@ #include #include -#define VERSION "1.2" +#define PROGRAM_VERSION "1.2" /* * The variables below are set by command line arguments. @@ -70,9 +70,11 @@ static struct args myargs = { 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_version = PROGRAM_VERSION; const char *argp_program_bug_address = PACKAGE_BUGREPORT; -static char doc[] = "\nVersion: " VERSION "\n\t" +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t" BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" "\nMake UBI Volume.\n"; diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c index f810263..43679bc 100644 --- a/ubi-utils/src/ubirmvol.c +++ b/ubi-utils/src/ubirmvol.c @@ -36,7 +36,7 @@ #include #include -#define VERSION "1.1" +#define PROGRAM_VERSION "1.1" /* * The below variables are set by command line options. @@ -60,9 +60,11 @@ static struct args myargs = { 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_version = PROGRAM_VERSION; const char *argp_program_bug_address = PACKAGE_BUGREPORT; -static char doc[] = "\nVersion: " VERSION "\n\t" +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t" BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" "\nMake UBI Volume.\n"; diff --git a/ubi-utils/src/ubiupdatevol.c b/ubi-utils/src/ubiupdatevol.c index fd68dd8..dcb7399 100644 --- a/ubi-utils/src/ubiupdatevol.c +++ b/ubi-utils/src/ubiupdatevol.c @@ -41,7 +41,7 @@ #include #include -#define VERSION "1.0" +#define PROGRAM_VERSION "1.0" #define MAXPATH 1024 #define BUFSIZE 128 * 1024 @@ -72,9 +72,10 @@ static struct args myargs = { static error_t parse_opt (int key, char *arg, struct argp_state *state); static int verbose = 0; +const char *argp_program_version = PROGRAM_VERSION; const char *argp_program_bug_address = PACKAGE_BUGREPORT; -static char doc[] = "\nVersion: " VERSION "\n\t" +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t" BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" "\nWrite to UBI Volume.\n"; -- cgit v1.2.3 From 5f758f67b71d15c22aedcdd094390e71664a7afe Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Mon, 11 Dec 2006 14:34:23 +0100 Subject: [PATCH 10/13] Convert ubirmvol to use getopt option parsing Signed-off-by: Josh Boyer Acked-by: Frank Haverkamp --- ubi-utils/src/ubirmvol.c | 157 +++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 88 deletions(-) (limited to 'ubi-utils/src/ubirmvol.c') diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c index 43679bc..69e4d0e 100644 --- a/ubi-utils/src/ubirmvol.c +++ b/ubi-utils/src/ubirmvol.c @@ -25,7 +25,6 @@ * 1.1 Reworked the userinterface to use argp. */ -#include #include #include #include @@ -38,6 +37,9 @@ #define PROGRAM_VERSION "1.1" +extern char *optarg; +extern int optind; + /* * The below variables are set by command line options. */ @@ -59,43 +61,30 @@ static struct args myargs = { }; 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_version = PROGRAM_VERSION; -const char *argp_program_bug_address = PACKAGE_BUGREPORT; static char doc[] = "\nVersion: " PROGRAM_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 = "", - .flags = 0, - .doc = "UBI device", - .group = OPTION_ARG_OPTIONAL }, - - { .name = "vol_id", - .key = 'n', - .arg = "", - .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, +static const char *optionsstr = +" -d, --devn= UBI device\n" +" -n, --vol_id= UBI volume id, if not specified, the volume ID\n" +" will be assigned automatically\n" +" -?, --help Give this help list\n" +" --usage Give a short usage message\n" +" -V, --version Print program version\n"; + +static const char *usage = +"Usage: ubirmvol [-?V] [-d ] [-n ] [--devn=]\n" +" [--vol_id=] [--help] [--usage] [--version]\n"; + +struct option long_options[] = { + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, + { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0} }; /* @@ -110,66 +99,59 @@ static struct argp argp = { * 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) +static int +parse_opt(int argc, char **argv, struct args *args) { char *endp; - struct args *args = state->input; - - switch (key) { - case 'd': /* --devn= */ - 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= */ - 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); + while (1) { + int key; + + key = getopt_long(argc, argv, "d:n:?V", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'd': /* --devn= */ + 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= */ + 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 '?': /* help */ + fprintf(stderr, "Usage: ubirmvol [OPTION...]\n"); + fprintf(stderr, "%s", doc); + fprintf(stderr, "%s", optionsstr); + fprintf(stderr, "\nReport bugs to %s\n", PACKAGE_BUGREPORT); + exit(0); + break; + case 'V': + fprintf(stderr, "%s\n", PACKAGE_VERSION); + exit(0); + break; + default: + fprintf(stderr, "%s", usage); + exit(-1); + } } return 0; out: - return(ARGP_ERR_UNKNOWN); + return -1; } static int param_sanity_check(struct args *args, ubi_lib_t lib) @@ -203,8 +185,7 @@ int main(int argc, char * const argv[]) int err, old_errno; ubi_lib_t lib; - err = argp_parse(&argp, argc, (char **)argv, ARGP_IN_ORDER, 0, - &myargs); + err = parse_opt(argc, (char **)argv, &myargs); if (err) return err == 1 ? 0 : -1; -- cgit v1.2.3 From da59698ccf81a1df3a250edb81a91f1b8a3decf0 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Mon, 11 Dec 2006 14:34:23 +0100 Subject: [MTD] UBI Utils: Tools should have individual version numbers The tools had a mixture of different version numbers. This is changed now. The internal change to move to remove glibc dependencies should be reflected by an increase of the version number, so that we can react if trouble is seen with the new code. Singed-off-by: Frank Haverkamp --- ubi-utils/src/bin2nand.c | 24 +++++++++++++++--------- ubi-utils/src/config.h | 4 ++-- ubi-utils/src/mkbootenv.c | 19 ++++++++++++------- ubi-utils/src/nand2bin.c | 12 +++++++++--- ubi-utils/src/pddcustomize.c | 22 +++++++++++++++------- ubi-utils/src/pfi2bin.c | 9 ++++++--- ubi-utils/src/pfiflash.c | 2 +- ubi-utils/src/ubigen.c | 35 +++++++++++++++++++++-------------- ubi-utils/src/ubimirror.c | 17 ++++++++++++----- ubi-utils/src/ubimkvol.c | 16 ++++++++++------ ubi-utils/src/ubirmvol.c | 11 +++++++---- ubi-utils/src/ubiupdatevol.c | 2 +- ubi-utils/src/unubi.c | 4 +++- 13 files changed, 114 insertions(+), 63 deletions(-) (limited to 'ubi-utils/src/ubirmvol.c') diff --git a/ubi-utils/src/bin2nand.c b/ubi-utils/src/bin2nand.c index df838af..4bab1ad 100644 --- a/ubi-utils/src/bin2nand.c +++ b/ubi-utils/src/bin2nand.c @@ -22,10 +22,11 @@ * Create a flashable NAND image from a binary image * * History: - * 1.0: Initial release (tglx) - * 1.1: Understands hex and dec input parameters (tglx) - * 1.2: Generates separated OOB data, if needed. (oloh) - * 1.3: Padds data/oob to a given size. (oloh) + * 1.0 Initial release (tglx) + * 1.1 Understands hex and dec input parameters (tglx) + * 1.2 Generates separated OOB data, if needed. (oloh) + * 1.3 Padds data/oob to a given size. (oloh) + * 1.4 Removed argp because we want to use uClibc. */ #include @@ -44,6 +45,8 @@ #include "config.h" #include "nandecc.h" +#define PROGRAM_VERSION "1.4" + #define CHECK_ENDP(option, endp) do { \ if (*endp) { \ fprintf(stderr, \ @@ -65,7 +68,7 @@ typedef enum action_t { extern char *optarg; extern int optind; -static char doc[] = "\nVersion: " PACKAGE_VERSION "\n\tBuilt on " +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" "\n" "bin2nand - a tool for adding OOB information to a " @@ -153,11 +156,13 @@ parse_opt(int argc, char **argv, myargs *args) switch (key) { case 'p': /* pagesize */ - args->pagesize = (size_t) ustrtoull(optarg, &endp, 0); + args->pagesize = (size_t) + ustrtoull(optarg, &endp, 0); CHECK_ENDP("p", endp); break; case 'j': /* padding */ - args->padding = (size_t) ustrtoull(optarg, &endp, 0); + args->padding = (size_t) + ustrtoull(optarg, &endp, 0); CHECK_ENDP("j", endp); break; case 'o': /* output */ @@ -172,7 +177,7 @@ parse_opt(int argc, char **argv, myargs *args) exit(0); break; case 'V': - printf("%s\n", PACKAGE_VERSION); + printf("%s\n", PROGRAM_VERSION); exit(0); break; case 'c': @@ -187,7 +192,8 @@ parse_opt(int argc, char **argv, myargs *args) if (optind < argc) { args->fp_in = fopen(argv[optind++], "rb"); if ((args->fp_in) == NULL) { - err_quit("Cannot open file %s for input\n", argv[optind++]); + err_quit("Cannot open file %s for input\n", + argv[optind++]); } } diff --git a/ubi-utils/src/config.h b/ubi-utils/src/config.h index b5bbd5b..8c4dd54 100644 --- a/ubi-utils/src/config.h +++ b/ubi-utils/src/config.h @@ -20,8 +20,8 @@ * Author: Frank Haverkamp */ -#define PACKAGE_VERSION "1.1" -#define PACKAGE_BUGREPORT "haver@vnet.ibm.com, dedekind@linutronix.de, or tglx@linutronix.de" +#define PACKAGE_BUGREPORT \ + "haver@vnet.ibm.com, dedekind@linutronix.de, or tglx@linutronix.de" #define __unused __attribute__((unused)) diff --git a/ubi-utils/src/mkbootenv.c b/ubi-utils/src/mkbootenv.c index a556939..c05f4e2 100644 --- a/ubi-utils/src/mkbootenv.c +++ b/ubi-utils/src/mkbootenv.c @@ -18,6 +18,8 @@ * Author: Oliver Lohmann * * Create boot-parameter/pdd data from an ASCII-text input file. + * + * 1.2 Removed argp because we want to use uClibc. */ #include @@ -32,10 +34,12 @@ #include "bootenv.h" #include "error.h" +#define PROGRAM_VERSION "1.2" + extern char *optarg; extern int optind; -static char doc[] = "\nVersion: " PACKAGE_VERSION "\n\tBuilt on " +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" "\n" "mkbootenv - processes bootenv text files and convertes " @@ -91,19 +95,20 @@ parse_opt(int argc, char **argv, myargs *args) case 'o': args->fp_out = fopen(optarg, "wb"); if ((args->fp_out) == NULL) { - fprintf(stderr, - "Cannot open file %s for output\n", optarg); + fprintf(stderr, "Cannot open file %s " + "for output\n", optarg); exit(1); } break; case '?': /* help */ printf("%s", doc); printf("%s", optionsstr); - printf("\nReport bugs to %s\n", PACKAGE_BUGREPORT); + printf("\nReport bugs to %s\n", + PACKAGE_BUGREPORT); exit(0); break; case 'V': - printf("%s\n", PACKAGE_VERSION); + printf("%s\n", PROGRAM_VERSION); exit(0); break; default: @@ -115,8 +120,8 @@ parse_opt(int argc, char **argv, myargs *args) if (optind < argc) { args->fp_in = fopen(argv[optind++], "rb"); if ((args->fp_in) == NULL) { - fprintf(stderr, - "Cannot open file %s for input\n", argv[optind]); + fprintf(stderr, "Cannot open file %s for input\n", + argv[optind]); exit(1); } } diff --git a/ubi-utils/src/nand2bin.c b/ubi-utils/src/nand2bin.c index a9b68bd..34cce40 100644 --- a/ubi-utils/src/nand2bin.c +++ b/ubi-utils/src/nand2bin.c @@ -18,7 +18,10 @@ * Author: Frank Haverkamp * * An utility to decompose NAND images and strip OOB off. Not yet finished ... + * + * 1.2 Removed argp because we want to use uClibc. */ + #include #include #include @@ -36,6 +39,8 @@ #include "config.h" #include "nandecc.h" +#define PROGRAM_VERSION "1.2" + #define MAXPATH 1024 #define MIN(x,y) ((x)<(y)?(x):(y)) @@ -60,7 +65,7 @@ static struct args myargs = { .options = NULL, }; -static char doc[] = "\nVersion: " PACKAGE_VERSION "\n\t" +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t" BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" "\nSplit data and OOB.\n"; @@ -147,12 +152,13 @@ parse_opt(int argc, char **argv, struct args *args) printf("Usage: nand2bin [OPTION...] input.mif\n"); printf("%s", doc); printf("%s", optionsstr); - printf("\nReport bugs to %s\n", PACKAGE_BUGREPORT); + printf("\nReport bugs to %s\n", + PACKAGE_BUGREPORT); exit(0); break; case 'V': - printf("%s\n", PACKAGE_VERSION); + printf("%s\n", PROGRAM_VERSION); exit(0); break; diff --git a/ubi-utils/src/pddcustomize.c b/ubi-utils/src/pddcustomize.c index 5d1864a..5c2a5f0 100644 --- a/ubi-utils/src/pddcustomize.c +++ b/ubi-utils/src/pddcustomize.c @@ -23,6 +23,8 @@ * if the system is updated and one must be able to modify them when * the system has booted the first time. This tool is intended to do * PDD modification. + * + * 1.3 Removed argp because we want to use uClibc. */ #include @@ -41,6 +43,8 @@ #include "libubi.h" #include "ubimirror.h" +#define PROGRAM_VERSION "1.3" + typedef enum action_t { ACT_NORMAL = 0, ACT_LIST, @@ -59,7 +63,7 @@ typedef enum action_t { extern char *optarg; extern int optind; -static char doc[] = "\nVersion: " PACKAGE_VERSION "\n\tBuilt on " +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" "\n" "pddcustomize - customize bootenv and pdd values.\n"; @@ -160,7 +164,8 @@ parse_opt(int argc, char **argv, myargs *args) while (1) { int key; - key = getopt_long(argc, argv, "clbxs:i:o:?V", long_options, NULL); + key = getopt_long(argc, argv, "clbxs:i:o:?V", + long_options, NULL); if (key == -1) break; @@ -182,8 +187,9 @@ parse_opt(int argc, char **argv, myargs *args) args->side = get_update_side(optarg); if (args->side < 0) { err_msg("Unsupported seqnum: %d.\n" - "Supported seqnums are '0' and '1'\n", - args->side, optarg); + "Supported seqnums are " + "'0' and '1'\n", + args->side, optarg); ERR_ARGP; } break; @@ -194,14 +200,16 @@ parse_opt(int argc, char **argv, myargs *args) args->file_out = optarg; break; case '?': /* help */ - err_msg("Usage: pddcustomize.orig [OPTION...] [key=value] [...]"); + err_msg("Usage: pddcustomize.orig [OPTION...] " + "[key=value] [...]"); err_msg("%s", doc); err_msg("%s", optionsstr); - err_msg("\nReport bugs to %s", PACKAGE_BUGREPORT); + err_msg("\nReport bugs to %s", + PACKAGE_BUGREPORT); exit(0); break; case 'V': - err_msg("%s", PACKAGE_VERSION); + err_msg("%s", PROGRAM_VERSION); exit(0); break; default: diff --git a/ubi-utils/src/pfi2bin.c b/ubi-utils/src/pfi2bin.c index 044fa24..9265fd5 100644 --- a/ubi-utils/src/pfi2bin.c +++ b/ubi-utils/src/pfi2bin.c @@ -22,6 +22,8 @@ * chips in a manufacturing step where the flashes are written before * being soldered onto the hardware. For NAND images another step is * required to add the right OOB data to the binary image. + * + * 1.3 Removed argp because we want to use uClibc. */ #include @@ -42,7 +44,7 @@ #include "peb.h" #include "crc32.h" -#define PROGRAM_VERSION "1.2" +#define PROGRAM_VERSION "1.3" #define MAX_FNAME 255 #define DEFAULT_ERASE_COUNT 0 /* Hmmm.... Perhaps */ @@ -157,12 +159,13 @@ parse_opt(int argc, char **argv, myargs *args) printf("pfi2bin [OPTION...] pfifile\n"); printf("%s", doc); printf("%s", optionsstr); - printf("\nReport bugs to %s\n", PACKAGE_BUGREPORT); + printf("\nReport bugs to %s\n", + PACKAGE_BUGREPORT); exit(0); break; case 'V': - printf("%s\n", PACKAGE_VERSION); + printf("%s\n", PROGRAM_VERSION); exit(0); break; diff --git a/ubi-utils/src/pfiflash.c b/ubi-utils/src/pfiflash.c index 259a647..63487b9 100644 --- a/ubi-utils/src/pfiflash.c +++ b/ubi-utils/src/pfiflash.c @@ -193,7 +193,7 @@ parse_opt(int argc, char **argv, myargs *args) exit(0); break; case 'V': - err_msg("%s", PACKAGE_VERSION); + err_msg("%s", PROGRAM_VERSION); exit(0); break; default: diff --git a/ubi-utils/src/ubigen.c b/ubi-utils/src/ubigen.c index 226834f..877f469 100644 --- a/ubi-utils/src/ubigen.c +++ b/ubi-utils/src/ubigen.c @@ -21,6 +21,7 @@ * * 1.0 Initial version * 1.1 Different CRC32 start value + * 1.2 Removed argp because we want to use uClibc. */ #include @@ -34,6 +35,8 @@ #include "ubigen.h" #include "config.h" +#define PROGRAM_VERSION "1.2" + typedef enum action_t { ACT_NORMAL = 0x00000001, ACT_BROKEN_UPDATE = 0x00000002, @@ -42,7 +45,7 @@ typedef enum action_t { extern char *optarg; extern int optind; -static char doc[] = "\nVersion: " PACKAGE_VERSION "\n\tBuilt on " +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" "\n" "ubigen - a tool for adding UBI information to a binary input file.\n"; @@ -187,16 +190,16 @@ parse_opt(int argc, char **argv, myargs *args) case 'o': /* output */ args->fp_out = fopen(optarg, "wb"); if ((args->fp_out) == NULL) { - fprintf(stderr, "Cannot open file %s for output\n", - optarg); + fprintf(stderr, "Cannot open file %s " + "for output\n", optarg); exit(1); } break; case 'i': /* input */ args->fp_in = fopen(optarg, "rb"); if ((args->fp_in) == NULL) { - fprintf(stderr, "Cannot open file %s for input\n", - optarg); + fprintf(stderr, "Cannot open file %s " + "for input\n", optarg); exit(1); } break; @@ -205,23 +208,26 @@ parse_opt(int argc, char **argv, myargs *args) break; case 'B': /* eb_size */ - args->eb_size = (uint32_t) ustrtoul(optarg, &endp, 0); + args->eb_size = + (uint32_t)ustrtoul(optarg, &endp, 0); CHECK_ENDP("B", endp); break; case 'E': /* erasecount */ - args->ec = (uint64_t) strtoul(optarg, &endp, 0); + args->ec = (uint64_t)strtoul(optarg, &endp, 0); CHECK_ENDP("E", endp); break; case 'I': /* id */ - args->id = (uint16_t) strtoul(optarg, &endp, 0); + args->id = (uint16_t)strtoul(optarg, &endp, 0); CHECK_ENDP("I", endp); break; case 'T': /* type */ - args->type = (uint16_t) strtoul(optarg, &endp, 0); + args->type = + (uint16_t)strtoul(optarg, &endp, 0); CHECK_ENDP("T", endp); break; case 'X': /* versionnr */ - args->version = (uint8_t) strtoul(optarg, &endp, 0); + args->version = + (uint8_t)strtoul(optarg, &endp, 0); CHECK_ENDP("X", endp); break; case 'O': /* offset for volume hdr */ @@ -241,12 +247,13 @@ parse_opt(int argc, char **argv, myargs *args) fprintf(stderr, "Usage: ubigen [OPTION...]\n"); fprintf(stderr, "%s", doc); fprintf(stderr, "%s", optionsstr); - fprintf(stderr, "\nReport bugs to %s\n", PACKAGE_BUGREPORT); + fprintf(stderr, "\nReport bugs to %s\n", + PACKAGE_BUGREPORT); exit(0); break; case 'V': - fprintf(stderr, "%s\n", PACKAGE_VERSION); + fprintf(stderr, "%s\n", PROGRAM_VERSION); exit(0); break; @@ -260,8 +267,8 @@ parse_opt(int argc, char **argv, myargs *args) if (!args->fp_in) { args->fp_in = fopen(argv[optind++], "rb"); if ((args->fp_in) == NULL) { - fprintf(stderr, - "Cannot open file %s for input\n", argv[optind]); + fprintf(stderr, "Cannot open file %s for " + "input\n", argv[optind]); exit(1); } } diff --git a/ubi-utils/src/ubimirror.c b/ubi-utils/src/ubimirror.c index 1b1d0be..533a0ee 100644 --- a/ubi-utils/src/ubimirror.c +++ b/ubi-utils/src/ubimirror.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Author: Oliver Lohmann + * + * 1.2 Removed argp because we want to use uClibc. */ #include @@ -32,6 +34,8 @@ #include "example_ubi.h" #include "ubimirror.h" +#define PROGRAM_VERSION "1.2" + typedef enum action_t { ACT_NORMAL = 0, ACT_ARGP_ABORT, @@ -51,7 +55,7 @@ typedef enum action_t { extern char *optarg; extern int optind; -static char doc[] = "\nVersion: " PACKAGE_VERSION "\n\tBuilt on " +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" "\n" "ubimirror - mirrors ubi volumes.\n"; @@ -122,19 +126,22 @@ parse_opt(int argc, char **argv, myargs *args) args->side = get_update_side(optarg); if (args->side < 0) { err_msg("Unsupported seqnum: %s.\n" - "Supported seqnums are '0' and '1'\n", optarg); + "Supported seqnums are '0' " + "and '1'\n", optarg); ERR_ARGP; } break; case '?': /* help */ - err_msg("Usage: ubimirror [OPTION...] \n"); + err_msg("Usage: ubimirror [OPTION...] " + " \n"); err_msg("%s", doc); err_msg("%s", optionsstr); - err_msg("\nReport bugs to %s\n", PACKAGE_BUGREPORT); + err_msg("\nReport bugs to %s\n", + PACKAGE_BUGREPORT); exit(0); break; case 'V': - err_msg("%s", PACKAGE_VERSION); + err_msg("%s", PROGRAM_VERSION); exit(0); break; default: diff --git a/ubi-utils/src/ubimkvol.c b/ubi-utils/src/ubimkvol.c index 7d510eb..e878d70 100644 --- a/ubi-utils/src/ubimkvol.c +++ b/ubi-utils/src/ubimkvol.c @@ -26,6 +26,7 @@ * 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. + * 1.3 Removed argp because we want to use uClibc. */ #include @@ -38,7 +39,7 @@ #include #include -#define PROGRAM_VERSION "1.2" +#define PROGRAM_VERSION "1.3" extern char *optarg; extern int optind; @@ -179,10 +180,12 @@ parse_opt(int argc, char **argv, struct args *args) break; case 'n': /* --volid= */ args->vol_id = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || - (args->vol_id < 0 && args->vol_id != UBI_DYNAMIC_VOLUME)) { + if (*endp != '\0' || + endp == optarg || + (args->vol_id < 0 && + args->vol_id != UBI_DYNAMIC_VOLUME)) { fprintf(stderr, "Bad volume ID: " - "\"%s\"\n", optarg); + "\"%s\"\n", optarg); goto out; } break; @@ -199,12 +202,13 @@ parse_opt(int argc, char **argv, struct args *args) fprintf(stderr, "Usage: ubimkvol [OPTION...]\n"); fprintf(stderr, "%s", doc); fprintf(stderr, "%s", optionsstr); - fprintf(stderr, "\nReport bugs to %s\n", PACKAGE_BUGREPORT); + fprintf(stderr, "\nReport bugs to %s\n", + PACKAGE_BUGREPORT); exit(0); break; case 'V': - fprintf(stderr, "%s\n", PACKAGE_VERSION); + fprintf(stderr, "%s\n", PROGRAM_VERSION); exit(0); break; diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c index 69e4d0e..04ec085 100644 --- a/ubi-utils/src/ubirmvol.c +++ b/ubi-utils/src/ubirmvol.c @@ -23,6 +23,7 @@ * Frank Haverkamp * * 1.1 Reworked the userinterface to use argp. + * 1.2 Removed argp because we want to use uClibc. */ #include @@ -35,7 +36,7 @@ #include #include -#define PROGRAM_VERSION "1.1" +#define PROGRAM_VERSION "1.2" extern char *optarg; extern int optind; @@ -123,7 +124,8 @@ parse_opt(int argc, char **argv, struct args *args) case 'n': /* --volid= */ args->vol_id = strtoul(optarg, &endp, 0); if (*endp != '\0' || endp == optarg || - (args->vol_id < 0 && args->vol_id != UBI_DYNAMIC_VOLUME)) { + (args->vol_id < 0 && + args->vol_id != UBI_DYNAMIC_VOLUME)) { fprintf(stderr, "Bad volume ID: " "\"%s\"\n", optarg); goto out; @@ -136,11 +138,12 @@ parse_opt(int argc, char **argv, struct args *args) fprintf(stderr, "Usage: ubirmvol [OPTION...]\n"); fprintf(stderr, "%s", doc); fprintf(stderr, "%s", optionsstr); - fprintf(stderr, "\nReport bugs to %s\n", PACKAGE_BUGREPORT); + fprintf(stderr, "\nReport bugs to %s\n", + PACKAGE_BUGREPORT); exit(0); break; case 'V': - fprintf(stderr, "%s\n", PACKAGE_VERSION); + fprintf(stderr, "%s\n", PROGRAM_VERSION); exit(0); break; default: diff --git a/ubi-utils/src/ubiupdatevol.c b/ubi-utils/src/ubiupdatevol.c index 753ad61..011d532 100644 --- a/ubi-utils/src/ubiupdatevol.c +++ b/ubi-utils/src/ubiupdatevol.c @@ -154,7 +154,7 @@ parse_opt(int argc, char **argv, struct args *args) break; case 'V': - fprintf(stderr, "%s\n", PACKAGE_VERSION); + fprintf(stderr, "%s\n", PROGRAM_VERSION); exit(0); break; diff --git a/ubi-utils/src/unubi.c b/ubi-utils/src/unubi.c index f8045d8..0f8945f 100644 --- a/ubi-utils/src/unubi.c +++ b/ubi-utils/src/unubi.c @@ -19,6 +19,8 @@ /* * Authors: Frank Haverkamp, haver@vnet.ibm.com * Drake Dowsett, dowsett@de.ibm.com + * + * 1.2 Removed argp because we want to use uClibc. */ /* @@ -51,7 +53,7 @@ #define EXEC "unubi" #define CONTACT "haver@vnet.ibm.com" -#define VERSION "0.9" +#define VERSION "1.0" extern char *optarg; extern int optind; -- cgit v1.2.3 From d45b87985d5371b2e47458ee0666f7979d5a8c21 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 12 Dec 2006 09:22:48 +0100 Subject: [PATCH] Minor ubi utils cleanups Remove getopt extern declarations Minor whitespace cleanups Remove incorrect program names that snuck in during getopt rewrite Change comments to match reality Signed-off-by: Josh Boyer Acked-by: Frank Haverkamp --- ubi-utils/src/bin2nand.c | 6 ++---- ubi-utils/src/mkbootenv.c | 6 ++---- ubi-utils/src/nand2bin.c | 14 +++++--------- ubi-utils/src/pddcustomize.c | 10 ++++------ ubi-utils/src/pfi2bin.c | 8 +++----- ubi-utils/src/pfiflash.c | 8 +++----- ubi-utils/src/ubigen.c | 8 +++----- ubi-utils/src/ubimirror.c | 6 ++---- ubi-utils/src/ubimkvol.c | 35 ++++++++++++++++++----------------- ubi-utils/src/ubirmvol.c | 25 ++++++++++++------------- ubi-utils/src/ubiupdatevol.c | 7 ++----- ubi-utils/src/unubi.c | 19 +++++++------------ 12 files changed, 63 insertions(+), 89 deletions(-) (limited to 'ubi-utils/src/ubirmvol.c') diff --git a/ubi-utils/src/bin2nand.c b/ubi-utils/src/bin2nand.c index 4bab1ad..20fc90a 100644 --- a/ubi-utils/src/bin2nand.c +++ b/ubi-utils/src/bin2nand.c @@ -27,6 +27,7 @@ * 1.2 Generates separated OOB data, if needed. (oloh) * 1.3 Padds data/oob to a given size. (oloh) * 1.4 Removed argp because we want to use uClibc. + * 1.5 Minor cleanup */ #include @@ -45,7 +46,7 @@ #include "config.h" #include "nandecc.h" -#define PROGRAM_VERSION "1.4" +#define PROGRAM_VERSION "1.5" #define CHECK_ENDP(option, endp) do { \ if (*endp) { \ @@ -65,9 +66,6 @@ typedef enum action_t { #define PADDING 0 /* 0 means, do not adjust anything */ #define BUFSIZE 4096 -extern char *optarg; -extern int optind; - static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" "\n" diff --git a/ubi-utils/src/mkbootenv.c b/ubi-utils/src/mkbootenv.c index c05f4e2..4a8cc6a 100644 --- a/ubi-utils/src/mkbootenv.c +++ b/ubi-utils/src/mkbootenv.c @@ -20,6 +20,7 @@ * Create boot-parameter/pdd data from an ASCII-text input file. * * 1.2 Removed argp because we want to use uClibc. + * 1.3 Minor cleanup */ #include @@ -34,10 +35,7 @@ #include "bootenv.h" #include "error.h" -#define PROGRAM_VERSION "1.2" - -extern char *optarg; -extern int optind; +#define PROGRAM_VERSION "1.3" static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" diff --git a/ubi-utils/src/nand2bin.c b/ubi-utils/src/nand2bin.c index 34cce40..636ee6f 100644 --- a/ubi-utils/src/nand2bin.c +++ b/ubi-utils/src/nand2bin.c @@ -20,6 +20,7 @@ * An utility to decompose NAND images and strip OOB off. Not yet finished ... * * 1.2 Removed argp because we want to use uClibc. + * 1.3 Minor cleanup */ #include @@ -39,14 +40,11 @@ #include "config.h" #include "nandecc.h" -#define PROGRAM_VERSION "1.2" +#define PROGRAM_VERSION "1.3" #define MAXPATH 1024 #define MIN(x,y) ((x)<(y)?(x):(y)) -extern char *optarg; -extern int optind; - struct args { const char *oob_file; const char *output_file; @@ -116,14 +114,12 @@ uint32_t str_to_num(char *str) /* * @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. + * @param argc The number of arguments + * @param argv The argument list + * @param args Pointer to program args structure * * @return error * - * Get the `input' argument from `argp_parse', which we know is a - * pointer to our arguments structure. */ static int parse_opt(int argc, char **argv, struct args *args) diff --git a/ubi-utils/src/pddcustomize.c b/ubi-utils/src/pddcustomize.c index 5c2a5f0..764f2e7 100644 --- a/ubi-utils/src/pddcustomize.c +++ b/ubi-utils/src/pddcustomize.c @@ -25,6 +25,7 @@ * PDD modification. * * 1.3 Removed argp because we want to use uClibc. + * 1.4 Minor cleanups */ #include @@ -43,7 +44,7 @@ #include "libubi.h" #include "ubimirror.h" -#define PROGRAM_VERSION "1.3" +#define PROGRAM_VERSION "1.4" typedef enum action_t { ACT_NORMAL = 0, @@ -60,9 +61,6 @@ typedef enum action_t { args->action = ACT_ARGP_ERR; \ } while (0) -extern char *optarg; -extern int optind; - static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" "\n" @@ -81,7 +79,7 @@ static const char *optionsstr = " -V, --version Print program version\n"; static const char *usage = -"Usage: pddcustomize.orig [-bclx?V] [-i ] [-o ] [-s ]\n" +"Usage: pddcustomize [-bclx?V] [-i ] [-o ] [-s ]\n" " [--both] [--copyright] [--input=] [--list]\n" " [--output=] [--side=] [--host] [--help] [--usage]\n" " [--version] [key=value] [...]\n"; @@ -200,7 +198,7 @@ parse_opt(int argc, char **argv, myargs *args) args->file_out = optarg; break; case '?': /* help */ - err_msg("Usage: pddcustomize.orig [OPTION...] " + err_msg("Usage: pddcustomize [OPTION...] " "[key=value] [...]"); err_msg("%s", doc); err_msg("%s", optionsstr); diff --git a/ubi-utils/src/pfi2bin.c b/ubi-utils/src/pfi2bin.c index 9265fd5..57c4ea5 100644 --- a/ubi-utils/src/pfi2bin.c +++ b/ubi-utils/src/pfi2bin.c @@ -24,6 +24,7 @@ * required to add the right OOB data to the binary image. * * 1.3 Removed argp because we want to use uClibc. + * 1.4 Minor cleanups */ #include @@ -44,7 +45,7 @@ #include "peb.h" #include "crc32.h" -#define PROGRAM_VERSION "1.3" +#define PROGRAM_VERSION "1.4" #define MAX_FNAME 255 #define DEFAULT_ERASE_COUNT 0 /* Hmmm.... Perhaps */ @@ -52,9 +53,6 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) -extern char *optarg; -extern int optind; - static uint32_t crc32_table[256]; static char err_buf[ERR_BUF_SIZE]; @@ -92,7 +90,7 @@ static const char *optionsstr = " -V, --version Print program version\n"; static const char *usage = -"Usage: pfi2bin.orig [-cv?V] [-j pdd-file] [-o filename] [--copyright]\n" +"Usage: pfi2bin [-cv?V] [-j pdd-file] [-o filename] [--copyright]\n" " [--verbose] [--platform=pdd-file] [--output=filename] [--help]\n" " [--usage] [--version] pfifile\n"; diff --git a/ubi-utils/src/pfiflash.c b/ubi-utils/src/pfiflash.c index 63487b9..0b0da56 100644 --- a/ubi-utils/src/pfiflash.c +++ b/ubi-utils/src/pfiflash.c @@ -25,6 +25,7 @@ * 1.1 fixed output to stderr and stdout in logfile mode. * 1.2 updated. * 1.3 removed argp parsing to be able to use uClib. + * 1.4 Minor cleanups */ #include @@ -41,10 +42,7 @@ #include "error.h" #include "config.h" -#define PROGRAM_VERSION "1.3" - -extern char *optarg; -extern int optind; +#define PROGRAM_VERSION "1.4" static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" @@ -70,7 +68,7 @@ static const char *optionsstr = " -V, --version Print program version\n"; static const char *usage = -"Usage: pfiflash.orig [-cvC?V] [-l ] [-p ] [-r ] [-s ]\n" +"Usage: pfiflash [-cvC?V] [-l ] [-p ] [-r ] [-s ]\n" " [--copyright] [--logfile=] [--verbose] [--complete]\n" " [--pdd-update=] [--raw-flash=] [--side=]\n" " [--help] [--usage] [--version] [pfifile]\n"; diff --git a/ubi-utils/src/ubigen.c b/ubi-utils/src/ubigen.c index 877f469..d99ba2d 100644 --- a/ubi-utils/src/ubigen.c +++ b/ubi-utils/src/ubigen.c @@ -22,6 +22,7 @@ * 1.0 Initial version * 1.1 Different CRC32 start value * 1.2 Removed argp because we want to use uClibc. + * 1.3 Minor cleanups */ #include @@ -35,16 +36,13 @@ #include "ubigen.h" #include "config.h" -#define PROGRAM_VERSION "1.2" +#define PROGRAM_VERSION "1.3" typedef enum action_t { ACT_NORMAL = 0x00000001, ACT_BROKEN_UPDATE = 0x00000002, } action_t; -extern char *optarg; -extern int optind; - static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" "\n" @@ -85,7 +83,7 @@ static const char *optionsstr = " -V, --version Print program version\n"; static const char *usage = -"Usage: ubigen.orig [-cdv?V] [-A ] [-B ] [-E ] [-I ]\n" +"Usage: ubigen [-cdv?V] [-A ] [-B ] [-E ] [-I ]\n" " [-O ] [-T ] [-X ] [-i ] [-o ]\n" " [-U ] [--copyright] [--debug] [--verbose] [--alignment=]\n" " [--blocksize=] [--erasecount=] [--id=]\n" diff --git a/ubi-utils/src/ubimirror.c b/ubi-utils/src/ubimirror.c index 533a0ee..eeedb3a 100644 --- a/ubi-utils/src/ubimirror.c +++ b/ubi-utils/src/ubimirror.c @@ -18,6 +18,7 @@ * Author: Oliver Lohmann * * 1.2 Removed argp because we want to use uClibc. + * 1.3 Minor cleanups */ #include @@ -34,7 +35,7 @@ #include "example_ubi.h" #include "ubimirror.h" -#define PROGRAM_VERSION "1.2" +#define PROGRAM_VERSION "1.3" typedef enum action_t { ACT_NORMAL = 0, @@ -52,9 +53,6 @@ typedef enum action_t { #define VOL_ARGS_MAX 2 -extern char *optarg; -extern int optind; - static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\tBuilt on " BUILD_CPU" "BUILD_OS" at "__DATE__" "__TIME__"\n" "\n" diff --git a/ubi-utils/src/ubimkvol.c b/ubi-utils/src/ubimkvol.c index e878d70..879dcb6 100644 --- a/ubi-utils/src/ubimkvol.c +++ b/ubi-utils/src/ubimkvol.c @@ -27,6 +27,7 @@ * the number of bytes. * 1.2 Reworked the user-interface to use argp. * 1.3 Removed argp because we want to use uClibc. + * 1.4 Minor cleanups */ #include @@ -39,10 +40,7 @@ #include #include -#define PROGRAM_VERSION "1.3" - -extern char *optarg; -extern int optind; +#define PROGRAM_VERSION "1.4" /* * The variables below are set by command line arguments. @@ -114,14 +112,12 @@ struct option long_options[] = { /* * @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. + * @param argc The number of arguments + * @param argv The list of arguments + * @param args Pointer to argument structure * * @return error * - * Get the `input' argument from `argp_parse', which we know is a - * pointer to our arguments structure. */ static int parse_opt(int argc, char **argv, struct args *args) @@ -142,16 +138,18 @@ parse_opt(int argc, char **argv, struct args *args) else if (!strcmp(optarg, "static")) args->vol_type = UBI_STATIC_VOLUME; else { - fprintf(stderr, "Bad volume type: \"%s\"\n", - optarg); + fprintf(stderr, + "Bad volume type: \"%s\"\n", + optarg); goto out; } break; case 's': args->bytes = strtoull(optarg, &endp, 0); if (endp == optarg || args->bytes < 0) { - fprintf(stderr, "Bad volume size: \"%s\"\n", - optarg); + fprintf(stderr, + "Bad volume size: \"%s\"\n", + optarg); goto out; } if (endp != '\0') { @@ -172,9 +170,11 @@ parse_opt(int argc, char **argv, struct args *args) break; case 'd': /* --devn= */ args->devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args->devn < 0) { - fprintf(stderr, "Bad UBI device number: " - "\"%s\"\n", optarg); + if (*endp != '\0' || endp == optarg || + args->devn < 0) { + fprintf(stderr, + "Bad UBI device number: " + "\"%s\"\n", optarg); goto out; } break; @@ -199,7 +199,8 @@ parse_opt(int argc, char **argv, struct args *args) goto out; case '?': /* help */ - fprintf(stderr, "Usage: ubimkvol [OPTION...]\n"); + fprintf(stderr, + "Usage: ubimkvol [OPTION...]\n"); fprintf(stderr, "%s", doc); fprintf(stderr, "%s", optionsstr); fprintf(stderr, "\nReport bugs to %s\n", diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c index 04ec085..f458e8a 100644 --- a/ubi-utils/src/ubirmvol.c +++ b/ubi-utils/src/ubirmvol.c @@ -24,6 +24,7 @@ * * 1.1 Reworked the userinterface to use argp. * 1.2 Removed argp because we want to use uClibc. + * 1.3 Minor cleanups */ #include @@ -36,10 +37,7 @@ #include #include -#define PROGRAM_VERSION "1.2" - -extern char *optarg; -extern int optind; +#define PROGRAM_VERSION "1.3" /* * The below variables are set by command line options. @@ -91,14 +89,12 @@ struct option long_options[] = { /* * @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. + * @param argc The number of arguments + * @param argv The list of arguments + * @param args Pointer to argument structure * * @return error * - * Get the `input' argument from `argp_parse', which we know is a - * pointer to our arguments structure. */ static int parse_opt(int argc, char **argv, struct args *args) @@ -115,9 +111,11 @@ parse_opt(int argc, char **argv, struct args *args) switch (key) { case 'd': /* --devn= */ args->devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args->devn < 0) { - fprintf(stderr, "Bad UBI device number: " - "\"%s\"\n", optarg); + if (*endp != '\0' || endp == optarg || + args->devn < 0) { + fprintf(stderr, + "Bad UBI device number: " + "\"%s\"\n", optarg); goto out; } break; @@ -135,7 +133,8 @@ parse_opt(int argc, char **argv, struct args *args) fprintf(stderr, "Parameter is missing\n"); goto out; case '?': /* help */ - fprintf(stderr, "Usage: ubirmvol [OPTION...]\n"); + fprintf(stderr, + "Usage: ubirmvol [OPTION...]\n"); fprintf(stderr, "%s", doc); fprintf(stderr, "%s", optionsstr); fprintf(stderr, "\nReport bugs to %s\n", diff --git a/ubi-utils/src/ubiupdatevol.c b/ubi-utils/src/ubiupdatevol.c index 011d532..b3c4bf1 100644 --- a/ubi-utils/src/ubiupdatevol.c +++ b/ubi-utils/src/ubiupdatevol.c @@ -24,6 +24,7 @@ * * 1.0 Reworked the userinterface to use argp. * 1.1 Removed argp parsing because we want to use uClib. + * 1.2 Minor cleanups */ #include @@ -42,16 +43,12 @@ #include #include -#define PROGRAM_VERSION "1.1" +#define PROGRAM_VERSION "1.2" #define MAXPATH 1024 #define BUFSIZE 128 * 1024 #define MIN(x,y) ((x)<(y)?(x):(y)) -/* FIXME is this not covered by including getopt.h? */ -extern char *optarg; -extern int optind; - struct args { int devn; int vol_id; diff --git a/ubi-utils/src/unubi.c b/ubi-utils/src/unubi.c index 0f8945f..cade1e1 100644 --- a/ubi-utils/src/unubi.c +++ b/ubi-utils/src/unubi.c @@ -21,6 +21,7 @@ * Drake Dowsett, dowsett@de.ibm.com * * 1.2 Removed argp because we want to use uClibc. + * 1.3 Minor cleanups */ /* @@ -53,10 +54,7 @@ #define EXEC "unubi" #define CONTACT "haver@vnet.ibm.com" -#define VERSION "1.0" - -extern char *optarg; -extern int optind; +#define VERSION "1.3" static char doc[] = "\nVersion: " VERSION "\n\t" BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" @@ -177,12 +175,6 @@ str_to_num(char *str) return num; } - -/** - * parses the arguments passed into the program - * get the input argument from argp_parse, which we know is a - * pointer to our arguments structure; - **/ static int parse_opt(int argc, char **argv, struct args *args) { @@ -225,10 +217,13 @@ parse_opt(int argc, char **argv, struct args *args) args->vol_split = SPLIT_RAW; break; case '?': /* help */ - fprintf(stderr, "Usage: unubi [OPTION...] image-file\n"); + fprintf(stderr, + "Usage: unubi [OPTION...] " + "image-file\n"); fprintf(stderr, "%s", doc); fprintf(stderr, "%s", optionsstr); - fprintf(stderr, "\nReport bugs to %s\n", CONTACT); + fprintf(stderr, + "\nReport bugs to %s\n", CONTACT); exit(0); break; case 'J': -- cgit v1.2.3 From 9c37b558705b776e51f7d522f376de019a6ea203 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 21 Mar 2007 11:53:25 +0200 Subject: UBI-Utils: Convert to new ubi library Signed-off-by: Adrian Hunter --- ubi-utils/Makefile | 20 +- ubi-utils/inc/libubi.h | 268 ++++++++++++ ubi-utils/src/libpfiflash.c | 2 +- ubi-utils/src/libubi.c | 917 ++++++++++++++++++++++++++++++++++++++++ ubi-utils/src/libubi_int.h | 129 ++++++ ubi-utils/src/libubimirror.c | 10 +- ubi-utils/src/libubiold.c | 6 +- ubi-utils/src/libubiold_sysfs.c | 2 +- ubi-utils/src/pddcustomize.c | 2 +- ubi-utils/src/reader.c | 13 +- ubi-utils/src/ubimkvol.c | 33 +- ubi-utils/src/ubirmvol.c | 24 +- ubi-utils/src/ubiupdatevol.c | 46 +- 13 files changed, 1409 insertions(+), 63 deletions(-) create mode 100644 ubi-utils/inc/libubi.h create mode 100644 ubi-utils/src/libubi.c create mode 100644 ubi-utils/src/libubi_int.h (limited to 'ubi-utils/src/ubirmvol.c') diff --git a/ubi-utils/Makefile b/ubi-utils/Makefile index 0818a9b..797807d 100644 --- a/ubi-utils/Makefile +++ b/ubi-utils/Makefile @@ -16,11 +16,12 @@ CFLAGS := -I./inc -I./src -I$(KERNELHDR) -O2 -g -Wall -Werror \ -Wwrite-strings -W -std=gnu99 \ -DHOST_OS_NAME=\"$(HOST_OS_NAME)\" \ -DHOST_VERSION_NAME=\"$(HOST_VERSION_NAME)\" \ - -DBUILD_CPU=\"$(BUILD_CPU)\" -DBUILD_OS=\"$(BUILD_OS)\" + -DBUILD_CPU=\"$(BUILD_CPU)\" -DBUILD_OS=\"$(BUILD_OS)\" \ + -DPACKAGE_VERSION=\"1.0\" PERLPROGS = mkpfi ubicrc32.pl TARGETS = ubiupdatevol ubimkvol ubirmvol pfiflash pddcustomize ubimirror \ - bin2nand nand2bin ubigen mkbootenv unubi pfi2bin + bin2nand nand2bin ubigen mkbootenv unubi pfi2bin ubicrc32 vpath %.c ./src @@ -38,25 +39,25 @@ IGNORE=${wildcard .*.c.dep} clean: rm -rf *.o $(TARGETS) .*.c.dep -ubiupdatevol: ubiupdatevol.o error.o libubi.o libubi_sysfs.o +ubiupdatevol: ubiupdatevol.o error.o libubi.o $(CC) $(LDFLAGS) -o $@ $^ -ubimkvol: ubimkvol.o error.o libubi.o libubi_sysfs.o +ubimkvol: ubimkvol.o error.o libubi.o $(CC) $(LDFLAGS) -o $@ $^ -ubirmvol: ubirmvol.o error.o libubi.o libubi_sysfs.o +ubirmvol: ubirmvol.o error.o libubi.o $(CC) $(LDFLAGS) -o $@ $^ pddcustomize: pddcustomize.o error.o libubimirror.o bootenv.o hashmap.o \ - libubi.o libubi_sysfs.o crc32.o + libubiold.o libubiold_sysfs.o crc32.o $(CC) $(LDFLAGS) -o $@ $^ pfiflash: pfiflash.o libpfiflash.o list.o reader.o error.o libubimirror.o \ - bootenv.o hashmap.o pfi.o libubi.o libubi_sysfs.o crc32.o + bootenv.o hashmap.o pfi.o libubiold.o libubiold_sysfs.o crc32.o $(CC) $(LDFLAGS) -o $@ $^ ubimirror: ubimirror.o error.o libubimirror.o bootenv.o hashmap.o \ - libubi.o libubi_sysfs.o crc32.o + libubiold.o libubiold_sysfs.o crc32.o $(CC) $(LDFLAGS) -o $@ $^ nand2bin: nand2bin.o nandecc.o nandcorr.o @@ -78,6 +79,9 @@ pfi2bin: pfi2bin.o peb.o error.o list.o crc32.o libubigen.o bootenv.o \ hashmap.o reader.o pfi.o $(CC) $(LDFLAGS) -o $@ $^ +ubicrc32: ubicrc32.o crc32.o + $(CC) $(LDFLAGS) -o $@ $^ + install: ${TARGETS} mkdir -p ${DESTDIR}/${SBINDIR} install -m0755 ${TARGETS} ${DESTDIR}/${SBINDIR}/ diff --git a/ubi-utils/inc/libubi.h b/ubi-utils/inc/libubi.h new file mode 100644 index 0000000..d39c1b9 --- /dev/null +++ b/ubi-utils/inc/libubi.h @@ -0,0 +1,268 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * 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. + * + * Author: Artem B. Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#ifndef __LIBUBI_H__ +#define __LIBUBI_H__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* UBI version libubi is made for */ +#define LIBUBI_UBI_VERSION 1 + +/* UBI library descriptor */ +typedef void * libubi_t; + +/** + * struct ubi_mkvol_request - volume creation request. + * */ +struct ubi_mkvol_request +{ + int vol_id; + int alignment; + long long bytes; + int vol_type; + const char *name; +}; + +/** + * struct ubi_info - general UBI information. + * + * @dev_count count of UBI devices in system + * @lowest_dev_num lowest UBI device number + * @highest_dev_num highest UBI device number + * @version UBI version + */ +struct ubi_info +{ + int dev_count; + int lowest_dev_num; + int highest_dev_num; + int version; +}; + +/** + * struct ubi_dev_info - UBI device information. + * + * @vol_count count of volumes on this UBI device + * @lowest_vol_num lowest volume number + * @highest_vol_num highest volume number + * @total_ebs total number of eraseblocks on this UBI device + * @avail_ebs how many eraseblocks are not used and available for new + * volumes + * @total_bytes @total_ebs * @eb_size + * @avail_bytes @avail_ebs * @eb_size + * @bad_count count of bad eraseblocks + * @eb_size size of UBI eraseblock + * @max_ec current highest erase counter value + * @bad_rsvd how many physical eraseblocks of the underlying flash + * device are reserved for bad eraseblocks handling + * @max_vol_count maximum count of volumes on this UBI device + * @min_io_size minimum input/output size of the UBI device + */ +struct ubi_dev_info +{ + int dev_num; + int vol_count; + int lowest_vol_num; + int highest_vol_num; + int total_ebs; + int avail_ebs; + long long total_bytes; + long long avail_bytes; + int bad_count; + int eb_size; + long long max_ec; + int bad_rsvd; + int max_vol_count; + int min_io_size; +}; + +/** + * struct ubi_vol_info - UBI volume information. + * + * @dev_num UBI device number the volume resides on + * @vol_id ID of this volume + * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @alignment alignemnt of this volume + * @data_bytes how many data bytes are stored on this volume (equivalent to + * @rsvd_bytes for dynamic volumes) + * @rsvd_bytes how many bytes are reserved for this volume + * @rsvd_ebs how many eraseblocks are reserved for this volume + * @eb_size logical eraseblock size of this volume (may be less then + * device's logical eraseblock size due to alignment) + * @corrupted the volume is corrupted if this flag is not zero + * @name volume name (null-terminated) + */ +struct ubi_vol_info +{ + int dev_num; + int vol_id; + int type; + int alignment; + long long data_bytes; + long long rsvd_bytes; + int rsvd_ebs; + int eb_size; + int corrupted; + char name[UBI_VOL_NAME_MAX + 1]; +}; + +/** + * libubi_open - open UBI library. + * + * This function initializes and opens the UBI library and returns UBI library + * descriptor in case of success and %NULL in case of failure. + */ +libubi_t libubi_open(void); + +/** + * libubi_close - close UBI library + * + * @desc UBI library descriptor + */ +void libubi_close(libubi_t desc); + +/** + * ubi_get_info - get general UBI information. + * + * @info pointer to the &struct ubi_info object to fill + * @desc UBI library descriptor + * + * This function fills the passed @info object with general UBI information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_info(libubi_t desc, struct ubi_info *info); + +/** + * ubi_mkvol - create an UBI volume. + * + * @desc UBI library descriptor + * @node name of the UBI character device to create a volume at + * @req UBI volume creation request (defined at ) + * + * This function creates a UBI volume as described at @req and returns %0 in + * case of success and %-1 in case of failure. The assigned volume ID is + * returned in @req->vol_id. + */ +int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req); + +/** + * ubi_rmvol - remove a UBI volume. + * + * @desc UBI library descriptor + * @node name of the UBI character device to remove a volume from + * @vol_id ID of the volume to remove + * + * This function removes volume @vol_id from UBI device @node and returns %0 in + * case of success and %-1 in case of failure. + */ +int ubi_rmvol(libubi_t desc, const char *node, int vol_id); + +/** + * ubi_rsvol - re-size UBI volume. + * + * @desc UBI library descriptor + * @node name of the UBI character device owning the volume which should be + * re-sized + * @vol_id volume ID to re-size + * @bytes new volume size in bytes + * + * This function returns %0 in case of success and %-1 in case of error. + */ +int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes); + +/** + * ubi_get_dev_info - get UBI device information. + * + * @desc UBI library descriptor + * @node name of the UBI character device to fetch information about + * @info pointer to the &struct ubi_dev_info object to fill + * + * This function fills the passed @info object with UBI device information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_dev_info(libubi_t desc, const char *node, + struct ubi_dev_info *info); + +/** + * ubi_get_dev_info1 - get UBI device information. + * + * @desc UBI library descriptor + * @dev_num UBI device number to fetch information about + * @info pointer to the &struct ubi_dev_info object to fill + * + * This function is identical to 'ubi_get_dev_info()' except that it accepts UBI + * device number, not UBI character device. + */ +int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info); + +/** + * ubi_get_vol_info - get UBI volume information. + * + * @desc UBI library descriptor + * @node name of the UBI volume character device to fetch information about + * @info pointer to the &struct ubi_vol_info object to fill + * + * This function fills the passed @info object with UBI volume information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_vol_info(libubi_t desc, const char *node, + struct ubi_vol_info *info); + +/** + * ubi_get_vol_info1 - get UBI volume information. + * + * @desc UBI library descriptor + * @dev_num UBI device number + * @vol_id ID of the UBI volume to fetch information about + * @info pointer to the &struct ubi_vol_info object to fill + * + * This function is identical to 'ubi_get_vol_info()' except that it accepts UBI + * volume number, not UBI volume character device. + */ +int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, + struct ubi_vol_info *info); + +/** + * ubi_update_start - start UBI volume update. + * + * @desc UBI library descriptor + * @fd volume character devie file descriptor + * @bytes how many bytes will be written to the volume + * + * This function initiates UBI volume update and returns %0 in case of success + * and %-1 in case of error. + */ +int ubi_update_start(libubi_t desc, int fd, long long bytes); + +#ifdef __cplusplus +} +#endif + +#endif /* !__LIBUBI_H__ */ diff --git a/ubi-utils/src/libpfiflash.c b/ubi-utils/src/libpfiflash.c index 4dfafea..4f1f5cd 100644 --- a/ubi-utils/src/libpfiflash.c +++ b/ubi-utils/src/libpfiflash.c @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include /* FIXME Is this ok here? */ diff --git a/ubi-utils/src/libubi.c b/ubi-utils/src/libubi.c new file mode 100644 index 0000000..17ab4ee --- /dev/null +++ b/ubi-utils/src/libubi.c @@ -0,0 +1,917 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * 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. + * + * Author: Artem B. Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libubi.h" +#include "libubi_int.h" + +libubi_t libubi_open(void) +{ + int fd, version; + struct libubi *lib; + + lib = calloc(1, sizeof(struct libubi)); + if (!lib) + return NULL; + + /* TODO: this must be discovered instead */ + lib->sysfs = strdup("/sys"); + if (!lib->sysfs) + goto error; + + lib->sysfs_ubi = mkpath(lib->sysfs, SYSFS_UBI); + if (!lib->sysfs_ubi) + goto error; + + /* Make sure UBI is present */ + fd = open(lib->sysfs_ubi, O_RDONLY); + if (fd == -1) + goto error; + close(fd); + + lib->ubi_dev = mkpath(lib->sysfs_ubi, UBI_DEV_NAME_PATT); + if (!lib->ubi_dev) + goto error; + + lib->ubi_version = mkpath(lib->sysfs_ubi, UBI_VER); + if (!lib->ubi_version) + goto error; + + lib->dev_dev = mkpath(lib->ubi_dev, DEV_DEV); + if (!lib->dev_dev) + goto error; + + lib->dev_avail_ebs = mkpath(lib->ubi_dev, DEV_AVAIL_EBS); + if (!lib->dev_avail_ebs) + goto error; + + lib->dev_total_ebs = mkpath(lib->ubi_dev, DEV_TOTAL_EBS); + if (!lib->dev_total_ebs) + goto error; + + lib->dev_bad_count = mkpath(lib->ubi_dev, DEV_BAD_COUNT); + if (!lib->dev_bad_count) + goto error; + + lib->dev_eb_size = mkpath(lib->ubi_dev, DEV_EB_SIZE); + if (!lib->dev_eb_size) + goto error; + + lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC); + if (!lib->dev_max_ec) + goto error; + + lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD); + if (!lib->dev_bad_rsvd) + goto error; + + lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS); + if (!lib->dev_max_vols) + goto error; + + lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE); + if (!lib->dev_min_io_size) + goto error; + + lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT); + if (!lib->ubi_vol) + goto error; + + lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE); + if (!lib->vol_type) + goto error; + + lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV); + if (!lib->vol_dev) + goto error; + + lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT); + if (!lib->vol_alignment) + goto error; + + lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES); + if (!lib->vol_data_bytes) + goto error; + + lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS); + if (!lib->vol_rsvd_ebs) + goto error; + + lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE); + if (!lib->vol_eb_size) + goto error; + + lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED); + if (!lib->vol_corrupted) + goto error; + + lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME); + if (!lib->vol_name) + goto error; + + if (read_int(lib->ubi_version, &version)) + goto error; + if (version != LIBUBI_UBI_VERSION) { + fprintf(stderr, "LIBUBI: this library was made for UBI version " + "%d, but UBI version %d is detected\n", + LIBUBI_UBI_VERSION, version); + goto error; + } + + return lib; + +error: + free(lib->vol_corrupted); + free(lib->vol_eb_size); + free(lib->vol_rsvd_ebs); + free(lib->vol_data_bytes); + free(lib->vol_alignment); + free(lib->vol_dev); + free(lib->vol_type); + free(lib->ubi_vol); + free(lib->dev_min_io_size); + free(lib->dev_max_vols); + free(lib->dev_bad_rsvd); + free(lib->dev_max_ec); + free(lib->dev_eb_size); + free(lib->dev_bad_count); + free(lib->dev_total_ebs); + free(lib->dev_avail_ebs); + free(lib->dev_dev); + free(lib->ubi_version); + free(lib->ubi_dev); + free(lib->sysfs_ubi); + free(lib->sysfs); + free(lib); + return NULL; +} + +void libubi_close(libubi_t desc) +{ + struct libubi *lib = (struct libubi *)desc; + + free(lib->vol_name); + free(lib->vol_corrupted); + free(lib->vol_eb_size); + free(lib->vol_rsvd_ebs); + free(lib->vol_data_bytes); + free(lib->vol_alignment); + free(lib->vol_dev); + free(lib->vol_type); + free(lib->ubi_vol); + free(lib->dev_min_io_size); + free(lib->dev_max_vols); + free(lib->dev_bad_rsvd); + free(lib->dev_max_ec); + free(lib->dev_eb_size); + free(lib->dev_bad_count); + free(lib->dev_total_ebs); + free(lib->dev_avail_ebs); + free(lib->dev_dev); + free(lib->ubi_version); + free(lib->ubi_dev); + free(lib->sysfs_ubi); + free(lib->sysfs); + free(lib); +} + +int ubi_get_info(libubi_t desc, struct ubi_info *info) +{ + DIR *sysfs_ubi; + struct dirent *dirent; + struct libubi *lib = (struct libubi *)desc; + + memset(info, '\0', sizeof(struct ubi_info)); + + /* + * We have to scan the UBI sysfs directory to identify how many UBI + * devices are present. + */ + sysfs_ubi = opendir(lib->sysfs_ubi); + if (!sysfs_ubi) + return -1; + + info->lowest_dev_num = INT_MAX; + while ((dirent = readdir(sysfs_ubi))) { + char *name = &dirent->d_name[0]; + int dev_num, ret; + + ret = sscanf(name, UBI_DEV_NAME_PATT, &dev_num); + if (ret == 1) { + info->dev_count += 1; + if (dev_num > info->highest_dev_num) + info->highest_dev_num = dev_num; + if (dev_num < info->lowest_dev_num) + info->lowest_dev_num = dev_num; + } + } + + if (info->lowest_dev_num == INT_MAX) + info->lowest_dev_num = 0; + + if (read_int(lib->ubi_version, &info->version)) + goto close; + + return closedir(sysfs_ubi); + +close: + closedir(sysfs_ubi); + return -1; +} + +int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req) +{ + int fd, ret; + struct ubi_mkvol_req r; + size_t n; + + desc = desc; + r.vol_id = req->vol_id; + r.alignment = req->alignment; + r.bytes = req->bytes; + r.vol_type = req->vol_type; + + n = strlen(req->name); + if (n > UBI_MAX_VOLUME_NAME) + return -1; + + strncpy(r.name, req->name, UBI_MAX_VOLUME_NAME + 1); + r.name_len = n; + + fd = open(node, O_RDONLY); + if (fd == -1) + return -1; + + ret = ioctl(fd, UBI_IOCMKVOL, &r); + + if (!ret) + req->vol_id = r.vol_id; + + close(fd); + return ret; +} + +int ubi_rmvol(libubi_t desc, const char *node, int vol_id) +{ + int fd, ret; + + desc = desc; + fd = open(node, O_RDONLY); + if (fd == -1) + return -1; + + ret = ioctl(fd, UBI_IOCRMVOL, &vol_id); + close(fd); + return ret; +} + +int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes) +{ + int fd, ret; + struct ubi_rsvol_req req; + + desc = desc; + fd = open(node, O_RDONLY); + if (fd == -1) + return -1; + + req.bytes = bytes; + req.vol_id = vol_id; + + ret = ioctl(fd, UBI_IOCRSVOL, &req); + close(fd); + return ret; +} + +int ubi_update_start(libubi_t desc, int fd, long long bytes) +{ + desc = desc; + if (ioctl(fd, UBI_IOCVOLUP, &bytes)) + return -1; + return 0; +} + +int ubi_get_dev_info(libubi_t desc, const char *node, struct ubi_dev_info *info) +{ + int dev_num; + struct libubi *lib = (struct libubi *)desc; + + dev_num = find_dev_num(lib, node); + if (dev_num == -1) + return -1; + + return ubi_get_dev_info1(desc, dev_num, info); +} + +int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info) +{ + DIR *sysfs_ubi; + struct dirent *dirent; + struct libubi *lib = (struct libubi *)desc; + + memset(info, '\0', sizeof(struct ubi_dev_info)); + info->dev_num = dev_num; + + sysfs_ubi = opendir(lib->sysfs_ubi); + if (!sysfs_ubi) + return -1; + + info->lowest_vol_num = INT_MAX; + while ((dirent = readdir(sysfs_ubi))) { + char *name = &dirent->d_name[0]; + int vol_id, ret, devno; + + ret = sscanf(name, UBI_VOL_NAME_PATT, &devno, &vol_id); + if (ret == 2 && devno == dev_num) { + info->vol_count += 1; + if (vol_id > info->highest_vol_num) + info->highest_vol_num = vol_id; + if (vol_id < info->lowest_vol_num) + info->lowest_vol_num = vol_id; + } + } + + closedir(sysfs_ubi); + + if (info->lowest_vol_num == INT_MAX) + info->lowest_vol_num = 0; + + if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_ebs)) + return -1; + if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_ebs)) + return -1; + if (dev_read_int(lib->dev_bad_count, dev_num, &info->bad_count)) + return -1; + if (dev_read_int(lib->dev_eb_size, dev_num, &info->eb_size)) + return -1; + if (dev_read_int(lib->dev_bad_rsvd, dev_num, &info->bad_rsvd)) + return -1; + if (dev_read_ll(lib->dev_max_ec, dev_num, &info->max_ec)) + return -1; + if (dev_read_int(lib->dev_max_vols, dev_num, &info->max_vol_count)) + return -1; + if (dev_read_int(lib->dev_min_io_size, dev_num, &info->min_io_size)) + return -1; + + info->avail_bytes = info->avail_ebs * info->eb_size; + info->total_bytes = info->total_ebs * info->eb_size; + + return 0; +} + +int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info) +{ + int vol_id, dev_num; + struct libubi *lib = (struct libubi *)desc; + + dev_num = find_dev_num_vol(lib, node); + if (dev_num == -1) + return -1; + + vol_id = find_vol_num(lib, dev_num, node); + if (vol_id == -1) + return -1; + + return ubi_get_vol_info1(desc, dev_num, vol_id, info); +} + +int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, + struct ubi_vol_info *info) +{ + int ret; + struct libubi *lib = (struct libubi *)desc; + char buf[50]; + + memset(info, '\0', sizeof(struct ubi_vol_info)); + info->dev_num = dev_num; + info->vol_id = vol_id; + + ret = vol_read_data(lib->vol_type, dev_num, vol_id, &buf[0], 50); + if (ret < 0) + return -1; + + if (strncmp(&buf[0], "static\n", ret) == 0) + info->type = UBI_STATIC_VOLUME; + else if (strncmp(&buf[0], "dynamic\n", ret) == 0) + info->type = UBI_DYNAMIC_VOLUME; + else { + fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); + errno = EINVAL; + return -1; + } + + ret = vol_read_int(lib->vol_alignment, dev_num, vol_id, + &info->alignment); + if (ret) + return -1; + ret = vol_read_ll(lib->vol_data_bytes, dev_num, vol_id, + &info->data_bytes); + if (ret) + return -1; + ret = vol_read_int(lib->vol_rsvd_ebs, dev_num, vol_id, &info->rsvd_ebs); + if (ret) + return -1; + ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->eb_size); + if (ret) + return -1; + ret = vol_read_int(lib->vol_corrupted, dev_num, vol_id, + &info->corrupted); + if (ret) + return -1; + info->rsvd_bytes = info->eb_size * info->rsvd_ebs; + + ret = vol_read_data(lib->vol_name, dev_num, vol_id, &info->name, + UBI_VOL_NAME_MAX + 2); + if (ret < 0) + return -1; + + info->name[ret - 1] = '\0'; + + return 0; +} + +/** + * read_int - read an 'int' value from a file. + * + * @file the file to read from + * @value the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int read_int(const char *file, int *value) +{ + int fd, rd; + char buf[50]; + + fd = open(file, O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, &buf[0], 50); + if (rd == -1) + goto error; + + if (sscanf(&buf[0], "%d\n", value) != 1) { + /* This must be a UBI bug */ + fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); + errno = EINVAL; + goto error; + } + + close(fd); + return 0; + +error: + close(fd); + return -1; +} + +/** + * dev_read_int - read an 'int' value from an UBI device's sysfs file. + * + * @patt the file pattern to read from + * @dev_num UBI device number + * @value the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int dev_read_int(const char *patt, int dev_num, int *value) +{ + int fd, rd; + char buf[50]; + char file[strlen(patt) + 50]; + + sprintf(&file[0], patt, dev_num); + fd = open(&file[0], O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, &buf[0], 50); + if (rd == -1) + goto error; + + if (sscanf(&buf[0], "%d\n", value) != 1) { + /* This must be a UBI bug */ + fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); + errno = EINVAL; + goto error; + } + + close(fd); + return 0; + +error: + close(fd); + return -1; +} + +/** + * dev_read_ll - read a 'long long' value from an UBI device's sysfs file. + * + * @patt the file pattern to read from + * @dev_num UBI device number + * @value the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int dev_read_ll(const char *patt, int dev_num, long long *value) +{ + int fd, rd; + char buf[50]; + char file[strlen(patt) + 50]; + + sprintf(&file[0], patt, dev_num); + fd = open(&file[0], O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, &buf[0], 50); + if (rd == -1) + goto error; + + if (sscanf(&buf[0], "%lld\n", value) != 1) { + /* This must be a UBI bug */ + fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); + errno = EINVAL; + goto error; + } + + close(fd); + return 0; + +error: + close(fd); + return -1; +} + +/** + * dev_read_data - read data from an UBI device's sysfs file. + * + * @patt the file pattern to read from + * @dev_num UBI device number + * @buf buffer to read data to + * @buf_len buffer length + * + * This function returns number of read bytes in case of success and %-1 in + * case of failure. + */ +static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len) +{ + int fd, rd; + char file[strlen(patt) + 50]; + + sprintf(&file[0], patt, dev_num); + fd = open(&file[0], O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, buf, buf_len); + if (rd == -1) { + close(fd); + return -1; + } + + close(fd); + return rd; +} + +/** + * vol_read_int - read an 'int' value from an UBI volume's sysfs file. + * + * @patt the file pattern to read from + * @dev_num UBI device number + * @vol_id volume identifier + * @value the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value) +{ + int fd, rd; + char buf[50]; + char file[strlen(patt) + 100]; + + sprintf(&file[0], patt, dev_num, vol_id); + fd = open(&file[0], O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, &buf[0], 50); + if (rd == -1) + goto error; + + if (sscanf(&buf[0], "%d\n", value) != 1) { + /* This must be a UBI bug */ + fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); + errno = EINVAL; + goto error; + } + + close(fd); + return 0; + +error: + close(fd); + return -1; +} + +/** + * vol_read_ll - read a 'long long' value from an UBI volume's sysfs file. + * + * @patt the file pattern to read from + * @dev_num UBI device number + * @vol_id volume identifier + * @value the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int vol_read_ll(const char *patt, int dev_num, int vol_id, + long long *value) +{ + int fd, rd; + char buf[50]; + char file[strlen(patt) + 100]; + + sprintf(&file[0], patt, dev_num, vol_id); + fd = open(&file[0], O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, &buf[0], 50); + if (rd == -1) + goto error; + + if (sscanf(&buf[0], "%lld\n", value) != 1) { + /* This must be a UBI bug */ + fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); + errno = EINVAL; + goto error; + } + + close(fd); + return 0; + +error: + close(fd); + return -1; +} + +/** + * vol_read_data - read data from an UBI volume's sysfs file. + * + * @patt the file pattern to read from + * @dev_num UBI device number + * @vol_id volume identifier + * @buf buffer to read to + * @buf_len buffer length + * + * This function returns number of read bytes in case of success and %-1 in + * case of failure. + */ +static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf, + int buf_len) +{ + int fd, rd; + char file[strlen(patt) + 100]; + + sprintf(&file[0], patt, dev_num, vol_id); + fd = open(&file[0], O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, buf, buf_len); + if (rd == -1) { + close(fd); + return -1; + } + + close(fd); + return rd; +} + +/** + * mkpath - compose full path from 2 given components. + * + * @path first component + * @name second component + * + * This function returns the resulting path in case of success and %NULL in + * case of failure. + */ +static char *mkpath(const char *path, const char *name) +{ + char *n; + int len1 = strlen(path); + int len2 = strlen(name); + + n = malloc(len1 + len2 + 2); + if (!n) + return NULL; + + memcpy(n, path, len1); + if (n[len1 - 1] != '/') + n[len1++] = '/'; + + memcpy(n + len1, name, len2 + 1); + return n; +} + +/** + * find_dev_num - find UBI device number by its character device node. + * + * @lib UBI library descriptor + * @node UBI character device node name + * + * This function returns positive UBI device number in case of success and %-1 + * in case of failure. + */ +static int find_dev_num(struct libubi *lib, const char *node) +{ + struct stat stat; + struct ubi_info info; + int i, major, minor; + + if (lstat(node, &stat)) + return -1; + + if (!S_ISCHR(stat.st_mode)) { + errno = EINVAL; + return -1; + } + + major = major(stat.st_rdev); + minor = minor(stat.st_rdev); + + if (minor != 0) { + errno = -EINVAL; + return -1; + } + + if (ubi_get_info((libubi_t *)lib, &info)) + return -1; + + for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { + int major1, minor1, ret; + char buf[50]; + + ret = dev_read_data(lib->dev_dev, i, &buf[0], 50); + if (ret < 0) + return -1; + + ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1); + if (ret != 2) { + fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); + errno = EINVAL; + return -1; + } + + if (minor1 == minor && major1 == major) + return i; + } + + errno = ENOENT; + return -1; +} + +/** + * find_dev_num_vol - find UBI device number by volume character device node. + * + * @lib UBI library descriptor + * @node UBI character device node name + * + * This function returns positive UBI device number in case of success and %-1 + * in case of failure. + */ +static int find_dev_num_vol(struct libubi *lib, const char *node) +{ + struct stat stat; + struct ubi_info info; + int i, major; + + if (lstat(node, &stat)) + return -1; + + if (!S_ISCHR(stat.st_mode)) { + errno = EINVAL; + return -1; + } + + major = major(stat.st_rdev); + + if (minor(stat.st_rdev) == 0) { + errno = -EINVAL; + return -1; + } + + if (ubi_get_info((libubi_t *)lib, &info)) + return -1; + + for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { + int major1, minor1, ret; + char buf[50]; + + ret = dev_read_data(lib->dev_dev, i, &buf[0], 50); + if (ret < 0) + return -1; + + ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1); + if (ret != 2) { + fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); + errno = EINVAL; + return -1; + } + + if (major1 == major) + return i; + } + + errno = ENOENT; + return -1; +} + +/** + * find_vol_num - find UBI volume number by its character device node. + * + * @lib UBI library descriptor + * @dev_num UBI device number + * @node UBI volume character device node name + * + * This function returns positive UBI volume number in case of success and %-1 + * in case of failure. + */ +static int find_vol_num(struct libubi *lib, int dev_num, const char *node) +{ + struct stat stat; + struct ubi_dev_info info; + int i, major, minor; + + if (lstat(node, &stat)) + return -1; + + if (!S_ISCHR(stat.st_mode)) { + errno = EINVAL; + return -1; + } + + major = major(stat.st_rdev); + minor = minor(stat.st_rdev); + + if (minor == 0) { + errno = -EINVAL; + return -1; + } + + if (ubi_get_dev_info1((libubi_t *)lib, dev_num, &info)) + return -1; + + for (i = info.lowest_vol_num; i <= info.highest_vol_num; i++) { + int major1, minor1, ret; + char buf[50]; + + ret = vol_read_data(lib->vol_dev, dev_num, i, &buf[0], 50); + if (ret < 0) + return -1; + + ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1); + if (ret != 2) { + fprintf(stderr, "LIBUBI: bad value at sysfs file\n"); + errno = EINVAL; + return -1; + } + + if (minor1 == minor && major1 == major) + return i; + } + + errno = ENOENT; + return -1; +} diff --git a/ubi-utils/src/libubi_int.h b/ubi-utils/src/libubi_int.h new file mode 100644 index 0000000..e68b791 --- /dev/null +++ b/ubi-utils/src/libubi_int.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * 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. + * + * Author: Artem B. Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#ifndef __LIBUBI_INT_H__ +#define __LIBUBI_INT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * UBI heavily makes use of the sysfs file system to interact with users-pace. + * The below are pre-define UBI file and directory names. + */ + +#define SYSFS_UBI "class/ubi" +#define UBI_DEV_NAME_PATT "ubi%d" +#define UBI_VER "version" +#define DEV_DEV "dev" +#define UBI_VOL_NAME_PATT "ubi%d_%d" +#define DEV_AVAIL_EBS "avail_eraseblocks" +#define DEV_TOTAL_EBS "total_eraseblocks" +#define DEV_BAD_COUNT "bad_peb_count" +#define DEV_EB_SIZE "eraseblock_size" +#define DEV_MAX_EC "max_ec" +#define DEV_MAX_RSVD "reserved_for_bad" +#define DEV_MAX_VOLS "max_vol_count" +#define DEV_MIN_IO_SIZE "min_io_size" +#define VOL_TYPE "type" +#define VOL_DEV "dev" +#define VOL_ALIGNMENT "alignment" +#define VOL_DATA_BYTES "data_bytes" +#define VOL_RSVD_EBS "reserved_ebs" +#define VOL_EB_SIZE "usable_eb_size" +#define VOL_CORRUPTED "corrupted" +#define VOL_NAME "name" + +/** + * libubi - UBI library description data structure. + * + * @sysfs sysfs file system path + * @sysfs_ubi UBI directory in sysfs + * @ubi_dev UBI device sysfs directory pattern + * @ubi_version UBI version file sysfs path + * @dev_dev UBI device's major/minor numbers file pattern + * @dev_avail_ebs count of available eraseblocks sysfs path pattern + * @dev_total_ebs total eraseblocks count sysfs path pattern + * @dev_bad_count count of bad eraseblocks sysfs path pattern + * @dev_eb_size size of UBI device's eraseblocks sysfs path pattern + * @dev_max_ec maximum erase counter sysfs path pattern + * @dev_bad_rsvd count of physical eraseblock reserved for bad eraseblocks + * handling + * @dev_max_vols maximum volumes number count sysfs path pattern + * @dev_min_io_size minimum I/O unit size sysfs path pattern + * @ubi_vol UBI volume sysfs directory pattern + * @vol_type volume type sysfs path pattern + * @vol_dev volume's major/minor numbers file pattern + * @vol_alignment volume alignment sysfs path pattern + * @vol_data_bytes volume data size sysfs path pattern + * @vol_rsvd_ebs volume reserved size sysfs path pattern + * @vol_eb_size volume eraseblock size sysfs path pattern + * @vol_corrupted volume corruption flag sysfs path pattern + * @vol_name volume name sysfs path pattern + */ +struct libubi +{ + char *sysfs; + char *sysfs_ubi; + char *ubi_dev; + char *ubi_version; + char *dev_dev; + char *dev_avail_ebs; + char *dev_total_ebs; + char *dev_bad_count; + char *dev_eb_size; + char *dev_max_ec; + char *dev_bad_rsvd; + char *dev_max_vols; + char *dev_min_io_size; + char *ubi_vol; + char *vol_type; + char *vol_dev; + char *vol_alignment; + char *vol_data_bytes; + char *vol_rsvd_ebs; + char *vol_eb_size; + char *vol_corrupted; + char *vol_name; + char *vol_max_count; +}; + +static int read_int(const char *file, int *value); +static int dev_read_int(const char *patt, int dev_num, int *value); +static int dev_read_ll(const char *patt, int dev_num, long long *value); +static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len); +static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value); +static int vol_read_ll(const char *patt, int dev_num, int vol_id, + long long *value); +static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf, + int buf_len); +static char *mkpath(const char *path, const char *name); +static int find_dev_num(struct libubi *lib, const char *node); +static int find_dev_num_vol(struct libubi *lib, const char *node); +static int find_vol_num(struct libubi *lib, int dev_num, const char *node); + +#ifdef __cplusplus +} +#endif + +#endif /* !__LIBUBI_INT_H__ */ diff --git a/ubi-utils/src/libubimirror.c b/ubi-utils/src/libubimirror.c index e5715fc..d8ea548 100644 --- a/ubi-utils/src/libubimirror.c +++ b/ubi-utils/src/libubimirror.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include "ubimirror.h" #define COMPARE_BUF_SIZE (128 * 1024) @@ -207,11 +207,11 @@ ubimirror(uint32_t devno, int seqnum, uint32_t *ids, ssize_t ids_size, fd_out = -1; } err: - if (ulib != NULL) - ubi_close(&ulib); - if (fd_in != -1) - ubi_vol_close(fd_in); if (fd_out != -1) ubi_vol_close(fd_out); + if (fd_in != -1) + ubi_vol_close(fd_in); + if (ulib != NULL) + ubi_close(&ulib); return rc; } diff --git a/ubi-utils/src/libubiold.c b/ubi-utils/src/libubiold.c index da4919b..0ff8bae 100644 --- a/ubi-utils/src/libubiold.c +++ b/ubi-utils/src/libubiold.c @@ -36,9 +36,9 @@ #include #include -#include "libubi.h" -#include "libubi_int.h" -#include "libubi_sysfs.h" +#include "libubiold.h" +#include "libubiold_int.h" +#include "libubiold_sysfs.h" /** * struct ubi_lib - UBI library descriptor. diff --git a/ubi-utils/src/libubiold_sysfs.c b/ubi-utils/src/libubiold_sysfs.c index 95fd3de..c4860f6 100644 --- a/ubi-utils/src/libubiold_sysfs.c +++ b/ubi-utils/src/libubiold_sysfs.c @@ -33,7 +33,7 @@ #include #include "config.h" -#include "libubi_int.h" +#include "libubiold_int.h" int sysfs_read_data(const char *file, void *buf, int len) diff --git a/ubi-utils/src/pddcustomize.c b/ubi-utils/src/pddcustomize.c index 764f2e7..a86e942 100644 --- a/ubi-utils/src/pddcustomize.c +++ b/ubi-utils/src/pddcustomize.c @@ -41,7 +41,7 @@ #include "bootenv.h" #include "error.h" #include "example_ubi.h" -#include "libubi.h" +#include "libubiold.h" #include "ubimirror.h" #define PROGRAM_VERSION "1.4" diff --git a/ubi-utils/src/reader.c b/ubi-utils/src/reader.c index 7935a15..0ea8c6d 100644 --- a/ubi-utils/src/reader.c +++ b/ubi-utils/src/reader.c @@ -142,6 +142,7 @@ read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_raw_t* pfi_raw, char tmp_str[PFI_KEYWORD_LEN]; bootenv_list_t raw_start_list = NULL; pfi_raw_t res; + size_t size; res = (pfi_raw_t) malloc(sizeof(struct pfi_raw)); if (!res) @@ -178,8 +179,9 @@ read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_raw_t* pfi_raw, } rc = bootenv_list_to_num_vector(raw_start_list, - (void *) &(res->starts_size), - &(res->starts)); + &size, &(res->starts)); + res->starts_size = size; + if (rc != 0) { EBUF_PFI("Cannot create numeric value array: %s", tmp_str); goto err; @@ -209,6 +211,7 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi, bootenv_list_t ubi_name_list = NULL; pfi_ubi_t res; uint32_t i; + size_t size; res = (pfi_ubi_t) calloc(1, sizeof(struct pfi_ubi)); if (!res) @@ -247,8 +250,9 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi, goto err; } - rc = bootenv_list_to_num_vector(ubi_id_list, (void *) &(res->ids_size), + rc = bootenv_list_to_num_vector(ubi_id_list, &size, &(res->ids)); + res->ids_size = size; if (rc != 0) { EBUF_PFI("Cannot create numeric value array: %s", tmp_str); goto err; @@ -299,8 +303,9 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi, EBUF_PFI("Cannot translate PFI value: %s", tmp_str); goto err; } - rc = bootenv_list_to_vector(ubi_name_list, (void *) &(res->names_size), + rc = bootenv_list_to_vector(ubi_name_list, &size, &(tmp_names)); + res->names_size = size; if (rc != 0) { EBUF_PFI("Cannot create string array: %s", tmp_str); goto err; diff --git a/ubi-utils/src/ubimkvol.c b/ubi-utils/src/ubimkvol.c index 879dcb6..1368671 100644 --- a/ubi-utils/src/ubimkvol.c +++ b/ubi-utils/src/ubimkvol.c @@ -28,6 +28,7 @@ * 1.2 Reworked the user-interface to use argp. * 1.3 Removed argp because we want to use uClibc. * 1.4 Minor cleanups + * 1.5 Use a different libubi */ #include @@ -40,7 +41,7 @@ #include #include -#define PROGRAM_VERSION "1.4" +#define PROGRAM_VERSION "1.5" /* * The variables below are set by command line arguments. @@ -53,6 +54,7 @@ struct args { int alignment; char *name; int nlen; + char node[256]; /* special stuff needed to get additional arguments */ char *arg1; @@ -69,7 +71,7 @@ static struct args myargs = { .nlen = 0, }; -static int param_sanity_check(struct args *args, ubi_lib_t lib); +static int param_sanity_check(struct args *args, libubi_t libubi); static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t" BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" @@ -177,6 +179,7 @@ parse_opt(int argc, char **argv, struct args *args) "\"%s\"\n", optarg); goto out; } + sprintf(args->node, "/dev/ubi%d", args->devn); break; case 'n': /* --volid= */ args->vol_id = strtoul(optarg, &endp, 0); @@ -224,7 +227,7 @@ parse_opt(int argc, char **argv, struct args *args) return -1; } -static int param_sanity_check(struct args *args, ubi_lib_t lib) +static int param_sanity_check(struct args *args, libubi_t libubi) { int err, len; struct ubi_info ubi; @@ -239,7 +242,7 @@ static int param_sanity_check(struct args *args, ubi_lib_t lib) goto out; } - err = ubi_get_info(lib, &ubi); + err = ubi_get_info(libubi, &ubi); if (err) return -1; @@ -264,7 +267,8 @@ out: int main(int argc, char * const argv[]) { int err; - ubi_lib_t lib; + libubi_t libubi; + struct ubi_mkvol_request req; err = parse_opt(argc, (char **)argv, &myargs); if (err) { @@ -278,21 +282,26 @@ int main(int argc, char * const argv[]) return -1; } - err = ubi_open(&lib); - if (err) { + libubi = libubi_open(); + if (libubi == NULL) { perror("Cannot open libubi"); return -1; } - err = param_sanity_check(&myargs, lib); + err = param_sanity_check(&myargs, libubi); 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); + req.vol_id = myargs.vol_id; + req.alignment = myargs.alignment; + req.bytes = myargs.bytes; + req.vol_type = myargs.vol_type; + req.name = myargs.name; + + err = ubi_mkvol(libubi, myargs.node, &req); if (err < 0) { perror("Cannot create volume"); fprintf(stderr, " err=%d\n", err); @@ -304,10 +313,10 @@ int main(int argc, char * const argv[]) "dynamic" : "static", name); */ myargs.vol_id = err; - ubi_close(&lib); + libubi_close(libubi); return 0; out_libubi: - ubi_close(&lib); + libubi_close(libubi); return -1; } diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c index f458e8a..f32cbe0 100644 --- a/ubi-utils/src/ubirmvol.c +++ b/ubi-utils/src/ubirmvol.c @@ -25,6 +25,7 @@ * 1.1 Reworked the userinterface to use argp. * 1.2 Removed argp because we want to use uClibc. * 1.3 Minor cleanups + * 1.4 Use a different libubi */ #include @@ -37,7 +38,7 @@ #include #include -#define PROGRAM_VERSION "1.3" +#define PROGRAM_VERSION "1.4" /* * The below variables are set by command line options. @@ -45,6 +46,7 @@ struct args { int devn; int vol_id; + char node[256]; /* special stuff needed to get additional arguments */ char *arg1; @@ -59,7 +61,7 @@ static struct args myargs = { .options = NULL, }; -static int param_sanity_check(struct args *args, ubi_lib_t lib); +static int param_sanity_check(struct args *args, libubi_t libubi); static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t" BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n" @@ -118,6 +120,7 @@ parse_opt(int argc, char **argv, struct args *args) "\"%s\"\n", optarg); goto out; } + sprintf(args->node, "/dev/ubi%d", args->devn); break; case 'n': /* --volid= */ args->vol_id = strtoul(optarg, &endp, 0); @@ -156,7 +159,7 @@ parse_opt(int argc, char **argv, struct args *args) return -1; } -static int param_sanity_check(struct args *args, ubi_lib_t lib) +static int param_sanity_check(struct args *args, libubi_t libubi) { int err; struct ubi_info ubi; @@ -166,7 +169,7 @@ static int param_sanity_check(struct args *args, ubi_lib_t lib) goto out; } - err = ubi_get_info(lib, &ubi); + err = ubi_get_info(libubi, &ubi); if (err) return -1; @@ -185,7 +188,7 @@ out: int main(int argc, char * const argv[]) { int err, old_errno; - ubi_lib_t lib; + libubi_t libubi; err = parse_opt(argc, (char **)argv, &myargs); if (err) @@ -197,20 +200,20 @@ int main(int argc, char * const argv[]) return -1; } - err = ubi_open(&lib); - if (err) { + libubi = libubi_open(); + if (libubi == NULL) { perror("Cannot open libubi"); return -1; } - err = param_sanity_check(&myargs, lib); + err = param_sanity_check(&myargs, libubi); if (err) { perror("Input parameters check"); fprintf(stderr, "Use -h option for help\n"); goto out_libubi; } - err = ubi_rmvol(lib, myargs.devn, myargs.vol_id); + err = ubi_rmvol(libubi, myargs.node, myargs.vol_id); old_errno = errno; if (err < 0) { perror("Cannot remove volume"); @@ -218,9 +221,10 @@ int main(int argc, char * const argv[]) goto out_libubi; } + libubi_close(libubi); return 0; out_libubi: - ubi_close(&lib); + libubi_close(libubi); return -1; } diff --git a/ubi-utils/src/ubiupdatevol.c b/ubi-utils/src/ubiupdatevol.c index c0b4178..5401eb1 100644 --- a/ubi-utils/src/ubiupdatevol.c +++ b/ubi-utils/src/ubiupdatevol.c @@ -25,6 +25,7 @@ * 1.0 Reworked the userinterface to use argp. * 1.1 Removed argp parsing because we want to use uClib. * 1.2 Minor cleanups + * 1.3 Use a different libubi */ #include @@ -36,14 +37,12 @@ #include #include #include -#include #include -#include #include #include -#define PROGRAM_VERSION "1.2" +#define PROGRAM_VERSION "1.3" #define MAXPATH 1024 #define BUFSIZE 128 * 1024 @@ -174,7 +173,7 @@ parse_opt(int argc, char **argv, struct args *args) * some reason nothing is written. The volume is unusable after this. */ static int -ubi_truncate_volume(struct args *args, int64_t bytes) +ubi_truncate_volume(struct args *args, int64_t bytes,libubi_t libubi) { int rc, ofd; char path[MAXPATH]; @@ -188,7 +187,7 @@ ubi_truncate_volume(struct args *args, int64_t bytes) fprintf(stderr, "Cannot open volume %s\n", path); exit(EXIT_FAILURE); } - rc = ioctl(ofd, UBI_IOCVOLUP, &bytes); + rc = ubi_update_start(libubi, ofd, bytes); old_errno = errno; if (rc < 0) { perror("UBI volume update ioctl"); @@ -220,7 +219,7 @@ static ssize_t ubi_write(int fd, const void *buf, size_t count) } static int -ubi_update_volume(struct args *args) +ubi_update_volume(struct args *args, libubi_t libubi) { int rc, ofd; FILE *ifp = NULL; @@ -263,7 +262,7 @@ ubi_update_volume(struct args *args) exit(EXIT_FAILURE); } - rc = ioctl(ofd, UBI_IOCVOLUP, &bytes); + rc = ubi_update_start(libubi, ofd, bytes); old_errno = errno; if (rc < 0) { perror("UBI volume update ioctl"); @@ -304,24 +303,35 @@ int main(int argc, char *argv[]) { int rc; + libubi_t libubi; parse_opt(argc, argv, &myargs); + libubi = libubi_open(); + if (libubi == NULL) { + perror("Cannot open libubi"); + return -1; + } + if (myargs.truncate) { - rc = ubi_truncate_volume(&myargs, 0LL); + rc = ubi_truncate_volume(&myargs, 0LL, libubi); if (rc < 0) - exit(EXIT_FAILURE); - exit(EXIT_SUCCESS); + goto out_libubi; } - if (myargs.broken_update) { - rc = ubi_truncate_volume(&myargs, 1LL); + else if (myargs.broken_update) { + rc = ubi_truncate_volume(&myargs, 1LL, libubi); if (rc < 0) - exit(EXIT_FAILURE); - exit(EXIT_SUCCESS); + goto out_libubi; + } else { + rc = ubi_update_volume(&myargs, libubi); + if (rc < 0) + goto out_libubi; } - rc = ubi_update_volume(&myargs); - if (rc < 0) - exit(EXIT_FAILURE); - exit(EXIT_SUCCESS); + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; } -- cgit v1.2.3