From 1e9a4f56f574471707244db9f7038ad0581dec16 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 21 Apr 2019 14:30:19 +0200 Subject: examples/var_service: use "exec sleep 5" instead of "{ sleep 5; exit; }" Signed-off-by: Denys Vlasenko --- examples/var_service/dhcp_if/run | 2 +- examples/var_service/dhcpd_if/run | 2 +- examples/var_service/ifplugd_if/run | 2 +- examples/var_service/supplicant_if/run | 2 +- examples/var_service/zcip_if/run | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/var_service/dhcp_if/run b/examples/var_service/dhcp_if/run index d8f343586..882f008d6 100755 --- a/examples/var_service/dhcp_if/run +++ b/examples/var_service/dhcp_if/run @@ -8,7 +8,7 @@ pwd="$PWD" if="${PWD##*/dhcp_}" echo "* Upping iface $if" -ip link set dev "$if" up || { sleep 5; exit; } +ip link set dev "$if" up || exec sleep 5 echo "* Starting udhcpc on $if [$$]" exec \ diff --git a/examples/var_service/dhcpd_if/run b/examples/var_service/dhcpd_if/run index e3d1b00f4..82ac08aa4 100755 --- a/examples/var_service/dhcpd_if/run +++ b/examples/var_service/dhcpd_if/run @@ -8,7 +8,7 @@ pwd="$PWD" if="${PWD##*/dhcpd_}" echo "* Upping iface $if" -ip link set dev $if up || { sleep 5; exit; } +ip link set dev $if up || exec sleep 5 >>udhcpd.leases sed 's/^interface.*$/interface '"$if/" -i udhcpd.conf diff --git a/examples/var_service/ifplugd_if/run b/examples/var_service/ifplugd_if/run index e7816619d..cfddfec06 100755 --- a/examples/var_service/ifplugd_if/run +++ b/examples/var_service/ifplugd_if/run @@ -9,7 +9,7 @@ pwd="$PWD" if="${PWD##*/ifplugd_}" echo "* Upping iface $if" -ip link set dev "$if" up || { sleep 5; exit; } +ip link set dev "$if" up || exec sleep 5 echo "* Starting ifplugd on $if [$$]" exec \ diff --git a/examples/var_service/supplicant_if/run b/examples/var_service/supplicant_if/run index bc16fb606..5c813b07f 100755 --- a/examples/var_service/supplicant_if/run +++ b/examples/var_service/supplicant_if/run @@ -9,7 +9,7 @@ if="${PWD##*/dhcp_}" echo "* Upping iface $if" # "or sleep" idiom prevents rapid respawning if iface does not exist -ip link set dev "$if" up || { sleep 5; exit; } +ip link set dev "$if" up || exec sleep 5 ##echo "* Powersave disable on $if" ##iw dev "$if" set power_save off diff --git a/examples/var_service/zcip_if/run b/examples/var_service/zcip_if/run index 699823246..69f8b9bae 100755 --- a/examples/var_service/zcip_if/run +++ b/examples/var_service/zcip_if/run @@ -8,7 +8,7 @@ pwd="$PWD" if="${PWD##*/zcip_}" echo "* Upping iface $if" -ip link set dev "$if" up || { sleep 5; exit; } +ip link set dev "$if" up || exec sleep 5 echo "* Starting zcip on $if [$$]" exec \ -- cgit v1.2.3-55-g6feb From 100fa20c68564311cef8f625bcb1b423e96c97d6 Mon Sep 17 00:00:00 2001 From: Alexander Vickberg Date: Sat, 27 Apr 2019 15:42:41 +0200 Subject: start-stop-daemon: Fix -x is not required for -K Commit 088fec36fedff2cd50437c95b7fb430abf8d303c made -x required for all. However it isn't for -K. function old new delta start_stop_daemon_main 1084 1105 +21 packed_usage 33343 33326 -17 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 21/-17) Total: 4 bytes Signed-off-by: Alexander Vickberg Signed-off-by: Denys Vlasenko --- debianutils/start_stop_daemon.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 3a4c1044a..72642ae74 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c @@ -94,7 +94,7 @@ Misc options: //usage: "\n -n NAME Match processes with NAME" //usage: "\n in comm field in /proc/PID/stat" //usage: "\n -x EXECUTABLE Match processes with this command" -//usage: "\n command in /proc/PID/cmdline" +//usage: "\n in /proc/PID/cmdline" //usage: "\n -p FILE Match a process with PID from FILE" //usage: "\n All specified conditions must match" //usage: "\n-S only:" @@ -452,31 +452,34 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) // "start-stop-daemon -S -a sleep -- 5" // NB: -n option does _not_ behave in this way: this will try to execute "5": // "start-stop-daemon -S -n sleep -- 5" - if (!execname) { /* -x is not given */ - execname = startas; - if (!execname) { /* neither -x nor -a is given */ - execname = argv[0]; - if (!execname) - bb_show_usage(); - argv++; + if (opt & CTX_START) { + if (!execname) { /* -x is not given */ + execname = startas; + if (!execname) { /* neither -x nor -a is given */ + execname = argv[0]; + if (!execname) + bb_show_usage(); + argv++; + } } + if (!startas) /* -a is not given: use -x EXECUTABLE or argv[0] */ + startas = execname; + *--argv = startas; + } + if (execname) { + G.execname_sizeof = strlen(execname) + 1; + G.execname_cmpbuf = xmalloc(G.execname_sizeof + 1); } - if (!startas) /* -a is not given: use -x EXECUTABLE or argv[0] */ - startas = execname; - *--argv = startas; - G.execname_sizeof = strlen(execname) + 1; - G.execname_cmpbuf = xmalloc(G.execname_sizeof + 1); - // IF_FEATURE_START_STOP_DAEMON_FANCY( // if (retry_arg) // retries = xatoi_positive(retry_arg); // ) - if (userspec) { user_id = bb_strtou(userspec, NULL, 10); if (errno) user_id = xuname2uid(userspec); } + /* Both start and stop need to know current processes */ do_procinit(); @@ -485,6 +488,8 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) return (opt & OPT_OKNODO) ? 0 : (i <= 0); } + /* else: CTX_START (-S). execname can't be NULL. */ + if (G.found_procs) { if (!QUIET) printf("%s is already running\n", execname); -- cgit v1.2.3-55-g6feb From a4d76ea1373a7cf06d3d0a3c8905646638e97a13 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 27 Apr 2019 21:01:35 +0200 Subject: ash,hush: fix ulimit to be more bash-compat, closes 11791 function old new delta shell_builtin_ulimit 486 651 +165 limit_chars - 14 +14 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/0 up/down: 179/0) Total: 179 bytes Signed-off-by: Denys Vlasenko --- shell/shell_common.c | 265 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 181 insertions(+), 84 deletions(-) diff --git a/shell/shell_common.c b/shell/shell_common.c index f2bf5ab65..686c18f54 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -335,62 +335,93 @@ shell_builtin_read(struct builtin_read_params *params) struct limits { uint8_t cmd; /* RLIMIT_xxx fit into it */ uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */ - char option; const char *name; }; static const struct limits limits_tbl[] = { -#ifdef RLIMIT_FSIZE - { RLIMIT_FSIZE, 9, 'f', "file size (blocks)" }, -#endif +/* No RLIMIT_FSIZE define guard since -f is the default limit and this must exist */ + { RLIMIT_FSIZE, 9, "file size (blocks)" }, // -f #ifdef RLIMIT_CPU - { RLIMIT_CPU, 0, 't', "cpu time (seconds)" }, + { RLIMIT_CPU, 0, "cpu time (seconds)" }, // -t #endif #ifdef RLIMIT_DATA - { RLIMIT_DATA, 10, 'd', "data seg size (kb)" }, + { RLIMIT_DATA, 10, "data seg size (kb)" }, // -d #endif #ifdef RLIMIT_STACK - { RLIMIT_STACK, 10, 's', "stack size (kb)" }, + { RLIMIT_STACK, 10, "stack size (kb)" }, // -s #endif #ifdef RLIMIT_CORE - { RLIMIT_CORE, 9, 'c', "core file size (blocks)" }, + { RLIMIT_CORE, 9, "core file size (blocks)" }, // -c #endif #ifdef RLIMIT_RSS - { RLIMIT_RSS, 10, 'm', "resident set size (kb)" }, + { RLIMIT_RSS, 10, "resident set size (kb)" }, // -m #endif #ifdef RLIMIT_MEMLOCK - { RLIMIT_MEMLOCK, 10, 'l', "locked memory (kb)" }, + { RLIMIT_MEMLOCK, 10, "locked memory (kb)" }, // -l #endif #ifdef RLIMIT_NPROC - { RLIMIT_NPROC, 0, 'p', "processes" }, + { RLIMIT_NPROC, 0, "processes" }, // -p #endif #ifdef RLIMIT_NOFILE - { RLIMIT_NOFILE, 0, 'n', "file descriptors" }, + { RLIMIT_NOFILE, 0, "file descriptors" }, // -n #endif #ifdef RLIMIT_AS - { RLIMIT_AS, 10, 'v', "address space (kb)" }, + { RLIMIT_AS, 10, "address space (kb)" }, // -v #endif #ifdef RLIMIT_LOCKS - { RLIMIT_LOCKS, 0, 'w', "locks" }, + { RLIMIT_LOCKS, 0, "locks" }, // -w #endif #ifdef RLIMIT_NICE - { RLIMIT_NICE, 0, 'e', "scheduling priority" }, + { RLIMIT_NICE, 0, "scheduling priority" }, // -e #endif #ifdef RLIMIT_RTPRIO - { RLIMIT_RTPRIO, 0, 'r', "real-time priority" }, + { RLIMIT_RTPRIO, 0, "real-time priority" }, // -r #endif }; -enum { - OPT_hard = (1 << 0), - OPT_soft = (1 << 1), -}; +static const char limit_chars[] ALIGN1 = + "f" +#ifdef RLIMIT_CPU + "t" +#endif +#ifdef RLIMIT_DATA + "d" +#endif +#ifdef RLIMIT_STACK + "s" +#endif +#ifdef RLIMIT_CORE + "c" +#endif +#ifdef RLIMIT_RSS + "m" +#endif +#ifdef RLIMIT_MEMLOCK + "l" +#endif +#ifdef RLIMIT_NPROC + "p" +#endif +#ifdef RLIMIT_NOFILE + "n" +#endif +#ifdef RLIMIT_AS + "v" +#endif +#ifdef RLIMIT_LOCKS + "w" +#endif +#ifdef RLIMIT_NICE + "e" +#endif +#ifdef RLIMIT_RTPRIO + "r" +#endif +; /* "-": treat args as parameters of option with ASCII code 1 */ static const char ulimit_opt_string[] ALIGN1 = "-HSa" -#ifdef RLIMIT_FSIZE "f::" -#endif #ifdef RLIMIT_CPU "t::" #endif @@ -429,13 +460,19 @@ static const char ulimit_opt_string[] ALIGN1 = "-HSa" #endif ; +enum { + OPT_hard = (1 << 0), + OPT_soft = (1 << 1), + OPT_all = (1 << 2), +}; + static void printlim(unsigned opts, const struct rlimit *limit, const struct limits *l) { rlim_t val; val = limit->rlim_max; - if (!(opts & OPT_hard)) + if (opts & OPT_soft) val = limit->rlim_cur; if (val == RLIM_INFINITY) @@ -449,8 +486,11 @@ static void printlim(unsigned opts, const struct rlimit *limit, int FAST_FUNC shell_builtin_ulimit(char **argv) { + struct rlimit limit; + unsigned opt_cnt; unsigned opts; unsigned argc; + unsigned i; /* We can't use getopt32: need to handle commands like * ulimit 123 -c2 -l 456 @@ -461,12 +501,48 @@ shell_builtin_ulimit(char **argv) */ GETOPT_RESET(); +// bash 4.4.23: +// +// -H and/or -S change meaning even of options *before* them: ulimit -f 2000 -H +// sets hard limit, ulimit -a -H prints hard limits. +// +// -a is equivalent for requesting all limits to be shown. +// +// If -a is specified, attempts to set limits are ignored: +// ulimit -m 1000; ulimit -m 2000 -a +// shows 1000, not 2000. HOWEVER, *implicit* -f form "ulimit 2000 -a" +// DOES set -f limit [we don't implement this quirk], "ulimit -a 2000" does not. +// Options are still parsed: ulimit -az complains about unknown -z opt. +// +// -a is not cumulative: "ulimit -a -a" = "ulimit -a -f -m" = "ulimit -a" +// +// -HSa can be combined in one argument and with one other option (example: -Sm), +// but other options can't: limit value is an optional argument, +// thus "-mf" means "-m f", f is the parameter of -m. +// +// Limit can be set and then printed: ulimit -m 2000 -m +// If set more than once, they are set and printed in order: +// try ulimit -m -m 1000 -m -m 2000 -m -m 3000 -m +// +// Limits are shown in the order of options given: +// ulimit -m -f is not the same as ulimit -f -m. +// +// If both -S and -H are given, show soft limit. +// +// Short printout (limit value only) is printed only if just one option +// is given: ulimit -m. ulimit -f -m prints verbose lines. +// ulimit -f -f prints same verbose line twice. +// ulimit -m 10000 -f prints verbose line for -f. + argc = string_array_len(argv); + /* First pass over options: detect -H/-S/-a status, + * and "bare ulimit" and "only one option" cases + * by counting other opts. + */ + opt_cnt = 0; opts = 0; while (1) { - struct rlimit limit; - const struct limits *l; int opt_char = getopt(argc, argv, ulimit_opt_string); if (opt_char == -1) @@ -479,72 +555,93 @@ shell_builtin_ulimit(char **argv) opts |= OPT_soft; continue; } - if (opt_char == 'a') { - for (l = limits_tbl; l != &limits_tbl[ARRAY_SIZE(limits_tbl)]; l++) { - getrlimit(l->cmd, &limit); - printf("-%c: %-30s ", l->option, l->name); - printlim(opts, &limit, l); - } + opts |= OPT_all; continue; } + if (opt_char == '?') { + /* bad option. getopt already complained. */ + return EXIT_FAILURE; + } + opt_cnt++; + } /* while (there are options) */ - if (opt_char == 1) - opt_char = 'f'; - for (l = limits_tbl; l != &limits_tbl[ARRAY_SIZE(limits_tbl)]; l++) { - if (opt_char == l->option) { - char *val_str; - - getrlimit(l->cmd, &limit); - - val_str = optarg; - if (!val_str && argv[optind] && argv[optind][0] != '-') - val_str = argv[optind++]; /* ++ skips NN in "-c NN" case */ - if (val_str) { - rlim_t val; - - if (strcmp(val_str, "unlimited") == 0) - val = RLIM_INFINITY; - else { - if (sizeof(val) == sizeof(int)) - val = bb_strtou(val_str, NULL, 10); - else if (sizeof(val) == sizeof(long)) - val = bb_strtoul(val_str, NULL, 10); - else - val = bb_strtoull(val_str, NULL, 10); - if (errno) { - bb_error_msg("invalid number '%s'", val_str); - return EXIT_FAILURE; - } - val <<= l->factor_shift; - } -//bb_error_msg("opt %c val_str:'%s' val:%lld", opt_char, val_str, (long long)val); - /* from man bash: "If neither -H nor -S - * is specified, both the soft and hard - * limits are set. */ - if (!opts) - opts = OPT_hard + OPT_soft; - if (opts & OPT_hard) - limit.rlim_max = val; - if (opts & OPT_soft) - limit.rlim_cur = val; -//bb_error_msg("setrlimit(%d, %lld, %lld)", l->cmd, (long long)limit.rlim_cur, (long long)limit.rlim_max); - if (setrlimit(l->cmd, &limit) < 0) { - bb_perror_msg("error setting limit"); - return EXIT_FAILURE; - } - } else { - printlim(opts, &limit, l); - } - break; - } - } /* for (every possible opt) */ + if (!(opts & (OPT_hard | OPT_soft))) + opts |= (OPT_hard | OPT_soft); + if (opts & OPT_all) { + for (i = 0; i < ARRAY_SIZE(limits_tbl); i++) { + getrlimit(limits_tbl[i].cmd, &limit); + printf("-%c: %-30s ", limit_chars[i], limits_tbl[i].name); + printlim(opts, &limit, &limits_tbl[i]); + } + return EXIT_SUCCESS; + } - if (l == &limits_tbl[ARRAY_SIZE(limits_tbl)]) { - /* bad option. getopt already complained. */ + /* Second pass: set or print limits, in order */ + GETOPT_RESET(); + while (1) { + char *val_str; + int opt_char = getopt(argc, argv, ulimit_opt_string); + + if (opt_char == -1) break; + if (opt_char == 'H') + continue; + if (opt_char == 'S') + continue; + //if (opt_char == 'a') - impossible + + i = 0; /* if "ulimit NNN", -f is assumed */ + if (opt_char != 1) { + i = strchrnul(limit_chars, opt_char) - limit_chars; + //if (i >= ARRAY_SIZE(limits_tbl)) - bad option, impossible + } + + val_str = optarg; + if (!val_str && argv[optind] && argv[optind][0] != '-') + val_str = argv[optind++]; /* ++ skips NN in "-c NN" case */ + + getrlimit(limits_tbl[i].cmd, &limit); + if (!val_str) { + if (opt_cnt > 1) + printf("-%c: %-30s ", limit_chars[i], limits_tbl[i].name); + printlim(opts, &limit, &limits_tbl[i]); + } else { + rlim_t val = RLIM_INFINITY; + if (strcmp(val_str, "unlimited") != 0) { + if (sizeof(val) == sizeof(int)) + val = bb_strtou(val_str, NULL, 10); + else if (sizeof(val) == sizeof(long)) + val = bb_strtoul(val_str, NULL, 10); + else + val = bb_strtoull(val_str, NULL, 10); + if (errno) { + bb_error_msg("invalid number '%s'", val_str); + return EXIT_FAILURE; + } + val <<= limits_tbl[i].factor_shift; + } +//bb_error_msg("opt %c val_str:'%s' val:%lld", opt_char, val_str, (long long)val); + /* from man bash: "If neither -H nor -S + * is specified, both the soft and hard + * limits are set. */ + if (opts & OPT_hard) + limit.rlim_max = val; + if (opts & OPT_soft) + limit.rlim_cur = val; +//bb_error_msg("setrlimit(%d, %lld, %lld)", limits_tbl[i].cmd, (long long)limit.rlim_cur, (long long)limit.rlim_max); + if (setrlimit(limits_tbl[i].cmd, &limit) < 0) { + bb_perror_msg("error setting limit"); + return EXIT_FAILURE; + } } } /* while (there are options) */ - return 0; + if (opt_cnt == 0) { + /* "bare ulimit": treat it as if it was -f */ + getrlimit(limits_tbl[0].cmd, &limit); + printlim(opts, &limit, &limits_tbl[0]); + } + + return EXIT_SUCCESS; } -- cgit v1.2.3-55-g6feb From a92a9601f89d59597b268e29e7098597a8766778 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 27 Apr 2019 21:23:39 +0200 Subject: ash,hush: bash compat for ulimit: -w => -x, -p => -u Signed-off-by: Denys Vlasenko --- shell/shell_common.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/shell/shell_common.c b/shell/shell_common.c index 686c18f54..a992682a8 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -354,22 +354,22 @@ static const struct limits limits_tbl[] = { { RLIMIT_CORE, 9, "core file size (blocks)" }, // -c #endif #ifdef RLIMIT_RSS - { RLIMIT_RSS, 10, "resident set size (kb)" }, // -m + { RLIMIT_RSS, 10, "max memory size (kb)" }, // -m #endif #ifdef RLIMIT_MEMLOCK - { RLIMIT_MEMLOCK, 10, "locked memory (kb)" }, // -l + { RLIMIT_MEMLOCK, 10, "max locked memory (kb)" }, // -l #endif #ifdef RLIMIT_NPROC - { RLIMIT_NPROC, 0, "processes" }, // -p + { RLIMIT_NPROC, 0, "max user processes" }, // -u #endif #ifdef RLIMIT_NOFILE - { RLIMIT_NOFILE, 0, "file descriptors" }, // -n + { RLIMIT_NOFILE, 0, "open files" }, // -n #endif #ifdef RLIMIT_AS - { RLIMIT_AS, 10, "address space (kb)" }, // -v + { RLIMIT_AS, 10, "virtual memory (kb)" }, // -v #endif #ifdef RLIMIT_LOCKS - { RLIMIT_LOCKS, 0, "locks" }, // -w + { RLIMIT_LOCKS, 0, "file locks" }, // -x #endif #ifdef RLIMIT_NICE { RLIMIT_NICE, 0, "scheduling priority" }, // -e @@ -378,6 +378,10 @@ static const struct limits limits_tbl[] = { { RLIMIT_RTPRIO, 0, "real-time priority" }, // -r #endif }; +// bash also has these: +//pending signals (-i) 61858 //RLIMIT_SIGPENDING +//pipe size (512 bytes, -p) 8 +//POSIX message queues (bytes, -q) 819200 //RLIMIT_MSGQUEUE static const char limit_chars[] ALIGN1 = "f" @@ -400,7 +404,7 @@ static const char limit_chars[] ALIGN1 = "l" #endif #ifdef RLIMIT_NPROC - "p" + "u" #endif #ifdef RLIMIT_NOFILE "n" @@ -409,7 +413,7 @@ static const char limit_chars[] ALIGN1 = "v" #endif #ifdef RLIMIT_LOCKS - "w" + "x" #endif #ifdef RLIMIT_NICE "e" @@ -441,7 +445,7 @@ static const char ulimit_opt_string[] ALIGN1 = "-HSa" "l::" #endif #ifdef RLIMIT_NPROC - "p::" + "u::" #endif #ifdef RLIMIT_NOFILE "n::" @@ -450,7 +454,7 @@ static const char ulimit_opt_string[] ALIGN1 = "-HSa" "v::" #endif #ifdef RLIMIT_LOCKS - "w::" + "x::" #endif #ifdef RLIMIT_NICE "e::" @@ -571,7 +575,7 @@ shell_builtin_ulimit(char **argv) if (opts & OPT_all) { for (i = 0; i < ARRAY_SIZE(limits_tbl); i++) { getrlimit(limits_tbl[i].cmd, &limit); - printf("-%c: %-30s ", limit_chars[i], limits_tbl[i].name); + printf("%-32s(-%c) ", limits_tbl[i].name, limit_chars[i]); printlim(opts, &limit, &limits_tbl[i]); } return EXIT_SUCCESS; @@ -604,7 +608,7 @@ shell_builtin_ulimit(char **argv) getrlimit(limits_tbl[i].cmd, &limit); if (!val_str) { if (opt_cnt > 1) - printf("-%c: %-30s ", limit_chars[i], limits_tbl[i].name); + printf("%-32s(-%c) ", limits_tbl[i].name, limit_chars[i]); printlim(opts, &limit, &limits_tbl[i]); } else { rlim_t val = RLIM_INFINITY; -- cgit v1.2.3-55-g6feb From 57e1b0ad5ebd77705841fbcd01a79f2552fbab8e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 28 Apr 2019 11:20:09 +0200 Subject: ash,hush: bash compat for ulimit: reorder to match Signed-off-by: Denys Vlasenko --- shell/shell_common.c | 125 ++++++++++++++++++++++----------------------------- 1 file changed, 53 insertions(+), 72 deletions(-) diff --git a/shell/shell_common.c b/shell/shell_common.c index a992682a8..cc518d54b 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -339,44 +339,38 @@ struct limits { }; static const struct limits limits_tbl[] = { -/* No RLIMIT_FSIZE define guard since -f is the default limit and this must exist */ + { RLIMIT_CORE, 9, "core file size (blocks)" }, // -c + { RLIMIT_DATA, 10, "data seg size (kb)" }, // -d + { RLIMIT_NICE, 0, "scheduling priority" }, // -e { RLIMIT_FSIZE, 9, "file size (blocks)" }, // -f -#ifdef RLIMIT_CPU - { RLIMIT_CPU, 0, "cpu time (seconds)" }, // -t +#define LIMIT_F_IDX 3 +#ifdef RLIMIT_MEMLOCK + { RLIMIT_MEMLOCK, 10, "max locked memory (kb)" }, // -l #endif -#ifdef RLIMIT_DATA - { RLIMIT_DATA, 10, "data seg size (kb)" }, // -d +#ifdef RLIMIT_RSS + { RLIMIT_RSS, 10, "max memory size (kb)" }, // -m #endif -#ifdef RLIMIT_STACK - { RLIMIT_STACK, 10, "stack size (kb)" }, // -s +#ifdef RLIMIT_NOFILE + { RLIMIT_NOFILE, 0, "open files" }, // -n #endif -#ifdef RLIMIT_CORE - { RLIMIT_CORE, 9, "core file size (blocks)" }, // -c +#ifdef RLIMIT_RTPRIO + { RLIMIT_RTPRIO, 0, "real-time priority" }, // -r #endif -#ifdef RLIMIT_RSS - { RLIMIT_RSS, 10, "max memory size (kb)" }, // -m +#ifdef RLIMIT_STACK + { RLIMIT_STACK, 10, "stack size (kb)" }, // -s #endif -#ifdef RLIMIT_MEMLOCK - { RLIMIT_MEMLOCK, 10, "max locked memory (kb)" }, // -l +#ifdef RLIMIT_CPU + { RLIMIT_CPU, 0, "cpu time (seconds)" }, // -t #endif #ifdef RLIMIT_NPROC { RLIMIT_NPROC, 0, "max user processes" }, // -u #endif -#ifdef RLIMIT_NOFILE - { RLIMIT_NOFILE, 0, "open files" }, // -n -#endif #ifdef RLIMIT_AS { RLIMIT_AS, 10, "virtual memory (kb)" }, // -v #endif #ifdef RLIMIT_LOCKS { RLIMIT_LOCKS, 0, "file locks" }, // -x #endif -#ifdef RLIMIT_NICE - { RLIMIT_NICE, 0, "scheduling priority" }, // -e -#endif -#ifdef RLIMIT_RTPRIO - { RLIMIT_RTPRIO, 0, "real-time priority" }, // -r -#endif }; // bash also has these: //pending signals (-i) 61858 //RLIMIT_SIGPENDING @@ -384,85 +378,73 @@ static const struct limits limits_tbl[] = { //POSIX message queues (bytes, -q) 819200 //RLIMIT_MSGQUEUE static const char limit_chars[] ALIGN1 = + "c" + "d" + "e" "f" -#ifdef RLIMIT_CPU - "t" +#ifdef RLIMIT_MEMLOCK + "l" #endif -#ifdef RLIMIT_DATA - "d" +#ifdef RLIMIT_RSS + "m" #endif -#ifdef RLIMIT_STACK - "s" +#ifdef RLIMIT_NOFILE + "n" #endif -#ifdef RLIMIT_CORE - "c" +#ifdef RLIMIT_RTPRIO + "r" #endif -#ifdef RLIMIT_RSS - "m" +#ifdef RLIMIT_STACK + "s" #endif -#ifdef RLIMIT_MEMLOCK - "l" +#ifdef RLIMIT_CPU + "t" #endif #ifdef RLIMIT_NPROC "u" #endif -#ifdef RLIMIT_NOFILE - "n" -#endif #ifdef RLIMIT_AS "v" #endif #ifdef RLIMIT_LOCKS "x" #endif -#ifdef RLIMIT_NICE - "e" -#endif -#ifdef RLIMIT_RTPRIO - "r" -#endif ; /* "-": treat args as parameters of option with ASCII code 1 */ static const char ulimit_opt_string[] ALIGN1 = "-HSa" + "c::" + "d::" + "e::" "f::" -#ifdef RLIMIT_CPU - "t::" +#ifdef RLIMIT_MEMLOCK + "l::" #endif -#ifdef RLIMIT_DATA - "d::" +#ifdef RLIMIT_RSS + "m::" #endif -#ifdef RLIMIT_STACK - "s::" +#ifdef RLIMIT_NOFILE + "n::" #endif -#ifdef RLIMIT_CORE - "c::" +#ifdef RLIMIT_RTPRIO + "r::" #endif -#ifdef RLIMIT_RSS - "m::" +#ifdef RLIMIT_STACK + "s::" #endif -#ifdef RLIMIT_MEMLOCK - "l::" +#ifdef RLIMIT_CPU + "t::" #endif #ifdef RLIMIT_NPROC "u::" #endif -#ifdef RLIMIT_NOFILE - "n::" -#endif #ifdef RLIMIT_AS "v::" #endif #ifdef RLIMIT_LOCKS "x::" #endif -#ifdef RLIMIT_NICE - "e::" -#endif -#ifdef RLIMIT_RTPRIO - "r::" -#endif - ; +; enum { OPT_hard = (1 << 0), @@ -595,11 +577,10 @@ shell_builtin_ulimit(char **argv) continue; //if (opt_char == 'a') - impossible - i = 0; /* if "ulimit NNN", -f is assumed */ - if (opt_char != 1) { - i = strchrnul(limit_chars, opt_char) - limit_chars; - //if (i >= ARRAY_SIZE(limits_tbl)) - bad option, impossible - } + if (opt_char == 1) /* if "ulimit NNN", -f is assumed */ + opt_char = 'f'; + i = strchrnul(limit_chars, opt_char) - limit_chars; + //if (i >= ARRAY_SIZE(limits_tbl)) - bad option, impossible val_str = optarg; if (!val_str && argv[optind] && argv[optind][0] != '-') @@ -643,8 +624,8 @@ shell_builtin_ulimit(char **argv) if (opt_cnt == 0) { /* "bare ulimit": treat it as if it was -f */ - getrlimit(limits_tbl[0].cmd, &limit); - printlim(opts, &limit, &limits_tbl[0]); + getrlimit(limits_tbl[LIMIT_F_IDX].cmd, &limit); + printlim(opts, &limit, &limits_tbl[LIMIT_F_IDX]); } return EXIT_SUCCESS; -- cgit v1.2.3-55-g6feb From 93f0b39a0712f3247349f1590757484ca18e725e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 28 Apr 2019 11:25:11 +0200 Subject: ash,hush: ulimit: add -i RLIMIT_SIGPENDING, -q RLIMIT_MSGQUEUE function old new delta limits_tbl 104 120 +16 ulimit_opt_string 44 50 +6 limit_chars 14 16 +2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 24/0) Total: 24 bytes text data bss dec hex filename 981996 485 7296 989777 f1a51 busybox_old 982065 485 7296 989846 f1a96 busybox_unstripped Signed-off-by: Denys Vlasenko --- shell/shell_common.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/shell/shell_common.c b/shell/shell_common.c index cc518d54b..da3165329 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -344,6 +344,9 @@ static const struct limits limits_tbl[] = { { RLIMIT_NICE, 0, "scheduling priority" }, // -e { RLIMIT_FSIZE, 9, "file size (blocks)" }, // -f #define LIMIT_F_IDX 3 +#ifdef RLIMIT_SIGPENDING + { RLIMIT_SIGPENDING, 0, "pending signals" }, // -i +#endif #ifdef RLIMIT_MEMLOCK { RLIMIT_MEMLOCK, 10, "max locked memory (kb)" }, // -l #endif @@ -353,6 +356,9 @@ static const struct limits limits_tbl[] = { #ifdef RLIMIT_NOFILE { RLIMIT_NOFILE, 0, "open files" }, // -n #endif +#ifdef RLIMIT_MSGQUEUE + { RLIMIT_MSGQUEUE, 0, "POSIX message queues (bytes)" }, // -q +#endif #ifdef RLIMIT_RTPRIO { RLIMIT_RTPRIO, 0, "real-time priority" }, // -r #endif @@ -372,16 +378,17 @@ static const struct limits limits_tbl[] = { { RLIMIT_LOCKS, 0, "file locks" }, // -x #endif }; -// bash also has these: -//pending signals (-i) 61858 //RLIMIT_SIGPENDING +// bash also shows: //pipe size (512 bytes, -p) 8 -//POSIX message queues (bytes, -q) 819200 //RLIMIT_MSGQUEUE static const char limit_chars[] ALIGN1 = "c" "d" "e" "f" +#ifdef RLIMIT_SIGPENDING + "i" +#endif #ifdef RLIMIT_MEMLOCK "l" #endif @@ -391,6 +398,9 @@ static const char limit_chars[] ALIGN1 = #ifdef RLIMIT_NOFILE "n" #endif +#ifdef RLIMIT_MSGQUEUE + "q" +#endif #ifdef RLIMIT_RTPRIO "r" #endif @@ -417,6 +427,9 @@ static const char ulimit_opt_string[] ALIGN1 = "-HSa" "d::" "e::" "f::" +#ifdef RLIMIT_SIGPENDING + "i::" +#endif #ifdef RLIMIT_MEMLOCK "l::" #endif @@ -426,6 +439,9 @@ static const char ulimit_opt_string[] ALIGN1 = "-HSa" #ifdef RLIMIT_NOFILE "n::" #endif +#ifdef RLIMIT_MSGQUEUE + "q::" +#endif #ifdef RLIMIT_RTPRIO "r::" #endif -- cgit v1.2.3-55-g6feb From 4b49422a08b89bd01023e7b4fa73ab058ee66932 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 28 Apr 2019 09:09:33 +0100 Subject: vi: fix changes to word at end of line. Closes 11796 As reported in bug 11796 BusyBox vi incorrectly handles changes to a word at the end of a line. If the following line starts with whitespace changing or deleting the last word of a line with the 'cw' or 'dw' commands causes the lines to be joined. This happens because the range for the change returned by find_range() covers all whitespace after the word, including newlines. The problem can be fixed by setting 'ml' to zero to indicate to yank_delete() that processing should stop at the end of the current line. However, this results in a new problem. 'dw' correctly deletes all whitespace following the word but so does 'cw', which should preserve the trailing whitespace. To fix this the code to omit whitespace from the change is modified to include all whitespace not just blanks. function old new delta do_cmd 5034 5069 +35 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 35/0) Total: 35 bytes Reported-by: David Kelly Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- editors/vi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index c4360f8d3..dfef42019 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -3770,11 +3770,10 @@ static void do_cmd(int c) if (c1 == 27) { // ESC- user changed mind and wants out c = c1 = 27; // Escape- do nothing } else if (strchr("wW", c1)) { + ml = 0; // multi-line ranges aren't allowed for words if (c == 'c') { // don't include trailing WS as part of word - while (isblank(*q)) { - if (q <= text || q[-1] == '\n') - break; + while (isspace(*q) && q > p) { q--; } } -- cgit v1.2.3-55-g6feb From 7b93e317c13053e40e76cc5c36404f92d05dd41c Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 28 Apr 2019 09:10:16 +0100 Subject: vi: enable 'dG' command. Closes 11801 The 'G' command was omitted from the list of commands that change or delete whole lines. Add it in the appropriate places so the 'dG', 'cG' and 'yG' commands work, including in cases where an explicit line number has been supplied. function old new delta find_range 534 596 +62 .rodata 175166 175167 +1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 63/0) Total: 63 bytes Reported-by: David Kelly Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- editors/vi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index dfef42019..8af1ef76b 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -3001,11 +3001,14 @@ static void do_cmd(int c); static int find_range(char **start, char **stop, char c) { char *save_dot, *p, *q, *t; - int cnt, multiline = 0; + int cnt, multiline = 0, forward; save_dot = dot; p = q = dot; + // will a 'G' command move forwards or backwards? + forward = cmdcnt == 0 || cmdcnt > count_lines(text, dot); + if (strchr("cdy><", c)) { // these cmds operate on whole lines p = q = begin_line(p); @@ -3029,13 +3032,13 @@ static int find_range(char **start, char **stop, char c) if (dot > text && *dot == '\n') dot--; // stay off NL q = dot; - } else if (strchr("H-k{", c)) { + } else if (strchr("H-k{", c) || (c == 'G' && !forward)) { // these operate on multi-lines backwards q = end_line(dot); // find NL do_cmd(c); // execute movement cmd dot_begin(); p = dot; - } else if (strchr("L+j}\r\n", c)) { + } else if (strchr("L+j}\r\n", c) || (c == 'G' && forward)) { // these operate on multi-lines forwards p = begin_line(dot); do_cmd(c); // execute movement cmd @@ -3781,7 +3784,7 @@ static void do_cmd(int c) } else if (strchr("^0bBeEft%$ lh\b\177", c1)) { // partial line copy text into a register and delete dot = yank_delete(p, q, ml, yf, ALLOW_UNDO); // delete word - } else if (strchr("cdykjHL+-{}\r\n", c1)) { + } else if (strchr("cdykjGHL+-{}\r\n", c1)) { // whole line copy text into a register and delete dot = yank_delete(p, q, ml, yf, ALLOW_UNDO); // delete lines whole = 1; -- cgit v1.2.3-55-g6feb From 405095d84b1f3be17efb4e10d87d480bd054877f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 28 Apr 2019 17:55:27 +0200 Subject: ifupdown: close memory leak function old new delta execute_all 80 91 +11 Signed-off-by: Denys Vlasenko --- networking/ifupdown.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 8a6efc976..5327b0979 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -1177,8 +1177,15 @@ static int doit(char *str) static int execute_all(struct interface_defn_t *ifd, const char *opt) { + /* 'opt' is always short, the longest value is "post-down". + * Can use on-stack buffer instead of xasprintf'ed one. + */ + char buf[sizeof("run-parts /etc/network/if-%s.d") + + sizeof("post-down") + /*paranoia:*/ + 8 + ]; int i; - char *buf; + for (i = 0; i < ifd->n_options; i++) { if (strcmp(ifd->option[i].name, opt) == 0) { if (!doit(ifd->option[i].value)) { @@ -1192,8 +1199,7 @@ static int execute_all(struct interface_defn_t *ifd, const char *opt) * complains, and this message _is_ annoyingly visible. * Don't "fix" this (unless newer Debian does). */ - buf = xasprintf("run-parts /etc/network/if-%s.d", opt); - /* heh, we don't bother free'ing it */ + sprintf(buf, "run-parts /etc/network/if-%s.d", opt); return doit(buf); } -- cgit v1.2.3-55-g6feb From 13f42045616320119bb47cf8df302cfcc76ade9a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 29 Apr 2019 00:34:07 +0200 Subject: ip: fix comment placement Signed-off-by: Denys Vlasenko --- networking/libiproute/ipaddress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 8364f6a3e..fc6a4fb77 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -571,8 +571,8 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush) for (l = linfo; l; l = l->next) { if ((oneline && G_filter.family != AF_PACKET) - || (print_linkinfo(&l->h) == 0) /* ^^^^^^^^^ "ip -oneline a" does not print link info */ + || (print_linkinfo(&l->h) == 0) ) { struct ifinfomsg *ifi = NLMSG_DATA(&l->h); if (G_filter.family != AF_PACKET) -- cgit v1.2.3-55-g6feb From fa8878bf1fe331df752395cce90da212e25e07b7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 29 Apr 2019 14:24:07 +0200 Subject: start-stop-daemon: do try to close fds > 2 sh -c 'exec 3>&1; exec start-stop-daemon -S -b -x /bin/sleep -- 123' now closes fd 3. function old new delta bb_daemonize_or_rexec 183 192 +9 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 9/0) Total: 9 bytes Signed-off-by: Denys Vlasenko --- libbb/vfork_daemon_rexec.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 1aac27b36..65271e84f 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -263,12 +263,6 @@ void FAST_FUNC bb_daemonize_or_rexec(int flags, char **argv) if (flags & DAEMON_CHDIR_ROOT) xchdir("/"); - if (flags & DAEMON_DEVNULL_STDIO) { - close(0); - close(1); - close(2); - } - fd = open(bb_dev_null, O_RDWR); if (fd < 0) { /* NB: we can be called as bb_sanitize_stdio() from init @@ -278,8 +272,15 @@ void FAST_FUNC bb_daemonize_or_rexec(int flags, char **argv) fd = xopen("/", O_RDONLY); /* don't believe this can fail */ } - while ((unsigned)fd < 2) - fd = dup(fd); /* have 0,1,2 open at least to /dev/null */ + if (flags & DAEMON_DEVNULL_STDIO) { + xdup2(fd, 0); + xdup2(fd, 1); + xdup2(fd, 2); + } else { + /* have 0,1,2 open at least to /dev/null */ + while ((unsigned)fd < 2) + fd = dup(fd); + } if (!(flags & DAEMON_ONLY_SANITIZE)) { -- cgit v1.2.3-55-g6feb From f3a064f4956e113978e74486300dcd1e3e044efa Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 29 Apr 2019 17:59:08 +0200 Subject: libbbb: find_mount_point() too eager to stat mounted devices None of the below "devices" (first word on the line) are real. sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 devtmpfs /dev devtmpfs rw,nosuid,size=7917900k,nr_inodes=1979475,mode=755 0 0 tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0 devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 tmpfs /run tmpfs rw,nosuid,nodev,mode=755 0 0 pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0 configfs /sys/kernel/config configfs rw,relatime 0 0 tmpfs /tmp tmpfs rw,relatime 0 0 function old new delta find_mount_point 297 302 +5 Signed-off-by: Denys Vlasenko --- libbb/find_mount_point.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libbb/find_mount_point.c b/libbb/find_mount_point.c index 94bbf1d4a..0e1be3820 100644 --- a/libbb/find_mount_point.c +++ b/libbb/find_mount_point.c @@ -56,11 +56,22 @@ struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too) continue; /* Is device's dev_t == name's dev_t? */ - if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == devno_of_name) + if (mountEntry->mnt_fsname[0] == '/' + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * avoid stat'ing "sysfs", "proc", "none" and such, + * useless at best, can stat unrelated files at worst. + */ + && stat(mountEntry->mnt_fsname, &s) == 0 + && s.st_rdev == devno_of_name + ) { break; + } /* Match the directory's mount point. */ - if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == devno_of_name) + if (stat(mountEntry->mnt_dir, &s) == 0 + && s.st_dev == devno_of_name + ) { break; + } } endmntent(mtab_fp); -- cgit v1.2.3-55-g6feb From 253c4e787a799a3e1f92957ed791b5222f8d2f64 Mon Sep 17 00:00:00 2001 From: James Byrne Date: Fri, 12 Apr 2019 17:01:51 +0000 Subject: Optionally re-introduce bb_info_msg() Between Busybox 1.24.2 and 1.25.0 the bb_info_msg() function was eliminated and calls to it changed to be bb_error_msg(). The downside of this is that daemons now log all messages to syslog at the LOG_ERR level which makes it hard to filter errors from informational messages. This change optionally re-introduces bb_info_msg(), controlled by a new option FEATURE_SYSLOG_INFO, restores all the calls to bb_info_msg() that were removed (only in applets that set logmode to LOGMODE_SYSLOG or LOGMODE_BOTH), and also changes informational messages in ifplugd and ntpd. The code size change of this is as follows (using 'defconfig' on x86_64 with gcc 7.3.0-27ubuntu1~18.04) function old new delta bb_info_msg - 182 +182 bb_vinfo_msg - 27 +27 static.log7 194 198 +4 log8 190 191 +1 log5 190 191 +1 crondlog 45 - -45 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 3/0 up/down: 215/-45) Total: 170 bytes If you don't care about everything being logged at LOG_ERR level then when FEATURE_SYSLOG_INFO is disabled Busybox actually gets smaller: function old new delta static.log7 194 200 +6 log8 190 193 +3 log5 190 193 +3 syslog_level 1 - -1 bb_verror_msg 583 581 -2 crondlog 45 - -45 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 3/1 up/down: 12/-48) Total: -36 bytes Signed-off-by: James Byrne Signed-off-by: Denys Vlasenko --- Config.in | 9 ++++++++ include/libbb.h | 9 +++++++- libbb/verror_msg.c | 22 ++++++++++++++++++-- loginutils/chpasswd.c | 2 +- loginutils/passwd.c | 2 +- loginutils/sulogin.c | 6 +++--- miscutils/crond.c | 6 ++---- miscutils/devfsd.c | 2 +- networking/dnsd.c | 10 ++++----- networking/ifplugd.c | 20 +++++++++--------- networking/ntpd.c | 4 ++-- networking/tftp.c | 2 +- networking/udhcp/common.c | 2 +- networking/udhcp/common.h | 6 +++--- networking/udhcp/d6_dhcpc.c | 49 ++++++++++++++++++++++---------------------- networking/udhcp/d6_packet.c | 4 ++-- networking/udhcp/dhcpc.c | 42 ++++++++++++++++++------------------- networking/udhcp/dhcpd.c | 22 ++++++++++---------- networking/udhcp/packet.c | 6 +++--- networking/zcip.c | 4 ++-- 20 files changed, 130 insertions(+), 99 deletions(-) diff --git a/Config.in b/Config.in index 1a44c5b6d..1a726f043 100644 --- a/Config.in +++ b/Config.in @@ -339,6 +339,15 @@ config FEATURE_CLEAN_UP Don't enable this unless you have a really good reason to clean things up manually. +config FEATURE_SYSLOG_INFO + bool "Support LOG_INFO level syslog messages" + default y + depends on FEATURE_SYSLOG + help + Applets which send their output to syslog use either LOG_INFO or + LOG_ERR log levels, but by disabling this option all messages will + be logged at the LOG_ERR level, saving just under 200 bytes. + # These are auto-selected by other options config FEATURE_SYSLOG diff --git a/include/libbb.h b/include/libbb.h index a20d5e403..57cfce385 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1316,7 +1316,6 @@ enum { LOGMODE_BOTH = LOGMODE_SYSLOG + LOGMODE_STDIO, }; extern const char *msg_eol; -extern smallint syslog_level; extern smallint logmode; extern uint8_t xfunc_error_retval; extern void (*die_func)(void); @@ -1336,6 +1335,14 @@ void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC; void bb_die_memory_exhausted(void) NORETURN FAST_FUNC; void bb_logenv_override(void) FAST_FUNC; +#if ENABLE_FEATURE_SYSLOG_INFO +void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; +void bb_vinfo_msg(const char *s, va_list p) FAST_FUNC; +#else +#define bb_info_msg bb_error_msg +#define bb_vinfo_msg(s,p) bb_verror_msg(s,p,NULL) +#endif + /* We need to export XXX_main from libbusybox * only if we build "individual" binaries */ diff --git a/libbb/verror_msg.c b/libbb/verror_msg.c index 22c30357b..6d3459905 100644 --- a/libbb/verror_msg.c +++ b/libbb/verror_msg.c @@ -12,7 +12,7 @@ #endif #if ENABLE_FEATURE_SYSLOG -smallint syslog_level = LOG_ERR; +static smallint syslog_level = LOG_ERR; #endif smallint logmode = LOGMODE_STDIO; const char *msg_eol = "\n"; @@ -154,7 +154,7 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) } # if ENABLE_FEATURE_SYSLOG if (logmode & LOGMODE_SYSLOG) { - syslog(LOG_ERR, "%s", msgc); + syslog(syslog_level, "%s", msgc); } # endif free(msgc); @@ -180,3 +180,21 @@ void FAST_FUNC bb_error_msg(const char *s, ...) bb_verror_msg(s, p, NULL); va_end(p); } + +#if ENABLE_FEATURE_SYSLOG_INFO +void FAST_FUNC bb_vinfo_msg(const char *s, va_list p) +{ + syslog_level = LOG_INFO; + bb_verror_msg(s, p, NULL); + syslog_level = LOG_ERR; +} + +void FAST_FUNC bb_info_msg(const char *s, ...) +{ + va_list p; + + va_start(p, s); + bb_vinfo_msg(s, p); + va_end(p); +} +#endif diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index 4b3602e7a..dd0532c66 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c @@ -114,7 +114,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) if (rc < 0) bb_error_msg_and_die("an error occurred updating password for %s", name); if (rc) - bb_error_msg("password for '%s' changed", name); + bb_info_msg("password for '%s' changed", name); logmode = LOGMODE_STDIO; free(name); free(free_me); diff --git a/loginutils/passwd.c b/loginutils/passwd.c index 30e096460..6c643d3d0 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c @@ -228,7 +228,7 @@ int passwd_main(int argc UNUSED_PARAM, char **argv) /* LOGMODE_BOTH */ if (rc < 0) bb_error_msg_and_die("can't update password file %s", filename); - bb_error_msg("password for %s changed by %s", name, myname); + bb_info_msg("password for %s changed by %s", name, myname); /*if (ENABLE_FEATURE_CLEAN_UP) free(newp); - can't, it may be non-malloced */ skip: diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 27ea5dff0..9bb4d3613 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c @@ -68,17 +68,17 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) ); if (r < 0) { /* ^D, ^C, timeout, or read error */ - bb_error_msg("normal startup"); + bb_info_msg("normal startup"); return 0; } if (r > 0) { break; } bb_do_delay(LOGIN_FAIL_DELAY); - bb_error_msg("Login incorrect"); + bb_info_msg("Login incorrect"); } - bb_error_msg("starting shell for system maintenance"); + bb_info_msg("starting shell for system maintenance"); IF_SELINUX(renew_current_security_context()); diff --git a/miscutils/crond.c b/miscutils/crond.c index 25e5503c7..b533a3991 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c @@ -181,9 +181,7 @@ static void crondlog(unsigned level, const char *msg, va_list va) * need not touch syslog_level * (they are ok with LOG_ERR default). */ - syslog_level = LOG_INFO; - bb_verror_msg(msg, va, /* strerr: */ NULL); - syslog_level = LOG_ERR; + bb_vinfo_msg(msg, va); } } @@ -1108,7 +1106,7 @@ int crond_main(int argc UNUSED_PARAM, char **argv) process_cron_update_file(); log5("wakeup dt=%ld", dt); if (dt < -60 * 60 || dt > 60 * 60) { - bb_error_msg("time disparity of %ld minutes detected", dt / 60); + bb_info_msg("time disparity of %ld minutes detected", dt / 60); /* and we do not run any jobs in this case */ } else if (dt > 0) { /* Usual case: time advances forward, as expected */ diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 3bf06b965..e4d104d0c 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c @@ -343,7 +343,7 @@ static const char bb_msg_variable_not_found[] ALIGN1 = "variable: %s not found"; /* Busybox stuff */ #if ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG -#define info_logger(p, fmt, args...) bb_error_msg(fmt, ## args) +#define info_logger(p, fmt, args...) bb_info_msg(fmt, ## args) #define msg_logger(p, fmt, args...) bb_error_msg(fmt, ## args) #define msg_logger_and_die(p, fmt, args...) bb_error_msg_and_die(fmt, ## args) #define error_logger(p, fmt, args...) bb_perror_msg(fmt, ## args) diff --git a/networking/dnsd.c b/networking/dnsd.c index 37a80309d..f2c6bddc6 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c @@ -133,7 +133,7 @@ static struct dns_entry *parse_conf_file(const char *fileconf) } if (OPT_verbose) - bb_error_msg("name:%s, ip:%s", token[0], token[1]); + bb_info_msg("name:%s, ip:%s", token[0], token[1]); /* sizeof(*m) includes 1 byte for m->name[0] */ m = xzalloc(sizeof(*m) + strlen(token[0]) + 1); @@ -438,7 +438,7 @@ static int process_packet(struct dns_entry *conf_data, answstr = table_lookup(conf_data, type, query_string); #if DEBUG /* Shows lengths instead of dots, unusable for !DEBUG */ - bb_error_msg("'%s'->'%s'", query_string, answstr); + bb_info_msg("'%s'->'%s'", query_string, answstr); #endif outr_rlen = 4; if (answstr && type == htons(REQ_PTR)) { @@ -474,7 +474,7 @@ static int process_packet(struct dns_entry *conf_data, * RCODE = 0 "success" */ if (OPT_verbose) - bb_error_msg("returning positive reply"); + bb_info_msg("returning positive reply"); outr_flags = htons(0x8000 | 0x0400 | 0); /* we have one answer */ head->nansw = htons(1); @@ -539,7 +539,7 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv) { char *p = xmalloc_sockaddr2dotted(&lsa->u.sa); - bb_error_msg("accepting UDP packets on %s", p); + bb_info_msg("accepting UDP packets on %s", p); free(p); } @@ -557,7 +557,7 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv) continue; } if (OPT_verbose) - bb_error_msg("got UDP packet"); + bb_info_msg("got UDP packet"); buf[r] = '\0'; /* paranoia */ r = process_packet(conf_data, conf_ttl, buf); if (r <= 0) diff --git a/networking/ifplugd.c b/networking/ifplugd.c index 026ff1cc8..1426709cb 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c @@ -326,7 +326,7 @@ static int run_script(const char *action) char *argv[5]; int r; - bb_error_msg("executing '%s %s %s'", G.script_name, G.iface, action); + bb_info_msg("executing '%s %s %s'", G.script_name, G.iface, action); argv[0] = (char*) G.script_name; argv[1] = (char*) G.iface; @@ -345,7 +345,7 @@ static int run_script(const char *action) bb_unsetenv_and_free(env_PREVIOUS); bb_unsetenv_and_free(env_CURRENT); - bb_error_msg("exit code: %d", r & 0xff); + bb_info_msg("exit code: %d", r & 0xff); return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r; } @@ -365,7 +365,7 @@ static void up_iface(void) if (!(ifrequest.ifr_flags & IFF_UP)) { ifrequest.ifr_flags |= IFF_UP; /* Let user know we mess up with interface */ - bb_error_msg("upping interface"); + bb_info_msg("upping interface"); if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0) { if (errno != ENODEV && errno != EADDRNOTAVAIL) xfunc_die(); @@ -414,7 +414,7 @@ static void maybe_up_new_iface(void) (uint8_t)(ifrequest.ifr_hwaddr.sa_data[5])); } - bb_error_msg("using interface %s%s with driver<%s> (version: %s)", + bb_info_msg("using interface %s%s with driver<%s> (version: %s)", G.iface, buf, driver_info.driver, driver_info.version); } #endif @@ -447,7 +447,7 @@ static smallint detect_link(void) logmode = sv_logmode; if (status != IFSTATUS_ERR) { G.api_method_num = i; - bb_error_msg("using %s detection mode", method_table[i].name); + bb_info_msg("using %s detection mode", method_table[i].name); break; } } @@ -632,7 +632,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) /* | (1 << SIGCHLD) - run_script does not use it anymore */ , record_signo); - bb_error_msg("started: %s", bb_banner); + bb_info_msg("started: %s", bb_banner); if (opts & FLAG_MONITOR) { struct ifreq ifrequest; @@ -649,7 +649,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) iface_status_str = strstatus(iface_status); if (opts & FLAG_MONITOR) { - bb_error_msg("interface %s", + bb_info_msg("interface %s", G.iface_exists ? "exists" : "doesn't exist, waiting"); } @@ -657,7 +657,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) * by potentially lying that it really exists */ if (G.iface_exists) { - bb_error_msg("link is %s", iface_status_str); + bb_info_msg("link is %s", iface_status_str); } if ((!(opts & FLAG_NO_STARTUP) @@ -712,7 +712,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) if (G.iface_exists < 0) /* error */ goto exiting; if (iface_exists_old != G.iface_exists) { - bb_error_msg("interface %sappeared", + bb_info_msg("interface %sappeared", G.iface_exists ? "" : "dis"); if (G.iface_exists) maybe_up_new_iface(); @@ -730,7 +730,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) iface_status_str = strstatus(iface_status); if (iface_status_old != iface_status) { - bb_error_msg("link is %s", iface_status_str); + bb_info_msg("link is %s", iface_status_str); if (delay_time) { /* link restored its old status before diff --git a/networking/ntpd.c b/networking/ntpd.c index 027cfe783..cd6da2b38 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -1130,7 +1130,7 @@ step_time(double offset) } tval = tvn.tv_sec; strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval); - bb_error_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset); + bb_info_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset); //maybe? G.FREQHOLD_cnt = 0; /* Correct various fields which contain time-relative values: */ @@ -2132,7 +2132,7 @@ recv_and_process_peer_pkt(peer_t *p) p->reachable_bits |= 1; if ((MAX_VERBOSE && G.verbose) || (option_mask32 & OPT_w)) { - bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", + bb_info_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", p->p_dotted, offset, p->p_raw_delay, diff --git a/networking/tftp.c b/networking/tftp.c index d20d4ca4b..5ebd22105 100644 --- a/networking/tftp.c +++ b/networking/tftp.c @@ -245,7 +245,7 @@ static int tftp_blksize_check(const char *blksize_str, int maxsize) return -1; } # if ENABLE_TFTP_DEBUG - bb_error_msg("using blksize %u", blksize); + bb_info_msg("using blksize %u", blksize); # endif return blksize; } diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 59cf723ee..62ad248ce 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c @@ -191,7 +191,7 @@ static void log_option(const char *pfx, const uint8_t *opt) if (dhcp_verbose >= 2) { char buf[256 * 2 + 2]; *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0'; - bb_error_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); + bb_info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); } } #else diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 9d1f71aae..a897837f9 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -274,16 +274,16 @@ struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 # define IF_UDHCP_VERBOSE(...) __VA_ARGS__ extern unsigned dhcp_verbose; -# define log1(...) do { if (dhcp_verbose >= 1) bb_error_msg(__VA_ARGS__); } while (0) +# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) # if CONFIG_UDHCP_DEBUG >= 2 void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; -# define log2(...) do { if (dhcp_verbose >= 2) bb_error_msg(__VA_ARGS__); } while (0) +# define log2(...) do { if (dhcp_verbose >= 2) bb_info_msg(__VA_ARGS__); } while (0) # else # define udhcp_dump_packet(...) ((void)0) # define log2(...) ((void)0) # endif # if CONFIG_UDHCP_DEBUG >= 3 -# define log3(...) do { if (dhcp_verbose >= 3) bb_error_msg(__VA_ARGS__); } while (0) +# define log3(...) do { if (dhcp_verbose >= 3) bb_info_msg(__VA_ARGS__); } while (0) # else # define log3(...) ((void)0) # endif diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 3562988fd..1a0a5739e 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -670,7 +670,7 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip */ opt_ptr = add_d6_client_options(opt_ptr); - bb_error_msg("sending %s", "discover"); + bb_info_msg("sending %s", "discover"); return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); } @@ -727,7 +727,7 @@ static NOINLINE int send_d6_select(uint32_t xid) */ opt_ptr = add_d6_client_options(opt_ptr); - bb_error_msg("sending %s", "select"); + bb_info_msg("sending %s", "select"); return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); } @@ -800,7 +800,7 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st */ opt_ptr = add_d6_client_options(opt_ptr); - bb_error_msg("sending %s", "renew"); + bb_info_msg("sending %s", "renew"); if (server_ipv6) return d6_send_kernel_packet( &packet, (opt_ptr - (uint8_t*) &packet), @@ -830,7 +830,7 @@ int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) if (client6_data.ia_pd) opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2); - bb_error_msg("sending %s", "release"); + bb_info_msg("sending %s", "release"); return d6_send_kernel_packet( &packet, (opt_ptr - (uint8_t*) &packet), our_cur_ipv6, CLIENT_PORT6, @@ -1033,7 +1033,7 @@ static void change_listen_mode(int new_mode) /* Called only on SIGUSR1 */ static void perform_renew(void) { - bb_error_msg("performing DHCP renew"); + bb_info_msg("performing DHCP renew"); switch (state) { case BOUND: change_listen_mode(LISTEN_KERNEL); @@ -1061,10 +1061,10 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou || state == REBINDING || state == RENEW_REQUESTED ) { - bb_error_msg("unicasting a release"); + bb_info_msg("unicasting a release"); send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ } - bb_error_msg("entering released state"); + bb_info_msg("entering released state"); /* * We can be here on: SIGUSR2, * or on exit (SIGTERM) and -R "release on quit" is specified. @@ -1274,7 +1274,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* Create pidfile */ write_pidfile(client_config.pidfile); /* Goes to stdout (unless NOMMU) and possibly syslog */ - bb_error_msg("started, v"BB_VER); + bb_info_msg("started, v"BB_VER); /* Set up the signal pipe */ udhcp_sp_setup(); @@ -1363,7 +1363,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) d6_run_script_no_option("leasefail"); #if BB_MMU /* -b is not supported on NOMMU */ if (opt & OPT_b) { /* background if no lease */ - bb_error_msg("no lease, forking to background"); + bb_info_msg("no lease, forking to background"); client_background(); /* do not background again! */ opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f); @@ -1376,7 +1376,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) } else #endif if (opt & OPT_n) { /* abort if no lease */ - bb_error_msg("no lease, failing"); + bb_info_msg("no lease, failing"); retval = 1; goto ret; } @@ -1439,7 +1439,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) continue; } /* Timed out, enter init state */ - bb_error_msg("lease lost, entering init state"); + bb_info_msg("lease lost, entering init state"); d6_run_script_no_option("deconfig"); state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ @@ -1484,7 +1484,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) timeout = INT_MAX; continue; case SIGTERM: - bb_error_msg("received %s", "SIGTERM"); + bb_info_msg("received %s", "SIGTERM"); goto ret0; } @@ -1544,7 +1544,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE); if (option && (option->data[0] | option->data[1]) != 0) { /* return to init state */ - bb_error_msg("received DHCP NAK (%u)", option->data[4]); + bb_info_msg("received DHCP NAK (%u)", option->data[4]); d6_run_script(packet.d6_options, packet_end, "nak"); if (state != REQUESTING) @@ -1561,7 +1561,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) } option = d6_copy_option(packet.d6_options, packet_end, D6_OPT_SERVERID); if (!option) { - bb_error_msg("no server ID, ignoring packet"); + bb_info_msg("no server ID, ignoring packet"); continue; /* still selecting - this server looks bad */ } @@ -1670,11 +1670,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) free(client6_data.ia_na); client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA); if (!client6_data.ia_na) { - bb_error_msg("no %s option, ignoring packet", "IA_NA"); + bb_info_msg("no %s option, ignoring packet", "IA_NA"); continue; } if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) { - bb_error_msg("%s option is too short:%d bytes", + bb_info_msg("%s option is too short:%d bytes", "IA_NA", client6_data.ia_na->len); continue; } @@ -1683,11 +1683,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) D6_OPT_IAADDR ); if (!iaaddr) { - bb_error_msg("no %s option, ignoring packet", "IAADDR"); + bb_info_msg("no %s option, ignoring packet", "IAADDR"); continue; } if (iaaddr->len < (16 + 4 + 4)) { - bb_error_msg("%s option is too short:%d bytes", + bb_info_msg("%s option is too short:%d bytes", "IAADDR", iaaddr->len); continue; } @@ -1698,7 +1698,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) move_from_unaligned32(lease_seconds, iaaddr->data + 16 + 4); lease_seconds = ntohl(lease_seconds); /// TODO: check for 0 lease time? - bb_error_msg("%s obtained, lease time %u", + bb_info_msg("%s obtained, lease time %u", "IPv6", /*inet_ntoa(temp_addr),*/ (unsigned)lease_seconds); address_timeout = lease_seconds; } @@ -1708,11 +1708,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) free(client6_data.ia_pd); client6_data.ia_pd = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_PD); if (!client6_data.ia_pd) { - bb_error_msg("no %s option, ignoring packet", "IA_PD"); + bb_info_msg("no %s option, ignoring packet", "IA_PD"); continue; } if (client6_data.ia_pd->len < (4 + 4 + 4) + (2 + 2 + 4 + 4 + 1 + 16)) { - bb_error_msg("%s option is too short:%d bytes", + bb_info_msg("%s option is too short:%d bytes", "IA_PD", client6_data.ia_pd->len); continue; } @@ -1721,17 +1721,17 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) D6_OPT_IAPREFIX ); if (!iaprefix) { - bb_error_msg("no %s option, ignoring packet", "IAPREFIX"); + bb_info_msg("no %s option, ignoring packet", "IAPREFIX"); continue; } if (iaprefix->len < (4 + 4 + 1 + 16)) { - bb_error_msg("%s option is too short:%d bytes", + bb_info_msg("%s option is too short:%d bytes", "IAPREFIX", iaprefix->len); continue; } move_from_unaligned32(lease_seconds, iaprefix->data + 4); lease_seconds = ntohl(lease_seconds); - bb_error_msg("%s obtained, lease time %u", + bb_info_msg("%s obtained, lease time %u", "prefix", /*inet_ntoa(temp_addr),*/ (unsigned)lease_seconds); prefix_timeout = lease_seconds; } @@ -1781,4 +1781,3 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /*if (client_config.pidfile) - remove_pidfile has its own check */ remove_pidfile(client_config.pidfile); return retval; -} diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c index 493943d72..01d1c930b 100644 --- a/networking/udhcp/d6_packet.c +++ b/networking/udhcp/d6_packet.c @@ -17,7 +17,7 @@ void FAST_FUNC d6_dump_packet(struct d6_packet *packet) if (dhcp_verbose < 2) return; - bb_error_msg( + bb_info_msg( " xid %x" , packet->d6_xid32 ); @@ -40,7 +40,7 @@ int FAST_FUNC d6_recv_kernel_packet(struct in6_addr *peer_ipv6 } if (bytes < offsetof(struct d6_packet, d6_options)) { - bb_error_msg("packet with bad magic, ignoring"); + bb_info_msg("packet with bad magic, ignoring"); return -2; } log1("received %s", "a packet"); diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index e2fb18aba..0e673ae7e 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -730,7 +730,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested) */ add_client_options(&packet); - bb_error_msg("sending %s", "discover"); + bb_info_msg("sending %s", "discover"); return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); } @@ -774,7 +774,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste add_client_options(&packet); temp_addr.s_addr = requested; - bb_error_msg("sending select for %s", inet_ntoa(temp_addr)); + bb_info_msg("sending select for %s", inet_ntoa(temp_addr)); return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); } @@ -815,7 +815,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) add_client_options(&packet); temp_addr.s_addr = server; - bb_error_msg("sending renew to %s", inet_ntoa(temp_addr)); + bb_info_msg("sending renew to %s", inet_ntoa(temp_addr)); return bcast_or_ucast(&packet, ciaddr, server); } @@ -844,7 +844,7 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); - bb_error_msg("sending %s", "decline"); + bb_info_msg("sending %s", "decline"); return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); } #endif @@ -866,7 +866,7 @@ int send_release(uint32_t server, uint32_t ciaddr) udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); - bb_error_msg("sending %s", "release"); + bb_info_msg("sending %s", "release"); /* Note: normally we unicast here since "server" is not zero. * However, there _are_ people who run "address-less" DHCP servers, * and reportedly ISC dhcp client and Windows allow that. @@ -969,7 +969,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) skip_udp_sum_check: if (packet.data.cookie != htonl(DHCP_MAGIC)) { - bb_error_msg("packet with bad magic, ignoring"); + bb_info_msg("packet with bad magic, ignoring"); return -2; } @@ -1117,7 +1117,7 @@ static void change_listen_mode(int new_mode) /* Called only on SIGUSR1 */ static void perform_renew(void) { - bb_error_msg("performing DHCP renew"); + bb_info_msg("performing DHCP renew"); switch (state) { case BOUND: change_listen_mode(LISTEN_KERNEL); @@ -1151,11 +1151,11 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) temp_addr.s_addr = server_addr; strcpy(buffer, inet_ntoa(temp_addr)); temp_addr.s_addr = requested_ip; - bb_error_msg("unicasting a release of %s to %s", + bb_info_msg("unicasting a release of %s to %s", inet_ntoa(temp_addr), buffer); send_release(server_addr, requested_ip); /* unicast */ } - bb_error_msg("entering released state"); + bb_info_msg("entering released state"); /* * We can be here on: SIGUSR2, * or on exit (SIGTERM) and -R "release on quit" is specified. @@ -1391,7 +1391,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Create pidfile */ write_pidfile(client_config.pidfile); /* Goes to stdout (unless NOMMU) and possibly syslog */ - bb_error_msg("started, v"BB_VER); + bb_info_msg("started, v"BB_VER); /* Set up the signal pipe */ udhcp_sp_setup(); /* We want random_xid to be random... */ @@ -1481,7 +1481,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) udhcp_run_script(NULL, "leasefail"); #if BB_MMU /* -b is not supported on NOMMU */ if (opt & OPT_b) { /* background if no lease */ - bb_error_msg("no lease, forking to background"); + bb_info_msg("no lease, forking to background"); client_background(); /* do not background again! */ opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f); @@ -1494,7 +1494,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) } else #endif if (opt & OPT_n) { /* abort if no lease */ - bb_error_msg("no lease, failing"); + bb_info_msg("no lease, failing"); retval = 1; goto ret; } @@ -1570,7 +1570,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) continue; } /* Timed out, enter init state */ - bb_error_msg("lease lost, entering init state"); + bb_info_msg("lease lost, entering init state"); udhcp_run_script(NULL, "deconfig"); state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ @@ -1615,7 +1615,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) timeout = INT_MAX; continue; case SIGTERM: - bb_error_msg("received %s", "SIGTERM"); + bb_info_msg("received %s", "SIGTERM"); goto ret0; } @@ -1662,7 +1662,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) message = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE); if (message == NULL) { - bb_error_msg("no message type option, ignoring packet"); + bb_info_msg("no message type option, ignoring packet"); continue; } @@ -1691,7 +1691,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) * might work too. * "Next server" and router are definitely wrong ones to use, though... */ -/* We used to ignore pcakets without DHCP_SERVER_ID. +/* We used to ignore packets without DHCP_SERVER_ID. * I've got user reports from people who run "address-less" servers. * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all. * They say ISC DHCP client supports this case. @@ -1699,7 +1699,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) server_addr = 0; temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); if (!temp) { - bb_error_msg("no server ID, using 0.0.0.0"); + bb_info_msg("no server ID, using 0.0.0.0"); } else { /* it IS unaligned sometimes, don't "optimize" */ move_from_unaligned32(server_addr, temp); @@ -1726,7 +1726,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME); if (!temp) { - bb_error_msg("no lease time with ACK, using 1 hour lease"); + bb_info_msg("no lease time with ACK, using 1 hour lease"); lease_seconds = 60 * 60; } else { /* it IS unaligned sometimes, don't "optimize" */ @@ -1759,7 +1759,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) client_config.interface, arpping_ms) ) { - bb_error_msg("offered address is in use " + bb_info_msg("offered address is in use " "(got ARP reply), declining"); send_decline(/*xid,*/ server_addr, packet.yiaddr); @@ -1778,7 +1778,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) #endif /* enter bound state */ temp_addr.s_addr = packet.yiaddr; - bb_error_msg("lease of %s obtained, lease time %u", + bb_info_msg("lease of %s obtained, lease time %u", inet_ntoa(temp_addr), (unsigned)lease_seconds); requested_ip = packet.yiaddr; @@ -1831,7 +1831,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) goto non_matching_svid; } /* return to init state */ - bb_error_msg("received %s", "DHCP NAK"); + bb_info_msg("received %s", "DHCP NAK"); udhcp_run_script(&packet, "nak"); if (state != REQUESTING) udhcp_run_script(NULL, "deconfig"); diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 0c55fa5e4..d248d2b67 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -104,7 +104,7 @@ static void log_static_leases(struct static_lease **st_lease_pp) cur = *st_lease_pp; while (cur) { - bb_error_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", + bb_info_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", cur->mac[0], cur->mac[1], cur->mac[2], cur->mac[3], cur->mac[4], cur->mac[5], cur->nip @@ -242,7 +242,7 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigne return r; temp.s_addr = nip; - bb_error_msg("%s belongs to someone, reserving it for %u seconds", + bb_info_msg("%s belongs to someone, reserving it for %u seconds", inet_ntoa(temp), (unsigned)server_config.conflict_time); add_lease(NULL, nip, server_config.conflict_time, NULL, 0); return 0; @@ -722,7 +722,7 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, add_server_options(&packet); addr.s_addr = packet.yiaddr; - bb_error_msg("sending OFFER of %s", inet_ntoa(addr)); + bb_info_msg("sending OFFER of %s", inet_ntoa(addr)); /* send_packet emits error message itself if it detects failure */ send_packet(&packet, /*force_bcast:*/ 0); } @@ -755,7 +755,7 @@ static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) add_server_options(&packet); addr.s_addr = yiaddr; - bb_error_msg("sending ACK to %s", inet_ntoa(addr)); + bb_info_msg("sending ACK to %s", inet_ntoa(addr)); send_packet(&packet, /*force_bcast:*/ 0); p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME); @@ -865,7 +865,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) write_pidfile(server_config.pidfile); /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ - bb_error_msg("started, v"BB_VER); + bb_info_msg("started, v"BB_VER); option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); server_config.max_lease_sec = DEFAULT_LEASE_TIME; @@ -944,12 +944,12 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) if (pfds[0].revents) switch (udhcp_sp_read()) { case SIGUSR1: - bb_error_msg("received %s", "SIGUSR1"); + bb_info_msg("received %s", "SIGUSR1"); write_leases(); /* why not just reset the timeout, eh */ goto continue_with_autotime; case SIGTERM: - bb_error_msg("received %s", "SIGTERM"); + bb_info_msg("received %s", "SIGTERM"); write_leases(); goto ret0; } @@ -973,16 +973,16 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) continue; } if (packet.hlen != 6) { - bb_error_msg("MAC length != 6, ignoring packet"); + bb_info_msg("MAC length != 6, ignoring packet"); continue; } if (packet.op != BOOTREQUEST) { - bb_error_msg("not a REQUEST, ignoring packet"); + bb_info_msg("not a REQUEST, ignoring packet"); continue; } state = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE); if (state == NULL || state[0] < DHCP_MINTYPE || state[0] > DHCP_MAXTYPE) { - bb_error_msg("no or bad message type option, ignoring packet"); + bb_info_msg("no or bad message type option, ignoring packet"); continue; } @@ -1001,7 +1001,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) /* Look for a static/dynamic lease */ static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); if (static_lease_nip) { - bb_error_msg("found static lease: %x", static_lease_nip); + bb_info_msg("found static lease: %x", static_lease_nip); memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); fake_lease.lease_nip = static_lease_nip; fake_lease.expires = 0; diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index ff16904f7..64af802a3 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c @@ -40,7 +40,7 @@ void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet) if (dhcp_verbose < 2) return; - bb_error_msg( + bb_info_msg( //" op %x" //" htype %x" " hlen %x" @@ -73,7 +73,7 @@ void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet) //, packet->options[] ); *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; - bb_error_msg(" chaddr %s", buf); + bb_info_msg(" chaddr %s", buf); } #endif @@ -92,7 +92,7 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) if (bytes < offsetof(struct dhcp_packet, options) || packet->cookie != htonl(DHCP_MAGIC) ) { - bb_error_msg("packet with bad magic, ignoring"); + bb_info_msg("packet with bad magic, ignoring"); return -2; } log1("received %s", "a packet"); diff --git a/networking/zcip.c b/networking/zcip.c index 434762f12..f95b6f7fb 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -195,7 +195,7 @@ static int run(char *argv[3], const char *param, uint32_t nip) putenv(env_ip); fmt -= 3; } - bb_error_msg(fmt, argv[2], argv[0], addr); + bb_info_msg(fmt, argv[2], argv[0], addr); status = spawn_and_wait(argv + 1); if (nip != 0) bb_unsetenv_and_free(env_ip); @@ -339,7 +339,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) #if BB_MMU bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/); #endif - bb_error_msg("start, interface %s", argv_intf); + bb_info_msg("start, interface %s", argv_intf); } // Run the dynamic address negotiation protocol, -- cgit v1.2.3-55-g6feb From b052dbea54e2226ea49b9f3bdec3f6bccf879030 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 2 May 2019 17:13:20 +0200 Subject: login: remove extra IF(), no code changes Signed-off-by: Denys Vlasenko --- loginutils/login.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginutils/login.c b/loginutils/login.c index 4df651cc6..a08642a34 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -534,7 +534,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) wait_for_exitstatus(child_pid); update_utmp_DEAD_PROCESS(child_pid); } - IF_PAM(login_pam_end(pamh);) + login_pam_end(pamh); return 0; } #endif -- cgit v1.2.3-55-g6feb From 3106784e654e7443ab724d927f9de0230adbe5ac Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 3 May 2019 09:49:56 +0200 Subject: ps: ensure fields are separated by at least one space, closes 11826 Signed-off-by: Denys Vlasenko --- procps/ps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/procps/ps.c b/procps/ps.c index 54e6c40fc..815c11578 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -533,7 +533,7 @@ static void format_process(const procps_status_t *ps) len = out[i].width - len + 1; if (++i == out_cnt) /* do not pad last field */ break; - p += sprintf(p, "%*s", len, ""); + p += sprintf(p, "%*s", len, " "); /* " ", not "", to ensure separation of fields */ } printf("%.*s\n", terminal_width, buffer); } -- cgit v1.2.3-55-g6feb From 89023b167fad897fb6c0d2cdd24f0140beea7df3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 9 May 2019 15:58:46 +0200 Subject: dc: code shrink function old new delta check_under 20 21 +1 print_no_pop 32 27 -5 pop 24 18 -6 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 1/-11) Total: -10 bytes Signed-off-by: Denys Vlasenko --- miscutils/dc.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/miscutils/dc.c b/miscutils/dc.c index 17fdda8fd..5119c1383 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c @@ -35,10 +35,12 @@ enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof( base = 10; \ } while (0) -static void check_under(void) +static unsigned check_under(void) { - if (pointer == 0) + unsigned p = pointer; + if (p == 0) bb_error_msg_and_die("stack underflow"); + return p - 1; } static void push(double a) @@ -50,8 +52,9 @@ static void push(double a) static double pop(void) { - check_under(); - return stack[--pointer]; + unsigned p = check_under(); + pointer = p; + return stack[p]; } static void add(void) @@ -91,6 +94,14 @@ static void mod(void) { data_t d = pop(); + //if (d == 0) { + // bb_error_msg("remainder by zero"); + // pop(); + // push(0); + // return; + //} + //^^^^ without this, we simply get SIGFPE and die + push((data_t) pop() % d); } @@ -171,8 +182,7 @@ static void print_stack_no_pop(void) static void print_no_pop(void) { - check_under(); - print_base(stack[pointer-1]); + print_base(stack[check_under()]); } struct op { -- cgit v1.2.3-55-g6feb From 94f607a9045481b614cac1b319bd435af01b8860 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Thu, 9 May 2019 09:22:09 -0500 Subject: ln: correct 'ln -T' usage message Signed-off-by: John L. Hammond Signed-off-by: Denys Vlasenko --- coreutils/ln.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils/ln.c b/coreutils/ln.c index 3fe2f3f64..afeb0d72d 100644 --- a/coreutils/ln.c +++ b/coreutils/ln.c @@ -29,7 +29,7 @@ //usage: "\n -n Don't dereference symlinks - treat like normal file" //usage: "\n -b Make a backup of the target (if exists) before link operation" //usage: "\n -S suf Use suffix instead of ~ when making backup files" -//usage: "\n -T 2nd arg must be a DIR" +//usage: "\n -T Treat LINK as a file, not DIR" //usage: "\n -v Verbose" //usage: //usage:#define ln_example_usage -- cgit v1.2.3-55-g6feb From 15021f393d3d19d689028fceb5c35da930059430 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 10 May 2019 15:55:12 +0200 Subject: udhcpd: code shrink function old new delta is_nip_reserved_as_static - 28 +28 get_static_nip_by_mac 43 47 +4 udhcpd_main 1459 1454 -5 send_offer 449 444 -5 read_leases 309 299 -10 is_nip_reserved 20 - -20 packed_usage 33283 33243 -40 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 1/4 up/down: 32/-80) Total: -48 bytes Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpd.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index d248d2b67..c46e1721e 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -70,8 +70,10 @@ static void add_static_lease(struct static_lease **st_lease_pp, } /* Find static lease IP by mac */ -static uint32_t get_static_nip_by_mac(struct static_lease *st_lease, void *mac) +static uint32_t get_static_nip_by_mac(void *mac) { + struct static_lease *st_lease = server_config.static_leases; + while (st_lease) { if (memcmp(st_lease->mac, mac, 6) == 0) return st_lease->nip; @@ -81,8 +83,10 @@ static uint32_t get_static_nip_by_mac(struct static_lease *st_lease, void *mac) return 0; } -static int is_nip_reserved(struct static_lease *st_lease, uint32_t nip) +static int is_nip_reserved_as_static(uint32_t nip) { + struct static_lease *st_lease = server_config.static_leases; + while (st_lease) { if (st_lease->nip == nip) return 1; @@ -288,7 +292,7 @@ static uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arppi if (nip == server_config.server_nip) goto next_addr; /* is this a static lease addr? */ - if (is_nip_reserved(server_config.static_leases, nip)) + if (is_nip_reserved_as_static(nip)) goto next_addr; lease = find_lease_by_nip(nip); @@ -518,13 +522,13 @@ static NOINLINE void read_leases(const char *file) expires = 0; /* Check if there is a different static lease for this IP or MAC */ - static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac); + static_nip = get_static_nip_by_mac(lease.lease_mac); if (static_nip) { /* NB: we do not add lease even if static_nip == lease.lease_nip. */ continue; } - if (is_nip_reserved(server_config.static_leases, lease.lease_nip)) + if (is_nip_reserved_as_static(lease.lease_nip)) continue; /* NB: add_lease takes "relative time", IOW, @@ -999,7 +1003,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) } /* Look for a static/dynamic lease */ - static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); + static_lease_nip = get_static_nip_by_mac(&packet.chaddr); if (static_lease_nip) { bb_info_msg("found static lease: %x", static_lease_nip); memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); -- cgit v1.2.3-55-g6feb From 0545bfa841540a0d7d7e2953bc205eda64144c2e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 13 May 2019 16:29:34 +0200 Subject: sed: fix /regex/,+N match triggering only once, closes 11871 function old new delta process_files 2235 2246 +11 Signed-off-by: Denys Vlasenko --- editors/sed.c | 2 ++ testsuite/sed.tests | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/editors/sed.c b/editors/sed.c index bb39de149..57d3dda16 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -1097,6 +1097,8 @@ static void process_files(void) int old_matched, matched; old_matched = sed_cmd->in_match; + if (!old_matched) + sed_cmd->end_line = sed_cmd->end_line_orig; /* Determine if this command matches this line: */ diff --git a/testsuite/sed.tests b/testsuite/sed.tests index 675cb4f10..67ff87e93 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests @@ -361,6 +361,12 @@ testing "sed /regex/,+N{...} addresses work" \ "" \ "1\n2\n3\n4\n5\n" +testing "sed /regex/,+N{...} addresses work 2" \ + "sed -n '/a/,+1 p'" \ + "a\n1\na\n2\na\n3\n" \ + "" \ + "a\n1\nc\nc\na\n2\na\n3\n" + testing "sed /regex/,+N{...} -i works" \ "cat - >input2; sed /^4/,+2{d} -i input input2; echo \$?; cat input input2; rm input2" \ "0\n""1\n2\n3\n7\n8\n""1\n2\n7\n8\n" \ -- cgit v1.2.3-55-g6feb From 8c317f03f6d4d89fd7b0cc1e6eaf515040b8e701 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 14 May 2019 17:26:47 +0200 Subject: style fix, no code changes Signed-off-by: Denys Vlasenko --- libbb/lineedit.c | 13 ++++++++++--- modutils/lsmod.c | 5 ++++- networking/tc.c | 6 ++++-- networking/udhcp/dhcpd.c | 3 ++- networking/wget.c | 2 +- util-linux/mount.c | 5 ++++- 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 1d5fef5ee..fbabc6c12 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -70,13 +70,20 @@ #if ENABLE_UNICODE_SUPPORT # define BB_NUL ((wchar_t)0) # define CHAR_T wchar_t -static bool BB_isspace(CHAR_T c) { return ((unsigned)c < 256 && isspace(c)); } +static bool BB_isspace(CHAR_T c) +{ + return ((unsigned)c < 256 && isspace(c)); +} # if ENABLE_FEATURE_EDITING_VI -static bool BB_isalnum_or_underscore(CHAR_T c) { +static bool BB_isalnum_or_underscore(CHAR_T c) +{ return ((unsigned)c < 256 && isalnum(c)) || c == '_'; } # endif -static bool BB_ispunct(CHAR_T c) { return ((unsigned)c < 256 && ispunct(c)); } +static bool BB_ispunct(CHAR_T c) +{ + return ((unsigned)c < 256 && ispunct(c)); +} # undef isspace # undef isalnum # undef ispunct diff --git a/modutils/lsmod.c b/modutils/lsmod.c index 694205fda..39dc8e6b7 100644 --- a/modutils/lsmod.c +++ b/modutils/lsmod.c @@ -66,7 +66,10 @@ static void check_tainted(void) } } #else -static void check_tainted(void) { putchar('\n'); } +static ALWAYS_INLINE void check_tainted(void) +{ + putchar('\n'); +} #endif int lsmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; diff --git a/networking/tc.c b/networking/tc.c index 3e9808328..2e1078d31 100644 --- a/networking/tc.c +++ b/networking/tc.c @@ -124,7 +124,8 @@ static char* print_tc_classid(uint32_t cid) } /* Get a qdisc handle. Return 0 on success, !0 otherwise. */ -static int get_qdisc_handle(uint32_t *h, const char *str) { +static int get_qdisc_handle(uint32_t *h, const char *str) +{ uint32_t maj; char *p; @@ -143,7 +144,8 @@ static int get_qdisc_handle(uint32_t *h, const char *str) { } /* Get class ID. Return 0 on success, !0 otherwise. */ -static int get_tc_classid(uint32_t *h, const char *str) { +static int get_tc_classid(uint32_t *h, const char *str) +{ uint32_t maj, min; char *p; diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index c46e1721e..0642fc826 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -365,7 +365,8 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg) return 1; } -static int FAST_FUNC read_optset(const char *line, void *arg) { +static int FAST_FUNC read_optset(const char *line, void *arg) +{ return udhcp_str2optset(line, arg, dhcp_optflags, dhcp_option_strings, /*dhcpv6:*/ 0 diff --git a/networking/wget.c b/networking/wget.c index fa4d21afd..b6f9d605a 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -312,7 +312,7 @@ static void progress_meter(int flag) } } #else -static ALWAYS_INLINE void progress_meter(int flag UNUSED_PARAM) { } +static ALWAYS_INLINE void progress_meter(int flag UNUSED_PARAM) {} #endif diff --git a/util-linux/mount.c b/util-linux/mount.c index 526b4130c..e6bad7c2c 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -1194,7 +1194,10 @@ static int daemonize(void) return 1; } #else -static inline int daemonize(void) { return -ENOSYS; } +static inline int daemonize(void) +{ + return -ENOSYS; +} #endif /* TODO */ -- cgit v1.2.3-55-g6feb From 875ce094cf2d421ba05bed6cfd6c948084d52abe Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 14 May 2019 17:46:18 +0200 Subject: dd: fix handling of short result of full_write(), closes 11711 $ dd bs=1G --- coreutils/dd.c | 26 +++++++++++++------------- libbb/full_write.c | 3 ++- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/coreutils/dd.c b/coreutils/dd.c index 2fb9da77c..b5f3cbec5 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -192,23 +192,15 @@ static void dd_output_status(int UNUSED_PARAM cur_signal) #endif } -static ssize_t full_write_or_warn(const void *buf, size_t len, - const char *const filename) -{ - ssize_t n = full_write(ofd, buf, len); - if (n < 0) - bb_perror_msg("writing '%s'", filename); - return n; -} - static bool write_and_stats(const void *buf, size_t len, size_t obs, const char *filename) { - ssize_t n = full_write_or_warn(buf, len, filename); - if (n < 0) - return 1; + ssize_t n; + + n = full_write(ofd, buf, len); #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE - G.total_bytes += n; + if (n > 0) + G.total_bytes += n; #endif if ((size_t)n == obs) { G.out_full++; @@ -218,6 +210,14 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs, G.out_part++; return 0; } + /* n is < len (and possibly is -1). + * Even if n >= 0, errno is usually set correctly. + * For example, if writing to block device and getting ENOSPC, + * full_write() first sees a short write, then tries to write + * the remainder and gets errno set to ENOSPC. + * It returns n > 0 (the amount which it did write). + */ + bb_perror_msg("error writing '%s'", filename); return 1; } diff --git a/libbb/full_write.c b/libbb/full_write.c index 2b7983f4c..15766fc6c 100644 --- a/libbb/full_write.c +++ b/libbb/full_write.c @@ -11,7 +11,8 @@ /* * Write all of the supplied buffer out to a file. * This does multiple writes as necessary. - * Returns the amount written, or -1 on an error. + * Returns the amount written, or -1 if error was seen + * on the very first write. */ ssize_t FAST_FUNC full_write(int fd, const void *buf, size_t len) { -- cgit v1.2.3-55-g6feb From d8bd7012a30c6ce9efe26d06880ac223143709ad Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 14 May 2019 18:53:24 +0200 Subject: hush: fix "export PS1=xyz" and "local PS1=xyz" messing up prompt function old new delta helper_export_local 215 253 +38 leave_var_nest_level 107 127 +20 run_pipe 1840 1857 +17 handle_changed_special_names 101 105 +4 shell_builtin_read 1399 1398 -1 done_word 767 766 -1 parse_stream 2249 2245 -4 set_local_var 437 430 -7 is_well_formed_var_name 66 - -66 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 4/4 up/down: 79/-79) Total: 0 bytes text data bss dec hex filename 952376 485 7296 960157 ea69d busybox_old 952400 485 7296 960181 ea6b5 busybox_unstripped Signed-off-by: Denys Vlasenko --- shell/hush.c | 55 +++++++++++++++++++++++++++++++++++++--------------- shell/shell_common.c | 15 +------------- shell/shell_common.h | 2 -- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index b3ae73b9b..b612c80da 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2248,9 +2248,12 @@ static const char* FAST_FUNC get_local_var_value(const char *name) return NULL; } +#if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT) \ + || (ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS) static void handle_changed_special_names(const char *name, unsigned name_len) { if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT + && G_interactive_fd && name_len == 3 && name[0] == 'P' && name[1] == 'S' ) { cmdedit_update_prompt(); @@ -2274,6 +2277,10 @@ static void handle_changed_special_names(const char *name, unsigned name_len) #endif } } +#else +/* Do not even bother evaluating arguments */ +# define handle_changed_special_names(...) ((void)0) +#endif /* str holds "NAME=VAL" and is expected to be malloced. * We take ownership of it. @@ -2289,6 +2296,7 @@ static int set_local_var(char *str, unsigned flags) char *free_me = NULL; char *eq_sign; int name_len; + int retval; unsigned local_lvl = (flags >> SETFLAG_VARLVL_SHIFT); eq_sign = strchr(str, '='); @@ -2402,24 +2410,24 @@ static int set_local_var(char *str, unsigned flags) #endif if (flags & SETFLAG_EXPORT) cur->flg_export = 1; + retval = 0; if (cur->flg_export) { if (flags & SETFLAG_UNEXPORT) { cur->flg_export = 0; /* unsetenv was already done */ } else { - int i; debug_printf_env("%s: putenv '%s'/%u\n", __func__, cur->varstr, cur->var_nest_level); - i = putenv(cur->varstr); - /* only now we can free old exported malloced string */ - free(free_me); - return i; + retval = putenv(cur->varstr); + /* fall through to "free(free_me)" - + * only now we can free old exported malloced string + */ } } free(free_me); handle_changed_special_names(cur->varstr, name_len - 1); - return 0; + return retval; } static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val) @@ -2492,6 +2500,11 @@ static void add_vars(struct variable *var) } else { debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level); } + /* Testcase (interactive): + * f() { local PS1='\w \$ '; }; f + * the below call is needed to notice restored PS1 when f returns. + */ + handle_changed_special_names(var->varstr, endofname(var->varstr) - var->varstr); var = next; } } @@ -4198,7 +4211,7 @@ static int done_word(struct parse_context *ctx) #if ENABLE_HUSH_LOOPS if (ctx->ctx_res_w == RES_FOR) { if (ctx->word.has_quoted_part - || !is_well_formed_var_name(command->argv[0], '\0') + || endofname(command->argv[0])[0] != '\0' ) { /* bash says just "not a valid identifier" */ syntax_error("not a valid identifier in for"); @@ -5372,7 +5385,7 @@ static struct pipe *parse_stream(char **pstring, if ((ctx.is_assignment == MAYBE_ASSIGNMENT || ctx.is_assignment == WORD_IS_KEYWORD) && ch == '=' - && is_well_formed_var_name(ctx.word.data, '=') + && endofname(ctx.word.data)[0] == '=' ) { ctx.is_assignment = DEFINITELY_ASSIGNMENT; debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]); @@ -7598,10 +7611,10 @@ static int save_fd_on_redirect(int fd, int avoid_fd, struct squirrel **sqp) avoid_fd = 9; #if ENABLE_HUSH_INTERACTIVE - if (fd == G.interactive_fd) { + if (fd == G_interactive_fd) { /* Testcase: "ls -l /proc/$$/fd 255>&-" should work */ - G.interactive_fd = xdup_CLOEXEC_and_close(G.interactive_fd, avoid_fd); - debug_printf_redir("redirect_fd %d: matches interactive_fd, moving it to %d\n", fd, G.interactive_fd); + G_interactive_fd = xdup_CLOEXEC_and_close(G_interactive_fd, avoid_fd); + debug_printf_redir("redirect_fd %d: matches interactive_fd, moving it to %d\n", fd, G_interactive_fd); return 1; /* "we closed fd" */ } #endif @@ -7677,7 +7690,7 @@ static void restore_redirects(struct squirrel *sq) free(sq); } - /* If moved, G.interactive_fd stays on new fd, not restoring it */ + /* If moved, G_interactive_fd stays on new fd, not restoring it */ } #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU @@ -7694,7 +7707,7 @@ static int internally_opened_fd(int fd, struct squirrel *sq) int i; #if ENABLE_HUSH_INTERACTIVE - if (fd == G.interactive_fd) + if (fd == G_interactive_fd) return 1; #endif /* If this one of script's fds? */ @@ -7885,6 +7898,11 @@ static void remove_nested_vars(void) *cur_pp = cur->next; /* Free */ if (!cur->max_len) { + /* Testcase (interactive): + * f() { local PS1='\w \$ '; }; f + * we should forget local PS1: + */ + handle_changed_special_names(cur->varstr, endofname(cur->varstr) - cur->varstr); debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level); free(cur->varstr); } @@ -10687,9 +10705,7 @@ static int helper_export_local(char **argv, unsigned flags) { do { char *name = *argv; - char *name_end = strchrnul(name, '='); - - /* So far we do not check that name is valid (TODO?) */ + const char *name_end = endofname(name); if (*name_end == '\0') { struct variable *var, **vpp; @@ -10747,8 +10763,15 @@ static int helper_export_local(char **argv, unsigned flags) */ name = xasprintf("%s=", name); } else { + if (*name_end != '=') { + bb_error_msg("'%s': bad variable name", name); + /* do not parse following argv[]s: */ + return 1; + } /* (Un)exporting/making local NAME=VALUE */ name = xstrdup(name); + /* Testcase: export PS1='\w \$ ' */ + unbackslash(name); } debug_printf_env("%s: set_local_var('%s')\n", __func__, name); if (set_local_var(name, flags)) diff --git a/shell/shell_common.c b/shell/shell_common.c index da3165329..e0582adfb 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -22,19 +22,6 @@ const char defifsvar[] ALIGN1 = "IFS= \t\n"; const char defoptindvar[] ALIGN1 = "OPTIND=1"; - -int FAST_FUNC is_well_formed_var_name(const char *s, char terminator) -{ - if (!s || !(isalpha(*s) || *s == '_')) - return 0; - - do - s++; - while (isalnum(*s) || *s == '_'); - - return *s == terminator; -} - /* read builtin */ /* Needs to be interruptible: shell must handle traps and shell-special signals @@ -70,7 +57,7 @@ shell_builtin_read(struct builtin_read_params *params) argv = params->argv; pp = argv; while (*pp) { - if (!is_well_formed_var_name(*pp, '\0')) { + if (endofname(*pp)[0] != '\0') { /* Mimic bash message */ bb_error_msg("read: '%s': not a valid identifier", *pp); return (const char *)(uintptr_t)1; diff --git a/shell/shell_common.h b/shell/shell_common.h index a1323021d..7b478f1df 100644 --- a/shell/shell_common.h +++ b/shell/shell_common.h @@ -26,8 +26,6 @@ extern const char defifsvar[] ALIGN1; /* "IFS= \t\n" */ extern const char defoptindvar[] ALIGN1; /* "OPTIND=1" */ -int FAST_FUNC is_well_formed_var_name(const char *s, char terminator); - /* Builtins */ struct builtin_read_params { -- cgit v1.2.3-55-g6feb From 63d765e666a8b23e3923acecdc41be71d5679439 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 14 May 2019 19:15:20 +0200 Subject: shells: add tests for backslashes in export VAR=VAL Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-misc/export1.right | 1 + shell/ash_test/ash-misc/export1.tests | 2 ++ shell/hush_test/hush-misc/export1.right | 1 + shell/hush_test/hush-misc/export1.tests | 2 ++ 4 files changed, 6 insertions(+) create mode 100644 shell/ash_test/ash-misc/export1.right create mode 100755 shell/ash_test/ash-misc/export1.tests create mode 100644 shell/hush_test/hush-misc/export1.right create mode 100755 shell/hush_test/hush-misc/export1.tests diff --git a/shell/ash_test/ash-misc/export1.right b/shell/ash_test/ash-misc/export1.right new file mode 100644 index 000000000..56647af8e --- /dev/null +++ b/shell/ash_test/ash-misc/export1.right @@ -0,0 +1 @@ +|\w \\ \ \| diff --git a/shell/ash_test/ash-misc/export1.tests b/shell/ash_test/ash-misc/export1.tests new file mode 100755 index 000000000..4ffb40bdc --- /dev/null +++ b/shell/ash_test/ash-misc/export1.tests @@ -0,0 +1,2 @@ +export Z='\w \\ \ \' +echo "|$Z|" diff --git a/shell/hush_test/hush-misc/export1.right b/shell/hush_test/hush-misc/export1.right new file mode 100644 index 000000000..56647af8e --- /dev/null +++ b/shell/hush_test/hush-misc/export1.right @@ -0,0 +1 @@ +|\w \\ \ \| diff --git a/shell/hush_test/hush-misc/export1.tests b/shell/hush_test/hush-misc/export1.tests new file mode 100755 index 000000000..4ffb40bdc --- /dev/null +++ b/shell/hush_test/hush-misc/export1.tests @@ -0,0 +1,2 @@ +export Z='\w \\ \ \' +echo "|$Z|" -- cgit v1.2.3-55-g6feb From 8402969d4892891ddfde524fbb9ee73e076f3771 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 15 May 2019 13:08:48 +0200 Subject: udhcpd: code shrink - do not fetch requested IP twice function old new delta send_offer 444 443 -1 udhcpd_main 1454 1442 -12 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-13) Total: -13 bytes Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpd.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 0642fc826..bf44320a1 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -662,7 +662,7 @@ static uint32_t select_lease_time(struct dhcp_packet *packet) static NOINLINE void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, struct dyn_lease *lease, - uint8_t *requested_ip_opt, + uint32_t requested_nip, unsigned arpping_ms) { struct dhcp_packet packet; @@ -676,7 +676,6 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, /* Else: */ if (!static_lease_nip) { /* We have no static lease for client's chaddr */ - uint32_t req_nip; const char *p_host_name; if (lease) { @@ -687,18 +686,16 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, packet.yiaddr = lease->lease_nip; } /* Or: if client has requested an IP */ - else if (requested_ip_opt != NULL - /* (read IP) */ - && (move_from_unaligned32(req_nip, requested_ip_opt), 1) + else if (requested_nip != 0 /* and the IP is in the lease range */ - && ntohl(req_nip) >= server_config.start_ip - && ntohl(req_nip) <= server_config.end_ip + && ntohl(requested_nip) >= server_config.start_ip + && ntohl(requested_nip) <= server_config.end_ip /* and */ - && ( !(lease = find_lease_by_nip(req_nip)) /* is not already taken */ + && ( !(lease = find_lease_by_nip(requested_nip)) /* is not already taken */ || is_expired_lease(lease) /* or is taken, but expired */ ) ) { - packet.yiaddr = req_nip; + packet.yiaddr = requested_nip; } else { /* Otherwise, find a free IP */ @@ -913,7 +910,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) int tv; uint8_t *server_id_opt; uint8_t *requested_ip_opt; - uint32_t requested_nip = requested_nip; /* for compiler */ + uint32_t requested_nip; uint32_t static_lease_nip; struct dyn_lease *lease, fake_lease; @@ -1016,6 +1013,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) } /* Get REQUESTED_IP if present */ + requested_nip = 0; requested_ip_opt = udhcp_get_option32(&packet, DHCP_REQUESTED_IP); if (requested_ip_opt) { move_from_unaligned32(requested_nip, requested_ip_opt); @@ -1026,7 +1024,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) case DHCPDISCOVER: log1("received %s", "DISCOVER"); - send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms); + send_offer(&packet, static_lease_nip, lease, requested_nip, arpping_ms); break; case DHCPREQUEST: -- cgit v1.2.3-55-g6feb From 9e0adb9b09ec14afe2e5a222dda1c447f336ea06 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 15 May 2019 13:39:19 +0200 Subject: hush: fix quoted "${notexist-}" expansion to not disappear function old new delta expand_one_var 2296 2311 +15 Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-vars/param_expand_default.right | 2 ++ shell/ash_test/ash-vars/param_expand_default.tests | 5 +++++ shell/hush.c | 6 ++++++ shell/hush_test/hush-vars/param_expand_default.right | 2 ++ shell/hush_test/hush-vars/param_expand_default.tests | 5 +++++ 5 files changed, 20 insertions(+) diff --git a/shell/ash_test/ash-vars/param_expand_default.right b/shell/ash_test/ash-vars/param_expand_default.right index 3eecd1375..7a42f67e8 100644 --- a/shell/ash_test/ash-vars/param_expand_default.right +++ b/shell/ash_test/ash-vars/param_expand_default.right @@ -5,3 +5,5 @@ _aaaa _aaaa _aaaa _aaaa _aaaa _ _ _ _word _word _ _ _ _ _word _fff _fff _fff _fff _fff +1:1 +0:0 diff --git a/shell/ash_test/ash-vars/param_expand_default.tests b/shell/ash_test/ash-vars/param_expand_default.tests index 5e42d30e3..b5edfe1c5 100755 --- a/shell/ash_test/ash-vars/param_expand_default.tests +++ b/shell/ash_test/ash-vars/param_expand_default.tests @@ -21,3 +21,8 @@ echo _$f _${f-} _${f:-} _${f-word} _${f:-word} f=fff echo _$f _${f-} _${f:-} _${f-word} _${f:-word} + +set -- +set -- "${1-}"; echo 1:$# +set -- +set -- ${1-}; echo 0:$# diff --git a/shell/hush.c b/shell/hush.c index b612c80da..a103e8169 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -6132,6 +6132,12 @@ static int encode_then_append_var_plusminus(o_string *output, int n, /* string has no special chars * && string has no $IFS chars */ + if (dquoted) { + /* Prints 1 (quoted expansion is a "" word, not nothing): + * set -- "${notexist-}"; echo $# + */ + output->has_quoted_part = 1; + } return expand_vars_to_list(output, n, str); } diff --git a/shell/hush_test/hush-vars/param_expand_default.right b/shell/hush_test/hush-vars/param_expand_default.right index acc717205..dbade3003 100644 --- a/shell/hush_test/hush-vars/param_expand_default.right +++ b/shell/hush_test/hush-vars/param_expand_default.right @@ -6,3 +6,5 @@ _aaaa _aaaa _aaaa _aaaa _aaaa _ _ _ _word _word _ _ _ _ _word _fff _fff _fff _fff _fff +1:1 +0:0 diff --git a/shell/hush_test/hush-vars/param_expand_default.tests b/shell/hush_test/hush-vars/param_expand_default.tests index 16e5f8efe..754827ab3 100755 --- a/shell/hush_test/hush-vars/param_expand_default.tests +++ b/shell/hush_test/hush-vars/param_expand_default.tests @@ -22,3 +22,8 @@ echo _$f _${f-} _${f:-} _${f-word} _${f:-word} f=fff echo _$f _${f-} _${f:-} _${f-word} _${f:-word} + +set -- +set -- "${1-}"; echo 1:$# +set -- +set -- ${1-}; echo 0:$# -- cgit v1.2.3-55-g6feb From abe248b20880d4d3831ba0a188f69d4a8126498a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 15 May 2019 14:19:46 +0200 Subject: udhcpc6: unbreak Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_dhcpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 1a0a5739e..6cc2316c4 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -1781,3 +1781,4 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /*if (client_config.pidfile) - remove_pidfile has its own check */ remove_pidfile(client_config.pidfile); return retval; +} -- cgit v1.2.3-55-g6feb From 1113961dde21ce73c1543ca466913d9e17d06c1b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 16 May 2019 09:40:36 +0200 Subject: dc: make 4 % 0 emit error messgaes and set result to 0 function old new delta mod 105 136 +31 Signed-off-by: Denys Vlasenko --- miscutils/dc.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/miscutils/dc.c b/miscutils/dc.c index 5119c1383..5aef64b60 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c @@ -94,13 +94,18 @@ static void mod(void) { data_t d = pop(); - //if (d == 0) { - // bb_error_msg("remainder by zero"); - // pop(); - // push(0); - // return; - //} - //^^^^ without this, we simply get SIGFPE and die + /* compat with dc (GNU bc 1.07.1) 1.4.1: + * $ dc -e '4 0 % p' + * dc: remainder by zero + * 0 + */ + if (d == 0) { + bb_error_msg("remainder by zero"); + pop(); + push(0); + return; + } + /* ^^^^ without this, we simply get SIGFPE and die */ push((data_t) pop() % d); } -- cgit v1.2.3-55-g6feb From 9bf6780c2888805908d9485681dadffeab3414f7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 16 May 2019 09:56:45 +0200 Subject: shell: add TODO comment about BASE#nnn literals Signed-off-by: Denys Vlasenko --- shell/math.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell/math.h b/shell/math.h index 32e1ffe35..2c5ae9b44 100644 --- a/shell/math.h +++ b/shell/math.h @@ -72,6 +72,8 @@ typedef long arith_t; #define ARITH_FMT "%ld" #define strto_arith_t strtoul #endif +//TODO: bash supports "BASE#nnnnn" numeric literals, e.g. 2#1111 = 15. +//Make strto_arith_t() support that? typedef const char* FAST_FUNC (*arith_var_lookup_t)(const char *name); typedef void FAST_FUNC (*arith_var_set_t)(const char *name, const char *val); -- cgit v1.2.3-55-g6feb From a840884531df649aabc72debb2d6025dabe2abb3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 16 May 2019 11:18:49 +0200 Subject: udhcpd: support per-client hostnames in static leases function old new delta read_staticlease 222 299 +77 add_server_options 92 154 +62 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 139/0) Total: 139 bytes Signed-off-by: Denys Vlasenko --- examples/udhcp/udhcpd.conf | 9 ++++-- networking/udhcp/dhcpd.c | 72 ++++++++++++++++++++++++++++++++++++++++------ networking/udhcp/dhcpd.h | 6 +--- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/examples/udhcp/udhcpd.conf b/examples/udhcp/udhcpd.conf index bb8774e08..df1258aaf 100644 --- a/examples/udhcp/udhcpd.conf +++ b/examples/udhcp/udhcpd.conf @@ -44,7 +44,7 @@ interface eth0 #notify_file # default: no script #notify_file dumpleases # useful for debugging -# The following are bootp specific options +# The following are BOOTP specific options # next server to use in bootstrap #siaddr 192.168.0.22 # default: 0.0.0.0 (none) # tftp server name @@ -52,9 +52,14 @@ interface eth0 # tftp file to download (e.g. kernel image) #boot_file /var/nfs_root # default: none +# NOTE: "boot_file FILE" and "opt bootfile FILE" are conceptually the same, +# but "boot_file" goes into BOOTP-defined fixed-size field in the packet, +# whereas "opt bootfile" goes into DHCP option 0x43. +# Same for "sname HOST" and "opt tftp HOST". + # Static leases map #static_lease 00:60:08:11:CE:4E 192.168.0.54 -#static_lease 00:60:08:11:CE:3E 192.168.0.44 +#static_lease 00:60:08:11:CE:3E 192.168.0.44 optional_hostname # The remainder of options are DHCP options and can be specified with the # keyword 'opt' or 'option'. If an option can take multiple items, such diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index bf44320a1..f231e4001 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -48,14 +48,23 @@ #define g_leases ((struct dyn_lease*)ptr_to_globals) /* struct server_config_t server_config is in bb_common_bufsiz1 */ +struct static_lease { + struct static_lease *next; + uint32_t nip; + uint8_t mac[6]; + uint8_t opt[1]; +}; + /* Takes the address of the pointer to the static_leases linked list, * address to a 6 byte mac address, * 4 byte IP address */ static void add_static_lease(struct static_lease **st_lease_pp, uint8_t *mac, - uint32_t nip) + uint32_t nip, + const char *opts) { struct static_lease *st_lease; + unsigned optlen; /* Find the tail of the list */ while ((st_lease = *st_lease_pp) != NULL) { @@ -63,10 +72,17 @@ static void add_static_lease(struct static_lease **st_lease_pp, } /* Add new node */ - *st_lease_pp = st_lease = xzalloc(sizeof(*st_lease)); + optlen = (opts ? 1+1+strnlen(opts, 120) : 0); + *st_lease_pp = st_lease = xzalloc(sizeof(*st_lease) + optlen); memcpy(st_lease->mac, mac, 6); st_lease->nip = nip; /*st_lease->next = NULL;*/ + if (optlen) { + st_lease->opt[OPT_CODE] = DHCP_HOST_NAME; + optlen -= 2; + st_lease->opt[OPT_LEN] = optlen; + memcpy(&st_lease->opt[OPT_DATA], opts, optlen); + } } /* Find static lease IP by mac */ @@ -344,6 +360,7 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg) char *line; char *mac_string; char *ip_string; + char *opts; struct ether_addr mac_bytes; /* it's "struct { uint8_t mac[6]; }" */ uint32_t nip; @@ -358,7 +375,10 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg) if (!ip_string || !udhcp_str2nip(ip_string, &nip)) return 0; - add_static_lease(arg, (uint8_t*) &mac_bytes, nip); + opts = strtok_r(NULL, " \t", &line); + /* opts might be NULL, that's not an error */ + + add_static_lease(arg, (uint8_t*) &mac_bytes, nip, opts); log_static_leases(arg); @@ -626,14 +646,49 @@ static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacke */ static void add_server_options(struct dhcp_packet *packet) { - struct option_set *curr = server_config.options; + struct option_set *config_opts; + uint8_t *client_hostname_opt; + + client_hostname_opt = NULL; + if (packet->yiaddr) { /* if we aren't from send_inform()... */ + struct static_lease *st_lease = server_config.static_leases; + while (st_lease) { + if (st_lease->nip == packet->yiaddr) { + if (st_lease->opt[0] != 0) + client_hostname_opt = st_lease->opt; + break; + } + st_lease = st_lease->next; + } + } - while (curr) { - if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) - udhcp_add_binary_option(packet, curr->data); - curr = curr->next; + config_opts = server_config.options; + while (config_opts) { + if (config_opts->data[OPT_CODE] != DHCP_LEASE_TIME) { + /* ^^^^ + * DHCP_LEASE_TIME is already filled, or in case of + * send_inform(), should not be filled at all. + */ + if (config_opts->data[OPT_CODE] != DHCP_HOST_NAME + || !client_hostname_opt + ) { + /* Why "!client_hostname_opt": + * add hostname only if client has no hostname + * on its static lease line. + * (Not that "opt hostname HOST" + * makes much sense in udhcpd.conf, + * that'd give all clients the same hostname, + * but it's a valid configuration). + */ + udhcp_add_binary_option(packet, config_opts->data); + } + } + config_opts = config_opts->next; } + if (client_hostname_opt) + udhcp_add_binary_option(packet, client_hostname_opt); + packet->siaddr_nip = server_config.siaddr_nip; if (server_config.sname) @@ -753,7 +808,6 @@ static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) lease_time_sec = select_lease_time(oldpacket); udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec)); - add_server_options(&packet); addr.s_addr = yiaddr; diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h index b8f96b029..5c3bf5147 100644 --- a/networking/udhcp/dhcpd.h +++ b/networking/udhcp/dhcpd.h @@ -15,11 +15,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN #define DHCPD_CONF_FILE "/etc/udhcpd.conf" -struct static_lease { - struct static_lease *next; - uint32_t nip; - uint8_t mac[6]; -}; +struct static_lease; struct server_config_t { char *interface; /* interface to use */ -- cgit v1.2.3-55-g6feb From 25393fb55e515cab25bb932420813f2c5bbd18f9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 16 May 2019 11:27:28 +0200 Subject: udhcpd: code shrink function old new delta send_packet_verbose - 35 +35 send_offer 443 423 -20 send_ACK 152 131 -21 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/2 up/down: 35/-41) Total: -6 bytes Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpd.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index f231e4001..3d60abf8f 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -627,6 +627,15 @@ static void send_packet(struct dhcp_packet *dhcp_pkt, int force_broadcast) send_packet_to_client(dhcp_pkt, force_broadcast); } +static void send_packet_verbose(struct dhcp_packet *dhcp_pkt, const char *fmt) +{ + struct in_addr addr; + addr.s_addr = dhcp_pkt->yiaddr; + bb_info_msg(fmt, inet_ntoa(addr)); + /* send_packet emits error message itself if it detects failure */ + send_packet(dhcp_pkt, /*force_bcast:*/ 0); +} + static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacket, char type) { /* Sets op, htype, hlen, cookie fields @@ -722,7 +731,6 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, { struct dhcp_packet packet; uint32_t lease_time_sec; - struct in_addr addr; init_packet(&packet, oldpacket, DHCPOFFER); @@ -778,10 +786,8 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec)); add_server_options(&packet); - addr.s_addr = packet.yiaddr; - bb_info_msg("sending OFFER of %s", inet_ntoa(addr)); /* send_packet emits error message itself if it detects failure */ - send_packet(&packet, /*force_bcast:*/ 0); + send_packet_verbose(&packet, "sending OFFER to %s"); } /* NOINLINE: limit stack usage in caller */ @@ -800,7 +806,6 @@ static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) { struct dhcp_packet packet; uint32_t lease_time_sec; - struct in_addr addr; const char *p_host_name; init_packet(&packet, oldpacket, DHCPACK); @@ -810,9 +815,7 @@ static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec)); add_server_options(&packet); - addr.s_addr = yiaddr; - bb_info_msg("sending ACK to %s", inet_ntoa(addr)); - send_packet(&packet, /*force_bcast:*/ 0); + send_packet_verbose(&packet, "sending ACK to %s"); p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME); add_lease(packet.chaddr, packet.yiaddr, @@ -852,6 +855,7 @@ static NOINLINE void send_inform(struct dhcp_packet *oldpacket) add_server_options(&packet); send_packet(&packet, /*force_bcast:*/ 0); + // or maybe? send_packet_verbose(&packet, "sending ACK to %s"); } int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -- cgit v1.2.3-55-g6feb From 0ee0b658b3b651d952965dd85a7b1dd0ac5312dc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 16 May 2019 11:32:26 +0200 Subject: hush: small speedup in handle_changed_special_names() Signed-off-by: Denys Vlasenko --- shell/hush.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index a103e8169..ce341632a 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2253,10 +2253,10 @@ static const char* FAST_FUNC get_local_var_value(const char *name) static void handle_changed_special_names(const char *name, unsigned name_len) { if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT - && G_interactive_fd && name_len == 3 && name[0] == 'P' && name[1] == 'S' ) { - cmdedit_update_prompt(); + if (G_interactive_fd) + cmdedit_update_prompt(); return; } -- cgit v1.2.3-55-g6feb From a51eec0b5aaee3835a54ca35c65e3cfc87004b97 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 16 May 2019 14:31:58 +0200 Subject: typo fix in comment Signed-off-by: Denys Vlasenko --- examples/shutdown-1.0/script/stop_storage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/shutdown-1.0/script/stop_storage b/examples/shutdown-1.0/script/stop_storage index 1be5f735b..50f3b4dd2 100755 --- a/examples/shutdown-1.0/script/stop_storage +++ b/examples/shutdown-1.0/script/stop_storage @@ -4,7 +4,7 @@ # Repeat. umountcnt=2 -writeout=0 # increase if your kernel doesn ot guarantee writes to complete +writeout=0 # increase if your kernel does not guarantee writes to complete # No /usr - we are expecting all binaries to be accessible # from root fs alone -- cgit v1.2.3-55-g6feb From 4ebcdf7396b8e19ddf4e8b12a84b186fcbccabb8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 16 May 2019 15:39:19 +0200 Subject: hush: remove code to track PS1/2 values dynamically - it's too much work Assignments / exports / unsets of variables are far more frequent than prompt printing, and if we show prompt, we are likely to be limited by user typing speed - do not optimize for that scenario. Just re-query $PS1 / $PS2 values when need to show the prompt. function old new delta fgetc_interactive 236 259 +23 set_vars_and_save_old 150 147 -3 pseudo_exec_argv 597 594 -3 hush_main 1110 1105 -5 enter_var_nest_level 38 32 -6 builtin_local 56 50 -6 run_pipe 1857 1834 -23 leave_var_nest_level 127 98 -29 handle_changed_special_names 111 79 -32 cmdedit_update_prompt 57 - -57 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/8 up/down: 23/-164) Total: -141 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 82 ++++++++++++++++-------------------------------------------- 1 file changed, 21 insertions(+), 61 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index ce341632a..e2927afc4 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -854,8 +854,7 @@ struct globals { /* 'interactive_fd' is a fd# open to ctty, if we have one * _AND_ if we decided to act interactively */ int interactive_fd; - const char *PS1; - IF_FEATURE_EDITING_FANCY_PROMPT(const char *PS2;) + IF_NOT_FEATURE_EDITING_FANCY_PROMPT(char *PS1;) # define G_interactive_fd (G.interactive_fd) #else # define G_interactive_fd 0 @@ -1448,13 +1447,6 @@ static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch) #endif -#if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT -static void cmdedit_update_prompt(void); -#else -# define cmdedit_update_prompt() ((void)0) -#endif - - /* Utility functions */ /* Replace each \x with x in place, return ptr past NUL. */ @@ -2248,33 +2240,22 @@ static const char* FAST_FUNC get_local_var_value(const char *name) return NULL; } -#if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT) \ - || (ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS) +#if ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS static void handle_changed_special_names(const char *name, unsigned name_len) { - if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT - && name_len == 3 && name[0] == 'P' && name[1] == 'S' - ) { - if (G_interactive_fd) - cmdedit_update_prompt(); - return; - } - - if ((ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS) - && name_len == 6 - ) { -#if ENABLE_HUSH_LINENO_VAR + if (name_len == 6) { +# if ENABLE_HUSH_LINENO_VAR if (strncmp(name, "LINENO", 6) == 0) { G.lineno_var = NULL; return; } -#endif -#if ENABLE_HUSH_GETOPTS +# endif +# if ENABLE_HUSH_GETOPTS if (strncmp(name, "OPTIND", 6) == 0) { G.getopt_count = 0; return; } -#endif +# endif } } #else @@ -2470,7 +2451,7 @@ static int unset_local_var_len(const char *name, int name_len) cur_pp = &cur->next; } - /* Handle "unset PS1" et al even if did not find the variable to unset */ + /* Handle "unset LINENO" et al even if did not find the variable to unset */ handle_changed_special_names(name, name_len); return EXIT_SUCCESS; @@ -2500,11 +2481,6 @@ static void add_vars(struct variable *var) } else { debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level); } - /* Testcase (interactive): - * f() { local PS1='\w \$ '; }; f - * the below call is needed to notice restored PS1 when f returns. - */ - handle_changed_special_names(var->varstr, endofname(var->varstr) - var->varstr); var = next; } } @@ -2594,36 +2570,27 @@ static void reinit_unicode_for_hush(void) * \ * It exercises a lot of corner cases. */ -# if ENABLE_FEATURE_EDITING_FANCY_PROMPT -static void cmdedit_update_prompt(void) -{ - G.PS1 = get_local_var_value("PS1"); - if (G.PS1 == NULL) - G.PS1 = ""; - G.PS2 = get_local_var_value("PS2"); - if (G.PS2 == NULL) - G.PS2 = ""; -} -# endif static const char *setup_prompt_string(void) { const char *prompt_str; debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode); - IF_FEATURE_EDITING_FANCY_PROMPT( prompt_str = G.PS2;) - IF_NOT_FEATURE_EDITING_FANCY_PROMPT(prompt_str = "> ";) +# if ENABLE_FEATURE_EDITING_FANCY_PROMPT + prompt_str = get_local_var_value(G.promptmode == 0 ? "PS1" : "PS2"); + if (!prompt_str) + prompt_str = ""; +# else + prompt_str = "> "; /* if PS2, else... */ if (G.promptmode == 0) { /* PS1 */ - if (!ENABLE_FEATURE_EDITING_FANCY_PROMPT) { - /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */ - free((char*)G.PS1); - /* bash uses $PWD value, even if it is set by user. - * It uses current dir only if PWD is unset. - * We always use current dir. */ - G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#'); - } - prompt_str = G.PS1; + /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */ + free(G.PS1); + /* bash uses $PWD value, even if it is set by user. + * It uses current dir only if PWD is unset. + * We always use current dir. */ + G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#'); } +# endif debug_printf("prompt_str '%s'\n", prompt_str); return prompt_str; } @@ -7904,11 +7871,6 @@ static void remove_nested_vars(void) *cur_pp = cur->next; /* Free */ if (!cur->max_len) { - /* Testcase (interactive): - * f() { local PS1='\w \$ '; }; f - * we should forget local PS1: - */ - handle_changed_special_names(cur->varstr, endofname(cur->varstr) - cur->varstr); debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level); free(cur->varstr); } @@ -9997,8 +9959,6 @@ int hush_main(int argc, char **argv) #endif /* Initialize some more globals to non-zero values */ - cmdedit_update_prompt(); - die_func = restore_ttypgrp_and__exit; /* Shell is non-interactive at first. We need to call -- cgit v1.2.3-55-g6feb From ee9e5f92b659081a9d889ef16f91a070b8c36024 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Wed, 6 Mar 2019 21:06:10 -0800 Subject: networking: cc is not a register gcc accepts __asm__ ( "" : : : "%cc"); but cc is not a real register and clang does not like it. networking/tls_pstm_montgomery_reduce.c:385:4: error: unknown register name '%cc' in asm | INNERMUL; | ^ The % syntax nominally goes before a register, in this case cc, like "memory" isn't a true register it's just a way of specifying that the condition code registers for the target are clobbered Signed-off-by: Khem Raj Signed-off-by: Denys Vlasenko --- networking/tls_pstm_montgomery_reduce.c | 12 ++++++------ networking/tls_pstm_mul_comba.c | 4 ++-- networking/tls_pstm_sqr_comba.c | 22 +++++++++++----------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/networking/tls_pstm_montgomery_reduce.c b/networking/tls_pstm_montgomery_reduce.c index d46e2aa2b..20f9c26d5 100644 --- a/networking/tls_pstm_montgomery_reduce.c +++ b/networking/tls_pstm_montgomery_reduce.c @@ -73,7 +73,7 @@ asm( \ "movl %%edx,%1 \n\t" \ :"=g"(_c[LO]), "=r"(cy) \ :"0"(_c[LO]), "1"(cy), "g"(mu), "g"(*tmpm++) \ -: "%eax", "%edx", "%cc") +: "%eax", "%edx", "cc") #define PROPCARRY \ asm( \ @@ -82,7 +82,7 @@ asm( \ "movzbl %%al,%1 \n\t" \ :"=g"(_c[LO]), "=r"(cy) \ :"0"(_c[LO]), "1"(cy) \ -: "%eax", "%cc") +: "%eax", "cc") /******************************************************************************/ #elif defined(PSTM_X86_64) @@ -235,7 +235,7 @@ asm( \ " STR r0,%1 \n\t" \ :"=r"(cy),"=m"(_c[0])\ :"0"(cy),"r"(mu),"r"(*tmpm++),"m"(_c[0])\ - :"r0","%cc"); + :"r0","cc"); #define PROPCARRY \ asm( \ " LDR r0,%1 \n\t" \ @@ -246,7 +246,7 @@ asm( \ " MOVCC %0,#0 \n\t" \ :"=r"(cy),"=m"(_c[0])\ :"0"(cy),"m"(_c[0])\ - :"r0","%cc"); + :"r0","cc"); #else /* Non-Thumb2 code */ //#pragma message ("Using 32 bit ARM Assembly Optimizations") #define INNERMUL \ @@ -259,7 +259,7 @@ asm( \ " STR r0,%1 \n\t" \ :"=r"(cy),"=m"(_c[0])\ :"0"(cy),"r"(mu),"r"(*tmpm++),"m"(_c[0])\ - :"r0","%cc"); + :"r0","cc"); #define PROPCARRY \ asm( \ " LDR r0,%1 \n\t" \ @@ -269,7 +269,7 @@ asm( \ " MOVCC %0,#0 \n\t" \ :"=r"(cy),"=m"(_c[0])\ :"0"(cy),"m"(_c[0])\ - :"r0","%cc"); + :"r0","cc"); #endif /* __thumb2__ */ diff --git a/networking/tls_pstm_mul_comba.c b/networking/tls_pstm_mul_comba.c index ac4fcc3ef..af50358e5 100644 --- a/networking/tls_pstm_mul_comba.c +++ b/networking/tls_pstm_mul_comba.c @@ -85,7 +85,7 @@ asm( \ "addl %%eax,%0 \n\t" \ "adcl %%edx,%1 \n\t" \ "adcl $0,%2 \n\t" \ - :"=rm"(c0), "=rm"(c1), "=rm"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); + :"=rm"(c0), "=rm"(c1), "=rm"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","cc"); //bbox: ^^^ replaced "=r" with "=rm": %ebx is not available on shared build /******************************************************************************/ @@ -155,7 +155,7 @@ asm( \ " ADDS %0,%0,r0 \n\t" \ " ADCS %1,%1,r1 \n\t" \ " ADC %2,%2,#0 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "cc"); /******************************************************************************/ #elif defined(PSTM_MIPS) diff --git a/networking/tls_pstm_sqr_comba.c b/networking/tls_pstm_sqr_comba.c index 8604132d6..a4d421b89 100644 --- a/networking/tls_pstm_sqr_comba.c +++ b/networking/tls_pstm_sqr_comba.c @@ -78,7 +78,7 @@ asm( \ "addl %%eax,%0 \n\t" \ "adcl %%edx,%1 \n\t" \ "adcl $0,%2 \n\t" \ - :"=rm"(c0), "=rm"(c1), "=rm"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","%cc"); + :"=rm"(c0), "=rm"(c1), "=rm"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","cc"); //bbox: ^^^ replaced "=r" with "=rm": %ebx is not available on shared build #define SQRADD2(i, j) \ @@ -91,7 +91,7 @@ asm( \ "addl %%eax,%0 \n\t" \ "adcl %%edx,%1 \n\t" \ "adcl $0,%2 \n\t" \ - :"=rm"(c0), "=rm"(c1), "=rm"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); + :"=rm"(c0), "=rm"(c1), "=rm"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","cc"); //bbox: ^^^ replaced "=r" with "=rm": %ebx is not available on shared build #define SQRADDSC(i, j) \ @@ -101,7 +101,7 @@ asm( \ "movl %%eax,%0 \n\t" \ "movl %%edx,%1 \n\t" \ "xorl %2,%2 \n\t" \ - :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","%cc"); + :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","cc"); #define SQRADDAC(i, j) \ asm( \ @@ -110,7 +110,7 @@ asm( \ "addl %%eax,%0 \n\t" \ "adcl %%edx,%1 \n\t" \ "adcl $0,%2 \n\t" \ - :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","%cc"); + :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","cc"); #define SQRADDDB \ asm( \ @@ -120,7 +120,7 @@ asm( \ "addl %6,%0 \n\t" \ "adcl %7,%1 \n\t" \ "adcl %8,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "cc"); /******************************************************************************/ #elif defined(PSTM_X86_64) @@ -223,7 +223,7 @@ asm( \ " ADDS %0,%0,r0 \n\t" \ " ADCS %1,%1,r1 \n\t" \ " ADC %2,%2,#0 \n\t" \ -:"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i) : "r0", "r1", "%cc"); +:"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i) : "r0", "r1", "cc"); /* for squaring some of the terms are doubled... */ #define SQRADD2(i, j) \ @@ -235,13 +235,13 @@ asm( \ " ADDS %0,%0,r0 \n\t" \ " ADCS %1,%1,r1 \n\t" \ " ADC %2,%2,#0 \n\t" \ -:"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "%cc"); +:"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "cc"); #define SQRADDSC(i, j) \ asm( \ " UMULL %0,%1,%6,%7 \n\t" \ " SUB %2,%2,%2 \n\t" \ -:"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "%cc"); +:"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "cc"); #define SQRADDAC(i, j) \ asm( \ @@ -249,7 +249,7 @@ asm( \ " ADDS %0,%0,r0 \n\t" \ " ADCS %1,%1,r1 \n\t" \ " ADC %2,%2,#0 \n\t" \ -:"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "r0", "r1", "%cc"); +:"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "r0", "r1", "cc"); #define SQRADDDB \ asm( \ @@ -259,7 +259,7 @@ asm( \ " ADDS %0,%0,%3 \n\t" \ " ADCS %1,%1,%4 \n\t" \ " ADC %2,%2,%5 \n\t" \ -:"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "%cc"); +:"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "cc"); /******************************************************************************/ #elif defined(PSTM_MIPS) @@ -330,7 +330,7 @@ asm( \ " mflo %0 \n\t" \ " mfhi %1 \n\t" \ " xor %2,%2,%2 \n\t" \ - :"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i),"r"(j) : "%cc"); + :"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i),"r"(j) : "cc"); #define SQRADDAC(i, j) \ asm( \ -- cgit v1.2.3-55-g6feb From 08fb82c80cf06b776822b8388c3863e7c5565a74 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 19 May 2019 15:26:05 +0200 Subject: hush: handle LINENO the same way as RANDOM: variable is "ephemeral" "env - hush" invocation (that is, with empty environment) should not show LINENO in "set" output. function old new delta get_local_var_value 263 294 +31 hush_main 1105 1070 -35 handle_changed_special_names 79 38 -41 run_pipe 1834 1765 -69 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/3 up/down: 31/-145) Total: -114 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 50 ++++++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index e2927afc4..629b7ff92 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -967,8 +967,8 @@ struct globals { smallint we_have_children; #endif #if ENABLE_HUSH_LINENO_VAR - unsigned lineno; - char *lineno_var; + unsigned parse_lineno; + unsigned execute_lineno; #endif HFILE *HFILE_list; /* Which signals have non-DFL handler (even with no traps set)? @@ -2221,6 +2221,10 @@ static const char* FAST_FUNC get_local_var_value(const char *name) if (strcmp(name, "RANDOM") == 0) return utoa(next_random(&G.random_gen)); #endif +#if ENABLE_HUSH_LINENO_VAR + if (strcmp(name, "LINENO") == 0) + return utoa(G.execute_lineno); +#endif #if BASH_EPOCH_VARS { const char *fmt = NULL; @@ -2240,22 +2244,14 @@ static const char* FAST_FUNC get_local_var_value(const char *name) return NULL; } -#if ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS +#if ENABLE_HUSH_GETOPTS static void handle_changed_special_names(const char *name, unsigned name_len) { if (name_len == 6) { -# if ENABLE_HUSH_LINENO_VAR - if (strncmp(name, "LINENO", 6) == 0) { - G.lineno_var = NULL; - return; - } -# endif -# if ENABLE_HUSH_GETOPTS if (strncmp(name, "OPTIND", 6) == 0) { G.getopt_count = 0; return; } -# endif } } #else @@ -2727,8 +2723,8 @@ static int i_getch(struct in_str *i) i->last_char = ch; #if ENABLE_HUSH_LINENO_VAR if (ch == '\n') { - G.lineno++; - debug_printf_parse("G.lineno++ = %u\n", G.lineno); + G.parse_lineno++; + debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno); } #endif return ch; @@ -3730,8 +3726,8 @@ static int done_command(struct parse_context *ctx) clear_and_ret: memset(command, 0, sizeof(*command)); #if ENABLE_HUSH_LINENO_VAR - command->lineno = G.lineno; - debug_printf_parse("command->lineno = G.lineno (%u)\n", G.lineno); + command->lineno = G.parse_lineno; + debug_printf_parse("command->lineno = G.parse_lineno (%u)\n", G.parse_lineno); #endif return pi->num_cmds; /* used only for 0/nonzero check */ } @@ -7261,22 +7257,22 @@ static void parse_and_run_stream(struct in_str *inp, int end_trigger) static void parse_and_run_string(const char *s) { struct in_str input; - //IF_HUSH_LINENO_VAR(unsigned sv = G.lineno;) + //IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) setup_string_in_str(&input, s); parse_and_run_stream(&input, '\0'); - //IF_HUSH_LINENO_VAR(G.lineno = sv;) + //IF_HUSH_LINENO_VAR(G.parse_lineno = sv;) } static void parse_and_run_file(HFILE *fp) { struct in_str input; - IF_HUSH_LINENO_VAR(unsigned sv = G.lineno;) + IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) - IF_HUSH_LINENO_VAR(G.lineno = 1;) + IF_HUSH_LINENO_VAR(G.parse_lineno = 1;) setup_file_in_str(&input, fp); parse_and_run_stream(&input, ';'); - IF_HUSH_LINENO_VAR(G.lineno = sv;) + IF_HUSH_LINENO_VAR(G.parse_lineno = sv;) } #if ENABLE_HUSH_TICK @@ -8975,8 +8971,7 @@ static NOINLINE int run_pipe(struct pipe *pi) struct variable *old_vars; #if ENABLE_HUSH_LINENO_VAR - if (G.lineno_var) - strcpy(G.lineno_var + sizeof("LINENO=")-1, utoa(command->lineno)); + G.execute_lineno = command->lineno; #endif if (argv[command->assignment_cnt] == NULL) { @@ -9209,8 +9204,7 @@ static NOINLINE int run_pipe(struct pipe *pi) xpiped_pair(pipefds); #if ENABLE_HUSH_LINENO_VAR - if (G.lineno_var) - strcpy(G.lineno_var + sizeof("LINENO=")-1, utoa(command->lineno)); + G.execute_lineno = command->lineno; #endif command->pid = BB_MMU ? fork() : vfork(); @@ -9946,14 +9940,6 @@ int hush_main(int argc, char **argv) * PS4='+ ' */ -#if ENABLE_HUSH_LINENO_VAR - if (ENABLE_HUSH_LINENO_VAR) { - char *p = xasprintf("LINENO=%*s", (int)(sizeof(int)*3), ""); - set_local_var(p, /*flags*/ 0); - G.lineno_var = p; /* can't assign before set_local_var("LINENO=...") */ - } -#endif - #if ENABLE_FEATURE_EDITING G.line_input_state = new_line_input_t(FOR_SHELL); #endif -- cgit v1.2.3-55-g6feb From 0c3601936915d3d625683388c62c561de96a47da Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 19 May 2019 15:37:50 +0200 Subject: hush: set default PS1/2 only if we interactive "env - hush SCRIPT" invocation (that is, with empty environment) should not show PS1/2 in "set" output. function old new delta hush_main 1070 1075 +5 Signed-off-by: Denys Vlasenko --- shell/hush.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index 629b7ff92..2b9abbdfd 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -9888,14 +9888,6 @@ int hush_main(int argc, char **argv) /* Export PWD */ set_pwd_var(SETFLAG_EXPORT); -#if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT - /* Set (but not export) PS1/2 unless already set */ - if (!get_local_var_value("PS1")) - set_local_var_from_halves("PS1", "\\w \\$ "); - if (!get_local_var_value("PS2")) - set_local_var_from_halves("PS2", "> "); -#endif - #if BASH_HOSTNAME_VAR /* Set (but not export) HOSTNAME unless already set */ if (!get_local_var_value("HOSTNAME")) { @@ -9907,6 +9899,8 @@ int hush_main(int argc, char **argv) /* IFS is not inherited from the parent environment */ set_local_var_from_halves("IFS", defifs); + /* PS1/PS2 are set later, if we determine that we are interactive */ + /* bash also exports SHLVL and _, * and sets (but doesn't export) the following variables: * BASH=/bin/bash @@ -10278,14 +10272,23 @@ int hush_main(int argc, char **argv) * (--norc turns this off, --rcfile overrides) */ - if (!ENABLE_FEATURE_SH_EXTRA_QUIET && G_interactive_fd) { - /* note: ash and hush share this string */ - printf("\n\n%s %s\n" - IF_HUSH_HELP("Enter 'help' for a list of built-in commands.\n") - "\n", - bb_banner, - "hush - the humble shell" - ); + if (G_interactive_fd) { +#if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT + /* Set (but not export) PS1/2 unless already set */ + if (!get_local_var_value("PS1")) + set_local_var_from_halves("PS1", "\\w \\$ "); + if (!get_local_var_value("PS2")) + set_local_var_from_halves("PS2", "> "); +#endif + if (!ENABLE_FEATURE_SH_EXTRA_QUIET) { + /* note: ash and hush share this string */ + printf("\n\n%s %s\n" + IF_HUSH_HELP("Enter 'help' for a list of built-in commands.\n") + "\n", + bb_banner, + "hush - the humble shell" + ); + } } parse_and_run_file(hfopen(NULL)); /* stdin */ -- cgit v1.2.3-55-g6feb From ef8985c688e9e5e9e8bc29f38d1f05f543c30acb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 19 May 2019 16:29:09 +0200 Subject: hush: implement $-, set default PATH if it is not set on startup function old new delta expand_one_var 2311 2362 +51 hush_main 1075 1104 +29 parse_dollar 790 791 +1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 81/0) Total: 81 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index 2b9abbdfd..9dd893aa6 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -466,9 +466,9 @@ #define JOB_STATUS_FORMAT "[%u] %-22s %.40s\n" -#define _SPECIAL_VARS_STR "_*@$!?#" -#define SPECIAL_VARS_STR ("_*@$!?#" + 1) -#define NUMERIC_SPECVARS_STR ("_*@$!?#" + 3) +#define _SPECIAL_VARS_STR "_*@$!?#-" +#define SPECIAL_VARS_STR ("_*@$!?#-" + 1) +#define NUMERIC_SPECVARS_STR ("_*@$!?#-" + 3) #if BASH_PATTERN_SUBST /* Support / and // replace ops */ /* Note that // is stored as \ in "encoded" string representation */ @@ -1008,6 +1008,7 @@ struct globals { int debug_indent; #endif struct sigaction sa; + char optstring_buf[sizeof("eix")]; #if BASH_EPOCH_VARS char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; #endif @@ -4888,6 +4889,7 @@ static int parse_dollar(o_string *as_string, case '#': /* number of args */ case '*': /* args */ case '@': /* args */ + case '-': /* $- option flags set by set builtin or shell options (-i etc) */ goto make_one_char_var; case '{': { char len_single_ch; @@ -5062,11 +5064,10 @@ static int parse_dollar(o_string *as_string, case '_': goto make_var; #if 0 - /* TODO: $_ and $-: */ + /* TODO: $_: */ /* $_ Shell or shell script name; or last argument of last command * (if last command wasn't a pipe; if it was, bash sets $_ to ""); * but in command's env, set to full pathname used to invoke it */ - /* $- Option flags set by set builtin or shell options (-i etc) */ ch = i_getch(input); nommu_addchr(as_string, ch); ch = i_peek_and_eat_bkslash_nl(input); @@ -6397,6 +6398,23 @@ static NOINLINE int expand_one_var(o_string *output, int n, case '#': /* argc */ val = utoa(G.global_argc ? G.global_argc-1 : 0); break; + case '-': { /* active options */ + /* Check set_mode() to see what option chars we support */ + char *cp; + val = cp = G.optstring_buf; + if (G.o_opt[OPT_O_ERREXIT]) + *cp++ = 'e'; + if (G_interactive_fd) + *cp++ = 'i'; + if (G_x_mode) + *cp++ = 'x'; + /* If G.o_opt[OPT_O_NOEXEC] is true, + * commands read but are not executed, + * so $- can not execute too, 'n' is never seen in $-. + */ + *cp = '\0'; + break; + } default: val = get_local_var_value(var); } @@ -9899,6 +9917,9 @@ int hush_main(int argc, char **argv) /* IFS is not inherited from the parent environment */ set_local_var_from_halves("IFS", defifs); + if (!get_local_var_value("PATH")) + set_local_var_from_halves("PATH", bb_default_root_path); + /* PS1/PS2 are set later, if we determine that we are interactive */ /* bash also exports SHLVL and _, -- cgit v1.2.3-55-g6feb From 30a4c32a4d21728a7e25025f70fcc1d7cd722fe0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 19 May 2019 16:35:56 +0200 Subject: hush: remove test for "echo ${-}" errorring out - now it works Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-vars/param_expand_default.tests | 1 - shell/hush_test/hush-vars/param_expand_default.right | 1 - shell/hush_test/hush-vars/param_expand_default.tests | 2 -- 3 files changed, 4 deletions(-) diff --git a/shell/ash_test/ash-vars/param_expand_default.tests b/shell/ash_test/ash-vars/param_expand_default.tests index b5edfe1c5..dbd3e2218 100755 --- a/shell/ash_test/ash-vars/param_expand_default.tests +++ b/shell/ash_test/ash-vars/param_expand_default.tests @@ -1,6 +1,5 @@ # first try some invalid patterns (do in subshell due to parsing error) # (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) -# valid in bash and ash (same as $-): "$THIS_SH" -c 'echo ${-}' SHELL "$THIS_SH" -c 'echo ${:-}' SHELL # now some funky ones diff --git a/shell/hush_test/hush-vars/param_expand_default.right b/shell/hush_test/hush-vars/param_expand_default.right index dbade3003..8bd0814b0 100644 --- a/shell/hush_test/hush-vars/param_expand_default.right +++ b/shell/hush_test/hush-vars/param_expand_default.right @@ -1,5 +1,4 @@ hush: syntax error: unterminated ${name} -hush: syntax error: unterminated ${name} _0 _0 _ _ _ _word _word _aaaa _aaaa _aaaa _aaaa _aaaa diff --git a/shell/hush_test/hush-vars/param_expand_default.tests b/shell/hush_test/hush-vars/param_expand_default.tests index 754827ab3..dbd3e2218 100755 --- a/shell/hush_test/hush-vars/param_expand_default.tests +++ b/shell/hush_test/hush-vars/param_expand_default.tests @@ -1,7 +1,5 @@ # first try some invalid patterns (do in subshell due to parsing error) # (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) -# valid in bash and ash (same as $-), not supported in hush (yet?): -"$THIS_SH" -c 'echo ${-}' SHELL "$THIS_SH" -c 'echo ${:-}' SHELL # now some funky ones -- cgit v1.2.3-55-g6feb From 9edd268bad93128bcadfbdde28bb978a4b4c5bab Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 19 May 2019 17:23:31 +0200 Subject: shell: implement optional "BASE#nnnn" numeric literals function old new delta evaluate_string 729 851 +122 Signed-off-by: Denys Vlasenko --- shell/Config.src | 5 +++++ shell/math.c | 36 ++++++++++++++++++++++++++++++++++++ shell/math.h | 16 ++++++++++------ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/shell/Config.src b/shell/Config.src index bc7218fe5..d7623f774 100644 --- a/shell/Config.src +++ b/shell/Config.src @@ -99,6 +99,11 @@ config FEATURE_SH_MATH_64 slightly larger, but will allow computation with very large numbers. This is not in POSIX, so do not rely on this in portable code. +config FEATURE_SH_MATH_BASE + bool "Support BASE#nnnn literals" + default y + depends on FEATURE_SH_MATH + config FEATURE_SH_EXTRA_QUIET bool "Hide message on interactive shell startup" default y diff --git a/shell/math.c b/shell/math.c index 611b3beab..2ea0317e9 100644 --- a/shell/math.c +++ b/shell/math.c @@ -513,6 +513,42 @@ static const char op_tokens[] ALIGN1 = { }; #define ptr_to_rparen (&op_tokens[sizeof(op_tokens)-7]) +#if ENABLE_FEATURE_SH_MATH_BASE +static arith_t strto_arith_t(const char *nptr, char **endptr) +{ + unsigned base; + arith_t n; + +# if ENABLE_FEATURE_SH_MATH_64 + n = strtoull(nptr, endptr, 0); +# else + n = strtoul(nptr, endptr, 0); +# endif + if (**endptr != '#' + || (*nptr < '1' || *nptr > '9') + || (n < 2 || n > 64) + ) { + return n; + } + + /* It's "N#nnnn" or "NN#nnnn" syntax, NN can't start with 0, + * NN is in 2..64 range. + */ + base = (unsigned)n; + n = 0; + nptr = *endptr + 1; + /* bash allows "N#" (empty "nnnn" part) */ + while (isdigit(*nptr)) { + /* bash does not check for overflows */ + n = n * base + (*nptr++ - '0'); + } + *endptr = (char*)nptr; + return n; +} +#define strto_arith_t(nptr, endptr, base_is_always_0) \ + strto_arith_t(nptr, endptr) +#endif + static arith_t FAST_FUNC evaluate_string(arith_state_t *math_state, const char *expr) { diff --git a/shell/math.h b/shell/math.h index 2c5ae9b44..ec9decb1f 100644 --- a/shell/math.h +++ b/shell/math.h @@ -65,15 +65,19 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN #if ENABLE_FEATURE_SH_MATH_64 typedef long long arith_t; -#define ARITH_FMT "%lld" -#define strto_arith_t strtoull +# define ARITH_FMT "%lld" #else typedef long arith_t; -#define ARITH_FMT "%ld" -#define strto_arith_t strtoul +# define ARITH_FMT "%ld" +#endif + +#if !ENABLE_FEATURE_SH_MATH_BASE +# if ENABLE_FEATURE_SH_MATH_64 +# define strto_arith_t strtoull +# else +# define strto_arith_t strtoul +# endif #endif -//TODO: bash supports "BASE#nnnnn" numeric literals, e.g. 2#1111 = 15. -//Make strto_arith_t() support that? typedef const char* FAST_FUNC (*arith_var_lookup_t)(const char *name); typedef void FAST_FUNC (*arith_var_set_t)(const char *name, const char *val); -- cgit v1.2.3-55-g6feb From 76a4e8361a84efca256d4286cf36561c42c14d64 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 19 May 2019 18:24:52 +0200 Subject: hush: allocate line edit buffer only for interactive shell function old new delta builtin_history 16 20 +4 Signed-off-by: Denys Vlasenko --- shell/hush.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index 9dd893aa6..4dd940222 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2032,7 +2032,8 @@ static sighandler_t pick_sighandler(unsigned sig) static void hush_exit(int exitcode) { #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT - save_history(G.line_input_state); + if (G.line_input_state) + save_history(G.line_input_state); #endif fflush_all(); @@ -6412,6 +6413,8 @@ static NOINLINE int expand_one_var(o_string *output, int n, * commands read but are not executed, * so $- can not execute too, 'n' is never seen in $-. */ +//TODO: show 'c' if executed via "hush -c 'CMDS'" (bash only, not ash) +//TODO: show 's' if executed via "hush -s ARG1 ARG2", or if there were no args except options (ash does this too) *cp = '\0'; break; } @@ -9955,9 +9958,6 @@ int hush_main(int argc, char **argv) * PS4='+ ' */ -#if ENABLE_FEATURE_EDITING - G.line_input_state = new_line_input_t(FOR_SHELL); -#endif /* Initialize some more globals to non-zero values */ die_func = restore_ttypgrp_and__exit; @@ -10245,6 +10245,9 @@ int hush_main(int argc, char **argv) } enable_restore_tty_pgrp_on_exit(); +# if ENABLE_FEATURE_EDITING + G.line_input_state = new_line_input_t(FOR_SHELL); +# endif # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 { const char *hp = get_local_var_value("HISTFILE"); @@ -10372,7 +10375,8 @@ static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM) #if MAX_HISTORY && ENABLE_FEATURE_EDITING static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM) { - show_history(G.line_input_state); + if (G.line_input_state) + show_history(G.line_input_state); return EXIT_SUCCESS; } #endif -- cgit v1.2.3-55-g6feb From d8740b265a4d4e428b3494089d5a86e1ec90238a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 19 May 2019 19:11:21 +0200 Subject: hush: show 's' in $- function old new delta expand_one_var 2362 2375 +13 hush_main 1104 1108 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 17/0) Total: 17 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index 4dd940222..4b08232a4 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -902,6 +902,7 @@ struct globals { #else # define G_x_mode 0 #endif + char opt_s; #if ENABLE_HUSH_INTERACTIVE smallint promptmode; /* 0: PS1, 1: PS2 */ #endif @@ -1008,7 +1009,7 @@ struct globals { int debug_indent; #endif struct sigaction sa; - char optstring_buf[sizeof("eix")]; + char optstring_buf[sizeof("eixs")]; #if BASH_EPOCH_VARS char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; #endif @@ -6413,8 +6414,9 @@ static NOINLINE int expand_one_var(o_string *output, int n, * commands read but are not executed, * so $- can not execute too, 'n' is never seen in $-. */ + if (G.opt_s) + *cp++ = 's'; //TODO: show 'c' if executed via "hush -c 'CMDS'" (bash only, not ash) -//TODO: show 's' if executed via "hush -s ARG1 ARG2", or if there were no args except options (ash does this too) *cp = '\0'; break; } @@ -9958,7 +9960,6 @@ int hush_main(int argc, char **argv) * PS4='+ ' */ - /* Initialize some more globals to non-zero values */ die_func = restore_ttypgrp_and__exit; @@ -10177,6 +10178,7 @@ int hush_main(int argc, char **argv) #endif goto final_return; } + G.opt_s = 1; /* Up to here, shell was non-interactive. Now it may become one. * NB: don't forget to (re)run install_special_sighandlers() as needed. -- cgit v1.2.3-55-g6feb From 831844c13931f14bd0433c1eb848c863288a8c06 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 21 May 2019 16:06:34 +0200 Subject: udhcpd: fix printing of static leases function old new delta read_staticlease 299 282 -17 Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpd.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 3d60abf8f..058f86bca 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -66,13 +66,14 @@ static void add_static_lease(struct static_lease **st_lease_pp, struct static_lease *st_lease; unsigned optlen; + optlen = (opts ? 1+1+strnlen(opts, 120) : 0); + /* Find the tail of the list */ while ((st_lease = *st_lease_pp) != NULL) { st_lease_pp = &st_lease->next; } /* Add new node */ - optlen = (opts ? 1+1+strnlen(opts, 120) : 0); *st_lease_pp = st_lease = xzalloc(sizeof(*st_lease) + optlen); memcpy(st_lease->mac, mac, 6); st_lease->nip = nip; @@ -83,6 +84,17 @@ static void add_static_lease(struct static_lease **st_lease_pp, st_lease->opt[OPT_LEN] = optlen; memcpy(&st_lease->opt[OPT_DATA], opts, optlen); } + +#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 + /* Print out static leases just to check what's going on */ + if (dhcp_verbose >= 2) { + bb_info_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", + st_lease->mac[0], st_lease->mac[1], st_lease->mac[2], + st_lease->mac[3], st_lease->mac[4], st_lease->mac[5], + st_lease->nip + ); + } +#endif } /* Find static lease IP by mac */ @@ -112,30 +124,6 @@ static int is_nip_reserved_as_static(uint32_t nip) return 0; } -#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 -/* Print out static leases just to check what's going on */ -/* Takes the address of the pointer to the static_leases linked list */ -static void log_static_leases(struct static_lease **st_lease_pp) -{ - struct static_lease *cur; - - if (dhcp_verbose < 2) - return; - - cur = *st_lease_pp; - while (cur) { - bb_info_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", - cur->mac[0], cur->mac[1], cur->mac[2], - cur->mac[3], cur->mac[4], cur->mac[5], - cur->nip - ); - cur = cur->next; - } -} -#else -# define log_static_leases(st_lease_pp) ((void)0) -#endif - /* Find the oldest expired lease, NULL if there are no expired leases */ static struct dyn_lease *oldest_expired_lease(void) { @@ -380,8 +368,6 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg) add_static_lease(arg, (uint8_t*) &mac_bytes, nip, opts); - log_static_leases(arg); - return 1; } -- cgit v1.2.3-55-g6feb From 84fc645605827d53aa3e749dfff309978b1bc73d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 21 May 2019 17:29:24 +0200 Subject: *: slap on a few ALIGN1/2s where appropriate The result of looking at "grep -F -B2 '*fill*' busybox_unstripped.map" text data bss dec hex filename 952537 485 7296 960318 ea73e busybox_old 952527 485 7296 960308 ea734 busybox_unstripped Signed-off-by: Denys Vlasenko --- networking/libiproute/ll_proto.c | 2 +- networking/tls.c | 6 +++--- networking/tls_aes.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/networking/libiproute/ll_proto.c b/networking/libiproute/ll_proto.c index 7d46221ac..611e0a2c9 100644 --- a/networking/libiproute/ll_proto.c +++ b/networking/libiproute/ll_proto.c @@ -15,7 +15,7 @@ /* Please conditionalize exotic protocols on CONFIG_something */ -static const uint16_t llproto_ids[] = { +static const uint16_t llproto_ids[] ALIGN2 = { #define __PF(f,n) ETH_P_##f, __PF(LOOP,loop) __PF(PUP,pup) diff --git a/networking/tls.c b/networking/tls.c index db0034e66..db7be07f3 100644 --- a/networking/tls.c +++ b/networking/tls.c @@ -1387,12 +1387,12 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len) /* enter subjectPublicKeyInfo */ der = enter_der_item(der, &end); { /* check subjectPublicKeyInfo.algorithm */ - static const uint8_t OID_RSA_KEY_ALG[] = { + static const uint8_t OID_RSA_KEY_ALG[] ALIGN1 = { 0x30,0x0d, // SEQ 13 bytes 0x06,0x09, 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01, //OID_RSA_KEY_ALG 42.134.72.134.247.13.1.1.1 //0x05,0x00, // NULL }; - static const uint8_t OID_ECDSA_KEY_ALG[] = { + static const uint8_t OID_ECDSA_KEY_ALG[] ALIGN1 = { 0x30,0x13, // SEQ 0x13 bytes 0x06,0x07, 0x2a,0x86,0x48,0xce,0x3d,0x02,0x01, //OID_ECDSA_KEY_ALG 42.134.72.206.61.2.1 //allow any curve code for now... @@ -2083,7 +2083,7 @@ static void send_client_key_exchange(tls_state_t *tls) } } -static const uint8_t rec_CHANGE_CIPHER_SPEC[] = { +static const uint8_t rec_CHANGE_CIPHER_SPEC[] ALIGN1 = { RECORD_TYPE_CHANGE_CIPHER_SPEC, TLS_MAJ, TLS_MIN, 00, 01, 01 }; diff --git a/networking/tls_aes.c b/networking/tls_aes.c index cf6b5fe3d..5400ad9b5 100644 --- a/networking/tls_aes.c +++ b/networking/tls_aes.c @@ -130,7 +130,7 @@ static int KeyExpansion(uint32_t *RoundKey, const void *key, unsigned key_len) // The round constant word array, Rcon[i], contains the values given by // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8). // Note that i starts at 2, not 0. - static const uint8_t Rcon[] = { + static const uint8_t Rcon[] ALIGN1 = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 //..... 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6,... // but aes256 only uses values up to 0x36 -- cgit v1.2.3-55-g6feb From 028c5aa18b5273c029f0278232d922ee1a164de6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 22 May 2019 13:54:46 +0200 Subject: ip: use rtnl_send_check() on flush commands, closes 6962 function old new delta rtnl_send_check - 160 +160 xrtnl_wilddump_request 64 66 +2 ipneigh_list_or_flush 714 706 -8 rtnl_send 69 - -69 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 1/1 up/down: 162/-77) Total: 85 bytes Signed-off-by: Denys Vlasenko --- networking/libiproute/ipaddress.c | 6 ++++-- networking/libiproute/ipneigh.c | 9 ++++---- networking/libiproute/iproute.c | 5 ++++- networking/libiproute/libnetlink.c | 43 +++++++++++++++++++++++++++++++------- networking/libiproute/libnetlink.h | 19 +++++++++++++++-- 5 files changed, 65 insertions(+), 17 deletions(-) diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index fc6a4fb77..7b7e0154b 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -23,6 +23,7 @@ struct filter_t { char *label; + /* Flush cmd buf. If !NULL, print_addrinfo() constructs flush commands in it */ char *flushb; struct rtnl_handle *rth; int scope, scopemask; @@ -34,6 +35,8 @@ struct filter_t { smallint showqueue; smallint oneline; smallint up; + /* Misnomer. Does not mean "flushed something" */ + /* More like "flush commands were constructed by print_addrinfo()" */ smallint flushed; inet_prefix pfx; } FIX_ALIASING; @@ -201,7 +204,7 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n) static int flush_update(void) { - if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { + if (rtnl_send_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { bb_perror_msg("can't send flush request"); return -1; } @@ -510,7 +513,6 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush) xrtnl_dump_filter(&rth, store_nlmsg, &ainfo); } - if (G_filter.family && G_filter.family != AF_PACKET) { struct nlmsg_list **lp; lp = &linfo; diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c index f572414e9..984dd4bdd 100644 --- a/networking/libiproute/ipneigh.c +++ b/networking/libiproute/ipneigh.c @@ -32,7 +32,10 @@ struct filter_t { int state; int unused_only; inet_prefix pfx; + /* Misnomer. Does not mean "flushed N something" */ + /* More like "no_of_flush_commands_constructed_by_print_neigh()" */ int flushed; + /* Flush cmd buf. If !NULL, print_neigh() constructs flush commands in it */ char *flushb; int flushp; int flushe; @@ -45,7 +48,7 @@ typedef struct filter_t filter_t; static int flush_update(void) { - if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { + if (rtnl_send_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { bb_perror_msg("can't send flush request"); return -1; } @@ -299,9 +302,7 @@ static int FAST_FUNC ipneigh_list_or_flush(char **argv, int flush) G_filter.rth = &rth; while (round < MAX_ROUNDS) { - if (xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETNEIGH) < 0) { - bb_perror_msg_and_die("can't send dump request"); - } + xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETNEIGH); G_filter.flushed = 0; if (xrtnl_dump_filter(&rth, print_neigh, NULL) < 0) { bb_perror_msg_and_die("flush terminated"); diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 2a8610ea6..b11078ed5 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -26,7 +26,10 @@ struct filter_t { int tb; + /* Misnomer. Does not mean "flushed something" */ + /* More like "flush commands were constructed by print_route()" */ smallint flushed; + /* Flush cmd buf. If !NULL, print_route() constructs flush commands in it */ char *flushb; int flushp; int flushe; @@ -53,7 +56,7 @@ typedef struct filter_t filter_t; static int flush_update(void) { - if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { + if (rtnl_send_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { bb_perror_msg("can't send flush request"); return -1; } diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c index 40955fcae..b0d4166ac 100644 --- a/networking/libiproute/libnetlink.c +++ b/networking/libiproute/libnetlink.c @@ -34,7 +34,7 @@ void FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/) rth->seq = time(NULL); } -int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) +void FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) { struct { struct nlmsghdr nlh; @@ -48,18 +48,45 @@ int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int ty req.nlh.nlmsg_seq = rth->dump = ++rth->seq; req.g.rtgen_family = family; - return rtnl_send(rth, (void*)&req, sizeof(req)); + rtnl_send(rth, (void*)&req, sizeof(req)); } -//TODO: pass rth->fd instead of full rth? -int FAST_FUNC rtnl_send(struct rtnl_handle *rth, char *buf, int len) +/* A version which checks for e.g. EPERM errors. + * Try: setuidgid 1:1 ip addr flush dev eth0 + */ +int FAST_FUNC rtnl_send_check(struct rtnl_handle *rth, const void *buf, int len) { - struct sockaddr_nl nladdr; + struct nlmsghdr *h; + int status; + char resp[1024]; - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; + status = write(rth->fd, buf, len); + if (status < 0) + return status; + + /* Check for immediate errors */ + status = recv(rth->fd, resp, sizeof(resp), MSG_DONTWAIT|MSG_PEEK); + if (status < 0) { + if (errno == EAGAIN) /* if no error, this happens */ + return 0; + return -1; + } - return xsendto(rth->fd, buf, len, (struct sockaddr*)&nladdr, sizeof(nladdr)); + for (h = (struct nlmsghdr *)resp; + NLMSG_OK(h, status); + h = NLMSG_NEXT(h, status) + ) { + if (h->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); + if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) + bb_error_msg("ERROR truncated"); + else + errno = -err->error; + return -1; + } + } + + return 0; } int FAST_FUNC rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) diff --git a/networking/libiproute/libnetlink.h b/networking/libiproute/libnetlink.h index 51bee2d67..1b082e019 100644 --- a/networking/libiproute/libnetlink.h +++ b/networking/libiproute/libnetlink.h @@ -20,7 +20,7 @@ struct rtnl_handle { extern void xrtnl_open(struct rtnl_handle *rth) FAST_FUNC; #define rtnl_close(rth) (close((rth)->fd)) -extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type) FAST_FUNC; +extern void xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type) FAST_FUNC; extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) FAST_FUNC; extern int xrtnl_dump_filter(struct rtnl_handle *rth, int (*filter)(const struct sockaddr_nl*, struct nlmsghdr *n, void*) FAST_FUNC, @@ -34,8 +34,23 @@ extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), void *jarg) FAST_FUNC; -extern int rtnl_send(struct rtnl_handle *rth, char *buf, int) FAST_FUNC; +int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int len) FAST_FUNC; +//TODO: pass rth->fd instead of full rth? +static ALWAYS_INLINE void rtnl_send(struct rtnl_handle *rth, const void *buf, int len) +{ + // Used to be: + //struct sockaddr_nl nladdr; + //memset(&nladdr, 0, sizeof(nladdr)); + //nladdr.nl_family = AF_NETLINK; + //return xsendto(rth->fd, buf, len, (struct sockaddr*)&nladdr, sizeof(nladdr)); + // iproute2-4.2.0 simplified the above to: + //return send(rth->fd, buf, len, 0); + + // We are using even shorter: + xwrite(rth->fd, buf, len); + // and convert to void, inline. +} extern int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data) FAST_FUNC; extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) FAST_FUNC; -- cgit v1.2.3-55-g6feb From 58d998d2f927c20f2ba728611df587ac8ec8bda9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 23 May 2019 14:54:13 +0200 Subject: bunzip2: the correct condition is "n < groupCount", not "n <= groupCount". Closes 11896 function old new delta get_next_block 1677 1681 +4 Signed-off-by: Denys Vlasenko --- archival/libarchive/decompress_bunzip2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index 78366f26a..1f535b32a 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c @@ -235,9 +235,9 @@ static int get_next_block(bunzip_data *bd) /* Get next value */ int n = 0; while (get_bits(bd, 1)) { + n++; if (n >= groupCount) return RETVAL_DATA_ERROR; - n++; } /* Decode MTF to get the next selector */ tmp_byte = mtfSymbol[n]; -- cgit v1.2.3-55-g6feb From 1115e40c887fc4d9ddddbe2b0d71c091065ee997 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 23 May 2019 15:24:03 +0200 Subject: dhcp: tweak comments, no code changes Signed-off-by: Denys Vlasenko --- networking/udhcp/common.h | 52 ++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index a897837f9..bba3d6037 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -40,7 +40,7 @@ struct dhcp_packet { uint32_t yiaddr; /* 'your' (client) IP address */ /* IP address of next server to use in bootstrap, returned in DHCPOFFER, DHCPACK by server */ uint32_t siaddr_nip; - uint32_t gateway_nip; /* relay agent IP address */ + uint32_t gateway_nip; /* aka 'giaddr': relay agent IP address */ uint8_t chaddr[16]; /* link-layer client hardware address (MAC) */ uint8_t sname[64]; /* server host name (ASCIZ) */ uint8_t file[128]; /* boot file name (ASCIZ) */ @@ -222,10 +222,9 @@ uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) #endif struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) FAST_FUNC; - // RFC 2131 Table 5: Fields and options used by DHCP clients // -// Fields 'hops', 'yiaddr', 'siaddr', 'giaddr' are always zero +// Fields 'hops', 'yiaddr', 'siaddr', 'giaddr' are always zero, 'chaddr' is always client's MAC // // Field DHCPDISCOVER DHCPINFORM DHCPREQUEST DHCPDECLINE DHCPRELEASE // ----- ------------ ------------ ----------- ----------- ----------- @@ -234,40 +233,33 @@ struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) // 'secs' 0 or seconds since 0 or seconds since 0 or seconds since 0 0 // DHCP process started DHCP process started DHCP process started // 'flags' Set 'BROADCAST' Set 'BROADCAST' Set 'BROADCAST' 0 0 -// flag if client flag if client flag if client -// requires broadcast requires broadcast requires broadcast -// reply reply reply +// flag if client needs flag if client needs flag if client needs +// broadcast reply broadcast reply broadcast reply // 'ciaddr' 0 client's IP 0 or client's IP 0 client's IP // (BOUND/RENEW/REBIND) -// 'chaddr' client's MAC client's MAC client's MAC client's MAC client's MAC // 'sname' options or sname options or sname options or sname (unused) (unused) // 'file' options or file options or file options or file (unused) (unused) // 'options' options options options message type opt message type opt // -// Option DHCPDISCOVER DHCPINFORM DHCPREQUEST DHCPDECLINE DHCPRELEASE -// ------ ------------ ---------- ----------- ----------- ----------- -// Requested IP address MAY MUST NOT MUST (in MUST MUST NOT -// SELECTING or -// INIT-REBOOT) -// MUST NOT (in -// BOUND or -// RENEWING) -// IP address lease time MAY MUST NOT MAY MUST NOT MUST NOT -// Use 'file'/'sname' fields MAY MAY MAY MAY MAY -// Client identifier MAY MAY MAY MAY MAY -// Vendor class identifier MAY MAY MAY MUST NOT MUST NOT -// Server identifier MUST NOT MUST NOT MUST (after MUST MUST -// SELECTING) +// Option DHCPDISCOVER DHCPINFORM DHCPREQUEST DHCPDECLINE DHCPRELEASE +// ------ ------------ ---------- ----------- ----------- ----------- +// Requested IP address MAY MUST NOT MUST (in SELECTING MUST MUST NOT +// or INIT-REBOOT) +// MUST NOT (in BOUND +// or RENEWING) +// IP address lease time MAY MUST NOT MAY MUST NOT MUST NOT +// Use 'file'/'sname' fields MAY MAY MAY MAY MAY +// Client identifier MAY MAY MAY MAY MAY +// Vendor class identifier MAY MAY MAY MUST NOT MUST NOT +// Server identifier MUST NOT MUST NOT MUST (after SELECTING) MUST MUST // MUST NOT (after -// INIT-REBOOT, -// BOUND, RENEWING -// or REBINDING) -// Parameter request list MAY MAY MAY MUST NOT MUST NOT -// Maximum message size MAY MAY MAY MUST NOT MUST NOT -// Message SHOULD NOT SHOULD NOT SHOULD NOT SHOULD SHOULD -// Site-specific MAY MAY MAY MUST NOT MUST NOT -// All others MAY MAY MAY MUST NOT MUST NOT - +// INIT-REBOOT, BOUND, +// RENEWING or REBINDING) +// Parameter request list MAY MAY MAY MUST NOT MUST NOT +// Maximum message size MAY MAY MAY MUST NOT MUST NOT +// Message SHOULD NOT SHOULD NOT SHOULD NOT SHOULD SHOULD +// Site-specific MAY MAY MAY MUST NOT MUST NOT +// All others MAY MAY MAY MUST NOT MUST NOT /*** Logging ***/ -- cgit v1.2.3-55-g6feb From 309f5e3775ed9cc0837c6d93482735bc4f117d5b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 23 May 2019 16:11:42 +0200 Subject: losetup: implement -c function old new delta losetup_main 422 449 +27 packed_usage 33243 33264 +21 get_next_block 1677 1681 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 52/0) Total: 52 bytes Signed-off-by: Denys Vlasenko --- util-linux/losetup.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/util-linux/losetup.c b/util-linux/losetup.c index bf480e9bf..2248f2cba 100644 --- a/util-linux/losetup.c +++ b/util-linux/losetup.c @@ -20,10 +20,11 @@ //kbuild:lib-$(CONFIG_LOSETUP) += losetup.o //usage:#define losetup_trivial_usage -//usage: "[-r] [-o OFS] {-f|LOOPDEV} FILE - associate loop devices\n" -//usage: " losetup -d LOOPDEV - disassociate\n" -//usage: " losetup -a - show status\n" -//usage: " losetup -f - show next free loop device" +//usage: "[-r] [-o OFS] {-f|LOOPDEV} FILE: associate loop devices\n" +//usage: " losetup -c LOOPDEV: reread file size\n" +//usage: " losetup -d LOOPDEV: disassociate\n" +//usage: " losetup -a: show status\n" +//usage: " losetup -f: show next free loop device" //usage:#define losetup_full_usage "\n\n" //usage: " -o OFS Start OFS bytes into FILE" //usage: "\n -r Read-only" @@ -50,14 +51,15 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) char *opt_o; char dev[LOOP_NAMESIZE]; enum { - OPT_d = (1 << 0), - OPT_o = (1 << 1), - OPT_f = (1 << 2), - OPT_a = (1 << 3), - OPT_r = (1 << 4), /* must be last */ + OPT_c = (1 << 0), + OPT_d = (1 << 1), + OPT_o = (1 << 2), + OPT_f = (1 << 3), + OPT_a = (1 << 4), + OPT_r = (1 << 5), }; - opt = getopt32(argv, "^" "do:far" "\0" "?2:d--ofar:a--ofr", &opt_o); + opt = getopt32(argv, "^" "cdo:far" "\0" "?2:d--ofar:a--ofr", &opt_o); argv += optind; /* LOOPDEV */ @@ -73,6 +75,16 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) return EXIT_SUCCESS; } + /* -c LOOPDEV */ + if (opt == OPT_c && argv[0]) { + int fd = xopen(argv[0], O_RDONLY); +#ifndef LOOP_SET_CAPACITY +# define LOOP_SET_CAPACITY 0x4C07 +#endif + xioctl(fd, LOOP_SET_CAPACITY, /*ignored:*/0); + return EXIT_SUCCESS; + } + /* -d LOOPDEV */ if (opt == OPT_d && argv[0]) { if (del_loop(argv[0])) -- cgit v1.2.3-55-g6feb From dff2bd733fc2dac08d34f2cfad0e68aeb8e7a7a2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 24 May 2019 17:03:28 +0200 Subject: libarchive: treat one "FIXME: avoid seek" function old new delta xmalloc_read_with_initial_buf - 205 +205 setup_transformer_on_fd 154 150 -4 xmalloc_open_zipped_read_close 143 135 -8 xmalloc_read 201 10 -191 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/3 up/down: 205/-203) Total: 2 bytes Signed-off-by: Denys Vlasenko --- archival/libarchive/open_transformer.c | 44 +++++++++++++++++++++------------- include/bb_archive.h | 6 +++++ include/libbb.h | 1 + libbb/read_printf.c | 12 ++++++---- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 4a4bf3916..97bcc32f0 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -159,47 +159,44 @@ void FAST_FUNC fork_transformer(int fd, const char *transform_prog) */ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed) { - union { - uint8_t b[4]; - uint16_t b16[2]; - uint32_t b32[1]; - } magic; transformer_state_t *xstate; xstate = xzalloc(sizeof(*xstate)); xstate->src_fd = fd; - xstate->signature_skipped = 2; /* .gz and .bz2 both have 2-byte signature, and their * unpack_XXX_stream wants this header skipped. */ - xread(fd, magic.b16, sizeof(magic.b16[0])); + xstate->signature_skipped = 2; + xread(fd, xstate->magic.b16, 2); if (ENABLE_FEATURE_SEAMLESS_GZ - && magic.b16[0] == GZIP_MAGIC + && xstate->magic.b16[0] == GZIP_MAGIC ) { xstate->xformer = unpack_gz_stream; USE_FOR_NOMMU(xstate->xformer_prog = "gunzip";) goto found_magic; } if (ENABLE_FEATURE_SEAMLESS_Z - && magic.b16[0] == COMPRESS_MAGIC + && xstate->magic.b16[0] == COMPRESS_MAGIC ) { xstate->xformer = unpack_Z_stream; USE_FOR_NOMMU(xstate->xformer_prog = "uncompress";) goto found_magic; } if (ENABLE_FEATURE_SEAMLESS_BZ2 - && magic.b16[0] == BZIP2_MAGIC + && xstate->magic.b16[0] == BZIP2_MAGIC ) { xstate->xformer = unpack_bz2_stream; USE_FOR_NOMMU(xstate->xformer_prog = "bunzip2";) goto found_magic; } if (ENABLE_FEATURE_SEAMLESS_XZ - && magic.b16[0] == XZ_MAGIC1 + && xstate->magic.b16[0] == XZ_MAGIC1 ) { + uint32_t v32; xstate->signature_skipped = 6; - xread(fd, magic.b32, sizeof(magic.b32[0])); - if (magic.b32[0] == XZ_MAGIC2) { + xread(fd, &xstate->magic.b16[1], 4); + move_from_unaligned32(v32, &xstate->magic.b16[1]); + if (v32 == XZ_MAGIC2) { xstate->xformer = unpack_xz_stream; USE_FOR_NOMMU(xstate->xformer_prog = "unxz";) goto found_magic; @@ -344,11 +341,24 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ *maxsz_p = xstate->mem_output_size; } } else { - /* File is not compressed */ -//FIXME: avoid seek - xlseek(xstate->src_fd, - xstate->signature_skipped, SEEK_CUR); + /* File is not compressed. + * We already read first few bytes, account for that. + * Exmaple where it happens: + * "modinfo MODULE.ko" (not compressed) + * open("MODULE.ko", O_RDONLY|O_LARGEFILE) = 4 + * read(4, "\177E", 2) = 2 + * fstat64(4, ...) + * mmap(...) + * read(4, "LF\2\1\1\0\0\0\0"... + * ...and we avoided seeking on the fd! :) + */ xstate->signature_skipped = 0; - image = xmalloc_read(xstate->src_fd, maxsz_p); + image = xmalloc_read_with_initial_buf( + xstate->src_fd, + maxsz_p, + xmemdup(&xstate->magic, xstate->signature_skipped), + xstate->signature_skipped + ); } if (!image) diff --git a/include/bb_archive.h b/include/bb_archive.h index 561dd0c9d..9b1db5b3e 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h @@ -235,6 +235,12 @@ typedef struct transformer_state_t { off_t bytes_in; /* used in unzip code only: needs to know packed size */ uint32_t crc32; time_t mtime; /* gunzip code may set this on exit */ + + union { /* if we read magic, it's saved here */ + uint8_t b[8]; + uint16_t b16[4]; + uint32_t b32[2]; + } magic; } transformer_state_t; void init_transformer_state(transformer_state_t *xstate) FAST_FUNC; diff --git a/include/libbb.h b/include/libbb.h index 57cfce385..33766e989 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -881,6 +881,7 @@ extern ssize_t open_read_close(const char *filename, void *buf, size_t maxsz) FA extern char *xmalloc_reads(int fd, size_t *maxsz_p) FAST_FUNC; /* Reads block up to *maxsz_p (default: INT_MAX - 4095) */ extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; +extern void *xmalloc_read_with_initial_buf(int fd, size_t *maxsz_p, char *buf, size_t total) FAST_FUNC; /* Returns NULL if file can't be opened (default max size: INT_MAX - 4095) */ extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; /* Never returns NULL */ diff --git a/libbb/read_printf.c b/libbb/read_printf.c index b6a17cc36..cb582c080 100644 --- a/libbb/read_printf.c +++ b/libbb/read_printf.c @@ -102,10 +102,9 @@ char* FAST_FUNC xmalloc_reads(int fd, size_t *maxsz_p) // Read (potentially big) files in one go. File size is estimated // by stat. Extra '\0' byte is appended. -void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p) +void* FAST_FUNC xmalloc_read_with_initial_buf(int fd, size_t *maxsz_p, char *buf, size_t total) { - char *buf; - size_t size, rd_size, total; + size_t size, rd_size; size_t to_read; struct stat st; @@ -118,8 +117,6 @@ void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p) /* In order to make such files readable, we add small const */ size = (st.st_size | 0x3ff) + 1; - total = 0; - buf = NULL; while (1) { if (to_read < size) size = to_read; @@ -148,6 +145,11 @@ void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p) return buf; } +void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p) +{ + return xmalloc_read_with_initial_buf(fd, maxsz_p, NULL, 0); +} + #ifdef USING_LSEEK_TO_GET_SIZE /* Alternatively, file size can be obtained by lseek to the end. * The code is slightly bigger. Retained in case fstat approach -- cgit v1.2.3-55-g6feb From a4ed2c45b905057108e41aceda10c8b7976534ed Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 26 May 2019 13:05:04 +0200 Subject: dhcp: get rid of last global data function old new delta udhcpc_main 2680 2684 +4 state 1 - -1 listen_mode 1 - -1 sockfd 4 - -4 ------------------------------------------------------------------------------ (add/remove: 0/3 grow/shrink: 1/0 up/down: 4/-6) Total: -2 bytes Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_dhcpc.c | 77 +++++++++++++++++++++--------------------- networking/udhcp/dhcpc.c | 81 ++++++++++++++++++++++----------------------- networking/udhcp/dhcpc.h | 4 +++ 3 files changed, 82 insertions(+), 80 deletions(-) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 6cc2316c4..1973af99b 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -903,13 +903,12 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_pac /*** Main ***/ -static int sockfd = -1; - +/* Values for client_config.listen_mode */ #define LISTEN_NONE 0 #define LISTEN_KERNEL 1 #define LISTEN_RAW 2 -static smallint listen_mode; +/* Values for client_config.state */ /* initial state: (re)start DHCP negotiation */ #define INIT_SELECTING 0 /* discover was sent, DHCPOFFER reply received */ @@ -924,7 +923,6 @@ static smallint listen_mode; #define RENEW_REQUESTED 5 /* release, possibly manually requested (SIGUSR2) */ #define RELEASED 6 -static smallint state; static int d6_raw_socket(int ifindex) { @@ -1018,35 +1016,35 @@ static void change_listen_mode(int new_mode) : "none" ); - listen_mode = new_mode; - if (sockfd >= 0) { - close(sockfd); - sockfd = -1; + client_config.listen_mode = new_mode; + if (client_config.sockfd >= 0) { + close(client_config.sockfd); + client_config.sockfd = -1; } if (new_mode == LISTEN_KERNEL) - sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT6, client_config.interface); + client_config.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT6, client_config.interface); else if (new_mode != LISTEN_NONE) - sockfd = d6_raw_socket(client_config.ifindex); - /* else LISTEN_NONE: sockfd stays closed */ + client_config.sockfd = d6_raw_socket(client_config.ifindex); + /* else LISTEN_NONE: client_config.sockfd stays closed */ } /* Called only on SIGUSR1 */ static void perform_renew(void) { bb_info_msg("performing DHCP renew"); - switch (state) { + switch (client_config.state) { case BOUND: change_listen_mode(LISTEN_KERNEL); case RENEWING: case REBINDING: - state = RENEW_REQUESTED; + client_config.state = RENEW_REQUESTED; break; case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ d6_run_script_no_option("deconfig"); case REQUESTING: case RELEASED: change_listen_mode(LISTEN_RAW); - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; break; case INIT_SELECTING: break; @@ -1056,10 +1054,10 @@ static void perform_renew(void) static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) { /* send release packet */ - if (state == BOUND - || state == RENEWING - || state == REBINDING - || state == RENEW_REQUESTED + if (client_config.state == BOUND + || client_config.state == RENEWING + || client_config.state == REBINDING + || client_config.state == RENEW_REQUESTED ) { bb_info_msg("unicasting a release"); send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ @@ -1073,7 +1071,7 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou */ d6_run_script_no_option("deconfig"); change_listen_mode(LISTEN_NONE); - state = RELEASED; + client_config.state = RELEASED; } ///static uint8_t* alloc_dhcp_option(int code, const char *str, int extra) @@ -1174,6 +1172,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;) client_config.interface = "eth0"; client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; + client_config.sockfd = -1; /* Parse command line */ opt = getopt32long(argv, "^" @@ -1278,7 +1277,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* Set up the signal pipe */ udhcp_sp_setup(); - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; d6_run_script_no_option("deconfig"); change_listen_mode(LISTEN_RAW); packet_num = 0; @@ -1297,16 +1296,16 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* silence "uninitialized!" warning */ unsigned timestamp_before_wait = timestamp_before_wait; - //bb_error_msg("sockfd:%d, listen_mode:%d", sockfd, listen_mode); + //bb_error_msg("sockfd:%d, listen_mode:%d", client_config.sockfd, client_config.listen_mode); /* Was opening raw or udp socket here - * if (listen_mode != LISTEN_NONE && sockfd < 0), + * if (client_config.listen_mode != LISTEN_NONE && client_config.sockfd < 0), * but on fast network renew responses return faster * than we open sockets. Thus this code is moved * to change_listen_mode(). Thus we open listen socket * BEFORE we send renew request (see "case BOUND:"). */ - udhcp_sp_fd_set(pfds, sockfd); + udhcp_sp_fd_set(pfds, client_config.sockfd); tv = timeout - already_waited_sec; retval = 0; @@ -1348,7 +1347,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* We will restart the wait in any case */ already_waited_sec = 0; - switch (state) { + switch (client_config.state) { case INIT_SELECTING: if (!discover_retries || packet_num < discover_retries) { if (packet_num == 0) @@ -1397,11 +1396,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) * were seen in the wild. Treat them similarly * to "no response to discover" case */ change_listen_mode(LISTEN_RAW); - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; goto leasefail; case BOUND: /* 1/2 lease passed, enter renewing state */ - state = RENEWING; + client_config.state = RENEWING; client_config.first_secs = 0; /* make secs field count from 0 */ change_listen_mode(LISTEN_KERNEL); log1("entering renew state"); @@ -1425,7 +1424,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) } /* Timed out, enter rebinding state */ log1("entering rebinding state"); - state = REBINDING; + client_config.state = REBINDING; /* fall right through */ case REBINDING: /* Switch to bcast receive */ @@ -1441,7 +1440,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* Timed out, enter init state */ bb_info_msg("lease lost, entering init state"); d6_run_script_no_option("deconfig"); - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ /*timeout = 0; - already is */ packet_num = 0; @@ -1461,7 +1460,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) client_config.first_secs = 0; /* make secs field count from 0 */ already_waited_sec = 0; perform_renew(); - if (state == RENEW_REQUESTED) { + if (client_config.state == RENEW_REQUESTED) { /* We might be either on the same network * (in which case renew might work), * or we might be on a completely different one @@ -1496,15 +1495,15 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) int len; /* A packet is ready, read it */ - if (listen_mode == LISTEN_KERNEL) - len = d6_recv_kernel_packet(&srv6_buf, &packet, sockfd); + if (client_config.listen_mode == LISTEN_KERNEL) + len = d6_recv_kernel_packet(&srv6_buf, &packet, client_config.sockfd); else - len = d6_recv_raw_packet(&srv6_buf, &packet, sockfd); + len = d6_recv_raw_packet(&srv6_buf, &packet, client_config.sockfd); if (len == -1) { /* Error is severe, reopen socket */ bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO); sleep(discover_timeout); /* 3 seconds by default */ - change_listen_mode(listen_mode); /* just close and reopen */ + change_listen_mode(client_config.listen_mode); /* just close and reopen */ } /* If this packet will turn out to be unrelated/bogus, * we will go back and wait for next one. @@ -1521,7 +1520,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) continue; } - switch (state) { + switch (client_config.state) { case INIT_SELECTING: if (packet.d6_msg_type == D6_MSG_ADVERTISE) goto type_is_ok; @@ -1547,11 +1546,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) bb_info_msg("received DHCP NAK (%u)", option->data[4]); d6_run_script(packet.d6_options, packet_end, "nak"); - if (state != REQUESTING) + if (client_config.state != REQUESTING) d6_run_script_no_option("deconfig"); change_listen_mode(LISTEN_RAW); sleep(3); /* avoid excessive network traffic */ - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ requested_ipv6 = NULL; timeout = 0; @@ -1572,7 +1571,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) client6_data.server_id = option; if (packet.d6_msg_type == D6_MSG_ADVERTISE) { /* enter requesting state */ - state = REQUESTING; + client_config.state = REQUESTING; timeout = 0; packet_num = 0; already_waited_sec = 0; @@ -1747,9 +1746,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) timeout = 61; /* enter bound state */ d6_run_script(packet.d6_options, packet_end, - (state == REQUESTING ? "bound" : "renew")); + (client_config.state == REQUESTING ? "bound" : "renew")); - state = BOUND; + client_config.state = BOUND; change_listen_mode(LISTEN_NONE); if (opt & OPT_q) { /* quit after lease */ goto ret0; diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 0e673ae7e..7b1b23706 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -984,13 +984,12 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) /*** Main ***/ -static int sockfd = -1; - +/* Values for client_config.listen_mode */ #define LISTEN_NONE 0 #define LISTEN_KERNEL 1 #define LISTEN_RAW 2 -static smallint listen_mode; +/* Values for client_config.state */ /* initial state: (re)start DHCP negotiation */ #define INIT_SELECTING 0 /* discover was sent, DHCPOFFER reply received */ @@ -1005,7 +1004,6 @@ static smallint listen_mode; #define RENEW_REQUESTED 5 /* release, possibly manually requested (SIGUSR2) */ #define RELEASED 6 -static smallint state; static int udhcp_raw_socket(int ifindex) { @@ -1102,35 +1100,35 @@ static void change_listen_mode(int new_mode) : "none" ); - listen_mode = new_mode; - if (sockfd >= 0) { - close(sockfd); - sockfd = -1; + client_config.listen_mode = new_mode; + if (client_config.sockfd >= 0) { + close(client_config.sockfd); + client_config.sockfd = -1; } if (new_mode == LISTEN_KERNEL) - sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_config.interface); + client_config.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_config.interface); else if (new_mode != LISTEN_NONE) - sockfd = udhcp_raw_socket(client_config.ifindex); - /* else LISTEN_NONE: sockfd stays closed */ + client_config.sockfd = udhcp_raw_socket(client_config.ifindex); + /* else LISTEN_NONE: client_config.sockfd stays closed */ } /* Called only on SIGUSR1 */ static void perform_renew(void) { bb_info_msg("performing DHCP renew"); - switch (state) { + switch (client_config.state) { case BOUND: change_listen_mode(LISTEN_KERNEL); case RENEWING: case REBINDING: - state = RENEW_REQUESTED; + client_config.state = RENEW_REQUESTED; break; case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ udhcp_run_script(NULL, "deconfig"); case REQUESTING: case RELEASED: change_listen_mode(LISTEN_RAW); - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; break; case INIT_SELECTING: break; @@ -1143,10 +1141,10 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) struct in_addr temp_addr; /* send release packet */ - if (state == BOUND - || state == RENEWING - || state == REBINDING - || state == RENEW_REQUESTED + if (client_config.state == BOUND + || client_config.state == RENEWING + || client_config.state == REBINDING + || client_config.state == RENEW_REQUESTED ) { temp_addr.s_addr = server_addr; strcpy(buffer, inet_ntoa(temp_addr)); @@ -1165,7 +1163,7 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) udhcp_run_script(NULL, "deconfig"); change_listen_mode(LISTEN_NONE); - state = RELEASED; + client_config.state = RELEASED; } static uint8_t* alloc_dhcp_option(int code, const char *str, int extra) @@ -1270,6 +1268,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) client_config.interface = "eth0"; client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; + client_config.sockfd = -1; str_V = "udhcp "BB_VER; /* Parse command line */ @@ -1397,7 +1396,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* We want random_xid to be random... */ srand(monotonic_us()); - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; udhcp_run_script(NULL, "deconfig"); change_listen_mode(LISTEN_RAW); packet_num = 0; @@ -1415,16 +1414,16 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* silence "uninitialized!" warning */ unsigned timestamp_before_wait = timestamp_before_wait; - //bb_error_msg("sockfd:%d, listen_mode:%d", sockfd, listen_mode); + //bb_error_msg("sockfd:%d, listen_mode:%d", client_config.sockfd, client_config.listen_mode); /* Was opening raw or udp socket here - * if (listen_mode != LISTEN_NONE && sockfd < 0), + * if (client_config.listen_mode != LISTEN_NONE && client_config.sockfd < 0), * but on fast network renew responses return faster * than we open sockets. Thus this code is moved * to change_listen_mode(). Thus we open listen socket * BEFORE we send renew request (see "case BOUND:"). */ - udhcp_sp_fd_set(pfds, sockfd); + udhcp_sp_fd_set(pfds, client_config.sockfd); tv = timeout - already_waited_sec; retval = 0; @@ -1466,7 +1465,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* We will restart the wait in any case */ already_waited_sec = 0; - switch (state) { + switch (client_config.state) { case INIT_SELECTING: if (!discover_retries || packet_num < discover_retries) { if (packet_num == 0) @@ -1515,11 +1514,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) * were seen in the wild. Treat them similarly * to "no response to discover" case */ change_listen_mode(LISTEN_RAW); - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; goto leasefail; case BOUND: /* 1/2 lease passed, enter renewing state */ - state = RENEWING; + client_config.state = RENEWING; client_config.first_secs = 0; /* make secs field count from 0 */ change_listen_mode(LISTEN_KERNEL); log1("entering renew state"); @@ -1556,7 +1555,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) } /* Timed out or error, enter rebinding state */ log1("entering rebinding state"); - state = REBINDING; + client_config.state = REBINDING; /* fall right through */ case REBINDING: /* Switch to bcast receive */ @@ -1572,7 +1571,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Timed out, enter init state */ bb_info_msg("lease lost, entering init state"); udhcp_run_script(NULL, "deconfig"); - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ /*timeout = 0; - already is */ packet_num = 0; @@ -1592,7 +1591,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) client_config.first_secs = 0; /* make secs field count from 0 */ already_waited_sec = 0; perform_renew(); - if (state == RENEW_REQUESTED) { + if (client_config.state == RENEW_REQUESTED) { /* We might be either on the same network * (in which case renew might work), * or we might be on a completely different one @@ -1627,15 +1626,15 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) int len; /* A packet is ready, read it */ - if (listen_mode == LISTEN_KERNEL) - len = udhcp_recv_kernel_packet(&packet, sockfd); + if (client_config.listen_mode == LISTEN_KERNEL) + len = udhcp_recv_kernel_packet(&packet, client_config.sockfd); else - len = udhcp_recv_raw_packet(&packet, sockfd); + len = udhcp_recv_raw_packet(&packet, client_config.sockfd); if (len == -1) { /* Error is severe, reopen socket */ bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO); sleep(discover_timeout); /* 3 seconds by default */ - change_listen_mode(listen_mode); /* just close and reopen */ + change_listen_mode(client_config.listen_mode); /* just close and reopen */ } /* If this packet will turn out to be unrelated/bogus, * we will go back and wait for next one. @@ -1666,7 +1665,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) continue; } - switch (state) { + switch (client_config.state) { case INIT_SELECTING: /* Must be a DHCPOFFER */ if (*message == DHCPOFFER) { @@ -1708,7 +1707,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) requested_ip = packet.yiaddr; /* enter requesting state */ - state = REQUESTING; + client_config.state = REQUESTING; timeout = 0; packet_num = 0; already_waited_sec = 0; @@ -1763,10 +1762,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) "(got ARP reply), declining"); send_decline(/*xid,*/ server_addr, packet.yiaddr); - if (state != REQUESTING) + if (client_config.state != REQUESTING) udhcp_run_script(NULL, "deconfig"); change_listen_mode(LISTEN_RAW); - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ requested_ip = 0; timeout = tryagain_timeout; @@ -1783,7 +1782,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) requested_ip = packet.yiaddr; start = monotonic_sec(); - udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew"); + udhcp_run_script(&packet, client_config.state == REQUESTING ? "bound" : "renew"); already_waited_sec = (unsigned)monotonic_sec() - start; timeout = lease_seconds / 2; if ((unsigned)timeout < already_waited_sec) { @@ -1791,7 +1790,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) timeout = already_waited_sec = 0; } - state = BOUND; + client_config.state = BOUND; change_listen_mode(LISTEN_NONE); if (opt & OPT_q) { /* quit after lease */ goto ret0; @@ -1833,11 +1832,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* return to init state */ bb_info_msg("received %s", "DHCP NAK"); udhcp_run_script(&packet, "nak"); - if (state != REQUESTING) + if (client_config.state != REQUESTING) udhcp_run_script(NULL, "deconfig"); change_listen_mode(LISTEN_RAW); sleep(3); /* avoid excessive network traffic */ - state = INIT_SELECTING; + client_config.state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ requested_ip = 0; timeout = 0; diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index 7fdbc9a6c..2618b12b5 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h @@ -24,6 +24,10 @@ struct client_config_t { uint16_t first_secs; uint16_t last_secs; + + int sockfd; + smallint listen_mode; + smallint state; } FIX_ALIASING; /* server_config sits in 1st half of bb_common_bufsiz1 */ -- cgit v1.2.3-55-g6feb From cc71f79c1e5905992f4ba5cd6fe3466fe276737d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 26 May 2019 13:43:06 +0200 Subject: libarchive: treat one "FIXME: avoid seek", take 2 Signed-off-by: Denys Vlasenko --- archival/libarchive/open_transformer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 97bcc32f0..775bb580d 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -352,13 +352,13 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ * read(4, "LF\2\1\1\0\0\0\0"... * ...and we avoided seeking on the fd! :) */ - xstate->signature_skipped = 0; image = xmalloc_read_with_initial_buf( xstate->src_fd, maxsz_p, xmemdup(&xstate->magic, xstate->signature_skipped), xstate->signature_skipped ); + xstate->signature_skipped = 0; } if (!image) -- cgit v1.2.3-55-g6feb From eda83c9e69a430ecbee97fc53c0e691c6bb70d13 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 26 May 2019 13:46:49 +0200 Subject: comment fix Signed-off-by: Denys Vlasenko --- archival/libarchive/open_transformer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 775bb580d..a90f42a45 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -343,7 +343,7 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ } else { /* File is not compressed. * We already read first few bytes, account for that. - * Exmaple where it happens: + * Example where it happens: * "modinfo MODULE.ko" (not compressed) * open("MODULE.ko", O_RDONLY|O_LARGEFILE) = 4 * read(4, "\177E", 2) = 2 -- cgit v1.2.3-55-g6feb From b2c123d484dbe261758f27ced213f4649173803b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 26 May 2019 13:51:41 +0200 Subject: testsuite: fix bunzip2.tests expectations Signed-off-by: Denys Vlasenko --- testsuite/bunzip2.tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/bunzip2.tests b/testsuite/bunzip2.tests index edb332748..69e34dfd0 100755 --- a/testsuite/bunzip2.tests +++ b/testsuite/bunzip2.tests @@ -562,7 +562,7 @@ if test "${0##*/}" = "bunzip2.tests"; then fi errout="`${bb}bunzip2 &1 >/dev/null`" - if test x"$errout:$?" = x"bunzip2: bunzip error -3:1"; then + if test x"$errout:$?" = x"bunzip2: bunzip error -5:1"; then echo "PASS: $unpack: bz2_issue_12.bz2 corrupted example" else echo "FAIL: $unpack: bz2_issue_12.bz2 corrupted example" -- cgit v1.2.3-55-g6feb From 9501bc7da5f560f3dae6f6a1d2b11efa9d5dfe47 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 26 May 2019 13:53:41 +0200 Subject: ls: fix SEGV when --color is used and ENABLE_LS_COLOR=n Signed-off-by: Denys Vlasenko --- coreutils/ls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils/ls.c b/coreutils/ls.c index b2adb0c06..e5375a61a 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -1086,7 +1086,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) static const char ls_longopts[] ALIGN1 = "full-time\0" No_argument "\xff" "group-directories-first\0" No_argument "\xfe" - "color\0" Optional_argument "\xfd" + IF_FEATURE_LS_COLOR("color\0" Optional_argument "\xfd") ; #endif -- cgit v1.2.3-55-g6feb From 8b35f207bbd91a5bbca816dbdf5f8f33dd57f19d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 26 May 2019 14:02:10 +0200 Subject: shell: move all definitions of strto_arith_t() together Signed-off-by: Denys Vlasenko --- shell/math.c | 10 +++++++--- shell/math.h | 8 -------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/shell/math.c b/shell/math.c index 2ea0317e9..eaf4f2453 100644 --- a/shell/math.c +++ b/shell/math.c @@ -545,8 +545,12 @@ static arith_t strto_arith_t(const char *nptr, char **endptr) *endptr = (char*)nptr; return n; } -#define strto_arith_t(nptr, endptr, base_is_always_0) \ - strto_arith_t(nptr, endptr) +#else /* !ENABLE_FEATURE_SH_MATH_BASE */ +# if ENABLE_FEATURE_SH_MATH_64 +# define strto_arith_t(nptr, endptr) strtoull(nptr, endptr, 0) +# else +# define strto_arith_t(nptr, endptr) strtoul(nptr, endptr, 0) +# endif #endif static arith_t FAST_FUNC @@ -627,7 +631,7 @@ evaluate_string(arith_state_t *math_state, const char *expr) /* Number */ numstackptr->var = NULL; errno = 0; - numstackptr->val = strto_arith_t(expr, (char**) &expr, 0); + numstackptr->val = strto_arith_t(expr, (char**) &expr); if (errno) numstackptr->val = 0; /* bash compat */ goto num; diff --git a/shell/math.h b/shell/math.h index ec9decb1f..41ef6e8df 100644 --- a/shell/math.h +++ b/shell/math.h @@ -71,14 +71,6 @@ typedef long arith_t; # define ARITH_FMT "%ld" #endif -#if !ENABLE_FEATURE_SH_MATH_BASE -# if ENABLE_FEATURE_SH_MATH_64 -# define strto_arith_t strtoull -# else -# define strto_arith_t strtoul -# endif -#endif - typedef const char* FAST_FUNC (*arith_var_lookup_t)(const char *name); typedef void FAST_FUNC (*arith_var_set_t)(const char *name, const char *val); //typedef const char* FAST_FUNC (*arith_var_endofname_t)(const char *name); -- cgit v1.2.3-55-g6feb From 818d9e02f2de87aef3ba72c2b3bcec6eed4ef974 Mon Sep 17 00:00:00 2001 From: Martin Lewis Date: Sun, 26 May 2019 14:22:44 +0200 Subject: udhcpc6: Fixed aliasing compilation error Signed-off-by: Martin Lewis Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h index 2178cb9d6..dee2558e2 100644 --- a/networking/udhcp/d6_common.h +++ b/networking/udhcp/d6_common.h @@ -141,7 +141,7 @@ struct client6_data_t { unsigned env_idx; /* link-local IPv6 address */ struct in6_addr ll_ip6; -}; +} FIX_ALIASING; #define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)])) -- cgit v1.2.3-55-g6feb From bcb1fc3e6ca6fe902610f507eaf9b0b58a5c583a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 26 May 2019 15:01:13 +0200 Subject: udhcp: rename client_config to client_data, server_config to server_data Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_dhcpc.c | 152 +++++++++++++++---------------- networking/udhcp/dhcpc.c | 214 ++++++++++++++++++++++---------------------- networking/udhcp/dhcpc.h | 8 +- networking/udhcp/dhcpd.h | 2 +- 4 files changed, 188 insertions(+), 188 deletions(-) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 1973af99b..15e9f3924 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -63,7 +63,7 @@ #include #include -/* "struct client_config_t client_config" is in bb_common_bufsiz1 */ +/* "struct client_data_t client_data" is in bb_common_bufsiz1 */ static const struct dhcp_optflag d6_optflags[] = { #if ENABLE_FEATURE_UDHCPC6_RFC3646 @@ -427,7 +427,7 @@ static char **fill_envp(const uint8_t *option, const uint8_t *option_end) client6_data.env_ptr = NULL; client6_data.env_idx = 0; - *new_env() = xasprintf("interface=%s", client_config.interface); + *new_env() = xasprintf("interface=%s", client_data.interface); if (option) option_to_env(option, option_end); @@ -449,8 +449,8 @@ static void d6_run_script(const uint8_t *option, const uint8_t *option_end, envp = fill_envp(option, option_end); /* call script */ - log1("executing %s %s", client_config.script, name); - argv[0] = (char*) client_config.script; + log1("executing %s %s", client_data.script, name); + argv[0] = (char*) client_data.script; argv[1] = (char*) name; argv[2] = NULL; spawn_and_wait(argv); @@ -486,7 +486,7 @@ static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid packet->d6_xid32 = xid; packet->d6_msg_type = type; - clientid = (void*)client_config.clientid; + clientid = (void*)client_data.clientid; return mempcpy(packet->d6_options, clientid, clientid->len + 2+2); } @@ -499,7 +499,7 @@ static uint8_t *add_d6_client_options(uint8_t *ptr) ptr += 4; for (option = 1; option < 256; option++) { - if (client_config.opt_mask[option >> 3] & (1 << (option & 7))) { + if (client_data.opt_mask[option >> 3] & (1 << (option & 7))) { ptr[0] = (option >> 8); ptr[1] = option; ptr += 2; @@ -518,7 +518,7 @@ static uint8_t *add_d6_client_options(uint8_t *ptr) ptr = mempcpy(ptr, &opt_fqdn_req, sizeof(opt_fqdn_req)); #endif /* Add -x options if any */ - curr = client_config.options; + curr = client_data.options; while (curr) { len = (curr->data[D6_OPT_LEN] << 8) | curr->data[D6_OPT_LEN + 1]; ptr = mempcpy(ptr, curr->data, D6_OPT_DATA + len); @@ -528,7 +528,7 @@ static uint8_t *add_d6_client_options(uint8_t *ptr) return ptr; } -static int d6_mcast_from_client_config_ifindex(struct d6_packet *packet, uint8_t *end) +static int d6_mcast_from_client_data_ifindex(struct d6_packet *packet, uint8_t *end) { /* FF02::1:2 is "All_DHCP_Relay_Agents_and_Servers" address */ static const uint8_t FF02__1_2[16] = { @@ -540,7 +540,7 @@ static int d6_mcast_from_client_config_ifindex(struct d6_packet *packet, uint8_t packet, (end - (uint8_t*) packet), /*src*/ &client6_data.ll_ip6, CLIENT_PORT6, /*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_BCAST_ADDR, - client_config.ifindex + client_data.ifindex ); } @@ -671,7 +671,7 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip opt_ptr = add_d6_client_options(opt_ptr); bb_info_msg("sending %s", "discover"); - return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); + return d6_mcast_from_client_data_ifindex(&packet, opt_ptr); } /* Multicast a DHCPv6 request message @@ -728,7 +728,7 @@ static NOINLINE int send_d6_select(uint32_t xid) opt_ptr = add_d6_client_options(opt_ptr); bb_info_msg("sending %s", "select"); - return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); + return d6_mcast_from_client_data_ifindex(&packet, opt_ptr); } /* Unicast or broadcast a DHCP renew message @@ -806,9 +806,9 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st &packet, (opt_ptr - (uint8_t*) &packet), our_cur_ipv6, CLIENT_PORT6, server_ipv6, SERVER_PORT6, - client_config.ifindex + client_data.ifindex ); - return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); + return d6_mcast_from_client_data_ifindex(&packet, opt_ptr); } /* Unicast a DHCP release message */ @@ -835,7 +835,7 @@ int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) &packet, (opt_ptr - (uint8_t*) &packet), our_cur_ipv6, CLIENT_PORT6, server_ipv6, SERVER_PORT6, - client_config.ifindex + client_data.ifindex ); } @@ -903,12 +903,12 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_pac /*** Main ***/ -/* Values for client_config.listen_mode */ +/* Values for client_data.listen_mode */ #define LISTEN_NONE 0 #define LISTEN_KERNEL 1 #define LISTEN_RAW 2 -/* Values for client_config.state */ +/* Values for client_data.state */ /* initial state: (re)start DHCP negotiation */ #define INIT_SELECTING 0 /* discover was sent, DHCPOFFER reply received */ @@ -1016,35 +1016,35 @@ static void change_listen_mode(int new_mode) : "none" ); - client_config.listen_mode = new_mode; - if (client_config.sockfd >= 0) { - close(client_config.sockfd); - client_config.sockfd = -1; + client_data.listen_mode = new_mode; + if (client_data.sockfd >= 0) { + close(client_data.sockfd); + client_data.sockfd = -1; } if (new_mode == LISTEN_KERNEL) - client_config.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT6, client_config.interface); + client_data.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT6, client_data.interface); else if (new_mode != LISTEN_NONE) - client_config.sockfd = d6_raw_socket(client_config.ifindex); - /* else LISTEN_NONE: client_config.sockfd stays closed */ + client_data.sockfd = d6_raw_socket(client_data.ifindex); + /* else LISTEN_NONE: client_data.sockfd stays closed */ } /* Called only on SIGUSR1 */ static void perform_renew(void) { bb_info_msg("performing DHCP renew"); - switch (client_config.state) { + switch (client_data.state) { case BOUND: change_listen_mode(LISTEN_KERNEL); case RENEWING: case REBINDING: - client_config.state = RENEW_REQUESTED; + client_data.state = RENEW_REQUESTED; break; case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ d6_run_script_no_option("deconfig"); case REQUESTING: case RELEASED: change_listen_mode(LISTEN_RAW); - client_config.state = INIT_SELECTING; + client_data.state = INIT_SELECTING; break; case INIT_SELECTING: break; @@ -1054,10 +1054,10 @@ static void perform_renew(void) static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) { /* send release packet */ - if (client_config.state == BOUND - || client_config.state == RENEWING - || client_config.state == REBINDING - || client_config.state == RENEW_REQUESTED + if (client_data.state == BOUND + || client_data.state == RENEWING + || client_data.state == REBINDING + || client_data.state == RENEW_REQUESTED ) { bb_info_msg("unicasting a release"); send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ @@ -1071,7 +1071,7 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou */ d6_run_script_no_option("deconfig"); change_listen_mode(LISTEN_NONE); - client_config.state = RELEASED; + client_data.state = RELEASED; } ///static uint8_t* alloc_dhcp_option(int code, const char *str, int extra) @@ -1091,7 +1091,7 @@ static void client_background(void) bb_daemonize(0); logmode &= ~LOGMODE_STDIO; /* rewrite pidfile, as our pid is different now */ - write_pidfile(client_config.pidfile); + write_pidfile(client_data.pidfile); } #endif @@ -1170,9 +1170,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* Default options */ IF_FEATURE_UDHCP_PORT(SERVER_PORT6 = 547;) IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;) - client_config.interface = "eth0"; - client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; - client_config.sockfd = -1; + client_data.interface = "eth0"; + client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; + client_data.sockfd = -1; /* Parse command line */ opt = getopt32long(argv, "^" @@ -1184,8 +1184,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) "v" "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */ , udhcpc6_longopts - , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ - , &client_config.script /* s */ + , &client_data.interface, &client_data.pidfile, &str_r /* i,p */ + , &client_data.script /* s */ , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ , &list_O , &list_x @@ -1216,29 +1216,29 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) n = udhcp_option_idx(optstr, d6_option_strings); n = d6_optflags[n].code; } - client_config.opt_mask[n >> 3] |= 1 << (n & 7); + client_data.opt_mask[n >> 3] |= 1 << (n & 7); } if (!(opt & OPT_o)) { unsigned i, n; for (i = 0; (n = d6_optflags[i].code) != 0; i++) { if (d6_optflags[i].flags & OPTION_REQ) { - client_config.opt_mask[n >> 3] |= 1 << (n & 7); + client_data.opt_mask[n >> 3] |= 1 << (n & 7); } } } while (list_x) { char *optstr = xstrdup(llist_pop(&list_x)); - udhcp_str2optset(optstr, &client_config.options, + udhcp_str2optset(optstr, &client_data.options, d6_optflags, d6_option_strings, /*dhcpv6:*/ 1 ); free(optstr); } - if (d6_read_interface(client_config.interface, - &client_config.ifindex, + if (d6_read_interface(client_data.interface, + &client_data.ifindex, &client6_data.ll_ip6, - client_config.client_mac) + client_data.client_mac) ) { return 1; } @@ -1252,8 +1252,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) clientid->data[1] = 3; /* DUID-LL */ clientid->data[3] = 1; /* ethernet */ clientid_mac_ptr = clientid->data + 2+2; - memcpy(clientid_mac_ptr, client_config.client_mac, 6); - client_config.clientid = (void*)clientid; + memcpy(clientid_mac_ptr, client_data.client_mac, 6); + client_data.clientid = (void*)clientid; } #if !BB_MMU @@ -1271,13 +1271,13 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* Make sure fd 0,1,2 are open */ bb_sanitize_stdio(); /* Create pidfile */ - write_pidfile(client_config.pidfile); + write_pidfile(client_data.pidfile); /* Goes to stdout (unless NOMMU) and possibly syslog */ bb_info_msg("started, v"BB_VER); /* Set up the signal pipe */ udhcp_sp_setup(); - client_config.state = INIT_SELECTING; + client_data.state = INIT_SELECTING; d6_run_script_no_option("deconfig"); change_listen_mode(LISTEN_RAW); packet_num = 0; @@ -1296,16 +1296,16 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* silence "uninitialized!" warning */ unsigned timestamp_before_wait = timestamp_before_wait; - //bb_error_msg("sockfd:%d, listen_mode:%d", client_config.sockfd, client_config.listen_mode); + //bb_error_msg("sockfd:%d, listen_mode:%d", client_data.sockfd, client_data.listen_mode); /* Was opening raw or udp socket here - * if (client_config.listen_mode != LISTEN_NONE && client_config.sockfd < 0), + * if (client_data.listen_mode != LISTEN_NONE && client_data.sockfd < 0), * but on fast network renew responses return faster * than we open sockets. Thus this code is moved * to change_listen_mode(). Thus we open listen socket * BEFORE we send renew request (see "case BOUND:"). */ - udhcp_sp_fd_set(pfds, client_config.sockfd); + udhcp_sp_fd_set(pfds, client_data.sockfd); tv = timeout - already_waited_sec; retval = 0; @@ -1334,20 +1334,20 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) * or if the status of the bridge changed). * Refresh ifindex and client_mac: */ - if (d6_read_interface(client_config.interface, - &client_config.ifindex, + if (d6_read_interface(client_data.interface, + &client_data.ifindex, &client6_data.ll_ip6, - client_config.client_mac) + client_data.client_mac) ) { goto ret0; /* iface is gone? */ } - memcpy(clientid_mac_ptr, client_config.client_mac, 6); + memcpy(clientid_mac_ptr, client_data.client_mac, 6); /* We will restart the wait in any case */ already_waited_sec = 0; - switch (client_config.state) { + switch (client_data.state) { case INIT_SELECTING: if (!discover_retries || packet_num < discover_retries) { if (packet_num == 0) @@ -1396,12 +1396,12 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) * were seen in the wild. Treat them similarly * to "no response to discover" case */ change_listen_mode(LISTEN_RAW); - client_config.state = INIT_SELECTING; + client_data.state = INIT_SELECTING; goto leasefail; case BOUND: /* 1/2 lease passed, enter renewing state */ - client_config.state = RENEWING; - client_config.first_secs = 0; /* make secs field count from 0 */ + client_data.state = RENEWING; + client_data.first_secs = 0; /* make secs field count from 0 */ change_listen_mode(LISTEN_KERNEL); log1("entering renew state"); /* fall right through */ @@ -1424,7 +1424,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) } /* Timed out, enter rebinding state */ log1("entering rebinding state"); - client_config.state = REBINDING; + client_data.state = REBINDING; /* fall right through */ case REBINDING: /* Switch to bcast receive */ @@ -1440,8 +1440,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* Timed out, enter init state */ bb_info_msg("lease lost, entering init state"); d6_run_script_no_option("deconfig"); - client_config.state = INIT_SELECTING; - client_config.first_secs = 0; /* make secs field count from 0 */ + client_data.state = INIT_SELECTING; + client_data.first_secs = 0; /* make secs field count from 0 */ /*timeout = 0; - already is */ packet_num = 0; continue; @@ -1457,10 +1457,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* Is it a signal? */ switch (udhcp_sp_read()) { case SIGUSR1: - client_config.first_secs = 0; /* make secs field count from 0 */ + client_data.first_secs = 0; /* make secs field count from 0 */ already_waited_sec = 0; perform_renew(); - if (client_config.state == RENEW_REQUESTED) { + if (client_data.state == RENEW_REQUESTED) { /* We might be either on the same network * (in which case renew might work), * or we might be on a completely different one @@ -1495,15 +1495,15 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) int len; /* A packet is ready, read it */ - if (client_config.listen_mode == LISTEN_KERNEL) - len = d6_recv_kernel_packet(&srv6_buf, &packet, client_config.sockfd); + if (client_data.listen_mode == LISTEN_KERNEL) + len = d6_recv_kernel_packet(&srv6_buf, &packet, client_data.sockfd); else - len = d6_recv_raw_packet(&srv6_buf, &packet, client_config.sockfd); + len = d6_recv_raw_packet(&srv6_buf, &packet, client_data.sockfd); if (len == -1) { /* Error is severe, reopen socket */ bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO); sleep(discover_timeout); /* 3 seconds by default */ - change_listen_mode(client_config.listen_mode); /* just close and reopen */ + change_listen_mode(client_data.listen_mode); /* just close and reopen */ } /* If this packet will turn out to be unrelated/bogus, * we will go back and wait for next one. @@ -1520,7 +1520,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) continue; } - switch (client_config.state) { + switch (client_data.state) { case INIT_SELECTING: if (packet.d6_msg_type == D6_MSG_ADVERTISE) goto type_is_ok; @@ -1546,12 +1546,12 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) bb_info_msg("received DHCP NAK (%u)", option->data[4]); d6_run_script(packet.d6_options, packet_end, "nak"); - if (client_config.state != REQUESTING) + if (client_data.state != REQUESTING) d6_run_script_no_option("deconfig"); change_listen_mode(LISTEN_RAW); sleep(3); /* avoid excessive network traffic */ - client_config.state = INIT_SELECTING; - client_config.first_secs = 0; /* make secs field count from 0 */ + client_data.state = INIT_SELECTING; + client_data.first_secs = 0; /* make secs field count from 0 */ requested_ipv6 = NULL; timeout = 0; packet_num = 0; @@ -1571,7 +1571,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) client6_data.server_id = option; if (packet.d6_msg_type == D6_MSG_ADVERTISE) { /* enter requesting state */ - client_config.state = REQUESTING; + client_data.state = REQUESTING; timeout = 0; packet_num = 0; already_waited_sec = 0; @@ -1746,9 +1746,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) timeout = 61; /* enter bound state */ d6_run_script(packet.d6_options, packet_end, - (client_config.state == REQUESTING ? "bound" : "renew")); + (client_data.state == REQUESTING ? "bound" : "renew")); - client_config.state = BOUND; + client_data.state = BOUND; change_listen_mode(LISTEN_NONE); if (opt & OPT_q) { /* quit after lease */ goto ret0; @@ -1777,7 +1777,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) perform_d6_release(&srv6_buf, requested_ipv6); retval = 0; ret: - /*if (client_config.pidfile) - remove_pidfile has its own check */ - remove_pidfile(client_config.pidfile); + /*if (client_data.pidfile) - remove_pidfile has its own check */ + remove_pidfile(client_data.pidfile); return retval; } diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 7b1b23706..cb85fa9e3 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -49,7 +49,7 @@ struct tpacket_auxdata { #endif -/* "struct client_config_t client_config" is in bb_common_bufsiz1 */ +/* "struct client_data_t client_data" is in bb_common_bufsiz1 */ #if ENABLE_LONG_OPTS @@ -477,7 +477,7 @@ static char **fill_envp(struct dhcp_packet *packet) } curr = envp = xzalloc(sizeof(envp[0]) * envc); - *curr = xasprintf("interface=%s", client_config.interface); + *curr = xasprintf("interface=%s", client_data.interface); putenv(*curr++); if (!packet) @@ -577,8 +577,8 @@ static void udhcp_run_script(struct dhcp_packet *packet, const char *name) envp = fill_envp(packet); /* call script */ - log1("executing %s %s", client_config.script, name); - argv[0] = (char*) client_config.script; + log1("executing %s %s", client_data.script, name); + argv[0] = (char*) client_data.script; argv[1] = (char*) name; argv[2] = NULL; spawn_and_wait(argv); @@ -608,15 +608,15 @@ static void init_packet(struct dhcp_packet *packet, char type) packet->xid = random_xid(); - client_config.last_secs = monotonic_sec(); - if (client_config.first_secs == 0) - client_config.first_secs = client_config.last_secs; - secs = client_config.last_secs - client_config.first_secs; + client_data.last_secs = monotonic_sec(); + if (client_data.first_secs == 0) + client_data.first_secs = client_data.last_secs; + secs = client_data.last_secs - client_data.first_secs; packet->secs = htons(secs); - memcpy(packet->chaddr, client_config.client_mac, 6); - if (client_config.clientid) - udhcp_add_binary_option(packet, client_config.clientid); + memcpy(packet->chaddr, client_data.client_mac, 6); + if (client_data.clientid) + udhcp_add_binary_option(packet, client_data.clientid); } static void add_client_options(struct dhcp_packet *packet) @@ -631,7 +631,7 @@ static void add_client_options(struct dhcp_packet *packet) end = udhcp_end_option(packet->options); len = 0; for (i = 1; i < DHCP_END; i++) { - if (client_config.opt_mask[i >> 3] & (1 << (i & 7))) { + if (client_data.opt_mask[i >> 3] & (1 << (i & 7))) { packet->options[end + OPT_DATA + len] = i; len++; } @@ -642,12 +642,12 @@ static void add_client_options(struct dhcp_packet *packet) packet->options[end + OPT_DATA + len] = DHCP_END; } - if (client_config.vendorclass) - udhcp_add_binary_option(packet, client_config.vendorclass); - if (client_config.hostname) - udhcp_add_binary_option(packet, client_config.hostname); - if (client_config.fqdn) - udhcp_add_binary_option(packet, client_config.fqdn); + if (client_data.vendorclass) + udhcp_add_binary_option(packet, client_data.vendorclass); + if (client_data.hostname) + udhcp_add_binary_option(packet, client_data.hostname); + if (client_data.fqdn) + udhcp_add_binary_option(packet, client_data.fqdn); /* Request broadcast replies if we have no IP addr */ if ((option_mask32 & OPT_B) && packet->ciaddr == 0) @@ -655,15 +655,15 @@ static void add_client_options(struct dhcp_packet *packet) /* Add -x options if any */ { - struct option_set *curr = client_config.options; + struct option_set *curr = client_data.options; while (curr) { udhcp_add_binary_option(packet, curr->data); curr = curr->next; } -// if (client_config.sname) -// strncpy((char*)packet->sname, client_config.sname, sizeof(packet->sname) - 1); -// if (client_config.boot_file) -// strncpy((char*)packet->file, client_config.boot_file, sizeof(packet->file) - 1); +// if (client_data.sname) +// strncpy((char*)packet->sname, client_data.sname, sizeof(packet->sname) - 1); +// if (client_data.boot_file) +// strncpy((char*)packet->file, client_data.boot_file, sizeof(packet->file) - 1); } // This will be needed if we remove -V VENDOR_STR in favor of @@ -691,12 +691,12 @@ static void add_client_options(struct dhcp_packet *packet) * client reverts to using the IP broadcast address. */ -static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint32_t src_nip) +static int raw_bcast_from_client_data_ifindex(struct dhcp_packet *packet, uint32_t src_nip) { return udhcp_send_raw_packet(packet, /*src*/ src_nip, CLIENT_PORT, /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, - client_config.ifindex); + client_data.ifindex); } static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server) @@ -705,7 +705,7 @@ static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t return udhcp_send_kernel_packet(packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); - return raw_bcast_from_client_config_ifindex(packet, ciaddr); + return raw_bcast_from_client_data_ifindex(packet, ciaddr); } /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ @@ -731,7 +731,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested) add_client_options(&packet); bb_info_msg("sending %s", "discover"); - return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); + return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); } /* Broadcast a DHCP request message */ @@ -775,7 +775,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste temp_addr.s_addr = requested; bb_info_msg("sending select for %s", inet_ntoa(temp_addr)); - return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); + return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); } /* Unicast or broadcast a DHCP renew message */ @@ -845,7 +845,7 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); bb_info_msg("sending %s", "decline"); - return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); + return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); } #endif @@ -984,12 +984,12 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) /*** Main ***/ -/* Values for client_config.listen_mode */ +/* Values for client_data.listen_mode */ #define LISTEN_NONE 0 #define LISTEN_KERNEL 1 #define LISTEN_RAW 2 -/* Values for client_config.state */ +/* Values for client_data.state */ /* initial state: (re)start DHCP negotiation */ #define INIT_SELECTING 0 /* discover was sent, DHCPOFFER reply received */ @@ -1100,35 +1100,35 @@ static void change_listen_mode(int new_mode) : "none" ); - client_config.listen_mode = new_mode; - if (client_config.sockfd >= 0) { - close(client_config.sockfd); - client_config.sockfd = -1; + client_data.listen_mode = new_mode; + if (client_data.sockfd >= 0) { + close(client_data.sockfd); + client_data.sockfd = -1; } if (new_mode == LISTEN_KERNEL) - client_config.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_config.interface); + client_data.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_data.interface); else if (new_mode != LISTEN_NONE) - client_config.sockfd = udhcp_raw_socket(client_config.ifindex); - /* else LISTEN_NONE: client_config.sockfd stays closed */ + client_data.sockfd = udhcp_raw_socket(client_data.ifindex); + /* else LISTEN_NONE: client_data.sockfd stays closed */ } /* Called only on SIGUSR1 */ static void perform_renew(void) { bb_info_msg("performing DHCP renew"); - switch (client_config.state) { + switch (client_data.state) { case BOUND: change_listen_mode(LISTEN_KERNEL); case RENEWING: case REBINDING: - client_config.state = RENEW_REQUESTED; + client_data.state = RENEW_REQUESTED; break; case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ udhcp_run_script(NULL, "deconfig"); case REQUESTING: case RELEASED: change_listen_mode(LISTEN_RAW); - client_config.state = INIT_SELECTING; + client_data.state = INIT_SELECTING; break; case INIT_SELECTING: break; @@ -1141,10 +1141,10 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) struct in_addr temp_addr; /* send release packet */ - if (client_config.state == BOUND - || client_config.state == RENEWING - || client_config.state == REBINDING - || client_config.state == RENEW_REQUESTED + if (client_data.state == BOUND + || client_data.state == RENEWING + || client_data.state == REBINDING + || client_data.state == RENEW_REQUESTED ) { temp_addr.s_addr = server_addr; strcpy(buffer, inet_ntoa(temp_addr)); @@ -1163,7 +1163,7 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) udhcp_run_script(NULL, "deconfig"); change_listen_mode(LISTEN_NONE); - client_config.state = RELEASED; + client_data.state = RELEASED; } static uint8_t* alloc_dhcp_option(int code, const char *str, int extra) @@ -1183,7 +1183,7 @@ static void client_background(void) bb_daemonize(0); logmode &= ~LOGMODE_STDIO; /* rewrite pidfile, as our pid is different now */ - write_pidfile(client_config.pidfile); + write_pidfile(client_data.pidfile); } #endif @@ -1266,9 +1266,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Default options */ IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) - client_config.interface = "eth0"; - client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; - client_config.sockfd = -1; + client_data.interface = "eth0"; + client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; + client_data.sockfd = -1; str_V = "udhcp "BB_VER; /* Parse command line */ @@ -1282,9 +1282,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */ , udhcpc_longopts , &str_V, &str_h, &str_h, &str_F - , &client_config.interface, &client_config.pidfile /* i,p */ + , &client_data.interface, &client_data.pidfile /* i,p */ , &str_r /* r */ - , &client_config.script /* s */ + , &client_data.script /* s */ , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ , &list_O , &list_x @@ -1295,11 +1295,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) if (opt & (OPT_h|OPT_H)) { //msg added 2011-11 bb_error_msg("option -h NAME is deprecated, use -x hostname:NAME"); - client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); + client_data.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); } if (opt & OPT_F) { /* FQDN option format: [0x51][len][flags][0][0] */ - client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3); + client_data.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3); /* Flag bits: 0000NEOS * S: 1 = Client requests server to update A RR in DNS as well as PTR * O: 1 = Server indicates to client that DNS has been updated regardless @@ -1308,9 +1308,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) * N: 1 = Client requests server to not update DNS (S must be 0 then) * Two [0] bytes which follow are deprecated and must be 0. */ - client_config.fqdn[OPT_DATA + 0] = 0x1; - /*client_config.fqdn[OPT_DATA + 1] = 0; - xzalloc did it */ - /*client_config.fqdn[OPT_DATA + 2] = 0; */ + client_data.fqdn[OPT_DATA + 0] = 0x1; + /*client_data.fqdn[OPT_DATA + 1] = 0; - xzalloc did it */ + /*client_data.fqdn[OPT_DATA + 2] = 0; */ } if (opt & OPT_r) requested_ip = inet_addr(str_r); @@ -1328,49 +1328,49 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) n = udhcp_option_idx(optstr, dhcp_option_strings); n = dhcp_optflags[n].code; } - client_config.opt_mask[n >> 3] |= 1 << (n & 7); + client_data.opt_mask[n >> 3] |= 1 << (n & 7); } if (!(opt & OPT_o)) { unsigned i, n; for (i = 0; (n = dhcp_optflags[i].code) != 0; i++) { if (dhcp_optflags[i].flags & OPTION_REQ) { - client_config.opt_mask[n >> 3] |= 1 << (n & 7); + client_data.opt_mask[n >> 3] |= 1 << (n & 7); } } } while (list_x) { char *optstr = xstrdup(llist_pop(&list_x)); - udhcp_str2optset(optstr, &client_config.options, + udhcp_str2optset(optstr, &client_data.options, dhcp_optflags, dhcp_option_strings, /*dhcpv6:*/ 0 ); free(optstr); } - if (udhcp_read_interface(client_config.interface, - &client_config.ifindex, + if (udhcp_read_interface(client_data.interface, + &client_data.ifindex, NULL, - client_config.client_mac) + client_data.client_mac) ) { return 1; } clientid_mac_ptr = NULL; - if (!(opt & OPT_C) && !udhcp_find_option(client_config.options, DHCP_CLIENT_ID)) { + if (!(opt & OPT_C) && !udhcp_find_option(client_data.options, DHCP_CLIENT_ID)) { /* not suppressed and not set, set the default client ID */ - client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7); - client_config.clientid[OPT_DATA] = 1; /* type: ethernet */ - clientid_mac_ptr = client_config.clientid + OPT_DATA+1; - memcpy(clientid_mac_ptr, client_config.client_mac, 6); + client_data.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7); + client_data.clientid[OPT_DATA] = 1; /* type: ethernet */ + clientid_mac_ptr = client_data.clientid + OPT_DATA+1; + memcpy(clientid_mac_ptr, client_data.client_mac, 6); } if (str_V[0] != '\0') { - // can drop -V, str_V, client_config.vendorclass, + // can drop -V, str_V, client_data.vendorclass, // but need to add "vendor" to the list of recognized // string opts for this to work; // and need to tweak add_client_options() too... // ...so the question is, should we? //bb_error_msg("option -V VENDOR is deprecated, use -x vendor:VENDOR"); - client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); + client_data.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); } #if !BB_MMU @@ -1388,7 +1388,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Make sure fd 0,1,2 are open */ bb_sanitize_stdio(); /* Create pidfile */ - write_pidfile(client_config.pidfile); + write_pidfile(client_data.pidfile); /* Goes to stdout (unless NOMMU) and possibly syslog */ bb_info_msg("started, v"BB_VER); /* Set up the signal pipe */ @@ -1396,7 +1396,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* We want random_xid to be random... */ srand(monotonic_us()); - client_config.state = INIT_SELECTING; + client_data.state = INIT_SELECTING; udhcp_run_script(NULL, "deconfig"); change_listen_mode(LISTEN_RAW); packet_num = 0; @@ -1414,16 +1414,16 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* silence "uninitialized!" warning */ unsigned timestamp_before_wait = timestamp_before_wait; - //bb_error_msg("sockfd:%d, listen_mode:%d", client_config.sockfd, client_config.listen_mode); + //bb_error_msg("sockfd:%d, listen_mode:%d", client_data.sockfd, client_data.listen_mode); /* Was opening raw or udp socket here - * if (client_config.listen_mode != LISTEN_NONE && client_config.sockfd < 0), + * if (client_data.listen_mode != LISTEN_NONE && client_data.sockfd < 0), * but on fast network renew responses return faster * than we open sockets. Thus this code is moved * to change_listen_mode(). Thus we open listen socket * BEFORE we send renew request (see "case BOUND:"). */ - udhcp_sp_fd_set(pfds, client_config.sockfd); + udhcp_sp_fd_set(pfds, client_data.sockfd); tv = timeout - already_waited_sec; retval = 0; @@ -1452,20 +1452,20 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) * or if the status of the bridge changed). * Refresh ifindex and client_mac: */ - if (udhcp_read_interface(client_config.interface, - &client_config.ifindex, + if (udhcp_read_interface(client_data.interface, + &client_data.ifindex, NULL, - client_config.client_mac) + client_data.client_mac) ) { goto ret0; /* iface is gone? */ } if (clientid_mac_ptr) - memcpy(clientid_mac_ptr, client_config.client_mac, 6); + memcpy(clientid_mac_ptr, client_data.client_mac, 6); /* We will restart the wait in any case */ already_waited_sec = 0; - switch (client_config.state) { + switch (client_data.state) { case INIT_SELECTING: if (!discover_retries || packet_num < discover_retries) { if (packet_num == 0) @@ -1514,12 +1514,12 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) * were seen in the wild. Treat them similarly * to "no response to discover" case */ change_listen_mode(LISTEN_RAW); - client_config.state = INIT_SELECTING; + client_data.state = INIT_SELECTING; goto leasefail; case BOUND: /* 1/2 lease passed, enter renewing state */ - client_config.state = RENEWING; - client_config.first_secs = 0; /* make secs field count from 0 */ + client_data.state = RENEWING; + client_data.first_secs = 0; /* make secs field count from 0 */ change_listen_mode(LISTEN_KERNEL); log1("entering renew state"); /* fall right through */ @@ -1555,7 +1555,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) } /* Timed out or error, enter rebinding state */ log1("entering rebinding state"); - client_config.state = REBINDING; + client_data.state = REBINDING; /* fall right through */ case REBINDING: /* Switch to bcast receive */ @@ -1571,8 +1571,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Timed out, enter init state */ bb_info_msg("lease lost, entering init state"); udhcp_run_script(NULL, "deconfig"); - client_config.state = INIT_SELECTING; - client_config.first_secs = 0; /* make secs field count from 0 */ + client_data.state = INIT_SELECTING; + client_data.first_secs = 0; /* make secs field count from 0 */ /*timeout = 0; - already is */ packet_num = 0; continue; @@ -1588,10 +1588,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Is it a signal? */ switch (udhcp_sp_read()) { case SIGUSR1: - client_config.first_secs = 0; /* make secs field count from 0 */ + client_data.first_secs = 0; /* make secs field count from 0 */ already_waited_sec = 0; perform_renew(); - if (client_config.state == RENEW_REQUESTED) { + if (client_data.state == RENEW_REQUESTED) { /* We might be either on the same network * (in which case renew might work), * or we might be on a completely different one @@ -1626,15 +1626,15 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) int len; /* A packet is ready, read it */ - if (client_config.listen_mode == LISTEN_KERNEL) - len = udhcp_recv_kernel_packet(&packet, client_config.sockfd); + if (client_data.listen_mode == LISTEN_KERNEL) + len = udhcp_recv_kernel_packet(&packet, client_data.sockfd); else - len = udhcp_recv_raw_packet(&packet, client_config.sockfd); + len = udhcp_recv_raw_packet(&packet, client_data.sockfd); if (len == -1) { /* Error is severe, reopen socket */ bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO); sleep(discover_timeout); /* 3 seconds by default */ - change_listen_mode(client_config.listen_mode); /* just close and reopen */ + change_listen_mode(client_data.listen_mode); /* just close and reopen */ } /* If this packet will turn out to be unrelated/bogus, * we will go back and wait for next one. @@ -1652,7 +1652,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Ignore packets that aren't for us */ if (packet.hlen != 6 - || memcmp(packet.chaddr, client_config.client_mac, 6) != 0 + || memcmp(packet.chaddr, client_data.client_mac, 6) != 0 ) { //FIXME: need to also check that last 10 bytes are zero log1("chaddr does not match, ignoring packet"); // log2? @@ -1665,7 +1665,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) continue; } - switch (client_config.state) { + switch (client_data.state) { case INIT_SELECTING: /* Must be a DHCPOFFER */ if (*message == DHCPOFFER) { @@ -1707,7 +1707,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) requested_ip = packet.yiaddr; /* enter requesting state */ - client_config.state = REQUESTING; + client_data.state = REQUESTING; timeout = 0; packet_num = 0; already_waited_sec = 0; @@ -1754,19 +1754,19 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) if (!arpping(packet.yiaddr, NULL, (uint32_t) 0, - client_config.client_mac, - client_config.interface, + client_data.client_mac, + client_data.interface, arpping_ms) ) { bb_info_msg("offered address is in use " "(got ARP reply), declining"); send_decline(/*xid,*/ server_addr, packet.yiaddr); - if (client_config.state != REQUESTING) + if (client_data.state != REQUESTING) udhcp_run_script(NULL, "deconfig"); change_listen_mode(LISTEN_RAW); - client_config.state = INIT_SELECTING; - client_config.first_secs = 0; /* make secs field count from 0 */ + client_data.state = INIT_SELECTING; + client_data.first_secs = 0; /* make secs field count from 0 */ requested_ip = 0; timeout = tryagain_timeout; packet_num = 0; @@ -1782,7 +1782,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) requested_ip = packet.yiaddr; start = monotonic_sec(); - udhcp_run_script(&packet, client_config.state == REQUESTING ? "bound" : "renew"); + udhcp_run_script(&packet, client_data.state == REQUESTING ? "bound" : "renew"); already_waited_sec = (unsigned)monotonic_sec() - start; timeout = lease_seconds / 2; if ((unsigned)timeout < already_waited_sec) { @@ -1790,7 +1790,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) timeout = already_waited_sec = 0; } - client_config.state = BOUND; + client_data.state = BOUND; change_listen_mode(LISTEN_NONE); if (opt & OPT_q) { /* quit after lease */ goto ret0; @@ -1832,12 +1832,12 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* return to init state */ bb_info_msg("received %s", "DHCP NAK"); udhcp_run_script(&packet, "nak"); - if (client_config.state != REQUESTING) + if (client_data.state != REQUESTING) udhcp_run_script(NULL, "deconfig"); change_listen_mode(LISTEN_RAW); sleep(3); /* avoid excessive network traffic */ - client_config.state = INIT_SELECTING; - client_config.first_secs = 0; /* make secs field count from 0 */ + client_data.state = INIT_SELECTING; + client_data.first_secs = 0; /* make secs field count from 0 */ requested_ip = 0; timeout = 0; packet_num = 0; @@ -1855,7 +1855,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) perform_release(server_addr, requested_ip); retval = 0; ret: - /*if (client_config.pidfile) - remove_pidfile has its own check */ - remove_pidfile(client_config.pidfile); + /*if (client_data.pidfile) - remove_pidfile has its own check */ + remove_pidfile(client_data.pidfile); return retval; } diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index 2618b12b5..42fe71a36 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h @@ -7,7 +7,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN -struct client_config_t { +struct client_data_t { uint8_t client_mac[6]; /* Our mac address */ IF_FEATURE_UDHCP_PORT(uint16_t port;) int ifindex; /* Index number of the interface to use */ @@ -31,11 +31,11 @@ struct client_config_t { } FIX_ALIASING; /* server_config sits in 1st half of bb_common_bufsiz1 */ -#define client_config (*(struct client_config_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE / 2])) +#define client_data (*(struct client_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE / 2])) #if ENABLE_FEATURE_UDHCP_PORT -#define CLIENT_PORT (client_config.port) -#define CLIENT_PORT6 (client_config.port) +#define CLIENT_PORT (client_data.port) +#define CLIENT_PORT6 (client_data.port) #else #define CLIENT_PORT 68 #define CLIENT_PORT6 546 diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h index 5c3bf5147..ba11d77e8 100644 --- a/networking/udhcp/dhcpd.h +++ b/networking/udhcp/dhcpd.h @@ -54,7 +54,7 @@ struct server_config_t { } FIX_ALIASING; #define server_config (*(struct server_config_t*)bb_common_bufsiz1) -/* client_config sits in 2nd half of bb_common_bufsiz1 */ +/* client_data sits in 2nd half of bb_common_bufsiz1 */ #if ENABLE_FEATURE_UDHCP_PORT #define SERVER_PORT (server_config.port) -- cgit v1.2.3-55-g6feb