+
+ return retval;
+}
+
+static void print_mmp_block(ext2_filsys fs)
+{
+ struct mmp_struct *mmp;
+ time_t mmp_time;
+ errcode_t retval;
+
+ if (fs->mmp_buf == NULL) {
+ retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
+ if (retval) {
+ com_err(program_name, retval,
+ _("failed to alloc MMP buffer\n"));
+ return;
+ }
+ }
+
+ retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+ /* this is only dumping, not checking status, so OK to skip this */
+ if (retval == EXT2_ET_OP_NOT_SUPPORTED)
+ return;
+ if (retval) {
+ com_err(program_name, retval,
+ _("reading MMP block %llu from '%s'\n"),
+ (unsigned long long) fs->super->s_mmp_block,
+ fs->device_name);
+ return;
+ }
+
+ mmp = fs->mmp_buf;
+ mmp_time = mmp->mmp_time;
+ printf("MMP_block:\n");
+ printf(" mmp_magic: 0x%x\n", mmp->mmp_magic);
+ printf(" mmp_check_interval: %d\n", mmp->mmp_check_interval);
+ printf(" mmp_sequence: %#08x\n", mmp->mmp_seq);
+ printf(" mmp_update_date: %s", ctime(&mmp_time));
+ printf(" mmp_update_time: %llu\n",
+ (unsigned long long) mmp->mmp_time);
+ printf(" mmp_node_name: %.*s\n",
+ EXT2_LEN_STR(mmp->mmp_nodename));
+ printf(" mmp_device_name: %.*s\n",
+ EXT2_LEN_STR(mmp->mmp_bdevname));
+}
+
+static void parse_extended_opts(const char *opts, blk64_t *superblock,
+ int *blocksize)
+{
+ char *buf, *token, *next, *p, *arg, *badopt = 0;
+ int len;
+ int do_usage = 0;
+
+ len = strlen(opts);
+ buf = malloc(len+1);
+ if (!buf) {
+ fprintf(stderr, "%s",
+ _("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) {
+ do_usage++;
+ badopt = token;
+ continue;
+ }
+ *superblock = strtoul(arg, &p, 0);
+ if (*p) {
+ fprintf(stderr,
+ _("Invalid superblock parameter: %s\n"),
+ arg);
+ do_usage++;
+ continue;
+ }
+ } else if (strcmp(token, "blocksize") == 0 ||
+ strcmp(token, "bs") == 0) {
+ if (!arg) {
+ do_usage++;
+ badopt = token;
+ continue;
+ }
+ *blocksize = strtoul(arg, &p, 0);
+ if (*p) {
+ fprintf(stderr,
+ _("Invalid blocksize parameter: %s\n"),
+ arg);
+ do_usage++;
+ continue;
+ }
+ } else {
+ do_usage++;
+ badopt = token;
+ }
+ }
+ if (do_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 ? badopt : "");
+ free(buf);
+ exit(1);
+ }
+ free(buf);