diff options
Diffstat (limited to 'e2fsprogs/chattr.c')
-rw-r--r-- | e2fsprogs/chattr.c | 144 |
1 files changed, 72 insertions, 72 deletions
diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c index 1b7942e1f..82dba4adf 100644 --- a/e2fsprogs/chattr.c +++ b/e2fsprogs/chattr.c @@ -26,59 +26,54 @@ #define OPT_REM 2 #define OPT_SET 4 #define OPT_SET_VER 8 -static int flags; -static int recursive; -static unsigned long version; - -static unsigned long af; -static unsigned long rf; -static unsigned long sf; - -struct flags_char { - unsigned long flag; - char optchar; -}; - -static const struct flags_char flags_array[] = { - { EXT2_NOATIME_FL, 'A' }, - { EXT2_SYNC_FL, 'S' }, - { EXT2_DIRSYNC_FL, 'D' }, - { EXT2_APPEND_FL, 'a' }, - { EXT2_COMPR_FL, 'c' }, - { EXT2_NODUMP_FL, 'd' }, - { EXT2_IMMUTABLE_FL, 'i' }, - { EXT3_JOURNAL_DATA_FL, 'j' }, - { EXT2_SECRM_FL, 's' }, - { EXT2_UNRM_FL, 'u' }, - { EXT2_NOTAIL_FL, 't' }, - { EXT2_TOPDIR_FL, 'T' }, - { 0, 0 } +struct globals { + unsigned long version; + unsigned long af; + unsigned long rf; + smallint flags; + smallint recursive; }; static unsigned long get_flag(char c) { - const struct flags_char *fp; - for (fp = flags_array; fp->optchar; fp++) - if (fp->optchar == c) - return fp->flag; + /* Two separate vectors take less space than vector of structs */ + static const char flags_letter[] = "ASDacdijsutT"; + static const unsigned long flags_val[] = { + /* A */ EXT2_NOATIME_FL, + /* S */ EXT2_SYNC_FL, + /* D */ EXT2_DIRSYNC_FL, + /* a */ EXT2_APPEND_FL, + /* c */ EXT2_COMPR_FL, + /* d */ EXT2_NODUMP_FL, + /* i */ EXT2_IMMUTABLE_FL, + /* j */ EXT3_JOURNAL_DATA_FL, + /* s */ EXT2_SECRM_FL, + /* u */ EXT2_UNRM_FL, + /* t */ EXT2_NOTAIL_FL, + /* T */ EXT2_TOPDIR_FL, + }; + const char *fp; + + for (fp = flags_letter; *fp; fp++) + if (*fp == c) + return flags_val[fp - flags_letter]; bb_show_usage(); } -static int decode_arg(const char *arg) +static int decode_arg(const char *arg, struct globals *gp) { unsigned long *fl; char opt = *arg++; + fl = &gp->af; if (opt == '-') { - flags |= OPT_REM; - fl = &rf; + gp->flags |= OPT_REM; + fl = &gp->rf; } else if (opt == '+') { - flags |= OPT_ADD; - fl = ⁡ + gp->flags |= OPT_ADD; } else if (opt == '=') { - flags |= OPT_SET; - fl = &sf; + gp->flags |= OPT_SET; } else return 0; @@ -88,30 +83,29 @@ static int decode_arg(const char *arg) return 1; } -static void change_attributes(const char *name); +static void change_attributes(const char *name, struct globals *gp); -static int chattr_dir_proc(const char *dir_name, struct dirent *de, - void *private ATTRIBUTE_UNUSED) +static int chattr_dir_proc(const char *dir_name, struct dirent *de, void *gp) { char *path = concat_subpath_file(dir_name, de->d_name); /* path is NULL if de->d_name is "." or "..", else... */ if (path) { - change_attributes(path); + change_attributes(path, gp); free(path); } return 0; } -static void change_attributes(const char *name) +static void change_attributes(const char *name, struct globals *gp) { unsigned long fsflags; struct stat st; - if (lstat(name, &st) == -1) { + if (lstat(name, &st) != 0) { bb_perror_msg("stat %s", name); return; } - if (S_ISLNK(st.st_mode) && recursive) + if (S_ISLNK(st.st_mode) && gp->recursive) return; /* Don't try to open device files, fifos etc. We probably @@ -121,70 +115,76 @@ static void change_attributes(const char *name) if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode)) return; - if (flags & OPT_SET_VER) - if (fsetversion(name, version) == -1) + if (gp->flags & OPT_SET_VER) + if (fsetversion(name, gp->version) != 0) bb_perror_msg("setting version on %s", name); - if (flags & OPT_SET) { - fsflags = sf; + if (gp->flags & OPT_SET) { + fsflags = gp->af; } else { - if (fgetflags(name, &fsflags) == -1) { + if (fgetflags(name, &fsflags) != 0) { bb_perror_msg("reading flags on %s", name); goto skip_setflags; } - if (flags & OPT_REM) - fsflags &= ~rf; - if (flags & OPT_ADD) - fsflags |= af; + /*if (gp->flags & OPT_REM) - not needed, rf is zero otherwise */ + fsflags &= ~gp->rf; + /*if (gp->flags & OPT_ADD) - not needed, af is zero otherwise */ + fsflags |= gp->af; + /* What is this? And why it's not done for SET case? */ if (!S_ISDIR(st.st_mode)) fsflags &= ~EXT2_DIRSYNC_FL; } - if (fsetflags(name, fsflags) == -1) + if (fsetflags(name, fsflags) != 0) bb_perror_msg("setting flags on %s", name); skip_setflags: - if (recursive && S_ISDIR(st.st_mode)) - iterate_on_dir(name, chattr_dir_proc, NULL); + if (gp->recursive && S_ISDIR(st.st_mode)) + iterate_on_dir(name, chattr_dir_proc, gp); } int chattr_main(int argc, char **argv); int chattr_main(int argc, char **argv) { + struct globals g; char *arg; + memset(&g, 0, sizeof(g)); + /* parse the args */ while ((arg = *++argv)) { /* take care of -R and -v <version> */ - if (arg[0] == '-') { - if (arg[1] == 'R' && arg[2] == '\0') { - recursive = 1; - continue; - } - if (arg[1] == 'v' && arg[2] == '\0') { - if (!*++argv) - bb_show_usage(); - version = xatoul(*argv); - flags |= OPT_SET_VER; + if (arg[0] == '-' + && (arg[1] == 'R' || arg[1] == 'v') + && !arg[2] + ) { + if (arg[1] == 'R') { + g.recursive = 1; continue; } + /* arg[1] == 'v' */ + if (!*++argv) + bb_show_usage(); + g.version = xatoul(*argv); + g.flags |= OPT_SET_VER; + continue; } - if (!decode_arg(arg)) + if (!decode_arg(arg, &g)) break; } /* run sanity checks on all the arguments given us */ if (!*argv) bb_show_usage(); - if ((flags & OPT_SET) && (flags & (OPT_ADD|OPT_REM))) + if ((g.flags & OPT_SET) && (g.flags & (OPT_ADD|OPT_REM))) bb_error_msg_and_die("= is incompatible with - and +"); - if (rf & af) + if (g.rf & g.af) bb_error_msg_and_die("can't set and unset a flag"); - if (!flags) + if (!g.flags) bb_error_msg_and_die("must use '-v', =, - or +"); /* now run chattr on all the files passed to us */ - do change_attributes(*argv); while (*++argv); + do change_attributes(*argv, &g); while (*++argv); return EXIT_SUCCESS; } |