| From 4c4998004882f14170879655526657ea93a288f5 Mon Sep 17 00:00:00 2001 |
| From: Mike Frysinger <vapier@gentoo.org> |
| Date: Thu, 9 May 2013 13:43:46 -0400 |
| Subject: [PATCH [mtd-utils] 2/2] ubiupdatevol: add a --skip option |
| |
| This already has a --size option for controlling how many bytes to read |
| from the input. Add a --skip option to control the offset into the input |
| too. This way people don't have to do `dd | ubiupdatevol`. |
| |
| Signed-off-by: Mike Frysinger <vapier@gentoo.org> |
| --- |
| ubi-utils/ubiupdatevol.c | 44 ++++++++++++++++++++++++++++++++------------ |
| 1 file changed, 32 insertions(+), 12 deletions(-) |
| |
| diff --git a/ubi-utils/ubiupdatevol.c b/ubi-utils/ubiupdatevol.c |
| index 7fedb3c..84d5fbb 100644 |
| --- a/ubi-utils/ubiupdatevol.c |
| +++ b/ubi-utils/ubiupdatevol.c |
| @@ -45,7 +45,8 @@ struct args { |
| const char *img; |
| /* For deprecated -d and -B options handling */ |
| char dev_name[256]; |
| - int size; |
| + long long size; |
| + long long skip; |
| int use_stdin; |
| }; |
| |
| @@ -56,7 +57,8 @@ static const char doc[] = PROGRAM_NAME " version " VERSION |
| |
| static const char optionsstr[] = |
| "-t, --truncate truncate volume (wipe it out)\n" |
| -"-s, --size=<bytes> bytes in input, if not reading from file\n" |
| +"-s, --size=<bytes> bytes to read from input\n" |
| +" --skip=<bytes> leading bytes to skip from input\n" |
| "-h, --help print help message\n" |
| "-V, --version print program version"; |
| |
| @@ -67,6 +69,8 @@ static const char usage[] = |
| "Example 2: " PROGRAM_NAME " /dev/ubi0_1 -t - wipe out UBI volume /dev/ubi0_1"; |
| |
| static const struct option long_options[] = { |
| + /* Order matters for opts w/val=0; see option_index below. */ |
| + { .name = "skip", .has_arg = 1, .flag = NULL, .val = 0 }, |
| { .name = "truncate", .has_arg = 0, .flag = NULL, .val = 't' }, |
| { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, |
| { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, |
| @@ -77,19 +81,29 @@ static const struct option long_options[] = { |
| static int parse_opt(int argc, char * const argv[]) |
| { |
| while (1) { |
| - int key, error = 0; |
| + int option_index, key, error = 0; |
| |
| - key = getopt_long(argc, argv, "ts:h?V", long_options, NULL); |
| + key = getopt_long(argc, argv, "ts:h?V", long_options, &option_index); |
| if (key == -1) |
| break; |
| |
| switch (key) { |
| + case 0: |
| + switch (option_index) { |
| + case 0: /* --skip */ |
| + args.skip = simple_strtoull(optarg, &error); |
| + if (error || args.skip < 0) |
| + return errmsg("bad skip: " "\"%s\"", optarg); |
| + break; |
| + } |
| + break; |
| + |
| case 't': |
| args.truncate = 1; |
| break; |
| |
| case 's': |
| - args.size = simple_strtoul(optarg, &error); |
| + args.size = simple_strtoull(optarg, &error); |
| if (error || args.size < 0) |
| return errmsg("bad size: " "\"%s\"", optarg); |
| break; |
| @@ -198,7 +211,7 @@ static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info) |
| goto out_free; |
| } |
| |
| - bytes = st.st_size; |
| + bytes = st.st_size - args.skip; |
| } else |
| bytes = args.size; |
| |
| @@ -214,14 +227,23 @@ static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info) |
| goto out_free; |
| } |
| |
| - if (args.use_stdin) |
| + if (args.use_stdin) { |
| ifd = STDIN_FILENO; |
| - else { |
| + if (args.skip) { |
| + errmsg("seeking stdin not supported"); |
| + goto out_close1; |
| + } |
| + } else { |
| ifd = open(args.img, O_RDONLY); |
| if (ifd == -1) { |
| sys_errmsg("cannot open \"%s\"", args.img); |
| goto out_close1; |
| } |
| + |
| + if (args.skip && lseek(ifd, args.skip, SEEK_CUR) == -1) { |
| + sys_errmsg("lseek input by %lld failed", args.skip); |
| + goto out_close; |
| + } |
| } |
| |
| err = ubi_update_start(libubi, fd, bytes); |
| @@ -231,10 +253,8 @@ static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info) |
| } |
| |
| while (bytes) { |
| - int ret, to_copy = vol_info->leb_size; |
| - |
| - if (to_copy > bytes) |
| - to_copy = bytes; |
| + ssize_t ret; |
| + int to_copy = min(vol_info->leb_size, bytes); |
| |
| ret = read(ifd, buf, to_copy); |
| if (ret <= 0) { |
| -- |
| 1.8.2.1 |
| |