diff options
author | Ron Yorston <rmy@pobox.com> | 2015-10-13 14:45:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2015-10-13 14:45:51 +0100 |
commit | 8e509f11bceeec419abc718300bef7422d1fee4c (patch) | |
tree | fdfbc752ad94102e3613a5d7254f14a93eaf7f56 | |
parent | 420f5edfe7676fe6e7cddbbf15c04649d096e422 (diff) | |
parent | 4d0c1ea4784c9844f8468d97ca5c26d3c70f9921 (diff) | |
download | busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.tar.gz busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.tar.bz2 busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.zip |
Merge branch 'busybox' into merge
135 files changed, 2335 insertions, 1275 deletions
@@ -1,5 +1,5 @@ | |||
1 | VERSION = 1 | 1 | VERSION = 1 |
2 | PATCHLEVEL = 24 | 2 | PATCHLEVEL = 25 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = .git | 4 | EXTRAVERSION = .git |
5 | NAME = Unnamed | 5 | NAME = Unnamed |
diff --git a/Makefile.flags b/Makefile.flags index 58fcf33eb..c3ac5b458 100644 --- a/Makefile.flags +++ b/Makefile.flags | |||
@@ -57,6 +57,9 @@ CFLAGS += $(call cc-option,-falign-functions=1 -falign-jumps=1 -falign-labels=1 | |||
57 | # Defeat .eh_frame bloat (gcc 4.6.3 x86-32 defconfig: 20% smaller busybox binary): | 57 | # Defeat .eh_frame bloat (gcc 4.6.3 x86-32 defconfig: 20% smaller busybox binary): |
58 | CFLAGS += $(call cc-option,-fno-unwind-tables,) | 58 | CFLAGS += $(call cc-option,-fno-unwind-tables,) |
59 | CFLAGS += $(call cc-option,-fno-asynchronous-unwind-tables,) | 59 | CFLAGS += $(call cc-option,-fno-asynchronous-unwind-tables,) |
60 | # No automatic printf->puts,putchar conversions | ||
61 | # (try disabling this and comparing assembly, it's instructive) | ||
62 | CFLAGS += $(call cc-option,-fno-builtin-printf,) | ||
60 | 63 | ||
61 | # FIXME: These warnings are at least partially to be concerned about and should | 64 | # FIXME: These warnings are at least partially to be concerned about and should |
62 | # be fixed.. | 65 | # be fixed.. |
@@ -134,15 +137,19 @@ else | |||
134 | LDLIBS += m | 137 | LDLIBS += m |
135 | endif | 138 | endif |
136 | 139 | ||
140 | # libpam may use libpthread, libdl and/or libaudit. | ||
141 | # On some platforms that requires an explicit -lpthread, -ldl, -laudit. | ||
142 | # However, on *other platforms* it fails when some of those flags | ||
143 | # given needlessly. On some systems, crypt needs pthread. | ||
144 | # | ||
145 | # I even had a system where a runtime test for pthread | ||
146 | # (similar to CRYPT_AVAILABLE test above) was not reliable. | ||
147 | # | ||
148 | # Do not propagate this mess by adding libraries to CONFIG_PAM/CRYPT_AVAILABLE blocks. | ||
149 | # Add libraries you need to CONFIG_EXTRA_LDLIBS instead. | ||
150 | |||
137 | ifeq ($(CONFIG_PAM),y) | 151 | ifeq ($(CONFIG_PAM),y) |
138 | # libpam uses libpthread, so for static builds busybox must be linked to | 152 | LDLIBS += pam pam_misc |
139 | # libpthread. On some platforms that requires an explicit -lpthread, so | ||
140 | # it should be in LDLIBS. For non-static builds, scripts/trylink will | ||
141 | # take care of removing -lpthread if possible. (Not bothering to check | ||
142 | # CONFIG_STATIC because even in a non-static build it could be that the | ||
143 | # only libpam available is libpam.a, so -lpthread could still be | ||
144 | # needed.) | ||
145 | LDLIBS += pam pam_misc pthread | ||
146 | endif | 153 | endif |
147 | 154 | ||
148 | ifeq ($(CONFIG_SELINUX),y) | 155 | ifeq ($(CONFIG_SELINUX),y) |
diff --git a/applets/usage_compressed b/applets/usage_compressed index fb6e1c286..186fcde77 100755 --- a/applets/usage_compressed +++ b/applets/usage_compressed | |||
@@ -20,6 +20,7 @@ exec >"$target.$$" | |||
20 | 20 | ||
21 | echo '#define UNPACKED_USAGE "" \' | 21 | echo '#define UNPACKED_USAGE "" \' |
22 | "$loc/usage" | od -v -b \ | 22 | "$loc/usage" | od -v -b \ |
23 | | grep -v '^ ' \ | ||
23 | | $SED -e 's/^[^ ]*//' \ | 24 | | $SED -e 's/^[^ ]*//' \ |
24 | -e 's/ //g' \ | 25 | -e 's/ //g' \ |
25 | -e '/^$/d' \ | 26 | -e '/^$/d' \ |
@@ -27,6 +28,13 @@ echo '#define UNPACKED_USAGE "" \' | |||
27 | -e 's/^/"/' \ | 28 | -e 's/^/"/' \ |
28 | -e 's/$/" \\/' | 29 | -e 's/$/" \\/' |
29 | echo '' | 30 | echo '' |
31 | # "grep -v '^ '" is for toybox's od bug: od -b prints some extra lines: | ||
32 | #0000000 010 000 010 000 133 055 144 146 135 040 133 055 143 040 103 117 | ||
33 | # 000010 000010 026533 063144 020135 026533 020143 047503 | ||
34 | #0000020 116 106 104 111 122 135 040 133 055 154 040 114 117 107 106 111 | ||
35 | # 043116 044504 056522 055440 066055 046040 043517 044506 | ||
36 | #0000040 114 105 135 040 133 055 141 040 101 103 124 111 117 116 106 111 | ||
37 | # 042514 020135 026533 020141 041501 044524 047117 044506 | ||
30 | 38 | ||
31 | echo '#define PACKED_USAGE \' | 39 | echo '#define PACKED_USAGE \' |
32 | ## Breaks on big-endian systems! | 40 | ## Breaks on big-endian systems! |
@@ -40,6 +48,7 @@ echo '#define PACKED_USAGE \' | |||
40 | ## -e 's/\(..\)\(..\)/0x\2,0x\1,/g' | 48 | ## -e 's/\(..\)\(..\)/0x\2,0x\1,/g' |
41 | ## -e 's/$/ \\/' | 49 | ## -e 's/$/ \\/' |
42 | "$loc/usage" | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -b \ | 50 | "$loc/usage" | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -b \ |
51 | | grep -v '^ ' \ | ||
43 | | $SED -e 's/^[^ ]*//' \ | 52 | | $SED -e 's/^[^ ]*//' \ |
44 | -e 's/ //g' \ | 53 | -e 's/ //g' \ |
45 | -e '/^$/d' \ | 54 | -e '/^$/d' \ |
diff --git a/archival/dpkg.c b/archival/dpkg.c index 151f0ca43..df7a0db64 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
@@ -1151,13 +1151,13 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count | |||
1151 | if (result && number_of_alternatives == 0) { | 1151 | if (result && number_of_alternatives == 0) { |
1152 | if (root_of_alternatives) | 1152 | if (root_of_alternatives) |
1153 | bb_error_msg_and_die( | 1153 | bb_error_msg_and_die( |
1154 | "package %s %sdepends on %s, " | 1154 | "package %s %sdepends on %s, which %s", |
1155 | "which cannot be satisfied", | ||
1156 | name_hashtable[package_node->name], | 1155 | name_hashtable[package_node->name], |
1157 | package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", | 1156 | package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", |
1158 | name_hashtable[root_of_alternatives->name]); | 1157 | name_hashtable[root_of_alternatives->name], |
1158 | "cannot be satisfied"); | ||
1159 | bb_error_msg_and_die( | 1159 | bb_error_msg_and_die( |
1160 | "package %s %sdepends on %s, which %s\n", | 1160 | "package %s %sdepends on %s, which %s", |
1161 | name_hashtable[package_node->name], | 1161 | name_hashtable[package_node->name], |
1162 | package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", | 1162 | package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", |
1163 | name_hashtable[package_edge->name], | 1163 | name_hashtable[package_edge->name], |
diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 5b32c2ec8..6f5317a0e 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c | |||
@@ -118,7 +118,7 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle) | |||
118 | bb_error_msg_and_die("'%s' returned status %d", | 118 | bb_error_msg_and_die("'%s' returned status %d", |
119 | archive_handle->tar__to_command, WEXITSTATUS(status)); | 119 | archive_handle->tar__to_command, WEXITSTATUS(status)); |
120 | if (WIFSIGNALED(status)) | 120 | if (WIFSIGNALED(status)) |
121 | bb_error_msg_and_die("'%s' terminated on signal %d", | 121 | bb_error_msg_and_die("'%s' terminated by signal %d", |
122 | archive_handle->tar__to_command, WTERMSIG(status)); | 122 | archive_handle->tar__to_command, WTERMSIG(status)); |
123 | 123 | ||
124 | if (!BB_MMU) { | 124 | if (!BB_MMU) { |
diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig index 01cc2dd15..66c85268f 100644 --- a/configs/android_ndk_defconfig +++ b/configs/android_ndk_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.21.0.git | 3 | # Busybox version: 1.24.0.git |
4 | # Mon May 28 21:51:18 2012 | 4 | # Fri Sep 18 20:39:29 2015 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | 7 | ||
@@ -36,12 +36,15 @@ CONFIG_LAST_SUPPORTED_WCHAR=0 | |||
36 | # CONFIG_UNICODE_BIDI_SUPPORT is not set | 36 | # CONFIG_UNICODE_BIDI_SUPPORT is not set |
37 | # CONFIG_UNICODE_NEUTRAL_TABLE is not set | 37 | # CONFIG_UNICODE_NEUTRAL_TABLE is not set |
38 | # CONFIG_UNICODE_PRESERVE_BROKEN is not set | 38 | # CONFIG_UNICODE_PRESERVE_BROKEN is not set |
39 | # CONFIG_PAM is not set | ||
40 | CONFIG_FEATURE_USE_SENDFILE=y | ||
39 | CONFIG_LONG_OPTS=y | 41 | CONFIG_LONG_OPTS=y |
40 | # CONFIG_FEATURE_DEVPTS is not set | 42 | # CONFIG_FEATURE_DEVPTS is not set |
41 | # CONFIG_FEATURE_CLEAN_UP is not set | 43 | # CONFIG_FEATURE_CLEAN_UP is not set |
42 | # CONFIG_FEATURE_UTMP is not set | 44 | # CONFIG_FEATURE_UTMP is not set |
43 | # CONFIG_FEATURE_WTMP is not set | 45 | # CONFIG_FEATURE_WTMP is not set |
44 | # CONFIG_FEATURE_PIDFILE is not set | 46 | # CONFIG_FEATURE_PIDFILE is not set |
47 | CONFIG_PID_FILE_PATH="" | ||
45 | # CONFIG_FEATURE_SUID is not set | 48 | # CONFIG_FEATURE_SUID is not set |
46 | # CONFIG_FEATURE_SUID_CONFIG is not set | 49 | # CONFIG_FEATURE_SUID_CONFIG is not set |
47 | # CONFIG_FEATURE_SUID_CONFIG_QUIET is not set | 50 | # CONFIG_FEATURE_SUID_CONFIG_QUIET is not set |
@@ -63,7 +66,7 @@ CONFIG_FEATURE_SYSLOG=y | |||
63 | # CONFIG_LFS is not set | 66 | # CONFIG_LFS is not set |
64 | CONFIG_CROSS_COMPILER_PREFIX="arm-linux-androideabi-" | 67 | CONFIG_CROSS_COMPILER_PREFIX="arm-linux-androideabi-" |
65 | CONFIG_SYSROOT="/opt/android-ndk/platforms/android-9/arch-arm" | 68 | CONFIG_SYSROOT="/opt/android-ndk/platforms/android-9/arch-arm" |
66 | CONFIG_EXTRA_CFLAGS="-DANDROID -D__ANDROID__ -DSK_RELEASE -nostdlib -march=armv7-a -msoft-float -mfloat-abi=softfp -mfpu=neon -mthumb -mthumb-interwork -fpic -fno-short-enums -fgcse-after-reload -frename-registers" | 69 | CONFIG_EXTRA_CFLAGS="-DANDROID -D__ANDROID__ -DSK_RELEASE -nostdlib -march=armv7-a -msoft-float -mfloat-abi=softfp -mfpu=neon -mthumb -mthumb-interwork -fpic -fno-short-enums -fgcse-after-reload -frename-registers -fuse-ld=bfd" |
67 | CONFIG_EXTRA_LDFLAGS="-Xlinker -z -Xlinker muldefs -nostdlib -Bdynamic -Xlinker -dynamic-linker -Xlinker /system/bin/linker -Xlinker -z -Xlinker nocopyreloc -Xlinker --no-undefined ${SYSROOT}/usr/lib/crtbegin_dynamic.o ${SYSROOT}/usr/lib/crtend_android.o" | 70 | CONFIG_EXTRA_LDFLAGS="-Xlinker -z -Xlinker muldefs -nostdlib -Bdynamic -Xlinker -dynamic-linker -Xlinker /system/bin/linker -Xlinker -z -Xlinker nocopyreloc -Xlinker --no-undefined ${SYSROOT}/usr/lib/crtbegin_dynamic.o ${SYSROOT}/usr/lib/crtend_android.o" |
68 | CONFIG_EXTRA_LDLIBS="dl m c gcc" | 71 | CONFIG_EXTRA_LDLIBS="dl m c gcc" |
69 | 72 | ||
@@ -72,6 +75,7 @@ CONFIG_EXTRA_LDLIBS="dl m c gcc" | |||
72 | # | 75 | # |
73 | # CONFIG_DEBUG is not set | 76 | # CONFIG_DEBUG is not set |
74 | # CONFIG_DEBUG_PESSIMIZE is not set | 77 | # CONFIG_DEBUG_PESSIMIZE is not set |
78 | # CONFIG_UNIT_TEST is not set | ||
75 | # CONFIG_WERROR is not set | 79 | # CONFIG_WERROR is not set |
76 | CONFIG_NO_DEBUG_LIB=y | 80 | CONFIG_NO_DEBUG_LIB=y |
77 | # CONFIG_DMALLOC is not set | 81 | # CONFIG_DMALLOC is not set |
@@ -96,6 +100,7 @@ CONFIG_PREFIX="./_install" | |||
96 | # CONFIG_FEATURE_RTMINMAX is not set | 100 | # CONFIG_FEATURE_RTMINMAX is not set |
97 | CONFIG_PASSWORD_MINLEN=6 | 101 | CONFIG_PASSWORD_MINLEN=6 |
98 | CONFIG_MD5_SMALL=1 | 102 | CONFIG_MD5_SMALL=1 |
103 | CONFIG_SHA3_SMALL=1 | ||
99 | # CONFIG_FEATURE_FAST_TOP is not set | 104 | # CONFIG_FEATURE_FAST_TOP is not set |
100 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 105 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
101 | CONFIG_FEATURE_USE_TERMIOS=y | 106 | CONFIG_FEATURE_USE_TERMIOS=y |
@@ -133,7 +138,14 @@ CONFIG_FEATURE_SEAMLESS_Z=y | |||
133 | CONFIG_AR=y | 138 | CONFIG_AR=y |
134 | CONFIG_FEATURE_AR_LONG_FILENAMES=y | 139 | CONFIG_FEATURE_AR_LONG_FILENAMES=y |
135 | CONFIG_FEATURE_AR_CREATE=y | 140 | CONFIG_FEATURE_AR_CREATE=y |
141 | CONFIG_UNCOMPRESS=y | ||
142 | CONFIG_GUNZIP=y | ||
136 | CONFIG_BUNZIP2=y | 143 | CONFIG_BUNZIP2=y |
144 | CONFIG_UNLZMA=y | ||
145 | CONFIG_FEATURE_LZMA_FAST=y | ||
146 | CONFIG_LZMA=y | ||
147 | CONFIG_UNXZ=y | ||
148 | CONFIG_XZ=y | ||
137 | CONFIG_BZIP2=y | 149 | CONFIG_BZIP2=y |
138 | CONFIG_CPIO=y | 150 | CONFIG_CPIO=y |
139 | CONFIG_FEATURE_CPIO_O=y | 151 | CONFIG_FEATURE_CPIO_O=y |
@@ -141,14 +153,14 @@ CONFIG_FEATURE_CPIO_P=y | |||
141 | CONFIG_DPKG=y | 153 | CONFIG_DPKG=y |
142 | CONFIG_DPKG_DEB=y | 154 | CONFIG_DPKG_DEB=y |
143 | # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set | 155 | # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set |
144 | CONFIG_GUNZIP=y | ||
145 | CONFIG_GZIP=y | 156 | CONFIG_GZIP=y |
146 | # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set | 157 | # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set |
147 | CONFIG_GZIP_FAST=0 | 158 | CONFIG_GZIP_FAST=0 |
159 | # CONFIG_FEATURE_GZIP_LEVELS is not set | ||
148 | CONFIG_LZOP=y | 160 | CONFIG_LZOP=y |
149 | CONFIG_LZOP_COMPR_HIGH=y | 161 | CONFIG_LZOP_COMPR_HIGH=y |
150 | CONFIG_RPM2CPIO=y | ||
151 | CONFIG_RPM=y | 162 | CONFIG_RPM=y |
163 | CONFIG_RPM2CPIO=y | ||
152 | CONFIG_TAR=y | 164 | CONFIG_TAR=y |
153 | CONFIG_FEATURE_TAR_CREATE=y | 165 | CONFIG_FEATURE_TAR_CREATE=y |
154 | CONFIG_FEATURE_TAR_AUTODETECT=y | 166 | CONFIG_FEATURE_TAR_AUTODETECT=y |
@@ -161,12 +173,6 @@ CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y | |||
161 | CONFIG_FEATURE_TAR_UNAME_GNAME=y | 173 | CONFIG_FEATURE_TAR_UNAME_GNAME=y |
162 | CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y | 174 | CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y |
163 | # CONFIG_FEATURE_TAR_SELINUX is not set | 175 | # CONFIG_FEATURE_TAR_SELINUX is not set |
164 | CONFIG_UNCOMPRESS=y | ||
165 | CONFIG_UNLZMA=y | ||
166 | CONFIG_FEATURE_LZMA_FAST=y | ||
167 | CONFIG_LZMA=y | ||
168 | CONFIG_UNXZ=y | ||
169 | CONFIG_XZ=y | ||
170 | CONFIG_UNZIP=y | 176 | CONFIG_UNZIP=y |
171 | 177 | ||
172 | # | 178 | # |
@@ -178,16 +184,27 @@ CONFIG_CAT=y | |||
178 | # CONFIG_FEATURE_DATE_ISOFMT is not set | 184 | # CONFIG_FEATURE_DATE_ISOFMT is not set |
179 | # CONFIG_FEATURE_DATE_NANO is not set | 185 | # CONFIG_FEATURE_DATE_NANO is not set |
180 | # CONFIG_FEATURE_DATE_COMPAT is not set | 186 | # CONFIG_FEATURE_DATE_COMPAT is not set |
187 | CONFIG_DD=y | ||
188 | CONFIG_FEATURE_DD_SIGNAL_HANDLING=y | ||
189 | CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y | ||
190 | CONFIG_FEATURE_DD_IBS_OBS=y | ||
191 | CONFIG_FEATURE_DD_STATUS=y | ||
181 | # CONFIG_HOSTID is not set | 192 | # CONFIG_HOSTID is not set |
182 | # CONFIG_ID is not set | 193 | # CONFIG_ID is not set |
183 | # CONFIG_GROUPS is not set | 194 | # CONFIG_GROUPS is not set |
195 | CONFIG_SHUF=y | ||
196 | CONFIG_SYNC=y | ||
197 | # CONFIG_FEATURE_SYNC_FANCY is not set | ||
184 | CONFIG_TEST=y | 198 | CONFIG_TEST=y |
185 | CONFIG_FEATURE_TEST_64=y | 199 | CONFIG_FEATURE_TEST_64=y |
186 | CONFIG_TOUCH=y | 200 | CONFIG_TOUCH=y |
201 | # CONFIG_FEATURE_TOUCH_NODEREF is not set | ||
187 | CONFIG_FEATURE_TOUCH_SUSV3=y | 202 | CONFIG_FEATURE_TOUCH_SUSV3=y |
188 | CONFIG_TR=y | 203 | CONFIG_TR=y |
189 | CONFIG_FEATURE_TR_CLASSES=y | 204 | CONFIG_FEATURE_TR_CLASSES=y |
190 | CONFIG_FEATURE_TR_EQUIV=y | 205 | CONFIG_FEATURE_TR_EQUIV=y |
206 | CONFIG_TRUNCATE=y | ||
207 | CONFIG_UNLINK=y | ||
191 | CONFIG_BASE64=y | 208 | CONFIG_BASE64=y |
192 | # CONFIG_WHO is not set | 209 | # CONFIG_WHO is not set |
193 | # CONFIG_USERS is not set | 210 | # CONFIG_USERS is not set |
@@ -203,10 +220,6 @@ CONFIG_COMM=y | |||
203 | CONFIG_CP=y | 220 | CONFIG_CP=y |
204 | # CONFIG_FEATURE_CP_LONG_OPTIONS is not set | 221 | # CONFIG_FEATURE_CP_LONG_OPTIONS is not set |
205 | CONFIG_CUT=y | 222 | CONFIG_CUT=y |
206 | CONFIG_DD=y | ||
207 | CONFIG_FEATURE_DD_SIGNAL_HANDLING=y | ||
208 | CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y | ||
209 | CONFIG_FEATURE_DD_IBS_OBS=y | ||
210 | # CONFIG_DF is not set | 223 | # CONFIG_DF is not set |
211 | # CONFIG_FEATURE_DF_FANCY is not set | 224 | # CONFIG_FEATURE_DF_FANCY is not set |
212 | CONFIG_DIRNAME=y | 225 | CONFIG_DIRNAME=y |
@@ -263,6 +276,7 @@ CONFIG_SEQ=y | |||
263 | CONFIG_SHA1SUM=y | 276 | CONFIG_SHA1SUM=y |
264 | CONFIG_SHA256SUM=y | 277 | CONFIG_SHA256SUM=y |
265 | CONFIG_SHA512SUM=y | 278 | CONFIG_SHA512SUM=y |
279 | CONFIG_SHA3SUM=y | ||
266 | CONFIG_SLEEP=y | 280 | CONFIG_SLEEP=y |
267 | CONFIG_FEATURE_FANCY_SLEEP=y | 281 | CONFIG_FEATURE_FANCY_SLEEP=y |
268 | CONFIG_FEATURE_FLOAT_SLEEP=y | 282 | CONFIG_FEATURE_FLOAT_SLEEP=y |
@@ -274,7 +288,6 @@ CONFIG_FEATURE_SPLIT_FANCY=y | |||
274 | # CONFIG_FEATURE_STAT_FORMAT is not set | 288 | # CONFIG_FEATURE_STAT_FORMAT is not set |
275 | CONFIG_STTY=y | 289 | CONFIG_STTY=y |
276 | CONFIG_SUM=y | 290 | CONFIG_SUM=y |
277 | CONFIG_SYNC=y | ||
278 | CONFIG_TAC=y | 291 | CONFIG_TAC=y |
279 | CONFIG_TAIL=y | 292 | CONFIG_TAIL=y |
280 | CONFIG_FEATURE_FANCY_TAIL=y | 293 | CONFIG_FEATURE_FANCY_TAIL=y |
@@ -283,6 +296,7 @@ CONFIG_FEATURE_TEE_USE_BLOCK_IO=y | |||
283 | CONFIG_TRUE=y | 296 | CONFIG_TRUE=y |
284 | # CONFIG_TTY is not set | 297 | # CONFIG_TTY is not set |
285 | CONFIG_UNAME=y | 298 | CONFIG_UNAME=y |
299 | CONFIG_UNAME_OSNAME="GNU/Linux" | ||
286 | CONFIG_UNEXPAND=y | 300 | CONFIG_UNEXPAND=y |
287 | # CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set | 301 | # CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set |
288 | CONFIG_UNIQ=y | 302 | CONFIG_UNIQ=y |
@@ -295,6 +309,11 @@ CONFIG_WHOAMI=y | |||
295 | CONFIG_YES=y | 309 | CONFIG_YES=y |
296 | 310 | ||
297 | # | 311 | # |
312 | # Common options | ||
313 | # | ||
314 | CONFIG_FEATURE_VERBOSE=y | ||
315 | |||
316 | # | ||
298 | # Common options for cp and mv | 317 | # Common options for cp and mv |
299 | # | 318 | # |
300 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | 319 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y |
@@ -310,7 +329,7 @@ CONFIG_FEATURE_AUTOWIDTH=y | |||
310 | CONFIG_FEATURE_HUMAN_READABLE=y | 329 | CONFIG_FEATURE_HUMAN_READABLE=y |
311 | 330 | ||
312 | # | 331 | # |
313 | # Common options for md5sum, sha1sum, sha256sum, sha512sum | 332 | # Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum |
314 | # | 333 | # |
315 | CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y | 334 | CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y |
316 | 335 | ||
@@ -356,7 +375,16 @@ CONFIG_WHICH=y | |||
356 | # | 375 | # |
357 | # Editors | 376 | # Editors |
358 | # | 377 | # |
378 | CONFIG_AWK=y | ||
379 | CONFIG_FEATURE_AWK_LIBM=y | ||
380 | CONFIG_FEATURE_AWK_GNU_EXTENSIONS=y | ||
381 | CONFIG_CMP=y | ||
382 | CONFIG_DIFF=y | ||
383 | # CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set | ||
384 | CONFIG_FEATURE_DIFF_DIR=y | ||
385 | CONFIG_ED=y | ||
359 | CONFIG_PATCH=y | 386 | CONFIG_PATCH=y |
387 | CONFIG_SED=y | ||
360 | CONFIG_VI=y | 388 | CONFIG_VI=y |
361 | CONFIG_FEATURE_VI_MAX_LEN=4096 | 389 | CONFIG_FEATURE_VI_MAX_LEN=4096 |
362 | CONFIG_FEATURE_VI_8BIT=y | 390 | CONFIG_FEATURE_VI_8BIT=y |
@@ -371,14 +399,9 @@ CONFIG_FEATURE_VI_SETOPTS=y | |||
371 | CONFIG_FEATURE_VI_SET=y | 399 | CONFIG_FEATURE_VI_SET=y |
372 | CONFIG_FEATURE_VI_WIN_RESIZE=y | 400 | CONFIG_FEATURE_VI_WIN_RESIZE=y |
373 | CONFIG_FEATURE_VI_ASK_TERMINAL=y | 401 | CONFIG_FEATURE_VI_ASK_TERMINAL=y |
374 | CONFIG_AWK=y | 402 | CONFIG_FEATURE_VI_UNDO=y |
375 | CONFIG_FEATURE_AWK_LIBM=y | 403 | CONFIG_FEATURE_VI_UNDO_QUEUE=y |
376 | CONFIG_CMP=y | 404 | CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 |
377 | CONFIG_DIFF=y | ||
378 | # CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set | ||
379 | CONFIG_FEATURE_DIFF_DIR=y | ||
380 | CONFIG_ED=y | ||
381 | CONFIG_SED=y | ||
382 | CONFIG_FEATURE_ALLOW_EXEC=y | 405 | CONFIG_FEATURE_ALLOW_EXEC=y |
383 | 406 | ||
384 | # | 407 | # |
@@ -395,6 +418,7 @@ CONFIG_FEATURE_FIND_MAXDEPTH=y | |||
395 | CONFIG_FEATURE_FIND_NEWER=y | 418 | CONFIG_FEATURE_FIND_NEWER=y |
396 | CONFIG_FEATURE_FIND_INUM=y | 419 | CONFIG_FEATURE_FIND_INUM=y |
397 | CONFIG_FEATURE_FIND_EXEC=y | 420 | CONFIG_FEATURE_FIND_EXEC=y |
421 | CONFIG_FEATURE_FIND_EXEC_PLUS=y | ||
398 | CONFIG_FEATURE_FIND_USER=y | 422 | CONFIG_FEATURE_FIND_USER=y |
399 | CONFIG_FEATURE_FIND_GROUP=y | 423 | CONFIG_FEATURE_FIND_GROUP=y |
400 | CONFIG_FEATURE_FIND_NOT=y | 424 | CONFIG_FEATURE_FIND_NOT=y |
@@ -416,6 +440,7 @@ CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y | |||
416 | CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y | 440 | CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y |
417 | CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y | 441 | CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y |
418 | CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y | 442 | CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y |
443 | CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y | ||
419 | 444 | ||
420 | # | 445 | # |
421 | # Init Utilities | 446 | # Init Utilities |
@@ -447,11 +472,12 @@ CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y | |||
447 | # CONFIG_FEATURE_SHADOWPASSWDS is not set | 472 | # CONFIG_FEATURE_SHADOWPASSWDS is not set |
448 | # CONFIG_USE_BB_PWD_GRP is not set | 473 | # CONFIG_USE_BB_PWD_GRP is not set |
449 | # CONFIG_USE_BB_SHADOW is not set | 474 | # CONFIG_USE_BB_SHADOW is not set |
450 | # CONFIG_USE_BB_CRYPT is not set | 475 | CONFIG_USE_BB_CRYPT=y |
451 | # CONFIG_USE_BB_CRYPT_SHA is not set | 476 | CONFIG_USE_BB_CRYPT_SHA=y |
452 | # CONFIG_ADDUSER is not set | 477 | # CONFIG_ADDUSER is not set |
453 | # CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set | 478 | # CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set |
454 | # CONFIG_FEATURE_CHECK_NAMES is not set | 479 | # CONFIG_FEATURE_CHECK_NAMES is not set |
480 | CONFIG_LAST_ID=0 | ||
455 | CONFIG_FIRST_SYSTEM_ID=0 | 481 | CONFIG_FIRST_SYSTEM_ID=0 |
456 | CONFIG_LAST_SYSTEM_ID=0 | 482 | CONFIG_LAST_SYSTEM_ID=0 |
457 | # CONFIG_ADDGROUP is not set | 483 | # CONFIG_ADDGROUP is not set |
@@ -463,7 +489,6 @@ CONFIG_LAST_SYSTEM_ID=0 | |||
463 | # CONFIG_GETTY is not set | 489 | # CONFIG_GETTY is not set |
464 | # CONFIG_LOGIN is not set | 490 | # CONFIG_LOGIN is not set |
465 | # CONFIG_LOGIN_SESSION_AS_CHILD is not set | 491 | # CONFIG_LOGIN_SESSION_AS_CHILD is not set |
466 | # CONFIG_PAM is not set | ||
467 | # CONFIG_LOGIN_SCRIPTS is not set | 492 | # CONFIG_LOGIN_SCRIPTS is not set |
468 | # CONFIG_FEATURE_NOLOGIN is not set | 493 | # CONFIG_FEATURE_NOLOGIN is not set |
469 | # CONFIG_FEATURE_SECURETTY is not set | 494 | # CONFIG_FEATURE_SECURETTY is not set |
@@ -521,13 +546,26 @@ CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | |||
521 | # Linux System Utilities | 546 | # Linux System Utilities |
522 | # | 547 | # |
523 | CONFIG_BLOCKDEV=y | 548 | CONFIG_BLOCKDEV=y |
524 | CONFIG_MDEV=y | 549 | CONFIG_FATATTR=y |
525 | CONFIG_FEATURE_MDEV_CONF=y | 550 | CONFIG_FSTRIM=y |
526 | CONFIG_FEATURE_MDEV_RENAME=y | 551 | # CONFIG_MDEV is not set |
527 | CONFIG_FEATURE_MDEV_RENAME_REGEXP=y | 552 | # CONFIG_FEATURE_MDEV_CONF is not set |
528 | CONFIG_FEATURE_MDEV_EXEC=y | 553 | # CONFIG_FEATURE_MDEV_RENAME is not set |
529 | CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y | 554 | # CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set |
555 | # CONFIG_FEATURE_MDEV_EXEC is not set | ||
556 | # CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set | ||
557 | # CONFIG_MOUNT is not set | ||
558 | # CONFIG_FEATURE_MOUNT_FAKE is not set | ||
559 | # CONFIG_FEATURE_MOUNT_VERBOSE is not set | ||
560 | # CONFIG_FEATURE_MOUNT_HELPERS is not set | ||
561 | # CONFIG_FEATURE_MOUNT_LABEL is not set | ||
562 | # CONFIG_FEATURE_MOUNT_NFS is not set | ||
563 | # CONFIG_FEATURE_MOUNT_CIFS is not set | ||
564 | # CONFIG_FEATURE_MOUNT_FLAGS is not set | ||
565 | # CONFIG_FEATURE_MOUNT_FSTAB is not set | ||
566 | # CONFIG_FEATURE_MOUNT_OTHERTAB is not set | ||
530 | CONFIG_REV=y | 567 | CONFIG_REV=y |
568 | CONFIG_UEVENT=y | ||
531 | # CONFIG_ACPID is not set | 569 | # CONFIG_ACPID is not set |
532 | # CONFIG_FEATURE_ACPID_COMPAT is not set | 570 | # CONFIG_FEATURE_ACPID_COMPAT is not set |
533 | CONFIG_BLKID=y | 571 | CONFIG_BLKID=y |
@@ -573,15 +611,6 @@ CONFIG_LSUSB=y | |||
573 | CONFIG_MKSWAP=y | 611 | CONFIG_MKSWAP=y |
574 | CONFIG_FEATURE_MKSWAP_UUID=y | 612 | CONFIG_FEATURE_MKSWAP_UUID=y |
575 | CONFIG_MORE=y | 613 | CONFIG_MORE=y |
576 | # CONFIG_MOUNT is not set | ||
577 | # CONFIG_FEATURE_MOUNT_FAKE is not set | ||
578 | # CONFIG_FEATURE_MOUNT_VERBOSE is not set | ||
579 | # CONFIG_FEATURE_MOUNT_HELPERS is not set | ||
580 | # CONFIG_FEATURE_MOUNT_LABEL is not set | ||
581 | # CONFIG_FEATURE_MOUNT_NFS is not set | ||
582 | # CONFIG_FEATURE_MOUNT_CIFS is not set | ||
583 | # CONFIG_FEATURE_MOUNT_FLAGS is not set | ||
584 | # CONFIG_FEATURE_MOUNT_FSTAB is not set | ||
585 | # CONFIG_PIVOT_ROOT is not set | 614 | # CONFIG_PIVOT_ROOT is not set |
586 | # CONFIG_RDATE is not set | 615 | # CONFIG_RDATE is not set |
587 | CONFIG_RDEV=y | 616 | CONFIG_RDEV=y |
@@ -591,6 +620,7 @@ CONFIG_SCRIPT=y | |||
591 | CONFIG_SCRIPTREPLAY=y | 620 | CONFIG_SCRIPTREPLAY=y |
592 | # CONFIG_SETARCH is not set | 621 | # CONFIG_SETARCH is not set |
593 | # CONFIG_SWAPONOFF is not set | 622 | # CONFIG_SWAPONOFF is not set |
623 | # CONFIG_FEATURE_SWAPON_DISCARD is not set | ||
594 | # CONFIG_FEATURE_SWAPON_PRI is not set | 624 | # CONFIG_FEATURE_SWAPON_PRI is not set |
595 | CONFIG_SWITCH_ROOT=y | 625 | CONFIG_SWITCH_ROOT=y |
596 | # CONFIG_UMOUNT is not set | 626 | # CONFIG_UMOUNT is not set |
@@ -603,32 +633,45 @@ CONFIG_VOLUMEID=y | |||
603 | # | 633 | # |
604 | # Filesystem/Volume identification | 634 | # Filesystem/Volume identification |
605 | # | 635 | # |
606 | CONFIG_FEATURE_VOLUMEID_EXT=y | ||
607 | CONFIG_FEATURE_VOLUMEID_BTRFS=y | 636 | CONFIG_FEATURE_VOLUMEID_BTRFS=y |
608 | CONFIG_FEATURE_VOLUMEID_REISERFS=y | 637 | CONFIG_FEATURE_VOLUMEID_CRAMFS=y |
638 | CONFIG_FEATURE_VOLUMEID_EXFAT=y | ||
639 | CONFIG_FEATURE_VOLUMEID_EXT=y | ||
640 | CONFIG_FEATURE_VOLUMEID_F2FS=y | ||
609 | CONFIG_FEATURE_VOLUMEID_FAT=y | 641 | CONFIG_FEATURE_VOLUMEID_FAT=y |
610 | CONFIG_FEATURE_VOLUMEID_HFS=y | 642 | CONFIG_FEATURE_VOLUMEID_HFS=y |
611 | CONFIG_FEATURE_VOLUMEID_JFS=y | ||
612 | CONFIG_FEATURE_VOLUMEID_XFS=y | ||
613 | CONFIG_FEATURE_VOLUMEID_NTFS=y | ||
614 | CONFIG_FEATURE_VOLUMEID_ISO9660=y | 643 | CONFIG_FEATURE_VOLUMEID_ISO9660=y |
615 | CONFIG_FEATURE_VOLUMEID_UDF=y | 644 | CONFIG_FEATURE_VOLUMEID_JFS=y |
616 | CONFIG_FEATURE_VOLUMEID_LUKS=y | 645 | CONFIG_FEATURE_VOLUMEID_LINUXRAID=y |
617 | CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y | 646 | CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y |
618 | CONFIG_FEATURE_VOLUMEID_CRAMFS=y | 647 | CONFIG_FEATURE_VOLUMEID_LUKS=y |
648 | CONFIG_FEATURE_VOLUMEID_NILFS=y | ||
649 | CONFIG_FEATURE_VOLUMEID_NTFS=y | ||
650 | CONFIG_FEATURE_VOLUMEID_OCFS2=y | ||
651 | CONFIG_FEATURE_VOLUMEID_REISERFS=y | ||
619 | CONFIG_FEATURE_VOLUMEID_ROMFS=y | 652 | CONFIG_FEATURE_VOLUMEID_ROMFS=y |
653 | CONFIG_FEATURE_VOLUMEID_SQUASHFS=y | ||
620 | CONFIG_FEATURE_VOLUMEID_SYSV=y | 654 | CONFIG_FEATURE_VOLUMEID_SYSV=y |
621 | CONFIG_FEATURE_VOLUMEID_OCFS2=y | 655 | CONFIG_FEATURE_VOLUMEID_UDF=y |
622 | CONFIG_FEATURE_VOLUMEID_LINUXRAID=y | 656 | CONFIG_FEATURE_VOLUMEID_XFS=y |
623 | 657 | ||
624 | # | 658 | # |
625 | # Miscellaneous Utilities | 659 | # Miscellaneous Utilities |
626 | # | 660 | # |
627 | # CONFIG_CONSPY is not set | 661 | # CONFIG_CONSPY is not set |
662 | CONFIG_CROND=y | ||
663 | CONFIG_FEATURE_CROND_D=y | ||
664 | CONFIG_FEATURE_CROND_CALL_SENDMAIL=y | ||
665 | CONFIG_FEATURE_CROND_DIR="/var/spool/cron" | ||
666 | CONFIG_I2CGET=y | ||
667 | CONFIG_I2CSET=y | ||
668 | CONFIG_I2CDUMP=y | ||
669 | CONFIG_I2CDETECT=y | ||
628 | CONFIG_LESS=y | 670 | CONFIG_LESS=y |
629 | CONFIG_FEATURE_LESS_MAXLINES=9999999 | 671 | CONFIG_FEATURE_LESS_MAXLINES=9999999 |
630 | CONFIG_FEATURE_LESS_BRACKETS=y | 672 | CONFIG_FEATURE_LESS_BRACKETS=y |
631 | CONFIG_FEATURE_LESS_FLAGS=y | 673 | CONFIG_FEATURE_LESS_FLAGS=y |
674 | CONFIG_FEATURE_LESS_TRUNCATE=y | ||
632 | CONFIG_FEATURE_LESS_MARKS=y | 675 | CONFIG_FEATURE_LESS_MARKS=y |
633 | CONFIG_FEATURE_LESS_REGEXP=y | 676 | CONFIG_FEATURE_LESS_REGEXP=y |
634 | CONFIG_FEATURE_LESS_WINCH=y | 677 | CONFIG_FEATURE_LESS_WINCH=y |
@@ -637,13 +680,17 @@ CONFIG_FEATURE_LESS_DASHCMD=y | |||
637 | CONFIG_FEATURE_LESS_LINENUMS=y | 680 | CONFIG_FEATURE_LESS_LINENUMS=y |
638 | # CONFIG_NANDWRITE is not set | 681 | # CONFIG_NANDWRITE is not set |
639 | CONFIG_NANDDUMP=y | 682 | CONFIG_NANDDUMP=y |
683 | # CONFIG_RFKILL is not set | ||
640 | CONFIG_SETSERIAL=y | 684 | CONFIG_SETSERIAL=y |
685 | # CONFIG_TASKSET is not set | ||
686 | # CONFIG_FEATURE_TASKSET_FANCY is not set | ||
641 | # CONFIG_UBIATTACH is not set | 687 | # CONFIG_UBIATTACH is not set |
642 | # CONFIG_UBIDETACH is not set | 688 | # CONFIG_UBIDETACH is not set |
643 | # CONFIG_UBIMKVOL is not set | 689 | # CONFIG_UBIMKVOL is not set |
644 | # CONFIG_UBIRMVOL is not set | 690 | # CONFIG_UBIRMVOL is not set |
645 | # CONFIG_UBIRSVOL is not set | 691 | # CONFIG_UBIRSVOL is not set |
646 | # CONFIG_UBIUPDATEVOL is not set | 692 | # CONFIG_UBIUPDATEVOL is not set |
693 | # CONFIG_WALL is not set | ||
647 | # CONFIG_ADJTIMEX is not set | 694 | # CONFIG_ADJTIMEX is not set |
648 | CONFIG_BBCONFIG=y | 695 | CONFIG_BBCONFIG=y |
649 | CONFIG_FEATURE_COMPRESS_BBCONFIG=y | 696 | CONFIG_FEATURE_COMPRESS_BBCONFIG=y |
@@ -659,10 +706,6 @@ CONFIG_FEATURE_CHAT_SEND_ESCAPES=y | |||
659 | CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y | 706 | CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y |
660 | CONFIG_FEATURE_CHAT_CLR_ABORT=y | 707 | CONFIG_FEATURE_CHAT_CLR_ABORT=y |
661 | CONFIG_CHRT=y | 708 | CONFIG_CHRT=y |
662 | CONFIG_CROND=y | ||
663 | CONFIG_FEATURE_CROND_D=y | ||
664 | CONFIG_FEATURE_CROND_CALL_SENDMAIL=y | ||
665 | CONFIG_FEATURE_CROND_DIR="/var/spool/cron" | ||
666 | CONFIG_CRONTAB=y | 709 | CONFIG_CRONTAB=y |
667 | CONFIG_DC=y | 710 | CONFIG_DC=y |
668 | CONFIG_FEATURE_DC_LIBM=y | 711 | CONFIG_FEATURE_DC_LIBM=y |
@@ -700,18 +743,14 @@ CONFIG_MAN=y | |||
700 | # CONFIG_MT is not set | 743 | # CONFIG_MT is not set |
701 | CONFIG_RAIDAUTORUN=y | 744 | CONFIG_RAIDAUTORUN=y |
702 | # CONFIG_READAHEAD is not set | 745 | # CONFIG_READAHEAD is not set |
703 | # CONFIG_RFKILL is not set | ||
704 | # CONFIG_RUNLEVEL is not set | 746 | # CONFIG_RUNLEVEL is not set |
705 | CONFIG_RX=y | 747 | CONFIG_RX=y |
706 | CONFIG_SETSID=y | 748 | CONFIG_SETSID=y |
707 | CONFIG_STRINGS=y | 749 | CONFIG_STRINGS=y |
708 | # CONFIG_TASKSET is not set | ||
709 | # CONFIG_FEATURE_TASKSET_FANCY is not set | ||
710 | CONFIG_TIME=y | 750 | CONFIG_TIME=y |
711 | CONFIG_TIMEOUT=y | 751 | CONFIG_TIMEOUT=y |
712 | CONFIG_TTYSIZE=y | 752 | CONFIG_TTYSIZE=y |
713 | CONFIG_VOLNAME=y | 753 | CONFIG_VOLNAME=y |
714 | # CONFIG_WALL is not set | ||
715 | # CONFIG_WATCHDOG is not set | 754 | # CONFIG_WATCHDOG is not set |
716 | 755 | ||
717 | # | 756 | # |
@@ -743,13 +782,13 @@ CONFIG_FAKEIDENTD=y | |||
743 | CONFIG_FTPD=y | 782 | CONFIG_FTPD=y |
744 | CONFIG_FEATURE_FTP_WRITE=y | 783 | CONFIG_FEATURE_FTP_WRITE=y |
745 | CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y | 784 | CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y |
785 | CONFIG_FEATURE_FTP_AUTHENTICATION=y | ||
746 | CONFIG_FTPGET=y | 786 | CONFIG_FTPGET=y |
747 | CONFIG_FTPPUT=y | 787 | CONFIG_FTPPUT=y |
748 | # CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set | 788 | # CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set |
749 | # CONFIG_HOSTNAME is not set | 789 | # CONFIG_HOSTNAME is not set |
750 | CONFIG_HTTPD=y | 790 | CONFIG_HTTPD=y |
751 | CONFIG_FEATURE_HTTPD_RANGES=y | 791 | CONFIG_FEATURE_HTTPD_RANGES=y |
752 | CONFIG_FEATURE_HTTPD_USE_SENDFILE=y | ||
753 | CONFIG_FEATURE_HTTPD_SETUID=y | 792 | CONFIG_FEATURE_HTTPD_SETUID=y |
754 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y | 793 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y |
755 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set | 794 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set |
@@ -806,6 +845,7 @@ CONFIG_FEATURE_NETSTAT_PRG=y | |||
806 | # CONFIG_NSLOOKUP is not set | 845 | # CONFIG_NSLOOKUP is not set |
807 | # CONFIG_NTPD is not set | 846 | # CONFIG_NTPD is not set |
808 | # CONFIG_FEATURE_NTPD_SERVER is not set | 847 | # CONFIG_FEATURE_NTPD_SERVER is not set |
848 | # CONFIG_FEATURE_NTPD_CONF is not set | ||
809 | CONFIG_PSCAN=y | 849 | CONFIG_PSCAN=y |
810 | CONFIG_ROUTE=y | 850 | CONFIG_ROUTE=y |
811 | # CONFIG_SLATTACH is not set | 851 | # CONFIG_SLATTACH is not set |
@@ -843,6 +883,7 @@ CONFIG_FEATURE_TUNCTL_UG=y | |||
843 | CONFIG_DHCPD_LEASES_FILE="" | 883 | CONFIG_DHCPD_LEASES_FILE="" |
844 | CONFIG_UDHCPC=y | 884 | CONFIG_UDHCPC=y |
845 | CONFIG_FEATURE_UDHCPC_ARPING=y | 885 | CONFIG_FEATURE_UDHCPC_ARPING=y |
886 | CONFIG_FEATURE_UDHCPC_SANITIZEOPT=y | ||
846 | CONFIG_FEATURE_UDHCP_PORT=y | 887 | CONFIG_FEATURE_UDHCP_PORT=y |
847 | CONFIG_UDHCP_DEBUG=9 | 888 | CONFIG_UDHCP_DEBUG=9 |
848 | CONFIG_FEATURE_UDHCP_RFC3397=y | 889 | CONFIG_FEATURE_UDHCP_RFC3397=y |
@@ -889,6 +930,13 @@ CONFIG_POWERTOP=y | |||
889 | CONFIG_PSTREE=y | 930 | CONFIG_PSTREE=y |
890 | CONFIG_PWDX=y | 931 | CONFIG_PWDX=y |
891 | CONFIG_SMEMCAP=y | 932 | CONFIG_SMEMCAP=y |
933 | CONFIG_TOP=y | ||
934 | CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y | ||
935 | CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y | ||
936 | CONFIG_FEATURE_TOP_SMP_CPU=y | ||
937 | CONFIG_FEATURE_TOP_DECIMALS=y | ||
938 | CONFIG_FEATURE_TOP_SMP_PROCESS=y | ||
939 | CONFIG_FEATURE_TOPMEM=y | ||
892 | CONFIG_UPTIME=y | 940 | CONFIG_UPTIME=y |
893 | # CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set | 941 | # CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set |
894 | CONFIG_FREE=y | 942 | CONFIG_FREE=y |
@@ -909,13 +957,6 @@ CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y | |||
909 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set | 957 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set |
910 | CONFIG_RENICE=y | 958 | CONFIG_RENICE=y |
911 | CONFIG_BB_SYSCTL=y | 959 | CONFIG_BB_SYSCTL=y |
912 | CONFIG_TOP=y | ||
913 | CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y | ||
914 | CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y | ||
915 | CONFIG_FEATURE_TOP_SMP_CPU=y | ||
916 | CONFIG_FEATURE_TOP_DECIMALS=y | ||
917 | CONFIG_FEATURE_TOP_SMP_PROCESS=y | ||
918 | CONFIG_FEATURE_TOPMEM=y | ||
919 | CONFIG_FEATURE_SHOW_THREADS=y | 960 | CONFIG_FEATURE_SHOW_THREADS=y |
920 | CONFIG_WATCH=y | 961 | CONFIG_WATCH=y |
921 | 962 | ||
@@ -961,6 +1002,7 @@ CONFIG_SOFTLIMIT=y | |||
961 | # CONFIG_ASH_BUILTIN_ECHO is not set | 1002 | # CONFIG_ASH_BUILTIN_ECHO is not set |
962 | # CONFIG_ASH_BUILTIN_PRINTF is not set | 1003 | # CONFIG_ASH_BUILTIN_PRINTF is not set |
963 | # CONFIG_ASH_BUILTIN_TEST is not set | 1004 | # CONFIG_ASH_BUILTIN_TEST is not set |
1005 | # CONFIG_ASH_HELP is not set | ||
964 | # CONFIG_ASH_CMDCMD is not set | 1006 | # CONFIG_ASH_CMDCMD is not set |
965 | # CONFIG_ASH_MAIL is not set | 1007 | # CONFIG_ASH_MAIL is not set |
966 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set | 1008 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set |
@@ -1010,6 +1052,7 @@ CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 | |||
1010 | CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 | 1052 | CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 |
1011 | # CONFIG_LOGREAD is not set | 1053 | # CONFIG_LOGREAD is not set |
1012 | # CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set | 1054 | # CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set |
1055 | # CONFIG_FEATURE_KMSG_SYSLOG is not set | ||
1013 | CONFIG_KLOGD=y | 1056 | CONFIG_KLOGD=y |
1014 | CONFIG_FEATURE_KLOGD_KLOGCTL=y | 1057 | CONFIG_FEATURE_KLOGD_KLOGCTL=y |
1015 | # CONFIG_LOGGER is not set | 1058 | # CONFIG_LOGGER is not set |
diff --git a/coreutils/chmod.c b/coreutils/chmod.c index 5ee45b942..a21c6d501 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c | |||
@@ -69,9 +69,9 @@ static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void | |||
69 | if (S_ISLNK(statbuf->st_mode)) | 69 | if (S_ISLNK(statbuf->st_mode)) |
70 | return TRUE; | 70 | return TRUE; |
71 | } | 71 | } |
72 | newmode = statbuf->st_mode; | ||
73 | 72 | ||
74 | if (!bb_parse_mode((char *)param, &newmode)) | 73 | newmode = bb_parse_mode((char *)param, statbuf->st_mode); |
74 | if (newmode == (mode_t)-1) | ||
75 | bb_error_msg_and_die("invalid mode '%s'", (char *)param); | 75 | bb_error_msg_and_die("invalid mode '%s'", (char *)param); |
76 | 76 | ||
77 | if (chmod(fileName, newmode) == 0) { | 77 | if (chmod(fileName, newmode) == 0) { |
diff --git a/coreutils/install.c b/coreutils/install.c index 73f9c70d5..8aa51cc34 100644 --- a/coreutils/install.c +++ b/coreutils/install.c | |||
@@ -159,7 +159,7 @@ int install_main(int argc, char **argv) | |||
159 | } | 159 | } |
160 | mode = 0755; /* GNU coreutils 6.10 compat */ | 160 | mode = 0755; /* GNU coreutils 6.10 compat */ |
161 | if (opts & OPT_MODE) | 161 | if (opts & OPT_MODE) |
162 | bb_parse_mode(mode_str, &mode); | 162 | mode = bb_parse_mode(mode_str, mode); |
163 | uid = (opts & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); | 163 | uid = (opts & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); |
164 | gid = (opts & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); | 164 | gid = (opts & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); |
165 | 165 | ||
diff --git a/coreutils/libcoreutils/getopt_mk_fifo_nod.c b/coreutils/libcoreutils/getopt_mk_fifo_nod.c index 222717149..47375ff91 100644 --- a/coreutils/libcoreutils/getopt_mk_fifo_nod.c +++ b/coreutils/libcoreutils/getopt_mk_fifo_nod.c | |||
@@ -33,7 +33,9 @@ mode_t FAST_FUNC getopt_mk_fifo_nod(char **argv) | |||
33 | int opt; | 33 | int opt; |
34 | opt = getopt32(argv, "m:" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); | 34 | opt = getopt32(argv, "m:" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); |
35 | if (opt & 1) { | 35 | if (opt & 1) { |
36 | if (bb_parse_mode(smode, &mode)) | 36 | mode = bb_parse_mode(smode, mode); |
37 | if (mode != (mode_t)-1) /* if mode is valid */ | ||
38 | /* make future mknod/mkfifo set mode bits exactly */ | ||
37 | umask(0); | 39 | umask(0); |
38 | } | 40 | } |
39 | 41 | ||
diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c index 864edfb0a..6f7b004dd 100644 --- a/coreutils/mkdir.c +++ b/coreutils/mkdir.c | |||
@@ -71,8 +71,8 @@ int mkdir_main(int argc UNUSED_PARAM, char **argv) | |||
71 | #endif | 71 | #endif |
72 | opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); | 72 | opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); |
73 | if (opt & 1) { | 73 | if (opt & 1) { |
74 | mode_t mmode = 0777; | 74 | mode_t mmode = bb_parse_mode(smode, 0777); |
75 | if (!bb_parse_mode(smode, &mmode)) { | 75 | if (mmode == (mode_t)-1) { |
76 | bb_error_msg_and_die("invalid mode '%s'", smode); | 76 | bb_error_msg_and_die("invalid mode '%s'", smode); |
77 | } | 77 | } |
78 | mode = mmode; | 78 | mode = mmode; |
diff --git a/coreutils/sort.c b/coreutils/sort.c index 1cb4c3e3f..36f02543b 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c | |||
@@ -25,14 +25,14 @@ | |||
25 | //usage: "\n -f Ignore case" | 25 | //usage: "\n -f Ignore case" |
26 | //usage: "\n -g General numerical sort" | 26 | //usage: "\n -g General numerical sort" |
27 | //usage: "\n -i Ignore unprintable characters" | 27 | //usage: "\n -i Ignore unprintable characters" |
28 | //usage: "\n -k Sort key" | ||
29 | //usage: "\n -M Sort month" | 28 | //usage: "\n -M Sort month" |
30 | //usage: ) | 29 | //usage: ) |
30 | //-h, --human-numeric-sort: compare human readable numbers (e.g., 2K 1G) | ||
31 | //usage: "\n -n Sort numbers" | 31 | //usage: "\n -n Sort numbers" |
32 | //usage: IF_FEATURE_SORT_BIG( | 32 | //usage: IF_FEATURE_SORT_BIG( |
33 | //usage: "\n -o Output to file" | 33 | //usage: "\n -o Output to file" |
34 | //usage: "\n -k Sort by key" | 34 | //usage: "\n -t CHAR Field separator" |
35 | //usage: "\n -t CHAR Key separator" | 35 | //usage: "\n -k N[,M] Sort by Nth field" |
36 | //usage: ) | 36 | //usage: ) |
37 | //usage: "\n -r Reverse sort order" | 37 | //usage: "\n -r Reverse sort order" |
38 | //usage: IF_FEATURE_SORT_BIG( | 38 | //usage: IF_FEATURE_SORT_BIG( |
@@ -143,6 +143,9 @@ static char *get_key(char *str, struct sort_key *key, int flags) | |||
143 | } | 143 | } |
144 | } | 144 | } |
145 | } | 145 | } |
146 | /* Remove last delim: "abc:def:" => "abc:def" */ | ||
147 | if (key_separator && j && end != 0) | ||
148 | end--; | ||
146 | } | 149 | } |
147 | if (!j) start = end; | 150 | if (!j) start = end; |
148 | } | 151 | } |
@@ -163,7 +166,8 @@ static char *get_key(char *str, struct sort_key *key, int flags) | |||
163 | if (start > len) start = len; | 166 | if (start > len) start = len; |
164 | } | 167 | } |
165 | /* Make the copy */ | 168 | /* Make the copy */ |
166 | if (end < start) end = start; | 169 | if (end < start) |
170 | end = start; | ||
167 | str = xstrndup(str+start, end-start); | 171 | str = xstrndup(str+start, end-start); |
168 | /* Handle -d */ | 172 | /* Handle -d */ |
169 | if (flags & FLAG_d) { | 173 | if (flags & FLAG_d) { |
diff --git a/coreutils/uniq.c b/coreutils/uniq.c index 9208d34ec..e0133998a 100644 --- a/coreutils/uniq.c +++ b/coreutils/uniq.c | |||
@@ -112,7 +112,7 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) | |||
112 | /* %7lu matches GNU coreutils 6.9 */ | 112 | /* %7lu matches GNU coreutils 6.9 */ |
113 | printf("%7lu ", dups + 1); | 113 | printf("%7lu ", dups + 1); |
114 | } | 114 | } |
115 | printf("%s\n", old_line); | 115 | puts(old_line); |
116 | } | 116 | } |
117 | free(old_line); | 117 | free(old_line); |
118 | } | 118 | } |
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index 7aa5c67f2..37b254d30 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c | |||
@@ -29,9 +29,19 @@ static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags U | |||
29 | { | 29 | { |
30 | char *line; | 30 | char *line; |
31 | 31 | ||
32 | while ((line = xmalloc_fgetline(src_stream)) != NULL) { | 32 | for (;;) { |
33 | int encoded_len, str_len; | 33 | int encoded_len, str_len; |
34 | char *line_ptr, *dst; | 34 | char *line_ptr, *dst; |
35 | size_t line_len; | ||
36 | |||
37 | line_len = 64 * 1024; | ||
38 | line = xmalloc_fgets_str_len(src_stream, "\n", &line_len); | ||
39 | if (!line) | ||
40 | break; | ||
41 | /* Handle both Unix and MSDOS text, and stray trailing spaces */ | ||
42 | str_len = line_len; | ||
43 | while (--str_len >= 0 && isspace(line[str_len])) | ||
44 | line[str_len] = '\0'; | ||
35 | 45 | ||
36 | if (strcmp(line, "end") == 0) { | 46 | if (strcmp(line, "end") == 0) { |
37 | return; /* the only non-error exit */ | 47 | return; /* the only non-error exit */ |
@@ -128,6 +138,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv) | |||
128 | if (!outname) | 138 | if (!outname) |
129 | break; | 139 | break; |
130 | outname++; | 140 | outname++; |
141 | trim(outname); /* remove trailing space (and '\r' for DOS text) */ | ||
131 | if (!outname[0]) | 142 | if (!outname[0]) |
132 | break; | 143 | break; |
133 | } | 144 | } |
diff --git a/coreutils/who.c b/coreutils/who.c index 8337212c9..f694d0c60 100644 --- a/coreutils/who.c +++ b/coreutils/who.c | |||
@@ -81,7 +81,7 @@ int who_main(int argc UNUSED_PARAM, char **argv) | |||
81 | opt_complementary = "=0"; | 81 | opt_complementary = "=0"; |
82 | opt = getopt32(argv, do_users ? "" : "aH"); | 82 | opt = getopt32(argv, do_users ? "" : "aH"); |
83 | if (opt & 2) // -H | 83 | if (opt & 2) // -H |
84 | printf("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST\n"); | 84 | puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST"); |
85 | 85 | ||
86 | setutxent(); | 86 | setutxent(); |
87 | while ((ut = getutxent()) != NULL) { | 87 | while ((ut = getutxent()) != NULL) { |
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index 527fae227..dd6fe7d49 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c | |||
@@ -189,7 +189,7 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv) | |||
189 | if (ret < 0) | 189 | if (ret < 0) |
190 | bb_perror_msg("can't execute '%s'", name); | 190 | bb_perror_msg("can't execute '%s'", name); |
191 | else /* ret > 0 */ | 191 | else /* ret > 0 */ |
192 | bb_error_msg("%s exited with code %d", name, ret & 0xff); | 192 | bb_error_msg("%s: exit status %u", name, ret & 0xff); |
193 | 193 | ||
194 | if (option_mask32 & OPT_e) | 194 | if (option_mask32 & OPT_e) |
195 | xfunc_die(); | 195 | xfunc_die(); |
diff --git a/editors/awk.c b/editors/awk.c index b4b6c5f78..142ab670f 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -207,7 +207,7 @@ typedef struct tsplitter_s { | |||
207 | 207 | ||
208 | /* simple token classes */ | 208 | /* simple token classes */ |
209 | /* Order and hex values are very important!!! See next_token() */ | 209 | /* Order and hex values are very important!!! See next_token() */ |
210 | #define TC_SEQSTART 1 /* ( */ | 210 | #define TC_SEQSTART (1 << 0) /* ( */ |
211 | #define TC_SEQTERM (1 << 1) /* ) */ | 211 | #define TC_SEQTERM (1 << 1) /* ) */ |
212 | #define TC_REGEXP (1 << 2) /* /.../ */ | 212 | #define TC_REGEXP (1 << 2) /* /.../ */ |
213 | #define TC_OUTRDR (1 << 3) /* | > >> */ | 213 | #define TC_OUTRDR (1 << 3) /* | > >> */ |
@@ -227,16 +227,22 @@ typedef struct tsplitter_s { | |||
227 | #define TC_WHILE (1 << 17) | 227 | #define TC_WHILE (1 << 17) |
228 | #define TC_ELSE (1 << 18) | 228 | #define TC_ELSE (1 << 18) |
229 | #define TC_BUILTIN (1 << 19) | 229 | #define TC_BUILTIN (1 << 19) |
230 | #define TC_GETLINE (1 << 20) | 230 | /* This costs ~50 bytes of code. |
231 | #define TC_FUNCDECL (1 << 21) /* `function' `func' */ | 231 | * A separate class to support deprecated "length" form. If we don't need that |
232 | #define TC_BEGIN (1 << 22) | 232 | * (i.e. if we demand that only "length()" with () is valid), then TC_LENGTH |
233 | #define TC_END (1 << 23) | 233 | * can be merged with TC_BUILTIN: |
234 | #define TC_EOF (1 << 24) | 234 | */ |
235 | #define TC_VARIABLE (1 << 25) | 235 | #define TC_LENGTH (1 << 20) |
236 | #define TC_ARRAY (1 << 26) | 236 | #define TC_GETLINE (1 << 21) |
237 | #define TC_FUNCTION (1 << 27) | 237 | #define TC_FUNCDECL (1 << 22) /* `function' `func' */ |
238 | #define TC_STRING (1 << 28) | 238 | #define TC_BEGIN (1 << 23) |
239 | #define TC_NUMBER (1 << 29) | 239 | #define TC_END (1 << 24) |
240 | #define TC_EOF (1 << 25) | ||
241 | #define TC_VARIABLE (1 << 26) | ||
242 | #define TC_ARRAY (1 << 27) | ||
243 | #define TC_FUNCTION (1 << 28) | ||
244 | #define TC_STRING (1 << 29) | ||
245 | #define TC_NUMBER (1 << 30) | ||
240 | 246 | ||
241 | #define TC_UOPPRE (TC_UOPPRE1 | TC_UOPPRE2) | 247 | #define TC_UOPPRE (TC_UOPPRE1 | TC_UOPPRE2) |
242 | 248 | ||
@@ -244,14 +250,16 @@ typedef struct tsplitter_s { | |||
244 | #define TC_BINOP (TC_BINOPX | TC_COMMA | TC_PIPE | TC_IN) | 250 | #define TC_BINOP (TC_BINOPX | TC_COMMA | TC_PIPE | TC_IN) |
245 | //#define TC_UNARYOP (TC_UOPPRE | TC_UOPPOST) | 251 | //#define TC_UNARYOP (TC_UOPPRE | TC_UOPPOST) |
246 | #define TC_OPERAND (TC_VARIABLE | TC_ARRAY | TC_FUNCTION \ | 252 | #define TC_OPERAND (TC_VARIABLE | TC_ARRAY | TC_FUNCTION \ |
247 | | TC_BUILTIN | TC_GETLINE | TC_SEQSTART | TC_STRING | TC_NUMBER) | 253 | | TC_BUILTIN | TC_LENGTH | TC_GETLINE \ |
254 | | TC_SEQSTART | TC_STRING | TC_NUMBER) | ||
248 | 255 | ||
249 | #define TC_STATEMNT (TC_STATX | TC_WHILE) | 256 | #define TC_STATEMNT (TC_STATX | TC_WHILE) |
250 | #define TC_OPTERM (TC_SEMICOL | TC_NEWLINE) | 257 | #define TC_OPTERM (TC_SEMICOL | TC_NEWLINE) |
251 | 258 | ||
252 | /* word tokens, cannot mean something else if not expected */ | 259 | /* word tokens, cannot mean something else if not expected */ |
253 | #define TC_WORD (TC_IN | TC_STATEMNT | TC_ELSE | TC_BUILTIN \ | 260 | #define TC_WORD (TC_IN | TC_STATEMNT | TC_ELSE \ |
254 | | TC_GETLINE | TC_FUNCDECL | TC_BEGIN | TC_END) | 261 | | TC_BUILTIN | TC_LENGTH | TC_GETLINE \ |
262 | | TC_FUNCDECL | TC_BEGIN | TC_END) | ||
255 | 263 | ||
256 | /* discard newlines after these */ | 264 | /* discard newlines after these */ |
257 | #define TC_NOTERM (TC_COMMA | TC_GRPSTART | TC_GRPTERM \ | 265 | #define TC_NOTERM (TC_COMMA | TC_GRPSTART | TC_GRPTERM \ |
@@ -346,54 +354,54 @@ enum { | |||
346 | #define NTC "\377" /* switch to next token class (tc<<1) */ | 354 | #define NTC "\377" /* switch to next token class (tc<<1) */ |
347 | #define NTCC '\377' | 355 | #define NTCC '\377' |
348 | 356 | ||
349 | #define OC_B OC_BUILTIN | ||
350 | |||
351 | static const char tokenlist[] ALIGN1 = | 357 | static const char tokenlist[] ALIGN1 = |
352 | "\1(" NTC | 358 | "\1(" NTC /* TC_SEQSTART */ |
353 | "\1)" NTC | 359 | "\1)" NTC /* TC_SEQTERM */ |
354 | "\1/" NTC /* REGEXP */ | 360 | "\1/" NTC /* TC_REGEXP */ |
355 | "\2>>" "\1>" "\1|" NTC /* OUTRDR */ | 361 | "\2>>" "\1>" "\1|" NTC /* TC_OUTRDR */ |
356 | "\2++" "\2--" NTC /* UOPPOST */ | 362 | "\2++" "\2--" NTC /* TC_UOPPOST */ |
357 | "\2++" "\2--" "\1$" NTC /* UOPPRE1 */ | 363 | "\2++" "\2--" "\1$" NTC /* TC_UOPPRE1 */ |
358 | "\2==" "\1=" "\2+=" "\2-=" /* BINOPX */ | 364 | "\2==" "\1=" "\2+=" "\2-=" /* TC_BINOPX */ |
359 | "\2*=" "\2/=" "\2%=" "\2^=" | 365 | "\2*=" "\2/=" "\2%=" "\2^=" |
360 | "\1+" "\1-" "\3**=" "\2**" | 366 | "\1+" "\1-" "\3**=" "\2**" |
361 | "\1/" "\1%" "\1^" "\1*" | 367 | "\1/" "\1%" "\1^" "\1*" |
362 | "\2!=" "\2>=" "\2<=" "\1>" | 368 | "\2!=" "\2>=" "\2<=" "\1>" |
363 | "\1<" "\2!~" "\1~" "\2&&" | 369 | "\1<" "\2!~" "\1~" "\2&&" |
364 | "\2||" "\1?" "\1:" NTC | 370 | "\2||" "\1?" "\1:" NTC |
365 | "\2in" NTC | 371 | "\2in" NTC /* TC_IN */ |
366 | "\1," NTC | 372 | "\1," NTC /* TC_COMMA */ |
367 | "\1|" NTC | 373 | "\1|" NTC /* TC_PIPE */ |
368 | "\1+" "\1-" "\1!" NTC /* UOPPRE2 */ | 374 | "\1+" "\1-" "\1!" NTC /* TC_UOPPRE2 */ |
369 | "\1]" NTC | 375 | "\1]" NTC /* TC_ARRTERM */ |
370 | "\1{" NTC | 376 | "\1{" NTC /* TC_GRPSTART */ |
371 | "\1}" NTC | 377 | "\1}" NTC /* TC_GRPTERM */ |
372 | "\1;" NTC | 378 | "\1;" NTC /* TC_SEMICOL */ |
373 | "\1\n" NTC | 379 | "\1\n" NTC /* TC_NEWLINE */ |
374 | "\2if" "\2do" "\3for" "\5break" /* STATX */ | 380 | "\2if" "\2do" "\3for" "\5break" /* TC_STATX */ |
375 | "\10continue" "\6delete" "\5print" | 381 | "\10continue" "\6delete" "\5print" |
376 | "\6printf" "\4next" "\10nextfile" | 382 | "\6printf" "\4next" "\10nextfile" |
377 | "\6return" "\4exit" NTC | 383 | "\6return" "\4exit" NTC |
378 | "\5while" NTC | 384 | "\5while" NTC /* TC_WHILE */ |
379 | "\4else" NTC | 385 | "\4else" NTC /* TC_ELSE */ |
380 | 386 | "\3and" "\5compl" "\6lshift" "\2or" /* TC_BUILTIN */ | |
381 | "\3and" "\5compl" "\6lshift" "\2or" | ||
382 | "\6rshift" "\3xor" | 387 | "\6rshift" "\3xor" |
383 | "\5close" "\6system" "\6fflush" "\5atan2" /* BUILTIN */ | 388 | "\5close" "\6system" "\6fflush" "\5atan2" |
384 | "\3cos" "\3exp" "\3int" "\3log" | 389 | "\3cos" "\3exp" "\3int" "\3log" |
385 | "\4rand" "\3sin" "\4sqrt" "\5srand" | 390 | "\4rand" "\3sin" "\4sqrt" "\5srand" |
386 | "\6gensub" "\4gsub" "\5index" "\6length" | 391 | "\6gensub" "\4gsub" "\5index" /* "\6length" was here */ |
387 | "\5match" "\5split" "\7sprintf" "\3sub" | 392 | "\5match" "\5split" "\7sprintf" "\3sub" |
388 | "\6substr" "\7systime" "\10strftime" "\6mktime" | 393 | "\6substr" "\7systime" "\10strftime" "\6mktime" |
389 | "\7tolower" "\7toupper" NTC | 394 | "\7tolower" "\7toupper" NTC |
390 | "\7getline" NTC | 395 | "\6length" NTC /* TC_LENGTH */ |
391 | "\4func" "\10function" NTC | 396 | "\7getline" NTC /* TC_GETLINE */ |
392 | "\5BEGIN" NTC | 397 | "\4func" "\10function" NTC /* TC_FUNCDECL */ |
393 | "\3END" | 398 | "\5BEGIN" NTC /* TC_BEGIN */ |
399 | "\3END" /* TC_END */ | ||
394 | /* compiler adds trailing "\0" */ | 400 | /* compiler adds trailing "\0" */ |
395 | ; | 401 | ; |
396 | 402 | ||
403 | #define OC_B OC_BUILTIN | ||
404 | |||
397 | static const uint32_t tokeninfo[] = { | 405 | static const uint32_t tokeninfo[] = { |
398 | 0, | 406 | 0, |
399 | 0, | 407 | 0, |
@@ -408,7 +416,7 @@ static const uint32_t tokeninfo[] = { | |||
408 | OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1, | 416 | OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1, |
409 | OC_COMPARE|VV|P(39)|2, OC_MATCH|Sx|P(45)|'!', OC_MATCH|Sx|P(45)|'~', OC_LAND|Vx|P(55), | 417 | OC_COMPARE|VV|P(39)|2, OC_MATCH|Sx|P(45)|'!', OC_MATCH|Sx|P(45)|'~', OC_LAND|Vx|P(55), |
410 | OC_LOR|Vx|P(59), OC_TERNARY|Vx|P(64)|'?', OC_COLON|xx|P(67)|':', | 418 | OC_LOR|Vx|P(59), OC_TERNARY|Vx|P(64)|'?', OC_COLON|xx|P(67)|':', |
411 | OC_IN|SV|P(49), /* in */ | 419 | OC_IN|SV|P(49), /* TC_IN */ |
412 | OC_COMMA|SS|P(80), | 420 | OC_COMMA|SS|P(80), |
413 | OC_PGETLINE|SV|P(37), | 421 | OC_PGETLINE|SV|P(37), |
414 | OC_UNARY|xV|P(19)|'+', OC_UNARY|xV|P(19)|'-', OC_UNARY|xV|P(19)|'!', | 422 | OC_UNARY|xV|P(19)|'+', OC_UNARY|xV|P(19)|'-', OC_UNARY|xV|P(19)|'!', |
@@ -423,20 +431,20 @@ static const uint32_t tokeninfo[] = { | |||
423 | OC_RETURN|Vx, OC_EXIT|Nx, | 431 | OC_RETURN|Vx, OC_EXIT|Nx, |
424 | ST_WHILE, | 432 | ST_WHILE, |
425 | 0, /* else */ | 433 | 0, /* else */ |
426 | |||
427 | OC_B|B_an|P(0x83), OC_B|B_co|P(0x41), OC_B|B_ls|P(0x83), OC_B|B_or|P(0x83), | 434 | OC_B|B_an|P(0x83), OC_B|B_co|P(0x41), OC_B|B_ls|P(0x83), OC_B|B_or|P(0x83), |
428 | OC_B|B_rs|P(0x83), OC_B|B_xo|P(0x83), | 435 | OC_B|B_rs|P(0x83), OC_B|B_xo|P(0x83), |
429 | OC_FBLTIN|Sx|F_cl, OC_FBLTIN|Sx|F_sy, OC_FBLTIN|Sx|F_ff, OC_B|B_a2|P(0x83), | 436 | OC_FBLTIN|Sx|F_cl, OC_FBLTIN|Sx|F_sy, OC_FBLTIN|Sx|F_ff, OC_B|B_a2|P(0x83), |
430 | OC_FBLTIN|Nx|F_co, OC_FBLTIN|Nx|F_ex, OC_FBLTIN|Nx|F_in, OC_FBLTIN|Nx|F_lg, | 437 | OC_FBLTIN|Nx|F_co, OC_FBLTIN|Nx|F_ex, OC_FBLTIN|Nx|F_in, OC_FBLTIN|Nx|F_lg, |
431 | OC_FBLTIN|F_rn, OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr, | 438 | OC_FBLTIN|F_rn, OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr, |
432 | OC_B|B_ge|P(0xd6), OC_B|B_gs|P(0xb6), OC_B|B_ix|P(0x9b), OC_FBLTIN|Sx|F_le, | 439 | OC_B|B_ge|P(0xd6), OC_B|B_gs|P(0xb6), OC_B|B_ix|P(0x9b), /* OC_FBLTIN|Sx|F_le, was here */ |
433 | OC_B|B_ma|P(0x89), OC_B|B_sp|P(0x8b), OC_SPRINTF, OC_B|B_su|P(0xb6), | 440 | OC_B|B_ma|P(0x89), OC_B|B_sp|P(0x8b), OC_SPRINTF, OC_B|B_su|P(0xb6), |
434 | OC_B|B_ss|P(0x8f), OC_FBLTIN|F_ti, OC_B|B_ti|P(0x0b), OC_B|B_mt|P(0x0b), | 441 | OC_B|B_ss|P(0x8f), OC_FBLTIN|F_ti, OC_B|B_ti|P(0x0b), OC_B|B_mt|P(0x0b), |
435 | OC_B|B_lo|P(0x49), OC_B|B_up|P(0x49), | 442 | OC_B|B_lo|P(0x49), OC_B|B_up|P(0x49), |
443 | OC_FBLTIN|Sx|F_le, /* TC_LENGTH */ | ||
436 | OC_GETLINE|SV|P(0), | 444 | OC_GETLINE|SV|P(0), |
437 | 0, 0, | 445 | 0, 0, |
438 | 0, | 446 | 0, |
439 | 0 /* END */ | 447 | 0 /* TC_END */ |
440 | }; | 448 | }; |
441 | 449 | ||
442 | /* internal variable names and their initial values */ | 450 | /* internal variable names and their initial values */ |
@@ -1206,9 +1214,10 @@ static uint32_t next_token(uint32_t expected) | |||
1206 | ltclass = t_tclass; | 1214 | ltclass = t_tclass; |
1207 | 1215 | ||
1208 | /* Are we ready for this? */ | 1216 | /* Are we ready for this? */ |
1209 | if (!(ltclass & expected)) | 1217 | if (!(ltclass & expected)) { |
1210 | syntax_error((ltclass & (TC_NEWLINE | TC_EOF)) ? | 1218 | syntax_error((ltclass & (TC_NEWLINE | TC_EOF)) ? |
1211 | EMSG_UNEXP_EOS : EMSG_UNEXP_TOKEN); | 1219 | EMSG_UNEXP_EOS : EMSG_UNEXP_TOKEN); |
1220 | } | ||
1212 | 1221 | ||
1213 | return ltclass; | 1222 | return ltclass; |
1214 | #undef concat_inserted | 1223 | #undef concat_inserted |
@@ -1375,6 +1384,16 @@ static node *parse_expr(uint32_t iexp) | |||
1375 | debug_printf_parse("%s: TC_BUILTIN\n", __func__); | 1384 | debug_printf_parse("%s: TC_BUILTIN\n", __func__); |
1376 | cn->l.n = condition(); | 1385 | cn->l.n = condition(); |
1377 | break; | 1386 | break; |
1387 | |||
1388 | case TC_LENGTH: | ||
1389 | debug_printf_parse("%s: TC_LENGTH\n", __func__); | ||
1390 | next_token(TC_SEQSTART | TC_OPTERM | TC_GRPTERM); | ||
1391 | rollback_token(); | ||
1392 | if (t_tclass & TC_SEQSTART) { | ||
1393 | /* It was a "(" token. Handle just like TC_BUILTIN */ | ||
1394 | cn->l.n = condition(); | ||
1395 | } | ||
1396 | break; | ||
1378 | } | 1397 | } |
1379 | } | 1398 | } |
1380 | } | 1399 | } |
diff --git a/editors/diff.c b/editors/diff.c index e0adcee59..a892cfdf2 100644 --- a/editors/diff.c +++ b/editors/diff.c | |||
@@ -433,7 +433,7 @@ static void fetch(FILE_and_pos_t *ft, const off_t *ix, int a, int b, int ch) | |||
433 | for (j = 0, col = 0; j < ix[i] - ix[i - 1]; j++) { | 433 | for (j = 0, col = 0; j < ix[i] - ix[i - 1]; j++) { |
434 | int c = fgetc(ft->ft_fp); | 434 | int c = fgetc(ft->ft_fp); |
435 | if (c == EOF) { | 435 | if (c == EOF) { |
436 | printf("\n\\ No newline at end of file\n"); | 436 | puts("\n\\ No newline at end of file"); |
437 | return; | 437 | return; |
438 | } | 438 | } |
439 | ft->ft_pos++; | 439 | ft->ft_pos++; |
@@ -692,7 +692,7 @@ static bool diff(FILE* fp[2], char *file[2]) | |||
692 | continue; | 692 | continue; |
693 | printf(",%d", (a < b) ? b - a + 1 : 0); | 693 | printf(",%d", (a < b) ? b - a + 1 : 0); |
694 | } | 694 | } |
695 | printf(" @@\n"); | 695 | puts(" @@"); |
696 | /* | 696 | /* |
697 | * Output changes in "unified" diff format--the old and new lines | 697 | * Output changes in "unified" diff format--the old and new lines |
698 | * are printed together. | 698 | * are printed together. |
diff --git a/editors/ed.c b/editors/ed.c index f0e5e4d5d..a4c419099 100644 --- a/editors/ed.c +++ b/editors/ed.c | |||
@@ -206,7 +206,7 @@ static void doCommands(void) | |||
206 | if (fileName) | 206 | if (fileName) |
207 | printf("\"%s\"\n", fileName); | 207 | printf("\"%s\"\n", fileName); |
208 | else | 208 | else |
209 | printf("No file name\n"); | 209 | puts("No file name"); |
210 | break; | 210 | break; |
211 | } | 211 | } |
212 | free(fileName); | 212 | free(fileName); |
diff --git a/editors/vi.c b/editors/vi.c index 075f714cf..b2d185193 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -2919,10 +2919,10 @@ static int file_insert(const char *fn, char *p, int initial) | |||
2919 | int fd, size; | 2919 | int fd, size; |
2920 | struct stat statbuf; | 2920 | struct stat statbuf; |
2921 | 2921 | ||
2922 | if (p < text || p > end) { | 2922 | if (p < text) |
2923 | status_line_bold("Trying to insert file outside of memory"); | 2923 | p = text; |
2924 | return cnt; | 2924 | if (p > end) |
2925 | } | 2925 | p = end; |
2926 | 2926 | ||
2927 | fd = open(fn, O_RDONLY); | 2927 | fd = open(fn, O_RDONLY); |
2928 | if (fd < 0) { | 2928 | if (fd < 0) { |
diff --git a/findutils/find.c b/findutils/find.c index ced8922e7..bd7ccc323 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -768,7 +768,10 @@ ACTF(delete) | |||
768 | { | 768 | { |
769 | int rc; | 769 | int rc; |
770 | if (S_ISDIR(statbuf->st_mode)) { | 770 | if (S_ISDIR(statbuf->st_mode)) { |
771 | rc = rmdir(fileName); | 771 | /* "find . -delete" skips rmdir(".") */ |
772 | rc = 0; | ||
773 | if (NOT_LONE_CHAR(fileName, '.')) | ||
774 | rc = rmdir(fileName); | ||
772 | } else { | 775 | } else { |
773 | rc = unlink(fileName); | 776 | rc = unlink(fileName); |
774 | } | 777 | } |
@@ -1261,7 +1264,8 @@ static action*** parse_params(char **argv) | |||
1261 | ap->perm_char = arg1[0]; | 1264 | ap->perm_char = arg1[0]; |
1262 | arg1 = (arg1[0] == '/' ? arg1+1 : plus_minus_num(arg1)); | 1265 | arg1 = (arg1[0] == '/' ? arg1+1 : plus_minus_num(arg1)); |
1263 | /*ap->perm_mask = 0; - ALLOC_ACTION did it */ | 1266 | /*ap->perm_mask = 0; - ALLOC_ACTION did it */ |
1264 | if (!bb_parse_mode(arg1, &ap->perm_mask)) | 1267 | ap->perm_mask = bb_parse_mode(arg1, ap->perm_mask); |
1268 | if (ap->perm_mask == (mode_t)-1) | ||
1265 | bb_error_msg_and_die("invalid mode '%s'", arg1); | 1269 | bb_error_msg_and_die("invalid mode '%s'", arg1); |
1266 | } | 1270 | } |
1267 | #endif | 1271 | #endif |
diff --git a/findutils/xargs.c b/findutils/xargs.c index 1ca136128..dba74ea61 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -125,7 +125,7 @@ static int xargs_exec(void) | |||
125 | return 124; | 125 | return 124; |
126 | } | 126 | } |
127 | if (status >= 0x180) { | 127 | if (status >= 0x180) { |
128 | bb_error_msg("%s: terminated by signal %d", | 128 | bb_error_msg("'%s' terminated by signal %d", |
129 | G.args[0], status - 0x180); | 129 | G.args[0], status - 0x180); |
130 | return 125; | 130 | return 125; |
131 | } | 131 | } |
diff --git a/include/applets.src.h b/include/applets.src.h index 9f3ac78cb..dac83e7fb 100644 --- a/include/applets.src.h +++ b/include/applets.src.h | |||
@@ -382,7 +382,6 @@ IF_VOLNAME(APPLET(volname, BB_DIR_USR_BIN, BB_SUID_DROP)) | |||
382 | IF_WATCH(APPLET(watch, BB_DIR_BIN, BB_SUID_DROP)) | 382 | IF_WATCH(APPLET(watch, BB_DIR_BIN, BB_SUID_DROP)) |
383 | IF_WATCHDOG(APPLET(watchdog, BB_DIR_SBIN, BB_SUID_DROP)) | 383 | IF_WATCHDOG(APPLET(watchdog, BB_DIR_SBIN, BB_SUID_DROP)) |
384 | IF_WC(APPLET(wc, BB_DIR_USR_BIN, BB_SUID_DROP)) | 384 | IF_WC(APPLET(wc, BB_DIR_USR_BIN, BB_SUID_DROP)) |
385 | IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
386 | IF_WHICH(APPLET(which, BB_DIR_USR_BIN, BB_SUID_DROP)) | 385 | IF_WHICH(APPLET(which, BB_DIR_USR_BIN, BB_SUID_DROP)) |
387 | IF_WHOAMI(APPLET_NOFORK(whoami, whoami, BB_DIR_USR_BIN, BB_SUID_DROP, whoami)) | 386 | IF_WHOAMI(APPLET_NOFORK(whoami, whoami, BB_DIR_USR_BIN, BB_SUID_DROP, whoami)) |
388 | IF_YES(APPLET_NOFORK(yes, yes, BB_DIR_USR_BIN, BB_SUID_DROP, yes)) | 387 | IF_YES(APPLET_NOFORK(yes, yes, BB_DIR_USR_BIN, BB_SUID_DROP, yes)) |
diff --git a/include/libbb.h b/include/libbb.h index 729704974..2f90b35f7 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -424,6 +424,7 @@ const char *bb_basename(const char *name) FAST_FUNC; | |||
424 | char *last_char_is(const char *s, int c) FAST_FUNC; | 424 | char *last_char_is(const char *s, int c) FAST_FUNC; |
425 | const char* endofname(const char *name) FAST_FUNC; | 425 | const char* endofname(const char *name) FAST_FUNC; |
426 | char *is_prefixed_with(const char *string, const char *key) FAST_FUNC; | 426 | char *is_prefixed_with(const char *string, const char *key) FAST_FUNC; |
427 | char *is_suffixed_with(const char *string, const char *key) FAST_FUNC; | ||
427 | 428 | ||
428 | int ndelay_on(int fd) FAST_FUNC; | 429 | int ndelay_on(int fd) FAST_FUNC; |
429 | int ndelay_off(int fd) FAST_FUNC; | 430 | int ndelay_off(int fd) FAST_FUNC; |
@@ -572,6 +573,11 @@ void xlisten(int s, int backlog) FAST_FUNC; | |||
572 | void xconnect(int s, const struct sockaddr *saddr, socklen_t addrlen) FAST_FUNC; | 573 | void xconnect(int s, const struct sockaddr *saddr, socklen_t addrlen) FAST_FUNC; |
573 | ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, | 574 | ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, |
574 | socklen_t tolen) FAST_FUNC; | 575 | socklen_t tolen) FAST_FUNC; |
576 | |||
577 | int setsockopt_int(int fd, int level, int optname, int optval) FAST_FUNC; | ||
578 | int setsockopt_1(int fd, int level, int optname) FAST_FUNC; | ||
579 | int setsockopt_SOL_SOCKET_int(int fd, int optname, int optval) FAST_FUNC; | ||
580 | int setsockopt_SOL_SOCKET_1(int fd, int optname) FAST_FUNC; | ||
575 | /* SO_REUSEADDR allows a server to rebind to an address that is already | 581 | /* SO_REUSEADDR allows a server to rebind to an address that is already |
576 | * "in use" by old connections to e.g. previous server instance which is | 582 | * "in use" by old connections to e.g. previous server instance which is |
577 | * killed or crashed. Without it bind will fail until all such connections | 583 | * killed or crashed. Without it bind will fail until all such connections |
@@ -579,6 +585,7 @@ ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, | |||
579 | * regardless of SO_REUSEADDR (unlike some other flavors of Unix). | 585 | * regardless of SO_REUSEADDR (unlike some other flavors of Unix). |
580 | * Turn it on before you call bind(). */ | 586 | * Turn it on before you call bind(). */ |
581 | void setsockopt_reuseaddr(int fd) FAST_FUNC; /* On Linux this never fails. */ | 587 | void setsockopt_reuseaddr(int fd) FAST_FUNC; /* On Linux this never fails. */ |
588 | int setsockopt_keepalive(int fd) FAST_FUNC; | ||
582 | int setsockopt_broadcast(int fd) FAST_FUNC; | 589 | int setsockopt_broadcast(int fd) FAST_FUNC; |
583 | int setsockopt_bindtodevice(int fd, const char *iface) FAST_FUNC; | 590 | int setsockopt_bindtodevice(int fd, const char *iface) FAST_FUNC; |
584 | /* NB: returns port in host byte order */ | 591 | /* NB: returns port in host byte order */ |
@@ -696,6 +703,7 @@ int bb_putchar(int ch) FAST_FUNC; | |||
696 | /* Note: does not use stdio, writes to fd 2 directly */ | 703 | /* Note: does not use stdio, writes to fd 2 directly */ |
697 | int bb_putchar_stderr(char ch) FAST_FUNC; | 704 | int bb_putchar_stderr(char ch) FAST_FUNC; |
698 | char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC; | 705 | char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC; |
706 | char *auto_string(char *str) FAST_FUNC; | ||
699 | // gcc-4.1.1 still isn't good enough at optimizing it | 707 | // gcc-4.1.1 still isn't good enough at optimizing it |
700 | // (+200 bytes compared to macro) | 708 | // (+200 bytes compared to macro) |
701 | //static ALWAYS_INLINE | 709 | //static ALWAYS_INLINE |
@@ -1134,9 +1142,8 @@ enum { | |||
1134 | extern const char *msg_eol; | 1142 | extern const char *msg_eol; |
1135 | extern smallint syslog_level; | 1143 | extern smallint syslog_level; |
1136 | extern smallint logmode; | 1144 | extern smallint logmode; |
1137 | extern int die_sleep; | ||
1138 | extern uint8_t xfunc_error_retval; | 1145 | extern uint8_t xfunc_error_retval; |
1139 | extern jmp_buf die_jmp; | 1146 | extern void (*die_func)(void); |
1140 | extern void xfunc_die(void) NORETURN FAST_FUNC; | 1147 | extern void xfunc_die(void) NORETURN FAST_FUNC; |
1141 | extern void bb_show_usage(void) NORETURN FAST_FUNC; | 1148 | extern void bb_show_usage(void) NORETURN FAST_FUNC; |
1142 | extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; | 1149 | extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; |
@@ -1258,7 +1265,8 @@ char *bb_ask_stdin(const char * prompt) FAST_FUNC; | |||
1258 | char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC; | 1265 | char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC; |
1259 | int bb_ask_confirmation(void) FAST_FUNC; | 1266 | int bb_ask_confirmation(void) FAST_FUNC; |
1260 | 1267 | ||
1261 | int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC; | 1268 | /* Returns -1 if input is invalid. current_mode is a base for e.g. "u+rw" */ |
1269 | int bb_parse_mode(const char* s, unsigned cur_mode) FAST_FUNC; | ||
1262 | 1270 | ||
1263 | /* | 1271 | /* |
1264 | * Config file parser | 1272 | * Config file parser |
@@ -1832,7 +1840,7 @@ extern const char bb_PATH_root_path[] ALIGN1; /* "PATH=/sbin:/usr/sbin:/bin:/usr | |||
1832 | #define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin")) | 1840 | #define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin")) |
1833 | 1841 | ||
1834 | extern const int const_int_0; | 1842 | extern const int const_int_0; |
1835 | extern const int const_int_1; | 1843 | //extern const int const_int_1; |
1836 | 1844 | ||
1837 | 1845 | ||
1838 | /* Providing hard guarantee on minimum size (think of BUFSIZ == 128) */ | 1846 | /* Providing hard guarantee on minimum size (think of BUFSIZ == 128) */ |
@@ -1918,6 +1926,7 @@ extern const char bb_default_login_shell[] ALIGN1; | |||
1918 | 1926 | ||
1919 | 1927 | ||
1920 | #define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0]))) | 1928 | #define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0]))) |
1929 | #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) | ||
1921 | 1930 | ||
1922 | 1931 | ||
1923 | /* We redefine ctype macros. Unicode-correct handling of char types | 1932 | /* We redefine ctype macros. Unicode-correct handling of char types |
@@ -2008,7 +2017,6 @@ static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a) | |||
2008 | typedef void (*bbunit_testfunc)(void); | 2017 | typedef void (*bbunit_testfunc)(void); |
2009 | 2018 | ||
2010 | struct bbunit_listelem { | 2019 | struct bbunit_listelem { |
2011 | struct bbunit_listelem* next; | ||
2012 | const char* name; | 2020 | const char* name; |
2013 | bbunit_testfunc testfunc; | 2021 | bbunit_testfunc testfunc; |
2014 | }; | 2022 | }; |
diff --git a/init/init.c b/init/init.c index b2fe85635..80c5d0f74 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -1015,6 +1015,11 @@ void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) | |||
1015 | } | 1015 | } |
1016 | #endif | 1016 | #endif |
1017 | 1017 | ||
1018 | static void sleep_much(void) | ||
1019 | { | ||
1020 | sleep(30 * 24*60*60); | ||
1021 | } | ||
1022 | |||
1018 | int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1023 | int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
1019 | int init_main(int argc UNUSED_PARAM, char **argv) | 1024 | int init_main(int argc UNUSED_PARAM, char **argv) |
1020 | { | 1025 | { |
@@ -1051,12 +1056,12 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
1051 | 1056 | ||
1052 | /* If, say, xmalloc would ever die, we don't want to oops kernel | 1057 | /* If, say, xmalloc would ever die, we don't want to oops kernel |
1053 | * by exiting. | 1058 | * by exiting. |
1054 | * NB: we set die_sleep *after* PID 1 check and bb_show_usage. | 1059 | * NB: we set die_func *after* PID 1 check and bb_show_usage. |
1055 | * Otherwise, for example, "init u" ("please rexec yourself" | 1060 | * Otherwise, for example, "init u" ("please rexec yourself" |
1056 | * command for sysvinit) will show help text (which isn't too bad), | 1061 | * command for sysvinit) will show help text (which isn't too bad), |
1057 | * *and sleep forever* (which is bad!) | 1062 | * *and sleep forever* (which is bad!) |
1058 | */ | 1063 | */ |
1059 | die_sleep = 30 * 24*60*60; | 1064 | die_func = sleep_much; |
1060 | 1065 | ||
1061 | /* Figure out where the default console should be */ | 1066 | /* Figure out where the default console should be */ |
1062 | console_init(); | 1067 | console_init(); |
diff --git a/libbb/auto_string.c b/libbb/auto_string.c new file mode 100644 index 000000000..ae940069a --- /dev/null +++ b/libbb/auto_string.c | |||
@@ -0,0 +1,23 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) 2015 Denys Vlasenko | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | //kbuild:lib-y += auto_string.o | ||
10 | |||
11 | #include "libbb.h" | ||
12 | |||
13 | char* FAST_FUNC auto_string(char *str) | ||
14 | { | ||
15 | static char *saved[4]; | ||
16 | static uint8_t cur_saved; /* = 0 */ | ||
17 | |||
18 | free(saved[cur_saved]); | ||
19 | saved[cur_saved] = str; | ||
20 | cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1); | ||
21 | |||
22 | return str; | ||
23 | } | ||
diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c index 1927ba9e9..c2580b9eb 100644 --- a/libbb/bb_askpass.c +++ b/libbb/bb_askpass.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Ask for a password | 3 | * Ask for a password |
4 | * I use a static buffer in this function. Plan accordingly. | ||
5 | * | 4 | * |
6 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> | 5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
7 | * | 6 | * |
@@ -23,8 +22,8 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) | |||
23 | { | 22 | { |
24 | /* Was static char[BIGNUM] */ | 23 | /* Was static char[BIGNUM] */ |
25 | enum { sizeof_passwd = 128 }; | 24 | enum { sizeof_passwd = 128 }; |
26 | static char *passwd; | ||
27 | 25 | ||
26 | char *passwd; | ||
28 | char *ret; | 27 | char *ret; |
29 | int i; | 28 | int i; |
30 | struct sigaction sa, oldsa; | 29 | struct sigaction sa, oldsa; |
@@ -62,8 +61,7 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) | |||
62 | alarm(timeout); | 61 | alarm(timeout); |
63 | } | 62 | } |
64 | 63 | ||
65 | if (!passwd) | 64 | passwd = auto_string(xmalloc(sizeof_passwd)); |
66 | passwd = xmalloc(sizeof_passwd); | ||
67 | ret = passwd; | 65 | ret = passwd; |
68 | i = 0; | 66 | i = 0; |
69 | while (1) { | 67 | while (1) { |
diff --git a/libbb/bbunit.c b/libbb/bbunit.c index 4c692d59f..db67b1081 100644 --- a/libbb/bbunit.c +++ b/libbb/bbunit.c | |||
@@ -17,8 +17,6 @@ | |||
17 | 17 | ||
18 | #include "libbb.h" | 18 | #include "libbb.h" |
19 | 19 | ||
20 | #define WANT_TIMING 0 | ||
21 | |||
22 | static llist_t *tests = NULL; | 20 | static llist_t *tests = NULL; |
23 | static unsigned tests_registered = 0; | 21 | static unsigned tests_registered = 0; |
24 | static int test_retval; | 22 | static int test_retval; |
@@ -34,57 +32,34 @@ void bbunit_settestfailed(void) | |||
34 | test_retval = -1; | 32 | test_retval = -1; |
35 | } | 33 | } |
36 | 34 | ||
37 | #if WANT_TIMING | ||
38 | static void timeval_diff(struct timeval* res, | ||
39 | const struct timeval* x, | ||
40 | const struct timeval* y) | ||
41 | { | ||
42 | long udiff = x->tv_usec - y->tv_usec; | ||
43 | |||
44 | res->tv_sec = x->tv_sec - y->tv_sec - (udiff < 0); | ||
45 | res->tv_usec = (udiff >= 0 ? udiff : udiff + 1000000); | ||
46 | } | ||
47 | #endif | ||
48 | |||
49 | int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) MAIN_EXTERNALLY_VISIBLE; | 35 | int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) MAIN_EXTERNALLY_VISIBLE; |
50 | int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | 36 | int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) |
51 | { | 37 | { |
52 | unsigned tests_run = 0; | 38 | unsigned tests_run = 0; |
53 | unsigned tests_failed = 0; | 39 | unsigned tests_failed = 0; |
54 | #if WANT_TIMING | ||
55 | struct timeval begin; | ||
56 | struct timeval end; | ||
57 | struct timeval time_spent; | ||
58 | gettimeofday(&begin, NULL); | ||
59 | #endif | ||
60 | 40 | ||
61 | bb_error_msg("Running %d test(s)...", tests_registered); | 41 | bb_error_msg("Running %d test(s)...", tests_registered); |
62 | for (;;) { | 42 | for (;;) { |
63 | struct bbunit_listelem* el = llist_pop(&tests); | 43 | struct bbunit_listelem* el = llist_pop(&tests); |
64 | if (!el) | 44 | if (!el) |
65 | break; | 45 | break; |
46 | |||
66 | bb_error_msg("Case: [%s]", el->name); | 47 | bb_error_msg("Case: [%s]", el->name); |
67 | test_retval = 0; | 48 | test_retval = 0; |
68 | el->testfunc(); | 49 | el->testfunc(); |
50 | |||
69 | if (test_retval < 0) { | 51 | if (test_retval < 0) { |
70 | bb_error_msg("[ERROR] [%s]: TEST FAILED", el->name); | 52 | bb_error_msg("[ERROR] [%s]: TEST FAILED", el->name); |
71 | tests_failed++; | 53 | tests_failed++; |
72 | } | 54 | } |
73 | tests_run++; | 55 | tests_run++; |
74 | el = el->next; | ||
75 | } | 56 | } |
76 | 57 | ||
77 | #if WANT_TIMING | ||
78 | gettimeofday(&end, NULL); | ||
79 | timeval_diff(&time_spent, &end, &begin); | ||
80 | bb_error_msg("Elapsed time %u.%06u seconds", | ||
81 | (int)time_spent.tv_sec, | ||
82 | (int)time_spent.tv_usec); | ||
83 | #endif | ||
84 | if (tests_failed > 0) { | 58 | if (tests_failed > 0) { |
85 | bb_error_msg("[ERROR] %u test(s) FAILED", tests_failed); | 59 | bb_error_msg("[ERROR] %u test(s) FAILED", tests_failed); |
86 | return EXIT_FAILURE; | 60 | return EXIT_FAILURE; |
87 | } | 61 | } |
62 | |||
88 | bb_error_msg("All tests passed"); | 63 | bb_error_msg("All tests passed"); |
89 | return EXIT_SUCCESS; | 64 | return EXIT_SUCCESS; |
90 | } | 65 | } |
diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c index e24815a03..2f51237a3 100644 --- a/libbb/compare_string_array.c +++ b/libbb/compare_string_array.c | |||
@@ -5,6 +5,11 @@ | |||
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | 7 | ||
8 | /* | ||
9 | * Return NULL if string is not prefixed with key. Return pointer to the | ||
10 | * first character in string after the prefix key. If key is an empty string, | ||
11 | * return pointer to the beginning of string. | ||
12 | */ | ||
8 | char* FAST_FUNC is_prefixed_with(const char *string, const char *key) | 13 | char* FAST_FUNC is_prefixed_with(const char *string, const char *key) |
9 | { | 14 | { |
10 | #if 0 /* Two passes over key - probably slower */ | 15 | #if 0 /* Two passes over key - probably slower */ |
@@ -23,6 +28,26 @@ char* FAST_FUNC is_prefixed_with(const char *string, const char *key) | |||
23 | #endif | 28 | #endif |
24 | } | 29 | } |
25 | 30 | ||
31 | /* | ||
32 | * Return NULL if string is not suffixed with key. Return pointer to the | ||
33 | * beginning of prefix key in string. If key is an empty string return pointer | ||
34 | * to the end of string. | ||
35 | */ | ||
36 | char* FAST_FUNC is_suffixed_with(const char *string, const char *key) | ||
37 | { | ||
38 | size_t key_len = strlen(key); | ||
39 | ssize_t len_diff = strlen(string) - key_len; | ||
40 | |||
41 | if (len_diff >= 0) { | ||
42 | string += len_diff; | ||
43 | if (strcmp(string, key) == 0) { | ||
44 | return (char*)string; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | return NULL; | ||
49 | } | ||
50 | |||
26 | /* returns the array index of the string */ | 51 | /* returns the array index of the string */ |
27 | /* (index of first match is returned, or -1) */ | 52 | /* (index of first match is returned, or -1) */ |
28 | int FAST_FUNC index_in_str_array(const char *const string_array[], const char *key) | 53 | int FAST_FUNC index_in_str_array(const char *const string_array[], const char *key) |
@@ -110,3 +135,37 @@ smallint FAST_FUNC yesno(const char *str) | |||
110 | return ret / 3; | 135 | return ret / 3; |
111 | } | 136 | } |
112 | #endif | 137 | #endif |
138 | |||
139 | #if ENABLE_UNIT_TEST | ||
140 | |||
141 | BBUNIT_DEFINE_TEST(is_prefixed_with) | ||
142 | { | ||
143 | BBUNIT_ASSERT_STREQ(" bar", is_prefixed_with("foo bar", "foo")); | ||
144 | BBUNIT_ASSERT_STREQ("bar", is_prefixed_with("foo bar", "foo ")); | ||
145 | BBUNIT_ASSERT_STREQ("", is_prefixed_with("foo", "foo")); | ||
146 | BBUNIT_ASSERT_STREQ("foo", is_prefixed_with("foo", "")); | ||
147 | BBUNIT_ASSERT_STREQ("", is_prefixed_with("", "")); | ||
148 | |||
149 | BBUNIT_ASSERT_NULL(is_prefixed_with("foo", "bar foo")); | ||
150 | BBUNIT_ASSERT_NULL(is_prefixed_with("foo foo", "bar")); | ||
151 | BBUNIT_ASSERT_NULL(is_prefixed_with("", "foo")); | ||
152 | |||
153 | BBUNIT_ENDTEST; | ||
154 | } | ||
155 | |||
156 | BBUNIT_DEFINE_TEST(is_suffixed_with) | ||
157 | { | ||
158 | BBUNIT_ASSERT_STREQ("bar", is_suffixed_with("foo bar", "bar")); | ||
159 | BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("foo", "foo")); | ||
160 | BBUNIT_ASSERT_STREQ("", is_suffixed_with("foo", "")); | ||
161 | BBUNIT_ASSERT_STREQ("", is_suffixed_with("", "")); | ||
162 | BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("barfoofoo", "foo")); | ||
163 | |||
164 | BBUNIT_ASSERT_NULL(is_suffixed_with("foo", "bar foo")); | ||
165 | BBUNIT_ASSERT_NULL(is_suffixed_with("foo foo", "bar")); | ||
166 | BBUNIT_ASSERT_NULL(is_suffixed_with("", "foo")); | ||
167 | |||
168 | BBUNIT_ENDTEST; | ||
169 | } | ||
170 | |||
171 | #endif /* ENABLE_UNIT_TEST */ | ||
diff --git a/libbb/fflush_stdout_and_exit.c b/libbb/fflush_stdout_and_exit.c index 9ad5dbf96..b4bed865f 100644 --- a/libbb/fflush_stdout_and_exit.c +++ b/libbb/fflush_stdout_and_exit.c | |||
@@ -15,15 +15,10 @@ | |||
15 | 15 | ||
16 | void FAST_FUNC fflush_stdout_and_exit(int retval) | 16 | void FAST_FUNC fflush_stdout_and_exit(int retval) |
17 | { | 17 | { |
18 | xfunc_error_retval = retval; | ||
18 | if (fflush(stdout)) | 19 | if (fflush(stdout)) |
19 | bb_perror_msg_and_die(bb_msg_standard_output); | 20 | bb_perror_msg_and_die(bb_msg_standard_output); |
20 | 21 | /* In case we are in NOFORK applet. Do not exit() directly, | |
21 | if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) { | 22 | * but use xfunc_die() */ |
22 | /* We are in NOFORK applet. Do not exit() directly, | 23 | xfunc_die(); |
23 | * but use xfunc_die() */ | ||
24 | xfunc_error_retval = retval; | ||
25 | xfunc_die(); | ||
26 | } | ||
27 | |||
28 | exit(retval); | ||
29 | } | 24 | } |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index 1f63ccdee..d08c6b2f7 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -137,7 +137,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
137 | #if MD5_SMALL > 0 | 137 | #if MD5_SMALL > 0 |
138 | /* Before we start, one word to the strange constants. | 138 | /* Before we start, one word to the strange constants. |
139 | They are defined in RFC 1321 as | 139 | They are defined in RFC 1321 as |
140 | T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 | 140 | T[i] = (int)(2^32 * fabs(sin(i))), i=1..64 |
141 | */ | 141 | */ |
142 | static const uint32_t C_array[] = { | 142 | static const uint32_t C_array[] = { |
143 | /* round 1 */ | 143 | /* round 1 */ |
@@ -213,7 +213,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
213 | case 2: | 213 | case 2: |
214 | temp += FH(B, C, D); | 214 | temp += FH(B, C, D); |
215 | break; | 215 | break; |
216 | case 3: | 216 | default: /* case 3 */ |
217 | temp += FI(B, C, D); | 217 | temp += FI(B, C, D); |
218 | } | 218 | } |
219 | temp += words[(int) (*pp++)] + *pc++; | 219 | temp += words[(int) (*pp++)] + *pc++; |
@@ -277,10 +277,6 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
277 | 277 | ||
278 | #else /* MD5_SMALL == 0 or 1 */ | 278 | #else /* MD5_SMALL == 0 or 1 */ |
279 | 279 | ||
280 | uint32_t A_save = A; | ||
281 | uint32_t B_save = B; | ||
282 | uint32_t C_save = C; | ||
283 | uint32_t D_save = D; | ||
284 | # if MD5_SMALL == 1 | 280 | # if MD5_SMALL == 1 |
285 | const uint32_t *pc; | 281 | const uint32_t *pc; |
286 | const char *pp; | 282 | const char *pp; |
@@ -425,10 +421,10 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
425 | # undef OP | 421 | # undef OP |
426 | # endif | 422 | # endif |
427 | /* Add checksum to the starting values */ | 423 | /* Add checksum to the starting values */ |
428 | ctx->hash[0] = A_save + A; | 424 | ctx->hash[0] += A; |
429 | ctx->hash[1] = B_save + B; | 425 | ctx->hash[1] += B; |
430 | ctx->hash[2] = C_save + C; | 426 | ctx->hash[2] += C; |
431 | ctx->hash[3] = D_save + D; | 427 | ctx->hash[3] += D; |
432 | #endif | 428 | #endif |
433 | } | 429 | } |
434 | #undef FF | 430 | #undef FF |
diff --git a/libbb/human_readable.c b/libbb/human_readable.c index 0b2eb777e..5c7fc076f 100644 --- a/libbb/human_readable.c +++ b/libbb/human_readable.c | |||
@@ -37,8 +37,6 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val, | |||
37 | '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' | 37 | '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static char *str; | ||
41 | |||
42 | unsigned frac; /* 0..9 - the fractional digit */ | 40 | unsigned frac; /* 0..9 - the fractional digit */ |
43 | const char *u; | 41 | const char *u; |
44 | const char *fmt; | 42 | const char *fmt; |
@@ -81,12 +79,7 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val, | |||
81 | #endif | 79 | #endif |
82 | } | 80 | } |
83 | 81 | ||
84 | if (!str) { | 82 | return auto_string(xasprintf(fmt, val, frac, *u)); |
85 | /* sufficient for any width of val */ | ||
86 | str = xmalloc(sizeof(val)*3 + 2 + 3); | ||
87 | } | ||
88 | sprintf(str, fmt, val, frac, *u); | ||
89 | return str; | ||
90 | } | 83 | } |
91 | 84 | ||
92 | 85 | ||
diff --git a/libbb/messages.c b/libbb/messages.c index ef42b30d7..108cb0285 100644 --- a/libbb/messages.c +++ b/libbb/messages.c | |||
@@ -45,7 +45,7 @@ const char bb_PATH_root_path[] ALIGN1 = | |||
45 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH; | 45 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH; |
46 | 46 | ||
47 | 47 | ||
48 | const int const_int_1 = 1; | 48 | //const int const_int_1 = 1; |
49 | /* explicitly = 0, otherwise gcc may make it a common variable | 49 | /* explicitly = 0, otherwise gcc may make it a common variable |
50 | * and it will end up in bss */ | 50 | * and it will end up in bss */ |
51 | const int const_int_0 = 0; | 51 | const int const_int_0 = 0; |
diff --git a/libbb/parse_mode.c b/libbb/parse_mode.c index 5a4e1c579..bddd39bca 100644 --- a/libbb/parse_mode.c +++ b/libbb/parse_mode.c | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) | 16 | #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) |
17 | 17 | ||
18 | int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) | 18 | int FAST_FUNC bb_parse_mode(const char *s, unsigned current_mode) |
19 | { | 19 | { |
20 | static const mode_t who_mask[] = { | 20 | static const mode_t who_mask[] = { |
21 | S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */ | 21 | S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */ |
@@ -46,13 +46,12 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) | |||
46 | 46 | ||
47 | tmp = strtoul(s, &e, 8); | 47 | tmp = strtoul(s, &e, 8); |
48 | if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ | 48 | if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ |
49 | return 0; | 49 | return -1; |
50 | } | 50 | } |
51 | *current_mode = tmp; | 51 | return tmp; |
52 | return 1; | ||
53 | } | 52 | } |
54 | 53 | ||
55 | new_mode = *current_mode; | 54 | new_mode = current_mode; |
56 | 55 | ||
57 | /* Note: we allow empty clauses, and hence empty modes. | 56 | /* Note: we allow empty clauses, and hence empty modes. |
58 | * We treat an empty mode as no change to perms. */ | 57 | * We treat an empty mode as no change to perms. */ |
@@ -71,7 +70,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) | |||
71 | if (*p == *s) { | 70 | if (*p == *s) { |
72 | wholist |= who_mask[(int)(p-who_chars)]; | 71 | wholist |= who_mask[(int)(p-who_chars)]; |
73 | if (!*++s) { | 72 | if (!*++s) { |
74 | return 0; | 73 | return -1; |
75 | } | 74 | } |
76 | goto WHO_LIST; | 75 | goto WHO_LIST; |
77 | } | 76 | } |
@@ -80,7 +79,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) | |||
80 | do { /* Process action list. */ | 79 | do { /* Process action list. */ |
81 | if ((*s != '+') && (*s != '-')) { | 80 | if ((*s != '+') && (*s != '-')) { |
82 | if (*s != '=') { | 81 | if (*s != '=') { |
83 | return 0; | 82 | return -1; |
84 | } | 83 | } |
85 | /* Since op is '=', clear all bits corresponding to the | 84 | /* Since op is '=', clear all bits corresponding to the |
86 | * wholist, or all file bits if wholist is empty. */ | 85 | * wholist, or all file bits if wholist is empty. */ |
@@ -145,6 +144,5 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) | |||
145 | } while (*s && (*s != ',')); | 144 | } while (*s && (*s != ',')); |
146 | } | 145 | } |
147 | 146 | ||
148 | *current_mode = new_mode; | 147 | return new_mode; |
149 | return 1; | ||
150 | } | 148 | } |
diff --git a/libbb/printable_string.c b/libbb/printable_string.c index 3e768d0b9..e638a178e 100644 --- a/libbb/printable_string.c +++ b/libbb/printable_string.c | |||
@@ -11,9 +11,6 @@ | |||
11 | 11 | ||
12 | const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str) | 12 | const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str) |
13 | { | 13 | { |
14 | static char *saved[4]; | ||
15 | static unsigned cur_saved; /* = 0 */ | ||
16 | |||
17 | char *dst; | 14 | char *dst; |
18 | const char *s; | 15 | const char *s; |
19 | 16 | ||
@@ -56,10 +53,5 @@ const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str) | |||
56 | } | 53 | } |
57 | } | 54 | } |
58 | #endif | 55 | #endif |
59 | 56 | return auto_string(dst); | |
60 | free(saved[cur_saved]); | ||
61 | saved[cur_saved] = dst; | ||
62 | cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1); | ||
63 | |||
64 | return dst; | ||
65 | } | 57 | } |
diff --git a/libbb/procps.c b/libbb/procps.c index 32dae43e3..5a4ea59d0 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -284,7 +284,6 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | |||
284 | } | 284 | } |
285 | #endif | 285 | #endif |
286 | 286 | ||
287 | void BUG_comm_size(void); | ||
288 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | 287 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) |
289 | { | 288 | { |
290 | if (!sp) | 289 | if (!sp) |
@@ -386,8 +385,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
386 | /*if (!cp || cp[1] != ' ') | 385 | /*if (!cp || cp[1] != ' ') |
387 | continue;*/ | 386 | continue;*/ |
388 | cp[0] = '\0'; | 387 | cp[0] = '\0'; |
389 | if (sizeof(sp->comm) < 16) | 388 | BUILD_BUG_ON(sizeof(sp->comm) < 16); |
390 | BUG_comm_size(); | ||
391 | comm1 = strchr(buf, '('); | 389 | comm1 = strchr(buf, '('); |
392 | /*if (comm1)*/ | 390 | /*if (comm1)*/ |
393 | safe_strncpy(sp->comm, comm1 + 1, sizeof(sp->comm)); | 391 | safe_strncpy(sp->comm, comm1 + 1, sizeof(sp->comm)); |
diff --git a/libbb/udp_io.c b/libbb/udp_io.c index 7985a9723..a32af9bd2 100644 --- a/libbb/udp_io.c +++ b/libbb/udp_io.c | |||
@@ -16,10 +16,10 @@ void FAST_FUNC | |||
16 | socket_want_pktinfo(int fd UNUSED_PARAM) | 16 | socket_want_pktinfo(int fd UNUSED_PARAM) |
17 | { | 17 | { |
18 | #ifdef IP_PKTINFO | 18 | #ifdef IP_PKTINFO |
19 | setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); | 19 | setsockopt_1(fd, IPPROTO_IP, IP_PKTINFO); |
20 | #endif | 20 | #endif |
21 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) | 21 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) |
22 | setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int)); | 22 | setsockopt_1(fd, IPPROTO_IPV6, IPV6_PKTINFO); |
23 | #endif | 23 | #endif |
24 | } | 24 | } |
25 | 25 | ||
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index de4d14fce..2d3204507 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -71,28 +71,44 @@ pid_t FAST_FUNC xspawn(char **argv) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | #if ENABLE_FEATURE_PREFER_APPLETS | 73 | #if ENABLE_FEATURE_PREFER_APPLETS |
74 | static jmp_buf die_jmp; | ||
75 | static void jump(void) | ||
76 | { | ||
77 | /* Special case. We arrive here if NOFORK applet | ||
78 | * calls xfunc, which then decides to die. | ||
79 | * We don't die, but jump instead back to caller. | ||
80 | * NOFORK applets still cannot carelessly call xfuncs: | ||
81 | * p = xmalloc(10); | ||
82 | * q = xmalloc(10); // BUG! if this dies, we leak p! | ||
83 | */ | ||
84 | /* | 0x100 allows to pass zero exitcode (longjmp can't pass 0). | ||
85 | * This works because exitcodes are bytes, | ||
86 | * run_nofork_applet() ensures that by "& 0xff" */ | ||
87 | longjmp(die_jmp, xfunc_error_retval | 0x100); | ||
88 | } | ||
89 | |||
74 | struct nofork_save_area { | 90 | struct nofork_save_area { |
75 | jmp_buf die_jmp; | 91 | jmp_buf die_jmp; |
92 | void (*die_func)(void); | ||
76 | const char *applet_name; | 93 | const char *applet_name; |
77 | uint32_t option_mask32; | 94 | uint32_t option_mask32; |
78 | int die_sleep; | ||
79 | uint8_t xfunc_error_retval; | 95 | uint8_t xfunc_error_retval; |
80 | }; | 96 | }; |
81 | static void save_nofork_data(struct nofork_save_area *save) | 97 | static void save_nofork_data(struct nofork_save_area *save) |
82 | { | 98 | { |
83 | memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); | 99 | memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); |
100 | save->die_func = die_func; | ||
84 | save->applet_name = applet_name; | 101 | save->applet_name = applet_name; |
85 | save->xfunc_error_retval = xfunc_error_retval; | ||
86 | save->option_mask32 = option_mask32; | 102 | save->option_mask32 = option_mask32; |
87 | save->die_sleep = die_sleep; | 103 | save->xfunc_error_retval = xfunc_error_retval; |
88 | } | 104 | } |
89 | static void restore_nofork_data(struct nofork_save_area *save) | 105 | static void restore_nofork_data(struct nofork_save_area *save) |
90 | { | 106 | { |
91 | memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); | 107 | memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); |
108 | die_func = save->die_func; | ||
92 | applet_name = save->applet_name; | 109 | applet_name = save->applet_name; |
93 | xfunc_error_retval = save->xfunc_error_retval; | ||
94 | option_mask32 = save->option_mask32; | 110 | option_mask32 = save->option_mask32; |
95 | die_sleep = save->die_sleep; | 111 | xfunc_error_retval = save->xfunc_error_retval; |
96 | } | 112 | } |
97 | 113 | ||
98 | int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | 114 | int FAST_FUNC run_nofork_applet(int applet_no, char **argv) |
@@ -135,11 +151,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
135 | while (argv[argc]) | 151 | while (argv[argc]) |
136 | argc++; | 152 | argc++; |
137 | 153 | ||
138 | /* Special flag for xfunc_die(). If xfunc will "die" | 154 | /* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */ |
139 | * in NOFORK applet, xfunc_die() sees negative | 155 | die_func = jump; |
140 | * die_sleep and longjmp here instead. */ | ||
141 | die_sleep = -1; | ||
142 | |||
143 | rc = setjmp(die_jmp); | 156 | rc = setjmp(die_jmp); |
144 | if (!rc) { | 157 | if (!rc) { |
145 | /* Some callers (xargs) | 158 | /* Some callers (xargs) |
@@ -148,10 +161,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
148 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | 161 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); |
149 | /* Finally we can call NOFORK applet's main() */ | 162 | /* Finally we can call NOFORK applet's main() */ |
150 | rc = applet_main[applet_no](argc, tmp_argv); | 163 | rc = applet_main[applet_no](argc, tmp_argv); |
151 | } else { /* xfunc died in NOFORK applet */ | 164 | } else { |
152 | /* in case they meant to return 0... */ | 165 | /* xfunc died in NOFORK applet */ |
153 | if (rc == -2222) | ||
154 | rc = 0; | ||
155 | } | 166 | } |
156 | 167 | ||
157 | /* Restoring some globals */ | 168 | /* Restoring some globals */ |
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 442482a8b..0a4d8f128 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -14,13 +14,34 @@ | |||
14 | #include <sys/un.h> | 14 | #include <sys/un.h> |
15 | #include "libbb.h" | 15 | #include "libbb.h" |
16 | 16 | ||
17 | int FAST_FUNC setsockopt_int(int fd, int level, int optname, int optval) | ||
18 | { | ||
19 | return setsockopt(fd, level, optname, &optval, sizeof(int)); | ||
20 | } | ||
21 | int FAST_FUNC setsockopt_1(int fd, int level, int optname) | ||
22 | { | ||
23 | return setsockopt_int(fd, level, optname, 1); | ||
24 | } | ||
25 | int FAST_FUNC setsockopt_SOL_SOCKET_int(int fd, int optname, int optval) | ||
26 | { | ||
27 | return setsockopt_int(fd, SOL_SOCKET, optname, optval); | ||
28 | } | ||
29 | int FAST_FUNC setsockopt_SOL_SOCKET_1(int fd, int optname) | ||
30 | { | ||
31 | return setsockopt_SOL_SOCKET_int(fd, optname, 1); | ||
32 | } | ||
33 | |||
17 | void FAST_FUNC setsockopt_reuseaddr(int fd) | 34 | void FAST_FUNC setsockopt_reuseaddr(int fd) |
18 | { | 35 | { |
19 | setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_1, sizeof(const_int_1)); | 36 | setsockopt_SOL_SOCKET_1(fd, SO_REUSEADDR); |
20 | } | 37 | } |
21 | int FAST_FUNC setsockopt_broadcast(int fd) | 38 | int FAST_FUNC setsockopt_broadcast(int fd) |
22 | { | 39 | { |
23 | return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1)); | 40 | return setsockopt_SOL_SOCKET_1(fd, SO_BROADCAST); |
41 | } | ||
42 | int FAST_FUNC setsockopt_keepalive(int fd) | ||
43 | { | ||
44 | return setsockopt_SOL_SOCKET_1(fd, SO_KEEPALIVE); | ||
24 | } | 45 | } |
25 | 46 | ||
26 | #ifdef SO_BINDTODEVICE | 47 | #ifdef SO_BINDTODEVICE |
diff --git a/libbb/xfunc_die.c b/libbb/xfunc_die.c index 204e5e49d..73f7998e5 100644 --- a/libbb/xfunc_die.c +++ b/libbb/xfunc_die.c | |||
@@ -7,34 +7,16 @@ | |||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | 7 | * Licensed under GPLv2, see file LICENSE in this source tree. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* Keeping it separate allows to NOT suck in stdio for VERY small applets. | 10 | /* Keeping it separate allows to NOT pull in stdio for VERY small applets. |
11 | * Try building busybox with only "true" enabled... */ | 11 | * Try building busybox with only "true" enabled... */ |
12 | 12 | ||
13 | #include "libbb.h" | 13 | #include "libbb.h" |
14 | 14 | ||
15 | int die_sleep; | 15 | void (*die_func)(void); |
16 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH | ||
17 | jmp_buf die_jmp; | ||
18 | #endif | ||
19 | 16 | ||
20 | void FAST_FUNC xfunc_die(void) | 17 | void FAST_FUNC xfunc_die(void) |
21 | { | 18 | { |
22 | if (die_sleep) { | 19 | if (die_func) |
23 | if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) | 20 | die_func(); |
24 | && die_sleep < 0 | ||
25 | ) { | ||
26 | /* Special case. We arrive here if NOFORK applet | ||
27 | * calls xfunc, which then decides to die. | ||
28 | * We don't die, but jump instead back to caller. | ||
29 | * NOFORK applets still cannot carelessly call xfuncs: | ||
30 | * p = xmalloc(10); | ||
31 | * q = xmalloc(10); // BUG! if this dies, we leak p! | ||
32 | */ | ||
33 | /* -2222 means "zero" (longjmp can't pass 0) | ||
34 | * run_nofork_applet() catches -2222. */ | ||
35 | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); | ||
36 | } | ||
37 | sleep(die_sleep); | ||
38 | } | ||
39 | exit(xfunc_error_retval); | 21 | exit(xfunc_error_retval); |
40 | } | 22 | } |
diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index 3886facf0..cefbc8a7e 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c | |||
@@ -16,11 +16,10 @@ | |||
16 | * a) must contain the expected number of fields (as per count of field | 16 | * a) must contain the expected number of fields (as per count of field |
17 | * delimeters ":") or we will complain with a error message. | 17 | * delimeters ":") or we will complain with a error message. |
18 | * b) leading and trailing whitespace in fields is stripped. | 18 | * b) leading and trailing whitespace in fields is stripped. |
19 | * c) some fields are not allowed to be empty (e.g. username, uid/gid, | 19 | * c) some fields are not allowed to be empty (e.g. username, uid/gid), |
20 | * homedir, shell) and in this case NULL is returned and errno is | 20 | * and in this case NULL is returned and errno is set to EINVAL. |
21 | * set to EINVAL. This behaviour could be easily changed by | 21 | * This behaviour could be easily changed by modifying PW_DEF, GR_DEF, |
22 | * modifying PW_DEF, GR_DEF, SP_DEF strings (uppercase | 22 | * SP_DEF strings (uppercase makes a field mandatory). |
23 | * makes a field mandatory). | ||
24 | * d) the string representing uid/gid must be convertible by strtoXX | 23 | * d) the string representing uid/gid must be convertible by strtoXX |
25 | * functions, or errno is set to EINVAL. | 24 | * functions, or errno is set to EINVAL. |
26 | * e) leading and trailing whitespace in group member names is stripped. | 25 | * e) leading and trailing whitespace in group member names is stripped. |
@@ -58,7 +57,7 @@ struct passdb { | |||
58 | * I = uid,gid, l = long maybe empty, m = members, | 57 | * I = uid,gid, l = long maybe empty, m = members, |
59 | * r = reserved | 58 | * r = reserved |
60 | */ | 59 | */ |
61 | #define PW_DEF "SsIIsSS" | 60 | #define PW_DEF "SsIIsss" |
62 | #define GR_DEF "SsIm" | 61 | #define GR_DEF "SsIm" |
63 | #define SP_DEF "Ssllllllr" | 62 | #define SP_DEF "Ssllllllr" |
64 | 63 | ||
@@ -70,8 +69,8 @@ static const struct const_passdb const_pw_db = { | |||
70 | offsetof(struct passwd, pw_uid), /* 2 I */ | 69 | offsetof(struct passwd, pw_uid), /* 2 I */ |
71 | offsetof(struct passwd, pw_gid), /* 3 I */ | 70 | offsetof(struct passwd, pw_gid), /* 3 I */ |
72 | offsetof(struct passwd, pw_gecos), /* 4 s */ | 71 | offsetof(struct passwd, pw_gecos), /* 4 s */ |
73 | offsetof(struct passwd, pw_dir), /* 5 S */ | 72 | offsetof(struct passwd, pw_dir), /* 5 s */ |
74 | offsetof(struct passwd, pw_shell) /* 6 S */ | 73 | offsetof(struct passwd, pw_shell) /* 6 s */ |
75 | }, | 74 | }, |
76 | sizeof(PW_DEF)-1, sizeof(struct passwd) | 75 | sizeof(PW_DEF)-1, sizeof(struct passwd) |
77 | }; | 76 | }; |
@@ -122,7 +121,7 @@ static struct statics *ptr_to_statics; | |||
122 | #if ENABLE_FEATURE_CLEAN_UP | 121 | #if ENABLE_FEATURE_CLEAN_UP |
123 | static void free_static(void) | 122 | static void free_static(void) |
124 | { | 123 | { |
125 | free(S.db[0].malloced); | 124 | free(S.db[0].malloced); |
126 | free(S.db[1].malloced); | 125 | free(S.db[1].malloced); |
127 | # if ENABLE_USE_BB_SHADOW | 126 | # if ENABLE_USE_BB_SHADOW |
128 | free(S.db[2].malloced); | 127 | free(S.db[2].malloced); |
diff --git a/loginutils/add-remove-shell.c b/loginutils/add-remove-shell.c index e492b6e5a..9419ff5e7 100644 --- a/loginutils/add-remove-shell.c +++ b/loginutils/add-remove-shell.c | |||
@@ -100,7 +100,7 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | |||
100 | cpp++; | 100 | cpp++; |
101 | } | 101 | } |
102 | /* copy shell name from old to new file */ | 102 | /* copy shell name from old to new file */ |
103 | printf("%s\n", line); | 103 | puts(line); |
104 | next_line: | 104 | next_line: |
105 | free(line); | 105 | free(line); |
106 | } | 106 | } |
@@ -112,7 +112,7 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | |||
112 | char **cpp = argv; | 112 | char **cpp = argv; |
113 | while (*cpp) { | 113 | while (*cpp) { |
114 | if (*cpp != dont_add) | 114 | if (*cpp != dont_add) |
115 | printf("%s\n", *cpp); | 115 | puts(*cpp); |
116 | cpp++; | 116 | cpp++; |
117 | } | 117 | } |
118 | } | 118 | } |
diff --git a/loginutils/adduser.c b/loginutils/adduser.c index 568a3018e..605e3363f 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c | |||
@@ -20,6 +20,7 @@ | |||
20 | //usage: "\n -D Don't assign a password" | 20 | //usage: "\n -D Don't assign a password" |
21 | //usage: "\n -H Don't create home directory" | 21 | //usage: "\n -H Don't create home directory" |
22 | //usage: "\n -u UID User id" | 22 | //usage: "\n -u UID User id" |
23 | //usage: "\n -k SKEL Skeleton directory (/etc/skel)" | ||
23 | 24 | ||
24 | #include "libbb.h" | 25 | #include "libbb.h" |
25 | 26 | ||
@@ -39,6 +40,7 @@ | |||
39 | #define OPT_SYSTEM_ACCOUNT (1 << 5) | 40 | #define OPT_SYSTEM_ACCOUNT (1 << 5) |
40 | #define OPT_DONT_MAKE_HOME (1 << 6) | 41 | #define OPT_DONT_MAKE_HOME (1 << 6) |
41 | #define OPT_UID (1 << 7) | 42 | #define OPT_UID (1 << 7) |
43 | #define OPT_SKEL (1 << 8) | ||
42 | 44 | ||
43 | /* remix */ | 45 | /* remix */ |
44 | /* recoded such that the uid may be passed in *p */ | 46 | /* recoded such that the uid may be passed in *p */ |
@@ -134,6 +136,7 @@ static const char adduser_longopts[] ALIGN1 = | |||
134 | "system\0" No_argument "S" | 136 | "system\0" No_argument "S" |
135 | "no-create-home\0" No_argument "H" | 137 | "no-create-home\0" No_argument "H" |
136 | "uid\0" Required_argument "u" | 138 | "uid\0" Required_argument "u" |
139 | "skel\0" Required_argument "k" | ||
137 | ; | 140 | ; |
138 | #endif | 141 | #endif |
139 | 142 | ||
@@ -150,6 +153,7 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) | |||
150 | char *p; | 153 | char *p; |
151 | unsigned opts; | 154 | unsigned opts; |
152 | char *uid; | 155 | char *uid; |
156 | const char *skel = "/etc/skel"; | ||
153 | 157 | ||
154 | #if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS | 158 | #if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS |
155 | applet_long_options = adduser_longopts; | 159 | applet_long_options = adduser_longopts; |
@@ -168,7 +172,7 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) | |||
168 | /* at least one and at most two non-option args */ | 172 | /* at least one and at most two non-option args */ |
169 | /* disable interactive passwd for system accounts */ | 173 | /* disable interactive passwd for system accounts */ |
170 | opt_complementary = "-1:?2:SD"; | 174 | opt_complementary = "-1:?2:SD"; |
171 | opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &uid); | 175 | opts = getopt32(argv, "h:g:s:G:DSHu:k:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &uid, &skel); |
172 | if (opts & OPT_UID) | 176 | if (opts & OPT_UID) |
173 | pw.pw_uid = xatou_range(uid, 0, CONFIG_LAST_ID); | 177 | pw.pw_uid = xatou_range(uid, 0, CONFIG_LAST_ID); |
174 | 178 | ||
@@ -250,8 +254,9 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) | |||
250 | NULL | 254 | NULL |
251 | }; | 255 | }; |
252 | /* Be silent on any errors (like: no /etc/skel) */ | 256 | /* Be silent on any errors (like: no /etc/skel) */ |
253 | logmode = LOGMODE_NONE; | 257 | if (!(opts & OPT_SKEL)) |
254 | copy_file("/etc/skel", pw.pw_dir, FILEUTILS_RECUR); | 258 | logmode = LOGMODE_NONE; |
259 | copy_file(skel, pw.pw_dir, FILEUTILS_RECUR); | ||
255 | logmode = LOGMODE_STDIO; | 260 | logmode = LOGMODE_STDIO; |
256 | chown_main(4, (char**)args); | 261 | chown_main(4, (char**)args); |
257 | } | 262 | } |
diff --git a/loginutils/getty.c b/loginutils/getty.c index 174542841..762d5c773 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
@@ -520,6 +520,11 @@ static void alarm_handler(int sig UNUSED_PARAM) | |||
520 | _exit(EXIT_SUCCESS); | 520 | _exit(EXIT_SUCCESS); |
521 | } | 521 | } |
522 | 522 | ||
523 | static void sleep10(void) | ||
524 | { | ||
525 | sleep(10); | ||
526 | } | ||
527 | |||
523 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 528 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
524 | int getty_main(int argc UNUSED_PARAM, char **argv) | 529 | int getty_main(int argc UNUSED_PARAM, char **argv) |
525 | { | 530 | { |
@@ -599,7 +604,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
599 | close(n--); | 604 | close(n--); |
600 | 605 | ||
601 | /* Logging. We want special flavor of error_msg_and_die */ | 606 | /* Logging. We want special flavor of error_msg_and_die */ |
602 | die_sleep = 10; | 607 | die_func = sleep10; |
603 | msg_eol = "\r\n"; | 608 | msg_eol = "\r\n"; |
604 | /* most likely will internally use fd #3 in CLOEXEC mode: */ | 609 | /* most likely will internally use fd #3 in CLOEXEC mode: */ |
605 | openlog(applet_name, LOG_PID, LOG_AUTH); | 610 | openlog(applet_name, LOG_PID, LOG_AUTH); |
diff --git a/loginutils/login.c b/loginutils/login.c index b9d910331..1700cfcb5 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -489,7 +489,8 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
489 | } | 489 | } |
490 | #endif | 490 | #endif |
491 | 491 | ||
492 | motd(); | 492 | if (access(".hushlogin", F_OK) != 0) |
493 | motd(); | ||
493 | 494 | ||
494 | if (pw->pw_uid == 0) | 495 | if (pw->pw_uid == 0) |
495 | syslog(LOG_INFO, "root login%s", fromhost); | 496 | syslog(LOG_INFO, "root login%s", fromhost); |
diff --git a/mailutils/mail.c b/mailutils/mail.c index 199f64407..a7e43c0d1 100644 --- a/mailutils/mail.c +++ b/mailutils/mail.c | |||
@@ -154,7 +154,7 @@ void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol) | |||
154 | // encode the buffer we just read in | 154 | // encode the buffer we just read in |
155 | bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64); | 155 | bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64); |
156 | if (fname) { | 156 | if (fname) { |
157 | printf("%s\n", eol); | 157 | puts(eol); |
158 | } else { | 158 | } else { |
159 | src_buf += size; | 159 | src_buf += size; |
160 | len -= size; | 160 | len -= size; |
diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index 9455b4e7a..4355e4dc5 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c | |||
@@ -375,7 +375,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
375 | // N.B. we need to escape the leading dot regardless of | 375 | // N.B. we need to escape the leading dot regardless of |
376 | // whether it is single or not character on the line | 376 | // whether it is single or not character on the line |
377 | if ('.' == s[0] /*&& '\0' == s[1] */) | 377 | if ('.' == s[0] /*&& '\0' == s[1] */) |
378 | printf("."); | 378 | bb_putchar('.'); |
379 | // dump read line | 379 | // dump read line |
380 | send_r_n(s); | 380 | send_r_n(s); |
381 | free(s); | 381 | free(s); |
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 5a6aec6bd..9256567cc 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c | |||
@@ -1142,19 +1142,19 @@ static void signal_handler(int sig) | |||
1142 | 1142 | ||
1143 | static const char *get_variable(const char *variable, void *info) | 1143 | static const char *get_variable(const char *variable, void *info) |
1144 | { | 1144 | { |
1145 | static char sbuf[sizeof(int)*3 + 2]; /* sign and NUL */ | ||
1146 | static char *hostname; | 1145 | static char *hostname; |
1147 | 1146 | ||
1148 | struct get_variable_info *gv_info = info; | 1147 | struct get_variable_info *gv_info = info; |
1149 | const char *field_names[] = { | 1148 | const char *field_names[] = { |
1150 | "hostname", "mntpt", "devpath", "devname", | 1149 | "hostname", "mntpt", "devpath", "devname", "uid", "gid", "mode", |
1151 | "uid", "gid", "mode", hostname, mount_point, | 1150 | NULL, mount_point, gv_info->devpath, gv_info->devname, NULL |
1152 | gv_info->devpath, gv_info->devname, NULL | ||
1153 | }; | 1151 | }; |
1154 | int i; | 1152 | int i; |
1155 | 1153 | ||
1156 | if (!hostname) | 1154 | if (!hostname) |
1157 | hostname = safe_gethostname(); | 1155 | hostname = safe_gethostname(); |
1156 | field_names[7] = hostname; | ||
1157 | |||
1158 | /* index_in_str_array returns i>=0 */ | 1158 | /* index_in_str_array returns i>=0 */ |
1159 | i = index_in_str_array(field_names, variable); | 1159 | i = index_in_str_array(field_names, variable); |
1160 | 1160 | ||
@@ -1164,12 +1164,11 @@ static const char *get_variable(const char *variable, void *info) | |||
1164 | return field_names[i + 7]; | 1164 | return field_names[i + 7]; |
1165 | 1165 | ||
1166 | if (i == 4) | 1166 | if (i == 4) |
1167 | sprintf(sbuf, "%u", gv_info->info->uid); | 1167 | return auto_string(xasprintf("%u", gv_info->info->uid)); |
1168 | else if (i == 5) | 1168 | if (i == 5) |
1169 | sprintf(sbuf, "%u", gv_info->info->gid); | 1169 | return auto_string(xasprintf("%u", gv_info->info->gid)); |
1170 | else if (i == 6) | 1170 | /* i == 6 */ |
1171 | sprintf(sbuf, "%o", gv_info->info->mode); | 1171 | return auto_string(xasprintf("%o", gv_info->info->mode)); |
1172 | return sbuf; | ||
1173 | } /* End Function get_variable */ | 1172 | } /* End Function get_variable */ |
1174 | 1173 | ||
1175 | static void service(struct stat statbuf, char *path) | 1174 | static void service(struct stat statbuf, char *path) |
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index f0e9c9d75..9c486e7aa 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c | |||
@@ -763,9 +763,9 @@ static void identify(uint16_t *val) | |||
763 | ) { | 763 | ) { |
764 | like_std = 5; | 764 | like_std = 5; |
765 | if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)) | 765 | if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)) |
766 | printf("powers-up in standby; SET FEATURES subcmd spins-up.\n"); | 766 | puts("powers-up in standby; SET FEATURES subcmd spins-up."); |
767 | if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)) | 767 | if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)) |
768 | printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n"); | 768 | puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n"); |
769 | } | 769 | } |
770 | 770 | ||
771 | /* output the model and serial numbers and the fw revision */ | 771 | /* output the model and serial numbers and the fw revision */ |
@@ -875,7 +875,7 @@ static void identify(uint16_t *val) | |||
875 | if (min_std == 0xffff) | 875 | if (min_std == 0xffff) |
876 | min_std = like_std > 4 ? like_std - 3 : 1; | 876 | min_std = like_std > 4 ? like_std - 3 : 1; |
877 | 877 | ||
878 | printf("Configuration:\n"); | 878 | puts("Configuration:"); |
879 | /* more info from the general configuration word */ | 879 | /* more info from the general configuration word */ |
880 | if ((eqpt != CDROM) && (like_std == 1)) { | 880 | if ((eqpt != CDROM) && (like_std == 1)) { |
881 | jj = val[GEN_CONFIG] >> 1; | 881 | jj = val[GEN_CONFIG] >> 1; |
@@ -909,7 +909,7 @@ static void identify(uint16_t *val) | |||
909 | mm = 0; | 909 | mm = 0; |
910 | bbbig = 0; | 910 | bbbig = 0; |
911 | if ((ll > 0x00FBFC10) && (!val[LCYLS])) | 911 | if ((ll > 0x00FBFC10) && (!val[LCYLS])) |
912 | printf("\tCHS addressing not supported\n"); | 912 | puts("\tCHS addressing not supported"); |
913 | else { | 913 | else { |
914 | jj = val[WHATS_VALID] & OK_W54_58; | 914 | jj = val[WHATS_VALID] & OK_W54_58; |
915 | printf("\tLogical\t\tmax\tcurrent\n" | 915 | printf("\tLogical\t\tmax\tcurrent\n" |
@@ -980,7 +980,7 @@ static void identify(uint16_t *val) | |||
980 | !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "", | 980 | !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "", |
981 | (val[CAPAB_0] & IORDY_OFF) ? "" :"not"); | 981 | (val[CAPAB_0] & IORDY_OFF) ? "" :"not"); |
982 | } else | 982 | } else |
983 | printf("no IORDY\n"); | 983 | puts("no IORDY"); |
984 | 984 | ||
985 | if ((like_std == 1) && val[BUF_TYPE]) { | 985 | if ((like_std == 1) && val[BUF_TYPE]) { |
986 | printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE], | 986 | printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE], |
@@ -1012,13 +1012,13 @@ static void identify(uint16_t *val) | |||
1012 | } | 1012 | } |
1013 | printf("\tR/W multiple sector transfer: "); | 1013 | printf("\tR/W multiple sector transfer: "); |
1014 | if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER)) | 1014 | if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER)) |
1015 | printf("not supported\n"); | 1015 | puts("not supported"); |
1016 | else { | 1016 | else { |
1017 | printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER); | 1017 | printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER); |
1018 | if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID) | 1018 | if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID) |
1019 | printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER); | 1019 | printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER); |
1020 | else | 1020 | else |
1021 | printf("?\n"); | 1021 | puts("?"); |
1022 | } | 1022 | } |
1023 | if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) { | 1023 | if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) { |
1024 | /* We print out elsewhere whether the APM feature is enabled or | 1024 | /* We print out elsewhere whether the APM feature is enabled or |
@@ -1040,7 +1040,7 @@ static void identify(uint16_t *val) | |||
1040 | } else { | 1040 | } else { |
1041 | /* ATAPI */ | 1041 | /* ATAPI */ |
1042 | if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ)) | 1042 | if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ)) |
1043 | printf("\tATA sw reset required\n"); | 1043 | puts("\tATA sw reset required"); |
1044 | 1044 | ||
1045 | if (val[PKT_REL] || val[SVC_NBSY]) { | 1045 | if (val[PKT_REL] || val[SVC_NBSY]) { |
1046 | printf("\tOverlap support:"); | 1046 | printf("\tOverlap support:"); |
@@ -1056,7 +1056,7 @@ static void identify(uint16_t *val) | |||
1056 | /* DMA stuff. Check that only one DMA mode is selected. */ | 1056 | /* DMA stuff. Check that only one DMA mode is selected. */ |
1057 | printf("\tDMA: "); | 1057 | printf("\tDMA: "); |
1058 | if (!(val[CAPAB_0] & DMA_SUP)) | 1058 | if (!(val[CAPAB_0] & DMA_SUP)) |
1059 | printf("not supported\n"); | 1059 | puts("not supported"); |
1060 | else { | 1060 | else { |
1061 | if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA]) | 1061 | if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA]) |
1062 | printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8); | 1062 | printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8); |
@@ -1079,7 +1079,7 @@ static void identify(uint16_t *val) | |||
1079 | bb_putchar('\n'); | 1079 | bb_putchar('\n'); |
1080 | 1080 | ||
1081 | if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP)) | 1081 | if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP)) |
1082 | printf("\t\tInterleaved DMA support\n"); | 1082 | puts("\t\tInterleaved DMA support"); |
1083 | 1083 | ||
1084 | if ((val[WHATS_VALID] & OK_W64_70) | 1084 | if ((val[WHATS_VALID] & OK_W64_70) |
1085 | && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM]) | 1085 | && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM]) |
@@ -1121,8 +1121,8 @@ static void identify(uint16_t *val) | |||
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) { | 1123 | if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) { |
1124 | printf("Commands/features:\n" | 1124 | puts("Commands/features:\n" |
1125 | "\tEnabled\tSupported:\n"); | 1125 | "\tEnabled\tSupported:"); |
1126 | jj = val[CMDS_SUPP_0]; | 1126 | jj = val[CMDS_SUPP_0]; |
1127 | kk = val[CMDS_EN_0]; | 1127 | kk = val[CMDS_EN_0]; |
1128 | for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) { | 1128 | for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) { |
@@ -1150,7 +1150,7 @@ static void identify(uint16_t *val) | |||
1150 | if ((eqpt != CDROM) && (like_std > 3) | 1150 | if ((eqpt != CDROM) && (like_std > 3) |
1151 | && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME]) | 1151 | && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME]) |
1152 | ) { | 1152 | ) { |
1153 | printf("Security:\n"); | 1153 | puts("Security:"); |
1154 | if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1)) | 1154 | if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1)) |
1155 | printf("\tMaster password revision code = %u\n", val[PSWD_CODE]); | 1155 | printf("\tMaster password revision code = %u\n", val[PSWD_CODE]); |
1156 | jj = val[SECU_STATUS]; | 1156 | jj = val[SECU_STATUS]; |
@@ -1366,7 +1366,7 @@ static NOINLINE void dump_identity(const struct hd_driveid *id) | |||
1366 | } | 1366 | } |
1367 | } | 1367 | } |
1368 | #endif /* __NEW_HD_DRIVE_ID */ | 1368 | #endif /* __NEW_HD_DRIVE_ID */ |
1369 | printf("\n\n * current active mode\n\n"); | 1369 | puts("\n\n * current active mode\n"); |
1370 | } | 1370 | } |
1371 | #endif | 1371 | #endif |
1372 | 1372 | ||
@@ -1507,7 +1507,7 @@ static void bus_state_value(unsigned value) | |||
1507 | else if (value == BUSSTATE_OFF) | 1507 | else if (value == BUSSTATE_OFF) |
1508 | on_off(0); | 1508 | on_off(0); |
1509 | else if (value == BUSSTATE_TRISTATE) | 1509 | else if (value == BUSSTATE_TRISTATE) |
1510 | printf(" (tristate)\n"); | 1510 | puts(" (tristate)"); |
1511 | else | 1511 | else |
1512 | printf(" (unknown: %u)\n", value); | 1512 | printf(" (unknown: %u)\n", value); |
1513 | } | 1513 | } |
@@ -1531,7 +1531,7 @@ static void interpret_standby(uint8_t standby) | |||
1531 | printf("vendor-specific"); | 1531 | printf("vendor-specific"); |
1532 | if (standby == 254) | 1532 | if (standby == 254) |
1533 | printf("reserved"); | 1533 | printf("reserved"); |
1534 | printf(")\n"); | 1534 | puts(")"); |
1535 | } | 1535 | } |
1536 | 1536 | ||
1537 | static const uint8_t xfermode_val[] ALIGN1 = { | 1537 | static const uint8_t xfermode_val[] ALIGN1 = { |
@@ -1582,7 +1582,7 @@ static void interpret_xfermode(unsigned xfermode) | |||
1582 | printf("UltraDMA mode%u", xfermode - 64); | 1582 | printf("UltraDMA mode%u", xfermode - 64); |
1583 | else | 1583 | else |
1584 | printf("unknown"); | 1584 | printf("unknown"); |
1585 | printf(")\n"); | 1585 | puts(")"); |
1586 | } | 1586 | } |
1587 | #endif /* HDIO_DRIVE_CMD */ | 1587 | #endif /* HDIO_DRIVE_CMD */ |
1588 | 1588 | ||
@@ -1633,7 +1633,7 @@ static void process_dev(char *devname) | |||
1633 | if (noisy_piomode) { | 1633 | if (noisy_piomode) { |
1634 | printf(" attempting to "); | 1634 | printf(" attempting to "); |
1635 | if (piomode == 255) | 1635 | if (piomode == 255) |
1636 | printf("auto-tune PIO mode\n"); | 1636 | puts("auto-tune PIO mode"); |
1637 | else if (piomode < 100) | 1637 | else if (piomode < 100) |
1638 | printf("set PIO mode to %d\n", piomode); | 1638 | printf("set PIO mode to %d\n", piomode); |
1639 | else if (piomode < 200) | 1639 | else if (piomode < 200) |
@@ -1762,7 +1762,7 @@ static void process_dev(char *devname) | |||
1762 | #ifndef WIN_STANDBYNOW2 | 1762 | #ifndef WIN_STANDBYNOW2 |
1763 | #define WIN_STANDBYNOW2 0x94 | 1763 | #define WIN_STANDBYNOW2 0x94 |
1764 | #endif | 1764 | #endif |
1765 | printf(" issuing standby command\n"); | 1765 | puts(" issuing standby command"); |
1766 | args[0] = WIN_STANDBYNOW1; | 1766 | args[0] = WIN_STANDBYNOW1; |
1767 | ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2); | 1767 | ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2); |
1768 | } | 1768 | } |
@@ -1773,13 +1773,13 @@ static void process_dev(char *devname) | |||
1773 | #ifndef WIN_SLEEPNOW2 | 1773 | #ifndef WIN_SLEEPNOW2 |
1774 | #define WIN_SLEEPNOW2 0x99 | 1774 | #define WIN_SLEEPNOW2 0x99 |
1775 | #endif | 1775 | #endif |
1776 | printf(" issuing sleep command\n"); | 1776 | puts(" issuing sleep command"); |
1777 | args[0] = WIN_SLEEPNOW1; | 1777 | args[0] = WIN_SLEEPNOW1; |
1778 | ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2); | 1778 | ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2); |
1779 | } | 1779 | } |
1780 | if (set_seagate) { | 1780 | if (set_seagate) { |
1781 | args[0] = 0xfb; | 1781 | args[0] = 0xfb; |
1782 | printf(" disabling Seagate auto powersaving mode\n"); | 1782 | puts(" disabling Seagate auto powersaving mode"); |
1783 | ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); | 1783 | ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); |
1784 | } | 1784 | } |
1785 | if (getset_standby == IS_SET) { | 1785 | if (getset_standby == IS_SET) { |
@@ -1815,17 +1815,17 @@ static void process_dev(char *devname) | |||
1815 | if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) { | 1815 | if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) { |
1816 | printf(" IO_support\t=%3ld (", parm); | 1816 | printf(" IO_support\t=%3ld (", parm); |
1817 | if (parm == 0) | 1817 | if (parm == 0) |
1818 | printf("default 16-bit)\n"); | 1818 | puts("default 16-bit)"); |
1819 | else if (parm == 2) | 1819 | else if (parm == 2) |
1820 | printf("16-bit)\n"); | 1820 | puts("16-bit)"); |
1821 | else if (parm == 1) | 1821 | else if (parm == 1) |
1822 | printf("32-bit)\n"); | 1822 | puts("32-bit)"); |
1823 | else if (parm == 3) | 1823 | else if (parm == 3) |
1824 | printf("32-bit w/sync)\n"); | 1824 | puts("32-bit w/sync)"); |
1825 | else if (parm == 8) | 1825 | else if (parm == 8) |
1826 | printf("Request-Queue-Bypass)\n"); | 1826 | puts("Request-Queue-Bypass)"); |
1827 | else | 1827 | else |
1828 | printf("\?\?\?)\n"); | 1828 | puts("\?\?\?)"); |
1829 | } | 1829 | } |
1830 | } | 1830 | } |
1831 | if (getset_unmask) { | 1831 | if (getset_unmask) { |
@@ -1837,7 +1837,7 @@ static void process_dev(char *devname) | |||
1837 | if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) { | 1837 | if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) { |
1838 | printf(fmt, "using_dma", parm); | 1838 | printf(fmt, "using_dma", parm); |
1839 | if (parm == 8) | 1839 | if (parm == 8) |
1840 | printf(" (DMA-Assisted-PIO)\n"); | 1840 | puts(" (DMA-Assisted-PIO)"); |
1841 | else | 1841 | else |
1842 | on_off(parm != 0); | 1842 | on_off(parm != 0); |
1843 | } | 1843 | } |
@@ -1921,7 +1921,7 @@ static void process_dev(char *devname) | |||
1921 | id.multsect_valid &= ~1; | 1921 | id.multsect_valid &= ~1; |
1922 | dump_identity(&id); | 1922 | dump_identity(&id); |
1923 | } else if (errno == -ENOMSG) | 1923 | } else if (errno == -ENOMSG) |
1924 | printf(" no identification info available\n"); | 1924 | puts(" no identification info available"); |
1925 | else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */ | 1925 | else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */ |
1926 | bb_perror_msg("HDIO_GET_IDENTITY"); | 1926 | bb_perror_msg("HDIO_GET_IDENTITY"); |
1927 | else | 1927 | else |
diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 38d90ff10..d77e6bacf 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c | |||
@@ -61,112 +61,14 @@ | |||
61 | 61 | ||
62 | #include "libbb.h" | 62 | #include "libbb.h" |
63 | 63 | ||
64 | /* | 64 | #include <linux/i2c.h> |
65 | * /dev/i2c-X ioctl commands. The ioctl's parameter is always an unsigned long, | 65 | #include <linux/i2c-dev.h> |
66 | * except for: | ||
67 | * - I2C_FUNCS, takes pointer to an unsigned long | ||
68 | * - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data | ||
69 | * - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data | ||
70 | */ | ||
71 | |||
72 | /* | ||
73 | * NOTE: Slave address is 7 or 10 bits, but 10-bit addresses | ||
74 | * are not supported due to code brokenness. | ||
75 | */ | ||
76 | 66 | ||
77 | /* Use this slave address. */ | 67 | #define I2CDUMP_NUM_REGS 256 |
78 | #define I2C_SLAVE 0x0703 | ||
79 | /* Use this slave address, even if it is already in use by a driver. */ | ||
80 | #define I2C_SLAVE_FORCE 0x0706 | ||
81 | /* 0 for 7 bit addrs, != 0 for 10 bit. */ | ||
82 | #define I2C_TENBIT 0x0704 | ||
83 | /* Get the adapter functionality mask. */ | ||
84 | #define I2C_FUNCS 0x0705 | ||
85 | /* Combined R/W transfer (one STOP only). */ | ||
86 | #define I2C_RDWR 0x0707 | ||
87 | /* != 0 to use PEC with SMBus. */ | ||
88 | #define I2C_PEC 0x0708 | ||
89 | /* SMBus transfer. */ | ||
90 | #define I2C_SMBUS 0x0720 | ||
91 | |||
92 | /* Structure used in the I2C_SMBUS ioctl call. */ | ||
93 | struct i2c_smbus_ioctl_data { | ||
94 | uint8_t read_write; | ||
95 | uint8_t command; | ||
96 | uint32_t size; | ||
97 | union i2c_smbus_data *data; | ||
98 | }; | ||
99 | |||
100 | /* Structure used in the I2C_RDWR ioctl call. */ | ||
101 | struct i2c_rdwr_ioctl_data { | ||
102 | struct i2c_msg *msgs; /* Pointers to i2c_msgs. */ | ||
103 | uint32_t nmsgs; /* Number of i2c_msgs. */ | ||
104 | }; | ||
105 | |||
106 | /* As specified in SMBus standard. */ | ||
107 | #define I2C_SMBUS_BLOCK_MAX 32 | ||
108 | /* Not specified but we use same structure. */ | ||
109 | #define I2C_SMBUS_I2C_BLOCK_MAX 32 | ||
110 | |||
111 | /* Data for SMBus Messages. */ | ||
112 | union i2c_smbus_data { | ||
113 | uint8_t byte; | ||
114 | uint16_t word; | ||
115 | /* block[0] is used for length and one more for PEC */ | ||
116 | uint8_t block[I2C_SMBUS_BLOCK_MAX + 2]; | ||
117 | }; | ||
118 | 68 | ||
119 | #define I2C_RDRW_IOCTL_MAX_MSGS 42 | 69 | #define I2CDETECT_MODE_AUTO 0 |
120 | #define I2C_MAX_REGS 256 | 70 | #define I2CDETECT_MODE_QUICK 1 |
121 | 71 | #define I2CDETECT_MODE_READ 2 | |
122 | /* Smbus_access read or write markers. */ | ||
123 | #define I2C_SMBUS_READ 1 | ||
124 | #define I2C_SMBUS_WRITE 0 | ||
125 | |||
126 | /* SMBus transaction types (size parameter in the below functions). */ | ||
127 | #define I2C_SMBUS_QUICK 0 | ||
128 | #define I2C_SMBUS_BYTE 1 | ||
129 | #define I2C_SMBUS_BYTE_DATA 2 | ||
130 | #define I2C_SMBUS_WORD_DATA 3 | ||
131 | #define I2C_SMBUS_PROC_CALL 4 | ||
132 | #define I2C_SMBUS_BLOCK_DATA 5 | ||
133 | #define I2C_SMBUS_I2C_BLOCK_BROKEN 6 | ||
134 | #define I2C_SMBUS_BLOCK_PROC_CALL 7 | ||
135 | #define I2C_SMBUS_I2C_BLOCK_DATA 8 | ||
136 | |||
137 | #define DETECT_MODE_AUTO 0 | ||
138 | #define DETECT_MODE_QUICK 1 | ||
139 | #define DETECT_MODE_READ 2 | ||
140 | |||
141 | /* Defines to determine what functionality is present. */ | ||
142 | #define I2C_FUNC_I2C 0x00000001 | ||
143 | #define I2C_FUNC_10BIT_ADDR 0x00000002 | ||
144 | #define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 | ||
145 | #define I2C_FUNC_SMBUS_PEC 0x00000008 | ||
146 | #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 | ||
147 | #define I2C_FUNC_SMBUS_QUICK 0x00010000 | ||
148 | #define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 | ||
149 | #define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 | ||
150 | #define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 | ||
151 | #define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 | ||
152 | #define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 | ||
153 | #define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 | ||
154 | #define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 | ||
155 | #define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 | ||
156 | #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 | ||
157 | #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 | ||
158 | #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 | ||
159 | |||
160 | #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ | ||
161 | I2C_FUNC_SMBUS_WRITE_BYTE) | ||
162 | #define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ | ||
163 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA) | ||
164 | #define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ | ||
165 | I2C_FUNC_SMBUS_WRITE_WORD_DATA) | ||
166 | #define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ | ||
167 | I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) | ||
168 | #define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ | ||
169 | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) | ||
170 | 72 | ||
171 | /* | 73 | /* |
172 | * This is needed for ioctl_or_perror_and_die() since it only accepts pointers. | 74 | * This is needed for ioctl_or_perror_and_die() since it only accepts pointers. |
@@ -456,7 +358,7 @@ static void check_read_funcs(int fd, int mode, int data_addr, int pec) | |||
456 | break; | 358 | break; |
457 | #endif /* ENABLE_I2CDUMP */ | 359 | #endif /* ENABLE_I2CDUMP */ |
458 | default: | 360 | default: |
459 | bb_error_msg_and_die("Programmer goofed!"); | 361 | bb_error_msg_and_die("internal error"); |
460 | } | 362 | } |
461 | check_funcs_test_end(funcs, pec, err); | 363 | check_funcs_test_end(funcs, pec, err); |
462 | } | 364 | } |
@@ -799,7 +701,7 @@ int i2cset_main(int argc, char **argv) | |||
799 | } | 701 | } |
800 | 702 | ||
801 | if (status < 0) { | 703 | if (status < 0) { |
802 | printf("Warning - readback failed\n"); | 704 | puts("Warning - readback failed"); |
803 | } else | 705 | } else |
804 | if (status != val) { | 706 | if (status != val) { |
805 | printf("Warning - data mismatch - wrote " | 707 | printf("Warning - data mismatch - wrote " |
@@ -818,14 +720,14 @@ int i2cset_main(int argc, char **argv) | |||
818 | #if ENABLE_I2CDUMP | 720 | #if ENABLE_I2CDUMP |
819 | static int read_block_data(int buf_fd, int mode, int *block) | 721 | static int read_block_data(int buf_fd, int mode, int *block) |
820 | { | 722 | { |
821 | uint8_t cblock[I2C_SMBUS_BLOCK_MAX + I2C_MAX_REGS]; | 723 | uint8_t cblock[I2C_SMBUS_BLOCK_MAX + I2CDUMP_NUM_REGS]; |
822 | int res, blen = 0, tmp, i; | 724 | int res, blen = 0, tmp, i; |
823 | 725 | ||
824 | if (mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) { | 726 | if (mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) { |
825 | res = i2c_smbus_read_block_data(buf_fd, 0, cblock); | 727 | res = i2c_smbus_read_block_data(buf_fd, 0, cblock); |
826 | blen = res; | 728 | blen = res; |
827 | } else { | 729 | } else { |
828 | for (res = 0; res < I2C_MAX_REGS; res += tmp) { | 730 | for (res = 0; res < I2CDUMP_NUM_REGS; res += tmp) { |
829 | tmp = i2c_smbus_read_i2c_block_data( | 731 | tmp = i2c_smbus_read_i2c_block_data( |
830 | buf_fd, res, I2C_SMBUS_BLOCK_MAX, | 732 | buf_fd, res, I2C_SMBUS_BLOCK_MAX, |
831 | cblock + res); | 733 | cblock + res); |
@@ -834,14 +736,14 @@ static int read_block_data(int buf_fd, int mode, int *block) | |||
834 | } | 736 | } |
835 | } | 737 | } |
836 | 738 | ||
837 | if (res >= I2C_MAX_REGS) | 739 | if (res >= I2CDUMP_NUM_REGS) |
838 | res = I2C_MAX_REGS; | 740 | res = I2CDUMP_NUM_REGS; |
839 | 741 | ||
840 | for (i = 0; i < res; i++) | 742 | for (i = 0; i < res; i++) |
841 | block[i] = cblock[i]; | 743 | block[i] = cblock[i]; |
842 | 744 | ||
843 | if (mode != I2C_SMBUS_BLOCK_DATA) | 745 | if (mode != I2C_SMBUS_BLOCK_DATA) |
844 | for (i = res; i < I2C_MAX_REGS; i++) | 746 | for (i = res; i < I2CDUMP_NUM_REGS; i++) |
845 | block[i] = -1; | 747 | block[i] = -1; |
846 | } | 748 | } |
847 | 749 | ||
@@ -854,10 +756,10 @@ static void dump_data(int bus_fd, int mode, unsigned first, | |||
854 | { | 756 | { |
855 | int i, j, res; | 757 | int i, j, res; |
856 | 758 | ||
857 | printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" | 759 | puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" |
858 | " 0123456789abcdef\n"); | 760 | " 0123456789abcdef"); |
859 | 761 | ||
860 | for (i = 0; i < I2C_MAX_REGS; i += 0x10) { | 762 | for (i = 0; i < I2CDUMP_NUM_REGS; i += 0x10) { |
861 | if (mode == I2C_SMBUS_BLOCK_DATA && i >= blen) | 763 | if (mode == I2C_SMBUS_BLOCK_DATA && i >= blen) |
862 | break; | 764 | break; |
863 | if (i/16 < first/16) | 765 | if (i/16 < first/16) |
@@ -924,22 +826,22 @@ static void dump_data(int bus_fd, int mode, unsigned first, | |||
924 | break; | 826 | break; |
925 | /* Skip unwanted registers */ | 827 | /* Skip unwanted registers */ |
926 | if (i+j < first || i+j > last) { | 828 | if (i+j < first || i+j > last) { |
927 | printf(" "); | 829 | bb_putchar(' '); |
928 | continue; | 830 | continue; |
929 | } | 831 | } |
930 | 832 | ||
931 | res = block[i+j]; | 833 | res = block[i+j]; |
932 | if (res < 0) { | 834 | if (res < 0) { |
933 | printf("X"); | 835 | bb_putchar('X'); |
934 | } else if (res == 0x00 || res == 0xff) { | 836 | } else if (res == 0x00 || res == 0xff) { |
935 | printf("."); | 837 | bb_putchar('.'); |
936 | } else if (res < 32 || res >= 127) { | 838 | } else if (res < 32 || res >= 127) { |
937 | printf("?"); | 839 | bb_putchar('?'); |
938 | } else { | 840 | } else { |
939 | printf("%c", res); | 841 | bb_putchar(res); |
940 | } | 842 | } |
941 | } | 843 | } |
942 | printf("\n"); | 844 | bb_putchar('\n'); |
943 | } | 845 | } |
944 | } | 846 | } |
945 | 847 | ||
@@ -948,7 +850,7 @@ static void dump_word_data(int bus_fd, unsigned first, unsigned last) | |||
948 | int i, j, rv; | 850 | int i, j, rv; |
949 | 851 | ||
950 | /* Word data. */ | 852 | /* Word data. */ |
951 | printf(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f\n"); | 853 | puts(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f"); |
952 | for (i = 0; i < 256; i += 8) { | 854 | for (i = 0; i < 256; i += 8) { |
953 | if (i/8 < first/8) | 855 | if (i/8 < first/8) |
954 | continue; | 856 | continue; |
@@ -969,7 +871,7 @@ static void dump_word_data(int bus_fd, unsigned first, unsigned last) | |||
969 | else | 871 | else |
970 | printf("%04x ", rv & 0xffff); | 872 | printf("%04x ", rv & 0xffff); |
971 | } | 873 | } |
972 | printf("\n"); | 874 | bb_putchar('\n'); |
973 | } | 875 | } |
974 | } | 876 | } |
975 | 877 | ||
@@ -1120,33 +1022,33 @@ static const struct i2c_func i2c_funcs_tab[] = { | |||
1120 | { .value = I2C_FUNC_I2C, | 1022 | { .value = I2C_FUNC_I2C, |
1121 | .name = "I2C" }, | 1023 | .name = "I2C" }, |
1122 | { .value = I2C_FUNC_SMBUS_QUICK, | 1024 | { .value = I2C_FUNC_SMBUS_QUICK, |
1123 | .name = "SMBus Quick Command" }, | 1025 | .name = "SMBus quick command" }, |
1124 | { .value = I2C_FUNC_SMBUS_WRITE_BYTE, | 1026 | { .value = I2C_FUNC_SMBUS_WRITE_BYTE, |
1125 | .name = "SMBus Send Byte" }, | 1027 | .name = "SMBus send byte" }, |
1126 | { .value = I2C_FUNC_SMBUS_READ_BYTE, | 1028 | { .value = I2C_FUNC_SMBUS_READ_BYTE, |
1127 | .name = "SMBus Receive Byte" }, | 1029 | .name = "SMBus receive byte" }, |
1128 | { .value = I2C_FUNC_SMBUS_WRITE_BYTE_DATA, | 1030 | { .value = I2C_FUNC_SMBUS_WRITE_BYTE_DATA, |
1129 | .name = "SMBus Write Byte" }, | 1031 | .name = "SMBus write byte" }, |
1130 | { .value = I2C_FUNC_SMBUS_READ_BYTE_DATA, | 1032 | { .value = I2C_FUNC_SMBUS_READ_BYTE_DATA, |
1131 | .name = "SMBus Read Byte" }, | 1033 | .name = "SMBus read byte" }, |
1132 | { .value = I2C_FUNC_SMBUS_WRITE_WORD_DATA, | 1034 | { .value = I2C_FUNC_SMBUS_WRITE_WORD_DATA, |
1133 | .name = "SMBus Write Word" }, | 1035 | .name = "SMBus write word" }, |
1134 | { .value = I2C_FUNC_SMBUS_READ_WORD_DATA, | 1036 | { .value = I2C_FUNC_SMBUS_READ_WORD_DATA, |
1135 | .name = "SMBus Read Word" }, | 1037 | .name = "SMBus read word" }, |
1136 | { .value = I2C_FUNC_SMBUS_PROC_CALL, | 1038 | { .value = I2C_FUNC_SMBUS_PROC_CALL, |
1137 | .name = "SMBus Process Call" }, | 1039 | .name = "SMBus process call" }, |
1138 | { .value = I2C_FUNC_SMBUS_WRITE_BLOCK_DATA, | 1040 | { .value = I2C_FUNC_SMBUS_WRITE_BLOCK_DATA, |
1139 | .name = "SMBus Block Write" }, | 1041 | .name = "SMBus block write" }, |
1140 | { .value = I2C_FUNC_SMBUS_READ_BLOCK_DATA, | 1042 | { .value = I2C_FUNC_SMBUS_READ_BLOCK_DATA, |
1141 | .name = "SMBus Block Read" }, | 1043 | .name = "SMBus block read" }, |
1142 | { .value = I2C_FUNC_SMBUS_BLOCK_PROC_CALL, | 1044 | { .value = I2C_FUNC_SMBUS_BLOCK_PROC_CALL, |
1143 | .name = "SMBus Block Process Call" }, | 1045 | .name = "SMBus block process call" }, |
1144 | { .value = I2C_FUNC_SMBUS_PEC, | 1046 | { .value = I2C_FUNC_SMBUS_PEC, |
1145 | .name = "SMBus PEC" }, | 1047 | .name = "SMBus PEC" }, |
1146 | { .value = I2C_FUNC_SMBUS_WRITE_I2C_BLOCK, | 1048 | { .value = I2C_FUNC_SMBUS_WRITE_I2C_BLOCK, |
1147 | .name = "I2C Block Write" }, | 1049 | .name = "I2C block write" }, |
1148 | { .value = I2C_FUNC_SMBUS_READ_I2C_BLOCK, | 1050 | { .value = I2C_FUNC_SMBUS_READ_I2C_BLOCK, |
1149 | .name = "I2C Block Read" }, | 1051 | .name = "I2C block read" }, |
1150 | { .value = 0, .name = NULL } | 1052 | { .value = 0, .name = NULL } |
1151 | }; | 1053 | }; |
1152 | 1054 | ||
@@ -1298,7 +1200,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) | |||
1298 | opt_F = (1 << 4), opt_l = (1 << 5); | 1200 | opt_F = (1 << 4), opt_l = (1 << 5); |
1299 | const char *const optstr = "yaqrFl"; | 1201 | const char *const optstr = "yaqrFl"; |
1300 | 1202 | ||
1301 | int fd, bus_num, i, j, mode = DETECT_MODE_AUTO, status; | 1203 | int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status; |
1302 | unsigned first = 0x03, last = 0x77, opts; | 1204 | unsigned first = 0x03, last = 0x77, opts; |
1303 | unsigned long funcs; | 1205 | unsigned long funcs; |
1304 | 1206 | ||
@@ -1329,9 +1231,9 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) | |||
1329 | } | 1231 | } |
1330 | 1232 | ||
1331 | if (opts & opt_r) | 1233 | if (opts & opt_r) |
1332 | mode = DETECT_MODE_READ; | 1234 | mode = I2CDETECT_MODE_READ; |
1333 | else if (opts & opt_q) | 1235 | else if (opts & opt_q) |
1334 | mode = DETECT_MODE_QUICK; | 1236 | mode = I2CDETECT_MODE_QUICK; |
1335 | 1237 | ||
1336 | if (opts & opt_a) { | 1238 | if (opts & opt_a) { |
1337 | first = 0x00; | 1239 | first = 0x00; |
@@ -1348,42 +1250,42 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) | |||
1348 | if (!(funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) { | 1250 | if (!(funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) { |
1349 | no_support("detection commands"); | 1251 | no_support("detection commands"); |
1350 | } else | 1252 | } else |
1351 | if (mode == DETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK)) { | 1253 | if (mode == I2CDETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK)) { |
1352 | no_support("SMBus Quick Write command"); | 1254 | no_support("SMBus quick write"); |
1353 | } else | 1255 | } else |
1354 | if (mode == DETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) { | 1256 | if (mode == I2CDETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) { |
1355 | no_support("SMBus Receive Byte command"); | 1257 | no_support("SMBus receive byte"); |
1356 | } | 1258 | } |
1357 | 1259 | ||
1358 | if (mode == DETECT_MODE_AUTO) { | 1260 | if (mode == I2CDETECT_MODE_AUTO) { |
1359 | if (!(funcs & I2C_FUNC_SMBUS_QUICK)) | 1261 | if (!(funcs & I2C_FUNC_SMBUS_QUICK)) |
1360 | will_skip("SMBus Quick Write"); | 1262 | will_skip("SMBus quick write"); |
1361 | if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE)) | 1263 | if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE)) |
1362 | will_skip("SMBus Receive Byte"); | 1264 | will_skip("SMBus receive byte"); |
1363 | } | 1265 | } |
1364 | 1266 | ||
1365 | if (!(opts & opt_y)) | 1267 | if (!(opts & opt_y)) |
1366 | confirm_action(-1, -1, -1, 0); | 1268 | confirm_action(-1, -1, -1, 0); |
1367 | 1269 | ||
1368 | printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); | 1270 | puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f"); |
1369 | for (i = 0; i < 128; i += 16) { | 1271 | for (i = 0; i < 128; i += 16) { |
1370 | printf("%02x: ", i); | 1272 | printf("%02x: ", i); |
1371 | for(j = 0; j < 16; j++) { | 1273 | for(j = 0; j < 16; j++) { |
1372 | fflush_all(); | 1274 | fflush_all(); |
1373 | 1275 | ||
1374 | if (mode == DETECT_MODE_AUTO) { | 1276 | if (mode == I2CDETECT_MODE_AUTO) { |
1375 | if ((i+j >= 0x30 && i+j <= 0x37) || | 1277 | if ((i+j >= 0x30 && i+j <= 0x37) || |
1376 | (i+j >= 0x50 && i+j <= 0x5F)) | 1278 | (i+j >= 0x50 && i+j <= 0x5F)) |
1377 | mode = DETECT_MODE_READ; | 1279 | mode = I2CDETECT_MODE_READ; |
1378 | else | 1280 | else |
1379 | mode = DETECT_MODE_QUICK; | 1281 | mode = I2CDETECT_MODE_QUICK; |
1380 | } | 1282 | } |
1381 | 1283 | ||
1382 | /* Skip unwanted addresses. */ | 1284 | /* Skip unwanted addresses. */ |
1383 | if (i+j < first | 1285 | if (i+j < first |
1384 | || i+j > last | 1286 | || i+j > last |
1385 | || (mode == DETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) | 1287 | || (mode == I2CDETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) |
1386 | || (mode == DETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) | 1288 | || (mode == I2CDETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) |
1387 | { | 1289 | { |
1388 | printf(" "); | 1290 | printf(" "); |
1389 | continue; | 1291 | continue; |
@@ -1401,14 +1303,14 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) | |||
1401 | } | 1303 | } |
1402 | 1304 | ||
1403 | switch (mode) { | 1305 | switch (mode) { |
1404 | case DETECT_MODE_READ: | 1306 | case I2CDETECT_MODE_READ: |
1405 | /* | 1307 | /* |
1406 | * This is known to lock SMBus on various | 1308 | * This is known to lock SMBus on various |
1407 | * write-only chips (mainly clock chips). | 1309 | * write-only chips (mainly clock chips). |
1408 | */ | 1310 | */ |
1409 | status = i2c_smbus_read_byte(fd); | 1311 | status = i2c_smbus_read_byte(fd); |
1410 | break; | 1312 | break; |
1411 | default: /* DETECT_MODE_QUICK: */ | 1313 | default: /* I2CDETECT_MODE_QUICK: */ |
1412 | /* | 1314 | /* |
1413 | * This is known to corrupt the Atmel | 1315 | * This is known to corrupt the Atmel |
1414 | * AT24RF08 EEPROM. | 1316 | * AT24RF08 EEPROM. |
@@ -1423,7 +1325,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) | |||
1423 | else | 1325 | else |
1424 | printf("%02x ", i+j); | 1326 | printf("%02x ", i+j); |
1425 | } | 1327 | } |
1426 | printf("\n"); | 1328 | bb_putchar('\n'); |
1427 | } | 1329 | } |
1428 | 1330 | ||
1429 | return 0; | 1331 | return 0; |
diff --git a/miscutils/last.c b/miscutils/last.c index 6d8b58463..f8f34371a 100644 --- a/miscutils/last.c +++ b/miscutils/last.c | |||
@@ -34,7 +34,8 @@ | |||
34 | && ((UT_LINESIZE != 32) || (UT_NAMESIZE != 32) || (UT_HOSTSIZE != 256)) | 34 | && ((UT_LINESIZE != 32) || (UT_NAMESIZE != 32) || (UT_HOSTSIZE != 256)) |
35 | #error struct utmpx member char[] size(s) have changed! | 35 | #error struct utmpx member char[] size(s) have changed! |
36 | #elif defined __UT_LINESIZE \ | 36 | #elif defined __UT_LINESIZE \ |
37 | && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 64) || (__UT_HOSTSIZE != 256)) | 37 | && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 32) || (__UT_HOSTSIZE != 256)) |
38 | /* __UT_NAMESIZE was checked with 64 above, but glibc-2.11 definitely uses 32! */ | ||
38 | #error struct utmpx member char[] size(s) have changed! | 39 | #error struct utmpx member char[] size(s) have changed! |
39 | #endif | 40 | #endif |
40 | 41 | ||
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 996de4074..314a7a1cb 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
@@ -348,6 +348,38 @@ static const char *humanly_readable_name(struct module_entry *m) | |||
348 | return m->probed_name ? m->probed_name : m->modname; | 348 | return m->probed_name ? m->probed_name : m->modname; |
349 | } | 349 | } |
350 | 350 | ||
351 | /* Like strsep(&stringp, "\n\t ") but quoted text goes to single token | ||
352 | * even if it contains whitespace. | ||
353 | */ | ||
354 | static char *strsep_quotes(char **stringp) | ||
355 | { | ||
356 | char *s, *start = *stringp; | ||
357 | |||
358 | if (!start) | ||
359 | return NULL; | ||
360 | |||
361 | for (s = start; ; s++) { | ||
362 | switch (*s) { | ||
363 | case '"': | ||
364 | s = strchrnul(s + 1, '"'); /* find trailing quote */ | ||
365 | if (*s != '\0') | ||
366 | s++; /* skip trailing quote */ | ||
367 | /* fall through */ | ||
368 | case '\0': | ||
369 | case '\n': | ||
370 | case '\t': | ||
371 | case ' ': | ||
372 | if (*s != '\0') { | ||
373 | *s = '\0'; | ||
374 | *stringp = s + 1; | ||
375 | } else { | ||
376 | *stringp = NULL; | ||
377 | } | ||
378 | return start; | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | |||
351 | static char *parse_and_add_kcmdline_module_options(char *options, const char *modulename) | 383 | static char *parse_and_add_kcmdline_module_options(char *options, const char *modulename) |
352 | { | 384 | { |
353 | char *kcmdline_buf; | 385 | char *kcmdline_buf; |
@@ -359,7 +391,7 @@ static char *parse_and_add_kcmdline_module_options(char *options, const char *mo | |||
359 | return options; | 391 | return options; |
360 | 392 | ||
361 | kcmdline = kcmdline_buf; | 393 | kcmdline = kcmdline_buf; |
362 | while ((kptr = strsep(&kcmdline, "\n\t ")) != NULL) { | 394 | while ((kptr = strsep_quotes(&kcmdline)) != NULL) { |
363 | char *after_modulename = is_prefixed_with(kptr, modulename); | 395 | char *after_modulename = is_prefixed_with(kptr, modulename); |
364 | if (!after_modulename || *after_modulename != '.') | 396 | if (!after_modulename || *after_modulename != '.') |
365 | continue; | 397 | continue; |
diff --git a/networking/Config.src b/networking/Config.src index da36e8627..43ccbf385 100644 --- a/networking/Config.src +++ b/networking/Config.src | |||
@@ -533,6 +533,13 @@ config FEATURE_IP_ROUTE | |||
533 | help | 533 | help |
534 | Add support for routing table management to "ip". | 534 | Add support for routing table management to "ip". |
535 | 535 | ||
536 | config FEATURE_IP_ROUTE_DIR | ||
537 | string "ip route configuration directory" | ||
538 | default "/etc/iproute2" | ||
539 | depends on FEATURE_IP_ROUTE | ||
540 | help | ||
541 | Location of the "ip" applet routing configuration. | ||
542 | |||
536 | config FEATURE_IP_TUNNEL | 543 | config FEATURE_IP_TUNNEL |
537 | bool "ip tunnel" | 544 | bool "ip tunnel" |
538 | default y | 545 | default y |
@@ -947,48 +954,6 @@ config VCONFIG | |||
947 | help | 954 | help |
948 | Creates, removes, and configures VLAN interfaces | 955 | Creates, removes, and configures VLAN interfaces |
949 | 956 | ||
950 | config WGET | ||
951 | bool "wget" | ||
952 | default y | ||
953 | help | ||
954 | wget is a utility for non-interactive download of files from HTTP | ||
955 | and FTP servers. | ||
956 | |||
957 | config FEATURE_WGET_STATUSBAR | ||
958 | bool "Enable a nifty process meter (+2k)" | ||
959 | default y | ||
960 | depends on WGET | ||
961 | help | ||
962 | Enable the transfer progress bar for wget transfers. | ||
963 | |||
964 | config FEATURE_WGET_AUTHENTICATION | ||
965 | bool "Enable HTTP authentication" | ||
966 | default y | ||
967 | depends on WGET | ||
968 | help | ||
969 | Support authenticated HTTP transfers. | ||
970 | |||
971 | config FEATURE_WGET_LONG_OPTIONS | ||
972 | bool "Enable long options" | ||
973 | default y | ||
974 | depends on WGET && LONG_OPTS | ||
975 | help | ||
976 | Support long options for the wget applet. | ||
977 | |||
978 | config FEATURE_WGET_TIMEOUT | ||
979 | bool "Enable timeout option -T SEC" | ||
980 | default y | ||
981 | depends on WGET | ||
982 | help | ||
983 | Supports network read and connect timeouts for wget, | ||
984 | so that wget will give up and timeout, through the -T | ||
985 | command line option. | ||
986 | |||
987 | Currently only connect and network data read timeout are | ||
988 | supported (i.e., timeout is not applied to the DNS query). When | ||
989 | FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option | ||
990 | will work in addition to -T. | ||
991 | |||
992 | config ZCIP | 957 | config ZCIP |
993 | bool "zcip" | 958 | bool "zcip" |
994 | default y | 959 | default y |
diff --git a/networking/Kbuild.src b/networking/Kbuild.src index 944f27be1..79f54824b 100644 --- a/networking/Kbuild.src +++ b/networking/Kbuild.src | |||
@@ -41,7 +41,6 @@ lib-$(CONFIG_TFTPD) += tftp.o | |||
41 | lib-$(CONFIG_TRACEROUTE) += traceroute.o | 41 | lib-$(CONFIG_TRACEROUTE) += traceroute.o |
42 | lib-$(CONFIG_TUNCTL) += tunctl.o | 42 | lib-$(CONFIG_TUNCTL) += tunctl.o |
43 | lib-$(CONFIG_VCONFIG) += vconfig.o | 43 | lib-$(CONFIG_VCONFIG) += vconfig.o |
44 | lib-$(CONFIG_WGET) += wget.o | ||
45 | lib-$(CONFIG_ZCIP) += zcip.o | 44 | lib-$(CONFIG_ZCIP) += zcip.o |
46 | 45 | ||
47 | lib-$(CONFIG_TCPSVD) += tcpudp.o tcpudp_perhost.o | 46 | lib-$(CONFIG_TCPSVD) += tcpudp.o tcpudp_perhost.o |
diff --git a/networking/arping.c b/networking/arping.c index dbfd75ef5..ef205e5e6 100644 --- a/networking/arping.c +++ b/networking/arping.c | |||
@@ -13,11 +13,11 @@ | |||
13 | //usage: "\n -f Quit on first ARP reply" | 13 | //usage: "\n -f Quit on first ARP reply" |
14 | //usage: "\n -q Quiet" | 14 | //usage: "\n -q Quiet" |
15 | //usage: "\n -b Keep broadcasting, don't go unicast" | 15 | //usage: "\n -b Keep broadcasting, don't go unicast" |
16 | //usage: "\n -D Duplicated address detection mode" | 16 | //usage: "\n -D Exit with 1 if DST_IP replies" |
17 | //usage: "\n -U Unsolicited ARP mode, update your neighbors" | 17 | //usage: "\n -U Unsolicited ARP mode, update your neighbors" |
18 | //usage: "\n -A ARP answer mode, update your neighbors" | 18 | //usage: "\n -A ARP answer mode, update your neighbors" |
19 | //usage: "\n -c N Stop after sending N ARP requests" | 19 | //usage: "\n -c N Stop after sending N ARP requests" |
20 | //usage: "\n -w TIMEOUT Time to wait for ARP reply, seconds" | 20 | //usage: "\n -w TIMEOUT Seconds to wait for ARP reply" |
21 | //usage: "\n -I IFACE Interface to use (default eth0)" | 21 | //usage: "\n -I IFACE Interface to use (default eth0)" |
22 | //usage: "\n -s SRC_IP Sender IP address" | 22 | //usage: "\n -s SRC_IP Sender IP address" |
23 | //usage: "\n DST_IP Target IP address" | 23 | //usage: "\n DST_IP Target IP address" |
@@ -162,7 +162,7 @@ static void catcher(void) | |||
162 | alarm(1); | 162 | alarm(1); |
163 | } | 163 | } |
164 | 164 | ||
165 | static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | 165 | static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) |
166 | { | 166 | { |
167 | struct arphdr *ah = (struct arphdr *) buf; | 167 | struct arphdr *ah = (struct arphdr *) buf; |
168 | unsigned char *p = (unsigned char *) (ah + 1); | 168 | unsigned char *p = (unsigned char *) (ah + 1); |
@@ -181,33 +181,33 @@ static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
181 | if (FROM->sll_pkttype != PACKET_HOST | 181 | if (FROM->sll_pkttype != PACKET_HOST |
182 | && FROM->sll_pkttype != PACKET_BROADCAST | 182 | && FROM->sll_pkttype != PACKET_BROADCAST |
183 | && FROM->sll_pkttype != PACKET_MULTICAST) | 183 | && FROM->sll_pkttype != PACKET_MULTICAST) |
184 | return false; | 184 | return; |
185 | 185 | ||
186 | /* Only these types are recognized */ | 186 | /* Only these types are recognized */ |
187 | if (ah->ar_op != htons(ARPOP_REQUEST) && ah->ar_op != htons(ARPOP_REPLY)) | 187 | if (ah->ar_op != htons(ARPOP_REQUEST) && ah->ar_op != htons(ARPOP_REPLY)) |
188 | return false; | 188 | return; |
189 | 189 | ||
190 | /* ARPHRD check and this darned FDDI hack here :-( */ | 190 | /* ARPHRD check and this darned FDDI hack here :-( */ |
191 | if (ah->ar_hrd != htons(FROM->sll_hatype) | 191 | if (ah->ar_hrd != htons(FROM->sll_hatype) |
192 | && (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER))) | 192 | && (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER))) |
193 | return false; | 193 | return; |
194 | 194 | ||
195 | /* Protocol must be IP. */ | 195 | /* Protocol must be IP. */ |
196 | if (ah->ar_pro != htons(ETH_P_IP) | 196 | if (ah->ar_pro != htons(ETH_P_IP) |
197 | || (ah->ar_pln != 4) | 197 | || (ah->ar_pln != 4) |
198 | || (ah->ar_hln != me.sll_halen) | 198 | || (ah->ar_hln != me.sll_halen) |
199 | || (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln)))) | 199 | || (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln)))) |
200 | return false; | 200 | return; |
201 | 201 | ||
202 | move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln); | 202 | move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln); |
203 | move_from_unaligned32(dst_ip.s_addr, p + ah->ar_hln + 4 + ah->ar_hln); | 203 | move_from_unaligned32(dst_ip.s_addr, p + ah->ar_hln + 4 + ah->ar_hln); |
204 | 204 | ||
205 | if (dst.s_addr != src_ip.s_addr) | 205 | if (dst.s_addr != src_ip.s_addr) |
206 | return false; | 206 | return; |
207 | if (!(option_mask32 & DAD)) { | 207 | if (!(option_mask32 & DAD)) { |
208 | if ((src.s_addr != dst_ip.s_addr) | 208 | if ((src.s_addr != dst_ip.s_addr) |
209 | || (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln))) | 209 | || (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln))) |
210 | return false; | 210 | return; |
211 | } else { | 211 | } else { |
212 | /* DAD packet was: | 212 | /* DAD packet was: |
213 | src_ip = 0 (or some src) | 213 | src_ip = 0 (or some src) |
@@ -224,7 +224,7 @@ static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
224 | */ | 224 | */ |
225 | if ((memcmp(p, &me.sll_addr, me.sll_halen) == 0) | 225 | if ((memcmp(p, &me.sll_addr, me.sll_halen) == 0) |
226 | || (src.s_addr && src.s_addr != dst_ip.s_addr)) | 226 | || (src.s_addr && src.s_addr != dst_ip.s_addr)) |
227 | return false; | 227 | return; |
228 | } | 228 | } |
229 | if (!(option_mask32 & QUIET)) { | 229 | if (!(option_mask32 & QUIET)) { |
230 | int s_printed = 0; | 230 | int s_printed = 0; |
@@ -249,7 +249,7 @@ static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
249 | unsigned diff = MONOTONIC_US() - last; | 249 | unsigned diff = MONOTONIC_US() - last; |
250 | printf(" %u.%03ums\n", diff / 1000, diff % 1000); | 250 | printf(" %u.%03ums\n", diff / 1000, diff % 1000); |
251 | } else { | 251 | } else { |
252 | printf(" UNSOLICITED?\n"); | 252 | puts(" UNSOLICITED?"); |
253 | } | 253 | } |
254 | fflush_all(); | 254 | fflush_all(); |
255 | } | 255 | } |
@@ -264,7 +264,6 @@ static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
264 | memcpy(he.sll_addr, p, me.sll_halen); | 264 | memcpy(he.sll_addr, p, me.sll_halen); |
265 | option_mask32 |= UNICASTING; | 265 | option_mask32 |= UNICASTING; |
266 | } | 266 | } |
267 | return true; | ||
268 | } | 267 | } |
269 | 268 | ||
270 | int arping_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 269 | int arping_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
@@ -358,8 +357,8 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
358 | saddr.sin_port = htons(1025); | 357 | saddr.sin_port = htons(1025); |
359 | saddr.sin_addr = dst; | 358 | saddr.sin_addr = dst; |
360 | 359 | ||
361 | if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1) | 360 | if (setsockopt_SOL_SOCKET_1(probe_fd, SO_DONTROUTE) != 0) |
362 | bb_perror_msg("setsockopt(SO_DONTROUTE)"); | 361 | bb_perror_msg("setsockopt(%s)", "SO_DONTROUTE"); |
363 | xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); | 362 | xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); |
364 | getsockname(probe_fd, (struct sockaddr *) &saddr, &alen); | 363 | getsockname(probe_fd, (struct sockaddr *) &saddr, &alen); |
365 | //never happens: | 364 | //never happens: |
diff --git a/networking/brctl.c b/networking/brctl.c index 207b069aa..c01a86998 100644 --- a/networking/brctl.c +++ b/networking/brctl.c | |||
@@ -64,7 +64,57 @@ | |||
64 | #define BRCTL_USE_INTERNAL 1 | 64 | #define BRCTL_USE_INTERNAL 1 |
65 | 65 | ||
66 | #if ENABLE_FEATURE_BRCTL_FANCY | 66 | #if ENABLE_FEATURE_BRCTL_FANCY |
67 | # include <linux/if_bridge.h> | 67 | /* #include <linux/if_bridge.h> |
68 | * breaks on musl: we already included netinet/in.h in libbb.h, | ||
69 | * if we include <linux/if_bridge.h> here, we get this: | ||
70 | * In file included from /usr/include/linux/if_bridge.h:18, | ||
71 | * from networking/brctl.c:67: | ||
72 | * /usr/include/linux/in6.h:32: error: redefinition of 'struct in6_addr' | ||
73 | * /usr/include/linux/in6.h:49: error: redefinition of 'struct sockaddr_in6' | ||
74 | * /usr/include/linux/in6.h:59: error: redefinition of 'struct ipv6_mreq' | ||
75 | */ | ||
76 | /* From <linux/if_bridge.h> */ | ||
77 | #define BRCTL_GET_VERSION 0 | ||
78 | #define BRCTL_GET_BRIDGES 1 | ||
79 | #define BRCTL_ADD_BRIDGE 2 | ||
80 | #define BRCTL_DEL_BRIDGE 3 | ||
81 | #define BRCTL_ADD_IF 4 | ||
82 | #define BRCTL_DEL_IF 5 | ||
83 | #define BRCTL_GET_BRIDGE_INFO 6 | ||
84 | #define BRCTL_GET_PORT_LIST 7 | ||
85 | #define BRCTL_SET_BRIDGE_FORWARD_DELAY 8 | ||
86 | #define BRCTL_SET_BRIDGE_HELLO_TIME 9 | ||
87 | #define BRCTL_SET_BRIDGE_MAX_AGE 10 | ||
88 | #define BRCTL_SET_AGEING_TIME 11 | ||
89 | #define BRCTL_SET_GC_INTERVAL 12 | ||
90 | #define BRCTL_GET_PORT_INFO 13 | ||
91 | #define BRCTL_SET_BRIDGE_STP_STATE 14 | ||
92 | #define BRCTL_SET_BRIDGE_PRIORITY 15 | ||
93 | #define BRCTL_SET_PORT_PRIORITY 16 | ||
94 | #define BRCTL_SET_PATH_COST 17 | ||
95 | #define BRCTL_GET_FDB_ENTRIES 18 | ||
96 | struct __bridge_info { | ||
97 | uint64_t designated_root; | ||
98 | uint64_t bridge_id; | ||
99 | uint32_t root_path_cost; | ||
100 | uint32_t max_age; | ||
101 | uint32_t hello_time; | ||
102 | uint32_t forward_delay; | ||
103 | uint32_t bridge_max_age; | ||
104 | uint32_t bridge_hello_time; | ||
105 | uint32_t bridge_forward_delay; | ||
106 | uint8_t topology_change; | ||
107 | uint8_t topology_change_detected; | ||
108 | uint8_t root_port; | ||
109 | uint8_t stp_enabled; | ||
110 | uint32_t ageing_time; | ||
111 | uint32_t gc_interval; | ||
112 | uint32_t hello_timer_value; | ||
113 | uint32_t tcn_timer_value; | ||
114 | uint32_t topology_change_timer_value; | ||
115 | uint32_t gc_timer_value; | ||
116 | }; | ||
117 | /* end <linux/if_bridge.h> */ | ||
68 | 118 | ||
69 | /* FIXME: These 4 funcs are not really clean and could be improved */ | 119 | /* FIXME: These 4 funcs are not really clean and could be improved */ |
70 | static ALWAYS_INLINE void bb_strtotimeval(struct timeval *tv, | 120 | static ALWAYS_INLINE void bb_strtotimeval(struct timeval *tv, |
@@ -167,7 +217,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) | |||
167 | arm_ioctl(args, BRCTL_GET_BRIDGES, | 217 | arm_ioctl(args, BRCTL_GET_BRIDGES, |
168 | (unsigned long) bridx, MAX_PORTS); | 218 | (unsigned long) bridx, MAX_PORTS); |
169 | num = xioctl(fd, SIOCGIFBR, args); | 219 | num = xioctl(fd, SIOCGIFBR, args); |
170 | printf("bridge name\tbridge id\t\tSTP enabled\tinterfaces\n"); | 220 | puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces"); |
171 | for (i = 0; i < num; i++) { | 221 | for (i = 0; i < num; i++) { |
172 | char ifname[IFNAMSIZ]; | 222 | char ifname[IFNAMSIZ]; |
173 | int j, tabs; | 223 | int j, tabs; |
@@ -186,7 +236,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) | |||
186 | /* print bridge id */ | 236 | /* print bridge id */ |
187 | x = (unsigned char *) &bi.bridge_id; | 237 | x = (unsigned char *) &bi.bridge_id; |
188 | for (j = 0; j < 8; j++) { | 238 | for (j = 0; j < 8; j++) { |
189 | printf("%.2x", x[j]); | 239 | printf("%02x", x[j]); |
190 | if (j == 1) | 240 | if (j == 1) |
191 | bb_putchar('.'); | 241 | bb_putchar('.'); |
192 | } | 242 | } |
diff --git a/networking/ftpd.c b/networking/ftpd.c index 2351d6dd3..8345ae67c 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c | |||
@@ -377,7 +377,7 @@ ftpdataio_get_pasv_fd(void) | |||
377 | return remote_fd; | 377 | return remote_fd; |
378 | } | 378 | } |
379 | 379 | ||
380 | setsockopt(remote_fd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); | 380 | setsockopt_keepalive(remote_fd); |
381 | return remote_fd; | 381 | return remote_fd; |
382 | } | 382 | } |
383 | 383 | ||
@@ -1186,11 +1186,11 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |||
1186 | , SIG_IGN); | 1186 | , SIG_IGN); |
1187 | 1187 | ||
1188 | /* Set up options on the command socket (do we need these all? why?) */ | 1188 | /* Set up options on the command socket (do we need these all? why?) */ |
1189 | setsockopt(STDIN_FILENO, IPPROTO_TCP, TCP_NODELAY, &const_int_1, sizeof(const_int_1)); | 1189 | setsockopt_1(STDIN_FILENO, IPPROTO_TCP, TCP_NODELAY); |
1190 | setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); | 1190 | setsockopt_keepalive(STDIN_FILENO); |
1191 | /* Telnet protocol over command link may send "urgent" data, | 1191 | /* Telnet protocol over command link may send "urgent" data, |
1192 | * we prefer it to be received in the "normal" data stream: */ | 1192 | * we prefer it to be received in the "normal" data stream: */ |
1193 | setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &const_int_1, sizeof(const_int_1)); | 1193 | setsockopt_1(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE); |
1194 | 1194 | ||
1195 | WRITE_OK(FTP_GREET); | 1195 | WRITE_OK(FTP_GREET); |
1196 | signal(SIGALRM, timeout_handler); | 1196 | signal(SIGALRM, timeout_handler); |
@@ -1223,11 +1223,26 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |||
1223 | #endif | 1223 | #endif |
1224 | argv += optind; | 1224 | argv += optind; |
1225 | if (argv[0]) { | 1225 | if (argv[0]) { |
1226 | const char *basedir = argv[0]; | ||
1226 | #if !BB_MMU | 1227 | #if !BB_MMU |
1227 | G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY); | 1228 | G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY); |
1228 | close_on_exec_on(G.root_fd); | 1229 | close_on_exec_on(G.root_fd); |
1229 | #endif | 1230 | #endif |
1230 | xchroot(argv[0]); | 1231 | if (chroot(basedir) == 0) |
1232 | basedir = "/"; | ||
1233 | #if !BB_MMU | ||
1234 | else { | ||
1235 | close(G.root_fd); | ||
1236 | G.root_fd = -1; | ||
1237 | } | ||
1238 | #endif | ||
1239 | /* | ||
1240 | * If chroot failed, assume that we aren't root, | ||
1241 | * and at least chdir to the specified DIR | ||
1242 | * (older versions were dying with error message). | ||
1243 | * If chroot worked, move current dir to new "/": | ||
1244 | */ | ||
1245 | xchdir(basedir); | ||
1231 | } | 1246 | } |
1232 | 1247 | ||
1233 | #if ENABLE_FEATURE_FTP_AUTHENTICATION | 1248 | #if ENABLE_FEATURE_FTP_AUTHENTICATION |
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c index 0670b2141..607e82713 100644 --- a/networking/ftpgetput.c +++ b/networking/ftpgetput.c | |||
@@ -62,9 +62,6 @@ struct globals { | |||
62 | } FIX_ALIASING; | 62 | } FIX_ALIASING; |
63 | #define G (*(struct globals*)&bb_common_bufsiz1) | 63 | #define G (*(struct globals*)&bb_common_bufsiz1) |
64 | enum { BUFSZ = COMMON_BUFSIZE - offsetof(struct globals, buf) }; | 64 | enum { BUFSZ = COMMON_BUFSIZE - offsetof(struct globals, buf) }; |
65 | struct BUG_G_too_big { | ||
66 | char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; | ||
67 | }; | ||
68 | #define user (G.user ) | 65 | #define user (G.user ) |
69 | #define password (G.password ) | 66 | #define password (G.password ) |
70 | #define lsa (G.lsa ) | 67 | #define lsa (G.lsa ) |
@@ -72,7 +69,9 @@ struct BUG_G_too_big { | |||
72 | #define verbose_flag (G.verbose_flag ) | 69 | #define verbose_flag (G.verbose_flag ) |
73 | #define do_continue (G.do_continue ) | 70 | #define do_continue (G.do_continue ) |
74 | #define buf (G.buf ) | 71 | #define buf (G.buf ) |
75 | #define INIT_G() do { } while (0) | 72 | #define INIT_G() do { \ |
73 | BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ | ||
74 | } while (0) | ||
76 | 75 | ||
77 | 76 | ||
78 | static void ftp_die(const char *msg) NORETURN; | 77 | static void ftp_die(const char *msg) NORETURN; |
diff --git a/networking/httpd.c b/networking/httpd.c index 7a9065fcc..00169c36d 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -1222,12 +1222,12 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1222 | out_cnt += count; | 1222 | out_cnt += count; |
1223 | count = 0; | 1223 | count = 0; |
1224 | /* "Status" header format is: "Status: 302 Redirected\r\n" */ | 1224 | /* "Status" header format is: "Status: 302 Redirected\r\n" */ |
1225 | if (out_cnt >= 8 && memcmp(rbuf, "Status: ", 8) == 0) { | 1225 | if (out_cnt >= 7 && memcmp(rbuf, "Status:", 7) == 0) { |
1226 | /* send "HTTP/1.0 " */ | 1226 | /* send "HTTP/1.0 " */ |
1227 | if (full_write(STDOUT_FILENO, HTTP_200, 9) != 9) | 1227 | if (full_write(STDOUT_FILENO, HTTP_200, 9) != 9) |
1228 | break; | 1228 | break; |
1229 | rbuf += 8; /* skip "Status: " */ | 1229 | rbuf += 7; /* skip "Status:" */ |
1230 | count = out_cnt - 8; | 1230 | count = out_cnt - 7; |
1231 | out_cnt = -1; /* buffering off */ | 1231 | out_cnt = -1; /* buffering off */ |
1232 | } else if (out_cnt >= 4) { | 1232 | } else if (out_cnt >= 4) { |
1233 | /* Did CGI add "HTTP"? */ | 1233 | /* Did CGI add "HTTP"? */ |
@@ -2352,7 +2352,7 @@ static void mini_httpd(int server_socket) | |||
2352 | continue; | 2352 | continue; |
2353 | 2353 | ||
2354 | /* set the KEEPALIVE option to cull dead connections */ | 2354 | /* set the KEEPALIVE option to cull dead connections */ |
2355 | setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); | 2355 | setsockopt_keepalive(n); |
2356 | 2356 | ||
2357 | if (fork() == 0) { | 2357 | if (fork() == 0) { |
2358 | /* child */ | 2358 | /* child */ |
@@ -2395,7 +2395,7 @@ static void mini_httpd_nommu(int server_socket, int argc, char **argv) | |||
2395 | continue; | 2395 | continue; |
2396 | 2396 | ||
2397 | /* set the KEEPALIVE option to cull dead connections */ | 2397 | /* set the KEEPALIVE option to cull dead connections */ |
2398 | setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); | 2398 | setsockopt_keepalive(n); |
2399 | 2399 | ||
2400 | if (vfork() == 0) { | 2400 | if (vfork() == 0) { |
2401 | /* child */ | 2401 | /* child */ |
diff --git a/networking/ifenslave.c b/networking/ifenslave.c index c3be8180b..6b234adee 100644 --- a/networking/ifenslave.c +++ b/networking/ifenslave.c | |||
@@ -577,8 +577,8 @@ int ifenslave_main(int argc UNUSED_PARAM, char **argv) | |||
577 | /* Can't work with this slave, */ | 577 | /* Can't work with this slave, */ |
578 | /* remember the error and skip it */ | 578 | /* remember the error and skip it */ |
579 | bb_perror_msg( | 579 | bb_perror_msg( |
580 | "skipping %s: can't get flags", | 580 | "skipping %s: can't get %s", |
581 | slave_ifname); | 581 | slave_ifname, "flags"); |
582 | res = rv; | 582 | res = rv; |
583 | continue; | 583 | continue; |
584 | } | 584 | } |
@@ -595,8 +595,8 @@ int ifenslave_main(int argc UNUSED_PARAM, char **argv) | |||
595 | /* Can't work with this slave, */ | 595 | /* Can't work with this slave, */ |
596 | /* remember the error and skip it */ | 596 | /* remember the error and skip it */ |
597 | bb_perror_msg( | 597 | bb_perror_msg( |
598 | "skipping %s: can't get settings", | 598 | "skipping %s: can't get %s", |
599 | slave_ifname); | 599 | slave_ifname, "settings"); |
600 | res = rv; | 600 | res = rv; |
601 | continue; | 601 | continue; |
602 | } | 602 | } |
diff --git a/networking/ifplugd.c b/networking/ifplugd.c index fef7a5ac9..f0defb5c8 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c | |||
@@ -38,7 +38,17 @@ | |||
38 | #include <linux/mii.h> | 38 | #include <linux/mii.h> |
39 | #include <linux/ethtool.h> | 39 | #include <linux/ethtool.h> |
40 | #ifdef HAVE_NET_ETHERNET_H | 40 | #ifdef HAVE_NET_ETHERNET_H |
41 | # include <net/ethernet.h> | 41 | /* musl breakage: |
42 | * In file included from /usr/include/net/ethernet.h:10, | ||
43 | * from networking/ifplugd.c:41: | ||
44 | * /usr/include/netinet/if_ether.h:96: error: redefinition of 'struct ethhdr' | ||
45 | * | ||
46 | * Build succeeds without it on musl. Commented it out. | ||
47 | * If on your system you need it, consider removing <linux/ethtool.h> | ||
48 | * and copy-pasting its definitions here (<linux/ethtool.h> is what pulls in | ||
49 | * conflicting definition of struct ethhdr on musl). | ||
50 | */ | ||
51 | /* # include <net/ethernet.h> */ | ||
42 | #endif | 52 | #endif |
43 | #include <linux/netlink.h> | 53 | #include <linux/netlink.h> |
44 | #include <linux/rtnetlink.h> | 54 | #include <linux/rtnetlink.h> |
@@ -48,6 +58,10 @@ | |||
48 | #define __user | 58 | #define __user |
49 | #include <linux/wireless.h> | 59 | #include <linux/wireless.h> |
50 | 60 | ||
61 | #ifndef ETH_ALEN | ||
62 | # define ETH_ALEN 6 | ||
63 | #endif | ||
64 | |||
51 | /* | 65 | /* |
52 | From initial port to busybox, removed most of the redundancy by | 66 | From initial port to busybox, removed most of the redundancy by |
53 | converting implementation of a polymorphic interface to the strict | 67 | converting implementation of a polymorphic interface to the strict |
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 606fc049f..7c45e8927 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -395,7 +395,7 @@ static int FAST_FUNC static_up6(struct interface_defn_t *ifd, execfn *exec) | |||
395 | result = execute("ip addr add %address%/%netmask% dev %iface%[[ label %label%]]", ifd, exec); | 395 | result = execute("ip addr add %address%/%netmask% dev %iface%[[ label %label%]]", ifd, exec); |
396 | result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); | 396 | result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); |
397 | /* Was: "[[ ip ....%gateway% ]]". Removed extra spaces w/o checking */ | 397 | /* Was: "[[ ip ....%gateway% ]]". Removed extra spaces w/o checking */ |
398 | result += execute("[[ip route add ::/0 via %gateway%]][[ prio %metric%]]", ifd, exec); | 398 | result += execute("[[ip route add ::/0 via %gateway%]][[ metric %metric%]]", ifd, exec); |
399 | # else | 399 | # else |
400 | result = execute("ifconfig %iface%[[ media %media%]][[ hw %hwaddress%]][[ mtu %mtu%]] up", ifd, exec); | 400 | result = execute("ifconfig %iface%[[ media %media%]][[ hw %hwaddress%]][[ mtu %mtu%]] up", ifd, exec); |
401 | result += execute("ifconfig %iface% add %address%/%netmask%", ifd, exec); | 401 | result += execute("ifconfig %iface% add %address%/%netmask%", ifd, exec); |
@@ -482,7 +482,7 @@ static int FAST_FUNC static_up(struct interface_defn_t *ifd, execfn *exec) | |||
482 | result = execute("ip addr add %address%/%bnmask%[[ broadcast %broadcast%]] " | 482 | result = execute("ip addr add %address%/%bnmask%[[ broadcast %broadcast%]] " |
483 | "dev %iface%[[ peer %pointopoint%]][[ label %label%]]", ifd, exec); | 483 | "dev %iface%[[ peer %pointopoint%]][[ label %label%]]", ifd, exec); |
484 | result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); | 484 | result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); |
485 | result += execute("[[ip route add default via %gateway% dev %iface%[[ prio %metric%]]]]", ifd, exec); | 485 | result += execute("[[ip route add default via %gateway% dev %iface%[[ metric %metric%]]]]", ifd, exec); |
486 | return ((result == 3) ? 3 : 0); | 486 | return ((result == 3) ? 3 : 0); |
487 | # else | 487 | # else |
488 | /* ifconfig said to set iface up before it processes hw %hwaddress%, | 488 | /* ifconfig said to set iface up before it processes hw %hwaddress%, |
diff --git a/networking/interface.c b/networking/interface.c index b0572d04e..24bd13c57 100644 --- a/networking/interface.c +++ b/networking/interface.c | |||
@@ -89,13 +89,9 @@ struct in6_ifreq { | |||
89 | /* Display an Internet socket address. */ | 89 | /* Display an Internet socket address. */ |
90 | static const char* FAST_FUNC INET_sprint(struct sockaddr *sap, int numeric) | 90 | static const char* FAST_FUNC INET_sprint(struct sockaddr *sap, int numeric) |
91 | { | 91 | { |
92 | static char *buff; /* defaults to NULL */ | ||
93 | |||
94 | if (sap->sa_family == 0xFFFF || sap->sa_family == 0) | 92 | if (sap->sa_family == 0xFFFF || sap->sa_family == 0) |
95 | return "[NONE SET]"; | 93 | return "[NONE SET]"; |
96 | free(buff); | 94 | return auto_string(INET_rresolve((struct sockaddr_in *) sap, numeric, 0xffffff00)); |
97 | buff = INET_rresolve((struct sockaddr_in *) sap, numeric, 0xffffff00); | ||
98 | return buff; | ||
99 | } | 95 | } |
100 | 96 | ||
101 | #ifdef UNUSED_AND_BUGGY | 97 | #ifdef UNUSED_AND_BUGGY |
@@ -171,13 +167,9 @@ static const struct aftype inet_aftype = { | |||
171 | /* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */ | 167 | /* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */ |
172 | static const char* FAST_FUNC INET6_sprint(struct sockaddr *sap, int numeric) | 168 | static const char* FAST_FUNC INET6_sprint(struct sockaddr *sap, int numeric) |
173 | { | 169 | { |
174 | static char *buff; | ||
175 | |||
176 | if (sap->sa_family == 0xFFFF || sap->sa_family == 0) | 170 | if (sap->sa_family == 0xFFFF || sap->sa_family == 0) |
177 | return "[NONE SET]"; | 171 | return "[NONE SET]"; |
178 | free(buff); | 172 | return auto_string(INET6_rresolve((struct sockaddr_in6 *) sap, numeric)); |
179 | buff = INET6_rresolve((struct sockaddr_in6 *) sap, numeric); | ||
180 | return buff; | ||
181 | } | 173 | } |
182 | 174 | ||
183 | #ifdef UNUSED | 175 | #ifdef UNUSED |
@@ -223,13 +215,11 @@ static const struct aftype inet6_aftype = { | |||
223 | /* Display an UNSPEC address. */ | 215 | /* Display an UNSPEC address. */ |
224 | static char* FAST_FUNC UNSPEC_print(unsigned char *ptr) | 216 | static char* FAST_FUNC UNSPEC_print(unsigned char *ptr) |
225 | { | 217 | { |
226 | static char *buff; | 218 | char *buff; |
227 | |||
228 | char *pos; | 219 | char *pos; |
229 | unsigned int i; | 220 | unsigned int i; |
230 | 221 | ||
231 | if (!buff) | 222 | buff = auto_string(xmalloc(sizeof(struct sockaddr) * 3 + 1)); |
232 | buff = xmalloc(sizeof(struct sockaddr) * 3 + 1); | ||
233 | pos = buff; | 223 | pos = buff; |
234 | for (i = 0; i < sizeof(struct sockaddr); i++) { | 224 | for (i = 0; i < sizeof(struct sockaddr); i++) { |
235 | /* careful -- not every libc's sprintf returns # bytes written */ | 225 | /* careful -- not every libc's sprintf returns # bytes written */ |
@@ -712,14 +702,12 @@ static const struct hwtype loop_hwtype = { | |||
712 | /* Display an Ethernet address in readable format. */ | 702 | /* Display an Ethernet address in readable format. */ |
713 | static char* FAST_FUNC ether_print(unsigned char *ptr) | 703 | static char* FAST_FUNC ether_print(unsigned char *ptr) |
714 | { | 704 | { |
715 | static char *buff; | 705 | char *buff; |
716 | |||
717 | free(buff); | ||
718 | buff = xasprintf("%02X:%02X:%02X:%02X:%02X:%02X", | 706 | buff = xasprintf("%02X:%02X:%02X:%02X:%02X:%02X", |
719 | (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377), | 707 | (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377), |
720 | (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377) | 708 | (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377) |
721 | ); | 709 | ); |
722 | return buff; | 710 | return auto_string(buff); |
723 | } | 711 | } |
724 | 712 | ||
725 | static const struct hwtype ether_hwtype = { | 713 | static const struct hwtype ether_hwtype = { |
diff --git a/networking/isrv.c b/networking/isrv.c index 1c6491edd..3673db715 100644 --- a/networking/isrv.c +++ b/networking/isrv.c | |||
@@ -194,7 +194,6 @@ static void handle_accept(isrv_state_t *state, int fd) | |||
194 | remove_peer(state, n); /* unsuccesful peer start */ | 194 | remove_peer(state, n); /* unsuccesful peer start */ |
195 | } | 195 | } |
196 | 196 | ||
197 | void BUG_sizeof_fd_set_is_strange(void); | ||
198 | static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void **)) | 197 | static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void **)) |
199 | { | 198 | { |
200 | enum { LONG_CNT = sizeof(fd_set) / sizeof(long) }; | 199 | enum { LONG_CNT = sizeof(fd_set) / sizeof(long) }; |
@@ -203,8 +202,7 @@ static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void * | |||
203 | /* need to know value at _the beginning_ of this routine */ | 202 | /* need to know value at _the beginning_ of this routine */ |
204 | int fd_cnt = FD_COUNT; | 203 | int fd_cnt = FD_COUNT; |
205 | 204 | ||
206 | if (LONG_CNT * sizeof(long) != sizeof(fd_set)) | 205 | BUILD_BUG_ON(LONG_CNT * sizeof(long) != sizeof(fd_set)); |
207 | BUG_sizeof_fd_set_is_strange(); | ||
208 | 206 | ||
209 | fds_pos = 0; | 207 | fds_pos = 0; |
210 | while (1) { | 208 | while (1) { |
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index a6d5129e7..8845cab91 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c | |||
@@ -137,12 +137,11 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n) | |||
137 | { | 137 | { |
138 | unsigned m_flag = 0; | 138 | unsigned m_flag = 0; |
139 | if (tb[IFLA_LINK]) { | 139 | if (tb[IFLA_LINK]) { |
140 | SPRINT_BUF(b1); | ||
141 | int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); | 140 | int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); |
142 | if (iflink == 0) | 141 | if (iflink == 0) |
143 | printf("@NONE: "); | 142 | printf("@NONE: "); |
144 | else { | 143 | else { |
145 | printf("@%s: ", ll_idx_n2a(iflink, b1)); | 144 | printf("@%s: ", ll_index_to_name(iflink)); |
146 | m_flag = ll_index_to_flags(iflink); | 145 | m_flag = ll_index_to_flags(iflink); |
147 | m_flag = !(m_flag & IFF_UP); | 146 | m_flag = !(m_flag & IFF_UP); |
148 | } | 147 | } |
@@ -158,8 +157,7 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n) | |||
158 | printf("qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); | 157 | printf("qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); |
159 | #ifdef IFLA_MASTER | 158 | #ifdef IFLA_MASTER |
160 | if (tb[IFLA_MASTER]) { | 159 | if (tb[IFLA_MASTER]) { |
161 | SPRINT_BUF(b1); | 160 | printf("master %s ", ll_index_to_name(*(int*)RTA_DATA(tb[IFLA_MASTER]))); |
162 | printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); | ||
163 | } | 161 | } |
164 | #endif | 162 | #endif |
165 | /* IFLA_OPERSTATE was added to kernel with the same commit as IFF_DORMANT */ | 163 | /* IFLA_OPERSTATE was added to kernel with the same commit as IFF_DORMANT */ |
@@ -218,7 +216,6 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, | |||
218 | int len = n->nlmsg_len; | 216 | int len = n->nlmsg_len; |
219 | struct rtattr * rta_tb[IFA_MAX+1]; | 217 | struct rtattr * rta_tb[IFA_MAX+1]; |
220 | char abuf[256]; | 218 | char abuf[256]; |
221 | SPRINT_BUF(b1); | ||
222 | 219 | ||
223 | if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) | 220 | if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) |
224 | return 0; | 221 | return 0; |
@@ -250,7 +247,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, | |||
250 | if (rta_tb[IFA_LABEL]) | 247 | if (rta_tb[IFA_LABEL]) |
251 | label = RTA_DATA(rta_tb[IFA_LABEL]); | 248 | label = RTA_DATA(rta_tb[IFA_LABEL]); |
252 | else | 249 | else |
253 | label = ll_idx_n2a(ifa->ifa_index, b1); | 250 | label = ll_index_to_name(ifa->ifa_index); |
254 | if (fnmatch(G_filter.label, label, 0) != 0) | 251 | if (fnmatch(G_filter.label, label, 0) != 0) |
255 | return 0; | 252 | return 0; |
256 | } | 253 | } |
@@ -325,7 +322,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, | |||
325 | abuf, sizeof(abuf)) | 322 | abuf, sizeof(abuf)) |
326 | ); | 323 | ); |
327 | } | 324 | } |
328 | printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1)); | 325 | printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope)); |
329 | if (ifa->ifa_flags & IFA_F_SECONDARY) { | 326 | if (ifa->ifa_flags & IFA_F_SECONDARY) { |
330 | ifa->ifa_flags &= ~IFA_F_SECONDARY; | 327 | ifa->ifa_flags &= ~IFA_F_SECONDARY; |
331 | printf("secondary "); | 328 | printf("secondary "); |
@@ -556,12 +553,11 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush) | |||
556 | continue; | 553 | continue; |
557 | } | 554 | } |
558 | if (G_filter.label) { | 555 | if (G_filter.label) { |
559 | SPRINT_BUF(b1); | ||
560 | const char *label; | 556 | const char *label; |
561 | if (tb[IFA_LABEL]) | 557 | if (tb[IFA_LABEL]) |
562 | label = RTA_DATA(tb[IFA_LABEL]); | 558 | label = RTA_DATA(tb[IFA_LABEL]); |
563 | else | 559 | else |
564 | label = ll_idx_n2a(ifa->ifa_index, b1); | 560 | label = ll_index_to_name(ifa->ifa_index); |
565 | if (fnmatch(G_filter.label, label, 0) != 0) | 561 | if (fnmatch(G_filter.label, label, 0) != 0) |
566 | continue; | 562 | continue; |
567 | } | 563 | } |
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 170c67b30..6ecd5f719 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c | |||
@@ -87,7 +87,6 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
87 | inet_prefix dst; | 87 | inet_prefix dst; |
88 | inet_prefix src; | 88 | inet_prefix src; |
89 | int host_len = -1; | 89 | int host_len = -1; |
90 | SPRINT_BUF(b1); | ||
91 | 90 | ||
92 | if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) { | 91 | if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) { |
93 | fprintf(stderr, "Not a route: %08x %08x %08x\n", | 92 | fprintf(stderr, "Not a route: %08x %08x %08x\n", |
@@ -236,7 +235,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
236 | printf("Deleted "); | 235 | printf("Deleted "); |
237 | } | 236 | } |
238 | if (r->rtm_type != RTN_UNICAST /* && !G_filter.type - always 0 */) { | 237 | if (r->rtm_type != RTN_UNICAST /* && !G_filter.type - always 0 */) { |
239 | printf("%s ", rtnl_rtntype_n2a(r->rtm_type, b1)); | 238 | printf("%s ", rtnl_rtntype_n2a(r->rtm_type)); |
240 | } | 239 | } |
241 | 240 | ||
242 | if (tb[RTA_DST]) { | 241 | if (tb[RTA_DST]) { |
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c index 8dbe6bd92..774a3e220 100644 --- a/networking/libiproute/iprule.c +++ b/networking/libiproute/iprule.c | |||
@@ -45,7 +45,6 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, | |||
45 | int host_len = -1; | 45 | int host_len = -1; |
46 | struct rtattr * tb[RTA_MAX+1]; | 46 | struct rtattr * tb[RTA_MAX+1]; |
47 | char abuf[256]; | 47 | char abuf[256]; |
48 | SPRINT_BUF(b1); | ||
49 | 48 | ||
50 | if (n->nlmsg_type != RTM_NEWRULE) | 49 | if (n->nlmsg_type != RTM_NEWRULE) |
51 | return 0; | 50 | return 0; |
@@ -110,7 +109,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, | |||
110 | } | 109 | } |
111 | 110 | ||
112 | if (r->rtm_tos) { | 111 | if (r->rtm_tos) { |
113 | printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1)); | 112 | printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos)); |
114 | } | 113 | } |
115 | if (tb[RTA_PROTOINFO]) { | 114 | if (tb[RTA_PROTOINFO]) { |
116 | printf("fwmark %#x ", *(uint32_t*)RTA_DATA(tb[RTA_PROTOINFO])); | 115 | printf("fwmark %#x ", *(uint32_t*)RTA_DATA(tb[RTA_PROTOINFO])); |
@@ -121,7 +120,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, | |||
121 | } | 120 | } |
122 | 121 | ||
123 | if (r->rtm_table) | 122 | if (r->rtm_table) |
124 | printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table, b1)); | 123 | printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table)); |
125 | 124 | ||
126 | if (tb[RTA_FLOW]) { | 125 | if (tb[RTA_FLOW]) { |
127 | uint32_t to = *(uint32_t*)RTA_DATA(tb[RTA_FLOW]); | 126 | uint32_t to = *(uint32_t*)RTA_DATA(tb[RTA_FLOW]); |
@@ -129,10 +128,10 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, | |||
129 | to &= 0xFFFF; | 128 | to &= 0xFFFF; |
130 | if (from) { | 129 | if (from) { |
131 | printf("realms %s/", | 130 | printf("realms %s/", |
132 | rtnl_rtrealm_n2a(from, b1)); | 131 | rtnl_rtrealm_n2a(from)); |
133 | } | 132 | } |
134 | printf("%s ", | 133 | printf("%s ", |
135 | rtnl_rtrealm_n2a(to, b1)); | 134 | rtnl_rtrealm_n2a(to)); |
136 | } | 135 | } |
137 | 136 | ||
138 | if (r->rtm_type == RTN_NAT) { | 137 | if (r->rtm_type == RTN_NAT) { |
@@ -145,7 +144,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, | |||
145 | } else | 144 | } else |
146 | printf("masquerade"); | 145 | printf("masquerade"); |
147 | } else if (r->rtm_type != RTN_UNICAST) | 146 | } else if (r->rtm_type != RTN_UNICAST) |
148 | fputs(rtnl_rtntype_n2a(r->rtm_type, b1), stdout); | 147 | fputs(rtnl_rtntype_n2a(r->rtm_type), stdout); |
149 | 148 | ||
150 | bb_putchar('\n'); | 149 | bb_putchar('\n'); |
151 | /*fflush_all();*/ | 150 | /*fflush_all();*/ |
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c index b54c3c53f..a65d5e579 100644 --- a/networking/libiproute/iptunnel.c +++ b/networking/libiproute/iptunnel.c | |||
@@ -432,13 +432,12 @@ static void print_tunnel(struct ip_tunnel_parm *p) | |||
432 | else | 432 | else |
433 | printf(" ttl inherit "); | 433 | printf(" ttl inherit "); |
434 | if (p->iph.tos) { | 434 | if (p->iph.tos) { |
435 | SPRINT_BUF(b1); | ||
436 | printf(" tos"); | 435 | printf(" tos"); |
437 | if (p->iph.tos & 1) | 436 | if (p->iph.tos & 1) |
438 | printf(" inherit"); | 437 | printf(" inherit"); |
439 | if (p->iph.tos & ~1) | 438 | if (p->iph.tos & ~1) |
440 | printf("%c%s ", p->iph.tos & 1 ? '/' : ' ', | 439 | printf("%c%s ", p->iph.tos & 1 ? '/' : ' ', |
441 | rtnl_dsfield_n2a(p->iph.tos & ~1, b1)); | 440 | rtnl_dsfield_n2a(p->iph.tos & ~1)); |
442 | } | 441 | } |
443 | if (!(p->iph.frag_off & htons(IP_DF))) | 442 | if (!(p->iph.frag_off & htons(IP_DF))) |
444 | printf(" nopmtudisc"); | 443 | printf(" nopmtudisc"); |
diff --git a/networking/libiproute/ll_map.c b/networking/libiproute/ll_map.c index 27cd90f34..e2b85fc7b 100644 --- a/networking/libiproute/ll_map.c +++ b/networking/libiproute/ll_map.c | |||
@@ -86,7 +86,8 @@ int FAST_FUNC ll_remember_index(const struct sockaddr_nl *who UNUSED_PARAM, | |||
86 | return 0; | 86 | return 0; |
87 | } | 87 | } |
88 | 88 | ||
89 | const char FAST_FUNC *ll_idx_n2a(int idx, char *buf) | 89 | static |
90 | const char FAST_FUNC *ll_idx_n2a(int idx/*, char *buf*/) | ||
90 | { | 91 | { |
91 | struct idxmap *im; | 92 | struct idxmap *im; |
92 | 93 | ||
@@ -95,16 +96,15 @@ const char FAST_FUNC *ll_idx_n2a(int idx, char *buf) | |||
95 | im = find_by_index(idx); | 96 | im = find_by_index(idx); |
96 | if (im) | 97 | if (im) |
97 | return im->name; | 98 | return im->name; |
98 | snprintf(buf, 16, "if%d", idx); | 99 | //snprintf(buf, 16, "if%d", idx); |
99 | return buf; | 100 | //return buf; |
101 | return auto_string(xasprintf("if%d", idx)); | ||
100 | } | 102 | } |
101 | 103 | ||
102 | |||
103 | const char FAST_FUNC *ll_index_to_name(int idx) | 104 | const char FAST_FUNC *ll_index_to_name(int idx) |
104 | { | 105 | { |
105 | static char nbuf[16]; | 106 | //static char nbuf[16]; |
106 | 107 | return ll_idx_n2a(idx/*, nbuf*/); | |
107 | return ll_idx_n2a(idx, nbuf); | ||
108 | } | 108 | } |
109 | 109 | ||
110 | #ifdef UNUSED | 110 | #ifdef UNUSED |
diff --git a/networking/libiproute/ll_map.h b/networking/libiproute/ll_map.h index c5d383422..7ea383c81 100644 --- a/networking/libiproute/ll_map.h +++ b/networking/libiproute/ll_map.h | |||
@@ -7,8 +7,8 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |||
7 | int ll_remember_index(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) FAST_FUNC; | 7 | int ll_remember_index(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) FAST_FUNC; |
8 | int ll_init_map(struct rtnl_handle *rth) FAST_FUNC; | 8 | int ll_init_map(struct rtnl_handle *rth) FAST_FUNC; |
9 | int xll_name_to_index(const char *name) FAST_FUNC; | 9 | int xll_name_to_index(const char *name) FAST_FUNC; |
10 | //static: const char *ll_idx_n2a(int idx, char *buf) FAST_FUNC; | ||
10 | const char *ll_index_to_name(int idx) FAST_FUNC; | 11 | const char *ll_index_to_name(int idx) FAST_FUNC; |
11 | const char *ll_idx_n2a(int idx, char *buf) FAST_FUNC; | ||
12 | /* int ll_index_to_type(int idx); */ | 12 | /* int ll_index_to_type(int idx); */ |
13 | unsigned ll_index_to_flags(int idx) FAST_FUNC; | 13 | unsigned ll_index_to_flags(int idx) FAST_FUNC; |
14 | 14 | ||
diff --git a/networking/libiproute/rt_names.c b/networking/libiproute/rt_names.c index c474ab903..51f2e9bdb 100644 --- a/networking/libiproute/rt_names.c +++ b/networking/libiproute/rt_names.c | |||
@@ -10,20 +10,32 @@ | |||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | #include "rt_names.h" | 11 | #include "rt_names.h" |
12 | 12 | ||
13 | #define CONFDIR CONFIG_FEATURE_IP_ROUTE_DIR | ||
14 | |||
13 | typedef struct rtnl_tab_t { | 15 | typedef struct rtnl_tab_t { |
14 | const char *cached_str; | 16 | const char *cached_str; |
15 | unsigned cached_result; | 17 | unsigned cached_result; |
16 | const char *tab[256]; | 18 | /* upstream version switched to a hash table and removed |
19 | * id < 256 limit. For now bbox bumps this array size from 256 | ||
20 | * to 1024. If you plan to change this to a hash table, | ||
21 | * consider merging several hash tables we have (for example, | ||
22 | * awk has resizable one! | ||
23 | */ | ||
24 | #define RT_TABLE_MAX 1023 | ||
25 | const char *tab[RT_TABLE_MAX+1]; | ||
17 | } rtnl_tab_t; | 26 | } rtnl_tab_t; |
18 | 27 | ||
19 | static void rtnl_tab_initialize(const char *file, const char **tab) | 28 | static void rtnl_tab_initialize(const char *file, const char **tab) |
20 | { | 29 | { |
21 | char *token[2]; | 30 | char *token[2]; |
22 | parser_t *parser = config_open2(file, fopen_for_read); | 31 | char fullname[sizeof(CONFDIR"/rt_dsfield") + 8]; |
32 | parser_t *parser; | ||
23 | 33 | ||
34 | sprintf(fullname, CONFDIR"/rt_%s", file); | ||
35 | parser = config_open2(fullname, fopen_for_read); | ||
24 | while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { | 36 | while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { |
25 | unsigned id = bb_strtou(token[0], NULL, 0); | 37 | unsigned id = bb_strtou(token[0], NULL, 0); |
26 | if (id > 256) { | 38 | if (id > RT_TABLE_MAX) { |
27 | bb_error_msg("database %s is corrupted at line %d", | 39 | bb_error_msg("database %s is corrupted at line %d", |
28 | file, parser->lineno); | 40 | file, parser->lineno); |
29 | break; | 41 | break; |
@@ -42,7 +54,7 @@ static int rtnl_a2n(rtnl_tab_t *tab, uint32_t *id, const char *arg, int base) | |||
42 | return 0; | 54 | return 0; |
43 | } | 55 | } |
44 | 56 | ||
45 | for (i = 0; i < 256; i++) { | 57 | for (i = 0; i <= RT_TABLE_MAX; i++) { |
46 | if (tab->tab[i] | 58 | if (tab->tab[i] |
47 | && strcmp(tab->tab[i], arg) == 0 | 59 | && strcmp(tab->tab[i], arg) == 0 |
48 | ) { | 60 | ) { |
@@ -54,7 +66,7 @@ static int rtnl_a2n(rtnl_tab_t *tab, uint32_t *id, const char *arg, int base) | |||
54 | } | 66 | } |
55 | 67 | ||
56 | i = bb_strtou(arg, NULL, base); | 68 | i = bb_strtou(arg, NULL, base); |
57 | if (i > 255) | 69 | if (i > RT_TABLE_MAX) |
58 | return -1; | 70 | return -1; |
59 | *id = i; | 71 | *id = i; |
60 | return 0; | 72 | return 0; |
@@ -85,24 +97,23 @@ static void rtnl_rtprot_initialize(void) | |||
85 | return; | 97 | return; |
86 | rtnl_rtprot_tab = xzalloc(sizeof(*rtnl_rtprot_tab)); | 98 | rtnl_rtprot_tab = xzalloc(sizeof(*rtnl_rtprot_tab)); |
87 | memcpy(rtnl_rtprot_tab->tab, init_tab, sizeof(init_tab)); | 99 | memcpy(rtnl_rtprot_tab->tab, init_tab, sizeof(init_tab)); |
88 | rtnl_tab_initialize("/etc/iproute2/rt_protos", rtnl_rtprot_tab->tab); | 100 | rtnl_tab_initialize("protos", rtnl_rtprot_tab->tab); |
89 | } | 101 | } |
90 | 102 | ||
91 | const char* FAST_FUNC rtnl_rtprot_n2a(int id, char *buf) | 103 | #if 0 /* UNUSED */ |
104 | const char* FAST_FUNC rtnl_rtprot_n2a(int id) | ||
92 | { | 105 | { |
93 | if (id < 0 || id >= 256) { | 106 | if (id < 0 || id > RT_TABLE_MAX) { |
94 | sprintf(buf, "%d", id); | 107 | return itoa(id); |
95 | return buf; | ||
96 | } | 108 | } |
97 | 109 | ||
98 | rtnl_rtprot_initialize(); | 110 | rtnl_rtprot_initialize(); |
99 | 111 | ||
100 | if (rtnl_rtprot_tab->tab[id]) | 112 | if (rtnl_rtprot_tab->tab[id]) |
101 | return rtnl_rtprot_tab->tab[id]; | 113 | return rtnl_rtprot_tab->tab[id]; |
102 | /* buf is SPRINT_BSIZE big */ | 114 | return itoa(id); |
103 | sprintf(buf, "%d", id); | ||
104 | return buf; | ||
105 | } | 115 | } |
116 | #endif | ||
106 | 117 | ||
107 | int FAST_FUNC rtnl_rtprot_a2n(uint32_t *id, char *arg) | 118 | int FAST_FUNC rtnl_rtprot_a2n(uint32_t *id, char *arg) |
108 | { | 119 | { |
@@ -123,23 +134,20 @@ static void rtnl_rtscope_initialize(void) | |||
123 | rtnl_rtscope_tab->tab[254] = "host"; | 134 | rtnl_rtscope_tab->tab[254] = "host"; |
124 | rtnl_rtscope_tab->tab[253] = "link"; | 135 | rtnl_rtscope_tab->tab[253] = "link"; |
125 | rtnl_rtscope_tab->tab[200] = "site"; | 136 | rtnl_rtscope_tab->tab[200] = "site"; |
126 | rtnl_tab_initialize("/etc/iproute2/rt_scopes", rtnl_rtscope_tab->tab); | 137 | rtnl_tab_initialize("scopes", rtnl_rtscope_tab->tab); |
127 | } | 138 | } |
128 | 139 | ||
129 | const char* FAST_FUNC rtnl_rtscope_n2a(int id, char *buf) | 140 | const char* FAST_FUNC rtnl_rtscope_n2a(int id) |
130 | { | 141 | { |
131 | if (id < 0 || id >= 256) { | 142 | if (id < 0 || id > RT_TABLE_MAX) { |
132 | sprintf(buf, "%d", id); | 143 | return itoa(id); |
133 | return buf; | ||
134 | } | 144 | } |
135 | 145 | ||
136 | rtnl_rtscope_initialize(); | 146 | rtnl_rtscope_initialize(); |
137 | 147 | ||
138 | if (rtnl_rtscope_tab->tab[id]) | 148 | if (rtnl_rtscope_tab->tab[id]) |
139 | return rtnl_rtscope_tab->tab[id]; | 149 | return rtnl_rtscope_tab->tab[id]; |
140 | /* buf is SPRINT_BSIZE big */ | 150 | return itoa(id); |
141 | sprintf(buf, "%d", id); | ||
142 | return buf; | ||
143 | } | 151 | } |
144 | 152 | ||
145 | int FAST_FUNC rtnl_rtscope_a2n(uint32_t *id, char *arg) | 153 | int FAST_FUNC rtnl_rtscope_a2n(uint32_t *id, char *arg) |
@@ -156,7 +164,7 @@ static void rtnl_rtrealm_initialize(void) | |||
156 | if (rtnl_rtrealm_tab) return; | 164 | if (rtnl_rtrealm_tab) return; |
157 | rtnl_rtrealm_tab = xzalloc(sizeof(*rtnl_rtrealm_tab)); | 165 | rtnl_rtrealm_tab = xzalloc(sizeof(*rtnl_rtrealm_tab)); |
158 | rtnl_rtrealm_tab->tab[0] = "unknown"; | 166 | rtnl_rtrealm_tab->tab[0] = "unknown"; |
159 | rtnl_tab_initialize("/etc/iproute2/rt_realms", rtnl_rtrealm_tab->tab); | 167 | rtnl_tab_initialize("realms", rtnl_rtrealm_tab->tab); |
160 | } | 168 | } |
161 | 169 | ||
162 | int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg) | 170 | int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg) |
@@ -166,20 +174,17 @@ int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg) | |||
166 | } | 174 | } |
167 | 175 | ||
168 | #if ENABLE_FEATURE_IP_RULE | 176 | #if ENABLE_FEATURE_IP_RULE |
169 | const char* FAST_FUNC rtnl_rtrealm_n2a(int id, char *buf) | 177 | const char* FAST_FUNC rtnl_rtrealm_n2a(int id) |
170 | { | 178 | { |
171 | if (id < 0 || id >= 256) { | 179 | if (id < 0 || id > RT_TABLE_MAX) { |
172 | sprintf(buf, "%d", id); | 180 | return itoa(id); |
173 | return buf; | ||
174 | } | 181 | } |
175 | 182 | ||
176 | rtnl_rtrealm_initialize(); | 183 | rtnl_rtrealm_initialize(); |
177 | 184 | ||
178 | if (rtnl_rtrealm_tab->tab[id]) | 185 | if (rtnl_rtrealm_tab->tab[id]) |
179 | return rtnl_rtrealm_tab->tab[id]; | 186 | return rtnl_rtrealm_tab->tab[id]; |
180 | /* buf is SPRINT_BSIZE big */ | 187 | return itoa(id); |
181 | sprintf(buf, "%d", id); | ||
182 | return buf; | ||
183 | } | 188 | } |
184 | #endif | 189 | #endif |
185 | 190 | ||
@@ -191,23 +196,20 @@ static void rtnl_rtdsfield_initialize(void) | |||
191 | if (rtnl_rtdsfield_tab) return; | 196 | if (rtnl_rtdsfield_tab) return; |
192 | rtnl_rtdsfield_tab = xzalloc(sizeof(*rtnl_rtdsfield_tab)); | 197 | rtnl_rtdsfield_tab = xzalloc(sizeof(*rtnl_rtdsfield_tab)); |
193 | rtnl_rtdsfield_tab->tab[0] = "0"; | 198 | rtnl_rtdsfield_tab->tab[0] = "0"; |
194 | rtnl_tab_initialize("/etc/iproute2/rt_dsfield", rtnl_rtdsfield_tab->tab); | 199 | rtnl_tab_initialize("dsfield", rtnl_rtdsfield_tab->tab); |
195 | } | 200 | } |
196 | 201 | ||
197 | const char* FAST_FUNC rtnl_dsfield_n2a(int id, char *buf) | 202 | const char* FAST_FUNC rtnl_dsfield_n2a(int id) |
198 | { | 203 | { |
199 | if (id < 0 || id >= 256) { | 204 | if (id < 0 || id > RT_TABLE_MAX) { |
200 | sprintf(buf, "%d", id); | 205 | return itoa(id); |
201 | return buf; | ||
202 | } | 206 | } |
203 | 207 | ||
204 | rtnl_rtdsfield_initialize(); | 208 | rtnl_rtdsfield_initialize(); |
205 | 209 | ||
206 | if (rtnl_rtdsfield_tab->tab[id]) | 210 | if (rtnl_rtdsfield_tab->tab[id]) |
207 | return rtnl_rtdsfield_tab->tab[id]; | 211 | return rtnl_rtdsfield_tab->tab[id]; |
208 | /* buf is SPRINT_BSIZE big */ | 212 | return itoa(id); |
209 | sprintf(buf, "0x%02x", id); | ||
210 | return buf; | ||
211 | } | 213 | } |
212 | 214 | ||
213 | int FAST_FUNC rtnl_dsfield_a2n(uint32_t *id, char *arg) | 215 | int FAST_FUNC rtnl_dsfield_a2n(uint32_t *id, char *arg) |
@@ -222,29 +224,28 @@ static rtnl_tab_t *rtnl_rttable_tab; | |||
222 | 224 | ||
223 | static void rtnl_rttable_initialize(void) | 225 | static void rtnl_rttable_initialize(void) |
224 | { | 226 | { |
225 | if (rtnl_rtdsfield_tab) return; | 227 | if (rtnl_rttable_tab) |
228 | return; | ||
229 | |||
226 | rtnl_rttable_tab = xzalloc(sizeof(*rtnl_rttable_tab)); | 230 | rtnl_rttable_tab = xzalloc(sizeof(*rtnl_rttable_tab)); |
227 | rtnl_rttable_tab->tab[0] = "unspec"; | 231 | rtnl_rttable_tab->tab[0] = "unspec"; |
228 | rtnl_rttable_tab->tab[255] = "local"; | 232 | rtnl_rttable_tab->tab[255] = "local"; |
229 | rtnl_rttable_tab->tab[254] = "main"; | 233 | rtnl_rttable_tab->tab[254] = "main"; |
230 | rtnl_rttable_tab->tab[253] = "default"; | 234 | rtnl_rttable_tab->tab[253] = "default"; |
231 | rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab->tab); | 235 | rtnl_tab_initialize("tables", rtnl_rttable_tab->tab); |
232 | } | 236 | } |
233 | 237 | ||
234 | const char* FAST_FUNC rtnl_rttable_n2a(int id, char *buf) | 238 | const char* FAST_FUNC rtnl_rttable_n2a(int id) |
235 | { | 239 | { |
236 | if (id < 0 || id >= 256) { | 240 | if (id < 0 || id > RT_TABLE_MAX) { |
237 | sprintf(buf, "%d", id); | 241 | return itoa(id); |
238 | return buf; | ||
239 | } | 242 | } |
240 | 243 | ||
241 | rtnl_rttable_initialize(); | 244 | rtnl_rttable_initialize(); |
242 | 245 | ||
243 | if (rtnl_rttable_tab->tab[id]) | 246 | if (rtnl_rttable_tab->tab[id]) |
244 | return rtnl_rttable_tab->tab[id]; | 247 | return rtnl_rttable_tab->tab[id]; |
245 | /* buf is SPRINT_BSIZE big */ | 248 | return itoa(id); |
246 | sprintf(buf, "%d", id); | ||
247 | return buf; | ||
248 | } | 249 | } |
249 | 250 | ||
250 | int FAST_FUNC rtnl_rttable_a2n(uint32_t *id, char *arg) | 251 | int FAST_FUNC rtnl_rttable_a2n(uint32_t *id, char *arg) |
diff --git a/networking/libiproute/rt_names.h b/networking/libiproute/rt_names.h index e73aa851c..29932d6a4 100644 --- a/networking/libiproute/rt_names.h +++ b/networking/libiproute/rt_names.h | |||
@@ -4,12 +4,11 @@ | |||
4 | 4 | ||
5 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | 5 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN |
6 | 6 | ||
7 | /* buf is SPRINT_BSIZE big */ | 7 | extern const char* rtnl_rtprot_n2a(int id) FAST_FUNC; |
8 | extern const char* rtnl_rtprot_n2a(int id, char *buf) FAST_FUNC; | 8 | extern const char* rtnl_rtscope_n2a(int id) FAST_FUNC; |
9 | extern const char* rtnl_rtscope_n2a(int id, char *buf) FAST_FUNC; | 9 | extern const char* rtnl_rtrealm_n2a(int id) FAST_FUNC; |
10 | extern const char* rtnl_rtrealm_n2a(int id, char *buf) FAST_FUNC; | 10 | extern const char* rtnl_dsfield_n2a(int id) FAST_FUNC; |
11 | extern const char* rtnl_dsfield_n2a(int id, char *buf) FAST_FUNC; | 11 | extern const char* rtnl_rttable_n2a(int id) FAST_FUNC; |
12 | extern const char* rtnl_rttable_n2a(int id, char *buf) FAST_FUNC; | ||
13 | extern int rtnl_rtprot_a2n(uint32_t *id, char *arg) FAST_FUNC; | 12 | extern int rtnl_rtprot_a2n(uint32_t *id, char *arg) FAST_FUNC; |
14 | extern int rtnl_rtscope_a2n(uint32_t *id, char *arg) FAST_FUNC; | 13 | extern int rtnl_rtscope_a2n(uint32_t *id, char *arg) FAST_FUNC; |
15 | extern int rtnl_rtrealm_a2n(uint32_t *id, char *arg) FAST_FUNC; | 14 | extern int rtnl_rtrealm_a2n(uint32_t *id, char *arg) FAST_FUNC; |
diff --git a/networking/libiproute/rtm_map.c b/networking/libiproute/rtm_map.c index 3bab53baf..c763da049 100644 --- a/networking/libiproute/rtm_map.c +++ b/networking/libiproute/rtm_map.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "rt_names.h" | 12 | #include "rt_names.h" |
13 | #include "utils.h" | 13 | #include "utils.h" |
14 | 14 | ||
15 | const char* FAST_FUNC rtnl_rtntype_n2a(int id, char *buf) | 15 | const char* FAST_FUNC rtnl_rtntype_n2a(int id) |
16 | { | 16 | { |
17 | switch (id) { | 17 | switch (id) { |
18 | case RTN_UNSPEC: | 18 | case RTN_UNSPEC: |
@@ -40,9 +40,7 @@ const char* FAST_FUNC rtnl_rtntype_n2a(int id, char *buf) | |||
40 | case RTN_XRESOLVE: | 40 | case RTN_XRESOLVE: |
41 | return "xresolve"; | 41 | return "xresolve"; |
42 | default: | 42 | default: |
43 | /* buf is SPRINT_BSIZE big */ | 43 | return itoa(id); |
44 | sprintf(buf, "%d", id); | ||
45 | return buf; | ||
46 | } | 44 | } |
47 | } | 45 | } |
48 | 46 | ||
diff --git a/networking/libiproute/rtm_map.h b/networking/libiproute/rtm_map.h index 4377bd590..63b665169 100644 --- a/networking/libiproute/rtm_map.h +++ b/networking/libiproute/rtm_map.h | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | 5 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN |
6 | 6 | ||
7 | const char *rtnl_rtntype_n2a(int id, char *buf) FAST_FUNC; | 7 | const char *rtnl_rtntype_n2a(int id) FAST_FUNC; |
8 | int rtnl_rtntype_a2n(int *id, char *arg) FAST_FUNC; | 8 | int rtnl_rtntype_a2n(int *id, char *arg) FAST_FUNC; |
9 | 9 | ||
10 | int get_rt_realms(uint32_t *realms, char *arg) FAST_FUNC; | 10 | int get_rt_realms(uint32_t *realms, char *arg) FAST_FUNC; |
diff --git a/networking/nbd-client.c b/networking/nbd-client.c index cadda5261..a601430b6 100644 --- a/networking/nbd-client.c +++ b/networking/nbd-client.c | |||
@@ -83,7 +83,7 @@ int nbdclient_main(int argc, char **argv) | |||
83 | 83 | ||
84 | // Find and connect to server | 84 | // Find and connect to server |
85 | sock = create_and_connect_stream_or_die(host, xatou16(port)); | 85 | sock = create_and_connect_stream_or_die(host, xatou16(port)); |
86 | setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &const_int_1, sizeof(const_int_1)); | 86 | setsockopt_1(sock, IPPROTO_TCP, TCP_NODELAY); |
87 | 87 | ||
88 | // Log on to the server | 88 | // Log on to the server |
89 | xread(sock, &nbd_header, 8+8+8+4 + 124); | 89 | xread(sock, &nbd_header, 8+8+8+4 + 124); |
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index b28d05f51..471ae1a12 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c | |||
@@ -863,8 +863,8 @@ int nc_main(int argc UNUSED_PARAM, char **argv) | |||
863 | xbind(netfd, &ouraddr->u.sa, ouraddr->len); | 863 | xbind(netfd, &ouraddr->u.sa, ouraddr->len); |
864 | } | 864 | } |
865 | #if 0 | 865 | #if 0 |
866 | setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); | 866 | setsockopt_SOL_SOCKET_int(netfd, SO_RCVBUF, o_rcvbuf); |
867 | setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); | 867 | setsockopt_SOL_SOCKET_int(netfd, SO_SNDBUF, o_sndbuf); |
868 | #endif | 868 | #endif |
869 | 869 | ||
870 | #ifdef BLOAT | 870 | #ifdef BLOAT |
diff --git a/networking/ntpd.c b/networking/ntpd.c index b5120a70d..9732c9b1a 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -405,8 +405,6 @@ struct globals { | |||
405 | }; | 405 | }; |
406 | #define G (*ptr_to_globals) | 406 | #define G (*ptr_to_globals) |
407 | 407 | ||
408 | static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY; | ||
409 | |||
410 | 408 | ||
411 | #define VERB1 if (MAX_VERBOSE && G.verbose) | 409 | #define VERB1 if (MAX_VERBOSE && G.verbose) |
412 | #define VERB2 if (MAX_VERBOSE >= 2 && G.verbose >= 2) | 410 | #define VERB2 if (MAX_VERBOSE >= 2 && G.verbose >= 2) |
@@ -837,7 +835,7 @@ send_query_to_peer(peer_t *p) | |||
837 | #if ENABLE_FEATURE_IPV6 | 835 | #if ENABLE_FEATURE_IPV6 |
838 | if (family == AF_INET) | 836 | if (family == AF_INET) |
839 | #endif | 837 | #endif |
840 | setsockopt(fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY)); | 838 | setsockopt_int(fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); |
841 | free(local_lsa); | 839 | free(local_lsa); |
842 | } | 840 | } |
843 | 841 | ||
@@ -2186,7 +2184,7 @@ static NOINLINE void ntp_init(char **argv) | |||
2186 | xfunc_die(); | 2184 | xfunc_die(); |
2187 | } | 2185 | } |
2188 | socket_want_pktinfo(G_listen_fd); | 2186 | socket_want_pktinfo(G_listen_fd); |
2189 | setsockopt(G_listen_fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY)); | 2187 | setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); |
2190 | } | 2188 | } |
2191 | #endif | 2189 | #endif |
2192 | if (!(opts & OPT_n)) { | 2190 | if (!(opts & OPT_n)) { |
diff --git a/networking/ping.c b/networking/ping.c index c475395e7..0eb1ae799 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -247,7 +247,7 @@ static void ping6(len_and_sockaddr *lsa) | |||
247 | pkt->icmp6_type = ICMP6_ECHO_REQUEST; | 247 | pkt->icmp6_type = ICMP6_ECHO_REQUEST; |
248 | 248 | ||
249 | sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); | 249 | sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); |
250 | setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt)); | 250 | setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); |
251 | 251 | ||
252 | xsendto(pingsock, G.packet, DEFDATALEN + sizeof(struct icmp6_hdr), &lsa->u.sa, lsa->len); | 252 | xsendto(pingsock, G.packet, DEFDATALEN + sizeof(struct icmp6_hdr), &lsa->u.sa, lsa->len); |
253 | 253 | ||
@@ -396,10 +396,8 @@ struct globals { | |||
396 | #define dotted (G.dotted ) | 396 | #define dotted (G.dotted ) |
397 | #define pingaddr (G.pingaddr ) | 397 | #define pingaddr (G.pingaddr ) |
398 | #define rcvd_tbl (G.rcvd_tbl ) | 398 | #define rcvd_tbl (G.rcvd_tbl ) |
399 | void BUG_ping_globals_too_big(void); | ||
400 | #define INIT_G() do { \ | 399 | #define INIT_G() do { \ |
401 | if (sizeof(G) > COMMON_BUFSIZE) \ | 400 | BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ |
402 | BUG_ping_globals_too_big(); \ | ||
403 | datalen = DEFDATALEN; \ | 401 | datalen = DEFDATALEN; \ |
404 | timeout = MAXWAIT; \ | 402 | timeout = MAXWAIT; \ |
405 | tmin = UINT_MAX; \ | 403 | tmin = UINT_MAX; \ |
@@ -700,12 +698,12 @@ static void ping4(len_and_sockaddr *lsa) | |||
700 | /* set recv buf (needed if we can get lots of responses: flood ping, | 698 | /* set recv buf (needed if we can get lots of responses: flood ping, |
701 | * broadcast ping etc) */ | 699 | * broadcast ping etc) */ |
702 | sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */ | 700 | sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */ |
703 | setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt)); | 701 | setsockopt_SOL_SOCKET_int(pingsock, SO_RCVBUF, sockopt); |
704 | 702 | ||
705 | if (opt_ttl != 0) { | 703 | if (opt_ttl != 0) { |
706 | setsockopt(pingsock, IPPROTO_IP, IP_TTL, &opt_ttl, sizeof(opt_ttl)); | 704 | setsockopt_int(pingsock, IPPROTO_IP, IP_TTL, opt_ttl); |
707 | /* above doesnt affect packets sent to bcast IP, so... */ | 705 | /* above doesnt affect packets sent to bcast IP, so... */ |
708 | setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, &opt_ttl, sizeof(opt_ttl)); | 706 | setsockopt_int(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, opt_ttl); |
709 | } | 707 | } |
710 | 708 | ||
711 | signal(SIGINT, print_stats_and_exit); | 709 | signal(SIGINT, print_stats_and_exit); |
@@ -732,7 +730,6 @@ static void ping4(len_and_sockaddr *lsa) | |||
732 | } | 730 | } |
733 | } | 731 | } |
734 | #if ENABLE_PING6 | 732 | #if ENABLE_PING6 |
735 | extern int BUG_bad_offsetof_icmp6_cksum(void); | ||
736 | static void ping6(len_and_sockaddr *lsa) | 733 | static void ping6(len_and_sockaddr *lsa) |
737 | { | 734 | { |
738 | int sockopt; | 735 | int sockopt; |
@@ -756,7 +753,7 @@ static void ping6(len_and_sockaddr *lsa) | |||
756 | } | 753 | } |
757 | if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, | 754 | if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, |
758 | sizeof(filt)) < 0) | 755 | sizeof(filt)) < 0) |
759 | bb_error_msg_and_die("setsockopt(ICMP6_FILTER)"); | 756 | bb_error_msg_and_die("setsockopt(%s)", "ICMP6_FILTER"); |
760 | } | 757 | } |
761 | #endif /*ICMP6_FILTER*/ | 758 | #endif /*ICMP6_FILTER*/ |
762 | 759 | ||
@@ -766,15 +763,14 @@ static void ping6(len_and_sockaddr *lsa) | |||
766 | /* set recv buf (needed if we can get lots of responses: flood ping, | 763 | /* set recv buf (needed if we can get lots of responses: flood ping, |
767 | * broadcast ping etc) */ | 764 | * broadcast ping etc) */ |
768 | sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */ | 765 | sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */ |
769 | setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt)); | 766 | setsockopt_SOL_SOCKET_int(pingsock, SO_RCVBUF, sockopt); |
770 | 767 | ||
771 | sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); | 768 | sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); |
772 | if (offsetof(struct icmp6_hdr, icmp6_cksum) != 2) | 769 | BUILD_BUG_ON(offsetof(struct icmp6_hdr, icmp6_cksum) != 2); |
773 | BUG_bad_offsetof_icmp6_cksum(); | 770 | setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); |
774 | setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt)); | ||
775 | 771 | ||
776 | /* request ttl info to be returned in ancillary data */ | 772 | /* request ttl info to be returned in ancillary data */ |
777 | setsockopt(pingsock, SOL_IPV6, IPV6_HOPLIMIT, &const_int_1, sizeof(const_int_1)); | 773 | setsockopt_1(pingsock, SOL_IPV6, IPV6_HOPLIMIT); |
778 | 774 | ||
779 | if (if_index) | 775 | if (if_index) |
780 | pingaddr.sin6.sin6_scope_id = if_index; | 776 | pingaddr.sin6.sin6_scope_id = if_index; |
diff --git a/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 b/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 new file mode 100755 index 000000000..50b6102d9 --- /dev/null +++ b/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 | |||
@@ -0,0 +1,22 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # How to configure & build a static wolfssl-3.6.8 library | ||
4 | # suitable for static build of ssl_helper. | ||
5 | |||
6 | export CC="i686-gcc" | ||
7 | export CFLAGS="\ | ||
8 | -Os \ | ||
9 | -static \ | ||
10 | -fomit-frame-pointer \ | ||
11 | -falign-functions=1 -falign-labels=1 -falign-loops=1 -falign-jumps=1 \ | ||
12 | -ffunction-sections -fdata-sections \ | ||
13 | " | ||
14 | |||
15 | ./configure \ | ||
16 | --host=i686 \ | ||
17 | --enable-static \ | ||
18 | --enable-singlethreaded \ | ||
19 | --disable-shared \ | ||
20 | || exit $? | ||
21 | |||
22 | make | ||
diff --git a/networking/ssl_helper-wolfssl/README b/networking/ssl_helper-wolfssl/README new file mode 100644 index 000000000..58a381c20 --- /dev/null +++ b/networking/ssl_helper-wolfssl/README | |||
@@ -0,0 +1,20 @@ | |||
1 | A small SSL helper for busybox wget. | ||
2 | |||
3 | Precompiled static binary may be found in | ||
4 | http://busybox.net/downloads/binaries/ | ||
5 | |||
6 | Build instructions: | ||
7 | |||
8 | * Unpack wolfssl-3.6.8.zip | ||
9 | * Build it: | ||
10 | ./configure --enable-static --disable-shared && make | ||
11 | * Drop this directory into wolfssl-3.6.8/ssl_helper | ||
12 | * Run ssl_helper.sh to compile and link the helper | ||
13 | |||
14 | Usage: "ssl_helper -d FILE_DESCRIPTOR" where FILE_DESCRIPTOR is open to the peer. | ||
15 | |||
16 | In bash, you can do it this way: | ||
17 | $ ssl_helper -d3 3<>/dev/tcp/HOST/PORT | ||
18 | |||
19 | Stdin will be SSL-encrypted and sent to FILE_DESCRIPTOR. | ||
20 | Data from FILE_DESCRIPTOR will be decrypted and sent to stdout. | ||
diff --git a/networking/ssl_helper-wolfssl/ssl_helper.c b/networking/ssl_helper-wolfssl/ssl_helper.c new file mode 100644 index 000000000..38b7b56c6 --- /dev/null +++ b/networking/ssl_helper-wolfssl/ssl_helper.c | |||
@@ -0,0 +1,480 @@ | |||
1 | /* | ||
2 | * Adapted from: | ||
3 | * | ||
4 | * client.c | ||
5 | * | ||
6 | * Copyright (C) 2006-2015 wolfSSL Inc. | ||
7 | * | ||
8 | * This file is part of wolfSSL. (formerly known as CyaSSL) | ||
9 | * | ||
10 | * wolfSSL is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * wolfSSL is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA | ||
23 | */ | ||
24 | #include <stdlib.h> | ||
25 | #include <unistd.h> | ||
26 | #include <stdarg.h> | ||
27 | #include <string.h> | ||
28 | #include <errno.h> | ||
29 | #include <fcntl.h> | ||
30 | #include <stdio.h> | ||
31 | #include <time.h> | ||
32 | #include <poll.h> | ||
33 | #include <sys/socket.h> | ||
34 | |||
35 | #include <wolfssl/wolfcrypt/types.h> | ||
36 | #include <wolfssl/ssl.h> | ||
37 | |||
38 | #if 0 | ||
39 | # define dbg(...) say(__VA_ARGS__) | ||
40 | #else | ||
41 | # define dbg(...) ((void)0) | ||
42 | #endif | ||
43 | |||
44 | static ssize_t safe_write(int fd, const void *buf, size_t count) | ||
45 | { | ||
46 | ssize_t n; | ||
47 | |||
48 | do { | ||
49 | n = write(fd, buf, count); | ||
50 | } while (n < 0 && errno == EINTR); | ||
51 | |||
52 | return n; | ||
53 | } | ||
54 | |||
55 | static ssize_t full_write(int fd, const void *buf, size_t len) | ||
56 | { | ||
57 | ssize_t cc; | ||
58 | ssize_t total; | ||
59 | |||
60 | total = 0; | ||
61 | |||
62 | while (len) { | ||
63 | cc = safe_write(fd, buf, len); | ||
64 | |||
65 | if (cc < 0) { | ||
66 | if (total) { | ||
67 | /* we already wrote some! */ | ||
68 | /* user can do another write to know the error code */ | ||
69 | return total; | ||
70 | } | ||
71 | return cc; /* write() returns -1 on failure. */ | ||
72 | } | ||
73 | |||
74 | total += cc; | ||
75 | buf = ((const char *)buf) + cc; | ||
76 | len -= cc; | ||
77 | } | ||
78 | |||
79 | return total; | ||
80 | } | ||
81 | |||
82 | static void say(const char *s, ...) | ||
83 | { | ||
84 | char buf[256]; | ||
85 | va_list p; | ||
86 | int sz; | ||
87 | |||
88 | va_start(p, s); | ||
89 | sz = vsnprintf(buf, sizeof(buf), s, p); | ||
90 | full_write(STDERR_FILENO, buf, sz >= 0 && sz < sizeof(buf) ? sz : strlen(buf)); | ||
91 | va_end(p); | ||
92 | } | ||
93 | |||
94 | static void die(const char *s, ...) | ||
95 | { | ||
96 | char buf[256]; | ||
97 | va_list p; | ||
98 | int sz; | ||
99 | |||
100 | va_start(p, s); | ||
101 | sz = vsnprintf(buf, sizeof(buf), s, p); | ||
102 | full_write(STDERR_FILENO, buf, sz >= 0 && sz < sizeof(buf) ? sz : strlen(buf)); | ||
103 | exit(1); | ||
104 | va_end(p); | ||
105 | } | ||
106 | |||
107 | static void err_sys(const char *msg) | ||
108 | { | ||
109 | die("%s\n", msg); | ||
110 | } | ||
111 | |||
112 | /* ==== */ | ||
113 | |||
114 | #if 0 | ||
115 | static void showPeer(WOLFSSL* ssl) | ||
116 | { | ||
117 | WOLFSSL_CIPHER* cipher; | ||
118 | WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl); | ||
119 | if (peer) | ||
120 | ShowX509(peer, "peer's cert info:"); | ||
121 | else | ||
122 | say("peer has no cert!\n"); | ||
123 | say("SSL version is %s\n", wolfSSL_get_version(ssl)); | ||
124 | |||
125 | cipher = wolfSSL_get_current_cipher(ssl); | ||
126 | say("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher)); | ||
127 | |||
128 | { | ||
129 | WOLFSSL_X509_CHAIN* chain = wolfSSL_get_peer_chain(ssl); | ||
130 | int count = wolfSSL_get_chain_count(chain); | ||
131 | int i; | ||
132 | |||
133 | for (i = 0; i < count; i++) { | ||
134 | int length; | ||
135 | unsigned char buffer[3072]; | ||
136 | WOLFSSL_X509* chainX509; | ||
137 | |||
138 | wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length); | ||
139 | buffer[length] = 0; | ||
140 | say("cert %d has length %d data = \n%s\n", i, length, buffer); | ||
141 | |||
142 | chainX509 = wolfSSL_get_chain_X509(chain, i); | ||
143 | if (chainX509) | ||
144 | ShowX509(chainX509, "session cert info:"); | ||
145 | else | ||
146 | say("get_chain_X509 failed\n"); | ||
147 | wolfSSL_FreeX509(chainX509); | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | #endif | ||
152 | |||
153 | WOLFSSL *prepare(int sockfd) | ||
154 | { | ||
155 | WOLFSSL_METHOD* method; | ||
156 | WOLFSSL_CTX* ctx; | ||
157 | WOLFSSL* ssl; | ||
158 | |||
159 | wolfSSL_Init(); | ||
160 | |||
161 | method = wolfTLSv1_1_client_method(); | ||
162 | if (method == NULL) | ||
163 | err_sys("out of memory"); | ||
164 | ctx = wolfSSL_CTX_new(method); | ||
165 | if (ctx == NULL) | ||
166 | err_sys("out of memory"); | ||
167 | // if (cipherList) | ||
168 | // if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) | ||
169 | // err_sys("client can't set cipher list 1"); | ||
170 | |||
171 | // if (fewerPackets) | ||
172 | // wolfSSL_CTX_set_group_messages(ctx); | ||
173 | |||
174 | //#ifndef NO_DH | ||
175 | // wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits); | ||
176 | //#endif | ||
177 | |||
178 | // if (usePsk) { | ||
179 | // wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb); | ||
180 | // if (cipherList == NULL) { | ||
181 | // const char *defaultCipherList; | ||
182 | //#if defined(HAVE_AESGCM) && !defined(NO_DH) | ||
183 | // defaultCipherList = "DHE-PSK-AES128-GCM-SHA256"; | ||
184 | //#elif defined(HAVE_NULL_CIPHER) | ||
185 | // defaultCipherList = "PSK-NULL-SHA256"; | ||
186 | //#else | ||
187 | // defaultCipherList = "PSK-AES128-CBC-SHA256"; | ||
188 | //#endif | ||
189 | // if (wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList) != SSL_SUCCESS) | ||
190 | // err_sys("client can't set cipher list 2"); | ||
191 | // } | ||
192 | // useClientCert = 0; | ||
193 | // } | ||
194 | |||
195 | // if (useAnon) { | ||
196 | // if (cipherList == NULL) { | ||
197 | // wolfSSL_CTX_allow_anon_cipher(ctx); | ||
198 | // if (wolfSSL_CTX_set_cipher_list(ctx,"ADH-AES128-SHA") != SSL_SUCCESS) | ||
199 | // err_sys("client can't set cipher list 4"); | ||
200 | // } | ||
201 | // useClientCert = 0; | ||
202 | // } | ||
203 | |||
204 | //#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) | ||
205 | // wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); | ||
206 | //#endif | ||
207 | |||
208 | // if (useOcsp) { | ||
209 | // if (ocspUrl != NULL) { | ||
210 | // wolfSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl); | ||
211 | // wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE | ||
212 | // | WOLFSSL_OCSP_URL_OVERRIDE); | ||
213 | // } | ||
214 | // else | ||
215 | // wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE); | ||
216 | // } | ||
217 | // | ||
218 | //#ifdef USER_CA_CB | ||
219 | // wolfSSL_CTX_SetCACb(ctx, CaCb); | ||
220 | //#endif | ||
221 | // | ||
222 | //#ifdef VERIFY_CALLBACK | ||
223 | // wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify); | ||
224 | //#endif | ||
225 | //#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) | ||
226 | // if (useClientCert) { | ||
227 | // if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert) != SSL_SUCCESS) | ||
228 | // err_sys("can't load client cert file, check file and run from" | ||
229 | // " wolfSSL home dir"); | ||
230 | // if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) | ||
231 | // err_sys("can't load client private key file, check file and run " | ||
232 | // "from wolfSSL home dir"); | ||
233 | // } | ||
234 | // | ||
235 | // if (!usePsk && !useAnon) { | ||
236 | // if (wolfSSL_CTX_load_verify_locations(ctx, verifyCert,0) != SSL_SUCCESS) | ||
237 | // err_sys("can't load ca file, Please run from wolfSSL home dir"); | ||
238 | //#ifdef HAVE_ECC | ||
239 | // /* load ecc verify too, echoserver uses it by default w/ ecc */ | ||
240 | // if (wolfSSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS) | ||
241 | // err_sys("can't load ecc ca file, Please run from wolfSSL home dir"); | ||
242 | //#endif | ||
243 | // } | ||
244 | //#endif /* !NO_FILESYSTEM && !NO_CERTS */ | ||
245 | |||
246 | //#if !defined(NO_CERTS) | ||
247 | // if (!usePsk && !useAnon && doPeerCheck == 0) | ||
248 | // wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); | ||
249 | // if (!usePsk && !useAnon && overrideDateErrors == 1) | ||
250 | // wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myDateCb); | ||
251 | //#endif | ||
252 | |||
253 | wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); | ||
254 | |||
255 | //#ifdef HAVE_SNI | ||
256 | // if (sniHostName) | ||
257 | // if (wolfSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName)) != SSL_SUCCESS) | ||
258 | // err_sys("UseSNI failed"); | ||
259 | //#endif | ||
260 | |||
261 | //#ifdef HAVE_MAX_FRAGMENT | ||
262 | // if (maxFragment) | ||
263 | // if (wolfSSL_CTX_UseMaxFragment(ctx, maxFragment) != SSL_SUCCESS) | ||
264 | // err_sys("UseMaxFragment failed"); | ||
265 | //#endif | ||
266 | //#ifdef HAVE_TRUNCATED_HMAC | ||
267 | // if (truncatedHMAC) | ||
268 | // if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS) | ||
269 | // err_sys("UseTruncatedHMAC failed"); | ||
270 | //#endif | ||
271 | //#ifdef HAVE_SESSION_TICKET | ||
272 | // if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS) | ||
273 | // err_sys("UseSessionTicket failed"); | ||
274 | //#endif | ||
275 | |||
276 | //#if defined(WOLFSSL_MDK_ARM) | ||
277 | // wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); | ||
278 | //#endif | ||
279 | |||
280 | ssl = wolfSSL_new(ctx); | ||
281 | if (ssl == NULL) | ||
282 | err_sys("out of memory"); | ||
283 | |||
284 | //#ifdef HAVE_SESSION_TICKET | ||
285 | // wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session"); | ||
286 | //#endif | ||
287 | |||
288 | // if (doDTLS) { | ||
289 | // SOCKADDR_IN_T addr; | ||
290 | // build_addr(&addr, host, port, 1); | ||
291 | // wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); | ||
292 | // tcp_socket(&sockfd, 1); | ||
293 | // } wlse { | ||
294 | // tcp_connect(&sockfd, host, port, 0); | ||
295 | // } | ||
296 | |||
297 | //#ifdef HAVE_POLY1305 | ||
298 | // /* use old poly to connect with google server */ | ||
299 | // if (!XSTRNCMP(domain, "www.google.com", 14)) { | ||
300 | // if (wolfSSL_use_old_poly(ssl, 1) != 0) | ||
301 | // err_sys("unable to set to old poly"); | ||
302 | // } | ||
303 | //#endif | ||
304 | |||
305 | wolfSSL_set_fd(ssl, sockfd); | ||
306 | |||
307 | //#ifdef HAVE_CRL | ||
308 | // if (disableCRL == 0) { | ||
309 | // if (wolfSSL_EnableCRL(ssl, WOLFSSL_CRL_CHECKALL) != SSL_SUCCESS) | ||
310 | // err_sys("can't enable crl check"); | ||
311 | // if (wolfSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, 0) != SSL_SUCCESS) | ||
312 | // err_sys("can't load crl, check crlfile and date validity"); | ||
313 | // if (wolfSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS) | ||
314 | // err_sys("can't set crl callback"); | ||
315 | // } | ||
316 | //#endif | ||
317 | //#ifdef HAVE_SECURE_RENEGOTIATION | ||
318 | // if (scr) { | ||
319 | // if (wolfSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS) | ||
320 | // err_sys("can't enable secure renegotiation"); | ||
321 | // } | ||
322 | //#endif | ||
323 | //#ifdef ATOMIC_USER | ||
324 | // if (atomicUser) | ||
325 | // SetupAtomicUser(ctx, ssl); | ||
326 | //#endif | ||
327 | //#ifdef HAVE_PK_CALLBACKS | ||
328 | // if (pkCallbacks) | ||
329 | // SetupPkCallbacks(ctx, ssl); | ||
330 | //#endif | ||
331 | // if (matchName && doPeerCheck) | ||
332 | // wolfSSL_check_domain_name(ssl, domain); | ||
333 | |||
334 | if (wolfSSL_connect(ssl) != SSL_SUCCESS) { | ||
335 | // /* see note at top of README */ | ||
336 | // int err = wolfSSL_get_error(ssl, 0); | ||
337 | // char buffer[WOLFSSL_MAX_ERROR_SZ]; | ||
338 | // say("err = %d, %s\n", err, | ||
339 | // wolfSSL_ERR_error_string(err, buffer)); | ||
340 | err_sys("SSL_connect failed"); | ||
341 | } | ||
342 | // showPeer(ssl); | ||
343 | |||
344 | //#ifdef HAVE_SECURE_RENEGOTIATION | ||
345 | // if (scr && forceScr) { | ||
346 | // if (wolfSSL_Rehandshake(ssl) != SSL_SUCCESS) { | ||
347 | // int err = wolfSSL_get_error(ssl, 0); | ||
348 | // char buffer[WOLFSSL_MAX_ERROR_SZ]; | ||
349 | // say("err = %d, %s\n", err, | ||
350 | // wolfSSL_ERR_error_string(err, buffer)); | ||
351 | // err_sys("wolfSSL_Rehandshake failed"); | ||
352 | // } | ||
353 | // } | ||
354 | //#endif | ||
355 | |||
356 | return ssl; | ||
357 | } | ||
358 | |||
359 | static struct pollfd pfd[2] = { | ||
360 | { -1, POLLIN|POLLERR|POLLHUP, 0 }, | ||
361 | { -1, POLLIN|POLLERR|POLLHUP, 0 }, | ||
362 | }; | ||
363 | #define STDIN pfd[0] | ||
364 | #define NETWORK pfd[1] | ||
365 | #define STDIN_READY() (pfd[0].revents & (POLLIN|POLLERR|POLLHUP)) | ||
366 | #define NETWORK_READY() (pfd[1].revents & (POLLIN|POLLERR|POLLHUP)) | ||
367 | |||
368 | static void wait_for_input(void) | ||
369 | { | ||
370 | if (STDIN.fd == NETWORK.fd) /* means both are -1 */ | ||
371 | exit(0); | ||
372 | dbg("polling\n"); | ||
373 | STDIN.revents = NETWORK.revents = 0; | ||
374 | while (poll(pfd, 2, -1) < 0 && errno == EINTR) | ||
375 | continue; | ||
376 | } | ||
377 | |||
378 | static void do_io_until_eof_and_exit(WOLFSSL *ssl, int fd) | ||
379 | { | ||
380 | int len; | ||
381 | char ibuf[4 * 1024]; | ||
382 | |||
383 | NETWORK.fd = fd; | ||
384 | STDIN.fd = 0; | ||
385 | |||
386 | len = 0; /* only to suppress compiler warning */ | ||
387 | for (;;) { | ||
388 | wait_for_input(); | ||
389 | |||
390 | if (STDIN_READY()) { | ||
391 | dbg("reading stdin\n"); | ||
392 | len = read(STDIN_FILENO, ibuf, sizeof(ibuf)); | ||
393 | if (len < 0) | ||
394 | die("read error on stdin\n"); | ||
395 | if (len == 0) { | ||
396 | dbg("read len = 0, stdin not polled anymore\n"); | ||
397 | STDIN.fd = -1; | ||
398 | } else { | ||
399 | int n = wolfSSL_write(ssl, ibuf, len); | ||
400 | if (n != len) | ||
401 | die("SSL_write(%d) failed (returned %d)\n", len, n); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | if (NETWORK_READY()) { | ||
406 | dbg("%s%s%s\n", | ||
407 | (pfd[1].revents & POLLIN) ? "POLLIN" : "", | ||
408 | (pfd[1].revents & POLLERR) ? "|POLLERR" : "", | ||
409 | (pfd[1].revents & POLLHUP) ? "|POLLHUP" : "" | ||
410 | ); | ||
411 | /* We are using blocking socket here. | ||
412 | * (Nonblocking socket would complicate writing to it). | ||
413 | * Therefore, SSL_read _can block_ here. | ||
414 | * This is not what wget expects (it wants to see short reads). | ||
415 | * Therefore, we use smallish buffer here, to approximate that. | ||
416 | */ | ||
417 | len = wolfSSL_read(ssl, ibuf, | ||
418 | sizeof(ibuf) < 1024 ? sizeof(ibuf) : 1024 | ||
419 | ); | ||
420 | if (len < 0) | ||
421 | die("SSL_read error on network (%d)\n", len); | ||
422 | if (len > 0) { | ||
423 | int n; | ||
424 | n = full_write(STDOUT_FILENO, ibuf, len); | ||
425 | if (n != len) | ||
426 | die("write(%d) to stdout returned %d\n", len, n); | ||
427 | continue; | ||
428 | } | ||
429 | /* Blocking reads are easier wtr EOF detection (no EAGAIN error to check for) */ | ||
430 | dbg("read len = 0, network not polled anymore\n"); | ||
431 | NETWORK.fd = -1; | ||
432 | /* saw EOF on network, and we processed | ||
433 | * and wrote out all ssl data. Signal it: | ||
434 | */ | ||
435 | close(STDOUT_FILENO); | ||
436 | } | ||
437 | } | ||
438 | } | ||
439 | |||
440 | int main(int argc, char **argv) | ||
441 | { | ||
442 | WOLFSSL *ssl; | ||
443 | int fd; | ||
444 | char *fd_str; | ||
445 | |||
446 | if (!argv[1]) | ||
447 | die("Syntax error\n"); | ||
448 | if (argv[1][0] != '-') | ||
449 | die("Syntax error\n"); | ||
450 | if (argv[1][1] != 'd') | ||
451 | die("Syntax error\n"); | ||
452 | fd_str = argv[1] + 2; | ||
453 | if (!fd_str[0]) | ||
454 | fd_str = argv[2]; | ||
455 | if (!fd_str || fd_str[0] < '0' || fd_str[0] > '9') | ||
456 | die("Syntax error\n"); | ||
457 | |||
458 | fd = atoi(fd_str); | ||
459 | if (fd < 3) | ||
460 | die("Syntax error\n"); | ||
461 | |||
462 | ssl = prepare(fd); | ||
463 | do_io_until_eof_and_exit(ssl, fd); | ||
464 | /* does not return */ | ||
465 | |||
466 | // if (doDTLS == 0) { /* don't send alert after "break" command */ | ||
467 | // ret = wolfSSL_shutdown(ssl); | ||
468 | // if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE) | ||
469 | // wolfSSL_shutdown(ssl); /* bidirectional shutdown */ | ||
470 | // } | ||
471 | //#ifdef ATOMIC_USER | ||
472 | // if (atomicUser) | ||
473 | // FreeAtomicUser(ssl); | ||
474 | //#endif | ||
475 | // wolfSSL_free(ssl); | ||
476 | // CloseSocket(sockfd); | ||
477 | // wolfSSL_CTX_free(ctx); | ||
478 | |||
479 | return 0; | ||
480 | } | ||
diff --git a/networking/ssl_helper-wolfssl/ssl_helper.sh b/networking/ssl_helper-wolfssl/ssl_helper.sh new file mode 100755 index 000000000..184ffe67e --- /dev/null +++ b/networking/ssl_helper-wolfssl/ssl_helper.sh | |||
@@ -0,0 +1,12 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # I use this to build static uclibc based binary using Aboriginal Linux toolchain: | ||
4 | PREFIX="i686-" | ||
5 | STATIC="-static" | ||
6 | # Standard build: | ||
7 | #PREFIX="" | ||
8 | #STATIC="" | ||
9 | |||
10 | ${PREFIX}gcc -Os -Wall -I.. -c ssl_helper.c -o ssl_helper.o | ||
11 | ${PREFIX}gcc $STATIC --start-group ssl_helper.o -lm ../src/.libs/libwolfssl.a --end-group -o ssl_helper | ||
12 | ${PREFIX}-strip ssl_helper | ||
diff --git a/networking/tc.c b/networking/tc.c index 76e2e8359..6d1fef993 100644 --- a/networking/tc.c +++ b/networking/tc.c | |||
@@ -64,15 +64,14 @@ struct globals { | |||
64 | uint32_t filter_proto; | 64 | uint32_t filter_proto; |
65 | } FIX_ALIASING; | 65 | } FIX_ALIASING; |
66 | #define G (*(struct globals*)&bb_common_bufsiz1) | 66 | #define G (*(struct globals*)&bb_common_bufsiz1) |
67 | struct BUG_G_too_big { | ||
68 | char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; | ||
69 | }; | ||
70 | #define filter_ifindex (G.filter_ifindex) | 67 | #define filter_ifindex (G.filter_ifindex) |
71 | #define filter_qdisc (G.filter_qdisc) | 68 | #define filter_qdisc (G.filter_qdisc) |
72 | #define filter_parent (G.filter_parent) | 69 | #define filter_parent (G.filter_parent) |
73 | #define filter_prio (G.filter_prio) | 70 | #define filter_prio (G.filter_prio) |
74 | #define filter_proto (G.filter_proto) | 71 | #define filter_proto (G.filter_proto) |
75 | #define INIT_G() do { } while (0) | 72 | #define INIT_G() do { \ |
73 | BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ | ||
74 | } while (0) | ||
76 | 75 | ||
77 | /* Allocates a buffer containing the name of a class id. | 76 | /* Allocates a buffer containing the name of a class id. |
78 | * The caller must free the returned memory. */ | 77 | * The caller must free the returned memory. */ |
diff --git a/networking/telnet.c b/networking/telnet.c index a25579773..3bb6fb1ba 100644 --- a/networking/telnet.c +++ b/networking/telnet.c | |||
@@ -623,7 +623,7 @@ int telnet_main(int argc UNUSED_PARAM, char **argv) | |||
623 | 623 | ||
624 | xmove_fd(create_and_connect_stream_or_die(host, port), netfd); | 624 | xmove_fd(create_and_connect_stream_or_die(host, port), netfd); |
625 | 625 | ||
626 | setsockopt(netfd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); | 626 | setsockopt_keepalive(netfd); |
627 | 627 | ||
628 | signal(SIGINT, record_signo); | 628 | signal(SIGINT, record_signo); |
629 | 629 | ||
diff --git a/networking/telnetd.c b/networking/telnetd.c index 6aee95871..25d05fe7a 100644 --- a/networking/telnetd.c +++ b/networking/telnetd.c | |||
@@ -265,7 +265,7 @@ make_new_session( | |||
265 | close_on_exec_on(fd); | 265 | close_on_exec_on(fd); |
266 | 266 | ||
267 | /* SO_KEEPALIVE by popular demand */ | 267 | /* SO_KEEPALIVE by popular demand */ |
268 | setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); | 268 | setsockopt_keepalive(sock); |
269 | #if ENABLE_FEATURE_TELNETD_STANDALONE | 269 | #if ENABLE_FEATURE_TELNETD_STANDALONE |
270 | ts->sockfd_read = sock; | 270 | ts->sockfd_read = sock; |
271 | ndelay_on(sock); | 271 | ndelay_on(sock); |
diff --git a/networking/tftp.c b/networking/tftp.c index 8ecd7bb6f..ad9308e52 100644 --- a/networking/tftp.c +++ b/networking/tftp.c | |||
@@ -129,10 +129,9 @@ struct globals { | |||
129 | #endif | 129 | #endif |
130 | } FIX_ALIASING; | 130 | } FIX_ALIASING; |
131 | #define G (*(struct globals*)&bb_common_bufsiz1) | 131 | #define G (*(struct globals*)&bb_common_bufsiz1) |
132 | struct BUG_G_too_big { | 132 | #define INIT_G() do { \ |
133 | char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; | 133 | BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ |
134 | }; | 134 | } while (0) |
135 | #define INIT_G() do { } while (0) | ||
136 | 135 | ||
137 | #define G_error_pkt_reason (G.error_pkt[3]) | 136 | #define G_error_pkt_reason (G.error_pkt[3]) |
138 | #define G_error_pkt_str ((char*)(G.error_pkt + 4)) | 137 | #define G_error_pkt_str ((char*)(G.error_pkt + 4)) |
diff --git a/networking/traceroute.c b/networking/traceroute.c index 12ba614e8..642110c54 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -211,60 +211,62 @@ | |||
211 | */ | 211 | */ |
212 | 212 | ||
213 | //usage:#define traceroute_trivial_usage | 213 | //usage:#define traceroute_trivial_usage |
214 | //usage: "[-"IF_TRACEROUTE6("46")"FIldnrv] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]\n" | 214 | //usage: "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n" |
215 | //usage: " [-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE]\n" | 215 | //usage: " [-t TOS] [-w WAIT_SEC]" |
216 | //usage: IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(" [-g GATEWAY]")" [-s SRC_IP] [-i IFACE]\n" | ||
216 | //usage: " [-z PAUSE_MSEC] HOST [BYTES]" | 217 | //usage: " [-z PAUSE_MSEC] HOST [BYTES]" |
217 | //usage:#define traceroute_full_usage "\n\n" | 218 | //usage:#define traceroute_full_usage "\n\n" |
218 | //usage: "Trace the route to HOST\n" | 219 | //usage: "Trace the route to HOST\n" |
219 | //usage: IF_TRACEROUTE6( | 220 | //usage: IF_TRACEROUTE6( |
220 | //usage: "\n -4,-6 Force IP or IPv6 name resolution" | 221 | //usage: "\n -4,-6 Force IP or IPv6 name resolution" |
221 | //usage: ) | 222 | //usage: ) |
222 | //usage: "\n -F Set the don't fragment bit" | 223 | //usage: "\n -F Set don't fragment bit" |
224 | //usage: IF_FEATURE_TRACEROUTE_USE_ICMP( | ||
223 | //usage: "\n -I Use ICMP ECHO instead of UDP datagrams" | 225 | //usage: "\n -I Use ICMP ECHO instead of UDP datagrams" |
224 | //usage: "\n -l Display the TTL value of the returned packet" | 226 | //usage: ) |
225 | //usage: "\n -d Set SO_DEBUG options to socket" | 227 | //usage: "\n -l Display TTL value of the returned packet" |
228 | //Currently disabled (TRACEROUTE_SO_DEBUG==0) | ||
229 | ////usage: "\n -d Set SO_DEBUG options to socket" | ||
226 | //usage: "\n -n Print numeric addresses" | 230 | //usage: "\n -n Print numeric addresses" |
227 | //usage: "\n -r Bypass routing tables, send directly to HOST" | 231 | //usage: "\n -r Bypass routing tables, send directly to HOST" |
232 | //usage: IF_FEATURE_TRACEROUTE_VERBOSE( | ||
228 | //usage: "\n -v Verbose" | 233 | //usage: "\n -v Verbose" |
229 | //usage: "\n -m Max time-to-live (max number of hops)" | 234 | //usage: ) |
230 | //usage: "\n -p Base UDP port number used in probes" | 235 | //usage: "\n -f N First number of hops (default 1)" |
236 | //usage: "\n -m N Max number of hops" | ||
237 | //usage: "\n -q N Number of probes per hop (default 3)" | ||
238 | //usage: "\n -p N Base UDP port number used in probes" | ||
231 | //usage: "\n (default 33434)" | 239 | //usage: "\n (default 33434)" |
232 | //usage: "\n -q Number of probes per TTL (default 3)" | 240 | //usage: "\n -s IP Source address" |
233 | //usage: "\n -s IP address to use as the source address" | 241 | //usage: "\n -i IFACE Source interface" |
234 | //usage: "\n -t Type-of-service in probe packets (default 0)" | 242 | //usage: "\n -t N Type-of-service in probe packets (default 0)" |
235 | //usage: "\n -w Time in seconds to wait for a response (default 3)" | 243 | //usage: "\n -w SEC Time to wait for a response (default 3)" |
236 | //usage: "\n -g Loose source route gateway (8 max)" | 244 | //usage: "\n -g IP Loose source route gateway (8 max)" |
237 | //usage: | 245 | //usage: |
238 | //usage:#define traceroute6_trivial_usage | 246 | //usage:#define traceroute6_trivial_usage |
239 | //usage: "[-dnrv] [-m MAXTTL] [-p PORT] [-q PROBES]\n" | 247 | //usage: "[-nrv] [-m MAXTTL] [-q PROBES] [-p PORT]\n" |
240 | //usage: " [-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-i IFACE]\n" | 248 | //usage: " [-t TOS] [-w WAIT_SEC] [-s SRC_IP] [-i IFACE]\n" |
241 | //usage: " HOST [BYTES]" | 249 | //usage: " HOST [BYTES]" |
242 | //usage:#define traceroute6_full_usage "\n\n" | 250 | //usage:#define traceroute6_full_usage "\n\n" |
243 | //usage: "Trace the route to HOST\n" | 251 | //usage: "Trace the route to HOST\n" |
244 | //usage: "\n -d Set SO_DEBUG options to socket" | 252 | //Currently disabled (TRACEROUTE_SO_DEBUG==0) |
253 | ////usage: "\n -d Set SO_DEBUG options to socket" | ||
245 | //usage: "\n -n Print numeric addresses" | 254 | //usage: "\n -n Print numeric addresses" |
246 | //usage: "\n -r Bypass routing tables, send directly to HOST" | 255 | //usage: "\n -r Bypass routing tables, send directly to HOST" |
256 | //usage: IF_FEATURE_TRACEROUTE_VERBOSE( | ||
247 | //usage: "\n -v Verbose" | 257 | //usage: "\n -v Verbose" |
248 | //usage: "\n -m Max time-to-live (max number of hops)" | 258 | //usage: ) |
249 | //usage: "\n -p Base UDP port number used in probes" | 259 | //usage: "\n -m N Max number of hops" |
250 | //usage: "\n (default is 33434)" | 260 | //usage: "\n -q N Number of probes per hop (default 3)" |
251 | //usage: "\n -q Number of probes per TTL (default 3)" | 261 | //usage: "\n -p N Base UDP port number used in probes" |
252 | //usage: "\n -s IP address to use as the source address" | 262 | //usage: "\n (default 33434)" |
253 | //usage: "\n -t Type-of-service in probe packets (default 0)" | 263 | //usage: "\n -s IP Source address" |
254 | //usage: "\n -w Time in seconds to wait for a response (default 3)" | 264 | //usage: "\n -i IFACE Source interface" |
265 | //usage: "\n -t N Type-of-service in probe packets (default 0)" | ||
266 | //usage: "\n -w SEC Time wait for a response (default 3)" | ||
255 | 267 | ||
256 | #define TRACEROUTE_SO_DEBUG 0 | 268 | #define TRACEROUTE_SO_DEBUG 0 |
257 | 269 | ||
258 | /* TODO: undefs were uncommented - ??! we have config system for that! */ | ||
259 | /* probably ok to remove altogether */ | ||
260 | //#undef CONFIG_FEATURE_TRACEROUTE_VERBOSE | ||
261 | //#define CONFIG_FEATURE_TRACEROUTE_VERBOSE | ||
262 | //#undef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
263 | //#define CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
264 | //#undef CONFIG_FEATURE_TRACEROUTE_USE_ICMP | ||
265 | //#define CONFIG_FEATURE_TRACEROUTE_USE_ICMP | ||
266 | |||
267 | |||
268 | #include <net/if.h> | 270 | #include <net/if.h> |
269 | #include <arpa/inet.h> | 271 | #include <arpa/inet.h> |
270 | #include <netinet/in.h> | 272 | #include <netinet/in.h> |
@@ -471,18 +473,18 @@ send_probe(int seq, int ttl) | |||
471 | 473 | ||
472 | #if ENABLE_TRACEROUTE6 | 474 | #if ENABLE_TRACEROUTE6 |
473 | if (dest_lsa->u.sa.sa_family == AF_INET6) { | 475 | if (dest_lsa->u.sa.sa_family == AF_INET6) { |
474 | res = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)); | 476 | res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl); |
475 | if (res < 0) | 477 | if (res != 0) |
476 | bb_perror_msg_and_die("setsockopt UNICAST_HOPS %d", ttl); | 478 | bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl); |
477 | out = outip; | 479 | out = outip; |
478 | len = packlen; | 480 | len = packlen; |
479 | } else | 481 | } else |
480 | #endif | 482 | #endif |
481 | { | 483 | { |
482 | #if defined IP_TTL | 484 | #if defined IP_TTL |
483 | res = setsockopt(sndsock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)); | 485 | res = setsockopt_int(sndsock, IPPROTO_IP, IP_TTL, ttl); |
484 | if (res < 0) | 486 | if (res != 0) |
485 | bb_perror_msg_and_die("setsockopt ttl %d", ttl); | 487 | bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl); |
486 | #endif | 488 | #endif |
487 | out = outicmp; | 489 | out = outicmp; |
488 | len = packlen - sizeof(*outip); | 490 | len = packlen - sizeof(*outip); |
@@ -900,13 +902,10 @@ common_traceroute_main(int op, char **argv) | |||
900 | if (af == AF_INET6) { | 902 | if (af == AF_INET6) { |
901 | xmove_fd(xsocket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6), rcvsock); | 903 | xmove_fd(xsocket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6), rcvsock); |
902 | # ifdef IPV6_RECVPKTINFO | 904 | # ifdef IPV6_RECVPKTINFO |
903 | setsockopt(rcvsock, SOL_IPV6, IPV6_RECVPKTINFO, | 905 | setsockopt_1(rcvsock, SOL_IPV6, IPV6_RECVPKTINFO); |
904 | &const_int_1, sizeof(const_int_1)); | 906 | setsockopt_1(rcvsock, SOL_IPV6, IPV6_2292PKTINFO); |
905 | setsockopt(rcvsock, SOL_IPV6, IPV6_2292PKTINFO, | ||
906 | &const_int_1, sizeof(const_int_1)); | ||
907 | # else | 907 | # else |
908 | setsockopt(rcvsock, SOL_IPV6, IPV6_PKTINFO, | 908 | setsockopt_1(rcvsock, SOL_IPV6, IPV6_PKTINFO); |
909 | &const_int_1, sizeof(const_int_1)); | ||
910 | # endif | 909 | # endif |
911 | } else | 910 | } else |
912 | #endif | 911 | #endif |
@@ -916,18 +915,15 @@ common_traceroute_main(int op, char **argv) | |||
916 | 915 | ||
917 | #if TRACEROUTE_SO_DEBUG | 916 | #if TRACEROUTE_SO_DEBUG |
918 | if (op & OPT_DEBUG) | 917 | if (op & OPT_DEBUG) |
919 | setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG, | 918 | setsockopt_SOL_SOCKET_1(rcvsock, SO_DEBUG); |
920 | &const_int_1, sizeof(const_int_1)); | ||
921 | #endif | 919 | #endif |
922 | if (op & OPT_BYPASS_ROUTE) | 920 | if (op & OPT_BYPASS_ROUTE) |
923 | setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE, | 921 | setsockopt_SOL_SOCKET_1(rcvsock, SO_DONTROUTE); |
924 | &const_int_1, sizeof(const_int_1)); | ||
925 | 922 | ||
926 | #if ENABLE_TRACEROUTE6 | 923 | #if ENABLE_TRACEROUTE6 |
927 | if (af == AF_INET6) { | 924 | if (af == AF_INET6) { |
928 | static const int two = 2; | 925 | if (setsockopt_int(rcvsock, SOL_RAW, IPV6_CHECKSUM, 2) != 0) |
929 | if (setsockopt(rcvsock, SOL_RAW, IPV6_CHECKSUM, &two, sizeof(two)) < 0) | 926 | bb_perror_msg_and_die("setsockopt(%s)", "IPV6_CHECKSUM"); |
930 | bb_perror_msg_and_die("setsockopt RAW_CHECKSUM"); | ||
931 | xmove_fd(xsocket(af, SOCK_DGRAM, 0), sndsock); | 927 | xmove_fd(xsocket(af, SOCK_DGRAM, 0), sndsock); |
932 | } else | 928 | } else |
933 | #endif | 929 | #endif |
@@ -964,28 +960,25 @@ common_traceroute_main(int op, char **argv) | |||
964 | } | 960 | } |
965 | 961 | ||
966 | #ifdef SO_SNDBUF | 962 | #ifdef SO_SNDBUF |
967 | if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, &packlen, sizeof(packlen)) < 0) { | 963 | if (setsockopt_SOL_SOCKET_int(sndsock, SO_SNDBUF, packlen) != 0) { |
968 | bb_perror_msg_and_die("SO_SNDBUF"); | 964 | bb_perror_msg_and_die("setsockopt(%s)", "SO_SNDBUF"); |
969 | } | 965 | } |
970 | #endif | 966 | #endif |
971 | #ifdef IP_TOS | 967 | #ifdef IP_TOS |
972 | if ((op & OPT_TOS) && setsockopt(sndsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) { | 968 | if ((op & OPT_TOS) && setsockopt_int(sndsock, IPPROTO_IP, IP_TOS, tos) != 0) { |
973 | bb_perror_msg_and_die("setsockopt tos %d", tos); | 969 | bb_perror_msg_and_die("setsockopt(%s) %d", "TOS", tos); |
974 | } | 970 | } |
975 | #endif | 971 | #endif |
976 | #ifdef IP_DONTFRAG | 972 | #ifdef IP_DONTFRAG |
977 | if (op & OPT_DONT_FRAGMNT) | 973 | if (op & OPT_DONT_FRAGMNT) |
978 | setsockopt(sndsock, IPPROTO_IP, IP_DONTFRAG, | 974 | setsockopt_1(sndsock, IPPROTO_IP, IP_DONTFRAG); |
979 | &const_int_1, sizeof(const_int_1)); | ||
980 | #endif | 975 | #endif |
981 | #if TRACEROUTE_SO_DEBUG | 976 | #if TRACEROUTE_SO_DEBUG |
982 | if (op & OPT_DEBUG) | 977 | if (op & OPT_DEBUG) |
983 | setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, | 978 | setsockopt_SOL_SOCKET_1(sndsock, SO_DEBUG); |
984 | &const_int_1, sizeof(const_int_1)); | ||
985 | #endif | 979 | #endif |
986 | if (op & OPT_BYPASS_ROUTE) | 980 | if (op & OPT_BYPASS_ROUTE) |
987 | setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, | 981 | setsockopt_SOL_SOCKET_1(sndsock, SO_DONTROUTE); |
988 | &const_int_1, sizeof(const_int_1)); | ||
989 | 982 | ||
990 | outip = xzalloc(packlen); | 983 | outip = xzalloc(packlen); |
991 | 984 | ||
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 811a1a1ee..915f65935 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -29,6 +29,20 @@ | |||
29 | #include <linux/filter.h> | 29 | #include <linux/filter.h> |
30 | #include <linux/if_packet.h> | 30 | #include <linux/if_packet.h> |
31 | 31 | ||
32 | #ifndef PACKET_AUXDATA | ||
33 | # define PACKET_AUXDATA 8 | ||
34 | struct tpacket_auxdata { | ||
35 | uint32_t tp_status; | ||
36 | uint32_t tp_len; | ||
37 | uint32_t tp_snaplen; | ||
38 | uint16_t tp_mac; | ||
39 | uint16_t tp_net; | ||
40 | uint16_t tp_vlan_tci; | ||
41 | uint16_t tp_padding; | ||
42 | }; | ||
43 | #endif | ||
44 | |||
45 | |||
32 | /* "struct client_config_t client_config" is in bb_common_bufsiz1 */ | 46 | /* "struct client_config_t client_config" is in bb_common_bufsiz1 */ |
33 | 47 | ||
34 | 48 | ||
@@ -1043,9 +1057,7 @@ static int udhcp_raw_socket(int ifindex) | |||
1043 | } | 1057 | } |
1044 | #endif | 1058 | #endif |
1045 | 1059 | ||
1046 | if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, | 1060 | if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) { |
1047 | &const_int_1, sizeof(int)) < 0 | ||
1048 | ) { | ||
1049 | if (errno != ENOPROTOOPT) | 1061 | if (errno != ENOPROTOOPT) |
1050 | log1("Can't set PACKET_AUXDATA on raw socket"); | 1062 | log1("Can't set PACKET_AUXDATA on raw socket"); |
1051 | } | 1063 | } |
diff --git a/networking/wget.c b/networking/wget.c index e09bd2368..0082ced39 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -9,6 +9,94 @@ | |||
9 | * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2. | 9 | * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | //config:config WGET | ||
13 | //config: bool "wget" | ||
14 | //config: default y | ||
15 | //config: help | ||
16 | //config: wget is a utility for non-interactive download of files from HTTP | ||
17 | //config: and FTP servers. | ||
18 | //config: | ||
19 | //config:config FEATURE_WGET_STATUSBAR | ||
20 | //config: bool "Enable a nifty process meter (+2k)" | ||
21 | //config: default y | ||
22 | //config: depends on WGET | ||
23 | //config: help | ||
24 | //config: Enable the transfer progress bar for wget transfers. | ||
25 | //config: | ||
26 | //config:config FEATURE_WGET_AUTHENTICATION | ||
27 | //config: bool "Enable HTTP authentication" | ||
28 | //config: default y | ||
29 | //config: depends on WGET | ||
30 | //config: help | ||
31 | //config: Support authenticated HTTP transfers. | ||
32 | //config: | ||
33 | //config:config FEATURE_WGET_LONG_OPTIONS | ||
34 | //config: bool "Enable long options" | ||
35 | //config: default y | ||
36 | //config: depends on WGET && LONG_OPTS | ||
37 | //config: help | ||
38 | //config: Support long options for the wget applet. | ||
39 | //config: | ||
40 | //config:config FEATURE_WGET_TIMEOUT | ||
41 | //config: bool "Enable timeout option -T SEC" | ||
42 | //config: default y | ||
43 | //config: depends on WGET | ||
44 | //config: help | ||
45 | //config: Supports network read and connect timeouts for wget, | ||
46 | //config: so that wget will give up and timeout, through the -T | ||
47 | //config: command line option. | ||
48 | //config: | ||
49 | //config: Currently only connect and network data read timeout are | ||
50 | //config: supported (i.e., timeout is not applied to the DNS query). When | ||
51 | //config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option | ||
52 | //config: will work in addition to -T. | ||
53 | //config: | ||
54 | //config:config FEATURE_WGET_OPENSSL | ||
55 | //config: bool "Try to connect to HTTPS using openssl" | ||
56 | //config: default y | ||
57 | //config: depends on WGET | ||
58 | //config: help | ||
59 | //config: Choose how wget establishes SSL connection for https:// URLs. | ||
60 | //config: | ||
61 | //config: Busybox itself contains no SSL code. wget will spawn | ||
62 | //config: a helper program to talk over HTTPS. | ||
63 | //config: | ||
64 | //config: OpenSSL has a simple SSL client for debug purposes. | ||
65 | //config: If you select "openssl" helper, wget will effectively call | ||
66 | //config: "openssl s_client -quiet -connect IP:443 2>/dev/null" | ||
67 | //config: and pipe its data through it. | ||
68 | //config: Note inconvenient API: host resolution is done twice, | ||
69 | //config: and there is no guarantee openssl's idea of IPv6 address | ||
70 | //config: format is the same as ours. | ||
71 | //config: Another problem is that s_client prints debug information | ||
72 | //config: to stderr, and it needs to be suppressed. This means | ||
73 | //config: all error messages get suppressed too. | ||
74 | //config: openssl is also a big binary, often dynamically linked | ||
75 | //config: against ~15 libraries. | ||
76 | //config: | ||
77 | //config:config FEATURE_WGET_SSL_HELPER | ||
78 | //config: bool "Try to connect to HTTPS using ssl_helper" | ||
79 | //config: default y | ||
80 | //config: depends on WGET | ||
81 | //config: help | ||
82 | //config: Choose how wget establishes SSL connection for https:// URLs. | ||
83 | //config: | ||
84 | //config: Busybox itself contains no SSL code. wget will spawn | ||
85 | //config: a helper program to talk over HTTPS. | ||
86 | //config: | ||
87 | //config: ssl_helper is a tool which can be built statically | ||
88 | //config: from busybox sources against a small embedded SSL library. | ||
89 | //config: Please see networking/ssl_helper/README. | ||
90 | //config: It does not require double host resolution and emits | ||
91 | //config: error messages to stderr. | ||
92 | //config: | ||
93 | //config: Precompiled static binary may be available at | ||
94 | //config: http://busybox.net/downloads/binaries/ | ||
95 | |||
96 | //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
97 | |||
98 | //kbuild:lib-$(CONFIG_WGET) += wget.o | ||
99 | |||
12 | //usage:#define wget_trivial_usage | 100 | //usage:#define wget_trivial_usage |
13 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( | 101 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( |
14 | //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" | 102 | //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" |
@@ -59,7 +147,9 @@ struct host_info { | |||
59 | }; | 147 | }; |
60 | static const char P_FTP[] = "ftp"; | 148 | static const char P_FTP[] = "ftp"; |
61 | static const char P_HTTP[] = "http"; | 149 | static const char P_HTTP[] = "http"; |
150 | #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER | ||
62 | static const char P_HTTPS[] = "https"; | 151 | static const char P_HTTPS[] = "https"; |
152 | #endif | ||
63 | 153 | ||
64 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS | 154 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS |
65 | /* User-specified headers prevent using our corresponding built-in headers. */ | 155 | /* User-specified headers prevent using our corresponding built-in headers. */ |
@@ -328,7 +418,7 @@ static void parse_url(const char *src_url, struct host_info *h) | |||
328 | if (strcmp(url, P_FTP) == 0) { | 418 | if (strcmp(url, P_FTP) == 0) { |
329 | h->port = bb_lookup_port(P_FTP, "tcp", 21); | 419 | h->port = bb_lookup_port(P_FTP, "tcp", 21); |
330 | } else | 420 | } else |
331 | #if !ENABLE_PLATFORM_MINGW32 | 421 | #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER |
332 | if (strcmp(url, P_HTTPS) == 0) { | 422 | if (strcmp(url, P_HTTPS) == 0) { |
333 | h->port = bb_lookup_port(P_HTTPS, "tcp", 443); | 423 | h->port = bb_lookup_port(P_HTTPS, "tcp", 443); |
334 | h->protocol = P_HTTPS; | 424 | h->protocol = P_HTTPS; |
@@ -528,12 +618,13 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ | |||
528 | return sfp; | 618 | return sfp; |
529 | } | 619 | } |
530 | 620 | ||
531 | #if !ENABLE_PLATFORM_MINGW32 | 621 | #if ENABLE_FEATURE_WGET_OPENSSL |
532 | static int spawn_https_helper(const char *host, unsigned port) | 622 | static int spawn_https_helper_openssl(const char *host, unsigned port) |
533 | { | 623 | { |
534 | char *allocated = NULL; | 624 | char *allocated = NULL; |
535 | int sp[2]; | 625 | int sp[2]; |
536 | int pid; | 626 | int pid; |
627 | IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) | ||
537 | 628 | ||
538 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) | 629 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) |
539 | /* Kernel can have AF_UNIX support disabled */ | 630 | /* Kernel can have AF_UNIX support disabled */ |
@@ -542,7 +633,8 @@ static int spawn_https_helper(const char *host, unsigned port) | |||
542 | if (!strchr(host, ':')) | 633 | if (!strchr(host, ':')) |
543 | host = allocated = xasprintf("%s:%u", host, port); | 634 | host = allocated = xasprintf("%s:%u", host, port); |
544 | 635 | ||
545 | pid = BB_MMU ? xfork() : xvfork(); | 636 | fflush_all(); |
637 | pid = xvfork(); | ||
546 | if (pid == 0) { | 638 | if (pid == 0) { |
547 | /* Child */ | 639 | /* Child */ |
548 | char *argv[6]; | 640 | char *argv[6]; |
@@ -551,10 +643,6 @@ static int spawn_https_helper(const char *host, unsigned port) | |||
551 | xmove_fd(sp[1], 0); | 643 | xmove_fd(sp[1], 0); |
552 | xdup2(0, 1); | 644 | xdup2(0, 1); |
553 | /* | 645 | /* |
554 | * TODO: develop a tiny ssl/tls helper (using matrixssl?), | ||
555 | * try to exec it here before falling back to big fat openssl. | ||
556 | */ | ||
557 | /* | ||
558 | * openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null | 646 | * openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null |
559 | * It prints some debug stuff on stderr, don't know how to suppress it. | 647 | * It prints some debug stuff on stderr, don't know how to suppress it. |
560 | * Work around by dev-nulling stderr. We lose all error messages :( | 648 | * Work around by dev-nulling stderr. We lose all error messages :( |
@@ -569,22 +657,31 @@ static int spawn_https_helper(const char *host, unsigned port) | |||
569 | argv[5] = NULL; | 657 | argv[5] = NULL; |
570 | BB_EXECVP(argv[0], argv); | 658 | BB_EXECVP(argv[0], argv); |
571 | xmove_fd(3, 2); | 659 | xmove_fd(3, 2); |
660 | # if ENABLE_FEATURE_WGET_SSL_HELPER | ||
661 | child_failed = 1; | ||
662 | xfunc_die(); | ||
663 | # else | ||
572 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); | 664 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); |
665 | # endif | ||
573 | /* notreached */ | 666 | /* notreached */ |
574 | } | 667 | } |
575 | 668 | ||
576 | /* Parent */ | 669 | /* Parent */ |
577 | free(allocated); | 670 | free(allocated); |
578 | close(sp[1]); | 671 | close(sp[1]); |
672 | # if ENABLE_FEATURE_WGET_SSL_HELPER | ||
673 | if (child_failed) { | ||
674 | close(sp[0]); | ||
675 | return -1; | ||
676 | } | ||
677 | # endif | ||
579 | return sp[0]; | 678 | return sp[0]; |
580 | } | 679 | } |
581 | #endif | 680 | #endif |
582 | 681 | ||
583 | /* See networking/ssl_helper/README */ | 682 | /* See networking/ssl_helper/README how to build one */ |
584 | #define SSL_HELPER 0 | 683 | #if ENABLE_FEATURE_WGET_SSL_HELPER |
585 | 684 | static void spawn_https_helper_small(int network_fd) | |
586 | #if SSL_HELPER | ||
587 | static void spawn_https_helper1(int network_fd) | ||
588 | { | 685 | { |
589 | int sp[2]; | 686 | int sp[2]; |
590 | int pid; | 687 | int pid; |
@@ -861,21 +958,37 @@ static void download_one_url(const char *url) | |||
861 | int status; | 958 | int status; |
862 | 959 | ||
863 | /* Open socket to http(s) server */ | 960 | /* Open socket to http(s) server */ |
864 | #if !ENABLE_PLATFORM_MINGW32 | 961 | #if ENABLE_FEATURE_WGET_OPENSSL |
962 | /* openssl (and maybe ssl_helper) support is configured */ | ||
865 | if (target.protocol == P_HTTPS) { | 963 | if (target.protocol == P_HTTPS) { |
866 | /* openssl-based helper | 964 | /* openssl-based helper |
867 | * Inconvenient API since we can't give it an open fd | 965 | * Inconvenient API since we can't give it an open fd |
868 | */ | 966 | */ |
869 | int fd = spawn_https_helper(server.host, server.port); | 967 | int fd = spawn_https_helper_openssl(server.host, server.port); |
968 | # if ENABLE_FEATURE_WGET_SSL_HELPER | ||
969 | if (fd < 0) { /* no openssl? try ssl_helper */ | ||
970 | sfp = open_socket(lsa); | ||
971 | spawn_https_helper_small(fileno(sfp)); | ||
972 | goto socket_opened; | ||
973 | } | ||
974 | # else | ||
975 | /* We don't check for exec("openssl") failure in this case */ | ||
976 | # endif | ||
870 | sfp = fdopen(fd, "r+"); | 977 | sfp = fdopen(fd, "r+"); |
871 | if (!sfp) | 978 | if (!sfp) |
872 | bb_perror_msg_and_die(bb_msg_memory_exhausted); | 979 | bb_perror_msg_and_die(bb_msg_memory_exhausted); |
873 | } else | 980 | goto socket_opened; |
874 | #endif | 981 | } |
875 | sfp = open_socket(lsa); | 982 | sfp = open_socket(lsa); |
876 | #if SSL_HELPER | 983 | socket_opened: |
984 | #elif ENABLE_FEATURE_WGET_SSL_HELPER | ||
985 | /* Only ssl_helper support is configured */ | ||
986 | sfp = open_socket(lsa); | ||
877 | if (target.protocol == P_HTTPS) | 987 | if (target.protocol == P_HTTPS) |
878 | spawn_https_helper1(fileno(sfp)); | 988 | spawn_https_helper_small(fileno(sfp)); |
989 | #else | ||
990 | /* ssl (https) support is not configured */ | ||
991 | sfp = open_socket(lsa); | ||
879 | #endif | 992 | #endif |
880 | /* Send HTTP request */ | 993 | /* Send HTTP request */ |
881 | if (use_proxy) { | 994 | if (use_proxy) { |
diff --git a/networking/zcip.c b/networking/zcip.c index 69644b230..d15c67d55 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -56,9 +56,6 @@ struct arp_packet { | |||
56 | } PACKED; | 56 | } PACKED; |
57 | 57 | ||
58 | enum { | 58 | enum { |
59 | /* 169.254.0.0 */ | ||
60 | LINKLOCAL_ADDR = 0xa9fe0000, | ||
61 | |||
62 | /* 0-1 seconds before sending 1st probe */ | 59 | /* 0-1 seconds before sending 1st probe */ |
63 | PROBE_WAIT = 1, | 60 | PROBE_WAIT = 1, |
64 | /* 1-2 seconds between probes */ | 61 | /* 1-2 seconds between probes */ |
@@ -70,7 +67,7 @@ enum { | |||
70 | /* if probe/announce sees a conflict, multiply RANDOM(NUM_CONFLICT) by... */ | 67 | /* if probe/announce sees a conflict, multiply RANDOM(NUM_CONFLICT) by... */ |
71 | CONFLICT_MULTIPLIER = 2, | 68 | CONFLICT_MULTIPLIER = 2, |
72 | /* if we monitor and see a conflict, how long is defend state? */ | 69 | /* if we monitor and see a conflict, how long is defend state? */ |
73 | DEFEND_INTERVAL = 10 | 70 | DEFEND_INTERVAL = 10, |
74 | }; | 71 | }; |
75 | 72 | ||
76 | /* States during the configuration process. */ | 73 | /* States during the configuration process. */ |
@@ -90,7 +87,7 @@ enum { | |||
90 | 87 | ||
91 | struct globals { | 88 | struct globals { |
92 | struct sockaddr iface_sockaddr; | 89 | struct sockaddr iface_sockaddr; |
93 | struct ether_addr eth_addr; | 90 | struct ether_addr our_ethaddr; |
94 | uint32_t localnet_ip; | 91 | uint32_t localnet_ip; |
95 | } FIX_ALIASING; | 92 | } FIX_ALIASING; |
96 | #define G (*(struct globals*)&bb_common_bufsiz1) | 93 | #define G (*(struct globals*)&bb_common_bufsiz1) |
@@ -121,14 +118,14 @@ static const char *nip_to_a(uint32_t nip) | |||
121 | /** | 118 | /** |
122 | * Broadcast an ARP packet. | 119 | * Broadcast an ARP packet. |
123 | */ | 120 | */ |
124 | static void arp( | 121 | static void send_arp_request( |
125 | /* int op, - always ARPOP_REQUEST */ | 122 | /* int op, - always ARPOP_REQUEST */ |
126 | /* const struct ether_addr *source_eth, - always &G.eth_addr */ | 123 | /* const struct ether_addr *source_eth, - always &G.our_ethaddr */ |
127 | uint32_t source_nip, | 124 | uint32_t source_nip, |
128 | const struct ether_addr *target_eth, uint32_t target_nip) | 125 | const struct ether_addr *target_eth, uint32_t target_nip) |
129 | { | 126 | { |
130 | enum { op = ARPOP_REQUEST }; | 127 | enum { op = ARPOP_REQUEST }; |
131 | #define source_eth (&G.eth_addr) | 128 | #define source_eth (&G.our_ethaddr) |
132 | 129 | ||
133 | struct arp_packet p; | 130 | struct arp_packet p; |
134 | memset(&p, 0, sizeof(p)); | 131 | memset(&p, 0, sizeof(p)); |
@@ -196,7 +193,7 @@ static int run(char *argv[3], const char *param, uint32_t nip) | |||
196 | */ | 193 | */ |
197 | static ALWAYS_INLINE unsigned random_delay_ms(unsigned secs) | 194 | static ALWAYS_INLINE unsigned random_delay_ms(unsigned secs) |
198 | { | 195 | { |
199 | return rand() % (secs * 1000); | 196 | return (unsigned)rand() % (secs * 1000); |
200 | } | 197 | } |
201 | 198 | ||
202 | /** | 199 | /** |
@@ -205,37 +202,34 @@ static ALWAYS_INLINE unsigned random_delay_ms(unsigned secs) | |||
205 | int zcip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 202 | int zcip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
206 | int zcip_main(int argc UNUSED_PARAM, char **argv) | 203 | int zcip_main(int argc UNUSED_PARAM, char **argv) |
207 | { | 204 | { |
208 | int state; | ||
209 | char *r_opt; | 205 | char *r_opt; |
210 | const char *l_opt = "169.254.0.0"; | 206 | const char *l_opt = "169.254.0.0"; |
207 | int state; | ||
208 | int nsent; | ||
211 | unsigned opts; | 209 | unsigned opts; |
212 | 210 | ||
213 | // ugly trick, but I want these zeroed in one go | 211 | // Ugly trick, but I want these zeroed in one go |
214 | struct { | 212 | struct { |
215 | const struct ether_addr null_addr; | 213 | const struct ether_addr null_ethaddr; |
216 | struct ifreq ifr; | 214 | struct ifreq ifr; |
217 | uint32_t chosen_nip; | 215 | uint32_t chosen_nip; |
218 | int timeout_ms; /* must be signed */ | 216 | int conflicts; |
219 | unsigned conflicts; | 217 | int timeout_ms; // must be signed |
220 | unsigned nprobes; | ||
221 | unsigned nclaims; | ||
222 | int verbose; | 218 | int verbose; |
223 | } L; | 219 | } L; |
224 | #define null_addr (L.null_addr ) | 220 | #define null_ethaddr (L.null_ethaddr) |
225 | #define chosen_nip (L.chosen_nip) | 221 | #define ifr (L.ifr ) |
226 | #define ifr (L.ifr ) | 222 | #define chosen_nip (L.chosen_nip ) |
227 | #define timeout_ms (L.timeout_ms) | 223 | #define conflicts (L.conflicts ) |
228 | #define conflicts (L.conflicts ) | 224 | #define timeout_ms (L.timeout_ms ) |
229 | #define nprobes (L.nprobes ) | 225 | #define verbose (L.verbose ) |
230 | #define nclaims (L.nclaims ) | ||
231 | #define verbose (L.verbose ) | ||
232 | 226 | ||
233 | memset(&L, 0, sizeof(L)); | 227 | memset(&L, 0, sizeof(L)); |
234 | INIT_G(); | 228 | INIT_G(); |
235 | 229 | ||
236 | #define FOREGROUND (opts & 1) | 230 | #define FOREGROUND (opts & 1) |
237 | #define QUIT (opts & 2) | 231 | #define QUIT (opts & 2) |
238 | // parse commandline: prog [options] ifname script | 232 | // Parse commandline: prog [options] ifname script |
239 | // exactly 2 args; -v accumulates and implies -f | 233 | // exactly 2 args; -v accumulates and implies -f |
240 | opt_complementary = "=2:vv:vf"; | 234 | opt_complementary = "=2:vv:vf"; |
241 | opts = getopt32(argv, "fqr:l:v", &r_opt, &l_opt, &verbose); | 235 | opts = getopt32(argv, "fqr:l:v", &r_opt, &l_opt, &verbose); |
@@ -244,7 +238,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
244 | if (!FOREGROUND) | 238 | if (!FOREGROUND) |
245 | bb_daemonize_or_rexec(0 /*was: DAEMON_CHDIR_ROOT*/, argv); | 239 | bb_daemonize_or_rexec(0 /*was: DAEMON_CHDIR_ROOT*/, argv); |
246 | #endif | 240 | #endif |
247 | // open an ARP socket | 241 | // Open an ARP socket |
248 | // (need to do it before openlog to prevent openlog from taking | 242 | // (need to do it before openlog to prevent openlog from taking |
249 | // fd 3 (sock_fd==3)) | 243 | // fd 3 (sock_fd==3)) |
250 | xmove_fd(xsocket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)), sock_fd); | 244 | xmove_fd(xsocket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)), sock_fd); |
@@ -284,26 +278,26 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
284 | 278 | ||
285 | xsetenv("interface", argv_intf); | 279 | xsetenv("interface", argv_intf); |
286 | 280 | ||
287 | // initialize the interface (modprobe, ifup, etc) | 281 | // Initialize the interface (modprobe, ifup, etc) |
288 | if (run(argv, "init", 0)) | 282 | if (run(argv, "init", 0)) |
289 | return EXIT_FAILURE; | 283 | return EXIT_FAILURE; |
290 | 284 | ||
291 | // initialize G.iface_sockaddr | 285 | // Initialize G.iface_sockaddr |
292 | // G.iface_sockaddr is: { u16 sa_family; u8 sa_data[14]; } | 286 | // G.iface_sockaddr is: { u16 sa_family; u8 sa_data[14]; } |
293 | //memset(&G.iface_sockaddr, 0, sizeof(G.iface_sockaddr)); | 287 | //memset(&G.iface_sockaddr, 0, sizeof(G.iface_sockaddr)); |
294 | //TODO: are we leaving sa_family == 0 (AF_UNSPEC)?! | 288 | //TODO: are we leaving sa_family == 0 (AF_UNSPEC)?! |
295 | safe_strncpy(G.iface_sockaddr.sa_data, argv_intf, sizeof(G.iface_sockaddr.sa_data)); | 289 | safe_strncpy(G.iface_sockaddr.sa_data, argv_intf, sizeof(G.iface_sockaddr.sa_data)); |
296 | 290 | ||
297 | // bind to the interface's ARP socket | 291 | // Bind to the interface's ARP socket |
298 | xbind(sock_fd, &G.iface_sockaddr, sizeof(G.iface_sockaddr)); | 292 | xbind(sock_fd, &G.iface_sockaddr, sizeof(G.iface_sockaddr)); |
299 | 293 | ||
300 | // get the interface's ethernet address | 294 | // Get the interface's ethernet address |
301 | //memset(&ifr, 0, sizeof(ifr)); | 295 | //memset(&ifr, 0, sizeof(ifr)); |
302 | strncpy_IFNAMSIZ(ifr.ifr_name, argv_intf); | 296 | strncpy_IFNAMSIZ(ifr.ifr_name, argv_intf); |
303 | xioctl(sock_fd, SIOCGIFHWADDR, &ifr); | 297 | xioctl(sock_fd, SIOCGIFHWADDR, &ifr); |
304 | memcpy(&G.eth_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN); | 298 | memcpy(&G.our_ethaddr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN); |
305 | 299 | ||
306 | // start with some stable ip address, either a function of | 300 | // Start with some stable ip address, either a function of |
307 | // the hardware address or else the last address we used. | 301 | // the hardware address or else the last address we used. |
308 | // we are taking low-order four bytes, as top-order ones | 302 | // we are taking low-order four bytes, as top-order ones |
309 | // aren't random enough. | 303 | // aren't random enough. |
@@ -311,17 +305,14 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
311 | // depending on when we detect conflicts. | 305 | // depending on when we detect conflicts. |
312 | { | 306 | { |
313 | uint32_t t; | 307 | uint32_t t; |
314 | move_from_unaligned32(t, ((char *)&G.eth_addr + 2)); | 308 | move_from_unaligned32(t, ((char *)&G.our_ethaddr + 2)); |
315 | srand(t); | 309 | srand(t); |
316 | } | 310 | } |
317 | if (chosen_nip == 0) | ||
318 | chosen_nip = pick_nip(); | ||
319 | |||
320 | // FIXME cases to handle: | 311 | // FIXME cases to handle: |
321 | // - zcip already running! | 312 | // - zcip already running! |
322 | // - link already has local address... just defend/update | 313 | // - link already has local address... just defend/update |
323 | 314 | ||
324 | // daemonize now; don't delay system startup | 315 | // Daemonize now; don't delay system startup |
325 | if (!FOREGROUND) { | 316 | if (!FOREGROUND) { |
326 | #if BB_MMU | 317 | #if BB_MMU |
327 | bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/); | 318 | bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/); |
@@ -329,14 +320,14 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
329 | bb_info_msg("start, interface %s", argv_intf); | 320 | bb_info_msg("start, interface %s", argv_intf); |
330 | } | 321 | } |
331 | 322 | ||
332 | // run the dynamic address negotiation protocol, | 323 | // Run the dynamic address negotiation protocol, |
333 | // restarting after address conflicts: | 324 | // restarting after address conflicts: |
334 | // - start with some address we want to try | 325 | // - start with some address we want to try |
335 | // - short random delay | 326 | // - short random delay |
336 | // - arp probes to see if another host uses it | 327 | // - arp probes to see if another host uses it |
337 | // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ARP (0x0806): arp who-has 169.254.194.171 tell 0.0.0.0 | 328 | // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff arp who-has 169.254.194.171 tell 0.0.0.0 |
338 | // - arp announcements that we're claiming it | 329 | // - arp announcements that we're claiming it |
339 | // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ARP (0x0806): arp who-has 169.254.194.171 (00:04:e2:64:23:c2) tell 169.254.194.171 | 330 | // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff arp who-has 169.254.194.171 (00:04:e2:64:23:c2) tell 169.254.194.171 |
340 | // - use it | 331 | // - use it |
341 | // - defend it, within limits | 332 | // - defend it, within limits |
342 | // exit if: | 333 | // exit if: |
@@ -344,215 +335,191 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
344 | // run "<script> config", then exit with exitcode 0 | 335 | // run "<script> config", then exit with exitcode 0 |
345 | // - poll error (when does this happen?) | 336 | // - poll error (when does this happen?) |
346 | // - read error (when does this happen?) | 337 | // - read error (when does this happen?) |
347 | // - sendto error (in arp()) (when does this happen?) | 338 | // - sendto error (in send_arp_request()) (when does this happen?) |
348 | // - revents & POLLERR (link down). run "<script> deconfig" first | 339 | // - revents & POLLERR (link down). run "<script> deconfig" first |
340 | if (chosen_nip == 0) { | ||
341 | new_nip_and_PROBE: | ||
342 | chosen_nip = pick_nip(); | ||
343 | } | ||
344 | nsent = 0; | ||
349 | state = PROBE; | 345 | state = PROBE; |
350 | while (1) { | 346 | while (1) { |
351 | struct pollfd fds[1]; | 347 | struct pollfd fds[1]; |
352 | unsigned deadline_us; | 348 | unsigned deadline_us; |
353 | struct arp_packet p; | 349 | struct arp_packet p; |
354 | int source_ip_conflict; | 350 | int ip_conflict; |
355 | int target_ip_conflict; | 351 | int n; |
356 | 352 | ||
357 | fds[0].fd = sock_fd; | 353 | fds[0].fd = sock_fd; |
358 | fds[0].events = POLLIN; | 354 | fds[0].events = POLLIN; |
359 | fds[0].revents = 0; | 355 | fds[0].revents = 0; |
360 | 356 | ||
361 | // poll, being ready to adjust current timeout | 357 | // Poll, being ready to adjust current timeout |
362 | if (!timeout_ms) { | 358 | if (!timeout_ms) { |
363 | timeout_ms = random_delay_ms(PROBE_WAIT); | 359 | timeout_ms = random_delay_ms(PROBE_WAIT); |
364 | // FIXME setsockopt(sock_fd, SO_ATTACH_FILTER, ...) to | 360 | // FIXME setsockopt(sock_fd, SO_ATTACH_FILTER, ...) to |
365 | // make the kernel filter out all packets except | 361 | // make the kernel filter out all packets except |
366 | // ones we'd care about. | 362 | // ones we'd care about. |
367 | } | 363 | } |
368 | // set deadline_us to the point in time when we timeout | 364 | // Set deadline_us to the point in time when we timeout |
369 | deadline_us = MONOTONIC_US() + timeout_ms * 1000; | 365 | deadline_us = MONOTONIC_US() + timeout_ms * 1000; |
370 | 366 | ||
371 | VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", | 367 | VDBG("...wait %d %s nsent=%u\n", |
372 | timeout_ms, argv_intf, nprobes, nclaims); | 368 | timeout_ms, argv_intf, nsent); |
373 | |||
374 | switch (safe_poll(fds, 1, timeout_ms)) { | ||
375 | 369 | ||
376 | default: | 370 | n = safe_poll(fds, 1, timeout_ms); |
371 | if (n < 0) { | ||
377 | //bb_perror_msg("poll"); - done in safe_poll | 372 | //bb_perror_msg("poll"); - done in safe_poll |
378 | return EXIT_FAILURE; | 373 | return EXIT_FAILURE; |
379 | 374 | } | |
380 | // timeout | 375 | if (n == 0) { // timed out? |
381 | case 0: | 376 | VDBG("state:%d\n", state); |
382 | VDBG("state = %d\n", state); | ||
383 | switch (state) { | 377 | switch (state) { |
384 | case PROBE: | 378 | case PROBE: |
385 | // timeouts in the PROBE state mean no conflicting ARP packets | 379 | // No conflicting ARP packets were seen: |
386 | // have been received, so we can progress through the states | 380 | // we can progress through the states |
387 | if (nprobes < PROBE_NUM) { | 381 | if (nsent < PROBE_NUM) { |
388 | nprobes++; | 382 | nsent++; |
389 | VDBG("probe/%u %s@%s\n", | 383 | VDBG("probe/%u %s@%s\n", |
390 | nprobes, argv_intf, nip_to_a(chosen_nip)); | 384 | nsent, argv_intf, nip_to_a(chosen_nip)); |
391 | timeout_ms = PROBE_MIN * 1000; | 385 | timeout_ms = PROBE_MIN * 1000; |
392 | timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); | 386 | timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); |
393 | arp(/* ARPOP_REQUEST, */ | 387 | send_arp_request(0, &null_ethaddr, chosen_nip); |
394 | /* &G.eth_addr, */ 0, | 388 | continue; |
395 | &null_addr, chosen_nip); | ||
396 | break; | ||
397 | } | 389 | } |
398 | // Switch to announce state. | 390 | // Switch to announce state |
399 | nclaims = 0; | 391 | nsent = 0; |
400 | state = ANNOUNCE; | 392 | state = ANNOUNCE; |
401 | goto send_announce; | 393 | goto send_announce; |
402 | case ANNOUNCE: | 394 | case ANNOUNCE: |
403 | // timeouts in the ANNOUNCE state mean no conflicting ARP packets | 395 | // No conflicting ARP packets were seen: |
404 | // have been received, so we can progress through the states | 396 | // we can progress through the states |
405 | if (nclaims < ANNOUNCE_NUM) { | 397 | if (nsent < ANNOUNCE_NUM) { |
406 | send_announce: | 398 | send_announce: |
407 | nclaims++; | 399 | nsent++; |
408 | VDBG("announce/%u %s@%s\n", | 400 | VDBG("announce/%u %s@%s\n", |
409 | nclaims, argv_intf, nip_to_a(chosen_nip)); | 401 | nsent, argv_intf, nip_to_a(chosen_nip)); |
410 | timeout_ms = ANNOUNCE_INTERVAL * 1000; | 402 | timeout_ms = ANNOUNCE_INTERVAL * 1000; |
411 | arp(/* ARPOP_REQUEST, */ | 403 | send_arp_request(chosen_nip, &G.our_ethaddr, chosen_nip); |
412 | /* &G.eth_addr, */ chosen_nip, | 404 | continue; |
413 | &G.eth_addr, chosen_nip); | ||
414 | break; | ||
415 | } | 405 | } |
416 | // Switch to monitor state. | 406 | // Switch to monitor state |
417 | // FIXME update filters | 407 | // FIXME update filters |
418 | run(argv, "config", chosen_nip); | 408 | run(argv, "config", chosen_nip); |
419 | // NOTE: all other exit paths should deconfig... | 409 | // NOTE: all other exit paths should deconfig... |
420 | if (QUIT) | 410 | if (QUIT) |
421 | return EXIT_SUCCESS; | 411 | return EXIT_SUCCESS; |
422 | conflicts = 0; | 412 | // fall through: switch to MONITOR |
423 | timeout_ms = -1; // Never timeout in the monitor state. | 413 | default: |
424 | state = MONITOR; | 414 | // case DEFEND: |
425 | break; | 415 | // case MONITOR: (shouldn't happen, MONITOR timeout is infinite) |
426 | case DEFEND: | 416 | // Defend period ended with no ARP replies - we won |
427 | // Defend period ended with no ARP replies - we won. | 417 | timeout_ms = -1; // never timeout in monitor state |
428 | conflicts = 0; | ||
429 | timeout_ms = -1; | ||
430 | state = MONITOR; | 418 | state = MONITOR; |
431 | break; | ||
432 | } // switch (state) | ||
433 | break; // case 0 (timeout) | ||
434 | |||
435 | // packets arriving, or link went down | ||
436 | case 1: | ||
437 | // We need to adjust the timeout in case we didn't receive | ||
438 | // a conflicting packet. | ||
439 | if (timeout_ms > 0) { | ||
440 | unsigned diff = deadline_us - MONOTONIC_US(); | ||
441 | if ((int)(diff) < 0) { | ||
442 | // Current time is greater than the expected timeout time. | ||
443 | diff = 0; | ||
444 | } | ||
445 | VDBG("adjusting timeout\n"); | ||
446 | timeout_ms = (diff / 1000) | 1; /* never 0 */ | ||
447 | } | ||
448 | |||
449 | if ((fds[0].revents & POLLIN) == 0) { | ||
450 | if (fds[0].revents & POLLERR) { | ||
451 | // FIXME: links routinely go down; | ||
452 | // this shouldn't necessarily exit. | ||
453 | bb_error_msg("iface %s is down", argv_intf); | ||
454 | if (state >= MONITOR) { | ||
455 | /* only if we are in MONITOR or DEFEND */ | ||
456 | run(argv, "deconfig", chosen_nip); | ||
457 | } | ||
458 | return EXIT_FAILURE; | ||
459 | } | ||
460 | continue; | 419 | continue; |
461 | } | 420 | } |
421 | } | ||
462 | 422 | ||
463 | // read ARP packet | 423 | // Packet arrived, or link went down. |
464 | if (safe_read(sock_fd, &p, sizeof(p)) < 0) { | 424 | // We need to adjust the timeout in case we didn't receive |
465 | bb_perror_msg_and_die(bb_msg_read_error); | 425 | // a conflicting packet. |
426 | if (timeout_ms > 0) { | ||
427 | unsigned diff = deadline_us - MONOTONIC_US(); | ||
428 | if ((int)(diff) < 0) { | ||
429 | // Current time is greater than the expected timeout time. | ||
430 | diff = 0; | ||
466 | } | 431 | } |
432 | VDBG("adjusting timeout\n"); | ||
433 | timeout_ms = (diff / 1000) | 1; // never 0 | ||
434 | } | ||
467 | 435 | ||
468 | if (p.eth.ether_type != htons(ETHERTYPE_ARP)) | 436 | if ((fds[0].revents & POLLIN) == 0) { |
469 | continue; | 437 | if (fds[0].revents & POLLERR) { |
470 | if (p.arp.arp_op != htons(ARPOP_REQUEST) | 438 | // FIXME: links routinely go down; |
471 | && p.arp.arp_op != htons(ARPOP_REPLY) | 439 | // this shouldn't necessarily exit. |
472 | ) { | 440 | bb_error_msg("iface %s is down", argv_intf); |
473 | continue; | 441 | if (state >= MONITOR) { |
442 | // Only if we are in MONITOR or DEFEND | ||
443 | run(argv, "deconfig", chosen_nip); | ||
444 | } | ||
445 | return EXIT_FAILURE; | ||
474 | } | 446 | } |
447 | continue; | ||
448 | } | ||
449 | |||
450 | // Read ARP packet | ||
451 | if (safe_read(sock_fd, &p, sizeof(p)) < 0) { | ||
452 | bb_perror_msg_and_die(bb_msg_read_error); | ||
453 | } | ||
454 | |||
455 | if (p.eth.ether_type != htons(ETHERTYPE_ARP)) | ||
456 | continue; | ||
457 | if (p.arp.arp_op != htons(ARPOP_REQUEST) | ||
458 | && p.arp.arp_op != htons(ARPOP_REPLY) | ||
459 | ) { | ||
460 | continue; | ||
461 | } | ||
475 | #ifdef DEBUG | 462 | #ifdef DEBUG |
476 | { | 463 | { |
477 | struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha; | 464 | struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha; |
478 | struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; | 465 | struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; |
479 | struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; | 466 | struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; |
480 | struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; | 467 | struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; |
481 | VDBG("%s recv arp type=%d, op=%d,\n", | 468 | VDBG("source=%s %s\n", ether_ntoa(sha), inet_ntoa(*spa)); |
482 | argv_intf, ntohs(p.eth.ether_type), | 469 | VDBG("target=%s %s\n", ether_ntoa(tha), inet_ntoa(*tpa)); |
483 | ntohs(p.arp.arp_op)); | 470 | } |
484 | VDBG("\tsource=%s %s\n", | ||
485 | ether_ntoa(sha), | ||
486 | inet_ntoa(*spa)); | ||
487 | VDBG("\ttarget=%s %s\n", | ||
488 | ether_ntoa(tha), | ||
489 | inet_ntoa(*tpa)); | ||
490 | } | ||
491 | #endif | 471 | #endif |
492 | source_ip_conflict = 0; | 472 | ip_conflict = 0; |
493 | target_ip_conflict = 0; | 473 | if (memcmp(&p.arp.arp_sha, &G.our_ethaddr, ETH_ALEN) != 0) { |
494 | 474 | if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) { | |
495 | if (memcmp(&p.arp.arp_sha, &G.eth_addr, ETH_ALEN) != 0) { | 475 | // A probe or reply with source_ip == chosen ip |
496 | if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) { | 476 | ip_conflict = 1; |
497 | /* A probe or reply with source_ip == chosen ip */ | ||
498 | source_ip_conflict = 1; | ||
499 | } | ||
500 | if (p.arp.arp_op == htons(ARPOP_REQUEST) | ||
501 | && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0 | ||
502 | && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0 | ||
503 | ) { | ||
504 | /* A probe with source_ip == 0.0.0.0, target_ip == chosen ip: | ||
505 | * another host trying to claim this ip! | ||
506 | */ | ||
507 | target_ip_conflict = 1; | ||
508 | } | ||
509 | } | 477 | } |
478 | if (p.arp.arp_op == htons(ARPOP_REQUEST) | ||
479 | && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0 | ||
480 | && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0 | ||
481 | ) { | ||
482 | // A probe with source_ip == 0.0.0.0, target_ip == chosen ip: | ||
483 | // another host trying to claim this ip! | ||
484 | ip_conflict |= 2; | ||
485 | } | ||
486 | } | ||
487 | VDBG("state:%d ip_conflict:%d\n", state, ip_conflict); | ||
488 | if (!ip_conflict) | ||
489 | continue; | ||
490 | |||
491 | // Either src or target IP conflict exists | ||
492 | if (state <= ANNOUNCE) { | ||
493 | // PROBE or ANNOUNCE | ||
494 | conflicts++; | ||
495 | timeout_ms = PROBE_MIN * 1000 | ||
496 | + CONFLICT_MULTIPLIER * random_delay_ms(conflicts); | ||
497 | goto new_nip_and_PROBE; | ||
498 | } | ||
510 | 499 | ||
511 | VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n", | 500 | // MONITOR or DEFEND: only src IP conflict is a problem |
512 | state, source_ip_conflict, target_ip_conflict); | 501 | if (ip_conflict & 1) { |
513 | switch (state) { | 502 | if (state == MONITOR) { |
514 | case PROBE: | 503 | // Src IP conflict, defend with a single ARP probe |
515 | case ANNOUNCE: | 504 | VDBG("monitor conflict - defending\n"); |
516 | // When probing or announcing, check for source IP conflicts | 505 | timeout_ms = DEFEND_INTERVAL * 1000; |
517 | // and other hosts doing ARP probes (target IP conflicts). | 506 | state = DEFEND; |
518 | if (source_ip_conflict || target_ip_conflict) { | 507 | send_arp_request(chosen_nip, &G.our_ethaddr, chosen_nip); |
519 | conflicts++; | 508 | continue; |
520 | timeout_ms = PROBE_MIN * 1000 | 509 | } |
521 | + CONFLICT_MULTIPLIER * random_delay_ms(conflicts); | 510 | // state == DEFEND |
522 | chosen_nip = pick_nip(); | 511 | // Another src IP conflict, start over |
523 | nprobes = 0; | 512 | VDBG("defend conflict - starting over\n"); |
524 | nclaims = 0; | 513 | run(argv, "deconfig", chosen_nip); |
525 | state = PROBE; | 514 | conflicts = 0; |
526 | } | 515 | timeout_ms = 0; |
527 | break; | 516 | goto new_nip_and_PROBE; |
528 | case MONITOR: | 517 | } |
529 | // If a conflict, we try to defend with a single ARP probe. | 518 | // Note: if we only have a target IP conflict here (ip_conflict & 2), |
530 | if (source_ip_conflict) { | 519 | // IOW: if we just saw this sort of ARP packet: |
531 | VDBG("monitor conflict -- defending\n"); | 520 | // aa:bb:cc:dd:ee:ff > xx:xx:xx:xx:xx:xx arp who-has <chosen_nip> tell 0.0.0.0 |
532 | timeout_ms = DEFEND_INTERVAL * 1000; | 521 | // we expect _kernel_ to respond to that, because <chosen_nip> |
533 | state = DEFEND; | 522 | // is (expected to be) configured on this iface. |
534 | arp(/* ARPOP_REQUEST, */ | ||
535 | /* &G.eth_addr, */ chosen_nip, | ||
536 | &G.eth_addr, chosen_nip); | ||
537 | } | ||
538 | break; | ||
539 | case DEFEND: | ||
540 | // Well, we tried. Start over (on conflict). | ||
541 | if (source_ip_conflict) { | ||
542 | VDBG("defend conflict -- starting over\n"); | ||
543 | run(argv, "deconfig", chosen_nip); | ||
544 | |||
545 | // restart the whole protocol | ||
546 | timeout_ms = 0; | ||
547 | chosen_nip = pick_nip(); | ||
548 | nprobes = 0; | ||
549 | nclaims = 0; | ||
550 | state = PROBE; | ||
551 | } | ||
552 | break; | ||
553 | } // switch state | ||
554 | break; // case 1 (packets arriving) | ||
555 | } // switch poll | ||
556 | } // while (1) | 523 | } // while (1) |
557 | #undef argv_intf | 524 | #undef argv_intf |
558 | } | 525 | } |
diff --git a/printutils/lpd.c b/printutils/lpd.c index eaf42c08b..c98bbb347 100644 --- a/printutils/lpd.c +++ b/printutils/lpd.c | |||
@@ -200,7 +200,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) | |||
200 | if (2 != s[0] && 3 != s[0]) | 200 | if (2 != s[0] && 3 != s[0]) |
201 | goto unsupported_cmd; | 201 | goto unsupported_cmd; |
202 | if (spooling & (1 << (s[0]-1))) { | 202 | if (spooling & (1 << (s[0]-1))) { |
203 | printf("Duplicated subcommand\n"); | 203 | puts("Duplicated subcommand"); |
204 | goto err_exit; | 204 | goto err_exit; |
205 | } | 205 | } |
206 | // get filename | 206 | // get filename |
@@ -208,7 +208,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) | |||
208 | fname = strchr(s, ' '); | 208 | fname = strchr(s, ' '); |
209 | if (!fname) { | 209 | if (!fname) { |
210 | // bad_fname: | 210 | // bad_fname: |
211 | printf("No or bad filename\n"); | 211 | puts("No or bad filename"); |
212 | goto err_exit; | 212 | goto err_exit; |
213 | } | 213 | } |
214 | *fname++ = '\0'; | 214 | *fname++ = '\0'; |
@@ -219,13 +219,13 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) | |||
219 | // get length | 219 | // get length |
220 | expected_len = bb_strtou(s + 1, NULL, 10); | 220 | expected_len = bb_strtou(s + 1, NULL, 10); |
221 | if (errno || expected_len < 0) { | 221 | if (errno || expected_len < 0) { |
222 | printf("Bad length\n"); | 222 | puts("Bad length"); |
223 | goto err_exit; | 223 | goto err_exit; |
224 | } | 224 | } |
225 | if (2 == s[0] && expected_len > 16 * 1024) { | 225 | if (2 == s[0] && expected_len > 16 * 1024) { |
226 | // SECURITY: | 226 | // SECURITY: |
227 | // ctrlfile can't be big (we want to read it back later!) | 227 | // ctrlfile can't be big (we want to read it back later!) |
228 | printf("File is too big\n"); | 228 | puts("File is too big"); |
229 | goto err_exit; | 229 | goto err_exit; |
230 | } | 230 | } |
231 | 231 | ||
diff --git a/procps/iostat.c b/procps/iostat.c index 8d272c87c..c290c594b 100644 --- a/procps/iostat.c +++ b/procps/iostat.c | |||
@@ -142,7 +142,7 @@ static void print_timestamp(void) | |||
142 | /* %x: date representation for the current locale */ | 142 | /* %x: date representation for the current locale */ |
143 | /* %X: time representation for the current locale */ | 143 | /* %X: time representation for the current locale */ |
144 | strftime(buf, sizeof(buf), "%x %X", &G.tmtime); | 144 | strftime(buf, sizeof(buf), "%x %X", &G.tmtime); |
145 | printf("%s\n", buf); | 145 | puts(buf); |
146 | } | 146 | } |
147 | 147 | ||
148 | static cputime_t get_smp_uptime(void) | 148 | static cputime_t get_smp_uptime(void) |
diff --git a/procps/powertop.c b/procps/powertop.c index 1de5d329e..ce85f4191 100644 --- a/procps/powertop.c +++ b/procps/powertop.c | |||
@@ -591,7 +591,7 @@ static NOINLINE void print_intel_cstates(void) | |||
591 | if (!edx || !(ecx & 1)) | 591 | if (!edx || !(ecx & 1)) |
592 | return; | 592 | return; |
593 | 593 | ||
594 | printf("Your CPU supports the following C-states: "); | 594 | printf("Your %s the following C-states: ", "CPU supports"); |
595 | i = 0; | 595 | i = 0; |
596 | while (edx) { | 596 | while (edx) { |
597 | if (edx & 7) | 597 | if (edx & 7) |
@@ -602,7 +602,7 @@ static NOINLINE void print_intel_cstates(void) | |||
602 | bb_putchar('\n'); | 602 | bb_putchar('\n'); |
603 | 603 | ||
604 | /* Print BIOS C-States */ | 604 | /* Print BIOS C-States */ |
605 | printf("Your BIOS reports the following C-states: "); | 605 | printf("Your %s the following C-states: ", "BIOS reports"); |
606 | for (i = 0; i < ARRAY_SIZE(bios_table); i++) | 606 | for (i = 0; i < ARRAY_SIZE(bios_table); i++) |
607 | if (bios_table[i]) | 607 | if (bios_table[i]) |
608 | printf("C%u ", i); | 608 | printf("C%u ", i); |
@@ -704,7 +704,7 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv) | |||
704 | /* Get number of CPUs */ | 704 | /* Get number of CPUs */ |
705 | G.total_cpus = get_cpu_count(); | 705 | G.total_cpus = get_cpu_count(); |
706 | 706 | ||
707 | printf("Collecting data for "DEFAULT_SLEEP_STR" seconds\n"); | 707 | puts("Collecting data for "DEFAULT_SLEEP_STR" seconds"); |
708 | 708 | ||
709 | #if ENABLE_FEATURE_USE_TERMIOS | 709 | #if ENABLE_FEATURE_USE_TERMIOS |
710 | tcgetattr(0, (void *)&G.init_settings); | 710 | tcgetattr(0, (void *)&G.init_settings); |
diff --git a/qemu_multiarch_testing/README b/qemu_multiarch_testing/README new file mode 100644 index 000000000..9757ff0e4 --- /dev/null +++ b/qemu_multiarch_testing/README | |||
@@ -0,0 +1,58 @@ | |||
1 | How to test build using Aboriginal Linux system images. | ||
2 | |||
3 | * Put a source tree into hdc.dir/. | ||
4 | For example, this should work: | ||
5 | git clone git://busybox.net/var/lib/git/busybox.git | ||
6 | |||
7 | * Run ./make-hdc-img.sh: it will generate ext2 image file, | ||
8 | hdc.img, from hdc.dir/* data. This requires root for loop mount. | ||
9 | |||
10 | * Download and unpack, or build from source and unpack | ||
11 | one or more system-image-ARCH directories into this directory | ||
12 | (the one which contains this README). | ||
13 | |||
14 | * Run: ./parallel-build-hdc-img.sh system-image-DIR1 system-image-DIR2... | ||
15 | (background it if you don't want to see "Waiting to finish" thing). | ||
16 | This runs build in several qemu virtual machines in parallel. | ||
17 | |||
18 | * Observe system-image-*.log file(s) with growing log of the build. | ||
19 | |||
20 | There is no automated detection of errors for now: you need to examine | ||
21 | logs yourself. | ||
22 | |||
23 | Log files will also contain uuencoded (or if all else fails, od -tx1'ed) | ||
24 | binary, if build was successful. | ||
25 | |||
26 | To debug a build problem in one of the sandboxes, change keep_hdb | ||
27 | to "keep_hdb=true" in parallel-build-hdc-img.sh | ||
28 | - this preserves system-image-ARCH/hdb.img after the build, | ||
29 | so you can go into system-image-ARCH and run | ||
30 | "HDB=hdb.img ./dev-environment.sh" to debug the problem. | ||
31 | |||
32 | You can also run "./parallel-build-hdc-img.sh -s system-image-ARCH" | ||
33 | - single mode, output is to screen and serial input is from keyboard. | ||
34 | |||
35 | If hdc.dir/bin/busybox-$ARCH exists, it will be used during build | ||
36 | to supply additional tools (dir with all applets appended to $PATH). | ||
37 | |||
38 | For me, the following system images worked: | ||
39 | system-image-armv4l | ||
40 | system-image-armv4tl | ||
41 | system-image-armv5l | ||
42 | od is buggy on arm*: | ||
43 | # echo Hello-hello-hello-hello | od -b | ||
44 | 0000000 110 145 154 154 157 055 150 145 154 154 157 055 150 145 154 154 | ||
45 | 0000000 157 055 150 145 154 154 157 012 <= WRONG OFFSET | ||
46 | 0000000 (can also be even more bogus like 17767153361) | ||
47 | system-image-i686 | ||
48 | system-image-mips - od is buggy | ||
49 | system-image-mipsel - od is buggy | ||
50 | system-image-x86_64 | ||
51 | system-image-powerpc - qemu 1.2.2 didn't work, 2.4.0 worked; od is buggy | ||
52 | system-image-sparc - qemu 1.2.2 didn't work, 2.4.0 worked; od is buggy | ||
53 | |||
54 | And these did not: | ||
55 | system-image-armv6l - hang on "Uncompressing Linux... done, booting the kernel" | ||
56 | system-image-m68k - my qemu doesn't like "-M q800" | ||
57 | system-image-mips64 - init dies "Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000a" | ||
58 | system-image-sh4 - qemu segfaults early in kernel boot | ||
diff --git a/qemu_multiarch_testing/extract_od_binary.sh b/qemu_multiarch_testing/extract_od_binary.sh new file mode 100755 index 000000000..1006e5153 --- /dev/null +++ b/qemu_multiarch_testing/extract_od_binary.sh | |||
@@ -0,0 +1,6 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # Converts textual result of "od -tx1 <FILE" | ||
4 | # back into a binary FILE | ||
5 | |||
6 | grep -a '^[0-7][0-7][0-7][0-7][0-7][0-7][0-7][0-7]* [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f]' | busybox hexdump -R | ||
diff --git a/qemu_multiarch_testing/hdc.dir/build b/qemu_multiarch_testing/hdc.dir/build new file mode 100755 index 000000000..a9981864a --- /dev/null +++ b/qemu_multiarch_testing/hdc.dir/build | |||
@@ -0,0 +1,50 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | umount /mnt # optional | ||
4 | |||
5 | test -x "bin/busybox-$HOST" && { | ||
6 | echo "Found bin/busybox-$HOST, using it" | ||
7 | cp -a "bin/busybox-$HOST" bin/busybox | ||
8 | bin/busybox --install -s bin/ | ||
9 | # Supply missing stuff (e.g. bzip2): | ||
10 | PATH="$PATH:$PWD/bin" | ||
11 | # Override known-buggy host binaries: | ||
12 | cp -af bin/od `which od` | ||
13 | } | ||
14 | |||
15 | ( | ||
16 | #set -e -x | ||
17 | cd busybox | ||
18 | |||
19 | make defconfig | ||
20 | # Want static build | ||
21 | sed 's/^.*CONFIG_STATIC.*$/CONFIG_STATIC=y/' -i .config | ||
22 | bzip2 </dev/null >/dev/null || { | ||
23 | # Drats, newer Aboriginal Linux has no bzip2 | ||
24 | sed 's/^.*CONFIG_FEATURE_COMPRESS_USAGE.*$/# CONFIG_FEATURE_COMPRESS_USAGE is not set/' -i .config | ||
25 | } | ||
26 | test x"`uname -m`" = x"mips" && { | ||
27 | # Without this, I get MIPS-I binary instead of MIPS32. | ||
28 | # No idea what's the difference, but my router wants MIPS32. | ||
29 | sed 's/^.*CONFIG_EXTRA_CFLAGS.*$/CONFIG_EXTRA_CFLAGS="-mips32"/' -i .config | ||
30 | } | ||
31 | # These won't build because of toolchain/libc breakage: | ||
32 | sed 's/^.*CONFIG_FEATURE_SYNC_FANCY.*$/# CONFIG_FEATURE_SYNC_FANCY is not set/' -i .config # no syncfs() | ||
33 | sed 's/^.*CONFIG_FEATURE_WTMP.*$/# CONFIG_FEATURE_WTMP is not set/' -i .config | ||
34 | sed 's/^.*CONFIG_FEATURE_UTMP.*$/# CONFIG_FEATURE_UTMP is not set/' -i .config | ||
35 | sed 's/^.*CONFIG_FEATURE_INETD_RPC.*$/# CONFIG_FEATURE_INETD_RPC is not set/' -i .config | ||
36 | |||
37 | make #V=1 || sh | ||
38 | size busybox | ||
39 | ./busybox || echo "Exit code: $?" | ||
40 | if uuencode TEST </dev/null >/dev/null && bzip2 </dev/null >/dev/null; then | ||
41 | bzip2 <busybox | uuencode busybox.bz2 | ||
42 | else | ||
43 | od -v -tx1 <busybox | ||
44 | fi | ||
45 | #test "x$FTP_PORT" = x || | ||
46 | # ftpput -P "$FTP_PORT" "$FTP_SERVER" strace | ||
47 | ) 2>&1 | tee build.log | ||
48 | mount -o remount,ro /home | ||
49 | sync | ||
50 | sleep 1 | ||
diff --git a/qemu_multiarch_testing/hdc.dir/init b/qemu_multiarch_testing/hdc.dir/init new file mode 100755 index 000000000..692371db6 --- /dev/null +++ b/qemu_multiarch_testing/hdc.dir/init | |||
@@ -0,0 +1,9 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # Emit a msg to let user know this place was reached | ||
4 | echo "Copying to /home" | ||
5 | # Had a case where cp SEGVs, let's have diagnostics for it | ||
6 | cp -a /mnt /home || { echo "cp: $?"; exit 1; } | ||
7 | cd /home/mnt || { echo "cd: $?"; exit 1; } | ||
8 | exec ./build | ||
9 | echo "Failed to exec ./build" | ||
diff --git a/qemu_multiarch_testing/make-hdc-img.sh b/qemu_multiarch_testing/make-hdc-img.sh new file mode 100755 index 000000000..3c35f4ead --- /dev/null +++ b/qemu_multiarch_testing/make-hdc-img.sh | |||
@@ -0,0 +1,30 @@ | |||
1 | #!/bin/sh -ex | ||
2 | |||
3 | mountpoint -q / | ||
4 | [ ! -e hdc.img.dir ] | ||
5 | |||
6 | cleanup() | ||
7 | { | ||
8 | trap - EXIT | ||
9 | if mountpoint -q hdc.img.dir; then | ||
10 | umount -d hdc.img.dir | ||
11 | fi | ||
12 | mountpoint -q hdc.img.dir || | ||
13 | rm -rf hdc.img.dir | ||
14 | exit $@ | ||
15 | } | ||
16 | |||
17 | trap 'cleanup $?' EXIT | ||
18 | trap 'cleanup 1' HUP PIPE INT QUIT TERM | ||
19 | |||
20 | size=$(du -ks hdc.dir | sed -rn 's/^([0-9]+).*/\1/p') | ||
21 | [ "$size" -gt 0 ] | ||
22 | |||
23 | rm -f hdc.img | ||
24 | dd if=/dev/zero of=hdc.img count=1 bs=1024 seek=$(($size*2)) | ||
25 | mkfs.ext3 -q -F -b 1024 -i 4096 hdc.img | ||
26 | tune2fs -c 0 -i 0 hdc.img | ||
27 | mkdir hdc.img.dir | ||
28 | mount -o loop hdc.img hdc.img.dir | ||
29 | cp -a hdc.dir/* hdc.img.dir/ | ||
30 | umount -d hdc.img.dir | ||
diff --git a/qemu_multiarch_testing/parallel-build-hdc-img.sh b/qemu_multiarch_testing/parallel-build-hdc-img.sh new file mode 100755 index 000000000..9ee54ebb8 --- /dev/null +++ b/qemu_multiarch_testing/parallel-build-hdc-img.sh | |||
@@ -0,0 +1,40 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | export HDBMEGS=100 | ||
4 | keep_hdb=false | ||
5 | |||
6 | build_in_dir() | ||
7 | { | ||
8 | cd "$1" || exit 1 | ||
9 | rm -f hdb.img | ||
10 | nice -n10 time ./native-build.sh ../hdc.img | ||
11 | $keep_hdb || rm -f hdb.img | ||
12 | echo >&3 "Finished: $1" | ||
13 | } | ||
14 | |||
15 | test "$1" = "-s" && { | ||
16 | dir="$2" | ||
17 | # single mode: build one directory, show output | ||
18 | test -d "$dir" || exit 1 | ||
19 | test -e "$dir/native-build.sh" || exit 1 | ||
20 | build_in_dir "$dir" | ||
21 | exit $? | ||
22 | } | ||
23 | |||
24 | started=false | ||
25 | for dir; do | ||
26 | test -d "$dir" || continue | ||
27 | test -e "$dir/native-build.sh" || continue | ||
28 | echo "Starting: $dir" | ||
29 | build_in_dir "$dir" 3>&1 </dev/null >"$dir.log" 2>&1 & | ||
30 | started=true | ||
31 | done | ||
32 | |||
33 | $started || { | ||
34 | echo "Give me system-image-ARCH directories on command line" | ||
35 | exit 1 | ||
36 | } | ||
37 | |||
38 | echo "Waiting to finish" | ||
39 | wait | ||
40 | echo "Done, check the logs" | ||
diff --git a/runit/runsv.c b/runit/runsv.c index d941e897d..6cf5bcc29 100644 --- a/runit/runsv.c +++ b/runit/runsv.c | |||
@@ -49,16 +49,11 @@ static void gettimeofday_ns(struct timespec *ts) | |||
49 | #else | 49 | #else |
50 | static void gettimeofday_ns(struct timespec *ts) | 50 | static void gettimeofday_ns(struct timespec *ts) |
51 | { | 51 | { |
52 | if (sizeof(struct timeval) == sizeof(struct timespec) | 52 | BUILD_BUG_ON(sizeof(struct timeval) != sizeof(struct timespec)); |
53 | && sizeof(((struct timeval*)ts)->tv_usec) == sizeof(ts->tv_nsec) | 53 | BUILD_BUG_ON(sizeof(((struct timeval*)ts)->tv_usec) != sizeof(ts->tv_nsec)); |
54 | ) { | 54 | /* Cheat */ |
55 | /* Cheat */ | 55 | gettimeofday((void*)ts, NULL); |
56 | gettimeofday((void*)ts, NULL); | 56 | ts->tv_nsec *= 1000; |
57 | ts->tv_nsec *= 1000; | ||
58 | } else { | ||
59 | extern void BUG_need_to_implement_gettimeofday_ns(void); | ||
60 | BUG_need_to_implement_gettimeofday_ns(); | ||
61 | } | ||
62 | } | 57 | } |
63 | #endif | 58 | #endif |
64 | 59 | ||
@@ -114,7 +109,7 @@ struct globals { | |||
114 | 109 | ||
115 | static void fatal2_cannot(const char *m1, const char *m2) | 110 | static void fatal2_cannot(const char *m1, const char *m2) |
116 | { | 111 | { |
117 | bb_perror_msg_and_die("%s: fatal: cannot %s%s", dir, m1, m2); | 112 | bb_perror_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2); |
118 | /* was exiting 111 */ | 113 | /* was exiting 111 */ |
119 | } | 114 | } |
120 | static void fatal_cannot(const char *m) | 115 | static void fatal_cannot(const char *m) |
@@ -124,7 +119,7 @@ static void fatal_cannot(const char *m) | |||
124 | } | 119 | } |
125 | static void fatal2x_cannot(const char *m1, const char *m2) | 120 | static void fatal2x_cannot(const char *m1, const char *m2) |
126 | { | 121 | { |
127 | bb_error_msg_and_die("%s: fatal: cannot %s%s", dir, m1, m2); | 122 | bb_error_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2); |
128 | /* was exiting 111 */ | 123 | /* was exiting 111 */ |
129 | } | 124 | } |
130 | static void warn_cannot(const char *m) | 125 | static void warn_cannot(const char *m) |
diff --git a/scripts/randomtest b/scripts/randomtest index d2b26bc76..e2513d058 100755 --- a/scripts/randomtest +++ b/scripts/randomtest | |||
@@ -65,14 +65,16 @@ if test x"$LIBC" = x"uclibc"; then | |||
65 | | grep -v CONFIG_BUILD_LIBBUSYBOX \ | 65 | | grep -v CONFIG_BUILD_LIBBUSYBOX \ |
66 | | grep -v CONFIG_PIE \ | 66 | | grep -v CONFIG_PIE \ |
67 | \ | 67 | \ |
68 | | grep -v CONFIG_FEATURE_TOUCH_NODEREF \ | ||
69 | | grep -v CONFIG_FEATURE_2_4_MODULES \ | 68 | | grep -v CONFIG_FEATURE_2_4_MODULES \ |
69 | | grep -v CONFIG_FEATURE_SYNC_FANCY \ | ||
70 | | grep -v CONFIG_FEATURE_TOUCH_NODEREF \ | ||
70 | >.config.new | 71 | >.config.new |
71 | mv .config.new .config | 72 | mv .config.new .config |
72 | echo 'CONFIG_STATIC=y' >>.config | 73 | echo 'CONFIG_STATIC=y' >>.config |
73 | echo '# CONFIG_BUILD_LIBBUSYBOX is not set' >>.config | 74 | echo '# CONFIG_BUILD_LIBBUSYBOX is not set' >>.config |
74 | echo '# CONFIG_PIE is not set' >>.config | 75 | echo '# CONFIG_PIE is not set' >>.config |
75 | echo '# CONFIG_FEATURE_2_4_MODULES is not set' >>.config | 76 | echo '# CONFIG_FEATURE_2_4_MODULES is not set' >>.config |
77 | echo '# CONFIG_FEATURE_SYNC_FANCY is not set' >>.config | ||
76 | echo '# CONFIG_FEATURE_TOUCH_NODEREF is not set' >>.config | 78 | echo '# CONFIG_FEATURE_TOUCH_NODEREF is not set' >>.config |
77 | fi | 79 | fi |
78 | 80 | ||
diff --git a/shell/ash.c b/shell/ash.c index e9850f493..21fc05f01 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -607,11 +607,12 @@ flush_stdout_stderr(void) | |||
607 | INT_ON; | 607 | INT_ON; |
608 | } | 608 | } |
609 | 609 | ||
610 | /* Was called outcslow(c,FILE*), but c was always '\n' */ | ||
610 | static void | 611 | static void |
611 | outcslow(int c, FILE *dest) | 612 | newline_and_flush(FILE *dest) |
612 | { | 613 | { |
613 | INT_OFF; | 614 | INT_OFF; |
614 | putc(c, dest); | 615 | putc('\n', dest); |
615 | fflush(dest); | 616 | fflush(dest); |
616 | INT_ON; | 617 | INT_ON; |
617 | } | 618 | } |
@@ -1272,7 +1273,7 @@ ash_vmsg(const char *msg, va_list ap) | |||
1272 | fprintf(stderr, "line %d: ", startlinno); | 1273 | fprintf(stderr, "line %d: ", startlinno); |
1273 | } | 1274 | } |
1274 | vfprintf(stderr, msg, ap); | 1275 | vfprintf(stderr, msg, ap); |
1275 | outcslow('\n', stderr); | 1276 | newline_and_flush(stderr); |
1276 | } | 1277 | } |
1277 | 1278 | ||
1278 | /* | 1279 | /* |
@@ -3528,6 +3529,7 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
3528 | #define SHOW_ONLY_PGID 0x01 /* show only pgid (jobs -p) */ | 3529 | #define SHOW_ONLY_PGID 0x01 /* show only pgid (jobs -p) */ |
3529 | #define SHOW_PIDS 0x02 /* show individual pids, not just one line per job */ | 3530 | #define SHOW_PIDS 0x02 /* show individual pids, not just one line per job */ |
3530 | #define SHOW_CHANGED 0x04 /* only jobs whose state has changed */ | 3531 | #define SHOW_CHANGED 0x04 /* only jobs whose state has changed */ |
3532 | #define SHOW_STDERR 0x08 /* print to stderr (else stdout) */ | ||
3531 | 3533 | ||
3532 | /* | 3534 | /* |
3533 | * A job structure contains information about a job. A job is either a | 3535 | * A job structure contains information about a job. A job is either a |
@@ -4046,7 +4048,7 @@ showpipe(struct job *jp /*, FILE *out*/) | |||
4046 | psend = jp->ps + jp->nprocs; | 4048 | psend = jp->ps + jp->nprocs; |
4047 | for (ps = jp->ps + 1; ps < psend; ps++) | 4049 | for (ps = jp->ps + 1; ps < psend; ps++) |
4048 | printf(" | %s", ps->ps_cmd); | 4050 | printf(" | %s", ps->ps_cmd); |
4049 | outcslow('\n', stdout); | 4051 | newline_and_flush(stdout); |
4050 | flush_stdout_stderr(); | 4052 | flush_stdout_stderr(); |
4051 | } | 4053 | } |
4052 | 4054 | ||
@@ -4106,39 +4108,33 @@ fg_bgcmd(int argc UNUSED_PARAM, char **argv) | |||
4106 | #endif | 4108 | #endif |
4107 | 4109 | ||
4108 | static int | 4110 | static int |
4109 | sprint_status(char *s, int status, int sigonly) | 4111 | sprint_status48(char *s, int status, int sigonly) |
4110 | { | 4112 | { |
4111 | int col; | 4113 | int col; |
4112 | int st; | 4114 | int st; |
4113 | 4115 | ||
4114 | col = 0; | 4116 | col = 0; |
4115 | if (!WIFEXITED(status)) { | 4117 | if (!WIFEXITED(status)) { |
4116 | #if JOBS | 4118 | if (JOBS && WIFSTOPPED(status)) |
4117 | if (WIFSTOPPED(status)) | ||
4118 | st = WSTOPSIG(status); | 4119 | st = WSTOPSIG(status); |
4119 | else | 4120 | else |
4120 | #endif | ||
4121 | st = WTERMSIG(status); | 4121 | st = WTERMSIG(status); |
4122 | if (sigonly) { | 4122 | if (sigonly) { |
4123 | if (st == SIGINT || st == SIGPIPE) | 4123 | if (st == SIGINT || st == SIGPIPE) |
4124 | goto out; | 4124 | goto out; |
4125 | #if JOBS | 4125 | if (JOBS && WIFSTOPPED(status)) |
4126 | if (WIFSTOPPED(status)) | ||
4127 | goto out; | 4126 | goto out; |
4128 | #endif | ||
4129 | } | 4127 | } |
4130 | st &= 0x7f; | 4128 | st &= 0x7f; |
4131 | //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata | 4129 | //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata |
4132 | col = fmtstr(s, 32, strsignal(st)); | 4130 | col = fmtstr(s, 32, strsignal(st)); |
4133 | if (WCOREDUMP(status)) { | 4131 | if (WCOREDUMP(status)) { |
4134 | col += fmtstr(s + col, 16, " (core dumped)"); | 4132 | strcpy(s + col, " (core dumped)"); |
4133 | col += sizeof(" (core dumped)")-1; | ||
4135 | } | 4134 | } |
4136 | } else if (!sigonly) { | 4135 | } else if (!sigonly) { |
4137 | st = WEXITSTATUS(status); | 4136 | st = WEXITSTATUS(status); |
4138 | if (st) | 4137 | col = fmtstr(s, 16, (st ? "Done(%d)" : "Done"), st); |
4139 | col = fmtstr(s, 16, "Done(%d)", st); | ||
4140 | else | ||
4141 | col = fmtstr(s, 16, "Done"); | ||
4142 | } | 4138 | } |
4143 | out: | 4139 | out: |
4144 | return col; | 4140 | return col; |
@@ -4224,7 +4220,6 @@ dowait(int wait_flags, struct job *job) | |||
4224 | int status; | 4220 | int status; |
4225 | struct job *jp; | 4221 | struct job *jp; |
4226 | struct job *thisjob; | 4222 | struct job *thisjob; |
4227 | int state; | ||
4228 | 4223 | ||
4229 | TRACE(("dowait(0x%x) called\n", wait_flags)); | 4224 | TRACE(("dowait(0x%x) called\n", wait_flags)); |
4230 | 4225 | ||
@@ -4246,11 +4241,12 @@ dowait(int wait_flags, struct job *job) | |||
4246 | INT_OFF; | 4241 | INT_OFF; |
4247 | thisjob = NULL; | 4242 | thisjob = NULL; |
4248 | for (jp = curjob; jp; jp = jp->prev_job) { | 4243 | for (jp = curjob; jp; jp = jp->prev_job) { |
4244 | int jobstate; | ||
4249 | struct procstat *ps; | 4245 | struct procstat *ps; |
4250 | struct procstat *psend; | 4246 | struct procstat *psend; |
4251 | if (jp->state == JOBDONE) | 4247 | if (jp->state == JOBDONE) |
4252 | continue; | 4248 | continue; |
4253 | state = JOBDONE; | 4249 | jobstate = JOBDONE; |
4254 | ps = jp->ps; | 4250 | ps = jp->ps; |
4255 | psend = ps + jp->nprocs; | 4251 | psend = ps + jp->nprocs; |
4256 | do { | 4252 | do { |
@@ -4264,41 +4260,41 @@ dowait(int wait_flags, struct job *job) | |||
4264 | ps->ps_pid = -1; | 4260 | ps->ps_pid = -1; |
4265 | } | 4261 | } |
4266 | if (ps->ps_status == -1) | 4262 | if (ps->ps_status == -1) |
4267 | state = JOBRUNNING; | 4263 | jobstate = JOBRUNNING; |
4268 | #if JOBS | 4264 | #if JOBS |
4269 | if (state == JOBRUNNING) | 4265 | if (jobstate == JOBRUNNING) |
4270 | continue; | 4266 | continue; |
4271 | if (WIFSTOPPED(ps->ps_status)) { | 4267 | if (WIFSTOPPED(ps->ps_status)) { |
4272 | jp->stopstatus = ps->ps_status; | 4268 | jp->stopstatus = ps->ps_status; |
4273 | state = JOBSTOPPED; | 4269 | jobstate = JOBSTOPPED; |
4274 | } | 4270 | } |
4275 | #endif | 4271 | #endif |
4276 | } while (++ps < psend); | 4272 | } while (++ps < psend); |
4277 | if (thisjob) | 4273 | if (!thisjob) |
4278 | goto gotjob; | 4274 | continue; |
4279 | } | ||
4280 | #if JOBS | ||
4281 | if (!WIFSTOPPED(status)) | ||
4282 | #endif | ||
4283 | jobless--; | ||
4284 | goto out; | ||
4285 | |||
4286 | gotjob: | ||
4287 | if (state != JOBRUNNING) { | ||
4288 | thisjob->changed = 1; | ||
4289 | 4275 | ||
4290 | if (thisjob->state != state) { | 4276 | /* Found the job where one of its processes changed its state. |
4291 | TRACE(("Job %d: changing state from %d to %d\n", | 4277 | * Is there at least one live and running process in this job? */ |
4292 | jobno(thisjob), thisjob->state, state)); | 4278 | if (jobstate != JOBRUNNING) { |
4293 | thisjob->state = state; | 4279 | /* No. All live processes in the job are stopped |
4280 | * (JOBSTOPPED) or there are no live processes (JOBDONE) | ||
4281 | */ | ||
4282 | thisjob->changed = 1; | ||
4283 | if (thisjob->state != jobstate) { | ||
4284 | TRACE(("Job %d: changing state from %d to %d\n", | ||
4285 | jobno(thisjob), thisjob->state, jobstate)); | ||
4286 | thisjob->state = jobstate; | ||
4294 | #if JOBS | 4287 | #if JOBS |
4295 | if (state == JOBSTOPPED) { | 4288 | if (jobstate == JOBSTOPPED) |
4296 | set_curjob(thisjob, CUR_STOPPED); | 4289 | set_curjob(thisjob, CUR_STOPPED); |
4297 | } | ||
4298 | #endif | 4290 | #endif |
4291 | } | ||
4299 | } | 4292 | } |
4293 | goto out; | ||
4300 | } | 4294 | } |
4301 | 4295 | /* The process wasn't found in job list */ | |
4296 | if (JOBS && !WIFSTOPPED(status)) | ||
4297 | jobless--; | ||
4302 | out: | 4298 | out: |
4303 | INT_ON; | 4299 | INT_ON; |
4304 | 4300 | ||
@@ -4306,7 +4302,7 @@ dowait(int wait_flags, struct job *job) | |||
4306 | char s[48 + 1]; | 4302 | char s[48 + 1]; |
4307 | int len; | 4303 | int len; |
4308 | 4304 | ||
4309 | len = sprint_status(s, status, 1); | 4305 | len = sprint_status48(s, status, 1); |
4310 | if (len) { | 4306 | if (len) { |
4311 | s[len] = '\n'; | 4307 | s[len] = '\n'; |
4312 | s[len + 1] = '\0'; | 4308 | s[len + 1] = '\0'; |
@@ -4327,13 +4323,14 @@ blocking_wait_with_raise_on_sig(void) | |||
4327 | 4323 | ||
4328 | #if JOBS | 4324 | #if JOBS |
4329 | static void | 4325 | static void |
4330 | showjob(FILE *out, struct job *jp, int mode) | 4326 | showjob(struct job *jp, int mode) |
4331 | { | 4327 | { |
4332 | struct procstat *ps; | 4328 | struct procstat *ps; |
4333 | struct procstat *psend; | 4329 | struct procstat *psend; |
4334 | int col; | 4330 | int col; |
4335 | int indent_col; | 4331 | int indent_col; |
4336 | char s[80]; | 4332 | char s[16 + 16 + 48]; |
4333 | FILE *out = (mode & SHOW_STDERR ? stderr : stdout); | ||
4337 | 4334 | ||
4338 | ps = jp->ps; | 4335 | ps = jp->ps; |
4339 | 4336 | ||
@@ -4363,7 +4360,7 @@ showjob(FILE *out, struct job *jp, int mode) | |||
4363 | int status = psend[-1].ps_status; | 4360 | int status = psend[-1].ps_status; |
4364 | if (jp->state == JOBSTOPPED) | 4361 | if (jp->state == JOBSTOPPED) |
4365 | status = jp->stopstatus; | 4362 | status = jp->stopstatus; |
4366 | col += sprint_status(s + col, status, 0); | 4363 | col += sprint_status48(s + col, status, 0); |
4367 | } | 4364 | } |
4368 | /* By now, "[JOBID]* [maybe PID] STATUS" is printed */ | 4365 | /* By now, "[JOBID]* [maybe PID] STATUS" is printed */ |
4369 | 4366 | ||
@@ -4390,7 +4387,7 @@ showjob(FILE *out, struct job *jp, int mode) | |||
4390 | ps->ps_cmd | 4387 | ps->ps_cmd |
4391 | ); | 4388 | ); |
4392 | } while (++ps != psend); | 4389 | } while (++ps != psend); |
4393 | outcslow('\n', out); | 4390 | newline_and_flush(out); |
4394 | 4391 | ||
4395 | jp->changed = 0; | 4392 | jp->changed = 0; |
4396 | 4393 | ||
@@ -4405,7 +4402,7 @@ showjob(FILE *out, struct job *jp, int mode) | |||
4405 | * statuses have changed since the last call to showjobs. | 4402 | * statuses have changed since the last call to showjobs. |
4406 | */ | 4403 | */ |
4407 | static void | 4404 | static void |
4408 | showjobs(FILE *out, int mode) | 4405 | showjobs(int mode) |
4409 | { | 4406 | { |
4410 | struct job *jp; | 4407 | struct job *jp; |
4411 | 4408 | ||
@@ -4417,7 +4414,7 @@ showjobs(FILE *out, int mode) | |||
4417 | 4414 | ||
4418 | for (jp = curjob; jp; jp = jp->prev_job) { | 4415 | for (jp = curjob; jp; jp = jp->prev_job) { |
4419 | if (!(mode & SHOW_CHANGED) || jp->changed) { | 4416 | if (!(mode & SHOW_CHANGED) || jp->changed) { |
4420 | showjob(out, jp, mode); | 4417 | showjob(jp, mode); |
4421 | } | 4418 | } |
4422 | } | 4419 | } |
4423 | } | 4420 | } |
@@ -4438,10 +4435,10 @@ jobscmd(int argc UNUSED_PARAM, char **argv) | |||
4438 | argv = argptr; | 4435 | argv = argptr; |
4439 | if (*argv) { | 4436 | if (*argv) { |
4440 | do | 4437 | do |
4441 | showjob(stdout, getjob(*argv, 0), mode); | 4438 | showjob(getjob(*argv, 0), mode); |
4442 | while (*++argv); | 4439 | while (*++argv); |
4443 | } else { | 4440 | } else { |
4444 | showjobs(stdout, mode); | 4441 | showjobs(mode); |
4445 | } | 4442 | } |
4446 | 4443 | ||
4447 | return 0; | 4444 | return 0; |
@@ -5894,8 +5891,8 @@ cvtnum(arith_t num) | |||
5894 | { | 5891 | { |
5895 | int len; | 5892 | int len; |
5896 | 5893 | ||
5897 | expdest = makestrspace(32, expdest); | 5894 | expdest = makestrspace(sizeof(arith_t)*3 + 2, expdest); |
5898 | len = fmtstr(expdest, 32, ARITH_FMT, num); | 5895 | len = fmtstr(expdest, sizeof(arith_t)*3 + 2, ARITH_FMT, num); |
5899 | STADJUST(len, expdest); | 5896 | STADJUST(len, expdest); |
5900 | return len; | 5897 | return len; |
5901 | } | 5898 | } |
@@ -7326,10 +7323,11 @@ expmeta(char *expdir, char *enddir, char *name) | |||
7326 | struct dirent *dp; | 7323 | struct dirent *dp; |
7327 | int atend; | 7324 | int atend; |
7328 | int matchdot; | 7325 | int matchdot; |
7326 | int esc; | ||
7329 | 7327 | ||
7330 | metaflag = 0; | 7328 | metaflag = 0; |
7331 | start = name; | 7329 | start = name; |
7332 | for (p = name; *p; p++) { | 7330 | for (p = name; esc = 0, *p; p += esc + 1) { |
7333 | if (*p == '*' || *p == '?') | 7331 | if (*p == '*' || *p == '?') |
7334 | metaflag = 1; | 7332 | metaflag = 1; |
7335 | else if (*p == '[') { | 7333 | else if (*p == '[') { |
@@ -7346,15 +7344,16 @@ expmeta(char *expdir, char *enddir, char *name) | |||
7346 | break; | 7344 | break; |
7347 | } | 7345 | } |
7348 | } | 7346 | } |
7349 | } else if (*p == '\\') | 7347 | } else { |
7350 | p++; | 7348 | if (*p == '\\') |
7351 | else if (*p == '/') { | 7349 | esc++; |
7352 | if (metaflag) | 7350 | if (p[esc] == '/') { |
7353 | goto out; | 7351 | if (metaflag) |
7354 | start = p + 1; | 7352 | break; |
7353 | start = p + esc + 1; | ||
7354 | } | ||
7355 | } | 7355 | } |
7356 | } | 7356 | } |
7357 | out: | ||
7358 | if (metaflag == 0) { /* we've reached the end of the file name */ | 7357 | if (metaflag == 0) { /* we've reached the end of the file name */ |
7359 | if (enddir != expdir) | 7358 | if (enddir != expdir) |
7360 | metaflag++; | 7359 | metaflag++; |
@@ -7394,7 +7393,8 @@ expmeta(char *expdir, char *enddir, char *name) | |||
7394 | atend = 1; | 7393 | atend = 1; |
7395 | } else { | 7394 | } else { |
7396 | atend = 0; | 7395 | atend = 0; |
7397 | *endname++ = '\0'; | 7396 | *endname = '\0'; |
7397 | endname += esc + 1; | ||
7398 | } | 7398 | } |
7399 | matchdot = 0; | 7399 | matchdot = 0; |
7400 | p = start; | 7400 | p = start; |
@@ -7419,7 +7419,7 @@ expmeta(char *expdir, char *enddir, char *name) | |||
7419 | } | 7419 | } |
7420 | closedir(dirp); | 7420 | closedir(dirp); |
7421 | if (!atend) | 7421 | if (!atend) |
7422 | endname[-1] = '/'; | 7422 | endname[-esc - 1] = esc ? '\\' : '/'; |
7423 | } | 7423 | } |
7424 | 7424 | ||
7425 | static struct strlist * | 7425 | static struct strlist * |
@@ -10118,7 +10118,7 @@ preadfd(void) | |||
10118 | } | 10118 | } |
10119 | # if ENABLE_ASH_IDLE_TIMEOUT | 10119 | # if ENABLE_ASH_IDLE_TIMEOUT |
10120 | else if (errno == EAGAIN && timeout > 0) { | 10120 | else if (errno == EAGAIN && timeout > 0) { |
10121 | printf("\007timed out waiting for input: auto-logout\n"); | 10121 | puts("\007timed out waiting for input: auto-logout"); |
10122 | exitshell(); | 10122 | exitshell(); |
10123 | } | 10123 | } |
10124 | # endif | 10124 | # endif |
@@ -10472,10 +10472,8 @@ setinputstring(char *string) | |||
10472 | 10472 | ||
10473 | #if ENABLE_ASH_MAIL | 10473 | #if ENABLE_ASH_MAIL |
10474 | 10474 | ||
10475 | #define MAXMBOXES 10 | 10475 | /* Hash of mtimes of mailboxes */ |
10476 | 10476 | static unsigned mailtime_hash; | |
10477 | /* times of mailboxes */ | ||
10478 | static time_t mailtime[MAXMBOXES]; | ||
10479 | /* Set if MAIL or MAILPATH is changed. */ | 10477 | /* Set if MAIL or MAILPATH is changed. */ |
10480 | static smallint mail_var_path_changed; | 10478 | static smallint mail_var_path_changed; |
10481 | 10479 | ||
@@ -10491,13 +10489,14 @@ chkmail(void) | |||
10491 | const char *mpath; | 10489 | const char *mpath; |
10492 | char *p; | 10490 | char *p; |
10493 | char *q; | 10491 | char *q; |
10494 | time_t *mtp; | 10492 | unsigned new_hash; |
10495 | struct stackmark smark; | 10493 | struct stackmark smark; |
10496 | struct stat statb; | 10494 | struct stat statb; |
10497 | 10495 | ||
10498 | setstackmark(&smark); | 10496 | setstackmark(&smark); |
10499 | mpath = mpathset() ? mpathval() : mailval(); | 10497 | mpath = mpathset() ? mpathval() : mailval(); |
10500 | for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) { | 10498 | new_hash = 0; |
10499 | for (;;) { | ||
10501 | p = path_advance(&mpath, nullstr); | 10500 | p = path_advance(&mpath, nullstr); |
10502 | if (p == NULL) | 10501 | if (p == NULL) |
10503 | break; | 10502 | break; |
@@ -10511,16 +10510,15 @@ chkmail(void) | |||
10511 | #endif | 10510 | #endif |
10512 | q[-1] = '\0'; /* delete trailing '/' */ | 10511 | q[-1] = '\0'; /* delete trailing '/' */ |
10513 | if (stat(p, &statb) < 0) { | 10512 | if (stat(p, &statb) < 0) { |
10514 | *mtp = 0; | ||
10515 | continue; | 10513 | continue; |
10516 | } | 10514 | } |
10517 | if (!mail_var_path_changed && statb.st_mtime != *mtp) { | 10515 | /* Very simplistic "hash": just a sum of all mtimes */ |
10518 | fprintf( | 10516 | new_hash += (unsigned)statb.st_mtime; |
10519 | stderr, "%s\n", | 10517 | } |
10520 | pathopt ? pathopt : "you have mail" | 10518 | if (!mail_var_path_changed && mailtime_hash != new_hash) { |
10521 | ); | 10519 | if (mailtime_hash != 0) |
10522 | } | 10520 | out2str("you have mail\n"); |
10523 | *mtp = statb.st_mtime; | 10521 | mailtime_hash = new_hash; |
10524 | } | 10522 | } |
10525 | mail_var_path_changed = 0; | 10523 | mail_var_path_changed = 0; |
10526 | popstackmark(&smark); | 10524 | popstackmark(&smark); |
@@ -10792,9 +10790,11 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt | |||
10792 | char c = '?'; | 10790 | char c = '?'; |
10793 | int done = 0; | 10791 | int done = 0; |
10794 | int err = 0; | 10792 | int err = 0; |
10795 | char s[12]; | 10793 | char sbuf[2]; |
10796 | char **optnext; | 10794 | char **optnext; |
10797 | 10795 | ||
10796 | sbuf[1] = '\0'; | ||
10797 | |||
10798 | if (*param_optind < 1) | 10798 | if (*param_optind < 1) |
10799 | return 1; | 10799 | return 1; |
10800 | optnext = optfirst + *param_optind - 1; | 10800 | optnext = optfirst + *param_optind - 1; |
@@ -10821,9 +10821,9 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt | |||
10821 | for (q = optstr; *q != c;) { | 10821 | for (q = optstr; *q != c;) { |
10822 | if (*q == '\0') { | 10822 | if (*q == '\0') { |
10823 | if (optstr[0] == ':') { | 10823 | if (optstr[0] == ':') { |
10824 | s[0] = c; | 10824 | sbuf[0] = c; |
10825 | s[1] = '\0'; | 10825 | /*sbuf[1] = '\0'; - already is */ |
10826 | err |= setvarsafe("OPTARG", s, 0); | 10826 | err |= setvarsafe("OPTARG", sbuf, 0); |
10827 | } else { | 10827 | } else { |
10828 | fprintf(stderr, "Illegal option -%c\n", c); | 10828 | fprintf(stderr, "Illegal option -%c\n", c); |
10829 | unsetvar("OPTARG"); | 10829 | unsetvar("OPTARG"); |
@@ -10838,9 +10838,9 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt | |||
10838 | if (*++q == ':') { | 10838 | if (*++q == ':') { |
10839 | if (*p == '\0' && (p = *optnext) == NULL) { | 10839 | if (*p == '\0' && (p = *optnext) == NULL) { |
10840 | if (optstr[0] == ':') { | 10840 | if (optstr[0] == ':') { |
10841 | s[0] = c; | 10841 | sbuf[0] = c; |
10842 | s[1] = '\0'; | 10842 | /*sbuf[1] = '\0'; - already is */ |
10843 | err |= setvarsafe("OPTARG", s, 0); | 10843 | err |= setvarsafe("OPTARG", sbuf, 0); |
10844 | c = ':'; | 10844 | c = ':'; |
10845 | } else { | 10845 | } else { |
10846 | fprintf(stderr, "No arg for -%c option\n", c); | 10846 | fprintf(stderr, "No arg for -%c option\n", c); |
@@ -10859,11 +10859,10 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt | |||
10859 | out: | 10859 | out: |
10860 | *optoff = p ? p - *(optnext - 1) : -1; | 10860 | *optoff = p ? p - *(optnext - 1) : -1; |
10861 | *param_optind = optnext - optfirst + 1; | 10861 | *param_optind = optnext - optfirst + 1; |
10862 | fmtstr(s, sizeof(s), "%d", *param_optind); | 10862 | err |= setvarsafe("OPTIND", itoa(*param_optind), VNOFUNC); |
10863 | err |= setvarsafe("OPTIND", s, VNOFUNC); | 10863 | sbuf[0] = c; |
10864 | s[0] = c; | 10864 | /*sbuf[1] = '\0'; - already is */ |
10865 | s[1] = '\0'; | 10865 | err |= setvarsafe(optvar, sbuf, 0); |
10866 | err |= setvarsafe(optvar, s, 0); | ||
10867 | if (err) { | 10866 | if (err) { |
10868 | *param_optind = 1; | 10867 | *param_optind = 1; |
10869 | *optoff = -1; | 10868 | *optoff = -1; |
@@ -12559,7 +12558,7 @@ cmdloop(int top) | |||
12559 | setstackmark(&smark); | 12558 | setstackmark(&smark); |
12560 | #if JOBS | 12559 | #if JOBS |
12561 | if (doing_jobctl) | 12560 | if (doing_jobctl) |
12562 | showjobs(stderr, SHOW_CHANGED); | 12561 | showjobs(SHOW_CHANGED|SHOW_STDERR); |
12563 | #endif | 12562 | #endif |
12564 | inter = 0; | 12563 | inter = 0; |
12565 | if (iflag && top) { | 12564 | if (iflag && top) { |
@@ -13298,21 +13297,11 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13298 | } | 13297 | } |
13299 | 13298 | ||
13300 | static int FAST_FUNC | 13299 | static int FAST_FUNC |
13301 | umaskcmd(int argc UNUSED_PARAM, char **argv) | 13300 | umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) |
13302 | { | 13301 | { |
13303 | static const char permuser[3] ALIGN1 = "ugo"; | 13302 | static const char permuser[3] ALIGN1 = "ogu"; |
13304 | static const char permmode[3] ALIGN1 = "rwx"; | ||
13305 | static const short permmask[] ALIGN2 = { | ||
13306 | S_IRUSR, S_IWUSR, S_IXUSR, | ||
13307 | S_IRGRP, S_IWGRP, S_IXGRP, | ||
13308 | S_IROTH, S_IWOTH, S_IXOTH | ||
13309 | }; | ||
13310 | |||
13311 | /* TODO: use bb_parse_mode() instead */ | ||
13312 | 13303 | ||
13313 | char *ap; | ||
13314 | mode_t mask; | 13304 | mode_t mask; |
13315 | int i; | ||
13316 | int symbolic_mode = 0; | 13305 | int symbolic_mode = 0; |
13317 | 13306 | ||
13318 | while (nextopt("S") != '\0') { | 13307 | while (nextopt("S") != '\0') { |
@@ -13324,45 +13313,43 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) | |||
13324 | umask(mask); | 13313 | umask(mask); |
13325 | INT_ON; | 13314 | INT_ON; |
13326 | 13315 | ||
13327 | ap = *argptr; | 13316 | if (*argptr == NULL) { |
13328 | if (ap == NULL) { | ||
13329 | if (symbolic_mode) { | 13317 | if (symbolic_mode) { |
13330 | char buf[18]; | 13318 | char buf[sizeof(",u=rwx,g=rwx,o=rwx")]; |
13331 | char *p = buf; | 13319 | char *p = buf; |
13320 | int i; | ||
13332 | 13321 | ||
13333 | for (i = 0; i < 3; i++) { | 13322 | i = 2; |
13334 | int j; | 13323 | for (;;) { |
13335 | 13324 | *p++ = ','; | |
13336 | *p++ = permuser[i]; | 13325 | *p++ = permuser[i]; |
13337 | *p++ = '='; | 13326 | *p++ = '='; |
13338 | for (j = 0; j < 3; j++) { | 13327 | /* mask is 0..0uuugggooo. i=2 selects uuu bits */ |
13339 | if ((mask & permmask[3 * i + j]) == 0) { | 13328 | if (!(mask & 0400)) *p++ = 'r'; |
13340 | *p++ = permmode[j]; | 13329 | if (!(mask & 0200)) *p++ = 'w'; |
13341 | } | 13330 | if (!(mask & 0100)) *p++ = 'x'; |
13342 | } | 13331 | mask <<= 3; |
13343 | *p++ = ','; | 13332 | if (--i < 0) |
13333 | break; | ||
13344 | } | 13334 | } |
13345 | *--p = 0; | 13335 | *p = '\0'; |
13346 | puts(buf); | 13336 | puts(buf + 1); |
13347 | } else { | 13337 | } else { |
13348 | out1fmt("%.4o\n", mask); | 13338 | out1fmt("%04o\n", mask); |
13349 | } | 13339 | } |
13350 | } else { | 13340 | } else { |
13351 | if (isdigit((unsigned char) *ap)) { | 13341 | char *modestr = *argptr; |
13352 | mask = 0; | 13342 | /* numeric umasks are taken as-is */ |
13353 | do { | 13343 | /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ |
13354 | if (*ap >= '8' || *ap < '0') | 13344 | if (!isdigit(modestr[0])) |
13355 | ash_msg_and_raise_error(msg_illnum, argv[1]); | 13345 | mask ^= 0777; |
13356 | mask = (mask << 3) + (*ap - '0'); | 13346 | mask = bb_parse_mode(modestr, mask); |
13357 | } while (*++ap != '\0'); | 13347 | if ((unsigned)mask > 0777) { |
13358 | umask(mask); | 13348 | ash_msg_and_raise_error("illegal mode: %s", modestr); |
13359 | } else { | 13349 | } |
13360 | mask = ~mask & 0777; | 13350 | if (!isdigit(modestr[0])) |
13361 | if (!bb_parse_mode(ap, &mask)) { | 13351 | mask ^= 0777; |
13362 | ash_msg_and_raise_error("illegal mode: %s", ap); | 13352 | umask(mask); |
13363 | } | ||
13364 | umask(~mask & 0777); | ||
13365 | } | ||
13366 | } | 13353 | } |
13367 | return 0; | 13354 | return 0; |
13368 | } | 13355 | } |
@@ -13713,7 +13700,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
13713 | exitshell(); | 13700 | exitshell(); |
13714 | } | 13701 | } |
13715 | if (e == EXINT) { | 13702 | if (e == EXINT) { |
13716 | outcslow('\n', stderr); | 13703 | newline_and_flush(stderr); |
13717 | } | 13704 | } |
13718 | 13705 | ||
13719 | popstackmark(&smark); | 13706 | popstackmark(&smark); |
diff --git a/shell/ash_test/ash-glob/glob1.right b/shell/ash_test/ash-glob/glob1.right new file mode 100644 index 000000000..f29ab4e65 --- /dev/null +++ b/shell/ash_test/ash-glob/glob1.right | |||
@@ -0,0 +1,2 @@ | |||
1 | glob1.tests | ||
2 | glob1.tests | ||
diff --git a/shell/ash_test/ash-glob/glob1.tests b/shell/ash_test/ash-glob/glob1.tests new file mode 100755 index 000000000..f980ce064 --- /dev/null +++ b/shell/ash_test/ash-glob/glob1.tests | |||
@@ -0,0 +1,2 @@ | |||
1 | echo *glob1?t[e]sts* | ||
2 | echo "glob1"?'t'[e]s* | ||
diff --git a/shell/ash_test/ash-glob/glob2.right b/shell/ash_test/ash-glob/glob2.right new file mode 100644 index 000000000..7a70c2263 --- /dev/null +++ b/shell/ash_test/ash-glob/glob2.right | |||
@@ -0,0 +1,18 @@ | |||
1 | Expected Actual | ||
2 | Z\* : Z\* | ||
3 | Z* : Z* | ||
4 | Z\f : Z\f | ||
5 | Z\* : Z\* | ||
6 | |||
7 | Z\z : Z\z | ||
8 | Zz : Zz | ||
9 | Z\z : Z\z | ||
10 | Z\z : Z\z | ||
11 | |||
12 | Z\ : Z\ | ||
13 | Z\ : Z\ | ||
14 | |||
15 | Z\f Zf : Z\f Zf | ||
16 | Z\f Zf : Z\f Zf | ||
17 | |||
18 | Done: 0 | ||
diff --git a/shell/ash_test/ash-glob/glob2.tests b/shell/ash_test/ash-glob/glob2.tests new file mode 100755 index 000000000..00618b9db --- /dev/null +++ b/shell/ash_test/ash-glob/glob2.tests | |||
@@ -0,0 +1,27 @@ | |||
1 | # This test demonstrates that in unquoted $v, backslashes expand by this rule: | ||
2 | # \z -> \\\z; \<eol> -> \\<eol> (for any z, special or not), | ||
3 | # and subsequently globbing converts \\ to \ and treats \z as literal z | ||
4 | # even if it is a special char. | ||
5 | |||
6 | >'Zf' | ||
7 | >'Z\f' | ||
8 | echo 'Expected' 'Actual' | ||
9 | v='\*'; echo 'Z\* :' Z$v # ash is buggy here: prints 'Z\f' | ||
10 | echo 'Z* :' Z\* | ||
11 | echo 'Z\f :' Z\\* | ||
12 | echo 'Z\* :' Z\\\* # NB! only this matches Z$v output | ||
13 | echo | ||
14 | v='\z'; echo 'Z\z :' Z$v | ||
15 | echo 'Zz :' Z\z | ||
16 | echo 'Z\z :' Z\\z | ||
17 | echo 'Z\z :' Z\\\z | ||
18 | echo | ||
19 | v='\'; echo 'Z\ :' Z$v | ||
20 | echo 'Z\ :' Z\\ | ||
21 | echo | ||
22 | v='*'; echo 'Z\f Zf :' Z$v | ||
23 | echo 'Z\f Zf :' Z* | ||
24 | echo | ||
25 | |||
26 | rm 'Z\f' 'Zf' | ||
27 | echo Done: $? | ||
diff --git a/shell/ash_test/ash-glob/glob3.right b/shell/ash_test/ash-glob/glob3.right new file mode 100644 index 000000000..161b589e0 --- /dev/null +++ b/shell/ash_test/ash-glob/glob3.right | |||
@@ -0,0 +1,2 @@ | |||
1 | glob3.tests | ||
2 | ./glob3.tests | ||
diff --git a/shell/ash_test/ash-glob/glob3.tests b/shell/ash_test/ash-glob/glob3.tests new file mode 100755 index 000000000..bdf54001e --- /dev/null +++ b/shell/ash_test/ash-glob/glob3.tests | |||
@@ -0,0 +1,2 @@ | |||
1 | echo "glob3.test"* | ||
2 | echo "./glob3.test"* | ||
diff --git a/shell/ash_test/ash-glob/glob_and_assign.right b/shell/ash_test/ash-glob/glob_and_assign.right new file mode 100644 index 000000000..d46e44363 --- /dev/null +++ b/shell/ash_test/ash-glob/glob_and_assign.right | |||
@@ -0,0 +1,6 @@ | |||
1 | ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp | ||
2 | ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp | ||
3 | *.tmp | ||
4 | ZVAR=z.tmp z.tmp | ||
5 | ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp | ||
6 | ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp | ||
diff --git a/shell/ash_test/ash-glob/glob_and_assign.tests b/shell/ash_test/ash-glob/glob_and_assign.tests new file mode 100755 index 000000000..0b158f20f --- /dev/null +++ b/shell/ash_test/ash-glob/glob_and_assign.tests | |||
@@ -0,0 +1,10 @@ | |||
1 | >ZVAR=z.tmp | ||
2 | >z.tmp | ||
3 | ZVAR=*.tmp echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" | ||
4 | ZVAR=*.tmp /bin/echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" | ||
5 | ZVAR=*.tmp | ||
6 | echo "$ZVAR" | ||
7 | echo $ZVAR | ||
8 | echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" | ||
9 | /bin/echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" | ||
10 | rm ZVAR=z.tmp z.tmp | ||
diff --git a/shell/ash_test/ash-glob/glob_redir.right b/shell/ash_test/ash-glob/glob_redir.right new file mode 100644 index 000000000..fbd0309b0 --- /dev/null +++ b/shell/ash_test/ash-glob/glob_redir.right | |||
@@ -0,0 +1,2 @@ | |||
1 | z.tmp: | ||
2 | ?.tmp: TEST | ||
diff --git a/shell/ash_test/ash-glob/glob_redir.tests b/shell/ash_test/ash-glob/glob_redir.tests new file mode 100755 index 000000000..621d12017 --- /dev/null +++ b/shell/ash_test/ash-glob/glob_redir.tests | |||
@@ -0,0 +1,9 @@ | |||
1 | # Redirections are not globbed. | ||
2 | # bash: | ||
3 | # if run as "sh", they are not globbed, but | ||
4 | # if run as "bash", they are! | ||
5 | >z.tmp | ||
6 | echo TEST >?.tmp | ||
7 | echo 'z.tmp:' `cat 'z.tmp'` | ||
8 | echo '?.tmp:' `cat '?.tmp'` | ||
9 | rm 'z.tmp' '?.tmp' | ||
diff --git a/shell/hush.c b/shell/hush.c index 3ca04494c..eabe83ac6 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1479,10 +1479,11 @@ static sighandler_t install_sighandler(int sig, sighandler_t handler) | |||
1479 | 1479 | ||
1480 | #if ENABLE_HUSH_JOB | 1480 | #if ENABLE_HUSH_JOB |
1481 | 1481 | ||
1482 | static void xfunc_has_died(void); | ||
1482 | /* After [v]fork, in child: do not restore tty pgrp on xfunc death */ | 1483 | /* After [v]fork, in child: do not restore tty pgrp on xfunc death */ |
1483 | # define disable_restore_tty_pgrp_on_exit() (die_sleep = 0) | 1484 | # define disable_restore_tty_pgrp_on_exit() (die_func = NULL) |
1484 | /* After [v]fork, in parent: restore tty pgrp on xfunc death */ | 1485 | /* After [v]fork, in parent: restore tty pgrp on xfunc death */ |
1485 | # define enable_restore_tty_pgrp_on_exit() (die_sleep = -1) | 1486 | # define enable_restore_tty_pgrp_on_exit() (die_func = xfunc_has_died) |
1486 | 1487 | ||
1487 | /* Restores tty foreground process group, and exits. | 1488 | /* Restores tty foreground process group, and exits. |
1488 | * May be called as signal handler for fatal signal | 1489 | * May be called as signal handler for fatal signal |
@@ -1587,6 +1588,15 @@ static void hush_exit(int exitcode) | |||
1587 | #endif | 1588 | #endif |
1588 | } | 1589 | } |
1589 | 1590 | ||
1591 | static void xfunc_has_died(void) NORETURN; | ||
1592 | static void xfunc_has_died(void) | ||
1593 | { | ||
1594 | /* xfunc has failed! die die die */ | ||
1595 | /* no EXIT traps, this is an escape hatch! */ | ||
1596 | G.exiting = 1; | ||
1597 | hush_exit(xfunc_error_retval); | ||
1598 | } | ||
1599 | |||
1590 | 1600 | ||
1591 | //TODO: return a mask of ALL handled sigs? | 1601 | //TODO: return a mask of ALL handled sigs? |
1592 | static int check_and_run_traps(void) | 1602 | static int check_and_run_traps(void) |
@@ -3161,11 +3171,29 @@ static int reserved_word(o_string *word, struct parse_context *ctx) | |||
3161 | old->command->group = ctx->list_head; | 3171 | old->command->group = ctx->list_head; |
3162 | old->command->cmd_type = CMD_NORMAL; | 3172 | old->command->cmd_type = CMD_NORMAL; |
3163 | # if !BB_MMU | 3173 | # if !BB_MMU |
3164 | o_addstr(&old->as_string, ctx->as_string.data); | 3174 | /* At this point, the compound command's string is in |
3165 | o_free_unsafe(&ctx->as_string); | 3175 | * ctx->as_string... except for the leading keyword! |
3166 | old->command->group_as_string = xstrdup(old->as_string.data); | 3176 | * Consider this example: "echo a | if true; then echo a; fi" |
3167 | debug_printf_parse("pop, remembering as:'%s'\n", | 3177 | * ctx->as_string will contain "true; then echo a; fi", |
3168 | old->command->group_as_string); | 3178 | * with "if " remaining in old->as_string! |
3179 | */ | ||
3180 | { | ||
3181 | char *str; | ||
3182 | int len = old->as_string.length; | ||
3183 | /* Concatenate halves */ | ||
3184 | o_addstr(&old->as_string, ctx->as_string.data); | ||
3185 | o_free_unsafe(&ctx->as_string); | ||
3186 | /* Find where leading keyword starts in first half */ | ||
3187 | str = old->as_string.data + len; | ||
3188 | if (str > old->as_string.data) | ||
3189 | str--; /* skip whitespace after keyword */ | ||
3190 | while (str > old->as_string.data && isalpha(str[-1])) | ||
3191 | str--; | ||
3192 | /* Ugh, we're done with this horrid hack */ | ||
3193 | old->command->group_as_string = xstrdup(str); | ||
3194 | debug_printf_parse("pop, remembering as:'%s'\n", | ||
3195 | old->command->group_as_string); | ||
3196 | } | ||
3169 | # endif | 3197 | # endif |
3170 | *ctx = *old; /* physical copy */ | 3198 | *ctx = *old; /* physical copy */ |
3171 | free(old); | 3199 | free(old); |
@@ -4248,7 +4276,7 @@ static struct pipe *parse_stream(char **pstring, | |||
4248 | pi = NULL; | 4276 | pi = NULL; |
4249 | } | 4277 | } |
4250 | #if !BB_MMU | 4278 | #if !BB_MMU |
4251 | debug_printf_parse("as_string '%s'\n", ctx.as_string.data); | 4279 | debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data); |
4252 | if (pstring) | 4280 | if (pstring) |
4253 | *pstring = ctx.as_string.data; | 4281 | *pstring = ctx.as_string.data; |
4254 | else | 4282 | else |
@@ -4399,7 +4427,7 @@ static struct pipe *parse_stream(char **pstring, | |||
4399 | ) { | 4427 | ) { |
4400 | o_free(&dest); | 4428 | o_free(&dest); |
4401 | #if !BB_MMU | 4429 | #if !BB_MMU |
4402 | debug_printf_parse("as_string '%s'\n", ctx.as_string.data); | 4430 | debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data); |
4403 | if (pstring) | 4431 | if (pstring) |
4404 | *pstring = ctx.as_string.data; | 4432 | *pstring = ctx.as_string.data; |
4405 | else | 4433 | else |
@@ -4639,9 +4667,6 @@ static struct pipe *parse_stream(char **pstring, | |||
4639 | * with redirect_opt_num(), but bash doesn't do it. | 4667 | * with redirect_opt_num(), but bash doesn't do it. |
4640 | * "echo foo 2| cat" yields "foo 2". */ | 4668 | * "echo foo 2| cat" yields "foo 2". */ |
4641 | done_command(&ctx); | 4669 | done_command(&ctx); |
4642 | #if !BB_MMU | ||
4643 | o_reset_to_empty_unquoted(&ctx.as_string); | ||
4644 | #endif | ||
4645 | } | 4670 | } |
4646 | goto new_cmd; | 4671 | goto new_cmd; |
4647 | case '(': | 4672 | case '(': |
@@ -6779,7 +6804,7 @@ static int checkjobs(struct pipe *fg_pipe) | |||
6779 | int sig = WTERMSIG(status); | 6804 | int sig = WTERMSIG(status); |
6780 | if (i == fg_pipe->num_cmds-1) | 6805 | if (i == fg_pipe->num_cmds-1) |
6781 | /* TODO: use strsignal() instead for bash compat? but that's bloat... */ | 6806 | /* TODO: use strsignal() instead for bash compat? but that's bloat... */ |
6782 | printf("%s\n", sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig)); | 6807 | puts(sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig)); |
6783 | /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */ | 6808 | /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */ |
6784 | /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here? | 6809 | /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here? |
6785 | * Maybe we need to use sig | 128? */ | 6810 | * Maybe we need to use sig | 128? */ |
@@ -7851,12 +7876,7 @@ int hush_main(int argc, char **argv) | |||
7851 | /* Initialize some more globals to non-zero values */ | 7876 | /* Initialize some more globals to non-zero values */ |
7852 | cmdedit_update_prompt(); | 7877 | cmdedit_update_prompt(); |
7853 | 7878 | ||
7854 | if (setjmp(die_jmp)) { | 7879 | die_func = xfunc_has_died; |
7855 | /* xfunc has failed! die die die */ | ||
7856 | /* no EXIT traps, this is an escape hatch! */ | ||
7857 | G.exiting = 1; | ||
7858 | hush_exit(xfunc_error_retval); | ||
7859 | } | ||
7860 | 7880 | ||
7861 | /* Shell is non-interactive at first. We need to call | 7881 | /* Shell is non-interactive at first. We need to call |
7862 | * install_special_sighandlers() if we are going to execute "sh <script>", | 7882 | * install_special_sighandlers() if we are going to execute "sh <script>", |
@@ -8114,9 +8134,7 @@ int hush_main(int argc, char **argv) | |||
8114 | /* Grab control of the terminal */ | 8134 | /* Grab control of the terminal */ |
8115 | tcsetpgrp(G_interactive_fd, getpid()); | 8135 | tcsetpgrp(G_interactive_fd, getpid()); |
8116 | } | 8136 | } |
8117 | /* -1 is special - makes xfuncs longjmp, not exit | 8137 | enable_restore_tty_pgrp_on_exit(); |
8118 | * (we reset die_sleep = 0 whereever we [v]fork) */ | ||
8119 | enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */ | ||
8120 | 8138 | ||
8121 | # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 | 8139 | # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 |
8122 | { | 8140 | { |
@@ -8950,24 +8968,29 @@ static int FAST_FUNC builtin_umask(char **argv) | |||
8950 | int rc; | 8968 | int rc; |
8951 | mode_t mask; | 8969 | mode_t mask; |
8952 | 8970 | ||
8971 | rc = 1; | ||
8953 | mask = umask(0); | 8972 | mask = umask(0); |
8954 | argv = skip_dash_dash(argv); | 8973 | argv = skip_dash_dash(argv); |
8955 | if (argv[0]) { | 8974 | if (argv[0]) { |
8956 | mode_t old_mask = mask; | 8975 | mode_t old_mask = mask; |
8957 | 8976 | ||
8958 | mask ^= 0777; | 8977 | /* numeric umasks are taken as-is */ |
8959 | rc = bb_parse_mode(argv[0], &mask); | 8978 | /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ |
8960 | mask ^= 0777; | 8979 | if (!isdigit(argv[0][0])) |
8961 | if (rc == 0) { | 8980 | mask ^= 0777; |
8981 | mask = bb_parse_mode(argv[0], mask); | ||
8982 | if (!isdigit(argv[0][0])) | ||
8983 | mask ^= 0777; | ||
8984 | if ((unsigned)mask > 0777) { | ||
8962 | mask = old_mask; | 8985 | mask = old_mask; |
8963 | /* bash messages: | 8986 | /* bash messages: |
8964 | * bash: umask: 'q': invalid symbolic mode operator | 8987 | * bash: umask: 'q': invalid symbolic mode operator |
8965 | * bash: umask: 999: octal number out of range | 8988 | * bash: umask: 999: octal number out of range |
8966 | */ | 8989 | */ |
8967 | bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]); | 8990 | bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]); |
8991 | rc = 0; | ||
8968 | } | 8992 | } |
8969 | } else { | 8993 | } else { |
8970 | rc = 1; | ||
8971 | /* Mimic bash */ | 8994 | /* Mimic bash */ |
8972 | printf("%04o\n", (unsigned) mask); | 8995 | printf("%04o\n", (unsigned) mask); |
8973 | /* fall through and restore mask which we set to 0 */ | 8996 | /* fall through and restore mask which we set to 0 */ |
@@ -9097,12 +9120,9 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
9097 | return EXIT_FAILURE; | 9120 | return EXIT_FAILURE; |
9098 | } | 9121 | } |
9099 | if (waitpid(pid, &status, 0) == pid) { | 9122 | if (waitpid(pid, &status, 0) == pid) { |
9123 | ret = WEXITSTATUS(status); | ||
9100 | if (WIFSIGNALED(status)) | 9124 | if (WIFSIGNALED(status)) |
9101 | ret = 128 + WTERMSIG(status); | 9125 | ret = 128 + WTERMSIG(status); |
9102 | else if (WIFEXITED(status)) | ||
9103 | ret = WEXITSTATUS(status); | ||
9104 | else /* wtf? */ | ||
9105 | ret = EXIT_FAILURE; | ||
9106 | } else { | 9126 | } else { |
9107 | bb_perror_msg("wait %s", *argv); | 9127 | bb_perror_msg("wait %s", *argv); |
9108 | ret = 127; | 9128 | ret = 127; |
diff --git a/shell/hush_test/hush-glob/glob3.right b/shell/hush_test/hush-glob/glob3.right new file mode 100644 index 000000000..161b589e0 --- /dev/null +++ b/shell/hush_test/hush-glob/glob3.right | |||
@@ -0,0 +1,2 @@ | |||
1 | glob3.tests | ||
2 | ./glob3.tests | ||
diff --git a/shell/hush_test/hush-glob/glob3.tests b/shell/hush_test/hush-glob/glob3.tests new file mode 100755 index 000000000..bdf54001e --- /dev/null +++ b/shell/hush_test/hush-glob/glob3.tests | |||
@@ -0,0 +1,2 @@ | |||
1 | echo "glob3.test"* | ||
2 | echo "./glob3.test"* | ||
diff --git a/shell/hush_test/hush-misc/nommu3.right b/shell/hush_test/hush-misc/nommu3.right new file mode 100644 index 000000000..da1534bef --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.right | |||
@@ -0,0 +1,2 @@ | |||
1 | Ok | ||
2 | 0 | ||
diff --git a/shell/hush_test/hush-misc/nommu3.tests b/shell/hush_test/hush-misc/nommu3.tests new file mode 100755 index 000000000..ac82a6a11 --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.tests | |||
@@ -0,0 +1,15 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | func() | ||
4 | { | ||
5 | while read p; do echo "$p"; done | ||
6 | } | ||
7 | |||
8 | pipe_to_func() | ||
9 | { | ||
10 | # We had a NOMMU bug which caused "echo Ok |" part to be lost | ||
11 | echo Ok | func | ||
12 | } | ||
13 | |||
14 | pipe_to_func | cat | ||
15 | echo $? | ||
diff --git a/shell/shell_common.c b/shell/shell_common.c index 1567d1de4..dbd4286bf 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c | |||
@@ -387,7 +387,7 @@ static void printlim(unsigned opts, const struct rlimit *limit, | |||
387 | val = limit->rlim_cur; | 387 | val = limit->rlim_cur; |
388 | 388 | ||
389 | if (val == RLIM_INFINITY) | 389 | if (val == RLIM_INFINITY) |
390 | printf("unlimited\n"); | 390 | puts("unlimited"); |
391 | else { | 391 | else { |
392 | val >>= l->factor_shift; | 392 | val >>= l->factor_shift; |
393 | printf("%llu\n", (long long) val); | 393 | printf("%llu\n", (long long) val); |
diff --git a/testsuite/awk.tests b/testsuite/awk.tests index 9e6952ffd..adab4ae1e 100755 --- a/testsuite/awk.tests +++ b/testsuite/awk.tests | |||
@@ -281,6 +281,11 @@ testing "awk length(array)" \ | |||
281 | "2\n" \ | 281 | "2\n" \ |
282 | "" "" | 282 | "" "" |
283 | 283 | ||
284 | testing "awk length()" \ | ||
285 | "awk '{print length; print length(); print length(\"qwe\"); print length(99+9)}'" \ | ||
286 | "3\n3\n3\n3\n" \ | ||
287 | "" "qwe" | ||
288 | |||
284 | testing "awk -f and ARGC" \ | 289 | testing "awk -f and ARGC" \ |
285 | "awk -f - input" \ | 290 | "awk -f - input" \ |
286 | "re\n2\n" \ | 291 | "re\n2\n" \ |
diff --git a/testsuite/bzcat.tests b/testsuite/bzcat.tests index 9a1c28425..0ae530dc7 100755 --- a/testsuite/bzcat.tests +++ b/testsuite/bzcat.tests | |||
@@ -28,7 +28,10 @@ hello_bz2() { | |||
28 | $ECHO -ne "\x17\x72\x45\x38\x50\x90\x5b\xb8\xe8\xa3" | 28 | $ECHO -ne "\x17\x72\x45\x38\x50\x90\x5b\xb8\xe8\xa3" |
29 | } | 29 | } |
30 | 30 | ||
31 | for ext in gz bz2 Z | 31 | for ext in \ |
32 | `test x"$CONFIG_GUNZIP" = x"y" && echo gz` \ | ||
33 | `test x"$CONFIG_BUNZIP2" = x"y" && echo bz2` \ | ||
34 | `test x"$CONFIG_UNCOMPRESS" = x"y" && echo Z` | ||
32 | do | 35 | do |
33 | prep() { | 36 | prep() { |
34 | rm -f t1.$ext t2.$ext t_actual | 37 | rm -f t1.$ext t2.$ext t_actual |
@@ -49,11 +52,12 @@ do | |||
49 | mkdir testdir 2>/dev/null | 52 | mkdir testdir 2>/dev/null |
50 | ( | 53 | ( |
51 | cd testdir || { echo "cannot cd testdir!"; exit 1; } | 54 | cd testdir || { echo "cannot cd testdir!"; exit 1; } |
52 | |||
53 | expected="HELLO\nok\n" | 55 | expected="HELLO\nok\n" |
54 | prep; check "zcat: dont delete $ext src" "${bb}zcat t2.$ext; test -f t2.$ext && echo ok" | 56 | prep |
55 | 57 | check "zcat: dont delete $ext src" "${bb}zcat t2.$ext; test -f t2.$ext && echo ok" | |
58 | exit $FAILCOUNT | ||
56 | ) | 59 | ) |
60 | FAILCOUNT=$? | ||
57 | rm -rf testdir | 61 | rm -rf testdir |
58 | done | 62 | done |
59 | 63 | ||
@@ -89,6 +93,7 @@ testing "bzcat can handle compressed zero-length bzip2 files" \ | |||
89 | ## compress algorithm | 93 | ## compress algorithm |
90 | 94 | ||
91 | # "input" file is compressed (.Z) file with "a\n" data | 95 | # "input" file is compressed (.Z) file with "a\n" data |
96 | test x"$CONFIG_UNCOMPRESS" = x"y" && \ | ||
92 | testing "zcat can print many files" \ | 97 | testing "zcat can print many files" \ |
93 | "$ECHO -ne '$hexdump' | zcat input input; echo \$?" \ | 98 | "$ECHO -ne '$hexdump' | zcat input input; echo \$?" \ |
94 | "\ | 99 | "\ |
@@ -100,7 +105,8 @@ a | |||
100 | " "" | 105 | " "" |
101 | 106 | ||
102 | # "input" file is compressed (.Z) zero byte file | 107 | # "input" file is compressed (.Z) zero byte file |
103 | testing "zcat can handle compressed zero-length compressed (.Z) files" \ | 108 | test x"$CONFIG_UNCOMPRESS" = x"y" && \ |
109 | testing "zcat can handle compressed zero-length (.Z) files" \ | ||
104 | "$ECHO -ne '$hexdump' | zcat input input; echo \$?" \ | 110 | "$ECHO -ne '$hexdump' | zcat input input; echo \$?" \ |
105 | "0\n" \ | 111 | "0\n" \ |
106 | "\x1f\x9d\x90\x00" "" | 112 | "\x1f\x9d\x90\x00" "" |
diff --git a/testsuite/makedevs.tests b/testsuite/makedevs.tests index fd12460ec..b51fe0798 100755 --- a/testsuite/makedevs.tests +++ b/testsuite/makedevs.tests | |||
@@ -25,7 +25,7 @@ FILTER_LS2="sed -e 's/, */,/g' -e 's/ */ /g' | cut -d' ' -f 1-4,9-" | |||
25 | rm -rf makedevs.testdir | 25 | rm -rf makedevs.testdir |
26 | mkdir makedevs.testdir | 26 | mkdir makedevs.testdir |
27 | 27 | ||
28 | optional FEATURE_MAKEDEVS_TABLE FEATURE_FIND_NOT FEATURE_FIND_TYPE FEATURE_LS_RECURSIVE FEATURE_LS_SORTFILES | 28 | optional FEATURE_MAKEDEVS_TABLE FEATURE_FIND_NOT FEATURE_FIND_TYPE FEATURE_LS_RECURSIVE FEATURE_LS_SORTFILES FEATURE_LS_TIMESTAMPS |
29 | testing "makedevs -d ../makedevs.device_table.txt ." \ | 29 | testing "makedevs -d ../makedevs.device_table.txt ." \ |
30 | "(cd makedevs.testdir && makedevs -d ../makedevs.device_table.txt . 2>&1); | 30 | "(cd makedevs.testdir && makedevs -d ../makedevs.device_table.txt . 2>&1); |
31 | find makedevs.testdir ! -type d | sort | xargs ls -lnR | $FILTER_LS" \ | 31 | find makedevs.testdir ! -type d | sort | xargs ls -lnR | $FILTER_LS" \ |
diff --git a/testsuite/pwd/pwd-prints-working-directory b/testsuite/pwd/pwd-prints-working-directory index 8575347d6..971adb5a6 100644 --- a/testsuite/pwd/pwd-prints-working-directory +++ b/testsuite/pwd/pwd-prints-working-directory | |||
@@ -1 +1,4 @@ | |||
1 | test $(pwd) = $(busybox pwd) | 1 | # shell's $PWD may leave symlinks unresolved. |
2 | # "pwd" may be a built-in and have the same problem. | ||
3 | # External pwd _can't_ have that problem (current dir on Unix is physical). | ||
4 | test $(`which pwd`) = $(busybox pwd) | ||
diff --git a/testsuite/readlink.tests b/testsuite/readlink.tests index c7fc8adf0..e9d8da0fc 100755 --- a/testsuite/readlink.tests +++ b/testsuite/readlink.tests | |||
@@ -21,10 +21,15 @@ testing "readlink on a link" "readlink ./$TESTLINK" "./$TESTFILE\n" "" "" | |||
21 | 21 | ||
22 | optional FEATURE_READLINK_FOLLOW | 22 | optional FEATURE_READLINK_FOLLOW |
23 | 23 | ||
24 | testing "readlink -f on a file" "readlink -f ./$TESTFILE" "$PWD/$TESTFILE\n" "" "" | 24 | # shell's $PWD may leave symlinks unresolved. |
25 | testing "readlink -f on a link" "readlink -f ./$TESTLINK" "$PWD/$TESTFILE\n" "" "" | 25 | # "pwd" may be a built-in and have the same problem. |
26 | # External pwd _can't_ have that problem (current dir on Unix is physical). | ||
27 | pwd=`which pwd` | ||
28 | pwd=`$pwd` | ||
29 | testing "readlink -f on a file" "readlink -f ./$TESTFILE" "$pwd/$TESTFILE\n" "" "" | ||
30 | testing "readlink -f on a link" "readlink -f ./$TESTLINK" "$pwd/$TESTFILE\n" "" "" | ||
26 | testing "readlink -f on an invalid link" "readlink -f ./$FAILLINK" "" "" "" | 31 | testing "readlink -f on an invalid link" "readlink -f ./$FAILLINK" "" "" "" |
27 | testing "readlink -f on a wierd dir" "readlink -f $TESTDIR/../$TESTFILE" "$PWD/$TESTFILE\n" "" "" | 32 | testing "readlink -f on a wierd dir" "readlink -f $TESTDIR/../$TESTFILE" "$pwd/$TESTFILE\n" "" "" |
28 | 33 | ||
29 | 34 | ||
30 | # clean up | 35 | # clean up |
diff --git a/testsuite/sort.tests b/testsuite/sort.tests index 68fa3e405..c4b223464 100755 --- a/testsuite/sort.tests +++ b/testsuite/sort.tests | |||
@@ -98,6 +98,14 @@ testing "sort with non-default leading delim 3" "sort -n -k3 -t/ input" "\ | |||
98 | //b/1 | 98 | //b/1 |
99 | " "" | 99 | " "" |
100 | 100 | ||
101 | testing "sort with non-default leading delim 4" "sort -t: -k1,1 input" "\ | ||
102 | a:b | ||
103 | a/a:a | ||
104 | " "\ | ||
105 | a/a:a | ||
106 | a:b | ||
107 | " "" | ||
108 | |||
101 | testing "sort -u should consider field only when discarding" "sort -u -k2 input" "\ | 109 | testing "sort -u should consider field only when discarding" "sort -u -k2 input" "\ |
102 | a c | 110 | a c |
103 | " "\ | 111 | " "\ |
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c index 81ba1c9d1..e543446c1 100644 --- a/util-linux/dmesg.c +++ b/util-linux/dmesg.c | |||
@@ -16,6 +16,7 @@ | |||
16 | //usage: "\n -c Clear ring buffer after printing" | 16 | //usage: "\n -c Clear ring buffer after printing" |
17 | //usage: "\n -n LEVEL Set console logging level" | 17 | //usage: "\n -n LEVEL Set console logging level" |
18 | //usage: "\n -s SIZE Buffer size" | 18 | //usage: "\n -s SIZE Buffer size" |
19 | //usage: "\n -r Print raw message buffer" | ||
19 | 20 | ||
20 | #include <sys/klog.h> | 21 | #include <sys/klog.h> |
21 | #include "libbb.h" | 22 | #include "libbb.h" |
@@ -29,11 +30,12 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv) | |||
29 | enum { | 30 | enum { |
30 | OPT_c = 1 << 0, | 31 | OPT_c = 1 << 0, |
31 | OPT_s = 1 << 1, | 32 | OPT_s = 1 << 1, |
32 | OPT_n = 1 << 2 | 33 | OPT_n = 1 << 2, |
34 | OPT_r = 1 << 3 | ||
33 | }; | 35 | }; |
34 | 36 | ||
35 | opt_complementary = "s+:n+"; /* numeric */ | 37 | opt_complementary = "s+:n+"; /* numeric */ |
36 | opts = getopt32(argv, "cs:n:", &len, &level); | 38 | opts = getopt32(argv, "cs:n:r", &len, &level); |
37 | if (opts & OPT_n) { | 39 | if (opts & OPT_n) { |
38 | if (klogctl(8, NULL, (long) level)) | 40 | if (klogctl(8, NULL, (long) level)) |
39 | bb_perror_msg_and_die("klogctl"); | 41 | bb_perror_msg_and_die("klogctl"); |
@@ -55,7 +57,7 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv) | |||
55 | return EXIT_SUCCESS; | 57 | return EXIT_SUCCESS; |
56 | 58 | ||
57 | 59 | ||
58 | if (ENABLE_FEATURE_DMESG_PRETTY) { | 60 | if (ENABLE_FEATURE_DMESG_PRETTY && !(opts & OPT_r)) { |
59 | int last = '\n'; | 61 | int last = '\n'; |
60 | int in = 0; | 62 | int in = 0; |
61 | 63 | ||
diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c index 6f49cec8f..6ef6445e6 100644 --- a/util-linux/fdformat.c +++ b/util-linux/fdformat.c | |||
@@ -93,7 +93,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | xioctl(fd, FDFMTEND, NULL); | 95 | xioctl(fd, FDFMTEND, NULL); |
96 | printf("done\n"); | 96 | puts("Done"); |
97 | 97 | ||
98 | /* VERIFY */ | 98 | /* VERIFY */ |
99 | if (verify) { | 99 | if (verify) { |
@@ -126,7 +126,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) | |||
126 | 126 | ||
127 | if (ENABLE_FEATURE_CLEAN_UP) free(data); | 127 | if (ENABLE_FEATURE_CLEAN_UP) free(data); |
128 | 128 | ||
129 | printf("done\n"); | 129 | puts("Done"); |
130 | } | 130 | } |
131 | 131 | ||
132 | if (ENABLE_FEATURE_CLEAN_UP) close(fd); | 132 | if (ENABLE_FEATURE_CLEAN_UP) close(fd); |
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 7fe70fb72..f49ce95a4 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c | |||
@@ -1102,11 +1102,11 @@ warn_geometry(void) | |||
1102 | printf(" sectors"); | 1102 | printf(" sectors"); |
1103 | if (!g_cylinders) | 1103 | if (!g_cylinders) |
1104 | printf(" cylinders"); | 1104 | printf(" cylinders"); |
1105 | printf( | ||
1106 | #if ENABLE_FEATURE_FDISK_WRITABLE | 1105 | #if ENABLE_FEATURE_FDISK_WRITABLE |
1107 | " (settable in the extra functions menu)" | 1106 | puts(" (settable in the extra functions menu)"); |
1107 | #else | ||
1108 | bb_putchar('\n'); | ||
1108 | #endif | 1109 | #endif |
1109 | "\n"); | ||
1110 | return 1; | 1110 | return 1; |
1111 | } | 1111 | } |
1112 | 1112 | ||
@@ -1150,7 +1150,7 @@ read_extended(int ext) | |||
1150 | 1150 | ||
1151 | p = pex->part_table; | 1151 | p = pex->part_table; |
1152 | if (!get_start_sect(p)) { | 1152 | if (!get_start_sect(p)) { |
1153 | printf("Bad offset in primary extended partition\n"); | 1153 | puts("Bad offset in primary extended partition"); |
1154 | return; | 1154 | return; |
1155 | } | 1155 | } |
1156 | 1156 | ||
@@ -1450,8 +1450,8 @@ static int get_boot(void) | |||
1450 | current_label_type = LABEL_OSF; | 1450 | current_label_type = LABEL_OSF; |
1451 | return 0; | 1451 | return 0; |
1452 | } | 1452 | } |
1453 | printf("This disk has both DOS and BSD magic.\n" | 1453 | puts("This disk has both DOS and BSD magic.\n" |
1454 | "Give the 'b' command to go to BSD mode.\n"); | 1454 | "Give the 'b' command to go to BSD mode."); |
1455 | } | 1455 | } |
1456 | #endif | 1456 | #endif |
1457 | 1457 | ||
@@ -1461,9 +1461,9 @@ static int get_boot(void) | |||
1461 | #else | 1461 | #else |
1462 | if (!valid_part_table_flag(MBRbuffer)) { | 1462 | if (!valid_part_table_flag(MBRbuffer)) { |
1463 | if (what == OPEN_MAIN) { | 1463 | if (what == OPEN_MAIN) { |
1464 | printf("Device contains neither a valid DOS " | 1464 | puts("Device contains neither a valid DOS " |
1465 | "partition table, nor Sun, SGI, OSF or GPT " | 1465 | "partition table, nor Sun, SGI, OSF or GPT " |
1466 | "disklabel\n"); | 1466 | "disklabel"); |
1467 | #ifdef __sparc__ | 1467 | #ifdef __sparc__ |
1468 | IF_FEATURE_SUN_LABEL(create_sunlabel();) | 1468 | IF_FEATURE_SUN_LABEL(create_sunlabel();) |
1469 | #else | 1469 | #else |
@@ -1596,7 +1596,7 @@ read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char * | |||
1596 | } | 1596 | } |
1597 | if (value >= low && value <= high) | 1597 | if (value >= low && value <= high) |
1598 | break; | 1598 | break; |
1599 | printf("Value is out of range\n"); | 1599 | puts("Value is out of range"); |
1600 | } | 1600 | } |
1601 | return value; | 1601 | return value; |
1602 | } | 1602 | } |
@@ -1641,7 +1641,7 @@ get_existing_partition(int warn, unsigned max) | |||
1641 | printf("Selected partition %u\n", pno+1); | 1641 | printf("Selected partition %u\n", pno+1); |
1642 | return pno; | 1642 | return pno; |
1643 | } | 1643 | } |
1644 | printf("No partition is defined yet!\n"); | 1644 | puts("No partition is defined yet!"); |
1645 | return -1; | 1645 | return -1; |
1646 | 1646 | ||
1647 | not_unique: | 1647 | not_unique: |
@@ -1668,7 +1668,7 @@ get_nonexisting_partition(int warn, unsigned max) | |||
1668 | printf("Selected partition %u\n", pno+1); | 1668 | printf("Selected partition %u\n", pno+1); |
1669 | return pno; | 1669 | return pno; |
1670 | } | 1670 | } |
1671 | printf("All primary partitions have been defined already!\n"); | 1671 | puts("All primary partitions have been defined already!"); |
1672 | return -1; | 1672 | return -1; |
1673 | 1673 | ||
1674 | not_unique: | 1674 | not_unique: |
@@ -1703,10 +1703,10 @@ toggle_dos_compatibility_flag(void) | |||
1703 | dos_compatible_flag = 1 - dos_compatible_flag; | 1703 | dos_compatible_flag = 1 - dos_compatible_flag; |
1704 | if (dos_compatible_flag) { | 1704 | if (dos_compatible_flag) { |
1705 | sector_offset = g_sectors; | 1705 | sector_offset = g_sectors; |
1706 | printf("DOS Compatibility flag is set\n"); | 1706 | printf("DOS Compatibility flag is %sset\n", ""); |
1707 | } else { | 1707 | } else { |
1708 | sector_offset = 1; | 1708 | sector_offset = 1; |
1709 | printf("DOS Compatibility flag is not set\n"); | 1709 | printf("DOS Compatibility flag is %sset\n", "not "); |
1710 | } | 1710 | } |
1711 | } | 1711 | } |
1712 | 1712 | ||
@@ -1813,16 +1813,16 @@ change_sysid(void) | |||
1813 | sys = read_hex(get_sys_types()); | 1813 | sys = read_hex(get_sys_types()); |
1814 | 1814 | ||
1815 | if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN) { | 1815 | if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN) { |
1816 | printf("Type 0 means free space to many systems\n" | 1816 | puts("Type 0 means free space to many systems\n" |
1817 | "(but not to Linux). Having partitions of\n" | 1817 | "(but not to Linux). Having partitions of\n" |
1818 | "type 0 is probably unwise.\n"); | 1818 | "type 0 is probably unwise."); |
1819 | /* break; */ | 1819 | /* break; */ |
1820 | } | 1820 | } |
1821 | 1821 | ||
1822 | if (!LABEL_IS_SUN && !LABEL_IS_SGI) { | 1822 | if (!LABEL_IS_SUN && !LABEL_IS_SGI) { |
1823 | if (IS_EXTENDED(sys) != IS_EXTENDED(p->sys_ind)) { | 1823 | if (IS_EXTENDED(sys) != IS_EXTENDED(p->sys_ind)) { |
1824 | printf("You cannot change a partition into" | 1824 | puts("You cannot change a partition into" |
1825 | " an extended one or vice versa\n"); | 1825 | " an extended one or vice versa"); |
1826 | break; | 1826 | break; |
1827 | } | 1827 | } |
1828 | } | 1828 | } |
@@ -1830,10 +1830,10 @@ change_sysid(void) | |||
1830 | if (sys < 256) { | 1830 | if (sys < 256) { |
1831 | #if ENABLE_FEATURE_SUN_LABEL | 1831 | #if ENABLE_FEATURE_SUN_LABEL |
1832 | if (LABEL_IS_SUN && i == 2 && sys != SUN_WHOLE_DISK) | 1832 | if (LABEL_IS_SUN && i == 2 && sys != SUN_WHOLE_DISK) |
1833 | printf("Consider leaving partition 3 " | 1833 | puts("Consider leaving partition 3 " |
1834 | "as Whole disk (5),\n" | 1834 | "as Whole disk (5),\n" |
1835 | "as SunOS/Solaris expects it and " | 1835 | "as SunOS/Solaris expects it and " |
1836 | "even Linux likes it\n\n"); | 1836 | "even Linux likes it\n"); |
1837 | #endif | 1837 | #endif |
1838 | #if ENABLE_FEATURE_SGI_LABEL | 1838 | #if ENABLE_FEATURE_SGI_LABEL |
1839 | if (LABEL_IS_SGI && | 1839 | if (LABEL_IS_SGI && |
@@ -1842,10 +1842,10 @@ change_sysid(void) | |||
1842 | (i == 8 && sys != 0) | 1842 | (i == 8 && sys != 0) |
1843 | ) | 1843 | ) |
1844 | ) { | 1844 | ) { |
1845 | printf("Consider leaving partition 9 " | 1845 | puts("Consider leaving partition 9 " |
1846 | "as volume header (0),\nand " | 1846 | "as volume header (0),\nand " |
1847 | "partition 11 as entire volume (6)" | 1847 | "partition 11 as entire volume (6)" |
1848 | "as IRIX expects it\n\n"); | 1848 | "as IRIX expects it\n"); |
1849 | } | 1849 | } |
1850 | #endif | 1850 | #endif |
1851 | if (sys == origsys) | 1851 | if (sys == origsys) |
@@ -2067,7 +2067,7 @@ fix_partition_table_order(void) | |||
2067 | int i,k; | 2067 | int i,k; |
2068 | 2068 | ||
2069 | if (!wrong_p_order(NULL)) { | 2069 | if (!wrong_p_order(NULL)) { |
2070 | printf("Ordering is already correct\n\n"); | 2070 | puts("Ordering is already correct\n"); |
2071 | return; | 2071 | return; |
2072 | } | 2072 | } |
2073 | 2073 | ||
@@ -2095,7 +2095,7 @@ fix_partition_table_order(void) | |||
2095 | if (i) | 2095 | if (i) |
2096 | fix_chain_of_logicals(); | 2096 | fix_chain_of_logicals(); |
2097 | 2097 | ||
2098 | printf("Done.\n"); | 2098 | puts("Done"); |
2099 | } | 2099 | } |
2100 | #endif | 2100 | #endif |
2101 | 2101 | ||
@@ -2178,7 +2178,7 @@ list_table(int xtra) | |||
2178 | * if this is a sgi, sun or aix labeled disk... */ | 2178 | * if this is a sgi, sun or aix labeled disk... */ |
2179 | if (LABEL_IS_DOS && wrong_p_order(NULL)) { | 2179 | if (LABEL_IS_DOS && wrong_p_order(NULL)) { |
2180 | /* FIXME */ | 2180 | /* FIXME */ |
2181 | printf("\nPartition table entries are not in disk order\n"); | 2181 | puts("\nPartition table entries are not in disk order"); |
2182 | } | 2182 | } |
2183 | } | 2183 | } |
2184 | 2184 | ||
@@ -2192,7 +2192,7 @@ x_list_table(int extend) | |||
2192 | 2192 | ||
2193 | printf("\nDisk %s: %u heads, %u sectors, %u cylinders\n\n", | 2193 | printf("\nDisk %s: %u heads, %u sectors, %u cylinders\n\n", |
2194 | disk_device, g_heads, g_sectors, g_cylinders); | 2194 | disk_device, g_heads, g_sectors, g_cylinders); |
2195 | printf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"); | 2195 | puts("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID"); |
2196 | for (i = 0; i < g_partitions; i++) { | 2196 | for (i = 0; i < g_partitions; i++) { |
2197 | pe = &ptes[i]; | 2197 | pe = &ptes[i]; |
2198 | p = (extend ? pe->ext_pointer : pe->part_table); | 2198 | p = (extend ? pe->ext_pointer : pe->part_table); |
@@ -2419,7 +2419,7 @@ add_partition(int n, int sys) | |||
2419 | limit = first[i] - 1; | 2419 | limit = first[i] - 1; |
2420 | } | 2420 | } |
2421 | if (start > limit) { | 2421 | if (start > limit) { |
2422 | printf("No free sectors available\n"); | 2422 | puts("No free sectors available"); |
2423 | if (n > 4) | 2423 | if (n > 4) |
2424 | g_partitions--; | 2424 | g_partitions--; |
2425 | return; | 2425 | return; |
@@ -2490,9 +2490,9 @@ new_partition(void) | |||
2490 | return; | 2490 | return; |
2491 | } | 2491 | } |
2492 | if (LABEL_IS_AIX) { | 2492 | if (LABEL_IS_AIX) { |
2493 | printf("Sorry - this fdisk cannot handle AIX disk labels.\n" | 2493 | puts("Sorry - this fdisk cannot handle AIX disk labels.\n" |
2494 | "If you want to add DOS-type partitions, create a new empty DOS partition\n" | 2494 | "If you want to add DOS-type partitions, create a new empty DOS partition\n" |
2495 | "table first (use 'o'). This will destroy the present disk contents.\n"); | 2495 | "table first (use 'o'). This will destroy the present disk contents."); |
2496 | return; | 2496 | return; |
2497 | } | 2497 | } |
2498 | 2498 | ||
@@ -2500,7 +2500,7 @@ new_partition(void) | |||
2500 | free_primary += !ptes[i].part_table->sys_ind; | 2500 | free_primary += !ptes[i].part_table->sys_ind; |
2501 | 2501 | ||
2502 | if (!free_primary && g_partitions >= MAXIMUM_PARTS) { | 2502 | if (!free_primary && g_partitions >= MAXIMUM_PARTS) { |
2503 | printf("The maximum number of partitions has been created\n"); | 2503 | puts("The maximum number of partitions has been created"); |
2504 | return; | 2504 | return; |
2505 | } | 2505 | } |
2506 | 2506 | ||
@@ -2508,8 +2508,8 @@ new_partition(void) | |||
2508 | if (extended_offset) | 2508 | if (extended_offset) |
2509 | add_logical(); | 2509 | add_logical(); |
2510 | else | 2510 | else |
2511 | printf("You must delete some partition and add " | 2511 | puts("You must delete some partition and add " |
2512 | "an extended partition first\n"); | 2512 | "an extended partition first"); |
2513 | } else { | 2513 | } else { |
2514 | char c, line[80]; | 2514 | char c, line[80]; |
2515 | snprintf(line, sizeof(line), | 2515 | snprintf(line, sizeof(line), |
@@ -2547,7 +2547,7 @@ reread_partition_table(int leave) | |||
2547 | { | 2547 | { |
2548 | int i; | 2548 | int i; |
2549 | 2549 | ||
2550 | printf("Calling ioctl() to re-read partition table\n"); | 2550 | puts("Calling ioctl() to re-read partition table"); |
2551 | sync(); | 2551 | sync(); |
2552 | /* Users with slow external USB disks on a 320MHz ARM system (year 2011) | 2552 | /* Users with slow external USB disks on a 320MHz ARM system (year 2011) |
2553 | * report that sleep is needed, otherwise BLKRRPART may fail with -EIO: | 2553 | * report that sleep is needed, otherwise BLKRRPART may fail with -EIO: |
@@ -2558,10 +2558,10 @@ reread_partition_table(int leave) | |||
2558 | "failed, kernel still uses old table"); | 2558 | "failed, kernel still uses old table"); |
2559 | #if 0 | 2559 | #if 0 |
2560 | if (dos_changed) | 2560 | if (dos_changed) |
2561 | printf( | 2561 | puts( |
2562 | "\nWARNING: If you have created or modified any DOS 6.x\n" | 2562 | "\nWARNING: If you have created or modified any DOS 6.x\n" |
2563 | "partitions, please see the fdisk manual page for additional\n" | 2563 | "partitions, please see the fdisk manual page for additional\n" |
2564 | "information\n"); | 2564 | "information"); |
2565 | #endif | 2565 | #endif |
2566 | 2566 | ||
2567 | if (leave) { | 2567 | if (leave) { |
@@ -2589,7 +2589,7 @@ write_table(void) | |||
2589 | } | 2589 | } |
2590 | } | 2590 | } |
2591 | else if (LABEL_IS_SGI) { | 2591 | else if (LABEL_IS_SGI) { |
2592 | /* no test on change? the printf below might be mistaken */ | 2592 | /* no test on change? the "altered" msg below might be mistaken */ |
2593 | sgi_write_table(); | 2593 | sgi_write_table(); |
2594 | } | 2594 | } |
2595 | else if (LABEL_IS_SUN) { | 2595 | else if (LABEL_IS_SUN) { |
@@ -2601,7 +2601,7 @@ write_table(void) | |||
2601 | } | 2601 | } |
2602 | } | 2602 | } |
2603 | 2603 | ||
2604 | printf("The partition table has been altered.\n"); | 2604 | puts("The partition table has been altered."); |
2605 | reread_partition_table(1); | 2605 | reread_partition_table(1); |
2606 | } | 2606 | } |
2607 | #endif /* FEATURE_FDISK_WRITABLE */ | 2607 | #endif /* FEATURE_FDISK_WRITABLE */ |
@@ -2744,8 +2744,8 @@ xselect(void) | |||
2744 | user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, "Number of sectors"); | 2744 | user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, "Number of sectors"); |
2745 | if (dos_compatible_flag) { | 2745 | if (dos_compatible_flag) { |
2746 | sector_offset = g_sectors; | 2746 | sector_offset = g_sectors; |
2747 | printf("Warning: setting sector offset for DOS " | 2747 | puts("Warning: setting sector offset for DOS " |
2748 | "compatiblity\n"); | 2748 | "compatiblity"); |
2749 | } | 2749 | } |
2750 | update_units(); | 2750 | update_units(); |
2751 | break; | 2751 | break; |
@@ -3024,7 +3024,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) | |||
3024 | sgi_get_bootfile()); | 3024 | sgi_get_bootfile()); |
3025 | if (read_maybe_empty("Please enter the name of the " | 3025 | if (read_maybe_empty("Please enter the name of the " |
3026 | "new boot file: ") == '\n') | 3026 | "new boot file: ") == '\n') |
3027 | printf("Boot file unchanged\n"); | 3027 | puts("Boot file unchanged"); |
3028 | else | 3028 | else |
3029 | sgi_set_bootfile(line_ptr); | 3029 | sgi_set_bootfile(line_ptr); |
3030 | } | 3030 | } |
@@ -3106,8 +3106,8 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) | |||
3106 | #if ENABLE_FEATURE_FDISK_ADVANCED | 3106 | #if ENABLE_FEATURE_FDISK_ADVANCED |
3107 | case 'x': | 3107 | case 'x': |
3108 | if (LABEL_IS_SGI) { | 3108 | if (LABEL_IS_SGI) { |
3109 | printf("\n\tSorry, no experts menu for SGI " | 3109 | puts("\n\tSorry, no experts menu for SGI " |
3110 | "partition tables available\n\n"); | 3110 | "partition tables available\n"); |
3111 | } else | 3111 | } else |
3112 | xselect(); | 3112 | xselect(); |
3113 | break; | 3113 | break; |
diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c index 5786d5f7d..715e227ca 100644 --- a/util-linux/fdisk_gpt.c +++ b/util-linux/fdisk_gpt.c | |||
@@ -106,7 +106,7 @@ gpt_list_table(int xtra UNUSED_PARAM) | |||
106 | (unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba), | 106 | (unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba), |
107 | (unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba)); | 107 | (unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba)); |
108 | 108 | ||
109 | printf("Number Start (sector) End (sector) Size Code Name\n"); | 109 | puts("Number Start (sector) End (sector) Size Code Name"); |
110 | for (i = 0; i < n_parts; i++) { | 110 | for (i = 0; i < n_parts; i++) { |
111 | gpt_partition *p = gpt_part(i); | 111 | gpt_partition *p = gpt_part(i); |
112 | if (p->lba_start) { | 112 | if (p->lba_start) { |
@@ -119,7 +119,7 @@ gpt_list_table(int xtra UNUSED_PARAM) | |||
119 | numstr6, | 119 | numstr6, |
120 | 0x0700 /* FIXME */); | 120 | 0x0700 /* FIXME */); |
121 | gpt_print_wide(p->name, 18); | 121 | gpt_print_wide(p->name, 18); |
122 | printf("\n"); | 122 | bb_putchar('\n'); |
123 | } | 123 | } |
124 | } | 124 | } |
125 | } | 125 | } |
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c index 33767a1af..d2f3524b4 100644 --- a/util-linux/fsck_minix.c +++ b/util-linux/fsck_minix.c | |||
@@ -371,9 +371,9 @@ static int ask(const char *string, int def) | |||
371 | } | 371 | } |
372 | } | 372 | } |
373 | if (def) | 373 | if (def) |
374 | printf("y\n"); | 374 | puts("y"); |
375 | else { | 375 | else { |
376 | printf("n\n"); | 376 | puts("n"); |
377 | errors_uncorrected = 1; | 377 | errors_uncorrected = 1; |
378 | } | 378 | } |
379 | return def; | 379 | return def; |
@@ -405,7 +405,7 @@ static void check_mount(void) | |||
405 | if (isatty(0) && isatty(1)) | 405 | if (isatty(0) && isatty(1)) |
406 | cont = ask("Do you really want to continue", 0); | 406 | cont = ask("Do you really want to continue", 0); |
407 | if (!cont) { | 407 | if (!cont) { |
408 | printf("Check aborted\n"); | 408 | puts("Check aborted"); |
409 | exit(EXIT_SUCCESS); | 409 | exit(EXIT_SUCCESS); |
410 | } | 410 | } |
411 | } | 411 | } |
@@ -470,8 +470,8 @@ static void write_block(unsigned nr, void *addr) | |||
470 | if (!nr) | 470 | if (!nr) |
471 | return; | 471 | return; |
472 | if (nr < FIRSTZONE || nr >= ZONES) { | 472 | if (nr < FIRSTZONE || nr >= ZONES) { |
473 | printf("Internal error: trying to write bad block\n" | 473 | puts("Internal error: trying to write bad block\n" |
474 | "Write request ignored\n"); | 474 | "Write request ignored"); |
475 | errors_uncorrected = 1; | 475 | errors_uncorrected = 1; |
476 | return; | 476 | return; |
477 | } | 477 | } |
@@ -659,7 +659,7 @@ static void read_tables(void) | |||
659 | if (INODE_BUFFER_SIZE != read(dev_fd, inode_buffer, INODE_BUFFER_SIZE)) | 659 | if (INODE_BUFFER_SIZE != read(dev_fd, inode_buffer, INODE_BUFFER_SIZE)) |
660 | die("can't read inodes"); | 660 | die("can't read inodes"); |
661 | if (NORM_FIRSTZONE != FIRSTZONE) { | 661 | if (NORM_FIRSTZONE != FIRSTZONE) { |
662 | printf("warning: firstzone!=norm_firstzone\n"); | 662 | puts("warning: firstzone!=norm_firstzone"); |
663 | errors_uncorrected = 1; | 663 | errors_uncorrected = 1; |
664 | } | 664 | } |
665 | get_dirsize(); | 665 | get_dirsize(); |
@@ -713,7 +713,7 @@ static void get_inode_common(unsigned nr, uint16_t i_mode) | |||
713 | } else | 713 | } else |
714 | links++; | 714 | links++; |
715 | if (!++inode_count[nr]) { | 715 | if (!++inode_count[nr]) { |
716 | printf("Warning: inode count too big\n"); | 716 | puts("Warning: inode count too big"); |
717 | inode_count[nr]--; | 717 | inode_count[nr]--; |
718 | errors_uncorrected = 1; | 718 | errors_uncorrected = 1; |
719 | } | 719 | } |
@@ -1299,7 +1299,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv) | |||
1299 | } | 1299 | } |
1300 | if (changed) { | 1300 | if (changed) { |
1301 | write_tables(); | 1301 | write_tables(); |
1302 | printf("FILE SYSTEM HAS BEEN CHANGED\n"); | 1302 | puts("FILE SYSTEM HAS BEEN CHANGED"); |
1303 | sync(); | 1303 | sync(); |
1304 | } else if (OPT_repair) | 1304 | } else if (OPT_repair) |
1305 | write_superblock(); | 1305 | write_superblock(); |
diff --git a/util-linux/getopt.c b/util-linux/getopt.c index 58df1c823..b9dadf13c 100644 --- a/util-linux/getopt.c +++ b/util-linux/getopt.c | |||
@@ -378,7 +378,7 @@ int getopt_main(int argc, char **argv) | |||
378 | if (compatible) { | 378 | if (compatible) { |
379 | /* For some reason, the original getopt gave no error | 379 | /* For some reason, the original getopt gave no error |
380 | * when there were no arguments. */ | 380 | * when there were no arguments. */ |
381 | printf(" --\n"); | 381 | puts(" --"); |
382 | return 0; | 382 | return 0; |
383 | } | 383 | } |
384 | bb_error_msg_and_die("missing optstring argument"); | 384 | bb_error_msg_and_die("missing optstring argument"); |
diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c index 888f70ef8..38d81af50 100644 --- a/util-linux/ipcrm.c +++ b/util-linux/ipcrm.c | |||
@@ -119,7 +119,7 @@ int ipcrm_main(int argc, char **argv) | |||
119 | 119 | ||
120 | if (remove_ids(what, &argv[2])) | 120 | if (remove_ids(what, &argv[2])) |
121 | fflush_stdout_and_exit(EXIT_FAILURE); | 121 | fflush_stdout_and_exit(EXIT_FAILURE); |
122 | printf("resource(s) deleted\n"); | 122 | puts("resource(s) deleted"); |
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
125 | } | 125 | } |
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 662e8ab38..51781d597 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -406,7 +406,7 @@ static void parse_next_rule(void) | |||
406 | } | 406 | } |
407 | 407 | ||
408 | /* 3rd field: mode - device permissions */ | 408 | /* 3rd field: mode - device permissions */ |
409 | bb_parse_mode(tokens[2], &G.cur_rule.mode); | 409 | G.cur_rule.mode = bb_parse_mode(tokens[2], G.cur_rule.mode); |
410 | 410 | ||
411 | /* 4th field (opt): ">|=alias" or "!" to not create the node */ | 411 | /* 4th field (opt): ">|=alias" or "!" to not create the node */ |
412 | val = tokens[3]; | 412 | val = tokens[3]; |
diff --git a/util-linux/mkfs_minix.c b/util-linux/mkfs_minix.c index d65a5161c..88d797584 100644 --- a/util-linux/mkfs_minix.c +++ b/util-linux/mkfs_minix.c | |||
@@ -576,11 +576,11 @@ static void setup_tables(void) | |||
576 | for (i = MINIX_ROOT_INO; i <= SB_INODES; i++) | 576 | for (i = MINIX_ROOT_INO; i <= SB_INODES; i++) |
577 | unmark_inode(i); | 577 | unmark_inode(i); |
578 | G.inode_buffer = xzalloc(INODE_BUFFER_SIZE); | 578 | G.inode_buffer = xzalloc(INODE_BUFFER_SIZE); |
579 | printf("%ld inodes\n", (long)SB_INODES); | 579 | printf("%lu inodes\n", (unsigned long)SB_INODES); |
580 | printf("%ld blocks\n", (long)SB_ZONES); | 580 | printf("%lu blocks\n", (unsigned long)SB_ZONES); |
581 | printf("Firstdatazone=%ld (%ld)\n", (long)SB_FIRSTZONE, (long)norm_firstzone); | 581 | printf("Firstdatazone=%lu (%lu)\n", (unsigned long)SB_FIRSTZONE, (unsigned long)norm_firstzone); |
582 | printf("Zonesize=%d\n", BLOCK_SIZE << SB_ZONE_SIZE); | 582 | printf("Zonesize=%u\n", BLOCK_SIZE << SB_ZONE_SIZE); |
583 | printf("Maxsize=%ld\n", (long)SB_MAXSIZE); | 583 | printf("Maxsize=%lu\n", (unsigned long)SB_MAXSIZE); |
584 | } | 584 | } |
585 | 585 | ||
586 | int mkfs_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 586 | int mkfs_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c index a301b365b..7960b672c 100644 --- a/util-linux/switch_root.c +++ b/util-linux/switch_root.c | |||
@@ -206,7 +206,7 @@ because they're what all paths your process uses would be relative to. | |||
206 | 206 | ||
207 | That's why the careful sequencing above: we cd into the new mount point before | 207 | That's why the careful sequencing above: we cd into the new mount point before |
208 | we do the mount --move. Moving the mount point would otherwise make it | 208 | we do the mount --move. Moving the mount point would otherwise make it |
209 | totally inaccessible to is because cd-ing to the old path wouldn't give it to | 209 | totally inaccessible to us because cd-ing to the old path wouldn't give it to |
210 | us anymore, and cd "/" just gives us the cached dentry from when the process | 210 | us anymore, and cd "/" just gives us the cached dentry from when the process |
211 | was created (in this case the old initramfs one). But the "." symlink gives | 211 | was created (in this case the old initramfs one). But the "." symlink gives |
212 | us the dentry of the filesystem we just moved, so we can then "chroot ." to | 212 | us the dentry of the filesystem we just moved, so we can then "chroot ." to |
diff --git a/util-linux/uevent.c b/util-linux/uevent.c index fb98b4845..514a9e934 100644 --- a/util-linux/uevent.c +++ b/util-linux/uevent.c | |||
@@ -37,7 +37,7 @@ enum { | |||
37 | #ifndef SO_RCVBUFFORCE | 37 | #ifndef SO_RCVBUFFORCE |
38 | #define SO_RCVBUFFORCE 33 | 38 | #define SO_RCVBUFFORCE 33 |
39 | #endif | 39 | #endif |
40 | static const int RCVBUF = 2 * 1024 * 1024; | 40 | enum { RCVBUF = 2 * 1024 * 1024 }; |
41 | 41 | ||
42 | int uevent_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 42 | int uevent_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
43 | int uevent_main(int argc UNUSED_PARAM, char **argv) | 43 | int uevent_main(int argc UNUSED_PARAM, char **argv) |
@@ -63,8 +63,8 @@ int uevent_main(int argc UNUSED_PARAM, char **argv) | |||
63 | // find /sys -name uevent -exec sh -c 'echo add >"{}"' ';' | 63 | // find /sys -name uevent -exec sh -c 'echo add >"{}"' ';' |
64 | // | 64 | // |
65 | // SO_RCVBUFFORCE (root only) can go above net.core.rmem_max sysctl | 65 | // SO_RCVBUFFORCE (root only) can go above net.core.rmem_max sysctl |
66 | setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &RCVBUF, sizeof(RCVBUF)); | 66 | setsockopt_SOL_SOCKET_int(fd, SO_RCVBUF, RCVBUF); |
67 | setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &RCVBUF, sizeof(RCVBUF)); | 67 | setsockopt_SOL_SOCKET_int(fd, SO_RCVBUFFORCE, RCVBUF); |
68 | if (0) { | 68 | if (0) { |
69 | int z; | 69 | int z; |
70 | socklen_t zl = sizeof(z); | 70 | socklen_t zl = sizeof(z); |
diff --git a/util-linux/umount.c b/util-linux/umount.c index 4c2e8821e..00910977d 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c | |||
@@ -81,8 +81,9 @@ int umount_main(int argc UNUSED_PARAM, char **argv) | |||
81 | argv += optind; | 81 | argv += optind; |
82 | 82 | ||
83 | // MNT_FORCE and MNT_DETACH (from linux/fs.h) must match | 83 | // MNT_FORCE and MNT_DETACH (from linux/fs.h) must match |
84 | // OPT_FORCE and OPT_LAZY, otherwise this trick won't work: | 84 | // OPT_FORCE and OPT_LAZY. |
85 | doForce = MAX((opt & OPT_FORCE), (opt & OPT_LAZY)); | 85 | BUILD_BUG_ON(OPT_FORCE != MNT_FORCE || OPT_LAZY != MNT_DETACH); |
86 | doForce = opt & (OPT_FORCE|OPT_LAZY); | ||
86 | 87 | ||
87 | /* Get a list of mount points from mtab. We read them all in now mostly | 88 | /* Get a list of mount points from mtab. We read them all in now mostly |
88 | * for umount -a (so we don't have to worry about the list changing while | 89 | * for umount -a (so we don't have to worry about the list changing while |
@@ -147,11 +148,18 @@ int umount_main(int argc UNUSED_PARAM, char **argv) | |||
147 | // umount the directory even if we were given the block device. | 148 | // umount the directory even if we were given the block device. |
148 | if (m) zapit = m->dir; | 149 | if (m) zapit = m->dir; |
149 | 150 | ||
151 | // umount from util-linux 2.22.2 does not do this: | ||
152 | // umount -f uses umount2(MNT_FORCE) immediately, | ||
153 | // not trying umount() first. | ||
154 | // (Strangely, umount -fl ignores -f: it is equivalent to umount -l. | ||
155 | // We do pass both flags in this case) | ||
156 | #if 0 | ||
150 | // Let's ask the thing nicely to unmount. | 157 | // Let's ask the thing nicely to unmount. |
151 | curstat = umount(zapit); | 158 | curstat = umount(zapit); |
152 | 159 | ||
153 | // Force the unmount, if necessary. | 160 | // Unmount with force and/or lazy flags, if necessary. |
154 | if (curstat && doForce) | 161 | if (curstat && doForce) |
162 | #endif | ||
155 | curstat = umount2(zapit, doForce); | 163 | curstat = umount2(zapit, doForce); |
156 | 164 | ||
157 | // If still can't umount, maybe remount read-only? | 165 | // If still can't umount, maybe remount read-only? |
@@ -168,7 +176,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv) | |||
168 | bb_error_msg(msg, m->device); | 176 | bb_error_msg(msg, m->device); |
169 | } else { | 177 | } else { |
170 | status = EXIT_FAILURE; | 178 | status = EXIT_FAILURE; |
171 | bb_perror_msg("can't %sumount %s", (doForce ? "forcibly " : ""), zapit); | 179 | bb_perror_msg("can't unmount %s", zapit); |
172 | } | 180 | } |
173 | } else { | 181 | } else { |
174 | // De-allocate the loop device. This ioctl should be ignored on | 182 | // De-allocate the loop device. This ioctl should be ignored on |