From db197a81cc7841af1afeb499645fd2a5767fa146 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 26 Feb 2008 19:05:33 -0500 Subject: [PATCH] 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" --- misc/dumpe2fs.8.in | 10 +++--- misc/dumpe2fs.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 97 insertions(+), 16 deletions(-) diff --git a/misc/dumpe2fs.8.in b/misc/dumpe2fs.8.in index 6d57d23..79cf863 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 fcae0f0..394f8b2 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); -- 1.8.3.1