diff options
author | Ron Yorston <rmy@pobox.com> | 2016-04-04 16:22:54 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2016-04-04 16:22:54 +0100 |
commit | 253dbd612b2d2f041f4263e15a3b94df70f41e36 (patch) | |
tree | f6c6e12a0541233058a7f7ccb1251afeb457da06 | |
parent | 3cf56a021d7a62512b477640e930e1a78288075c (diff) | |
parent | d7d4750e1e213e7448147186dddfe3bfbb47eea0 (diff) | |
download | busybox-w32-253dbd612b2d2f041f4263e15a3b94df70f41e36.tar.gz busybox-w32-253dbd612b2d2f041f4263e15a3b94df70f41e36.tar.bz2 busybox-w32-253dbd612b2d2f041f4263e15a3b94df70f41e36.zip |
Merge branch 'busybox' into merge
85 files changed, 2897 insertions, 641 deletions
diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 92bf1e447..843f2ec08 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c | |||
@@ -41,8 +41,6 @@ struct bb_applet { | |||
41 | 41 | ||
42 | enum { NUM_APPLETS = ARRAY_SIZE(applets) }; | 42 | enum { NUM_APPLETS = ARRAY_SIZE(applets) }; |
43 | 43 | ||
44 | static int offset[NUM_APPLETS]; | ||
45 | |||
46 | static int cmp_name(const void *a, const void *b) | 44 | static int cmp_name(const void *a, const void *b) |
47 | { | 45 | { |
48 | const struct bb_applet *aa = a; | 46 | const struct bb_applet *aa = a; |
@@ -62,24 +60,30 @@ static int str_isalnum_(const char *s) | |||
62 | 60 | ||
63 | int main(int argc, char **argv) | 61 | int main(int argc, char **argv) |
64 | { | 62 | { |
65 | int i; | 63 | int i, j; |
66 | int ofs; | 64 | |
67 | // unsigned MAX_APPLET_NAME_LEN = 1; | 65 | // In find_applet_by_name(), before linear search, narrow it down |
66 | // by looking at N "equidistant" names. With ~350 applets: | ||
67 | // KNOWN_APPNAME_OFFSETS cycles | ||
68 | // 0 9057 | ||
69 | // 2 4604 + ~100 bytes of code | ||
70 | // 4 2407 + 4 bytes | ||
71 | // 8 1342 + 8 bytes | ||
72 | // 16 908 + 16 bytes | ||
73 | // 32 884 + 32 bytes | ||
74 | // With 8, int16_t applet_nameofs[] table has 7 elements. | ||
75 | int KNOWN_APPNAME_OFFSETS = 8; | ||
76 | // With 128 applets we do two linear searches, with 1..7 strcmp's in the first one | ||
77 | // and 1..16 strcmp's in the second. With 256 apps, second search does 1..32 strcmp's. | ||
78 | if (NUM_APPLETS < 128) | ||
79 | KNOWN_APPNAME_OFFSETS = 4; | ||
80 | if (NUM_APPLETS < 32) | ||
81 | KNOWN_APPNAME_OFFSETS = 0; | ||
68 | 82 | ||
69 | qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); | 83 | qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); |
70 | 84 | ||
71 | ofs = 0; | ||
72 | for (i = 0; i < NUM_APPLETS; i++) { | ||
73 | offset[i] = ofs; | ||
74 | ofs += strlen(applets[i].name) + 1; | ||
75 | } | ||
76 | /* We reuse 4 high-order bits of offset array for other purposes, | ||
77 | * so if they are indeed needed, refuse to proceed */ | ||
78 | if (ofs > 0xfff) | ||
79 | return 1; | ||
80 | if (!argv[1]) | 85 | if (!argv[1]) |
81 | return 1; | 86 | return 1; |
82 | |||
83 | i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666); | 87 | i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666); |
84 | if (i < 0) | 88 | if (i < 0) |
85 | return 1; | 89 | return 1; |
@@ -94,7 +98,27 @@ int main(int argc, char **argv) | |||
94 | printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); | 98 | printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); |
95 | printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); | 99 | printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); |
96 | } | 100 | } |
97 | printf("\n"); | 101 | |
102 | printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS); | ||
103 | if (KNOWN_APPNAME_OFFSETS > 0) { | ||
104 | int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS]; | ||
105 | for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++) | ||
106 | index[i] = i * NUM_APPLETS / KNOWN_APPNAME_OFFSETS; | ||
107 | ofs = 0; | ||
108 | for (i = 0; i < NUM_APPLETS; i++) { | ||
109 | for (j = 0; j < KNOWN_APPNAME_OFFSETS; j++) | ||
110 | if (i == index[j]) | ||
111 | offset[j] = ofs; | ||
112 | ofs += strlen(applets[i].name) + 1; | ||
113 | } | ||
114 | /* If the list of names is too long refuse to proceed */ | ||
115 | if (ofs > 0xffff) | ||
116 | return 1; | ||
117 | printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); | ||
118 | for (i = 1; i < KNOWN_APPNAME_OFFSETS; i++) | ||
119 | printf("%d,\n", offset[i]); | ||
120 | printf("};\n\n"); | ||
121 | } | ||
98 | 122 | ||
99 | //printf("#ifndef SKIP_definitions\n"); | 123 | //printf("#ifndef SKIP_definitions\n"); |
100 | printf("const char applet_names[] ALIGN1 = \"\"\n"); | 124 | printf("const char applet_names[] ALIGN1 = \"\"\n"); |
@@ -119,20 +143,39 @@ int main(int argc, char **argv) | |||
119 | printf("};\n"); | 143 | printf("};\n"); |
120 | printf("#endif\n\n"); | 144 | printf("#endif\n\n"); |
121 | 145 | ||
122 | printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); | ||
123 | for (i = 0; i < NUM_APPLETS; i++) { | ||
124 | printf("0x%04x,\n", | ||
125 | offset[i] | ||
126 | #if ENABLE_FEATURE_PREFER_APPLETS | 146 | #if ENABLE_FEATURE_PREFER_APPLETS |
127 | + (applets[i].nofork << 12) | 147 | printf("const uint8_t applet_flags[] ALIGN1 = {\n"); |
128 | + (applets[i].noexec << 13) | 148 | i = 0; |
149 | while (i < NUM_APPLETS) { | ||
150 | int v = applets[i].nofork + (applets[i].noexec << 1); | ||
151 | if (++i < NUM_APPLETS) | ||
152 | v |= (applets[i].nofork + (applets[i].noexec << 1)) << 2; | ||
153 | if (++i < NUM_APPLETS) | ||
154 | v |= (applets[i].nofork + (applets[i].noexec << 1)) << 4; | ||
155 | if (++i < NUM_APPLETS) | ||
156 | v |= (applets[i].nofork + (applets[i].noexec << 1)) << 6; | ||
157 | printf("0x%02x,\n", v); | ||
158 | i++; | ||
159 | } | ||
160 | printf("};\n\n"); | ||
129 | #endif | 161 | #endif |
162 | |||
130 | #if ENABLE_FEATURE_SUID | 163 | #if ENABLE_FEATURE_SUID |
131 | + (applets[i].need_suid << 14) /* 2 bits */ | 164 | printf("const uint8_t applet_suid[] ALIGN1 = {\n"); |
132 | #endif | 165 | i = 0; |
133 | ); | 166 | while (i < NUM_APPLETS) { |
167 | int v = applets[i].need_suid; /* 2 bits */ | ||
168 | if (++i < NUM_APPLETS) | ||
169 | v |= applets[i].need_suid << 2; | ||
170 | if (++i < NUM_APPLETS) | ||
171 | v |= applets[i].need_suid << 4; | ||
172 | if (++i < NUM_APPLETS) | ||
173 | v |= applets[i].need_suid << 6; | ||
174 | printf("0x%02x,\n", v); | ||
175 | i++; | ||
134 | } | 176 | } |
135 | printf("};\n\n"); | 177 | printf("};\n\n"); |
178 | #endif | ||
136 | 179 | ||
137 | #if ENABLE_FEATURE_INSTALLER | 180 | #if ENABLE_FEATURE_INSTALLER |
138 | printf("const uint8_t applet_install_loc[] ALIGN1 = {\n"); | 181 | printf("const uint8_t applet_install_loc[] ALIGN1 = {\n"); |
diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 6f5317a0e..5d8769382 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c | |||
@@ -112,8 +112,7 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle) | |||
112 | bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size); | 112 | bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size); |
113 | close(p[1]); | 113 | close(p[1]); |
114 | 114 | ||
115 | if (safe_waitpid(pid, &status, 0) == -1) | 115 | status = wait_for_exitstatus(pid); |
116 | bb_perror_msg_and_die("waitpid"); | ||
117 | if (WIFEXITED(status) && WEXITSTATUS(status)) | 116 | if (WIFEXITED(status) && WEXITSTATUS(status)) |
118 | bb_error_msg_and_die("'%s' returned status %d", | 117 | bb_error_msg_and_die("'%s' returned status %d", |
119 | archive_handle->tar__to_command, WEXITSTATUS(status)); | 118 | archive_handle->tar__to_command, WEXITSTATUS(status)); |
diff --git a/configs/TEST_nommu_defconfig b/configs/TEST_nommu_defconfig index b45afd956..5f822e598 100644 --- a/configs/TEST_nommu_defconfig +++ b/configs/TEST_nommu_defconfig | |||
@@ -390,7 +390,7 @@ CONFIG_FEATURE_INIT_SCTTY=y | |||
390 | CONFIG_FEATURE_INIT_SYSLOG=y | 390 | CONFIG_FEATURE_INIT_SYSLOG=y |
391 | CONFIG_FEATURE_EXTRA_QUIET=y | 391 | CONFIG_FEATURE_EXTRA_QUIET=y |
392 | CONFIG_FEATURE_INIT_COREDUMPS=y | 392 | CONFIG_FEATURE_INIT_COREDUMPS=y |
393 | CONFIG_FEATURE_INITRD=y | 393 | CONFIG_LINUXRC=y |
394 | CONFIG_HALT=y | 394 | CONFIG_HALT=y |
395 | # CONFIG_FEATURE_CALL_TELINIT is not set | 395 | # CONFIG_FEATURE_CALL_TELINIT is not set |
396 | CONFIG_TELINIT_PATH="" | 396 | CONFIG_TELINIT_PATH="" |
diff --git a/configs/TEST_noprintf_defconfig b/configs/TEST_noprintf_defconfig index 809b60cd8..c56781e32 100644 --- a/configs/TEST_noprintf_defconfig +++ b/configs/TEST_noprintf_defconfig | |||
@@ -395,7 +395,7 @@ CONFIG_FEATURE_KILL_DELAY=0 | |||
395 | # CONFIG_FEATURE_INIT_SYSLOG is not set | 395 | # CONFIG_FEATURE_INIT_SYSLOG is not set |
396 | # CONFIG_FEATURE_EXTRA_QUIET is not set | 396 | # CONFIG_FEATURE_EXTRA_QUIET is not set |
397 | # CONFIG_FEATURE_INIT_COREDUMPS is not set | 397 | # CONFIG_FEATURE_INIT_COREDUMPS is not set |
398 | # CONFIG_FEATURE_INITRD is not set | 398 | # CONFIG_LINUXRC is not set |
399 | # CONFIG_HALT is not set | 399 | # CONFIG_HALT is not set |
400 | # CONFIG_FEATURE_CALL_TELINIT is not set | 400 | # CONFIG_FEATURE_CALL_TELINIT is not set |
401 | CONFIG_TELINIT_PATH="" | 401 | CONFIG_TELINIT_PATH="" |
diff --git a/configs/TEST_rh9_defconfig b/configs/TEST_rh9_defconfig index 565b826d0..28daa6273 100644 --- a/configs/TEST_rh9_defconfig +++ b/configs/TEST_rh9_defconfig | |||
@@ -407,7 +407,7 @@ CONFIG_FEATURE_INIT_SCTTY=y | |||
407 | CONFIG_FEATURE_INIT_SYSLOG=y | 407 | CONFIG_FEATURE_INIT_SYSLOG=y |
408 | CONFIG_FEATURE_EXTRA_QUIET=y | 408 | CONFIG_FEATURE_EXTRA_QUIET=y |
409 | CONFIG_FEATURE_INIT_COREDUMPS=y | 409 | CONFIG_FEATURE_INIT_COREDUMPS=y |
410 | CONFIG_FEATURE_INITRD=y | 410 | CONFIG_LINUXRC=y |
411 | CONFIG_HALT=y | 411 | CONFIG_HALT=y |
412 | # CONFIG_FEATURE_CALL_TELINIT is not set | 412 | # CONFIG_FEATURE_CALL_TELINIT is not set |
413 | CONFIG_TELINIT_PATH="" | 413 | CONFIG_TELINIT_PATH="" |
diff --git a/configs/android2_defconfig b/configs/android2_defconfig index 1095094fe..fbc0da091 100644 --- a/configs/android2_defconfig +++ b/configs/android2_defconfig | |||
@@ -425,7 +425,7 @@ CONFIG_FEATURE_INIT_SCTTY=y | |||
425 | CONFIG_FEATURE_INIT_SYSLOG=y | 425 | CONFIG_FEATURE_INIT_SYSLOG=y |
426 | CONFIG_FEATURE_EXTRA_QUIET=y | 426 | CONFIG_FEATURE_EXTRA_QUIET=y |
427 | CONFIG_FEATURE_INIT_COREDUMPS=y | 427 | CONFIG_FEATURE_INIT_COREDUMPS=y |
428 | CONFIG_FEATURE_INITRD=y | 428 | CONFIG_LINUXRC=y |
429 | CONFIG_INIT_TERMINAL_TYPE="linux" | 429 | CONFIG_INIT_TERMINAL_TYPE="linux" |
430 | CONFIG_MESG=y | 430 | CONFIG_MESG=y |
431 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y | 431 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y |
diff --git a/configs/android_502_defconfig b/configs/android_502_defconfig new file mode 100644 index 000000000..7ef1585fb --- /dev/null +++ b/configs/android_502_defconfig | |||
@@ -0,0 +1,1142 @@ | |||
1 | ## This config was successfully used to build busybox on | ||
2 | ## Samsung SM-T700 tablet | ||
3 | ## Android 5.0.2 | ||
4 | ## gcc/toolchain from https://termux.com/ | ||
5 | ## binutils 2.26.20160125 | ||
6 | ## gcc 4.9.3 | ||
7 | ## bionic ANDROID_API 21 | ||
8 | ## | ||
9 | ## Static build did not work (static libraries not installed?): | ||
10 | ## # CONFIG_STATIC is not set | ||
11 | ## syslog() requires an additional library: | ||
12 | ## CONFIG_EXTRA_LDLIBS="log" | ||
13 | ## Bionic's botched off_t: | ||
14 | ## # CONFIG_LFS is not set | ||
15 | ## | ||
16 | ## Incompatible password database API: | ||
17 | ## # CONFIG_FEATURE_SHADOWPASSWDS is not set | ||
18 | ## # CONFIG_USE_BB_PWD_GRP is not set | ||
19 | ## # CONFIG_USE_BB_SHADOW is not set | ||
20 | ## # CONFIG_ADDUSER is not set | ||
21 | ## # CONFIG_ADDGROUP is not set | ||
22 | ## # CONFIG_DELUSER is not set | ||
23 | ## # CONFIG_DELGROUP is not set | ||
24 | ## | ||
25 | ## No utmp/wtmp: | ||
26 | ## # CONFIG_FEATURE_UTMP is not set | ||
27 | ## # CONFIG_FEATURE_WTMP is not set | ||
28 | ## # CONFIG_WHO is not set | ||
29 | ## # CONFIG_LAST is not set | ||
30 | ## # CONFIG_USERS is not set | ||
31 | ## # CONFIG_WALL is not set | ||
32 | ## | ||
33 | ## Assorted header problems: | ||
34 | ## # CONFIG_HOSTID is not set | ||
35 | ## # CONFIG_FEATURE_SYNC_FANCY is not set - syncfs() | ||
36 | ## # CONFIG_FEATURE_TOUCH_NODEREF is not set - lutimes() | ||
37 | ## # CONFIG_LOGNAME is not set - getlogin_r() | ||
38 | ## # CONFIG_LOADFONT is not set | ||
39 | ## # CONFIG_SETFONT is not set | ||
40 | ## # CONFIG_MDEV is not set | ||
41 | ## # CONFIG_FSCK_MINIX is not set | ||
42 | ## # CONFIG_MKFS_MINIX is not set | ||
43 | ## # CONFIG_IPCRM is not set | ||
44 | ## # CONFIG_IPCS is not set | ||
45 | ## # CONFIG_SWAPONOFF is not set | ||
46 | ## # CONFIG_CONSPY is not set | ||
47 | ## # CONFIG_NANDWRITE is not set | ||
48 | ## # CONFIG_NANDDUMP is not set | ||
49 | ## # CONFIG_RFKILL is not set | ||
50 | ## # CONFIG_UBIATTACH is not set | ||
51 | ## # CONFIG_UBIDETACH is not set | ||
52 | ## # CONFIG_UBIMKVOL is not set | ||
53 | ## # CONFIG_UBIRMVOL is not set | ||
54 | ## # CONFIG_UBIRSVOL is not set | ||
55 | ## # CONFIG_UBIUPDATEVOL is not set | ||
56 | ## # CONFIG_FEATURE_EJECT_SCSI is not set - scsi headers | ||
57 | ## # CONFIG_ARP is not set | ||
58 | ## # CONFIG_ARPING is not set | ||
59 | ## # CONFIG_ETHER_WAKE is not set | ||
60 | ## # CONFIG_IFCONFIG is not set | ||
61 | ## # CONFIG_IFENSLAVE is not set | ||
62 | ## # CONFIG_NSLOOKUP is not set | ||
63 | ## # CONFIG_ROUTE is not set | ||
64 | ## # CONFIG_ZCIP is not set | ||
65 | ## # CONFIG_HUSH is not set - glob.h | ||
66 | ## # CONFIG_KLOGD is not set | ||
67 | ## # CONFIG_LOGGER is not set | ||
68 | ## # CONFIG_LOGREAD is not set | ||
69 | ## # CONFIG_SYSLOGD is not set | ||
70 | ##----------------------------------------------- | ||
71 | |||
72 | # | ||
73 | # Automatically generated make config: don't edit | ||
74 | # Busybox version: 1.25.0.git | ||
75 | # Mon Mar 14 20:43:42 2016 | ||
76 | # | ||
77 | CONFIG_HAVE_DOT_CONFIG=y | ||
78 | |||
79 | # | ||
80 | # Busybox Settings | ||
81 | # | ||
82 | |||
83 | # | ||
84 | # General Configuration | ||
85 | # | ||
86 | CONFIG_DESKTOP=y | ||
87 | # CONFIG_EXTRA_COMPAT is not set | ||
88 | CONFIG_INCLUDE_SUSv2=y | ||
89 | # CONFIG_USE_PORTABLE_CODE is not set | ||
90 | CONFIG_PLATFORM_LINUX=y | ||
91 | CONFIG_FEATURE_BUFFERS_USE_MALLOC=y | ||
92 | # CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set | ||
93 | # CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set | ||
94 | CONFIG_SHOW_USAGE=y | ||
95 | CONFIG_FEATURE_VERBOSE_USAGE=y | ||
96 | CONFIG_FEATURE_COMPRESS_USAGE=y | ||
97 | CONFIG_FEATURE_INSTALLER=y | ||
98 | # CONFIG_INSTALL_NO_USR is not set | ||
99 | # CONFIG_LOCALE_SUPPORT is not set | ||
100 | CONFIG_UNICODE_SUPPORT=y | ||
101 | # CONFIG_UNICODE_USING_LOCALE is not set | ||
102 | # CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set | ||
103 | CONFIG_SUBST_WCHAR=63 | ||
104 | CONFIG_LAST_SUPPORTED_WCHAR=767 | ||
105 | # CONFIG_UNICODE_COMBINING_WCHARS is not set | ||
106 | # CONFIG_UNICODE_WIDE_WCHARS is not set | ||
107 | # CONFIG_UNICODE_BIDI_SUPPORT is not set | ||
108 | # CONFIG_UNICODE_NEUTRAL_TABLE is not set | ||
109 | # CONFIG_UNICODE_PRESERVE_BROKEN is not set | ||
110 | # CONFIG_PAM is not set | ||
111 | CONFIG_FEATURE_USE_SENDFILE=y | ||
112 | CONFIG_LONG_OPTS=y | ||
113 | CONFIG_FEATURE_DEVPTS=y | ||
114 | # CONFIG_FEATURE_CLEAN_UP is not set | ||
115 | # CONFIG_FEATURE_UTMP is not set | ||
116 | # CONFIG_FEATURE_WTMP is not set | ||
117 | CONFIG_FEATURE_PIDFILE=y | ||
118 | CONFIG_PID_FILE_PATH="/var/run" | ||
119 | CONFIG_FEATURE_SUID=y | ||
120 | CONFIG_FEATURE_SUID_CONFIG=y | ||
121 | CONFIG_FEATURE_SUID_CONFIG_QUIET=y | ||
122 | # CONFIG_SELINUX is not set | ||
123 | # CONFIG_FEATURE_PREFER_APPLETS is not set | ||
124 | CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" | ||
125 | CONFIG_FEATURE_SYSLOG=y | ||
126 | # CONFIG_FEATURE_HAVE_RPC is not set | ||
127 | |||
128 | # | ||
129 | # Build Options | ||
130 | # | ||
131 | # CONFIG_STATIC is not set | ||
132 | # CONFIG_PIE is not set | ||
133 | # CONFIG_NOMMU is not set | ||
134 | # CONFIG_BUILD_LIBBUSYBOX is not set | ||
135 | # CONFIG_FEATURE_INDIVIDUAL is not set | ||
136 | # CONFIG_FEATURE_SHARED_BUSYBOX is not set | ||
137 | # CONFIG_LFS is not set | ||
138 | CONFIG_CROSS_COMPILER_PREFIX="" | ||
139 | CONFIG_SYSROOT="" | ||
140 | CONFIG_EXTRA_CFLAGS="" | ||
141 | CONFIG_EXTRA_LDFLAGS="" | ||
142 | CONFIG_EXTRA_LDLIBS="log" | ||
143 | |||
144 | # | ||
145 | # Debugging Options | ||
146 | # | ||
147 | # CONFIG_DEBUG is not set | ||
148 | # CONFIG_DEBUG_PESSIMIZE is not set | ||
149 | # CONFIG_DEBUG_SANITIZE is not set | ||
150 | # CONFIG_UNIT_TEST is not set | ||
151 | # CONFIG_WERROR is not set | ||
152 | CONFIG_NO_DEBUG_LIB=y | ||
153 | # CONFIG_DMALLOC is not set | ||
154 | # CONFIG_EFENCE is not set | ||
155 | |||
156 | # | ||
157 | # Installation Options ("make install" behavior) | ||
158 | # | ||
159 | CONFIG_INSTALL_APPLET_SYMLINKS=y | ||
160 | # CONFIG_INSTALL_APPLET_HARDLINKS is not set | ||
161 | # CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set | ||
162 | # CONFIG_INSTALL_APPLET_DONT is not set | ||
163 | # CONFIG_INSTALL_SH_APPLET_SYMLINK is not set | ||
164 | # CONFIG_INSTALL_SH_APPLET_HARDLINK is not set | ||
165 | # CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set | ||
166 | CONFIG_PREFIX="./_install" | ||
167 | |||
168 | # | ||
169 | # Busybox Library Tuning | ||
170 | # | ||
171 | CONFIG_FEATURE_RTMINMAX=y | ||
172 | CONFIG_PASSWORD_MINLEN=6 | ||
173 | CONFIG_MD5_SMALL=1 | ||
174 | CONFIG_SHA3_SMALL=1 | ||
175 | # CONFIG_FEATURE_FAST_TOP is not set | ||
176 | # CONFIG_FEATURE_ETC_NETWORKS is not set | ||
177 | CONFIG_FEATURE_USE_TERMIOS=y | ||
178 | CONFIG_FEATURE_EDITING=y | ||
179 | CONFIG_FEATURE_EDITING_MAX_LEN=1024 | ||
180 | # CONFIG_FEATURE_EDITING_VI is not set | ||
181 | CONFIG_FEATURE_EDITING_HISTORY=255 | ||
182 | CONFIG_FEATURE_EDITING_SAVEHISTORY=y | ||
183 | # CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set | ||
184 | CONFIG_FEATURE_REVERSE_SEARCH=y | ||
185 | CONFIG_FEATURE_TAB_COMPLETION=y | ||
186 | # CONFIG_FEATURE_USERNAME_COMPLETION is not set | ||
187 | CONFIG_FEATURE_EDITING_FANCY_PROMPT=y | ||
188 | # CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set | ||
189 | CONFIG_FEATURE_NON_POSIX_CP=y | ||
190 | # CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set | ||
191 | CONFIG_FEATURE_COPYBUF_KB=4 | ||
192 | CONFIG_FEATURE_SKIP_ROOTFS=y | ||
193 | CONFIG_MONOTONIC_SYSCALL=y | ||
194 | CONFIG_IOCTL_HEX2STR_ERROR=y | ||
195 | CONFIG_FEATURE_HWIB=y | ||
196 | |||
197 | # | ||
198 | # Applets | ||
199 | # | ||
200 | |||
201 | # | ||
202 | # Archival Utilities | ||
203 | # | ||
204 | CONFIG_FEATURE_SEAMLESS_XZ=y | ||
205 | CONFIG_FEATURE_SEAMLESS_LZMA=y | ||
206 | CONFIG_FEATURE_SEAMLESS_BZ2=y | ||
207 | CONFIG_FEATURE_SEAMLESS_GZ=y | ||
208 | # CONFIG_FEATURE_SEAMLESS_Z is not set | ||
209 | # CONFIG_AR is not set | ||
210 | # CONFIG_FEATURE_AR_LONG_FILENAMES is not set | ||
211 | # CONFIG_FEATURE_AR_CREATE is not set | ||
212 | # CONFIG_UNCOMPRESS is not set | ||
213 | CONFIG_GUNZIP=y | ||
214 | CONFIG_FEATURE_GUNZIP_LONG_OPTIONS=y | ||
215 | CONFIG_BUNZIP2=y | ||
216 | CONFIG_UNLZMA=y | ||
217 | # CONFIG_FEATURE_LZMA_FAST is not set | ||
218 | CONFIG_LZMA=y | ||
219 | CONFIG_UNXZ=y | ||
220 | CONFIG_XZ=y | ||
221 | CONFIG_BZIP2=y | ||
222 | CONFIG_CPIO=y | ||
223 | CONFIG_FEATURE_CPIO_O=y | ||
224 | CONFIG_FEATURE_CPIO_P=y | ||
225 | # CONFIG_DPKG is not set | ||
226 | # CONFIG_DPKG_DEB is not set | ||
227 | # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set | ||
228 | CONFIG_GZIP=y | ||
229 | CONFIG_FEATURE_GZIP_LONG_OPTIONS=y | ||
230 | CONFIG_GZIP_FAST=0 | ||
231 | # CONFIG_FEATURE_GZIP_LEVELS is not set | ||
232 | CONFIG_LZOP=y | ||
233 | # CONFIG_LZOP_COMPR_HIGH is not set | ||
234 | CONFIG_RPM=y | ||
235 | CONFIG_RPM2CPIO=y | ||
236 | CONFIG_TAR=y | ||
237 | CONFIG_FEATURE_TAR_CREATE=y | ||
238 | CONFIG_FEATURE_TAR_AUTODETECT=y | ||
239 | CONFIG_FEATURE_TAR_FROM=y | ||
240 | CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y | ||
241 | CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y | ||
242 | CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y | ||
243 | CONFIG_FEATURE_TAR_LONG_OPTIONS=y | ||
244 | CONFIG_FEATURE_TAR_TO_COMMAND=y | ||
245 | CONFIG_FEATURE_TAR_UNAME_GNAME=y | ||
246 | CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y | ||
247 | # CONFIG_FEATURE_TAR_SELINUX is not set | ||
248 | CONFIG_UNZIP=y | ||
249 | |||
250 | # | ||
251 | # Coreutils | ||
252 | # | ||
253 | CONFIG_BASENAME=y | ||
254 | CONFIG_CAT=y | ||
255 | CONFIG_DATE=y | ||
256 | CONFIG_FEATURE_DATE_ISOFMT=y | ||
257 | # CONFIG_FEATURE_DATE_NANO is not set | ||
258 | CONFIG_FEATURE_DATE_COMPAT=y | ||
259 | CONFIG_DD=y | ||
260 | CONFIG_FEATURE_DD_SIGNAL_HANDLING=y | ||
261 | CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y | ||
262 | CONFIG_FEATURE_DD_IBS_OBS=y | ||
263 | CONFIG_FEATURE_DD_STATUS=y | ||
264 | # CONFIG_HOSTID is not set | ||
265 | CONFIG_ID=y | ||
266 | CONFIG_GROUPS=y | ||
267 | CONFIG_SHUF=y | ||
268 | CONFIG_STAT=y | ||
269 | CONFIG_FEATURE_STAT_FORMAT=y | ||
270 | CONFIG_FEATURE_STAT_FILESYSTEM=y | ||
271 | CONFIG_SYNC=y | ||
272 | # CONFIG_FEATURE_SYNC_FANCY is not set | ||
273 | CONFIG_TEST=y | ||
274 | CONFIG_FEATURE_TEST_64=y | ||
275 | CONFIG_TOUCH=y | ||
276 | # CONFIG_FEATURE_TOUCH_NODEREF is not set | ||
277 | CONFIG_FEATURE_TOUCH_SUSV3=y | ||
278 | CONFIG_TR=y | ||
279 | CONFIG_FEATURE_TR_CLASSES=y | ||
280 | CONFIG_FEATURE_TR_EQUIV=y | ||
281 | CONFIG_TRUNCATE=y | ||
282 | CONFIG_UNLINK=y | ||
283 | CONFIG_BASE64=y | ||
284 | # CONFIG_WHO is not set | ||
285 | # CONFIG_USERS is not set | ||
286 | CONFIG_CAL=y | ||
287 | CONFIG_CATV=y | ||
288 | CONFIG_CHGRP=y | ||
289 | CONFIG_CHMOD=y | ||
290 | CONFIG_CHOWN=y | ||
291 | CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y | ||
292 | CONFIG_CHROOT=y | ||
293 | CONFIG_CKSUM=y | ||
294 | CONFIG_COMM=y | ||
295 | CONFIG_CP=y | ||
296 | CONFIG_FEATURE_CP_LONG_OPTIONS=y | ||
297 | CONFIG_CUT=y | ||
298 | CONFIG_DF=y | ||
299 | CONFIG_FEATURE_DF_FANCY=y | ||
300 | CONFIG_DIRNAME=y | ||
301 | CONFIG_DOS2UNIX=y | ||
302 | CONFIG_UNIX2DOS=y | ||
303 | CONFIG_DU=y | ||
304 | CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y | ||
305 | CONFIG_ECHO=y | ||
306 | CONFIG_FEATURE_FANCY_ECHO=y | ||
307 | CONFIG_ENV=y | ||
308 | CONFIG_FEATURE_ENV_LONG_OPTIONS=y | ||
309 | CONFIG_EXPAND=y | ||
310 | CONFIG_FEATURE_EXPAND_LONG_OPTIONS=y | ||
311 | CONFIG_EXPR=y | ||
312 | CONFIG_EXPR_MATH_SUPPORT_64=y | ||
313 | CONFIG_FALSE=y | ||
314 | CONFIG_FOLD=y | ||
315 | CONFIG_FSYNC=y | ||
316 | CONFIG_HEAD=y | ||
317 | CONFIG_FEATURE_FANCY_HEAD=y | ||
318 | CONFIG_INSTALL=y | ||
319 | CONFIG_FEATURE_INSTALL_LONG_OPTIONS=y | ||
320 | CONFIG_LN=y | ||
321 | # CONFIG_LOGNAME is not set | ||
322 | CONFIG_LS=y | ||
323 | CONFIG_FEATURE_LS_FILETYPES=y | ||
324 | CONFIG_FEATURE_LS_FOLLOWLINKS=y | ||
325 | CONFIG_FEATURE_LS_RECURSIVE=y | ||
326 | CONFIG_FEATURE_LS_SORTFILES=y | ||
327 | CONFIG_FEATURE_LS_TIMESTAMPS=y | ||
328 | CONFIG_FEATURE_LS_USERNAME=y | ||
329 | CONFIG_FEATURE_LS_COLOR=y | ||
330 | CONFIG_FEATURE_LS_COLOR_IS_DEFAULT=y | ||
331 | CONFIG_MD5SUM=y | ||
332 | CONFIG_MKDIR=y | ||
333 | CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y | ||
334 | CONFIG_MKFIFO=y | ||
335 | CONFIG_MKNOD=y | ||
336 | CONFIG_MV=y | ||
337 | CONFIG_FEATURE_MV_LONG_OPTIONS=y | ||
338 | CONFIG_NICE=y | ||
339 | CONFIG_NOHUP=y | ||
340 | CONFIG_OD=y | ||
341 | CONFIG_PRINTENV=y | ||
342 | CONFIG_PRINTF=y | ||
343 | CONFIG_PWD=y | ||
344 | CONFIG_READLINK=y | ||
345 | CONFIG_FEATURE_READLINK_FOLLOW=y | ||
346 | CONFIG_REALPATH=y | ||
347 | CONFIG_RM=y | ||
348 | CONFIG_RMDIR=y | ||
349 | CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y | ||
350 | CONFIG_SEQ=y | ||
351 | CONFIG_SHA1SUM=y | ||
352 | CONFIG_SHA256SUM=y | ||
353 | CONFIG_SHA512SUM=y | ||
354 | CONFIG_SHA3SUM=y | ||
355 | CONFIG_SLEEP=y | ||
356 | CONFIG_FEATURE_FANCY_SLEEP=y | ||
357 | CONFIG_FEATURE_FLOAT_SLEEP=y | ||
358 | CONFIG_SORT=y | ||
359 | CONFIG_FEATURE_SORT_BIG=y | ||
360 | CONFIG_SPLIT=y | ||
361 | CONFIG_FEATURE_SPLIT_FANCY=y | ||
362 | CONFIG_STTY=y | ||
363 | CONFIG_SUM=y | ||
364 | CONFIG_TAC=y | ||
365 | CONFIG_TAIL=y | ||
366 | CONFIG_FEATURE_FANCY_TAIL=y | ||
367 | CONFIG_TEE=y | ||
368 | CONFIG_FEATURE_TEE_USE_BLOCK_IO=y | ||
369 | CONFIG_TRUE=y | ||
370 | CONFIG_TTY=y | ||
371 | CONFIG_UNAME=y | ||
372 | CONFIG_UNAME_OSNAME="GNU/Linux" | ||
373 | CONFIG_UNEXPAND=y | ||
374 | CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS=y | ||
375 | CONFIG_UNIQ=y | ||
376 | CONFIG_USLEEP=y | ||
377 | CONFIG_UUDECODE=y | ||
378 | CONFIG_UUENCODE=y | ||
379 | CONFIG_WC=y | ||
380 | CONFIG_FEATURE_WC_LARGE=y | ||
381 | CONFIG_WHOAMI=y | ||
382 | CONFIG_YES=y | ||
383 | |||
384 | # | ||
385 | # Common options | ||
386 | # | ||
387 | CONFIG_FEATURE_VERBOSE=y | ||
388 | |||
389 | # | ||
390 | # Common options for cp and mv | ||
391 | # | ||
392 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | ||
393 | |||
394 | # | ||
395 | # Common options for ls, more and telnet | ||
396 | # | ||
397 | CONFIG_FEATURE_AUTOWIDTH=y | ||
398 | |||
399 | # | ||
400 | # Common options for df, du, ls | ||
401 | # | ||
402 | CONFIG_FEATURE_HUMAN_READABLE=y | ||
403 | |||
404 | # | ||
405 | # Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum | ||
406 | # | ||
407 | CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y | ||
408 | |||
409 | # | ||
410 | # Console Utilities | ||
411 | # | ||
412 | CONFIG_CHVT=y | ||
413 | CONFIG_FGCONSOLE=y | ||
414 | CONFIG_CLEAR=y | ||
415 | CONFIG_DEALLOCVT=y | ||
416 | CONFIG_DUMPKMAP=y | ||
417 | CONFIG_KBD_MODE=y | ||
418 | # CONFIG_LOADFONT is not set | ||
419 | CONFIG_LOADKMAP=y | ||
420 | CONFIG_OPENVT=y | ||
421 | CONFIG_RESET=y | ||
422 | CONFIG_RESIZE=y | ||
423 | CONFIG_FEATURE_RESIZE_PRINT=y | ||
424 | CONFIG_SETCONSOLE=y | ||
425 | CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS=y | ||
426 | # CONFIG_SETFONT is not set | ||
427 | # CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set | ||
428 | CONFIG_DEFAULT_SETFONT_DIR="" | ||
429 | CONFIG_SETKEYCODES=y | ||
430 | CONFIG_SETLOGCONS=y | ||
431 | CONFIG_SHOWKEY=y | ||
432 | # CONFIG_FEATURE_LOADFONT_PSF2 is not set | ||
433 | # CONFIG_FEATURE_LOADFONT_RAW is not set | ||
434 | |||
435 | # | ||
436 | # Debian Utilities | ||
437 | # | ||
438 | CONFIG_MKTEMP=y | ||
439 | CONFIG_PIPE_PROGRESS=y | ||
440 | CONFIG_RUN_PARTS=y | ||
441 | CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS=y | ||
442 | CONFIG_FEATURE_RUN_PARTS_FANCY=y | ||
443 | CONFIG_START_STOP_DAEMON=y | ||
444 | CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y | ||
445 | CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y | ||
446 | CONFIG_WHICH=y | ||
447 | |||
448 | # | ||
449 | # Editors | ||
450 | # | ||
451 | CONFIG_AWK=y | ||
452 | CONFIG_FEATURE_AWK_LIBM=y | ||
453 | CONFIG_FEATURE_AWK_GNU_EXTENSIONS=y | ||
454 | CONFIG_CMP=y | ||
455 | CONFIG_DIFF=y | ||
456 | CONFIG_FEATURE_DIFF_LONG_OPTIONS=y | ||
457 | CONFIG_FEATURE_DIFF_DIR=y | ||
458 | CONFIG_ED=y | ||
459 | CONFIG_PATCH=y | ||
460 | CONFIG_SED=y | ||
461 | CONFIG_VI=y | ||
462 | CONFIG_FEATURE_VI_MAX_LEN=4096 | ||
463 | # CONFIG_FEATURE_VI_8BIT is not set | ||
464 | CONFIG_FEATURE_VI_COLON=y | ||
465 | CONFIG_FEATURE_VI_YANKMARK=y | ||
466 | CONFIG_FEATURE_VI_SEARCH=y | ||
467 | # CONFIG_FEATURE_VI_REGEX_SEARCH is not set | ||
468 | CONFIG_FEATURE_VI_USE_SIGNALS=y | ||
469 | CONFIG_FEATURE_VI_DOT_CMD=y | ||
470 | CONFIG_FEATURE_VI_READONLY=y | ||
471 | CONFIG_FEATURE_VI_SETOPTS=y | ||
472 | CONFIG_FEATURE_VI_SET=y | ||
473 | CONFIG_FEATURE_VI_WIN_RESIZE=y | ||
474 | CONFIG_FEATURE_VI_ASK_TERMINAL=y | ||
475 | CONFIG_FEATURE_VI_UNDO=y | ||
476 | CONFIG_FEATURE_VI_UNDO_QUEUE=y | ||
477 | CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 | ||
478 | CONFIG_FEATURE_ALLOW_EXEC=y | ||
479 | |||
480 | # | ||
481 | # Finding Utilities | ||
482 | # | ||
483 | CONFIG_FIND=y | ||
484 | CONFIG_FEATURE_FIND_PRINT0=y | ||
485 | CONFIG_FEATURE_FIND_MTIME=y | ||
486 | CONFIG_FEATURE_FIND_MMIN=y | ||
487 | CONFIG_FEATURE_FIND_PERM=y | ||
488 | CONFIG_FEATURE_FIND_TYPE=y | ||
489 | CONFIG_FEATURE_FIND_XDEV=y | ||
490 | CONFIG_FEATURE_FIND_MAXDEPTH=y | ||
491 | CONFIG_FEATURE_FIND_NEWER=y | ||
492 | CONFIG_FEATURE_FIND_INUM=y | ||
493 | CONFIG_FEATURE_FIND_EXEC=y | ||
494 | CONFIG_FEATURE_FIND_EXEC_PLUS=y | ||
495 | CONFIG_FEATURE_FIND_USER=y | ||
496 | CONFIG_FEATURE_FIND_GROUP=y | ||
497 | CONFIG_FEATURE_FIND_NOT=y | ||
498 | CONFIG_FEATURE_FIND_DEPTH=y | ||
499 | CONFIG_FEATURE_FIND_PAREN=y | ||
500 | CONFIG_FEATURE_FIND_SIZE=y | ||
501 | CONFIG_FEATURE_FIND_PRUNE=y | ||
502 | CONFIG_FEATURE_FIND_DELETE=y | ||
503 | CONFIG_FEATURE_FIND_PATH=y | ||
504 | CONFIG_FEATURE_FIND_REGEX=y | ||
505 | # CONFIG_FEATURE_FIND_CONTEXT is not set | ||
506 | CONFIG_FEATURE_FIND_LINKS=y | ||
507 | CONFIG_GREP=y | ||
508 | CONFIG_FEATURE_GREP_EGREP_ALIAS=y | ||
509 | CONFIG_FEATURE_GREP_FGREP_ALIAS=y | ||
510 | CONFIG_FEATURE_GREP_CONTEXT=y | ||
511 | CONFIG_XARGS=y | ||
512 | CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y | ||
513 | CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y | ||
514 | CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y | ||
515 | CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y | ||
516 | CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y | ||
517 | |||
518 | # | ||
519 | # Init Utilities | ||
520 | # | ||
521 | CONFIG_BOOTCHARTD=y | ||
522 | CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER=y | ||
523 | CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE=y | ||
524 | CONFIG_HALT=y | ||
525 | # CONFIG_FEATURE_CALL_TELINIT is not set | ||
526 | CONFIG_TELINIT_PATH="" | ||
527 | CONFIG_INIT=y | ||
528 | CONFIG_FEATURE_USE_INITTAB=y | ||
529 | # CONFIG_FEATURE_KILL_REMOVED is not set | ||
530 | CONFIG_FEATURE_KILL_DELAY=0 | ||
531 | CONFIG_FEATURE_INIT_SCTTY=y | ||
532 | CONFIG_FEATURE_INIT_SYSLOG=y | ||
533 | CONFIG_FEATURE_EXTRA_QUIET=y | ||
534 | CONFIG_FEATURE_INIT_COREDUMPS=y | ||
535 | CONFIG_LINUXRC=y | ||
536 | CONFIG_INIT_TERMINAL_TYPE="linux" | ||
537 | CONFIG_FEATURE_INIT_MODIFY_CMDLINE=y | ||
538 | CONFIG_MESG=y | ||
539 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y | ||
540 | |||
541 | # | ||
542 | # Login/Password Management Utilities | ||
543 | # | ||
544 | # CONFIG_FEATURE_SHADOWPASSWDS is not set | ||
545 | # CONFIG_USE_BB_PWD_GRP is not set | ||
546 | # CONFIG_USE_BB_SHADOW is not set | ||
547 | CONFIG_USE_BB_CRYPT=y | ||
548 | CONFIG_USE_BB_CRYPT_SHA=y | ||
549 | CONFIG_ADD_SHELL=y | ||
550 | CONFIG_REMOVE_SHELL=y | ||
551 | # CONFIG_ADDGROUP is not set | ||
552 | # CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set | ||
553 | # CONFIG_FEATURE_ADDUSER_TO_GROUP is not set | ||
554 | # CONFIG_ADDUSER is not set | ||
555 | # CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set | ||
556 | # CONFIG_FEATURE_CHECK_NAMES is not set | ||
557 | CONFIG_LAST_ID=0 | ||
558 | CONFIG_FIRST_SYSTEM_ID=0 | ||
559 | CONFIG_LAST_SYSTEM_ID=0 | ||
560 | CONFIG_CHPASSWD=y | ||
561 | CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="des" | ||
562 | CONFIG_CRYPTPW=y | ||
563 | # CONFIG_DELUSER is not set | ||
564 | # CONFIG_DELGROUP is not set | ||
565 | # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set | ||
566 | CONFIG_GETTY=y | ||
567 | CONFIG_LOGIN=y | ||
568 | # CONFIG_LOGIN_SESSION_AS_CHILD is not set | ||
569 | CONFIG_LOGIN_SCRIPTS=y | ||
570 | CONFIG_FEATURE_NOLOGIN=y | ||
571 | CONFIG_FEATURE_SECURETTY=y | ||
572 | CONFIG_PASSWD=y | ||
573 | CONFIG_FEATURE_PASSWD_WEAK_CHECK=y | ||
574 | CONFIG_SU=y | ||
575 | CONFIG_FEATURE_SU_SYSLOG=y | ||
576 | CONFIG_FEATURE_SU_CHECKS_SHELLS=y | ||
577 | CONFIG_SULOGIN=y | ||
578 | CONFIG_VLOCK=y | ||
579 | |||
580 | # | ||
581 | # Linux Ext2 FS Progs | ||
582 | # | ||
583 | CONFIG_CHATTR=y | ||
584 | CONFIG_FSCK=y | ||
585 | CONFIG_LSATTR=y | ||
586 | # CONFIG_TUNE2FS is not set | ||
587 | |||
588 | # | ||
589 | # Linux Module Utilities | ||
590 | # | ||
591 | CONFIG_MODINFO=y | ||
592 | CONFIG_MODPROBE_SMALL=y | ||
593 | CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE=y | ||
594 | CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y | ||
595 | # CONFIG_INSMOD is not set | ||
596 | # CONFIG_RMMOD is not set | ||
597 | # CONFIG_LSMOD is not set | ||
598 | # CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set | ||
599 | # CONFIG_MODPROBE is not set | ||
600 | # CONFIG_FEATURE_MODPROBE_BLACKLIST is not set | ||
601 | # CONFIG_DEPMOD is not set | ||
602 | |||
603 | # | ||
604 | # Options common to multiple modutils | ||
605 | # | ||
606 | # CONFIG_FEATURE_2_4_MODULES is not set | ||
607 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set | ||
608 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set | ||
609 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set | ||
610 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set | ||
611 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set | ||
612 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set | ||
613 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set | ||
614 | # CONFIG_FEATURE_MODUTILS_ALIAS is not set | ||
615 | # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set | ||
616 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" | ||
617 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | ||
618 | |||
619 | # | ||
620 | # Linux System Utilities | ||
621 | # | ||
622 | CONFIG_BLKDISCARD=y | ||
623 | CONFIG_BLOCKDEV=y | ||
624 | CONFIG_FATATTR=y | ||
625 | CONFIG_FSTRIM=y | ||
626 | # CONFIG_MDEV is not set | ||
627 | # CONFIG_FEATURE_MDEV_CONF is not set | ||
628 | # CONFIG_FEATURE_MDEV_RENAME is not set | ||
629 | # CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set | ||
630 | # CONFIG_FEATURE_MDEV_EXEC is not set | ||
631 | # CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set | ||
632 | CONFIG_MOUNT=y | ||
633 | CONFIG_FEATURE_MOUNT_FAKE=y | ||
634 | CONFIG_FEATURE_MOUNT_VERBOSE=y | ||
635 | # CONFIG_FEATURE_MOUNT_HELPERS is not set | ||
636 | CONFIG_FEATURE_MOUNT_LABEL=y | ||
637 | # CONFIG_FEATURE_MOUNT_NFS is not set | ||
638 | CONFIG_FEATURE_MOUNT_CIFS=y | ||
639 | CONFIG_FEATURE_MOUNT_FLAGS=y | ||
640 | CONFIG_FEATURE_MOUNT_FSTAB=y | ||
641 | CONFIG_FEATURE_MOUNT_OTHERTAB=y | ||
642 | CONFIG_REV=y | ||
643 | CONFIG_SETARCH=y | ||
644 | CONFIG_UEVENT=y | ||
645 | CONFIG_ACPID=y | ||
646 | CONFIG_FEATURE_ACPID_COMPAT=y | ||
647 | CONFIG_BLKID=y | ||
648 | # CONFIG_FEATURE_BLKID_TYPE is not set | ||
649 | CONFIG_DMESG=y | ||
650 | CONFIG_FEATURE_DMESG_PRETTY=y | ||
651 | CONFIG_FBSET=y | ||
652 | CONFIG_FEATURE_FBSET_FANCY=y | ||
653 | CONFIG_FEATURE_FBSET_READMODE=y | ||
654 | CONFIG_FDFLUSH=y | ||
655 | CONFIG_FDFORMAT=y | ||
656 | CONFIG_FDISK=y | ||
657 | CONFIG_FDISK_SUPPORT_LARGE_DISKS=y | ||
658 | CONFIG_FEATURE_FDISK_WRITABLE=y | ||
659 | # CONFIG_FEATURE_AIX_LABEL is not set | ||
660 | # CONFIG_FEATURE_SGI_LABEL is not set | ||
661 | # CONFIG_FEATURE_SUN_LABEL is not set | ||
662 | # CONFIG_FEATURE_OSF_LABEL is not set | ||
663 | # CONFIG_FEATURE_GPT_LABEL is not set | ||
664 | CONFIG_FEATURE_FDISK_ADVANCED=y | ||
665 | CONFIG_FINDFS=y | ||
666 | CONFIG_FLOCK=y | ||
667 | CONFIG_FREERAMDISK=y | ||
668 | # CONFIG_FSCK_MINIX is not set | ||
669 | CONFIG_MKFS_EXT2=y | ||
670 | # CONFIG_MKFS_MINIX is not set | ||
671 | # CONFIG_FEATURE_MINIX2 is not set | ||
672 | # CONFIG_MKFS_REISER is not set | ||
673 | CONFIG_MKFS_VFAT=y | ||
674 | CONFIG_GETOPT=y | ||
675 | CONFIG_FEATURE_GETOPT_LONG=y | ||
676 | CONFIG_HEXDUMP=y | ||
677 | CONFIG_FEATURE_HEXDUMP_REVERSE=y | ||
678 | CONFIG_HD=y | ||
679 | CONFIG_HWCLOCK=y | ||
680 | CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS=y | ||
681 | # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set | ||
682 | # CONFIG_IPCRM is not set | ||
683 | # CONFIG_IPCS is not set | ||
684 | CONFIG_LOSETUP=y | ||
685 | CONFIG_LSPCI=y | ||
686 | CONFIG_LSUSB=y | ||
687 | CONFIG_MKSWAP=y | ||
688 | CONFIG_FEATURE_MKSWAP_UUID=y | ||
689 | CONFIG_MORE=y | ||
690 | CONFIG_PIVOT_ROOT=y | ||
691 | CONFIG_RDATE=y | ||
692 | CONFIG_RDEV=y | ||
693 | CONFIG_READPROFILE=y | ||
694 | CONFIG_RTCWAKE=y | ||
695 | CONFIG_SCRIPT=y | ||
696 | CONFIG_SCRIPTREPLAY=y | ||
697 | # CONFIG_SWAPONOFF is not set | ||
698 | # CONFIG_FEATURE_SWAPON_DISCARD is not set | ||
699 | # CONFIG_FEATURE_SWAPON_PRI is not set | ||
700 | CONFIG_SWITCH_ROOT=y | ||
701 | CONFIG_UMOUNT=y | ||
702 | CONFIG_FEATURE_UMOUNT_ALL=y | ||
703 | |||
704 | # | ||
705 | # Common options for mount/umount | ||
706 | # | ||
707 | CONFIG_FEATURE_MOUNT_LOOP=y | ||
708 | CONFIG_FEATURE_MOUNT_LOOP_CREATE=y | ||
709 | # CONFIG_FEATURE_MTAB_SUPPORT is not set | ||
710 | CONFIG_VOLUMEID=y | ||
711 | |||
712 | # | ||
713 | # Filesystem/Volume identification | ||
714 | # | ||
715 | CONFIG_FEATURE_VOLUMEID_BCACHE=y | ||
716 | CONFIG_FEATURE_VOLUMEID_BTRFS=y | ||
717 | CONFIG_FEATURE_VOLUMEID_CRAMFS=y | ||
718 | CONFIG_FEATURE_VOLUMEID_EXFAT=y | ||
719 | CONFIG_FEATURE_VOLUMEID_EXT=y | ||
720 | CONFIG_FEATURE_VOLUMEID_F2FS=y | ||
721 | CONFIG_FEATURE_VOLUMEID_FAT=y | ||
722 | CONFIG_FEATURE_VOLUMEID_HFS=y | ||
723 | CONFIG_FEATURE_VOLUMEID_ISO9660=y | ||
724 | CONFIG_FEATURE_VOLUMEID_JFS=y | ||
725 | CONFIG_FEATURE_VOLUMEID_LINUXRAID=y | ||
726 | CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y | ||
727 | CONFIG_FEATURE_VOLUMEID_LUKS=y | ||
728 | CONFIG_FEATURE_VOLUMEID_NILFS=y | ||
729 | CONFIG_FEATURE_VOLUMEID_NTFS=y | ||
730 | CONFIG_FEATURE_VOLUMEID_OCFS2=y | ||
731 | CONFIG_FEATURE_VOLUMEID_REISERFS=y | ||
732 | CONFIG_FEATURE_VOLUMEID_ROMFS=y | ||
733 | # CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set | ||
734 | CONFIG_FEATURE_VOLUMEID_SYSV=y | ||
735 | CONFIG_FEATURE_VOLUMEID_UDF=y | ||
736 | CONFIG_FEATURE_VOLUMEID_XFS=y | ||
737 | |||
738 | # | ||
739 | # Miscellaneous Utilities | ||
740 | # | ||
741 | # CONFIG_CONSPY is not set | ||
742 | CONFIG_CROND=y | ||
743 | CONFIG_FEATURE_CROND_D=y | ||
744 | CONFIG_FEATURE_CROND_CALL_SENDMAIL=y | ||
745 | CONFIG_FEATURE_CROND_DIR="/var/spool/cron" | ||
746 | CONFIG_I2CGET=y | ||
747 | CONFIG_I2CSET=y | ||
748 | CONFIG_I2CDUMP=y | ||
749 | CONFIG_I2CDETECT=y | ||
750 | CONFIG_LESS=y | ||
751 | CONFIG_FEATURE_LESS_MAXLINES=9999999 | ||
752 | CONFIG_FEATURE_LESS_BRACKETS=y | ||
753 | CONFIG_FEATURE_LESS_FLAGS=y | ||
754 | CONFIG_FEATURE_LESS_TRUNCATE=y | ||
755 | CONFIG_FEATURE_LESS_MARKS=y | ||
756 | CONFIG_FEATURE_LESS_REGEXP=y | ||
757 | CONFIG_FEATURE_LESS_WINCH=y | ||
758 | CONFIG_FEATURE_LESS_ASK_TERMINAL=y | ||
759 | CONFIG_FEATURE_LESS_DASHCMD=y | ||
760 | CONFIG_FEATURE_LESS_LINENUMS=y | ||
761 | # CONFIG_NANDWRITE is not set | ||
762 | # CONFIG_NANDDUMP is not set | ||
763 | # CONFIG_RFKILL is not set | ||
764 | CONFIG_SETSERIAL=y | ||
765 | CONFIG_TASKSET=y | ||
766 | CONFIG_FEATURE_TASKSET_FANCY=y | ||
767 | # CONFIG_UBIATTACH is not set | ||
768 | # CONFIG_UBIDETACH is not set | ||
769 | # CONFIG_UBIMKVOL is not set | ||
770 | # CONFIG_UBIRMVOL is not set | ||
771 | # CONFIG_UBIRSVOL is not set | ||
772 | # CONFIG_UBIUPDATEVOL is not set | ||
773 | # CONFIG_WALL is not set | ||
774 | CONFIG_ADJTIMEX=y | ||
775 | # CONFIG_BBCONFIG is not set | ||
776 | # CONFIG_FEATURE_COMPRESS_BBCONFIG is not set | ||
777 | CONFIG_BEEP=y | ||
778 | CONFIG_FEATURE_BEEP_FREQ=4000 | ||
779 | CONFIG_FEATURE_BEEP_LENGTH_MS=30 | ||
780 | CONFIG_CHAT=y | ||
781 | CONFIG_FEATURE_CHAT_NOFAIL=y | ||
782 | # CONFIG_FEATURE_CHAT_TTY_HIFI is not set | ||
783 | CONFIG_FEATURE_CHAT_IMPLICIT_CR=y | ||
784 | CONFIG_FEATURE_CHAT_SWALLOW_OPTS=y | ||
785 | CONFIG_FEATURE_CHAT_SEND_ESCAPES=y | ||
786 | CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y | ||
787 | CONFIG_FEATURE_CHAT_CLR_ABORT=y | ||
788 | CONFIG_CHRT=y | ||
789 | CONFIG_CRONTAB=y | ||
790 | CONFIG_DC=y | ||
791 | CONFIG_FEATURE_DC_LIBM=y | ||
792 | # CONFIG_DEVFSD is not set | ||
793 | # CONFIG_DEVFSD_MODLOAD is not set | ||
794 | # CONFIG_DEVFSD_FG_NP is not set | ||
795 | # CONFIG_DEVFSD_VERBOSE is not set | ||
796 | # CONFIG_FEATURE_DEVFS is not set | ||
797 | CONFIG_DEVMEM=y | ||
798 | CONFIG_EJECT=y | ||
799 | # CONFIG_FEATURE_EJECT_SCSI is not set | ||
800 | CONFIG_FBSPLASH=y | ||
801 | # CONFIG_FLASHCP is not set | ||
802 | # CONFIG_FLASH_LOCK is not set | ||
803 | # CONFIG_FLASH_UNLOCK is not set | ||
804 | # CONFIG_FLASH_ERASEALL is not set | ||
805 | CONFIG_IONICE=y | ||
806 | # CONFIG_INOTIFYD is not set | ||
807 | # CONFIG_LAST is not set | ||
808 | # CONFIG_FEATURE_LAST_FANCY is not set | ||
809 | CONFIG_HDPARM=y | ||
810 | CONFIG_FEATURE_HDPARM_GET_IDENTITY=y | ||
811 | CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y | ||
812 | CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF=y | ||
813 | CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET=y | ||
814 | CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF=y | ||
815 | CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA=y | ||
816 | CONFIG_MAKEDEVS=y | ||
817 | # CONFIG_FEATURE_MAKEDEVS_LEAF is not set | ||
818 | CONFIG_FEATURE_MAKEDEVS_TABLE=y | ||
819 | CONFIG_MAN=y | ||
820 | CONFIG_MICROCOM=y | ||
821 | CONFIG_MOUNTPOINT=y | ||
822 | # CONFIG_MT is not set | ||
823 | CONFIG_RAIDAUTORUN=y | ||
824 | # CONFIG_READAHEAD is not set | ||
825 | # CONFIG_RUNLEVEL is not set | ||
826 | CONFIG_RX=y | ||
827 | CONFIG_SETSID=y | ||
828 | CONFIG_STRINGS=y | ||
829 | CONFIG_TIME=y | ||
830 | CONFIG_TIMEOUT=y | ||
831 | CONFIG_TTYSIZE=y | ||
832 | CONFIG_VOLNAME=y | ||
833 | CONFIG_WATCHDOG=y | ||
834 | |||
835 | # | ||
836 | # Networking Utilities | ||
837 | # | ||
838 | CONFIG_NAMEIF=y | ||
839 | CONFIG_FEATURE_NAMEIF_EXTENDED=y | ||
840 | CONFIG_NBDCLIENT=y | ||
841 | CONFIG_NC=y | ||
842 | CONFIG_NC_SERVER=y | ||
843 | CONFIG_NC_EXTRA=y | ||
844 | # CONFIG_NC_110_COMPAT is not set | ||
845 | CONFIG_PING=y | ||
846 | CONFIG_PING6=y | ||
847 | CONFIG_FEATURE_FANCY_PING=y | ||
848 | CONFIG_WGET=y | ||
849 | CONFIG_FEATURE_WGET_STATUSBAR=y | ||
850 | CONFIG_FEATURE_WGET_AUTHENTICATION=y | ||
851 | CONFIG_FEATURE_WGET_LONG_OPTIONS=y | ||
852 | CONFIG_FEATURE_WGET_TIMEOUT=y | ||
853 | CONFIG_FEATURE_WGET_OPENSSL=y | ||
854 | CONFIG_FEATURE_WGET_SSL_HELPER=y | ||
855 | CONFIG_WHOIS=y | ||
856 | CONFIG_FEATURE_IPV6=y | ||
857 | # CONFIG_FEATURE_UNIX_LOCAL is not set | ||
858 | CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y | ||
859 | # CONFIG_VERBOSE_RESOLUTION_ERRORS is not set | ||
860 | # CONFIG_ARP is not set | ||
861 | # CONFIG_ARPING is not set | ||
862 | CONFIG_BRCTL=y | ||
863 | CONFIG_FEATURE_BRCTL_FANCY=y | ||
864 | CONFIG_FEATURE_BRCTL_SHOW=y | ||
865 | CONFIG_DNSD=y | ||
866 | # CONFIG_ETHER_WAKE is not set | ||
867 | CONFIG_FAKEIDENTD=y | ||
868 | CONFIG_FTPD=y | ||
869 | CONFIG_FEATURE_FTP_WRITE=y | ||
870 | CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y | ||
871 | CONFIG_FEATURE_FTP_AUTHENTICATION=y | ||
872 | CONFIG_FTPGET=y | ||
873 | CONFIG_FTPPUT=y | ||
874 | CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS=y | ||
875 | CONFIG_HOSTNAME=y | ||
876 | CONFIG_HTTPD=y | ||
877 | CONFIG_FEATURE_HTTPD_RANGES=y | ||
878 | CONFIG_FEATURE_HTTPD_SETUID=y | ||
879 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y | ||
880 | CONFIG_FEATURE_HTTPD_AUTH_MD5=y | ||
881 | CONFIG_FEATURE_HTTPD_CGI=y | ||
882 | CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y | ||
883 | CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y | ||
884 | CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y | ||
885 | CONFIG_FEATURE_HTTPD_ERROR_PAGES=y | ||
886 | CONFIG_FEATURE_HTTPD_PROXY=y | ||
887 | CONFIG_FEATURE_HTTPD_GZIP=y | ||
888 | # CONFIG_IFCONFIG is not set | ||
889 | # CONFIG_FEATURE_IFCONFIG_STATUS is not set | ||
890 | # CONFIG_FEATURE_IFCONFIG_SLIP is not set | ||
891 | # CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set | ||
892 | # CONFIG_FEATURE_IFCONFIG_HW is not set | ||
893 | # CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set | ||
894 | # CONFIG_IFENSLAVE is not set | ||
895 | CONFIG_IFPLUGD=y | ||
896 | CONFIG_IFUPDOWN=y | ||
897 | CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate" | ||
898 | CONFIG_FEATURE_IFUPDOWN_IP=y | ||
899 | CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y | ||
900 | # CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set | ||
901 | CONFIG_FEATURE_IFUPDOWN_IPV4=y | ||
902 | CONFIG_FEATURE_IFUPDOWN_IPV6=y | ||
903 | CONFIG_FEATURE_IFUPDOWN_MAPPING=y | ||
904 | # CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set | ||
905 | CONFIG_INETD=y | ||
906 | CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO=y | ||
907 | CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD=y | ||
908 | CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME=y | ||
909 | CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME=y | ||
910 | CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN=y | ||
911 | # CONFIG_FEATURE_INETD_RPC is not set | ||
912 | CONFIG_IP=y | ||
913 | CONFIG_FEATURE_IP_ADDRESS=y | ||
914 | CONFIG_FEATURE_IP_LINK=y | ||
915 | CONFIG_FEATURE_IP_ROUTE=y | ||
916 | CONFIG_FEATURE_IP_ROUTE_DIR="/etc/iproute2" | ||
917 | CONFIG_FEATURE_IP_TUNNEL=y | ||
918 | CONFIG_FEATURE_IP_RULE=y | ||
919 | CONFIG_FEATURE_IP_NEIGH=y | ||
920 | CONFIG_FEATURE_IP_SHORT_FORMS=y | ||
921 | # CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set | ||
922 | CONFIG_IPADDR=y | ||
923 | CONFIG_IPLINK=y | ||
924 | CONFIG_IPROUTE=y | ||
925 | CONFIG_IPTUNNEL=y | ||
926 | CONFIG_IPRULE=y | ||
927 | CONFIG_IPNEIGH=y | ||
928 | CONFIG_IPCALC=y | ||
929 | CONFIG_FEATURE_IPCALC_FANCY=y | ||
930 | CONFIG_FEATURE_IPCALC_LONG_OPTIONS=y | ||
931 | CONFIG_NETSTAT=y | ||
932 | CONFIG_FEATURE_NETSTAT_WIDE=y | ||
933 | CONFIG_FEATURE_NETSTAT_PRG=y | ||
934 | # CONFIG_NSLOOKUP is not set | ||
935 | CONFIG_NTPD=y | ||
936 | CONFIG_FEATURE_NTPD_SERVER=y | ||
937 | CONFIG_FEATURE_NTPD_CONF=y | ||
938 | CONFIG_PSCAN=y | ||
939 | # CONFIG_ROUTE is not set | ||
940 | CONFIG_SLATTACH=y | ||
941 | CONFIG_TCPSVD=y | ||
942 | CONFIG_TELNET=y | ||
943 | CONFIG_FEATURE_TELNET_TTYPE=y | ||
944 | CONFIG_FEATURE_TELNET_AUTOLOGIN=y | ||
945 | CONFIG_TELNETD=y | ||
946 | CONFIG_FEATURE_TELNETD_STANDALONE=y | ||
947 | CONFIG_FEATURE_TELNETD_INETD_WAIT=y | ||
948 | CONFIG_TFTP=y | ||
949 | CONFIG_TFTPD=y | ||
950 | |||
951 | # | ||
952 | # Common options for tftp/tftpd | ||
953 | # | ||
954 | CONFIG_FEATURE_TFTP_GET=y | ||
955 | CONFIG_FEATURE_TFTP_PUT=y | ||
956 | CONFIG_FEATURE_TFTP_BLOCKSIZE=y | ||
957 | CONFIG_FEATURE_TFTP_PROGRESS_BAR=y | ||
958 | # CONFIG_TFTP_DEBUG is not set | ||
959 | CONFIG_TRACEROUTE=y | ||
960 | CONFIG_TRACEROUTE6=y | ||
961 | CONFIG_FEATURE_TRACEROUTE_VERBOSE=y | ||
962 | # CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set | ||
963 | # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set | ||
964 | CONFIG_TUNCTL=y | ||
965 | CONFIG_FEATURE_TUNCTL_UG=y | ||
966 | # CONFIG_UDHCPC6 is not set | ||
967 | CONFIG_UDHCPD=y | ||
968 | CONFIG_DHCPRELAY=y | ||
969 | CONFIG_DUMPLEASES=y | ||
970 | CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY=y | ||
971 | # CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set | ||
972 | CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases" | ||
973 | CONFIG_UDHCPC=y | ||
974 | CONFIG_FEATURE_UDHCPC_ARPING=y | ||
975 | CONFIG_FEATURE_UDHCPC_SANITIZEOPT=y | ||
976 | # CONFIG_FEATURE_UDHCP_PORT is not set | ||
977 | CONFIG_UDHCP_DEBUG=9 | ||
978 | CONFIG_FEATURE_UDHCP_RFC3397=y | ||
979 | CONFIG_FEATURE_UDHCP_8021Q=y | ||
980 | CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" | ||
981 | CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 | ||
982 | CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n" | ||
983 | CONFIG_UDPSVD=y | ||
984 | CONFIG_VCONFIG=y | ||
985 | # CONFIG_ZCIP is not set | ||
986 | |||
987 | # | ||
988 | # Print Utilities | ||
989 | # | ||
990 | CONFIG_LPD=y | ||
991 | CONFIG_LPR=y | ||
992 | CONFIG_LPQ=y | ||
993 | |||
994 | # | ||
995 | # Mail Utilities | ||
996 | # | ||
997 | CONFIG_MAKEMIME=y | ||
998 | CONFIG_FEATURE_MIME_CHARSET="us-ascii" | ||
999 | CONFIG_POPMAILDIR=y | ||
1000 | CONFIG_FEATURE_POPMAILDIR_DELIVERY=y | ||
1001 | CONFIG_REFORMIME=y | ||
1002 | CONFIG_FEATURE_REFORMIME_COMPAT=y | ||
1003 | CONFIG_SENDMAIL=y | ||
1004 | |||
1005 | # | ||
1006 | # Process Utilities | ||
1007 | # | ||
1008 | CONFIG_IOSTAT=y | ||
1009 | CONFIG_LSOF=y | ||
1010 | CONFIG_MPSTAT=y | ||
1011 | CONFIG_NMETER=y | ||
1012 | CONFIG_PMAP=y | ||
1013 | CONFIG_POWERTOP=y | ||
1014 | CONFIG_PSTREE=y | ||
1015 | CONFIG_PWDX=y | ||
1016 | CONFIG_SMEMCAP=y | ||
1017 | CONFIG_TOP=y | ||
1018 | CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y | ||
1019 | CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y | ||
1020 | CONFIG_FEATURE_TOP_SMP_CPU=y | ||
1021 | CONFIG_FEATURE_TOP_DECIMALS=y | ||
1022 | CONFIG_FEATURE_TOP_SMP_PROCESS=y | ||
1023 | CONFIG_FEATURE_TOPMEM=y | ||
1024 | CONFIG_UPTIME=y | ||
1025 | # CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set | ||
1026 | CONFIG_FREE=y | ||
1027 | CONFIG_FUSER=y | ||
1028 | CONFIG_KILL=y | ||
1029 | CONFIG_KILLALL=y | ||
1030 | CONFIG_KILLALL5=y | ||
1031 | CONFIG_PGREP=y | ||
1032 | CONFIG_PIDOF=y | ||
1033 | CONFIG_FEATURE_PIDOF_SINGLE=y | ||
1034 | CONFIG_FEATURE_PIDOF_OMIT=y | ||
1035 | CONFIG_PKILL=y | ||
1036 | CONFIG_PS=y | ||
1037 | # CONFIG_FEATURE_PS_WIDE is not set | ||
1038 | # CONFIG_FEATURE_PS_LONG is not set | ||
1039 | CONFIG_FEATURE_PS_TIME=y | ||
1040 | CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y | ||
1041 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set | ||
1042 | CONFIG_RENICE=y | ||
1043 | CONFIG_BB_SYSCTL=y | ||
1044 | CONFIG_FEATURE_SHOW_THREADS=y | ||
1045 | CONFIG_WATCH=y | ||
1046 | |||
1047 | # | ||
1048 | # Runit Utilities | ||
1049 | # | ||
1050 | CONFIG_CHPST=y | ||
1051 | CONFIG_SETUIDGID=y | ||
1052 | CONFIG_ENVUIDGID=y | ||
1053 | CONFIG_ENVDIR=y | ||
1054 | CONFIG_SOFTLIMIT=y | ||
1055 | CONFIG_RUNSV=y | ||
1056 | CONFIG_RUNSVDIR=y | ||
1057 | # CONFIG_FEATURE_RUNSVDIR_LOG is not set | ||
1058 | CONFIG_SV=y | ||
1059 | CONFIG_SV_DEFAULT_SERVICE_DIR="/var/service" | ||
1060 | CONFIG_SVLOGD=y | ||
1061 | # CONFIG_CHCON is not set | ||
1062 | # CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set | ||
1063 | # CONFIG_GETENFORCE is not set | ||
1064 | # CONFIG_GETSEBOOL is not set | ||
1065 | # CONFIG_LOAD_POLICY is not set | ||
1066 | # CONFIG_MATCHPATHCON is not set | ||
1067 | # CONFIG_RESTORECON is not set | ||
1068 | # CONFIG_RUNCON is not set | ||
1069 | # CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set | ||
1070 | # CONFIG_SELINUXENABLED is not set | ||
1071 | # CONFIG_SETENFORCE is not set | ||
1072 | # CONFIG_SETFILES is not set | ||
1073 | # CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set | ||
1074 | # CONFIG_SETSEBOOL is not set | ||
1075 | # CONFIG_SESTATUS is not set | ||
1076 | |||
1077 | # | ||
1078 | # Shells | ||
1079 | # | ||
1080 | CONFIG_ASH=y | ||
1081 | CONFIG_ASH_BASH_COMPAT=y | ||
1082 | # CONFIG_ASH_IDLE_TIMEOUT is not set | ||
1083 | CONFIG_ASH_JOB_CONTROL=y | ||
1084 | CONFIG_ASH_ALIAS=y | ||
1085 | CONFIG_ASH_GETOPTS=y | ||
1086 | CONFIG_ASH_BUILTIN_ECHO=y | ||
1087 | CONFIG_ASH_BUILTIN_PRINTF=y | ||
1088 | CONFIG_ASH_BUILTIN_TEST=y | ||
1089 | CONFIG_ASH_HELP=y | ||
1090 | CONFIG_ASH_CMDCMD=y | ||
1091 | # CONFIG_ASH_MAIL is not set | ||
1092 | CONFIG_ASH_OPTIMIZE_FOR_SIZE=y | ||
1093 | CONFIG_ASH_RANDOM_SUPPORT=y | ||
1094 | CONFIG_ASH_EXPAND_PRMT=y | ||
1095 | CONFIG_CTTYHACK=y | ||
1096 | # CONFIG_HUSH is not set | ||
1097 | # CONFIG_HUSH_BASH_COMPAT is not set | ||
1098 | # CONFIG_HUSH_BRACE_EXPANSION is not set | ||
1099 | # CONFIG_HUSH_HELP is not set | ||
1100 | # CONFIG_HUSH_INTERACTIVE is not set | ||
1101 | # CONFIG_HUSH_SAVEHISTORY is not set | ||
1102 | # CONFIG_HUSH_JOB is not set | ||
1103 | # CONFIG_HUSH_TICK is not set | ||
1104 | # CONFIG_HUSH_IF is not set | ||
1105 | # CONFIG_HUSH_LOOPS is not set | ||
1106 | # CONFIG_HUSH_CASE is not set | ||
1107 | # CONFIG_HUSH_FUNCTIONS is not set | ||
1108 | # CONFIG_HUSH_LOCAL is not set | ||
1109 | # CONFIG_HUSH_RANDOM_SUPPORT is not set | ||
1110 | # CONFIG_HUSH_EXPORT_N is not set | ||
1111 | # CONFIG_HUSH_MODE_X is not set | ||
1112 | # CONFIG_MSH is not set | ||
1113 | CONFIG_FEATURE_SH_IS_ASH=y | ||
1114 | # CONFIG_FEATURE_SH_IS_HUSH is not set | ||
1115 | # CONFIG_FEATURE_SH_IS_NONE is not set | ||
1116 | # CONFIG_FEATURE_BASH_IS_ASH is not set | ||
1117 | # CONFIG_FEATURE_BASH_IS_HUSH is not set | ||
1118 | CONFIG_FEATURE_BASH_IS_NONE=y | ||
1119 | CONFIG_SH_MATH_SUPPORT=y | ||
1120 | CONFIG_SH_MATH_SUPPORT_64=y | ||
1121 | CONFIG_FEATURE_SH_EXTRA_QUIET=y | ||
1122 | # CONFIG_FEATURE_SH_STANDALONE is not set | ||
1123 | # CONFIG_FEATURE_SH_NOFORK is not set | ||
1124 | CONFIG_FEATURE_SH_HISTFILESIZE=y | ||
1125 | |||
1126 | # | ||
1127 | # System Logging Utilities | ||
1128 | # | ||
1129 | # CONFIG_KLOGD is not set | ||
1130 | # CONFIG_FEATURE_KLOGD_KLOGCTL is not set | ||
1131 | # CONFIG_LOGGER is not set | ||
1132 | # CONFIG_LOGREAD is not set | ||
1133 | # CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set | ||
1134 | # CONFIG_SYSLOGD is not set | ||
1135 | # CONFIG_FEATURE_ROTATE_LOGFILE is not set | ||
1136 | # CONFIG_FEATURE_REMOTE_LOG is not set | ||
1137 | # CONFIG_FEATURE_SYSLOGD_DUP is not set | ||
1138 | # CONFIG_FEATURE_SYSLOGD_CFG is not set | ||
1139 | CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 | ||
1140 | # CONFIG_FEATURE_IPC_SYSLOG is not set | ||
1141 | CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 | ||
1142 | # CONFIG_FEATURE_KMSG_SYSLOG is not set | ||
diff --git a/configs/android_defconfig b/configs/android_defconfig index 082994b6c..4e0224207 100644 --- a/configs/android_defconfig +++ b/configs/android_defconfig | |||
@@ -448,7 +448,7 @@ CONFIG_FEATURE_INIT_SCTTY=y | |||
448 | CONFIG_FEATURE_INIT_SYSLOG=y | 448 | CONFIG_FEATURE_INIT_SYSLOG=y |
449 | CONFIG_FEATURE_EXTRA_QUIET=y | 449 | CONFIG_FEATURE_EXTRA_QUIET=y |
450 | CONFIG_FEATURE_INIT_COREDUMPS=y | 450 | CONFIG_FEATURE_INIT_COREDUMPS=y |
451 | CONFIG_FEATURE_INITRD=y | 451 | CONFIG_LINUXRC=y |
452 | CONFIG_INIT_TERMINAL_TYPE="linux" | 452 | CONFIG_INIT_TERMINAL_TYPE="linux" |
453 | CONFIG_MESG=y | 453 | CONFIG_MESG=y |
454 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y | 454 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y |
diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig index 63fafb468..d657d33e9 100644 --- a/configs/android_ndk_defconfig +++ b/configs/android_ndk_defconfig | |||
@@ -458,7 +458,7 @@ CONFIG_FEATURE_INIT_SCTTY=y | |||
458 | CONFIG_FEATURE_INIT_SYSLOG=y | 458 | CONFIG_FEATURE_INIT_SYSLOG=y |
459 | CONFIG_FEATURE_EXTRA_QUIET=y | 459 | CONFIG_FEATURE_EXTRA_QUIET=y |
460 | CONFIG_FEATURE_INIT_COREDUMPS=y | 460 | CONFIG_FEATURE_INIT_COREDUMPS=y |
461 | CONFIG_FEATURE_INITRD=y | 461 | CONFIG_LINUXRC=y |
462 | CONFIG_INIT_TERMINAL_TYPE="linux" | 462 | CONFIG_INIT_TERMINAL_TYPE="linux" |
463 | CONFIG_MESG=y | 463 | CONFIG_MESG=y |
464 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y | 464 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y |
diff --git a/configs/cygwin_defconfig b/configs/cygwin_defconfig index 2c02be743..38d580ad1 100644 --- a/configs/cygwin_defconfig +++ b/configs/cygwin_defconfig | |||
@@ -425,7 +425,7 @@ CONFIG_FEATURE_KILL_DELAY=0 | |||
425 | # CONFIG_FEATURE_INIT_SYSLOG is not set | 425 | # CONFIG_FEATURE_INIT_SYSLOG is not set |
426 | # CONFIG_FEATURE_EXTRA_QUIET is not set | 426 | # CONFIG_FEATURE_EXTRA_QUIET is not set |
427 | # CONFIG_FEATURE_INIT_COREDUMPS is not set | 427 | # CONFIG_FEATURE_INIT_COREDUMPS is not set |
428 | # CONFIG_FEATURE_INITRD is not set | 428 | # CONFIG_LINUXRC is not set |
429 | CONFIG_INIT_TERMINAL_TYPE="" | 429 | CONFIG_INIT_TERMINAL_TYPE="" |
430 | CONFIG_MESG=y | 430 | CONFIG_MESG=y |
431 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y | 431 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y |
diff --git a/configs/freebsd_defconfig b/configs/freebsd_defconfig index ec3ed03c4..ae62f1389 100644 --- a/configs/freebsd_defconfig +++ b/configs/freebsd_defconfig | |||
@@ -422,7 +422,7 @@ CONFIG_FEATURE_KILL_DELAY=0 | |||
422 | # CONFIG_FEATURE_INIT_SYSLOG is not set | 422 | # CONFIG_FEATURE_INIT_SYSLOG is not set |
423 | # CONFIG_FEATURE_EXTRA_QUIET is not set | 423 | # CONFIG_FEATURE_EXTRA_QUIET is not set |
424 | # CONFIG_FEATURE_INIT_COREDUMPS is not set | 424 | # CONFIG_FEATURE_INIT_COREDUMPS is not set |
425 | # CONFIG_FEATURE_INITRD is not set | 425 | # CONFIG_LINUXRC is not set |
426 | CONFIG_INIT_TERMINAL_TYPE="" | 426 | CONFIG_INIT_TERMINAL_TYPE="" |
427 | # CONFIG_MESG is not set | 427 | # CONFIG_MESG is not set |
428 | 428 | ||
diff --git a/coreutils/ls.c b/coreutils/ls.c index c48498858..20bd61860 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -668,7 +668,7 @@ static void display_files(struct dnode **dn, unsigned nfiles) | |||
668 | if (column_width < len) | 668 | if (column_width < len) |
669 | column_width = len; | 669 | column_width = len; |
670 | } | 670 | } |
671 | column_width += 1 + | 671 | column_width += 2 + |
672 | IF_SELINUX( ((G.all_fmt & LIST_CONTEXT) ? 33 : 0) + ) | 672 | IF_SELINUX( ((G.all_fmt & LIST_CONTEXT) ? 33 : 0) + ) |
673 | ((G.all_fmt & LIST_INO) ? 8 : 0) + | 673 | ((G.all_fmt & LIST_INO) ? 8 : 0) + |
674 | ((G.all_fmt & LIST_BLOCKS) ? 5 : 0); | 674 | ((G.all_fmt & LIST_BLOCKS) ? 5 : 0); |
@@ -696,8 +696,8 @@ static void display_files(struct dnode **dn, unsigned nfiles) | |||
696 | if (i < nfiles) { | 696 | if (i < nfiles) { |
697 | if (column > 0) { | 697 | if (column > 0) { |
698 | nexttab -= column; | 698 | nexttab -= column; |
699 | printf("%*s ", nexttab, ""); | 699 | printf("%*s", nexttab, ""); |
700 | column += nexttab + 1; | 700 | column += nexttab; |
701 | } | 701 | } |
702 | nexttab = column + column_width; | 702 | nexttab = column + column_width; |
703 | column += display_single(dn[i]); | 703 | column += display_single(dn[i]); |
diff --git a/coreutils/sort.c b/coreutils/sort.c index 07d903388..9139d9f47 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c | |||
@@ -14,23 +14,23 @@ | |||
14 | 14 | ||
15 | //usage:#define sort_trivial_usage | 15 | //usage:#define sort_trivial_usage |
16 | //usage: "[-nru" | 16 | //usage: "[-nru" |
17 | //usage: IF_FEATURE_SORT_BIG("gMcszbdfimSTokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR") | 17 | //usage: IF_FEATURE_SORT_BIG("gMcszbdfiokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR") |
18 | //usage: "] [FILE]..." | 18 | //usage: "] [FILE]..." |
19 | //usage:#define sort_full_usage "\n\n" | 19 | //usage:#define sort_full_usage "\n\n" |
20 | //usage: "Sort lines of text\n" | 20 | //usage: "Sort lines of text\n" |
21 | //usage: IF_FEATURE_SORT_BIG( | 21 | //usage: IF_FEATURE_SORT_BIG( |
22 | //usage: "\n -b Ignore leading blanks" | 22 | //usage: "\n -o FILE Output to FILE" |
23 | //usage: "\n -c Check whether input is sorted" | 23 | //usage: "\n -c Check whether input is sorted" |
24 | //usage: "\n -d Dictionary order (blank or alphanumeric only)" | 24 | //usage: "\n -b Ignore leading blanks" |
25 | //usage: "\n -f Ignore case" | 25 | //usage: "\n -f Ignore case" |
26 | //usage: "\n -g General numerical sort" | ||
27 | //usage: "\n -i Ignore unprintable characters" | 26 | //usage: "\n -i Ignore unprintable characters" |
27 | //usage: "\n -d Dictionary order (blank or alphanumeric only)" | ||
28 | //usage: "\n -g General numerical sort" | ||
28 | //usage: "\n -M Sort month" | 29 | //usage: "\n -M Sort month" |
29 | //usage: ) | 30 | //usage: ) |
30 | //-h, --human-numeric-sort: compare human readable numbers (e.g., 2K 1G) | 31 | //-h, --human-numeric-sort: compare human readable numbers (e.g., 2K 1G) |
31 | //usage: "\n -n Sort numbers" | 32 | //usage: "\n -n Sort numbers" |
32 | //usage: IF_FEATURE_SORT_BIG( | 33 | //usage: IF_FEATURE_SORT_BIG( |
33 | //usage: "\n -o Output to file" | ||
34 | //usage: "\n -t CHAR Field separator" | 34 | //usage: "\n -t CHAR Field separator" |
35 | //usage: "\n -k N[,M] Sort by Nth field" | 35 | //usage: "\n -k N[,M] Sort by Nth field" |
36 | //usage: ) | 36 | //usage: ) |
@@ -41,7 +41,10 @@ | |||
41 | //usage: "\n -u Suppress duplicate lines" | 41 | //usage: "\n -u Suppress duplicate lines" |
42 | //usage: IF_FEATURE_SORT_BIG( | 42 | //usage: IF_FEATURE_SORT_BIG( |
43 | //usage: "\n -z Lines are terminated by NUL, not newline" | 43 | //usage: "\n -z Lines are terminated by NUL, not newline" |
44 | //usage: "\n -mST Ignored for GNU compatibility") | 44 | ////usage: "\n -m Ignored for GNU compatibility" |
45 | ////usage: "\n -S BUFSZ Ignored for GNU compatibility" | ||
46 | ////usage: "\n -T TMPDIR Ignored for GNU compatibility" | ||
47 | //usage: ) | ||
45 | //usage: | 48 | //usage: |
46 | //usage:#define sort_example_usage | 49 | //usage:#define sort_example_usage |
47 | //usage: "$ echo -e \"e\\nf\\nb\\nd\\nc\\na\" | sort\n" | 50 | //usage: "$ echo -e \"e\\nf\\nb\\nd\\nc\\na\" | sort\n" |
diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index 627d2be31..987d97528 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c | |||
@@ -345,7 +345,7 @@ static void load_fs_info(const char *filename) | |||
345 | 345 | ||
346 | // Loop through entries | 346 | // Loop through entries |
347 | while (getmntent_r(fstab, &mte, buf, sizeof(buf))) { | 347 | while (getmntent_r(fstab, &mte, buf, sizeof(buf))) { |
348 | //bb_info_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir, | 348 | //bb_error_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir, |
349 | // mte.mnt_type, mte.mnt_opts, | 349 | // mte.mnt_type, mte.mnt_opts, |
350 | // mte.mnt_passno); | 350 | // mte.mnt_passno); |
351 | create_fs_device(mte.mnt_fsname, mte.mnt_dir, | 351 | create_fs_device(mte.mnt_fsname, mte.mnt_dir, |
@@ -602,7 +602,7 @@ static void fsck_device(struct fs_info *fs /*, int interactive */) | |||
602 | if (strcmp(fs->type, "auto") != 0) { | 602 | if (strcmp(fs->type, "auto") != 0) { |
603 | type = fs->type; | 603 | type = fs->type; |
604 | if (G.verbose > 2) | 604 | if (G.verbose > 2) |
605 | bb_info_msg("using filesystem type '%s' %s", | 605 | printf("using filesystem type '%s' %s\n", |
606 | type, "from fstab"); | 606 | type, "from fstab"); |
607 | } else if (G.fstype | 607 | } else if (G.fstype |
608 | && (G.fstype[0] != 'n' || G.fstype[1] != 'o') /* != "no" */ | 608 | && (G.fstype[0] != 'n' || G.fstype[1] != 'o') /* != "no" */ |
@@ -612,12 +612,12 @@ static void fsck_device(struct fs_info *fs /*, int interactive */) | |||
612 | ) { | 612 | ) { |
613 | type = G.fstype; | 613 | type = G.fstype; |
614 | if (G.verbose > 2) | 614 | if (G.verbose > 2) |
615 | bb_info_msg("using filesystem type '%s' %s", | 615 | printf("using filesystem type '%s' %s\n", |
616 | type, "from -t"); | 616 | type, "from -t"); |
617 | } else { | 617 | } else { |
618 | type = "auto"; | 618 | type = "auto"; |
619 | if (G.verbose > 2) | 619 | if (G.verbose > 2) |
620 | bb_info_msg("using filesystem type '%s' %s", | 620 | printf("using filesystem type '%s' %s\n", |
621 | type, "(default)"); | 621 | type, "(default)"); |
622 | } | 622 | } |
623 | 623 | ||
diff --git a/examples/undeb b/examples/undeb index 37104e9d8..c30baf31b 100755 --- a/examples/undeb +++ b/examples/undeb | |||
@@ -5,49 +5,55 @@ | |||
5 | # Requires the programs (ar, tar, gzip, and the pager more or less). | 5 | # Requires the programs (ar, tar, gzip, and the pager more or less). |
6 | # | 6 | # |
7 | usage() { | 7 | usage() { |
8 | echo "Usage: undeb -c package.deb <Print control file info>" | 8 | cat <<EOF |
9 | echo " undeb -l package.deb <List contents of deb package>" | 9 | Usage: undeb -c package.deb <Print control file info> |
10 | echo " undeb -x package.deb /foo/boo <Extract deb package to this directory," | 10 | undeb -l package.deb <List contents of deb package> |
11 | echo " put . for current directory>" | 11 | undeb -x package.deb /foo/boo <Extract deb package to this directory, |
12 | exit | 12 | put . for current directory> |
13 | EOF | ||
14 | exit | ||
13 | } | 15 | } |
14 | 16 | ||
15 | deb=$2 | 17 | deb=$2 |
16 | 18 | ||
17 | exist() { | 19 | exist() { |
18 | if [ "$deb" = "" ]; then | 20 | if [ -z "${deb}" ]; then |
19 | usage | 21 | usage |
20 | elif [ ! -s "$deb" ]; then | 22 | elif [ ! -s "${deb}" ]; then |
21 | echo "Can't find $deb!" | 23 | echo "Can't find ${deb}!" |
22 | exit | 24 | exit 1 |
23 | fi | 25 | fi |
24 | } | 26 | } |
25 | 27 | ||
26 | if [ "$1" = "" ]; then | 28 | if [ -z "$1" ]; then |
27 | usage | 29 | usage |
28 | elif [ "$1" = "-l" ]; then | 30 | elif [ "$1" = "-l" ]; then |
29 | exist | 31 | exist |
30 | type more >/dev/null 2>&1 && pager=more | 32 | type more >/dev/null 2>&1 && pager=more |
31 | type less >/dev/null 2>&1 && pager=less | 33 | type less >/dev/null 2>&1 && pager=less |
32 | [ "$pager" = "" ] && echo "No pager found!" && exit | 34 | [ -z "${pager}" ] && echo "No pager found!" && exit 1 |
33 | (ar -p $deb control.tar.gz | tar -xzO *control ; echo -e "\nPress enter to scroll, q to Quit!\n" ; ar -p $deb data.tar.gz | tar -tzv) | $pager | 35 | ( |
34 | exit | 36 | ar -p "${deb}" control.tar.gz | tar -xzO *control |
37 | printf "\nPress enter to scroll, q to Quit!\n\n" | ||
38 | ar -p "${deb}" data.tar.gz | tar -tzv | ||
39 | ) | ${pager} | ||
40 | exit | ||
35 | elif [ "$1" = "-c" ]; then | 41 | elif [ "$1" = "-c" ]; then |
36 | exist | 42 | exist |
37 | ar -p $deb control.tar.gz | tar -xzO *control | 43 | ar -p "${deb}" control.tar.gz | tar -xzO *control |
38 | exit | 44 | exit |
39 | elif [ "$1" = "-x" ]; then | 45 | elif [ "$1" = "-x" ]; then |
40 | exist | 46 | exist |
41 | if [ "$3" = "" ]; then | 47 | if [ -z "$3" ]; then |
42 | usage | 48 | usage |
43 | elif [ ! -d "$3" ]; then | 49 | elif [ ! -d "$3" ]; then |
44 | echo "No such directory $3!" | 50 | echo "No such directory $3!" |
45 | exit | 51 | exit 1 |
46 | fi | 52 | fi |
47 | ar -p $deb data.tar.gz | tar -xzvpf - -C $3 || exit | 53 | ar -p "${deb}" data.tar.gz | tar -xzvpf - -C "$3" || exit |
48 | echo | 54 | echo |
49 | echo "Extracted $deb to $3!" | 55 | echo "Extracted ${deb} to $3!" |
50 | exit | 56 | exit |
51 | else | 57 | else |
52 | usage | 58 | usage |
53 | fi | 59 | fi |
diff --git a/examples/unrpm b/examples/unrpm index 7fd3676f6..f48550b0a 100755 --- a/examples/unrpm +++ b/examples/unrpm | |||
@@ -5,44 +5,49 @@ | |||
5 | # Requires the programs (cpio, gzip, and the pager more or less). | 5 | # Requires the programs (cpio, gzip, and the pager more or less). |
6 | # | 6 | # |
7 | usage() { | 7 | usage() { |
8 | echo "Usage: unrpm -l package.rpm <List contents of rpm package>" | 8 | cat <<EOF |
9 | echo " unrpm -x package.rpm /foo/boo <Extract rpm package to this directory," | 9 | Usage: unrpm -l package.rpm <List contents of rpm package> |
10 | echo " put . for current directory>" | 10 | unrpm -x package.rpm /foo/boo <Extract rpm package to this directory, |
11 | exit | 11 | put . for current directory> |
12 | EOF | ||
13 | exit | ||
12 | } | 14 | } |
13 | 15 | ||
14 | rpm=$2 | 16 | rpm=$2 |
15 | 17 | ||
16 | exist() { | 18 | exist() { |
17 | if [ "$rpm" = "" ]; then | 19 | if [ -z "${rpm}" ]; then |
18 | usage | 20 | usage |
19 | elif [ ! -s "$rpm" ]; then | 21 | elif [ ! -s "${rpm}" ]; then |
20 | echo "Can't find $rpm!" | 22 | echo "Can't find ${rpm}!" |
21 | exit | 23 | exit 1 |
22 | fi | 24 | fi |
23 | } | 25 | } |
24 | 26 | ||
25 | if [ "$1" = "" ]; then | 27 | if [ -z "$1" ]; then |
26 | usage | 28 | usage |
27 | elif [ "$1" = "-l" ]; then | 29 | elif [ "$1" = "-l" ]; then |
28 | exist | 30 | exist |
29 | type more >/dev/null 2>&1 && pager=more | 31 | type more >/dev/null 2>&1 && pager=more |
30 | type less >/dev/null 2>&1 && pager=less | 32 | type less >/dev/null 2>&1 && pager=less |
31 | [ "$pager" = "" ] && echo "No pager found!" && exit | 33 | [ "$pager" = "" ] && echo "No pager found!" && exit |
32 | (echo -e "\nPress enter to scroll, q to Quit!\n" ; rpm2cpio $rpm | cpio -tv --quiet) | $pager | 34 | ( |
33 | exit | 35 | printf "\nPress enter to scroll, q to Quit!\n\n" |
36 | rpm2cpio "${rpm}" | cpio -tv --quiet | ||
37 | ) | ${pager} | ||
38 | exit | ||
34 | elif [ "$1" = "-x" ]; then | 39 | elif [ "$1" = "-x" ]; then |
35 | exist | 40 | exist |
36 | if [ "$3" = "" ]; then | 41 | if [ -z "$3" ]; then |
37 | usage | 42 | usage |
38 | elif [ ! -d "$3" ]; then | 43 | elif [ ! -d "$3" ]; then |
39 | echo "No such directory $3!" | 44 | echo "No such directory $3!" |
40 | exit | 45 | exit 1 |
41 | fi | 46 | fi |
42 | rpm2cpio $rpm | (umask 0 ; cd $3 ; cpio -idmuv) || exit | 47 | rpm2cpio "${rpm}" | (umask 0 ; cd "$3" ; cpio -idmuv) || exit |
43 | echo | 48 | echo |
44 | echo "Extracted $rpm to $3!" | 49 | echo "Extracted ${rpm} to $3!" |
45 | exit | 50 | exit |
46 | else | 51 | else |
47 | usage | 52 | usage |
48 | fi | 53 | fi |
diff --git a/findutils/grep.c b/findutils/grep.c index e163e6562..5ed3faab2 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -689,11 +689,15 @@ int grep_main(int argc UNUSED_PARAM, char **argv) | |||
689 | FILE *file; | 689 | FILE *file; |
690 | int matched; | 690 | int matched; |
691 | llist_t *fopt = NULL; | 691 | llist_t *fopt = NULL; |
692 | |||
693 | /* do normal option parsing */ | ||
694 | #if ENABLE_FEATURE_GREP_CONTEXT | 692 | #if ENABLE_FEATURE_GREP_CONTEXT |
695 | int Copt, opts; | 693 | int Copt, opts; |
694 | #endif | ||
696 | 695 | ||
696 | /* For grep, exitcode of 1 is "not found". Other errors are 2: */ | ||
697 | xfunc_error_retval = 2; | ||
698 | |||
699 | /* do normal option parsing */ | ||
700 | #if ENABLE_FEATURE_GREP_CONTEXT | ||
697 | /* -H unsets -h; -C unsets -A,-B; -e,-f are lists; | 701 | /* -H unsets -h; -C unsets -A,-B; -e,-f are lists; |
698 | * -m,-A,-B,-C have numeric param */ | 702 | * -m,-A,-B,-C have numeric param */ |
699 | opt_complementary = "H-h:C-AB:e::f::m+:A+:B+:C+"; | 703 | opt_complementary = "H-h:C-AB:e::f::m+:A+:B+:C+"; |
diff --git a/include/busybox.h b/include/busybox.h index b1e31e5ee..737627bd0 100644 --- a/include/busybox.h +++ b/include/busybox.h | |||
@@ -15,25 +15,20 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |||
15 | /* Keep in sync with applets/applet_tables.c! */ | 15 | /* Keep in sync with applets/applet_tables.c! */ |
16 | extern const char applet_names[] ALIGN1; | 16 | extern const char applet_names[] ALIGN1; |
17 | extern int (*const applet_main[])(int argc, char **argv); | 17 | extern int (*const applet_main[])(int argc, char **argv); |
18 | extern const uint16_t applet_nameofs[]; | 18 | extern const uint8_t applet_flags[] ALIGN1; |
19 | extern const uint8_t applet_suid[] ALIGN1; | ||
19 | extern const uint8_t applet_install_loc[] ALIGN1; | 20 | extern const uint8_t applet_install_loc[] ALIGN1; |
20 | 21 | ||
21 | #if ENABLE_FEATURE_SUID || ENABLE_FEATURE_PREFER_APPLETS | ||
22 | # define APPLET_NAME(i) (applet_names + (applet_nameofs[i] & 0x0fff)) | ||
23 | #else | ||
24 | # define APPLET_NAME(i) (applet_names + applet_nameofs[i]) | ||
25 | #endif | ||
26 | |||
27 | #if ENABLE_FEATURE_PREFER_APPLETS | 22 | #if ENABLE_FEATURE_PREFER_APPLETS |
28 | # define APPLET_IS_NOFORK(i) (applet_nameofs[i] & (1 << 12)) | 23 | # define APPLET_IS_NOFORK(i) (applet_flags[(i)/4] & (1 << (2 * ((i)%4)))) |
29 | # define APPLET_IS_NOEXEC(i) (applet_nameofs[i] & (1 << 13)) | 24 | # define APPLET_IS_NOEXEC(i) (applet_flags[(i)/4] & (1 << ((2 * ((i)%4))+1))) |
30 | #else | 25 | #else |
31 | # define APPLET_IS_NOFORK(i) 0 | 26 | # define APPLET_IS_NOFORK(i) 0 |
32 | # define APPLET_IS_NOEXEC(i) 0 | 27 | # define APPLET_IS_NOEXEC(i) 0 |
33 | #endif | 28 | #endif |
34 | 29 | ||
35 | #if ENABLE_FEATURE_SUID | 30 | #if ENABLE_FEATURE_SUID |
36 | # define APPLET_SUID(i) ((applet_nameofs[i] >> 14) & 0x3) | 31 | # define APPLET_SUID(i) ((applet_suid[(i)/4] >> (2 * ((i)%4)) & 3)) |
37 | #endif | 32 | #endif |
38 | 33 | ||
39 | #if ENABLE_FEATURE_INSTALLER | 34 | #if ENABLE_FEATURE_INSTALLER |
diff --git a/include/libbb.h b/include/libbb.h index cb61faad9..ffe1504e1 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -148,14 +148,18 @@ | |||
148 | # include <ws2tcpip.h> | 148 | # include <ws2tcpip.h> |
149 | #else | 149 | #else |
150 | # include <arpa/inet.h> | 150 | # include <arpa/inet.h> |
151 | # if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED) | 151 | //This breaks on bionic: |
152 | /* We #define socklen_t *after* includes, otherwise we get | 152 | //# if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED) |
153 | * typedef redefinition errors from system headers | 153 | ///* We #define socklen_t *after* includes, otherwise we get |
154 | * (in case "is it defined already" detection above failed) | 154 | // * typedef redefinition errors from system headers |
155 | */ | 155 | // * (in case "is it defined already" detection above failed) |
156 | # define socklen_t bb_socklen_t | 156 | // */ |
157 | typedef unsigned socklen_t; | 157 | //# define socklen_t bb_socklen_t |
158 | # endif | 158 | // typedef unsigned socklen_t; |
159 | //# endif | ||
160 | //if this is still needed, add a fix along the lines of | ||
161 | // ifdef SPECIFIC_BROKEN_LIBC_CHECK / typedef socklen_t / endif | ||
162 | //in platform.h instead! | ||
159 | #endif | 163 | #endif |
160 | #ifndef HAVE_CLEARENV | 164 | #ifndef HAVE_CLEARENV |
161 | # define clearenv() do { if (environ) environ[0] = NULL; } while (0) | 165 | # define clearenv() do { if (environ) environ[0] = NULL; } while (0) |
@@ -507,6 +511,7 @@ void xsetuid(uid_t uid) FAST_FUNC; | |||
507 | void xsetegid(gid_t egid) FAST_FUNC; | 511 | void xsetegid(gid_t egid) FAST_FUNC; |
508 | void xseteuid(uid_t euid) FAST_FUNC; | 512 | void xseteuid(uid_t euid) FAST_FUNC; |
509 | void xchdir(const char *path) FAST_FUNC; | 513 | void xchdir(const char *path) FAST_FUNC; |
514 | void xfchdir(int fd) FAST_FUNC; | ||
510 | void xchroot(const char *path) FAST_FUNC; | 515 | void xchroot(const char *path) FAST_FUNC; |
511 | void xsetenv(const char *key, const char *value) FAST_FUNC; | 516 | void xsetenv(const char *key, const char *value) FAST_FUNC; |
512 | void bb_unsetenv(const char *key) FAST_FUNC; | 517 | void bb_unsetenv(const char *key) FAST_FUNC; |
@@ -1001,9 +1006,10 @@ int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC; | |||
1001 | #define BB_EXECVP(prog,cmd) execvp(prog,cmd) | 1006 | #define BB_EXECVP(prog,cmd) execvp(prog,cmd) |
1002 | #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__) | 1007 | #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__) |
1003 | #endif | 1008 | #endif |
1004 | int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; | 1009 | void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; |
1010 | void exec_prog_or_SHELL(char **argv) NORETURN FAST_FUNC; | ||
1005 | 1011 | ||
1006 | /* xvfork() can't be a _function_, return after vfork mangles stack | 1012 | /* xvfork() can't be a _function_, return after vfork in child mangles stack |
1007 | * in the parent. It must be a macro. */ | 1013 | * in the parent. It must be a macro. */ |
1008 | #define xvfork() \ | 1014 | #define xvfork() \ |
1009 | ({ \ | 1015 | ({ \ |
@@ -1015,6 +1021,7 @@ int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; | |||
1015 | #if BB_MMU | 1021 | #if BB_MMU |
1016 | pid_t xfork(void) FAST_FUNC; | 1022 | pid_t xfork(void) FAST_FUNC; |
1017 | #endif | 1023 | #endif |
1024 | void xvfork_parent_waits_and_exits(void) FAST_FUNC; | ||
1018 | 1025 | ||
1019 | /* NOMMU friendy fork+exec: */ | 1026 | /* NOMMU friendy fork+exec: */ |
1020 | pid_t spawn(char **argv) FAST_FUNC; | 1027 | pid_t spawn(char **argv) FAST_FUNC; |
@@ -1031,6 +1038,7 @@ pid_t wait_any_nohang(int *wstat) FAST_FUNC; | |||
1031 | * if (rc > 0) bb_error_msg("exit code: %d", rc & 0xff); | 1038 | * if (rc > 0) bb_error_msg("exit code: %d", rc & 0xff); |
1032 | */ | 1039 | */ |
1033 | int wait4pid(pid_t pid) FAST_FUNC; | 1040 | int wait4pid(pid_t pid) FAST_FUNC; |
1041 | int wait_for_exitstatus(pid_t pid) FAST_FUNC; | ||
1034 | /* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */ | 1042 | /* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */ |
1035 | int spawn_and_wait(char **argv) FAST_FUNC; | 1043 | int spawn_and_wait(char **argv) FAST_FUNC; |
1036 | /* Does NOT check that applet is NOFORK, just blindly runs it */ | 1044 | /* Does NOT check that applet is NOFORK, just blindly runs it */ |
@@ -1160,7 +1168,6 @@ extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, | |||
1160 | extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; | 1168 | extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; |
1161 | extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC; | 1169 | extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC; |
1162 | extern void bb_perror_nomsg(void) FAST_FUNC; | 1170 | extern void bb_perror_nomsg(void) FAST_FUNC; |
1163 | extern void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; | ||
1164 | extern void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC; | 1171 | extern void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC; |
1165 | extern void bb_logenv_override(void) FAST_FUNC; | 1172 | extern void bb_logenv_override(void) FAST_FUNC; |
1166 | 1173 | ||
@@ -1784,6 +1791,9 @@ void bb_progress_update(bb_progress_t *p, | |||
1784 | uoff_t transferred, | 1791 | uoff_t transferred, |
1785 | uoff_t totalsize) FAST_FUNC; | 1792 | uoff_t totalsize) FAST_FUNC; |
1786 | 1793 | ||
1794 | unsigned ubi_devnum_from_devname(const char *str) FAST_FUNC; | ||
1795 | int ubi_get_volid_by_name(unsigned ubi_devnum, const char *vol_name) FAST_FUNC; | ||
1796 | |||
1787 | 1797 | ||
1788 | extern const char *applet_name; | 1798 | extern const char *applet_name; |
1789 | 1799 | ||
diff --git a/init/halt.c b/init/halt.c index ad12d9148..572d751b0 100644 --- a/init/halt.c +++ b/init/halt.c | |||
@@ -135,7 +135,7 @@ int halt_main(int argc UNUSED_PARAM, char **argv) | |||
135 | if (!(flags & 4)) { /* no -f */ | 135 | if (!(flags & 4)) { /* no -f */ |
136 | //TODO: I tend to think that signalling linuxrc is wrong | 136 | //TODO: I tend to think that signalling linuxrc is wrong |
137 | // pity original author didn't comment on it... | 137 | // pity original author didn't comment on it... |
138 | if (ENABLE_FEATURE_INITRD) { | 138 | if (ENABLE_LINUXRC) { |
139 | /* talk to linuxrc */ | 139 | /* talk to linuxrc */ |
140 | /* bbox init/linuxrc assumed */ | 140 | /* bbox init/linuxrc assumed */ |
141 | pid_t *pidlist = find_pid_by_name("linuxrc"); | 141 | pid_t *pidlist = find_pid_by_name("linuxrc"); |
diff --git a/init/init.c b/init/init.c index 25bfaec8c..6eb76b80e 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -16,10 +16,21 @@ | |||
16 | //config: help | 16 | //config: help |
17 | //config: init is the first program run when the system boots. | 17 | //config: init is the first program run when the system boots. |
18 | //config: | 18 | //config: |
19 | //config:config LINUXRC | ||
20 | //config: bool "Support running init from within an initrd (not initramfs)" | ||
21 | //config: default y | ||
22 | //config: select FEATURE_SYSLOG | ||
23 | //config: help | ||
24 | //config: Legacy support for running init under the old-style initrd. Allows | ||
25 | //config: the name linuxrc to act as init, and it doesn't assume init is PID 1. | ||
26 | //config: | ||
27 | //config: This does not apply to initramfs, which runs /init as PID 1 and | ||
28 | //config: requires no special support. | ||
29 | //config: | ||
19 | //config:config FEATURE_USE_INITTAB | 30 | //config:config FEATURE_USE_INITTAB |
20 | //config: bool "Support reading an inittab file" | 31 | //config: bool "Support reading an inittab file" |
21 | //config: default y | 32 | //config: default y |
22 | //config: depends on INIT | 33 | //config: depends on INIT || LINUXRC |
23 | //config: help | 34 | //config: help |
24 | //config: Allow init to read an inittab file when the system boot. | 35 | //config: Allow init to read an inittab file when the system boot. |
25 | //config: | 36 | //config: |
@@ -46,7 +57,7 @@ | |||
46 | //config:config FEATURE_INIT_SCTTY | 57 | //config:config FEATURE_INIT_SCTTY |
47 | //config: bool "Run commands with leading dash with controlling tty" | 58 | //config: bool "Run commands with leading dash with controlling tty" |
48 | //config: default y | 59 | //config: default y |
49 | //config: depends on INIT | 60 | //config: depends on INIT || LINUXRC |
50 | //config: help | 61 | //config: help |
51 | //config: If this option is enabled, init will try to give a controlling | 62 | //config: If this option is enabled, init will try to give a controlling |
52 | //config: tty to any command which has leading hyphen (often it's "-/bin/sh"). | 63 | //config: tty to any command which has leading hyphen (often it's "-/bin/sh"). |
@@ -61,40 +72,29 @@ | |||
61 | //config:config FEATURE_INIT_SYSLOG | 72 | //config:config FEATURE_INIT_SYSLOG |
62 | //config: bool "Enable init to write to syslog" | 73 | //config: bool "Enable init to write to syslog" |
63 | //config: default y | 74 | //config: default y |
64 | //config: depends on INIT | 75 | //config: depends on INIT || LINUXRC |
65 | //config: | 76 | //config: |
66 | //config:config FEATURE_EXTRA_QUIET | 77 | //config:config FEATURE_EXTRA_QUIET |
67 | //config: bool "Be _extra_ quiet on boot" | 78 | //config: bool "Be _extra_ quiet on boot" |
68 | //config: default y | 79 | //config: default y |
69 | //config: depends on INIT | 80 | //config: depends on INIT || LINUXRC |
70 | //config: help | 81 | //config: help |
71 | //config: Prevent init from logging some messages to the console during boot. | 82 | //config: Prevent init from logging some messages to the console during boot. |
72 | //config: | 83 | //config: |
73 | //config:config FEATURE_INIT_COREDUMPS | 84 | //config:config FEATURE_INIT_COREDUMPS |
74 | //config: bool "Support dumping core for child processes (debugging only)" | 85 | //config: bool "Support dumping core for child processes (debugging only)" |
75 | //config: default y | 86 | //config: default y |
76 | //config: depends on INIT | 87 | //config: depends on INIT || LINUXRC |
77 | //config: help | 88 | //config: help |
78 | //config: If this option is enabled and the file /.init_enable_core | 89 | //config: If this option is enabled and the file /.init_enable_core |
79 | //config: exists, then init will call setrlimit() to allow unlimited | 90 | //config: exists, then init will call setrlimit() to allow unlimited |
80 | //config: core file sizes. If this option is disabled, processes | 91 | //config: core file sizes. If this option is disabled, processes |
81 | //config: will not generate any core files. | 92 | //config: will not generate any core files. |
82 | //config: | 93 | //config: |
83 | //config:config FEATURE_INITRD | ||
84 | //config: bool "Support running init from within an initrd (not initramfs)" | ||
85 | //config: default y | ||
86 | //config: depends on INIT | ||
87 | //config: help | ||
88 | //config: Legacy support for running init under the old-style initrd. Allows | ||
89 | //config: the name linuxrc to act as init, and it doesn't assume init is PID 1. | ||
90 | //config: | ||
91 | //config: This does not apply to initramfs, which runs /init as PID 1 and | ||
92 | //config: requires no special support. | ||
93 | //config: | ||
94 | //config:config INIT_TERMINAL_TYPE | 94 | //config:config INIT_TERMINAL_TYPE |
95 | //config: string "Initial terminal type" | 95 | //config: string "Initial terminal type" |
96 | //config: default "linux" | 96 | //config: default "linux" |
97 | //config: depends on INIT | 97 | //config: depends on INIT || LINUXRC |
98 | //config: help | 98 | //config: help |
99 | //config: This is the initial value set by init for the TERM environment | 99 | //config: This is the initial value set by init for the TERM environment |
100 | //config: variable. This variable is used by programs which make use of | 100 | //config: variable. This variable is used by programs which make use of |
@@ -106,7 +106,7 @@ | |||
106 | //config:config FEATURE_INIT_MODIFY_CMDLINE | 106 | //config:config FEATURE_INIT_MODIFY_CMDLINE |
107 | //config: bool "Modify the command-line to \"init\"" | 107 | //config: bool "Modify the command-line to \"init\"" |
108 | //config: default y | 108 | //config: default y |
109 | //config: depends on INIT | 109 | //config: depends on INIT || LINUXRC |
110 | //config: help | 110 | //config: help |
111 | //config: When launched as PID 1 and after parsing its arguments, init | 111 | //config: When launched as PID 1 and after parsing its arguments, init |
112 | //config: wipes all the arguments but argv[0] and rewrites argv[0] to | 112 | //config: wipes all the arguments but argv[0] and rewrites argv[0] to |
@@ -119,9 +119,10 @@ | |||
119 | //config: retrieved in /proc/1/cmdline on Linux, for example. | 119 | //config: retrieved in /proc/1/cmdline on Linux, for example. |
120 | 120 | ||
121 | //applet:IF_INIT(APPLET(init, BB_DIR_SBIN, BB_SUID_DROP)) | 121 | //applet:IF_INIT(APPLET(init, BB_DIR_SBIN, BB_SUID_DROP)) |
122 | //applet:IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) | 122 | //applet:IF_LINUXRC(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) |
123 | 123 | ||
124 | //kbuild:lib-$(CONFIG_INIT) += init.o | 124 | //kbuild:lib-$(CONFIG_INIT) += init.o |
125 | //kbuild:lib-$(CONFIG_LINUXRC) += init.o | ||
125 | 126 | ||
126 | #define DEBUG_SEGV_HANDLER 0 | 127 | #define DEBUG_SEGV_HANDLER 0 |
127 | 128 | ||
@@ -1057,7 +1058,7 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
1057 | if (!DEBUG_INIT) { | 1058 | if (!DEBUG_INIT) { |
1058 | /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ | 1059 | /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ |
1059 | if (getpid() != 1 | 1060 | if (getpid() != 1 |
1060 | && (!ENABLE_FEATURE_INITRD || applet_name[0] != 'l') /* not linuxrc? */ | 1061 | && (!ENABLE_LINUXRC || applet_name[0] != 'l') /* not linuxrc? */ |
1061 | ) { | 1062 | ) { |
1062 | bb_error_msg_and_die("must be run as PID 1"); | 1063 | bb_error_msg_and_die("must be run as PID 1"); |
1063 | } | 1064 | } |
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index e0898565a..0e14e351e 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
@@ -43,7 +43,7 @@ lib-y += getopt32.o | |||
43 | lib-y += get_volsize.o | 43 | lib-y += get_volsize.o |
44 | lib-y += herror_msg.o | 44 | lib-y += herror_msg.o |
45 | lib-y += human_readable.o | 45 | lib-y += human_readable.o |
46 | lib-y += info_msg.o | 46 | lib-y += inet_common.o |
47 | lib-y += inode_hash.o | 47 | lib-y += inode_hash.o |
48 | lib-y += isdirectory.o | 48 | lib-y += isdirectory.o |
49 | lib-y += last_char_is.o | 49 | lib-y += last_char_is.o |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 1d6a4b274..b71f2dd7e 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -140,32 +140,127 @@ void FAST_FUNC bb_show_usage(void) | |||
140 | xfunc_die(); | 140 | xfunc_die(); |
141 | } | 141 | } |
142 | 142 | ||
143 | #if NUM_APPLETS > 8 | ||
144 | static int applet_name_compare(const void *name, const void *idx) | ||
145 | { | ||
146 | int i = (int)(ptrdiff_t)idx - 1; | ||
147 | return strcmp(name, APPLET_NAME(i)); | ||
148 | } | ||
149 | #endif | ||
150 | int FAST_FUNC find_applet_by_name(const char *name) | 143 | int FAST_FUNC find_applet_by_name(const char *name) |
151 | { | 144 | { |
152 | #if NUM_APPLETS > 8 | 145 | unsigned i, max; |
153 | /* Do a binary search to find the applet entry given the name. */ | 146 | int j; |
154 | const char *p; | 147 | const char *p; |
155 | p = bsearch(name, (void*)(ptrdiff_t)1, ARRAY_SIZE(applet_main), 1, applet_name_compare); | 148 | |
156 | /* | 149 | /* The commented-out word-at-a-time code is ~40% faster, but +160 bytes. |
157 | * if (!p) return -1; | 150 | * "Faster" here saves ~0.5 microsecond of real time - not worth it. |
158 | * ^^^^^^^^^^^^^^^^^^ the code below will do this if p == NULL :) | 151 | */ |
159 | */ | 152 | #if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/ |
160 | return (int)(ptrdiff_t)p - 1; | 153 | uint32_t n32; |
154 | |||
155 | /* Handle all names < 2 chars long early */ | ||
156 | if (name[0] == '\0') | ||
157 | return -1; /* "" is not a valid applet name */ | ||
158 | if (name[1] == '\0') { | ||
159 | if (!ENABLE_TEST) | ||
160 | return -1; /* 1-char name is not valid */ | ||
161 | if (name[0] != ']') | ||
162 | return -1; /* 1-char name which isn't "[" is not valid */ | ||
163 | /* applet "[" is always applet #0: */ | ||
164 | return 0; | ||
165 | } | ||
166 | #endif | ||
167 | |||
168 | p = applet_names; | ||
169 | i = 0; | ||
170 | #if KNOWN_APPNAME_OFFSETS <= 0 | ||
171 | max = NUM_APPLETS; | ||
161 | #else | 172 | #else |
162 | /* A version which does not pull in bsearch */ | 173 | max = NUM_APPLETS * KNOWN_APPNAME_OFFSETS; |
163 | int i = 0; | 174 | for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) { |
164 | const char *p = applet_names; | 175 | const char *pp = applet_names + applet_nameofs[j]; |
165 | while (i < NUM_APPLETS) { | 176 | if (strcmp(name, pp) >= 0) { |
166 | if (strcmp(name, p) == 0) | 177 | //bb_error_msg("name:'%s' >= pp:'%s'", name, pp); |
178 | p = pp; | ||
179 | i = max - NUM_APPLETS; | ||
180 | break; | ||
181 | } | ||
182 | max -= NUM_APPLETS; | ||
183 | } | ||
184 | max /= (unsigned)KNOWN_APPNAME_OFFSETS; | ||
185 | i /= (unsigned)KNOWN_APPNAME_OFFSETS; | ||
186 | //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max); | ||
187 | #endif | ||
188 | |||
189 | /* Open-coded linear search without strcmp/strlen calls for speed */ | ||
190 | |||
191 | #if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/ | ||
192 | /* skip "[\0" name, it's surely not it */ | ||
193 | if (ENABLE_TEST && LONE_CHAR(p, '[')) | ||
194 | i++, p += 2; | ||
195 | /* All remaining applet names in p[] are at least 2 chars long */ | ||
196 | /* name[] is also at least 2 chars long */ | ||
197 | |||
198 | n32 = (name[0] << 0) | (name[1] << 8) | (name[2] << 16); | ||
199 | while (i < max) { | ||
200 | uint32_t p32; | ||
201 | char ch; | ||
202 | |||
203 | /* Quickly check match of the first 3 bytes */ | ||
204 | move_from_unaligned32(p32, p); | ||
205 | p += 3; | ||
206 | if ((p32 & 0x00ffffff) != n32) { | ||
207 | /* Most likely case: 3 first bytes do not match */ | ||
208 | i++; | ||
209 | if ((p32 & 0x00ff0000) == '\0') | ||
210 | continue; // p[2] was NUL | ||
211 | p++; | ||
212 | if ((p32 & 0xff000000) == '\0') | ||
213 | continue; // p[3] was NUL | ||
214 | /* p[0..3] aren't matching and none is NUL, check the rest */ | ||
215 | while (*p++ != '\0') | ||
216 | continue; | ||
217 | continue; | ||
218 | } | ||
219 | |||
220 | /* Unlikely branch: first 3 bytes ([0..2]) match */ | ||
221 | if ((p32 & 0x00ff0000) == '\0') { | ||
222 | /* name is 2-byte long, it is full match */ | ||
223 | //bb_error_msg("found:'%s' i:%u", name, i); | ||
167 | return i; | 224 | return i; |
168 | p += strlen(p) + 1; | 225 | } |
226 | /* Check remaining bytes [3..NUL] */ | ||
227 | ch = (p32 >> 24); | ||
228 | j = 3; | ||
229 | while (ch == name[j]) { | ||
230 | if (ch == '\0') { | ||
231 | //bb_error_msg("found:'%s' i:%u", name, i); | ||
232 | return i; | ||
233 | } | ||
234 | ch = *++p; | ||
235 | j++; | ||
236 | } | ||
237 | /* Not a match. Skip it, including NUL */ | ||
238 | while (ch != '\0') | ||
239 | ch = *++p; | ||
240 | p++; | ||
241 | i++; | ||
242 | } | ||
243 | return -1; | ||
244 | #else | ||
245 | while (i < max) { | ||
246 | char ch; | ||
247 | j = 0; | ||
248 | /* Do we see "name\0" in applet_names[p] position? */ | ||
249 | while ((ch = *p) == name[j]) { | ||
250 | if (ch == '\0') { | ||
251 | //bb_error_msg("found:'%s' i:%u", name, i); | ||
252 | return i; /* yes */ | ||
253 | } | ||
254 | p++; | ||
255 | j++; | ||
256 | } | ||
257 | /* No. | ||
258 | * p => 1st non-matching char in applet_names[], | ||
259 | * skip to and including NUL. | ||
260 | */ | ||
261 | while (ch != '\0') | ||
262 | ch = *++p; | ||
263 | p++; | ||
169 | i++; | 264 | i++; |
170 | } | 265 | } |
171 | return -1; | 266 | return -1; |
@@ -588,6 +683,7 @@ static void install_links(const char *busybox, int use_symbolic_links, | |||
588 | * busybox.h::bb_install_loc_t, or else... */ | 683 | * busybox.h::bb_install_loc_t, or else... */ |
589 | int (*lf)(const char *, const char *); | 684 | int (*lf)(const char *, const char *); |
590 | char *fpc; | 685 | char *fpc; |
686 | const char *appname = applet_names; | ||
591 | unsigned i; | 687 | unsigned i; |
592 | int rc; | 688 | int rc; |
593 | 689 | ||
@@ -598,7 +694,7 @@ static void install_links(const char *busybox, int use_symbolic_links, | |||
598 | for (i = 0; i < ARRAY_SIZE(applet_main); i++) { | 694 | for (i = 0; i < ARRAY_SIZE(applet_main); i++) { |
599 | fpc = concat_path_file( | 695 | fpc = concat_path_file( |
600 | custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)], | 696 | custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)], |
601 | APPLET_NAME(i)); | 697 | appname); |
602 | // debug: bb_error_msg("%slinking %s to busybox", | 698 | // debug: bb_error_msg("%slinking %s to busybox", |
603 | // use_symbolic_links ? "sym" : "", fpc); | 699 | // use_symbolic_links ? "sym" : "", fpc); |
604 | rc = lf(busybox, fpc); | 700 | rc = lf(busybox, fpc); |
@@ -606,6 +702,8 @@ static void install_links(const char *busybox, int use_symbolic_links, | |||
606 | bb_simple_perror_msg(fpc); | 702 | bb_simple_perror_msg(fpc); |
607 | } | 703 | } |
608 | free(fpc); | 704 | free(fpc); |
705 | while (*appname++ != '\0') | ||
706 | continue; | ||
609 | } | 707 | } |
610 | } | 708 | } |
611 | # else | 709 | # else |
@@ -769,7 +867,7 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) | |||
769 | 867 | ||
770 | /* Reinit some shared global data */ | 868 | /* Reinit some shared global data */ |
771 | xfunc_error_retval = EXIT_FAILURE; | 869 | xfunc_error_retval = EXIT_FAILURE; |
772 | applet_name = APPLET_NAME(applet_no); | 870 | applet_name = bb_get_last_path_component_nostrip(argv[0]); |
773 | 871 | ||
774 | /* Special case. POSIX says "test --help" | 872 | /* Special case. POSIX says "test --help" |
775 | * should be no different from e.g. "test --foo". | 873 | * should be no different from e.g. "test --foo". |
@@ -800,11 +898,14 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) | |||
800 | 898 | ||
801 | void FAST_FUNC run_applet_and_exit(const char *name, char **argv) | 899 | void FAST_FUNC run_applet_and_exit(const char *name, char **argv) |
802 | { | 900 | { |
803 | int applet = find_applet_by_name(name); | 901 | int applet; |
804 | if (applet >= 0) | 902 | |
805 | run_applet_no_and_exit(applet, argv); | ||
806 | if (is_prefixed_with(name, "busybox")) | 903 | if (is_prefixed_with(name, "busybox")) |
807 | exit(busybox_main(argv)); | 904 | exit(busybox_main(argv)); |
905 | /* find_applet_by_name() search is more expensive, so goes second */ | ||
906 | applet = find_applet_by_name(name); | ||
907 | if (applet >= 0) | ||
908 | run_applet_no_and_exit(applet, argv); | ||
808 | } | 909 | } |
809 | 910 | ||
810 | #endif /* !defined(SINGLE_APPLET_MAIN) */ | 911 | #endif /* !defined(SINGLE_APPLET_MAIN) */ |
@@ -817,6 +918,19 @@ int lbb_main(char **argv) | |||
817 | int main(int argc UNUSED_PARAM, char **argv) | 918 | int main(int argc UNUSED_PARAM, char **argv) |
818 | #endif | 919 | #endif |
819 | { | 920 | { |
921 | #if 0 | ||
922 | /* TODO: find a use for a block of memory between end of .bss | ||
923 | * and end of page. For example, I'm getting "_end:0x812e698 2408 bytes" | ||
924 | * - more than 2k of wasted memory (in this particular build) | ||
925 | * *per each running process*! | ||
926 | * (If your linker does not generate "_end" name, weak attribute | ||
927 | * makes &_end == NULL, end_len == 0 here.) | ||
928 | */ | ||
929 | extern char _end[] __attribute__((weak)); | ||
930 | unsigned end_len = (-(int)_end) & 0xfff; | ||
931 | printf("_end:%p %u bytes\n", &_end, end_len); | ||
932 | #endif | ||
933 | |||
820 | /* Tweak malloc for reduced memory consumption */ | 934 | /* Tweak malloc for reduced memory consumption */ |
821 | #ifdef M_TRIM_THRESHOLD | 935 | #ifdef M_TRIM_THRESHOLD |
822 | /* M_TRIM_THRESHOLD is the maximum amount of freed top-most memory | 936 | /* M_TRIM_THRESHOLD is the maximum amount of freed top-most memory |
diff --git a/libbb/executable.c b/libbb/executable.c index 12a48cea3..308c525a3 100644 --- a/libbb/executable.c +++ b/libbb/executable.c | |||
@@ -97,10 +97,19 @@ int FAST_FUNC BB_EXECVP(const char *file, char *const argv[]) | |||
97 | } | 97 | } |
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | int FAST_FUNC BB_EXECVP_or_die(char **argv) | 100 | void FAST_FUNC BB_EXECVP_or_die(char **argv) |
101 | { | 101 | { |
102 | BB_EXECVP(argv[0], argv); | 102 | BB_EXECVP(argv[0], argv); |
103 | /* SUSv3-mandated exit codes */ | 103 | /* SUSv3-mandated exit codes */ |
104 | xfunc_error_retval = (errno == ENOENT) ? 127 : 126; | 104 | xfunc_error_retval = (errno == ENOENT) ? 127 : 126; |
105 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); | 105 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); |
106 | } | 106 | } |
107 | |||
108 | /* Typical idiom for applets which exec *optional* PROG [ARGS] */ | ||
109 | void FAST_FUNC exec_prog_or_SHELL(char **argv) | ||
110 | { | ||
111 | if (argv[0]) { | ||
112 | BB_EXECVP_or_die(argv); | ||
113 | } | ||
114 | run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL); | ||
115 | } | ||
diff --git a/libbb/info_msg.c b/libbb/info_msg.c deleted file mode 100644 index 56ca2efd4..000000000 --- a/libbb/info_msg.c +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | |||
10 | #include "libbb.h" | ||
11 | #if ENABLE_FEATURE_SYSLOG | ||
12 | # include <syslog.h> | ||
13 | #endif | ||
14 | |||
15 | void FAST_FUNC bb_info_msg(const char *s, ...) | ||
16 | { | ||
17 | #ifdef THIS_ONE_DOESNT_DO_SINGLE_WRITE | ||
18 | va_list p; | ||
19 | /* va_copy is used because it is not portable | ||
20 | * to use va_list p twice */ | ||
21 | va_list p2; | ||
22 | |||
23 | va_start(p, s); | ||
24 | va_copy(p2, p); | ||
25 | if (logmode & LOGMODE_STDIO) { | ||
26 | vprintf(s, p); | ||
27 | fputs(msg_eol, stdout); | ||
28 | } | ||
29 | # if ENABLE_FEATURE_SYSLOG | ||
30 | if (logmode & LOGMODE_SYSLOG) | ||
31 | vsyslog(LOG_INFO, s, p2); | ||
32 | # endif | ||
33 | va_end(p2); | ||
34 | va_end(p); | ||
35 | #else | ||
36 | int used; | ||
37 | char *msg; | ||
38 | va_list p; | ||
39 | |||
40 | if (logmode == 0) | ||
41 | return; | ||
42 | |||
43 | va_start(p, s); | ||
44 | used = vasprintf(&msg, s, p); | ||
45 | va_end(p); | ||
46 | if (used < 0) | ||
47 | return; | ||
48 | |||
49 | # if ENABLE_FEATURE_SYSLOG | ||
50 | if (logmode & LOGMODE_SYSLOG) | ||
51 | syslog(LOG_INFO, "%s", msg); | ||
52 | # endif | ||
53 | if (logmode & LOGMODE_STDIO) { | ||
54 | fflush_all(); | ||
55 | /* used = strlen(msg); - must be true already */ | ||
56 | msg[used++] = '\n'; | ||
57 | full_write(STDOUT_FILENO, msg, used); | ||
58 | } | ||
59 | |||
60 | free(msg); | ||
61 | #endif | ||
62 | } | ||
diff --git a/libbb/ubi.c b/libbb/ubi.c new file mode 100644 index 000000000..34595d797 --- /dev/null +++ b/libbb/ubi.c | |||
@@ -0,0 +1,43 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) 2016 Denys Vlasenko | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | //kbuild:lib-y += ubi.o | ||
10 | |||
11 | #include "libbb.h" | ||
12 | |||
13 | // from ubi-media.h | ||
14 | #define UBI_MAX_VOLUME_NAME 127 | ||
15 | #define UBI_MAX_VOLUMES 128 | ||
16 | |||
17 | unsigned FAST_FUNC ubi_devnum_from_devname(const char *str) | ||
18 | { | ||
19 | unsigned ubi_devnum; | ||
20 | |||
21 | if (sscanf(str, "/dev/ubi%u", &ubi_devnum) != 1) | ||
22 | bb_error_msg_and_die("not an UBI device: '%s'", str); | ||
23 | return ubi_devnum; | ||
24 | } | ||
25 | |||
26 | int FAST_FUNC ubi_get_volid_by_name(unsigned ubi_devnum, const char *vol_name) | ||
27 | { | ||
28 | unsigned i; | ||
29 | |||
30 | for (i = 0; i < UBI_MAX_VOLUMES; i++) { | ||
31 | char buf[UBI_MAX_VOLUME_NAME + 1]; | ||
32 | char fname[sizeof("/sys/class/ubi/ubi%u_%u/name") + 2 * sizeof(int)*3]; | ||
33 | |||
34 | sprintf(fname, "/sys/class/ubi/ubi%u_%u/name", ubi_devnum, i); | ||
35 | if (open_read_close(fname, buf, sizeof(buf)) <= 0) | ||
36 | continue; | ||
37 | |||
38 | strchrnul(buf, '\n')[0] = '\0'; | ||
39 | if (strcmp(vol_name, buf) == 0) | ||
40 | return i; | ||
41 | } | ||
42 | bb_error_msg_and_die("volume '%s' not found", vol_name); | ||
43 | } | ||
diff --git a/libbb/verror_msg.c b/libbb/verror_msg.c index 0ef2a311f..22c30357b 100644 --- a/libbb/verror_msg.c +++ b/libbb/verror_msg.c | |||
@@ -20,6 +20,7 @@ const char *msg_eol = "\n"; | |||
20 | void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) | 20 | void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) |
21 | { | 21 | { |
22 | char *msg, *msg1; | 22 | char *msg, *msg1; |
23 | char stack_msg[80]; | ||
23 | int applet_len, strerr_len, msgeol_len, used; | 24 | int applet_len, strerr_len, msgeol_len, used; |
24 | 25 | ||
25 | if (!logmode) | 26 | if (!logmode) |
@@ -28,6 +29,27 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) | |||
28 | if (!s) /* nomsg[_and_die] uses NULL fmt */ | 29 | if (!s) /* nomsg[_and_die] uses NULL fmt */ |
29 | s = ""; /* some libc don't like printf(NULL) */ | 30 | s = ""; /* some libc don't like printf(NULL) */ |
30 | 31 | ||
32 | applet_len = strlen(applet_name) + 2; /* "applet: " */ | ||
33 | strerr_len = strerr ? strlen(strerr) : 0; | ||
34 | msgeol_len = strlen(msg_eol); | ||
35 | |||
36 | /* This costs ~90 bytes of code, but avoids costly | ||
37 | * malloc()[in vasprintf]+realloc()+memmove()+free() in 99% of cases. | ||
38 | * ~40% speedup. | ||
39 | */ | ||
40 | if ((int)sizeof(stack_msg) - applet_len > 0) { | ||
41 | va_list p2; | ||
42 | |||
43 | /* It is not portable to use va_list twice, need to va_copy it */ | ||
44 | va_copy(p2, p); | ||
45 | used = vsnprintf(stack_msg + applet_len, (int)sizeof(stack_msg) - applet_len, s, p2); | ||
46 | va_end(p2); | ||
47 | msg = stack_msg; | ||
48 | used += applet_len; | ||
49 | if (used < (int)sizeof(stack_msg) - 3 - msgeol_len - strerr_len) | ||
50 | goto add_pfx_and_sfx; | ||
51 | } | ||
52 | |||
31 | used = vasprintf(&msg, s, p); | 53 | used = vasprintf(&msg, s, p); |
32 | if (used < 0) | 54 | if (used < 0) |
33 | return; | 55 | return; |
@@ -37,9 +59,6 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) | |||
37 | * This is needed for e.g. httpd logging, when multiple | 59 | * This is needed for e.g. httpd logging, when multiple |
38 | * children can produce log messages simultaneously. */ | 60 | * children can produce log messages simultaneously. */ |
39 | 61 | ||
40 | applet_len = strlen(applet_name) + 2; /* "applet: " */ | ||
41 | strerr_len = strerr ? strlen(strerr) : 0; | ||
42 | msgeol_len = strlen(msg_eol); | ||
43 | /* can't use xrealloc: it calls error_msg on failure, | 62 | /* can't use xrealloc: it calls error_msg on failure, |
44 | * that may result in a recursion */ | 63 | * that may result in a recursion */ |
45 | /* +3 is for ": " before strerr and for terminating NUL */ | 64 | /* +3 is for ": " before strerr and for terminating NUL */ |
@@ -52,6 +71,7 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) | |||
52 | /* TODO: maybe use writev instead of memmoving? Need full_writev? */ | 71 | /* TODO: maybe use writev instead of memmoving? Need full_writev? */ |
53 | memmove(msg + applet_len, msg, used); | 72 | memmove(msg + applet_len, msg, used); |
54 | used += applet_len; | 73 | used += applet_len; |
74 | add_pfx_and_sfx: | ||
55 | strcpy(msg, applet_name); | 75 | strcpy(msg, applet_name); |
56 | msg[applet_len - 2] = ':'; | 76 | msg[applet_len - 2] = ':'; |
57 | msg[applet_len - 1] = ' '; | 77 | msg[applet_len - 1] = ' '; |
@@ -76,7 +96,8 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) | |||
76 | syslog(syslog_level, "%s", msg + applet_len); | 96 | syslog(syslog_level, "%s", msg + applet_len); |
77 | } | 97 | } |
78 | #endif | 98 | #endif |
79 | free(msg); | 99 | if (msg != stack_msg) |
100 | free(msg); | ||
80 | } | 101 | } |
81 | 102 | ||
82 | #ifdef VERSION_WITH_WRITEV | 103 | #ifdef VERSION_WITH_WRITEV |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 2d3204507..f488f8e0c 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -118,8 +118,6 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
118 | 118 | ||
119 | save_nofork_data(&old); | 119 | save_nofork_data(&old); |
120 | 120 | ||
121 | applet_name = APPLET_NAME(applet_no); | ||
122 | |||
123 | xfunc_error_retval = EXIT_FAILURE; | 121 | xfunc_error_retval = EXIT_FAILURE; |
124 | 122 | ||
125 | /* In case getopt() or getopt32() was already called: | 123 | /* In case getopt() or getopt32() was already called: |
@@ -159,6 +157,7 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
159 | * need argv untouched because they free argv[i]! */ | 157 | * need argv untouched because they free argv[i]! */ |
160 | char *tmp_argv[argc+1]; | 158 | char *tmp_argv[argc+1]; |
161 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | 159 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); |
160 | applet_name = tmp_argv[0]; | ||
162 | /* Finally we can call NOFORK applet's main() */ | 161 | /* Finally we can call NOFORK applet's main() */ |
163 | rc = applet_main[applet_no](argc, tmp_argv); | 162 | rc = applet_main[applet_no](argc, tmp_argv); |
164 | } else { | 163 | } else { |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 206edb4a0..3f9a84ad4 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -315,3 +315,15 @@ int FAST_FUNC wait4pid(pid_t pid) | |||
315 | return WTERMSIG(status) + 0x180; | 315 | return WTERMSIG(status) + 0x180; |
316 | return 0; | 316 | return 0; |
317 | } | 317 | } |
318 | |||
319 | // Useful when we do know that pid is valid, and we just want to wait | ||
320 | // for it to exit. Not existing pid is fatal. waitpid() status is not returned. | ||
321 | int FAST_FUNC wait_for_exitstatus(pid_t pid) | ||
322 | { | ||
323 | int exit_status, n; | ||
324 | |||
325 | n = safe_waitpid(pid, &exit_status, 0); | ||
326 | if (n < 0) | ||
327 | bb_perror_msg_and_die("waitpid"); | ||
328 | return exit_status; | ||
329 | } | ||
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index 73488908d..e9222f690 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c | |||
@@ -390,6 +390,12 @@ void FAST_FUNC xchdir(const char *path) | |||
390 | bb_perror_msg_and_die("can't change directory to '%s'", path); | 390 | bb_perror_msg_and_die("can't change directory to '%s'", path); |
391 | } | 391 | } |
392 | 392 | ||
393 | void FAST_FUNC xfchdir(int fd) | ||
394 | { | ||
395 | if (fchdir(fd)) | ||
396 | bb_perror_msg_and_die("fchdir"); | ||
397 | } | ||
398 | |||
393 | void FAST_FUNC xchroot(const char *path) | 399 | void FAST_FUNC xchroot(const char *path) |
394 | { | 400 | { |
395 | if (chroot(path)) | 401 | if (chroot(path)) |
@@ -653,3 +659,19 @@ pid_t FAST_FUNC xfork(void) | |||
653 | return pid; | 659 | return pid; |
654 | } | 660 | } |
655 | #endif | 661 | #endif |
662 | |||
663 | void FAST_FUNC xvfork_parent_waits_and_exits(void) | ||
664 | { | ||
665 | pid_t pid; | ||
666 | |||
667 | fflush_all(); | ||
668 | pid = xvfork(); | ||
669 | if (pid > 0) { | ||
670 | /* Parent */ | ||
671 | int exit_status = wait_for_exitstatus(pid); | ||
672 | if (WIFSIGNALED(exit_status)) | ||
673 | kill_myself_with_sig(WTERMSIG(exit_status)); | ||
674 | _exit(WEXITSTATUS(exit_status)); | ||
675 | } | ||
676 | /* Child continues */ | ||
677 | } | ||
diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index a022a42d6..2d268be67 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c | |||
@@ -105,7 +105,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) | |||
105 | if (rc < 0) | 105 | if (rc < 0) |
106 | bb_error_msg_and_die("an error occurred updating password for %s", name); | 106 | bb_error_msg_and_die("an error occurred updating password for %s", name); |
107 | if (rc) | 107 | if (rc) |
108 | bb_info_msg("Password for '%s' changed", name); | 108 | bb_error_msg("password for '%s' changed", name); |
109 | logmode = LOGMODE_STDIO; | 109 | logmode = LOGMODE_STDIO; |
110 | free(name); | 110 | free(name); |
111 | free(free_me); | 111 | free(free_me); |
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index 55dcc2914..23a1884f4 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c | |||
@@ -14,13 +14,22 @@ | |||
14 | //config: default y | 14 | //config: default y |
15 | //config: help | 15 | //config: help |
16 | //config: Encrypts the given password with the crypt(3) libc function | 16 | //config: Encrypts the given password with the crypt(3) libc function |
17 | //config: using the given salt. | ||
18 | //config: | ||
19 | //config:config MKPASSWD | ||
20 | //config: bool "mkpasswd" | ||
21 | //config: default y | ||
22 | //config: help | ||
23 | //config: Encrypts the given password with the crypt(3) libc function | ||
17 | //config: using the given salt. Debian has this utility under mkpasswd | 24 | //config: using the given salt. Debian has this utility under mkpasswd |
18 | //config: name. Busybox provides mkpasswd as an alias for cryptpw. | 25 | //config: name. Busybox provides mkpasswd as an alias for cryptpw. |
19 | 26 | ||
20 | //applet:IF_CRYPTPW(APPLET(cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP)) | 27 | //applet:IF_CRYPTPW(APPLET(cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP)) |
21 | //applet:IF_CRYPTPW(APPLET_ODDNAME(mkpasswd, cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP, mkpasswd)) | 28 | // APPLET_ODDNAME:name main location suid_type help |
29 | //applet:IF_MKPASSWD(APPLET_ODDNAME(mkpasswd, cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP, cryptpw)) | ||
22 | 30 | ||
23 | //kbuild:lib-$(CONFIG_CRYPTPW) += cryptpw.o | 31 | //kbuild:lib-$(CONFIG_CRYPTPW) += cryptpw.o |
32 | //kbuild:lib-$(CONFIG_MKPASSWD) += cryptpw.o | ||
24 | 33 | ||
25 | //usage:#define cryptpw_trivial_usage | 34 | //usage:#define cryptpw_trivial_usage |
26 | //usage: "[OPTIONS] [PASSWORD] [SALT]" | 35 | //usage: "[OPTIONS] [PASSWORD] [SALT]" |
@@ -40,25 +49,6 @@ | |||
40 | //usage: "\n -S SALT" | 49 | //usage: "\n -S SALT" |
41 | //usage: ) | 50 | //usage: ) |
42 | 51 | ||
43 | /* mkpasswd is an alias to cryptpw */ | ||
44 | //usage:#define mkpasswd_trivial_usage | ||
45 | //usage: "[OPTIONS] [PASSWORD] [SALT]" | ||
46 | /* We do support -s, we just don't mention it */ | ||
47 | //usage:#define mkpasswd_full_usage "\n\n" | ||
48 | //usage: "Crypt PASSWORD using crypt(3)\n" | ||
49 | //usage: IF_LONG_OPTS( | ||
50 | //usage: "\n -P,--password-fd=N Read password from fd N" | ||
51 | /* //usage: "\n -s,--stdin Use stdin; like -P0" */ | ||
52 | //usage: "\n -m,--method=TYPE Encryption method" | ||
53 | //usage: "\n -S,--salt=SALT" | ||
54 | //usage: ) | ||
55 | //usage: IF_NOT_LONG_OPTS( | ||
56 | //usage: "\n -P N Read password from fd N" | ||
57 | /* //usage: "\n -s Use stdin; like -P0" */ | ||
58 | //usage: "\n -m TYPE Encryption method TYPE" | ||
59 | //usage: "\n -S SALT" | ||
60 | //usage: ) | ||
61 | |||
62 | #include "libbb.h" | 52 | #include "libbb.h" |
63 | 53 | ||
64 | /* Debian has 'mkpasswd' utility, manpage says: | 54 | /* Debian has 'mkpasswd' utility, manpage says: |
@@ -140,7 +130,7 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv) | |||
140 | if (!password) { | 130 | if (!password) { |
141 | /* Only mkpasswd, and only from tty, prompts. | 131 | /* Only mkpasswd, and only from tty, prompts. |
142 | * Otherwise it is a plain read. */ | 132 | * Otherwise it is a plain read. */ |
143 | password = (isatty(STDIN_FILENO) && applet_name[0] == 'm') | 133 | password = (ENABLE_MKPASSWD && isatty(STDIN_FILENO) && applet_name[0] == 'm') |
144 | ? bb_ask_stdin("Password: ") | 134 | ? bb_ask_stdin("Password: ") |
145 | : xmalloc_fgetline(stdin) | 135 | : xmalloc_fgetline(stdin) |
146 | ; | 136 | ; |
diff --git a/loginutils/passwd.c b/loginutils/passwd.c index 73726d3e0..52b66ca50 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c | |||
@@ -230,7 +230,7 @@ int passwd_main(int argc UNUSED_PARAM, char **argv) | |||
230 | /* LOGMODE_BOTH */ | 230 | /* LOGMODE_BOTH */ |
231 | if (rc < 0) | 231 | if (rc < 0) |
232 | bb_error_msg_and_die("can't update password file %s", filename); | 232 | bb_error_msg_and_die("can't update password file %s", filename); |
233 | bb_info_msg("Password for %s changed by %s", name, myname); | 233 | bb_error_msg("password for %s changed by %s", name, myname); |
234 | 234 | ||
235 | /*if (ENABLE_FEATURE_CLEAN_UP) free(newp); - can't, it may be non-malloced */ | 235 | /*if (ENABLE_FEATURE_CLEAN_UP) free(newp); - can't, it may be non-malloced */ |
236 | skip: | 236 | skip: |
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 19b1e304c..f32469551 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c | |||
@@ -12,7 +12,6 @@ | |||
12 | //config: sulogin is invoked when the system goes into single user | 12 | //config: sulogin is invoked when the system goes into single user |
13 | //config: mode (this is done through an entry in inittab). | 13 | //config: mode (this is done through an entry in inittab). |
14 | 14 | ||
15 | //applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ | ||
16 | //applet:IF_SULOGIN(APPLET(sulogin, BB_DIR_SBIN, BB_SUID_DROP)) | 15 | //applet:IF_SULOGIN(APPLET(sulogin, BB_DIR_SBIN, BB_SUID_DROP)) |
17 | 16 | ||
18 | //kbuild:lib-$(CONFIG_SULOGIN) += sulogin.o | 17 | //kbuild:lib-$(CONFIG_SULOGIN) += sulogin.o |
@@ -33,6 +32,14 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) | |||
33 | struct passwd *pwd; | 32 | struct passwd *pwd; |
34 | const char *shell; | 33 | const char *shell; |
35 | 34 | ||
35 | /* Note: sulogin is not a suid app. It is meant to be run by init | ||
36 | * for single user / emergency mode. init starts it as root. | ||
37 | * Normal users (potentially malisious ones) can only run it under | ||
38 | * their UID, therefore no paranoia here is warranted: | ||
39 | * $LD_LIBRARY_PATH in env, TTY = /dev/sda | ||
40 | * are no more dangerous here than in e.g. cp applet. | ||
41 | */ | ||
42 | |||
36 | logmode = LOGMODE_BOTH; | 43 | logmode = LOGMODE_BOTH; |
37 | openlog(applet_name, 0, LOG_AUTH); | 44 | openlog(applet_name, 0, LOG_AUTH); |
38 | 45 | ||
@@ -48,18 +55,9 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) | |||
48 | dup(0); | 55 | dup(0); |
49 | } | 56 | } |
50 | 57 | ||
51 | /* Malicious use like "sulogin /dev/sda"? */ | ||
52 | if (!isatty(0) || !isatty(1) || !isatty(2)) { | ||
53 | logmode = LOGMODE_SYSLOG; | ||
54 | bb_error_msg_and_die("not a tty"); | ||
55 | } | ||
56 | |||
57 | /* Clear dangerous stuff, set PATH */ | ||
58 | sanitize_env_if_suid(); | ||
59 | |||
60 | pwd = getpwuid(0); | 58 | pwd = getpwuid(0); |
61 | if (!pwd) { | 59 | if (!pwd) { |
62 | goto auth_error; | 60 | bb_error_msg_and_die("no password entry for root"); |
63 | } | 61 | } |
64 | 62 | ||
65 | while (1) { | 63 | while (1) { |
@@ -71,17 +69,17 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) | |||
71 | ); | 69 | ); |
72 | if (r < 0) { | 70 | if (r < 0) { |
73 | /* ^D, ^C, timeout, or read error */ | 71 | /* ^D, ^C, timeout, or read error */ |
74 | bb_info_msg("Normal startup"); | 72 | bb_error_msg("normal startup"); |
75 | return 0; | 73 | return 0; |
76 | } | 74 | } |
77 | if (r > 0) { | 75 | if (r > 0) { |
78 | break; | 76 | break; |
79 | } | 77 | } |
80 | bb_do_delay(LOGIN_FAIL_DELAY); | 78 | bb_do_delay(LOGIN_FAIL_DELAY); |
81 | bb_info_msg("Login incorrect"); | 79 | bb_error_msg("Login incorrect"); |
82 | } | 80 | } |
83 | 81 | ||
84 | bb_info_msg("System Maintenance Mode"); | 82 | bb_error_msg("starting shell for system maintenance"); |
85 | 83 | ||
86 | IF_SELINUX(renew_current_security_context()); | 84 | IF_SELINUX(renew_current_security_context()); |
87 | 85 | ||
@@ -93,7 +91,4 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) | |||
93 | 91 | ||
94 | /* Exec login shell with no additional parameters. Never returns. */ | 92 | /* Exec login shell with no additional parameters. Never returns. */ |
95 | run_shell(shell, 1, NULL, NULL); | 93 | run_shell(shell, 1, NULL, NULL); |
96 | |||
97 | auth_error: | ||
98 | bb_error_msg_and_die("no password entry for root"); | ||
99 | } | 94 | } |
diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index 4355e4dc5..5143fac8f 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c | |||
@@ -270,7 +270,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
270 | // G.method = xstrdup(a+1); | 270 | // G.method = xstrdup(a+1); |
271 | } | 271 | } |
272 | // N.B. list == NULL here | 272 | // N.B. list == NULL here |
273 | //bb_info_msg("OPT[%x] AU[%s], AP[%s], AM[%s], ARGV[%s]", opts, au, ap, am, *argv); | 273 | //bb_error_msg("OPT[%x] AU[%s], AP[%s], AM[%s], ARGV[%s]", opts, au, ap, am, *argv); |
274 | 274 | ||
275 | // connect to server | 275 | // connect to server |
276 | 276 | ||
diff --git a/miscutils/beep.c b/miscutils/beep.c index 910e03e1b..18b160cc4 100644 --- a/miscutils/beep.c +++ b/miscutils/beep.c | |||
@@ -88,7 +88,7 @@ int beep_main(int argc, char **argv) | |||
88 | bb_show_usage(); | 88 | bb_show_usage(); |
89 | } | 89 | } |
90 | while (rep) { | 90 | while (rep) { |
91 | //bb_info_msg("rep[%d] freq=%d, length=%d, delay=%d", rep, freq, length, delay); | 91 | //bb_error_msg("rep[%d] freq=%d, length=%d, delay=%d", rep, freq, length, delay); |
92 | xioctl(speaker, KIOCSOUND, (void*)(uintptr_t)tickrate_div_freq); | 92 | xioctl(speaker, KIOCSOUND, (void*)(uintptr_t)tickrate_div_freq); |
93 | usleep(1000 * length); | 93 | usleep(1000 * length); |
94 | ioctl(speaker, KIOCSOUND, (void*)0); | 94 | ioctl(speaker, KIOCSOUND, (void*)0); |
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 9256567cc..6217918da 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c | |||
@@ -284,7 +284,7 @@ static const char bb_msg_variable_not_found[] ALIGN1 = "variable: %s not found"; | |||
284 | 284 | ||
285 | /* Busybox stuff */ | 285 | /* Busybox stuff */ |
286 | #if ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG | 286 | #if ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG |
287 | #define info_logger(p, fmt, args...) bb_info_msg(fmt, ## args) | 287 | #define info_logger(p, fmt, args...) bb_error_msg(fmt, ## args) |
288 | #define msg_logger(p, fmt, args...) bb_error_msg(fmt, ## args) | 288 | #define msg_logger(p, fmt, args...) bb_error_msg(fmt, ## args) |
289 | #define msg_logger_and_die(p, fmt, args...) bb_error_msg_and_die(fmt, ## args) | 289 | #define msg_logger_and_die(p, fmt, args...) bb_error_msg_and_die(fmt, ## args) |
290 | #define error_logger(p, fmt, args...) bb_perror_msg(fmt, ## args) | 290 | #define error_logger(p, fmt, args...) bb_perror_msg(fmt, ## args) |
diff --git a/miscutils/eject.c b/miscutils/eject.c index a20e04b7f..e33d79127 100644 --- a/miscutils/eject.c +++ b/miscutils/eject.c | |||
@@ -25,23 +25,19 @@ | |||
25 | 25 | ||
26 | #include <sys/mount.h> | 26 | #include <sys/mount.h> |
27 | #include "libbb.h" | 27 | #include "libbb.h" |
28 | #if ENABLE_FEATURE_EJECT_SCSI | ||
28 | /* Must be after libbb.h: they need size_t */ | 29 | /* Must be after libbb.h: they need size_t */ |
29 | #include "fix_u32.h" | 30 | # include "fix_u32.h" |
30 | #include <scsi/sg.h> | 31 | # include <scsi/sg.h> |
31 | #include <scsi/scsi.h> | 32 | # include <scsi/scsi.h> |
32 | 33 | #endif | |
33 | /* various defines swiped from linux/cdrom.h */ | ||
34 | #define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ | ||
35 | #define CDROMEJECT 0x5309 /* Ejects the cdrom media */ | ||
36 | #define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ | ||
37 | /* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ | ||
38 | #define CDS_TRAY_OPEN 2 | ||
39 | 34 | ||
40 | #define dev_fd 3 | 35 | #define dev_fd 3 |
41 | 36 | ||
42 | /* Code taken from the original eject (http://eject.sourceforge.net/), | 37 | /* Code taken from the original eject (http://eject.sourceforge.net/), |
43 | * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */ | 38 | * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */ |
44 | 39 | ||
40 | #if ENABLE_FEATURE_EJECT_SCSI | ||
45 | static void eject_scsi(const char *dev) | 41 | static void eject_scsi(const char *dev) |
46 | { | 42 | { |
47 | static const char sg_commands[3][6] = { | 43 | static const char sg_commands[3][6] = { |
@@ -76,6 +72,16 @@ static void eject_scsi(const char *dev) | |||
76 | /* force kernel to reread partition table when new disc is inserted */ | 72 | /* force kernel to reread partition table when new disc is inserted */ |
77 | ioctl(dev_fd, BLKRRPART); | 73 | ioctl(dev_fd, BLKRRPART); |
78 | } | 74 | } |
75 | #else | ||
76 | # define eject_scsi(dev) ((void)0) | ||
77 | #endif | ||
78 | |||
79 | /* various defines swiped from linux/cdrom.h */ | ||
80 | #define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ | ||
81 | #define CDROMEJECT 0x5309 /* Ejects the cdrom media */ | ||
82 | #define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ | ||
83 | /* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ | ||
84 | #define CDS_TRAY_OPEN 2 | ||
79 | 85 | ||
80 | #define FLAG_CLOSE 1 | 86 | #define FLAG_CLOSE 1 |
81 | #define FLAG_SMART 2 | 87 | #define FLAG_SMART 2 |
diff --git a/miscutils/flash_eraseall.c b/miscutils/flash_eraseall.c index bf9b739a1..d95d214d9 100644 --- a/miscutils/flash_eraseall.c +++ b/miscutils/flash_eraseall.c | |||
@@ -147,7 +147,7 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv) | |||
147 | ret = ioctl(fd, MEMGETBADBLOCK, &offset); | 147 | ret = ioctl(fd, MEMGETBADBLOCK, &offset); |
148 | if (ret > 0) { | 148 | if (ret > 0) { |
149 | if (!(flags & OPTION_Q)) | 149 | if (!(flags & OPTION_Q)) |
150 | bb_info_msg("\nSkipping bad block at 0x%08x", erase.start); | 150 | printf("\nSkipping bad block at 0x%08x\n", erase.start); |
151 | continue; | 151 | continue; |
152 | } | 152 | } |
153 | if (ret < 0) { | 153 | if (ret < 0) { |
diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c index 7a1a6a2e5..908d657fd 100644 --- a/miscutils/inotifyd.c +++ b/miscutils/inotifyd.c | |||
@@ -47,8 +47,8 @@ | |||
47 | //usage: "\n o Event queue overflowed" | 47 | //usage: "\n o Event queue overflowed" |
48 | //usage: "\n x File can't be watched anymore" | 48 | //usage: "\n x File can't be watched anymore" |
49 | //usage: "\nIf watching a directory:" | 49 | //usage: "\nIf watching a directory:" |
50 | //usage: "\n m Subfile is moved into dir" | 50 | //usage: "\n y Subfile is moved into dir" |
51 | //usage: "\n y Subfile is moved out of dir" | 51 | //usage: "\n m Subfile is moved out of dir" |
52 | //usage: "\n n Subfile is created" | 52 | //usage: "\n n Subfile is created" |
53 | //usage: "\n d Subfile is deleted" | 53 | //usage: "\n d Subfile is deleted" |
54 | //usage: "\n" | 54 | //usage: "\n" |
diff --git a/miscutils/taskset.c b/miscutils/taskset.c index 100b1d926..fb352ab8d 100644 --- a/miscutils/taskset.c +++ b/miscutils/taskset.c | |||
@@ -75,27 +75,26 @@ static char *from_cpuset(cpu_set_t *mask) | |||
75 | #define TASKSET_PRINTF_MASK "%llx" | 75 | #define TASKSET_PRINTF_MASK "%llx" |
76 | static unsigned long long from_cpuset(cpu_set_t *mask) | 76 | static unsigned long long from_cpuset(cpu_set_t *mask) |
77 | { | 77 | { |
78 | char *p = (void*)mask; | 78 | BUILD_BUG_ON(CPU_SETSIZE < 8*sizeof(int)); |
79 | 79 | ||
80 | BUILD_BUG_ON(CPU_SETSIZE < sizeof(int)); | 80 | /* Take the least significant bits. Assume cpu_set_t is |
81 | 81 | * implemented as an array of unsigned long or unsigned | |
82 | /* Take the least significant bits. Careful! | 82 | * int. |
83 | * Consider both CPU_SETSIZE=4 and CPU_SETSIZE=1024 cases | ||
84 | */ | 83 | */ |
85 | #if BB_BIG_ENDIAN | 84 | if (CPU_SETSIZE < 8*sizeof(long)) |
86 | /* For big endian, it means LAST bits */ | 85 | return *(unsigned*)mask; |
87 | if (CPU_SETSIZE < sizeof(long)) | 86 | if (CPU_SETSIZE < 8*sizeof(long long)) |
88 | p += CPU_SETSIZE - sizeof(int); | 87 | return *(unsigned long*)mask; |
89 | else if (CPU_SETSIZE < sizeof(long long)) | 88 | # if BB_BIG_ENDIAN |
90 | p += CPU_SETSIZE - sizeof(long); | 89 | if (sizeof(long long) > sizeof(long)) { |
91 | else | 90 | /* We can put two long in the long long, but they have to |
92 | p += CPU_SETSIZE - sizeof(long long); | 91 | * be swapped: the least significant word comes first in the |
93 | #endif | 92 | * array */ |
94 | if (CPU_SETSIZE < sizeof(long)) | 93 | unsigned long *p = (void*)mask; |
95 | return *(unsigned*)p; | 94 | return p[0] + ((unsigned long long)p[1] << (8*sizeof(long))); |
96 | if (CPU_SETSIZE < sizeof(long long)) | 95 | } |
97 | return *(unsigned long*)p; | 96 | # endif |
98 | return *(unsigned long long*)p; | 97 | return *(unsigned long long*)mask; |
99 | } | 98 | } |
100 | #endif | 99 | #endif |
101 | 100 | ||
diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c index dd1bda300..4364bc807 100644 --- a/miscutils/ubi_tools.c +++ b/miscutils/ubi_tools.c | |||
@@ -195,7 +195,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
195 | } else | 195 | } else |
196 | 196 | ||
197 | //usage:#define ubimkvol_trivial_usage | 197 | //usage:#define ubimkvol_trivial_usage |
198 | //usage: "UBI_DEVICE -N NAME [-s SIZE | -m]" | 198 | //usage: "-N NAME [-s SIZE | -m] UBI_DEVICE" |
199 | //usage:#define ubimkvol_full_usage "\n\n" | 199 | //usage:#define ubimkvol_full_usage "\n\n" |
200 | //usage: "Create UBI volume\n" | 200 | //usage: "Create UBI volume\n" |
201 | //usage: "\n -a ALIGNMENT Volume alignment (default 1)" | 201 | //usage: "\n -a ALIGNMENT Volume alignment (default 1)" |
@@ -212,9 +212,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
212 | unsigned num; | 212 | unsigned num; |
213 | char *p; | 213 | char *p; |
214 | 214 | ||
215 | if (sscanf(ubi_ctrl, "/dev/ubi%u", &num) != 1) | 215 | num = ubi_devnum_from_devname(ubi_ctrl); |
216 | bb_error_msg_and_die("wrong format of UBI device name"); | ||
217 | |||
218 | p = path_sys_class_ubi_ubi + sprintf(path_sys_class_ubi_ubi, "%u/", num); | 216 | p = path_sys_class_ubi_ubi + sprintf(path_sys_class_ubi_ubi, "%u/", num); |
219 | 217 | ||
220 | strcpy(p, "avail_eraseblocks"); | 218 | strcpy(p, "avail_eraseblocks"); |
@@ -248,20 +246,31 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
248 | } else | 246 | } else |
249 | 247 | ||
250 | //usage:#define ubirmvol_trivial_usage | 248 | //usage:#define ubirmvol_trivial_usage |
251 | //usage: "UBI_DEVICE -n VOLID" | 249 | //usage: "-n VOLID / -N VOLNAME UBI_DEVICE" |
252 | //usage:#define ubirmvol_full_usage "\n\n" | 250 | //usage:#define ubirmvol_full_usage "\n\n" |
253 | //usage: "Remove UBI volume\n" | 251 | //usage: "Remove UBI volume\n" |
254 | //usage: "\n -n VOLID Volume ID" | 252 | //usage: "\n -n VOLID Volume ID" |
253 | //usage: "\n -N VOLNAME Volume name" | ||
255 | if (do_rmvol) { | 254 | if (do_rmvol) { |
256 | if (!(opts & OPTION_n)) | 255 | if (!(opts & (OPTION_n|OPTION_N))) |
257 | bb_error_msg_and_die("volume id not specified"); | 256 | bb_error_msg_and_die("volume id not specified"); |
258 | 257 | ||
259 | /* FIXME? kernel expects int32_t* here: */ | 258 | if (opts & OPTION_N) { |
260 | xioctl(fd, UBI_IOCRMVOL, &vol_id); | 259 | unsigned num = ubi_devnum_from_devname(ubi_ctrl); |
260 | vol_id = ubi_get_volid_by_name(num, vol_name); | ||
261 | } | ||
262 | |||
263 | if (sizeof(vol_id) != 4) { | ||
264 | /* kernel expects int32_t* in this ioctl */ | ||
265 | int32_t t = vol_id; | ||
266 | xioctl(fd, UBI_IOCRMVOL, &t); | ||
267 | } else { | ||
268 | xioctl(fd, UBI_IOCRMVOL, &vol_id); | ||
269 | } | ||
261 | } else | 270 | } else |
262 | 271 | ||
263 | //usage:#define ubirsvol_trivial_usage | 272 | //usage:#define ubirsvol_trivial_usage |
264 | //usage: "UBI_DEVICE -n VOLID -s SIZE" | 273 | //usage: "-n VOLID -s SIZE UBI_DEVICE" |
265 | //usage:#define ubirsvol_full_usage "\n\n" | 274 | //usage:#define ubirsvol_full_usage "\n\n" |
266 | //usage: "Resize UBI volume\n" | 275 | //usage: "Resize UBI volume\n" |
267 | //usage: "\n -n VOLID Volume ID" | 276 | //usage: "\n -n VOLID Volume ID" |
@@ -279,7 +288,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
279 | } else | 288 | } else |
280 | 289 | ||
281 | //usage:#define ubiupdatevol_trivial_usage | 290 | //usage:#define ubiupdatevol_trivial_usage |
282 | //usage: "UBI_DEVICE [-t | [-s SIZE] IMG_FILE]" | 291 | //usage: "[-t | [-s SIZE] IMG_FILE] UBI_DEVICE" |
283 | //usage:#define ubiupdatevol_full_usage "\n\n" | 292 | //usage:#define ubiupdatevol_full_usage "\n\n" |
284 | //usage: "Update UBI volume\n" | 293 | //usage: "Update UBI volume\n" |
285 | //usage: "\n -t Truncate to zero size" | 294 | //usage: "\n -t Truncate to zero size" |
diff --git a/miscutils/ubirename.c b/miscutils/ubirename.c new file mode 100644 index 000000000..8b1c3785a --- /dev/null +++ b/miscutils/ubirename.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* ubirename - port of the ubirename from the mtd-utils package | ||
2 | * | ||
3 | * A utility to rename one UBI volume. | ||
4 | * | ||
5 | * 2016-03-01 Sven Eisenberg <sven.eisenberg@novero.com> | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | //config:config UBIRENAME | ||
10 | //config: bool "ubirename" | ||
11 | //config: default y | ||
12 | //config: select PLATFORM_LINUX | ||
13 | //config: help | ||
14 | //config: Utility to rename UBI volumes | ||
15 | |||
16 | //applet:IF_UBIRENAME(APPLET(ubirename, BB_DIR_USR_SBIN, BB_SUID_DROP)) | ||
17 | |||
18 | //kbuild:lib-$(CONFIG_UBIRENAME) += ubirename.o | ||
19 | |||
20 | //usage:#define ubirename_trivial_usage | ||
21 | //usage: "UBI_DEVICE OLD_VOLNAME NEW_VOLNAME [OLD2 NEW2]..." | ||
22 | //usage:#define ubirename_full_usage "\n\n" | ||
23 | //usage: "Rename UBI volumes on UBI_DEVICE" | ||
24 | |||
25 | #include "libbb.h" | ||
26 | #include <mtd/mtd-user.h> | ||
27 | |||
28 | #ifndef __packed | ||
29 | # define __packed __attribute__((packed)) | ||
30 | #endif | ||
31 | |||
32 | // from ubi-media.h | ||
33 | #define UBI_MAX_VOLUME_NAME 127 | ||
34 | #define UBI_MAX_VOLUMES 128 | ||
35 | // end ubi-media.h | ||
36 | |||
37 | // from ubi-user.h | ||
38 | /* ioctl commands of UBI character devices */ | ||
39 | #define UBI_IOC_MAGIC 'o' | ||
40 | |||
41 | /* Re-name volumes */ | ||
42 | #define UBI_IOCRNVOL _IOW(UBI_IOC_MAGIC, 3, struct ubi_rnvol_req) | ||
43 | |||
44 | /* Maximum amount of UBI volumes that can be re-named at one go */ | ||
45 | #define UBI_MAX_RNVOL 32 | ||
46 | |||
47 | struct ubi_rnvol_req { | ||
48 | int32_t count; | ||
49 | int8_t padding1[12]; | ||
50 | struct { | ||
51 | int32_t vol_id; | ||
52 | int16_t name_len; | ||
53 | int8_t padding2[2]; | ||
54 | char name[UBI_MAX_VOLUME_NAME + 1]; | ||
55 | } ents[UBI_MAX_RNVOL]; | ||
56 | } __packed; | ||
57 | // end ubi-user.h | ||
58 | |||
59 | int ubirename_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
60 | int ubirename_main(int argc, char **argv) | ||
61 | { | ||
62 | struct ubi_rnvol_req *rnvol; | ||
63 | const char *ubi_devname; | ||
64 | unsigned ubi_devnum; | ||
65 | unsigned n; | ||
66 | |||
67 | /* argc can be 4, 6, 8, ... */ | ||
68 | if ((argc & 1) || (argc >>= 1) < 2) | ||
69 | bb_show_usage(); | ||
70 | |||
71 | rnvol = xzalloc(sizeof(*rnvol)); | ||
72 | rnvol->count = --argc; | ||
73 | if (argc > ARRAY_SIZE(rnvol->ents)) | ||
74 | bb_error_msg_and_die("too many renames requested"); | ||
75 | |||
76 | ubi_devname = argv[1]; | ||
77 | ubi_devnum = ubi_devnum_from_devname(ubi_devname); | ||
78 | |||
79 | n = 0; | ||
80 | argv += 2; | ||
81 | while (argv[0]) { | ||
82 | rnvol->ents[n].vol_id = ubi_get_volid_by_name(ubi_devnum, argv[0]); | ||
83 | rnvol->ents[n].name_len = strlen(argv[1]); | ||
84 | if (rnvol->ents[n].name_len >= sizeof(rnvol->ents[n].name)) | ||
85 | bb_error_msg_and_die("new name '%s' is too long", argv[1]); | ||
86 | strcpy(rnvol->ents[n].name, argv[1]); | ||
87 | n++; | ||
88 | argv += 2; | ||
89 | } | ||
90 | |||
91 | xioctl(xopen(ubi_devname, O_RDONLY), UBI_IOCRNVOL, rnvol); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 997ee3c67..8130c40b7 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
@@ -214,7 +214,7 @@ static void add_probe(const char *name) | |||
214 | static int FAST_FUNC config_file_action(const char *filename, | 214 | static int FAST_FUNC config_file_action(const char *filename, |
215 | struct stat *statbuf UNUSED_PARAM, | 215 | struct stat *statbuf UNUSED_PARAM, |
216 | void *userdata UNUSED_PARAM, | 216 | void *userdata UNUSED_PARAM, |
217 | int depth UNUSED_PARAM) | 217 | int depth) |
218 | { | 218 | { |
219 | char *tokens[3]; | 219 | char *tokens[3]; |
220 | parser_t *p; | 220 | parser_t *p; |
@@ -222,15 +222,20 @@ static int FAST_FUNC config_file_action(const char *filename, | |||
222 | int rc = TRUE; | 222 | int rc = TRUE; |
223 | const char *base, *ext; | 223 | const char *base, *ext; |
224 | 224 | ||
225 | /* Skip files that begin with a ".". */ | 225 | /* Skip files that begin with a "." */ |
226 | base = bb_basename(filename); | 226 | base = bb_basename(filename); |
227 | if (base[0] == '.') | 227 | if (base[0] == '.') |
228 | goto error; | 228 | goto error; |
229 | 229 | ||
230 | /* Skip files that do not end with a ".conf". */ | 230 | /* In dir recursion, skip files that do not end with a ".conf" |
231 | ext = strrchr(base, '.'); | 231 | * depth==0: read_config("modules.{symbols,alias}") must work, |
232 | if (ext == NULL || strcmp(ext + 1, "conf")) | 232 | * "include FILE_NOT_ENDING_IN_CONF" must work too. |
233 | goto error; | 233 | */ |
234 | if (depth != 0) { | ||
235 | ext = strrchr(base, '.'); | ||
236 | if (ext == NULL || strcmp(ext + 1, "conf")) | ||
237 | goto error; | ||
238 | } | ||
234 | 239 | ||
235 | p = config_open2(filename, fopen_for_read); | 240 | p = config_open2(filename, fopen_for_read); |
236 | if (p == NULL) { | 241 | if (p == NULL) { |
@@ -275,7 +280,7 @@ static int FAST_FUNC config_file_action(const char *filename, | |||
275 | m = get_or_add_modentry(tokens[1]); | 280 | m = get_or_add_modentry(tokens[1]); |
276 | m->options = gather_options_str(m->options, tokens[2]); | 281 | m->options = gather_options_str(m->options, tokens[2]); |
277 | } else if (strcmp(tokens[0], "include") == 0) { | 282 | } else if (strcmp(tokens[0], "include") == 0) { |
278 | /* include <filename> */ | 283 | /* include <filename>/<dirname> (yes, directories also must work) */ |
279 | read_config(tokens[1]); | 284 | read_config(tokens[1]); |
280 | } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST | 285 | } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST |
281 | && strcmp(tokens[0], "blacklist") == 0 | 286 | && strcmp(tokens[0], "blacklist") == 0 |
@@ -292,7 +297,8 @@ static int FAST_FUNC config_file_action(const char *filename, | |||
292 | static int read_config(const char *path) | 297 | static int read_config(const char *path) |
293 | { | 298 | { |
294 | return recursive_action(path, ACTION_RECURSE | ACTION_QUIET, | 299 | return recursive_action(path, ACTION_RECURSE | ACTION_QUIET, |
295 | config_file_action, NULL, NULL, 1); | 300 | config_file_action, NULL, NULL, |
301 | /*depth:*/ 0); | ||
296 | } | 302 | } |
297 | 303 | ||
298 | static const char *humanly_readable_name(struct module_entry *m) | 304 | static const char *humanly_readable_name(struct module_entry *m) |
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 766dfabbd..2c6db926f 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -850,7 +850,6 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in | |||
850 | char *iface_name; | 850 | char *iface_name; |
851 | char *address_family_name; | 851 | char *address_family_name; |
852 | char *method_name; | 852 | char *method_name; |
853 | llist_t *iface_list; | ||
854 | 853 | ||
855 | currif = xzalloc(sizeof(*currif)); | 854 | currif = xzalloc(sizeof(*currif)); |
856 | iface_name = next_word(&rest_of_line); | 855 | iface_name = next_word(&rest_of_line); |
@@ -875,7 +874,20 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in | |||
875 | currif->method = get_method(currif->address_family, method_name); | 874 | currif->method = get_method(currif->address_family, method_name); |
876 | if (!currif->method) | 875 | if (!currif->method) |
877 | bb_error_msg_and_die("unknown method \"%s\"", method_name); | 876 | bb_error_msg_and_die("unknown method \"%s\"", method_name); |
878 | 877 | #if 0 | |
878 | // Allegedly, Debian allows a duplicate definition: | ||
879 | // iface eth0 inet static | ||
880 | // address 192.168.0.15 | ||
881 | // netmask 255.255.0.0 | ||
882 | // gateway 192.168.0.1 | ||
883 | // | ||
884 | // iface eth0 inet static | ||
885 | // address 10.0.0.1 | ||
886 | // netmask 255.255.255.0 | ||
887 | // | ||
888 | // This adds *two* addresses to eth0 (probably requires use of "ip", not "ifconfig" | ||
889 | // | ||
890 | llist_t *iface_list; | ||
879 | for (iface_list = defn->ifaces; iface_list; iface_list = iface_list->link) { | 891 | for (iface_list = defn->ifaces; iface_list; iface_list = iface_list->link) { |
880 | struct interface_defn_t *tmp = (struct interface_defn_t *) iface_list->data; | 892 | struct interface_defn_t *tmp = (struct interface_defn_t *) iface_list->data; |
881 | if ((strcmp(tmp->iface, currif->iface) == 0) | 893 | if ((strcmp(tmp->iface, currif->iface) == 0) |
@@ -884,6 +896,7 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in | |||
884 | bb_error_msg_and_die("duplicate interface \"%s\"", tmp->iface); | 896 | bb_error_msg_and_die("duplicate interface \"%s\"", tmp->iface); |
885 | } | 897 | } |
886 | } | 898 | } |
899 | #endif | ||
887 | llist_add_to_end(&(defn->ifaces), (char*)currif); | 900 | llist_add_to_end(&(defn->ifaces), (char*)currif); |
888 | 901 | ||
889 | debug_noise("iface %s %s %s\n", currif->iface, address_family_name, method_name); | 902 | debug_noise("iface %s %s %s\n", currif->iface, address_family_name, method_name); |
diff --git a/networking/inetd.c b/networking/inetd.c index 243165a07..4f6673b12 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -834,10 +834,10 @@ static NOINLINE servtab_t *parse_one_line(void) | |||
834 | goto parse_err; | 834 | goto parse_err; |
835 | } | 835 | } |
836 | 836 | ||
837 | // bb_info_msg( | 837 | //bb_error_msg( |
838 | // "ENTRY[%s][%s][%s][%d][%d][%d][%d][%d][%s][%s][%s]", | 838 | // "ENTRY[%s][%s][%s][%d][%d][%d][%d][%d][%s][%s][%s]", |
839 | // sep->se_local_hostname, sep->se_service, sep->se_proto, sep->se_wait, sep->se_proto_no, | 839 | // sep->se_local_hostname, sep->se_service, sep->se_proto, sep->se_wait, sep->se_proto_no, |
840 | // sep->se_max, sep->se_count, sep->se_time, sep->se_user, sep->se_group, sep->se_program); | 840 | // sep->se_max, sep->se_count, sep->se_time, sep->se_user, sep->se_group, sep->se_program); |
841 | 841 | ||
842 | /* check if the hostname specifier is a comma separated list | 842 | /* check if the hostname specifier is a comma separated list |
843 | * of hostnames. we'll make new entries for each address. */ | 843 | * of hostnames. we'll make new entries for each address. */ |
diff --git a/networking/ntpd.c b/networking/ntpd.c index 1651670d9..410318979 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -267,6 +267,7 @@ typedef struct { | |||
267 | 267 | ||
268 | typedef struct { | 268 | typedef struct { |
269 | len_and_sockaddr *p_lsa; | 269 | len_and_sockaddr *p_lsa; |
270 | char *p_hostname; | ||
270 | char *p_dotted; | 271 | char *p_dotted; |
271 | int p_fd; | 272 | int p_fd; |
272 | int datapoint_idx; | 273 | int datapoint_idx; |
@@ -727,7 +728,7 @@ reset_peer_stats(peer_t *p, double offset) | |||
727 | 728 | ||
728 | /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP | 729 | /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP |
729 | * and clear reachable bits, but this proved to be too agressive: | 730 | * and clear reachable bits, but this proved to be too agressive: |
730 | * after step (tested with suspinding laptop for ~30 secs), | 731 | * after step (tested with suspending laptop for ~30 secs), |
731 | * this caused all previous data to be considered invalid, | 732 | * this caused all previous data to be considered invalid, |
732 | * making us needing to collect full ~8 datapoins per peer | 733 | * making us needing to collect full ~8 datapoins per peer |
733 | * after step in order to start trusting them. | 734 | * after step in order to start trusting them. |
@@ -766,11 +767,29 @@ reset_peer_stats(peer_t *p, double offset) | |||
766 | static void | 767 | static void |
767 | add_peers(const char *s) | 768 | add_peers(const char *s) |
768 | { | 769 | { |
770 | llist_t *item; | ||
769 | peer_t *p; | 771 | peer_t *p; |
770 | 772 | ||
771 | p = xzalloc(sizeof(*p)); | 773 | p = xzalloc(sizeof(*p)); |
772 | p->p_lsa = xhost2sockaddr(s, 123); | 774 | p->p_lsa = xhost2sockaddr(s, 123); |
773 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); | 775 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); |
776 | |||
777 | /* Names like N.<country2chars>.pool.ntp.org are randomly resolved | ||
778 | * to a pool of machines. Sometimes different N's resolve to the same IP. | ||
779 | * It is not useful to have two peers with same IP. We skip duplicates. | ||
780 | */ | ||
781 | for (item = G.ntp_peers; item != NULL; item = item->link) { | ||
782 | peer_t *pp = (peer_t *) item->data; | ||
783 | if (strcmp(p->p_dotted, pp->p_dotted) == 0) { | ||
784 | bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); | ||
785 | free(p->p_lsa); | ||
786 | free(p->p_dotted); | ||
787 | free(p); | ||
788 | return; | ||
789 | } | ||
790 | } | ||
791 | |||
792 | p->p_hostname = xstrdup(s); | ||
774 | p->p_fd = -1; | 793 | p->p_fd = -1; |
775 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); | 794 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); |
776 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ | 795 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ |
@@ -1685,8 +1704,14 @@ update_local_clock(peer_t *p) | |||
1685 | VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", | 1704 | VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", |
1686 | rc, tmx.freq, tmx.offset, tmx.status); | 1705 | rc, tmx.freq, tmx.offset, tmx.status); |
1687 | G.kernel_freq_drift = tmx.freq / 65536; | 1706 | G.kernel_freq_drift = tmx.freq / 65536; |
1688 | VERB2 bb_error_msg("update from:%s offset:%+f jitter:%f clock drift:%+.3fppm tc:%d", | 1707 | VERB2 bb_error_msg("update from:%s offset:%+f delay:%f jitter:%f clock drift:%+.3fppm tc:%d", |
1689 | p->p_dotted, offset, G.discipline_jitter, (double)tmx.freq / 65536, (int)tmx.constant); | 1708 | p->p_dotted, |
1709 | offset, | ||
1710 | p->lastpkt_delay, | ||
1711 | G.discipline_jitter, | ||
1712 | (double)tmx.freq / 65536, | ||
1713 | (int)tmx.constant | ||
1714 | ); | ||
1690 | 1715 | ||
1691 | return 1; /* "ok to increase poll interval" */ | 1716 | return 1; /* "ok to increase poll interval" */ |
1692 | } | 1717 | } |
@@ -1947,8 +1972,8 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1947 | adjust_poll(MINPOLL); | 1972 | adjust_poll(MINPOLL); |
1948 | } else { | 1973 | } else { |
1949 | VERB3 if (rc > 0) | 1974 | VERB3 if (rc > 0) |
1950 | bb_error_msg("want smaller poll interval: offset/jitter > %u", | 1975 | bb_error_msg("want smaller interval: offset/jitter = %u", |
1951 | POLLADJ_GATE); | 1976 | G.offset_to_jitter_ratio); |
1952 | adjust_poll(-G.poll_exp * 2); | 1977 | adjust_poll(-G.poll_exp * 2); |
1953 | } | 1978 | } |
1954 | } | 1979 | } |
@@ -2311,6 +2336,21 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
2311 | timeout = poll_interval(NOREPLY_INTERVAL); | 2336 | timeout = poll_interval(NOREPLY_INTERVAL); |
2312 | bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us", | 2337 | bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us", |
2313 | p->p_dotted, p->reachable_bits, timeout); | 2338 | p->p_dotted, p->reachable_bits, timeout); |
2339 | |||
2340 | /* What if don't see it because it changed its IP? */ | ||
2341 | if (p->reachable_bits == 0) { | ||
2342 | len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123); | ||
2343 | if (lsa) { | ||
2344 | char *dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); | ||
2345 | //if (strcmp(dotted, p->p_dotted) != 0) | ||
2346 | // bb_error_msg("peer IP changed"); | ||
2347 | free(p->p_lsa); | ||
2348 | free(p->p_dotted); | ||
2349 | p->p_lsa = lsa; | ||
2350 | p->p_dotted = dotted; | ||
2351 | } | ||
2352 | } | ||
2353 | |||
2314 | set_next(p, timeout); | 2354 | set_next(p, timeout); |
2315 | } | 2355 | } |
2316 | } | 2356 | } |
diff --git a/networking/ntpd.diff b/networking/ntpd.diff new file mode 100644 index 000000000..4afd7e134 --- /dev/null +++ b/networking/ntpd.diff | |||
@@ -0,0 +1,24 @@ | |||
1 | This patch scales down small offsets quadratically. Reduces sensitivity to jitter | ||
2 | |||
3 | diff --git a/networking/ntpd.c b/networking/ntpd.c | ||
4 | index 4695c33..ac05815 100644 | ||
5 | --- a/networking/ntpd.c | ||
6 | +++ b/networking/ntpd.c | ||
7 | @@ -1654,6 +1654,17 @@ update_local_clock(peer_t *p) | ||
8 | */ | ||
9 | if (G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) | ||
10 | tmx.constant--; | ||
11 | + | ||
12 | +{ | ||
13 | + double d = p->lastpkt_delay; | ||
14 | + if (d > SLEW_THRESHOLD) | ||
15 | + d = SLEW_THRESHOLD; | ||
16 | + d /= 2; | ||
17 | + if ((abs_offset / d) < 1) { | ||
18 | + offset *= (abs_offset / d); | ||
19 | + } | ||
20 | +} | ||
21 | + | ||
22 | tmx.offset = (long)(offset * 1000000); /* usec */ | ||
23 | if (SLEW_THRESHOLD < STEP_THRESHOLD) { | ||
24 | if (tmx.offset > (long)(SLEW_THRESHOLD * 1000000)) { | ||
diff --git a/networking/traceroute.c b/networking/traceroute.c index 642110c54..eee4f8873 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -497,7 +497,7 @@ send_probe(int seq, int ttl) | |||
497 | 497 | ||
498 | res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len); | 498 | res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len); |
499 | if (res != len) | 499 | if (res != len) |
500 | bb_info_msg("sent %d octets, ret=%d", len, res); | 500 | bb_error_msg("sent %d octets, ret=%d", len, res); |
501 | } | 501 | } |
502 | 502 | ||
503 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE | 503 | #if ENABLE_FEATURE_TRACEROUTE_VERBOSE |
diff --git a/networking/tunctl.c b/networking/tunctl.c index 3a0870eb5..941e8bbd3 100644 --- a/networking/tunctl.c +++ b/networking/tunctl.c | |||
@@ -82,7 +82,7 @@ int tunctl_main(int argc UNUSED_PARAM, char **argv) | |||
82 | // delete? | 82 | // delete? |
83 | if (opts & OPT_d) { | 83 | if (opts & OPT_d) { |
84 | IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0); | 84 | IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0); |
85 | bb_info_msg("Set '%s' %spersistent", ifr.ifr_name, "non"); | 85 | printf("Set '%s' nonpersistent\n", ifr.ifr_name); |
86 | return EXIT_SUCCESS; | 86 | return EXIT_SUCCESS; |
87 | } | 87 | } |
88 | 88 | ||
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c index fad2283c3..c98027316 100644 --- a/networking/udhcp/arpping.c +++ b/networking/udhcp/arpping.c | |||
@@ -132,6 +132,6 @@ int FAST_FUNC arpping(uint32_t test_nip, | |||
132 | 132 | ||
133 | ret: | 133 | ret: |
134 | close(s); | 134 | close(s); |
135 | log1("%srp reply received for this address", rv ? "No a" : "A"); | 135 | log1("%srp reply received for this address", rv ? "no a" : "A"); |
136 | return rv; | 136 | return rv; |
137 | } | 137 | } |
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index bc41c8d4d..0cf4dab63 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -142,7 +142,7 @@ const char dhcp_option_strings[] ALIGN1 = | |||
142 | * udhcp_str2optset: to determine how many bytes to allocate. | 142 | * udhcp_str2optset: to determine how many bytes to allocate. |
143 | * xmalloc_optname_optval: to estimate string length | 143 | * xmalloc_optname_optval: to estimate string length |
144 | * from binary option length: (option[LEN] / dhcp_option_lengths[opt_type]) | 144 | * from binary option length: (option[LEN] / dhcp_option_lengths[opt_type]) |
145 | * is the number of elements, multiply in by one element's string width | 145 | * is the number of elements, multiply it by one element's string width |
146 | * (len_of_option_as_string[opt_type]) and you know how wide string you need. | 146 | * (len_of_option_as_string[opt_type]) and you know how wide string you need. |
147 | */ | 147 | */ |
148 | const uint8_t dhcp_option_lengths[] ALIGN1 = { | 148 | const uint8_t dhcp_option_lengths[] ALIGN1 = { |
@@ -162,7 +162,18 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { | |||
162 | [OPTION_S32] = 4, | 162 | [OPTION_S32] = 4, |
163 | /* Just like OPTION_STRING, we use minimum length here */ | 163 | /* Just like OPTION_STRING, we use minimum length here */ |
164 | [OPTION_STATIC_ROUTES] = 5, | 164 | [OPTION_STATIC_ROUTES] = 5, |
165 | [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */ | 165 | [OPTION_6RD] = 12, /* ignored by udhcp_str2optset */ |
166 | /* The above value was chosen as follows: | ||
167 | * len_of_option_as_string[] for this option is >60: it's a string of the form | ||
168 | * "32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 ". | ||
169 | * Each additional ipv4 address takes 4 bytes in binary option and appends | ||
170 | * another "255.255.255.255 " 16-byte string. We can set [OPTION_6RD] = 4 | ||
171 | * but this severely overestimates string length: instead of 16 bytes, | ||
172 | * it adds >60 for every 4 bytes in binary option. | ||
173 | * We cheat and declare here that option is in units of 12 bytes. | ||
174 | * This adds more than 60 bytes for every three ipv4 addresses - more than enough. | ||
175 | * (Even 16 instead of 12 should work, but let's be paranoid). | ||
176 | */ | ||
166 | }; | 177 | }; |
167 | 178 | ||
168 | 179 | ||
@@ -172,7 +183,7 @@ static void log_option(const char *pfx, const uint8_t *opt) | |||
172 | if (dhcp_verbose >= 2) { | 183 | if (dhcp_verbose >= 2) { |
173 | char buf[256 * 2 + 2]; | 184 | char buf[256 * 2 + 2]; |
174 | *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0'; | 185 | *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0'; |
175 | bb_info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); | 186 | bb_error_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); |
176 | } | 187 | } |
177 | } | 188 | } |
178 | #else | 189 | #else |
@@ -246,7 +257,7 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |||
246 | continue; /* complain and return NULL */ | 257 | continue; /* complain and return NULL */ |
247 | 258 | ||
248 | if (optionptr[OPT_CODE] == code) { | 259 | if (optionptr[OPT_CODE] == code) { |
249 | log_option("Option found", optionptr); | 260 | log_option("option found", optionptr); |
250 | return optionptr + OPT_DATA; | 261 | return optionptr + OPT_DATA; |
251 | } | 262 | } |
252 | 263 | ||
@@ -258,7 +269,7 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |||
258 | } | 269 | } |
259 | 270 | ||
260 | /* log3 because udhcpc uses it a lot - very noisy */ | 271 | /* log3 because udhcpc uses it a lot - very noisy */ |
261 | log3("Option 0x%02x not found", code); | 272 | log3("option 0x%02x not found", code); |
262 | return NULL; | 273 | return NULL; |
263 | } | 274 | } |
264 | 275 | ||
@@ -292,7 +303,7 @@ void FAST_FUNC udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addo | |||
292 | addopt[OPT_CODE]); | 303 | addopt[OPT_CODE]); |
293 | return; | 304 | return; |
294 | } | 305 | } |
295 | log_option("Adding option", addopt); | 306 | log_option("adding option", addopt); |
296 | memcpy(optionptr + end, addopt, len); | 307 | memcpy(optionptr + end, addopt, len); |
297 | optionptr[end + len] = DHCP_END; | 308 | optionptr[end + len] = DHCP_END; |
298 | } | 309 | } |
@@ -391,7 +402,7 @@ static NOINLINE void attach_option( | |||
391 | struct option_set *new, **curr; | 402 | struct option_set *new, **curr; |
392 | 403 | ||
393 | /* make a new option */ | 404 | /* make a new option */ |
394 | log2("Attaching option %02x to list", optflag->code); | 405 | log2("attaching option %02x to list", optflag->code); |
395 | new = xmalloc(sizeof(*new)); | 406 | new = xmalloc(sizeof(*new)); |
396 | new->data = xmalloc(length + OPT_DATA); | 407 | new->data = xmalloc(length + OPT_DATA); |
397 | new->data[OPT_CODE] = optflag->code; | 408 | new->data[OPT_CODE] = optflag->code; |
@@ -411,7 +422,7 @@ static NOINLINE void attach_option( | |||
411 | unsigned old_len; | 422 | unsigned old_len; |
412 | 423 | ||
413 | /* add it to an existing option */ | 424 | /* add it to an existing option */ |
414 | log2("Attaching option %02x to existing member of list", optflag->code); | 425 | log2("attaching option %02x to existing member of list", optflag->code); |
415 | old_len = existing->data[OPT_LEN]; | 426 | old_len = existing->data[OPT_LEN]; |
416 | if (old_len + length < 255) { | 427 | if (old_len + length < 255) { |
417 | /* actually 255 is ok too, but adding a space can overlow it */ | 428 | /* actually 255 is ok too, but adding a space can overlow it */ |
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index d20659e2f..496ab11a1 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -256,16 +256,16 @@ struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) | |||
256 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | 256 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 |
257 | # define IF_UDHCP_VERBOSE(...) __VA_ARGS__ | 257 | # define IF_UDHCP_VERBOSE(...) __VA_ARGS__ |
258 | extern unsigned dhcp_verbose; | 258 | extern unsigned dhcp_verbose; |
259 | # define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) | 259 | # define log1(...) do { if (dhcp_verbose >= 1) bb_error_msg(__VA_ARGS__); } while (0) |
260 | # if CONFIG_UDHCP_DEBUG >= 2 | 260 | # if CONFIG_UDHCP_DEBUG >= 2 |
261 | void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; | 261 | void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; |
262 | # define log2(...) do { if (dhcp_verbose >= 2) bb_info_msg(__VA_ARGS__); } while (0) | 262 | # define log2(...) do { if (dhcp_verbose >= 2) bb_error_msg(__VA_ARGS__); } while (0) |
263 | # else | 263 | # else |
264 | # define udhcp_dump_packet(...) ((void)0) | 264 | # define udhcp_dump_packet(...) ((void)0) |
265 | # define log2(...) ((void)0) | 265 | # define log2(...) ((void)0) |
266 | # endif | 266 | # endif |
267 | # if CONFIG_UDHCP_DEBUG >= 3 | 267 | # if CONFIG_UDHCP_DEBUG >= 3 |
268 | # define log3(...) do { if (dhcp_verbose >= 3) bb_info_msg(__VA_ARGS__); } while (0) | 268 | # define log3(...) do { if (dhcp_verbose >= 3) bb_error_msg(__VA_ARGS__); } while (0) |
269 | # else | 269 | # else |
270 | # define log3(...) ((void)0) | 270 | # define log3(...) ((void)0) |
271 | # endif | 271 | # endif |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 4e9b705b9..422254d62 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -251,7 +251,7 @@ static void d6_run_script(struct d6_packet *packet, const char *name) | |||
251 | envp = fill_envp(packet); | 251 | envp = fill_envp(packet); |
252 | 252 | ||
253 | /* call script */ | 253 | /* call script */ |
254 | log1("Executing %s %s", client_config.script, name); | 254 | log1("executing %s %s", client_config.script, name); |
255 | argv[0] = (char*) client_config.script; | 255 | argv[0] = (char*) client_config.script; |
256 | argv[1] = (char*) name; | 256 | argv[1] = (char*) name; |
257 | argv[2] = NULL; | 257 | argv[2] = NULL; |
@@ -428,7 +428,7 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip | |||
428 | */ | 428 | */ |
429 | opt_ptr = add_d6_client_options(opt_ptr); | 429 | opt_ptr = add_d6_client_options(opt_ptr); |
430 | 430 | ||
431 | bb_info_msg("Sending discover..."); | 431 | bb_error_msg("sending %s", "discover"); |
432 | return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); | 432 | return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); |
433 | } | 433 | } |
434 | 434 | ||
@@ -481,7 +481,7 @@ static NOINLINE int send_d6_select(uint32_t xid) | |||
481 | */ | 481 | */ |
482 | opt_ptr = add_d6_client_options(opt_ptr); | 482 | opt_ptr = add_d6_client_options(opt_ptr); |
483 | 483 | ||
484 | bb_info_msg("Sending select..."); | 484 | bb_error_msg("sending %s", "select"); |
485 | return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); | 485 | return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); |
486 | } | 486 | } |
487 | 487 | ||
@@ -550,7 +550,7 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st | |||
550 | */ | 550 | */ |
551 | opt_ptr = add_d6_client_options(opt_ptr); | 551 | opt_ptr = add_d6_client_options(opt_ptr); |
552 | 552 | ||
553 | bb_info_msg("Sending renew..."); | 553 | bb_error_msg("sending %s", "renew"); |
554 | if (server_ipv6) | 554 | if (server_ipv6) |
555 | return d6_send_kernel_packet( | 555 | return d6_send_kernel_packet( |
556 | &packet, (opt_ptr - (uint8_t*) &packet), | 556 | &packet, (opt_ptr - (uint8_t*) &packet), |
@@ -573,7 +573,7 @@ static int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cu | |||
573 | /* IA NA (contains our current IP) */ | 573 | /* IA NA (contains our current IP) */ |
574 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); | 574 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); |
575 | 575 | ||
576 | bb_info_msg("Sending release..."); | 576 | bb_error_msg("sending %s", "release"); |
577 | return d6_send_kernel_packet( | 577 | return d6_send_kernel_packet( |
578 | &packet, (opt_ptr - (uint8_t*) &packet), | 578 | &packet, (opt_ptr - (uint8_t*) &packet), |
579 | our_cur_ipv6, CLIENT_PORT6, | 579 | our_cur_ipv6, CLIENT_PORT6, |
@@ -592,19 +592,19 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 | |||
592 | 592 | ||
593 | bytes = safe_read(fd, &packet, sizeof(packet)); | 593 | bytes = safe_read(fd, &packet, sizeof(packet)); |
594 | if (bytes < 0) { | 594 | if (bytes < 0) { |
595 | log1("Packet read error, ignoring"); | 595 | log1("packet read error, ignoring"); |
596 | /* NB: possible down interface, etc. Caller should pause. */ | 596 | /* NB: possible down interface, etc. Caller should pause. */ |
597 | return bytes; /* returns -1 */ | 597 | return bytes; /* returns -1 */ |
598 | } | 598 | } |
599 | 599 | ||
600 | if (bytes < (int) (sizeof(packet.ip6) + sizeof(packet.udp))) { | 600 | if (bytes < (int) (sizeof(packet.ip6) + sizeof(packet.udp))) { |
601 | log1("Packet is too short, ignoring"); | 601 | log1("packet is too short, ignoring"); |
602 | return -2; | 602 | return -2; |
603 | } | 603 | } |
604 | 604 | ||
605 | if (bytes < sizeof(packet.ip6) + ntohs(packet.ip6.ip6_plen)) { | 605 | if (bytes < sizeof(packet.ip6) + ntohs(packet.ip6.ip6_plen)) { |
606 | /* packet is bigger than sizeof(packet), we did partial read */ | 606 | /* packet is bigger than sizeof(packet), we did partial read */ |
607 | log1("Oversized packet, ignoring"); | 607 | log1("oversized packet, ignoring"); |
608 | return -2; | 608 | return -2; |
609 | } | 609 | } |
610 | 610 | ||
@@ -618,7 +618,7 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 | |||
618 | /* || bytes > (int) sizeof(packet) - can't happen */ | 618 | /* || bytes > (int) sizeof(packet) - can't happen */ |
619 | || packet.udp.len != packet.ip6.ip6_plen | 619 | || packet.udp.len != packet.ip6.ip6_plen |
620 | ) { | 620 | ) { |
621 | log1("Unrelated/bogus packet, ignoring"); | 621 | log1("unrelated/bogus packet, ignoring"); |
622 | return -2; | 622 | return -2; |
623 | } | 623 | } |
624 | 624 | ||
@@ -630,11 +630,11 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 | |||
630 | // check = packet.udp.check; | 630 | // check = packet.udp.check; |
631 | // packet.udp.check = 0; | 631 | // packet.udp.check = 0; |
632 | // if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { | 632 | // if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { |
633 | // log1("Packet with bad UDP checksum received, ignoring"); | 633 | // log1("packet with bad UDP checksum received, ignoring"); |
634 | // return -2; | 634 | // return -2; |
635 | // } | 635 | // } |
636 | 636 | ||
637 | log1("Received a packet"); | 637 | log1("received %s", "a packet"); |
638 | d6_dump_packet(&packet.data); | 638 | d6_dump_packet(&packet.data); |
639 | 639 | ||
640 | bytes -= sizeof(packet.ip6) + sizeof(packet.udp); | 640 | bytes -= sizeof(packet.ip6) + sizeof(packet.udp); |
@@ -722,10 +722,10 @@ static int d6_raw_socket(int ifindex) | |||
722 | }; | 722 | }; |
723 | #endif | 723 | #endif |
724 | 724 | ||
725 | log1("Opening raw socket on ifindex %d", ifindex); //log2? | 725 | log1("opening raw socket on ifindex %d", ifindex); //log2? |
726 | 726 | ||
727 | fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); | 727 | fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); |
728 | log1("Got raw socket fd %d", fd); //log2? | 728 | log1("got raw socket fd %d", fd); //log2? |
729 | 729 | ||
730 | sock.sll_family = AF_PACKET; | 730 | sock.sll_family = AF_PACKET; |
731 | sock.sll_protocol = htons(ETH_P_IPV6); | 731 | sock.sll_protocol = htons(ETH_P_IPV6); |
@@ -738,18 +738,18 @@ static int d6_raw_socket(int ifindex) | |||
738 | /* Ignoring error (kernel may lack support for this) */ | 738 | /* Ignoring error (kernel may lack support for this) */ |
739 | if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, | 739 | if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, |
740 | sizeof(filter_prog)) >= 0) | 740 | sizeof(filter_prog)) >= 0) |
741 | log1("Attached filter to raw socket fd %d", fd); // log? | 741 | log1("attached filter to raw socket fd %d", fd); // log? |
742 | } | 742 | } |
743 | #endif | 743 | #endif |
744 | 744 | ||
745 | log1("Created raw socket"); | 745 | log1("created raw socket"); |
746 | 746 | ||
747 | return fd; | 747 | return fd; |
748 | } | 748 | } |
749 | 749 | ||
750 | static void change_listen_mode(int new_mode) | 750 | static void change_listen_mode(int new_mode) |
751 | { | 751 | { |
752 | log1("Entering listen mode: %s", | 752 | log1("entering listen mode: %s", |
753 | new_mode != LISTEN_NONE | 753 | new_mode != LISTEN_NONE |
754 | ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw") | 754 | ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw") |
755 | : "none" | 755 | : "none" |
@@ -770,7 +770,7 @@ static void change_listen_mode(int new_mode) | |||
770 | /* Called only on SIGUSR1 */ | 770 | /* Called only on SIGUSR1 */ |
771 | static void perform_renew(void) | 771 | static void perform_renew(void) |
772 | { | 772 | { |
773 | bb_info_msg("Performing a DHCP renew"); | 773 | bb_error_msg("performing DHCP renew"); |
774 | switch (state) { | 774 | switch (state) { |
775 | case BOUND: | 775 | case BOUND: |
776 | change_listen_mode(LISTEN_KERNEL); | 776 | change_listen_mode(LISTEN_KERNEL); |
@@ -794,11 +794,11 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou | |||
794 | { | 794 | { |
795 | /* send release packet */ | 795 | /* send release packet */ |
796 | if (state == BOUND || state == RENEWING || state == REBINDING) { | 796 | if (state == BOUND || state == RENEWING || state == REBINDING) { |
797 | bb_info_msg("Unicasting a release"); | 797 | bb_error_msg("unicasting a release"); |
798 | send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ | 798 | send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ |
799 | d6_run_script(NULL, "deconfig"); | 799 | d6_run_script(NULL, "deconfig"); |
800 | } | 800 | } |
801 | bb_info_msg("Entering released state"); | 801 | bb_error_msg("entering released state"); |
802 | 802 | ||
803 | change_listen_mode(LISTEN_NONE); | 803 | change_listen_mode(LISTEN_NONE); |
804 | state = RELEASED; | 804 | state = RELEASED; |
@@ -1034,7 +1034,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1034 | /* Create pidfile */ | 1034 | /* Create pidfile */ |
1035 | write_pidfile(client_config.pidfile); | 1035 | write_pidfile(client_config.pidfile); |
1036 | /* Goes to stdout (unless NOMMU) and possibly syslog */ | 1036 | /* Goes to stdout (unless NOMMU) and possibly syslog */ |
1037 | bb_info_msg("%s (v"BB_VER") started", applet_name); | 1037 | bb_error_msg("started, v"BB_VER); |
1038 | /* Set up the signal pipe */ | 1038 | /* Set up the signal pipe */ |
1039 | udhcp_sp_setup(); | 1039 | udhcp_sp_setup(); |
1040 | /* We want random_xid to be random... */ | 1040 | /* We want random_xid to be random... */ |
@@ -1074,7 +1074,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1074 | retval = 0; | 1074 | retval = 0; |
1075 | /* If we already timed out, fall through with retval = 0, else... */ | 1075 | /* If we already timed out, fall through with retval = 0, else... */ |
1076 | if ((int)tv.tv_sec > 0) { | 1076 | if ((int)tv.tv_sec > 0) { |
1077 | log1("Waiting on select %u seconds", (int)tv.tv_sec); | 1077 | log1("waiting on select %u seconds", (int)tv.tv_sec); |
1078 | timestamp_before_wait = (unsigned)monotonic_sec(); | 1078 | timestamp_before_wait = (unsigned)monotonic_sec(); |
1079 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); | 1079 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); |
1080 | if (retval < 0) { | 1080 | if (retval < 0) { |
@@ -1124,14 +1124,14 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1124 | d6_run_script(NULL, "leasefail"); | 1124 | d6_run_script(NULL, "leasefail"); |
1125 | #if BB_MMU /* -b is not supported on NOMMU */ | 1125 | #if BB_MMU /* -b is not supported on NOMMU */ |
1126 | if (opt & OPT_b) { /* background if no lease */ | 1126 | if (opt & OPT_b) { /* background if no lease */ |
1127 | bb_info_msg("No lease, forking to background"); | 1127 | bb_error_msg("no lease, forking to background"); |
1128 | client_background(); | 1128 | client_background(); |
1129 | /* do not background again! */ | 1129 | /* do not background again! */ |
1130 | opt = ((opt & ~OPT_b) | OPT_f); | 1130 | opt = ((opt & ~OPT_b) | OPT_f); |
1131 | } else | 1131 | } else |
1132 | #endif | 1132 | #endif |
1133 | if (opt & OPT_n) { /* abort if no lease */ | 1133 | if (opt & OPT_n) { /* abort if no lease */ |
1134 | bb_info_msg("No lease, failing"); | 1134 | bb_error_msg("no lease, failing"); |
1135 | retval = 1; | 1135 | retval = 1; |
1136 | goto ret; | 1136 | goto ret; |
1137 | } | 1137 | } |
@@ -1159,7 +1159,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1159 | state = RENEWING; | 1159 | state = RENEWING; |
1160 | client_config.first_secs = 0; /* make secs field count from 0 */ | 1160 | client_config.first_secs = 0; /* make secs field count from 0 */ |
1161 | change_listen_mode(LISTEN_KERNEL); | 1161 | change_listen_mode(LISTEN_KERNEL); |
1162 | log1("Entering renew state"); | 1162 | log1("entering renew state"); |
1163 | /* fall right through */ | 1163 | /* fall right through */ |
1164 | case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ | 1164 | case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ |
1165 | case_RENEW_REQUESTED: | 1165 | case_RENEW_REQUESTED: |
@@ -1179,7 +1179,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1179 | continue; | 1179 | continue; |
1180 | } | 1180 | } |
1181 | /* Timed out, enter rebinding state */ | 1181 | /* Timed out, enter rebinding state */ |
1182 | log1("Entering rebinding state"); | 1182 | log1("entering rebinding state"); |
1183 | state = REBINDING; | 1183 | state = REBINDING; |
1184 | /* fall right through */ | 1184 | /* fall right through */ |
1185 | case REBINDING: | 1185 | case REBINDING: |
@@ -1194,7 +1194,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1194 | continue; | 1194 | continue; |
1195 | } | 1195 | } |
1196 | /* Timed out, enter init state */ | 1196 | /* Timed out, enter init state */ |
1197 | bb_info_msg("Lease lost, entering init state"); | 1197 | bb_error_msg("lease lost, entering init state"); |
1198 | d6_run_script(NULL, "deconfig"); | 1198 | d6_run_script(NULL, "deconfig"); |
1199 | state = INIT_SELECTING; | 1199 | state = INIT_SELECTING; |
1200 | client_config.first_secs = 0; /* make secs field count from 0 */ | 1200 | client_config.first_secs = 0; /* make secs field count from 0 */ |
@@ -1242,7 +1242,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1242 | timeout = INT_MAX; | 1242 | timeout = INT_MAX; |
1243 | continue; | 1243 | continue; |
1244 | case SIGTERM: | 1244 | case SIGTERM: |
1245 | bb_info_msg("Received SIGTERM"); | 1245 | bb_error_msg("received %s", "SIGTERM"); |
1246 | goto ret0; | 1246 | goto ret0; |
1247 | } | 1247 | } |
1248 | 1248 | ||
@@ -1260,7 +1260,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1260 | len = d6_recv_raw_packet(&srv6_buf, &packet, sockfd); | 1260 | len = d6_recv_raw_packet(&srv6_buf, &packet, sockfd); |
1261 | if (len == -1) { | 1261 | if (len == -1) { |
1262 | /* Error is severe, reopen socket */ | 1262 | /* Error is severe, reopen socket */ |
1263 | bb_info_msg("Read error: %s, reopening socket", strerror(errno)); | 1263 | bb_error_msg("read error: %s, reopening socket", strerror(errno)); |
1264 | sleep(discover_timeout); /* 3 seconds by default */ | 1264 | sleep(discover_timeout); /* 3 seconds by default */ |
1265 | change_listen_mode(listen_mode); /* just close and reopen */ | 1265 | change_listen_mode(listen_mode); /* just close and reopen */ |
1266 | } | 1266 | } |
@@ -1298,7 +1298,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1298 | option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE); | 1298 | option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE); |
1299 | if (option && option->data[4] != 0) { | 1299 | if (option && option->data[4] != 0) { |
1300 | /* return to init state */ | 1300 | /* return to init state */ |
1301 | bb_info_msg("Received DHCP NAK (%u)", option->data[4]); | 1301 | bb_error_msg("received DHCP NAK (%u)", option->data[4]); |
1302 | d6_run_script(&packet, "nak"); | 1302 | d6_run_script(&packet, "nak"); |
1303 | if (state != REQUESTING) | 1303 | if (state != REQUESTING) |
1304 | d6_run_script(NULL, "deconfig"); | 1304 | d6_run_script(NULL, "deconfig"); |
@@ -1453,7 +1453,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1453 | lease_seconds = 0x0fffffff; | 1453 | lease_seconds = 0x0fffffff; |
1454 | /* enter bound state */ | 1454 | /* enter bound state */ |
1455 | timeout = lease_seconds / 2; | 1455 | timeout = lease_seconds / 2; |
1456 | bb_info_msg("Lease obtained, lease time %u", | 1456 | bb_error_msg("lease obtained, lease time %u", |
1457 | /*inet_ntoa(temp_addr),*/ (unsigned)lease_seconds); | 1457 | /*inet_ntoa(temp_addr),*/ (unsigned)lease_seconds); |
1458 | d6_run_script(&packet, state == REQUESTING ? "bound" : "renew"); | 1458 | d6_run_script(&packet, state == REQUESTING ? "bound" : "renew"); |
1459 | 1459 | ||
diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c index 79b2946ef..e166f520d 100644 --- a/networking/udhcp/d6_packet.c +++ b/networking/udhcp/d6_packet.c | |||
@@ -17,12 +17,12 @@ void FAST_FUNC d6_dump_packet(struct d6_packet *packet) | |||
17 | if (dhcp_verbose < 2) | 17 | if (dhcp_verbose < 2) |
18 | return; | 18 | return; |
19 | 19 | ||
20 | bb_info_msg( | 20 | bb_error_msg( |
21 | " xid %x" | 21 | "xid %x" |
22 | , packet->d6_xid32 | 22 | , packet->d6_xid32 |
23 | ); | 23 | ); |
24 | //*bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; | 24 | //*bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; |
25 | //bb_info_msg(" chaddr %s", buf); | 25 | //bb_error_msg(" chaddr %s", buf); |
26 | } | 26 | } |
27 | #endif | 27 | #endif |
28 | 28 | ||
@@ -35,15 +35,15 @@ int FAST_FUNC d6_recv_kernel_packet(struct in6_addr *peer_ipv6 | |||
35 | memset(packet, 0, sizeof(*packet)); | 35 | memset(packet, 0, sizeof(*packet)); |
36 | bytes = safe_read(fd, packet, sizeof(*packet)); | 36 | bytes = safe_read(fd, packet, sizeof(*packet)); |
37 | if (bytes < 0) { | 37 | if (bytes < 0) { |
38 | log1("Packet read error, ignoring"); | 38 | log1("packet read error, ignoring"); |
39 | return bytes; /* returns -1 */ | 39 | return bytes; /* returns -1 */ |
40 | } | 40 | } |
41 | 41 | ||
42 | if (bytes < offsetof(struct d6_packet, d6_options)) { | 42 | if (bytes < offsetof(struct d6_packet, d6_options)) { |
43 | bb_info_msg("Packet with bad magic, ignoring"); | 43 | bb_error_msg("packet with bad magic, ignoring"); |
44 | return -2; | 44 | return -2; |
45 | } | 45 | } |
46 | log1("Received a packet"); | 46 | log1("received %s", "a packet"); |
47 | d6_dump_packet(packet); | 47 | d6_dump_packet(packet); |
48 | 48 | ||
49 | return bytes; | 49 | return bytes; |
diff --git a/networking/udhcp/d6_socket.c b/networking/udhcp/d6_socket.c index 56f69f6a1..910f296a3 100644 --- a/networking/udhcp/d6_socket.c +++ b/networking/udhcp/d6_socket.c | |||
@@ -13,7 +13,7 @@ int FAST_FUNC d6_listen_socket(int port, const char *inf) | |||
13 | int fd; | 13 | int fd; |
14 | struct sockaddr_in6 addr; | 14 | struct sockaddr_in6 addr; |
15 | 15 | ||
16 | log1("Opening listen socket on *:%d %s", port, inf); | 16 | log1("opening listen socket on *:%d %s", port, inf); |
17 | fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); | 17 | fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); |
18 | 18 | ||
19 | setsockopt_reuseaddr(fd); | 19 | setsockopt_reuseaddr(fd); |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 48097bc24..660b943ce 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -113,7 +113,7 @@ static const uint8_t len_of_option_as_string[] = { | |||
113 | [OPTION_IP ] = sizeof("255.255.255.255 "), | 113 | [OPTION_IP ] = sizeof("255.255.255.255 "), |
114 | [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, | 114 | [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, |
115 | [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), | 115 | [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), |
116 | [OPTION_6RD ] = sizeof("32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "), | 116 | [OPTION_6RD ] = sizeof("132 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "), |
117 | [OPTION_STRING ] = 1, | 117 | [OPTION_STRING ] = 1, |
118 | [OPTION_STRING_HOST ] = 1, | 118 | [OPTION_STRING_HOST ] = 1, |
119 | #if ENABLE_FEATURE_UDHCP_RFC3397 | 119 | #if ENABLE_FEATURE_UDHCP_RFC3397 |
@@ -222,7 +222,7 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ | |||
222 | type = optflag->flags & OPTION_TYPE_MASK; | 222 | type = optflag->flags & OPTION_TYPE_MASK; |
223 | optlen = dhcp_option_lengths[type]; | 223 | optlen = dhcp_option_lengths[type]; |
224 | upper_length = len_of_option_as_string[type] | 224 | upper_length = len_of_option_as_string[type] |
225 | * ((unsigned)(len + optlen - 1) / (unsigned)optlen); | 225 | * ((unsigned)(len + optlen) / (unsigned)optlen); |
226 | 226 | ||
227 | dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); | 227 | dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); |
228 | dest += sprintf(ret, "%s=", opt_name); | 228 | dest += sprintf(ret, "%s=", opt_name); |
@@ -561,7 +561,7 @@ static void udhcp_run_script(struct dhcp_packet *packet, const char *name) | |||
561 | envp = fill_envp(packet); | 561 | envp = fill_envp(packet); |
562 | 562 | ||
563 | /* call script */ | 563 | /* call script */ |
564 | log1("Executing %s %s", client_config.script, name); | 564 | log1("executing %s %s", client_config.script, name); |
565 | argv[0] = (char*) client_config.script; | 565 | argv[0] = (char*) client_config.script; |
566 | argv[1] = (char*) name; | 566 | argv[1] = (char*) name; |
567 | argv[2] = NULL; | 567 | argv[2] = NULL; |
@@ -675,10 +675,10 @@ static void add_client_options(struct dhcp_packet *packet) | |||
675 | * client reverts to using the IP broadcast address. | 675 | * client reverts to using the IP broadcast address. |
676 | */ | 676 | */ |
677 | 677 | ||
678 | static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet) | 678 | static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint32_t src_nip) |
679 | { | 679 | { |
680 | return udhcp_send_raw_packet(packet, | 680 | return udhcp_send_raw_packet(packet, |
681 | /*src*/ INADDR_ANY, CLIENT_PORT, | 681 | /*src*/ src_nip, CLIENT_PORT, |
682 | /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, | 682 | /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, |
683 | client_config.ifindex); | 683 | client_config.ifindex); |
684 | } | 684 | } |
@@ -689,7 +689,7 @@ static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t | |||
689 | return udhcp_send_kernel_packet(packet, | 689 | return udhcp_send_kernel_packet(packet, |
690 | ciaddr, CLIENT_PORT, | 690 | ciaddr, CLIENT_PORT, |
691 | server, SERVER_PORT); | 691 | server, SERVER_PORT); |
692 | return raw_bcast_from_client_config_ifindex(packet); | 692 | return raw_bcast_from_client_config_ifindex(packet, ciaddr); |
693 | } | 693 | } |
694 | 694 | ||
695 | /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ | 695 | /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ |
@@ -714,8 +714,8 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested) | |||
714 | */ | 714 | */ |
715 | add_client_options(&packet); | 715 | add_client_options(&packet); |
716 | 716 | ||
717 | bb_info_msg("Sending discover..."); | 717 | bb_error_msg("sending %s", "discover"); |
718 | return raw_bcast_from_client_config_ifindex(&packet); | 718 | return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); |
719 | } | 719 | } |
720 | 720 | ||
721 | /* Broadcast a DHCP request message */ | 721 | /* Broadcast a DHCP request message */ |
@@ -758,8 +758,8 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste | |||
758 | add_client_options(&packet); | 758 | add_client_options(&packet); |
759 | 759 | ||
760 | addr.s_addr = requested; | 760 | addr.s_addr = requested; |
761 | bb_info_msg("Sending select for %s...", inet_ntoa(addr)); | 761 | bb_error_msg("sending select for %s", inet_ntoa(addr)); |
762 | return raw_bcast_from_client_config_ifindex(&packet); | 762 | return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); |
763 | } | 763 | } |
764 | 764 | ||
765 | /* Unicast or broadcast a DHCP renew message */ | 765 | /* Unicast or broadcast a DHCP renew message */ |
@@ -797,7 +797,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | |||
797 | */ | 797 | */ |
798 | add_client_options(&packet); | 798 | add_client_options(&packet); |
799 | 799 | ||
800 | bb_info_msg("Sending renew..."); | 800 | bb_error_msg("sending %s", "renew"); |
801 | return bcast_or_ucast(&packet, ciaddr, server); | 801 | return bcast_or_ucast(&packet, ciaddr, server); |
802 | } | 802 | } |
803 | 803 | ||
@@ -826,8 +826,8 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req | |||
826 | 826 | ||
827 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 827 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
828 | 828 | ||
829 | bb_info_msg("Sending decline..."); | 829 | bb_error_msg("sending %s", "decline"); |
830 | return raw_bcast_from_client_config_ifindex(&packet); | 830 | return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); |
831 | } | 831 | } |
832 | #endif | 832 | #endif |
833 | 833 | ||
@@ -846,7 +846,7 @@ static int send_release(uint32_t server, uint32_t ciaddr) | |||
846 | 846 | ||
847 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 847 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
848 | 848 | ||
849 | bb_info_msg("Sending release..."); | 849 | bb_error_msg("sending %s", "release"); |
850 | /* Note: normally we unicast here since "server" is not zero. | 850 | /* Note: normally we unicast here since "server" is not zero. |
851 | * However, there _are_ people who run "address-less" DHCP servers, | 851 | * However, there _are_ people who run "address-less" DHCP servers, |
852 | * and reportedly ISC dhcp client and Windows allow that. | 852 | * and reportedly ISC dhcp client and Windows allow that. |
@@ -881,7 +881,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) | |||
881 | if (bytes < 0) { | 881 | if (bytes < 0) { |
882 | if (errno == EINTR) | 882 | if (errno == EINTR) |
883 | continue; | 883 | continue; |
884 | log1("Packet read error, ignoring"); | 884 | log1("packet read error, ignoring"); |
885 | /* NB: possible down interface, etc. Caller should pause. */ | 885 | /* NB: possible down interface, etc. Caller should pause. */ |
886 | return bytes; /* returns -1 */ | 886 | return bytes; /* returns -1 */ |
887 | } | 887 | } |
@@ -889,13 +889,13 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) | |||
889 | } | 889 | } |
890 | 890 | ||
891 | if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) { | 891 | if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) { |
892 | log1("Packet is too short, ignoring"); | 892 | log1("packet is too short, ignoring"); |
893 | return -2; | 893 | return -2; |
894 | } | 894 | } |
895 | 895 | ||
896 | if (bytes < ntohs(packet.ip.tot_len)) { | 896 | if (bytes < ntohs(packet.ip.tot_len)) { |
897 | /* packet is bigger than sizeof(packet), we did partial read */ | 897 | /* packet is bigger than sizeof(packet), we did partial read */ |
898 | log1("Oversized packet, ignoring"); | 898 | log1("oversized packet, ignoring"); |
899 | return -2; | 899 | return -2; |
900 | } | 900 | } |
901 | 901 | ||
@@ -910,7 +910,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) | |||
910 | /* || bytes > (int) sizeof(packet) - can't happen */ | 910 | /* || bytes > (int) sizeof(packet) - can't happen */ |
911 | || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip)) | 911 | || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip)) |
912 | ) { | 912 | ) { |
913 | log1("Unrelated/bogus packet, ignoring"); | 913 | log1("unrelated/bogus packet, ignoring"); |
914 | return -2; | 914 | return -2; |
915 | } | 915 | } |
916 | 916 | ||
@@ -918,7 +918,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) | |||
918 | check = packet.ip.check; | 918 | check = packet.ip.check; |
919 | packet.ip.check = 0; | 919 | packet.ip.check = 0; |
920 | if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) { | 920 | if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) { |
921 | log1("Bad IP header checksum, ignoring"); | 921 | log1("bad IP header checksum, ignoring"); |
922 | return -2; | 922 | return -2; |
923 | } | 923 | } |
924 | 924 | ||
@@ -943,17 +943,17 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) | |||
943 | check = packet.udp.check; | 943 | check = packet.udp.check; |
944 | packet.udp.check = 0; | 944 | packet.udp.check = 0; |
945 | if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { | 945 | if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { |
946 | log1("Packet with bad UDP checksum received, ignoring"); | 946 | log1("packet with bad UDP checksum received, ignoring"); |
947 | return -2; | 947 | return -2; |
948 | } | 948 | } |
949 | skip_udp_sum_check: | 949 | skip_udp_sum_check: |
950 | 950 | ||
951 | if (packet.data.cookie != htonl(DHCP_MAGIC)) { | 951 | if (packet.data.cookie != htonl(DHCP_MAGIC)) { |
952 | bb_info_msg("Packet with bad magic, ignoring"); | 952 | bb_error_msg("packet with bad magic, ignoring"); |
953 | return -2; | 953 | return -2; |
954 | } | 954 | } |
955 | 955 | ||
956 | log1("Received a packet"); | 956 | log1("received %s", "a packet"); |
957 | udhcp_dump_packet(&packet.data); | 957 | udhcp_dump_packet(&packet.data); |
958 | 958 | ||
959 | bytes -= sizeof(packet.ip) + sizeof(packet.udp); | 959 | bytes -= sizeof(packet.ip) + sizeof(packet.udp); |
@@ -992,14 +992,14 @@ static int udhcp_raw_socket(int ifindex) | |||
992 | int fd; | 992 | int fd; |
993 | struct sockaddr_ll sock; | 993 | struct sockaddr_ll sock; |
994 | 994 | ||
995 | log1("Opening raw socket on ifindex %d", ifindex); //log2? | 995 | log1("opening raw socket on ifindex %d", ifindex); //log2? |
996 | 996 | ||
997 | fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); | 997 | fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); |
998 | /* ^^^^^ | 998 | /* ^^^^^ |
999 | * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them) | 999 | * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them) |
1000 | * ETH_P_IP: want to receive only packets with IPv4 eth type | 1000 | * ETH_P_IP: want to receive only packets with IPv4 eth type |
1001 | */ | 1001 | */ |
1002 | log1("Got raw socket fd"); //log2? | 1002 | log1("got raw socket fd"); //log2? |
1003 | 1003 | ||
1004 | sock.sll_family = AF_PACKET; | 1004 | sock.sll_family = AF_PACKET; |
1005 | sock.sll_protocol = htons(ETH_P_IP); | 1005 | sock.sll_protocol = htons(ETH_P_IP); |
@@ -1055,23 +1055,23 @@ static int udhcp_raw_socket(int ifindex) | |||
1055 | /* Ignoring error (kernel may lack support for this) */ | 1055 | /* Ignoring error (kernel may lack support for this) */ |
1056 | if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, | 1056 | if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, |
1057 | sizeof(filter_prog)) >= 0) | 1057 | sizeof(filter_prog)) >= 0) |
1058 | log1("Attached filter to raw socket fd"); // log? | 1058 | log1("attached filter to raw socket fd"); // log? |
1059 | } | 1059 | } |
1060 | #endif | 1060 | #endif |
1061 | 1061 | ||
1062 | if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) { | 1062 | if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) { |
1063 | if (errno != ENOPROTOOPT) | 1063 | if (errno != ENOPROTOOPT) |
1064 | log1("Can't set PACKET_AUXDATA on raw socket"); | 1064 | log1("can't set PACKET_AUXDATA on raw socket"); |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | log1("Created raw socket"); | 1067 | log1("created raw socket"); |
1068 | 1068 | ||
1069 | return fd; | 1069 | return fd; |
1070 | } | 1070 | } |
1071 | 1071 | ||
1072 | static void change_listen_mode(int new_mode) | 1072 | static void change_listen_mode(int new_mode) |
1073 | { | 1073 | { |
1074 | log1("Entering listen mode: %s", | 1074 | log1("entering listen mode: %s", |
1075 | new_mode != LISTEN_NONE | 1075 | new_mode != LISTEN_NONE |
1076 | ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw") | 1076 | ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw") |
1077 | : "none" | 1077 | : "none" |
@@ -1092,7 +1092,7 @@ static void change_listen_mode(int new_mode) | |||
1092 | /* Called only on SIGUSR1 */ | 1092 | /* Called only on SIGUSR1 */ |
1093 | static void perform_renew(void) | 1093 | static void perform_renew(void) |
1094 | { | 1094 | { |
1095 | bb_info_msg("Performing a DHCP renew"); | 1095 | bb_error_msg("performing DHCP renew"); |
1096 | switch (state) { | 1096 | switch (state) { |
1097 | case BOUND: | 1097 | case BOUND: |
1098 | change_listen_mode(LISTEN_KERNEL); | 1098 | change_listen_mode(LISTEN_KERNEL); |
@@ -1122,12 +1122,12 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) | |||
1122 | temp_addr.s_addr = server_addr; | 1122 | temp_addr.s_addr = server_addr; |
1123 | strcpy(buffer, inet_ntoa(temp_addr)); | 1123 | strcpy(buffer, inet_ntoa(temp_addr)); |
1124 | temp_addr.s_addr = requested_ip; | 1124 | temp_addr.s_addr = requested_ip; |
1125 | bb_info_msg("Unicasting a release of %s to %s", | 1125 | bb_error_msg("unicasting a release of %s to %s", |
1126 | inet_ntoa(temp_addr), buffer); | 1126 | inet_ntoa(temp_addr), buffer); |
1127 | send_release(server_addr, requested_ip); /* unicast */ | 1127 | send_release(server_addr, requested_ip); /* unicast */ |
1128 | udhcp_run_script(NULL, "deconfig"); | 1128 | udhcp_run_script(NULL, "deconfig"); |
1129 | } | 1129 | } |
1130 | bb_info_msg("Entering released state"); | 1130 | bb_error_msg("entering released state"); |
1131 | 1131 | ||
1132 | change_listen_mode(LISTEN_NONE); | 1132 | change_listen_mode(LISTEN_NONE); |
1133 | state = RELEASED; | 1133 | state = RELEASED; |
@@ -1395,7 +1395,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1395 | /* Create pidfile */ | 1395 | /* Create pidfile */ |
1396 | write_pidfile(client_config.pidfile); | 1396 | write_pidfile(client_config.pidfile); |
1397 | /* Goes to stdout (unless NOMMU) and possibly syslog */ | 1397 | /* Goes to stdout (unless NOMMU) and possibly syslog */ |
1398 | bb_info_msg("%s (v"BB_VER") started", applet_name); | 1398 | bb_error_msg("started, v"BB_VER); |
1399 | /* Set up the signal pipe */ | 1399 | /* Set up the signal pipe */ |
1400 | udhcp_sp_setup(); | 1400 | udhcp_sp_setup(); |
1401 | /* We want random_xid to be random... */ | 1401 | /* We want random_xid to be random... */ |
@@ -1434,7 +1434,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1434 | retval = 0; | 1434 | retval = 0; |
1435 | /* If we already timed out, fall through with retval = 0, else... */ | 1435 | /* If we already timed out, fall through with retval = 0, else... */ |
1436 | if ((int)tv.tv_sec > 0) { | 1436 | if ((int)tv.tv_sec > 0) { |
1437 | log1("Waiting on select %u seconds", (int)tv.tv_sec); | 1437 | log1("waiting on select %u seconds", (int)tv.tv_sec); |
1438 | timestamp_before_wait = (unsigned)monotonic_sec(); | 1438 | timestamp_before_wait = (unsigned)monotonic_sec(); |
1439 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); | 1439 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); |
1440 | if (retval < 0) { | 1440 | if (retval < 0) { |
@@ -1485,14 +1485,14 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1485 | udhcp_run_script(NULL, "leasefail"); | 1485 | udhcp_run_script(NULL, "leasefail"); |
1486 | #if BB_MMU /* -b is not supported on NOMMU */ | 1486 | #if BB_MMU /* -b is not supported on NOMMU */ |
1487 | if (opt & OPT_b) { /* background if no lease */ | 1487 | if (opt & OPT_b) { /* background if no lease */ |
1488 | bb_info_msg("No lease, forking to background"); | 1488 | bb_error_msg("no lease, forking to background"); |
1489 | client_background(); | 1489 | client_background(); |
1490 | /* do not background again! */ | 1490 | /* do not background again! */ |
1491 | opt = ((opt & ~OPT_b) | OPT_f); | 1491 | opt = ((opt & ~OPT_b) | OPT_f); |
1492 | } else | 1492 | } else |
1493 | #endif | 1493 | #endif |
1494 | if (opt & OPT_n) { /* abort if no lease */ | 1494 | if (opt & OPT_n) { /* abort if no lease */ |
1495 | bb_info_msg("No lease, failing"); | 1495 | bb_error_msg("no lease, failing"); |
1496 | retval = 1; | 1496 | retval = 1; |
1497 | goto ret; | 1497 | goto ret; |
1498 | } | 1498 | } |
@@ -1501,7 +1501,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1501 | packet_num = 0; | 1501 | packet_num = 0; |
1502 | continue; | 1502 | continue; |
1503 | case REQUESTING: | 1503 | case REQUESTING: |
1504 | if (!discover_retries || packet_num < discover_retries) { | 1504 | if (packet_num < 3) { |
1505 | /* send broadcast select packet */ | 1505 | /* send broadcast select packet */ |
1506 | send_select(xid, server_addr, requested_ip); | 1506 | send_select(xid, server_addr, requested_ip); |
1507 | timeout = discover_timeout; | 1507 | timeout = discover_timeout; |
@@ -1520,7 +1520,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1520 | state = RENEWING; | 1520 | state = RENEWING; |
1521 | client_config.first_secs = 0; /* make secs field count from 0 */ | 1521 | client_config.first_secs = 0; /* make secs field count from 0 */ |
1522 | change_listen_mode(LISTEN_KERNEL); | 1522 | change_listen_mode(LISTEN_KERNEL); |
1523 | log1("Entering renew state"); | 1523 | log1("entering renew state"); |
1524 | /* fall right through */ | 1524 | /* fall right through */ |
1525 | case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ | 1525 | case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ |
1526 | case_RENEW_REQUESTED: | 1526 | case_RENEW_REQUESTED: |
@@ -1540,7 +1540,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1540 | continue; | 1540 | continue; |
1541 | } | 1541 | } |
1542 | /* Timed out, enter rebinding state */ | 1542 | /* Timed out, enter rebinding state */ |
1543 | log1("Entering rebinding state"); | 1543 | log1("entering rebinding state"); |
1544 | state = REBINDING; | 1544 | state = REBINDING; |
1545 | /* fall right through */ | 1545 | /* fall right through */ |
1546 | case REBINDING: | 1546 | case REBINDING: |
@@ -1555,7 +1555,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1555 | continue; | 1555 | continue; |
1556 | } | 1556 | } |
1557 | /* Timed out, enter init state */ | 1557 | /* Timed out, enter init state */ |
1558 | bb_info_msg("Lease lost, entering init state"); | 1558 | bb_error_msg("lease lost, entering init state"); |
1559 | udhcp_run_script(NULL, "deconfig"); | 1559 | udhcp_run_script(NULL, "deconfig"); |
1560 | state = INIT_SELECTING; | 1560 | state = INIT_SELECTING; |
1561 | client_config.first_secs = 0; /* make secs field count from 0 */ | 1561 | client_config.first_secs = 0; /* make secs field count from 0 */ |
@@ -1603,7 +1603,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1603 | timeout = INT_MAX; | 1603 | timeout = INT_MAX; |
1604 | continue; | 1604 | continue; |
1605 | case SIGTERM: | 1605 | case SIGTERM: |
1606 | bb_info_msg("Received SIGTERM"); | 1606 | bb_error_msg("received %s", "SIGTERM"); |
1607 | goto ret0; | 1607 | goto ret0; |
1608 | } | 1608 | } |
1609 | 1609 | ||
@@ -1621,7 +1621,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1621 | len = udhcp_recv_raw_packet(&packet, sockfd); | 1621 | len = udhcp_recv_raw_packet(&packet, sockfd); |
1622 | if (len == -1) { | 1622 | if (len == -1) { |
1623 | /* Error is severe, reopen socket */ | 1623 | /* Error is severe, reopen socket */ |
1624 | bb_info_msg("Read error: %s, reopening socket", strerror(errno)); | 1624 | bb_error_msg("read error: %s, reopening socket", strerror(errno)); |
1625 | sleep(discover_timeout); /* 3 seconds by default */ | 1625 | sleep(discover_timeout); /* 3 seconds by default */ |
1626 | change_listen_mode(listen_mode); /* just close and reopen */ | 1626 | change_listen_mode(listen_mode); /* just close and reopen */ |
1627 | } | 1627 | } |
@@ -1744,7 +1744,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1744 | client_config.interface, | 1744 | client_config.interface, |
1745 | arpping_ms) | 1745 | arpping_ms) |
1746 | ) { | 1746 | ) { |
1747 | bb_info_msg("Offered address is in use " | 1747 | bb_error_msg("offered address is in use " |
1748 | "(got ARP reply), declining"); | 1748 | "(got ARP reply), declining"); |
1749 | send_decline(/*xid,*/ server_addr, packet.yiaddr); | 1749 | send_decline(/*xid,*/ server_addr, packet.yiaddr); |
1750 | 1750 | ||
@@ -1763,7 +1763,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1763 | #endif | 1763 | #endif |
1764 | /* enter bound state */ | 1764 | /* enter bound state */ |
1765 | temp_addr.s_addr = packet.yiaddr; | 1765 | temp_addr.s_addr = packet.yiaddr; |
1766 | bb_info_msg("Lease of %s obtained, lease time %u", | 1766 | bb_error_msg("lease of %s obtained, lease time %u", |
1767 | inet_ntoa(temp_addr), (unsigned)lease_seconds); | 1767 | inet_ntoa(temp_addr), (unsigned)lease_seconds); |
1768 | requested_ip = packet.yiaddr; | 1768 | requested_ip = packet.yiaddr; |
1769 | 1769 | ||
@@ -1817,7 +1817,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1817 | goto non_matching_svid; | 1817 | goto non_matching_svid; |
1818 | } | 1818 | } |
1819 | /* return to init state */ | 1819 | /* return to init state */ |
1820 | bb_info_msg("Received DHCP NAK"); | 1820 | bb_error_msg("received %s", "DHCP NAK"); |
1821 | udhcp_run_script(&packet, "nak"); | 1821 | udhcp_run_script(&packet, "nak"); |
1822 | if (state != REQUESTING) | 1822 | if (state != REQUESTING) |
1823 | udhcp_run_script(NULL, "deconfig"); | 1823 | udhcp_run_script(NULL, "deconfig"); |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 2de074f9b..2671ea3e2 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -61,11 +61,11 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc | |||
61 | || (dhcp_pkt->flags & htons(BROADCAST_FLAG)) | 61 | || (dhcp_pkt->flags & htons(BROADCAST_FLAG)) |
62 | || dhcp_pkt->ciaddr == 0 | 62 | || dhcp_pkt->ciaddr == 0 |
63 | ) { | 63 | ) { |
64 | log1("Broadcasting packet to client"); | 64 | log1("broadcasting packet to client"); |
65 | ciaddr = INADDR_BROADCAST; | 65 | ciaddr = INADDR_BROADCAST; |
66 | chaddr = MAC_BCAST_ADDR; | 66 | chaddr = MAC_BCAST_ADDR; |
67 | } else { | 67 | } else { |
68 | log1("Unicasting packet to client ciaddr"); | 68 | log1("unicasting packet to client ciaddr"); |
69 | ciaddr = dhcp_pkt->ciaddr; | 69 | ciaddr = dhcp_pkt->ciaddr; |
70 | chaddr = dhcp_pkt->chaddr; | 70 | chaddr = dhcp_pkt->chaddr; |
71 | } | 71 | } |
@@ -79,7 +79,7 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc | |||
79 | /* Send a packet to gateway_nip using the kernel ip stack */ | 79 | /* Send a packet to gateway_nip using the kernel ip stack */ |
80 | static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) | 80 | static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) |
81 | { | 81 | { |
82 | log1("Forwarding packet to relay"); | 82 | log1("forwarding packet to relay"); |
83 | 83 | ||
84 | udhcp_send_kernel_packet(dhcp_pkt, | 84 | udhcp_send_kernel_packet(dhcp_pkt, |
85 | server_config.server_nip, SERVER_PORT, | 85 | server_config.server_nip, SERVER_PORT, |
@@ -214,7 +214,7 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, | |||
214 | add_server_options(&packet); | 214 | add_server_options(&packet); |
215 | 215 | ||
216 | addr.s_addr = packet.yiaddr; | 216 | addr.s_addr = packet.yiaddr; |
217 | bb_info_msg("Sending OFFER of %s", inet_ntoa(addr)); | 217 | bb_error_msg("sending OFFER of %s", inet_ntoa(addr)); |
218 | /* send_packet emits error message itself if it detects failure */ | 218 | /* send_packet emits error message itself if it detects failure */ |
219 | send_packet(&packet, /*force_bcast:*/ 0); | 219 | send_packet(&packet, /*force_bcast:*/ 0); |
220 | } | 220 | } |
@@ -226,7 +226,7 @@ static NOINLINE void send_NAK(struct dhcp_packet *oldpacket) | |||
226 | 226 | ||
227 | init_packet(&packet, oldpacket, DHCPNAK); | 227 | init_packet(&packet, oldpacket, DHCPNAK); |
228 | 228 | ||
229 | log1("Sending NAK"); | 229 | log1("sending %s", "NAK"); |
230 | send_packet(&packet, /*force_bcast:*/ 1); | 230 | send_packet(&packet, /*force_bcast:*/ 1); |
231 | } | 231 | } |
232 | 232 | ||
@@ -247,7 +247,7 @@ static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) | |||
247 | add_server_options(&packet); | 247 | add_server_options(&packet); |
248 | 248 | ||
249 | addr.s_addr = yiaddr; | 249 | addr.s_addr = yiaddr; |
250 | bb_info_msg("Sending ACK to %s", inet_ntoa(addr)); | 250 | bb_error_msg("sending ACK to %s", inet_ntoa(addr)); |
251 | send_packet(&packet, /*force_bcast:*/ 0); | 251 | send_packet(&packet, /*force_bcast:*/ 0); |
252 | 252 | ||
253 | p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME); | 253 | p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME); |
@@ -361,7 +361,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
361 | write_pidfile(server_config.pidfile); | 361 | write_pidfile(server_config.pidfile); |
362 | /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ | 362 | /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ |
363 | 363 | ||
364 | bb_info_msg("%s (v"BB_VER") started", applet_name); | 364 | bb_error_msg("started, v"BB_VER); |
365 | 365 | ||
366 | option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); | 366 | option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); |
367 | server_config.max_lease_sec = DEFAULT_LEASE_TIME; | 367 | server_config.max_lease_sec = DEFAULT_LEASE_TIME; |
@@ -427,18 +427,18 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
427 | goto continue_with_autotime; | 427 | goto continue_with_autotime; |
428 | } | 428 | } |
429 | if (retval < 0 && errno != EINTR) { | 429 | if (retval < 0 && errno != EINTR) { |
430 | log1("Error on select"); | 430 | log1("error on select"); |
431 | continue; | 431 | continue; |
432 | } | 432 | } |
433 | 433 | ||
434 | switch (udhcp_sp_read(&rfds)) { | 434 | switch (udhcp_sp_read(&rfds)) { |
435 | case SIGUSR1: | 435 | case SIGUSR1: |
436 | bb_info_msg("Received SIGUSR1"); | 436 | bb_error_msg("received %s", "SIGUSR1"); |
437 | write_leases(); | 437 | write_leases(); |
438 | /* why not just reset the timeout, eh */ | 438 | /* why not just reset the timeout, eh */ |
439 | goto continue_with_autotime; | 439 | goto continue_with_autotime; |
440 | case SIGTERM: | 440 | case SIGTERM: |
441 | bb_info_msg("Received SIGTERM"); | 441 | bb_error_msg("received %s", "SIGTERM"); |
442 | write_leases(); | 442 | write_leases(); |
443 | goto ret0; | 443 | goto ret0; |
444 | case 0: /* no signal: read a packet */ | 444 | case 0: /* no signal: read a packet */ |
@@ -451,7 +451,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
451 | if (bytes < 0) { | 451 | if (bytes < 0) { |
452 | /* bytes can also be -2 ("bad packet data") */ | 452 | /* bytes can also be -2 ("bad packet data") */ |
453 | if (bytes == -1 && errno != EINTR) { | 453 | if (bytes == -1 && errno != EINTR) { |
454 | log1("Read error: %s, reopening socket", strerror(errno)); | 454 | log1("read error: %s, reopening socket", strerror(errno)); |
455 | close(server_socket); | 455 | close(server_socket); |
456 | server_socket = -1; | 456 | server_socket = -1; |
457 | } | 457 | } |
@@ -486,7 +486,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
486 | /* Look for a static/dynamic lease */ | 486 | /* Look for a static/dynamic lease */ |
487 | static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); | 487 | static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); |
488 | if (static_lease_nip) { | 488 | if (static_lease_nip) { |
489 | bb_info_msg("Found static lease: %x", static_lease_nip); | 489 | bb_error_msg("found static lease: %x", static_lease_nip); |
490 | memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); | 490 | memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); |
491 | fake_lease.lease_nip = static_lease_nip; | 491 | fake_lease.lease_nip = static_lease_nip; |
492 | fake_lease.expires = 0; | 492 | fake_lease.expires = 0; |
@@ -504,13 +504,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
504 | switch (state[0]) { | 504 | switch (state[0]) { |
505 | 505 | ||
506 | case DHCPDISCOVER: | 506 | case DHCPDISCOVER: |
507 | log1("Received DISCOVER"); | 507 | log1("received %s", "DISCOVER"); |
508 | 508 | ||
509 | send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms); | 509 | send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms); |
510 | break; | 510 | break; |
511 | 511 | ||
512 | case DHCPREQUEST: | 512 | case DHCPREQUEST: |
513 | log1("Received REQUEST"); | 513 | log1("received %s", "REQUEST"); |
514 | /* RFC 2131: | 514 | /* RFC 2131: |
515 | 515 | ||
516 | o DHCPREQUEST generated during SELECTING state: | 516 | o DHCPREQUEST generated during SELECTING state: |
@@ -635,7 +635,7 @@ o DHCPREQUEST generated during REBINDING state: | |||
635 | * chaddr must be filled in, | 635 | * chaddr must be filled in, |
636 | * ciaddr must be 0 (we do not check this) | 636 | * ciaddr must be 0 (we do not check this) |
637 | */ | 637 | */ |
638 | log1("Received DECLINE"); | 638 | log1("received %s", "DECLINE"); |
639 | if (server_id_opt | 639 | if (server_id_opt |
640 | && requested_ip_opt | 640 | && requested_ip_opt |
641 | && lease /* chaddr matches this lease */ | 641 | && lease /* chaddr matches this lease */ |
@@ -655,7 +655,7 @@ o DHCPREQUEST generated during REBINDING state: | |||
655 | * chaddr must be filled in, | 655 | * chaddr must be filled in, |
656 | * ciaddr must be filled in | 656 | * ciaddr must be filled in |
657 | */ | 657 | */ |
658 | log1("Received RELEASE"); | 658 | log1("received %s", "RELEASE"); |
659 | if (server_id_opt | 659 | if (server_id_opt |
660 | && lease /* chaddr matches this lease */ | 660 | && lease /* chaddr matches this lease */ |
661 | && packet.ciaddr == lease->lease_nip | 661 | && packet.ciaddr == lease->lease_nip |
@@ -665,7 +665,7 @@ o DHCPREQUEST generated during REBINDING state: | |||
665 | break; | 665 | break; |
666 | 666 | ||
667 | case DHCPINFORM: | 667 | case DHCPINFORM: |
668 | log1("Received INFORM"); | 668 | log1("received %s", "INFORM"); |
669 | send_inform(&packet); | 669 | send_inform(&packet); |
670 | break; | 670 | break; |
671 | } | 671 | } |
diff --git a/networking/udhcp/domain_codec.c b/networking/udhcp/domain_codec.c index c1325d8be..5a923cc2c 100644 --- a/networking/udhcp/domain_codec.c +++ b/networking/udhcp/domain_codec.c | |||
@@ -7,6 +7,7 @@ | |||
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 | #ifdef DNS_COMPR_TESTING | 9 | #ifdef DNS_COMPR_TESTING |
10 | # define _GNU_SOURCE | ||
10 | # define FAST_FUNC /* nothing */ | 11 | # define FAST_FUNC /* nothing */ |
11 | # define xmalloc malloc | 12 | # define xmalloc malloc |
12 | # include <stdlib.h> | 13 | # include <stdlib.h> |
@@ -42,7 +43,7 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) | |||
42 | */ | 43 | */ |
43 | while (1) { | 44 | while (1) { |
44 | /* note: "return NULL" below are leak-safe since | 45 | /* note: "return NULL" below are leak-safe since |
45 | * dst isn't yet allocated */ | 46 | * dst isn't allocated yet */ |
46 | const uint8_t *c; | 47 | const uint8_t *c; |
47 | unsigned crtpos, retpos, depth, len; | 48 | unsigned crtpos, retpos, depth, len; |
48 | 49 | ||
@@ -63,11 +64,10 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) | |||
63 | if (crtpos + *c + 1 > clen) /* label too long? abort */ | 64 | if (crtpos + *c + 1 > clen) /* label too long? abort */ |
64 | return NULL; | 65 | return NULL; |
65 | if (dst) | 66 | if (dst) |
66 | memcpy(dst + len, c + 1, *c); | 67 | /* \3com ---> "com." */ |
68 | ((char*)mempcpy(dst + len, c + 1, *c))[0] = '.'; | ||
67 | len += *c + 1; | 69 | len += *c + 1; |
68 | crtpos += *c + 1; | 70 | crtpos += *c + 1; |
69 | if (dst) | ||
70 | dst[len - 1] = '.'; | ||
71 | } else { | 71 | } else { |
72 | /* NUL: end of current domain name */ | 72 | /* NUL: end of current domain name */ |
73 | if (retpos == 0) { | 73 | if (retpos == 0) { |
@@ -78,7 +78,10 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) | |||
78 | crtpos = retpos; | 78 | crtpos = retpos; |
79 | retpos = depth = 0; | 79 | retpos = depth = 0; |
80 | } | 80 | } |
81 | if (dst) | 81 | if (dst && len != 0) |
82 | /* \4host\3com\0\4host and we are at \0: | ||
83 | * \3com was converted to "com.", change dot to space. | ||
84 | */ | ||
82 | dst[len - 1] = ' '; | 85 | dst[len - 1] = ' '; |
83 | } | 86 | } |
84 | 87 | ||
@@ -95,9 +98,8 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) | |||
95 | if (!dst) { /* first pass? */ | 98 | if (!dst) { /* first pass? */ |
96 | /* allocate dst buffer and copy pre */ | 99 | /* allocate dst buffer and copy pre */ |
97 | unsigned plen = strlen(pre); | 100 | unsigned plen = strlen(pre); |
98 | ret = dst = xmalloc(plen + len); | 101 | ret = xmalloc(plen + len); |
99 | memcpy(dst, pre, plen); | 102 | dst = stpcpy(ret, pre); |
100 | dst += plen; | ||
101 | } else { | 103 | } else { |
102 | dst[len - 1] = '\0'; | 104 | dst[len - 1] = '\0'; |
103 | break; | 105 | break; |
@@ -228,6 +230,9 @@ int main(int argc, char **argv) | |||
228 | int len; | 230 | int len; |
229 | uint8_t *encoded; | 231 | uint8_t *encoded; |
230 | 232 | ||
233 | uint8_t str[6] = { 0x00, 0x00, 0x02, 0x65, 0x65, 0x00 }; | ||
234 | printf("NUL:'%s'\n", dname_dec(str, 6, "")); | ||
235 | |||
231 | #define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre)) | 236 | #define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre)) |
232 | printf("'%s'\n", DNAME_DEC("\4host\3com\0", "test1:")); | 237 | printf("'%s'\n", DNAME_DEC("\4host\3com\0", "test1:")); |
233 | printf("test2:'%s'\n", DNAME_DEC("\4host\3com\0\4host\3com\0", "")); | 238 | printf("test2:'%s'\n", DNAME_DEC("\4host\3com\0\4host\3com\0", "")); |
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 1c8808c0f..7b57c6258 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c | |||
@@ -195,7 +195,11 @@ void FAST_FUNC read_leases(const char *file) | |||
195 | uint32_t static_nip; | 195 | uint32_t static_nip; |
196 | 196 | ||
197 | if (expires <= 0) | 197 | if (expires <= 0) |
198 | continue; | 198 | /* We keep expired leases: add_lease() will add |
199 | * a lease with 0 seconds remaining. | ||
200 | * Fewer IP address changes this way for mass reboot scenario. | ||
201 | */ | ||
202 | expires = 0; | ||
199 | 203 | ||
200 | /* Check if there is a different static lease for this IP or MAC */ | 204 | /* Check if there is a different static lease for this IP or MAC */ |
201 | static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac); | 205 | static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac); |
@@ -222,7 +226,7 @@ void FAST_FUNC read_leases(const char *file) | |||
222 | #endif | 226 | #endif |
223 | } | 227 | } |
224 | } | 228 | } |
225 | log1("Read %d leases", i); | 229 | log1("read %d leases", i); |
226 | ret: | 230 | ret: |
227 | close(fd); | 231 | close(fd); |
228 | } | 232 | } |
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index 844bb60b1..6642e396d 100644 --- a/networking/udhcp/leases.c +++ b/networking/udhcp/leases.c | |||
@@ -17,7 +17,9 @@ static struct dyn_lease *oldest_expired_lease(void) | |||
17 | /* Unexpired leases have g_leases[i].expires >= current time | 17 | /* Unexpired leases have g_leases[i].expires >= current time |
18 | * and therefore can't ever match */ | 18 | * and therefore can't ever match */ |
19 | for (i = 0; i < server_config.max_leases; i++) { | 19 | for (i = 0; i < server_config.max_leases; i++) { |
20 | if (g_leases[i].expires < oldest_time) { | 20 | if (g_leases[i].expires == 0 /* empty entry */ |
21 | || g_leases[i].expires < oldest_time | ||
22 | ) { | ||
21 | oldest_time = g_leases[i].expires; | 23 | oldest_time = g_leases[i].expires; |
22 | oldest_lease = &g_leases[i]; | 24 | oldest_lease = &g_leases[i]; |
23 | } | 25 | } |
@@ -131,7 +133,7 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigne | |||
131 | return r; | 133 | return r; |
132 | 134 | ||
133 | temp.s_addr = nip; | 135 | temp.s_addr = nip; |
134 | bb_info_msg("%s belongs to someone, reserving it for %u seconds", | 136 | bb_error_msg("%s belongs to someone, reserving it for %u seconds", |
135 | inet_ntoa(temp), (unsigned)server_config.conflict_time); | 137 | inet_ntoa(temp), (unsigned)server_config.conflict_time); |
136 | add_lease(NULL, nip, server_config.conflict_time, NULL, 0); | 138 | add_lease(NULL, nip, server_config.conflict_time, NULL, 0); |
137 | return 0; | 139 | return 0; |
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 148f52551..0a31f2643 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c | |||
@@ -38,8 +38,8 @@ void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet) | |||
38 | if (dhcp_verbose < 2) | 38 | if (dhcp_verbose < 2) |
39 | return; | 39 | return; |
40 | 40 | ||
41 | bb_info_msg( | 41 | bb_error_msg( |
42 | //" op %x" | 42 | //"op %x" |
43 | //" htype %x" | 43 | //" htype %x" |
44 | " hlen %x" | 44 | " hlen %x" |
45 | //" hops %x" | 45 | //" hops %x" |
@@ -73,7 +73,7 @@ void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet) | |||
73 | //, packet->options[] | 73 | //, packet->options[] |
74 | ); | 74 | ); |
75 | *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; | 75 | *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; |
76 | bb_info_msg(" chaddr %s", buf); | 76 | bb_error_msg("chaddr %s", buf); |
77 | } | 77 | } |
78 | #endif | 78 | #endif |
79 | 79 | ||
@@ -85,17 +85,17 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) | |||
85 | memset(packet, 0, sizeof(*packet)); | 85 | memset(packet, 0, sizeof(*packet)); |
86 | bytes = safe_read(fd, packet, sizeof(*packet)); | 86 | bytes = safe_read(fd, packet, sizeof(*packet)); |
87 | if (bytes < 0) { | 87 | if (bytes < 0) { |
88 | log1("Packet read error, ignoring"); | 88 | log1("packet read error, ignoring"); |
89 | return bytes; /* returns -1 */ | 89 | return bytes; /* returns -1 */ |
90 | } | 90 | } |
91 | 91 | ||
92 | if (bytes < offsetof(struct dhcp_packet, options) | 92 | if (bytes < offsetof(struct dhcp_packet, options) |
93 | || packet->cookie != htonl(DHCP_MAGIC) | 93 | || packet->cookie != htonl(DHCP_MAGIC) |
94 | ) { | 94 | ) { |
95 | bb_info_msg("Packet with bad magic, ignoring"); | 95 | bb_error_msg("packet with bad magic, ignoring"); |
96 | return -2; | 96 | return -2; |
97 | } | 97 | } |
98 | log1("Received a packet"); | 98 | log1("received %s", "a packet"); |
99 | udhcp_dump_packet(packet); | 99 | udhcp_dump_packet(packet); |
100 | 100 | ||
101 | return bytes; | 101 | return bytes; |
diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c index a42106960..4fd79f423 100644 --- a/networking/udhcp/socket.c +++ b/networking/udhcp/socket.c | |||
@@ -56,7 +56,7 @@ int FAST_FUNC udhcp_read_interface(const char *interface, int *ifindex, uint32_t | |||
56 | close(fd); | 56 | close(fd); |
57 | return -1; | 57 | return -1; |
58 | } | 58 | } |
59 | log1("Adapter index %d", ifr->ifr_ifindex); | 59 | log1("adapter index %d", ifr->ifr_ifindex); |
60 | *ifindex = ifr->ifr_ifindex; | 60 | *ifindex = ifr->ifr_ifindex; |
61 | } | 61 | } |
62 | 62 | ||
@@ -82,7 +82,7 @@ int FAST_FUNC udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) | |||
82 | struct sockaddr_in addr; | 82 | struct sockaddr_in addr; |
83 | char *colon; | 83 | char *colon; |
84 | 84 | ||
85 | log1("Opening listen socket on *:%d %s", port, inf); | 85 | log1("opening listen socket on *:%d %s", port, inf); |
86 | fd = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); | 86 | fd = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); |
87 | 87 | ||
88 | setsockopt_reuseaddr(fd); | 88 | setsockopt_reuseaddr(fd); |
diff --git a/networking/udhcp/static_leases.c b/networking/udhcp/static_leases.c index f4a24ab62..b7f9e5c59 100644 --- a/networking/udhcp/static_leases.c +++ b/networking/udhcp/static_leases.c | |||
@@ -66,7 +66,7 @@ void FAST_FUNC log_static_leases(struct static_lease **st_lease_pp) | |||
66 | 66 | ||
67 | cur = *st_lease_pp; | 67 | cur = *st_lease_pp; |
68 | while (cur) { | 68 | while (cur) { |
69 | bb_info_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", | 69 | bb_error_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", |
70 | cur->mac[0], cur->mac[1], cur->mac[2], | 70 | cur->mac[0], cur->mac[1], cur->mac[2], |
71 | cur->mac[3], cur->mac[4], cur->mac[5], | 71 | cur->mac[3], cur->mac[4], cur->mac[5], |
72 | cur->nip | 72 | cur->nip |
diff --git a/networking/wget.c b/networking/wget.c index edf8fd8af..87d3bbd13 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -203,7 +203,7 @@ struct globals { | |||
203 | const char *user_agent; /* "User-Agent" header field */ | 203 | const char *user_agent; /* "User-Agent" header field */ |
204 | #if ENABLE_FEATURE_WGET_TIMEOUT | 204 | #if ENABLE_FEATURE_WGET_TIMEOUT |
205 | unsigned timeout_seconds; | 205 | unsigned timeout_seconds; |
206 | bool connecting; | 206 | bool die_if_timed_out; |
207 | #endif | 207 | #endif |
208 | int output_fd; | 208 | int output_fd; |
209 | int o_flags; | 209 | int o_flags; |
@@ -333,9 +333,20 @@ static char* sanitize_string(char *s) | |||
333 | static void alarm_handler(int sig UNUSED_PARAM) | 333 | static void alarm_handler(int sig UNUSED_PARAM) |
334 | { | 334 | { |
335 | /* This is theoretically unsafe (uses stdio and malloc in signal handler) */ | 335 | /* This is theoretically unsafe (uses stdio and malloc in signal handler) */ |
336 | if (G.connecting) | 336 | if (G.die_if_timed_out) |
337 | bb_error_msg_and_die("download timed out"); | 337 | bb_error_msg_and_die("download timed out"); |
338 | } | 338 | } |
339 | static void set_alarm(void) | ||
340 | { | ||
341 | if (G.timeout_seconds) { | ||
342 | alarm(G.timeout_seconds); | ||
343 | G.die_if_timed_out = 1; | ||
344 | } | ||
345 | } | ||
346 | # define clear_alarm() ((void)(G.die_if_timed_out = 0)) | ||
347 | #else | ||
348 | # define set_alarm() ((void)0) | ||
349 | # define clear_alarm() ((void)0) | ||
339 | #endif | 350 | #endif |
340 | 351 | ||
341 | static FILE *open_socket(len_and_sockaddr *lsa) | 352 | static FILE *open_socket(len_and_sockaddr *lsa) |
@@ -343,9 +354,9 @@ static FILE *open_socket(len_and_sockaddr *lsa) | |||
343 | int fd; | 354 | int fd; |
344 | FILE *fp; | 355 | FILE *fp; |
345 | 356 | ||
346 | IF_FEATURE_WGET_TIMEOUT(alarm(G.timeout_seconds); G.connecting = 1;) | 357 | set_alarm(); |
347 | fd = xconnect_stream(lsa); | 358 | fd = xconnect_stream(lsa); |
348 | IF_FEATURE_WGET_TIMEOUT(G.connecting = 0;) | 359 | clear_alarm(); |
349 | 360 | ||
350 | /* glibc 2.4 seems to try seeking on it - ??! */ | 361 | /* glibc 2.4 seems to try seeking on it - ??! */ |
351 | /* hopefully it understands what ESPIPE means... */ | 362 | /* hopefully it understands what ESPIPE means... */ |
@@ -357,14 +368,15 @@ static FILE *open_socket(len_and_sockaddr *lsa) | |||
357 | } | 368 | } |
358 | 369 | ||
359 | /* Returns '\n' if it was seen, else '\0'. Trims at first '\r' or '\n' */ | 370 | /* Returns '\n' if it was seen, else '\0'. Trims at first '\r' or '\n' */ |
360 | /* FIXME: does not respect FEATURE_WGET_TIMEOUT and -T N: */ | ||
361 | static char fgets_and_trim(FILE *fp) | 371 | static char fgets_and_trim(FILE *fp) |
362 | { | 372 | { |
363 | char c; | 373 | char c; |
364 | char *buf_ptr; | 374 | char *buf_ptr; |
365 | 375 | ||
376 | set_alarm(); | ||
366 | if (fgets(G.wget_buf, sizeof(G.wget_buf) - 1, fp) == NULL) | 377 | if (fgets(G.wget_buf, sizeof(G.wget_buf) - 1, fp) == NULL) |
367 | bb_perror_msg_and_die("error getting response"); | 378 | bb_perror_msg_and_die("error getting response"); |
379 | clear_alarm(); | ||
368 | 380 | ||
369 | buf_ptr = strchrnul(G.wget_buf, '\n'); | 381 | buf_ptr = strchrnul(G.wget_buf, '\n'); |
370 | c = *buf_ptr; | 382 | c = *buf_ptr; |
diff --git a/networking/zcip.c b/networking/zcip.c index 1d6910555..c93082619 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -176,7 +176,7 @@ static int run(char *argv[3], const char *param, uint32_t nip) | |||
176 | xsetenv("ip", addr); | 176 | xsetenv("ip", addr); |
177 | fmt -= 3; | 177 | fmt -= 3; |
178 | } | 178 | } |
179 | bb_info_msg(fmt, argv[2], argv[0], addr); | 179 | bb_error_msg(fmt, argv[2], argv[0], addr); |
180 | 180 | ||
181 | status = spawn_and_wait(argv + 1); | 181 | status = spawn_and_wait(argv + 1); |
182 | if (status < 0) { | 182 | if (status < 0) { |
@@ -317,7 +317,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
317 | #if BB_MMU | 317 | #if BB_MMU |
318 | bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/); | 318 | bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/); |
319 | #endif | 319 | #endif |
320 | bb_info_msg("start, interface %s", argv_intf); | 320 | bb_error_msg("start, interface %s", argv_intf); |
321 | } | 321 | } |
322 | 322 | ||
323 | // Run the dynamic address negotiation protocol, | 323 | // Run the dynamic address negotiation protocol, |
diff --git a/procps/nmeter.c b/procps/nmeter.c index 5d5b83b8d..33de3790f 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c | |||
@@ -21,7 +21,7 @@ | |||
21 | //usage:#define nmeter_full_usage "\n\n" | 21 | //usage:#define nmeter_full_usage "\n\n" |
22 | //usage: "Monitor system in real time" | 22 | //usage: "Monitor system in real time" |
23 | //usage: "\n" | 23 | //usage: "\n" |
24 | //usage: "\n -d MSEC Milliseconds between updates (default:1000)" | 24 | //usage: "\n -d MSEC Milliseconds between updates, default:1000, none:-1" |
25 | //usage: "\n" | 25 | //usage: "\n" |
26 | //usage: "\nFormat specifiers:" | 26 | //usage: "\nFormat specifiers:" |
27 | //usage: "\n %Nc or %[cN] CPU. N - bar size (default:10)" | 27 | //usage: "\n %Nc or %[cN] CPU. N - bar size (default:10)" |
@@ -83,10 +83,10 @@ struct globals { | |||
83 | smallint is26; | 83 | smallint is26; |
84 | // 1 if sample delay is not an integer fraction of a second | 84 | // 1 if sample delay is not an integer fraction of a second |
85 | smallint need_seconds; | 85 | smallint need_seconds; |
86 | char final_char; | ||
86 | char *cur_outbuf; | 87 | char *cur_outbuf; |
87 | const char *final_str; | ||
88 | int delta; | 88 | int delta; |
89 | int deltanz; | 89 | unsigned deltanz; |
90 | struct timeval tv; | 90 | struct timeval tv; |
91 | #define first_proc_file proc_stat | 91 | #define first_proc_file proc_stat |
92 | proc_file proc_stat; // Must match the order of proc_name's! | 92 | proc_file proc_stat; // Must match the order of proc_name's! |
@@ -101,9 +101,6 @@ struct globals { | |||
101 | #define is26 (G.is26 ) | 101 | #define is26 (G.is26 ) |
102 | #define need_seconds (G.need_seconds ) | 102 | #define need_seconds (G.need_seconds ) |
103 | #define cur_outbuf (G.cur_outbuf ) | 103 | #define cur_outbuf (G.cur_outbuf ) |
104 | #define final_str (G.final_str ) | ||
105 | #define delta (G.delta ) | ||
106 | #define deltanz (G.deltanz ) | ||
107 | #define tv (G.tv ) | 104 | #define tv (G.tv ) |
108 | #define proc_stat (G.proc_stat ) | 105 | #define proc_stat (G.proc_stat ) |
109 | #define proc_loadavg (G.proc_loadavg ) | 106 | #define proc_loadavg (G.proc_loadavg ) |
@@ -114,8 +111,8 @@ struct globals { | |||
114 | #define INIT_G() do { \ | 111 | #define INIT_G() do { \ |
115 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 112 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
116 | cur_outbuf = outbuf; \ | 113 | cur_outbuf = outbuf; \ |
117 | final_str = "\n"; \ | 114 | G.final_char = '\n'; \ |
118 | deltanz = delta = 1000000; \ | 115 | G.deltanz = G.delta = 1000000; \ |
119 | } while (0) | 116 | } while (0) |
120 | 117 | ||
121 | // We depend on this being a char[], not char* - we take sizeof() of it | 118 | // We depend on this being a char[], not char* - we take sizeof() of it |
@@ -142,11 +139,11 @@ static void print_outbuf(void) | |||
142 | 139 | ||
143 | static void put(const char *s) | 140 | static void put(const char *s) |
144 | { | 141 | { |
145 | int sz = strlen(s); | 142 | char *p = cur_outbuf; |
146 | if (sz > outbuf + sizeof(outbuf) - cur_outbuf) | 143 | int sz = outbuf + sizeof(outbuf) - p; |
147 | sz = outbuf + sizeof(outbuf) - cur_outbuf; | 144 | while (*s && --sz >= 0) |
148 | memcpy(cur_outbuf, s, sz); | 145 | *p++ = *s++; |
149 | cur_outbuf += sz; | 146 | cur_outbuf = p; |
150 | } | 147 | } |
151 | 148 | ||
152 | static void put_c(char c) | 149 | static void put_c(char c) |
@@ -208,65 +205,50 @@ static ullong read_after_slash(const char *p) | |||
208 | return strtoull(p+1, NULL, 10); | 205 | return strtoull(p+1, NULL, 10); |
209 | } | 206 | } |
210 | 207 | ||
211 | enum conv_type { conv_decimal, conv_slash }; | 208 | enum conv_type { |
209 | conv_decimal = 0, | ||
210 | conv_slash = 1 | ||
211 | }; | ||
212 | 212 | ||
213 | // Reads decimal values from line. Values start after key, for example: | 213 | // Reads decimal values from line. Values start after key, for example: |
214 | // "cpu 649369 0 341297 4336769..." - key is "cpu" here. | 214 | // "cpu 649369 0 341297 4336769..." - key is "cpu" here. |
215 | // Values are stored in vec[]. arg_ptr has list of positions | 215 | // Values are stored in vec[]. |
216 | // we are interested in: for example: 1,2,5 - we want 1st, 2nd and 5th value. | 216 | // posbits is a bit lit of positions we are interested in. |
217 | static int vrdval(const char* p, const char* key, | 217 | // for example: 00100110 - we want 1st, 2nd and 5th value. |
218 | enum conv_type conv, ullong *vec, va_list arg_ptr) | 218 | // posbits.bit0 encodes conversion type. |
219 | static int rdval(const char* p, const char* key, ullong *vec, long posbits) | ||
219 | { | 220 | { |
220 | int indexline; | 221 | unsigned curpos; |
221 | int indexnext; | ||
222 | 222 | ||
223 | p = strstr(p, key); | 223 | p = strstr(p, key); |
224 | if (!p) return 1; | 224 | if (!p) return 1; |
225 | 225 | ||
226 | p += strlen(key); | 226 | p += strlen(key); |
227 | indexline = 1; | 227 | curpos = 1 << 1; |
228 | indexnext = va_arg(arg_ptr, int); | ||
229 | while (1) { | 228 | while (1) { |
230 | while (*p == ' ' || *p == '\t') p++; | 229 | while (*p == ' ' || *p == '\t') p++; |
231 | if (*p == '\n' || *p == '\0') break; | 230 | if (*p == '\n' || *p == '\0') break; |
232 | 231 | ||
233 | if (indexline == indexnext) { // read this value | 232 | if (curpos & posbits) { // read this value |
234 | *vec++ = conv==conv_decimal ? | 233 | *vec++ = (posbits & 1) == conv_decimal ? |
235 | strtoull(p, NULL, 10) : | 234 | strtoull(p, NULL, 10) : |
236 | read_after_slash(p); | 235 | read_after_slash(p); |
237 | indexnext = va_arg(arg_ptr, int); | 236 | posbits -= curpos; |
237 | if (posbits <= 1) | ||
238 | return 0; | ||
238 | } | 239 | } |
239 | while (*p > ' ') p++; // skip over value | 240 | while (*p > ' ') // skip over the value |
240 | indexline++; | 241 | p++; |
242 | curpos <<= 1; | ||
241 | } | 243 | } |
242 | return 0; | 244 | return 0; |
243 | } | 245 | } |
244 | 246 | ||
245 | // Parses files with lines like "cpu0 21727 0 15718 1813856 9461 10485 0 0": | ||
246 | // rdval(file_contents, "string_to_find", result_vector, value#, value#...) | ||
247 | // value# start with 1 | ||
248 | static int rdval(const char* p, const char* key, ullong *vec, ...) | ||
249 | { | ||
250 | va_list arg_ptr; | ||
251 | int result; | ||
252 | |||
253 | va_start(arg_ptr, vec); | ||
254 | result = vrdval(p, key, conv_decimal, vec, arg_ptr); | ||
255 | va_end(arg_ptr); | ||
256 | |||
257 | return result; | ||
258 | } | ||
259 | |||
260 | // Parses files with lines like "... ... ... 3/148 ...." | 247 | // Parses files with lines like "... ... ... 3/148 ...." |
261 | static int rdval_loadavg(const char* p, ullong *vec, ...) | 248 | static int rdval_loadavg(const char* p, ullong *vec, long posbits) |
262 | { | 249 | { |
263 | va_list arg_ptr; | ||
264 | int result; | 250 | int result; |
265 | 251 | result = rdval(p, "", vec, posbits | conv_slash); | |
266 | va_start(arg_ptr, vec); | ||
267 | result = vrdval(p, "", conv_slash, vec, arg_ptr); | ||
268 | va_end(arg_ptr); | ||
269 | |||
270 | return result; | 252 | return result; |
271 | } | 253 | } |
272 | 254 | ||
@@ -337,7 +319,6 @@ static void scale(ullong ul) | |||
337 | put(buf); | 319 | put(buf); |
338 | } | 320 | } |
339 | 321 | ||
340 | |||
341 | #define S_STAT(a) \ | 322 | #define S_STAT(a) \ |
342 | typedef struct a { \ | 323 | typedef struct a { \ |
343 | struct s_stat *next; \ | 324 | struct s_stat *next; \ |
@@ -359,21 +340,12 @@ static s_stat* init_literal(void) | |||
359 | return (s_stat*)s; | 340 | return (s_stat*)s; |
360 | } | 341 | } |
361 | 342 | ||
362 | static s_stat* init_delay(const char *param) | ||
363 | { | ||
364 | delta = strtoul(param, NULL, 0) * 1000; /* param can be "" */ | ||
365 | deltanz = delta > 0 ? delta : 1; | ||
366 | need_seconds = (1000000%deltanz) != 0; | ||
367 | return NULL; | ||
368 | } | ||
369 | |||
370 | static s_stat* init_cr(const char *param UNUSED_PARAM) | 343 | static s_stat* init_cr(const char *param UNUSED_PARAM) |
371 | { | 344 | { |
372 | final_str = "\r"; | 345 | G.final_char = '\r'; |
373 | return (s_stat*)0; | 346 | return NULL; |
374 | } | 347 | } |
375 | 348 | ||
376 | |||
377 | // user nice system idle iowait irq softirq (last 3 only in 2.6) | 349 | // user nice system idle iowait irq softirq (last 3 only in 2.6) |
378 | //cpu 649369 0 341297 4336769 11640 7122 1183 | 350 | //cpu 649369 0 341297 4336769 11640 7122 1183 |
379 | //cpuN 649369 0 341297 4336769 11640 7122 1183 | 351 | //cpuN 649369 0 341297 4336769 11640 7122 1183 |
@@ -381,10 +353,9 @@ enum { CPU_FIELDCNT = 7 }; | |||
381 | S_STAT(cpu_stat) | 353 | S_STAT(cpu_stat) |
382 | ullong old[CPU_FIELDCNT]; | 354 | ullong old[CPU_FIELDCNT]; |
383 | int bar_sz; | 355 | int bar_sz; |
384 | char *bar; | 356 | char bar[1]; |
385 | S_STAT_END(cpu_stat) | 357 | S_STAT_END(cpu_stat) |
386 | 358 | ||
387 | |||
388 | static void FAST_FUNC collect_cpu(cpu_stat *s) | 359 | static void FAST_FUNC collect_cpu(cpu_stat *s) |
389 | { | 360 | { |
390 | ullong data[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 }; | 361 | ullong data[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 }; |
@@ -395,7 +366,15 @@ static void FAST_FUNC collect_cpu(cpu_stat *s) | |||
395 | char *bar = s->bar; | 366 | char *bar = s->bar; |
396 | int i; | 367 | int i; |
397 | 368 | ||
398 | if (rdval(get_file(&proc_stat), "cpu ", data, 1, 2, 3, 4, 5, 6, 7)) { | 369 | if (rdval(get_file(&proc_stat), "cpu ", data, 0 |
370 | | (1 << 1) | ||
371 | | (1 << 2) | ||
372 | | (1 << 3) | ||
373 | | (1 << 4) | ||
374 | | (1 << 5) | ||
375 | | (1 << 6) | ||
376 | | (1 << 7)) | ||
377 | ) { | ||
399 | put_question_marks(bar_sz); | 378 | put_question_marks(bar_sz); |
400 | return; | 379 | return; |
401 | } | 380 | } |
@@ -438,22 +417,20 @@ static void FAST_FUNC collect_cpu(cpu_stat *s) | |||
438 | put(s->bar); | 417 | put(s->bar); |
439 | } | 418 | } |
440 | 419 | ||
441 | |||
442 | static s_stat* init_cpu(const char *param) | 420 | static s_stat* init_cpu(const char *param) |
443 | { | 421 | { |
444 | int sz; | 422 | int sz; |
445 | cpu_stat *s = xzalloc(sizeof(*s)); | 423 | cpu_stat *s; |
446 | s->collect = collect_cpu; | ||
447 | sz = strtoul(param, NULL, 0); /* param can be "" */ | 424 | sz = strtoul(param, NULL, 0); /* param can be "" */ |
448 | if (sz < 10) sz = 10; | 425 | if (sz < 10) sz = 10; |
449 | if (sz > 1000) sz = 1000; | 426 | if (sz > 1000) sz = 1000; |
450 | s->bar = xzalloc(sz+1); | 427 | s = xzalloc(sizeof(*s) + sz); |
451 | /*s->bar[sz] = '\0'; - xzalloc did it */ | 428 | /*s->bar[sz] = '\0'; - xzalloc did it */ |
452 | s->bar_sz = sz; | 429 | s->bar_sz = sz; |
430 | s->collect = collect_cpu; | ||
453 | return (s_stat*)s; | 431 | return (s_stat*)s; |
454 | } | 432 | } |
455 | 433 | ||
456 | |||
457 | S_STAT(int_stat) | 434 | S_STAT(int_stat) |
458 | ullong old; | 435 | ullong old; |
459 | int no; | 436 | int no; |
@@ -464,7 +441,7 @@ static void FAST_FUNC collect_int(int_stat *s) | |||
464 | ullong data[1]; | 441 | ullong data[1]; |
465 | ullong old; | 442 | ullong old; |
466 | 443 | ||
467 | if (rdval(get_file(&proc_stat), "intr", data, s->no)) { | 444 | if (rdval(get_file(&proc_stat), "intr", data, 1 << s->no)) { |
468 | put_question_marks(4); | 445 | put_question_marks(4); |
469 | return; | 446 | return; |
470 | } | 447 | } |
@@ -488,7 +465,6 @@ static s_stat* init_int(const char *param) | |||
488 | return (s_stat*)s; | 465 | return (s_stat*)s; |
489 | } | 466 | } |
490 | 467 | ||
491 | |||
492 | S_STAT(ctx_stat) | 468 | S_STAT(ctx_stat) |
493 | ullong old; | 469 | ullong old; |
494 | S_STAT_END(ctx_stat) | 470 | S_STAT_END(ctx_stat) |
@@ -498,7 +474,7 @@ static void FAST_FUNC collect_ctx(ctx_stat *s) | |||
498 | ullong data[1]; | 474 | ullong data[1]; |
499 | ullong old; | 475 | ullong old; |
500 | 476 | ||
501 | if (rdval(get_file(&proc_stat), "ctxt", data, 1)) { | 477 | if (rdval(get_file(&proc_stat), "ctxt", data, 1 << 1)) { |
502 | put_question_marks(4); | 478 | put_question_marks(4); |
503 | return; | 479 | return; |
504 | } | 480 | } |
@@ -516,7 +492,6 @@ static s_stat* init_ctx(const char *param UNUSED_PARAM) | |||
516 | return (s_stat*)s; | 492 | return (s_stat*)s; |
517 | } | 493 | } |
518 | 494 | ||
519 | |||
520 | S_STAT(blk_stat) | 495 | S_STAT(blk_stat) |
521 | const char* lookfor; | 496 | const char* lookfor; |
522 | ullong old[2]; | 497 | ullong old[2]; |
@@ -530,7 +505,10 @@ static void FAST_FUNC collect_blk(blk_stat *s) | |||
530 | if (is26) { | 505 | if (is26) { |
531 | i = rdval_diskstats(get_file(&proc_diskstats), data); | 506 | i = rdval_diskstats(get_file(&proc_diskstats), data); |
532 | } else { | 507 | } else { |
533 | i = rdval(get_file(&proc_stat), s->lookfor, data, 1, 2); | 508 | i = rdval(get_file(&proc_stat), s->lookfor, data, 0 |
509 | | (1 << 1) | ||
510 | | (1 << 2) | ||
511 | ); | ||
534 | // Linux 2.4 reports bio in Kbytes, convert to sectors: | 512 | // Linux 2.4 reports bio in Kbytes, convert to sectors: |
535 | data[0] *= 2; | 513 | data[0] *= 2; |
536 | data[1] *= 2; | 514 | data[1] *= 2; |
@@ -559,7 +537,6 @@ static s_stat* init_blk(const char *param UNUSED_PARAM) | |||
559 | return (s_stat*)s; | 537 | return (s_stat*)s; |
560 | } | 538 | } |
561 | 539 | ||
562 | |||
563 | S_STAT(fork_stat) | 540 | S_STAT(fork_stat) |
564 | ullong old; | 541 | ullong old; |
565 | S_STAT_END(fork_stat) | 542 | S_STAT_END(fork_stat) |
@@ -568,7 +545,7 @@ static void FAST_FUNC collect_thread_nr(fork_stat *s UNUSED_PARAM) | |||
568 | { | 545 | { |
569 | ullong data[1]; | 546 | ullong data[1]; |
570 | 547 | ||
571 | if (rdval_loadavg(get_file(&proc_loadavg), data, 4)) { | 548 | if (rdval_loadavg(get_file(&proc_loadavg), data, 1 << 4)) { |
572 | put_question_marks(4); | 549 | put_question_marks(4); |
573 | return; | 550 | return; |
574 | } | 551 | } |
@@ -580,7 +557,7 @@ static void FAST_FUNC collect_fork(fork_stat *s) | |||
580 | ullong data[1]; | 557 | ullong data[1]; |
581 | ullong old; | 558 | ullong old; |
582 | 559 | ||
583 | if (rdval(get_file(&proc_stat), "processes", data, 1)) { | 560 | if (rdval(get_file(&proc_stat), "processes", data, 1 << 1)) { |
584 | put_question_marks(4); | 561 | put_question_marks(4); |
585 | return; | 562 | return; |
586 | } | 563 | } |
@@ -602,7 +579,6 @@ static s_stat* init_fork(const char *param) | |||
602 | return (s_stat*)s; | 579 | return (s_stat*)s; |
603 | } | 580 | } |
604 | 581 | ||
605 | |||
606 | S_STAT(if_stat) | 582 | S_STAT(if_stat) |
607 | ullong old[4]; | 583 | ullong old[4]; |
608 | const char *device; | 584 | const char *device; |
@@ -614,7 +590,12 @@ static void FAST_FUNC collect_if(if_stat *s) | |||
614 | ullong data[4]; | 590 | ullong data[4]; |
615 | int i; | 591 | int i; |
616 | 592 | ||
617 | if (rdval(get_file(&proc_net_dev), s->device_colon, data, 1, 3, 9, 11)) { | 593 | if (rdval(get_file(&proc_net_dev), s->device_colon, data, 0 |
594 | | (1 << 1) | ||
595 | | (1 << 3) | ||
596 | | (1 << 9) | ||
597 | | (1 << 11)) | ||
598 | ) { | ||
618 | put_question_marks(10); | 599 | put_question_marks(10); |
619 | return; | 600 | return; |
620 | } | 601 | } |
@@ -644,7 +625,6 @@ static s_stat* init_if(const char *device) | |||
644 | return (s_stat*)s; | 625 | return (s_stat*)s; |
645 | } | 626 | } |
646 | 627 | ||
647 | |||
648 | S_STAT(mem_stat) | 628 | S_STAT(mem_stat) |
649 | char opt; | 629 | char opt; |
650 | S_STAT_END(mem_stat) | 630 | S_STAT_END(mem_stat) |
@@ -692,7 +672,7 @@ static void FAST_FUNC collect_mem(mem_stat *s) | |||
692 | ullong m_cached = 0; | 672 | ullong m_cached = 0; |
693 | ullong m_slab = 0; | 673 | ullong m_slab = 0; |
694 | 674 | ||
695 | if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1)) { | 675 | if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1 << 1)) { |
696 | put_question_marks(4); | 676 | put_question_marks(4); |
697 | return; | 677 | return; |
698 | } | 678 | } |
@@ -701,10 +681,10 @@ static void FAST_FUNC collect_mem(mem_stat *s) | |||
701 | return; | 681 | return; |
702 | } | 682 | } |
703 | 683 | ||
704 | if (rdval(proc_meminfo.file, "MemFree:", &m_free , 1) | 684 | if (rdval(proc_meminfo.file, "MemFree:", &m_free , 1 << 1) |
705 | || rdval(proc_meminfo.file, "Buffers:", &m_bufs , 1) | 685 | || rdval(proc_meminfo.file, "Buffers:", &m_bufs , 1 << 1) |
706 | || rdval(proc_meminfo.file, "Cached:", &m_cached, 1) | 686 | || rdval(proc_meminfo.file, "Cached:", &m_cached, 1 << 1) |
707 | || rdval(proc_meminfo.file, "Slab:", &m_slab , 1) | 687 | || rdval(proc_meminfo.file, "Slab:", &m_slab , 1 << 1) |
708 | ) { | 688 | ) { |
709 | put_question_marks(4); | 689 | put_question_marks(4); |
710 | return; | 690 | return; |
@@ -727,7 +707,6 @@ static s_stat* init_mem(const char *param) | |||
727 | return (s_stat*)s; | 707 | return (s_stat*)s; |
728 | } | 708 | } |
729 | 709 | ||
730 | |||
731 | S_STAT(swp_stat) | 710 | S_STAT(swp_stat) |
732 | S_STAT_END(swp_stat) | 711 | S_STAT_END(swp_stat) |
733 | 712 | ||
@@ -735,8 +714,8 @@ static void FAST_FUNC collect_swp(swp_stat *s UNUSED_PARAM) | |||
735 | { | 714 | { |
736 | ullong s_total[1]; | 715 | ullong s_total[1]; |
737 | ullong s_free[1]; | 716 | ullong s_free[1]; |
738 | if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1) | 717 | if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1 << 1) |
739 | || rdval(proc_meminfo.file, "SwapFree:" , s_free, 1) | 718 | || rdval(proc_meminfo.file, "SwapFree:" , s_free, 1 << 1) |
740 | ) { | 719 | ) { |
741 | put_question_marks(4); | 720 | put_question_marks(4); |
742 | return; | 721 | return; |
@@ -751,7 +730,6 @@ static s_stat* init_swp(const char *param UNUSED_PARAM) | |||
751 | return (s_stat*)s; | 730 | return (s_stat*)s; |
752 | } | 731 | } |
753 | 732 | ||
754 | |||
755 | S_STAT(fd_stat) | 733 | S_STAT(fd_stat) |
756 | S_STAT_END(fd_stat) | 734 | S_STAT_END(fd_stat) |
757 | 735 | ||
@@ -759,7 +737,10 @@ static void FAST_FUNC collect_fd(fd_stat *s UNUSED_PARAM) | |||
759 | { | 737 | { |
760 | ullong data[2]; | 738 | ullong data[2]; |
761 | 739 | ||
762 | if (rdval(get_file(&proc_sys_fs_filenr), "", data, 1, 2)) { | 740 | if (rdval(get_file(&proc_sys_fs_filenr), "", data, 0 |
741 | | (1 << 1) | ||
742 | | (1 << 2)) | ||
743 | ) { | ||
763 | put_question_marks(4); | 744 | put_question_marks(4); |
764 | return; | 745 | return; |
765 | } | 746 | } |
@@ -774,17 +755,16 @@ static s_stat* init_fd(const char *param UNUSED_PARAM) | |||
774 | return (s_stat*)s; | 755 | return (s_stat*)s; |
775 | } | 756 | } |
776 | 757 | ||
777 | |||
778 | S_STAT(time_stat) | 758 | S_STAT(time_stat) |
779 | int prec; | 759 | unsigned prec; |
780 | int scale; | 760 | unsigned scale; |
781 | S_STAT_END(time_stat) | 761 | S_STAT_END(time_stat) |
782 | 762 | ||
783 | static void FAST_FUNC collect_time(time_stat *s) | 763 | static void FAST_FUNC collect_time(time_stat *s) |
784 | { | 764 | { |
785 | char buf[sizeof("12:34:56.123456")]; | 765 | char buf[sizeof("12:34:56.123456")]; |
786 | struct tm* tm; | 766 | struct tm* tm; |
787 | int us = tv.tv_usec + s->scale/2; | 767 | unsigned us = tv.tv_usec + s->scale/2; |
788 | time_t t = tv.tv_sec; | 768 | time_t t = tv.tv_sec; |
789 | 769 | ||
790 | if (us >= 1000000) { | 770 | if (us >= 1000000) { |
@@ -825,11 +805,9 @@ static void FAST_FUNC collect_info(s_stat *s) | |||
825 | } | 805 | } |
826 | } | 806 | } |
827 | 807 | ||
828 | |||
829 | typedef s_stat* init_func(const char *param); | 808 | typedef s_stat* init_func(const char *param); |
830 | 809 | ||
831 | // Deprecated %NNNd is to be removed, -d MSEC supersedes it | 810 | static const char options[] ALIGN1 = "ncmsfixptbr"; |
832 | static const char options[] ALIGN1 = "ncmsfixptbdr"; | ||
833 | static init_func *const init_functions[] = { | 811 | static init_func *const init_functions[] = { |
834 | init_if, | 812 | init_if, |
835 | init_cpu, | 813 | init_cpu, |
@@ -841,7 +819,6 @@ static init_func *const init_functions[] = { | |||
841 | init_fork, | 819 | init_fork, |
842 | init_time, | 820 | init_time, |
843 | init_blk, | 821 | init_blk, |
844 | init_delay, | ||
845 | init_cr | 822 | init_cr |
846 | }; | 823 | }; |
847 | 824 | ||
@@ -864,8 +841,11 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) | |||
864 | is26 = (strstr(buf, " 2.4.") == NULL); | 841 | is26 = (strstr(buf, " 2.4.") == NULL); |
865 | } | 842 | } |
866 | 843 | ||
867 | if (getopt32(argv, "d:", &opt_d)) | 844 | if (getopt32(argv, "d:", &opt_d)) { |
868 | init_delay(opt_d); | 845 | G.delta = xatoi(opt_d) * 1000; |
846 | G.deltanz = G.delta > 0 ? G.delta : 1; | ||
847 | need_seconds = (1000000 % G.deltanz) != 0; | ||
848 | } | ||
869 | argv += optind; | 849 | argv += optind; |
870 | 850 | ||
871 | if (!argv[0]) | 851 | if (!argv[0]) |
@@ -920,8 +900,8 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) | |||
920 | last->next = s; | 900 | last->next = s; |
921 | last = s; | 901 | last = s; |
922 | } else { | 902 | } else { |
923 | // %NNNNd or %r option. remove it from string | 903 | // %r option. remove it from string |
924 | strcpy(prev + strlen(prev), cur); | 904 | overlapping_strcpy(prev + strlen(prev), cur); |
925 | cur = prev; | 905 | cur = prev; |
926 | } | 906 | } |
927 | } | 907 | } |
@@ -939,15 +919,15 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) | |||
939 | // Generate first samples but do not print them, they're bogus | 919 | // Generate first samples but do not print them, they're bogus |
940 | collect_info(first); | 920 | collect_info(first); |
941 | reset_outbuf(); | 921 | reset_outbuf(); |
942 | if (delta >= 0) { | 922 | if (G.delta >= 0) { |
943 | gettimeofday(&tv, NULL); | 923 | gettimeofday(&tv, NULL); |
944 | usleep(delta > 1000000 ? 1000000 : delta - tv.tv_usec%deltanz); | 924 | usleep(G.delta > 1000000 ? 1000000 : G.delta - tv.tv_usec % G.deltanz); |
945 | } | 925 | } |
946 | 926 | ||
947 | while (1) { | 927 | while (1) { |
948 | gettimeofday(&tv, NULL); | 928 | gettimeofday(&tv, NULL); |
949 | collect_info(first); | 929 | collect_info(first); |
950 | put(final_str); | 930 | put_c(G.final_char); |
951 | print_outbuf(); | 931 | print_outbuf(); |
952 | 932 | ||
953 | // Negative delta -> no usleep at all | 933 | // Negative delta -> no usleep at all |
@@ -955,18 +935,18 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) | |||
955 | // time resolution ;) | 935 | // time resolution ;) |
956 | // TODO: detect and avoid useless updates | 936 | // TODO: detect and avoid useless updates |
957 | // (like: nothing happens except time) | 937 | // (like: nothing happens except time) |
958 | if (delta >= 0) { | 938 | if (G.delta >= 0) { |
959 | int rem; | 939 | int rem; |
960 | // can be commented out, will sacrifice sleep time precision a bit | 940 | // can be commented out, will sacrifice sleep time precision a bit |
961 | gettimeofday(&tv, NULL); | 941 | gettimeofday(&tv, NULL); |
962 | if (need_seconds) | 942 | if (need_seconds) |
963 | rem = delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % deltanz; | 943 | rem = G.delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % G.deltanz; |
964 | else | 944 | else |
965 | rem = delta - tv.tv_usec%deltanz; | 945 | rem = G.delta - (unsigned)tv.tv_usec % G.deltanz; |
966 | // Sometimes kernel wakes us up just a tiny bit earlier than asked | 946 | // Sometimes kernel wakes us up just a tiny bit earlier than asked |
967 | // Do not go to very short sleep in this case | 947 | // Do not go to very short sleep in this case |
968 | if (rem < delta/128) { | 948 | if (rem < (unsigned)G.delta / 128) { |
969 | rem += delta; | 949 | rem += G.delta; |
970 | } | 950 | } |
971 | usleep(rem); | 951 | usleep(rem); |
972 | } | 952 | } |
diff --git a/procps/renice.c b/procps/renice.c index 77f400a1d..2b690e0ed 100644 --- a/procps/renice.c +++ b/procps/renice.c | |||
@@ -20,13 +20,14 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | //usage:#define renice_trivial_usage | 22 | //usage:#define renice_trivial_usage |
23 | //usage: "{{-n INCREMENT} | PRIORITY} [[-p | -g | -u] ID...]" | 23 | //usage: "[-n] PRIORITY [[-p | -g | -u] ID...]..." |
24 | //usage:#define renice_full_usage "\n\n" | 24 | //usage:#define renice_full_usage "\n\n" |
25 | //usage: "Change scheduling priority for a running process\n" | 25 | //usage: "Change scheduling priority of a running process\n" |
26 | //usage: "\n -n Adjust current nice value (smaller is faster)" | 26 | //usage: "\n -n Add PRIORITY to current nice value" |
27 | //usage: "\n -p Process id(s) (default)" | 27 | //usage: "\n Without -n, nice value is set to PRIORITY" |
28 | //usage: "\n -g Process group id(s)" | 28 | //usage: "\n -p Process ids (default)" |
29 | //usage: "\n -u Process user name(s) and/or id(s)" | 29 | //usage: "\n -g Process group ids" |
30 | //usage: "\n -u Process user names" | ||
30 | 31 | ||
31 | #include "libbb.h" | 32 | #include "libbb.h" |
32 | #include <sys/resource.h> | 33 | #include <sys/resource.h> |
diff --git a/runit/chpst.c b/runit/chpst.c index 301cdd08a..7fe5151db 100644 --- a/runit/chpst.c +++ b/runit/chpst.c | |||
@@ -255,8 +255,7 @@ static NOINLINE void edir(const char *directory_name) | |||
255 | xsetenv(d->d_name, buf); | 255 | xsetenv(d->d_name, buf); |
256 | } | 256 | } |
257 | closedir(dir); | 257 | closedir(dir); |
258 | if (fchdir(wdir) == -1) | 258 | xfchdir(wdir); |
259 | bb_perror_msg_and_die("fchdir"); | ||
260 | close(wdir); | 259 | close(wdir); |
261 | } | 260 | } |
262 | 261 | ||
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index d34dfd46d..5075ebf2d 100644..100755 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh | |||
@@ -4,7 +4,9 @@ | |||
4 | # What library to link | 4 | # What library to link |
5 | ldflags() | 5 | ldflags() |
6 | { | 6 | { |
7 | for ext in so a dylib ; do | 7 | pkg-config --libs ncursesw 2>/dev/null && exit |
8 | pkg-config --libs ncurses 2>/dev/null && exit | ||
9 | for ext in so a dll.a dylib ; do | ||
8 | for lib in ncursesw ncurses curses ; do | 10 | for lib in ncursesw ncurses curses ; do |
9 | $cc -print-file-name=lib${lib}.${ext} | grep -q / | 11 | $cc -print-file-name=lib${lib}.${ext} | grep -q / |
10 | if [ $? -eq 0 ]; then | 12 | if [ $? -eq 0 ]; then |
@@ -19,14 +21,17 @@ ldflags() | |||
19 | # Where is ncurses.h? | 21 | # Where is ncurses.h? |
20 | ccflags() | 22 | ccflags() |
21 | { | 23 | { |
22 | if [ -f /usr/include/ncursesw/ncurses.h ]; then | 24 | if pkg-config --cflags ncursesw 2>/dev/null; then |
23 | echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncurses.h>"' | 25 | echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1' |
26 | elif pkg-config --cflags ncurses 2>/dev/null; then | ||
27 | echo '-DCURSES_LOC="<ncurses.h>"' | ||
24 | elif [ -f /usr/include/ncursesw/curses.h ]; then | 28 | elif [ -f /usr/include/ncursesw/curses.h ]; then |
25 | echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"' | 29 | echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"' |
30 | echo ' -DNCURSES_WIDECHAR=1' | ||
26 | elif [ -f /usr/include/ncurses/ncurses.h ]; then | 31 | elif [ -f /usr/include/ncurses/ncurses.h ]; then |
27 | echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"' | 32 | echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"' |
28 | elif [ -f /usr/include/ncurses/curses.h ]; then | 33 | elif [ -f /usr/include/ncurses/curses.h ]; then |
29 | echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"' | 34 | echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"' |
30 | elif [ -f /usr/include/ncurses.h ]; then | 35 | elif [ -f /usr/include/ncurses.h ]; then |
31 | echo '-DCURSES_LOC="<ncurses.h>"' | 36 | echo '-DCURSES_LOC="<ncurses.h>"' |
32 | else | 37 | else |
@@ -40,7 +45,7 @@ trap "rm -f $tmp" 0 1 2 3 15 | |||
40 | 45 | ||
41 | # Check if we can link to ncurses | 46 | # Check if we can link to ncurses |
42 | check() { | 47 | check() { |
43 | $cc -xc - -o $tmp 2>/dev/null <<'EOF' | 48 | $cc -x c - -o $tmp 2>/dev/null <<'EOF' |
44 | #include CURSES_LOC | 49 | #include CURSES_LOC |
45 | main() {} | 50 | main() {} |
46 | EOF | 51 | EOF |
diff --git a/scripts/trylink b/scripts/trylink index 3c431edc3..15435f009 100755 --- a/scripts/trylink +++ b/scripts/trylink | |||
@@ -140,6 +140,8 @@ try $CC $CFLAGS $LDFLAGS \ | |||
140 | || { | 140 | || { |
141 | echo "Failed: $l_list" | 141 | echo "Failed: $l_list" |
142 | cat $EXE.out | 142 | cat $EXE.out |
143 | echo 'Note: if build needs additional libraries, put them in CONFIG_EXTRA_LDLIBS.' | ||
144 | echo 'Example: CONFIG_EXTRA_LDLIBS="pthread dl tirpc audit pam"' | ||
143 | exit 1 | 145 | exit 1 |
144 | } | 146 | } |
145 | 147 | ||
diff --git a/selinux/setfiles.c b/selinux/setfiles.c index c974c4a9d..de99dfe44 100644 --- a/selinux/setfiles.c +++ b/selinux/setfiles.c | |||
@@ -17,6 +17,7 @@ | |||
17 | //usage: ) | 17 | //usage: ) |
18 | //usage: "\n -d Show which specification matched each file" | 18 | //usage: "\n -d Show which specification matched each file" |
19 | //usage: "\n -l Log changes in file labels to syslog" | 19 | //usage: "\n -l Log changes in file labels to syslog" |
20 | //TODO: log to syslog is not yet implemented, it goes to stdout only now | ||
20 | //usage: "\n -n Don't change any file labels" | 21 | //usage: "\n -n Don't change any file labels" |
21 | //usage: "\n -q Suppress warnings" | 22 | //usage: "\n -q Suppress warnings" |
22 | //usage: "\n -r DIR Use an alternate root path" | 23 | //usage: "\n -r DIR Use an alternate root path" |
@@ -383,16 +384,16 @@ static int restore(const char *file) | |||
383 | * the user has changed but the role and type are the | 384 | * the user has changed but the role and type are the |
384 | * same. For "-vv", emit everything. */ | 385 | * same. For "-vv", emit everything. */ |
385 | if (verbose > 1 || !user_only_changed) { | 386 | if (verbose > 1 || !user_only_changed) { |
386 | bb_info_msg("%s: reset %s context %s->%s", | 387 | printf("%s: reset %s context %s->%s\n", |
387 | applet_name, my_file, context ? context : "", newcon); | 388 | applet_name, my_file, context ? context : "", newcon); |
388 | } | 389 | } |
389 | } | 390 | } |
390 | 391 | ||
391 | if (FLAG_l_take_log && !user_only_changed) { | 392 | if (FLAG_l_take_log && !user_only_changed) { |
392 | if (context) | 393 | if (context) |
393 | bb_info_msg("relabeling %s from %s to %s", my_file, context, newcon); | 394 | printf("relabeling %s from %s to %s\n", my_file, context, newcon); |
394 | else | 395 | else |
395 | bb_info_msg("labeling %s to %s", my_file, newcon); | 396 | printf("labeling %s to %s\n", my_file, newcon); |
396 | } | 397 | } |
397 | 398 | ||
398 | if (outfile && !user_only_changed) | 399 | if (outfile && !user_only_changed) |
diff --git a/shell/ash.c b/shell/ash.c index 57d192822..7cad34511 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -7026,6 +7026,8 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list) | |||
7026 | if (subtype == VSLENGTH && len > 0) { | 7026 | if (subtype == VSLENGTH && len > 0) { |
7027 | reinit_unicode_for_ash(); | 7027 | reinit_unicode_for_ash(); |
7028 | if (unicode_status == UNICODE_ON) { | 7028 | if (unicode_status == UNICODE_ON) { |
7029 | STADJUST(-len, expdest); | ||
7030 | discard = 0; | ||
7029 | len = unicode_strlen(p); | 7031 | len = unicode_strlen(p); |
7030 | } | 7032 | } |
7031 | } | 7033 | } |
diff --git a/shell/ash_test/.gitignore b/shell/ash_test/.gitignore new file mode 100644 index 000000000..a1f937cdd --- /dev/null +++ b/shell/ash_test/.gitignore | |||
@@ -0,0 +1,7 @@ | |||
1 | /ash | ||
2 | /printenv | ||
3 | /recho | ||
4 | /zecho | ||
5 | |||
6 | /*.fail | ||
7 | *.xx | ||
diff --git a/shell/ash_test/ash-vars/var-utf8-length.right b/shell/ash_test/ash-vars/var-utf8-length.right new file mode 100644 index 000000000..6f4247a62 --- /dev/null +++ b/shell/ash_test/ash-vars/var-utf8-length.right | |||
@@ -0,0 +1 @@ | |||
26 | |||
diff --git a/shell/ash_test/ash-vars/var-utf8-length.tests b/shell/ash_test/ash-vars/var-utf8-length.tests new file mode 100755 index 000000000..d04b2cbb6 --- /dev/null +++ b/shell/ash_test/ash-vars/var-utf8-length.tests | |||
@@ -0,0 +1,2 @@ | |||
1 | X=abcdÉfghÍjklmnÓpqrstÚvwcyz | ||
2 | echo ${#X} | ||
diff --git a/shell/ash_test/printenv.c b/shell/ash_test/printenv.c index c4ccda8a6..c0c5e197c 100644 --- a/shell/ash_test/printenv.c +++ b/shell/ash_test/printenv.c | |||
@@ -24,6 +24,7 @@ | |||
24 | with Bash; see the file COPYING. If not, write to the Free Software | 24 | with Bash; see the file COPYING. If not, write to the Free Software |
25 | Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ | 25 | Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ |
26 | 26 | ||
27 | #include <stdio.h> | ||
27 | #include <stdlib.h> | 28 | #include <stdlib.h> |
28 | #include <string.h> | 29 | #include <string.h> |
29 | 30 | ||
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 0ea557a6c..a119bdeae 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c | |||
@@ -33,7 +33,7 @@ | |||
33 | //config: depends on SYSLOGD | 33 | //config: depends on SYSLOGD |
34 | //config: help | 34 | //config: help |
35 | //config: This enables syslogd to rotate the message files | 35 | //config: This enables syslogd to rotate the message files |
36 | //config: on his own. No need to use an external rotatescript. | 36 | //config: on his own. No need to use an external rotate script. |
37 | //config: | 37 | //config: |
38 | //config:config FEATURE_REMOTE_LOG | 38 | //config:config FEATURE_REMOTE_LOG |
39 | //config: bool "Remote Log support" | 39 | //config: bool "Remote Log support" |
@@ -133,7 +133,7 @@ | |||
133 | //usage: IF_FEATURE_KMSG_SYSLOG( | 133 | //usage: IF_FEATURE_KMSG_SYSLOG( |
134 | //usage: "\n -K Log to kernel printk buffer (use dmesg to read it)" | 134 | //usage: "\n -K Log to kernel printk buffer (use dmesg to read it)" |
135 | //usage: ) | 135 | //usage: ) |
136 | //usage: "\n -O FILE Log to FILE (default:/var/log/messages, stdout if -)" | 136 | //usage: "\n -O FILE Log to FILE (default: /var/log/messages, stdout if -)" |
137 | //usage: IF_FEATURE_ROTATE_LOGFILE( | 137 | //usage: IF_FEATURE_ROTATE_LOGFILE( |
138 | //usage: "\n -s SIZE Max size (KB) before rotation (default:200KB, 0=off)" | 138 | //usage: "\n -s SIZE Max size (KB) before rotation (default:200KB, 0=off)" |
139 | //usage: "\n -b N N rotated logs to keep (default:1, max=99, 0=purge)" | 139 | //usage: "\n -b N N rotated logs to keep (default:1, max=99, 0=purge)" |
diff --git a/util-linux/fbset.c b/util-linux/fbset.c index ac0082f70..09e96b763 100644 --- a/util-linux/fbset.c +++ b/util-linux/fbset.c | |||
@@ -248,12 +248,12 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, | |||
248 | if (!p) | 248 | if (!p) |
249 | continue; | 249 | continue; |
250 | s = p + strlen(mode); | 250 | s = p + strlen(mode); |
251 | //bb_info_msg("CHECK[%s][%s][%d]", mode, p-1, *s); | 251 | //bb_error_msg("CHECK[%s][%s][%d]", mode, p-1, *s); |
252 | /* exact match? */ | 252 | /* exact match? */ |
253 | if (((!*s || isspace(*s)) && '"' != s[-1]) /* end-of-token */ | 253 | if (((!*s || isspace(*s)) && '"' != s[-1]) /* end-of-token */ |
254 | || ('"' == *s && '"' == p[-1]) /* ends with " but starts with " too! */ | 254 | || ('"' == *s && '"' == p[-1]) /* ends with " but starts with " too! */ |
255 | ) { | 255 | ) { |
256 | //bb_info_msg("FOUND[%s][%s][%s][%d]", token[1], p, mode, isspace(*s)); | 256 | //bb_error_msg("FOUND[%s][%s][%s][%d]", token[1], p, mode, isspace(*s)); |
257 | break; | 257 | break; |
258 | } | 258 | } |
259 | } | 259 | } |
@@ -264,9 +264,9 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, | |||
264 | while (config_read(parser, token, 2, 1, "# \t", PARSE_NORMAL)) { | 264 | while (config_read(parser, token, 2, 1, "# \t", PARSE_NORMAL)) { |
265 | int i; | 265 | int i; |
266 | 266 | ||
267 | //bb_info_msg("???[%s][%s]", token[0], token[1]); | 267 | //bb_error_msg("???[%s][%s]", token[0], token[1]); |
268 | if (strcmp(token[0], "endmode") == 0) { | 268 | if (strcmp(token[0], "endmode") == 0) { |
269 | //bb_info_msg("OK[%s]", mode); | 269 | //bb_error_msg("OK[%s]", mode); |
270 | return 1; | 270 | return 1; |
271 | } | 271 | } |
272 | p = token[1]; | 272 | p = token[1]; |
@@ -294,7 +294,7 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, | |||
294 | base->yres_virtual = base_yres_virtual; | 294 | base->yres_virtual = base_yres_virtual; |
295 | base->bits_per_pixel = base_bits_per_pixel; | 295 | base->bits_per_pixel = base_bits_per_pixel; |
296 | } | 296 | } |
297 | //bb_info_msg("GEO[%s]", p); | 297 | //bb_error_msg("GEO[%s]", p); |
298 | break; | 298 | break; |
299 | case 1: | 299 | case 1: |
300 | if (sizeof(int) == sizeof(base->xres)) { | 300 | if (sizeof(int) == sizeof(base->xres)) { |
@@ -321,13 +321,13 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, | |||
321 | base->hsync_len = base_hsync_len; | 321 | base->hsync_len = base_hsync_len; |
322 | base->vsync_len = base_vsync_len; | 322 | base->vsync_len = base_vsync_len; |
323 | } | 323 | } |
324 | //bb_info_msg("TIM[%s]", p); | 324 | //bb_error_msg("TIM[%s]", p); |
325 | break; | 325 | break; |
326 | case 2: | 326 | case 2: |
327 | case 3: { | 327 | case 3: { |
328 | static const uint32_t syncs[] = {FB_VMODE_INTERLACED, FB_VMODE_DOUBLE}; | 328 | static const uint32_t syncs[] = {FB_VMODE_INTERLACED, FB_VMODE_DOUBLE}; |
329 | ss(&base->vmode, syncs[i-2], p, "false"); | 329 | ss(&base->vmode, syncs[i-2], p, "false"); |
330 | //bb_info_msg("VMODE[%s]", p); | 330 | //bb_error_msg("VMODE[%s]", p); |
331 | break; | 331 | break; |
332 | } | 332 | } |
333 | case 4: | 333 | case 4: |
@@ -335,12 +335,12 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, | |||
335 | case 6: { | 335 | case 6: { |
336 | static const uint32_t syncs[] = {FB_SYNC_VERT_HIGH_ACT, FB_SYNC_HOR_HIGH_ACT, FB_SYNC_COMP_HIGH_ACT}; | 336 | static const uint32_t syncs[] = {FB_SYNC_VERT_HIGH_ACT, FB_SYNC_HOR_HIGH_ACT, FB_SYNC_COMP_HIGH_ACT}; |
337 | ss(&base->sync, syncs[i-4], p, "low"); | 337 | ss(&base->sync, syncs[i-4], p, "low"); |
338 | //bb_info_msg("SYNC[%s]", p); | 338 | //bb_error_msg("SYNC[%s]", p); |
339 | break; | 339 | break; |
340 | } | 340 | } |
341 | case 7: | 341 | case 7: |
342 | ss(&base->sync, FB_SYNC_EXT, p, "false"); | 342 | ss(&base->sync, FB_SYNC_EXT, p, "false"); |
343 | //bb_info_msg("EXTSYNC[%s]", p); | 343 | //bb_error_msg("EXTSYNC[%s]", p); |
344 | break; | 344 | break; |
345 | case 8: { | 345 | case 8: { |
346 | int red_offset, red_length; | 346 | int red_offset, red_length; |
diff --git a/util-linux/minix.h b/util-linux/minix.h index e0fbcf761..83ffe6da5 100644 --- a/util-linux/minix.h +++ b/util-linux/minix.h | |||
@@ -61,9 +61,14 @@ enum { | |||
61 | MINIX_ROOT_INO = 1, | 61 | MINIX_ROOT_INO = 1, |
62 | MINIX_BAD_INO = 2, | 62 | MINIX_BAD_INO = 2, |
63 | 63 | ||
64 | #undef MINIX1_SUPER_MAGIC | ||
64 | MINIX1_SUPER_MAGIC = 0x137F, /* original minix fs */ | 65 | MINIX1_SUPER_MAGIC = 0x137F, /* original minix fs */ |
66 | #undef MINIX1_SUPER_MAGIC2 | ||
65 | MINIX1_SUPER_MAGIC2 = 0x138F, /* minix fs, 30 char names */ | 67 | MINIX1_SUPER_MAGIC2 = 0x138F, /* minix fs, 30 char names */ |
68 | /* bionic has this define */ | ||
69 | #undef MINIX2_SUPER_MAGIC | ||
66 | MINIX2_SUPER_MAGIC = 0x2468, /* minix V2 fs */ | 70 | MINIX2_SUPER_MAGIC = 0x2468, /* minix V2 fs */ |
71 | #undef MINIX2_SUPER_MAGIC2 | ||
67 | MINIX2_SUPER_MAGIC2 = 0x2478, /* minix V2 fs, 30 char names */ | 72 | MINIX2_SUPER_MAGIC2 = 0x2478, /* minix V2 fs, 30 char names */ |
68 | MINIX_VALID_FS = 0x0001, /* clean fs */ | 73 | MINIX_VALID_FS = 0x0001, /* clean fs */ |
69 | MINIX_ERROR_FS = 0x0002, /* fs has errors */ | 74 | MINIX_ERROR_FS = 0x0002, /* fs has errors */ |
diff --git a/util-linux/mkfs_ext2.c b/util-linux/mkfs_ext2.c index 3258d7eee..f91a0b4bf 100644 --- a/util-linux/mkfs_ext2.c +++ b/util-linux/mkfs_ext2.c | |||
@@ -116,7 +116,7 @@ static void allocate(uint8_t *bitmap, uint32_t blocksize, uint32_t start, uint32 | |||
116 | { | 116 | { |
117 | uint32_t i; | 117 | uint32_t i; |
118 | 118 | ||
119 | //bb_info_msg("ALLOC: [%u][%u][%u]: [%u-%u]:=[%x],[%x]", blocksize, start, end, start/8, blocksize - end/8 - 1, (1 << (start & 7)) - 1, (uint8_t)(0xFF00 >> (end & 7))); | 119 | //bb_error_msg("ALLOC: [%u][%u][%u]: [%u-%u]:=[%x],[%x]", blocksize, start, end, start/8, blocksize - end/8 - 1, (1 << (start & 7)) - 1, (uint8_t)(0xFF00 >> (end & 7))); |
120 | memset(bitmap, 0, blocksize); | 120 | memset(bitmap, 0, blocksize); |
121 | i = start / 8; | 121 | i = start / 8; |
122 | memset(bitmap, 0xFF, i); | 122 | memset(bitmap, 0xFF, i); |
@@ -151,7 +151,7 @@ static uint32_t has_super(uint32_t x) | |||
151 | 151 | ||
152 | static void PUT(uint64_t off, void *buf, uint32_t size) | 152 | static void PUT(uint64_t off, void *buf, uint32_t size) |
153 | { | 153 | { |
154 | // bb_info_msg("PUT[%llu]:[%u]", off, size); | 154 | //bb_error_msg("PUT[%llu]:[%u]", off, size); |
155 | xlseek(fd, off, SEEK_SET); | 155 | xlseek(fd, off, SEEK_SET); |
156 | xwrite(fd, buf, size); | 156 | xwrite(fd, buf, size); |
157 | } | 157 | } |
@@ -412,7 +412,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
412 | // (a bit after 8M image size), but it works for two->three groups | 412 | // (a bit after 8M image size), but it works for two->three groups |
413 | // transition (at 16M). | 413 | // transition (at 16M). |
414 | if (remainder && (remainder < overhead + 50)) { | 414 | if (remainder && (remainder < overhead + 50)) { |
415 | //bb_info_msg("CHOP[%u]", remainder); | 415 | //bb_error_msg("CHOP[%u]", remainder); |
416 | nblocks -= remainder; | 416 | nblocks -= remainder; |
417 | goto retry; | 417 | goto retry; |
418 | } | 418 | } |
@@ -568,7 +568,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
568 | free_blocks = (n < blocks_per_group ? n : blocks_per_group) - overhead; | 568 | free_blocks = (n < blocks_per_group ? n : blocks_per_group) - overhead; |
569 | 569 | ||
570 | // mark preallocated blocks as allocated | 570 | // mark preallocated blocks as allocated |
571 | //bb_info_msg("ALLOC: [%u][%u][%u]", blocksize, overhead, blocks_per_group - (free_blocks + overhead)); | 571 | //bb_error_msg("ALLOC: [%u][%u][%u]", blocksize, overhead, blocks_per_group - (free_blocks + overhead)); |
572 | allocate(buf, blocksize, | 572 | allocate(buf, blocksize, |
573 | // reserve "overhead" blocks | 573 | // reserve "overhead" blocks |
574 | overhead, | 574 | overhead, |
@@ -647,7 +647,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
647 | n = FETCH_LE32(inode->i_block[0]) + 1; | 647 | n = FETCH_LE32(inode->i_block[0]) + 1; |
648 | for (i = 0; i < lost_and_found_blocks; ++i) | 648 | for (i = 0; i < lost_and_found_blocks; ++i) |
649 | STORE_LE(inode->i_block[i], i + n); // use next block | 649 | STORE_LE(inode->i_block[i], i + n); // use next block |
650 | //bb_info_msg("LAST BLOCK USED[%u]", i + n); | 650 | //bb_error_msg("LAST BLOCK USED[%u]", i + n); |
651 | PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_GOOD_OLD_FIRST_INO-1) * inodesize, | 651 | PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_GOOD_OLD_FIRST_INO-1) * inodesize, |
652 | buf, inodesize); | 652 | buf, inodesize); |
653 | 653 | ||
diff --git a/util-linux/mkfs_vfat.c b/util-linux/mkfs_vfat.c index 7d81ed06d..d53c751eb 100644 --- a/util-linux/mkfs_vfat.c +++ b/util-linux/mkfs_vfat.c | |||
@@ -578,7 +578,7 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) | |||
578 | start_data_sector = (reserved_sect + NUM_FATS * sect_per_fat) * (bytes_per_sect / SECTOR_SIZE); | 578 | start_data_sector = (reserved_sect + NUM_FATS * sect_per_fat) * (bytes_per_sect / SECTOR_SIZE); |
579 | start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) / SECTORS_PER_BLOCK; | 579 | start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) / SECTORS_PER_BLOCK; |
580 | 580 | ||
581 | bb_info_msg("searching for bad blocks "); | 581 | bb_error_msg("searching for bad blocks"); |
582 | currently_testing = 0; | 582 | currently_testing = 0; |
583 | try = TEST_BUFFER_BLOCKS; | 583 | try = TEST_BUFFER_BLOCKS; |
584 | while (currently_testing < volume_size_blocks) { | 584 | while (currently_testing < volume_size_blocks) { |
@@ -616,7 +616,7 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) | |||
616 | } | 616 | } |
617 | free(blkbuf); | 617 | free(blkbuf); |
618 | if (badblocks) | 618 | if (badblocks) |
619 | bb_info_msg("%d bad block(s)", badblocks); | 619 | bb_error_msg("%d bad block(s)", badblocks); |
620 | } | 620 | } |
621 | #endif | 621 | #endif |
622 | 622 | ||
diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c new file mode 100644 index 000000000..b08b3dae7 --- /dev/null +++ b/util-linux/nsenter.c | |||
@@ -0,0 +1,291 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Mini nsenter implementation for busybox. | ||
4 | * | ||
5 | * Copyright (C) 2016 by Bartosz Golaszewski <bartekgola@gmail.com> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | |||
10 | //config:config NSENTER | ||
11 | //config: bool "nsenter" | ||
12 | //config: default y | ||
13 | //config: select PLATFORM_LINUX | ||
14 | //config: help | ||
15 | //config: Run program with namespaces of other processes. | ||
16 | //config: | ||
17 | //config:config FEATURE_NSENTER_LONG_OPTS | ||
18 | //config: bool "Enable long options" | ||
19 | //config: default y | ||
20 | //config: depends on NSENTER && LONG_OPTS | ||
21 | //config: help | ||
22 | //config: Support long options for the nsenter applet. This makes | ||
23 | //config: the busybox implementation more compatible with upstream. | ||
24 | |||
25 | //applet:IF_NSENTER(APPLET(nsenter, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
26 | |||
27 | //kbuild:lib-$(CONFIG_NSENTER) += nsenter.o | ||
28 | |||
29 | //usage:#define nsenter_trivial_usage | ||
30 | //usage: "[OPTIONS] [PROG [ARGS]]" | ||
31 | //usage:#if ENABLE_FEATURE_NSENTER_LONG_OPTS | ||
32 | //usage:#define nsenter_full_usage "\n" | ||
33 | //usage: "\n -t, --target=PID Target process to get namespaces from" | ||
34 | //usage: "\n -m, --mount[=FILE] Enter mount namespace" | ||
35 | //usage: "\n -u, --uts[=FILE] Enter UTS namespace (hostname etc)" | ||
36 | //usage: "\n -i, --ipc[=FILE] Enter System V IPC namespace" | ||
37 | //usage: "\n -n, --net[=FILE] Enter network namespace" | ||
38 | //usage: "\n -p, --pid[=FILE] Enter pid namespace" | ||
39 | //usage: "\n -U, --user[=FILE] Enter user namespace" | ||
40 | //usage: "\n -S, --setuid=UID Set uid in entered namespace" | ||
41 | //usage: "\n -G, --setgid=GID Set gid in entered namespace" | ||
42 | //usage: "\n --preserve-credentials Don't touch uids or gids" | ||
43 | //usage: "\n -r, --root[=DIR] Set root directory" | ||
44 | //usage: "\n -w, --wd[=DIR] Set working directory" | ||
45 | //usage: "\n -F, --no-fork Don't fork before exec'ing PROG" | ||
46 | //usage:#else | ||
47 | //usage:#define nsenter_full_usage "\n" | ||
48 | //usage: "\n -t PID Target process to get namespaces from" | ||
49 | //usage: "\n -m[FILE] Enter mount namespace" | ||
50 | //usage: "\n -u[FILE] Enter UTS namespace (hostname etc)" | ||
51 | //usage: "\n -i[FILE] Enter System V IPC namespace" | ||
52 | //usage: "\n -n[FILE] Enter network namespace" | ||
53 | //usage: "\n -p[FILE] Enter pid namespace" | ||
54 | //usage: "\n -U[FILE] Enter user namespace" | ||
55 | //usage: "\n -S UID Set uid in entered namespace" | ||
56 | //usage: "\n -G GID Set gid in entered namespace" | ||
57 | //usage: "\n -r[DIR] Set root directory" | ||
58 | //usage: "\n -w[DIR] Set working directory" | ||
59 | //usage: "\n -F Don't fork before exec'ing PROG" | ||
60 | //usage:#endif | ||
61 | |||
62 | #include <sched.h> | ||
63 | #ifndef CLONE_NEWUTS | ||
64 | # define CLONE_NEWUTS 0x04000000 | ||
65 | #endif | ||
66 | #ifndef CLONE_NEWIPC | ||
67 | # define CLONE_NEWIPC 0x08000000 | ||
68 | #endif | ||
69 | #ifndef CLONE_NEWUSER | ||
70 | # define CLONE_NEWUSER 0x10000000 | ||
71 | #endif | ||
72 | #ifndef CLONE_NEWPID | ||
73 | # define CLONE_NEWPID 0x20000000 | ||
74 | #endif | ||
75 | #ifndef CLONE_NEWNET | ||
76 | # define CLONE_NEWNET 0x40000000 | ||
77 | #endif | ||
78 | |||
79 | #include "libbb.h" | ||
80 | |||
81 | struct namespace_descr { | ||
82 | int flag; /* value passed to setns() */ | ||
83 | char ns_nsfile8[8]; /* "ns/" + namespace file in process' procfs entry */ | ||
84 | }; | ||
85 | |||
86 | struct namespace_ctx { | ||
87 | char *path; /* optional path to a custom ns file */ | ||
88 | int fd; /* opened namespace file descriptor */ | ||
89 | }; | ||
90 | |||
91 | enum { | ||
92 | OPT_user = 1 << 0, | ||
93 | OPT_ipc = 1 << 1, | ||
94 | OPT_uts = 1 << 2, | ||
95 | OPT_network = 1 << 3, | ||
96 | OPT_pid = 1 << 4, | ||
97 | OPT_mount = 1 << 5, | ||
98 | OPT_target = 1 << 6, | ||
99 | OPT_setuid = 1 << 7, | ||
100 | OPT_setgid = 1 << 8, | ||
101 | OPT_root = 1 << 9, | ||
102 | OPT_wd = 1 << 10, | ||
103 | OPT_nofork = 1 << 11, | ||
104 | OPT_prescred = (1 << 12) * ENABLE_FEATURE_NSENTER_LONG_OPTS, | ||
105 | }; | ||
106 | enum { | ||
107 | NS_USR_POS = 0, | ||
108 | NS_IPC_POS, | ||
109 | NS_UTS_POS, | ||
110 | NS_NET_POS, | ||
111 | NS_PID_POS, | ||
112 | NS_MNT_POS, | ||
113 | NS_COUNT, | ||
114 | }; | ||
115 | /* | ||
116 | * The order is significant in nsenter. | ||
117 | * The user namespace comes first, so that it is entered first. | ||
118 | * This gives an unprivileged user the potential to enter other namespaces. | ||
119 | */ | ||
120 | static const struct namespace_descr ns_list[] = { | ||
121 | { CLONE_NEWUSER, "ns/user", }, | ||
122 | { CLONE_NEWIPC, "ns/ipc", }, | ||
123 | { CLONE_NEWUTS, "ns/uts", }, | ||
124 | { CLONE_NEWNET, "ns/net", }, | ||
125 | { CLONE_NEWPID, "ns/pid", }, | ||
126 | { CLONE_NEWNS, "ns/mnt", }, | ||
127 | }; | ||
128 | /* | ||
129 | * Upstream nsenter doesn't support the short option for --preserve-credentials | ||
130 | */ | ||
131 | static const char opt_str[] = "U::i::u::n::p::m::""t+S+G+r::w::F"; | ||
132 | |||
133 | #if ENABLE_FEATURE_NSENTER_LONG_OPTS | ||
134 | static const char nsenter_longopts[] ALIGN1 = | ||
135 | "user\0" Optional_argument "U" | ||
136 | "ipc\0" Optional_argument "i" | ||
137 | "uts\0" Optional_argument "u" | ||
138 | "network\0" Optional_argument "n" | ||
139 | "pid\0" Optional_argument "p" | ||
140 | "mount\0" Optional_argument "m" | ||
141 | "target\0" Required_argument "t" | ||
142 | "setuid\0" Required_argument "S" | ||
143 | "setgid\0" Required_argument "G" | ||
144 | "root\0" Optional_argument "r" | ||
145 | "wd\0" Optional_argument "w" | ||
146 | "no-fork\0" No_argument "F" | ||
147 | "preserve-credentials\0" No_argument "\xff" | ||
148 | ; | ||
149 | #endif | ||
150 | |||
151 | /* | ||
152 | * Open a file and return the new descriptor. If a full path is provided in | ||
153 | * fs_path, then the file to which it points is opened. Otherwise (fd_path is | ||
154 | * NULL) the routine builds a path to a procfs file using the following | ||
155 | * template: '/proc/<target_pid>/<target_file>'. | ||
156 | */ | ||
157 | static int open_by_path_or_target(const char *path, | ||
158 | pid_t target_pid, const char *target_file) | ||
159 | { | ||
160 | char proc_path_buf[sizeof("/proc/%u/1234567890") + sizeof(int)*3]; | ||
161 | |||
162 | if (!path) { | ||
163 | if (target_pid == 0) { | ||
164 | /* Example: | ||
165 | * "nsenter -p PROG" - neither -pFILE nor -tPID given. | ||
166 | */ | ||
167 | bb_show_usage(); | ||
168 | } | ||
169 | snprintf(proc_path_buf, sizeof(proc_path_buf), | ||
170 | "/proc/%u/%s", (unsigned)target_pid, target_file); | ||
171 | path = proc_path_buf; | ||
172 | } | ||
173 | |||
174 | return xopen(path, O_RDONLY); | ||
175 | } | ||
176 | |||
177 | int nsenter_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
178 | int nsenter_main(int argc UNUSED_PARAM, char **argv) | ||
179 | { | ||
180 | int i; | ||
181 | unsigned int opts; | ||
182 | const char *root_dir_str = NULL; | ||
183 | const char *wd_str = NULL; | ||
184 | struct namespace_ctx ns_ctx_list[NS_COUNT]; | ||
185 | int setgroups_failed; | ||
186 | int root_fd, wd_fd; | ||
187 | int target_pid = 0; | ||
188 | int uid = 0; | ||
189 | int gid = 0; | ||
190 | |||
191 | memset(ns_ctx_list, 0, sizeof(ns_ctx_list)); | ||
192 | |||
193 | IF_FEATURE_NSENTER_LONG_OPTS(applet_long_options = nsenter_longopts); | ||
194 | opts = getopt32(argv, opt_str, | ||
195 | &ns_ctx_list[NS_USR_POS].path, | ||
196 | &ns_ctx_list[NS_IPC_POS].path, | ||
197 | &ns_ctx_list[NS_UTS_POS].path, | ||
198 | &ns_ctx_list[NS_NET_POS].path, | ||
199 | &ns_ctx_list[NS_PID_POS].path, | ||
200 | &ns_ctx_list[NS_MNT_POS].path, | ||
201 | &target_pid, &uid, &gid, | ||
202 | &root_dir_str, &wd_str | ||
203 | ); | ||
204 | argv += optind; | ||
205 | |||
206 | root_fd = wd_fd = -1; | ||
207 | if (opts & OPT_root) | ||
208 | root_fd = open_by_path_or_target(root_dir_str, | ||
209 | target_pid, "root"); | ||
210 | if (opts & OPT_wd) | ||
211 | wd_fd = open_by_path_or_target(wd_str, target_pid, "cwd"); | ||
212 | |||
213 | for (i = 0; i < NS_COUNT; i++) { | ||
214 | const struct namespace_descr *ns = &ns_list[i]; | ||
215 | struct namespace_ctx *ns_ctx = &ns_ctx_list[i]; | ||
216 | |||
217 | ns_ctx->fd = -1; | ||
218 | if (opts & (1 << i)) | ||
219 | ns_ctx->fd = open_by_path_or_target(ns_ctx->path, | ||
220 | target_pid, ns->ns_nsfile8); | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Entering the user namespace without --preserve-credentials implies | ||
225 | * --setuid & --setgid and clearing root's groups. | ||
226 | */ | ||
227 | setgroups_failed = 0; | ||
228 | if ((opts & OPT_user) && !(opts & OPT_prescred)) { | ||
229 | opts |= (OPT_setuid | OPT_setgid); | ||
230 | /* | ||
231 | * We call setgroups() before and after setns() and only | ||
232 | * bail-out if it fails twice. | ||
233 | */ | ||
234 | setgroups_failed = (setgroups(0, NULL) < 0); | ||
235 | } | ||
236 | |||
237 | for (i = 0; i < NS_COUNT; i++) { | ||
238 | const struct namespace_descr *ns = &ns_list[i]; | ||
239 | struct namespace_ctx *ns_ctx = &ns_ctx_list[i]; | ||
240 | |||
241 | if (ns_ctx->fd < 0) | ||
242 | continue; | ||
243 | if (setns(ns_ctx->fd, ns->flag)) { | ||
244 | bb_perror_msg_and_die( | ||
245 | "setns(): can't reassociate to namespace '%s'", | ||
246 | ns->ns_nsfile8 + 3 /* skip over "ns/" */ | ||
247 | ); | ||
248 | } | ||
249 | close(ns_ctx->fd); /* should close fds, to not confuse exec'ed PROG */ | ||
250 | /*ns_ctx->fd = -1;*/ | ||
251 | } | ||
252 | |||
253 | if (root_fd >= 0) { | ||
254 | if (wd_fd < 0) { | ||
255 | /* | ||
256 | * Save the current working directory if we're not | ||
257 | * changing it. | ||
258 | */ | ||
259 | wd_fd = xopen(".", O_RDONLY); | ||
260 | } | ||
261 | xfchdir(root_fd); | ||
262 | xchroot("."); | ||
263 | close(root_fd); | ||
264 | /*root_fd = -1;*/ | ||
265 | } | ||
266 | |||
267 | if (wd_fd >= 0) { | ||
268 | xfchdir(wd_fd); | ||
269 | close(wd_fd); | ||
270 | /*wd_fd = -1;*/ | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * Entering the pid namespace implies forking unless it's been | ||
275 | * explicitly requested by the user not to. | ||
276 | */ | ||
277 | if (!(opts & OPT_nofork) && (opts & OPT_pid)) { | ||
278 | xvfork_parent_waits_and_exits(); | ||
279 | /* Child continues */ | ||
280 | } | ||
281 | |||
282 | if (opts & OPT_setgid) { | ||
283 | if (setgroups(0, NULL) < 0 && setgroups_failed) | ||
284 | bb_perror_msg_and_die("setgroups"); | ||
285 | xsetgid(gid); | ||
286 | } | ||
287 | if (opts & OPT_setuid) | ||
288 | xsetuid(uid); | ||
289 | |||
290 | exec_prog_or_SHELL(argv); | ||
291 | } | ||
diff --git a/util-linux/umount.c b/util-linux/umount.c index 00910977d..30bef1686 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c | |||
@@ -30,6 +30,9 @@ | |||
30 | 30 | ||
31 | #include <mntent.h> | 31 | #include <mntent.h> |
32 | #include <sys/mount.h> | 32 | #include <sys/mount.h> |
33 | #ifndef MNT_DETACH | ||
34 | # define MNT_DETACH 0x00000002 | ||
35 | #endif | ||
33 | #include "libbb.h" | 36 | #include "libbb.h" |
34 | 37 | ||
35 | #if defined(__dietlibc__) | 38 | #if defined(__dietlibc__) |
diff --git a/util-linux/unshare.c b/util-linux/unshare.c new file mode 100644 index 000000000..d05cfdb6c --- /dev/null +++ b/util-linux/unshare.c | |||
@@ -0,0 +1,380 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Mini unshare implementation for busybox. | ||
4 | * | ||
5 | * Copyright (C) 2016 by Bartosz Golaszewski <bartekgola@gmail.com> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | |||
10 | //config:config UNSHARE | ||
11 | //config: bool "unshare" | ||
12 | //config: default y | ||
13 | //config: depends on LONG_OPTS && !NOMMU | ||
14 | //config: select PLATFORM_LINUX | ||
15 | //config: help | ||
16 | //config: Run program with some namespaces unshared from parent. | ||
17 | |||
18 | // depends on LONG_OPTS: it is awkward to exclude code which handles --propagation | ||
19 | // and --setgroups based on LONG_OPTS, so instead applet requires LONG_OPTS. | ||
20 | // depends on !NOMMU: we need fork() | ||
21 | |||
22 | //applet:IF_UNSHARE(APPLET(unshare, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
23 | |||
24 | //kbuild:lib-$(CONFIG_UNSHARE) += unshare.o | ||
25 | |||
26 | //usage:#define unshare_trivial_usage | ||
27 | //usage: "[OPTIONS] [PROG [ARGS]]" | ||
28 | //usage:#define unshare_full_usage "\n" | ||
29 | //usage: "\n -m, --mount[=FILE] Unshare mount namespace" | ||
30 | //usage: "\n -u, --uts[=FILE] Unshare UTS namespace (hostname etc.)" | ||
31 | //usage: "\n -i, --ipc[=FILE] Unshare System V IPC namespace" | ||
32 | //usage: "\n -n, --net[=FILE] Unshare network namespace" | ||
33 | //usage: "\n -p, --pid[=FILE] Unshare PID namespace" | ||
34 | //usage: "\n -U, --user[=FILE} Unshare user namespace" | ||
35 | //usage: "\n -f, --fork Fork before execing PROG" | ||
36 | //usage: "\n -r, --map-root-user Map current user to root (implies -u)" | ||
37 | //usage: "\n --mount-proc[=DIR] Mount /proc filesystem first (implies -m)" | ||
38 | //usage: "\n --propagation slave|shared|private|unchanged" | ||
39 | //usage: "\n Modify mount propagation in mount namespace" | ||
40 | //usage: "\n --setgroups allow|deny Control the setgroups syscall in user namespaces" | ||
41 | |||
42 | #include <sched.h> | ||
43 | #ifndef CLONE_NEWUTS | ||
44 | # define CLONE_NEWUTS 0x04000000 | ||
45 | #endif | ||
46 | #ifndef CLONE_NEWIPC | ||
47 | # define CLONE_NEWIPC 0x08000000 | ||
48 | #endif | ||
49 | #ifndef CLONE_NEWUSER | ||
50 | # define CLONE_NEWUSER 0x10000000 | ||
51 | #endif | ||
52 | #ifndef CLONE_NEWPID | ||
53 | # define CLONE_NEWPID 0x20000000 | ||
54 | #endif | ||
55 | #ifndef CLONE_NEWNET | ||
56 | # define CLONE_NEWNET 0x40000000 | ||
57 | #endif | ||
58 | |||
59 | #include <sys/mount.h> | ||
60 | #ifndef MS_REC | ||
61 | # define MS_REC (1 << 14) | ||
62 | #endif | ||
63 | #ifndef MS_PRIVATE | ||
64 | # define MS_PRIVATE (1 << 18) | ||
65 | #endif | ||
66 | #ifndef MS_SLAVE | ||
67 | # define MS_SLAVE (1 << 19) | ||
68 | #endif | ||
69 | #ifndef MS_SHARED | ||
70 | # define MS_SHARED (1 << 20) | ||
71 | #endif | ||
72 | |||
73 | #include "libbb.h" | ||
74 | |||
75 | static void mount_or_die(const char *source, const char *target, | ||
76 | const char *fstype, unsigned long mountflags) | ||
77 | { | ||
78 | if (mount(source, target, fstype, mountflags, NULL)) { | ||
79 | bb_perror_msg_and_die("can't mount %s on %s (flags:0x%lx)", | ||
80 | source, target, mountflags); | ||
81 | /* fstype is always either NULL or "proc". | ||
82 | * "proc" is only used to mount /proc. | ||
83 | * No need to clutter up error message with fstype, | ||
84 | * it is easily deductible. | ||
85 | */ | ||
86 | } | ||
87 | } | ||
88 | |||
89 | #define PATH_PROC_SETGROUPS "/proc/self/setgroups" | ||
90 | #define PATH_PROC_UIDMAP "/proc/self/uid_map" | ||
91 | #define PATH_PROC_GIDMAP "/proc/self/gid_map" | ||
92 | |||
93 | struct namespace_descr { | ||
94 | int flag; | ||
95 | const char nsfile4[4]; | ||
96 | }; | ||
97 | |||
98 | struct namespace_ctx { | ||
99 | char *path; | ||
100 | }; | ||
101 | |||
102 | enum { | ||
103 | OPT_mount = 1 << 0, | ||
104 | OPT_uts = 1 << 1, | ||
105 | OPT_ipc = 1 << 2, | ||
106 | OPT_network = 1 << 3, | ||
107 | OPT_pid = 1 << 4, | ||
108 | OPT_user = 1 << 5, /* OPT_user, NS_USR_POS, and ns_list[] index must match! */ | ||
109 | OPT_fork = 1 << 6, | ||
110 | OPT_map_root = 1 << 7, | ||
111 | OPT_mount_proc = 1 << 8, | ||
112 | OPT_propagation = 1 << 9, | ||
113 | OPT_setgroups = 1 << 10, | ||
114 | }; | ||
115 | enum { | ||
116 | NS_MNT_POS = 0, | ||
117 | NS_UTS_POS, | ||
118 | NS_IPC_POS, | ||
119 | NS_NET_POS, | ||
120 | NS_PID_POS, | ||
121 | NS_USR_POS, /* OPT_user, NS_USR_POS, and ns_list[] index must match! */ | ||
122 | NS_COUNT, | ||
123 | }; | ||
124 | static const struct namespace_descr ns_list[] = { | ||
125 | { CLONE_NEWNS, "mnt" }, | ||
126 | { CLONE_NEWUTS, "uts" }, | ||
127 | { CLONE_NEWIPC, "ipc" }, | ||
128 | { CLONE_NEWNET, "net" }, | ||
129 | { CLONE_NEWPID, "pid" }, | ||
130 | { CLONE_NEWUSER, "user" }, /* OPT_user, NS_USR_POS, and ns_list[] index must match! */ | ||
131 | }; | ||
132 | |||
133 | /* | ||
134 | * Upstream unshare doesn't support short options for --mount-proc, | ||
135 | * --propagation, --setgroups. | ||
136 | * Optional arguments (namespace mountpoints) exist only for long opts, | ||
137 | * we are forced to use "fake" letters for them. | ||
138 | * '+': stop at first non-option. | ||
139 | */ | ||
140 | static const char opt_str[] = "+muinpU""fr""\xfd::""\xfe:""\xff:"; | ||
141 | static const char unshare_longopts[] ALIGN1 = | ||
142 | "mount\0" Optional_argument "\xf0" | ||
143 | "uts\0" Optional_argument "\xf1" | ||
144 | "ipc\0" Optional_argument "\xf2" | ||
145 | "network\0" Optional_argument "\xf3" | ||
146 | "pid\0" Optional_argument "\xf4" | ||
147 | "user\0" Optional_argument "\xf5" | ||
148 | "fork\0" No_argument "f" | ||
149 | "map-root-user\0" No_argument "r" | ||
150 | "mount-proc\0" Optional_argument "\xfd" | ||
151 | "propagation\0" Required_argument "\xfe" | ||
152 | "setgroups\0" Required_argument "\xff" | ||
153 | ; | ||
154 | |||
155 | /* Ugly-looking string reuse trick */ | ||
156 | #define PRIVATE_STR "private\0""unchanged\0""shared\0""slave\0" | ||
157 | #define PRIVATE_UNCHANGED_SHARED_SLAVE PRIVATE_STR | ||
158 | |||
159 | static unsigned long parse_propagation(const char *prop_str) | ||
160 | { | ||
161 | int i = index_in_strings(PRIVATE_UNCHANGED_SHARED_SLAVE, prop_str); | ||
162 | if (i < 0) | ||
163 | bb_error_msg_and_die("unrecognized: --%s=%s", "propagation", prop_str); | ||
164 | if (i == 0) | ||
165 | return MS_REC | MS_PRIVATE; | ||
166 | if (i == 1) | ||
167 | return 0; | ||
168 | if (i == 2) | ||
169 | return MS_REC | MS_SHARED; | ||
170 | return MS_REC | MS_SLAVE; | ||
171 | } | ||
172 | |||
173 | static void mount_namespaces(pid_t pid, struct namespace_ctx *ns_ctx_list) | ||
174 | { | ||
175 | const struct namespace_descr *ns; | ||
176 | struct namespace_ctx *ns_ctx; | ||
177 | int i; | ||
178 | |||
179 | for (i = 0; i < NS_COUNT; i++) { | ||
180 | char nsf[sizeof("/proc/%u/ns/AAAA") + sizeof(int)*3]; | ||
181 | |||
182 | ns = &ns_list[i]; | ||
183 | ns_ctx = &ns_ctx_list[i]; | ||
184 | if (!ns_ctx->path) | ||
185 | continue; | ||
186 | sprintf(nsf, "/proc/%u/ns/%.4s", (unsigned)pid, ns->nsfile4); | ||
187 | mount_or_die(nsf, ns_ctx->path, NULL, MS_BIND); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | int unshare_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
192 | int unshare_main(int argc UNUSED_PARAM, char **argv) | ||
193 | { | ||
194 | int i; | ||
195 | unsigned int opts; | ||
196 | int unsflags; | ||
197 | uintptr_t need_mount; | ||
198 | const char *proc_mnt_target; | ||
199 | const char *prop_str; | ||
200 | const char *setgrp_str; | ||
201 | unsigned long prop_flags; | ||
202 | uid_t reuid = geteuid(); | ||
203 | gid_t regid = getegid(); | ||
204 | struct fd_pair fdp; | ||
205 | pid_t child = child; /* for compiler */ | ||
206 | struct namespace_ctx ns_ctx_list[NS_COUNT]; | ||
207 | |||
208 | memset(ns_ctx_list, 0, sizeof(ns_ctx_list)); | ||
209 | proc_mnt_target = "/proc"; | ||
210 | prop_str = PRIVATE_STR; | ||
211 | setgrp_str = NULL; | ||
212 | |||
213 | opt_complementary = | ||
214 | "\xf0""m" /* long opts (via their "fake chars") imply short opts */ | ||
215 | ":\xf1""u" | ||
216 | ":\xf2""i" | ||
217 | ":\xf3""n" | ||
218 | ":\xf4""p" | ||
219 | ":\xf5""U" | ||
220 | ":ru" /* --map-root-user or -r implies -u */ | ||
221 | ":\xfd""m" /* --mount-proc implies -m */ | ||
222 | ; | ||
223 | applet_long_options = unshare_longopts; | ||
224 | opts = getopt32(argv, opt_str, | ||
225 | &proc_mnt_target, &prop_str, &setgrp_str, | ||
226 | &ns_ctx_list[NS_MNT_POS].path, | ||
227 | &ns_ctx_list[NS_UTS_POS].path, | ||
228 | &ns_ctx_list[NS_IPC_POS].path, | ||
229 | &ns_ctx_list[NS_NET_POS].path, | ||
230 | &ns_ctx_list[NS_PID_POS].path, | ||
231 | &ns_ctx_list[NS_USR_POS].path | ||
232 | ); | ||
233 | argv += optind; | ||
234 | //bb_error_msg("opts:0x%x", opts); | ||
235 | //bb_error_msg("mount:%s", ns_ctx_list[NS_MNT_POS].path); | ||
236 | //bb_error_msg("proc_mnt_target:%s", proc_mnt_target); | ||
237 | //bb_error_msg("prop_str:%s", prop_str); | ||
238 | //bb_error_msg("setgrp_str:%s", setgrp_str); | ||
239 | //exit(1); | ||
240 | |||
241 | if (setgrp_str) { | ||
242 | if (strcmp(setgrp_str, "allow") == 0) { | ||
243 | if (opts & OPT_map_root) { | ||
244 | bb_error_msg_and_die( | ||
245 | "--setgroups=allow and --map-root-user " | ||
246 | "are mutually exclusive" | ||
247 | ); | ||
248 | } | ||
249 | } else { | ||
250 | /* It's not "allow", must be "deny" */ | ||
251 | if (strcmp(setgrp_str, "deny") != 0) | ||
252 | bb_error_msg_and_die("unrecognized: --%s=%s", | ||
253 | "setgroups", setgrp_str); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | unsflags = 0; | ||
258 | need_mount = 0; | ||
259 | for (i = 0; i < NS_COUNT; i++) { | ||
260 | const struct namespace_descr *ns = &ns_list[i]; | ||
261 | struct namespace_ctx *ns_ctx = &ns_ctx_list[i]; | ||
262 | |||
263 | if (opts & (1 << i)) | ||
264 | unsflags |= ns->flag; | ||
265 | |||
266 | need_mount |= (uintptr_t)(ns_ctx->path); | ||
267 | } | ||
268 | /* need_mount != 0 if at least one FILE was given */ | ||
269 | |||
270 | prop_flags = MS_REC | MS_PRIVATE; | ||
271 | /* Silently ignore --propagation if --mount is not requested. */ | ||
272 | if (opts & OPT_mount) | ||
273 | prop_flags = parse_propagation(prop_str); | ||
274 | |||
275 | /* | ||
276 | * Special case: if we were requested to unshare the mount namespace | ||
277 | * AND to make any namespace persistent (by bind mounting it) we need | ||
278 | * to spawn a child process which will wait for the parent to call | ||
279 | * unshare(), then mount parent's namespaces while still in the | ||
280 | * previous namespace. | ||
281 | */ | ||
282 | fdp.wr = -1; | ||
283 | if (need_mount && (opts & OPT_mount)) { | ||
284 | /* | ||
285 | * Can't use getppid() in child, as we can be unsharing the | ||
286 | * pid namespace. | ||
287 | */ | ||
288 | pid_t ppid = getpid(); | ||
289 | |||
290 | xpiped_pair(fdp); | ||
291 | |||
292 | child = xfork(); | ||
293 | if (child == 0) { | ||
294 | /* Child */ | ||
295 | close(fdp.wr); | ||
296 | |||
297 | /* Wait until parent calls unshare() */ | ||
298 | read(fdp.rd, ns_ctx_list, 1); /* ...using bogus buffer */ | ||
299 | /*close(fdp.rd);*/ | ||
300 | |||
301 | /* Mount parent's unshared namespaces. */ | ||
302 | mount_namespaces(ppid, ns_ctx_list); | ||
303 | return EXIT_SUCCESS; | ||
304 | } | ||
305 | /* Parent continues */ | ||
306 | } | ||
307 | |||
308 | if (unshare(unsflags) != 0) | ||
309 | bb_perror_msg_and_die("unshare(0x%x)", unsflags); | ||
310 | |||
311 | if (fdp.wr >= 0) { | ||
312 | close(fdp.wr); /* Release child */ | ||
313 | close(fdp.rd); /* should close fd, to not confuse exec'ed PROG */ | ||
314 | } | ||
315 | |||
316 | if (need_mount) { | ||
317 | /* Wait for the child to finish mounting the namespaces. */ | ||
318 | if (opts & OPT_mount) { | ||
319 | int exit_status = wait_for_exitstatus(child); | ||
320 | if (WIFEXITED(exit_status) && | ||
321 | WEXITSTATUS(exit_status) != EXIT_SUCCESS) | ||
322 | return WEXITSTATUS(exit_status); | ||
323 | } else { | ||
324 | /* | ||
325 | * Regular way - we were requested to mount some other | ||
326 | * namespaces: mount them after the call to unshare(). | ||
327 | */ | ||
328 | mount_namespaces(getpid(), ns_ctx_list); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * When we're unsharing the pid namespace, it's not the process that | ||
334 | * calls unshare() that is put into the new namespace, but its first | ||
335 | * child. The user may want to use this option to spawn a new process | ||
336 | * that'll become PID 1 in this new namespace. | ||
337 | */ | ||
338 | if (opts & OPT_fork) { | ||
339 | xvfork_parent_waits_and_exits(); | ||
340 | /* Child continues */ | ||
341 | } | ||
342 | |||
343 | if (opts & OPT_map_root) { | ||
344 | char uidmap_buf[sizeof("%u 0 1") + sizeof(int)*3]; | ||
345 | |||
346 | /* | ||
347 | * Since Linux 3.19 unprivileged writing of /proc/self/gid_map | ||
348 | * has been disabled unless /proc/self/setgroups is written | ||
349 | * first to permanently disable the ability to call setgroups | ||
350 | * in that user namespace. | ||
351 | */ | ||
352 | xopen_xwrite_close(PATH_PROC_SETGROUPS, "deny"); | ||
353 | sprintf(uidmap_buf, "%u 0 1", (unsigned)reuid); | ||
354 | xopen_xwrite_close(PATH_PROC_UIDMAP, uidmap_buf); | ||
355 | sprintf(uidmap_buf, "%u 0 1", (unsigned)regid); | ||
356 | xopen_xwrite_close(PATH_PROC_GIDMAP, uidmap_buf); | ||
357 | } else | ||
358 | if (setgrp_str) { | ||
359 | /* Write "allow" or "deny" */ | ||
360 | xopen_xwrite_close(PATH_PROC_SETGROUPS, setgrp_str); | ||
361 | } | ||
362 | |||
363 | if (opts & OPT_mount) { | ||
364 | mount_or_die("none", "/", NULL, prop_flags); | ||
365 | } | ||
366 | |||
367 | if (opts & OPT_mount_proc) { | ||
368 | /* | ||
369 | * When creating a new pid namespace, we might want the pid | ||
370 | * subdirectories in /proc to remain consistent with the new | ||
371 | * process IDs. Without --mount-proc the pids in /proc would | ||
372 | * still reflect the old pid namespace. This is why we make | ||
373 | * /proc private here and then do a fresh mount. | ||
374 | */ | ||
375 | mount_or_die("none", proc_mnt_target, NULL, MS_PRIVATE | MS_REC); | ||
376 | mount_or_die("proc", proc_mnt_target, "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV); | ||
377 | } | ||
378 | |||
379 | exec_prog_or_SHELL(argv); | ||
380 | } | ||