e2fsprogs: stop using statics in chattr. Minor code shrinkage (-130 bytes)
No binary (build failed)
—
(log yok)
| @@ -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; | |
| } | |
| @@ -12,11 +12,11 @@ | |
| #define HAVE_EXT2_IOCTLS 1 | |
| #if INT_MAX == LONG_MAX | |
| - | #define IF_LONG_IS_SAME(x) x |
| - | #define IF_LONG_IS_WIDER(x) |
| + | #define IF_LONG_IS_SAME(...) __VA_ARGS__ |
| + | #define IF_LONG_IS_WIDER(...) |
| #else | |
| - | #define IF_LONG_IS_SAME(x) |
| - | #define IF_LONG_IS_WIDER(x) x |
| + | #define IF_LONG_IS_SAME(...) |
| + | #define IF_LONG_IS_WIDER(...) __VA_ARGS__ |
| #endif | |
| static void close_silently(int fd) | |
| @@ -147,6 +147,8 @@ struct flags_name { | |
| const char *long_name; | |
| }; | |
| + | /* TODO: apart from I and (disabled) COMPRESSION flags, this |
| + | * is a duplicate of a table from chattr. Merge? */ |
| static const struct flags_name flags_array[] = { | |
| { EXT2_SECRM_FL, 's', "Secure_Deletion" }, | |
| { EXT2_UNRM_FL, 'u' , "Undelete" }, | |
| @@ -34,11 +34,11 @@ static void list_attributes(const char *name) | |
| unsigned long fsflags; | |
| unsigned long generation; | |
| - | if (fgetflags(name, &fsflags) == -1) |
| + | if (fgetflags(name, &fsflags) != 0) |
| goto read_err; | |
| if (option_mask32 & OPT_GENERATION) { | |
| - | if (fgetversion(name, &generation) == -1) |
| + | if (fgetversion(name, &generation) != 0) |
| goto read_err; | |
| printf("%5lu ", generation); | |
| } | |
| @@ -65,14 +65,12 @@ static int lsattr_dir_proc(const char *dir_name, struct dirent *de, | |
| path = concat_path_file(dir_name, de->d_name); | |
| - | if (lstat(path, &st) == -1) |
| + | if (lstat(path, &st) != 0) |
| bb_perror_msg("stat %s", path); | |
| - | |
| else if (de->d_name[0] != '.' || (option_mask32 & OPT_ALL)) { | |
| list_attributes(path); | |
| if (S_ISDIR(st.st_mode) && (option_mask32 & OPT_RECUR) | |
| - | && (de->d_name[0] != '.' |
| - | || (de->d_name[1] != '\0' && NOT_LONE_CHAR(de->d_name+1, '.'))) |
| + | && !DOT_OR_DOTDOT(de->d_name) |
| ) { | |
| printf("\n%s:\n", path); | |
| iterate_on_dir(path, lsattr_dir_proc, NULL); | |
| @@ -81,7 +79,6 @@ static int lsattr_dir_proc(const char *dir_name, struct dirent *de, | |
| } | |
| free(path); | |
| - | |
| return 0; | |
| } | |