From e2b9215868a3d72691e5bc0f887354254606447b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 14 Jun 2021 20:47:20 +0200 Subject: *: --help tweaks function old new delta packed_usage 33589 33552 -37 Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 +- shell/hush.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index bcf7a3470..85d43ca6f 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -14398,7 +14398,7 @@ init(void) //usage:#define ash_trivial_usage -//usage: "[-il] [-/+Cabefmnuvx] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" +//usage: "[-il] [-|+Cabefmnuvx] [-|+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] | FILE [ARGS] | -s [ARGS]]" //////// comes from ^^^^^^^^^^optletters //usage:#define ash_full_usage "\n\n" //usage: "Unix shell interpreter" diff --git a/shell/hush.c b/shell/hush.c index 77921e11c..4a049899b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -339,7 +339,7 @@ * therefore we don't show them either. */ //usage:#define hush_trivial_usage -//usage: "[-enxl] [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" +//usage: "[-enxl] [-c 'SCRIPT' [ARG0 [ARGS]] | FILE [ARGS] | -s [ARGS]]" //usage:#define hush_full_usage "\n\n" //usage: "Unix shell interpreter" -- cgit v1.2.3-55-g6feb From 1f60d88cf6f5ad3efcad6e7ef1501ce334046e40 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Jun 2021 10:00:18 +0200 Subject: *: more --help tweaks function old new delta packed_usage 33552 33541 -11 Signed-off-by: Denys Vlasenko --- archival/unzip.c | 2 +- coreutils/who.c | 2 +- loginutils/su.c | 2 +- miscutils/bc.c | 2 +- miscutils/chat.c | 2 +- miscutils/ubi_tools.c | 2 +- procps/sysctl.c | 4 ++-- shell/ash.c | 2 +- shell/hush.c | 2 +- util-linux/renice.c | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) (limited to 'shell') diff --git a/archival/unzip.c b/archival/unzip.c index fcdda6dfa..fc92ac661 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -56,7 +56,7 @@ //kbuild:lib-$(CONFIG_UNZIP) += unzip.o //usage:#define unzip_trivial_usage -//usage: "[-lnojpq] FILE[.zip] [FILE]... [-x FILE...] [-d DIR]" +//usage: "[-lnojpq] FILE[.zip] [FILE]... [-x FILE]... [-d DIR]" //usage:#define unzip_full_usage "\n\n" //usage: "Extract FILEs from ZIP archive\n" //usage: "\n -l List contents (with -q for short form)" diff --git a/coreutils/who.c b/coreutils/who.c index be9c3ccca..3725d77f5 100644 --- a/coreutils/who.c +++ b/coreutils/who.c @@ -78,7 +78,7 @@ // root pts/1 Mon13 3:24m 1:01 0.01s w //usage:#define who_trivial_usage -//usage: "[-a]" +//usage: "[-aH]" //usage:#define who_full_usage "\n\n" //usage: "Show who is logged on\n" //usage: "\n -a Show all" diff --git a/loginutils/su.c b/loginutils/su.c index 784a53552..e1db7590f 100644 --- a/loginutils/su.c +++ b/loginutils/su.c @@ -35,7 +35,7 @@ //kbuild:lib-$(CONFIG_SU) += su.o //usage:#define su_trivial_usage -//usage: "[-lmp] [-] [-s SH] [USER [SCRIPT ARGS / -c 'CMD' ARG0 ARGS]]" +//usage: "[-lmp] [-s SH] [-] [USER [FILE ARGS | -c 'CMD' [ARG0 ARGS]]]" //usage:#define su_full_usage "\n\n" //usage: "Run shell under USER (by default, root)\n" //usage: "\n -,-l Clear environment, go to home dir, run shell as login shell" diff --git a/miscutils/bc.c b/miscutils/bc.c index a5d8734b3..f9b08b01e 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -108,7 +108,7 @@ //See www.gnu.org/software/bc/manual/bc.html //usage:#define bc_trivial_usage -//usage: "[-sqlw] [FILE...]" +//usage: "[-sqlw] [FILE]..." //usage: //usage:#define bc_full_usage "\n" //usage: "\nArbitrary precision calculator" diff --git a/miscutils/chat.c b/miscutils/chat.c index 86a114df6..f9e12a4ac 100644 --- a/miscutils/chat.c +++ b/miscutils/chat.c @@ -79,7 +79,7 @@ //kbuild:lib-$(CONFIG_CHAT) += chat.o //usage:#define chat_trivial_usage -//usage: "EXPECT [SEND [EXPECT [SEND...]]]" +//usage: "EXPECT [SEND [EXPECT [SEND]]...]" //usage:#define chat_full_usage "\n\n" //usage: "Useful for interacting with a modem connected to stdin/stdout.\n" //usage: "A script consists of \"expect-send\" argument pairs.\n" diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c index 69ead7a13..6d49f61d9 100644 --- a/miscutils/ubi_tools.c +++ b/miscutils/ubi_tools.c @@ -251,7 +251,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) } else //usage:#define ubirmvol_trivial_usage -//usage: "-n VOLID / -N VOLNAME UBI_DEVICE" +//usage: "-n VOLID | -N VOLNAME UBI_DEVICE" //usage:#define ubirmvol_full_usage "\n\n" //usage: "Remove UBI volume\n" //usage: "\n -n VOLID Volume ID" diff --git a/procps/sysctl.c b/procps/sysctl.c index e16b119e9..40afa0c90 100644 --- a/procps/sysctl.c +++ b/procps/sysctl.c @@ -21,16 +21,16 @@ //kbuild:lib-$(CONFIG_BB_SYSCTL) += sysctl.o //usage:#define sysctl_trivial_usage -//usage: "-p [-enq] [FILE...] / [-enqaw] [KEY[=VALUE]]..." +//usage: "[-enq] { -a | -p [FILE]... | [-w] [KEY[=VALUE]]... }" //usage:#define sysctl_full_usage "\n\n" //usage: "Show/set kernel parameters\n" -//usage: "\n -p Set values from FILEs (default /etc/sysctl.conf)" //usage: "\n -e Don't warn about unknown keys" //usage: "\n -n Don't show key names" //usage: "\n -q Quiet" //usage: "\n -a Show all values" /* Same as -a, no need to show it */ /* //usage: "\n -A Show all values in table form" */ +//usage: "\n -p Set values from FILEs (default /etc/sysctl.conf)" //usage: "\n -w Set values" //usage: //usage:#define sysctl_example_usage diff --git a/shell/ash.c b/shell/ash.c index 85d43ca6f..bee81920a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -14398,7 +14398,7 @@ init(void) //usage:#define ash_trivial_usage -//usage: "[-il] [-|+Cabefmnuvx] [-|+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] | FILE [ARGS] | -s [ARGS]]" +//usage: "[-il] [-|+Cabefmnuvx] [-|+o OPT]... [-c 'SCRIPT' [ARG0 ARGS] | FILE [ARGS] | -s [ARGS]]" //////// comes from ^^^^^^^^^^optletters //usage:#define ash_full_usage "\n\n" //usage: "Unix shell interpreter" diff --git a/shell/hush.c b/shell/hush.c index 4a049899b..741f93589 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -339,7 +339,7 @@ * therefore we don't show them either. */ //usage:#define hush_trivial_usage -//usage: "[-enxl] [-c 'SCRIPT' [ARG0 [ARGS]] | FILE [ARGS] | -s [ARGS]]" +//usage: "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE [ARGS] | -s [ARGS]]" //usage:#define hush_full_usage "\n\n" //usage: "Unix shell interpreter" diff --git a/util-linux/renice.c b/util-linux/renice.c index a318ffce0..fc72550f4 100644 --- a/util-linux/renice.c +++ b/util-linux/renice.c @@ -29,7 +29,7 @@ //kbuild:lib-$(CONFIG_RENICE) += renice.o //usage:#define renice_trivial_usage -//usage: "[-n] PRIORITY [[-p | -g | -u] ID...]..." +//usage: "[-n] PRIORITY [[-p|g|u] ID...]..." //usage:#define renice_full_usage "\n\n" //usage: "Change scheduling priority of a running process\n" //usage: "\n -n Add PRIORITY to current nice value" -- cgit v1.2.3-55-g6feb From 1b7a9b68d0e9aa19147d7fda16eb9a6b54156985 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Jun 2021 16:05:57 +0200 Subject: hush: fix handling of \^C and "^C" function old new delta parse_stream 2238 2252 +14 encode_string 243 256 +13 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 27/0) Total: 27 bytes Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-misc/control_char3.right | 1 + shell/ash_test/ash-misc/control_char3.tests | 2 ++ shell/ash_test/ash-misc/control_char4.right | 1 + shell/ash_test/ash-misc/control_char4.tests | 2 ++ shell/hush.c | 11 +++++++++++ shell/hush_test/hush-misc/control_char3.right | 1 + shell/hush_test/hush-misc/control_char3.tests | 2 ++ shell/hush_test/hush-misc/control_char4.right | 1 + shell/hush_test/hush-misc/control_char4.tests | 2 ++ 9 files changed, 23 insertions(+) create mode 100644 shell/ash_test/ash-misc/control_char3.right create mode 100755 shell/ash_test/ash-misc/control_char3.tests create mode 100644 shell/ash_test/ash-misc/control_char4.right create mode 100755 shell/ash_test/ash-misc/control_char4.tests create mode 100644 shell/hush_test/hush-misc/control_char3.right create mode 100755 shell/hush_test/hush-misc/control_char3.tests create mode 100644 shell/hush_test/hush-misc/control_char4.right create mode 100755 shell/hush_test/hush-misc/control_char4.tests (limited to 'shell') diff --git a/shell/ash_test/ash-misc/control_char3.right b/shell/ash_test/ash-misc/control_char3.right new file mode 100644 index 000000000..283e02cbb --- /dev/null +++ b/shell/ash_test/ash-misc/control_char3.right @@ -0,0 +1 @@ +SHELL: line 1: : not found diff --git a/shell/ash_test/ash-misc/control_char3.tests b/shell/ash_test/ash-misc/control_char3.tests new file mode 100755 index 000000000..4359db3f3 --- /dev/null +++ b/shell/ash_test/ash-misc/control_char3.tests @@ -0,0 +1,2 @@ +# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) +$THIS_SH -c '\' SHELL diff --git a/shell/ash_test/ash-misc/control_char4.right b/shell/ash_test/ash-misc/control_char4.right new file mode 100644 index 000000000..2bf18e684 --- /dev/null +++ b/shell/ash_test/ash-misc/control_char4.right @@ -0,0 +1 @@ +SHELL: line 1: -: not found diff --git a/shell/ash_test/ash-misc/control_char4.tests b/shell/ash_test/ash-misc/control_char4.tests new file mode 100755 index 000000000..48010f154 --- /dev/null +++ b/shell/ash_test/ash-misc/control_char4.tests @@ -0,0 +1,2 @@ +# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) +$THIS_SH -c '"-"' SHELL diff --git a/shell/hush.c b/shell/hush.c index 741f93589..e271c04d6 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -5237,6 +5237,11 @@ static int encode_string(o_string *as_string, } #endif o_addQchr(dest, ch); + if (ch == SPECIAL_VAR_SYMBOL) { + /* Convert "^C" to corresponding special variable reference */ + o_addchr(dest, SPECIAL_VAR_QUOTED_SVS); + o_addchr(dest, SPECIAL_VAR_SYMBOL); + } goto again; #undef as_string } @@ -5348,6 +5353,11 @@ static struct pipe *parse_stream(char **pstring, if (ch == '\n') continue; /* drop \, get next char */ nommu_addchr(&ctx.as_string, '\\'); + if (ch == SPECIAL_VAR_SYMBOL) { + nommu_addchr(&ctx.as_string, ch); + /* Convert \^C to corresponding special variable reference */ + goto case_SPECIAL_VAR_SYMBOL; + } o_addchr(&ctx.word, '\\'); if (ch == EOF) { /* Testcase: eval 'echo Ok\' */ @@ -5672,6 +5682,7 @@ static struct pipe *parse_stream(char **pstring, /* Note: nommu_addchr(&ctx.as_string, ch) is already done */ switch (ch) { + case_SPECIAL_VAR_SYMBOL: case SPECIAL_VAR_SYMBOL: /* Convert raw ^C to corresponding special variable reference */ o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); diff --git a/shell/hush_test/hush-misc/control_char3.right b/shell/hush_test/hush-misc/control_char3.right new file mode 100644 index 000000000..94b4f8699 --- /dev/null +++ b/shell/hush_test/hush-misc/control_char3.right @@ -0,0 +1 @@ +hush: can't execute '': No such file or directory diff --git a/shell/hush_test/hush-misc/control_char3.tests b/shell/hush_test/hush-misc/control_char3.tests new file mode 100755 index 000000000..4359db3f3 --- /dev/null +++ b/shell/hush_test/hush-misc/control_char3.tests @@ -0,0 +1,2 @@ +# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) +$THIS_SH -c '\' SHELL diff --git a/shell/hush_test/hush-misc/control_char4.right b/shell/hush_test/hush-misc/control_char4.right new file mode 100644 index 000000000..698e21427 --- /dev/null +++ b/shell/hush_test/hush-misc/control_char4.right @@ -0,0 +1 @@ +hush: can't execute '-': No such file or directory diff --git a/shell/hush_test/hush-misc/control_char4.tests b/shell/hush_test/hush-misc/control_char4.tests new file mode 100755 index 000000000..48010f154 --- /dev/null +++ b/shell/hush_test/hush-misc/control_char4.tests @@ -0,0 +1,2 @@ +# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) +$THIS_SH -c '"-"' SHELL -- cgit v1.2.3-55-g6feb From 83a4967e50422867f340328d404994553e56b839 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Jun 2021 18:12:13 +0200 Subject: hush: fix handling of "cmd && &" function old new delta done_pipe 213 231 +18 Signed-off-by: Denys Vlasenko --- shell/hush.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index e271c04d6..e8d24d40b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -3696,9 +3696,10 @@ static void debug_print_tree(struct pipe *pi, int lvl) pin = 0; while (pi) { - fdprintf(2, "%*spipe %d %sres_word=%s followup=%d %s\n", + fdprintf(2, "%*spipe %d #cmds:%d %sres_word=%s followup=%d %s\n", lvl*2, "", pin, + pi->num_cmds, (IF_HAS_KEYWORDS(pi->pi_inverted ? "! " :) ""), RES[pi->res_word], pi->followup, PIPE[pi->followup] @@ -3841,6 +3842,9 @@ static void done_pipe(struct parse_context *ctx, pipe_style type) #endif /* Replace all pipes in ctx with one newly created */ ctx->list_head = ctx->pipe = pi; + /* for cases like "cmd && &", do not be tricked by last command + * being null - the entire {...} & is NOT null! */ + not_null = 1; } else { no_conv: ctx->pipe->followup = type; -- cgit v1.2.3-55-g6feb From 97c3b5e3ff252b3399d10835d5c906886a7499f4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 19 Jun 2021 15:28:10 +0200 Subject: hush: fix bkslash+newline handling and number validation in ${NN} and ${#NN} Entering "${1a}" into interactive shell was making it exit. function old new delta parse_dollar 824 958 +134 i_getch_and_eat_bkslash_nl - 44 +44 parse_expr 917 938 +21 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/0 up/down: 199/0) Total: 199 bytes Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-parsing/bkslash_newline4.right | 4 ++++ shell/ash_test/ash-parsing/bkslash_newline4.tests | 14 +++++++++++ shell/hush.c | 28 +++++++++++++++++++++- .../hush_test/hush-parsing/bkslash_newline4.right | 4 ++++ .../hush_test/hush-parsing/bkslash_newline4.tests | 14 +++++++++++ shell/hush_test/hush-vars/var6.right | 2 +- 6 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 shell/ash_test/ash-parsing/bkslash_newline4.right create mode 100755 shell/ash_test/ash-parsing/bkslash_newline4.tests create mode 100644 shell/hush_test/hush-parsing/bkslash_newline4.right create mode 100755 shell/hush_test/hush-parsing/bkslash_newline4.tests (limited to 'shell') diff --git a/shell/ash_test/ash-parsing/bkslash_newline4.right b/shell/ash_test/ash-parsing/bkslash_newline4.right new file mode 100644 index 000000000..2110716d1 --- /dev/null +++ b/shell/ash_test/ash-parsing/bkslash_newline4.right @@ -0,0 +1,4 @@ +1:1 +22:22 +3:3 +Ok:0 diff --git a/shell/ash_test/ash-parsing/bkslash_newline4.tests b/shell/ash_test/ash-parsing/bkslash_newline4.tests new file mode 100755 index 000000000..c8f5037c4 --- /dev/null +++ b/shell/ash_test/ash-parsing/bkslash_newline4.tests @@ -0,0 +1,14 @@ +set -- 1 22 333 +echo 1:$\ +1 +echo 22:$\ +{\ +2\ +} +echo 3:$\ +{\ +#\ +3\ +} +echo Ok:$\ +? diff --git a/shell/hush.c b/shell/hush.c index e8d24d40b..1aa0a400d 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -4998,6 +4998,32 @@ static int parse_dollar(o_string *as_string, * which check invalid constructs like ${%}. * Oh well... let's check that the var name part is fine... */ + if (isdigit(len_single_ch) + || (len_single_ch == '#' && isdigit(i_peek_and_eat_bkslash_nl(input))) + ) { + /* Execution engine uses plain xatoi_positive() + * to interpret ${NNN} and {#NNN}, + * check syntax here in the parser. + * (bash does not support expressions in ${#NN}, + * e.g. ${#$var} and {#1:+WORD} are not supported). + */ + unsigned cnt = 9; /* max 9 digits for ${NN} and 8 for {#NN} */ + while (1) { + o_addchr(dest, ch); + debug_printf_parse(": '%c'\n", ch); + ch = i_getch_and_eat_bkslash_nl(input); + nommu_addchr(as_string, ch); + if (ch == '}') + break; + if (--cnt == 0) + goto bad_dollar_syntax; + if (len_single_ch != '#' && strchr(VAR_SUBST_OPS, ch)) + /* ${NN...} is valid */ + goto eat_until_closing; + if (!isdigit(ch)) + goto bad_dollar_syntax; + } + } else while (1) { unsigned pos; @@ -5008,7 +5034,6 @@ static int parse_dollar(o_string *as_string, nommu_addchr(as_string, ch); if (ch == '}') break; - if (!isalnum(ch) && ch != '_') { unsigned end_ch; unsigned char last_ch; @@ -5027,6 +5052,7 @@ static int parse_dollar(o_string *as_string, * special var name, e.g. ${#!}. */ } + eat_until_closing: /* Eat everything until closing '}' (or ':') */ end_ch = '}'; if (BASH_SUBSTR diff --git a/shell/hush_test/hush-parsing/bkslash_newline4.right b/shell/hush_test/hush-parsing/bkslash_newline4.right new file mode 100644 index 000000000..2110716d1 --- /dev/null +++ b/shell/hush_test/hush-parsing/bkslash_newline4.right @@ -0,0 +1,4 @@ +1:1 +22:22 +3:3 +Ok:0 diff --git a/shell/hush_test/hush-parsing/bkslash_newline4.tests b/shell/hush_test/hush-parsing/bkslash_newline4.tests new file mode 100755 index 000000000..c8f5037c4 --- /dev/null +++ b/shell/hush_test/hush-parsing/bkslash_newline4.tests @@ -0,0 +1,14 @@ +set -- 1 22 333 +echo 1:$\ +1 +echo 22:$\ +{\ +2\ +} +echo 3:$\ +{\ +#\ +3\ +} +echo Ok:$\ +? diff --git a/shell/hush_test/hush-vars/var6.right b/shell/hush_test/hush-vars/var6.right index 40e67fdf5..5e28d2fab 100644 --- a/shell/hush_test/hush-vars/var6.right +++ b/shell/hush_test/hush-vars/var6.right @@ -1,2 +1,2 @@ -hush: invalid number '1q' +hush: syntax error: unterminated ${name} hush: syntax error: unterminated ${name} -- cgit v1.2.3-55-g6feb From 96436fb36a5fa0ac8e993fb093b4788fb5448afe Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 23 Jun 2021 12:45:51 +0200 Subject: e2fsprogs/*: remove ioctl calling obfuscation function old new delta change_attributes 326 416 +90 list_attributes 222 248 +26 close_silently 22 - -22 .rodata 103722 103692 -30 fgetsetversion 74 - -74 fgetsetprojid 107 - -107 fgetsetflags 148 - -148 ------------------------------------------------------------------------------ (add/remove: 0/4 grow/shrink: 2/1 up/down: 116/-381) Total: -265 bytes Signed-off-by: Denys Vlasenko --- e2fsprogs/chattr.c | 70 +++++++++++++++++++----------- e2fsprogs/e2fs_lib.c | 119 +-------------------------------------------------- e2fsprogs/e2fs_lib.h | 17 +------- e2fsprogs/lsattr.c | 29 +++++++++---- shell/ash.c | 9 ++-- 5 files changed, 69 insertions(+), 175 deletions(-) (limited to 'shell') diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c index 4dfe803d2..f6a9fcf30 100644 --- a/e2fsprogs/chattr.c +++ b/e2fsprogs/chattr.c @@ -61,9 +61,9 @@ #define OPT_SET_PROJ (1 << 4) struct globals { - unsigned long version; - unsigned long af; - unsigned long rf; + unsigned version; + unsigned af; + unsigned rf; int flags; uint32_t projid; smallint recursive; @@ -79,7 +79,7 @@ static unsigned long get_flag(char c) static char** decode_arg(char **argv, struct globals *gp) { - unsigned long *fl; + unsigned *fl; const char *arg = *argv; char opt = *arg; @@ -149,7 +149,8 @@ static int FAST_FUNC chattr_dir_proc(const char *dir_name, struct dirent *de, vo static void change_attributes(const char *name, struct globals *gp) { - unsigned long fsflags; + unsigned fsflags; + int fd; struct stat st; if (lstat(name, &st) != 0) { @@ -166,33 +167,50 @@ static void change_attributes(const char *name, struct globals *gp) if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode)) return; - if (gp->flags & OPT_SET_VER) - if (fsetversion(name, gp->version) != 0) - bb_perror_msg("setting %s on %s", "version", name); + fd = open_or_warn(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */ + if (fd >= 0) { + int r; - if (gp->flags & OPT_SET_PROJ) - if (fsetprojid(name, gp->projid) != 0) - bb_perror_msg("setting %s on %s", "project ID", name); + if (gp->flags & OPT_SET_VER) { + r = ioctl(fd, EXT2_IOC_SETVERSION, &gp->version); + if (r != 0) + bb_perror_msg("setting %s on %s", "version", name); + } - if (gp->flags & OPT_SET) { - fsflags = gp->af; - } else { - if (fgetflags(name, &fsflags) != 0) { - bb_perror_msg("reading flags on %s", name); - goto skip_setflags; + if (gp->flags & OPT_SET_PROJ) { + struct ext2_fsxattr fsxattr; + r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr); + if (r != 0) + bb_perror_msg("getting %s on %s", "project ID", name); + fsxattr.fsx_projid = gp->projid; + r = ioctl(fd, EXT2_IOC_FSSETXATTR, &fsxattr); + if (r != 0) + bb_perror_msg("setting %s on %s", "project ID", name); } - /*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; + + if (gp->flags & OPT_SET) { + fsflags = gp->af; + } else { + r = ioctl(fd, EXT2_IOC_GETFLAGS, &fsflags); + if (r != 0) { + bb_perror_msg("getting %s on %s", "flags", name); + goto skip_setflags; + } + /*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 (!S_ISDIR(st.st_mode)) + fsflags &= ~EXT2_DIRSYNC_FL; + } + r = ioctl(fd, EXT2_IOC_SETFLAGS, &fsflags); + if (r != 0) + bb_perror_msg("setting %s on %s", "flags", name); + skip_setflags: + close(fd); } - if (fsetflags(name, fsflags) != 0) - bb_perror_msg("setting flags on %s", name); - skip_setflags: if (gp->recursive && S_ISDIR(st.st_mode)) iterate_on_dir(name, chattr_dir_proc, gp); } diff --git a/e2fsprogs/e2fs_lib.c b/e2fsprogs/e2fs_lib.c index 8d56add2d..0ec4eb2f2 100644 --- a/e2fsprogs/e2fs_lib.c +++ b/e2fsprogs/e2fs_lib.c @@ -8,8 +8,6 @@ #include "libbb.h" #include "e2fs_lib.h" -#define HAVE_EXT2_IOCTLS 1 - #if INT_MAX == LONG_MAX #define IF_LONG_IS_SAME(...) __VA_ARGS__ #define IF_LONG_IS_WIDER(...) @@ -18,14 +16,6 @@ #define IF_LONG_IS_WIDER(...) __VA_ARGS__ #endif -static void close_silently(int fd) -{ - int e = errno; - close(fd); - errno = e; -} - - /* Iterate a function on each entry of a directory */ int iterate_on_dir(const char *dir_name, int FAST_FUNC (*func)(const char *, struct dirent *, void *), @@ -45,113 +35,6 @@ int iterate_on_dir(const char *dir_name, return 0; } - -/* Get/set a file version on an ext2 file system */ -int fgetsetversion(const char *name, unsigned long *get_version, unsigned long set_version) -{ -#if HAVE_EXT2_IOCTLS - int fd, r; - IF_LONG_IS_WIDER(unsigned ver;) - - fd = open(name, O_RDONLY | O_NONBLOCK); - if (fd == -1) - return -1; - if (!get_version) { - IF_LONG_IS_WIDER( - ver = (unsigned) set_version; - r = ioctl(fd, EXT2_IOC_SETVERSION, &ver); - ) - IF_LONG_IS_SAME( - r = ioctl(fd, EXT2_IOC_SETVERSION, (void*)&set_version); - ) - } else { - IF_LONG_IS_WIDER( - r = ioctl(fd, EXT2_IOC_GETVERSION, &ver); - *get_version = ver; - ) - IF_LONG_IS_SAME( - r = ioctl(fd, EXT2_IOC_GETVERSION, (void*)get_version); - ) - } - close_silently(fd); - return r; -#else /* ! HAVE_EXT2_IOCTLS */ - errno = EOPNOTSUPP; - return -1; -#endif /* ! HAVE_EXT2_IOCTLS */ -} - -int fgetsetprojid(const char *name, uint32_t *get, uint32_t set) -{ -#if HAVE_EXT2_IOCTLS - struct ext2_fsxattr fsxattr; - int fd, r; - - fd = open(name, O_RDONLY | O_NONBLOCK); - if (fd == -1) - return -1; - r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr); - /* note: ^^^ may fail in 32-bit userspace on 64-bit kernel (seen on 4.12.0) */ - if (r == 0) { - if (get) { - *get = fsxattr.fsx_projid; - } else { - fsxattr.fsx_projid = set; - r = ioctl(fd, EXT2_IOC_FSSETXATTR, &fsxattr); - } - } - close_silently(fd); - return r; -#else /* ! HAVE_EXT2_IOCTLS */ - errno = EOPNOTSUPP; - return -1; -#endif /* ! HAVE_EXT2_IOCTLS */ -} - -/* Get/set a file flags on an ext2 file system */ -int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags) -{ -#if HAVE_EXT2_IOCTLS - struct stat buf; - int fd, r; - IF_LONG_IS_WIDER(unsigned f;) - - if (stat(name, &buf) == 0 /* stat is ok */ - && !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) - ) { - goto notsupp; - } - fd = open(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */ - if (fd == -1) - return -1; - - if (!get_flags) { - IF_LONG_IS_WIDER( - f = (unsigned) set_flags; - r = ioctl(fd, EXT2_IOC_SETFLAGS, &f); - ) - IF_LONG_IS_SAME( - r = ioctl(fd, EXT2_IOC_SETFLAGS, (void*)&set_flags); - ) - } else { - IF_LONG_IS_WIDER( - r = ioctl(fd, EXT2_IOC_GETFLAGS, &f); - *get_flags = f; - ) - IF_LONG_IS_SAME( - r = ioctl(fd, EXT2_IOC_GETFLAGS, (void*)get_flags); - ) - } - - close_silently(fd); - return r; - notsupp: -#endif /* HAVE_EXT2_IOCTLS */ - errno = EOPNOTSUPP; - return -1; -} - - /* Print file attributes on an ext2 file system */ const uint32_t e2attr_flags_value[] ALIGN4 = { #ifdef ENABLE_COMPRESSION @@ -215,7 +98,7 @@ static const char e2attr_flags_lname[] ALIGN1 = "Verity" "\0" /* Another trailing NUL is added by compiler */; -void print_e2flags(FILE *f, unsigned long flags, unsigned options) +void print_e2flags(FILE *f, unsigned flags, unsigned options) { const uint32_t *fv; const char *fn; diff --git a/e2fsprogs/e2fs_lib.h b/e2fsprogs/e2fs_lib.h index 82a1581cb..1a5d092c0 100644 --- a/e2fsprogs/e2fs_lib.h +++ b/e2fsprogs/e2fs_lib.h @@ -16,25 +16,10 @@ int iterate_on_dir(const char *dir_name, int FAST_FUNC (*func)(const char *, struct dirent *, void *), void *private); -/* Get/set a file version on an ext2 file system */ -int fgetsetversion(const char *name, unsigned long *get_version, unsigned long set_version); -#define fgetversion(name, version) fgetsetversion(name, version, 0) -#define fsetversion(name, version) fgetsetversion(name, NULL, version) - -/* Get/set a file project ID on an ext2 file system */ -int fgetsetprojid(const char *name, uint32_t *get, uint32_t set); -#define fgetprojid(name, projid) fgetsetprojid(name, projid, 0) -#define fsetprojid(name, projid) fgetsetprojid(name, NULL, projid) - -/* Get/set a file flags on an ext2 file system */ -int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags); -#define fgetflags(name, flags) fgetsetflags(name, flags, 0) -#define fsetflags(name, flags) fgetsetflags(name, NULL, flags) - /* Must be 1 for compatibility with 'int long_format'. */ #define PFOPT_LONG 1 /* Print file attributes on an ext2 file system */ -void print_e2flags(FILE *f, unsigned long flags, unsigned options); +void print_e2flags(FILE *f, unsigned flags, unsigned options); extern const uint32_t e2attr_flags_value[]; extern const char e2attr_flags_sname[]; diff --git a/e2fsprogs/lsattr.c b/e2fsprogs/lsattr.c index 9b035f584..3972ce8a7 100644 --- a/e2fsprogs/lsattr.c +++ b/e2fsprogs/lsattr.c @@ -46,25 +46,35 @@ enum { static void list_attributes(const char *name) { - unsigned long fsflags; + unsigned fsflags; + int fd, r; - if (fgetflags(name, &fsflags) != 0) - goto read_err; + fd = open_or_warn(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */ + if (fd < 0) /* for example, dangling links */ + return; if (option_mask32 & OPT_PROJID) { - uint32_t p; - if (fgetprojid(name, &p) != 0) + struct ext2_fsxattr fsxattr; + r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr); + if (r != 0) goto read_err; - printf("%5lu ", (unsigned long)p); + printf("%5u ", (unsigned)fsxattr.fsx_projid); } if (option_mask32 & OPT_GENERATION) { - unsigned long generation; - if (fgetversion(name, &generation) != 0) + unsigned generation; + r = ioctl(fd, EXT2_IOC_GETVERSION, &generation); + if (r != 0) goto read_err; - printf("%-10lu ", generation); + printf("%-10u ", generation); } + r = ioctl(fd, EXT2_IOC_GETFLAGS, &fsflags); + if (r != 0) + goto read_err; + + close(fd); + if (option_mask32 & OPT_PF_LONG) { printf("%-28s ", name); print_e2flags(stdout, fsflags, PFOPT_LONG); @@ -77,6 +87,7 @@ static void list_attributes(const char *name) return; read_err: bb_perror_msg("reading %s", name); + close(fd); } static int FAST_FUNC lsattr_dir_proc(const char *dir_name, diff --git a/shell/ash.c b/shell/ash.c index bee81920a..2eac6e113 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12751,7 +12751,7 @@ parsesub: { do { STPUTC(c, out); c = pgetc_eatbnl(); - } while (!subtype && isdigit(c)); + } while ((subtype == 0 || subtype == VSLENGTH) && isdigit(c)); } else if (c != '}') { /* $[{[#]][}] */ int cc = c; @@ -12781,11 +12781,6 @@ parsesub: { } else goto badsub; - if (c != '}' && subtype == VSLENGTH) { - /* ${#VAR didn't end with } */ - goto badsub; - } - if (subtype == 0) { static const char types[] ALIGN1 = "}-+?="; /* ${VAR...} but not $VAR or ${#VAR} */ @@ -12842,6 +12837,8 @@ parsesub: { #endif } } else { + if (subtype == VSLENGTH && c != '}') + subtype = 0; badsub: pungetc(); } -- cgit v1.2.3-55-g6feb From ad57e4e4b23926002ce72979729b017520bef1d0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 25 Jun 2021 02:08:38 +0200 Subject: ash: revert accidental change (should have been separate) Signed-off-by: Denys Vlasenko --- shell/ash.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 2eac6e113..bee81920a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12751,7 +12751,7 @@ parsesub: { do { STPUTC(c, out); c = pgetc_eatbnl(); - } while ((subtype == 0 || subtype == VSLENGTH) && isdigit(c)); + } while (!subtype && isdigit(c)); } else if (c != '}') { /* $[{[#]][}] */ int cc = c; @@ -12781,6 +12781,11 @@ parsesub: { } else goto badsub; + if (c != '}' && subtype == VSLENGTH) { + /* ${#VAR didn't end with } */ + goto badsub; + } + if (subtype == 0) { static const char types[] ALIGN1 = "}-+?="; /* ${VAR...} but not $VAR or ${#VAR} */ @@ -12837,8 +12842,6 @@ parsesub: { #endif } } else { - if (subtype == VSLENGTH && c != '}') - subtype = 0; badsub: pungetc(); } -- cgit v1.2.3-55-g6feb From 53a7a9cd8c15d64fcc2278cf8981ba526dfbe0d2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 25 Jun 2021 02:09:41 +0200 Subject: ash: parser: Fix VSLENGTH parsing with trailing garbage Let's adopt Herbert Xu's patch, not waiting for it to reach dash git: hush already has a similar fix. Signed-off-by: Denys Vlasenko --- shell/ash.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index bee81920a..2eac6e113 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12751,7 +12751,7 @@ parsesub: { do { STPUTC(c, out); c = pgetc_eatbnl(); - } while (!subtype && isdigit(c)); + } while ((subtype == 0 || subtype == VSLENGTH) && isdigit(c)); } else if (c != '}') { /* $[{[#]][}] */ int cc = c; @@ -12781,11 +12781,6 @@ parsesub: { } else goto badsub; - if (c != '}' && subtype == VSLENGTH) { - /* ${#VAR didn't end with } */ - goto badsub; - } - if (subtype == 0) { static const char types[] ALIGN1 = "}-+?="; /* ${VAR...} but not $VAR or ${#VAR} */ @@ -12842,6 +12837,8 @@ parsesub: { #endif } } else { + if (subtype == VSLENGTH && c != '}') + subtype = 0; badsub: pungetc(); } -- cgit v1.2.3-55-g6feb