aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-05-23 11:32:44 +0100
committerRon Yorston <rmy@pobox.com>2023-05-23 11:32:44 +0100
commit5adeafb91fe5d0fbfd2e4f773e64da9aa13d2f09 (patch)
tree5e739c2dd648786eeff06cc6a65fdff3d5ed8283
parentc2eb45989fcd59617884dc853743b5cc94b15935 (diff)
parent3e83699ce23400d75c7ddaa7ebfdec015177caa7 (diff)
downloadbusybox-w32-5adeafb91fe5d0fbfd2e4f773e64da9aa13d2f09.tar.gz
busybox-w32-5adeafb91fe5d0fbfd2e4f773e64da9aa13d2f09.tar.bz2
busybox-w32-5adeafb91fe5d0fbfd2e4f773e64da9aa13d2f09.zip
Merge branch 'busybox' into merge
-rw-r--r--Config.in11
-rw-r--r--Makefile.flags1
-rw-r--r--archival/cpio.c2
-rw-r--r--coreutils/factor.c71
-rw-r--r--coreutils/readlink.c9
-rw-r--r--examples/var_service/README2
-rw-r--r--networking/libiproute/ip_parse_common_args.c77
-rw-r--r--networking/libiproute/ipaddress.c10
-rw-r--r--networking/nslookup.c402
-rw-r--r--procps/nmeter.c18
-rw-r--r--shell/ash.c2
-rw-r--r--shell/hush.c9
12 files changed, 561 insertions, 53 deletions
diff --git a/Config.in b/Config.in
index 6b3d98b37..2da0a6aec 100644
--- a/Config.in
+++ b/Config.in
@@ -122,6 +122,17 @@ config LFS
122 programs that can benefit from large file support include dd, gzip, 122 programs that can benefit from large file support include dd, gzip,
123 cp, mount, tar. 123 cp, mount, tar.
124 124
125config TIME64
126 bool "Support 64bit wide time types"
127 default y
128 depends on LFS
129 help
130 Make times later than 2038 representable for several libc syscalls
131 (stat, clk_gettime etc.). Note this switch is specific to glibc
132 and has no effect on platforms that already use 64bit wide time types
133 (i.e. all 64bit archs and some selected 32bit archs (currently riscv
134 and x32)).
135
125config PAM 136config PAM
126 bool "Support PAM (Pluggable Authentication Modules)" 137 bool "Support PAM (Pluggable Authentication Modules)"
127 default n 138 default n
diff --git a/Makefile.flags b/Makefile.flags
index aa6565cf7..1a2923854 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -15,6 +15,7 @@ CPPFLAGS += \
15 -include include/autoconf.h \ 15 -include include/autoconf.h \
16 -D_GNU_SOURCE -DNDEBUG \ 16 -D_GNU_SOURCE -DNDEBUG \
17 $(if $(CONFIG_LFS),-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64) \ 17 $(if $(CONFIG_LFS),-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64) \
18 $(if $(CONFIG_TIME64),-D_TIME_BITS=64) \
18 -DMINGW_VER=$(squote)$(quote)$(MINGW_VER)$(quote)$(squote) \ 19 -DMINGW_VER=$(squote)$(quote)$(MINGW_VER)$(quote)$(squote) \
19 -DBB_VER=$(squote)$(quote)$(BB_VER)$(quote)$(squote) 20 -DBB_VER=$(squote)$(quote)$(BB_VER)$(quote)$(squote)
20 21
diff --git a/archival/cpio.c b/archival/cpio.c
index 388ba7c4f..167931bdb 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -62,7 +62,7 @@
62//usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]") 62//usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]")
63//usage: " [EXTR_FILE]..." 63//usage: " [EXTR_FILE]..."
64//usage:#define cpio_full_usage "\n\n" 64//usage:#define cpio_full_usage "\n\n"
65//usage: "Extract (-i) or list (-t) files from a cpio archive" 65//usage: "Extract (-i) or list (-t) files from a cpio archive on stdin"
66//usage: IF_FEATURE_CPIO_O(", or" 66//usage: IF_FEATURE_CPIO_O(", or"
67//usage: "\ntake file list from stdin and create an archive (-o)" 67//usage: "\ntake file list from stdin and create an archive (-o)"
68//usage: IF_FEATURE_CPIO_P(" or copy files (-p)") 68//usage: IF_FEATURE_CPIO_P(" or copy files (-p)")
diff --git a/coreutils/factor.c b/coreutils/factor.c
index a7a5a5030..f909a0d96 100644
--- a/coreutils/factor.c
+++ b/coreutils/factor.c
@@ -48,38 +48,40 @@ typedef unsigned long half_t;
48 * Larger wheels improve sieving only slightly, but quickly grow in size 48 * Larger wheels improve sieving only slightly, but quickly grow in size
49 * (adding just one prime, 13, results in 5766 element sieve). 49 * (adding just one prime, 13, results in 5766 element sieve).
50 */ 50 */
51#define R(a,b,c,d,e,f,g,h,i,j,A,B,C,D,E,F,G,H,I,J) \ 51#define R(a,b,c,d,e,f,g,h,i,j,A,B,C,D,E,F,G,H,I,J,x) \
52 (((uint64_t)(a<<0) | (b<<3) | (c<<6) | (d<<9) | (e<<12) | (f<<15) | (g<<18) | (h<<21) | (i<<24) | (j<<27)) << 1) | \ 52 (((uint64_t)(a<<0) | (b<<3) | (c<<6) | (d<<9) | (e<<12) | (f<<15) | (g<<18) | (h<<21) | (i<<24) | (j<<27)) << 1) | \
53 (((uint64_t)(A<<0) | (B<<3) | (C<<6) | (D<<9) | (E<<12) | (F<<15) | (G<<18) | (H<<21) | (I<<24) | (J<<27)) << 31) 53 (((uint64_t)(A<<0) | (B<<3) | (C<<6) | (D<<9) | (E<<12) | (F<<15) | (G<<18) | (H<<21) | (I<<24) | (J<<27)) << 31) | \
54#define P(a,b,c,d,e,f,g,h,i,j,A,B,C,D,E,F,G,H,I,J) \ 54 ((uint64_t)x << 61)
55#define P(a,b,c,d,e,f,g,h,i,j,A,B,C,D,E,F,G,H,I,J,x) \
55 R( (a/2),(b/2),(c/2),(d/2),(e/2),(f/2),(g/2),(h/2),(i/2),(j/2), \ 56 R( (a/2),(b/2),(c/2),(d/2),(e/2),(f/2),(g/2),(h/2),(i/2),(j/2), \
56 (A/2),(B/2),(C/2),(D/2),(E/2),(F/2),(G/2),(H/2),(I/2),(J/2) ) 57 (A/2),(B/2),(C/2),(D/2),(E/2),(F/2),(G/2),(H/2),(I/2),(J/2), \
58 (x/2) \
59 )
57static const uint64_t packed_wheel[] = { 60static const uint64_t packed_wheel[] = {
58 /*1, 2, 2, 4, 2,*/ 61 /* 1, 2, */
59 P( 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4), //01 62 P( 2, 4, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6),
60 P( 2, 4, 2, 4,14, 4, 6, 2,10, 2, 6, 6, 4, 2, 4, 6, 2,10, 2, 4), //02 63 P( 8, 4, 2, 4, 2, 4,14, 4, 6, 2,10, 2, 6, 6, 4, 2, 4, 6, 2,10, 2),
61 P( 2,12,10, 2, 4, 2, 4, 6, 2, 6, 4, 6, 6, 6, 2, 6, 4, 2, 6, 4), //03 64 P( 4, 2,12,10, 2, 4, 2, 4, 6, 2, 6, 4, 6, 6, 6, 2, 6, 4, 2, 6, 4),
62 P( 6, 8, 4, 2, 4, 6, 8, 6,10, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2), //04 65 P( 6, 8, 4, 2, 4, 6, 8, 6,10, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6),
63 P( 6, 4, 2, 6,10, 2,10, 2, 4, 2, 4, 6, 8, 4, 2, 4,12, 2, 6, 4), //05 66 P( 4, 2, 6,10, 2,10, 2, 4, 2, 4, 6, 8, 4, 2, 4,12, 2, 6, 4, 2, 6),
64 P( 2, 6, 4, 6,12, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6, 2, 6,10, 2), //06 67 P( 4, 6,12, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6, 2, 6,10, 2, 4, 6, 2),
65 P( 4, 6, 2, 6, 4, 2, 4, 2,10, 2,10, 2, 4, 6, 6, 2, 6, 6, 4, 6), //07 68 P( 6, 4, 2, 4, 2,10, 2,10, 2, 4, 6, 6, 2, 6, 6, 4, 6, 6, 2, 6, 4),
66 P( 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 6, 4, 8, 6, 4, 6, 2, 4, 6), //08 69 P( 2, 6, 4, 6, 8, 4, 2, 6, 4, 8, 6, 4, 6, 2, 4, 6, 8, 6, 4, 2,10),
67 P( 8, 6, 4, 2,10, 2, 6, 4, 2, 4, 2,10, 2,10, 2, 4, 2, 4, 8, 6), //09 70 P( 2, 6, 4, 2, 4, 2,10, 2,10, 2, 4, 2, 4, 8, 6, 4, 2, 4, 6, 6, 2),
68 P( 4, 2, 4, 6, 6, 2, 6, 4, 8, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4), //10 71 P( 6, 4, 8, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, 6, 6, 2, 6, 6, 4),
69 P( 6, 6, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2,10, 2,10, 2), //11 72 P( 2, 4, 6, 2, 6, 4, 2, 4, 2,10, 2,10, 2, 6, 4, 6, 2, 6, 4, 2, 4),
70 P( 6, 4, 6, 2, 6, 4, 2, 4, 6, 6, 8, 4, 2, 6,10, 8, 4, 2, 4, 2), //12 73 P( 6, 6, 8, 4, 2, 6,10, 8, 4, 2, 4, 2, 4, 8,10, 6, 2, 4, 8, 6, 6),
71 P( 4, 8,10, 6, 2, 4, 8, 6, 6, 4, 2, 4, 6, 2, 6, 4, 6, 2,10, 2), //13 74 P( 4, 2, 4, 6, 2, 6, 4, 6, 2,10, 2,10, 2, 4, 2, 4, 6, 2, 6, 4, 2),
72 P(10, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 6, 6, 4, 6, 8), //14 75 P( 4, 6, 6, 2, 6, 6, 6, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 8, 4, 6),
73 P( 4, 2, 4, 2, 4, 8, 6, 4, 8, 4, 6, 2, 6, 6, 4, 2, 4, 6, 8, 4), //15 76 P( 2, 6, 6, 4, 2, 4, 6, 8, 4, 2, 4, 2,10, 2,10, 2, 4, 2, 4, 6, 2),
74 P( 2, 4, 2,10, 2,10, 2, 4, 2, 4, 6, 2,10, 2, 4, 6, 8, 6, 4, 2), //16 77 P(10, 2, 4, 6, 8, 6, 4, 2, 6, 4, 6, 8, 4, 6, 2, 4, 8, 6, 4, 6, 2),
75 P( 6, 4, 6, 8, 4, 6, 2, 4, 8, 6, 4, 6, 2, 4, 6, 2, 6, 6, 4, 6), //17 78 P( 4, 6, 2, 6, 6, 4, 6, 6, 2, 6, 6, 4, 2,10, 2,10, 2, 4, 2, 4, 6),
76 P( 6, 2, 6, 6, 4, 2,10, 2,10, 2, 4, 2, 4, 6, 2, 6, 4, 2,10, 6), //18 79 P( 2, 6, 4, 2,10, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, 2,12, 6, 4),
77 P( 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, 2,12, 6, 4, 6, 2, 4, 6, 2), //19 80 P( 6, 2, 4, 6, 2,12, 4, 2, 4, 8, 6, 4, 2, 4, 2,10, 2,10, 6, 2, 4),
78 P(12, 4, 2, 4, 8, 6, 4, 2, 4, 2,10, 2,10, 6, 2, 4, 6, 2, 6, 4), //20 81 P( 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2,10, 6, 8, 6, 4, 2, 4, 8, 6),
79 P( 2, 4, 6, 6, 2, 6, 4, 2,10, 6, 8, 6, 4, 2, 4, 8, 6, 4, 6, 2), //21 82 P( 4, 6, 2, 4, 6, 2, 6, 6, 6, 4, 6, 2, 6, 4, 2, 4, 2,10,12, 2, 4),
80 P( 4, 6, 2, 6, 6, 6, 4, 6, 2, 6, 4, 2, 4, 2,10,12, 2, 4, 2,10), //22 83 P( 2,10, 2, 6, 4, 2, 4, 6, 6, 2,10, 2, 6, 4,14, 4, 2, 4, 2, 4, 8),
81 P( 2, 6, 4, 2, 4, 6, 6, 2,10, 2, 6, 4,14, 4, 2, 4, 2, 4, 8, 6), //23 84 P( 6, 4, 6, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4,12, 2,12),
82 P( 4, 6, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4,12, 2,12), //24
83}; 85};
84#undef P 86#undef P
85#undef R 87#undef R
@@ -93,8 +95,8 @@ static const uint64_t packed_wheel[] = {
93 * function old new delta 95 * function old new delta
94 * wheel_tab - 485 +485 96 * wheel_tab - 485 +485
95 * 3-bit-packed insanity: 97 * 3-bit-packed insanity:
96 * packed_wheel - 192 +192 98 * packed_wheel - 184 +184
97 * factor_main 108 171 +63 99 * factor_main 108 163 +55
98 */ 100 */
99static void unpack_wheel(void) 101static void unpack_wheel(void)
100{ 102{
@@ -104,10 +106,7 @@ static void unpack_wheel(void)
104 setup_common_bufsiz(); 106 setup_common_bufsiz();
105 wheel_tab[0] = 1; 107 wheel_tab[0] = 1;
106 wheel_tab[1] = 2; 108 wheel_tab[1] = 2;
107 wheel_tab[2] = 2; 109 p = &wheel_tab[2];
108 wheel_tab[3] = 4;
109 wheel_tab[4] = 2;
110 p = &wheel_tab[5];
111 for (i = 0; i < ARRAY_SIZE(packed_wheel); i++) { 110 for (i = 0; i < ARRAY_SIZE(packed_wheel); i++) {
112 uint64_t v = packed_wheel[i]; 111 uint64_t v = packed_wheel[i];
113 while ((v & 0xe) != 0) { 112 while ((v & 0xe) != 0) {
diff --git a/coreutils/readlink.c b/coreutils/readlink.c
index 0a9aa957e..e17fc3b1e 100644
--- a/coreutils/readlink.c
+++ b/coreutils/readlink.c
@@ -68,12 +68,11 @@ int readlink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
68int readlink_main(int argc UNUSED_PARAM, char **argv) 68int readlink_main(int argc UNUSED_PARAM, char **argv)
69{ 69{
70 char *buf; 70 char *buf;
71 char *fname;
72 unsigned opt; 71 unsigned opt;
73 72
73 /* -n must use bit 0 (see printf below) */
74 opt = getopt32(argv, "^" "n" IF_FEATURE_READLINK_FOLLOW("fvsq") 74 opt = getopt32(argv, "^" "n" IF_FEATURE_READLINK_FOLLOW("fvsq")
75 "\0" "=1"); 75 "\0" "=1");
76 fname = argv[optind];
77 76
78 /* compat: coreutils readlink reports errors silently via exit code */ 77 /* compat: coreutils readlink reports errors silently via exit code */
79 if (!(opt & 4)) /* not -v */ 78 if (!(opt & 4)) /* not -v */
@@ -81,14 +80,14 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)
81 80
82 /* NOFORK: only one alloc is allowed; must free */ 81 /* NOFORK: only one alloc is allowed; must free */
83 if (opt & 2) { /* -f */ 82 if (opt & 2) { /* -f */
84 buf = xmalloc_realpath_coreutils(fname); 83 buf = xmalloc_realpath_coreutils(argv[optind]);
85 } else { 84 } else {
86 buf = xmalloc_readlink_or_warn(fname); 85 buf = xmalloc_readlink_or_warn(argv[optind]);
87 } 86 }
88 87
89 if (!buf) 88 if (!buf)
90 return EXIT_FAILURE; 89 return EXIT_FAILURE;
91 printf((opt & 1) ? "%s" : "%s\n", buf); 90 printf("%s%s", buf, &"\n"[opt & 1]);
92 free(buf); 91 free(buf);
93 92
94 fflush_stdout_and_exit_SUCCESS(); 93 fflush_stdout_and_exit_SUCCESS();
diff --git a/examples/var_service/README b/examples/var_service/README
index 15a1bc9d2..02d987515 100644
--- a/examples/var_service/README
+++ b/examples/var_service/README
@@ -43,7 +43,7 @@ directory, running one child runsv process for the service in each
43subdirectory. A typical choice is to start an instance of runsvdir 43subdirectory. A typical choice is to start an instance of runsvdir
44which supervises services in subdirectories of /var/service/. 44which supervises services in subdirectories of /var/service/.
45 45
46If /var/service/log/ exists, runsv will supervise two services, 46If /var/service/SERVICE_DIR/log/ exists, runsv will supervise two services,
47and will connect stdout of main service to the stdin of log service. 47and will connect stdout of main service to the stdin of log service.
48This is primarily used for logging. 48This is primarily used for logging.
49 49
diff --git a/networking/libiproute/ip_parse_common_args.c b/networking/libiproute/ip_parse_common_args.c
index d693c54fa..eccd7e670 100644
--- a/networking/libiproute/ip_parse_common_args.c
+++ b/networking/libiproute/ip_parse_common_args.c
@@ -14,6 +14,83 @@
14#include "ip_common.h" /* #include "libbb.h" is inside */ 14#include "ip_common.h" /* #include "libbb.h" is inside */
15#include "utils.h" 15#include "utils.h"
16 16
17/* iproute2-5.17.0:
18-V, -Version
19 Print the version of the ip utility and exit.
20-h, -human, -human-readable
21 output statistics with human readable values followed by suffix.
22-b, -batch FILENAME
23 Read commands from provided file or standard input and invoke them.
24 First failure will cause termination of ip.
25-force Don't terminate ip on errors in batch mode. If there were any errors
26 during execution of the commands, the application return code will be
27 non zero.
28-s, -stats, -statistics
29 Output more information. If the option appears twice or more,
30 the amount of information increases. As a rule, the information
31 is statistics or some time values.
32-d, -details
33 Output more detailed information.
34-l, -loops COUNT
35 Specify maximum number of loops the 'ip address flush' logic will
36 attempt before giving up. The default is 10. Zero (0) means loop
37 until all addresses are removed.
38-f, -family FAMILY
39 Specifies the protocol family to use. The protocol family identifier
40 can be one of inet, inet6, bridge, mpls or link. If this option is
41 not present, the protocol family is guessed from other arguments.
42 If the rest of the command line does not give enough information
43 to guess the family, ip falls back to the default one, usually inet
44 or any. link is a special family identifier meaning that
45 no networking protocol is involved.
46-4 shortcut for -family inet.
47-6 shortcut for -family inet6.
48-B shortcut for -family bridge.
49-M shortcut for -family mpls.
50-0 shortcut for -family link.
51-o, -oneline
52 output each record on a single line, replacing line feeds with the '\'
53 character. This is convenient when you want to count records with wc(1)
54 or to grep(1) the output.
55-r, -resolve
56 use the system's name resolver to print DNS names instead of addresses.
57-n, -netns NETNS
58 switches ip to the specified network namespace NETNS. Actually it just
59 simplifies executing of:
60 ip netns exec NETNS ip [ OPTIONS ] OBJECT { COMMAND | help }
61 to
62 ip -n[etns] NETNS [ OPTIONS ] OBJECT { COMMAND | help }
63-N, -Numeric
64 Print the number of protocol, scope, dsfield, etc directly instead of
65 converting it to human readable name.
66-a, -all
67 executes specified command over all objects, it depends if command
68 supports this option.
69-c[color][={always|auto|never}
70 Configure color output. If parameter is omitted or always, color output
71 is enabled regardless of stdout state. If parameter is auto, stdout is
72 checked to be a terminal before enabling color output. If parameter is
73 never, color output is disabled. If specified multiple times, the last
74 one takes precedence. This flag is ignored if -json is also given.
75 Used color palette can be influenced by COLORFGBG environment variable.
76-t, -timestamp
77 display current time when using monitor option.
78-ts, -tshort
79 Like -timestamp, but use shorter format.
80-rc, -rcvbuf SIZE
81 Set the netlink socket receive buffer size, defaults to 1MB.
82-iec print human readable rates in IEC units (e.g. 1Ki = 1024).
83-br, -brief
84 Print only basic information in a tabular format for better readability.
85 This option is currently only supported by ip addr show , ip link show
86 & ip neigh show commands.
87-j, -json
88 Output results in JavaScript Object Notation (JSON).
89-p, -pretty
90 The default JSON format is compact and more efficient to parse but hard
91 for most users to read. This flag adds indentation for readability.
92*/
93
17family_t preferred_family = AF_UNSPEC; 94family_t preferred_family = AF_UNSPEC;
18smallint oneline; 95smallint oneline;
19char _SL_; 96char _SL_;
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index ecc3848ff..c8d77422c 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -44,7 +44,7 @@ struct filter_t {
44 int ifindex; 44 int ifindex;
45 family_t family; 45 family_t family;
46 smallint showqueue; 46 smallint showqueue;
47 smallint oneline; 47 /*smallint oneline; - redundant, global "oneline" flag is enough */
48 smallint up; 48 smallint up;
49 /* Misnomer. Does not mean "flushed something" */ 49 /* Misnomer. Does not mean "flushed something" */
50 /* More like "flush commands were constructed by print_addrinfo()" */ 50 /* More like "flush commands were constructed by print_addrinfo()" */
@@ -297,7 +297,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
297 if (n->nlmsg_type == RTM_DELADDR) 297 if (n->nlmsg_type == RTM_DELADDR)
298 printf("Deleted "); 298 printf("Deleted ");
299 299
300 if (G_filter.oneline) 300 if (/*G_filter.*/ oneline)
301 printf("%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); 301 printf("%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
302 if (ifa->ifa_family == AF_INET) 302 if (ifa->ifa_family == AF_INET)
303 printf(" inet "); 303 printf(" inet ");
@@ -427,10 +427,10 @@ static int FAST_FUNC store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr
427 return 0; 427 return 0;
428} 428}
429 429
430static void ipaddr_reset_filter(int _oneline) 430static void ipaddr_reset_filter(void /*int _oneline*/)
431{ 431{
432 memset(&G_filter, 0, sizeof(G_filter)); 432 memset(&G_filter, 0, sizeof(G_filter));
433 G_filter.oneline = _oneline; 433 /*G_filter.oneline = _oneline;*/
434} 434}
435 435
436/* Return value becomes exitcode. It's okay to not return at all */ 436/* Return value becomes exitcode. It's okay to not return at all */
@@ -444,7 +444,7 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
444 struct rtnl_handle rth; 444 struct rtnl_handle rth;
445 char *filter_dev = NULL; 445 char *filter_dev = NULL;
446 446
447 ipaddr_reset_filter(oneline); 447 ipaddr_reset_filter(/*oneline*/);
448 G_filter.showqueue = 1; 448 G_filter.showqueue = 1;
449 449
450 if (G_filter.family == AF_UNSPEC) 450 if (G_filter.family == AF_UNSPEC)
diff --git a/networking/nslookup.c b/networking/nslookup.c
index 6da97baf4..249083e24 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -34,16 +34,14 @@
34//usage: "Name: debian\n" 34//usage: "Name: debian\n"
35//usage: "Address: 127.0.0.1\n" 35//usage: "Address: 127.0.0.1\n"
36 36
37#if !ENABLE_FEATURE_NSLOOKUP_BIG
38
37#include <resolv.h> 39#include <resolv.h>
38#include <net/if.h> /* for IFNAMSIZ */
39//#include <arpa/inet.h> 40//#include <arpa/inet.h>
40//#include <netdb.h> 41//#include <netdb.h>
41#include "libbb.h" 42#include "libbb.h"
42#include "common_bufsiz.h" 43#include "common_bufsiz.h"
43 44
44
45#if !ENABLE_FEATURE_NSLOOKUP_BIG
46
47/* 45/*
48 * Mini nslookup implementation for busybox 46 * Mini nslookup implementation for busybox
49 * 47 *
@@ -248,12 +246,386 @@ int nslookup_main(int argc, char **argv)
248 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 246 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
249 */ 247 */
250 248
249#include "libbb.h"
250#include "common_bufsiz.h"
251
251#if 0 252#if 0
252# define dbg(...) fprintf(stderr, __VA_ARGS__) 253# define dbg(...) fprintf(stderr, __VA_ARGS__)
253#else 254#else
254# define dbg(...) ((void)0) 255# define dbg(...) ((void)0)
255#endif 256#endif
256 257
258/* Instead of using ancient libc DNS query support,
259 * we can carry our own, independent code.
260 * E.g. res_mkquery() loses
261 * three of its paramemters (they are unused!).
262 * Unfortunately, while it does eliminate
263 * ns_get16
264 * ns_get32
265 * ns_name_uncompress
266 * dn_skipname
267 * ns_skiprr
268 * ns_initparse
269 * ns_parserr
270 * libc functions from a static binary, libc versions of
271 * dn_expand and res_mkquery are still linked in
272 * - they are used by getnameinfo(). Each is ~230 bytes of code.
273 * This makes USE_LIBC_RESOLV = 0 code _bigger_ (by about 27 bytes),
274 * despite inlining and constant propagation.
275 */
276#define USE_LIBC_RESOLV 1
277
278#if USE_LIBC_RESOLV
279
280#include <resolv.h>
281
282#else
283
284#define RESOLVFUNC /*nothing*/
285#define BIGRESOLVFUNC /*nothing*/
286#define TINYRESOLVFUNC ALWAYS_INLINE
287
288/* This one is taken from musl 1.2.4 */
289
290#define NS_MAXDNAME 1025
291#define NS_INT32SZ 4
292#define NS_INT16SZ 2
293
294#define MAXDNAME NS_MAXDNAME
295
296typedef enum __ns_opcode {
297 ns_o_query = 0,
298} ns_opcode;
299typedef enum __ns_class {
300 ns_c_in = 1,
301} ns_class;
302typedef enum __ns_sect {
303 ns_s_qd = 0,
304 ns_s_zn = 0,
305 ns_s_an = 1,
306 ns_s_pr = 1,
307 ns_s_ns = 2,
308 ns_s_ud = 2,
309 ns_s_ar = 3,
310 ns_s_max = 4
311} ns_sect;
312typedef enum __ns_type {
313 ns_t_a = 1,
314 ns_t_ns = 2,
315 ns_t_cname = 5,
316 ns_t_soa = 6,
317 ns_t_ptr = 12,
318 ns_t_mx = 15,
319 ns_t_txt = 16,
320 ns_t_aaaa = 28,
321 ns_t_srv = 33,
322 ns_t_any = 255,
323} ns_type;
324#define QUERY ns_o_query
325#define T_A ns_t_a
326#define T_PTR ns_t_ptr
327#define T_AAAA ns_t_aaaa
328#define C_IN ns_c_in
329
330typedef struct __ns_msg {
331 const unsigned char *_msg, *_eom;
332 uint16_t _id, _flags, _counts[ns_s_max];
333 const unsigned char *_sections[ns_s_max];
334 ns_sect _sect;
335 int _rrnum;
336 const unsigned char *_msg_ptr;
337} ns_msg;
338#define ns_msg_id(handle) ((handle)._id + 0)
339#define ns_msg_base(handle) ((handle)._msg + 0)
340#define ns_msg_end(handle) ((handle)._eom + 0)
341#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
342#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
343#define ns_msg_getflag(handle, flag) \
344 (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
345
346typedef struct __ns_rr {
347 char name[NS_MAXDNAME];
348 uint16_t type;
349 uint16_t rr_class;
350 uint32_t ttl;
351 uint16_t rdlength;
352 const unsigned char *rdata;
353} ns_rr;
354#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
355#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
356#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
357#define ns_rr_ttl(rr) ((rr).ttl + 0)
358#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
359#define ns_rr_rdata(rr) ((rr).rdata + 0)
360
361typedef struct {
362 unsigned id :16;
363#if __BYTE_ORDER == __BIG_ENDIAN
364 unsigned qr: 1;
365 unsigned opcode: 4;
366 unsigned aa: 1;
367 unsigned tc: 1;
368 unsigned rd: 1;
369 unsigned ra: 1;
370 unsigned unused :1;
371 unsigned ad: 1;
372 unsigned cd: 1;
373 unsigned rcode :4;
374#else
375 unsigned rd :1;
376 unsigned tc :1;
377 unsigned aa :1;
378 unsigned opcode :4;
379 unsigned qr :1;
380 unsigned rcode :4;
381 unsigned cd: 1;
382 unsigned ad: 1;
383 unsigned unused :1;
384 unsigned ra :1;
385#endif
386 unsigned qdcount :16;
387 unsigned ancount :16;
388 unsigned nscount :16;
389 unsigned arcount :16;
390} HEADER;
391
392#define dn_ns_get16 bb_ns_get16
393static unsigned TINYRESOLVFUNC ns_get16(const unsigned char *cp)
394{
395 return cp[0]<<8 | cp[1];
396}
397#define ns_get32 bb_ns_get32
398static unsigned long TINYRESOLVFUNC ns_get32(const unsigned char *cp)
399{
400 return (unsigned)cp[0]<<24 | cp[1]<<16 | cp[2]<<8 | cp[3];
401}
402#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp)+=2)-2))
403#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp)+=4)-4))
404
405#define dn_expand bb_dn_expand
406static int BIGRESOLVFUNC dn_expand(const unsigned char *base, const unsigned char *end, const unsigned char *src, char *dest, int space)
407{
408 const unsigned char *p = src;
409 char *dend, *dbegin = dest;
410 int len = -1, i, j;
411 if (p==end || space <= 0) return -1;
412 dend = dest + (space > 254 ? 254 : space);
413 /* detect reference loop using an iteration counter */
414 for (i=0; i < end-base; i+=2) {
415 /* loop invariants: p<end, dest<dend */
416 if (*p & 0xc0) {
417 if (p+1==end) return -1;
418 j = ((p[0] & 0x3f) << 8) | p[1];
419 if (len < 0) len = p+2-src;
420 if (j >= end-base) return -1;
421 p = base+j;
422 } else if (*p) {
423 if (dest != dbegin) *dest++ = '.';
424 j = *p++;
425 if (j >= end-p || j >= dend-dest) return -1;
426 while (j--) *dest++ = *p++;
427 } else {
428 *dest = 0;
429 if (len < 0) len = p+1-src;
430 return len;
431 }
432 }
433 return -1;
434}
435
436#define ns_name_uncompress bb_ns_name_uncompress
437static int RESOLVFUNC ns_name_uncompress(const unsigned char *msg, const unsigned char *eom,
438 const unsigned char *src, char *dst, size_t dstsiz)
439{
440 int r;
441 r = dn_expand(msg, eom, src, dst, dstsiz);
442 if (r < 0) errno = EMSGSIZE;
443 return r;
444}
445
446#define dn_skipname bb_dn_skipname
447static int RESOLVFUNC dn_skipname(const unsigned char *s, const unsigned char *end)
448{
449 const unsigned char *p = s;
450 while (p < end)
451 if (!*p) return p-s+1;
452 else if (*p>=192)
453 if (p+1<end) return p-s+2;
454 else break;
455 else
456 if (end-p<*p+1) break;
457 else p += *p + 1;
458 return -1;
459}
460#define ns_skiprr bb_ns_skiprr
461static int BIGRESOLVFUNC ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count)
462{
463 const unsigned char *p = ptr;
464 int r;
465
466 while (count--) {
467 r = dn_skipname(p, eom);
468 if (r < 0) goto bad;
469 if (r + 2 * NS_INT16SZ > eom - p) goto bad;
470 p += r + 2 * NS_INT16SZ;
471 if (section != ns_s_qd) {
472 if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad;
473 p += NS_INT32SZ;
474 NS_GET16(r, p);
475 if (r > eom - p) goto bad;
476 p += r;
477 }
478 }
479 return p - ptr;
480bad:
481 errno = EMSGSIZE;
482 return -1;
483}
484
485#define ns_parserr bb_ns_parserr
486static int BIGRESOLVFUNC ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
487{
488 int r;
489
490 if (section < 0 || section >= ns_s_max) goto bad;
491 if (section != handle->_sect) {
492 handle->_sect = section;
493 handle->_rrnum = 0;
494 handle->_msg_ptr = handle->_sections[section];
495 }
496 if (rrnum == -1) rrnum = handle->_rrnum;
497 if (rrnum < 0 || rrnum >= handle->_counts[section]) goto bad;
498 if (rrnum < handle->_rrnum) {
499 handle->_rrnum = 0;
500 handle->_msg_ptr = handle->_sections[section];
501 }
502 if (rrnum > handle->_rrnum) {
503 r = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum);
504 if (r < 0) return -1;
505 handle->_msg_ptr += r;
506 handle->_rrnum = rrnum;
507 }
508 r = ns_name_uncompress(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME);
509 if (r < 0) return -1;
510 handle->_msg_ptr += r;
511 if (2 * NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
512 NS_GET16(rr->type, handle->_msg_ptr);
513 NS_GET16(rr->rr_class, handle->_msg_ptr);
514 if (section != ns_s_qd) {
515 if (NS_INT32SZ + NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
516 NS_GET32(rr->ttl, handle->_msg_ptr);
517 NS_GET16(rr->rdlength, handle->_msg_ptr);
518 if (rr->rdlength > handle->_eom - handle->_msg_ptr) goto size;
519 rr->rdata = handle->_msg_ptr;
520 handle->_msg_ptr += rr->rdlength;
521 } else {
522 rr->ttl = 0;
523 rr->rdlength = 0;
524 rr->rdata = NULL;
525 }
526 handle->_rrnum++;
527 if (handle->_rrnum > handle->_counts[section]) {
528 handle->_sect = section + 1;
529 if (handle->_sect == ns_s_max) {
530 handle->_rrnum = -1;
531 handle->_msg_ptr = NULL;
532 } else {
533 handle->_rrnum = 0;
534 }
535 }
536 return 0;
537bad:
538 errno = ENODEV;
539 return -1;
540size:
541 errno = EMSGSIZE;
542 return -1;
543}
544
545#define ns_initparse bb_ns_initparse
546static int BIGRESOLVFUNC ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
547{
548 int i, r;
549
550 handle->_msg = msg;
551 handle->_eom = msg + msglen;
552 if (msglen < (2 + ns_s_max) * NS_INT16SZ) goto bad;
553 NS_GET16(handle->_id, msg);
554 NS_GET16(handle->_flags, msg);
555 for (i = 0; i < ns_s_max; i++) NS_GET16(handle->_counts[i], msg);
556 for (i = 0; i < ns_s_max; i++) {
557 if (handle->_counts[i]) {
558 handle->_sections[i] = msg;
559 r = ns_skiprr(msg, handle->_eom, i, handle->_counts[i]);
560 if (r < 0) return -1;
561 msg += r;
562 } else {
563 handle->_sections[i] = NULL;
564 }
565 }
566 if (msg != handle->_eom) goto bad;
567 handle->_sect = ns_s_max;
568 handle->_rrnum = -1;
569 handle->_msg_ptr = NULL;
570 return 0;
571bad:
572 errno = EMSGSIZE;
573 return -1;
574}
575
576#define res_mkquery bb_res_mkquery
577static int RESOLVFUNC res_mkquery(int op, const char *dname, int class, int type,
578 const unsigned char *data UNUSED_PARAM, int datalen UNUSED_PARAM,
579 const unsigned char *newrr UNUSED_PARAM, unsigned char *buf, int buflen)
580{
581 int i, j;
582 unsigned char q[280];
583 size_t l = strnlen(dname, 255);
584 int n;
585
586 if (l && dname[l-1]=='.') l--;
587 if (l && dname[l-1]=='.') return -1;
588 n = 17+l+!!l;
589 if (l>253 || buflen<n || op>15u || class>255u || type>255u)
590 return -1;
591
592//TODO: why do we even have the q[] array? Use buf[] directly!
593 /* Construct query template - ID will be filled later */
594 memset(q, 0, n);
595 q[2] = op*8 + 1;
596 q[3] = 32; /* AD */
597 q[5] = 1;
598 memcpy((char *)q+13, dname, l);
599 for (i=13; q[i]; i=j+1) {
600 for (j=i; q[j] && q[j] != '.'; j++);
601 if (j-i-1u > 62u) return -1;
602 q[i-1] = j-i;
603 }
604 q[i+1] = type;
605 q[i+3] = class;
606#if 0
607//For some machines (here: a TP-Link RE200 powered by a MediaTek MT7620A)
608//the monotonic clock has a coarse resolution (here: 20us) and it can happen
609//that the requests for A and AAAA share the same transaction ID.
610
611//In that case the mapping from received responses to the sent queries
612//doesn't work and name resolution fails because the AAAA reply
613//is dropped as a duplicate reply to the A query.
614 /* Make a reasonably unpredictable id */
615 unsigned id;
616 struct timespec ts;
617 clock_gettime(CLOCK_REALTIME, &ts);
618 id = ts.tv_nsec + ((uint32_t)(ts.tv_nsec) >> 16);
619 q[0] = id/256;
620 q[1] = id;
621#endif
622 memcpy(buf, q, n);
623 return n;
624}
625
626#endif /* !USE_LIBC_RESOLV */
627
628
257struct ns { 629struct ns {
258 const char *name; 630 const char *name;
259 len_and_sockaddr *lsa; 631 len_and_sockaddr *lsa;
@@ -266,7 +638,12 @@ struct query {
266 unsigned qlen; 638 unsigned qlen;
267// unsigned latency; 639// unsigned latency;
268// uint8_t rcode; 640// uint8_t rcode;
269 unsigned char query[512]; 641 /* res_mkquery() balks on names > 253 chars.
642 * The formed query is 253+18 chars at max.
643 * Real hostnames are nowhere near that long anyway.
644 * Use of power-of-2 size means smaller code.
645 */
646 unsigned char query[512 - sizeof(int) - sizeof(char*)];
270// unsigned char reply[512]; 647// unsigned char reply[512];
271}; 648};
272 649
@@ -978,6 +1355,21 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
978 } 1355 }
979 } 1356 }
980 1357
1358 /* Ensure the Transaction IDs are unique.
1359 * See, for example, musl source of res_mkquery() where
1360 * it risks using current time (same value!) for ALL queries.
1361 */
1362 {
1363 struct timeval tv;
1364 unsigned id;
1365 xgettimeofday(&tv);
1366 id = tv.tv_sec + tv.tv_usec;
1367 for (rc = 0; rc < G.query_count; rc++) {
1368 G.query[rc].query[0] = id >> 8;
1369 G.query[rc].query[1] = id++;
1370 }
1371 }
1372
981 for (rc = 0; rc < G.serv_count;) { 1373 for (rc = 0; rc < G.serv_count;) {
982 int c; 1374 int c;
983 1375
diff --git a/procps/nmeter.c b/procps/nmeter.c
index e52c868df..4197174ba 100644
--- a/procps/nmeter.c
+++ b/procps/nmeter.c
@@ -985,6 +985,15 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
985 985
986 xgettimeofday(&G.start); 986 xgettimeofday(&G.start);
987 G.tv = G.start; 987 G.tv = G.start;
988
989 // Move back start of monotonic time a bit, to syncronize fractionals of %T and %t:
990 // nmeter -d500 '%6T %6t'
991 // 00:00:00.000161 12:32:07.500161
992 // 00:00:00.500282 12:32:08.000282
993 // 00:00:01.000286 12:32:08.500286
994 if (G.delta > 0)
995 G.start.tv_usec -= (G.start.tv_usec % (unsigned)G.delta);
996
988 while (1) { 997 while (1) {
989 collect_info(first); 998 collect_info(first);
990 put_c(G.final_char); 999 put_c(G.final_char);
@@ -999,6 +1008,15 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
999 int rem; 1008 int rem;
1000 // can be commented out, will sacrifice sleep time precision a bit 1009 // can be commented out, will sacrifice sleep time precision a bit
1001 xgettimeofday(&G.tv); 1010 xgettimeofday(&G.tv);
1011
1012 // TODO: nmeter -d10000 '%6T %6t'
1013 // 00:00:00.770333 12:34:44.770333
1014 // 00:00:06.000088 12:34:50.000088
1015 // 00:00:16.000094 12:35:00.000094
1016 // 00:00:26.000275 12:35:10.000275
1017 // we can't syncronize interval to start close to 10 seconds for both
1018 // %T and %t (as shown above), but what if there is only %T
1019 // in format string? Maybe sync _it_ instead of %t in this case?
1002 if (need_seconds) 1020 if (need_seconds)
1003 rem = G.delta - ((ullong)G.tv.tv_sec*1000000 + G.tv.tv_usec) % G.deltanz; 1021 rem = G.delta - ((ullong)G.tv.tv_sec*1000000 + G.tv.tv_usec) % G.deltanz;
1004 else 1022 else
diff --git a/shell/ash.c b/shell/ash.c
index 87df555dd..09e8725bf 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -8096,6 +8096,8 @@ subevalvar(char *start, char *str, int strloc,
8096 char *restart_detect = stackblock(); 8096 char *restart_detect = stackblock();
8097 if (quotes && *loc == '\\') { 8097 if (quotes && *loc == '\\') {
8098 STPUTC(CTLESC, expdest); 8098 STPUTC(CTLESC, expdest);
8099 if (stackblock() != restart_detect)
8100 goto restart;
8099 len++; 8101 len++;
8100 } 8102 }
8101 STPUTC(*loc, expdest); 8103 STPUTC(*loc, expdest);
diff --git a/shell/hush.c b/shell/hush.c
index f8951d084..810dafd35 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1429,6 +1429,7 @@ static void syntax_error_unterm_str(unsigned lineno UNUSED_PARAM, const char *s)
1429{ 1429{
1430 bb_error_msg("syntax error: unterminated %s", s); 1430 bb_error_msg("syntax error: unterminated %s", s);
1431//? source4.tests fails: in bash, echo ${^} in script does not terminate the script 1431//? source4.tests fails: in bash, echo ${^} in script does not terminate the script
1432// (but bash --posix, or if bash is run as "sh", does terminate in script, so maybe uncomment this?)
1432// die_if_script(); 1433// die_if_script();
1433} 1434}
1434 1435
@@ -7589,6 +7590,14 @@ static void parse_and_run_stream(struct in_str *inp, int end_trigger)
7589 } 7590 }
7590 /* Force prompt */ 7591 /* Force prompt */
7591 inp->p = NULL; 7592 inp->p = NULL;
7593 /* Clear "peeked" EOF. Without this,
7594 * $ { cmd }<Enter>
7595 * > ^D
7596 * hush: syntax error: unterminated {
7597 * exits interactive shell:
7598 */
7599 if (inp->peek_buf[0] == EOF)
7600 inp->peek_buf[0] = 0;
7592 /* This stream isn't empty */ 7601 /* This stream isn't empty */
7593 empty = 0; 7602 empty = 0;
7594 continue; 7603 continue;