From: Theodore Ts'o Date: Wed, 27 Feb 2008 00:05:33 +0000 (-0500) Subject: Fix dumpe2fs parsing of explicit superblock/blocksize parameters X-Git-Tag: v1.40.7~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db197a81cc7841af1afeb499645fd2a5767fa146;p=thirdparty%2Fe2fsprogs.git Fix dumpe2fs parsing of explicit superblock/blocksize parameters The dumpe2fs syntax documented in the man page has been broken for some time due to getopt() changes. Change the option syntax in dumpe2fs to be one which is more extensible and consistent with the format for extended options in mke2fs and tune2fs. Addresses-Sourceforge-Bug: #1830994 Signed-off-by: "Theodore Ts'o" --- diff --git a/misc/dumpe2fs.8.in b/misc/dumpe2fs.8.in index 6d57d23ff..79cf86382 100644 --- a/misc/dumpe2fs.8.in +++ b/misc/dumpe2fs.8.in @@ -11,12 +11,10 @@ dumpe2fs \- dump ext2/ext3 filesystem information .B \-bfhixV ] [ -.B \-ob -.I superblock +.B \-o superblock=\fIsuperblock ] [ -.B \-oB -.I blocksize +.B \-o blocksize=\fIblocksize ] .I device .SH DESCRIPTION @@ -34,14 +32,14 @@ program for the BSD Fast File System. .B \-b print the blocks which are reserved as bad in the filesystem. .TP -.BI \-ob " superblock" +.B \-o superblock=\fIsuperblock use the block .I superblock when examining the filesystem. This option is not usually needed except by a filesystem wizard who is examining the remains of a very badly corrupted filesystem. .TP -.BI \-oB " blocksize" +.B \-o blocksize=\fIblocksize use blocks of .I blocksize bytes when examining the filesystem. diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index fcae0f09e..394f8b2f2 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -323,6 +323,83 @@ static void print_journal_information(ext2_filsys fs) } } +static void parse_extended_opts(const char *opts, blk_t *superblock, + int *blocksize) +{ + char *buf, *token, *next, *p, *arg, *badopt = ""; + int len; + int usage = 0; + + len = strlen(opts); + buf = malloc(len+1); + if (!buf) { + fprintf(stderr, + _("Couldn't allocate memory to parse options!\n")); + exit(1); + } + strcpy(buf, opts); + for (token = buf; token && *token; token = next) { + p = strchr(token, ','); + next = 0; + if (p) { + *p = 0; + next = p+1; + } + arg = strchr(token, '='); + if (arg) { + *arg = 0; + arg++; + } + if (strcmp(token, "superblock") == 0 || + strcmp(token, "sb") == 0) { + if (!arg) { + usage++; + badopt = token; + continue; + } + *superblock = strtoul(arg, &p, 0); + if (*p) { + fprintf(stderr, + _("Invalid superblock parameter: %s\n"), + arg); + usage++; + continue; + } + } else if (strcmp(token, "blocksize") == 0 || + strcmp(token, "bs") == 0) { + if (!arg) { + usage++; + badopt = token; + continue; + } + *blocksize = strtoul(arg, &p, 0); + if (*p) { + fprintf(stderr, + _("Invalid blocksize parameter: %s\n"), + arg); + usage++; + continue; + } + } else { + usage++; + badopt = token; + } + } + if (usage) { + fprintf(stderr, _("\nBad extended option(s) specified: %s\n\n" + "Extended options are separated by commas, " + "and may take an argument which\n" + "\tis set off by an equals ('=') sign.\n\n" + "Valid extended options are:\n" + "\tsuperblock=\n" + "\tblocksize=\n"), + badopt); + free(buf); + exit(1); + } + free(buf); +} + int main (int argc, char ** argv) { errcode_t retval; @@ -364,12 +441,8 @@ int main (int argc, char ** argv) image_dump++; break; case 'o': - if (optarg[0] == 'b') - use_superblock = atoi(optarg+1); - else if (optarg[0] == 'B') - use_blocksize = atoi(optarg+1); - else - usage(); + parse_extended_opts(optarg, &use_superblock, + &use_blocksize); break; case 'V': /* Print version number and exit */ @@ -386,16 +459,26 @@ int main (int argc, char ** argv) if (optind > argc - 1) usage(); device_name = argv[optind++]; - if (use_superblock && !use_blocksize) - use_blocksize = 1024; flags = EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SOFTSUPP_FEATURES; if (force) flags |= EXT2_FLAG_FORCE; if (image_dump) flags |= EXT2_FLAG_IMAGE_FILE; - retval = ext2fs_open (device_name, flags, use_superblock, - use_blocksize, unix_io_manager, &fs); + if (use_superblock && !use_blocksize) { + for (use_blocksize = EXT2_MIN_BLOCK_SIZE; + use_blocksize <= EXT2_MAX_BLOCK_SIZE; + use_blocksize *= 2) { + retval = ext2fs_open (device_name, flags, + use_superblock, + use_blocksize, unix_io_manager, + &fs); + if (!retval) + break; + } + } else + retval = ext2fs_open (device_name, flags, use_superblock, + use_blocksize, unix_io_manager, &fs); if (retval) { com_err (program_name, retval, _("while trying to open %s"), device_name);