diff options
87 files changed, 1253 insertions, 625 deletions
@@ -408,7 +408,7 @@ config FEATURE_SUID_CONFIG_QUIET | |||
408 | config SELINUX | 408 | config SELINUX |
409 | bool "Support NSA Security Enhanced Linux" | 409 | bool "Support NSA Security Enhanced Linux" |
410 | default n | 410 | default n |
411 | depends on PLATFORM_LINUX | 411 | select PLATFORM_LINUX |
412 | help | 412 | help |
413 | Enable support for SELinux in applets ls, ps, and id. Also provide | 413 | Enable support for SELinux in applets ls, ps, and id. Also provide |
414 | the option of compiling in SELinux applets. | 414 | the option of compiling in SELinux applets. |
diff --git a/applets/.gitignore b/applets/.gitignore index cc932fcc0..459938d67 100644 --- a/applets/.gitignore +++ b/applets/.gitignore | |||
@@ -1,2 +1,3 @@ | |||
1 | /applet_tables | 1 | /applet_tables |
2 | /usage | 2 | /usage |
3 | /usage_pod | ||
diff --git a/applets/Kbuild.src b/applets/Kbuild.src index 9b9808f25..b61239948 100644 --- a/applets/Kbuild.src +++ b/applets/Kbuild.src | |||
@@ -42,3 +42,6 @@ quiet_cmd_gen_applet_tables = GEN include/applet_tables.h | |||
42 | 42 | ||
43 | include/applet_tables.h: applets/applet_tables | 43 | include/applet_tables.h: applets/applet_tables |
44 | $(call cmd,gen_applet_tables) | 44 | $(call cmd,gen_applet_tables) |
45 | |||
46 | include/NUM_APPLETS.h: applets/applet_tables | ||
47 | $(call cmd,gen_applet_tables) | ||
diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 2bbab7641..0e977049d 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c | |||
@@ -99,8 +99,12 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle) | |||
99 | close(p[1]); | 99 | close(p[1]); |
100 | xdup2(p[0], STDIN_FILENO); | 100 | xdup2(p[0], STDIN_FILENO); |
101 | signal(SIGPIPE, SIG_DFL); | 101 | signal(SIGPIPE, SIG_DFL); |
102 | execl(DEFAULT_SHELL, DEFAULT_SHELL_SHORT_NAME, "-c", archive_handle->tar__to_command, NULL); | 102 | execl(archive_handle->tar__to_command_shell, |
103 | bb_perror_msg_and_die("can't execute '%s'", DEFAULT_SHELL); | 103 | archive_handle->tar__to_command_shell, |
104 | "-c", | ||
105 | archive_handle->tar__to_command, | ||
106 | NULL); | ||
107 | bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell); | ||
104 | } | 108 | } |
105 | close(p[0]); | 109 | close(p[0]); |
106 | /* Our caller is expected to do signal(SIGPIPE, SIG_IGN) | 110 | /* Our caller is expected to do signal(SIGPIPE, SIG_IGN) |
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 2e0332792..f73cd338e 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -18,6 +18,35 @@ typedef uint32_t aliased_uint32_t FIX_ALIASING; | |||
18 | typedef off_t aliased_off_t FIX_ALIASING; | 18 | typedef off_t aliased_off_t FIX_ALIASING; |
19 | 19 | ||
20 | 20 | ||
21 | const char* FAST_FUNC strip_unsafe_prefix(const char *str) | ||
22 | { | ||
23 | const char *cp = str; | ||
24 | while (1) { | ||
25 | char *cp2; | ||
26 | if (*cp == '/') { | ||
27 | cp++; | ||
28 | continue; | ||
29 | } | ||
30 | if (strncmp(cp, "/../"+1, 3) == 0) { | ||
31 | cp += 3; | ||
32 | continue; | ||
33 | } | ||
34 | cp2 = strstr(cp, "/../"); | ||
35 | if (!cp2) | ||
36 | break; | ||
37 | cp = cp2 + 4; | ||
38 | } | ||
39 | if (cp != str) { | ||
40 | static smallint warned = 0; | ||
41 | if (!warned) { | ||
42 | warned = 1; | ||
43 | bb_error_msg("removing leading '%.*s' from member names", | ||
44 | (int)(cp - str), str); | ||
45 | } | ||
46 | } | ||
47 | return cp; | ||
48 | } | ||
49 | |||
21 | /* NB: _DESTROYS_ str[len] character! */ | 50 | /* NB: _DESTROYS_ str[len] character! */ |
22 | static unsigned long long getOctal(char *str, int len) | 51 | static unsigned long long getOctal(char *str, int len) |
23 | { | 52 | { |
@@ -422,12 +451,9 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
422 | p_linkname = NULL; | 451 | p_linkname = NULL; |
423 | } | 452 | } |
424 | #endif | 453 | #endif |
425 | if (strncmp(file_header->name, "/../"+1, 3) == 0 | 454 | |
426 | || strstr(file_header->name, "/../") | 455 | /* Everything up to and including last ".." component is stripped */ |
427 | ) { | 456 | overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name)); |
428 | bb_error_msg_and_die("name with '..' encountered: '%s'", | ||
429 | file_header->name); | ||
430 | } | ||
431 | 457 | ||
432 | /* Strip trailing '/' in directories */ | 458 | /* Strip trailing '/' in directories */ |
433 | /* Must be done after mode is set as '/' is used to check if it's a directory */ | 459 | /* Must be done after mode is set as '/' is used to check if it's a directory */ |
diff --git a/archival/tar.c b/archival/tar.c index 74d6fca91..52f3c364c 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -397,17 +397,8 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb | |||
397 | 397 | ||
398 | DBG("writeFileToTarball('%s')", fileName); | 398 | DBG("writeFileToTarball('%s')", fileName); |
399 | 399 | ||
400 | /* Strip leading '/' (must be before memorizing hardlink's name) */ | 400 | /* Strip leading '/' and such (must be before memorizing hardlink's name) */ |
401 | header_name = fileName; | 401 | header_name = strip_unsafe_prefix(fileName); |
402 | while (header_name[0] == '/') { | ||
403 | static smallint warned; | ||
404 | |||
405 | if (!warned) { | ||
406 | bb_error_msg("removing leading '/' from member names"); | ||
407 | warned = 1; | ||
408 | } | ||
409 | header_name++; | ||
410 | } | ||
411 | 402 | ||
412 | if (header_name[0] == '\0') | 403 | if (header_name[0] == '\0') |
413 | return TRUE; | 404 | return TRUE; |
@@ -981,6 +972,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
981 | putenv((char*)"TAR_FILETYPE=f"); | 972 | putenv((char*)"TAR_FILETYPE=f"); |
982 | signal(SIGPIPE, SIG_IGN); | 973 | signal(SIGPIPE, SIG_IGN); |
983 | tar_handle->action_data = data_extract_to_command; | 974 | tar_handle->action_data = data_extract_to_command; |
975 | IF_FEATURE_TAR_TO_COMMAND(tar_handle->tar__to_command_shell = xstrdup(get_shell_name());) | ||
984 | } | 976 | } |
985 | 977 | ||
986 | if (opt & OPT_KEEP_OLD) | 978 | if (opt & OPT_KEEP_OLD) |
diff --git a/console-tools/Config.src b/console-tools/Config.src index cdb26800e..c65704478 100644 --- a/console-tools/Config.src +++ b/console-tools/Config.src | |||
@@ -10,7 +10,7 @@ INSERT | |||
10 | config CHVT | 10 | config CHVT |
11 | bool "chvt" | 11 | bool "chvt" |
12 | default y | 12 | default y |
13 | depends on PLATFORM_LINUX | 13 | select PLATFORM_LINUX |
14 | help | 14 | help |
15 | This program is used to change to another terminal. | 15 | This program is used to change to another terminal. |
16 | Example: chvt 4 (change to terminal /dev/tty4) | 16 | Example: chvt 4 (change to terminal /dev/tty4) |
@@ -18,7 +18,7 @@ config CHVT | |||
18 | config FGCONSOLE | 18 | config FGCONSOLE |
19 | bool "fgconsole" | 19 | bool "fgconsole" |
20 | default y | 20 | default y |
21 | depends on PLATFORM_LINUX | 21 | select PLATFORM_LINUX |
22 | help | 22 | help |
23 | This program prints active (foreground) console number. | 23 | This program prints active (foreground) console number. |
24 | 24 | ||
@@ -31,14 +31,14 @@ config CLEAR | |||
31 | config DEALLOCVT | 31 | config DEALLOCVT |
32 | bool "deallocvt" | 32 | bool "deallocvt" |
33 | default y | 33 | default y |
34 | depends on PLATFORM_LINUX | 34 | select PLATFORM_LINUX |
35 | help | 35 | help |
36 | This program deallocates unused virtual consoles. | 36 | This program deallocates unused virtual consoles. |
37 | 37 | ||
38 | config DUMPKMAP | 38 | config DUMPKMAP |
39 | bool "dumpkmap" | 39 | bool "dumpkmap" |
40 | default y | 40 | default y |
41 | depends on PLATFORM_LINUX | 41 | select PLATFORM_LINUX |
42 | help | 42 | help |
43 | This program dumps the kernel's keyboard translation table to | 43 | This program dumps the kernel's keyboard translation table to |
44 | stdout, in binary format. You can then use loadkmap to load it. | 44 | stdout, in binary format. You can then use loadkmap to load it. |
@@ -46,21 +46,21 @@ config DUMPKMAP | |||
46 | config KBD_MODE | 46 | config KBD_MODE |
47 | bool "kbd_mode" | 47 | bool "kbd_mode" |
48 | default y | 48 | default y |
49 | depends on PLATFORM_LINUX | 49 | select PLATFORM_LINUX |
50 | help | 50 | help |
51 | This program reports and sets keyboard mode. | 51 | This program reports and sets keyboard mode. |
52 | 52 | ||
53 | config LOADFONT | 53 | config LOADFONT |
54 | bool "loadfont" | 54 | bool "loadfont" |
55 | default y | 55 | default y |
56 | depends on PLATFORM_LINUX | 56 | select PLATFORM_LINUX |
57 | help | 57 | help |
58 | This program loads a console font from standard input. | 58 | This program loads a console font from standard input. |
59 | 59 | ||
60 | config LOADKMAP | 60 | config LOADKMAP |
61 | bool "loadkmap" | 61 | bool "loadkmap" |
62 | default y | 62 | default y |
63 | depends on PLATFORM_LINUX | 63 | select PLATFORM_LINUX |
64 | help | 64 | help |
65 | This program loads a keyboard translation table from | 65 | This program loads a keyboard translation table from |
66 | standard input. | 66 | standard input. |
@@ -68,7 +68,7 @@ config LOADKMAP | |||
68 | config OPENVT | 68 | config OPENVT |
69 | bool "openvt" | 69 | bool "openvt" |
70 | default y | 70 | default y |
71 | depends on PLATFORM_LINUX | 71 | select PLATFORM_LINUX |
72 | help | 72 | help |
73 | This program is used to start a command on an unused | 73 | This program is used to start a command on an unused |
74 | virtual terminal. | 74 | virtual terminal. |
@@ -100,7 +100,7 @@ config FEATURE_RESIZE_PRINT | |||
100 | config SETCONSOLE | 100 | config SETCONSOLE |
101 | bool "setconsole" | 101 | bool "setconsole" |
102 | default y | 102 | default y |
103 | depends on PLATFORM_LINUX | 103 | select PLATFORM_LINUX |
104 | help | 104 | help |
105 | This program redirects the system console to another device, | 105 | This program redirects the system console to another device, |
106 | like the current tty while logged in via telnet. | 106 | like the current tty while logged in via telnet. |
@@ -115,7 +115,7 @@ config FEATURE_SETCONSOLE_LONG_OPTIONS | |||
115 | config SETFONT | 115 | config SETFONT |
116 | bool "setfont" | 116 | bool "setfont" |
117 | default y | 117 | default y |
118 | depends on PLATFORM_LINUX | 118 | select PLATFORM_LINUX |
119 | help | 119 | help |
120 | Allows to load console screen map. Useful for i18n. | 120 | Allows to load console screen map. Useful for i18n. |
121 | 121 | ||
@@ -137,7 +137,7 @@ config DEFAULT_SETFONT_DIR | |||
137 | config SETKEYCODES | 137 | config SETKEYCODES |
138 | bool "setkeycodes" | 138 | bool "setkeycodes" |
139 | default y | 139 | default y |
140 | depends on PLATFORM_LINUX | 140 | select PLATFORM_LINUX |
141 | help | 141 | help |
142 | This program loads entries into the kernel's scancode-to-keycode | 142 | This program loads entries into the kernel's scancode-to-keycode |
143 | map, allowing unusual keyboards to generate usable keycodes. | 143 | map, allowing unusual keyboards to generate usable keycodes. |
@@ -145,14 +145,14 @@ config SETKEYCODES | |||
145 | config SETLOGCONS | 145 | config SETLOGCONS |
146 | bool "setlogcons" | 146 | bool "setlogcons" |
147 | default y | 147 | default y |
148 | depends on PLATFORM_LINUX | 148 | select PLATFORM_LINUX |
149 | help | 149 | help |
150 | This program redirects the output console of kernel messages. | 150 | This program redirects the output console of kernel messages. |
151 | 151 | ||
152 | config SHOWKEY | 152 | config SHOWKEY |
153 | bool "showkey" | 153 | bool "showkey" |
154 | default y | 154 | default y |
155 | depends on PLATFORM_LINUX | 155 | select PLATFORM_LINUX |
156 | help | 156 | help |
157 | Shows keys pressed. | 157 | Shows keys pressed. |
158 | 158 | ||
diff --git a/console-tools/openvt.c b/console-tools/openvt.c index 6e0b589a0..56f50c6cd 100644 --- a/console-tools/openvt.c +++ b/console-tools/openvt.c | |||
@@ -144,9 +144,7 @@ int openvt_main(int argc UNUSED_PARAM, char **argv) | |||
144 | 144 | ||
145 | if (!argv[0]) { | 145 | if (!argv[0]) { |
146 | argv--; | 146 | argv--; |
147 | argv[0] = getenv("SHELL"); | 147 | argv[0] = (char *) get_shell_name(); |
148 | if (!argv[0]) | ||
149 | argv[0] = (char *) DEFAULT_SHELL; | ||
150 | /*argv[1] = NULL; - already is */ | 148 | /*argv[1] = NULL; - already is */ |
151 | } | 149 | } |
152 | 150 | ||
diff --git a/console-tools/showkey.c b/console-tools/showkey.c index e7834f702..06df68bfd 100644 --- a/console-tools/showkey.c +++ b/console-tools/showkey.c | |||
@@ -56,37 +56,45 @@ int showkey_main(int argc UNUSED_PARAM, char **argv) | |||
56 | // FIXME: aks are all mutually exclusive | 56 | // FIXME: aks are all mutually exclusive |
57 | getopt32(argv, "aks"); | 57 | getopt32(argv, "aks"); |
58 | 58 | ||
59 | // get keyboard settings | ||
60 | xioctl(STDIN_FILENO, KDGKBMODE, &kbmode); | ||
61 | printf("kb mode was %s\n\nPress any keys. Program terminates %s\n\n", | ||
62 | kbmode == K_RAW ? "RAW" : | ||
63 | (kbmode == K_XLATE ? "XLATE" : | ||
64 | (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" : | ||
65 | (kbmode == K_UNICODE ? "UNICODE" : "UNKNOWN"))) | ||
66 | , (option_mask32 & OPT_a) ? "on EOF (ctrl-D)" : "10s after last keypress" | ||
67 | ); | ||
68 | |||
69 | // prepare for raw mode | 59 | // prepare for raw mode |
70 | xget1(&tio, &tio0); | 60 | xget1(&tio, &tio0); |
71 | // put stdin in raw mode | 61 | // put stdin in raw mode |
72 | xset1(&tio); | 62 | xset1(&tio); |
73 | 63 | ||
64 | #define press_keys "Press any keys, program terminates %s:\r\n\n" | ||
65 | |||
74 | if (option_mask32 & OPT_a) { | 66 | if (option_mask32 & OPT_a) { |
67 | // just read stdin char by char | ||
75 | unsigned char c; | 68 | unsigned char c; |
76 | 69 | ||
77 | // just read stdin char by char | 70 | printf(press_keys, "on EOF (ctrl-D)"); |
71 | |||
72 | // read and show byte values | ||
78 | while (1 == read(STDIN_FILENO, &c, 1)) { | 73 | while (1 == read(STDIN_FILENO, &c, 1)) { |
79 | printf("%3u 0%03o 0x%02x\r\n", c, c, c); | 74 | printf("%3u 0%03o 0x%02x\r\n", c, c, c); |
80 | if (04 /*CTRL-D*/ == c) | 75 | if (04 /*CTRL-D*/ == c) |
81 | break; | 76 | break; |
82 | } | 77 | } |
78 | |||
83 | } else { | 79 | } else { |
80 | // we assume a PC keyboard | ||
81 | xioctl(STDIN_FILENO, KDGKBMODE, &kbmode); | ||
82 | printf("Keyboard mode was %s.\r\n\n", | ||
83 | kbmode == K_RAW ? "RAW" : | ||
84 | (kbmode == K_XLATE ? "XLATE" : | ||
85 | (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" : | ||
86 | (kbmode == K_UNICODE ? "UNICODE" : "UNKNOWN"))) | ||
87 | ); | ||
88 | |||
84 | // set raw keyboard mode | 89 | // set raw keyboard mode |
85 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW)); | 90 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW)); |
86 | 91 | ||
87 | // we should exit on any signal; signals should interrupt read | 92 | // we should exit on any signal; signals should interrupt read |
88 | bb_signals_recursive_norestart(BB_FATAL_SIGS, record_signo); | 93 | bb_signals_recursive_norestart(BB_FATAL_SIGS, record_signo); |
89 | 94 | ||
95 | // inform user that program ends after time of inactivity | ||
96 | printf(press_keys, "10s after last keypress"); | ||
97 | |||
90 | // read and show scancodes | 98 | // read and show scancodes |
91 | while (!bb_got_signal) { | 99 | while (!bb_got_signal) { |
92 | char buf[18]; | 100 | char buf[18]; |
@@ -94,6 +102,7 @@ int showkey_main(int argc UNUSED_PARAM, char **argv) | |||
94 | 102 | ||
95 | // setup 10s watchdog | 103 | // setup 10s watchdog |
96 | alarm(10); | 104 | alarm(10); |
105 | |||
97 | // read scancodes | 106 | // read scancodes |
98 | n = read(STDIN_FILENO, buf, sizeof(buf)); | 107 | n = read(STDIN_FILENO, buf, sizeof(buf)); |
99 | i = 0; | 108 | i = 0; |
@@ -121,11 +130,13 @@ int showkey_main(int argc UNUSED_PARAM, char **argv) | |||
121 | } | 130 | } |
122 | puts("\r"); | 131 | puts("\r"); |
123 | } | 132 | } |
133 | |||
134 | // restore keyboard mode | ||
135 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode); | ||
124 | } | 136 | } |
125 | 137 | ||
126 | // restore keyboard and console settings | 138 | // restore console settings |
127 | xset1(&tio0); | 139 | xset1(&tio0); |
128 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode); | ||
129 | 140 | ||
130 | return EXIT_SUCCESS; | 141 | return EXIT_SUCCESS; |
131 | } | 142 | } |
diff --git a/coreutils/Config.src b/coreutils/Config.src index 6297f43a3..2769aa07d 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src | |||
@@ -594,7 +594,7 @@ config FEATURE_SPLIT_FANCY | |||
594 | config STAT | 594 | config STAT |
595 | bool "stat" | 595 | bool "stat" |
596 | default y | 596 | default y |
597 | depends on PLATFORM_LINUX # statfs() | 597 | select PLATFORM_LINUX # statfs() |
598 | help | 598 | help |
599 | display file or filesystem status. | 599 | display file or filesystem status. |
600 | 600 | ||
diff --git a/coreutils/chroot.c b/coreutils/chroot.c index b80a12ee0..5ac2e890e 100644 --- a/coreutils/chroot.c +++ b/coreutils/chroot.c | |||
@@ -23,11 +23,9 @@ int chroot_main(int argc UNUSED_PARAM, char **argv) | |||
23 | ++argv; | 23 | ++argv; |
24 | if (!*argv) { /* no 2nd param (PROG), use shell */ | 24 | if (!*argv) { /* no 2nd param (PROG), use shell */ |
25 | argv -= 2; | 25 | argv -= 2; |
26 | argv[0] = getenv("SHELL"); | 26 | argv[0] = (char *) get_shell_name(); |
27 | if (!argv[0]) { | 27 | argv[1] = (char *) "-i"; /* GNU coreutils 8.4 compat */ |
28 | argv[0] = (char *) DEFAULT_SHELL; | 28 | /*argv[2] = NULL; - already is */ |
29 | } | ||
30 | argv[1] = (char *) "-i"; | ||
31 | } | 29 | } |
32 | 30 | ||
33 | BB_EXECVP_or_die(argv); | 31 | BB_EXECVP_or_die(argv); |
diff --git a/coreutils/cksum.c b/coreutils/cksum.c index 7a37e6add..53fb87a78 100644 --- a/coreutils/cksum.c +++ b/coreutils/cksum.c | |||
@@ -38,6 +38,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv) | |||
38 | 38 | ||
39 | #define read_buf bb_common_bufsiz1 | 39 | #define read_buf bb_common_bufsiz1 |
40 | while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) { | 40 | while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) { |
41 | length += bytes_read; | ||
41 | crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table); | 42 | crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table); |
42 | } | 43 | } |
43 | close(fd); | 44 | close(fd); |
diff --git a/coreutils/date.c b/coreutils/date.c index d36ed83fd..497031991 100644 --- a/coreutils/date.c +++ b/coreutils/date.c | |||
@@ -42,7 +42,8 @@ | |||
42 | //config:config FEATURE_DATE_NANO | 42 | //config:config FEATURE_DATE_NANO |
43 | //config: bool "Support %[num]N nanosecond format specifier" | 43 | //config: bool "Support %[num]N nanosecond format specifier" |
44 | //config: default n | 44 | //config: default n |
45 | //config: depends on DATE && PLATFORM_LINUX # syscall(__NR_clock_gettime) | 45 | //config: depends on DATE # syscall(__NR_clock_gettime) |
46 | //config: select PLATFORM_LINUX | ||
46 | //config: help | 47 | //config: help |
47 | //config: Support %[num]N format specifier. Adds ~250 bytes of code. | 48 | //config: Support %[num]N format specifier. Adds ~250 bytes of code. |
48 | //config: | 49 | //config: |
diff --git a/coreutils/dd.c b/coreutils/dd.c index da205ec69..544ece051 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -409,5 +409,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
409 | out_status: | 409 | out_status: |
410 | dd_output_status(0); | 410 | dd_output_status(0); |
411 | 411 | ||
412 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
413 | free(obuf); | ||
414 | if (flags & FLAG_TWOBUFS) | ||
415 | free(ibuf); | ||
416 | } | ||
417 | |||
412 | return exitcode; | 418 | return exitcode; |
413 | } | 419 | } |
diff --git a/coreutils/ln.c b/coreutils/ln.c index ddad120d1..6da290c11 100644 --- a/coreutils/ln.c +++ b/coreutils/ln.c | |||
@@ -40,8 +40,12 @@ int ln_main(int argc, char **argv) | |||
40 | last = argv[argc - 1]; | 40 | last = argv[argc - 1]; |
41 | argv += optind; | 41 | argv += optind; |
42 | 42 | ||
43 | if (argc == optind + 1) { | 43 | if (!argv[1]) { |
44 | /* "ln PATH/TO/FILE" -> "ln PATH/TO/FILE FILE" */ | ||
44 | *--argv = last; | 45 | *--argv = last; |
46 | /* xstrdup is needed: "ln -s PATH/TO/FILE/" is equivalent to | ||
47 | * "ln -s PATH/TO/FILE/ FILE", not "ln -s PATH/TO/FILE FILE" | ||
48 | */ | ||
45 | last = bb_get_last_path_component_strip(xstrdup(last)); | 49 | last = bb_get_last_path_component_strip(xstrdup(last)); |
46 | } | 50 | } |
47 | 51 | ||
diff --git a/coreutils/ls.c b/coreutils/ls.c index 1afe28c8d..4a41db76a 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -1,6 +1,5 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * tiny-ls.c version 0.1.0: A minimalist 'ls' | ||
4 | * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com> | 3 | * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com> |
5 | * | 4 | * |
6 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 5 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
@@ -159,7 +158,7 @@ STYLE_MASK = STYLE_SINGLE, | |||
159 | 158 | ||
160 | /* which of the three times will be used */ | 159 | /* which of the three times will be used */ |
161 | TIME_CHANGE = (1 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, | 160 | TIME_CHANGE = (1 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, |
162 | TIME_ACCESS = (1 << 22) * ENABLE_FEATURE_LS_TIMESTAMPS, | 161 | TIME_ACCESS = (2 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, |
163 | TIME_MASK = (3 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, | 162 | TIME_MASK = (3 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, |
164 | 163 | ||
165 | /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ | 164 | /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ |
@@ -189,10 +188,11 @@ LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ | |||
189 | /* Not fully compatible - we show not only '/' but other chars too */ | 188 | /* Not fully compatible - we show not only '/' but other chars too */ |
190 | /* -SXvhTw GNU options, busybox optionally supports */ | 189 | /* -SXvhTw GNU options, busybox optionally supports */ |
191 | /* -T TABWIDTH is ignored (we don't use tabs on output) */ | 190 | /* -T TABWIDTH is ignored (we don't use tabs on output) */ |
192 | /* -K SELinux mandated options, busybox optionally supports */ | 191 | /* -KZ SELinux mandated options, busybox optionally supports */ |
192 | /* (coreutils 8.4 has no -K, remove it?) */ | ||
193 | /* -e I think we made this one up (looks similar to GNU --full-time) */ | 193 | /* -e I think we made this one up (looks similar to GNU --full-time) */ |
194 | /* Std opts we do not support: */ | 194 | /* We already used up all 32 bits, if we need to add more, candidates for removal: */ |
195 | /* -H Follow the links on command line only */ | 195 | /* -K, -T, -e (add --full-time instead) */ |
196 | static const char ls_options[] ALIGN1 = | 196 | static const char ls_options[] ALIGN1 = |
197 | "Cadil1gnsxQAk" /* 13 opts, total 13 */ | 197 | "Cadil1gnsxQAk" /* 13 opts, total 13 */ |
198 | IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ | 198 | IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ |
@@ -203,7 +203,7 @@ static const char ls_options[] ALIGN1 = | |||
203 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 28 */ | 203 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 28 */ |
204 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 29 */ | 204 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 29 */ |
205 | IF_FEATURE_AUTOWIDTH("T:w:") /* 2, 31 */ | 205 | IF_FEATURE_AUTOWIDTH("T:w:") /* 2, 31 */ |
206 | ; | 206 | /* with --color, we use all 32 bits */; |
207 | enum { | 207 | enum { |
208 | //OPT_C = (1 << 0), | 208 | //OPT_C = (1 << 0), |
209 | //OPT_a = (1 << 1), | 209 | //OPT_a = (1 << 1), |
@@ -234,8 +234,8 @@ enum { | |||
234 | OPTBIT_Z, /* 25 */ | 234 | OPTBIT_Z, /* 25 */ |
235 | OPTBIT_L = OPTBIT_K + 2 * ENABLE_SELINUX, | 235 | OPTBIT_L = OPTBIT_K + 2 * ENABLE_SELINUX, |
236 | OPTBIT_H, /* 27 */ | 236 | OPTBIT_H, /* 27 */ |
237 | OPTBIT_h = OPTBIT_L + 1 * ENABLE_FEATURE_LS_FOLLOWLINKS, | 237 | OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS, |
238 | OPTBIT_T = OPTBIT_h + 2 * ENABLE_FEATURE_HUMAN_READABLE, | 238 | OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE, |
239 | OPTBIT_w, /* 30 */ | 239 | OPTBIT_w, /* 30 */ |
240 | OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_AUTOWIDTH, | 240 | OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_AUTOWIDTH, |
241 | 241 | ||
@@ -268,13 +268,13 @@ static const uint32_t opt_flags[] = { | |||
268 | LIST_INO, /* i */ | 268 | LIST_INO, /* i */ |
269 | LIST_LONG | STYLE_LONG, /* l */ | 269 | LIST_LONG | STYLE_LONG, /* l */ |
270 | STYLE_SINGLE, /* 1 */ | 270 | STYLE_SINGLE, /* 1 */ |
271 | 0, /* g (don't show owner) - handled via OPT_g */ | 271 | LIST_LONG | STYLE_LONG, /* g (don't show owner) - handled via OPT_g. assumes l */ |
272 | LIST_ID_NUMERIC, /* n */ | 272 | LIST_ID_NUMERIC | LIST_LONG | STYLE_LONG, /* n (assumes l) */ |
273 | LIST_BLOCKS, /* s */ | 273 | LIST_BLOCKS, /* s */ |
274 | DISP_ROWS | STYLE_COLUMNAR, /* x */ | 274 | DISP_ROWS | STYLE_COLUMNAR, /* x */ |
275 | 0, /* Q (quote filename) - handled via OPT_Q */ | 275 | 0, /* Q (quote filename) - handled via OPT_Q */ |
276 | DISP_HIDDEN, /* A */ | 276 | DISP_HIDDEN, /* A */ |
277 | ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */ | 277 | ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */ |
278 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 278 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
279 | TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ | 279 | TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ |
280 | LIST_FULLTIME, /* e */ | 280 | LIST_FULLTIME, /* e */ |
@@ -295,8 +295,8 @@ static const uint32_t opt_flags[] = { | |||
295 | DISP_RECURSIVE, /* R */ | 295 | DISP_RECURSIVE, /* R */ |
296 | #endif | 296 | #endif |
297 | #if ENABLE_SELINUX | 297 | #if ENABLE_SELINUX |
298 | LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ | 298 | LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME|STYLE_SINGLE, /* K */ |
299 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */ | 299 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT|STYLE_SINGLE, /* Z */ |
300 | #endif | 300 | #endif |
301 | (1U << 31) | 301 | (1U << 31) |
302 | /* options after Z are not processed through opt_flags */ | 302 | /* options after Z are not processed through opt_flags */ |
@@ -682,19 +682,28 @@ static NOINLINE unsigned list_single(const struct dnode *dn) | |||
682 | 682 | ||
683 | if (all_fmt & LIST_INO) | 683 | if (all_fmt & LIST_INO) |
684 | column += printf("%7llu ", (long long) dn->dstat.st_ino); | 684 | column += printf("%7llu ", (long long) dn->dstat.st_ino); |
685 | //TODO: -h should affect -s too: | ||
685 | if (all_fmt & LIST_BLOCKS) | 686 | if (all_fmt & LIST_BLOCKS) |
686 | #if ENABLE_PLATFORM_MINGW32 | 687 | #if ENABLE_PLATFORM_MINGW32 |
687 | /* MinGW does not have st_blocks */ | 688 | /* MinGW does not have st_blocks */ |
688 | column += printf("%4"OFF_FMT"u ", (off_t)0); | 689 | column += printf("%6"OFF_FMT"u ", (off_t)0); |
689 | #else | 690 | #else |
690 | column += printf("%4"OFF_FMT"u ", (off_t) (dn->dstat.st_blocks >> 1)); | 691 | column += printf("%6"OFF_FMT"u ", (off_t) (dn->dstat.st_blocks >> 1)); |
691 | #endif | 692 | #endif |
692 | if (all_fmt & LIST_MODEBITS) | 693 | if (all_fmt & LIST_MODEBITS) |
693 | column += printf("%-10s ", (char *) bb_mode_string(dn->dstat.st_mode)); | 694 | column += printf("%-10s ", (char *) bb_mode_string(dn->dstat.st_mode)); |
694 | if (all_fmt & LIST_NLINKS) | 695 | if (all_fmt & LIST_NLINKS) |
695 | column += printf("%4lu ", (long) dn->dstat.st_nlink); | 696 | column += printf("%4lu ", (long) dn->dstat.st_nlink); |
697 | if (all_fmt & LIST_ID_NUMERIC) { | ||
698 | if (option_mask32 & OPT_g) | ||
699 | column += printf("%-8u ", (int) dn->dstat.st_gid); | ||
700 | else | ||
701 | column += printf("%-8u %-8u ", | ||
702 | (int) dn->dstat.st_uid, | ||
703 | (int) dn->dstat.st_gid); | ||
704 | } | ||
696 | #if ENABLE_FEATURE_LS_USERNAME | 705 | #if ENABLE_FEATURE_LS_USERNAME |
697 | if (all_fmt & LIST_ID_NAME) { | 706 | else if (all_fmt & LIST_ID_NAME) { |
698 | if (option_mask32 & OPT_g) { | 707 | if (option_mask32 & OPT_g) { |
699 | column += printf("%-8.8s ", | 708 | column += printf("%-8.8s ", |
700 | get_cached_groupname(dn->dstat.st_gid)); | 709 | get_cached_groupname(dn->dstat.st_gid)); |
@@ -705,14 +714,6 @@ static NOINLINE unsigned list_single(const struct dnode *dn) | |||
705 | } | 714 | } |
706 | } | 715 | } |
707 | #endif | 716 | #endif |
708 | if (all_fmt & LIST_ID_NUMERIC) { | ||
709 | if (option_mask32 & OPT_g) | ||
710 | column += printf("%-8u ", (int) dn->dstat.st_gid); | ||
711 | else | ||
712 | column += printf("%-8u %-8u ", | ||
713 | (int) dn->dstat.st_uid, | ||
714 | (int) dn->dstat.st_gid); | ||
715 | } | ||
716 | if (all_fmt & LIST_SIZE) { | 717 | if (all_fmt & LIST_SIZE) { |
717 | if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) { | 718 | if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) { |
718 | column += printf("%4u, %3u ", | 719 | column += printf("%4u, %3u ", |
@@ -739,9 +740,12 @@ static NOINLINE unsigned list_single(const struct dnode *dn) | |||
739 | ttime = dn->dstat.st_ctime; | 740 | ttime = dn->dstat.st_ctime; |
740 | filetime = ctime(&ttime); | 741 | filetime = ctime(&ttime); |
741 | /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */ | 742 | /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */ |
742 | if (all_fmt & LIST_FULLTIME) | 743 | if (all_fmt & LIST_FULLTIME) { /* -e */ |
744 | /* Note: coreutils 8.4 ls --full-time prints: | ||
745 | * 2009-07-13 17:49:27.000000000 +0200 | ||
746 | */ | ||
743 | column += printf("%.24s ", filetime); | 747 | column += printf("%.24s ", filetime); |
744 | else { /* LIST_DATE_TIME */ | 748 | } else { /* LIST_DATE_TIME */ |
745 | /* current_time_t ~== time(NULL) */ | 749 | /* current_time_t ~== time(NULL) */ |
746 | time_t age = current_time_t - ttime; | 750 | time_t age = current_time_t - ttime; |
747 | printf("%.6s ", filetime + 4); /* "Jun 30" */ | 751 | printf("%.6s ", filetime + 4); /* "Jun 30" */ |
@@ -1049,7 +1053,8 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1049 | 1053 | ||
1050 | init_unicode(); | 1054 | init_unicode(); |
1051 | 1055 | ||
1052 | all_fmt = ENABLE_FEATURE_LS_SORTFILES * SORT_NAME; | 1056 | if (ENABLE_FEATURE_LS_SORTFILES) |
1057 | all_fmt = SORT_NAME; | ||
1053 | 1058 | ||
1054 | #if ENABLE_FEATURE_AUTOWIDTH | 1059 | #if ENABLE_FEATURE_AUTOWIDTH |
1055 | /* obtain the terminal width */ | 1060 | /* obtain the terminal width */ |
@@ -1090,14 +1095,12 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1090 | if (flags & TIME_MASK) | 1095 | if (flags & TIME_MASK) |
1091 | all_fmt &= ~TIME_MASK; | 1096 | all_fmt &= ~TIME_MASK; |
1092 | 1097 | ||
1093 | if (flags & LIST_CONTEXT) | ||
1094 | all_fmt |= STYLE_SINGLE; | ||
1095 | all_fmt |= flags; | 1098 | all_fmt |= flags; |
1096 | } | 1099 | } |
1097 | } | 1100 | } |
1098 | 1101 | ||
1099 | #if ENABLE_FEATURE_LS_COLOR | 1102 | #if ENABLE_FEATURE_LS_COLOR |
1100 | /* find color bit value - last position for short getopt */ | 1103 | /* set show_color = 1/0 */ |
1101 | if (ENABLE_FEATURE_LS_COLOR_IS_DEFAULT && isatty(STDOUT_FILENO)) { | 1104 | if (ENABLE_FEATURE_LS_COLOR_IS_DEFAULT && isatty(STDOUT_FILENO)) { |
1102 | char *p = getenv("LS_COLORS"); | 1105 | char *p = getenv("LS_COLORS"); |
1103 | /* LS_COLORS is unset, or (not empty && not "none") ? */ | 1106 | /* LS_COLORS is unset, or (not empty && not "none") ? */ |
@@ -1130,11 +1133,8 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1130 | if (all_fmt & TIME_ACCESS) | 1133 | if (all_fmt & TIME_ACCESS) |
1131 | all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME; | 1134 | all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME; |
1132 | } | 1135 | } |
1133 | if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */ | 1136 | if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* not -l? */ |
1134 | all_fmt &= ~(LIST_ID_NUMERIC|LIST_ID_NAME|LIST_FULLTIME); | 1137 | all_fmt &= ~(LIST_ID_NUMERIC|LIST_ID_NAME|LIST_FULLTIME); |
1135 | if (ENABLE_FEATURE_LS_USERNAME) | ||
1136 | if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC)) | ||
1137 | all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ | ||
1138 | 1138 | ||
1139 | /* choose a display format if one was not already specified by an option */ | 1139 | /* choose a display format if one was not already specified by an option */ |
1140 | if (!(all_fmt & STYLE_MASK)) | 1140 | if (!(all_fmt & STYLE_MASK)) |
@@ -1153,7 +1153,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1153 | do { | 1153 | do { |
1154 | cur = my_stat(*argv, *argv, | 1154 | cur = my_stat(*argv, *argv, |
1155 | /* follow links on command line unless -l, -s or -F: */ | 1155 | /* follow links on command line unless -l, -s or -F: */ |
1156 | !((all_fmt & (STYLE_LONG|LIST_BLOCKS)) || (option_mask32 & OPT_F)) | 1156 | !((all_fmt & STYLE_MASK) == STYLE_LONG |
1157 | || (all_fmt & LIST_BLOCKS) | ||
1158 | || (option_mask32 & OPT_F) | ||
1159 | ) | ||
1157 | /* ... or if -H: */ | 1160 | /* ... or if -H: */ |
1158 | || (option_mask32 & OPT_H) | 1161 | || (option_mask32 & OPT_H) |
1159 | ); | 1162 | ); |
diff --git a/coreutils/printenv.c b/coreutils/printenv.c index 33be5c096..d0fb71636 100644 --- a/coreutils/printenv.c +++ b/coreutils/printenv.c | |||
@@ -19,9 +19,14 @@ int printenv_main(int argc UNUSED_PARAM, char **argv) | |||
19 | 19 | ||
20 | /* no variables specified, show whole env */ | 20 | /* no variables specified, show whole env */ |
21 | if (!argv[1]) { | 21 | if (!argv[1]) { |
22 | int e = 0; | 22 | char **e = environ; |
23 | while (environ[e]) | 23 | |
24 | puts(environ[e++]); | 24 | /* environ can be NULL! (for example, after clearenv()) |
25 | * Check for that: | ||
26 | */ | ||
27 | if (e) | ||
28 | while (*e) | ||
29 | puts(*e++); | ||
25 | } else { | 30 | } else { |
26 | /* search for specified variables and print them out if found */ | 31 | /* search for specified variables and print them out if found */ |
27 | char *arg, *env; | 32 | char *arg, *env; |
diff --git a/coreutils/split.c b/coreutils/split.c index db5a1727a..79316ed74 100644 --- a/coreutils/split.c +++ b/coreutils/split.c | |||
@@ -32,7 +32,7 @@ static char *next_file(char *old, unsigned suffix_len) | |||
32 | unsigned i = 1; | 32 | unsigned i = 1; |
33 | char *curr; | 33 | char *curr; |
34 | 34 | ||
35 | do { | 35 | while (1) { |
36 | curr = old + end - i; | 36 | curr = old + end - i; |
37 | if (*curr < 'z') { | 37 | if (*curr < 'z') { |
38 | *curr += 1; | 38 | *curr += 1; |
@@ -43,7 +43,7 @@ static char *next_file(char *old, unsigned suffix_len) | |||
43 | return NULL; | 43 | return NULL; |
44 | } | 44 | } |
45 | *curr = 'a'; | 45 | *curr = 'a'; |
46 | } while (1); | 46 | } |
47 | 47 | ||
48 | return old; | 48 | return old; |
49 | } | 49 | } |
diff --git a/coreutils/test.c b/coreutils/test.c index caecd7d02..cb15ed725 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -45,7 +45,7 @@ | |||
45 | /* This is a NOFORK applet. Be very careful! */ | 45 | /* This is a NOFORK applet. Be very careful! */ |
46 | 46 | ||
47 | /* test_main() is called from shells, and we need to be extra careful here. | 47 | /* test_main() is called from shells, and we need to be extra careful here. |
48 | * This is true regardless of PREFER_APPLETS and STANDALONE_SHELL | 48 | * This is true regardless of PREFER_APPLETS and SH_STANDALONE |
49 | * state. */ | 49 | * state. */ |
50 | 50 | ||
51 | /* test(1) accepts the following grammar: | 51 | /* test(1) accepts the following grammar: |
diff --git a/coreutils/tr.c b/coreutils/tr.c index 21d77ef95..5b2b9a9a4 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c | |||
@@ -324,5 +324,11 @@ int tr_main(int argc UNUSED_PARAM, char **argv) | |||
324 | str2[out_index++] = last = coded; | 324 | str2[out_index++] = last = coded; |
325 | } | 325 | } |
326 | 326 | ||
327 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
328 | free(vector); | ||
329 | free(str2); | ||
330 | free(str1); | ||
331 | } | ||
332 | |||
327 | return EXIT_SUCCESS; | 333 | return EXIT_SUCCESS; |
328 | } | 334 | } |
diff --git a/docs/.gitignore b/docs/.gitignore index 11d616360..3d1c5bd8a 100644 --- a/docs/.gitignore +++ b/docs/.gitignore | |||
@@ -1,4 +1,5 @@ | |||
1 | /busybox.1 | 1 | /busybox.1 |
2 | /BusyBox.html | 2 | /BusyBox.html |
3 | /busybox.net | ||
3 | /BusyBox.txt | 4 | /BusyBox.txt |
4 | /busybox.pod | 5 | /busybox.pod |
diff --git a/e2fsprogs/Config.src b/e2fsprogs/Config.src index 6043e9b57..743e1e11f 100644 --- a/e2fsprogs/Config.src +++ b/e2fsprogs/Config.src | |||
@@ -33,7 +33,7 @@ config FSCK | |||
33 | config LSATTR | 33 | config LSATTR |
34 | bool "lsattr" | 34 | bool "lsattr" |
35 | default y | 35 | default y |
36 | depends on PLATFORM_LINUX | 36 | select PLATFORM_LINUX |
37 | help | 37 | help |
38 | lsattr lists the file attributes on a second extended file system. | 38 | lsattr lists the file attributes on a second extended file system. |
39 | 39 | ||
diff --git a/findutils/xargs.c b/findutils/xargs.c index 0ec80f809..967737133 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -15,10 +15,6 @@ | |||
15 | * http://www.opengroup.org/onlinepubs/007904975/utilities/xargs.html | 15 | * http://www.opengroup.org/onlinepubs/007904975/utilities/xargs.html |
16 | */ | 16 | */ |
17 | 17 | ||
18 | //applet:IF_XARGS(APPLET_NOEXEC(xargs, xargs, BB_DIR_USR_BIN, BB_SUID_DROP, xargs)) | ||
19 | |||
20 | //kbuild:lib-$(CONFIG_XARGS) += xargs.o | ||
21 | |||
22 | //config:config XARGS | 18 | //config:config XARGS |
23 | //config: bool "xargs" | 19 | //config: bool "xargs" |
24 | //config: default y | 20 | //config: default y |
@@ -58,6 +54,10 @@ | |||
58 | //config: instead of whitespace, and the quotes and backslash | 54 | //config: instead of whitespace, and the quotes and backslash |
59 | //config: are not special. | 55 | //config: are not special. |
60 | 56 | ||
57 | //applet:IF_XARGS(APPLET_NOEXEC(xargs, xargs, BB_DIR_USR_BIN, BB_SUID_DROP, xargs)) | ||
58 | |||
59 | //kbuild:lib-$(CONFIG_XARGS) += xargs.o | ||
60 | |||
61 | #include "libbb.h" | 61 | #include "libbb.h" |
62 | 62 | ||
63 | /* This is a NOEXEC applet. Be very careful! */ | 63 | /* This is a NOEXEC applet. Be very careful! */ |
@@ -89,7 +89,9 @@ struct globals { | |||
89 | int idx; | 89 | int idx; |
90 | } FIX_ALIASING; | 90 | } FIX_ALIASING; |
91 | #define G (*(struct globals*)&bb_common_bufsiz1) | 91 | #define G (*(struct globals*)&bb_common_bufsiz1) |
92 | #define INIT_G() do { } while (0) | 92 | #define INIT_G() do { \ |
93 | G.eof_str = NULL; /* need to clear by hand because we are NOEXEC applet */ \ | ||
94 | } while (0) | ||
93 | 95 | ||
94 | 96 | ||
95 | /* | 97 | /* |
@@ -412,7 +414,12 @@ int xargs_main(int argc, char **argv) | |||
412 | 414 | ||
413 | INIT_G(); | 415 | INIT_G(); |
414 | 416 | ||
415 | G.eof_str = NULL; | 417 | #if ENABLE_DESKTOP && ENABLE_LONG_OPTS |
418 | /* For example, Fedora's build system uses --no-run-if-empty */ | ||
419 | applet_long_options = | ||
420 | "no-run-if-empty\0" No_argument "r" | ||
421 | ; | ||
422 | #endif | ||
416 | opt = getopt32(argv, OPTION_STR, &max_args, &max_chars, &G.eof_str, &G.eof_str); | 423 | opt = getopt32(argv, OPTION_STR, &max_args, &max_chars, &G.eof_str, &G.eof_str); |
417 | 424 | ||
418 | /* -E ""? You may wonder why not just omit -E? | 425 | /* -E ""? You may wonder why not just omit -E? |
diff --git a/include/.gitignore b/include/.gitignore index f0ce546cf..9d9b6c499 100644 --- a/include/.gitignore +++ b/include/.gitignore | |||
@@ -1,6 +1,10 @@ | |||
1 | /config | 1 | /config |
2 | 2 | ||
3 | /applets.h | ||
3 | /applet_tables.h | 4 | /applet_tables.h |
4 | /autoconf.h | 5 | /autoconf.h |
6 | /bbconfigopts_bz2.h | ||
5 | /bbconfigopts.h | 7 | /bbconfigopts.h |
8 | /NUM_APPLETS.h | ||
6 | /usage_compressed.h | 9 | /usage_compressed.h |
10 | /usage.h | ||
diff --git a/include/archive.h b/include/archive.h index 49c478728..b139dc5be 100644 --- a/include/archive.h +++ b/include/archive.h | |||
@@ -84,6 +84,7 @@ typedef struct archive_handle_t { | |||
84 | # endif | 84 | # endif |
85 | #if ENABLE_FEATURE_TAR_TO_COMMAND | 85 | #if ENABLE_FEATURE_TAR_TO_COMMAND |
86 | char* tar__to_command; | 86 | char* tar__to_command; |
87 | const char* tar__to_command_shell; | ||
87 | #endif | 88 | #endif |
88 | # if ENABLE_FEATURE_TAR_SELINUX | 89 | # if ENABLE_FEATURE_TAR_SELINUX |
89 | char* tar__global_sctx; | 90 | char* tar__global_sctx; |
@@ -159,37 +160,39 @@ typedef struct unpack_info_t { | |||
159 | time_t mtime; | 160 | time_t mtime; |
160 | } unpack_info_t; | 161 | } unpack_info_t; |
161 | 162 | ||
162 | extern archive_handle_t *init_handle(void) FAST_FUNC; | 163 | archive_handle_t *init_handle(void) FAST_FUNC; |
163 | 164 | ||
164 | extern char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC; | 165 | char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC; |
165 | extern char filter_accept_list(archive_handle_t *archive_handle) FAST_FUNC; | 166 | char filter_accept_list(archive_handle_t *archive_handle) FAST_FUNC; |
166 | extern char filter_accept_list_reassign(archive_handle_t *archive_handle) FAST_FUNC; | 167 | char filter_accept_list_reassign(archive_handle_t *archive_handle) FAST_FUNC; |
167 | extern char filter_accept_reject_list(archive_handle_t *archive_handle) FAST_FUNC; | 168 | char filter_accept_reject_list(archive_handle_t *archive_handle) FAST_FUNC; |
168 | 169 | ||
169 | extern void unpack_ar_archive(archive_handle_t *ar_archive) FAST_FUNC; | 170 | void unpack_ar_archive(archive_handle_t *ar_archive) FAST_FUNC; |
170 | 171 | ||
171 | extern void data_skip(archive_handle_t *archive_handle) FAST_FUNC; | 172 | void data_skip(archive_handle_t *archive_handle) FAST_FUNC; |
172 | extern void data_extract_all(archive_handle_t *archive_handle) FAST_FUNC; | 173 | void data_extract_all(archive_handle_t *archive_handle) FAST_FUNC; |
173 | extern void data_extract_to_stdout(archive_handle_t *archive_handle) FAST_FUNC; | 174 | void data_extract_to_stdout(archive_handle_t *archive_handle) FAST_FUNC; |
174 | extern void data_extract_to_command(archive_handle_t *archive_handle) FAST_FUNC; | 175 | void data_extract_to_command(archive_handle_t *archive_handle) FAST_FUNC; |
175 | 176 | ||
176 | extern void header_skip(const file_header_t *file_header) FAST_FUNC; | 177 | void header_skip(const file_header_t *file_header) FAST_FUNC; |
177 | extern void header_list(const file_header_t *file_header) FAST_FUNC; | 178 | void header_list(const file_header_t *file_header) FAST_FUNC; |
178 | extern void header_verbose_list(const file_header_t *file_header) FAST_FUNC; | 179 | void header_verbose_list(const file_header_t *file_header) FAST_FUNC; |
179 | 180 | ||
180 | extern char get_header_ar(archive_handle_t *archive_handle) FAST_FUNC; | 181 | char get_header_ar(archive_handle_t *archive_handle) FAST_FUNC; |
181 | extern char get_header_cpio(archive_handle_t *archive_handle) FAST_FUNC; | 182 | char get_header_cpio(archive_handle_t *archive_handle) FAST_FUNC; |
182 | extern char get_header_tar(archive_handle_t *archive_handle) FAST_FUNC; | 183 | char get_header_tar(archive_handle_t *archive_handle) FAST_FUNC; |
183 | extern char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC; | 184 | char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC; |
184 | extern char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; | 185 | char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; |
185 | extern char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; | 186 | char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; |
186 | 187 | ||
187 | extern void seek_by_jump(int fd, off_t amount) FAST_FUNC; | 188 | void seek_by_jump(int fd, off_t amount) FAST_FUNC; |
188 | extern void seek_by_read(int fd, off_t amount) FAST_FUNC; | 189 | void seek_by_read(int fd, off_t amount) FAST_FUNC; |
189 | 190 | ||
190 | extern void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC; | 191 | const char *strip_unsafe_prefix(const char *str) FAST_FUNC; |
191 | extern const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC; | 192 | |
192 | extern const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC; | 193 | void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC; |
194 | const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC; | ||
195 | const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC; | ||
193 | 196 | ||
194 | /* A bit of bunzip2 internals are exposed for compressed help support: */ | 197 | /* A bit of bunzip2 internals are exposed for compressed help support: */ |
195 | typedef struct bunzip_data bunzip_data; | 198 | typedef struct bunzip_data bunzip_data; |
diff --git a/include/libbb.h b/include/libbb.h index 6564038e9..0006e7e55 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -855,14 +855,14 @@ char* xuid2uname(uid_t uid) FAST_FUNC; | |||
855 | char* xgid2group(gid_t gid) FAST_FUNC; | 855 | char* xgid2group(gid_t gid) FAST_FUNC; |
856 | char* uid2uname(uid_t uid) FAST_FUNC; | 856 | char* uid2uname(uid_t uid) FAST_FUNC; |
857 | char* gid2group(gid_t gid) FAST_FUNC; | 857 | char* gid2group(gid_t gid) FAST_FUNC; |
858 | char* uid2uname_utoa(long uid) FAST_FUNC; | 858 | char* uid2uname_utoa(uid_t uid) FAST_FUNC; |
859 | char* gid2group_utoa(long gid) FAST_FUNC; | 859 | char* gid2group_utoa(gid_t gid) FAST_FUNC; |
860 | /* versions which cache results (useful for ps, ls etc) */ | 860 | /* versions which cache results (useful for ps, ls etc) */ |
861 | const char* get_cached_username(uid_t uid) FAST_FUNC; | 861 | const char* get_cached_username(uid_t uid) FAST_FUNC; |
862 | const char* get_cached_groupname(gid_t gid) FAST_FUNC; | 862 | const char* get_cached_groupname(gid_t gid) FAST_FUNC; |
863 | void clear_username_cache(void) FAST_FUNC; | 863 | void clear_username_cache(void) FAST_FUNC; |
864 | /* internally usernames are saved in fixed-sized char[] buffers */ | 864 | /* internally usernames are saved in fixed-sized char[] buffers */ |
865 | enum { USERNAME_MAX_SIZE = 16 - sizeof(int) }; | 865 | enum { USERNAME_MAX_SIZE = 32 - sizeof(uid_t) }; |
866 | #if ENABLE_FEATURE_CHECK_NAMES | 866 | #if ENABLE_FEATURE_CHECK_NAMES |
867 | void die_if_bad_username(const char* name) FAST_FUNC; | 867 | void die_if_bad_username(const char* name) FAST_FUNC; |
868 | #else | 868 | #else |
@@ -1214,10 +1214,17 @@ char *bb_simplify_path(const char *path) FAST_FUNC; | |||
1214 | /* Returns ptr to NUL */ | 1214 | /* Returns ptr to NUL */ |
1215 | char *bb_simplify_abs_path_inplace(char *path) FAST_FUNC; | 1215 | char *bb_simplify_abs_path_inplace(char *path) FAST_FUNC; |
1216 | 1216 | ||
1217 | #define FAIL_DELAY 3 | 1217 | #define LOGIN_FAIL_DELAY 3 |
1218 | extern void bb_do_delay(int seconds) FAST_FUNC; | 1218 | extern void bb_do_delay(int seconds) FAST_FUNC; |
1219 | extern void change_identity(const struct passwd *pw) FAST_FUNC; | 1219 | extern void change_identity(const struct passwd *pw) FAST_FUNC; |
1220 | extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) NORETURN FAST_FUNC; | 1220 | extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) NORETURN FAST_FUNC; |
1221 | |||
1222 | /* Returns $SHELL, getpwuid(getuid())->pw_shell, or DEFAULT_SHELL. | ||
1223 | * Note that getpwuid result might need xstrdup'ing | ||
1224 | * if there is a possibility of intervening getpwxxx() calls. | ||
1225 | */ | ||
1226 | const char *get_shell_name(void); | ||
1227 | |||
1221 | #if ENABLE_SELINUX | 1228 | #if ENABLE_SELINUX |
1222 | extern void renew_current_security_context(void) FAST_FUNC; | 1229 | extern void renew_current_security_context(void) FAST_FUNC; |
1223 | extern void set_current_security_context(security_context_t sid) FAST_FUNC; | 1230 | extern void set_current_security_context(security_context_t sid) FAST_FUNC; |
diff --git a/include/unicode.h b/include/unicode.h index dee02e777..0317a2151 100644 --- a/include/unicode.h +++ b/include/unicode.h | |||
@@ -27,6 +27,7 @@ enum { | |||
27 | # define unicode_strwidth(string) strlen(string) | 27 | # define unicode_strwidth(string) strlen(string) |
28 | # define unicode_status UNICODE_OFF | 28 | # define unicode_status UNICODE_OFF |
29 | # define init_unicode() ((void)0) | 29 | # define init_unicode() ((void)0) |
30 | # define reinit_unicode(LANG) ((void)0) | ||
30 | 31 | ||
31 | #else | 32 | #else |
32 | 33 | ||
@@ -67,6 +68,7 @@ char* FAST_FUNC unicode_conv_to_printable_fixedwidth(/*uni_stat_t *stats,*/ cons | |||
67 | 68 | ||
68 | extern uint8_t unicode_status; | 69 | extern uint8_t unicode_status; |
69 | void init_unicode(void) FAST_FUNC; | 70 | void init_unicode(void) FAST_FUNC; |
71 | void reinit_unicode(const char *LANG) FAST_FUNC; | ||
70 | 72 | ||
71 | # else | 73 | # else |
72 | 74 | ||
@@ -75,9 +77,11 @@ void init_unicode(void) FAST_FUNC; | |||
75 | # if !ENABLE_FEATURE_CHECK_UNICODE_IN_ENV | 77 | # if !ENABLE_FEATURE_CHECK_UNICODE_IN_ENV |
76 | # define unicode_status UNICODE_ON | 78 | # define unicode_status UNICODE_ON |
77 | # define init_unicode() ((void)0) | 79 | # define init_unicode() ((void)0) |
80 | # define reinit_unicode(LANG) ((void)0) | ||
78 | # else | 81 | # else |
79 | extern uint8_t unicode_status; | 82 | extern uint8_t unicode_status; |
80 | void init_unicode(void) FAST_FUNC; | 83 | void init_unicode(void) FAST_FUNC; |
84 | void reinit_unicode(const char *LANG) FAST_FUNC; | ||
81 | # endif | 85 | # endif |
82 | 86 | ||
83 | # undef MB_CUR_MAX | 87 | # undef MB_CUR_MAX |
diff --git a/include/usage.src.h b/include/usage.src.h index c2575b561..d07b408a6 100644 --- a/include/usage.src.h +++ b/include/usage.src.h | |||
@@ -1273,23 +1273,6 @@ INSERT | |||
1273 | "\n -m Show \"mode not cleared\" warnings" \ | 1273 | "\n -m Show \"mode not cleared\" warnings" \ |
1274 | "\n -f Force file system check" \ | 1274 | "\n -f Force file system check" \ |
1275 | 1275 | ||
1276 | #define ftpd_trivial_usage \ | ||
1277 | "[-wvS] [-t N] [-T N] [DIR]" | ||
1278 | #define ftpd_full_usage "\n\n" \ | ||
1279 | "Anonymous FTP server\n" \ | ||
1280 | "\n" \ | ||
1281 | "ftpd should be used as an inetd service.\n" \ | ||
1282 | "ftpd's line for inetd.conf:\n" \ | ||
1283 | " 21 stream tcp nowait root ftpd ftpd /files/to/serve\n" \ | ||
1284 | "It also can be ran from tcpsvd:\n" \ | ||
1285 | " tcpsvd -vE 0.0.0.0 21 ftpd /files/to/serve\n" \ | ||
1286 | "\nOptions:" \ | ||
1287 | "\n -w Allow upload" \ | ||
1288 | "\n -v Log to stderr" \ | ||
1289 | "\n -S Log to syslog" \ | ||
1290 | "\n -t,-T Idle and absolute timeouts" \ | ||
1291 | "\n DIR Change root to this directory" \ | ||
1292 | |||
1293 | #define ftpget_trivial_usage \ | 1276 | #define ftpget_trivial_usage \ |
1294 | "[OPTIONS] HOST [LOCAL_FILE] REMOTE_FILE" | 1277 | "[OPTIONS] HOST [LOCAL_FILE] REMOTE_FILE" |
1295 | #define ftpget_full_usage "\n\n" \ | 1278 | #define ftpget_full_usage "\n\n" \ |
@@ -2499,7 +2482,7 @@ INSERT | |||
2499 | "\n [r]slave Convert [recursively] to a slave subtree" \ | 2482 | "\n [r]slave Convert [recursively] to a slave subtree" \ |
2500 | "\n [r]private Convert [recursively] to a private subtree" \ | 2483 | "\n [r]private Convert [recursively] to a private subtree" \ |
2501 | "\n [un]bindable Make mount point [un]able to be bind mounted" \ | 2484 | "\n [un]bindable Make mount point [un]able to be bind mounted" \ |
2502 | "\n bind Bind a file or directory to another location" \ | 2485 | "\n [r]bind Bind a file or directory [recursively] to another location" \ |
2503 | "\n move Relocate an existing mount point" \ | 2486 | "\n move Relocate an existing mount point" \ |
2504 | ) \ | 2487 | ) \ |
2505 | "\n remount Remount a mounted filesystem, changing flags" \ | 2488 | "\n remount Remount a mounted filesystem, changing flags" \ |
@@ -2546,20 +2529,6 @@ INSERT | |||
2546 | "ras3 reset retension rewind rewoffline seek setblk setdensity\n" \ | 2529 | "ras3 reset retension rewind rewoffline seek setblk setdensity\n" \ |
2547 | "setpart tell unload unlock weof wset" \ | 2530 | "setpart tell unload unlock weof wset" \ |
2548 | 2531 | ||
2549 | #define nameif_trivial_usage \ | ||
2550 | "[-s] [-c FILE] [{IFNAME MACADDR}]" | ||
2551 | #define nameif_full_usage "\n\n" \ | ||
2552 | "Rename network interface while it in the down state\n" \ | ||
2553 | "\nOptions:" \ | ||
2554 | "\n -c FILE Use configuration file (default: /etc/mactab)" \ | ||
2555 | "\n -s Use syslog (LOCAL0 facility)" \ | ||
2556 | "\n IFNAME MACADDR new_interface_name interface_mac_address" \ | ||
2557 | |||
2558 | #define nameif_example_usage \ | ||
2559 | "$ nameif -s dmz0 00:A0:C9:8C:F6:3F\n" \ | ||
2560 | " or\n" \ | ||
2561 | "$ nameif -c /etc/my_mactab_file\n" \ | ||
2562 | |||
2563 | #define nohup_trivial_usage \ | 2532 | #define nohup_trivial_usage \ |
2564 | "PROG ARGS" | 2533 | "PROG ARGS" |
2565 | #define nohup_full_usage "\n\n" \ | 2534 | #define nohup_full_usage "\n\n" \ |
@@ -4098,31 +4067,6 @@ INSERT | |||
4098 | "\n" \ | 4067 | "\n" \ |
4099 | "\nUse 500ms to specify period in milliseconds" \ | 4068 | "\nUse 500ms to specify period in milliseconds" \ |
4100 | 4069 | ||
4101 | #define wget_trivial_usage \ | ||
4102 | IF_FEATURE_WGET_LONG_OPTIONS( \ | ||
4103 | "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" \ | ||
4104 | " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" \ | ||
4105 | " [--no-check-certificate] [-U|--user-agent AGENT]" \ | ||
4106 | IF_FEATURE_WGET_TIMEOUT("[-T SEC] ") " URL" \ | ||
4107 | ) \ | ||
4108 | IF_NOT_FEATURE_WGET_LONG_OPTIONS( \ | ||
4109 | "[-csq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]" \ | ||
4110 | IF_FEATURE_WGET_TIMEOUT("[-T SEC] ") " URL" \ | ||
4111 | ) | ||
4112 | #define wget_full_usage "\n\n" \ | ||
4113 | "Retrieve files via HTTP or FTP\n" \ | ||
4114 | "\nOptions:" \ | ||
4115 | "\n -s Spider mode - only check file existence" \ | ||
4116 | "\n -c Continue retrieval of aborted transfer" \ | ||
4117 | "\n -q Quiet" \ | ||
4118 | "\n -P DIR Save to DIR (default .)" \ | ||
4119 | IF_FEATURE_WGET_TIMEOUT( \ | ||
4120 | "\n -T SEC Network read timeout is SEC seconds" \ | ||
4121 | ) \ | ||
4122 | "\n -O FILE Save to FILE ('-' for stdout)" \ | ||
4123 | "\n -U STR Use STR for User-Agent header" \ | ||
4124 | "\n -Y Use proxy ('on' or 'off')" \ | ||
4125 | |||
4126 | #define which_trivial_usage \ | 4070 | #define which_trivial_usage \ |
4127 | "[COMMAND]..." | 4071 | "[COMMAND]..." |
4128 | #define which_full_usage "\n\n" \ | 4072 | #define which_full_usage "\n\n" \ |
diff --git a/init/init.c b/init/init.c index 586e34a18..ff9dc06a4 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -414,6 +414,7 @@ static void init_exec(const char *command) | |||
414 | char *word, *next; | 414 | char *word, *next; |
415 | int i = 0; | 415 | int i = 0; |
416 | next = strcpy(buf, command - dash); /* command including "-" */ | 416 | next = strcpy(buf, command - dash); /* command including "-" */ |
417 | command = next + dash; | ||
417 | while ((word = strsep(&next, " \t")) != NULL) { | 418 | while ((word = strsep(&next, " \t")) != NULL) { |
418 | if (*word != '\0') { /* not two spaces/tabs together? */ | 419 | if (*word != '\0') { /* not two spaces/tabs together? */ |
419 | cmd[i] = word; | 420 | cmd[i] = word; |
diff --git a/init/mesg.c b/init/mesg.c index 676ca2e24..8489e621c 100644 --- a/init/mesg.c +++ b/init/mesg.c | |||
@@ -7,16 +7,28 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | //applet:IF_MESG(APPLET(mesg, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
11 | |||
12 | //kbuild:lib-$(CONFIG_MESG) += mesg.o | ||
13 | |||
14 | //config:config MESG | 10 | //config:config MESG |
15 | //config: bool "mesg" | 11 | //config: bool "mesg" |
16 | //config: default y | 12 | //config: default y |
17 | //config: help | 13 | //config: help |
18 | //config: Mesg controls access to your terminal by others. It is typically | 14 | //config: Mesg controls access to your terminal by others. It is typically |
19 | //config: used to allow or disallow other users to write to your terminal | 15 | //config: used to allow or disallow other users to write to your terminal |
16 | //config: | ||
17 | //config:config FEATURE_MESG_ENABLE_ONLY_GROUP | ||
18 | //config: bool "Enable writing to tty only by group, not by everybody" | ||
19 | //config: default y | ||
20 | //config: depends on MESG | ||
21 | //config: help | ||
22 | //config: Usually, ttys are owned by group "tty", and "write" tool is | ||
23 | //config: setgid to this group. This way, "mesg y" only needs to enable | ||
24 | //config: "write by owning group" bit in tty mode. | ||
25 | //config: | ||
26 | //config: If you set this option to N, "mesg y" will enable writing | ||
27 | //config: by anybody at all. This is not recommended. | ||
28 | |||
29 | //applet:IF_MESG(APPLET(mesg, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
30 | |||
31 | //kbuild:lib-$(CONFIG_MESG) += mesg.o | ||
20 | 32 | ||
21 | //usage:#define mesg_trivial_usage | 33 | //usage:#define mesg_trivial_usage |
22 | //usage: "[y|n]" | 34 | //usage: "[y|n]" |
@@ -27,7 +39,7 @@ | |||
27 | 39 | ||
28 | #include "libbb.h" | 40 | #include "libbb.h" |
29 | 41 | ||
30 | #ifdef USE_TTY_GROUP | 42 | #if ENABLE_FEATURE_MESG_ENABLE_ONLY_GROUP |
31 | #define S_IWGRP_OR_S_IWOTH S_IWGRP | 43 | #define S_IWGRP_OR_S_IWOTH S_IWGRP |
32 | #else | 44 | #else |
33 | #define S_IWGRP_OR_S_IWOTH (S_IWGRP | S_IWOTH) | 45 | #define S_IWGRP_OR_S_IWOTH (S_IWGRP | S_IWOTH) |
@@ -37,30 +49,28 @@ int mesg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
37 | int mesg_main(int argc UNUSED_PARAM, char **argv) | 49 | int mesg_main(int argc UNUSED_PARAM, char **argv) |
38 | { | 50 | { |
39 | struct stat sb; | 51 | struct stat sb; |
40 | const char *tty; | 52 | mode_t m; |
41 | char c = 0; | 53 | char c = 0; |
42 | 54 | ||
43 | argv++; | 55 | argv++; |
44 | 56 | ||
45 | if (!argv[0] | 57 | if (argv[0] |
46 | || (!argv[1] && ((c = argv[0][0]) == 'y' || c == 'n')) | 58 | && (argv[1] || ((c = argv[0][0]) != 'y' && c != 'n')) |
47 | ) { | 59 | ) { |
48 | tty = xmalloc_ttyname(STDERR_FILENO); | 60 | bb_show_usage(); |
49 | if (tty == NULL) { | 61 | } |
50 | tty = "ttyname"; | 62 | |
51 | } else if (stat(tty, &sb) == 0) { | 63 | if (!isatty(STDERR_FILENO)) |
52 | mode_t m; | 64 | bb_error_msg_and_die("not a tty"); |
53 | if (c == 0) { | 65 | |
54 | puts((sb.st_mode & (S_IWGRP|S_IWOTH)) ? "is y" : "is n"); | 66 | xfstat(STDERR_FILENO, &sb, "stderr"); |
55 | return EXIT_SUCCESS; | 67 | if (c == 0) { |
56 | } | 68 | puts((sb.st_mode & (S_IWGRP|S_IWOTH)) ? "is y" : "is n"); |
57 | m = (c == 'y') ? sb.st_mode | S_IWGRP_OR_S_IWOTH | 69 | return EXIT_SUCCESS; |
58 | : sb.st_mode & ~(S_IWGRP|S_IWOTH); | ||
59 | if (chmod(tty, m) == 0) { | ||
60 | return EXIT_SUCCESS; | ||
61 | } | ||
62 | } | ||
63 | bb_simple_perror_msg_and_die(tty); | ||
64 | } | 70 | } |
65 | bb_show_usage(); | 71 | m = (c == 'y') ? sb.st_mode | S_IWGRP_OR_S_IWOTH |
72 | : sb.st_mode & ~(S_IWGRP|S_IWOTH); | ||
73 | if (fchmod(STDERR_FILENO, m) != 0) | ||
74 | bb_perror_nomsg_and_die(); | ||
75 | return EXIT_SUCCESS; | ||
66 | } | 76 | } |
diff --git a/libbb/Config.src b/libbb/Config.src index 18bdc5151..a25af23b4 100644 --- a/libbb/Config.src +++ b/libbb/Config.src | |||
@@ -183,7 +183,7 @@ config FEATURE_SKIP_ROOTFS | |||
183 | config MONOTONIC_SYSCALL | 183 | config MONOTONIC_SYSCALL |
184 | bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" | 184 | bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" |
185 | default n | 185 | default n |
186 | depends on PLATFORM_LINUX | 186 | select PLATFORM_LINUX |
187 | help | 187 | help |
188 | Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring | 188 | Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring |
189 | time intervals (time, ping, traceroute etc need this). | 189 | time intervals (time, ping, traceroute etc need this). |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 4e32414b4..50e53aa25 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -713,12 +713,22 @@ static int busybox_main(char **argv) | |||
713 | if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { | 713 | if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { |
714 | int use_symbolic_links; | 714 | int use_symbolic_links; |
715 | const char *busybox; | 715 | const char *busybox; |
716 | |||
716 | busybox = xmalloc_readlink(bb_busybox_exec_path); | 717 | busybox = xmalloc_readlink(bb_busybox_exec_path); |
717 | if (!busybox) | 718 | if (!busybox) { |
718 | busybox = bb_busybox_exec_path; | 719 | /* bb_busybox_exec_path is usually "/proc/self/exe". |
719 | /* busybox --install [-s] [DIR]: */ | 720 | * In chroot, readlink("/proc/self/exe") usually fails. |
720 | /* -s: make symlinks */ | 721 | * In such case, better use argv[0] as symlink target |
721 | /* DIR: directory to install links to */ | 722 | * if it is a full path name. |
723 | */ | ||
724 | if (argv[0][0] != '/') | ||
725 | bb_error_msg_and_die("'%s' is not an absolute path", argv[0]); | ||
726 | busybox = argv[0]; | ||
727 | } | ||
728 | /* busybox --install [-s] [DIR]: | ||
729 | * -s: make symlinks | ||
730 | * DIR: directory to install links to | ||
731 | */ | ||
722 | use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && argv++); | 732 | use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && argv++); |
723 | install_links(busybox, use_symbolic_links, argv[2]); | 733 | install_links(busybox, use_symbolic_links, argv[2]); |
724 | return 0; | 734 | return 0; |
diff --git a/libbb/bb_pwd.c b/libbb/bb_pwd.c index 32406cb58..4829b723a 100644 --- a/libbb/bb_pwd.c +++ b/libbb/bb_pwd.c | |||
@@ -72,13 +72,13 @@ char* FAST_FUNC gid2group(gid_t gid) | |||
72 | return (gr) ? gr->gr_name : NULL; | 72 | return (gr) ? gr->gr_name : NULL; |
73 | } | 73 | } |
74 | 74 | ||
75 | char* FAST_FUNC uid2uname_utoa(long uid) | 75 | char* FAST_FUNC uid2uname_utoa(uid_t uid) |
76 | { | 76 | { |
77 | char *name = uid2uname(uid); | 77 | char *name = uid2uname(uid); |
78 | return (name) ? name : utoa(uid); | 78 | return (name) ? name : utoa(uid); |
79 | } | 79 | } |
80 | 80 | ||
81 | char* FAST_FUNC gid2group_utoa(long gid) | 81 | char* FAST_FUNC gid2group_utoa(gid_t gid) |
82 | { | 82 | { |
83 | char *name = gid2group(gid); | 83 | char *name = gid2group(gid); |
84 | return (name) ? name : utoa(gid); | 84 | return (name) ? name : utoa(gid); |
diff --git a/libbb/get_shell_name.c b/libbb/get_shell_name.c new file mode 100644 index 000000000..d196d293d --- /dev/null +++ b/libbb/get_shell_name.c | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * Copyright 2011, Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | |||
7 | //kbuild:lib-y += get_shell_name.o | ||
8 | |||
9 | #include "libbb.h" | ||
10 | |||
11 | const char *get_shell_name(void) | ||
12 | { | ||
13 | struct passwd *pw; | ||
14 | char *shell; | ||
15 | |||
16 | shell = getenv("SHELL"); | ||
17 | if (shell && shell[0]) | ||
18 | return shell; | ||
19 | |||
20 | #if !ENABLE_PLATFORM_MINGW32 | ||
21 | pw = getpwuid(getuid()); | ||
22 | if (pw && pw->pw_shell && pw->pw_shell[0]) | ||
23 | return pw->pw_shell; | ||
24 | #endif | ||
25 | |||
26 | return DEFAULT_SHELL; | ||
27 | } | ||
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 053ffc349..8087b3ba6 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -542,8 +542,6 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
542 | #endif | 542 | #endif |
543 | /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ | 543 | /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ |
544 | 544 | ||
545 | pargv = NULL; | ||
546 | |||
547 | /* Note: just "getopt() <= 0" will not work well for | 545 | /* Note: just "getopt() <= 0" will not work well for |
548 | * "fake" short options, like this one: | 546 | * "fake" short options, like this one: |
549 | * wget $'-\203' "Test: test" http://kernel.org/ | 547 | * wget $'-\203' "Test: test" http://kernel.org/ |
@@ -574,19 +572,16 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
574 | flags ^= trigger; | 572 | flags ^= trigger; |
575 | if (on_off->counter) | 573 | if (on_off->counter) |
576 | (*(on_off->counter))++; | 574 | (*(on_off->counter))++; |
577 | if (on_off->param_type == PARAM_LIST) { | 575 | if (optarg) { |
578 | if (optarg) | 576 | if (on_off->param_type == PARAM_LIST) { |
579 | llist_add_to_end((llist_t **)(on_off->optarg), optarg); | 577 | llist_add_to_end((llist_t **)(on_off->optarg), optarg); |
580 | } else if (on_off->param_type == PARAM_INT) { | 578 | } else if (on_off->param_type == PARAM_INT) { |
581 | if (optarg) | ||
582 | //TODO: xatoi_positive indirectly pulls in printf machinery | 579 | //TODO: xatoi_positive indirectly pulls in printf machinery |
583 | *(unsigned*)(on_off->optarg) = xatoi_positive(optarg); | 580 | *(unsigned*)(on_off->optarg) = xatoi_positive(optarg); |
584 | } else if (on_off->optarg) { | 581 | } else if (on_off->optarg) { |
585 | if (optarg) | ||
586 | *(char **)(on_off->optarg) = optarg; | 582 | *(char **)(on_off->optarg) = optarg; |
583 | } | ||
587 | } | 584 | } |
588 | if (pargv != NULL) | ||
589 | break; | ||
590 | } | 585 | } |
591 | 586 | ||
592 | /* check depending requires for given options */ | 587 | /* check depending requires for given options */ |
diff --git a/libbb/inet_common.c b/libbb/inet_common.c index 6f585ebd9..207720e96 100644 --- a/libbb/inet_common.c +++ b/libbb/inet_common.c | |||
@@ -164,17 +164,17 @@ char* FAST_FUNC INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t ne | |||
164 | 164 | ||
165 | int FAST_FUNC INET6_resolve(const char *name, struct sockaddr_in6 *sin6) | 165 | int FAST_FUNC INET6_resolve(const char *name, struct sockaddr_in6 *sin6) |
166 | { | 166 | { |
167 | struct addrinfo req, *ai; | 167 | struct addrinfo req, *ai = NULL; |
168 | int s; | 168 | int s; |
169 | 169 | ||
170 | memset(&req, '\0', sizeof req); | 170 | memset(&req, 0, sizeof(req)); |
171 | req.ai_family = AF_INET6; | 171 | req.ai_family = AF_INET6; |
172 | s = getaddrinfo(name, NULL, &req, &ai); | 172 | s = getaddrinfo(name, NULL, &req, &ai); |
173 | if (s) { | 173 | if (s != 0) { |
174 | bb_error_msg("getaddrinfo: %s: %d", name, s); | 174 | bb_error_msg("getaddrinfo: %s: %d", name, s); |
175 | return -1; | 175 | return -1; |
176 | } | 176 | } |
177 | memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6)); | 177 | memcpy(sin6, ai->ai_addr, sizeof(*sin6)); |
178 | freeaddrinfo(ai); | 178 | freeaddrinfo(ai); |
179 | return 0; | 179 | return 0; |
180 | } | 180 | } |
@@ -209,9 +209,11 @@ char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric) | |||
209 | return xstrdup("*"); | 209 | return xstrdup("*"); |
210 | } | 210 | } |
211 | 211 | ||
212 | s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), | 212 | s = getnameinfo((struct sockaddr *) sin6, sizeof(*sin6), |
213 | name, sizeof(name), NULL, 0, 0); | 213 | name, sizeof(name), |
214 | if (s) { | 214 | /*serv,servlen:*/ NULL, 0, |
215 | 0); | ||
216 | if (s != 0) { | ||
215 | bb_error_msg("getnameinfo failed"); | 217 | bb_error_msg("getnameinfo failed"); |
216 | return NULL; | 218 | return NULL; |
217 | } | 219 | } |
diff --git a/libbb/procps.c b/libbb/procps.c index c68d3e655..58772d4e9 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -12,13 +12,13 @@ | |||
12 | #include "libbb.h" | 12 | #include "libbb.h" |
13 | 13 | ||
14 | 14 | ||
15 | typedef struct unsigned_to_name_map_t { | 15 | typedef struct id_to_name_map_t { |
16 | long id; | 16 | uid_t id; |
17 | char name[USERNAME_MAX_SIZE]; | 17 | char name[USERNAME_MAX_SIZE]; |
18 | } unsigned_to_name_map_t; | 18 | } id_to_name_map_t; |
19 | 19 | ||
20 | typedef struct cache_t { | 20 | typedef struct cache_t { |
21 | unsigned_to_name_map_t *cache; | 21 | id_to_name_map_t *cache; |
22 | int size; | 22 | int size; |
23 | } cache_t; | 23 | } cache_t; |
24 | 24 | ||
@@ -39,7 +39,7 @@ void FAST_FUNC clear_username_cache(void) | |||
39 | #if 0 /* more generic, but we don't need that yet */ | 39 | #if 0 /* more generic, but we don't need that yet */ |
40 | /* Returns -N-1 if not found. */ | 40 | /* Returns -N-1 if not found. */ |
41 | /* cp->cache[N] is allocated and must be filled in this case */ | 41 | /* cp->cache[N] is allocated and must be filled in this case */ |
42 | static int get_cached(cache_t *cp, unsigned id) | 42 | static int get_cached(cache_t *cp, uid_t id) |
43 | { | 43 | { |
44 | int i; | 44 | int i; |
45 | for (i = 0; i < cp->size; i++) | 45 | for (i = 0; i < cp->size; i++) |
@@ -52,8 +52,8 @@ static int get_cached(cache_t *cp, unsigned id) | |||
52 | } | 52 | } |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | static char* get_cached(cache_t *cp, long id, | 55 | static char* get_cached(cache_t *cp, uid_t id, |
56 | char* FAST_FUNC x2x_utoa(long id)) | 56 | char* FAST_FUNC x2x_utoa(uid_t id)) |
57 | { | 57 | { |
58 | int i; | 58 | int i; |
59 | for (i = 0; i < cp->size; i++) | 59 | for (i = 0; i < cp->size; i++) |
diff --git a/libbb/progress.c b/libbb/progress.c index df43dad5c..372feb0c2 100644 --- a/libbb/progress.c +++ b/libbb/progress.c | |||
@@ -127,10 +127,12 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
127 | /* 32-bit CPU and 64-bit off_t. | 127 | /* 32-bit CPU and 64-bit off_t. |
128 | * Use a 40-bit shift, it is easier to do on 32-bit CPU. | 128 | * Use a 40-bit shift, it is easier to do on 32-bit CPU. |
129 | */ | 129 | */ |
130 | if (totalsize >= (uoff_t)(1ULL << 54)) { | 130 | /* ONE suppresses "warning: shift count >= width of type" */ |
131 | totalsize = (uint32_t)(totalsize >> 32) >> 8; | 131 | #define ONE (sizeof(off_t) > 4) |
132 | beg_size = (uint32_t)(beg_size >> 32) >> 8; | 132 | if (totalsize >= (uoff_t)(1ULL << 54*ONE)) { |
133 | transferred = (uint32_t)(transferred >> 32) >> 8; | 133 | totalsize = (uint32_t)(totalsize >> 32*ONE) >> 8; |
134 | beg_size = (uint32_t)(beg_size >> 32*ONE) >> 8; | ||
135 | transferred = (uint32_t)(transferred >> 32*ONE) >> 8; | ||
134 | kiloscale = 4; | 136 | kiloscale = 4; |
135 | } | 137 | } |
136 | } | 138 | } |
diff --git a/libbb/setup_environment.c b/libbb/setup_environment.c index a95fbc5bf..73229ca6c 100644 --- a/libbb/setup_environment.c +++ b/libbb/setup_environment.c | |||
@@ -32,6 +32,9 @@ | |||
32 | 32 | ||
33 | void FAST_FUNC setup_environment(const char *shell, int flags, const struct passwd *pw) | 33 | void FAST_FUNC setup_environment(const char *shell, int flags, const struct passwd *pw) |
34 | { | 34 | { |
35 | if (!shell || !shell[0]) | ||
36 | shell = DEFAULT_SHELL; | ||
37 | |||
35 | /* Change the current working directory to be the home directory | 38 | /* Change the current working directory to be the home directory |
36 | * of the user */ | 39 | * of the user */ |
37 | if (chdir(pw->pw_dir)) { | 40 | if (chdir(pw->pw_dir)) { |
diff --git a/libbb/unicode.c b/libbb/unicode.c index 08a4c7427..d01efd9a2 100644 --- a/libbb/unicode.c +++ b/libbb/unicode.c | |||
@@ -23,37 +23,43 @@ uint8_t unicode_status; | |||
23 | 23 | ||
24 | /* Unicode support using libc locale support. */ | 24 | /* Unicode support using libc locale support. */ |
25 | 25 | ||
26 | void FAST_FUNC init_unicode(void) | 26 | void FAST_FUNC reinit_unicode(const char *LANG UNUSED_PARAM) |
27 | { | 27 | { |
28 | static const char unicode_0x394[] = { 0xce, 0x94, 0 }; | 28 | static const char unicode_0x394[] = { 0xce, 0x94, 0 }; |
29 | size_t width; | 29 | size_t width; |
30 | 30 | ||
31 | if (unicode_status != UNICODE_UNKNOWN) | 31 | //TODO: call setlocale(LC_ALL, LANG) here? |
32 | return; | 32 | |
33 | /* In unicode, this is a one character string */ | 33 | /* In unicode, this is a one character string */ |
34 | // can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused | 34 | // can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused |
35 | width = mbstowcs(NULL, unicode_0x394, INT_MAX); | 35 | width = mbstowcs(NULL, unicode_0x394, INT_MAX); |
36 | unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF); | 36 | unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF); |
37 | } | 37 | } |
38 | 38 | ||
39 | void FAST_FUNC init_unicode(void) | ||
40 | { | ||
41 | if (unicode_status == UNICODE_UNKNOWN) | ||
42 | reinit_unicode(NULL /*getenv("LANG")*/); | ||
43 | } | ||
44 | |||
39 | #else | 45 | #else |
40 | 46 | ||
41 | /* Homegrown Unicode support. It knows only C and Unicode locales. */ | 47 | /* Homegrown Unicode support. It knows only C and Unicode locales. */ |
42 | 48 | ||
43 | # if ENABLE_FEATURE_CHECK_UNICODE_IN_ENV | 49 | # if ENABLE_FEATURE_CHECK_UNICODE_IN_ENV |
44 | void FAST_FUNC init_unicode(void) | 50 | void FAST_FUNC reinit_unicode(const char *LANG) |
45 | { | 51 | { |
46 | char *lang; | ||
47 | |||
48 | if (unicode_status != UNICODE_UNKNOWN) | ||
49 | return; | ||
50 | |||
51 | unicode_status = UNICODE_OFF; | 52 | unicode_status = UNICODE_OFF; |
52 | lang = getenv("LANG"); | 53 | if (!LANG || !(strstr(LANG, ".utf") || strstr(LANG, ".UTF"))) |
53 | if (!lang || !(strstr(lang, ".utf") || strstr(lang, ".UTF"))) | ||
54 | return; | 54 | return; |
55 | unicode_status = UNICODE_ON; | 55 | unicode_status = UNICODE_ON; |
56 | } | 56 | } |
57 | |||
58 | void FAST_FUNC init_unicode(void) | ||
59 | { | ||
60 | if (unicode_status == UNICODE_UNKNOWN) | ||
61 | reinit_unicode(getenv("LANG")); | ||
62 | } | ||
57 | # endif | 63 | # endif |
58 | 64 | ||
59 | static size_t wcrtomb_internal(char *s, wchar_t wc) | 65 | static size_t wcrtomb_internal(char *s, wchar_t wc) |
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 3a6585caa..127e2a5fc 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -255,7 +255,7 @@ IF_NOT_FEATURE_IPV6(sa_family_t af = AF_INET;) | |||
255 | 255 | ||
256 | memset(&hint, 0 , sizeof(hint)); | 256 | memset(&hint, 0 , sizeof(hint)); |
257 | hint.ai_family = af; | 257 | hint.ai_family = af; |
258 | /* Needed. Or else we will get each address thrice (or more) | 258 | /* Need SOCK_STREAM, or else we get each address thrice (or more) |
259 | * for each possible socket type (tcp,udp,raw...): */ | 259 | * for each possible socket type (tcp,udp,raw...): */ |
260 | hint.ai_socktype = SOCK_STREAM; | 260 | hint.ai_socktype = SOCK_STREAM; |
261 | hint.ai_flags = ai_flags & ~DIE_ON_ERROR; | 261 | hint.ai_flags = ai_flags & ~DIE_ON_ERROR; |
@@ -285,7 +285,8 @@ IF_NOT_FEATURE_IPV6(sa_family_t af = AF_INET;) | |||
285 | set_port: | 285 | set_port: |
286 | set_nport(r, htons(port)); | 286 | set_nport(r, htons(port)); |
287 | ret: | 287 | ret: |
288 | freeaddrinfo(result); | 288 | if (result) |
289 | freeaddrinfo(result); | ||
289 | return r; | 290 | return r; |
290 | } | 291 | } |
291 | #if !ENABLE_FEATURE_IPV6 | 292 | #if !ENABLE_FEATURE_IPV6 |
diff --git a/loginutils/adduser.c b/loginutils/adduser.c index d938b80f3..0c675caf9 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c | |||
@@ -67,15 +67,24 @@ static void passwd_study(struct passwd *p) | |||
67 | 67 | ||
68 | static void addgroup_wrapper(struct passwd *p, const char *group_name) | 68 | static void addgroup_wrapper(struct passwd *p, const char *group_name) |
69 | { | 69 | { |
70 | char *cmd; | 70 | char *argv[5]; |
71 | 71 | ||
72 | if (group_name) /* Add user to existing group */ | 72 | argv[0] = (char*)"addgroup"; |
73 | cmd = xasprintf("addgroup '%s' '%s'", p->pw_name, group_name); | 73 | if (group_name) { |
74 | else /* Add user to his own group with the first free gid found in passwd_study */ | 74 | /* Add user to existing group */ |
75 | cmd = xasprintf("addgroup -g %u '%s'", (unsigned)p->pw_gid, p->pw_name); | 75 | argv[1] = p->pw_name; |
76 | /* Warning: to be compatible with external addgroup programs we should use --gid instead */ | 76 | argv[2] = (char*)group_name; |
77 | system(cmd); | 77 | argv[3] = NULL; |
78 | free(cmd); | 78 | } else { |
79 | /* Add user to his own group with the first free gid found in passwd_study */ | ||
80 | //TODO: to be compatible with external addgroup programs we should use --gid instead... | ||
81 | argv[1] = (char*)"-g"; | ||
82 | argv[2] = utoa(p->pw_gid); | ||
83 | argv[3] = p->pw_name; | ||
84 | argv[4] = NULL; | ||
85 | } | ||
86 | |||
87 | spawn_and_wait(argv); | ||
79 | } | 88 | } |
80 | 89 | ||
81 | static void passwd_wrapper(const char *login_name) NORETURN; | 90 | static void passwd_wrapper(const char *login_name) NORETURN; |
@@ -123,7 +132,8 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) | |||
123 | } | 132 | } |
124 | 133 | ||
125 | pw.pw_gecos = (char *)"Linux User,,,"; | 134 | pw.pw_gecos = (char *)"Linux User,,,"; |
126 | pw.pw_shell = (char *)DEFAULT_SHELL; | 135 | /* We assume that newly created users "inherit" root's shell setting */ |
136 | pw.pw_shell = (char *)get_shell_name(); | ||
127 | pw.pw_dir = NULL; | 137 | pw.pw_dir = NULL; |
128 | 138 | ||
129 | /* exactly one non-option arg */ | 139 | /* exactly one non-option arg */ |
diff --git a/loginutils/getty.c b/loginutils/getty.c index 3f20c8e81..dfa15b3da 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
@@ -87,7 +87,7 @@ struct globals { | |||
87 | const char *login; /* login program */ | 87 | const char *login; /* login program */ |
88 | const char *fakehost; | 88 | const char *fakehost; |
89 | const char *tty; /* name of tty */ | 89 | const char *tty; /* name of tty */ |
90 | const char *initstring; /* modem init string */ | 90 | char *initstring; /* modem init string */ |
91 | const char *issue; /* alternative issue file */ | 91 | const char *issue; /* alternative issue file */ |
92 | int numspeed; /* number of baud rates to try */ | 92 | int numspeed; /* number of baud rates to try */ |
93 | int speeds[MAX_SPEED]; /* baud rates to be tried */ | 93 | int speeds[MAX_SPEED]; /* baud rates to be tried */ |
@@ -176,7 +176,7 @@ static void parse_args(char **argv) | |||
176 | if (flags & F_INITSTRING) { | 176 | if (flags & F_INITSTRING) { |
177 | G.initstring = xstrdup(G.initstring); | 177 | G.initstring = xstrdup(G.initstring); |
178 | /* decode \ddd octal codes into chars */ | 178 | /* decode \ddd octal codes into chars */ |
179 | strcpy_and_process_escape_sequences((char*)G.initstring, G.initstring); | 179 | strcpy_and_process_escape_sequences(G.initstring, G.initstring); |
180 | } | 180 | } |
181 | argv += optind; | 181 | argv += optind; |
182 | debug("after getopt\n"); | 182 | debug("after getopt\n"); |
diff --git a/loginutils/login.c b/loginutils/login.c index 952b3aadd..ce0d1741f 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -198,7 +198,6 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
198 | }; | 198 | }; |
199 | char *fromhost; | 199 | char *fromhost; |
200 | char username[USERNAME_SIZE]; | 200 | char username[USERNAME_SIZE]; |
201 | const char *shell; | ||
202 | int run_by_root; | 201 | int run_by_root; |
203 | unsigned opt; | 202 | unsigned opt; |
204 | int count = 0; | 203 | int count = 0; |
@@ -279,6 +278,14 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
279 | failed_msg = "set_item(TTY)"; | 278 | failed_msg = "set_item(TTY)"; |
280 | goto pam_auth_failed; | 279 | goto pam_auth_failed; |
281 | } | 280 | } |
281 | /* set RHOST */ | ||
282 | if (opt_host) { | ||
283 | pamret = pam_set_item(pamh, PAM_RHOST, opt_host); | ||
284 | if (pamret != PAM_SUCCESS) { | ||
285 | failed_msg = "set_item(RHOST)"; | ||
286 | goto pam_auth_failed; | ||
287 | } | ||
288 | } | ||
282 | pamret = pam_authenticate(pamh, 0); | 289 | pamret = pam_authenticate(pamh, 0); |
283 | if (pamret != PAM_SUCCESS) { | 290 | if (pamret != PAM_SUCCESS) { |
284 | failed_msg = "authenticate"; | 291 | failed_msg = "authenticate"; |
@@ -356,7 +363,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
356 | #endif /* ENABLE_PAM */ | 363 | #endif /* ENABLE_PAM */ |
357 | auth_failed: | 364 | auth_failed: |
358 | opt &= ~LOGIN_OPT_f; | 365 | opt &= ~LOGIN_OPT_f; |
359 | bb_do_delay(FAIL_DELAY); | 366 | bb_do_delay(LOGIN_FAIL_DELAY); |
360 | /* TODO: doesn't sound like correct English phrase to me */ | 367 | /* TODO: doesn't sound like correct English phrase to me */ |
361 | puts("Login incorrect"); | 368 | puts("Login incorrect"); |
362 | if (++count == 3) { | 369 | if (++count == 3) { |
@@ -391,10 +398,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
391 | run_login_script(pw, full_tty); | 398 | run_login_script(pw, full_tty); |
392 | 399 | ||
393 | change_identity(pw); | 400 | change_identity(pw); |
394 | shell = pw->pw_shell; | 401 | setup_environment(pw->pw_shell, |
395 | if (!shell || !shell[0]) | ||
396 | shell = DEFAULT_SHELL; | ||
397 | setup_environment(shell, | ||
398 | (!(opt & LOGIN_OPT_p) * SETUP_ENV_CLEARENV) + SETUP_ENV_CHANGEENV, | 402 | (!(opt & LOGIN_OPT_p) * SETUP_ENV_CLEARENV) + SETUP_ENV_CHANGEENV, |
399 | pw); | 403 | pw); |
400 | 404 | ||
@@ -442,7 +446,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
442 | signal(SIGINT, SIG_DFL); | 446 | signal(SIGINT, SIG_DFL); |
443 | 447 | ||
444 | /* Exec login shell with no additional parameters */ | 448 | /* Exec login shell with no additional parameters */ |
445 | run_shell(shell, 1, NULL, NULL); | 449 | run_shell(pw->pw_shell, 1, NULL, NULL); |
446 | 450 | ||
447 | /* return EXIT_FAILURE; - not reached */ | 451 | /* return EXIT_FAILURE; - not reached */ |
448 | } | 452 | } |
diff --git a/loginutils/passwd.c b/loginutils/passwd.c index 728e61867..f3928cecc 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c | |||
@@ -28,7 +28,7 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo) | |||
28 | if (strcmp(encrypted, pw->pw_passwd) != 0) { | 28 | if (strcmp(encrypted, pw->pw_passwd) != 0) { |
29 | syslog(LOG_WARNING, "incorrect password for %s", | 29 | syslog(LOG_WARNING, "incorrect password for %s", |
30 | pw->pw_name); | 30 | pw->pw_name); |
31 | bb_do_delay(FAIL_DELAY); | 31 | bb_do_delay(LOGIN_FAIL_DELAY); |
32 | puts("Incorrect password"); | 32 | puts("Incorrect password"); |
33 | goto err_ret; | 33 | goto err_ret; |
34 | } | 34 | } |
diff --git a/loginutils/su.c b/loginutils/su.c index db303af6d..72dd0f06f 100644 --- a/loginutils/su.c +++ b/loginutils/su.c | |||
@@ -114,20 +114,14 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
114 | opt_shell = getenv("SHELL"); | 114 | opt_shell = getenv("SHELL"); |
115 | } | 115 | } |
116 | 116 | ||
117 | /* Make sure pw->pw_shell is non-NULL. It may be NULL when NEW_USER | ||
118 | * is a username that is retrieved via NIS (YP), that doesn't have | ||
119 | * a default shell listed. */ | ||
120 | if (!pw->pw_shell || !pw->pw_shell[0]) | ||
121 | pw->pw_shell = (char *)DEFAULT_SHELL; | ||
122 | |||
123 | #if ENABLE_FEATURE_SU_CHECKS_SHELLS | 117 | #if ENABLE_FEATURE_SU_CHECKS_SHELLS |
124 | if (opt_shell && cur_uid != 0 && restricted_shell(pw->pw_shell)) { | 118 | if (opt_shell && cur_uid != 0 && pw->pw_shell && restricted_shell(pw->pw_shell)) { |
125 | /* The user being su'd to has a nonstandard shell, and so is | 119 | /* The user being su'd to has a nonstandard shell, and so is |
126 | * probably a uucp account or has restricted access. Don't | 120 | * probably a uucp account or has restricted access. Don't |
127 | * compromise the account by allowing access with a standard | 121 | * compromise the account by allowing access with a standard |
128 | * shell. */ | 122 | * shell. */ |
129 | bb_error_msg("using restricted shell"); | 123 | bb_error_msg("using restricted shell"); |
130 | opt_shell = NULL; | 124 | opt_shell = NULL; /* ignore -s PROG */ |
131 | } | 125 | } |
132 | /* else: user can run whatever he wants via "su -s PROG USER". | 126 | /* else: user can run whatever he wants via "su -s PROG USER". |
133 | * This is safe since PROG is run under user's uid/gid. */ | 127 | * This is safe since PROG is run under user's uid/gid. */ |
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 307536721..0e5b59433 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c | |||
@@ -88,8 +88,8 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) | |||
88 | if (r == 0) { | 88 | if (r == 0) { |
89 | break; | 89 | break; |
90 | } | 90 | } |
91 | bb_do_delay(FAIL_DELAY); | 91 | bb_do_delay(LOGIN_FAIL_DELAY); |
92 | bb_error_msg("login incorrect"); | 92 | bb_info_msg("Login incorrect"); |
93 | } | 93 | } |
94 | memset(cp, 0, strlen(cp)); | 94 | memset(cp, 0, strlen(cp)); |
95 | // signal(SIGALRM, SIG_DFL); | 95 | // signal(SIGALRM, SIG_DFL); |
diff --git a/loginutils/vlock.c b/loginutils/vlock.c index 216b317f1..3299afa50 100644 --- a/loginutils/vlock.c +++ b/loginutils/vlock.c | |||
@@ -93,16 +93,17 @@ int vlock_main(int argc UNUSED_PARAM, char **argv) | |||
93 | term.c_lflag &= ~(ECHO | ECHOCTL); | 93 | term.c_lflag &= ~(ECHO | ECHOCTL); |
94 | tcsetattr_stdin_TCSANOW(&term); | 94 | tcsetattr_stdin_TCSANOW(&term); |
95 | 95 | ||
96 | do { | 96 | while (1) { |
97 | printf("Virtual console%s locked by %s.\n", | 97 | printf("Virtual console%s locked by %s.\n", |
98 | option_mask32 /*o_lock_all*/ ? "s" : "", | 98 | /* "s" if -a, else "": */ "s" + !option_mask32, |
99 | pw->pw_name); | 99 | pw->pw_name |
100 | ); | ||
100 | if (correct_password(pw)) { | 101 | if (correct_password(pw)) { |
101 | break; | 102 | break; |
102 | } | 103 | } |
103 | bb_do_delay(FAIL_DELAY); | 104 | bb_do_delay(LOGIN_FAIL_DELAY); |
104 | puts("Password incorrect"); | 105 | puts("Incorrect password"); |
105 | } while (1); | 106 | } |
106 | 107 | ||
107 | #ifdef __linux__ | 108 | #ifdef __linux__ |
108 | ioctl(STDIN_FILENO, VT_SETMODE, &ovtm); | 109 | ioctl(STDIN_FILENO, VT_SETMODE, &ovtm); |
diff --git a/miscutils/Config.src b/miscutils/Config.src index b5866bbd7..61529141d 100644 --- a/miscutils/Config.src +++ b/miscutils/Config.src | |||
@@ -10,7 +10,7 @@ INSERT | |||
10 | config ADJTIMEX | 10 | config ADJTIMEX |
11 | bool "adjtimex" | 11 | bool "adjtimex" |
12 | default y | 12 | default y |
13 | depends on PLATFORM_LINUX | 13 | select PLATFORM_LINUX |
14 | help | 14 | help |
15 | Adjtimex reads and optionally sets adjustment parameters for | 15 | Adjtimex reads and optionally sets adjustment parameters for |
16 | the Linux clock adjustment algorithm. | 16 | the Linux clock adjustment algorithm. |
@@ -39,7 +39,7 @@ config FEATURE_COMPRESS_BBCONFIG | |||
39 | config BEEP | 39 | config BEEP |
40 | bool "beep" | 40 | bool "beep" |
41 | default y | 41 | default y |
42 | depends on PLATFORM_LINUX | 42 | select PLATFORM_LINUX |
43 | help | 43 | help |
44 | The beep applets beeps in a given freq/Hz. | 44 | The beep applets beeps in a given freq/Hz. |
45 | 45 | ||
@@ -194,7 +194,7 @@ config FEATURE_DC_LIBM | |||
194 | config DEVFSD | 194 | config DEVFSD |
195 | bool "devfsd (obsolete)" | 195 | bool "devfsd (obsolete)" |
196 | default n | 196 | default n |
197 | depends on PLATFORM_LINUX | 197 | select PLATFORM_LINUX |
198 | select FEATURE_SYSLOG | 198 | select FEATURE_SYSLOG |
199 | help | 199 | help |
200 | This is deprecated and should NOT be used anymore. | 200 | This is deprecated and should NOT be used anymore. |
@@ -238,7 +238,7 @@ config DEVFSD_VERBOSE | |||
238 | config FEATURE_DEVFS | 238 | config FEATURE_DEVFS |
239 | bool "Use devfs names for all devices (obsolete)" | 239 | bool "Use devfs names for all devices (obsolete)" |
240 | default n | 240 | default n |
241 | depends on PLATFORM_LINUX | 241 | select PLATFORM_LINUX |
242 | help | 242 | help |
243 | This is obsolete and should NOT be used anymore. | 243 | This is obsolete and should NOT be used anymore. |
244 | Use linux >= 2.6 (optionally with hotplug) and mdev instead! | 244 | Use linux >= 2.6 (optionally with hotplug) and mdev instead! |
@@ -258,7 +258,7 @@ config DEVMEM | |||
258 | config EJECT | 258 | config EJECT |
259 | bool "eject" | 259 | bool "eject" |
260 | default y | 260 | default y |
261 | depends on PLATFORM_LINUX | 261 | select PLATFORM_LINUX |
262 | help | 262 | help |
263 | Used to eject cdroms. (defaults to /dev/cdrom) | 263 | Used to eject cdroms. (defaults to /dev/cdrom) |
264 | 264 | ||
@@ -273,7 +273,7 @@ config FEATURE_EJECT_SCSI | |||
273 | config FBSPLASH | 273 | config FBSPLASH |
274 | bool "fbsplash" | 274 | bool "fbsplash" |
275 | default y | 275 | default y |
276 | depends on PLATFORM_LINUX | 276 | select PLATFORM_LINUX |
277 | help | 277 | help |
278 | Shows splash image and progress bar on framebuffer device. | 278 | Shows splash image and progress bar on framebuffer device. |
279 | Can be used during boot phase of an embedded device. ~2kb. | 279 | Can be used during boot phase of an embedded device. ~2kb. |
@@ -323,7 +323,7 @@ config FLASH_ERASEALL | |||
323 | config IONICE | 323 | config IONICE |
324 | bool "ionice" | 324 | bool "ionice" |
325 | default y | 325 | default y |
326 | depends on PLATFORM_LINUX | 326 | select PLATFORM_LINUX |
327 | help | 327 | help |
328 | Set/set program io scheduling class and priority | 328 | Set/set program io scheduling class and priority |
329 | Requires kernel >= 2.6.13 | 329 | Requires kernel >= 2.6.13 |
@@ -429,7 +429,7 @@ config FEATURE_LESS_LINENUMS | |||
429 | config HDPARM | 429 | config HDPARM |
430 | bool "hdparm" | 430 | bool "hdparm" |
431 | default y | 431 | default y |
432 | depends on PLATFORM_LINUX | 432 | select PLATFORM_LINUX |
433 | help | 433 | help |
434 | Get/Set hard drive parameters. Primarily intended for ATA | 434 | Get/Set hard drive parameters. Primarily intended for ATA |
435 | drives. Adds about 13k (or around 30k if you enable the | 435 | drives. Adds about 13k (or around 30k if you enable the |
@@ -546,7 +546,7 @@ config MT | |||
546 | config RAIDAUTORUN | 546 | config RAIDAUTORUN |
547 | bool "raidautorun" | 547 | bool "raidautorun" |
548 | default y | 548 | default y |
549 | depends on PLATFORM_LINUX | 549 | select PLATFORM_LINUX |
550 | help | 550 | help |
551 | raidautorun tells the kernel md driver to | 551 | raidautorun tells the kernel md driver to |
552 | search and start RAID arrays. | 552 | search and start RAID arrays. |
@@ -554,7 +554,8 @@ config RAIDAUTORUN | |||
554 | config READAHEAD | 554 | config READAHEAD |
555 | bool "readahead" | 555 | bool "readahead" |
556 | default y | 556 | default y |
557 | depends on LFS && PLATFORM_LINUX | 557 | depends on LFS |
558 | select PLATFORM_LINUX | ||
558 | help | 559 | help |
559 | Preload the files listed on the command line into RAM cache so that | 560 | Preload the files listed on the command line into RAM cache so that |
560 | subsequent reads on these files will not block on disk I/O. | 561 | subsequent reads on these files will not block on disk I/O. |
@@ -571,7 +572,7 @@ config READAHEAD | |||
571 | config RFKILL | 572 | config RFKILL |
572 | bool "rfkill" | 573 | bool "rfkill" |
573 | default n # doesn't build on Ubuntu 9.04 | 574 | default n # doesn't build on Ubuntu 9.04 |
574 | depends on PLATFORM_LINUX | 575 | select PLATFORM_LINUX |
575 | help | 576 | help |
576 | Enable/disable wireless devices. | 577 | Enable/disable wireless devices. |
577 | 578 | ||
@@ -593,7 +594,7 @@ config RUNLEVEL | |||
593 | config RX | 594 | config RX |
594 | bool "rx" | 595 | bool "rx" |
595 | default y | 596 | default y |
596 | depends on PLATFORM_LINUX | 597 | select PLATFORM_LINUX |
597 | help | 598 | help |
598 | Receive files using the Xmodem protocol. | 599 | Receive files using the Xmodem protocol. |
599 | 600 | ||
@@ -666,7 +667,7 @@ config WALL | |||
666 | config WATCHDOG | 667 | config WATCHDOG |
667 | bool "watchdog" | 668 | bool "watchdog" |
668 | default y | 669 | default y |
669 | depends on PLATFORM_LINUX | 670 | select PLATFORM_LINUX |
670 | help | 671 | help |
671 | The watchdog utility is used with hardware or software watchdog | 672 | The watchdog utility is used with hardware or software watchdog |
672 | device drivers. It opens the specified watchdog device special file | 673 | device drivers. It opens the specified watchdog device special file |
diff --git a/miscutils/conspy.c b/miscutils/conspy.c index 721eb6d59..9c5405332 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c | |||
@@ -17,7 +17,7 @@ | |||
17 | //config:config CONSPY | 17 | //config:config CONSPY |
18 | //config: bool "conspy" | 18 | //config: bool "conspy" |
19 | //config: default n | 19 | //config: default n |
20 | //config: depends on PLATFORM_LINUX | 20 | //config: select PLATFORM_LINUX |
21 | //config: help | 21 | //config: help |
22 | //config: A text-mode VNC like program for Linux virtual terminals. | 22 | //config: A text-mode VNC like program for Linux virtual terminals. |
23 | //config: example: conspy NUM shared access to console num | 23 | //config: example: conspy NUM shared access to console num |
@@ -316,10 +316,8 @@ static NOINLINE void start_shell_in_child(const char* tty_name) | |||
316 | int pid = xvfork(); | 316 | int pid = xvfork(); |
317 | if (pid == 0) { | 317 | if (pid == 0) { |
318 | struct termios termchild; | 318 | struct termios termchild; |
319 | char *shell = getenv("SHELL"); | 319 | const char *shell = get_shell_name(); |
320 | 320 | ||
321 | if (!shell) | ||
322 | shell = (char *) DEFAULT_SHELL; | ||
323 | signal(SIGHUP, SIG_IGN); | 321 | signal(SIGHUP, SIG_IGN); |
324 | // set tty as a controlling tty | 322 | // set tty as a controlling tty |
325 | setsid(); | 323 | setsid(); |
diff --git a/miscutils/crontab.c b/miscutils/crontab.c index 163e15dce..16d7fdf69 100644 --- a/miscutils/crontab.c +++ b/miscutils/crontab.c | |||
@@ -20,8 +20,9 @@ | |||
20 | static void edit_file(const struct passwd *pas, const char *file) | 20 | static void edit_file(const struct passwd *pas, const char *file) |
21 | { | 21 | { |
22 | const char *ptr; | 22 | const char *ptr; |
23 | int pid = xvfork(); | 23 | pid_t pid; |
24 | 24 | ||
25 | pid = xvfork(); | ||
25 | if (pid) { /* parent */ | 26 | if (pid) { /* parent */ |
26 | wait4pid(pid); | 27 | wait4pid(pid); |
27 | return; | 28 | return; |
@@ -30,7 +31,7 @@ static void edit_file(const struct passwd *pas, const char *file) | |||
30 | /* CHILD - change user and run editor */ | 31 | /* CHILD - change user and run editor */ |
31 | /* initgroups, setgid, setuid */ | 32 | /* initgroups, setgid, setuid */ |
32 | change_identity(pas); | 33 | change_identity(pas); |
33 | setup_environment(DEFAULT_SHELL, | 34 | setup_environment(pas->pw_shell, |
34 | SETUP_ENV_CHANGEENV | SETUP_ENV_TO_TMP, | 35 | SETUP_ENV_CHANGEENV | SETUP_ENV_TO_TMP, |
35 | pas); | 36 | pas); |
36 | ptr = getenv("VISUAL"); | 37 | ptr = getenv("VISUAL"); |
@@ -41,7 +42,7 @@ static void edit_file(const struct passwd *pas, const char *file) | |||
41 | } | 42 | } |
42 | 43 | ||
43 | BB_EXECLP(ptr, ptr, file, NULL); | 44 | BB_EXECLP(ptr, ptr, file, NULL); |
44 | bb_perror_msg_and_die("exec %s", ptr); | 45 | bb_perror_msg_and_die("can't execute '%s'", ptr); |
45 | } | 46 | } |
46 | 47 | ||
47 | static int open_as_user(const struct passwd *pas, const char *file) | 48 | static int open_as_user(const struct passwd *pas, const char *file) |
diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c index c5e2fb841..c7fbe7d9c 100644 --- a/miscutils/nandwrite.c +++ b/miscutils/nandwrite.c | |||
@@ -17,14 +17,14 @@ | |||
17 | //config:config NANDWRITE | 17 | //config:config NANDWRITE |
18 | //config: bool "nandwrite" | 18 | //config: bool "nandwrite" |
19 | //config: default n | 19 | //config: default n |
20 | //config: depends on PLATFORM_LINUX | 20 | //config: select PLATFORM_LINUX |
21 | //config: help | 21 | //config: help |
22 | //config: Write to the specified MTD device, with bad blocks awareness | 22 | //config: Write to the specified MTD device, with bad blocks awareness |
23 | //config: | 23 | //config: |
24 | //config:config NANDDUMP | 24 | //config:config NANDDUMP |
25 | //config: bool "nanddump" | 25 | //config: bool "nanddump" |
26 | //config: default n | 26 | //config: default n |
27 | //config: depends on PLATFORM_LINUX | 27 | //config: select PLATFORM_LINUX |
28 | //config: help | 28 | //config: help |
29 | //config: Dump the content of raw NAND chip | 29 | //config: Dump the content of raw NAND chip |
30 | 30 | ||
diff --git a/miscutils/ubi_attach_detach.c b/miscutils/ubi_attach_detach.c index fef9250ee..9007f8c3f 100644 --- a/miscutils/ubi_attach_detach.c +++ b/miscutils/ubi_attach_detach.c | |||
@@ -6,35 +6,35 @@ | |||
6 | //config:config UBIATTACH | 6 | //config:config UBIATTACH |
7 | //config: bool "ubiattach" | 7 | //config: bool "ubiattach" |
8 | //config: default y | 8 | //config: default y |
9 | //config: depends on PLATFORM_LINUX | 9 | //config: select PLATFORM_LINUX |
10 | //config: help | 10 | //config: help |
11 | //config: Attach MTD device to an UBI device. | 11 | //config: Attach MTD device to an UBI device. |
12 | //config: | 12 | //config: |
13 | //config:config UBIDETACH | 13 | //config:config UBIDETACH |
14 | //config: bool "ubidetach" | 14 | //config: bool "ubidetach" |
15 | //config: default y | 15 | //config: default y |
16 | //config: depends on PLATFORM_LINUX | 16 | //config: select PLATFORM_LINUX |
17 | //config: help | 17 | //config: help |
18 | //config: Detach MTD device from an UBI device. | 18 | //config: Detach MTD device from an UBI device. |
19 | //config: | 19 | //config: |
20 | //config:config UBIMKVOL | 20 | //config:config UBIMKVOL |
21 | //config: bool "ubimkvol" | 21 | //config: bool "ubimkvol" |
22 | //config: default y | 22 | //config: default y |
23 | //config: depends on PLATFORM_LINUX | 23 | //config: select PLATFORM_LINUX |
24 | //config: help | 24 | //config: help |
25 | //config: Create a UBI volume. | 25 | //config: Create a UBI volume. |
26 | //config: | 26 | //config: |
27 | //config:config UBIRMVOL | 27 | //config:config UBIRMVOL |
28 | //config: bool "ubirmvol" | 28 | //config: bool "ubirmvol" |
29 | //config: default y | 29 | //config: default y |
30 | //config: depends on PLATFORM_LINUX | 30 | //config: select PLATFORM_LINUX |
31 | //config: help | 31 | //config: help |
32 | //config: Delete a UBI volume. | 32 | //config: Delete a UBI volume. |
33 | //config: | 33 | //config: |
34 | //config:config UBIRSVOL | 34 | //config:config UBIRSVOL |
35 | //config: bool "ubirsvol" | 35 | //config: bool "ubirsvol" |
36 | //config: default y | 36 | //config: default y |
37 | //config: depends on PLATFORM_LINUX | 37 | //config: select PLATFORM_LINUX |
38 | //config: help | 38 | //config: help |
39 | //config: Resize a UBI volume. | 39 | //config: Resize a UBI volume. |
40 | 40 | ||
diff --git a/modutils/Config.src b/modutils/Config.src index 4191d29f2..449ac65af 100644 --- a/modutils/Config.src +++ b/modutils/Config.src | |||
@@ -4,13 +4,13 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | menu "Linux Module Utilities" | 6 | menu "Linux Module Utilities" |
7 | depends on PLATFORM_LINUX | ||
8 | 7 | ||
9 | INSERT | 8 | INSERT |
10 | 9 | ||
11 | config MODPROBE_SMALL | 10 | config MODPROBE_SMALL |
12 | bool "Simplified modutils" | 11 | bool "Simplified modutils" |
13 | default y | 12 | default y |
13 | select PLATFORM_LINUX | ||
14 | help | 14 | help |
15 | Simplified modutils. | 15 | Simplified modutils. |
16 | 16 | ||
@@ -45,6 +45,7 @@ config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | |||
45 | bool "Accept module options on modprobe command line" | 45 | bool "Accept module options on modprobe command line" |
46 | default y | 46 | default y |
47 | depends on MODPROBE_SMALL | 47 | depends on MODPROBE_SMALL |
48 | select PLATFORM_LINUX | ||
48 | help | 49 | help |
49 | Allow insmod and modprobe take module options from command line. | 50 | Allow insmod and modprobe take module options from command line. |
50 | 51 | ||
@@ -59,6 +60,7 @@ config INSMOD | |||
59 | bool "insmod" | 60 | bool "insmod" |
60 | default n | 61 | default n |
61 | depends on !MODPROBE_SMALL | 62 | depends on !MODPROBE_SMALL |
63 | select PLATFORM_LINUX | ||
62 | help | 64 | help |
63 | insmod is used to load specified modules in the running kernel. | 65 | insmod is used to load specified modules in the running kernel. |
64 | 66 | ||
@@ -66,6 +68,7 @@ config RMMOD | |||
66 | bool "rmmod" | 68 | bool "rmmod" |
67 | default n | 69 | default n |
68 | depends on !MODPROBE_SMALL | 70 | depends on !MODPROBE_SMALL |
71 | select PLATFORM_LINUX | ||
69 | help | 72 | help |
70 | rmmod is used to unload specified modules from the kernel. | 73 | rmmod is used to unload specified modules from the kernel. |
71 | 74 | ||
@@ -73,6 +76,7 @@ config LSMOD | |||
73 | bool "lsmod" | 76 | bool "lsmod" |
74 | default n | 77 | default n |
75 | depends on !MODPROBE_SMALL | 78 | depends on !MODPROBE_SMALL |
79 | select PLATFORM_LINUX | ||
76 | help | 80 | help |
77 | lsmod is used to display a list of loaded modules. | 81 | lsmod is used to display a list of loaded modules. |
78 | 82 | ||
@@ -80,6 +84,7 @@ config FEATURE_LSMOD_PRETTY_2_6_OUTPUT | |||
80 | bool "Pretty output" | 84 | bool "Pretty output" |
81 | default n | 85 | default n |
82 | depends on LSMOD | 86 | depends on LSMOD |
87 | select PLATFORM_LINUX | ||
83 | help | 88 | help |
84 | This option makes output format of lsmod adjusted to | 89 | This option makes output format of lsmod adjusted to |
85 | the format of module-init-tools for Linux kernel 2.6. | 90 | the format of module-init-tools for Linux kernel 2.6. |
@@ -89,6 +94,7 @@ config MODPROBE | |||
89 | bool "modprobe" | 94 | bool "modprobe" |
90 | default n | 95 | default n |
91 | depends on !MODPROBE_SMALL | 96 | depends on !MODPROBE_SMALL |
97 | select PLATFORM_LINUX | ||
92 | help | 98 | help |
93 | Handle the loading of modules, and their dependencies on a high | 99 | Handle the loading of modules, and their dependencies on a high |
94 | level. | 100 | level. |
@@ -97,6 +103,7 @@ config FEATURE_MODPROBE_BLACKLIST | |||
97 | bool "Blacklist support" | 103 | bool "Blacklist support" |
98 | default n | 104 | default n |
99 | depends on MODPROBE | 105 | depends on MODPROBE |
106 | select PLATFORM_LINUX | ||
100 | help | 107 | help |
101 | Say 'y' here to enable support for the 'blacklist' command in | 108 | Say 'y' here to enable support for the 'blacklist' command in |
102 | modprobe.conf. This prevents the alias resolver to resolve | 109 | modprobe.conf. This prevents the alias resolver to resolve |
@@ -108,6 +115,7 @@ config DEPMOD | |||
108 | bool "depmod" | 115 | bool "depmod" |
109 | default n | 116 | default n |
110 | depends on !MODPROBE_SMALL | 117 | depends on !MODPROBE_SMALL |
118 | select PLATFORM_LINUX | ||
111 | help | 119 | help |
112 | depmod generates modules.dep (and potentially modules.alias | 120 | depmod generates modules.dep (and potentially modules.alias |
113 | and modules.symbols) that contain dependency information | 121 | and modules.symbols) that contain dependency information |
@@ -119,6 +127,7 @@ config FEATURE_2_4_MODULES | |||
119 | bool "Support version 2.2/2.4 Linux kernels" | 127 | bool "Support version 2.2/2.4 Linux kernels" |
120 | default n | 128 | default n |
121 | depends on INSMOD || RMMOD || LSMOD | 129 | depends on INSMOD || RMMOD || LSMOD |
130 | select PLATFORM_LINUX | ||
122 | help | 131 | help |
123 | Support module loading for 2.2.x and 2.4.x Linux kernels. | 132 | Support module loading for 2.2.x and 2.4.x Linux kernels. |
124 | This increases size considerably. Say N unless you plan | 133 | This increases size considerably. Say N unless you plan |
@@ -128,6 +137,7 @@ config FEATURE_INSMOD_TRY_MMAP | |||
128 | bool "Try to load module from a mmap'ed area" | 137 | bool "Try to load module from a mmap'ed area" |
129 | default n | 138 | default n |
130 | depends on INSMOD || MODPROBE_SMALL | 139 | depends on INSMOD || MODPROBE_SMALL |
140 | select PLATFORM_LINUX | ||
131 | help | 141 | help |
132 | This option causes module loading code to try to mmap | 142 | This option causes module loading code to try to mmap |
133 | module first. If it does not work (for example, | 143 | module first. If it does not work (for example, |
@@ -144,6 +154,7 @@ config FEATURE_INSMOD_VERSION_CHECKING | |||
144 | bool "Enable module version checking" | 154 | bool "Enable module version checking" |
145 | default n | 155 | default n |
146 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) | 156 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) |
157 | select PLATFORM_LINUX | ||
147 | help | 158 | help |
148 | Support checking of versions for modules. This is used to | 159 | Support checking of versions for modules. This is used to |
149 | ensure that the kernel and module are made for each other. | 160 | ensure that the kernel and module are made for each other. |
@@ -152,6 +163,7 @@ config FEATURE_INSMOD_KSYMOOPS_SYMBOLS | |||
152 | bool "Add module symbols to kernel symbol table" | 163 | bool "Add module symbols to kernel symbol table" |
153 | default n | 164 | default n |
154 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) | 165 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) |
166 | select PLATFORM_LINUX | ||
155 | help | 167 | help |
156 | By adding module symbols to the kernel symbol table, Oops messages | 168 | By adding module symbols to the kernel symbol table, Oops messages |
157 | occuring within kernel modules can be properly debugged. By enabling | 169 | occuring within kernel modules can be properly debugged. By enabling |
@@ -163,6 +175,7 @@ config FEATURE_INSMOD_LOADINKMEM | |||
163 | bool "In kernel memory optimization (uClinux only)" | 175 | bool "In kernel memory optimization (uClinux only)" |
164 | default n | 176 | default n |
165 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) | 177 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) |
178 | select PLATFORM_LINUX | ||
166 | help | 179 | help |
167 | This is a special uClinux only memory optimization that lets insmod | 180 | This is a special uClinux only memory optimization that lets insmod |
168 | load the specified kernel module directly into kernel space, reducing | 181 | load the specified kernel module directly into kernel space, reducing |
@@ -173,6 +186,7 @@ config FEATURE_INSMOD_LOAD_MAP | |||
173 | bool "Enable insmod load map (-m) option" | 186 | bool "Enable insmod load map (-m) option" |
174 | default n | 187 | default n |
175 | depends on FEATURE_2_4_MODULES && INSMOD | 188 | depends on FEATURE_2_4_MODULES && INSMOD |
189 | select PLATFORM_LINUX | ||
176 | help | 190 | help |
177 | Enabling this, one would be able to get a load map | 191 | Enabling this, one would be able to get a load map |
178 | output on stdout. This makes kernel module debugging | 192 | output on stdout. This makes kernel module debugging |
@@ -184,6 +198,7 @@ config FEATURE_INSMOD_LOAD_MAP_FULL | |||
184 | bool "Symbols in load map" | 198 | bool "Symbols in load map" |
185 | default y | 199 | default y |
186 | depends on FEATURE_INSMOD_LOAD_MAP && !MODPROBE_SMALL | 200 | depends on FEATURE_INSMOD_LOAD_MAP && !MODPROBE_SMALL |
201 | select PLATFORM_LINUX | ||
187 | help | 202 | help |
188 | Without this option, -m will only output section | 203 | Without this option, -m will only output section |
189 | load map. With this option, -m will also output | 204 | load map. With this option, -m will also output |
@@ -193,6 +208,7 @@ config FEATURE_CHECK_TAINTED_MODULE | |||
193 | bool "Support tainted module checking with new kernels" | 208 | bool "Support tainted module checking with new kernels" |
194 | default y | 209 | default y |
195 | depends on (LSMOD || FEATURE_2_4_MODULES) && !MODPROBE_SMALL | 210 | depends on (LSMOD || FEATURE_2_4_MODULES) && !MODPROBE_SMALL |
211 | select PLATFORM_LINUX | ||
196 | help | 212 | help |
197 | Support checking for tainted modules. These are usually binary | 213 | Support checking for tainted modules. These are usually binary |
198 | only modules that will make the linux-kernel list ignore your | 214 | only modules that will make the linux-kernel list ignore your |
@@ -203,6 +219,7 @@ config FEATURE_MODUTILS_ALIAS | |||
203 | bool "Support for module.aliases file" | 219 | bool "Support for module.aliases file" |
204 | default y | 220 | default y |
205 | depends on DEPMOD || MODPROBE | 221 | depends on DEPMOD || MODPROBE |
222 | select PLATFORM_LINUX | ||
206 | help | 223 | help |
207 | Generate and parse modules.alias containing aliases for bus | 224 | Generate and parse modules.alias containing aliases for bus |
208 | identifiers: | 225 | identifiers: |
@@ -219,6 +236,7 @@ config FEATURE_MODUTILS_SYMBOLS | |||
219 | bool "Support for module.symbols file" | 236 | bool "Support for module.symbols file" |
220 | default y | 237 | default y |
221 | depends on DEPMOD || MODPROBE | 238 | depends on DEPMOD || MODPROBE |
239 | select PLATFORM_LINUX | ||
222 | help | 240 | help |
223 | Generate and parse modules.symbols containing aliases for | 241 | Generate and parse modules.symbols containing aliases for |
224 | symbol_request() kernel calls, such as: | 242 | symbol_request() kernel calls, such as: |
diff --git a/networking/Config.src b/networking/Config.src index 274fcae3a..8aeba0ef9 100644 --- a/networking/Config.src +++ b/networking/Config.src | |||
@@ -51,21 +51,21 @@ config VERBOSE_RESOLUTION_ERRORS | |||
51 | config ARP | 51 | config ARP |
52 | bool "arp" | 52 | bool "arp" |
53 | default y | 53 | default y |
54 | depends on PLATFORM_LINUX | 54 | select PLATFORM_LINUX |
55 | help | 55 | help |
56 | Manipulate the system ARP cache. | 56 | Manipulate the system ARP cache. |
57 | 57 | ||
58 | config ARPING | 58 | config ARPING |
59 | bool "arping" | 59 | bool "arping" |
60 | default y | 60 | default y |
61 | depends on PLATFORM_LINUX | 61 | select PLATFORM_LINUX |
62 | help | 62 | help |
63 | Ping hosts by ARP packets. | 63 | Ping hosts by ARP packets. |
64 | 64 | ||
65 | config BRCTL | 65 | config BRCTL |
66 | bool "brctl" | 66 | bool "brctl" |
67 | default y | 67 | default y |
68 | depends on PLATFORM_LINUX | 68 | select PLATFORM_LINUX |
69 | help | 69 | help |
70 | Manage ethernet bridges. | 70 | Manage ethernet bridges. |
71 | Supports addbr/delbr and addif/delif. | 71 | Supports addbr/delbr and addif/delif. |
@@ -98,7 +98,7 @@ config DNSD | |||
98 | config ETHER_WAKE | 98 | config ETHER_WAKE |
99 | bool "ether-wake" | 99 | bool "ether-wake" |
100 | default y | 100 | default y |
101 | depends on PLATFORM_LINUX | 101 | select PLATFORM_LINUX |
102 | help | 102 | help |
103 | Send a magic packet to wake up sleeping machines. | 103 | Send a magic packet to wake up sleeping machines. |
104 | 104 | ||
@@ -281,7 +281,7 @@ config FEATURE_HTTPD_GZIP | |||
281 | config IFCONFIG | 281 | config IFCONFIG |
282 | bool "ifconfig" | 282 | bool "ifconfig" |
283 | default y | 283 | default y |
284 | depends on PLATFORM_LINUX | 284 | select PLATFORM_LINUX |
285 | help | 285 | help |
286 | Ifconfig is used to configure the kernel-resident network interfaces. | 286 | Ifconfig is used to configure the kernel-resident network interfaces. |
287 | 287 | ||
@@ -329,7 +329,7 @@ config FEATURE_IFCONFIG_BROADCAST_PLUS | |||
329 | config IFENSLAVE | 329 | config IFENSLAVE |
330 | bool "ifenslave" | 330 | bool "ifenslave" |
331 | default y | 331 | default y |
332 | depends on PLATFORM_LINUX | 332 | select PLATFORM_LINUX |
333 | help | 333 | help |
334 | Userspace application to bind several interfaces | 334 | Userspace application to bind several interfaces |
335 | to a logical interface (use with kernel bonding driver). | 335 | to a logical interface (use with kernel bonding driver). |
@@ -337,7 +337,7 @@ config IFENSLAVE | |||
337 | config IFPLUGD | 337 | config IFPLUGD |
338 | bool "ifplugd" | 338 | bool "ifplugd" |
339 | default y | 339 | default y |
340 | depends on PLATFORM_LINUX | 340 | select PLATFORM_LINUX |
341 | help | 341 | help |
342 | Network interface plug detection daemon. | 342 | Network interface plug detection daemon. |
343 | 343 | ||
@@ -379,7 +379,8 @@ config FEATURE_IFUPDOWN_IP | |||
379 | config FEATURE_IFUPDOWN_IP_BUILTIN | 379 | config FEATURE_IFUPDOWN_IP_BUILTIN |
380 | bool "Use busybox ip applet" | 380 | bool "Use busybox ip applet" |
381 | default y | 381 | default y |
382 | depends on FEATURE_IFUPDOWN_IP && PLATFORM_LINUX | 382 | depends on FEATURE_IFUPDOWN_IP |
383 | select PLATFORM_LINUX | ||
383 | select IP | 384 | select IP |
384 | select FEATURE_IP_ADDRESS | 385 | select FEATURE_IP_ADDRESS |
385 | select FEATURE_IP_LINK | 386 | select FEATURE_IP_LINK |
@@ -498,7 +499,7 @@ config FEATURE_INETD_RPC | |||
498 | config IP | 499 | config IP |
499 | bool "ip" | 500 | bool "ip" |
500 | default y | 501 | default y |
501 | depends on PLATFORM_LINUX | 502 | select PLATFORM_LINUX |
502 | help | 503 | help |
503 | The "ip" applet is a TCP/IP interface configuration and routing | 504 | The "ip" applet is a TCP/IP interface configuration and routing |
504 | utility. You generally don't need "ip" to use busybox with | 505 | utility. You generally don't need "ip" to use busybox with |
@@ -611,39 +612,10 @@ config FEATURE_IPCALC_LONG_OPTIONS | |||
611 | help | 612 | help |
612 | Support long options for the ipcalc applet. | 613 | Support long options for the ipcalc applet. |
613 | 614 | ||
614 | config NAMEIF | ||
615 | bool "nameif" | ||
616 | default y | ||
617 | depends on PLATFORM_LINUX | ||
618 | select FEATURE_SYSLOG | ||
619 | help | ||
620 | nameif is used to rename network interface by its MAC address. | ||
621 | Renamed interfaces MUST be in the down state. | ||
622 | It is possible to use a file (default: /etc/mactab) | ||
623 | with list of new interface names and MACs. | ||
624 | Maximum interface name length: IFNAMSIZ = 16 | ||
625 | File fields are separated by space or tab. | ||
626 | File format: | ||
627 | # Comment | ||
628 | new_interface_name XX:XX:XX:XX:XX:XX | ||
629 | |||
630 | config FEATURE_NAMEIF_EXTENDED | ||
631 | bool "Extended nameif" | ||
632 | default y | ||
633 | depends on NAMEIF | ||
634 | help | ||
635 | This extends the nameif syntax to support the bus_info and driver | ||
636 | checks. The syntax is compatible to the normal nameif. | ||
637 | File format: | ||
638 | new_interface_name driver=asix bus=usb-0000:00:08.2-3 | ||
639 | new_interface_name bus=usb-0000:00:08.2-3 00:80:C8:38:91:B5 | ||
640 | new_interface_name mac=00:80:C8:38:91:B5 | ||
641 | new_interface_name 00:80:C8:38:91:B5 | ||
642 | |||
643 | config NETSTAT | 615 | config NETSTAT |
644 | bool "netstat" | 616 | bool "netstat" |
645 | default y | 617 | default y |
646 | depends on PLATFORM_LINUX | 618 | select PLATFORM_LINUX |
647 | help | 619 | help |
648 | netstat prints information about the Linux networking subsystem. | 620 | netstat prints information about the Linux networking subsystem. |
649 | 621 | ||
@@ -672,7 +644,7 @@ config NSLOOKUP | |||
672 | config NTPD | 644 | config NTPD |
673 | bool "ntpd" | 645 | bool "ntpd" |
674 | default y | 646 | default y |
675 | depends on PLATFORM_LINUX | 647 | select PLATFORM_LINUX |
676 | help | 648 | help |
677 | The NTP client/server daemon. | 649 | The NTP client/server daemon. |
678 | 650 | ||
@@ -693,14 +665,14 @@ config PSCAN | |||
693 | config ROUTE | 665 | config ROUTE |
694 | bool "route" | 666 | bool "route" |
695 | default y | 667 | default y |
696 | depends on PLATFORM_LINUX | 668 | select PLATFORM_LINUX |
697 | help | 669 | help |
698 | Route displays or manipulates the kernel's IP routing tables. | 670 | Route displays or manipulates the kernel's IP routing tables. |
699 | 671 | ||
700 | config SLATTACH | 672 | config SLATTACH |
701 | bool "slattach" | 673 | bool "slattach" |
702 | default y | 674 | default y |
703 | depends on PLATFORM_LINUX | 675 | select PLATFORM_LINUX |
704 | help | 676 | help |
705 | slattach is a small utility to attach network interfaces to serial | 677 | slattach is a small utility to attach network interfaces to serial |
706 | lines. | 678 | lines. |
@@ -887,7 +859,7 @@ config TFTP_DEBUG | |||
887 | config TRACEROUTE | 859 | config TRACEROUTE |
888 | bool "traceroute" | 860 | bool "traceroute" |
889 | default y | 861 | default y |
890 | depends on PLATFORM_LINUX | 862 | select PLATFORM_LINUX |
891 | help | 863 | help |
892 | Utility to trace the route of IP packets. | 864 | Utility to trace the route of IP packets. |
893 | 865 | ||
@@ -924,7 +896,7 @@ config FEATURE_TRACEROUTE_USE_ICMP | |||
924 | config TUNCTL | 896 | config TUNCTL |
925 | bool "tunctl" | 897 | bool "tunctl" |
926 | default y | 898 | default y |
927 | depends on PLATFORM_LINUX | 899 | select PLATFORM_LINUX |
928 | help | 900 | help |
929 | tunctl creates or deletes tun devices. | 901 | tunctl creates or deletes tun devices. |
930 | 902 | ||
@@ -957,7 +929,7 @@ config UDPSVD | |||
957 | config VCONFIG | 929 | config VCONFIG |
958 | bool "vconfig" | 930 | bool "vconfig" |
959 | default y | 931 | default y |
960 | depends on PLATFORM_LINUX | 932 | select PLATFORM_LINUX |
961 | help | 933 | help |
962 | Creates, removes, and configures VLAN interfaces | 934 | Creates, removes, and configures VLAN interfaces |
963 | 935 | ||
@@ -1004,7 +976,7 @@ config FEATURE_WGET_TIMEOUT | |||
1004 | config ZCIP | 976 | config ZCIP |
1005 | bool "zcip" | 977 | bool "zcip" |
1006 | default y | 978 | default y |
1007 | depends on PLATFORM_LINUX | 979 | select PLATFORM_LINUX |
1008 | select FEATURE_SYSLOG | 980 | select FEATURE_SYSLOG |
1009 | help | 981 | help |
1010 | ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927. | 982 | ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927. |
diff --git a/networking/ftpd.c b/networking/ftpd.c index 64068e467..b59135667 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c | |||
@@ -12,6 +12,23 @@ | |||
12 | * You have to run this daemon via inetd. | 12 | * You have to run this daemon via inetd. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | //usage:#define ftpd_trivial_usage | ||
16 | //usage: "[-wvS] [-t N] [-T N] [DIR]" | ||
17 | //usage:#define ftpd_full_usage "\n\n" | ||
18 | //usage: "Anonymous FTP server\n" | ||
19 | //usage: "\n" | ||
20 | //usage: "ftpd should be used as an inetd service.\n" | ||
21 | //usage: "ftpd's line for inetd.conf:\n" | ||
22 | //usage: " 21 stream tcp nowait root ftpd ftpd /files/to/serve\n" | ||
23 | //usage: "It also can be ran from tcpsvd:\n" | ||
24 | //usage: " tcpsvd -vE 0.0.0.0 21 ftpd /files/to/serve\n" | ||
25 | //usage: "\nOptions:" | ||
26 | //usage: "\n -w Allow upload" | ||
27 | //usage: "\n -v Log errors to stderr. -vv: verbose log" | ||
28 | //usage: "\n -S Log errors to syslog. -SS: verbose log" | ||
29 | //usage: "\n -t,-T Idle and absolute timeouts" | ||
30 | //usage: "\n DIR Change root to this directory" | ||
31 | |||
15 | #include "libbb.h" | 32 | #include "libbb.h" |
16 | #include <syslog.h> | 33 | #include <syslog.h> |
17 | #include <netinet/tcp.h> | 34 | #include <netinet/tcp.h> |
@@ -206,7 +223,7 @@ cmdio_write_error(unsigned status) | |||
206 | { | 223 | { |
207 | *(uint32_t *) G.msg_err = status; | 224 | *(uint32_t *) G.msg_err = status; |
208 | xwrite(STDOUT_FILENO, G.msg_err, sizeof("NNN " MSG_ERR) - 1); | 225 | xwrite(STDOUT_FILENO, G.msg_err, sizeof("NNN " MSG_ERR) - 1); |
209 | if (G.verbose > 1) | 226 | if (G.verbose > 0) |
210 | verbose_log(G.msg_err); | 227 | verbose_log(G.msg_err); |
211 | } | 228 | } |
212 | #define WRITE_ERR(a) cmdio_write_error(STRNUM32sp(a)) | 229 | #define WRITE_ERR(a) cmdio_write_error(STRNUM32sp(a)) |
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 59df4e80f..7706a84b7 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -106,6 +106,7 @@ enum { | |||
106 | struct globals { | 106 | struct globals { |
107 | char **my_environ; | 107 | char **my_environ; |
108 | const char *startup_PATH; | 108 | const char *startup_PATH; |
109 | char *shell; | ||
109 | } FIX_ALIASING; | 110 | } FIX_ALIASING; |
110 | #define G (*(struct globals*)&bb_common_bufsiz1) | 111 | #define G (*(struct globals*)&bb_common_bufsiz1) |
111 | #define INIT_G() do { } while (0) | 112 | #define INIT_G() do { } while (0) |
@@ -986,11 +987,10 @@ static int doit(char *str) | |||
986 | 987 | ||
987 | fflush_all(); | 988 | fflush_all(); |
988 | child = vfork(); | 989 | child = vfork(); |
989 | switch (child) { | 990 | if (child < 0) /* failure */ |
990 | case -1: /* failure */ | ||
991 | return 0; | 991 | return 0; |
992 | case 0: /* child */ | 992 | if (child == 0) { /* child */ |
993 | execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, (char *) NULL, G.my_environ); | 993 | execle(G.shell, G.shell, "-c", str, (char *) NULL, G.my_environ); |
994 | _exit(127); | 994 | _exit(127); |
995 | } | 995 | } |
996 | safe_waitpid(child, &status, 0); | 996 | safe_waitpid(child, &status, 0); |
@@ -1165,6 +1165,7 @@ int ifupdown_main(int argc UNUSED_PARAM, char **argv) | |||
1165 | INIT_G(); | 1165 | INIT_G(); |
1166 | 1166 | ||
1167 | G.startup_PATH = getenv("PATH"); | 1167 | G.startup_PATH = getenv("PATH"); |
1168 | G.shell = xstrdup(get_shell_name()); | ||
1168 | 1169 | ||
1169 | cmds = iface_down; | 1170 | cmds = iface_down; |
1170 | if (applet_name[2] == 'u') { | 1171 | if (applet_name[2] == 'u') { |
@@ -1220,13 +1221,13 @@ int ifupdown_main(int argc UNUSED_PARAM, char **argv) | |||
1220 | /* ifup */ | 1221 | /* ifup */ |
1221 | if (iface_state) { | 1222 | if (iface_state) { |
1222 | bb_error_msg("interface %s already configured", iface); | 1223 | bb_error_msg("interface %s already configured", iface); |
1223 | continue; | 1224 | goto next; |
1224 | } | 1225 | } |
1225 | } else { | 1226 | } else { |
1226 | /* ifdown */ | 1227 | /* ifdown */ |
1227 | if (!iface_state) { | 1228 | if (!iface_state) { |
1228 | bb_error_msg("interface %s not configured", iface); | 1229 | bb_error_msg("interface %s not configured", iface); |
1229 | continue; | 1230 | goto next; |
1230 | } | 1231 | } |
1231 | } | 1232 | } |
1232 | llist_free(state_list, free); | 1233 | llist_free(state_list, free); |
@@ -1316,6 +1317,9 @@ int ifupdown_main(int argc UNUSED_PARAM, char **argv) | |||
1316 | fclose(state_fp); | 1317 | fclose(state_fp); |
1317 | llist_free(state_list, free); | 1318 | llist_free(state_list, free); |
1318 | } | 1319 | } |
1320 | next: | ||
1321 | free(iface); | ||
1322 | free(liface); | ||
1319 | } | 1323 | } |
1320 | 1324 | ||
1321 | return any_failures; | 1325 | return any_failures; |
diff --git a/networking/nameif.c b/networking/nameif.c index d02c2c11b..78719edac 100644 --- a/networking/nameif.c +++ b/networking/nameif.c | |||
@@ -10,6 +10,66 @@ | |||
10 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 10 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | //config:config NAMEIF | ||
14 | //config: bool "nameif" | ||
15 | //config: default y | ||
16 | //config: select PLATFORM_LINUX | ||
17 | //config: select FEATURE_SYSLOG | ||
18 | //config: help | ||
19 | //config: nameif is used to rename network interface by its MAC address. | ||
20 | //config: Renamed interfaces MUST be in the down state. | ||
21 | //config: It is possible to use a file (default: /etc/mactab) | ||
22 | //config: with list of new interface names and MACs. | ||
23 | //config: Maximum interface name length: IFNAMSIZ = 16 | ||
24 | //config: File fields are separated by space or tab. | ||
25 | //config: File format: | ||
26 | //config: # Comment | ||
27 | //config: new_interface_name XX:XX:XX:XX:XX:XX | ||
28 | //config: | ||
29 | //config:config FEATURE_NAMEIF_EXTENDED | ||
30 | //config: bool "Extended nameif" | ||
31 | //config: default y | ||
32 | //config: depends on NAMEIF | ||
33 | //config: help | ||
34 | //config: This extends the nameif syntax to support the bus_info, driver, | ||
35 | //config: phyaddr selectors. The syntax is compatible to the normal nameif. | ||
36 | //config: File format: | ||
37 | //config: new_interface_name driver=asix bus=usb-0000:00:08.2-3 | ||
38 | //config: new_interface_name bus=usb-0000:00:08.2-3 00:80:C8:38:91:B5 | ||
39 | //config: new_interface_name phy_address=2 00:80:C8:38:91:B5 | ||
40 | //config: new_interface_name mac=00:80:C8:38:91:B5 | ||
41 | //config: new_interface_name 00:80:C8:38:91:B5 | ||
42 | |||
43 | //usage:#define nameif_trivial_usage | ||
44 | //usage: IF_NOT_FEATURE_NAMEIF_EXTENDED( | ||
45 | //usage: "[-s] [-c FILE] [IFNAME HWADDR]..." | ||
46 | //usage: ) | ||
47 | //usage: IF_FEATURE_NAMEIF_EXTENDED( | ||
48 | //usage: "[-s] [-c FILE] [IFNAME SELECTOR]..." | ||
49 | //usage: ) | ||
50 | //usage:#define nameif_full_usage "\n\n" | ||
51 | //usage: "Rename network interface while it in the down state." | ||
52 | //usage: IF_NOT_FEATURE_NAMEIF_EXTENDED( | ||
53 | //usage: "\nThe device with address HWADDR is renamed to IFACE." | ||
54 | //usage: ) | ||
55 | //usage: IF_FEATURE_NAMEIF_EXTENDED( | ||
56 | //usage: "\nThe device matched by SELECTOR is renamed to IFACE." | ||
57 | //usage: "\nSELECTOR can be a combination of:" | ||
58 | //usage: "\n driver=STRING" | ||
59 | //usage: "\n bus=STRING" | ||
60 | //usage: "\n phy_address=NUM" | ||
61 | //usage: "\n [mac=]XX:XX:XX:XX:XX:XX" | ||
62 | //usage: ) | ||
63 | //usage: "\n" | ||
64 | //usage: "\nOptions:" | ||
65 | //usage: "\n -c FILE Configuration file (default: /etc/mactab)" | ||
66 | //usage: "\n -s Log to syslog" | ||
67 | //usage: | ||
68 | //usage:#define nameif_example_usage | ||
69 | //usage: "$ nameif -s dmz0 00:A0:C9:8C:F6:3F\n" | ||
70 | //usage: " or\n" | ||
71 | //usage: "$ nameif -c /etc/my_mactab_file\n" | ||
72 | |||
13 | #include "libbb.h" | 73 | #include "libbb.h" |
14 | #include <syslog.h> | 74 | #include <syslog.h> |
15 | #include <net/if.h> | 75 | #include <net/if.h> |
@@ -38,6 +98,7 @@ typedef struct ethtable_s { | |||
38 | #if ENABLE_FEATURE_NAMEIF_EXTENDED | 98 | #if ENABLE_FEATURE_NAMEIF_EXTENDED |
39 | char *bus_info; | 99 | char *bus_info; |
40 | char *driver; | 100 | char *driver; |
101 | int32_t phy_address; | ||
41 | #endif | 102 | #endif |
42 | } ethtable_t; | 103 | } ethtable_t; |
43 | 104 | ||
@@ -59,6 +120,25 @@ struct ethtool_drvinfo { | |||
59 | uint32_t eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ | 120 | uint32_t eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ |
60 | uint32_t regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */ | 121 | uint32_t regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */ |
61 | }; | 122 | }; |
123 | |||
124 | struct ethtool_cmd { | ||
125 | __u32 cmd; | ||
126 | __u32 supported; /* Features this interface supports */ | ||
127 | __u32 advertising; /* Features this interface advertises */ | ||
128 | __u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ | ||
129 | __u8 duplex; /* Duplex, half or full */ | ||
130 | __u8 port; /* Which connector port */ | ||
131 | __u8 phy_address; | ||
132 | __u8 transceiver; /* Which transceiver to use */ | ||
133 | __u8 autoneg; /* Enable or disable autonegotiation */ | ||
134 | __u32 maxtxpkt; /* Tx pkts before generating tx int */ | ||
135 | __u32 maxrxpkt; /* Rx pkts before generating rx int */ | ||
136 | __u16 speed_hi; | ||
137 | __u16 reserved2; | ||
138 | __u32 reserved[3]; | ||
139 | }; | ||
140 | |||
141 | #define ETHTOOL_GSET 0x00000001 /* Get settings. */ | ||
62 | #define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */ | 142 | #define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */ |
63 | #endif | 143 | #endif |
64 | 144 | ||
@@ -74,6 +154,7 @@ static void nameif_parse_selector(ethtable_t *ch, char *selector) | |||
74 | #endif | 154 | #endif |
75 | selector = skip_whitespace(selector); | 155 | selector = skip_whitespace(selector); |
76 | #if ENABLE_FEATURE_NAMEIF_EXTENDED | 156 | #if ENABLE_FEATURE_NAMEIF_EXTENDED |
157 | ch->phy_address = -1; | ||
77 | if (*selector == '\0') | 158 | if (*selector == '\0') |
78 | break; | 159 | break; |
79 | /* Search for the end .... */ | 160 | /* Search for the end .... */ |
@@ -87,6 +168,9 @@ static void nameif_parse_selector(ethtable_t *ch, char *selector) | |||
87 | } else if (strncmp(selector, "driver=", 7) == 0) { | 168 | } else if (strncmp(selector, "driver=", 7) == 0) { |
88 | ch->driver = xstrdup(selector + 7); | 169 | ch->driver = xstrdup(selector + 7); |
89 | found_selector++; | 170 | found_selector++; |
171 | } else if (strncmp(selector, "phyaddr=", 8) == 0) { | ||
172 | ch->phy_address = xatoi_positive(selector + 8); | ||
173 | found_selector++; | ||
90 | } else { | 174 | } else { |
91 | #endif | 175 | #endif |
92 | lmac = xmalloc(ETH_ALEN); | 176 | lmac = xmalloc(ETH_ALEN); |
@@ -133,7 +217,7 @@ void delete_eth_table(ethtable_t *ch); | |||
133 | #endif | 217 | #endif |
134 | 218 | ||
135 | int nameif_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 219 | int nameif_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
136 | int nameif_main(int argc, char **argv) | 220 | int nameif_main(int argc UNUSED_PARAM, char **argv) |
137 | { | 221 | { |
138 | ethtable_t *clist = NULL; | 222 | ethtable_t *clist = NULL; |
139 | const char *fname = "/etc/mactab"; | 223 | const char *fname = "/etc/mactab"; |
@@ -148,17 +232,15 @@ int nameif_main(int argc, char **argv) | |||
148 | * can't hurt. 2>/dev/null if you don't like it: */ | 232 | * can't hurt. 2>/dev/null if you don't like it: */ |
149 | logmode |= LOGMODE_SYSLOG; | 233 | logmode |= LOGMODE_SYSLOG; |
150 | } | 234 | } |
151 | argc -= optind; | ||
152 | argv += optind; | 235 | argv += optind; |
153 | 236 | ||
154 | if (argc & 1) | 237 | if (argv[0]) { |
155 | bb_show_usage(); | 238 | do { |
156 | 239 | if (!argv[1]) | |
157 | if (argc) { | 240 | bb_show_usage(); |
158 | while (*argv) { | 241 | prepend_new_eth_table(&clist, argv[0], argv[1]); |
159 | char *ifname = xstrdup(*argv++); | 242 | argv += 2; |
160 | prepend_new_eth_table(&clist, ifname, *argv++); | 243 | } while (*argv); |
161 | } | ||
162 | } else { | 244 | } else { |
163 | parser = config_open(fname); | 245 | parser = config_open(fname); |
164 | while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) | 246 | while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) |
@@ -173,8 +255,9 @@ int nameif_main(int argc, char **argv) | |||
173 | struct ifreq ifr; | 255 | struct ifreq ifr; |
174 | #if ENABLE_FEATURE_NAMEIF_EXTENDED | 256 | #if ENABLE_FEATURE_NAMEIF_EXTENDED |
175 | struct ethtool_drvinfo drvinfo; | 257 | struct ethtool_drvinfo drvinfo; |
258 | struct ethtool_cmd eth_settings; | ||
176 | #endif | 259 | #endif |
177 | if (parser->lineno < 2) | 260 | if (parser->lineno <= 2) |
178 | continue; /* Skip the first two lines */ | 261 | continue; /* Skip the first two lines */ |
179 | 262 | ||
180 | /* Find the current interface name and copy it to ifr.ifr_name */ | 263 | /* Find the current interface name and copy it to ifr.ifr_name */ |
@@ -182,8 +265,14 @@ int nameif_main(int argc, char **argv) | |||
182 | strncpy_IFNAMSIZ(ifr.ifr_name, token[0]); | 265 | strncpy_IFNAMSIZ(ifr.ifr_name, token[0]); |
183 | 266 | ||
184 | #if ENABLE_FEATURE_NAMEIF_EXTENDED | 267 | #if ENABLE_FEATURE_NAMEIF_EXTENDED |
268 | /* Check for phy address */ | ||
269 | memset(ð_settings, 0, sizeof(eth_settings)); | ||
270 | eth_settings.cmd = ETHTOOL_GSET; | ||
271 | ifr.ifr_data = (caddr_t) ð_settings; | ||
272 | ioctl(ctl_sk, SIOCETHTOOL, &ifr); | ||
273 | |||
185 | /* Check for driver etc. */ | 274 | /* Check for driver etc. */ |
186 | memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); | 275 | memset(&drvinfo, 0, sizeof(drvinfo)); |
187 | drvinfo.cmd = ETHTOOL_GDRVINFO; | 276 | drvinfo.cmd = ETHTOOL_GDRVINFO; |
188 | ifr.ifr_data = (caddr_t) &drvinfo; | 277 | ifr.ifr_data = (caddr_t) &drvinfo; |
189 | /* Get driver and businfo first, so we have it in drvinfo */ | 278 | /* Get driver and businfo first, so we have it in drvinfo */ |
@@ -198,6 +287,8 @@ int nameif_main(int argc, char **argv) | |||
198 | continue; | 287 | continue; |
199 | if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0) | 288 | if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0) |
200 | continue; | 289 | continue; |
290 | if (ch->phy_address != -1 && ch->phy_address != eth_settings.phy_address) | ||
291 | continue; | ||
201 | #endif | 292 | #endif |
202 | if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0) | 293 | if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0) |
203 | continue; | 294 | continue; |
diff --git a/networking/nslookup.c b/networking/nslookup.c index dcac7379e..67fc01547 100644 --- a/networking/nslookup.c +++ b/networking/nslookup.c | |||
@@ -66,7 +66,7 @@ static int print_host(const char *hostname, const char *header) | |||
66 | // hint.ai_flags = AI_CANONNAME; | 66 | // hint.ai_flags = AI_CANONNAME; |
67 | rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result); | 67 | rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result); |
68 | 68 | ||
69 | if (!rc) { | 69 | if (rc == 0) { |
70 | struct addrinfo *cur = result; | 70 | struct addrinfo *cur = result; |
71 | unsigned cnt = 0; | 71 | unsigned cnt = 0; |
72 | 72 | ||
@@ -94,7 +94,7 @@ static int print_host(const char *hostname, const char *header) | |||
94 | bb_error_msg("can't resolve '%s'", hostname); | 94 | bb_error_msg("can't resolve '%s'", hostname); |
95 | #endif | 95 | #endif |
96 | } | 96 | } |
97 | if (ENABLE_FEATURE_CLEAN_UP) | 97 | if (ENABLE_FEATURE_CLEAN_UP && result) |
98 | freeaddrinfo(result); | 98 | freeaddrinfo(result); |
99 | return (rc != 0); | 99 | return (rc != 0); |
100 | } | 100 | } |
diff --git a/networking/ping.c b/networking/ping.c index c2ff42e2c..7a9c2d1f0 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -32,7 +32,7 @@ | |||
32 | //config:config PING | 32 | //config:config PING |
33 | //config: bool "ping" | 33 | //config: bool "ping" |
34 | //config: default y | 34 | //config: default y |
35 | //config: depends on PLATFORM_LINUX | 35 | //config: select PLATFORM_LINUX |
36 | //config: help | 36 | //config: help |
37 | //config: ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to | 37 | //config: ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to |
38 | //config: elicit an ICMP ECHO_RESPONSE from a host or gateway. | 38 | //config: elicit an ICMP ECHO_RESPONSE from a host or gateway. |
diff --git a/networking/route.c b/networking/route.c index b7d08dd63..98a03ded7 100644 --- a/networking/route.c +++ b/networking/route.c | |||
@@ -537,6 +537,7 @@ void FAST_FUNC bb_displayroutes(int noresolve, int netstatfmt) | |||
537 | printf("%-6d %-2d %7d %s\n", metric, ref, use, devname); | 537 | printf("%-6d %-2d %7d %s\n", metric, ref, use, devname); |
538 | } | 538 | } |
539 | } | 539 | } |
540 | fclose(fp); | ||
540 | } | 541 | } |
541 | 542 | ||
542 | #if ENABLE_FEATURE_IPV6 | 543 | #if ENABLE_FEATURE_IPV6 |
@@ -604,7 +605,7 @@ static void INET6_displayroutes(void) | |||
604 | set_flags(flags, (iflags & IPV6_MASK)); | 605 | set_flags(flags, (iflags & IPV6_MASK)); |
605 | 606 | ||
606 | r = 0; | 607 | r = 0; |
607 | do { | 608 | while (1) { |
608 | inet_pton(AF_INET6, addr6x + r, | 609 | inet_pton(AF_INET6, addr6x + r, |
609 | (struct sockaddr *) &snaddr6.sin6_addr); | 610 | (struct sockaddr *) &snaddr6.sin6_addr); |
610 | snaddr6.sin6_family = AF_INET6; | 611 | snaddr6.sin6_family = AF_INET6; |
@@ -623,8 +624,9 @@ static void INET6_displayroutes(void) | |||
623 | free(naddr6); | 624 | free(naddr6); |
624 | break; | 625 | break; |
625 | } | 626 | } |
626 | } while (1); | 627 | } |
627 | } | 628 | } |
629 | fclose(fp); | ||
628 | } | 630 | } |
629 | 631 | ||
630 | #endif | 632 | #endif |
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index 750a53a32..9cd8cbbae 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src | |||
@@ -8,7 +8,7 @@ INSERT | |||
8 | config UDHCPD | 8 | config UDHCPD |
9 | bool "udhcp server (udhcpd)" | 9 | bool "udhcp server (udhcpd)" |
10 | default y | 10 | default y |
11 | depends on PLATFORM_LINUX | 11 | select PLATFORM_LINUX |
12 | help | 12 | help |
13 | udhcpd is a DHCP server geared primarily toward embedded systems, | 13 | udhcpd is a DHCP server geared primarily toward embedded systems, |
14 | while striving to be fully functional and RFC compliant. | 14 | while striving to be fully functional and RFC compliant. |
@@ -66,7 +66,7 @@ config DHCPD_LEASES_FILE | |||
66 | config UDHCPC | 66 | config UDHCPC |
67 | bool "udhcp client (udhcpc)" | 67 | bool "udhcp client (udhcpc)" |
68 | default y | 68 | default y |
69 | depends on PLATFORM_LINUX | 69 | select PLATFORM_LINUX |
70 | help | 70 | help |
71 | udhcpc is a DHCP client geared primarily toward embedded systems, | 71 | udhcpc is a DHCP client geared primarily toward embedded systems, |
72 | while striving to be fully functional and RFC compliant. | 72 | while striving to be fully functional and RFC compliant. |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index d97a404fa..ca82d37e6 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -38,6 +38,67 @@ | |||
38 | /* struct client_config_t client_config is in bb_common_bufsiz1 */ | 38 | /* struct client_config_t client_config is in bb_common_bufsiz1 */ |
39 | 39 | ||
40 | 40 | ||
41 | #if ENABLE_LONG_OPTS | ||
42 | static const char udhcpc_longopts[] ALIGN1 = | ||
43 | "clientid-none\0" No_argument "C" | ||
44 | "vendorclass\0" Required_argument "V" | ||
45 | "hostname\0" Required_argument "H" | ||
46 | "fqdn\0" Required_argument "F" | ||
47 | "interface\0" Required_argument "i" | ||
48 | "now\0" No_argument "n" | ||
49 | "pidfile\0" Required_argument "p" | ||
50 | "quit\0" No_argument "q" | ||
51 | "release\0" No_argument "R" | ||
52 | "request\0" Required_argument "r" | ||
53 | "script\0" Required_argument "s" | ||
54 | "timeout\0" Required_argument "T" | ||
55 | "version\0" No_argument "v" | ||
56 | "retries\0" Required_argument "t" | ||
57 | "tryagain\0" Required_argument "A" | ||
58 | "syslog\0" No_argument "S" | ||
59 | "request-option\0" Required_argument "O" | ||
60 | "no-default-options\0" No_argument "o" | ||
61 | "foreground\0" No_argument "f" | ||
62 | "background\0" No_argument "b" | ||
63 | "broadcast\0" No_argument "B" | ||
64 | IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a") | ||
65 | IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") | ||
66 | ; | ||
67 | #endif | ||
68 | /* Must match getopt32 option string order */ | ||
69 | enum { | ||
70 | OPT_C = 1 << 0, | ||
71 | OPT_V = 1 << 1, | ||
72 | OPT_H = 1 << 2, | ||
73 | OPT_h = 1 << 3, | ||
74 | OPT_F = 1 << 4, | ||
75 | OPT_i = 1 << 5, | ||
76 | OPT_n = 1 << 6, | ||
77 | OPT_p = 1 << 7, | ||
78 | OPT_q = 1 << 8, | ||
79 | OPT_R = 1 << 9, | ||
80 | OPT_r = 1 << 10, | ||
81 | OPT_s = 1 << 11, | ||
82 | OPT_T = 1 << 12, | ||
83 | OPT_t = 1 << 13, | ||
84 | OPT_S = 1 << 14, | ||
85 | OPT_A = 1 << 15, | ||
86 | OPT_O = 1 << 16, | ||
87 | OPT_o = 1 << 17, | ||
88 | OPT_x = 1 << 18, | ||
89 | OPT_f = 1 << 19, | ||
90 | OPT_B = 1 << 20, | ||
91 | /* The rest has variable bit positions, need to be clever */ | ||
92 | OPTBIT_B = 20, | ||
93 | USE_FOR_MMU( OPTBIT_b,) | ||
94 | IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,) | ||
95 | IF_FEATURE_UDHCP_PORT( OPTBIT_P,) | ||
96 | USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,) | ||
97 | IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,) | ||
98 | IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) | ||
99 | }; | ||
100 | |||
101 | |||
41 | /*** Script execution code ***/ | 102 | /*** Script execution code ***/ |
42 | 103 | ||
43 | /* get a rough idea of how long an option will be (rounding up...) */ | 104 | /* get a rough idea of how long an option will be (rounding up...) */ |
@@ -346,11 +407,19 @@ static ALWAYS_INLINE uint32_t random_xid(void) | |||
346 | /* Initialize the packet with the proper defaults */ | 407 | /* Initialize the packet with the proper defaults */ |
347 | static void init_packet(struct dhcp_packet *packet, char type) | 408 | static void init_packet(struct dhcp_packet *packet, char type) |
348 | { | 409 | { |
410 | uint16_t secs; | ||
411 | |||
349 | /* Fill in: op, htype, hlen, cookie fields; message type option: */ | 412 | /* Fill in: op, htype, hlen, cookie fields; message type option: */ |
350 | udhcp_init_header(packet, type); | 413 | udhcp_init_header(packet, type); |
351 | 414 | ||
352 | packet->xid = random_xid(); | 415 | packet->xid = random_xid(); |
353 | 416 | ||
417 | client_config.last_secs = monotonic_sec(); | ||
418 | if (client_config.first_secs == 0) | ||
419 | client_config.first_secs = client_config.last_secs; | ||
420 | secs = client_config.last_secs - client_config.first_secs; | ||
421 | packet->secs = htons(secs); | ||
422 | |||
354 | memcpy(packet->chaddr, client_config.client_mac, 6); | 423 | memcpy(packet->chaddr, client_config.client_mac, 6); |
355 | if (client_config.clientid) | 424 | if (client_config.clientid) |
356 | udhcp_add_binary_option(packet, client_config.clientid); | 425 | udhcp_add_binary_option(packet, client_config.clientid); |
@@ -391,6 +460,10 @@ static void add_client_options(struct dhcp_packet *packet) | |||
391 | if (client_config.fqdn) | 460 | if (client_config.fqdn) |
392 | udhcp_add_binary_option(packet, client_config.fqdn); | 461 | udhcp_add_binary_option(packet, client_config.fqdn); |
393 | 462 | ||
463 | /* Request broadcast replies if we have no IP addr */ | ||
464 | if ((option_mask32 & OPT_B) && packet->ciaddr == 0) | ||
465 | packet->flags |= htons(BROADCAST_FLAG); | ||
466 | |||
394 | /* Add -x options if any */ | 467 | /* Add -x options if any */ |
395 | { | 468 | { |
396 | struct option_set *curr = client_config.options; | 469 | struct option_set *curr = client_config.options; |
@@ -783,6 +856,7 @@ static void change_listen_mode(int new_mode) | |||
783 | /* else LISTEN_NONE: sockfd stays closed */ | 856 | /* else LISTEN_NONE: sockfd stays closed */ |
784 | } | 857 | } |
785 | 858 | ||
859 | /* Called only on SIGUSR1 */ | ||
786 | static void perform_renew(void) | 860 | static void perform_renew(void) |
787 | { | 861 | { |
788 | bb_info_msg("Performing a DHCP renew"); | 862 | bb_info_msg("Performing a DHCP renew"); |
@@ -853,13 +927,14 @@ static void client_background(void) | |||
853 | //usage:# define IF_UDHCP_VERBOSE(...) | 927 | //usage:# define IF_UDHCP_VERBOSE(...) |
854 | //usage:#endif | 928 | //usage:#endif |
855 | //usage:#define udhcpc_trivial_usage | 929 | //usage:#define udhcpc_trivial_usage |
856 | //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCR] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" | 930 | //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" |
857 | //usage: " [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") | 931 | //usage: " [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") |
858 | //usage:#define udhcpc_full_usage "\n" | 932 | //usage:#define udhcpc_full_usage "\n" |
859 | //usage: IF_LONG_OPTS( | 933 | //usage: IF_LONG_OPTS( |
860 | //usage: "\n -i,--interface IFACE Interface to use (default eth0)" | 934 | //usage: "\n -i,--interface IFACE Interface to use (default eth0)" |
861 | //usage: "\n -p,--pidfile FILE Create pidfile" | 935 | //usage: "\n -p,--pidfile FILE Create pidfile" |
862 | //usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" | 936 | //usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" |
937 | //usage: "\n -B,--broadcast Request broadcast replies" | ||
863 | //usage: "\n -t,--retries N Send up to N discover packets" | 938 | //usage: "\n -t,--retries N Send up to N discover packets" |
864 | //usage: "\n -T,--timeout N Pause between packets (default 3 seconds)" | 939 | //usage: "\n -T,--timeout N Pause between packets (default 3 seconds)" |
865 | //usage: "\n -A,--tryagain N Wait N seconds after failure (default 20)" | 940 | //usage: "\n -A,--tryagain N Wait N seconds after failure (default 20)" |
@@ -897,6 +972,7 @@ static void client_background(void) | |||
897 | //usage: "\n -i IFACE Interface to use (default eth0)" | 972 | //usage: "\n -i IFACE Interface to use (default eth0)" |
898 | //usage: "\n -p FILE Create pidfile" | 973 | //usage: "\n -p FILE Create pidfile" |
899 | //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" | 974 | //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" |
975 | //usage: "\n -B Request broadcast replies" | ||
900 | //usage: "\n -t N Send up to N discover packets" | 976 | //usage: "\n -t N Send up to N discover packets" |
901 | //usage: "\n -T N Pause between packets (default 3 seconds)" | 977 | //usage: "\n -T N Pause between packets (default 3 seconds)" |
902 | //usage: "\n -A N Wait N seconds (default 20) after failure" | 978 | //usage: "\n -A N Wait N seconds (default 20) after failure" |
@@ -961,63 +1037,6 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
961 | struct dhcp_packet packet; | 1037 | struct dhcp_packet packet; |
962 | fd_set rfds; | 1038 | fd_set rfds; |
963 | 1039 | ||
964 | #if ENABLE_LONG_OPTS | ||
965 | static const char udhcpc_longopts[] ALIGN1 = | ||
966 | "clientid-none\0" No_argument "C" | ||
967 | "vendorclass\0" Required_argument "V" | ||
968 | "hostname\0" Required_argument "H" | ||
969 | "fqdn\0" Required_argument "F" | ||
970 | "interface\0" Required_argument "i" | ||
971 | "now\0" No_argument "n" | ||
972 | "pidfile\0" Required_argument "p" | ||
973 | "quit\0" No_argument "q" | ||
974 | "release\0" No_argument "R" | ||
975 | "request\0" Required_argument "r" | ||
976 | "script\0" Required_argument "s" | ||
977 | "timeout\0" Required_argument "T" | ||
978 | "version\0" No_argument "v" | ||
979 | "retries\0" Required_argument "t" | ||
980 | "tryagain\0" Required_argument "A" | ||
981 | "syslog\0" No_argument "S" | ||
982 | "request-option\0" Required_argument "O" | ||
983 | "no-default-options\0" No_argument "o" | ||
984 | "foreground\0" No_argument "f" | ||
985 | "background\0" No_argument "b" | ||
986 | IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a") | ||
987 | IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") | ||
988 | ; | ||
989 | #endif | ||
990 | enum { | ||
991 | OPT_C = 1 << 0, | ||
992 | OPT_V = 1 << 1, | ||
993 | OPT_H = 1 << 2, | ||
994 | OPT_h = 1 << 3, | ||
995 | OPT_F = 1 << 4, | ||
996 | OPT_i = 1 << 5, | ||
997 | OPT_n = 1 << 6, | ||
998 | OPT_p = 1 << 7, | ||
999 | OPT_q = 1 << 8, | ||
1000 | OPT_R = 1 << 9, | ||
1001 | OPT_r = 1 << 10, | ||
1002 | OPT_s = 1 << 11, | ||
1003 | OPT_T = 1 << 12, | ||
1004 | OPT_t = 1 << 13, | ||
1005 | OPT_S = 1 << 14, | ||
1006 | OPT_A = 1 << 15, | ||
1007 | OPT_O = 1 << 16, | ||
1008 | OPT_o = 1 << 17, | ||
1009 | OPT_x = 1 << 18, | ||
1010 | OPT_f = 1 << 19, | ||
1011 | /* The rest has variable bit positions, need to be clever */ | ||
1012 | OPTBIT_f = 19, | ||
1013 | USE_FOR_MMU( OPTBIT_b,) | ||
1014 | IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,) | ||
1015 | IF_FEATURE_UDHCP_PORT( OPTBIT_P,) | ||
1016 | USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,) | ||
1017 | IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,) | ||
1018 | IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) | ||
1019 | }; | ||
1020 | |||
1021 | /* Default options */ | 1040 | /* Default options */ |
1022 | IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) | 1041 | IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) |
1023 | IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) | 1042 | IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) |
@@ -1033,7 +1052,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1033 | #endif | 1052 | #endif |
1034 | ; | 1053 | ; |
1035 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) | 1054 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) |
1036 | opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:f" | 1055 | opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" |
1037 | USE_FOR_MMU("b") | 1056 | USE_FOR_MMU("b") |
1038 | IF_FEATURE_UDHCPC_ARPING("a") | 1057 | IF_FEATURE_UDHCPC_ARPING("a") |
1039 | IF_FEATURE_UDHCP_PORT("P:") | 1058 | IF_FEATURE_UDHCP_PORT("P:") |
@@ -1250,6 +1269,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1250 | case BOUND: | 1269 | case BOUND: |
1251 | /* 1/2 lease passed, enter renewing state */ | 1270 | /* 1/2 lease passed, enter renewing state */ |
1252 | state = RENEWING; | 1271 | state = RENEWING; |
1272 | client_config.first_secs = 0; /* make secs field count from 0 */ | ||
1253 | change_listen_mode(LISTEN_KERNEL); | 1273 | change_listen_mode(LISTEN_KERNEL); |
1254 | log1("Entering renew state"); | 1274 | log1("Entering renew state"); |
1255 | /* fall right through */ | 1275 | /* fall right through */ |
@@ -1289,6 +1309,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1289 | bb_info_msg("Lease lost, entering init state"); | 1309 | bb_info_msg("Lease lost, entering init state"); |
1290 | udhcp_run_script(NULL, "deconfig"); | 1310 | udhcp_run_script(NULL, "deconfig"); |
1291 | state = INIT_SELECTING; | 1311 | state = INIT_SELECTING; |
1312 | client_config.first_secs = 0; /* make secs field count from 0 */ | ||
1292 | /*timeout = 0; - already is */ | 1313 | /*timeout = 0; - already is */ |
1293 | packet_num = 0; | 1314 | packet_num = 0; |
1294 | continue; | 1315 | continue; |
@@ -1305,6 +1326,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1305 | /* note: udhcp_sp_read checks FD_ISSET before reading */ | 1326 | /* note: udhcp_sp_read checks FD_ISSET before reading */ |
1306 | switch (udhcp_sp_read(&rfds)) { | 1327 | switch (udhcp_sp_read(&rfds)) { |
1307 | case SIGUSR1: | 1328 | case SIGUSR1: |
1329 | client_config.first_secs = 0; /* make secs field count from 0 */ | ||
1308 | perform_renew(); | 1330 | perform_renew(); |
1309 | if (state == RENEW_REQUESTED) | 1331 | if (state == RENEW_REQUESTED) |
1310 | goto case_RENEW_REQUESTED; | 1332 | goto case_RENEW_REQUESTED; |
@@ -1436,6 +1458,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1436 | udhcp_run_script(NULL, "deconfig"); | 1458 | udhcp_run_script(NULL, "deconfig"); |
1437 | change_listen_mode(LISTEN_RAW); | 1459 | change_listen_mode(LISTEN_RAW); |
1438 | state = INIT_SELECTING; | 1460 | state = INIT_SELECTING; |
1461 | client_config.first_secs = 0; /* make secs field count from 0 */ | ||
1439 | requested_ip = 0; | 1462 | requested_ip = 0; |
1440 | timeout = tryagain_timeout; | 1463 | timeout = tryagain_timeout; |
1441 | packet_num = 0; | 1464 | packet_num = 0; |
@@ -1483,6 +1506,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1483 | change_listen_mode(LISTEN_RAW); | 1506 | change_listen_mode(LISTEN_RAW); |
1484 | sleep(3); /* avoid excessive network traffic */ | 1507 | sleep(3); /* avoid excessive network traffic */ |
1485 | state = INIT_SELECTING; | 1508 | state = INIT_SELECTING; |
1509 | client_config.first_secs = 0; /* make secs field count from 0 */ | ||
1486 | requested_ip = 0; | 1510 | requested_ip = 0; |
1487 | timeout = 0; | 1511 | timeout = 0; |
1488 | packet_num = 0; | 1512 | packet_num = 0; |
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index 9ef053a1b..2b3599120 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h | |||
@@ -21,6 +21,9 @@ struct client_config_t { | |||
21 | uint8_t *vendorclass; /* Optional vendor class-id to use */ | 21 | uint8_t *vendorclass; /* Optional vendor class-id to use */ |
22 | uint8_t *hostname; /* Optional hostname to use */ | 22 | uint8_t *hostname; /* Optional hostname to use */ |
23 | uint8_t *fqdn; /* Optional fully qualified domain name to use */ | 23 | uint8_t *fqdn; /* Optional fully qualified domain name to use */ |
24 | |||
25 | uint16_t first_secs; | ||
26 | uint16_t last_secs; | ||
24 | } FIX_ALIASING; | 27 | } FIX_ALIASING; |
25 | 28 | ||
26 | /* server_config sits in 1st half of bb_common_bufsiz1 */ | 29 | /* server_config sits in 1st half of bb_common_bufsiz1 */ |
diff --git a/networking/wget.c b/networking/wget.c index bbc161be8..41ec7f6dc 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -8,6 +8,32 @@ | |||
8 | * Copyright (C) 2010 Bradley M. Kuhn <bkuhn@ebb.org> | 8 | * Copyright (C) 2010 Bradley M. Kuhn <bkuhn@ebb.org> |
9 | * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2. | 9 | * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2. |
10 | */ | 10 | */ |
11 | |||
12 | //usage:#define wget_trivial_usage | ||
13 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( | ||
14 | //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" | ||
15 | //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" | ||
16 | //usage: " [--no-check-certificate] [-U|--user-agent AGENT]" | ||
17 | //usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." | ||
18 | //usage: ) | ||
19 | //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( | ||
20 | //usage: "[-csq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]" | ||
21 | //usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." | ||
22 | //usage: ) | ||
23 | //usage:#define wget_full_usage "\n\n" | ||
24 | //usage: "Retrieve files via HTTP or FTP\n" | ||
25 | //usage: "\nOptions:" | ||
26 | //usage: "\n -s Spider mode - only check file existence" | ||
27 | //usage: "\n -c Continue retrieval of aborted transfer" | ||
28 | //usage: "\n -q Quiet" | ||
29 | //usage: "\n -P DIR Save to DIR (default .)" | ||
30 | //usage: IF_FEATURE_WGET_TIMEOUT( | ||
31 | //usage: "\n -T SEC Network read timeout is SEC seconds" | ||
32 | //usage: ) | ||
33 | //usage: "\n -O FILE Save to FILE ('-' for stdout)" | ||
34 | //usage: "\n -U STR Use STR for User-Agent header" | ||
35 | //usage: "\n -Y Use proxy ('on' or 'off')" | ||
36 | |||
11 | #include "libbb.h" | 37 | #include "libbb.h" |
12 | 38 | ||
13 | //#define log_io(...) bb_error_msg(__VA_ARGS__) | 39 | //#define log_io(...) bb_error_msg(__VA_ARGS__) |
@@ -604,8 +630,14 @@ static void download_one_url(const char *url) | |||
604 | if (G.fname_out[0] == '/' || !G.fname_out[0]) | 630 | if (G.fname_out[0] == '/' || !G.fname_out[0]) |
605 | G.fname_out = (char*)"index.html"; | 631 | G.fname_out = (char*)"index.html"; |
606 | /* -P DIR is considered only if there was no -O FILE */ | 632 | /* -P DIR is considered only if there was no -O FILE */ |
607 | if (G.dir_prefix) | 633 | else { |
608 | G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out); | 634 | if (G.dir_prefix) |
635 | G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out); | ||
636 | else { | ||
637 | /* redirects may free target.path later, need to make a copy */ | ||
638 | G.fname_out = fname_out_alloc = xstrdup(G.fname_out); | ||
639 | } | ||
640 | } | ||
609 | } | 641 | } |
610 | #if ENABLE_FEATURE_WGET_STATUSBAR | 642 | #if ENABLE_FEATURE_WGET_STATUSBAR |
611 | G.curfile = bb_get_last_path_component_nostrip(G.fname_out); | 643 | G.curfile = bb_get_last_path_component_nostrip(G.fname_out); |
diff --git a/networking/whois.c b/networking/whois.c new file mode 100644 index 000000000..4eab9e5fe --- /dev/null +++ b/networking/whois.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * whois - tiny client for the whois directory service | ||
4 | * | ||
5 | * Copyright (c) 2011 Pere Orga <gotrunks@gmail.com> | ||
6 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
7 | */ | ||
8 | /* TODO | ||
9 | * Add ipv6 support | ||
10 | * Add proxy support | ||
11 | */ | ||
12 | |||
13 | //config:config WHOIS | ||
14 | //config: bool "whois" | ||
15 | //config: default y | ||
16 | //config: help | ||
17 | //config: whois is a client for the whois directory service | ||
18 | |||
19 | //applet:IF_WHOIS(APPLET(whois, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
20 | |||
21 | //kbuild:lib-$(CONFIG_WHOIS) += whois.o | ||
22 | |||
23 | //usage:#define whois_trivial_usage | ||
24 | //usage: "[-h SERVER] [-p PORT] NAME..." | ||
25 | //usage:#define whois_full_usage "\n\n" | ||
26 | //usage: "Query WHOIS info about NAME\n" | ||
27 | //usage: "\nOptions:" | ||
28 | //usage: "\n -h,-p Server to query" | ||
29 | |||
30 | #include "libbb.h" | ||
31 | |||
32 | static void pipe_out(int fd) | ||
33 | { | ||
34 | FILE *fp; | ||
35 | char buf[1024]; | ||
36 | |||
37 | fp = xfdopen_for_read(fd); | ||
38 | while (fgets(buf, sizeof(buf), fp)) { | ||
39 | char *p = strpbrk(buf, "\r\n"); | ||
40 | if (p) | ||
41 | *p = '\0'; | ||
42 | puts(buf); | ||
43 | } | ||
44 | |||
45 | fclose(fp); /* closes fd too */ | ||
46 | } | ||
47 | |||
48 | int whois_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
49 | int whois_main(int argc UNUSED_PARAM, char **argv) | ||
50 | { | ||
51 | int port = 43; | ||
52 | const char *host = "whois-servers.net"; | ||
53 | |||
54 | opt_complementary = "-1:p+"; | ||
55 | getopt32(argv, "h:p:", &host, &port); | ||
56 | |||
57 | argv += optind; | ||
58 | do { | ||
59 | int fd = create_and_connect_stream_or_die(host, port); | ||
60 | fdprintf(fd, "%s\r\n", *argv); | ||
61 | pipe_out(fd); | ||
62 | } | ||
63 | while (*++argv); | ||
64 | |||
65 | return EXIT_SUCCESS; | ||
66 | } | ||
diff --git a/procps/Config.src b/procps/Config.src index cf664eeb2..3e7df0b81 100644 --- a/procps/Config.src +++ b/procps/Config.src | |||
@@ -10,7 +10,7 @@ INSERT | |||
10 | config FREE | 10 | config FREE |
11 | bool "free" | 11 | bool "free" |
12 | default y | 12 | default y |
13 | depends on PLATFORM_LINUX #sysinfo() | 13 | select PLATFORM_LINUX #sysinfo() |
14 | help | 14 | help |
15 | free displays the total amount of free and used physical and swap | 15 | free displays the total amount of free and used physical and swap |
16 | memory in the system, as well as the buffers used by the kernel. | 16 | memory in the system, as well as the buffers used by the kernel. |
@@ -99,7 +99,8 @@ config FEATURE_PS_WIDE | |||
99 | config FEATURE_PS_TIME | 99 | config FEATURE_PS_TIME |
100 | bool "Enable time and elapsed time output" | 100 | bool "Enable time and elapsed time output" |
101 | default y | 101 | default y |
102 | depends on PS && DESKTOP && PLATFORM_LINUX #sysinfo() | 102 | depends on PS && DESKTOP |
103 | select PLATFORM_LINUX | ||
103 | help | 104 | help |
104 | Support -o time and -o etime output specifiers. | 105 | Support -o time and -o etime output specifiers. |
105 | 106 | ||
@@ -196,7 +197,7 @@ config FEATURE_SHOW_THREADS | |||
196 | config UPTIME | 197 | config UPTIME |
197 | bool "uptime" | 198 | bool "uptime" |
198 | default y | 199 | default y |
199 | depends on PLATFORM_LINUX #sysinfo() | 200 | select PLATFORM_LINUX #sysinfo() |
200 | help | 201 | help |
201 | uptime gives a one line display of the current time, how long | 202 | uptime gives a one line display of the current time, how long |
202 | the system has been running, how many users are currently logged | 203 | the system has been running, how many users are currently logged |
diff --git a/procps/kill.c b/procps/kill.c index e6f27af50..599152250 100644 --- a/procps/kill.c +++ b/procps/kill.c | |||
@@ -221,6 +221,7 @@ int kill_main(int argc, char **argv) | |||
221 | pid = bb_strtoi(arg, &end, 10); | 221 | pid = bb_strtoi(arg, &end, 10); |
222 | if (errno && (errno != EINVAL || *end != ' ')) { | 222 | if (errno && (errno != EINVAL || *end != ' ')) { |
223 | bb_error_msg("invalid number '%s'", arg); | 223 | bb_error_msg("invalid number '%s'", arg); |
224 | *end = '\0'; | ||
224 | errors++; | 225 | errors++; |
225 | } else if (kill(pid, signo) != 0) { | 226 | } else if (kill(pid, signo) != 0) { |
226 | bb_perror_msg("can't kill pid %d", (int)pid); | 227 | bb_perror_msg("can't kill pid %d", (int)pid); |
diff --git a/procps/pwdx.c b/procps/pwdx.c new file mode 100644 index 000000000..781810488 --- /dev/null +++ b/procps/pwdx.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * pwdx implementation for busybox | ||
4 | * | ||
5 | * Copyright (c) 2004 Nicholas Miell | ||
6 | * ported from procps by Pere Orga <gotrunks@gmail.com> 2011 | ||
7 | * | ||
8 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
9 | */ | ||
10 | |||
11 | //config:config PWDX | ||
12 | //config: bool "pwdx" | ||
13 | //config: default y | ||
14 | //config: help | ||
15 | //config: Report current working directory of a process | ||
16 | |||
17 | //applet:IF_PWDX(APPLET(pwdx, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
18 | |||
19 | //kbuild:lib-$(CONFIG_PWDX) += pwdx.o | ||
20 | |||
21 | //usage:#define pwdx_trivial_usage | ||
22 | //usage: "PID..." | ||
23 | //usage:#define pwdx_full_usage "\n\n" | ||
24 | //usage: "Show current directory for PIDs\n" | ||
25 | |||
26 | #include "libbb.h" | ||
27 | |||
28 | int pwdx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
29 | int pwdx_main(int argc UNUSED_PARAM, char **argv) | ||
30 | { | ||
31 | opt_complementary = "-1"; | ||
32 | getopt32(argv, ""); | ||
33 | argv += optind; | ||
34 | |||
35 | do { | ||
36 | char buf[sizeof("/proc/%u/cwd") + sizeof(int)*3]; | ||
37 | unsigned pid; | ||
38 | char *s; | ||
39 | char *arg = *argv; | ||
40 | |||
41 | // Allowed on the command line: | ||
42 | // /proc/NUM | ||
43 | // NUM | ||
44 | if (strncmp(arg, "/proc/", 6) == 0) | ||
45 | arg += 6; | ||
46 | |||
47 | pid = bb_strtou(arg, NULL, 10); | ||
48 | if (errno) | ||
49 | bb_error_msg_and_die("invalid process id: '%s'", arg); | ||
50 | |||
51 | sprintf(buf, "/proc/%u/cwd", pid); | ||
52 | |||
53 | s = xmalloc_readlink(buf); | ||
54 | // "pwdx /proc/1" says "/proc/1: DIR", not "1: DIR" | ||
55 | printf("%s: %s\n", *argv, s ? s : strerror(errno == ENOENT ? ESRCH : errno)); | ||
56 | free(s); | ||
57 | } while (*++argv); | ||
58 | |||
59 | return EXIT_SUCCESS; | ||
60 | } | ||
diff --git a/runit/svlogd.c b/runit/svlogd.c index cfa20a773..b0ba21bb6 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c | |||
@@ -187,6 +187,7 @@ struct globals { | |||
187 | unsigned nearest_rotate; | 187 | unsigned nearest_rotate; |
188 | 188 | ||
189 | void* (*memRchr)(const void *, int, size_t); | 189 | void* (*memRchr)(const void *, int, size_t); |
190 | char *shell; | ||
190 | 191 | ||
191 | smallint exitasap; | 192 | smallint exitasap; |
192 | smallint rotateasap; | 193 | smallint rotateasap; |
@@ -382,6 +383,9 @@ static void processorstart(struct logdir *ld) | |||
382 | /* vfork'ed child trashes this byte, save... */ | 383 | /* vfork'ed child trashes this byte, save... */ |
383 | sv_ch = ld->fnsave[26]; | 384 | sv_ch = ld->fnsave[26]; |
384 | 385 | ||
386 | if (!G.shell) | ||
387 | G.shell = xstrdup(get_shell_name()); | ||
388 | |||
385 | while ((pid = vfork()) == -1) | 389 | while ((pid = vfork()) == -1) |
386 | pause2cannot("vfork for processor", ld->name); | 390 | pause2cannot("vfork for processor", ld->name); |
387 | if (!pid) { | 391 | if (!pid) { |
@@ -416,8 +420,7 @@ static void processorstart(struct logdir *ld) | |||
416 | fd = xopen("newstate", O_WRONLY|O_NDELAY|O_TRUNC|O_CREAT); | 420 | fd = xopen("newstate", O_WRONLY|O_NDELAY|O_TRUNC|O_CREAT); |
417 | xmove_fd(fd, 5); | 421 | xmove_fd(fd, 5); |
418 | 422 | ||
419 | // getenv("SHELL")? | 423 | execl(G.shell, G.shell, "-c", ld->processor, (char*) NULL); |
420 | execl(DEFAULT_SHELL, DEFAULT_SHELL_SHORT_NAME, "-c", ld->processor, (char*) NULL); | ||
421 | bb_perror_msg_and_die(FATAL"can't %s processor %s", "run", ld->name); | 424 | bb_perror_msg_and_die(FATAL"can't %s processor %s", "run", ld->name); |
422 | } | 425 | } |
423 | ld->fnsave[26] = sv_ch; /* ...restore */ | 426 | ld->fnsave[26] = sv_ch; /* ...restore */ |
diff --git a/scripts/Makefile.IMA b/scripts/Makefile.IMA index a62618ae0..0eced2982 100644 --- a/scripts/Makefile.IMA +++ b/scripts/Makefile.IMA | |||
@@ -9,7 +9,10 @@ objtree := $(CURDIR) | |||
9 | src := $(srctree) | 9 | src := $(srctree) |
10 | obj := $(objtree) | 10 | obj := $(objtree) |
11 | 11 | ||
12 | # Look for make include files relative to root of kernel src | 12 | # Make generated files |
13 | DUMMY := $(shell $(Q)$(srctree)/scripts/gen_build_files.sh $(srctree) $(objtree) >&2) | ||
14 | |||
15 | # Look for make include files relative to root of src | ||
13 | MAKEFLAGS += --include-dir=$(srctree) | 16 | MAKEFLAGS += --include-dir=$(srctree) |
14 | 17 | ||
15 | default: busybox | 18 | default: busybox |
@@ -121,6 +124,9 @@ lib-y:= | |||
121 | include miscutils/Kbuild | 124 | include miscutils/Kbuild |
122 | lib-all-y += $(patsubst %,miscutils/%,$(sort $(lib-y))) | 125 | lib-all-y += $(patsubst %,miscutils/%,$(sort $(lib-y))) |
123 | lib-y:= | 126 | lib-y:= |
127 | include mailutils/Kbuild | ||
128 | lib-all-y += $(patsubst %,mailutils/%,$(sort $(lib-y))) | ||
129 | lib-y:= | ||
124 | include coreutils/libcoreutils/Kbuild | 130 | include coreutils/libcoreutils/Kbuild |
125 | lib-all-y += $(patsubst %,coreutils/libcoreutils/%,$(sort $(lib-y))) | 131 | lib-all-y += $(patsubst %,coreutils/libcoreutils/%,$(sort $(lib-y))) |
126 | lib-y:= | 132 | lib-y:= |
@@ -168,7 +174,7 @@ lib-all-y += $(patsubst %,libbb/%,$(sort $(lib-y))) | |||
168 | lib-y:= | 174 | lib-y:= |
169 | 175 | ||
170 | comma:=, | 176 | comma:=, |
171 | busybox_unstripped.o: $(usage_stuff) include/applet_tables.h include/autoconf.h | 177 | busybox_unstripped.o: $(usage_stuff) include/applet_tables.h include/NUM_APPLETS.h include/autoconf.h |
172 | $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) \ | 178 | $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) \ |
173 | $(patsubst %,-Wl$(comma)%,$(LDFLAGS) $(EXTRA_LDFLAGS)) \ | 179 | $(patsubst %,-Wl$(comma)%,$(LDFLAGS) $(EXTRA_LDFLAGS)) \ |
174 | -DGCC_COMBINE=1 \ | 180 | -DGCC_COMBINE=1 \ |
@@ -194,14 +200,9 @@ busybox: busybox_unstripped.o | |||
194 | include/autoconf.h: .config | 200 | include/autoconf.h: .config |
195 | $(MAKE) -f $(srctree)/Makefile silentoldconfig | 201 | $(MAKE) -f $(srctree)/Makefile silentoldconfig |
196 | 202 | ||
203 | # Override rules for host compile | ||
197 | applets/usage: include/autoconf.h | 204 | applets/usage: include/autoconf.h |
198 | $(HOSTCC) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -I$(srctree)/include -o applets/usage applets/usage.c | 205 | $(HOSTCC) -Wall -O2 -I$(srctree)/include -o applets/usage applets/usage.c |
199 | 206 | ||
200 | applets/applet_tables: include/autoconf.h | 207 | applets/applet_tables: include/autoconf.h |
201 | $(HOSTCC) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -I$(srctree)/include -o applets/applet_tables applets/applet_tables.c | 208 | $(HOSTCC) -Wall -O2 -I$(srctree)/include -o applets/applet_tables applets/applet_tables.c |
202 | |||
203 | include/usage_compressed.h: include/usage.h applets/usage | ||
204 | $(srctree)/applets/usage_compressed include/usage_compressed.h applets | ||
205 | |||
206 | include/applet_tables.h: include/applets.h | ||
207 | applets/applet_tables include/applet_tables.h | ||
diff --git a/scripts/defconfig.tig b/scripts/defconfig.tig index 52fddfbf6..3dd02983f 100644 --- a/scripts/defconfig.tig +++ b/scripts/defconfig.tig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.19.0.git | 3 | # Busybox version: 1.19.0.git |
4 | # Thu Mar 22 12:00:44 2012 | 4 | # Thu Mar 22 13:52:53 2012 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -431,6 +431,7 @@ CONFIG_FEATURE_KILL_DELAY=0 | |||
431 | # CONFIG_FEATURE_INITRD is not set | 431 | # CONFIG_FEATURE_INITRD is not set |
432 | CONFIG_INIT_TERMINAL_TYPE="" | 432 | CONFIG_INIT_TERMINAL_TYPE="" |
433 | # CONFIG_MESG is not set | 433 | # CONFIG_MESG is not set |
434 | # CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set | ||
434 | 435 | ||
435 | # | 436 | # |
436 | # Login/Password Management Utilities | 437 | # Login/Password Management Utilities |
@@ -476,6 +477,10 @@ CONFIG_LAST_SYSTEM_ID=0 | |||
476 | # CONFIG_FSCK is not set | 477 | # CONFIG_FSCK is not set |
477 | # CONFIG_LSATTR is not set | 478 | # CONFIG_LSATTR is not set |
478 | # CONFIG_TUNE2FS is not set | 479 | # CONFIG_TUNE2FS is not set |
480 | |||
481 | # | ||
482 | # Linux Module Utilities | ||
483 | # | ||
479 | # CONFIG_MODINFO is not set | 484 | # CONFIG_MODINFO is not set |
480 | # CONFIG_MODPROBE_SMALL is not set | 485 | # CONFIG_MODPROBE_SMALL is not set |
481 | # CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set | 486 | # CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set |
@@ -487,6 +492,10 @@ CONFIG_LAST_SYSTEM_ID=0 | |||
487 | # CONFIG_MODPROBE is not set | 492 | # CONFIG_MODPROBE is not set |
488 | # CONFIG_FEATURE_MODPROBE_BLACKLIST is not set | 493 | # CONFIG_FEATURE_MODPROBE_BLACKLIST is not set |
489 | # CONFIG_DEPMOD is not set | 494 | # CONFIG_DEPMOD is not set |
495 | |||
496 | # | ||
497 | # Options common to multiple modutils | ||
498 | # | ||
490 | # CONFIG_FEATURE_2_4_MODULES is not set | 499 | # CONFIG_FEATURE_2_4_MODULES is not set |
491 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set | 500 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set |
492 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set | 501 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set |
@@ -693,6 +702,8 @@ CONFIG_STRINGS=y | |||
693 | # | 702 | # |
694 | # Networking Utilities | 703 | # Networking Utilities |
695 | # | 704 | # |
705 | # CONFIG_NAMEIF is not set | ||
706 | # CONFIG_FEATURE_NAMEIF_EXTENDED is not set | ||
696 | # CONFIG_NBDCLIENT is not set | 707 | # CONFIG_NBDCLIENT is not set |
697 | # CONFIG_NC is not set | 708 | # CONFIG_NC is not set |
698 | # CONFIG_NC_SERVER is not set | 709 | # CONFIG_NC_SERVER is not set |
@@ -701,6 +712,7 @@ CONFIG_STRINGS=y | |||
701 | # CONFIG_PING is not set | 712 | # CONFIG_PING is not set |
702 | # CONFIG_PING6 is not set | 713 | # CONFIG_PING6 is not set |
703 | # CONFIG_FEATURE_FANCY_PING is not set | 714 | # CONFIG_FEATURE_FANCY_PING is not set |
715 | # CONFIG_WHOIS is not set | ||
704 | # CONFIG_FEATURE_IPV6 is not set | 716 | # CONFIG_FEATURE_IPV6 is not set |
705 | # CONFIG_FEATURE_UNIX_LOCAL is not set | 717 | # CONFIG_FEATURE_UNIX_LOCAL is not set |
706 | # CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set | 718 | # CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set |
@@ -773,8 +785,6 @@ CONFIG_IFUPDOWN_IFSTATE_PATH="" | |||
773 | # CONFIG_IPCALC is not set | 785 | # CONFIG_IPCALC is not set |
774 | # CONFIG_FEATURE_IPCALC_FANCY is not set | 786 | # CONFIG_FEATURE_IPCALC_FANCY is not set |
775 | # CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set | 787 | # CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set |
776 | # CONFIG_NAMEIF is not set | ||
777 | # CONFIG_FEATURE_NAMEIF_EXTENDED is not set | ||
778 | # CONFIG_NETSTAT is not set | 788 | # CONFIG_NETSTAT is not set |
779 | # CONFIG_FEATURE_NETSTAT_WIDE is not set | 789 | # CONFIG_FEATURE_NETSTAT_WIDE is not set |
780 | # CONFIG_FEATURE_NETSTAT_PRG is not set | 790 | # CONFIG_FEATURE_NETSTAT_PRG is not set |
@@ -855,6 +865,7 @@ CONFIG_FEATURE_MIME_CHARSET="" | |||
855 | # CONFIG_PMAP is not set | 865 | # CONFIG_PMAP is not set |
856 | # CONFIG_POWERTOP is not set | 866 | # CONFIG_POWERTOP is not set |
857 | # CONFIG_PSTREE is not set | 867 | # CONFIG_PSTREE is not set |
868 | # CONFIG_PWDX is not set | ||
858 | # CONFIG_SMEMCAP is not set | 869 | # CONFIG_SMEMCAP is not set |
859 | # CONFIG_FREE is not set | 870 | # CONFIG_FREE is not set |
860 | # CONFIG_FUSER is not set | 871 | # CONFIG_FUSER is not set |
diff --git a/shell/ash.c b/shell/ash.c index fd9141661..d12a483a3 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -56,6 +56,9 @@ | |||
56 | #include <fnmatch.h> | 56 | #include <fnmatch.h> |
57 | #include <sys/times.h> | 57 | #include <sys/times.h> |
58 | 58 | ||
59 | #include "busybox.h" /* for applet_names */ | ||
60 | #include "unicode.h" | ||
61 | |||
59 | #include "shell_common.h" | 62 | #include "shell_common.h" |
60 | #if ENABLE_SH_MATH_SUPPORT | 63 | #if ENABLE_SH_MATH_SUPPORT |
61 | # include "math.h" | 64 | # include "math.h" |
@@ -86,13 +89,6 @@ | |||
86 | # error "Do not even bother, ash will not run on NOMMU machine" | 89 | # error "Do not even bother, ash will not run on NOMMU machine" |
87 | #endif | 90 | #endif |
88 | 91 | ||
89 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) | ||
90 | //applet:IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, sh)) | ||
91 | //applet:IF_FEATURE_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, bash)) | ||
92 | |||
93 | //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o | ||
94 | //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o | ||
95 | |||
96 | //config:config ASH | 92 | //config:config ASH |
97 | //config: bool "ash" | 93 | //config: bool "ash" |
98 | //config: default y | 94 | //config: default y |
@@ -204,12 +200,12 @@ | |||
204 | //config: variable each time it is displayed. | 200 | //config: variable each time it is displayed. |
205 | //config: | 201 | //config: |
206 | 202 | ||
207 | //usage:#define ash_trivial_usage NOUSAGE_STR | 203 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) |
208 | //usage:#define ash_full_usage "" | 204 | //applet:IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, sh)) |
209 | //usage:#define sh_trivial_usage NOUSAGE_STR | 205 | //applet:IF_FEATURE_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, bash)) |
210 | //usage:#define sh_full_usage "" | 206 | |
211 | //usage:#define bash_trivial_usage NOUSAGE_STR | 207 | //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o |
212 | //usage:#define bash_full_usage "" | 208 | //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o |
213 | 209 | ||
214 | #if ENABLE_PLATFORM_MINGW32 | 210 | #if ENABLE_PLATFORM_MINGW32 |
215 | struct forkshell; | 211 | struct forkshell; |
@@ -3705,12 +3701,12 @@ set_curjob(struct job *jp, unsigned mode) | |||
3705 | 3701 | ||
3706 | /* first remove from list */ | 3702 | /* first remove from list */ |
3707 | jpp = curp = &curjob; | 3703 | jpp = curp = &curjob; |
3708 | do { | 3704 | while (1) { |
3709 | jp1 = *jpp; | 3705 | jp1 = *jpp; |
3710 | if (jp1 == jp) | 3706 | if (jp1 == jp) |
3711 | break; | 3707 | break; |
3712 | jpp = &jp1->prev_job; | 3708 | jpp = &jp1->prev_job; |
3713 | } while (1); | 3709 | } |
3714 | *jpp = jp1->prev_job; | 3710 | *jpp = jp1->prev_job; |
3715 | 3711 | ||
3716 | /* Then re-insert in correct position */ | 3712 | /* Then re-insert in correct position */ |
@@ -3726,14 +3722,14 @@ set_curjob(struct job *jp, unsigned mode) | |||
3726 | case CUR_RUNNING: | 3722 | case CUR_RUNNING: |
3727 | /* newly created job or backgrounded job, | 3723 | /* newly created job or backgrounded job, |
3728 | put after all stopped jobs. */ | 3724 | put after all stopped jobs. */ |
3729 | do { | 3725 | while (1) { |
3730 | jp1 = *jpp; | 3726 | jp1 = *jpp; |
3731 | #if JOBS | 3727 | #if JOBS |
3732 | if (!jp1 || jp1->state != JOBSTOPPED) | 3728 | if (!jp1 || jp1->state != JOBSTOPPED) |
3733 | #endif | 3729 | #endif |
3734 | break; | 3730 | break; |
3735 | jpp = &jp1->prev_job; | 3731 | jpp = &jp1->prev_job; |
3736 | } while (1); | 3732 | } |
3737 | /* FALLTHROUGH */ | 3733 | /* FALLTHROUGH */ |
3738 | #if JOBS | 3734 | #if JOBS |
3739 | case CUR_STOPPED: | 3735 | case CUR_STOPPED: |
@@ -3906,7 +3902,7 @@ setjobctl(int on) | |||
3906 | goto out; | 3902 | goto out; |
3907 | /* fd is a tty at this point */ | 3903 | /* fd is a tty at this point */ |
3908 | close_on_exec_on(fd); | 3904 | close_on_exec_on(fd); |
3909 | do { /* while we are in the background */ | 3905 | while (1) { /* while we are in the background */ |
3910 | pgrp = tcgetpgrp(fd); | 3906 | pgrp = tcgetpgrp(fd); |
3911 | if (pgrp < 0) { | 3907 | if (pgrp < 0) { |
3912 | out: | 3908 | out: |
@@ -3917,7 +3913,7 @@ setjobctl(int on) | |||
3917 | if (pgrp == getpgrp()) | 3913 | if (pgrp == getpgrp()) |
3918 | break; | 3914 | break; |
3919 | killpg(0, SIGTTIN); | 3915 | killpg(0, SIGTTIN); |
3920 | } while (1); | 3916 | } |
3921 | initialpgrp = pgrp; | 3917 | initialpgrp = pgrp; |
3922 | 3918 | ||
3923 | setsignal(SIGTSTP); | 3919 | setsignal(SIGTSTP); |
@@ -6328,7 +6324,7 @@ expari(int quotes) | |||
6328 | p = expdest - 1; | 6324 | p = expdest - 1; |
6329 | *p = '\0'; | 6325 | *p = '\0'; |
6330 | p--; | 6326 | p--; |
6331 | do { | 6327 | while (1) { |
6332 | int esc; | 6328 | int esc; |
6333 | 6329 | ||
6334 | while ((unsigned char)*p != CTLARI) { | 6330 | while ((unsigned char)*p != CTLARI) { |
@@ -6346,7 +6342,7 @@ expari(int quotes) | |||
6346 | } | 6342 | } |
6347 | 6343 | ||
6348 | p -= esc + 1; | 6344 | p -= esc + 1; |
6349 | } while (1); | 6345 | } |
6350 | 6346 | ||
6351 | begoff = p - start; | 6347 | begoff = p - start; |
6352 | 6348 | ||
@@ -7754,8 +7750,6 @@ static int builtinloc = -1; /* index in path of %builtin, or -1 */ | |||
7754 | static void | 7750 | static void |
7755 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp) | 7751 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp) |
7756 | { | 7752 | { |
7757 | int repeated = 0; | ||
7758 | |||
7759 | #if ENABLE_FEATURE_SH_STANDALONE | 7753 | #if ENABLE_FEATURE_SH_STANDALONE |
7760 | if (applet_no >= 0) { | 7754 | if (applet_no >= 0) { |
7761 | if (APPLET_IS_NOEXEC(applet_no)) { | 7755 | if (APPLET_IS_NOEXEC(applet_no)) { |
@@ -7779,25 +7773,36 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char ** | |||
7779 | #else | 7773 | #else |
7780 | execve(cmd, argv, envp); | 7774 | execve(cmd, argv, envp); |
7781 | #endif | 7775 | #endif |
7782 | if (repeated) { | 7776 | if (cmd == (char*) bb_busybox_exec_path) { |
7777 | /* We already visited ENOEXEC branch below, don't do it again */ | ||
7778 | //TODO: try execve(initial_argv0_of_shell, argv, envp) before giving up? | ||
7783 | free(argv); | 7779 | free(argv); |
7784 | return; | 7780 | return; |
7785 | } | 7781 | } |
7786 | if (errno == ENOEXEC) { | 7782 | if (errno == ENOEXEC) { |
7783 | /* Run "cmd" as a shell script: | ||
7784 | * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html | ||
7785 | * "If the execve() function fails with ENOEXEC, the shell | ||
7786 | * shall execute a command equivalent to having a shell invoked | ||
7787 | * with the command name as its first operand, | ||
7788 | * with any remaining arguments passed to the new shell" | ||
7789 | * | ||
7790 | * That is, do not use $SHELL, user's shell, or /bin/sh; | ||
7791 | * just call ourselves. | ||
7792 | */ | ||
7787 | char **ap; | 7793 | char **ap; |
7788 | char **new; | 7794 | char **new; |
7789 | 7795 | ||
7790 | for (ap = argv; *ap; ap++) | 7796 | for (ap = argv; *ap; ap++) |
7791 | continue; | 7797 | continue; |
7792 | ap = new = ckmalloc((ap - argv + 2) * sizeof(ap[0])); | 7798 | new = ckmalloc((ap - argv + 2) * sizeof(new[0])); |
7793 | ap[1] = cmd; | 7799 | new[0] = (char*) "ash"; |
7794 | ap[0] = cmd = (char *)DEFAULT_SHELL; | 7800 | new[1] = cmd; |
7795 | ap += 2; | 7801 | ap = new + 2; |
7796 | argv++; | 7802 | while ((*ap++ = *++argv) != NULL) |
7797 | while ((*ap++ = *argv++) != NULL) | ||
7798 | continue; | 7803 | continue; |
7804 | cmd = (char*) bb_busybox_exec_path; | ||
7799 | argv = new; | 7805 | argv = new; |
7800 | repeated++; | ||
7801 | goto repeat; | 7806 | goto repeat; |
7802 | } | 7807 | } |
7803 | } | 7808 | } |
@@ -10126,6 +10131,11 @@ preadfd(void) | |||
10126 | # if ENABLE_FEATURE_TAB_COMPLETION | 10131 | # if ENABLE_FEATURE_TAB_COMPLETION |
10127 | line_input_state->path_lookup = pathval(); | 10132 | line_input_state->path_lookup = pathval(); |
10128 | # endif | 10133 | # endif |
10134 | /* Unicode support should be activated even if LANG is set | ||
10135 | * _during_ shell execution, not only if it was set when | ||
10136 | * shell was started. Therefore, re-check LANG every time: | ||
10137 | */ | ||
10138 | reinit_unicode(lookupvar("LANG")); | ||
10129 | nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); | 10139 | nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); |
10130 | if (nr == 0) { | 10140 | if (nr == 0) { |
10131 | /* Ctrl+C pressed */ | 10141 | /* Ctrl+C pressed */ |
@@ -10673,7 +10683,7 @@ options(int cmdline) | |||
10673 | else if (*argptr == NULL) | 10683 | else if (*argptr == NULL) |
10674 | setparam(argptr); | 10684 | setparam(argptr); |
10675 | } | 10685 | } |
10676 | break; /* "-" or "--" terminates options */ | 10686 | break; /* "-" or "--" terminates options */ |
10677 | } | 10687 | } |
10678 | } | 10688 | } |
10679 | /* first char was + or - */ | 10689 | /* first char was + or - */ |
@@ -10775,10 +10785,10 @@ setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
10775 | 10785 | ||
10776 | if (!argv[1]) | 10786 | if (!argv[1]) |
10777 | return showvars(nullstr, 0, VUNSET); | 10787 | return showvars(nullstr, 0, VUNSET); |
10788 | |||
10778 | INT_OFF; | 10789 | INT_OFF; |
10779 | retval = 1; | 10790 | retval = options(/*cmdline:*/ 0); |
10780 | if (!options(0)) { /* if no parse error... */ | 10791 | if (retval == 0) { /* if no parse error... */ |
10781 | retval = 0; | ||
10782 | optschanged(); | 10792 | optschanged(); |
10783 | if (*argptr != NULL) { | 10793 | if (*argptr != NULL) { |
10784 | setparam(argptr); | 10794 | setparam(argptr); |
@@ -13525,14 +13535,32 @@ init(void) | |||
13525 | setvar("PPID", utoa(getppid()), 0); | 13535 | setvar("PPID", utoa(getppid()), 0); |
13526 | 13536 | ||
13527 | p = lookupvar("PWD"); | 13537 | p = lookupvar("PWD"); |
13528 | if (p) | 13538 | if (p) { |
13529 | if (*p != '/' || stat(p, &st1) || stat(".", &st2) | 13539 | if (*p != '/' || stat(p, &st1) || stat(".", &st2) |
13530 | || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) | 13540 | || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino |
13541 | ) { | ||
13531 | p = '\0'; | 13542 | p = '\0'; |
13543 | } | ||
13544 | } | ||
13532 | setpwd(p, 0); | 13545 | setpwd(p, 0); |
13533 | } | 13546 | } |
13534 | } | 13547 | } |
13535 | 13548 | ||
13549 | |||
13550 | //usage:#define ash_trivial_usage | ||
13551 | //usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS]]" | ||
13552 | //usage:#define ash_full_usage "\n\n" | ||
13553 | //usage: "Unix shell interpreter" | ||
13554 | |||
13555 | //usage:#if ENABLE_FEATURE_SH_IS_ASH | ||
13556 | //usage:# define sh_trivial_usage ash_trivial_usage | ||
13557 | //usage:# define sh_full_usage ash_full_usage | ||
13558 | //usage:#endif | ||
13559 | //usage:#if ENABLE_FEATURE_BASH_IS_ASH | ||
13560 | //usage:# define bash_trivial_usage ash_trivial_usage | ||
13561 | //usage:# define bash_full_usage ash_full_usage | ||
13562 | //usage:#endif | ||
13563 | |||
13536 | /* | 13564 | /* |
13537 | * Process the shell command line arguments. | 13565 | * Process the shell command line arguments. |
13538 | */ | 13566 | */ |
@@ -13550,7 +13578,7 @@ procargs(char **argv) | |||
13550 | for (i = 0; i < NOPTS; i++) | 13578 | for (i = 0; i < NOPTS; i++) |
13551 | optlist[i] = 2; | 13579 | optlist[i] = 2; |
13552 | argptr = xargv; | 13580 | argptr = xargv; |
13553 | if (options(1)) { | 13581 | if (options(/*cmdline:*/ 1)) { |
13554 | /* it already printed err message */ | 13582 | /* it already printed err message */ |
13555 | raise_exception(EXERROR); | 13583 | raise_exception(EXERROR); |
13556 | } | 13584 | } |
diff --git a/shell/hush.c b/shell/hush.c index 4d9e5f8c7..e4c3a7d77 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -81,7 +81,6 @@ | |||
81 | * $ "export" i=`echo 'aaa bbb'`; echo "$i" | 81 | * $ "export" i=`echo 'aaa bbb'`; echo "$i" |
82 | * aaa | 82 | * aaa |
83 | */ | 83 | */ |
84 | #include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */ | ||
85 | #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ | 84 | #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ |
86 | || defined(__APPLE__) \ | 85 | || defined(__APPLE__) \ |
87 | ) | 86 | ) |
@@ -93,6 +92,8 @@ | |||
93 | # include <fnmatch.h> | 92 | # include <fnmatch.h> |
94 | #endif | 93 | #endif |
95 | 94 | ||
95 | #include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */ | ||
96 | #include "unicode.h" | ||
96 | #include "shell_common.h" | 97 | #include "shell_common.h" |
97 | #include "math.h" | 98 | #include "math.h" |
98 | #include "match.h" | 99 | #include "match.h" |
@@ -105,14 +106,6 @@ | |||
105 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ | 106 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ |
106 | #endif | 107 | #endif |
107 | 108 | ||
108 | //applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP)) | ||
109 | //applet:IF_MSH(APPLET(msh, BB_DIR_BIN, BB_SUID_DROP)) | ||
110 | //applet:IF_FEATURE_SH_IS_HUSH(APPLET_ODDNAME(sh, hush, BB_DIR_BIN, BB_SUID_DROP, sh)) | ||
111 | //applet:IF_FEATURE_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, bash)) | ||
112 | |||
113 | //kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o | ||
114 | //kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o | ||
115 | |||
116 | //config:config HUSH | 109 | //config:config HUSH |
117 | //config: bool "hush" | 110 | //config: bool "hush" |
118 | //config: default y | 111 | //config: default y |
@@ -249,20 +242,35 @@ | |||
249 | //config: msh is deprecated and will be removed, please migrate to hush. | 242 | //config: msh is deprecated and will be removed, please migrate to hush. |
250 | //config: | 243 | //config: |
251 | 244 | ||
245 | //applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP)) | ||
246 | //applet:IF_MSH(APPLET(msh, BB_DIR_BIN, BB_SUID_DROP)) | ||
247 | //applet:IF_FEATURE_SH_IS_HUSH(APPLET_ODDNAME(sh, hush, BB_DIR_BIN, BB_SUID_DROP, sh)) | ||
248 | //applet:IF_FEATURE_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, bash)) | ||
249 | |||
250 | //kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o | ||
251 | //kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o | ||
252 | |||
252 | /* -i (interactive) and -s (read stdin) are also accepted, | 253 | /* -i (interactive) and -s (read stdin) are also accepted, |
253 | * but currently do nothing, therefore aren't shown in help. | 254 | * but currently do nothing, therefore aren't shown in help. |
254 | * NOMMU-specific options are not meant to be used by users, | 255 | * NOMMU-specific options are not meant to be used by users, |
255 | * therefore we don't show them either. | 256 | * therefore we don't show them either. |
256 | */ | 257 | */ |
257 | //usage:#define hush_trivial_usage | 258 | //usage:#define hush_trivial_usage |
258 | //usage: "[-nx] [-c SCRIPT]" | 259 | //usage: "[-nx] [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS]]" |
259 | //usage:#define hush_full_usage "" | 260 | //usage:#define hush_full_usage "\n\n" |
261 | //usage: "Unix shell interpreter" | ||
262 | |||
260 | //usage:#define msh_trivial_usage hush_trivial_usage | 263 | //usage:#define msh_trivial_usage hush_trivial_usage |
261 | //usage:#define msh_full_usage "" | 264 | //usage:#define msh_full_usage hush_full_usage |
262 | //usage:#define sh_trivial_usage NOUSAGE_STR | 265 | |
263 | //usage:#define sh_full_usage "" | 266 | //usage:#if ENABLE_FEATURE_SH_IS_HUSH |
264 | //usage:#define bash_trivial_usage NOUSAGE_STR | 267 | //usage:# define sh_trivial_usage hush_trivial_usage |
265 | //usage:#define bash_full_usage "" | 268 | //usage:# define sh_full_usage hush_full_usage |
269 | //usage:#endif | ||
270 | //usage:#if ENABLE_FEATURE_BASH_IS_HUSH | ||
271 | //usage:# define bash_trivial_usage hush_trivial_usage | ||
272 | //usage:# define bash_full_usage hush_full_usage | ||
273 | //usage:#endif | ||
266 | 274 | ||
267 | 275 | ||
268 | /* Build knobs */ | 276 | /* Build knobs */ |
@@ -1087,17 +1095,10 @@ static void syntax_error_unterm_str(unsigned lineno, const char *s) | |||
1087 | die_if_script(lineno, "syntax error: unterminated %s", s); | 1095 | die_if_script(lineno, "syntax error: unterminated %s", s); |
1088 | } | 1096 | } |
1089 | 1097 | ||
1090 | /* It so happens that all such cases are totally fatal | ||
1091 | * even if shell is interactive: EOF while looking for closing | ||
1092 | * delimiter. There is nowhere to read stuff from after that, | ||
1093 | * it's EOF! The only choice is to terminate. | ||
1094 | */ | ||
1095 | static void syntax_error_unterm_ch(unsigned lineno, char ch) NORETURN; | ||
1096 | static void syntax_error_unterm_ch(unsigned lineno, char ch) | 1098 | static void syntax_error_unterm_ch(unsigned lineno, char ch) |
1097 | { | 1099 | { |
1098 | char msg[2] = { ch, '\0' }; | 1100 | char msg[2] = { ch, '\0' }; |
1099 | syntax_error_unterm_str(lineno, msg); | 1101 | syntax_error_unterm_str(lineno, msg); |
1100 | xfunc_die(); | ||
1101 | } | 1102 | } |
1102 | 1103 | ||
1103 | static void syntax_error_unexpected_ch(unsigned lineno, int ch) | 1104 | static void syntax_error_unexpected_ch(unsigned lineno, int ch) |
@@ -1899,6 +1900,12 @@ static void get_user_input(struct in_str *i) | |||
1899 | /* Enable command line editing only while a command line | 1900 | /* Enable command line editing only while a command line |
1900 | * is actually being read */ | 1901 | * is actually being read */ |
1901 | do { | 1902 | do { |
1903 | /* Unicode support should be activated even if LANG is set | ||
1904 | * _during_ shell execution, not only if it was set when | ||
1905 | * shell was started. Therefore, re-check LANG every time: | ||
1906 | */ | ||
1907 | reinit_unicode(get_local_var_value("LANG")); | ||
1908 | |||
1902 | G.flag_SIGINT = 0; | 1909 | G.flag_SIGINT = 0; |
1903 | /* buglet: SIGINT will not make new prompt to appear _at once_, | 1910 | /* buglet: SIGINT will not make new prompt to appear _at once_, |
1904 | * only after <Enter>. (^C will work) */ | 1911 | * only after <Enter>. (^C will work) */ |
@@ -3525,39 +3532,40 @@ static int parse_group(o_string *dest, struct parse_context *ctx, | |||
3525 | 3532 | ||
3526 | #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS | 3533 | #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS |
3527 | /* Subroutines for copying $(...) and `...` things */ | 3534 | /* Subroutines for copying $(...) and `...` things */ |
3528 | static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquote); | 3535 | static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote); |
3529 | /* '...' */ | 3536 | /* '...' */ |
3530 | static void add_till_single_quote(o_string *dest, struct in_str *input) | 3537 | static int add_till_single_quote(o_string *dest, struct in_str *input) |
3531 | { | 3538 | { |
3532 | while (1) { | 3539 | while (1) { |
3533 | int ch = i_getch(input); | 3540 | int ch = i_getch(input); |
3534 | if (ch == EOF) { | 3541 | if (ch == EOF) { |
3535 | syntax_error_unterm_ch('\''); | 3542 | syntax_error_unterm_ch('\''); |
3536 | /*xfunc_die(); - redundant */ | 3543 | return 0; |
3537 | } | 3544 | } |
3538 | if (ch == '\'') | 3545 | if (ch == '\'') |
3539 | return; | 3546 | return 1; |
3540 | o_addchr(dest, ch); | 3547 | o_addchr(dest, ch); |
3541 | } | 3548 | } |
3542 | } | 3549 | } |
3543 | /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */ | 3550 | /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */ |
3544 | static void add_till_double_quote(o_string *dest, struct in_str *input) | 3551 | static int add_till_double_quote(o_string *dest, struct in_str *input) |
3545 | { | 3552 | { |
3546 | while (1) { | 3553 | while (1) { |
3547 | int ch = i_getch(input); | 3554 | int ch = i_getch(input); |
3548 | if (ch == EOF) { | 3555 | if (ch == EOF) { |
3549 | syntax_error_unterm_ch('"'); | 3556 | syntax_error_unterm_ch('"'); |
3550 | /*xfunc_die(); - redundant */ | 3557 | return 0; |
3551 | } | 3558 | } |
3552 | if (ch == '"') | 3559 | if (ch == '"') |
3553 | return; | 3560 | return 1; |
3554 | if (ch == '\\') { /* \x. Copy both chars. */ | 3561 | if (ch == '\\') { /* \x. Copy both chars. */ |
3555 | o_addchr(dest, ch); | 3562 | o_addchr(dest, ch); |
3556 | ch = i_getch(input); | 3563 | ch = i_getch(input); |
3557 | } | 3564 | } |
3558 | o_addchr(dest, ch); | 3565 | o_addchr(dest, ch); |
3559 | if (ch == '`') { | 3566 | if (ch == '`') { |
3560 | add_till_backquote(dest, input, /*in_dquote:*/ 1); | 3567 | if (!add_till_backquote(dest, input, /*in_dquote:*/ 1)) |
3568 | return 0; | ||
3561 | o_addchr(dest, ch); | 3569 | o_addchr(dest, ch); |
3562 | continue; | 3570 | continue; |
3563 | } | 3571 | } |
@@ -3578,12 +3586,12 @@ static void add_till_double_quote(o_string *dest, struct in_str *input) | |||
3578 | * Example Output | 3586 | * Example Output |
3579 | * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST | 3587 | * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST |
3580 | */ | 3588 | */ |
3581 | static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquote) | 3589 | static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote) |
3582 | { | 3590 | { |
3583 | while (1) { | 3591 | while (1) { |
3584 | int ch = i_getch(input); | 3592 | int ch = i_getch(input); |
3585 | if (ch == '`') | 3593 | if (ch == '`') |
3586 | return; | 3594 | return 1; |
3587 | if (ch == '\\') { | 3595 | if (ch == '\\') { |
3588 | /* \x. Copy both unless it is \`, \$, \\ and maybe \" */ | 3596 | /* \x. Copy both unless it is \`, \$, \\ and maybe \" */ |
3589 | ch = i_getch(input); | 3597 | ch = i_getch(input); |
@@ -3597,7 +3605,7 @@ static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquo | |||
3597 | } | 3605 | } |
3598 | if (ch == EOF) { | 3606 | if (ch == EOF) { |
3599 | syntax_error_unterm_ch('`'); | 3607 | syntax_error_unterm_ch('`'); |
3600 | /*xfunc_die(); - redundant */ | 3608 | return 0; |
3601 | } | 3609 | } |
3602 | o_addchr(dest, ch); | 3610 | o_addchr(dest, ch); |
3603 | } | 3611 | } |
@@ -3633,7 +3641,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
3633 | ch = i_getch(input); | 3641 | ch = i_getch(input); |
3634 | if (ch == EOF) { | 3642 | if (ch == EOF) { |
3635 | syntax_error_unterm_ch(end_ch); | 3643 | syntax_error_unterm_ch(end_ch); |
3636 | /*xfunc_die(); - redundant */ | 3644 | return 0; |
3637 | } | 3645 | } |
3638 | if (ch == end_ch IF_HUSH_BASH_COMPAT( || ch == end_char2)) { | 3646 | if (ch == end_ch IF_HUSH_BASH_COMPAT( || ch == end_char2)) { |
3639 | if (!dbl) | 3647 | if (!dbl) |
@@ -3647,22 +3655,26 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
3647 | o_addchr(dest, ch); | 3655 | o_addchr(dest, ch); |
3648 | if (ch == '(' || ch == '{') { | 3656 | if (ch == '(' || ch == '{') { |
3649 | ch = (ch == '(' ? ')' : '}'); | 3657 | ch = (ch == '(' ? ')' : '}'); |
3650 | add_till_closing_bracket(dest, input, ch); | 3658 | if (!add_till_closing_bracket(dest, input, ch)) |
3659 | return 0; | ||
3651 | o_addchr(dest, ch); | 3660 | o_addchr(dest, ch); |
3652 | continue; | 3661 | continue; |
3653 | } | 3662 | } |
3654 | if (ch == '\'') { | 3663 | if (ch == '\'') { |
3655 | add_till_single_quote(dest, input); | 3664 | if (!add_till_single_quote(dest, input)) |
3665 | return 0; | ||
3656 | o_addchr(dest, ch); | 3666 | o_addchr(dest, ch); |
3657 | continue; | 3667 | continue; |
3658 | } | 3668 | } |
3659 | if (ch == '"') { | 3669 | if (ch == '"') { |
3660 | add_till_double_quote(dest, input); | 3670 | if (!add_till_double_quote(dest, input)) |
3671 | return 0; | ||
3661 | o_addchr(dest, ch); | 3672 | o_addchr(dest, ch); |
3662 | continue; | 3673 | continue; |
3663 | } | 3674 | } |
3664 | if (ch == '`') { | 3675 | if (ch == '`') { |
3665 | add_till_backquote(dest, input, /*in_dquote:*/ 0); | 3676 | if (!add_till_backquote(dest, input, /*in_dquote:*/ 0)) |
3677 | return 0; | ||
3666 | o_addchr(dest, ch); | 3678 | o_addchr(dest, ch); |
3667 | continue; | 3679 | continue; |
3668 | } | 3680 | } |
@@ -3671,7 +3683,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
3671 | ch = i_getch(input); | 3683 | ch = i_getch(input); |
3672 | if (ch == EOF) { | 3684 | if (ch == EOF) { |
3673 | syntax_error_unterm_ch(')'); | 3685 | syntax_error_unterm_ch(')'); |
3674 | /*xfunc_die(); - redundant */ | 3686 | return 0; |
3675 | } | 3687 | } |
3676 | o_addchr(dest, ch); | 3688 | o_addchr(dest, ch); |
3677 | continue; | 3689 | continue; |
@@ -3742,8 +3754,8 @@ static int parse_dollar(o_string *as_string, | |||
3742 | ) { | 3754 | ) { |
3743 | bad_dollar_syntax: | 3755 | bad_dollar_syntax: |
3744 | syntax_error_unterm_str("${name}"); | 3756 | syntax_error_unterm_str("${name}"); |
3745 | debug_printf_parse("parse_dollar return 1: unterminated ${name}\n"); | 3757 | debug_printf_parse("parse_dollar return 0: unterminated ${name}\n"); |
3746 | return 1; | 3758 | return 0; |
3747 | } | 3759 | } |
3748 | nommu_addchr(as_string, ch); | 3760 | nommu_addchr(as_string, ch); |
3749 | ch |= quote_mask; | 3761 | ch |= quote_mask; |
@@ -3799,6 +3811,8 @@ static int parse_dollar(o_string *as_string, | |||
3799 | pos = dest->length; | 3811 | pos = dest->length; |
3800 | #if ENABLE_HUSH_DOLLAR_OPS | 3812 | #if ENABLE_HUSH_DOLLAR_OPS |
3801 | last_ch = add_till_closing_bracket(dest, input, end_ch); | 3813 | last_ch = add_till_closing_bracket(dest, input, end_ch); |
3814 | if (last_ch == 0) /* error? */ | ||
3815 | return 0; | ||
3802 | #else | 3816 | #else |
3803 | #error Simple code to only allow ${var} is not implemented | 3817 | #error Simple code to only allow ${var} is not implemented |
3804 | #endif | 3818 | #endif |
@@ -3843,7 +3857,8 @@ static int parse_dollar(o_string *as_string, | |||
3843 | o_addchr(dest, /*quote_mask |*/ '+'); | 3857 | o_addchr(dest, /*quote_mask |*/ '+'); |
3844 | if (!BB_MMU) | 3858 | if (!BB_MMU) |
3845 | pos = dest->length; | 3859 | pos = dest->length; |
3846 | add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG); | 3860 | if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG)) |
3861 | return 0; /* error */ | ||
3847 | if (as_string) { | 3862 | if (as_string) { |
3848 | o_addstr(as_string, dest->data + pos); | 3863 | o_addstr(as_string, dest->data + pos); |
3849 | o_addchr(as_string, ')'); | 3864 | o_addchr(as_string, ')'); |
@@ -3858,7 +3873,8 @@ static int parse_dollar(o_string *as_string, | |||
3858 | o_addchr(dest, quote_mask | '`'); | 3873 | o_addchr(dest, quote_mask | '`'); |
3859 | if (!BB_MMU) | 3874 | if (!BB_MMU) |
3860 | pos = dest->length; | 3875 | pos = dest->length; |
3861 | add_till_closing_bracket(dest, input, ')'); | 3876 | if (!add_till_closing_bracket(dest, input, ')')) |
3877 | return 0; /* error */ | ||
3862 | if (as_string) { | 3878 | if (as_string) { |
3863 | o_addstr(as_string, dest->data + pos); | 3879 | o_addstr(as_string, dest->data + pos); |
3864 | o_addchr(as_string, ')'); | 3880 | o_addchr(as_string, ')'); |
@@ -3885,8 +3901,8 @@ static int parse_dollar(o_string *as_string, | |||
3885 | default: | 3901 | default: |
3886 | o_addQchr(dest, '$'); | 3902 | o_addQchr(dest, '$'); |
3887 | } | 3903 | } |
3888 | debug_printf_parse("parse_dollar return 0\n"); | 3904 | debug_printf_parse("parse_dollar return 1 (ok)\n"); |
3889 | return 0; | 3905 | return 1; |
3890 | #undef as_string | 3906 | #undef as_string |
3891 | } | 3907 | } |
3892 | 3908 | ||
@@ -3927,13 +3943,13 @@ static int encode_string(o_string *as_string, | |||
3927 | if (ch != EOF) | 3943 | if (ch != EOF) |
3928 | nommu_addchr(as_string, ch); | 3944 | nommu_addchr(as_string, ch); |
3929 | if (ch == dquote_end) { /* may be only '"' or EOF */ | 3945 | if (ch == dquote_end) { /* may be only '"' or EOF */ |
3930 | debug_printf_parse("encode_string return 0\n"); | 3946 | debug_printf_parse("encode_string return 1 (ok)\n"); |
3931 | return 0; | 3947 | return 1; |
3932 | } | 3948 | } |
3933 | /* note: can't move it above ch == dquote_end check! */ | 3949 | /* note: can't move it above ch == dquote_end check! */ |
3934 | if (ch == EOF) { | 3950 | if (ch == EOF) { |
3935 | syntax_error_unterm_ch('"'); | 3951 | syntax_error_unterm_ch('"'); |
3936 | /*xfunc_die(); - redundant */ | 3952 | return 0; /* error */ |
3937 | } | 3953 | } |
3938 | next = '\0'; | 3954 | next = '\0'; |
3939 | if (ch != '\n') { | 3955 | if (ch != '\n') { |
@@ -3964,10 +3980,10 @@ static int encode_string(o_string *as_string, | |||
3964 | goto again; | 3980 | goto again; |
3965 | } | 3981 | } |
3966 | if (ch == '$') { | 3982 | if (ch == '$') { |
3967 | if (parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80) != 0) { | 3983 | if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) { |
3968 | debug_printf_parse("encode_string return 1: " | 3984 | debug_printf_parse("encode_string return 0: " |
3969 | "parse_dollar returned non-0\n"); | 3985 | "parse_dollar returned 0 (error)\n"); |
3970 | return 1; | 3986 | return 0; |
3971 | } | 3987 | } |
3972 | goto again; | 3988 | goto again; |
3973 | } | 3989 | } |
@@ -3976,7 +3992,8 @@ static int encode_string(o_string *as_string, | |||
3976 | //unsigned pos = dest->length; | 3992 | //unsigned pos = dest->length; |
3977 | o_addchr(dest, SPECIAL_VAR_SYMBOL); | 3993 | o_addchr(dest, SPECIAL_VAR_SYMBOL); |
3978 | o_addchr(dest, 0x80 | '`'); | 3994 | o_addchr(dest, 0x80 | '`'); |
3979 | add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"'); | 3995 | if (!add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"')) |
3996 | return 0; /* error */ | ||
3980 | o_addchr(dest, SPECIAL_VAR_SYMBOL); | 3997 | o_addchr(dest, SPECIAL_VAR_SYMBOL); |
3981 | //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); | 3998 | //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); |
3982 | goto again; | 3999 | goto again; |
@@ -4047,8 +4064,8 @@ static struct pipe *parse_stream(char **pstring, | |||
4047 | /* end_trigger == '}' case errors out earlier, | 4064 | /* end_trigger == '}' case errors out earlier, |
4048 | * checking only ')' */ | 4065 | * checking only ')' */ |
4049 | if (end_trigger == ')') { | 4066 | if (end_trigger == ')') { |
4050 | syntax_error_unterm_ch('('); /* exits */ | 4067 | syntax_error_unterm_ch('('); |
4051 | /* goto parse_error; */ | 4068 | goto parse_error; |
4052 | } | 4069 | } |
4053 | 4070 | ||
4054 | if (done_word(&dest, &ctx)) { | 4071 | if (done_word(&dest, &ctx)) { |
@@ -4339,9 +4356,9 @@ static struct pipe *parse_stream(char **pstring, | |||
4339 | dest.has_quoted_part = 1; | 4356 | dest.has_quoted_part = 1; |
4340 | break; | 4357 | break; |
4341 | case '$': | 4358 | case '$': |
4342 | if (parse_dollar(&ctx.as_string, &dest, input, /*quote_mask:*/ 0) != 0) { | 4359 | if (!parse_dollar(&ctx.as_string, &dest, input, /*quote_mask:*/ 0)) { |
4343 | debug_printf_parse("parse_stream parse error: " | 4360 | debug_printf_parse("parse_stream parse error: " |
4344 | "parse_dollar returned non-0\n"); | 4361 | "parse_dollar returned 0 (error)\n"); |
4345 | goto parse_error; | 4362 | goto parse_error; |
4346 | } | 4363 | } |
4347 | break; | 4364 | break; |
@@ -4351,7 +4368,7 @@ static struct pipe *parse_stream(char **pstring, | |||
4351 | ch = i_getch(input); | 4368 | ch = i_getch(input); |
4352 | if (ch == EOF) { | 4369 | if (ch == EOF) { |
4353 | syntax_error_unterm_ch('\''); | 4370 | syntax_error_unterm_ch('\''); |
4354 | /*xfunc_die(); - redundant */ | 4371 | goto parse_error; |
4355 | } | 4372 | } |
4356 | nommu_addchr(&ctx.as_string, ch); | 4373 | nommu_addchr(&ctx.as_string, ch); |
4357 | if (ch == '\'') | 4374 | if (ch == '\'') |
@@ -4363,7 +4380,7 @@ static struct pipe *parse_stream(char **pstring, | |||
4363 | dest.has_quoted_part = 1; | 4380 | dest.has_quoted_part = 1; |
4364 | if (dest.o_assignment == NOT_ASSIGNMENT) | 4381 | if (dest.o_assignment == NOT_ASSIGNMENT) |
4365 | dest.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS; | 4382 | dest.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS; |
4366 | if (encode_string(&ctx.as_string, &dest, input, '"', /*process_bkslash:*/ 1)) | 4383 | if (!encode_string(&ctx.as_string, &dest, input, '"', /*process_bkslash:*/ 1)) |
4367 | goto parse_error; | 4384 | goto parse_error; |
4368 | dest.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS; | 4385 | dest.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS; |
4369 | break; | 4386 | break; |
@@ -4374,7 +4391,8 @@ static struct pipe *parse_stream(char **pstring, | |||
4374 | o_addchr(&dest, SPECIAL_VAR_SYMBOL); | 4391 | o_addchr(&dest, SPECIAL_VAR_SYMBOL); |
4375 | o_addchr(&dest, '`'); | 4392 | o_addchr(&dest, '`'); |
4376 | pos = dest.length; | 4393 | pos = dest.length; |
4377 | add_till_backquote(&dest, input, /*in_dquote:*/ 0); | 4394 | if (!add_till_backquote(&dest, input, /*in_dquote:*/ 0)) |
4395 | goto parse_error; | ||
4378 | # if !BB_MMU | 4396 | # if !BB_MMU |
4379 | o_addstr(&ctx.as_string, dest.data + pos); | 4397 | o_addstr(&ctx.as_string, dest.data + pos); |
4380 | o_addchr(&ctx.as_string, '`'); | 4398 | o_addchr(&ctx.as_string, '`'); |
@@ -4650,6 +4668,7 @@ static char *encode_then_expand_string(const char *str, int process_bkslash, int | |||
4650 | */ | 4668 | */ |
4651 | setup_string_in_str(&input, str); | 4669 | setup_string_in_str(&input, str); |
4652 | encode_string(NULL, &dest, &input, EOF, process_bkslash); | 4670 | encode_string(NULL, &dest, &input, EOF, process_bkslash); |
4671 | //TODO: error check (encode_string returns 0 on error)? | ||
4653 | //bb_error_msg("'%s' -> '%s'", str, dest.data); | 4672 | //bb_error_msg("'%s' -> '%s'", str, dest.data); |
4654 | exp_str = expand_string_to_string(dest.data, /*unbackslash:*/ do_unbackslash); | 4673 | exp_str = expand_string_to_string(dest.data, /*unbackslash:*/ do_unbackslash); |
4655 | //bb_error_msg("'%s' -> '%s'", dest.data, exp_str); | 4674 | //bb_error_msg("'%s' -> '%s'", dest.data, exp_str); |
@@ -5540,6 +5559,10 @@ static void parse_and_run_stream(struct in_str *inp, int end_trigger) | |||
5540 | debug_printf_exec("parse_and_run_stream: run_and_free_list\n"); | 5559 | debug_printf_exec("parse_and_run_stream: run_and_free_list\n"); |
5541 | run_and_free_list(pipe_list); | 5560 | run_and_free_list(pipe_list); |
5542 | empty = 0; | 5561 | empty = 0; |
5562 | #if ENABLE_HUSH_FUNCTIONS | ||
5563 | if (G.flag_return_in_progress == 1) | ||
5564 | break; | ||
5565 | #endif | ||
5543 | } | 5566 | } |
5544 | } | 5567 | } |
5545 | 5568 | ||
@@ -8607,6 +8630,8 @@ static int FAST_FUNC builtin_source(char **argv) | |||
8607 | #endif | 8630 | #endif |
8608 | save_and_replace_G_args(&sv, argv); | 8631 | save_and_replace_G_args(&sv, argv); |
8609 | 8632 | ||
8633 | //TODO: syntax errors in sourced file should never abort the "calling" script. | ||
8634 | //Try: bash -c '. ./bad_file; echo YES' | ||
8610 | parse_and_run_file(input); | 8635 | parse_and_run_file(input); |
8611 | fclose(input); | 8636 | fclose(input); |
8612 | 8637 | ||
diff --git a/shell/hush_test/hush-misc/return1.right b/shell/hush_test/hush-misc/return1.right new file mode 100644 index 000000000..7b24a35ff --- /dev/null +++ b/shell/hush_test/hush-misc/return1.right | |||
@@ -0,0 +1 @@ | |||
Ok:0 | |||
diff --git a/shell/hush_test/hush-misc/return1.tests b/shell/hush_test/hush-misc/return1.tests new file mode 100755 index 000000000..eeb92ef3f --- /dev/null +++ b/shell/hush_test/hush-misc/return1.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | echo "true && return; echo Should not be printed" >return_sourced | ||
2 | . ./return_sourced | ||
3 | rm return_sourced | ||
4 | echo Ok:$? | ||
diff --git a/shell/hush_test/hush-misc/source1.right b/shell/hush_test/hush-misc/source1.right new file mode 100644 index 000000000..d4256034b --- /dev/null +++ b/shell/hush_test/hush-misc/source1.right | |||
@@ -0,0 +1,5 @@ | |||
1 | hush: syntax error: unterminated ${name} | ||
2 | line2 | ||
3 | Ok1:0 | ||
4 | hush: syntax error: unterminated ' | ||
5 | Ok2:1 | ||
diff --git a/shell/hush_test/hush-misc/source1.tests b/shell/hush_test/hush-misc/source1.tests new file mode 100755 index 000000000..c13888359 --- /dev/null +++ b/shell/hush_test/hush-misc/source1.tests | |||
@@ -0,0 +1,10 @@ | |||
1 | echo 'echo ${^} | ||
2 | echo line2' >sourced1 | ||
3 | . ./sourced1 | ||
4 | echo Ok1:$? | ||
5 | |||
6 | echo "echo '" >sourced1 | ||
7 | . ./sourced1 | ||
8 | echo Ok2:$? | ||
9 | |||
10 | rm sourced1 | ||
diff --git a/sysklogd/Config.src b/sysklogd/Config.src index 1e5987275..d62dc5f5c 100644 --- a/sysklogd/Config.src +++ b/sysklogd/Config.src | |||
@@ -119,7 +119,8 @@ config KLOGD | |||
119 | config FEATURE_KLOGD_KLOGCTL | 119 | config FEATURE_KLOGD_KLOGCTL |
120 | bool "Use the klogctl() interface" | 120 | bool "Use the klogctl() interface" |
121 | default y | 121 | default y |
122 | depends on KLOGD && PLATFORM_LINUX | 122 | depends on KLOGD |
123 | select PLATFORM_LINUX | ||
123 | help | 124 | help |
124 | The klogd applet supports two interfaces for reading | 125 | The klogd applet supports two interfaces for reading |
125 | kernel messages. Linux provides the klogctl() interface | 126 | kernel messages. Linux provides the klogctl() interface |
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index 0d4c2578d..db32065fb 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c | |||
@@ -150,12 +150,41 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) | |||
150 | */ | 150 | */ |
151 | klogd_open(); | 151 | klogd_open(); |
152 | openlog("kernel", 0, LOG_KERN); | 152 | openlog("kernel", 0, LOG_KERN); |
153 | /* | ||
154 | * glibc problem: for some reason, glibc changes LOG_KERN to LOG_USER | ||
155 | * above. The logic behind this is that standard | ||
156 | * http://pubs.opengroup.org/onlinepubs/9699919799/functions/syslog.html | ||
157 | * says the following about openlog and syslog: | ||
158 | * "LOG_USER | ||
159 | * Messages generated by arbitrary processes. | ||
160 | * This is the default facility identifier if none is specified." | ||
161 | * | ||
162 | * I believe glibc misinterpreted this text as "if openlog's | ||
163 | * third parameter is 0 (=LOG_KERN), treat it as LOG_USER". | ||
164 | * Whereas it was meant to say "if *syslog* is called with facility | ||
165 | * 0 in its 1st parameter without prior call to openlog, then perform | ||
166 | * implicit openlog(LOG_USER)". | ||
167 | * | ||
168 | * As a result of this, eh, feature, standard klogd was forced | ||
169 | * to open-code its own openlog and syslog implementation (!). | ||
170 | * | ||
171 | * Note that prohibiting openlog(LOG_KERN) on libc level does not | ||
172 | * add any security: any process can open a socket to "/dev/log" | ||
173 | * and write a string "<0>Voila, a LOG_KERN + LOG_EMERG message" | ||
174 | * | ||
175 | * Google code search tells me there is no widespread use of | ||
176 | * openlog("foo", 0, 0), thus fixing glibc won't break userspace. | ||
177 | * | ||
178 | * The bug against glibc was filed: | ||
179 | * bugzilla.redhat.com/show_bug.cgi?id=547000 | ||
180 | */ | ||
153 | 181 | ||
154 | if (i) | 182 | if (i) |
155 | klogd_setloglevel(i); | 183 | klogd_setloglevel(i); |
156 | 184 | ||
157 | bb_signals(BB_FATAL_SIGS, record_signo); | ||
158 | signal(SIGHUP, SIG_IGN); | 185 | signal(SIGHUP, SIG_IGN); |
186 | /* We want klogd_read to not be restarted, thus _norestart: */ | ||
187 | bb_signals_recursive_norestart(BB_FATAL_SIGS, record_signo); | ||
159 | 188 | ||
160 | syslog(LOG_NOTICE, "klogd started: %s", bb_banner); | 189 | syslog(LOG_NOTICE, "klogd started: %s", bb_banner); |
161 | 190 | ||
diff --git a/testsuite/ls.tests b/testsuite/ls.tests index 1669579e7..e2284658d 100755 --- a/testsuite/ls.tests +++ b/testsuite/ls.tests | |||
@@ -251,6 +251,16 @@ test x"$CONFIG_UNICODE_SUPPORT" = x"y" \ | |||
251 | 0110_5.3.2__U+FFFF_=_ef_bf_bf_=_"?"_______________________________________| | 251 | 0110_5.3.2__U+FFFF_=_ef_bf_bf_=_"?"_______________________________________| |
252 | ' "" "" | 252 | ' "" "" |
253 | 253 | ||
254 | rm -rf ls.testdir 2>/dev/null | ||
255 | mkdir ls.testdir || exit 1 | ||
256 | |||
257 | # testing "test name" "command" "expected result" "file input" "stdin" | ||
258 | |||
259 | testing "ls symlink_to_dir" \ | ||
260 | "touch ls.testdir/A ls.testdir/B; ln -s ls.testdir ls.link; ls ls.link; ls -1 ls.link/; ls -1 ls.link; rm -f ls.link" \ | ||
261 | "A\nB\nA\nB\nA\nB\n" \ | ||
262 | "" "" | ||
263 | |||
254 | # Clean up | 264 | # Clean up |
255 | rm -rf ls.testdir 2>/dev/null | 265 | rm -rf ls.testdir 2>/dev/null |
256 | 266 | ||
diff --git a/testsuite/mount.tests b/testsuite/mount.tests index d3d2400e8..58eeb2ec5 100755 --- a/testsuite/mount.tests +++ b/testsuite/mount.tests | |||
@@ -20,7 +20,7 @@ if test x"$CONFIG_MKFS_MINIX" != x"y" \ | |||
20 | exit 0 | 20 | exit 0 |
21 | fi | 21 | fi |
22 | 22 | ||
23 | testdir=$PWD/mount.testdir | 23 | testdir="$PWD/mount.testdir" |
24 | 24 | ||
25 | dd if=/dev/zero of=mount.image1m count=1 bs=1M 2>/dev/null || { echo "dd error"; exit 1; } | 25 | dd if=/dev/zero of=mount.image1m count=1 bs=1M 2>/dev/null || { echo "dd error"; exit 1; } |
26 | mkfs.minix -v mount.image1m >/dev/null 2>&1 || { echo "mkfs.minix error"; exit 1; } | 26 | mkfs.minix -v mount.image1m >/dev/null 2>&1 || { echo "mkfs.minix error"; exit 1; } |
@@ -44,4 +44,41 @@ umount -d "$testdir" | |||
44 | rmdir "$testdir" | 44 | rmdir "$testdir" |
45 | rm mount.image1m | 45 | rm mount.image1m |
46 | 46 | ||
47 | |||
48 | # Bug: mount.shared1 directory shows no files (has to show files a and b) | ||
49 | testing "mount bind+rshared" "\ | ||
50 | mkdir -p mount.dir mount.shared1 mount.shared2 | ||
51 | touch mount.dir/a mount.dir/b | ||
52 | |||
53 | mount --bind mount.shared1 mount.shared1 2>&1 | ||
54 | mount --make-rshared mount.shared1 2>&1 | ||
55 | mount --bind mount.shared2 mount.shared2 2>&1 | ||
56 | mount --make-rshared mount.shared2 2>&1 | ||
57 | |||
58 | mount --bind mount.shared2 mount.shared1 2>&1 | ||
59 | mount --bind mount.dir mount.shared2 2>&1 | ||
60 | |||
61 | ls -R mount.dir mount.shared1 mount.shared2 2>&1 | ||
62 | |||
63 | umount mount.dir mount.shared1 mount.shared2 2>/dev/null | ||
64 | umount mount.dir mount.shared1 mount.shared2 2>/dev/null | ||
65 | umount mount.dir mount.shared1 mount.shared2 2>/dev/null | ||
66 | rm -f mount.dir/a mount.dir/b mount.dir/c | ||
67 | rmdir mount.dir mount.shared1 mount.shared2 | ||
68 | " \ | ||
69 | "\ | ||
70 | mount.dir: | ||
71 | a | ||
72 | b | ||
73 | |||
74 | mount.shared1: | ||
75 | a | ||
76 | b | ||
77 | |||
78 | mount.shared2: | ||
79 | a | ||
80 | b | ||
81 | " \ | ||
82 | "" "" | ||
83 | |||
47 | exit $FAILCOUNT | 84 | exit $FAILCOUNT |
diff --git a/testsuite/tar.tests b/testsuite/tar.tests index 472064f7f..534135df8 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests | |||
@@ -168,6 +168,23 @@ Ok | |||
168 | " \ | 168 | " \ |
169 | "" "" | 169 | "" "" |
170 | 170 | ||
171 | # On extract, everything up to and including last ".." component is stripped | ||
172 | testing "tar strips /../ on extract" "\ | ||
173 | rm -rf input_* test.tar 2>/dev/null | ||
174 | mkdir input_dir | ||
175 | echo Ok >input_dir/file | ||
176 | tar cf test.tar ./../tar.tempdir/input_dir/../input_dir 2>&1 | ||
177 | rm -rf input_* 2>/dev/null | ||
178 | tar -vxf test.tar 2>&1 | ||
179 | cat input_dir/file 2>&1 | ||
180 | " "\ | ||
181 | tar: removing leading './../tar.tempdir/input_dir/../' from member names | ||
182 | input_dir/ | ||
183 | input_dir/file | ||
184 | Ok | ||
185 | " \ | ||
186 | "" "" | ||
187 | |||
171 | 188 | ||
172 | cd .. && rm -rf tar.tempdir || exit 1 | 189 | cd .. && rm -rf tar.tempdir || exit 1 |
173 | 190 | ||
diff --git a/util-linux/Config.src b/util-linux/Config.src index 941a47f90..90606bcae 100644 --- a/util-linux/Config.src +++ b/util-linux/Config.src | |||
@@ -10,7 +10,7 @@ INSERT | |||
10 | config ACPID | 10 | config ACPID |
11 | bool "acpid" | 11 | bool "acpid" |
12 | default y | 12 | default y |
13 | depends on PLATFORM_LINUX | 13 | select PLATFORM_LINUX |
14 | help | 14 | help |
15 | acpid listens to ACPI events coming either in textual form from | 15 | acpid listens to ACPI events coming either in textual form from |
16 | /proc/acpi/event (though it is marked deprecated it is still widely | 16 | /proc/acpi/event (though it is marked deprecated it is still widely |
@@ -33,7 +33,7 @@ config FEATURE_ACPID_COMPAT | |||
33 | config BLKID | 33 | config BLKID |
34 | bool "blkid" | 34 | bool "blkid" |
35 | default y | 35 | default y |
36 | depends on PLATFORM_LINUX | 36 | select PLATFORM_LINUX |
37 | select VOLUMEID | 37 | select VOLUMEID |
38 | help | 38 | help |
39 | Lists labels and UUIDs of all filesystems. | 39 | Lists labels and UUIDs of all filesystems. |
@@ -50,7 +50,7 @@ config FEATURE_BLKID_TYPE | |||
50 | config DMESG | 50 | config DMESG |
51 | bool "dmesg" | 51 | bool "dmesg" |
52 | default y | 52 | default y |
53 | depends on PLATFORM_LINUX | 53 | select PLATFORM_LINUX |
54 | help | 54 | help |
55 | dmesg is used to examine or control the kernel ring buffer. When the | 55 | dmesg is used to examine or control the kernel ring buffer. When the |
56 | Linux kernel prints messages to the system log, they are stored in | 56 | Linux kernel prints messages to the system log, they are stored in |
@@ -84,7 +84,7 @@ config FEATURE_DMESG_PRETTY | |||
84 | config FBSET | 84 | config FBSET |
85 | bool "fbset" | 85 | bool "fbset" |
86 | default y | 86 | default y |
87 | depends on PLATFORM_LINUX | 87 | select PLATFORM_LINUX |
88 | help | 88 | help |
89 | fbset is used to show or change the settings of a Linux frame buffer | 89 | fbset is used to show or change the settings of a Linux frame buffer |
90 | device. The frame buffer device provides a simple and unique | 90 | device. The frame buffer device provides a simple and unique |
@@ -113,7 +113,7 @@ config FEATURE_FBSET_READMODE | |||
113 | config FDFLUSH | 113 | config FDFLUSH |
114 | bool "fdflush" | 114 | bool "fdflush" |
115 | default y | 115 | default y |
116 | depends on PLATFORM_LINUX | 116 | select PLATFORM_LINUX |
117 | help | 117 | help |
118 | fdflush is only needed when changing media on slightly-broken | 118 | fdflush is only needed when changing media on slightly-broken |
119 | removable media drives. It is used to make Linux believe that a | 119 | removable media drives. It is used to make Linux believe that a |
@@ -126,14 +126,14 @@ config FDFLUSH | |||
126 | config FDFORMAT | 126 | config FDFORMAT |
127 | bool "fdformat" | 127 | bool "fdformat" |
128 | default y | 128 | default y |
129 | depends on PLATFORM_LINUX | 129 | select PLATFORM_LINUX |
130 | help | 130 | help |
131 | fdformat is used to low-level format a floppy disk. | 131 | fdformat is used to low-level format a floppy disk. |
132 | 132 | ||
133 | config FDISK | 133 | config FDISK |
134 | bool "fdisk" | 134 | bool "fdisk" |
135 | default y | 135 | default y |
136 | depends on PLATFORM_LINUX | 136 | select PLATFORM_LINUX |
137 | help | 137 | help |
138 | The fdisk utility is used to divide hard disks into one or more | 138 | The fdisk utility is used to divide hard disks into one or more |
139 | logical disks, which are generally called partitions. This utility | 139 | logical disks, which are generally called partitions. This utility |
@@ -209,7 +209,7 @@ config FEATURE_FDISK_ADVANCED | |||
209 | config FINDFS | 209 | config FINDFS |
210 | bool "findfs" | 210 | bool "findfs" |
211 | default y | 211 | default y |
212 | depends on PLATFORM_LINUX | 212 | select PLATFORM_LINUX |
213 | select VOLUMEID | 213 | select VOLUMEID |
214 | help | 214 | help |
215 | Prints the name of a filesystem with given label or UUID. | 215 | Prints the name of a filesystem with given label or UUID. |
@@ -225,7 +225,7 @@ config FLOCK | |||
225 | config FREERAMDISK | 225 | config FREERAMDISK |
226 | bool "freeramdisk" | 226 | bool "freeramdisk" |
227 | default y | 227 | default y |
228 | depends on PLATFORM_LINUX | 228 | select PLATFORM_LINUX |
229 | help | 229 | help |
230 | Linux allows you to create ramdisks. This utility allows you to | 230 | Linux allows you to create ramdisks. This utility allows you to |
231 | delete them and completely free all memory that was used for the | 231 | delete them and completely free all memory that was used for the |
@@ -248,14 +248,14 @@ config FSCK_MINIX | |||
248 | config MKFS_EXT2 | 248 | config MKFS_EXT2 |
249 | bool "mkfs_ext2" | 249 | bool "mkfs_ext2" |
250 | default y | 250 | default y |
251 | depends on PLATFORM_LINUX | 251 | select PLATFORM_LINUX |
252 | help | 252 | help |
253 | Utility to create EXT2 filesystems. | 253 | Utility to create EXT2 filesystems. |
254 | 254 | ||
255 | config MKFS_MINIX | 255 | config MKFS_MINIX |
256 | bool "mkfs_minix" | 256 | bool "mkfs_minix" |
257 | default y | 257 | default y |
258 | depends on PLATFORM_LINUX | 258 | select PLATFORM_LINUX |
259 | help | 259 | help |
260 | The minix filesystem is a nice, small, compact, read-write filesystem | 260 | The minix filesystem is a nice, small, compact, read-write filesystem |
261 | with little overhead. If you wish to be able to create minix | 261 | with little overhead. If you wish to be able to create minix |
@@ -273,7 +273,7 @@ config FEATURE_MINIX2 | |||
273 | config MKFS_REISER | 273 | config MKFS_REISER |
274 | bool "mkfs_reiser" | 274 | bool "mkfs_reiser" |
275 | default n | 275 | default n |
276 | depends on PLATFORM_LINUX | 276 | select PLATFORM_LINUX |
277 | help | 277 | help |
278 | Utility to create ReiserFS filesystems. | 278 | Utility to create ReiserFS filesystems. |
279 | Note: this applet needs a lot of testing and polishing. | 279 | Note: this applet needs a lot of testing and polishing. |
@@ -281,7 +281,7 @@ config MKFS_REISER | |||
281 | config MKFS_VFAT | 281 | config MKFS_VFAT |
282 | bool "mkfs_vfat" | 282 | bool "mkfs_vfat" |
283 | default y | 283 | default y |
284 | depends on PLATFORM_LINUX | 284 | select PLATFORM_LINUX |
285 | help | 285 | help |
286 | Utility to create FAT32 filesystems. | 286 | Utility to create FAT32 filesystems. |
287 | 287 | ||
@@ -330,7 +330,7 @@ config HD | |||
330 | config HWCLOCK | 330 | config HWCLOCK |
331 | bool "hwclock" | 331 | bool "hwclock" |
332 | default y | 332 | default y |
333 | depends on PLATFORM_LINUX | 333 | select PLATFORM_LINUX |
334 | help | 334 | help |
335 | The hwclock utility is used to read and set the hardware clock | 335 | The hwclock utility is used to read and set the hardware clock |
336 | on a system. This is primarily used to set the current time on | 336 | on a system. This is primarily used to set the current time on |
@@ -369,7 +369,7 @@ config IPCRM | |||
369 | config IPCS | 369 | config IPCS |
370 | bool "ipcs" | 370 | bool "ipcs" |
371 | default y | 371 | default y |
372 | depends on PLATFORM_LINUX | 372 | select PLATFORM_LINUX |
373 | help | 373 | help |
374 | The ipcs utility is used to provide information on the currently | 374 | The ipcs utility is used to provide information on the currently |
375 | allocated System V interprocess (IPC) objects in the system. | 375 | allocated System V interprocess (IPC) objects in the system. |
@@ -377,7 +377,7 @@ config IPCS | |||
377 | config LOSETUP | 377 | config LOSETUP |
378 | bool "losetup" | 378 | bool "losetup" |
379 | default y | 379 | default y |
380 | depends on PLATFORM_LINUX | 380 | select PLATFORM_LINUX |
381 | help | 381 | help |
382 | losetup is used to associate or detach a loop device with a regular | 382 | losetup is used to associate or detach a loop device with a regular |
383 | file or block device, and to query the status of a loop device. This | 383 | file or block device, and to query the status of a loop device. This |
@@ -386,7 +386,7 @@ config LOSETUP | |||
386 | config LSPCI | 386 | config LSPCI |
387 | bool "lspci" | 387 | bool "lspci" |
388 | default y | 388 | default y |
389 | #depends on PLATFORM_LINUX | 389 | #select PLATFORM_LINUX |
390 | help | 390 | help |
391 | lspci is a utility for displaying information about PCI buses in the | 391 | lspci is a utility for displaying information about PCI buses in the |
392 | system and devices connected to them. | 392 | system and devices connected to them. |
@@ -396,7 +396,7 @@ config LSPCI | |||
396 | config LSUSB | 396 | config LSUSB |
397 | bool "lsusb" | 397 | bool "lsusb" |
398 | default y | 398 | default y |
399 | #depends on PLATFORM_LINUX | 399 | #select PLATFORM_LINUX |
400 | help | 400 | help |
401 | lsusb is a utility for displaying information about USB buses in the | 401 | lsusb is a utility for displaying information about USB buses in the |
402 | system and devices connected to them. | 402 | system and devices connected to them. |
@@ -406,7 +406,7 @@ config LSUSB | |||
406 | config MDEV | 406 | config MDEV |
407 | bool "mdev" | 407 | bool "mdev" |
408 | default y | 408 | default y |
409 | depends on PLATFORM_LINUX | 409 | select PLATFORM_LINUX |
410 | help | 410 | help |
411 | mdev is a mini-udev implementation for dynamically creating device | 411 | mdev is a mini-udev implementation for dynamically creating device |
412 | nodes in the /dev directory. | 412 | nodes in the /dev directory. |
@@ -494,7 +494,7 @@ config MORE | |||
494 | config MOUNT | 494 | config MOUNT |
495 | bool "mount" | 495 | bool "mount" |
496 | default y | 496 | default y |
497 | depends on PLATFORM_LINUX | 497 | select PLATFORM_LINUX |
498 | help | 498 | help |
499 | All files and filesystems in Unix are arranged into one big directory | 499 | All files and filesystems in Unix are arranged into one big directory |
500 | tree. The 'mount' utility is used to graft a filesystem onto a | 500 | tree. The 'mount' utility is used to graft a filesystem onto a |
@@ -577,7 +577,7 @@ config FEATURE_MOUNT_FSTAB | |||
577 | config PIVOT_ROOT | 577 | config PIVOT_ROOT |
578 | bool "pivot_root" | 578 | bool "pivot_root" |
579 | default y | 579 | default y |
580 | depends on PLATFORM_LINUX | 580 | select PLATFORM_LINUX |
581 | help | 581 | help |
582 | The pivot_root utility swaps the mount points for the root filesystem | 582 | The pivot_root utility swaps the mount points for the root filesystem |
583 | with some other mounted filesystem. This allows you to do all sorts | 583 | with some other mounted filesystem. This allows you to do all sorts |
@@ -605,14 +605,14 @@ config RDEV | |||
605 | config READPROFILE | 605 | config READPROFILE |
606 | bool "readprofile" | 606 | bool "readprofile" |
607 | default y | 607 | default y |
608 | #depends on PLATFORM_LINUX | 608 | #select PLATFORM_LINUX |
609 | help | 609 | help |
610 | This allows you to parse /proc/profile for basic profiling. | 610 | This allows you to parse /proc/profile for basic profiling. |
611 | 611 | ||
612 | config RTCWAKE | 612 | config RTCWAKE |
613 | bool "rtcwake" | 613 | bool "rtcwake" |
614 | default y | 614 | default y |
615 | depends on PLATFORM_LINUX | 615 | select PLATFORM_LINUX |
616 | help | 616 | help |
617 | Enter a system sleep state until specified wakeup time. | 617 | Enter a system sleep state until specified wakeup time. |
618 | 618 | ||
@@ -632,7 +632,7 @@ config SCRIPTREPLAY | |||
632 | config SETARCH | 632 | config SETARCH |
633 | bool "setarch" | 633 | bool "setarch" |
634 | default y | 634 | default y |
635 | depends on PLATFORM_LINUX | 635 | select PLATFORM_LINUX |
636 | help | 636 | help |
637 | The linux32 utility is used to create a 32bit environment for the | 637 | The linux32 utility is used to create a 32bit environment for the |
638 | specified program (usually a shell). It only makes sense to have | 638 | specified program (usually a shell). It only makes sense to have |
@@ -642,7 +642,7 @@ config SETARCH | |||
642 | config SWAPONOFF | 642 | config SWAPONOFF |
643 | bool "swaponoff" | 643 | bool "swaponoff" |
644 | default y | 644 | default y |
645 | depends on PLATFORM_LINUX | 645 | select PLATFORM_LINUX |
646 | help | 646 | help |
647 | This option enables both the 'swapon' and the 'swapoff' utilities. | 647 | This option enables both the 'swapon' and the 'swapoff' utilities. |
648 | Once you have created some swap space using 'mkswap', you also need | 648 | Once you have created some swap space using 'mkswap', you also need |
@@ -661,7 +661,7 @@ config FEATURE_SWAPON_PRI | |||
661 | config SWITCH_ROOT | 661 | config SWITCH_ROOT |
662 | bool "switch_root" | 662 | bool "switch_root" |
663 | default y | 663 | default y |
664 | depends on PLATFORM_LINUX | 664 | select PLATFORM_LINUX |
665 | help | 665 | help |
666 | The switch_root utility is used from initramfs to select a new | 666 | The switch_root utility is used from initramfs to select a new |
667 | root device. Under initramfs, you have to use this instead of | 667 | root device. Under initramfs, you have to use this instead of |
@@ -681,7 +681,7 @@ config SWITCH_ROOT | |||
681 | config UMOUNT | 681 | config UMOUNT |
682 | bool "umount" | 682 | bool "umount" |
683 | default y | 683 | default y |
684 | depends on PLATFORM_LINUX | 684 | select PLATFORM_LINUX |
685 | help | 685 | help |
686 | When you want to remove a mounted filesystem from its current mount | 686 | When you want to remove a mounted filesystem from its current mount |
687 | point, for example when you are shutting down the system, the | 687 | point, for example when you are shutting down the system, the |
diff --git a/util-linux/more.c b/util-linux/more.c index c424a0e4b..7160b8b00 100644 --- a/util-linux/more.c +++ b/util-linux/more.c | |||
@@ -113,9 +113,12 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
113 | loop_top: | 113 | loop_top: |
114 | if (input != 'r' && please_display_more_prompt) { | 114 | if (input != 'r' && please_display_more_prompt) { |
115 | len = printf("--More-- "); | 115 | len = printf("--More-- "); |
116 | if (st.st_size > 0) { | 116 | if (st.st_size != 0) { |
117 | uoff_t d = (uoff_t)st.st_size / 100; | ||
118 | if (d == 0) | ||
119 | d = 1; | ||
117 | len += printf("(%u%% of %"OFF_FMT"u bytes)", | 120 | len += printf("(%u%% of %"OFF_FMT"u bytes)", |
118 | (int) (ftello(file)*100 / st.st_size), | 121 | (int) ((uoff_t)ftello(file) / d), |
119 | st.st_size); | 122 | st.st_size); |
120 | } | 123 | } |
121 | fflush_all(); | 124 | fflush_all(); |
@@ -159,7 +162,7 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
159 | /* Crudely convert tabs into spaces, which are | 162 | /* Crudely convert tabs into spaces, which are |
160 | * a bajillion times easier to deal with. */ | 163 | * a bajillion times easier to deal with. */ |
161 | if (c == '\t') { | 164 | if (c == '\t') { |
162 | spaces = CONVERTED_TAB_SIZE - 1; | 165 | spaces = ((unsigned)~len) % CONVERTED_TAB_SIZE; |
163 | c = ' '; | 166 | c = ' '; |
164 | } | 167 | } |
165 | 168 | ||
diff --git a/util-linux/mount.c b/util-linux/mount.c index 0baa74c7c..722d0be92 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -181,6 +181,7 @@ static const int32_t mount_options[] = { | |||
181 | /* "relatime" */ MS_RELATIME, | 181 | /* "relatime" */ MS_RELATIME, |
182 | /* "norelatime" */ ~MS_RELATIME, | 182 | /* "norelatime" */ ~MS_RELATIME, |
183 | /* "loud" */ ~MS_SILENT, | 183 | /* "loud" */ ~MS_SILENT, |
184 | /* "rbind" */ MS_BIND|MS_RECURSIVE, | ||
184 | 185 | ||
185 | // action flags | 186 | // action flags |
186 | /* "union" */ MS_UNION, | 187 | /* "union" */ MS_UNION, |
@@ -192,7 +193,7 @@ static const int32_t mount_options[] = { | |||
192 | /* "unbindable" */ MS_UNBINDABLE, | 193 | /* "unbindable" */ MS_UNBINDABLE, |
193 | /* "rshared" */ MS_SHARED|MS_RECURSIVE, | 194 | /* "rshared" */ MS_SHARED|MS_RECURSIVE, |
194 | /* "rslave" */ MS_SLAVE|MS_RECURSIVE, | 195 | /* "rslave" */ MS_SLAVE|MS_RECURSIVE, |
195 | /* "rprivate" */ MS_SLAVE|MS_RECURSIVE, | 196 | /* "rprivate" */ MS_PRIVATE|MS_RECURSIVE, |
196 | /* "runbindable" */ MS_UNBINDABLE|MS_RECURSIVE, | 197 | /* "runbindable" */ MS_UNBINDABLE|MS_RECURSIVE, |
197 | ) | 198 | ) |
198 | 199 | ||
@@ -236,6 +237,7 @@ static const char mount_option_str[] = | |||
236 | "relatime\0" | 237 | "relatime\0" |
237 | "norelatime\0" | 238 | "norelatime\0" |
238 | "loud\0" | 239 | "loud\0" |
240 | "rbind\0" | ||
239 | 241 | ||
240 | // action flags | 242 | // action flags |
241 | "union\0" | 243 | "union\0" |
@@ -279,6 +281,61 @@ enum { GETMNTENT_BUFSIZE = COMMON_BUFSIZE - offsetof(struct globals, getmntent_b | |||
279 | #define fslist (G.fslist ) | 281 | #define fslist (G.fslist ) |
280 | #define getmntent_buf (G.getmntent_buf ) | 282 | #define getmntent_buf (G.getmntent_buf ) |
281 | 283 | ||
284 | #if ENABLE_FEATURE_MTAB_SUPPORT | ||
285 | /* | ||
286 | * update_mtab_entry_on_move() is used to update entry in case of mount --move. | ||
287 | * we are looking for existing entries mnt_dir which is equal to mnt_fsname of | ||
288 | * input mntent and replace it by new one. | ||
289 | */ | ||
290 | static void FAST_FUNC update_mtab_entry_on_move(const struct mntent *mp) | ||
291 | { | ||
292 | struct mntent *entries, *m; | ||
293 | int i, count; | ||
294 | FILE *mountTable; | ||
295 | |||
296 | mountTable = setmntent(bb_path_mtab_file, "r"); | ||
297 | if (!mountTable) { | ||
298 | bb_perror_msg(bb_path_mtab_file); | ||
299 | return; | ||
300 | } | ||
301 | |||
302 | entries = NULL; | ||
303 | count = 0; | ||
304 | while ((m = getmntent(mountTable)) != NULL) { | ||
305 | entries = xrealloc_vector(entries, 3, count); | ||
306 | entries[count].mnt_fsname = xstrdup(m->mnt_fsname); | ||
307 | entries[count].mnt_dir = xstrdup(m->mnt_dir); | ||
308 | entries[count].mnt_type = xstrdup(m->mnt_type); | ||
309 | entries[count].mnt_opts = xstrdup(m->mnt_opts); | ||
310 | entries[count].mnt_freq = m->mnt_freq; | ||
311 | entries[count].mnt_passno = m->mnt_passno; | ||
312 | count++; | ||
313 | } | ||
314 | endmntent(mountTable); | ||
315 | |||
316 | mountTable = setmntent(bb_path_mtab_file, "w"); | ||
317 | if (mountTable) { | ||
318 | for (i = 0; i < count; i++) { | ||
319 | if (strcmp(entries[i].mnt_dir, mp->mnt_fsname) != 0) | ||
320 | addmntent(mountTable, &entries[i]); | ||
321 | else | ||
322 | addmntent(mountTable, mp); | ||
323 | } | ||
324 | endmntent(mountTable); | ||
325 | } else if (errno != EROFS) | ||
326 | bb_perror_msg(bb_path_mtab_file); | ||
327 | |||
328 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
329 | for (i = 0; i < count; i++) { | ||
330 | free(entries[i].mnt_fsname); | ||
331 | free(entries[i].mnt_dir); | ||
332 | free(entries[i].mnt_type); | ||
333 | free(entries[i].mnt_opts); | ||
334 | } | ||
335 | free(entries); | ||
336 | } | ||
337 | } | ||
338 | #endif | ||
282 | 339 | ||
283 | #if ENABLE_FEATURE_MOUNT_VERBOSE | 340 | #if ENABLE_FEATURE_MOUNT_VERBOSE |
284 | static int verbose_mount(const char *source, const char *target, | 341 | static int verbose_mount(const char *source, const char *target, |
@@ -496,12 +553,11 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts) | |||
496 | int i; | 553 | int i; |
497 | 554 | ||
498 | if (!mountTable) { | 555 | if (!mountTable) { |
499 | bb_error_msg("no %s", bb_path_mtab_file); | 556 | bb_perror_msg(bb_path_mtab_file); |
500 | goto ret; | 557 | goto ret; |
501 | } | 558 | } |
502 | 559 | ||
503 | // Add vfs string flags | 560 | // Add vfs string flags |
504 | |||
505 | for (i = 0; mount_options[i] != MS_REMOUNT; i++) { | 561 | for (i = 0; mount_options[i] != MS_REMOUNT; i++) { |
506 | if (mount_options[i] > 0 && (mount_options[i] & vfsflags)) | 562 | if (mount_options[i] > 0 && (mount_options[i] & vfsflags)) |
507 | append_mount_options(&(mp->mnt_opts), option_str); | 563 | append_mount_options(&(mp->mnt_opts), option_str); |
@@ -509,24 +565,28 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts) | |||
509 | } | 565 | } |
510 | 566 | ||
511 | // Remove trailing / (if any) from directory we mounted on | 567 | // Remove trailing / (if any) from directory we mounted on |
512 | |||
513 | i = strlen(mp->mnt_dir) - 1; | 568 | i = strlen(mp->mnt_dir) - 1; |
514 | if (i > 0 && mp->mnt_dir[i] == '/') mp->mnt_dir[i] = '\0'; | 569 | while (i > 0 && mp->mnt_dir[i] == '/') |
570 | mp->mnt_dir[i--] = '\0'; | ||
515 | 571 | ||
516 | // Convert to canonical pathnames as needed | 572 | // Convert to canonical pathnames as needed |
517 | |||
518 | mp->mnt_dir = bb_simplify_path(mp->mnt_dir); | 573 | mp->mnt_dir = bb_simplify_path(mp->mnt_dir); |
519 | fsname = 0; | 574 | fsname = NULL; |
520 | if (!mp->mnt_type || !*mp->mnt_type) { // bind mount | 575 | if (!mp->mnt_type || !*mp->mnt_type) { // bind mount |
521 | mp->mnt_fsname = fsname = bb_simplify_path(mp->mnt_fsname); | 576 | mp->mnt_fsname = fsname = bb_simplify_path(mp->mnt_fsname); |
522 | mp->mnt_type = (char*)"bind"; | 577 | mp->mnt_type = (char*)"bind"; |
523 | } | 578 | } |
524 | mp->mnt_freq = mp->mnt_passno = 0; | 579 | mp->mnt_freq = mp->mnt_passno = 0; |
525 | 580 | ||
526 | // Write and close. | 581 | // Write and close |
527 | 582 | #if ENABLE_FEATURE_MTAB_SUPPORT | |
528 | addmntent(mountTable, mp); | 583 | if (vfsflags & MS_MOVE) |
584 | update_mtab_entry_on_move(mp); | ||
585 | else | ||
586 | #endif | ||
587 | addmntent(mountTable, mp); | ||
529 | endmntent(mountTable); | 588 | endmntent(mountTable); |
589 | |||
530 | if (ENABLE_FEATURE_CLEAN_UP) { | 590 | if (ENABLE_FEATURE_CLEAN_UP) { |
531 | free(mp->mnt_dir); | 591 | free(mp->mnt_dir); |
532 | free(fsname); | 592 | free(fsname); |
diff --git a/util-linux/script.c b/util-linux/script.c index b9317fc7c..47efc4526 100644 --- a/util-linux/script.c +++ b/util-linux/script.c | |||
@@ -65,10 +65,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
65 | if (!(opt & OPT_q)) { | 65 | if (!(opt & OPT_q)) { |
66 | printf("Script started, file is %s\n", fname); | 66 | printf("Script started, file is %s\n", fname); |
67 | } | 67 | } |
68 | shell = getenv("SHELL"); | 68 | shell = get_shell_name(); |
69 | if (shell == NULL) { | ||
70 | shell = DEFAULT_SHELL; | ||
71 | } | ||
72 | 69 | ||
73 | pty = xgetpty(pty_line); | 70 | pty = xgetpty(pty_line); |
74 | 71 | ||