Whamcloud - gitweb
Fix dumpe2fs parsing of explicit superblock/blocksize parameters
authorTheodore Ts'o <tytso@mit.edu>
Wed, 27 Feb 2008 00:05:33 +0000 (19:05 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 27 Feb 2008 00:05:33 +0000 (19:05 -0500)
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" <tytso@mit.edu>
misc/dumpe2fs.8.in
misc/dumpe2fs.c

index 6d57d23..79cf863 100644 (file)
@@ -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.
index fcae0f0..394f8b2 100644 (file)
@@ -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=<superblock number>\n"
+                       "\tblocksize=<blocksize>\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);