diff options
author | Theodore Ts'o <tytso@mit.edu> | 2000-08-14 20:37:09 +0000 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2000-08-14 20:37:09 +0000 |
commit | c6bd0c97e4dc42511015b9a20b3e35dcdc8fd411 (patch) | |
tree | 482efd09b102ad8f03f7fc692aa2606a0e4e3124 /debugfs | |
parent | 53d3955001593b668b15e2d10b3a191f689f9779 (diff) | |
download | e2fsprogs-c6bd0c97e4dc42511015b9a20b3e35dcdc8fd411.tar.gz |
Makefile.in, debug_cmds.ct, setsuper.c, ChangeLog:
setsuper.c: New function which implements the set_super_value command.
Allows the user to set arbitrary superblock fields.
ChangeLog, util.c:
util.c (open_pager): If the PAGER environment variable is not set,
default to using "more".
Diffstat (limited to 'debugfs')
-rw-r--r-- | debugfs/ChangeLog | 7 | ||||
-rw-r--r-- | debugfs/Makefile.in | 5 | ||||
-rw-r--r-- | debugfs/debug_cmds.ct | 3 | ||||
-rw-r--r-- | debugfs/setsuper.c | 201 | ||||
-rw-r--r-- | debugfs/util.c | 9 |
5 files changed, 219 insertions, 6 deletions
diff --git a/debugfs/ChangeLog b/debugfs/ChangeLog index 8629e5f9..1fd1a3f0 100644 --- a/debugfs/ChangeLog +++ b/debugfs/ChangeLog @@ -1,5 +1,12 @@ 2000-08-14 <tytso@valinux.com> + * util.c (open_pager): If the PAGER environment variable is not + set, default to using "more". + + * setsuper.c: New function which implements the set_super_value + command. Allows the user to set arbitrary superblock + fields. + * debugfs.c (dump_inode): Cap the length when printing a fast symbolic link to inode.i_size. (list_blocks_proc): Print block ranges (4510-4533) to make diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in index 66a9a03f..7ecc55d7 100644 --- a/debugfs/Makefile.in +++ b/debugfs/Makefile.in @@ -16,11 +16,12 @@ MANPAGES= debugfs.8 MK_CMDS= _SS_DIR_OVERRIDE=../lib/ss ../lib/ss/mk_cmds -DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o lsdel.o dump.o +DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \ + lsdel.o dump.o setsuper.o SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c $(srcdir)/ls.c \ $(srcdir)/ncheck.c $(srcdir)/icheck.c $(srcdir)/lsdel.c \ - $(srcdir)/dump.c + $(srcdir)/dump.c $(srcdir)/setsuper.c LIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSS) $(LIBCOM_ERR) $(LIBUUID) DEPLIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSS) $(LIBCOM_ERR) $(DEPLIBUUID) diff --git a/debugfs/debug_cmds.ct b/debugfs/debug_cmds.ct index 9b2f5928..0d142ba4 100644 --- a/debugfs/debug_cmds.ct +++ b/debugfs/debug_cmds.ct @@ -118,5 +118,8 @@ request do_lcd, "Change the current directory on your native filesystem", request do_rdump, "Recursively dump a directory to the native filesystem", rdump; +request do_set_super, "Set superblock value", + set_super_value, ssv; + end; diff --git a/debugfs/setsuper.c b/debugfs/setsuper.c new file mode 100644 index 00000000..e57aa392 --- /dev/null +++ b/debugfs/setsuper.c @@ -0,0 +1,201 @@ +/* + * setsuper.c --- set a superblock value + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif +#include <fcntl.h> +#include <utime.h> + +#include "debugfs.h" + +static struct ext2_super_block set_sb; + +struct super_set_info { + char *name; + void *ptr; + int size; + errcode_t (*func)(struct super_set_info *info, char *arg); +}; + +static errcode_t parse_uint(struct super_set_info *info, char *arg); +static errcode_t parse_int(struct super_set_info *info, char *arg); +static errcode_t parse_string(struct super_set_info *info, char *arg); + +static struct super_set_info super_fields[] = { + { "inodes_count", &set_sb.s_inodes_count, 4, parse_uint }, + { "blocks_count", &set_sb.s_blocks_count, 4, parse_uint }, + { "r_blocks_count", &set_sb.s_r_blocks_count, 4, parse_uint }, + { "free_blocks_count", &set_sb.s_free_blocks_count, 4, parse_uint }, + { "free_inodes_count", &set_sb.s_free_inodes_count, 4, parse_uint }, + { "first_data_block", &set_sb.s_first_data_block, 4, parse_uint }, + { "log_block_size", &set_sb.s_log_block_size, 4, parse_uint }, + { "log_frag_size", &set_sb.s_log_frag_size, 4, parse_int }, + { "blocks_per_group", &set_sb.s_blocks_per_group, 4, parse_uint }, + { "frags_per_group", &set_sb.s_frags_per_group, 4, parse_uint }, + { "inodes_per_group", &set_sb.s_inodes_per_group, 4, parse_uint }, + /* s_mtime (time_t) */ + /* s_wtime (time_t) */ + { "mnt_count", &set_sb.s_mnt_count, 2, parse_uint }, + { "max_mnt_count", &set_sb.s_max_mnt_count, 2, parse_int }, + /* s_magic */ + { "state", &set_sb.s_state, 2, parse_uint }, + { "errors", &set_sb.s_errors, 2, parse_uint }, + { "minor_rev_level", &set_sb.s_minor_rev_level, 2, parse_uint }, + /* s_lastcheck (time_t) */ + { "checkinterval", &set_sb.s_checkinterval, 4, parse_uint }, + { "creator_os", &set_sb.s_creator_os, 4, parse_uint }, + { "rev_level", &set_sb.s_rev_level, 4, parse_uint }, + { "def_resuid", &set_sb.s_def_resuid, 2, parse_uint }, + { "def_resgid", &set_sb.s_def_resgid, 2, parse_uint }, + { "first_ino", &set_sb.s_first_ino, 4, parse_uint }, + { "s_inode_size", &set_sb. s_inode_size, 2, parse_uint }, + { "block_group_nr", &set_sb.s_block_group_nr, 2, parse_uint }, + { "feature_compat", &set_sb.s_feature_compat, 4, parse_uint }, + { "feature_incompat", &set_sb.s_feature_incompat, 4, parse_uint }, + { "feature_ro_compat", &set_sb.s_feature_ro_compat, 4, parse_uint }, + /* __u8 s_uuid[16]; */ + { "volume_name", &set_sb.s_volume_name, 16, parse_string }, + { "last_mounted", &set_sb.s_last_mounted, 64, parse_string }, + { "algorithm_usage_bitmap", &set_sb.s_algorithm_usage_bitmap, + 4, parse_uint }, + { "prealloc_blocks", &set_sb.s_prealloc_blocks, 1, parse_uint }, + { "prealloc_dir_blocks", &set_sb.s_prealloc_dir_blocks, 1, + parse_uint }, + /* s_padding1 */ + /* s_journal_uuid */ + { "journal_inum", &set_sb.s_journal_inum, 4, parse_uint }, + { "journal_dev", &set_sb.s_journal_dev, 4, parse_uint }, + { "last_orphan", &set_sb.s_last_orphan, 4, parse_uint }, + + { 0, 0, 0, 0 } +}; + +static struct super_set_info *find_field(char *field) +{ + struct super_set_info *ss; + + for (ss = super_fields ; ss->name ; ss++) { + if (strcmp(ss->name, field) == 0) + return ss; + } + return NULL; +} + +static errcode_t parse_uint(struct super_set_info *info, char *arg) +{ + unsigned long num; + char *tmp; + __u32 *ptr32; + __u16 *ptr16; + __u8 *ptr8; + + num = strtoul(arg, &tmp, 0); + if (*tmp) { + fprintf(stderr, "Couldn't parse '%s' for field %s.\n", + arg, info->name); + return EINVAL; + } + switch (info->size) { + case 4: + ptr32 = (__u32 *) info->ptr; + *ptr32 = num; + break; + case 2: + ptr16 = (__u16 *) info->ptr; + *ptr16 = num; + break; + case 1: + ptr8 = (__u8 *) info->ptr; + *ptr8 = num; + break; + } + return 0; +} + +static errcode_t parse_int(struct super_set_info *info, char *arg) +{ + long num; + char *tmp; + __s32 *ptr32; + __s16 *ptr16; + __s8 *ptr8; + + num = strtol(arg, &tmp, 0); + if (*tmp) { + fprintf(stderr, "Couldn't parse '%s' for field %s.\n", + arg, info->name); + return EINVAL; + } + switch (info->size) { + case 4: + ptr32 = (__s32 *) info->ptr; + *ptr32 = num; + break; + case 2: + ptr16 = (__s16 *) info->ptr; + *ptr16 = num; + break; + case 1: + ptr8 = (__s8 *) info->ptr; + *ptr8 = num; + break; + } + return 0; +} + +static errcode_t parse_string(struct super_set_info *info, char *arg) +{ + char *cp = (char *) info->ptr; + + if (strlen(arg) >= info->size) { + fprintf(stderr, "Error maximum size for %s is %d.\n", + info->name, info->size); + return EINVAL; + } + strcpy(cp, arg); + return 0; +} + +void do_set_super(int argc, char *argv[]) +{ + char *cp; + ino_t parent; + char *name; + errcode_t retval; + static struct super_set_info *ss; + + if (check_fs_open(argv[0])) + return; + + if (argc != 3) { + com_err(argv[0], 0, "Usage: set_super <field> <value>"); + return; + } + + if (check_fs_read_write(argv[0])) + return; + + if ((ss = find_field(argv[1])) == 0) { + com_err(argv[0], 0, "invalid field specifier: %s", argv[1]); + return; + } + set_sb = *current_fs->super; + if (ss->func(ss, argv[2]) == 0) { + *current_fs->super = set_sb; + ext2fs_mark_super_dirty(current_fs); + } +} + + + + diff --git a/debugfs/util.c b/debugfs/util.c index 66a0bea8..fc02ed55 100644 --- a/debugfs/util.c +++ b/debugfs/util.c @@ -21,11 +21,12 @@ FILE *open_pager(void) char *pager = getenv("PAGER"); if (!pager) + pager = "more"; + + outfile = popen(pager, "w"); + if (!outfile) outfile = stdout; - else { - outfile = popen(pager, "w"); - if (!outfile) outfile = stdout; - } + return (outfile); } |