diff options
author | Ron Yorston <rmy@pobox.com> | 2012-03-23 11:13:23 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-03-23 11:13:23 +0000 |
commit | 40514a0309939f2446f0d4ed9600cad5de396e7f (patch) | |
tree | 0f5f4a57d4bb7893418b5bb11d482858eb17ba8b | |
parent | 9db164d6e39050d09f38288c6045cd2a2cbf6d63 (diff) | |
parent | c0cae52662ccced9df19f19ec94238d1b1e3bd71 (diff) | |
download | busybox-w32-40514a0309939f2446f0d4ed9600cad5de396e7f.tar.gz busybox-w32-40514a0309939f2446f0d4ed9600cad5de396e7f.tar.bz2 busybox-w32-40514a0309939f2446f0d4ed9600cad5de396e7f.zip |
Merge commit 'c0cae52662ccced9df19f19ec94238d1b1e3bd71' into merge
Conflicts:
Makefile.flags
scripts/basic/fixdep.c
164 files changed, 3969 insertions, 1628 deletions
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 1 | 1 | VERSION = 1 |
2 | PATCHLEVEL = 19 | 2 | PATCHLEVEL = 20 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = | 4 | EXTRAVERSION = .git |
5 | NAME = Unnamed | 5 | NAME = Unnamed |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/Makefile.flags b/Makefile.flags index 513b6ebb2..b653d55c1 100644 --- a/Makefile.flags +++ b/Makefile.flags | |||
@@ -99,13 +99,18 @@ endif | |||
99 | 99 | ||
100 | ifeq ($(CONFIG_PLATFORM_MINGW32),y) | 100 | ifeq ($(CONFIG_PLATFORM_MINGW32),y) |
101 | # These defintions are not strictly needed, but they help shut up fnmatch.c warnings | 101 | # These defintions are not strictly needed, but they help shut up fnmatch.c warnings |
102 | CFLAGS += -Iwin32 -DHAVE_STRING_H=1 -DHAVE_CONFIG_H=0 | 102 | CFLAGS += -Iwin32 -DHAVE_STRING_H=1 -DHAVE_CONFIG_H=0 -fno-builtin-stpcpy |
103 | EXEEXT = .exe | 103 | EXEEXT = .exe |
104 | ifeq ($(CONFIG_WIN32_NET),y) | 104 | ifeq ($(CONFIG_WIN32_NET),y) |
105 | LDLIBS += ws2_32 | 105 | LDLIBS += ws2_32 |
106 | endif | 106 | endif |
107 | else | 107 | else |
108 | ifneq ($(CONFIG_CROSS_COMPILER_PREFIX),"arm-linux-androideabi-") | ||
108 | LDLIBS += m crypt | 109 | LDLIBS += m crypt |
110 | else | ||
111 | # Android libc has no crypt. TODO: make a generic CONFIG_LINK_WITH_CRYPT option? | ||
112 | LDLIBS += m | ||
113 | endif | ||
109 | endif | 114 | endif |
110 | 115 | ||
111 | ifeq ($(CONFIG_PAM),y) | 116 | ifeq ($(CONFIG_PAM),y) |
@@ -2,6 +2,8 @@ Busybox TODO | |||
2 | 2 | ||
3 | Harvest patches from | 3 | Harvest patches from |
4 | http://git.openembedded.org/cgit.cgi/openembedded/tree/recipes/busybox/ | 4 | http://git.openembedded.org/cgit.cgi/openembedded/tree/recipes/busybox/ |
5 | https://dev.openwrt.org/browser/trunk/package/busybox/patches/ | ||
6 | |||
5 | 7 | ||
6 | Stuff that needs to be done. This is organized by who plans to get around to | 8 | Stuff that needs to be done. This is organized by who plans to get around to |
7 | doing it eventually, but that doesn't mean they "own" the item. If you want to | 9 | doing it eventually, but that doesn't mean they "own" the item. If you want to |
diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 3859d7326..a47574737 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c | |||
@@ -80,8 +80,15 @@ int main(int argc, char **argv) | |||
80 | 80 | ||
81 | printf("#define NUM_APPLETS %u\n", NUM_APPLETS); | 81 | printf("#define NUM_APPLETS %u\n", NUM_APPLETS); |
82 | if (NUM_APPLETS == 1) { | 82 | if (NUM_APPLETS == 1) { |
83 | char *dash_to_underscore, *p; | ||
83 | printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); | 84 | printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); |
84 | printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].name); | 85 | /* Example: "ether-wake" -> "ether_wake" */ |
86 | p = dash_to_underscore = strdup(applets[0].name); | ||
87 | p--; | ||
88 | while (*++p) | ||
89 | if (*p == '-') | ||
90 | *p = '_'; | ||
91 | printf("#define SINGLE_APPLET_MAIN %s_main\n", dash_to_underscore); | ||
85 | } | 92 | } |
86 | printf("\n"); | 93 | printf("\n"); |
87 | 94 | ||
diff --git a/archival/Config.src b/archival/Config.src index 7e493f56f..f1d6d3511 100644 --- a/archival/Config.src +++ b/archival/Config.src | |||
@@ -187,6 +187,18 @@ config FEATURE_GZIP_LONG_OPTIONS | |||
187 | help | 187 | help |
188 | Enable use of long options, increases size by about 106 Bytes | 188 | Enable use of long options, increases size by about 106 Bytes |
189 | 189 | ||
190 | config GZIP_FAST | ||
191 | int "Trade memory for gzip speed (0:small,slow - 2:fast,big)" | ||
192 | default 0 | ||
193 | range 0 2 | ||
194 | depends on GZIP | ||
195 | help | ||
196 | Enable big memory options for gzip. | ||
197 | 0: small buffers, small hash-tables | ||
198 | 1: larger buffers, larger hash-tables | ||
199 | 2: larger buffers, largest hash-tables | ||
200 | Larger models may give slightly better compression | ||
201 | |||
190 | config LZOP | 202 | config LZOP |
191 | bool "lzop" | 203 | bool "lzop" |
192 | default y | 204 | default y |
@@ -331,15 +343,12 @@ config UNLZMA | |||
331 | is generally considerably better than that achieved by the bzip2 | 343 | is generally considerably better than that achieved by the bzip2 |
332 | compressors. | 344 | compressors. |
333 | 345 | ||
334 | The BusyBox unlzma applet is limited to de-compression only. | 346 | The BusyBox unlzma applet is limited to decompression only. |
335 | On an x86 system, this applet adds about 4K. | 347 | On an x86 system, this applet adds about 4K. |
336 | 348 | ||
337 | Unless you have a specific application which requires unlzma, you | ||
338 | should probably say N here. | ||
339 | |||
340 | config FEATURE_LZMA_FAST | 349 | config FEATURE_LZMA_FAST |
341 | bool "Optimize unlzma for speed" | 350 | bool "Optimize unlzma for speed" |
342 | default y | 351 | default n |
343 | depends on UNLZMA | 352 | depends on UNLZMA |
344 | help | 353 | help |
345 | This option reduces decompression time by about 25% at the cost of | 354 | This option reduces decompression time by about 25% at the cost of |
diff --git a/archival/ar.c b/archival/ar.c index acad20ff2..88236e878 100644 --- a/archival/ar.c +++ b/archival/ar.c | |||
@@ -28,7 +28,7 @@ | |||
28 | //usage: "\n -v Verbose" | 28 | //usage: "\n -v Verbose" |
29 | 29 | ||
30 | #include "libbb.h" | 30 | #include "libbb.h" |
31 | #include "archive.h" | 31 | #include "bb_archive.h" |
32 | #include "ar.h" | 32 | #include "ar.h" |
33 | 33 | ||
34 | #if ENABLE_FEATURE_AR_CREATE | 34 | #if ENABLE_FEATURE_AR_CREATE |
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 0b0d84994..c96e5396a 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 5 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
6 | */ | 6 | */ |
7 | #include "libbb.h" | 7 | #include "libbb.h" |
8 | #include "archive.h" | 8 | #include "bb_archive.h" |
9 | 9 | ||
10 | enum { | 10 | enum { |
11 | OPT_STDOUT = 1 << 0, | 11 | OPT_STDOUT = 1 << 0, |
@@ -103,7 +103,9 @@ int FAST_FUNC bbunpack(char **argv, | |||
103 | status = unpacker(&info); | 103 | status = unpacker(&info); |
104 | if (status < 0) | 104 | if (status < 0) |
105 | exitcode = 1; | 105 | exitcode = 1; |
106 | xclose(STDOUT_FILENO); /* with error check! */ | 106 | |
107 | if (!(option_mask32 & OPT_STDOUT)) | ||
108 | xclose(STDOUT_FILENO); /* with error check! */ | ||
107 | 109 | ||
108 | if (filename) { | 110 | if (filename) { |
109 | char *del = new_name; | 111 | char *del = new_name; |
@@ -145,6 +147,9 @@ int FAST_FUNC bbunpack(char **argv, | |||
145 | } | 147 | } |
146 | } while (*argv && *++argv); | 148 | } while (*argv && *++argv); |
147 | 149 | ||
150 | if (option_mask32 & OPT_STDOUT) | ||
151 | xclose(STDOUT_FILENO); /* with error check! */ | ||
152 | |||
148 | return exitcode; | 153 | return exitcode; |
149 | } | 154 | } |
150 | 155 | ||
diff --git a/archival/bzip2.c b/archival/bzip2.c index e39d7f704..0716fa89b 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c | |||
@@ -17,9 +17,9 @@ | |||
17 | //usage: "\n -f Force" | 17 | //usage: "\n -f Force" |
18 | 18 | ||
19 | #include "libbb.h" | 19 | #include "libbb.h" |
20 | #include "archive.h" | 20 | #include "bb_archive.h" |
21 | 21 | ||
22 | #define CONFIG_BZIP2_FEATURE_SPEED 1 | 22 | #define CONFIG_BZIP2_FAST 1 |
23 | 23 | ||
24 | /* Speed test: | 24 | /* Speed test: |
25 | * Compiled with gcc 4.2.1, run on Athlon 64 1800 MHz (512K L2 cache). | 25 | * Compiled with gcc 4.2.1, run on Athlon 64 1800 MHz (512K L2 cache). |
@@ -27,7 +27,7 @@ | |||
27 | * (time to compress gcc-4.2.1.tar is 126.4% compared to bbox). | 27 | * (time to compress gcc-4.2.1.tar is 126.4% compared to bbox). |
28 | * At SPEED 5 difference is 32.7%. | 28 | * At SPEED 5 difference is 32.7%. |
29 | * | 29 | * |
30 | * Test run of all CONFIG_BZIP2_FEATURE_SPEED values on a 11Mb text file: | 30 | * Test run of all CONFIG_BZIP2_FAST values on a 11Mb text file: |
31 | * Size Time (3 runs) | 31 | * Size Time (3 runs) |
32 | * 0: 10828 4.145 4.146 4.148 | 32 | * 0: 10828 4.145 4.146 4.148 |
33 | * 1: 11097 3.845 3.860 3.861 | 33 | * 1: 11097 3.845 3.860 3.861 |
diff --git a/archival/cpio.c b/archival/cpio.c index 9674a046b..c2a5b8ab9 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | #include "libbb.h" | 14 | #include "libbb.h" |
15 | #include "archive.h" | 15 | #include "bb_archive.h" |
16 | 16 | ||
17 | //usage:#define cpio_trivial_usage | 17 | //usage:#define cpio_trivial_usage |
18 | //usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") | 18 | //usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") |
diff --git a/archival/dpkg.c b/archival/dpkg.c index 2a6a7b3bf..bf9e9992c 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
@@ -57,7 +57,7 @@ | |||
57 | 57 | ||
58 | #include "libbb.h" | 58 | #include "libbb.h" |
59 | #include <fnmatch.h> | 59 | #include <fnmatch.h> |
60 | #include "archive.h" | 60 | #include "bb_archive.h" |
61 | 61 | ||
62 | /* note: if you vary hash_prime sizes be aware, | 62 | /* note: if you vary hash_prime sizes be aware, |
63 | * 1) tweaking these will have a big effect on how much memory this program uses. | 63 | * 1) tweaking these will have a big effect on how much memory this program uses. |
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index 5d814d7ef..a04ec9407 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c | |||
@@ -19,7 +19,7 @@ | |||
19 | //usage: "$ dpkg-deb -X ./busybox_0.48-1_i386.deb /tmp\n" | 19 | //usage: "$ dpkg-deb -X ./busybox_0.48-1_i386.deb /tmp\n" |
20 | 20 | ||
21 | #include "libbb.h" | 21 | #include "libbb.h" |
22 | #include "archive.h" | 22 | #include "bb_archive.h" |
23 | 23 | ||
24 | #define DPKG_DEB_OPT_CONTENTS 1 | 24 | #define DPKG_DEB_OPT_CONTENTS 1 |
25 | #define DPKG_DEB_OPT_CONTROL 2 | 25 | #define DPKG_DEB_OPT_CONTROL 2 |
diff --git a/archival/gzip.c b/archival/gzip.c index 507f5b151..f590fffa5 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -55,7 +55,7 @@ aa: 85.1% -- replaced with aa.gz | |||
55 | //usage: "-rw-rw-r-- 1 andersen andersen 554058 Apr 14 17:49 /tmp/busybox.tar.gz\n" | 55 | //usage: "-rw-rw-r-- 1 andersen andersen 554058 Apr 14 17:49 /tmp/busybox.tar.gz\n" |
56 | 56 | ||
57 | #include "libbb.h" | 57 | #include "libbb.h" |
58 | #include "archive.h" | 58 | #include "bb_archive.h" |
59 | 59 | ||
60 | 60 | ||
61 | /* =========================================================================== | 61 | /* =========================================================================== |
@@ -81,7 +81,15 @@ aa: 85.1% -- replaced with aa.gz | |||
81 | 81 | ||
82 | /* =========================================================================== | 82 | /* =========================================================================== |
83 | */ | 83 | */ |
84 | #define SMALL_MEM | 84 | #if CONFIG_GZIP_FAST == 0 |
85 | # define SMALL_MEM | ||
86 | #elif CONFIG_GZIP_FAST == 1 | ||
87 | # define MEDIUM_MEM | ||
88 | #elif CONFIG_GZIP_FAST == 2 | ||
89 | # define BIG_MEM | ||
90 | #else | ||
91 | # error "Invalid CONFIG_GZIP_FAST value" | ||
92 | #endif | ||
85 | 93 | ||
86 | #ifndef INBUFSIZ | 94 | #ifndef INBUFSIZ |
87 | # ifdef SMALL_MEM | 95 | # ifdef SMALL_MEM |
diff --git a/archival/libarchive/bz/blocksort.c b/archival/libarchive/bz/blocksort.c index f70c3701d..e600cb7a7 100644 --- a/archival/libarchive/bz/blocksort.c +++ b/archival/libarchive/bz/blocksort.c | |||
@@ -385,7 +385,7 @@ int mainGtU( | |||
385 | * but speeds up compression 10% overall | 385 | * but speeds up compression 10% overall |
386 | */ | 386 | */ |
387 | 387 | ||
388 | #if CONFIG_BZIP2_FEATURE_SPEED >= 1 | 388 | #if CONFIG_BZIP2_FAST >= 1 |
389 | 389 | ||
390 | #define TIMES_8(code) \ | 390 | #define TIMES_8(code) \ |
391 | code; code; code; code; \ | 391 | code; code; code; code; \ |
@@ -496,7 +496,7 @@ void mainSimpleSort(uint32_t* ptr, | |||
496 | i++; | 496 | i++; |
497 | 497 | ||
498 | /* 1.5% overall speedup, +290 bytes */ | 498 | /* 1.5% overall speedup, +290 bytes */ |
499 | #if CONFIG_BZIP2_FEATURE_SPEED >= 3 | 499 | #if CONFIG_BZIP2_FAST >= 3 |
500 | /*-- copy 2 --*/ | 500 | /*-- copy 2 --*/ |
501 | if (i > hi) break; | 501 | if (i > hi) break; |
502 | v = ptr[i]; | 502 | v = ptr[i]; |
@@ -750,7 +750,7 @@ void mainSort(EState* state, | |||
750 | j = block[0] << 8; | 750 | j = block[0] << 8; |
751 | i = nblock - 1; | 751 | i = nblock - 1; |
752 | /* 3%, +300 bytes */ | 752 | /* 3%, +300 bytes */ |
753 | #if CONFIG_BZIP2_FEATURE_SPEED >= 2 | 753 | #if CONFIG_BZIP2_FAST >= 2 |
754 | for (; i >= 3; i -= 4) { | 754 | for (; i >= 3; i -= 4) { |
755 | quadrant[i] = 0; | 755 | quadrant[i] = 0; |
756 | j = (j >> 8) | (((uint16_t)block[i]) << 8); | 756 | j = (j >> 8) | (((uint16_t)block[i]) << 8); |
@@ -787,7 +787,7 @@ void mainSort(EState* state, | |||
787 | 787 | ||
788 | s = block[0] << 8; | 788 | s = block[0] << 8; |
789 | i = nblock - 1; | 789 | i = nblock - 1; |
790 | #if CONFIG_BZIP2_FEATURE_SPEED >= 2 | 790 | #if CONFIG_BZIP2_FAST >= 2 |
791 | for (; i >= 3; i -= 4) { | 791 | for (; i >= 3; i -= 4) { |
792 | s = (s >> 8) | (block[i] << 8); | 792 | s = (s >> 8) | (block[i] << 8); |
793 | j = ftab[s] - 1; | 793 | j = ftab[s] - 1; |
diff --git a/archival/libarchive/bz/bzlib_private.h b/archival/libarchive/bz/bzlib_private.h index 6430ce407..43e674bec 100644 --- a/archival/libarchive/bz/bzlib_private.h +++ b/archival/libarchive/bz/bzlib_private.h | |||
@@ -183,7 +183,7 @@ typedef struct EState { | |||
183 | /* stack-saving measures: these can be local, but they are too big */ | 183 | /* stack-saving measures: these can be local, but they are too big */ |
184 | int32_t sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | 184 | int32_t sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; |
185 | int32_t sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | 185 | int32_t sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; |
186 | #if CONFIG_BZIP2_FEATURE_SPEED >= 5 | 186 | #if CONFIG_BZIP2_FAST >= 5 |
187 | /* second dimension: only 3 needed; 4 makes index calculations faster */ | 187 | /* second dimension: only 3 needed; 4 makes index calculations faster */ |
188 | uint32_t sendMTFValues__len_pack[BZ_MAX_ALPHA_SIZE][4]; | 188 | uint32_t sendMTFValues__len_pack[BZ_MAX_ALPHA_SIZE][4]; |
189 | #endif | 189 | #endif |
diff --git a/archival/libarchive/bz/compress.c b/archival/libarchive/bz/compress.c index f93671742..e9f1afdaf 100644 --- a/archival/libarchive/bz/compress.c +++ b/archival/libarchive/bz/compress.c | |||
@@ -61,7 +61,7 @@ void bsFinishWrite(EState* s) | |||
61 | /*---------------------------------------------------*/ | 61 | /*---------------------------------------------------*/ |
62 | static | 62 | static |
63 | /* Helps only on level 5, on other levels hurts. ? */ | 63 | /* Helps only on level 5, on other levels hurts. ? */ |
64 | #if CONFIG_BZIP2_FEATURE_SPEED >= 5 | 64 | #if CONFIG_BZIP2_FAST >= 5 |
65 | ALWAYS_INLINE | 65 | ALWAYS_INLINE |
66 | #endif | 66 | #endif |
67 | void bsW(EState* s, int32_t n, uint32_t v) | 67 | void bsW(EState* s, int32_t n, uint32_t v) |
@@ -331,7 +331,7 @@ void sendMTFValues(EState* s) | |||
331 | for (v = 0; v < alphaSize; v++) | 331 | for (v = 0; v < alphaSize; v++) |
332 | s->rfreq[t][v] = 0; | 332 | s->rfreq[t][v] = 0; |
333 | 333 | ||
334 | #if CONFIG_BZIP2_FEATURE_SPEED >= 5 | 334 | #if CONFIG_BZIP2_FAST >= 5 |
335 | /* | 335 | /* |
336 | * Set up an auxiliary length table which is used to fast-track | 336 | * Set up an auxiliary length table which is used to fast-track |
337 | * the common case (nGroups == 6). | 337 | * the common case (nGroups == 6). |
@@ -361,7 +361,7 @@ void sendMTFValues(EState* s) | |||
361 | */ | 361 | */ |
362 | for (t = 0; t < nGroups; t++) | 362 | for (t = 0; t < nGroups; t++) |
363 | cost[t] = 0; | 363 | cost[t] = 0; |
364 | #if CONFIG_BZIP2_FEATURE_SPEED >= 5 | 364 | #if CONFIG_BZIP2_FAST >= 5 |
365 | if (nGroups == 6 && 50 == ge-gs+1) { | 365 | if (nGroups == 6 && 50 == ge-gs+1) { |
366 | /*--- fast track the common case ---*/ | 366 | /*--- fast track the common case ---*/ |
367 | register uint32_t cost01, cost23, cost45; | 367 | register uint32_t cost01, cost23, cost45; |
@@ -420,7 +420,7 @@ void sendMTFValues(EState* s) | |||
420 | * Increment the symbol frequencies for the selected table. | 420 | * Increment the symbol frequencies for the selected table. |
421 | */ | 421 | */ |
422 | /* 1% faster compress. +800 bytes */ | 422 | /* 1% faster compress. +800 bytes */ |
423 | #if CONFIG_BZIP2_FEATURE_SPEED >= 4 | 423 | #if CONFIG_BZIP2_FAST >= 4 |
424 | if (nGroups == 6 && 50 == ge-gs+1) { | 424 | if (nGroups == 6 && 50 == ge-gs+1) { |
425 | /*--- fast track the common case ---*/ | 425 | /*--- fast track the common case ---*/ |
426 | #define BZ_ITUR(nn) s->rfreq[bt][mtfv[gs + (nn)]]++ | 426 | #define BZ_ITUR(nn) s->rfreq[bt][mtfv[gs + (nn)]]++ |
diff --git a/archival/libarchive/bz/huffman.c b/archival/libarchive/bz/huffman.c index 676b1af66..bbec11adb 100644 --- a/archival/libarchive/bz/huffman.c +++ b/archival/libarchive/bz/huffman.c | |||
@@ -48,7 +48,7 @@ in the file LICENSE. | |||
48 | 48 | ||
49 | 49 | ||
50 | /* 90 bytes, 0.3% of overall compress speed */ | 50 | /* 90 bytes, 0.3% of overall compress speed */ |
51 | #if CONFIG_BZIP2_FEATURE_SPEED >= 1 | 51 | #if CONFIG_BZIP2_FAST >= 1 |
52 | 52 | ||
53 | /* macro works better than inline (gcc 4.2.1) */ | 53 | /* macro works better than inline (gcc 4.2.1) */ |
54 | #define DOWNHEAP1(heap, weight, Heap) \ | 54 | #define DOWNHEAP1(heap, weight, Heap) \ |
diff --git a/archival/libarchive/data_align.c b/archival/libarchive/data_align.c index 2e56fa8ff..a6b84a440 100644 --- a/archival/libarchive/data_align.c +++ b/archival/libarchive/data_align.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | void FAST_FUNC data_align(archive_handle_t *archive_handle, unsigned boundary) | 9 | void FAST_FUNC data_align(archive_handle_t *archive_handle, unsigned boundary) |
10 | { | 10 | { |
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 1b25c8bd6..f565e5471 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | 9 | void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) |
10 | { | 10 | { |
diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 0e977049d..cc2ff7798 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | enum { | 9 | enum { |
10 | //TAR_FILETYPE, | 10 | //TAR_FILETYPE, |
diff --git a/archival/libarchive/data_extract_to_stdout.c b/archival/libarchive/data_extract_to_stdout.c index 91f3f3539..f849f3b42 100644 --- a/archival/libarchive/data_extract_to_stdout.c +++ b/archival/libarchive/data_extract_to_stdout.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | void FAST_FUNC data_extract_to_stdout(archive_handle_t *archive_handle) | 9 | void FAST_FUNC data_extract_to_stdout(archive_handle_t *archive_handle) |
10 | { | 10 | { |
diff --git a/archival/libarchive/data_skip.c b/archival/libarchive/data_skip.c index a055424e2..588167f01 100644 --- a/archival/libarchive/data_skip.c +++ b/archival/libarchive/data_skip.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | void FAST_FUNC data_skip(archive_handle_t *archive_handle) | 9 | void FAST_FUNC data_skip(archive_handle_t *archive_handle) |
10 | { | 10 | { |
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index 4e46e6849..c4640d489 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c | |||
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "libbb.h" | 42 | #include "libbb.h" |
43 | #include "archive.h" | 43 | #include "bb_archive.h" |
44 | 44 | ||
45 | /* Constants for Huffman coding */ | 45 | /* Constants for Huffman coding */ |
46 | #define MAX_GROUPS 6 | 46 | #define MAX_GROUPS 6 |
@@ -752,7 +752,14 @@ unpack_bz2_stream(int src_fd, int dst_fd) | |||
752 | } | 752 | } |
753 | } | 753 | } |
754 | 754 | ||
755 | if (i != RETVAL_LAST_BLOCK) { | 755 | if (i != RETVAL_LAST_BLOCK |
756 | /* Observed case when i == RETVAL_OK: | ||
757 | * "bzcat z.bz2", where "z.bz2" is a bzipped zero-length file | ||
758 | * (to be exact, z.bz2 is exactly these 14 bytes: | ||
759 | * 42 5a 68 39 17 72 45 38 50 90 00 00 00 00). | ||
760 | */ | ||
761 | && i != RETVAL_OK | ||
762 | ) { | ||
756 | bb_error_msg("bunzip error %d", i); | 763 | bb_error_msg("bunzip error %d", i); |
757 | break; | 764 | break; |
758 | } | 765 | } |
diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c index 44d894244..c6040d04b 100644 --- a/archival/libarchive/decompress_uncompress.c +++ b/archival/libarchive/decompress_uncompress.c | |||
@@ -25,7 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "libbb.h" | 27 | #include "libbb.h" |
28 | #include "archive.h" | 28 | #include "bb_archive.h" |
29 | 29 | ||
30 | 30 | ||
31 | /* Default input buffer size */ | 31 | /* Default input buffer size */ |
@@ -163,7 +163,8 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
163 | 163 | ||
164 | if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { | 164 | if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { |
165 | rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); | 165 | rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); |
166 | //error check?? | 166 | if (rsize < 0) |
167 | bb_error_msg_and_die(bb_msg_read_error); | ||
167 | insize += rsize; | 168 | insize += rsize; |
168 | } | 169 | } |
169 | 170 | ||
@@ -195,6 +196,8 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
195 | 196 | ||
196 | 197 | ||
197 | if (oldcode == -1) { | 198 | if (oldcode == -1) { |
199 | if (code >= 256) | ||
200 | bb_error_msg_and_die("corrupted data"); /* %ld", code); */ | ||
198 | oldcode = code; | 201 | oldcode = code; |
199 | finchar = (int) oldcode; | 202 | finchar = (int) oldcode; |
200 | outbuf[outpos++] = (unsigned char) finchar; | 203 | outbuf[outpos++] = (unsigned char) finchar; |
@@ -239,6 +242,8 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
239 | 242 | ||
240 | /* Generate output characters in reverse order */ | 243 | /* Generate output characters in reverse order */ |
241 | while ((long) code >= (long) 256) { | 244 | while ((long) code >= (long) 256) { |
245 | if (stackp <= &htabof(0)) | ||
246 | bb_error_msg_and_die("corrupted data"); | ||
242 | *--stackp = tab_suffixof(code); | 247 | *--stackp = tab_suffixof(code); |
243 | code = tab_prefixof(code); | 248 | code = tab_prefixof(code); |
244 | } | 249 | } |
@@ -263,8 +268,7 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
263 | } | 268 | } |
264 | 269 | ||
265 | if (outpos >= OBUFSIZ) { | 270 | if (outpos >= OBUFSIZ) { |
266 | full_write(fd_out, outbuf, outpos); | 271 | xwrite(fd_out, outbuf, outpos); |
267 | //error check?? | ||
268 | IF_DESKTOP(total_written += outpos;) | 272 | IF_DESKTOP(total_written += outpos;) |
269 | outpos = 0; | 273 | outpos = 0; |
270 | } | 274 | } |
@@ -292,8 +296,7 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
292 | } while (rsize > 0); | 296 | } while (rsize > 0); |
293 | 297 | ||
294 | if (outpos > 0) { | 298 | if (outpos > 0) { |
295 | full_write(fd_out, outbuf, outpos); | 299 | xwrite(fd_out, outbuf, outpos); |
296 | //error check?? | ||
297 | IF_DESKTOP(total_written += outpos;) | 300 | IF_DESKTOP(total_written += outpos;) |
298 | } | 301 | } |
299 | 302 | ||
diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index a04714341..3631b50cc 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 9 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
10 | */ | 10 | */ |
11 | #include "libbb.h" | 11 | #include "libbb.h" |
12 | #include "archive.h" | 12 | #include "bb_archive.h" |
13 | 13 | ||
14 | #if ENABLE_FEATURE_LZMA_FAST | 14 | #if ENABLE_FEATURE_LZMA_FAST |
15 | # define speed_inline ALWAYS_INLINE | 15 | # define speed_inline ALWAYS_INLINE |
diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index e90dfb06f..3e5d4edca 100644 --- a/archival/libarchive/decompress_unxz.c +++ b/archival/libarchive/decompress_unxz.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * Licensed under GPLv2, see file LICENSE in this source tree. | 10 | * Licensed under GPLv2, see file LICENSE in this source tree. |
11 | */ | 11 | */ |
12 | #include "libbb.h" | 12 | #include "libbb.h" |
13 | #include "archive.h" | 13 | #include "bb_archive.h" |
14 | 14 | ||
15 | #define XZ_FUNC FAST_FUNC | 15 | #define XZ_FUNC FAST_FUNC |
16 | #define XZ_EXTERN static | 16 | #define XZ_EXTERN static |
diff --git a/archival/libarchive/decompress_unzip.c b/archival/libarchive/decompress_unzip.c index a29eef837..aa5d22d0a 100644 --- a/archival/libarchive/decompress_unzip.c +++ b/archival/libarchive/decompress_unzip.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #include <setjmp.h> | 36 | #include <setjmp.h> |
37 | #include "libbb.h" | 37 | #include "libbb.h" |
38 | #include "archive.h" | 38 | #include "bb_archive.h" |
39 | 39 | ||
40 | typedef struct huft_t { | 40 | typedef struct huft_t { |
41 | unsigned char e; /* number of extra bits or operation */ | 41 | unsigned char e; /* number of extra bits or operation */ |
diff --git a/archival/libarchive/filter_accept_all.c b/archival/libarchive/filter_accept_all.c index e69deb679..c33f7d3e3 100644 --- a/archival/libarchive/filter_accept_all.c +++ b/archival/libarchive/filter_accept_all.c | |||
@@ -6,7 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "libbb.h" | 8 | #include "libbb.h" |
9 | #include "archive.h" | 9 | #include "bb_archive.h" |
10 | 10 | ||
11 | /* Accept any non-null name, its not really a filter at all */ | 11 | /* Accept any non-null name, its not really a filter at all */ |
12 | char FAST_FUNC filter_accept_all(archive_handle_t *archive_handle) | 12 | char FAST_FUNC filter_accept_all(archive_handle_t *archive_handle) |
diff --git a/archival/libarchive/filter_accept_list.c b/archival/libarchive/filter_accept_list.c index a7640af79..a2d4b23e9 100644 --- a/archival/libarchive/filter_accept_list.c +++ b/archival/libarchive/filter_accept_list.c | |||
@@ -6,7 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "libbb.h" | 8 | #include "libbb.h" |
9 | #include "archive.h" | 9 | #include "bb_archive.h" |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * Accept names that are in the accept list, ignoring reject list. | 12 | * Accept names that are in the accept list, ignoring reject list. |
diff --git a/archival/libarchive/filter_accept_list_reassign.c b/archival/libarchive/filter_accept_list_reassign.c index d80f71668..3d19abe44 100644 --- a/archival/libarchive/filter_accept_list_reassign.c +++ b/archival/libarchive/filter_accept_list_reassign.c | |||
@@ -6,7 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "libbb.h" | 8 | #include "libbb.h" |
9 | #include "archive.h" | 9 | #include "bb_archive.h" |
10 | 10 | ||
11 | /* Built and used only if ENABLE_DPKG || ENABLE_DPKG_DEB */ | 11 | /* Built and used only if ENABLE_DPKG || ENABLE_DPKG_DEB */ |
12 | 12 | ||
diff --git a/archival/libarchive/filter_accept_reject_list.c b/archival/libarchive/filter_accept_reject_list.c index 3e86cca65..39c811337 100644 --- a/archival/libarchive/filter_accept_reject_list.c +++ b/archival/libarchive/filter_accept_reject_list.c | |||
@@ -6,7 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "libbb.h" | 8 | #include "libbb.h" |
9 | #include "archive.h" | 9 | #include "bb_archive.h" |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * Accept names that are in the accept list and not in the reject list | 12 | * Accept names that are in the accept list and not in the reject list |
diff --git a/archival/libarchive/find_list_entry.c b/archival/libarchive/find_list_entry.c index 5efd1af2e..56032c65a 100644 --- a/archival/libarchive/find_list_entry.c +++ b/archival/libarchive/find_list_entry.c | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | #include <fnmatch.h> | 8 | #include <fnmatch.h> |
9 | #include "libbb.h" | 9 | #include "libbb.h" |
10 | #include "archive.h" | 10 | #include "bb_archive.h" |
11 | 11 | ||
12 | /* Find a string in a shell pattern list */ | 12 | /* Find a string in a shell pattern list */ |
13 | const llist_t* FAST_FUNC find_list_entry(const llist_t *list, const char *filename) | 13 | const llist_t* FAST_FUNC find_list_entry(const llist_t *list, const char *filename) |
diff --git a/archival/libarchive/get_header_ar.c b/archival/libarchive/get_header_ar.c index df603b111..23c412496 100644 --- a/archival/libarchive/get_header_ar.c +++ b/archival/libarchive/get_header_ar.c | |||
@@ -5,7 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include "libbb.h" | 7 | #include "libbb.h" |
8 | #include "archive.h" | 8 | #include "bb_archive.h" |
9 | #include "ar.h" | 9 | #include "ar.h" |
10 | 10 | ||
11 | static unsigned read_num(const char *str, int base) | 11 | static unsigned read_num(const char *str, int base) |
diff --git a/archival/libarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c index 3d99b492a..1a0058b63 100644 --- a/archival/libarchive/get_header_cpio.c +++ b/archival/libarchive/get_header_cpio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include "libbb.h" | 7 | #include "libbb.h" |
8 | #include "archive.h" | 8 | #include "bb_archive.h" |
9 | 9 | ||
10 | typedef struct hardlinks_t { | 10 | typedef struct hardlinks_t { |
11 | struct hardlinks_t *next; | 11 | struct hardlinks_t *next; |
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 79caff55a..a63c0fb01 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "libbb.h" | 14 | #include "libbb.h" |
15 | #include "archive.h" | 15 | #include "bb_archive.h" |
16 | 16 | ||
17 | typedef uint32_t aliased_uint32_t FIX_ALIASING; | 17 | typedef uint32_t aliased_uint32_t FIX_ALIASING; |
18 | typedef off_t aliased_off_t FIX_ALIASING; | 18 | typedef off_t aliased_off_t FIX_ALIASING; |
@@ -79,10 +79,10 @@ static unsigned long long getOctal(char *str, int len) | |||
79 | * | 79 | * |
80 | * NB: tarballs with NEGATIVE unix times encoded that way were seen! | 80 | * NB: tarballs with NEGATIVE unix times encoded that way were seen! |
81 | */ | 81 | */ |
82 | v = first; | 82 | /* Sign-extend 7bit 'first' to 64bit 'v' (that is, using 6th bit as sign): */ |
83 | /* Sign-extend using 6th bit: */ | 83 | first <<= 1; |
84 | v <<= sizeof(unsigned long long)*8 - 7; | 84 | first >>= 1; /* now 7th bit = 6th bit */ |
85 | v = (long long)v >> (sizeof(unsigned long long)*8 - 7); | 85 | v = first; /* sign-extend 8 bits to 64 */ |
86 | while (--len != 0) | 86 | while (--len != 0) |
87 | v = (v << 8) + (unsigned char) *str++; | 87 | v = (v << 8) + (unsigned char) *str++; |
88 | } | 88 | } |
diff --git a/archival/libarchive/get_header_tar_bz2.c b/archival/libarchive/get_header_tar_bz2.c index 60d32069f..e012dec3b 100644 --- a/archival/libarchive/get_header_tar_bz2.c +++ b/archival/libarchive/get_header_tar_bz2.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | char FAST_FUNC get_header_tar_bz2(archive_handle_t *archive_handle) | 9 | char FAST_FUNC get_header_tar_bz2(archive_handle_t *archive_handle) |
10 | { | 10 | { |
diff --git a/archival/libarchive/get_header_tar_gz.c b/archival/libarchive/get_header_tar_gz.c index 889fed0d9..b9679b0bd 100644 --- a/archival/libarchive/get_header_tar_gz.c +++ b/archival/libarchive/get_header_tar_gz.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) | 9 | char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) |
10 | { | 10 | { |
diff --git a/archival/libarchive/get_header_tar_lzma.c b/archival/libarchive/get_header_tar_lzma.c index da08e0c72..666700729 100644 --- a/archival/libarchive/get_header_tar_lzma.c +++ b/archival/libarchive/get_header_tar_lzma.c | |||
@@ -7,7 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include "libbb.h" | 9 | #include "libbb.h" |
10 | #include "archive.h" | 10 | #include "bb_archive.h" |
11 | 11 | ||
12 | char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle) | 12 | char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle) |
13 | { | 13 | { |
diff --git a/archival/libarchive/header_list.c b/archival/libarchive/header_list.c index c4fc75f38..0621aa406 100644 --- a/archival/libarchive/header_list.c +++ b/archival/libarchive/header_list.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
4 | */ | 4 | */ |
5 | #include "libbb.h" | 5 | #include "libbb.h" |
6 | #include "archive.h" | 6 | #include "bb_archive.h" |
7 | 7 | ||
8 | void FAST_FUNC header_list(const file_header_t *file_header) | 8 | void FAST_FUNC header_list(const file_header_t *file_header) |
9 | { | 9 | { |
diff --git a/archival/libarchive/header_skip.c b/archival/libarchive/header_skip.c index 2bfc5253c..f5987bfe2 100644 --- a/archival/libarchive/header_skip.c +++ b/archival/libarchive/header_skip.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
4 | */ | 4 | */ |
5 | #include "libbb.h" | 5 | #include "libbb.h" |
6 | #include "archive.h" | 6 | #include "bb_archive.h" |
7 | 7 | ||
8 | void FAST_FUNC header_skip(const file_header_t *file_header UNUSED_PARAM) | 8 | void FAST_FUNC header_skip(const file_header_t *file_header UNUSED_PARAM) |
9 | { | 9 | { |
diff --git a/archival/libarchive/header_verbose_list.c b/archival/libarchive/header_verbose_list.c index bc4e4154b..87dd82136 100644 --- a/archival/libarchive/header_verbose_list.c +++ b/archival/libarchive/header_verbose_list.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | void FAST_FUNC header_verbose_list(const file_header_t *file_header) | 9 | void FAST_FUNC header_verbose_list(const file_header_t *file_header) |
10 | { | 10 | { |
diff --git a/archival/libarchive/init_handle.c b/archival/libarchive/init_handle.c index 6644ea13b..cbae06ac3 100644 --- a/archival/libarchive/init_handle.c +++ b/archival/libarchive/init_handle.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | archive_handle_t* FAST_FUNC init_handle(void) | 9 | archive_handle_t* FAST_FUNC init_handle(void) |
10 | { | 10 | { |
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 26ae565f5..aa8c1021c 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | /* transformer(), more than meets the eye */ | 9 | /* transformer(), more than meets the eye */ |
10 | /* | 10 | /* |
diff --git a/archival/libarchive/seek_by_jump.c b/archival/libarchive/seek_by_jump.c index 7c2c52ae1..4fcd99ac8 100644 --- a/archival/libarchive/seek_by_jump.c +++ b/archival/libarchive/seek_by_jump.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | void FAST_FUNC seek_by_jump(int fd, off_t amount) | 9 | void FAST_FUNC seek_by_jump(int fd, off_t amount) |
10 | { | 10 | { |
diff --git a/archival/libarchive/seek_by_read.c b/archival/libarchive/seek_by_read.c index ad931a8de..c0fde9660 100644 --- a/archival/libarchive/seek_by_read.c +++ b/archival/libarchive/seek_by_read.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | /* If we are reading through a pipe, or from stdin then we can't lseek, | 9 | /* If we are reading through a pipe, or from stdin then we can't lseek, |
10 | * we must read and discard the data to skip over it. | 10 | * we must read and discard the data to skip over it. |
diff --git a/archival/libarchive/unpack_ar_archive.c b/archival/libarchive/unpack_ar_archive.c index 18dbfd54d..214d17e23 100644 --- a/archival/libarchive/unpack_ar_archive.c +++ b/archival/libarchive/unpack_ar_archive.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "archive.h" | 7 | #include "bb_archive.h" |
8 | #include "ar.h" | 8 | #include "ar.h" |
9 | 9 | ||
10 | void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive) | 10 | void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive) |
diff --git a/archival/lzop.c b/archival/lzop.c index 1326bd790..7e30091d9 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -51,7 +51,7 @@ | |||
51 | //usage: "\n -F Don't store or verify checksum" | 51 | //usage: "\n -F Don't store or verify checksum" |
52 | 52 | ||
53 | #include "libbb.h" | 53 | #include "libbb.h" |
54 | #include "archive.h" | 54 | #include "bb_archive.h" |
55 | #include "liblzo_interface.h" | 55 | #include "liblzo_interface.h" |
56 | 56 | ||
57 | /* lzo-2.03/src/lzo_ptr.h */ | 57 | /* lzo-2.03/src/lzo_ptr.h */ |
diff --git a/archival/rpm.c b/archival/rpm.c index 8174f4869..089b68983 100644 --- a/archival/rpm.c +++ b/archival/rpm.c | |||
@@ -20,7 +20,7 @@ | |||
20 | //usage: "\n -c List config files" | 20 | //usage: "\n -c List config files" |
21 | 21 | ||
22 | #include "libbb.h" | 22 | #include "libbb.h" |
23 | #include "archive.h" | 23 | #include "bb_archive.h" |
24 | #include "rpm.h" | 24 | #include "rpm.h" |
25 | 25 | ||
26 | #define RPM_CHAR_TYPE 1 | 26 | #define RPM_CHAR_TYPE 1 |
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index ff4a0d1b0..28b43a181 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c | |||
@@ -13,7 +13,7 @@ | |||
13 | //usage: "Output a cpio archive of the rpm file" | 13 | //usage: "Output a cpio archive of the rpm file" |
14 | 14 | ||
15 | #include "libbb.h" | 15 | #include "libbb.h" |
16 | #include "archive.h" | 16 | #include "bb_archive.h" |
17 | #include "rpm.h" | 17 | #include "rpm.h" |
18 | 18 | ||
19 | enum { rpm_fd = STDIN_FILENO }; | 19 | enum { rpm_fd = STDIN_FILENO }; |
diff --git a/archival/tar.c b/archival/tar.c index e7963b0b4..2b752f640 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -44,7 +44,7 @@ | |||
44 | 44 | ||
45 | #include <fnmatch.h> | 45 | #include <fnmatch.h> |
46 | #include "libbb.h" | 46 | #include "libbb.h" |
47 | #include "archive.h" | 47 | #include "bb_archive.h" |
48 | /* FIXME: Stop using this non-standard feature */ | 48 | /* FIXME: Stop using this non-standard feature */ |
49 | #ifndef FNM_LEADING_DIR | 49 | #ifndef FNM_LEADING_DIR |
50 | # define FNM_LEADING_DIR 0 | 50 | # define FNM_LEADING_DIR 0 |
diff --git a/archival/unzip.c b/archival/unzip.c index 4fa729326..3a11f78a5 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -32,7 +32,7 @@ | |||
32 | //usage: "\n -d DIR Extract files into DIR" | 32 | //usage: "\n -d DIR Extract files into DIR" |
33 | 33 | ||
34 | #include "libbb.h" | 34 | #include "libbb.h" |
35 | #include "archive.h" | 35 | #include "bb_archive.h" |
36 | 36 | ||
37 | enum { | 37 | enum { |
38 | #if BB_BIG_ENDIAN | 38 | #if BB_BIG_ENDIAN |
@@ -235,7 +235,7 @@ static void unzip_create_leading_dirs(const char *fn) | |||
235 | /* Create all leading directories */ | 235 | /* Create all leading directories */ |
236 | char *name = xstrdup(fn); | 236 | char *name = xstrdup(fn); |
237 | if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) { | 237 | if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) { |
238 | bb_error_msg_and_die("exiting"); /* bb_make_directory is noisy */ | 238 | xfunc_die(); /* bb_make_directory is noisy */ |
239 | } | 239 | } |
240 | free(name); | 240 | free(name); |
241 | } | 241 | } |
@@ -595,7 +595,7 @@ int unzip_main(int argc, char **argv) | |||
595 | } | 595 | } |
596 | unzip_create_leading_dirs(dst_fn); | 596 | unzip_create_leading_dirs(dst_fn); |
597 | if (bb_make_directory(dst_fn, dir_mode, 0)) { | 597 | if (bb_make_directory(dst_fn, dir_mode, 0)) { |
598 | bb_error_msg_and_die("exiting"); | 598 | xfunc_die(); |
599 | } | 599 | } |
600 | } else { | 600 | } else { |
601 | if (!S_ISDIR(stat_buf.st_mode)) { | 601 | if (!S_ISDIR(stat_buf.st_mode)) { |
@@ -619,6 +619,7 @@ int unzip_main(int argc, char **argv) | |||
619 | i = 'y'; | 619 | i = 'y'; |
620 | } else { | 620 | } else { |
621 | printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); | 621 | printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); |
622 | fflush_all(); | ||
622 | if (!fgets(key_buf, sizeof(key_buf), stdin)) { | 623 | if (!fgets(key_buf, sizeof(key_buf), stdin)) { |
623 | bb_perror_msg_and_die("can't read input"); | 624 | bb_perror_msg_and_die("can't read input"); |
624 | } | 625 | } |
diff --git a/configs/TEST_nommu_defconfig b/configs/TEST_nommu_defconfig index 905f65296..15e12b1d2 100644 --- a/configs/TEST_nommu_defconfig +++ b/configs/TEST_nommu_defconfig | |||
@@ -79,7 +79,7 @@ CONFIG_PREFIX="./_install" | |||
79 | # Busybox Library Tuning | 79 | # Busybox Library Tuning |
80 | # | 80 | # |
81 | CONFIG_PASSWORD_MINLEN=6 | 81 | CONFIG_PASSWORD_MINLEN=6 |
82 | CONFIG_MD5_SIZE_VS_SPEED=2 | 82 | CONFIG_MD5_SMALL=1 |
83 | CONFIG_FEATURE_FAST_TOP=y | 83 | CONFIG_FEATURE_FAST_TOP=y |
84 | CONFIG_FEATURE_ETC_NETWORKS=y | 84 | CONFIG_FEATURE_ETC_NETWORKS=y |
85 | CONFIG_FEATURE_EDITING=y | 85 | CONFIG_FEATURE_EDITING=y |
diff --git a/configs/TEST_noprintf_defconfig b/configs/TEST_noprintf_defconfig index b72e12856..f4338df71 100644 --- a/configs/TEST_noprintf_defconfig +++ b/configs/TEST_noprintf_defconfig | |||
@@ -89,7 +89,7 @@ CONFIG_PREFIX="./_install" | |||
89 | # Busybox Library Tuning | 89 | # Busybox Library Tuning |
90 | # | 90 | # |
91 | CONFIG_PASSWORD_MINLEN=6 | 91 | CONFIG_PASSWORD_MINLEN=6 |
92 | CONFIG_MD5_SIZE_VS_SPEED=2 | 92 | CONFIG_MD5_SMALL=1 |
93 | CONFIG_FEATURE_FAST_TOP=y | 93 | CONFIG_FEATURE_FAST_TOP=y |
94 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 94 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
95 | CONFIG_FEATURE_EDITING=y | 95 | CONFIG_FEATURE_EDITING=y |
diff --git a/configs/TEST_rh9_defconfig b/configs/TEST_rh9_defconfig index 23094e391..193d8f615 100644 --- a/configs/TEST_rh9_defconfig +++ b/configs/TEST_rh9_defconfig | |||
@@ -88,7 +88,7 @@ CONFIG_PREFIX="./_install" | |||
88 | # Busybox Library Tuning | 88 | # Busybox Library Tuning |
89 | # | 89 | # |
90 | CONFIG_PASSWORD_MINLEN=6 | 90 | CONFIG_PASSWORD_MINLEN=6 |
91 | CONFIG_MD5_SIZE_VS_SPEED=2 | 91 | CONFIG_MD5_SMALL=1 |
92 | CONFIG_FEATURE_FAST_TOP=y | 92 | CONFIG_FEATURE_FAST_TOP=y |
93 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 93 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
94 | CONFIG_FEATURE_EDITING=y | 94 | CONFIG_FEATURE_EDITING=y |
diff --git a/configs/android2_defconfig b/configs/android2_defconfig new file mode 100644 index 000000000..b5166e0fc --- /dev/null +++ b/configs/android2_defconfig | |||
@@ -0,0 +1,997 @@ | |||
1 | # Run "make android2_defconfig", then "make". | ||
2 | # | ||
3 | # Tested with the standalone toolchain from ndk r6: | ||
4 | # android-ndk-r6/build/tools/make-standalone-toolchain.sh --platform=android-8 | ||
5 | # | ||
6 | CONFIG_HAVE_DOT_CONFIG=y | ||
7 | |||
8 | # | ||
9 | # Busybox Settings | ||
10 | # | ||
11 | |||
12 | # | ||
13 | # General Configuration | ||
14 | # | ||
15 | # CONFIG_DESKTOP is not set | ||
16 | # CONFIG_EXTRA_COMPAT is not set | ||
17 | # CONFIG_INCLUDE_SUSv2 is not set | ||
18 | # CONFIG_USE_PORTABLE_CODE is not set | ||
19 | CONFIG_PLATFORM_LINUX=y | ||
20 | CONFIG_FEATURE_BUFFERS_USE_MALLOC=y | ||
21 | # CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set | ||
22 | # CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set | ||
23 | # CONFIG_SHOW_USAGE is not set | ||
24 | # CONFIG_FEATURE_VERBOSE_USAGE is not set | ||
25 | # CONFIG_FEATURE_COMPRESS_USAGE is not set | ||
26 | # CONFIG_FEATURE_INSTALLER is not set | ||
27 | # CONFIG_INSTALL_NO_USR is not set | ||
28 | # CONFIG_LOCALE_SUPPORT is not set | ||
29 | # CONFIG_UNICODE_SUPPORT is not set | ||
30 | # CONFIG_UNICODE_USING_LOCALE is not set | ||
31 | # CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set | ||
32 | CONFIG_SUBST_WCHAR=0 | ||
33 | CONFIG_LAST_SUPPORTED_WCHAR=0 | ||
34 | # CONFIG_UNICODE_COMBINING_WCHARS is not set | ||
35 | # CONFIG_UNICODE_WIDE_WCHARS is not set | ||
36 | # CONFIG_UNICODE_BIDI_SUPPORT is not set | ||
37 | # CONFIG_UNICODE_NEUTRAL_TABLE is not set | ||
38 | # CONFIG_UNICODE_PRESERVE_BROKEN is not set | ||
39 | # CONFIG_LONG_OPTS is not set | ||
40 | # CONFIG_FEATURE_DEVPTS is not set | ||
41 | # CONFIG_FEATURE_CLEAN_UP is not set | ||
42 | # CONFIG_FEATURE_UTMP is not set | ||
43 | # CONFIG_FEATURE_WTMP is not set | ||
44 | # CONFIG_FEATURE_PIDFILE is not set | ||
45 | # CONFIG_FEATURE_SUID is not set | ||
46 | # CONFIG_FEATURE_SUID_CONFIG is not set | ||
47 | # CONFIG_FEATURE_SUID_CONFIG_QUIET is not set | ||
48 | # CONFIG_SELINUX is not set | ||
49 | # CONFIG_FEATURE_PREFER_APPLETS is not set | ||
50 | CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" | ||
51 | CONFIG_FEATURE_SYSLOG=y | ||
52 | # CONFIG_FEATURE_HAVE_RPC is not set | ||
53 | |||
54 | # | ||
55 | # Build Options | ||
56 | # | ||
57 | # CONFIG_STATIC is not set | ||
58 | # CONFIG_PIE is not set | ||
59 | # CONFIG_NOMMU is not set | ||
60 | # CONFIG_BUILD_LIBBUSYBOX is not set | ||
61 | # CONFIG_FEATURE_INDIVIDUAL is not set | ||
62 | # CONFIG_FEATURE_SHARED_BUSYBOX is not set | ||
63 | # CONFIG_LFS is not set | ||
64 | CONFIG_CROSS_COMPILER_PREFIX="arm-linux-androideabi-" | ||
65 | CONFIG_EXTRA_CFLAGS="" | ||
66 | |||
67 | # | ||
68 | # Debugging Options | ||
69 | # | ||
70 | # CONFIG_DEBUG is not set | ||
71 | # CONFIG_DEBUG_PESSIMIZE is not set | ||
72 | # CONFIG_WERROR is not set | ||
73 | CONFIG_NO_DEBUG_LIB=y | ||
74 | # CONFIG_DMALLOC is not set | ||
75 | # CONFIG_EFENCE is not set | ||
76 | |||
77 | # | ||
78 | # Installation Options ("make install" behavior) | ||
79 | # | ||
80 | CONFIG_INSTALL_APPLET_SYMLINKS=y | ||
81 | # CONFIG_INSTALL_APPLET_HARDLINKS is not set | ||
82 | # CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set | ||
83 | # CONFIG_INSTALL_APPLET_DONT is not set | ||
84 | # CONFIG_INSTALL_SH_APPLET_SYMLINK is not set | ||
85 | # CONFIG_INSTALL_SH_APPLET_HARDLINK is not set | ||
86 | # CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set | ||
87 | CONFIG_PREFIX="./_install" | ||
88 | |||
89 | # | ||
90 | # Busybox Library Tuning | ||
91 | # | ||
92 | # CONFIG_FEATURE_SYSTEMD is not set | ||
93 | # CONFIG_FEATURE_RTMINMAX is not set | ||
94 | CONFIG_PASSWORD_MINLEN=6 | ||
95 | CONFIG_MD5_SMALL=1 | ||
96 | # CONFIG_FEATURE_FAST_TOP is not set | ||
97 | # CONFIG_FEATURE_ETC_NETWORKS is not set | ||
98 | CONFIG_FEATURE_USE_TERMIOS=y | ||
99 | # CONFIG_FEATURE_EDITING is not set | ||
100 | CONFIG_FEATURE_EDITING_MAX_LEN=0 | ||
101 | # CONFIG_FEATURE_EDITING_VI is not set | ||
102 | CONFIG_FEATURE_EDITING_HISTORY=0 | ||
103 | # CONFIG_FEATURE_EDITING_SAVEHISTORY is not set | ||
104 | # CONFIG_FEATURE_TAB_COMPLETION is not set | ||
105 | # CONFIG_FEATURE_USERNAME_COMPLETION is not set | ||
106 | # CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set | ||
107 | # CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set | ||
108 | # CONFIG_FEATURE_NON_POSIX_CP is not set | ||
109 | # CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set | ||
110 | CONFIG_FEATURE_COPYBUF_KB=4 | ||
111 | # CONFIG_FEATURE_SKIP_ROOTFS is not set | ||
112 | # CONFIG_MONOTONIC_SYSCALL is not set | ||
113 | # CONFIG_IOCTL_HEX2STR_ERROR is not set | ||
114 | # CONFIG_FEATURE_HWIB is not set | ||
115 | |||
116 | # | ||
117 | # Applets | ||
118 | # | ||
119 | |||
120 | # | ||
121 | # Archival Utilities | ||
122 | # | ||
123 | CONFIG_FEATURE_SEAMLESS_XZ=y | ||
124 | CONFIG_FEATURE_SEAMLESS_LZMA=y | ||
125 | CONFIG_FEATURE_SEAMLESS_BZ2=y | ||
126 | CONFIG_FEATURE_SEAMLESS_GZ=y | ||
127 | CONFIG_FEATURE_SEAMLESS_Z=y | ||
128 | CONFIG_AR=y | ||
129 | CONFIG_FEATURE_AR_LONG_FILENAMES=y | ||
130 | CONFIG_FEATURE_AR_CREATE=y | ||
131 | CONFIG_BUNZIP2=y | ||
132 | CONFIG_BZIP2=y | ||
133 | CONFIG_CPIO=y | ||
134 | CONFIG_FEATURE_CPIO_O=y | ||
135 | CONFIG_FEATURE_CPIO_P=y | ||
136 | CONFIG_DPKG=y | ||
137 | CONFIG_DPKG_DEB=y | ||
138 | # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set | ||
139 | CONFIG_GUNZIP=y | ||
140 | CONFIG_GZIP=y | ||
141 | # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set | ||
142 | CONFIG_LZOP=y | ||
143 | CONFIG_LZOP_COMPR_HIGH=y | ||
144 | CONFIG_RPM2CPIO=y | ||
145 | CONFIG_RPM=y | ||
146 | CONFIG_TAR=y | ||
147 | CONFIG_FEATURE_TAR_CREATE=y | ||
148 | CONFIG_FEATURE_TAR_AUTODETECT=y | ||
149 | CONFIG_FEATURE_TAR_FROM=y | ||
150 | CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y | ||
151 | CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y | ||
152 | CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y | ||
153 | # CONFIG_FEATURE_TAR_LONG_OPTIONS is not set | ||
154 | # CONFIG_FEATURE_TAR_TO_COMMAND is not set | ||
155 | CONFIG_FEATURE_TAR_UNAME_GNAME=y | ||
156 | CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y | ||
157 | # CONFIG_FEATURE_TAR_SELINUX is not set | ||
158 | CONFIG_UNCOMPRESS=y | ||
159 | CONFIG_UNLZMA=y | ||
160 | CONFIG_FEATURE_LZMA_FAST=y | ||
161 | CONFIG_LZMA=y | ||
162 | CONFIG_UNXZ=y | ||
163 | CONFIG_XZ=y | ||
164 | CONFIG_UNZIP=y | ||
165 | |||
166 | # | ||
167 | # Coreutils | ||
168 | # | ||
169 | CONFIG_BASENAME=y | ||
170 | CONFIG_CAT=y | ||
171 | # CONFIG_DATE is not set | ||
172 | # CONFIG_FEATURE_DATE_ISOFMT is not set | ||
173 | # CONFIG_FEATURE_DATE_NANO is not set | ||
174 | # CONFIG_FEATURE_DATE_COMPAT is not set | ||
175 | # CONFIG_ID is not set | ||
176 | # CONFIG_GROUPS is not set | ||
177 | CONFIG_TEST=y | ||
178 | CONFIG_FEATURE_TEST_64=y | ||
179 | CONFIG_TOUCH=y | ||
180 | CONFIG_TR=y | ||
181 | CONFIG_FEATURE_TR_CLASSES=y | ||
182 | CONFIG_FEATURE_TR_EQUIV=y | ||
183 | CONFIG_BASE64=y | ||
184 | CONFIG_CAL=y | ||
185 | CONFIG_CATV=y | ||
186 | CONFIG_CHGRP=y | ||
187 | CONFIG_CHMOD=y | ||
188 | CONFIG_CHOWN=y | ||
189 | # CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set | ||
190 | CONFIG_CHROOT=y | ||
191 | CONFIG_CKSUM=y | ||
192 | CONFIG_COMM=y | ||
193 | CONFIG_CP=y | ||
194 | # CONFIG_FEATURE_CP_LONG_OPTIONS is not set | ||
195 | CONFIG_CUT=y | ||
196 | CONFIG_DD=y | ||
197 | CONFIG_FEATURE_DD_SIGNAL_HANDLING=y | ||
198 | CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y | ||
199 | CONFIG_FEATURE_DD_IBS_OBS=y | ||
200 | # CONFIG_DF is not set | ||
201 | # CONFIG_FEATURE_DF_FANCY is not set | ||
202 | CONFIG_DIRNAME=y | ||
203 | CONFIG_DOS2UNIX=y | ||
204 | CONFIG_UNIX2DOS=y | ||
205 | CONFIG_DU=y | ||
206 | CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y | ||
207 | CONFIG_ECHO=y | ||
208 | CONFIG_FEATURE_FANCY_ECHO=y | ||
209 | # CONFIG_ENV is not set | ||
210 | # CONFIG_FEATURE_ENV_LONG_OPTIONS is not set | ||
211 | CONFIG_EXPAND=y | ||
212 | # CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set | ||
213 | # CONFIG_EXPR is not set | ||
214 | # CONFIG_EXPR_MATH_SUPPORT_64 is not set | ||
215 | CONFIG_FALSE=y | ||
216 | CONFIG_FOLD=y | ||
217 | # CONFIG_FSYNC is not set | ||
218 | CONFIG_HEAD=y | ||
219 | CONFIG_FEATURE_FANCY_HEAD=y | ||
220 | # CONFIG_HOSTID is not set | ||
221 | CONFIG_INSTALL=y | ||
222 | # CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set | ||
223 | CONFIG_LN=y | ||
224 | # CONFIG_LOGNAME is not set | ||
225 | CONFIG_LS=y | ||
226 | CONFIG_FEATURE_LS_FILETYPES=y | ||
227 | CONFIG_FEATURE_LS_FOLLOWLINKS=y | ||
228 | CONFIG_FEATURE_LS_RECURSIVE=y | ||
229 | CONFIG_FEATURE_LS_SORTFILES=y | ||
230 | CONFIG_FEATURE_LS_TIMESTAMPS=y | ||
231 | CONFIG_FEATURE_LS_USERNAME=y | ||
232 | # CONFIG_FEATURE_LS_COLOR is not set | ||
233 | # CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set | ||
234 | CONFIG_MD5SUM=y | ||
235 | CONFIG_MKDIR=y | ||
236 | # CONFIG_FEATURE_MKDIR_LONG_OPTIONS is not set | ||
237 | CONFIG_MKFIFO=y | ||
238 | CONFIG_MKNOD=y | ||
239 | CONFIG_MV=y | ||
240 | # CONFIG_FEATURE_MV_LONG_OPTIONS is not set | ||
241 | CONFIG_NICE=y | ||
242 | CONFIG_NOHUP=y | ||
243 | CONFIG_OD=y | ||
244 | CONFIG_PRINTENV=y | ||
245 | CONFIG_PRINTF=y | ||
246 | CONFIG_PWD=y | ||
247 | CONFIG_READLINK=y | ||
248 | CONFIG_FEATURE_READLINK_FOLLOW=y | ||
249 | CONFIG_REALPATH=y | ||
250 | CONFIG_RM=y | ||
251 | CONFIG_RMDIR=y | ||
252 | # CONFIG_FEATURE_RMDIR_LONG_OPTIONS is not set | ||
253 | CONFIG_SEQ=y | ||
254 | CONFIG_SHA1SUM=y | ||
255 | CONFIG_SHA256SUM=y | ||
256 | CONFIG_SHA512SUM=y | ||
257 | CONFIG_SLEEP=y | ||
258 | CONFIG_FEATURE_FANCY_SLEEP=y | ||
259 | CONFIG_FEATURE_FLOAT_SLEEP=y | ||
260 | CONFIG_SORT=y | ||
261 | CONFIG_FEATURE_SORT_BIG=y | ||
262 | CONFIG_SPLIT=y | ||
263 | CONFIG_FEATURE_SPLIT_FANCY=y | ||
264 | # CONFIG_STAT is not set | ||
265 | # CONFIG_FEATURE_STAT_FORMAT is not set | ||
266 | CONFIG_STTY=y | ||
267 | CONFIG_SUM=y | ||
268 | CONFIG_SYNC=y | ||
269 | CONFIG_TAC=y | ||
270 | CONFIG_TAIL=y | ||
271 | CONFIG_FEATURE_FANCY_TAIL=y | ||
272 | CONFIG_TEE=y | ||
273 | CONFIG_FEATURE_TEE_USE_BLOCK_IO=y | ||
274 | CONFIG_TRUE=y | ||
275 | # CONFIG_TTY is not set | ||
276 | CONFIG_UNAME=y | ||
277 | CONFIG_UNEXPAND=y | ||
278 | # CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set | ||
279 | CONFIG_UNIQ=y | ||
280 | # CONFIG_USLEEP is not set | ||
281 | CONFIG_UUDECODE=y | ||
282 | CONFIG_UUENCODE=y | ||
283 | CONFIG_WC=y | ||
284 | CONFIG_FEATURE_WC_LARGE=y | ||
285 | # CONFIG_WHO is not set | ||
286 | CONFIG_WHOAMI=y | ||
287 | CONFIG_YES=y | ||
288 | |||
289 | # | ||
290 | # Common options for cp and mv | ||
291 | # | ||
292 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | ||
293 | |||
294 | # | ||
295 | # Common options for ls, more and telnet | ||
296 | # | ||
297 | CONFIG_FEATURE_AUTOWIDTH=y | ||
298 | |||
299 | # | ||
300 | # Common options for df, du, ls | ||
301 | # | ||
302 | CONFIG_FEATURE_HUMAN_READABLE=y | ||
303 | |||
304 | # | ||
305 | # Common options for md5sum, sha1sum, sha256sum, sha512sum | ||
306 | # | ||
307 | CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y | ||
308 | |||
309 | # | ||
310 | # Console Utilities | ||
311 | # | ||
312 | CONFIG_CHVT=y | ||
313 | CONFIG_FGCONSOLE=y | ||
314 | CONFIG_CLEAR=y | ||
315 | CONFIG_DEALLOCVT=y | ||
316 | CONFIG_DUMPKMAP=y | ||
317 | # CONFIG_KBD_MODE is not set | ||
318 | # CONFIG_LOADFONT is not set | ||
319 | CONFIG_LOADKMAP=y | ||
320 | CONFIG_OPENVT=y | ||
321 | CONFIG_RESET=y | ||
322 | CONFIG_RESIZE=y | ||
323 | CONFIG_FEATURE_RESIZE_PRINT=y | ||
324 | CONFIG_SETCONSOLE=y | ||
325 | # CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set | ||
326 | # CONFIG_SETFONT is not set | ||
327 | # CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set | ||
328 | CONFIG_DEFAULT_SETFONT_DIR="" | ||
329 | CONFIG_SETKEYCODES=y | ||
330 | CONFIG_SETLOGCONS=y | ||
331 | CONFIG_SHOWKEY=y | ||
332 | # CONFIG_FEATURE_LOADFONT_PSF2 is not set | ||
333 | # CONFIG_FEATURE_LOADFONT_RAW is not set | ||
334 | |||
335 | # | ||
336 | # Debian Utilities | ||
337 | # | ||
338 | CONFIG_MKTEMP=y | ||
339 | CONFIG_PIPE_PROGRESS=y | ||
340 | CONFIG_RUN_PARTS=y | ||
341 | # CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set | ||
342 | CONFIG_FEATURE_RUN_PARTS_FANCY=y | ||
343 | CONFIG_START_STOP_DAEMON=y | ||
344 | CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y | ||
345 | # CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set | ||
346 | CONFIG_WHICH=y | ||
347 | |||
348 | # | ||
349 | # Editors | ||
350 | # | ||
351 | CONFIG_PATCH=y | ||
352 | # CONFIG_VI is not set | ||
353 | CONFIG_FEATURE_VI_MAX_LEN=0 | ||
354 | # CONFIG_FEATURE_VI_8BIT is not set | ||
355 | # CONFIG_FEATURE_VI_COLON is not set | ||
356 | # CONFIG_FEATURE_VI_YANKMARK is not set | ||
357 | # CONFIG_FEATURE_VI_SEARCH is not set | ||
358 | # CONFIG_FEATURE_VI_REGEX_SEARCH is not set | ||
359 | # CONFIG_FEATURE_VI_USE_SIGNALS is not set | ||
360 | # CONFIG_FEATURE_VI_DOT_CMD is not set | ||
361 | # CONFIG_FEATURE_VI_READONLY is not set | ||
362 | # CONFIG_FEATURE_VI_SETOPTS is not set | ||
363 | # CONFIG_FEATURE_VI_SET is not set | ||
364 | # CONFIG_FEATURE_VI_WIN_RESIZE is not set | ||
365 | # CONFIG_FEATURE_VI_ASK_TERMINAL is not set | ||
366 | # CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set | ||
367 | # CONFIG_AWK is not set | ||
368 | # CONFIG_FEATURE_AWK_LIBM is not set | ||
369 | CONFIG_CMP=y | ||
370 | CONFIG_DIFF=y | ||
371 | # CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set | ||
372 | CONFIG_FEATURE_DIFF_DIR=y | ||
373 | # CONFIG_ED is not set | ||
374 | # CONFIG_SED is not set | ||
375 | # CONFIG_FEATURE_ALLOW_EXEC is not set | ||
376 | |||
377 | # | ||
378 | # Finding Utilities | ||
379 | # | ||
380 | # CONFIG_FIND is not set | ||
381 | # CONFIG_FEATURE_FIND_PRINT0 is not set | ||
382 | # CONFIG_FEATURE_FIND_MTIME is not set | ||
383 | # CONFIG_FEATURE_FIND_MMIN is not set | ||
384 | # CONFIG_FEATURE_FIND_PERM is not set | ||
385 | # CONFIG_FEATURE_FIND_TYPE is not set | ||
386 | # CONFIG_FEATURE_FIND_XDEV is not set | ||
387 | # CONFIG_FEATURE_FIND_MAXDEPTH is not set | ||
388 | # CONFIG_FEATURE_FIND_NEWER is not set | ||
389 | # CONFIG_FEATURE_FIND_INUM is not set | ||
390 | # CONFIG_FEATURE_FIND_EXEC is not set | ||
391 | # CONFIG_FEATURE_FIND_USER is not set | ||
392 | # CONFIG_FEATURE_FIND_GROUP is not set | ||
393 | # CONFIG_FEATURE_FIND_NOT is not set | ||
394 | # CONFIG_FEATURE_FIND_DEPTH is not set | ||
395 | # CONFIG_FEATURE_FIND_PAREN is not set | ||
396 | # CONFIG_FEATURE_FIND_SIZE is not set | ||
397 | # CONFIG_FEATURE_FIND_PRUNE is not set | ||
398 | # CONFIG_FEATURE_FIND_DELETE is not set | ||
399 | # CONFIG_FEATURE_FIND_PATH is not set | ||
400 | # CONFIG_FEATURE_FIND_REGEX is not set | ||
401 | # CONFIG_FEATURE_FIND_CONTEXT is not set | ||
402 | # CONFIG_FEATURE_FIND_LINKS is not set | ||
403 | # CONFIG_GREP is not set | ||
404 | # CONFIG_FEATURE_GREP_EGREP_ALIAS is not set | ||
405 | # CONFIG_FEATURE_GREP_FGREP_ALIAS is not set | ||
406 | # CONFIG_FEATURE_GREP_CONTEXT is not set | ||
407 | CONFIG_XARGS=y | ||
408 | CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y | ||
409 | CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y | ||
410 | CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y | ||
411 | CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y | ||
412 | |||
413 | # | ||
414 | # Init Utilities | ||
415 | # | ||
416 | # CONFIG_BOOTCHARTD is not set | ||
417 | # CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set | ||
418 | # CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set | ||
419 | CONFIG_HALT=y | ||
420 | # CONFIG_FEATURE_CALL_TELINIT is not set | ||
421 | CONFIG_TELINIT_PATH="" | ||
422 | CONFIG_INIT=y | ||
423 | CONFIG_FEATURE_USE_INITTAB=y | ||
424 | # CONFIG_FEATURE_KILL_REMOVED is not set | ||
425 | CONFIG_FEATURE_KILL_DELAY=0 | ||
426 | CONFIG_FEATURE_INIT_SCTTY=y | ||
427 | CONFIG_FEATURE_INIT_SYSLOG=y | ||
428 | CONFIG_FEATURE_EXTRA_QUIET=y | ||
429 | CONFIG_FEATURE_INIT_COREDUMPS=y | ||
430 | CONFIG_FEATURE_INITRD=y | ||
431 | CONFIG_INIT_TERMINAL_TYPE="linux" | ||
432 | CONFIG_MESG=y | ||
433 | CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y | ||
434 | |||
435 | # | ||
436 | # Login/Password Management Utilities | ||
437 | # | ||
438 | # CONFIG_ADD_SHELL is not set | ||
439 | # CONFIG_REMOVE_SHELL is not set | ||
440 | # CONFIG_FEATURE_SHADOWPASSWDS is not set | ||
441 | # CONFIG_USE_BB_PWD_GRP is not set | ||
442 | # CONFIG_USE_BB_SHADOW is not set | ||
443 | # CONFIG_USE_BB_CRYPT is not set | ||
444 | # CONFIG_USE_BB_CRYPT_SHA is not set | ||
445 | # CONFIG_ADDUSER is not set | ||
446 | # CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set | ||
447 | # CONFIG_FEATURE_CHECK_NAMES is not set | ||
448 | CONFIG_FIRST_SYSTEM_ID=0 | ||
449 | CONFIG_LAST_SYSTEM_ID=0 | ||
450 | # CONFIG_ADDGROUP is not set | ||
451 | # CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set | ||
452 | # CONFIG_FEATURE_ADDUSER_TO_GROUP is not set | ||
453 | # CONFIG_DELUSER is not set | ||
454 | # CONFIG_DELGROUP is not set | ||
455 | # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set | ||
456 | # CONFIG_GETTY is not set | ||
457 | # CONFIG_LOGIN is not set | ||
458 | # CONFIG_PAM is not set | ||
459 | # CONFIG_LOGIN_SCRIPTS is not set | ||
460 | # CONFIG_FEATURE_NOLOGIN is not set | ||
461 | # CONFIG_FEATURE_SECURETTY is not set | ||
462 | # CONFIG_PASSWD is not set | ||
463 | # CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set | ||
464 | # CONFIG_CRYPTPW is not set | ||
465 | # CONFIG_CHPASSWD is not set | ||
466 | # CONFIG_SU is not set | ||
467 | # CONFIG_FEATURE_SU_SYSLOG is not set | ||
468 | # CONFIG_FEATURE_SU_CHECKS_SHELLS is not set | ||
469 | # CONFIG_SULOGIN is not set | ||
470 | # CONFIG_VLOCK is not set | ||
471 | |||
472 | # | ||
473 | # Linux Ext2 FS Progs | ||
474 | # | ||
475 | CONFIG_CHATTR=y | ||
476 | # CONFIG_FSCK is not set | ||
477 | CONFIG_LSATTR=y | ||
478 | CONFIG_TUNE2FS=y | ||
479 | |||
480 | # | ||
481 | # Linux Module Utilities | ||
482 | # | ||
483 | CONFIG_MODINFO=y | ||
484 | CONFIG_MODPROBE_SMALL=y | ||
485 | CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE=y | ||
486 | CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y | ||
487 | # CONFIG_INSMOD is not set | ||
488 | # CONFIG_RMMOD is not set | ||
489 | # CONFIG_LSMOD is not set | ||
490 | # CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set | ||
491 | # CONFIG_MODPROBE is not set | ||
492 | # CONFIG_FEATURE_MODPROBE_BLACKLIST is not set | ||
493 | # CONFIG_DEPMOD is not set | ||
494 | |||
495 | # | ||
496 | # Options common to multiple modutils | ||
497 | # | ||
498 | # CONFIG_FEATURE_2_4_MODULES is not set | ||
499 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set | ||
500 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set | ||
501 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set | ||
502 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set | ||
503 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set | ||
504 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set | ||
505 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set | ||
506 | # CONFIG_FEATURE_MODUTILS_ALIAS is not set | ||
507 | # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set | ||
508 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" | ||
509 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | ||
510 | |||
511 | # | ||
512 | # Linux System Utilities | ||
513 | # | ||
514 | CONFIG_BLOCKDEV=y | ||
515 | CONFIG_REV=y | ||
516 | # CONFIG_ACPID is not set | ||
517 | # CONFIG_FEATURE_ACPID_COMPAT is not set | ||
518 | CONFIG_BLKID=y | ||
519 | # CONFIG_FEATURE_BLKID_TYPE is not set | ||
520 | CONFIG_DMESG=y | ||
521 | CONFIG_FEATURE_DMESG_PRETTY=y | ||
522 | CONFIG_FBSET=y | ||
523 | CONFIG_FEATURE_FBSET_FANCY=y | ||
524 | CONFIG_FEATURE_FBSET_READMODE=y | ||
525 | CONFIG_FDFLUSH=y | ||
526 | CONFIG_FDFORMAT=y | ||
527 | CONFIG_FDISK=y | ||
528 | CONFIG_FDISK_SUPPORT_LARGE_DISKS=y | ||
529 | CONFIG_FEATURE_FDISK_WRITABLE=y | ||
530 | # CONFIG_FEATURE_AIX_LABEL is not set | ||
531 | # CONFIG_FEATURE_SGI_LABEL is not set | ||
532 | # CONFIG_FEATURE_SUN_LABEL is not set | ||
533 | # CONFIG_FEATURE_OSF_LABEL is not set | ||
534 | # CONFIG_FEATURE_GPT_LABEL is not set | ||
535 | CONFIG_FEATURE_FDISK_ADVANCED=y | ||
536 | CONFIG_FINDFS=y | ||
537 | CONFIG_FLOCK=y | ||
538 | CONFIG_FREERAMDISK=y | ||
539 | # CONFIG_FSCK_MINIX is not set | ||
540 | # CONFIG_MKFS_EXT2 is not set | ||
541 | # CONFIG_MKFS_MINIX is not set | ||
542 | # CONFIG_FEATURE_MINIX2 is not set | ||
543 | # CONFIG_MKFS_REISER is not set | ||
544 | # CONFIG_MKFS_VFAT is not set | ||
545 | CONFIG_GETOPT=y | ||
546 | CONFIG_FEATURE_GETOPT_LONG=y | ||
547 | CONFIG_HEXDUMP=y | ||
548 | CONFIG_FEATURE_HEXDUMP_REVERSE=y | ||
549 | CONFIG_HD=y | ||
550 | # CONFIG_HWCLOCK is not set | ||
551 | # CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set | ||
552 | # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set | ||
553 | # CONFIG_IPCRM is not set | ||
554 | # CONFIG_IPCS is not set | ||
555 | CONFIG_LOSETUP=y | ||
556 | CONFIG_LSPCI=y | ||
557 | CONFIG_LSUSB=y | ||
558 | # CONFIG_MDEV is not set | ||
559 | # CONFIG_FEATURE_MDEV_CONF is not set | ||
560 | # CONFIG_FEATURE_MDEV_RENAME is not set | ||
561 | # CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set | ||
562 | # CONFIG_FEATURE_MDEV_EXEC is not set | ||
563 | # CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set | ||
564 | CONFIG_MKSWAP=y | ||
565 | CONFIG_FEATURE_MKSWAP_UUID=y | ||
566 | CONFIG_MORE=y | ||
567 | # CONFIG_MOUNT is not set | ||
568 | # CONFIG_FEATURE_MOUNT_FAKE is not set | ||
569 | # CONFIG_FEATURE_MOUNT_VERBOSE is not set | ||
570 | # CONFIG_FEATURE_MOUNT_HELPERS is not set | ||
571 | # CONFIG_FEATURE_MOUNT_LABEL is not set | ||
572 | # CONFIG_FEATURE_MOUNT_NFS is not set | ||
573 | # CONFIG_FEATURE_MOUNT_CIFS is not set | ||
574 | # CONFIG_FEATURE_MOUNT_FLAGS is not set | ||
575 | # CONFIG_FEATURE_MOUNT_FSTAB is not set | ||
576 | # CONFIG_PIVOT_ROOT is not set | ||
577 | # CONFIG_RDATE is not set | ||
578 | CONFIG_RDEV=y | ||
579 | CONFIG_READPROFILE=y | ||
580 | CONFIG_RTCWAKE=y | ||
581 | CONFIG_SCRIPT=y | ||
582 | CONFIG_SCRIPTREPLAY=y | ||
583 | # CONFIG_SETARCH is not set | ||
584 | # CONFIG_SWAPONOFF is not set | ||
585 | # CONFIG_FEATURE_SWAPON_PRI is not set | ||
586 | # CONFIG_SWITCH_ROOT is not set | ||
587 | # CONFIG_UMOUNT is not set | ||
588 | # CONFIG_FEATURE_UMOUNT_ALL is not set | ||
589 | # CONFIG_FEATURE_MOUNT_LOOP is not set | ||
590 | # CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set | ||
591 | # CONFIG_FEATURE_MTAB_SUPPORT is not set | ||
592 | CONFIG_VOLUMEID=y | ||
593 | |||
594 | # | ||
595 | # Filesystem/Volume identification | ||
596 | # | ||
597 | CONFIG_FEATURE_VOLUMEID_EXT=y | ||
598 | CONFIG_FEATURE_VOLUMEID_BTRFS=y | ||
599 | CONFIG_FEATURE_VOLUMEID_REISERFS=y | ||
600 | CONFIG_FEATURE_VOLUMEID_FAT=y | ||
601 | CONFIG_FEATURE_VOLUMEID_HFS=y | ||
602 | CONFIG_FEATURE_VOLUMEID_JFS=y | ||
603 | CONFIG_FEATURE_VOLUMEID_XFS=y | ||
604 | CONFIG_FEATURE_VOLUMEID_NTFS=y | ||
605 | CONFIG_FEATURE_VOLUMEID_ISO9660=y | ||
606 | CONFIG_FEATURE_VOLUMEID_UDF=y | ||
607 | CONFIG_FEATURE_VOLUMEID_LUKS=y | ||
608 | CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y | ||
609 | CONFIG_FEATURE_VOLUMEID_CRAMFS=y | ||
610 | CONFIG_FEATURE_VOLUMEID_ROMFS=y | ||
611 | CONFIG_FEATURE_VOLUMEID_SYSV=y | ||
612 | CONFIG_FEATURE_VOLUMEID_OCFS2=y | ||
613 | CONFIG_FEATURE_VOLUMEID_LINUXRAID=y | ||
614 | |||
615 | # | ||
616 | # Miscellaneous Utilities | ||
617 | # | ||
618 | # CONFIG_CONSPY is not set | ||
619 | # CONFIG_NANDWRITE is not set | ||
620 | CONFIG_NANDDUMP=y | ||
621 | CONFIG_SETSERIAL=y | ||
622 | # CONFIG_UBIATTACH is not set | ||
623 | # CONFIG_UBIDETACH is not set | ||
624 | # CONFIG_UBIMKVOL is not set | ||
625 | # CONFIG_UBIRMVOL is not set | ||
626 | # CONFIG_UBIRSVOL is not set | ||
627 | # CONFIG_UBIUPDATEVOL is not set | ||
628 | # CONFIG_ADJTIMEX is not set | ||
629 | # CONFIG_BBCONFIG is not set | ||
630 | # CONFIG_FEATURE_COMPRESS_BBCONFIG is not set | ||
631 | CONFIG_BEEP=y | ||
632 | CONFIG_FEATURE_BEEP_FREQ=4000 | ||
633 | CONFIG_FEATURE_BEEP_LENGTH_MS=30 | ||
634 | CONFIG_CHAT=y | ||
635 | CONFIG_FEATURE_CHAT_NOFAIL=y | ||
636 | # CONFIG_FEATURE_CHAT_TTY_HIFI is not set | ||
637 | CONFIG_FEATURE_CHAT_IMPLICIT_CR=y | ||
638 | CONFIG_FEATURE_CHAT_SWALLOW_OPTS=y | ||
639 | CONFIG_FEATURE_CHAT_SEND_ESCAPES=y | ||
640 | CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y | ||
641 | CONFIG_FEATURE_CHAT_CLR_ABORT=y | ||
642 | CONFIG_CHRT=y | ||
643 | # CONFIG_CROND is not set | ||
644 | # CONFIG_FEATURE_CROND_D is not set | ||
645 | # CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set | ||
646 | CONFIG_FEATURE_CROND_DIR="" | ||
647 | # CONFIG_CRONTAB is not set | ||
648 | CONFIG_DC=y | ||
649 | CONFIG_FEATURE_DC_LIBM=y | ||
650 | # CONFIG_DEVFSD is not set | ||
651 | # CONFIG_DEVFSD_MODLOAD is not set | ||
652 | # CONFIG_DEVFSD_FG_NP is not set | ||
653 | # CONFIG_DEVFSD_VERBOSE is not set | ||
654 | # CONFIG_FEATURE_DEVFS is not set | ||
655 | CONFIG_DEVMEM=y | ||
656 | # CONFIG_EJECT is not set | ||
657 | # CONFIG_FEATURE_EJECT_SCSI is not set | ||
658 | CONFIG_FBSPLASH=y | ||
659 | CONFIG_FLASHCP=y | ||
660 | CONFIG_FLASH_LOCK=y | ||
661 | CONFIG_FLASH_UNLOCK=y | ||
662 | # CONFIG_FLASH_ERASEALL is not set | ||
663 | # CONFIG_IONICE is not set | ||
664 | CONFIG_INOTIFYD=y | ||
665 | # CONFIG_LAST is not set | ||
666 | # CONFIG_FEATURE_LAST_SMALL is not set | ||
667 | # CONFIG_FEATURE_LAST_FANCY is not set | ||
668 | # CONFIG_LESS is not set | ||
669 | CONFIG_FEATURE_LESS_MAXLINES=0 | ||
670 | # CONFIG_FEATURE_LESS_BRACKETS is not set | ||
671 | # CONFIG_FEATURE_LESS_FLAGS is not set | ||
672 | # CONFIG_FEATURE_LESS_MARKS is not set | ||
673 | # CONFIG_FEATURE_LESS_REGEXP is not set | ||
674 | # CONFIG_FEATURE_LESS_WINCH is not set | ||
675 | # CONFIG_FEATURE_LESS_DASHCMD is not set | ||
676 | # CONFIG_FEATURE_LESS_LINENUMS is not set | ||
677 | CONFIG_HDPARM=y | ||
678 | CONFIG_FEATURE_HDPARM_GET_IDENTITY=y | ||
679 | CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y | ||
680 | CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF=y | ||
681 | CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET=y | ||
682 | CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF=y | ||
683 | CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA=y | ||
684 | CONFIG_MAKEDEVS=y | ||
685 | # CONFIG_FEATURE_MAKEDEVS_LEAF is not set | ||
686 | CONFIG_FEATURE_MAKEDEVS_TABLE=y | ||
687 | CONFIG_MAN=y | ||
688 | # CONFIG_MICROCOM is not set | ||
689 | # CONFIG_MOUNTPOINT is not set | ||
690 | # CONFIG_MT is not set | ||
691 | CONFIG_RAIDAUTORUN=y | ||
692 | # CONFIG_READAHEAD is not set | ||
693 | # CONFIG_RFKILL is not set | ||
694 | # CONFIG_RUNLEVEL is not set | ||
695 | CONFIG_RX=y | ||
696 | CONFIG_SETSID=y | ||
697 | CONFIG_STRINGS=y | ||
698 | # CONFIG_TASKSET is not set | ||
699 | # CONFIG_FEATURE_TASKSET_FANCY is not set | ||
700 | CONFIG_TIME=y | ||
701 | CONFIG_TIMEOUT=y | ||
702 | CONFIG_TTYSIZE=y | ||
703 | CONFIG_VOLNAME=y | ||
704 | # CONFIG_WALL is not set | ||
705 | # CONFIG_WATCHDOG is not set | ||
706 | |||
707 | # | ||
708 | # Networking Utilities | ||
709 | # | ||
710 | # CONFIG_NAMEIF is not set | ||
711 | # CONFIG_FEATURE_NAMEIF_EXTENDED is not set | ||
712 | CONFIG_NBDCLIENT=y | ||
713 | CONFIG_NC=y | ||
714 | CONFIG_NC_SERVER=y | ||
715 | CONFIG_NC_EXTRA=y | ||
716 | # CONFIG_NC_110_COMPAT is not set | ||
717 | # CONFIG_PING is not set | ||
718 | # CONFIG_PING6 is not set | ||
719 | # CONFIG_FEATURE_FANCY_PING is not set | ||
720 | CONFIG_WHOIS=y | ||
721 | # CONFIG_FEATURE_IPV6 is not set | ||
722 | # CONFIG_FEATURE_UNIX_LOCAL is not set | ||
723 | # CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set | ||
724 | # CONFIG_VERBOSE_RESOLUTION_ERRORS is not set | ||
725 | CONFIG_ARP=y | ||
726 | # CONFIG_ARPING is not set | ||
727 | # CONFIG_BRCTL is not set | ||
728 | # CONFIG_FEATURE_BRCTL_FANCY is not set | ||
729 | # CONFIG_FEATURE_BRCTL_SHOW is not set | ||
730 | CONFIG_DNSD=y | ||
731 | # CONFIG_ETHER_WAKE is not set | ||
732 | CONFIG_FAKEIDENTD=y | ||
733 | CONFIG_FTPD=y | ||
734 | CONFIG_FEATURE_FTP_WRITE=y | ||
735 | CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y | ||
736 | CONFIG_FTPGET=y | ||
737 | CONFIG_FTPPUT=y | ||
738 | # CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set | ||
739 | # CONFIG_HOSTNAME is not set | ||
740 | CONFIG_HTTPD=y | ||
741 | CONFIG_FEATURE_HTTPD_RANGES=y | ||
742 | CONFIG_FEATURE_HTTPD_USE_SENDFILE=y | ||
743 | CONFIG_FEATURE_HTTPD_SETUID=y | ||
744 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y | ||
745 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set | ||
746 | CONFIG_FEATURE_HTTPD_CGI=y | ||
747 | CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y | ||
748 | CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y | ||
749 | CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y | ||
750 | CONFIG_FEATURE_HTTPD_ERROR_PAGES=y | ||
751 | CONFIG_FEATURE_HTTPD_PROXY=y | ||
752 | CONFIG_FEATURE_HTTPD_GZIP=y | ||
753 | CONFIG_IFCONFIG=y | ||
754 | CONFIG_FEATURE_IFCONFIG_STATUS=y | ||
755 | # CONFIG_FEATURE_IFCONFIG_SLIP is not set | ||
756 | CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ=y | ||
757 | CONFIG_FEATURE_IFCONFIG_HW=y | ||
758 | CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y | ||
759 | # CONFIG_IFENSLAVE is not set | ||
760 | # CONFIG_IFPLUGD is not set | ||
761 | CONFIG_IFUPDOWN=y | ||
762 | CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate" | ||
763 | CONFIG_FEATURE_IFUPDOWN_IP=y | ||
764 | CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y | ||
765 | # CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set | ||
766 | CONFIG_FEATURE_IFUPDOWN_IPV4=y | ||
767 | # CONFIG_FEATURE_IFUPDOWN_IPV6 is not set | ||
768 | CONFIG_FEATURE_IFUPDOWN_MAPPING=y | ||
769 | # CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set | ||
770 | # CONFIG_INETD is not set | ||
771 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set | ||
772 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set | ||
773 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set | ||
774 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set | ||
775 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set | ||
776 | # CONFIG_FEATURE_INETD_RPC is not set | ||
777 | CONFIG_IP=y | ||
778 | CONFIG_FEATURE_IP_ADDRESS=y | ||
779 | CONFIG_FEATURE_IP_LINK=y | ||
780 | CONFIG_FEATURE_IP_ROUTE=y | ||
781 | CONFIG_FEATURE_IP_TUNNEL=y | ||
782 | CONFIG_FEATURE_IP_RULE=y | ||
783 | CONFIG_FEATURE_IP_SHORT_FORMS=y | ||
784 | # CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set | ||
785 | CONFIG_IPADDR=y | ||
786 | CONFIG_IPLINK=y | ||
787 | CONFIG_IPROUTE=y | ||
788 | CONFIG_IPTUNNEL=y | ||
789 | CONFIG_IPRULE=y | ||
790 | CONFIG_IPCALC=y | ||
791 | CONFIG_FEATURE_IPCALC_FANCY=y | ||
792 | # CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set | ||
793 | CONFIG_NETSTAT=y | ||
794 | CONFIG_FEATURE_NETSTAT_WIDE=y | ||
795 | CONFIG_FEATURE_NETSTAT_PRG=y | ||
796 | # CONFIG_NSLOOKUP is not set | ||
797 | # CONFIG_NTPD is not set | ||
798 | # CONFIG_FEATURE_NTPD_SERVER is not set | ||
799 | CONFIG_PSCAN=y | ||
800 | CONFIG_ROUTE=y | ||
801 | # CONFIG_SLATTACH is not set | ||
802 | CONFIG_TCPSVD=y | ||
803 | # CONFIG_TELNET is not set | ||
804 | # CONFIG_FEATURE_TELNET_TTYPE is not set | ||
805 | # CONFIG_FEATURE_TELNET_AUTOLOGIN is not set | ||
806 | # CONFIG_TELNETD is not set | ||
807 | # CONFIG_FEATURE_TELNETD_STANDALONE is not set | ||
808 | # CONFIG_FEATURE_TELNETD_INETD_WAIT is not set | ||
809 | # CONFIG_TFTP is not set | ||
810 | # CONFIG_TFTPD is not set | ||
811 | # CONFIG_FEATURE_TFTP_GET is not set | ||
812 | # CONFIG_FEATURE_TFTP_PUT is not set | ||
813 | # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set | ||
814 | # CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set | ||
815 | # CONFIG_TFTP_DEBUG is not set | ||
816 | # CONFIG_TRACEROUTE is not set | ||
817 | # CONFIG_TRACEROUTE6 is not set | ||
818 | # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set | ||
819 | # CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set | ||
820 | # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set | ||
821 | CONFIG_TUNCTL=y | ||
822 | CONFIG_FEATURE_TUNCTL_UG=y | ||
823 | # CONFIG_UDHCPD is not set | ||
824 | # CONFIG_DHCPRELAY is not set | ||
825 | # CONFIG_DUMPLEASES is not set | ||
826 | # CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set | ||
827 | # CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set | ||
828 | CONFIG_DHCPD_LEASES_FILE="" | ||
829 | CONFIG_UDHCPC=y | ||
830 | CONFIG_FEATURE_UDHCPC_ARPING=y | ||
831 | # CONFIG_FEATURE_UDHCP_PORT is not set | ||
832 | CONFIG_UDHCP_DEBUG=9 | ||
833 | CONFIG_FEATURE_UDHCP_RFC3397=y | ||
834 | CONFIG_FEATURE_UDHCP_8021Q=y | ||
835 | CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" | ||
836 | CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 | ||
837 | CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n" | ||
838 | # CONFIG_UDPSVD is not set | ||
839 | # CONFIG_VCONFIG is not set | ||
840 | CONFIG_WGET=y | ||
841 | CONFIG_FEATURE_WGET_STATUSBAR=y | ||
842 | CONFIG_FEATURE_WGET_AUTHENTICATION=y | ||
843 | # CONFIG_FEATURE_WGET_LONG_OPTIONS is not set | ||
844 | CONFIG_FEATURE_WGET_TIMEOUT=y | ||
845 | # CONFIG_ZCIP is not set | ||
846 | |||
847 | # | ||
848 | # Print Utilities | ||
849 | # | ||
850 | CONFIG_LPD=y | ||
851 | CONFIG_LPR=y | ||
852 | CONFIG_LPQ=y | ||
853 | |||
854 | # | ||
855 | # Mail Utilities | ||
856 | # | ||
857 | CONFIG_MAKEMIME=y | ||
858 | CONFIG_FEATURE_MIME_CHARSET="us-ascii" | ||
859 | CONFIG_POPMAILDIR=y | ||
860 | CONFIG_FEATURE_POPMAILDIR_DELIVERY=y | ||
861 | CONFIG_REFORMIME=y | ||
862 | CONFIG_FEATURE_REFORMIME_COMPAT=y | ||
863 | CONFIG_SENDMAIL=y | ||
864 | |||
865 | # | ||
866 | # Process Utilities | ||
867 | # | ||
868 | CONFIG_IOSTAT=y | ||
869 | CONFIG_MPSTAT=y | ||
870 | CONFIG_NMETER=y | ||
871 | CONFIG_PMAP=y | ||
872 | CONFIG_POWERTOP=y | ||
873 | CONFIG_PSTREE=y | ||
874 | CONFIG_PWDX=y | ||
875 | CONFIG_SMEMCAP=y | ||
876 | # CONFIG_FREE is not set | ||
877 | CONFIG_FUSER=y | ||
878 | # CONFIG_KILL is not set | ||
879 | # CONFIG_KILLALL is not set | ||
880 | # CONFIG_KILLALL5 is not set | ||
881 | # CONFIG_PGREP is not set | ||
882 | CONFIG_PIDOF=y | ||
883 | CONFIG_FEATURE_PIDOF_SINGLE=y | ||
884 | CONFIG_FEATURE_PIDOF_OMIT=y | ||
885 | # CONFIG_PKILL is not set | ||
886 | # CONFIG_PS is not set | ||
887 | # CONFIG_FEATURE_PS_WIDE is not set | ||
888 | # CONFIG_FEATURE_PS_TIME is not set | ||
889 | # CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set | ||
890 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set | ||
891 | CONFIG_RENICE=y | ||
892 | CONFIG_BB_SYSCTL=y | ||
893 | CONFIG_TOP=y | ||
894 | CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y | ||
895 | CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y | ||
896 | CONFIG_FEATURE_TOP_SMP_CPU=y | ||
897 | CONFIG_FEATURE_TOP_DECIMALS=y | ||
898 | CONFIG_FEATURE_TOP_SMP_PROCESS=y | ||
899 | CONFIG_FEATURE_TOPMEM=y | ||
900 | CONFIG_FEATURE_SHOW_THREADS=y | ||
901 | # CONFIG_UPTIME is not set | ||
902 | CONFIG_WATCH=y | ||
903 | |||
904 | # | ||
905 | # Runit Utilities | ||
906 | # | ||
907 | CONFIG_RUNSV=y | ||
908 | CONFIG_RUNSVDIR=y | ||
909 | # CONFIG_FEATURE_RUNSVDIR_LOG is not set | ||
910 | CONFIG_SV=y | ||
911 | CONFIG_SV_DEFAULT_SERVICE_DIR="/var/service" | ||
912 | CONFIG_SVLOGD=y | ||
913 | CONFIG_CHPST=y | ||
914 | CONFIG_SETUIDGID=y | ||
915 | CONFIG_ENVUIDGID=y | ||
916 | CONFIG_ENVDIR=y | ||
917 | CONFIG_SOFTLIMIT=y | ||
918 | # CONFIG_CHCON is not set | ||
919 | # CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set | ||
920 | # CONFIG_GETENFORCE is not set | ||
921 | # CONFIG_GETSEBOOL is not set | ||
922 | # CONFIG_LOAD_POLICY is not set | ||
923 | # CONFIG_MATCHPATHCON is not set | ||
924 | # CONFIG_RESTORECON is not set | ||
925 | # CONFIG_RUNCON is not set | ||
926 | # CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set | ||
927 | # CONFIG_SELINUXENABLED is not set | ||
928 | # CONFIG_SETENFORCE is not set | ||
929 | # CONFIG_SETFILES is not set | ||
930 | # CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set | ||
931 | # CONFIG_SETSEBOOL is not set | ||
932 | # CONFIG_SESTATUS is not set | ||
933 | |||
934 | # | ||
935 | # Shells | ||
936 | # | ||
937 | # CONFIG_ASH is not set | ||
938 | # CONFIG_ASH_BASH_COMPAT is not set | ||
939 | # CONFIG_ASH_IDLE_TIMEOUT is not set | ||
940 | # CONFIG_ASH_JOB_CONTROL is not set | ||
941 | # CONFIG_ASH_ALIAS is not set | ||
942 | # CONFIG_ASH_GETOPTS is not set | ||
943 | # CONFIG_ASH_BUILTIN_ECHO is not set | ||
944 | # CONFIG_ASH_BUILTIN_PRINTF is not set | ||
945 | # CONFIG_ASH_BUILTIN_TEST is not set | ||
946 | # CONFIG_ASH_CMDCMD is not set | ||
947 | # CONFIG_ASH_MAIL is not set | ||
948 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set | ||
949 | # CONFIG_ASH_RANDOM_SUPPORT is not set | ||
950 | # CONFIG_ASH_EXPAND_PRMT is not set | ||
951 | CONFIG_CTTYHACK=y | ||
952 | # CONFIG_HUSH is not set | ||
953 | # CONFIG_HUSH_BASH_COMPAT is not set | ||
954 | # CONFIG_HUSH_BRACE_EXPANSION is not set | ||
955 | # CONFIG_HUSH_HELP is not set | ||
956 | # CONFIG_HUSH_INTERACTIVE is not set | ||
957 | # CONFIG_HUSH_SAVEHISTORY is not set | ||
958 | # CONFIG_HUSH_JOB is not set | ||
959 | # CONFIG_HUSH_TICK is not set | ||
960 | # CONFIG_HUSH_IF is not set | ||
961 | # CONFIG_HUSH_LOOPS is not set | ||
962 | # CONFIG_HUSH_CASE is not set | ||
963 | # CONFIG_HUSH_FUNCTIONS is not set | ||
964 | # CONFIG_HUSH_LOCAL is not set | ||
965 | # CONFIG_HUSH_RANDOM_SUPPORT is not set | ||
966 | # CONFIG_HUSH_EXPORT_N is not set | ||
967 | # CONFIG_HUSH_MODE_X is not set | ||
968 | # CONFIG_MSH is not set | ||
969 | # CONFIG_FEATURE_SH_IS_ASH is not set | ||
970 | # CONFIG_FEATURE_SH_IS_HUSH is not set | ||
971 | CONFIG_FEATURE_SH_IS_NONE=y | ||
972 | # CONFIG_FEATURE_BASH_IS_ASH is not set | ||
973 | # CONFIG_FEATURE_BASH_IS_HUSH is not set | ||
974 | CONFIG_FEATURE_BASH_IS_NONE=y | ||
975 | # CONFIG_SH_MATH_SUPPORT is not set | ||
976 | # CONFIG_SH_MATH_SUPPORT_64 is not set | ||
977 | # CONFIG_FEATURE_SH_EXTRA_QUIET is not set | ||
978 | # CONFIG_FEATURE_SH_STANDALONE is not set | ||
979 | # CONFIG_FEATURE_SH_NOFORK is not set | ||
980 | # CONFIG_FEATURE_SH_HISTFILESIZE is not set | ||
981 | |||
982 | # | ||
983 | # System Logging Utilities | ||
984 | # | ||
985 | # CONFIG_SYSLOGD is not set | ||
986 | # CONFIG_FEATURE_ROTATE_LOGFILE is not set | ||
987 | # CONFIG_FEATURE_REMOTE_LOG is not set | ||
988 | # CONFIG_FEATURE_SYSLOGD_DUP is not set | ||
989 | # CONFIG_FEATURE_SYSLOGD_CFG is not set | ||
990 | CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 | ||
991 | # CONFIG_FEATURE_IPC_SYSLOG is not set | ||
992 | CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 | ||
993 | # CONFIG_LOGREAD is not set | ||
994 | # CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set | ||
995 | CONFIG_KLOGD=y | ||
996 | CONFIG_FEATURE_KLOGD_KLOGCTL=y | ||
997 | # CONFIG_LOGGER is not set | ||
diff --git a/configs/android_defconfig b/configs/android_defconfig index 7e5232a84..b9df0ea02 100644 --- a/configs/android_defconfig +++ b/configs/android_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.19.0.git | 3 | # Busybox version: 1.20.0.git |
4 | # Wed Jun 29 12:01:57 2011 | 4 | # Wed Nov 2 17:54:00 2011 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | 7 | ||
@@ -12,7 +12,7 @@ CONFIG_HAVE_DOT_CONFIG=y | |||
12 | # | 12 | # |
13 | # General Configuration | 13 | # General Configuration |
14 | # | 14 | # |
15 | # CONFIG_DESKTOP is not set | 15 | CONFIG_DESKTOP=y |
16 | # CONFIG_EXTRA_COMPAT is not set | 16 | # CONFIG_EXTRA_COMPAT is not set |
17 | # CONFIG_INCLUDE_SUSv2 is not set | 17 | # CONFIG_INCLUDE_SUSv2 is not set |
18 | # CONFIG_USE_PORTABLE_CODE is not set | 18 | # CONFIG_USE_PORTABLE_CODE is not set |
@@ -60,7 +60,7 @@ CONFIG_FEATURE_SYSLOG=y | |||
60 | # CONFIG_BUILD_LIBBUSYBOX is not set | 60 | # CONFIG_BUILD_LIBBUSYBOX is not set |
61 | # CONFIG_FEATURE_INDIVIDUAL is not set | 61 | # CONFIG_FEATURE_INDIVIDUAL is not set |
62 | # CONFIG_FEATURE_SHARED_BUSYBOX is not set | 62 | # CONFIG_FEATURE_SHARED_BUSYBOX is not set |
63 | # CONFIG_LFS is not set | 63 | CONFIG_LFS=y |
64 | CONFIG_CROSS_COMPILER_PREFIX="arm-eabi-" | 64 | CONFIG_CROSS_COMPILER_PREFIX="arm-eabi-" |
65 | # | 65 | # |
66 | # Removed: | 66 | # Removed: |
@@ -70,6 +70,8 @@ CONFIG_CROSS_COMPILER_PREFIX="arm-eabi-" | |||
70 | # -Werror=sequence-point -Wstrict-aliasing=2 -Wno-undef -Wno-shadow | 70 | # -Werror=sequence-point -Wstrict-aliasing=2 -Wno-undef -Wno-shadow |
71 | # bbox already adds these: | 71 | # bbox already adds these: |
72 | # -ffunction-sections -fomit-frame-pointer | 72 | # -ffunction-sections -fomit-frame-pointer |
73 | # enabled implicitly by -Os: | ||
74 | # -frerun-cse-after-loop | ||
73 | # should be not needed, or even increases code size: | 75 | # should be not needed, or even increases code size: |
74 | # -finline-functions -fno-inline-functions-called-once -finline-limit=64 | 76 | # -finline-functions -fno-inline-functions-called-once -finline-limit=64 |
75 | # -fstack-protector -fno-strict-aliasing -fno-exceptions -funwind-tables | 77 | # -fstack-protector -fno-strict-aliasing -fno-exceptions -funwind-tables |
@@ -77,9 +79,8 @@ CONFIG_CROSS_COMPILER_PREFIX="arm-eabi-" | |||
77 | # todo: do we need these? - | 79 | # todo: do we need these? - |
78 | # -fno-short-enums | 80 | # -fno-short-enums |
79 | # -fgcse-after-reload | 81 | # -fgcse-after-reload |
80 | # -frerun-cse-after-loop | ||
81 | # -frename-registers | 82 | # -frename-registers |
82 | CONFIG_EXTRA_CFLAGS="-I$A/system/core/include -I$A/bionic/libc/arch-arm/include -I$A/bionic/libc/include -I$A/bionic/libc/kernel/common -I$A/bionic/libc/kernel/arch-arm -I$A/bionic/libm/include -I$A/bionic/libm/include/arch/arm -include $A/system/core/include/arch/linux-arm/AndroidConfig.h -I$A/system/core/include/arch/linux-arm/ -DANDROID -DSK_RELEASE -nostdlib -march=armv7-a -msoft-float -mfloat-abi=softfp -mfpu=neon -mthumb -mthumb-interwork -fpic -fno-short-enums -fgcse-after-reload -frerun-cse-after-loop -frename-registers" | 83 | CONFIG_EXTRA_CFLAGS="-I$A/system/core/include -I$A/bionic/libc/arch-arm/include -I$A/bionic/libc/include -I$A/bionic/libc/kernel/common -I$A/bionic/libc/kernel/arch-arm -I$A/bionic/libm/include -I$A/bionic/libm/include/arch/arm -include $A/system/core/include/arch/linux-arm/AndroidConfig.h -I$A/system/core/include/arch/linux-arm/ -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" |
83 | 84 | ||
84 | # | 85 | # |
85 | # Debugging Options | 86 | # Debugging Options |
@@ -109,7 +110,7 @@ CONFIG_PREFIX="./_install" | |||
109 | # CONFIG_FEATURE_SYSTEMD is not set | 110 | # CONFIG_FEATURE_SYSTEMD is not set |
110 | # CONFIG_FEATURE_RTMINMAX is not set | 111 | # CONFIG_FEATURE_RTMINMAX is not set |
111 | CONFIG_PASSWORD_MINLEN=6 | 112 | CONFIG_PASSWORD_MINLEN=6 |
112 | CONFIG_MD5_SIZE_VS_SPEED=2 | 113 | CONFIG_MD5_SMALL=1 |
113 | # CONFIG_FEATURE_FAST_TOP is not set | 114 | # CONFIG_FEATURE_FAST_TOP is not set |
114 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 115 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
115 | CONFIG_FEATURE_USE_TERMIOS=y | 116 | CONFIG_FEATURE_USE_TERMIOS=y |
@@ -118,6 +119,8 @@ CONFIG_FEATURE_EDITING_MAX_LEN=0 | |||
118 | # CONFIG_FEATURE_EDITING_VI is not set | 119 | # CONFIG_FEATURE_EDITING_VI is not set |
119 | CONFIG_FEATURE_EDITING_HISTORY=0 | 120 | CONFIG_FEATURE_EDITING_HISTORY=0 |
120 | # CONFIG_FEATURE_EDITING_SAVEHISTORY is not set | 121 | # CONFIG_FEATURE_EDITING_SAVEHISTORY is not set |
122 | # CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set | ||
123 | # CONFIG_FEATURE_REVERSE_SEARCH is not set | ||
121 | # CONFIG_FEATURE_TAB_COMPLETION is not set | 124 | # CONFIG_FEATURE_TAB_COMPLETION is not set |
122 | # CONFIG_FEATURE_USERNAME_COMPLETION is not set | 125 | # CONFIG_FEATURE_USERNAME_COMPLETION is not set |
123 | # CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set | 126 | # CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set |
@@ -156,6 +159,7 @@ CONFIG_DPKG_DEB=y | |||
156 | CONFIG_GUNZIP=y | 159 | CONFIG_GUNZIP=y |
157 | CONFIG_GZIP=y | 160 | CONFIG_GZIP=y |
158 | # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set | 161 | # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set |
162 | CONFIG_GZIP_FAST=0 | ||
159 | CONFIG_LZOP=y | 163 | CONFIG_LZOP=y |
160 | CONFIG_LZOP_COMPR_HIGH=y | 164 | CONFIG_LZOP_COMPR_HIGH=y |
161 | CONFIG_RPM2CPIO=y | 165 | CONFIG_RPM2CPIO=y |
@@ -189,6 +193,7 @@ CONFIG_CAT=y | |||
189 | # CONFIG_FEATURE_DATE_ISOFMT is not set | 193 | # CONFIG_FEATURE_DATE_ISOFMT is not set |
190 | # CONFIG_FEATURE_DATE_NANO is not set | 194 | # CONFIG_FEATURE_DATE_NANO is not set |
191 | # CONFIG_FEATURE_DATE_COMPAT is not set | 195 | # CONFIG_FEATURE_DATE_COMPAT is not set |
196 | # CONFIG_HOSTID is not set | ||
192 | # CONFIG_ID is not set | 197 | # CONFIG_ID is not set |
193 | # CONFIG_GROUPS is not set | 198 | # CONFIG_GROUPS is not set |
194 | CONFIG_TEST=y | 199 | CONFIG_TEST=y |
@@ -198,6 +203,8 @@ CONFIG_TR=y | |||
198 | CONFIG_FEATURE_TR_CLASSES=y | 203 | CONFIG_FEATURE_TR_CLASSES=y |
199 | CONFIG_FEATURE_TR_EQUIV=y | 204 | CONFIG_FEATURE_TR_EQUIV=y |
200 | CONFIG_BASE64=y | 205 | CONFIG_BASE64=y |
206 | # CONFIG_WHO is not set | ||
207 | # CONFIG_USERS is not set | ||
201 | CONFIG_CAL=y | 208 | CONFIG_CAL=y |
202 | CONFIG_CATV=y | 209 | CONFIG_CATV=y |
203 | CONFIG_CHGRP=y | 210 | CONFIG_CHGRP=y |
@@ -223,18 +230,17 @@ CONFIG_DU=y | |||
223 | CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y | 230 | CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y |
224 | CONFIG_ECHO=y | 231 | CONFIG_ECHO=y |
225 | CONFIG_FEATURE_FANCY_ECHO=y | 232 | CONFIG_FEATURE_FANCY_ECHO=y |
226 | # CONFIG_ENV is not set | 233 | CONFIG_ENV=y |
227 | # CONFIG_FEATURE_ENV_LONG_OPTIONS is not set | 234 | # CONFIG_FEATURE_ENV_LONG_OPTIONS is not set |
228 | CONFIG_EXPAND=y | 235 | CONFIG_EXPAND=y |
229 | # CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set | 236 | # CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set |
230 | # CONFIG_EXPR is not set | 237 | CONFIG_EXPR=y |
231 | # CONFIG_EXPR_MATH_SUPPORT_64 is not set | 238 | CONFIG_EXPR_MATH_SUPPORT_64=y |
232 | CONFIG_FALSE=y | 239 | CONFIG_FALSE=y |
233 | CONFIG_FOLD=y | 240 | CONFIG_FOLD=y |
234 | # CONFIG_FSYNC is not set | 241 | CONFIG_FSYNC=y |
235 | CONFIG_HEAD=y | 242 | CONFIG_HEAD=y |
236 | CONFIG_FEATURE_FANCY_HEAD=y | 243 | CONFIG_FEATURE_FANCY_HEAD=y |
237 | # CONFIG_HOSTID is not set | ||
238 | CONFIG_INSTALL=y | 244 | CONFIG_INSTALL=y |
239 | # CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set | 245 | # CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set |
240 | CONFIG_LN=y | 246 | CONFIG_LN=y |
@@ -294,12 +300,11 @@ CONFIG_UNAME=y | |||
294 | CONFIG_UNEXPAND=y | 300 | CONFIG_UNEXPAND=y |
295 | # CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set | 301 | # CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set |
296 | CONFIG_UNIQ=y | 302 | CONFIG_UNIQ=y |
297 | # CONFIG_USLEEP is not set | 303 | CONFIG_USLEEP=y |
298 | CONFIG_UUDECODE=y | 304 | CONFIG_UUDECODE=y |
299 | CONFIG_UUENCODE=y | 305 | CONFIG_UUENCODE=y |
300 | CONFIG_WC=y | 306 | CONFIG_WC=y |
301 | CONFIG_FEATURE_WC_LARGE=y | 307 | CONFIG_FEATURE_WC_LARGE=y |
302 | # CONFIG_WHO is not set | ||
303 | CONFIG_WHOAMI=y | 308 | CONFIG_WHOAMI=y |
304 | CONFIG_YES=y | 309 | CONFIG_YES=y |
305 | 310 | ||
@@ -366,61 +371,61 @@ CONFIG_WHICH=y | |||
366 | # Editors | 371 | # Editors |
367 | # | 372 | # |
368 | CONFIG_PATCH=y | 373 | CONFIG_PATCH=y |
369 | # CONFIG_VI is not set | 374 | CONFIG_VI=y |
370 | CONFIG_FEATURE_VI_MAX_LEN=0 | 375 | CONFIG_FEATURE_VI_MAX_LEN=4096 |
371 | # CONFIG_FEATURE_VI_8BIT is not set | 376 | CONFIG_FEATURE_VI_8BIT=y |
372 | # CONFIG_FEATURE_VI_COLON is not set | 377 | CONFIG_FEATURE_VI_COLON=y |
373 | # CONFIG_FEATURE_VI_YANKMARK is not set | 378 | CONFIG_FEATURE_VI_YANKMARK=y |
374 | # CONFIG_FEATURE_VI_SEARCH is not set | 379 | CONFIG_FEATURE_VI_SEARCH=y |
375 | # CONFIG_FEATURE_VI_REGEX_SEARCH is not set | 380 | # CONFIG_FEATURE_VI_REGEX_SEARCH is not set |
376 | # CONFIG_FEATURE_VI_USE_SIGNALS is not set | 381 | CONFIG_FEATURE_VI_USE_SIGNALS=y |
377 | # CONFIG_FEATURE_VI_DOT_CMD is not set | 382 | CONFIG_FEATURE_VI_DOT_CMD=y |
378 | # CONFIG_FEATURE_VI_READONLY is not set | 383 | CONFIG_FEATURE_VI_READONLY=y |
379 | # CONFIG_FEATURE_VI_SETOPTS is not set | 384 | CONFIG_FEATURE_VI_SETOPTS=y |
380 | # CONFIG_FEATURE_VI_SET is not set | 385 | CONFIG_FEATURE_VI_SET=y |
381 | # CONFIG_FEATURE_VI_WIN_RESIZE is not set | 386 | CONFIG_FEATURE_VI_WIN_RESIZE=y |
382 | # CONFIG_FEATURE_VI_ASK_TERMINAL is not set | 387 | CONFIG_FEATURE_VI_ASK_TERMINAL=y |
383 | # CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set | 388 | CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y |
384 | # CONFIG_AWK is not set | 389 | CONFIG_AWK=y |
385 | # CONFIG_FEATURE_AWK_LIBM is not set | 390 | CONFIG_FEATURE_AWK_LIBM=y |
386 | CONFIG_CMP=y | 391 | CONFIG_CMP=y |
387 | CONFIG_DIFF=y | 392 | CONFIG_DIFF=y |
388 | # CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set | 393 | # CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set |
389 | CONFIG_FEATURE_DIFF_DIR=y | 394 | CONFIG_FEATURE_DIFF_DIR=y |
390 | # CONFIG_ED is not set | 395 | CONFIG_ED=y |
391 | # CONFIG_SED is not set | 396 | CONFIG_SED=y |
392 | # CONFIG_FEATURE_ALLOW_EXEC is not set | 397 | CONFIG_FEATURE_ALLOW_EXEC=y |
393 | 398 | ||
394 | # | 399 | # |
395 | # Finding Utilities | 400 | # Finding Utilities |
396 | # | 401 | # |
397 | # CONFIG_FIND is not set | 402 | CONFIG_FIND=y |
398 | # CONFIG_FEATURE_FIND_PRINT0 is not set | 403 | CONFIG_FEATURE_FIND_PRINT0=y |
399 | # CONFIG_FEATURE_FIND_MTIME is not set | 404 | CONFIG_FEATURE_FIND_MTIME=y |
400 | # CONFIG_FEATURE_FIND_MMIN is not set | 405 | CONFIG_FEATURE_FIND_MMIN=y |
401 | # CONFIG_FEATURE_FIND_PERM is not set | 406 | CONFIG_FEATURE_FIND_PERM=y |
402 | # CONFIG_FEATURE_FIND_TYPE is not set | 407 | CONFIG_FEATURE_FIND_TYPE=y |
403 | # CONFIG_FEATURE_FIND_XDEV is not set | 408 | CONFIG_FEATURE_FIND_XDEV=y |
404 | # CONFIG_FEATURE_FIND_MAXDEPTH is not set | 409 | CONFIG_FEATURE_FIND_MAXDEPTH=y |
405 | # CONFIG_FEATURE_FIND_NEWER is not set | 410 | CONFIG_FEATURE_FIND_NEWER=y |
406 | # CONFIG_FEATURE_FIND_INUM is not set | 411 | CONFIG_FEATURE_FIND_INUM=y |
407 | # CONFIG_FEATURE_FIND_EXEC is not set | 412 | CONFIG_FEATURE_FIND_EXEC=y |
408 | # CONFIG_FEATURE_FIND_USER is not set | 413 | CONFIG_FEATURE_FIND_USER=y |
409 | # CONFIG_FEATURE_FIND_GROUP is not set | 414 | CONFIG_FEATURE_FIND_GROUP=y |
410 | # CONFIG_FEATURE_FIND_NOT is not set | 415 | CONFIG_FEATURE_FIND_NOT=y |
411 | # CONFIG_FEATURE_FIND_DEPTH is not set | 416 | CONFIG_FEATURE_FIND_DEPTH=y |
412 | # CONFIG_FEATURE_FIND_PAREN is not set | 417 | CONFIG_FEATURE_FIND_PAREN=y |
413 | # CONFIG_FEATURE_FIND_SIZE is not set | 418 | CONFIG_FEATURE_FIND_SIZE=y |
414 | # CONFIG_FEATURE_FIND_PRUNE is not set | 419 | CONFIG_FEATURE_FIND_PRUNE=y |
415 | # CONFIG_FEATURE_FIND_DELETE is not set | 420 | CONFIG_FEATURE_FIND_DELETE=y |
416 | # CONFIG_FEATURE_FIND_PATH is not set | 421 | CONFIG_FEATURE_FIND_PATH=y |
417 | # CONFIG_FEATURE_FIND_REGEX is not set | 422 | CONFIG_FEATURE_FIND_REGEX=y |
418 | # CONFIG_FEATURE_FIND_CONTEXT is not set | 423 | # CONFIG_FEATURE_FIND_CONTEXT is not set |
419 | # CONFIG_FEATURE_FIND_LINKS is not set | 424 | CONFIG_FEATURE_FIND_LINKS=y |
420 | # CONFIG_GREP is not set | 425 | CONFIG_GREP=y |
421 | # CONFIG_FEATURE_GREP_EGREP_ALIAS is not set | 426 | CONFIG_FEATURE_GREP_EGREP_ALIAS=y |
422 | # CONFIG_FEATURE_GREP_FGREP_ALIAS is not set | 427 | CONFIG_FEATURE_GREP_FGREP_ALIAS=y |
423 | # CONFIG_FEATURE_GREP_CONTEXT is not set | 428 | CONFIG_FEATURE_GREP_CONTEXT=y |
424 | CONFIG_XARGS=y | 429 | CONFIG_XARGS=y |
425 | CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y | 430 | CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y |
426 | CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y | 431 | CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y |
@@ -430,9 +435,9 @@ CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y | |||
430 | # | 435 | # |
431 | # Init Utilities | 436 | # Init Utilities |
432 | # | 437 | # |
433 | # CONFIG_BOOTCHARTD is not set | 438 | CONFIG_BOOTCHARTD=y |
434 | # CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set | 439 | CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER=y |
435 | # CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set | 440 | CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE=y |
436 | CONFIG_HALT=y | 441 | CONFIG_HALT=y |
437 | # CONFIG_FEATURE_CALL_TELINIT is not set | 442 | # CONFIG_FEATURE_CALL_TELINIT is not set |
438 | CONFIG_TELINIT_PATH="" | 443 | CONFIG_TELINIT_PATH="" |
@@ -472,6 +477,7 @@ CONFIG_LAST_SYSTEM_ID=0 | |||
472 | # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set | 477 | # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set |
473 | # CONFIG_GETTY is not set | 478 | # CONFIG_GETTY is not set |
474 | # CONFIG_LOGIN is not set | 479 | # CONFIG_LOGIN is not set |
480 | # CONFIG_LOGIN_SESSION_AS_CHILD is not set | ||
475 | # CONFIG_PAM is not set | 481 | # CONFIG_PAM is not set |
476 | # CONFIG_LOGIN_SCRIPTS is not set | 482 | # CONFIG_LOGIN_SCRIPTS is not set |
477 | # CONFIG_FEATURE_NOLOGIN is not set | 483 | # CONFIG_FEATURE_NOLOGIN is not set |
@@ -529,11 +535,17 @@ CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | |||
529 | # Linux System Utilities | 535 | # Linux System Utilities |
530 | # | 536 | # |
531 | CONFIG_BLOCKDEV=y | 537 | CONFIG_BLOCKDEV=y |
538 | CONFIG_MDEV=y | ||
539 | CONFIG_FEATURE_MDEV_CONF=y | ||
540 | CONFIG_FEATURE_MDEV_RENAME=y | ||
541 | CONFIG_FEATURE_MDEV_RENAME_REGEXP=y | ||
542 | CONFIG_FEATURE_MDEV_EXEC=y | ||
543 | CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y | ||
532 | CONFIG_REV=y | 544 | CONFIG_REV=y |
533 | # CONFIG_ACPID is not set | 545 | # CONFIG_ACPID is not set |
534 | # CONFIG_FEATURE_ACPID_COMPAT is not set | 546 | # CONFIG_FEATURE_ACPID_COMPAT is not set |
535 | CONFIG_BLKID=y | 547 | CONFIG_BLKID=y |
536 | # CONFIG_FEATURE_BLKID_TYPE is not set | 548 | CONFIG_FEATURE_BLKID_TYPE=y |
537 | CONFIG_DMESG=y | 549 | CONFIG_DMESG=y |
538 | CONFIG_FEATURE_DMESG_PRETTY=y | 550 | CONFIG_FEATURE_DMESG_PRETTY=y |
539 | CONFIG_FBSET=y | 551 | CONFIG_FBSET=y |
@@ -542,7 +554,7 @@ CONFIG_FEATURE_FBSET_READMODE=y | |||
542 | CONFIG_FDFLUSH=y | 554 | CONFIG_FDFLUSH=y |
543 | CONFIG_FDFORMAT=y | 555 | CONFIG_FDFORMAT=y |
544 | CONFIG_FDISK=y | 556 | CONFIG_FDISK=y |
545 | CONFIG_FDISK_SUPPORT_LARGE_DISKS=y | 557 | # CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set |
546 | CONFIG_FEATURE_FDISK_WRITABLE=y | 558 | CONFIG_FEATURE_FDISK_WRITABLE=y |
547 | # CONFIG_FEATURE_AIX_LABEL is not set | 559 | # CONFIG_FEATURE_AIX_LABEL is not set |
548 | # CONFIG_FEATURE_SGI_LABEL is not set | 560 | # CONFIG_FEATURE_SGI_LABEL is not set |
@@ -564,7 +576,7 @@ CONFIG_FEATURE_GETOPT_LONG=y | |||
564 | CONFIG_HEXDUMP=y | 576 | CONFIG_HEXDUMP=y |
565 | CONFIG_FEATURE_HEXDUMP_REVERSE=y | 577 | CONFIG_FEATURE_HEXDUMP_REVERSE=y |
566 | CONFIG_HD=y | 578 | CONFIG_HD=y |
567 | # CONFIG_HWCLOCK is not set | 579 | CONFIG_HWCLOCK=y |
568 | # CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set | 580 | # CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set |
569 | # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set | 581 | # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set |
570 | # CONFIG_IPCRM is not set | 582 | # CONFIG_IPCRM is not set |
@@ -572,12 +584,6 @@ CONFIG_HD=y | |||
572 | CONFIG_LOSETUP=y | 584 | CONFIG_LOSETUP=y |
573 | CONFIG_LSPCI=y | 585 | CONFIG_LSPCI=y |
574 | CONFIG_LSUSB=y | 586 | CONFIG_LSUSB=y |
575 | # CONFIG_MDEV is not set | ||
576 | # CONFIG_FEATURE_MDEV_CONF is not set | ||
577 | # CONFIG_FEATURE_MDEV_RENAME is not set | ||
578 | # CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set | ||
579 | # CONFIG_FEATURE_MDEV_EXEC is not set | ||
580 | # CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set | ||
581 | CONFIG_MKSWAP=y | 587 | CONFIG_MKSWAP=y |
582 | CONFIG_FEATURE_MKSWAP_UUID=y | 588 | CONFIG_FEATURE_MKSWAP_UUID=y |
583 | CONFIG_MORE=y | 589 | CONFIG_MORE=y |
@@ -600,7 +606,7 @@ CONFIG_SCRIPTREPLAY=y | |||
600 | # CONFIG_SETARCH is not set | 606 | # CONFIG_SETARCH is not set |
601 | # CONFIG_SWAPONOFF is not set | 607 | # CONFIG_SWAPONOFF is not set |
602 | # CONFIG_FEATURE_SWAPON_PRI is not set | 608 | # CONFIG_FEATURE_SWAPON_PRI is not set |
603 | # CONFIG_SWITCH_ROOT is not set | 609 | CONFIG_SWITCH_ROOT=y |
604 | # CONFIG_UMOUNT is not set | 610 | # CONFIG_UMOUNT is not set |
605 | # CONFIG_FEATURE_UMOUNT_ALL is not set | 611 | # CONFIG_FEATURE_UMOUNT_ALL is not set |
606 | # CONFIG_FEATURE_MOUNT_LOOP is not set | 612 | # CONFIG_FEATURE_MOUNT_LOOP is not set |
@@ -633,6 +639,16 @@ CONFIG_FEATURE_VOLUMEID_LINUXRAID=y | |||
633 | # Miscellaneous Utilities | 639 | # Miscellaneous Utilities |
634 | # | 640 | # |
635 | # CONFIG_CONSPY is not set | 641 | # CONFIG_CONSPY is not set |
642 | CONFIG_LESS=y | ||
643 | CONFIG_FEATURE_LESS_MAXLINES=9999999 | ||
644 | CONFIG_FEATURE_LESS_BRACKETS=y | ||
645 | CONFIG_FEATURE_LESS_FLAGS=y | ||
646 | CONFIG_FEATURE_LESS_MARKS=y | ||
647 | CONFIG_FEATURE_LESS_REGEXP=y | ||
648 | CONFIG_FEATURE_LESS_WINCH=y | ||
649 | CONFIG_FEATURE_LESS_ASK_TERMINAL=y | ||
650 | CONFIG_FEATURE_LESS_DASHCMD=y | ||
651 | CONFIG_FEATURE_LESS_LINENUMS=y | ||
636 | # CONFIG_NANDWRITE is not set | 652 | # CONFIG_NANDWRITE is not set |
637 | CONFIG_NANDDUMP=y | 653 | CONFIG_NANDDUMP=y |
638 | CONFIG_SETSERIAL=y | 654 | CONFIG_SETSERIAL=y |
@@ -657,11 +673,11 @@ CONFIG_FEATURE_CHAT_SEND_ESCAPES=y | |||
657 | CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y | 673 | CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y |
658 | CONFIG_FEATURE_CHAT_CLR_ABORT=y | 674 | CONFIG_FEATURE_CHAT_CLR_ABORT=y |
659 | CONFIG_CHRT=y | 675 | CONFIG_CHRT=y |
660 | # CONFIG_CROND is not set | 676 | CONFIG_CROND=y |
661 | # CONFIG_FEATURE_CROND_D is not set | 677 | CONFIG_FEATURE_CROND_D=y |
662 | # CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set | 678 | CONFIG_FEATURE_CROND_CALL_SENDMAIL=y |
663 | CONFIG_FEATURE_CROND_DIR="" | 679 | CONFIG_FEATURE_CROND_DIR="/var/spool/cron" |
664 | # CONFIG_CRONTAB is not set | 680 | CONFIG_CRONTAB=y |
665 | CONFIG_DC=y | 681 | CONFIG_DC=y |
666 | CONFIG_FEATURE_DC_LIBM=y | 682 | CONFIG_FEATURE_DC_LIBM=y |
667 | # CONFIG_DEVFSD is not set | 683 | # CONFIG_DEVFSD is not set |
@@ -682,15 +698,6 @@ CONFIG_INOTIFYD=y | |||
682 | # CONFIG_LAST is not set | 698 | # CONFIG_LAST is not set |
683 | # CONFIG_FEATURE_LAST_SMALL is not set | 699 | # CONFIG_FEATURE_LAST_SMALL is not set |
684 | # CONFIG_FEATURE_LAST_FANCY is not set | 700 | # CONFIG_FEATURE_LAST_FANCY is not set |
685 | # CONFIG_LESS is not set | ||
686 | CONFIG_FEATURE_LESS_MAXLINES=0 | ||
687 | # CONFIG_FEATURE_LESS_BRACKETS is not set | ||
688 | # CONFIG_FEATURE_LESS_FLAGS is not set | ||
689 | # CONFIG_FEATURE_LESS_MARKS is not set | ||
690 | # CONFIG_FEATURE_LESS_REGEXP is not set | ||
691 | # CONFIG_FEATURE_LESS_WINCH is not set | ||
692 | # CONFIG_FEATURE_LESS_DASHCMD is not set | ||
693 | # CONFIG_FEATURE_LESS_LINENUMS is not set | ||
694 | CONFIG_HDPARM=y | 701 | CONFIG_HDPARM=y |
695 | CONFIG_FEATURE_HDPARM_GET_IDENTITY=y | 702 | CONFIG_FEATURE_HDPARM_GET_IDENTITY=y |
696 | CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y | 703 | CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y |
@@ -731,9 +738,9 @@ CONFIG_NC=y | |||
731 | CONFIG_NC_SERVER=y | 738 | CONFIG_NC_SERVER=y |
732 | CONFIG_NC_EXTRA=y | 739 | CONFIG_NC_EXTRA=y |
733 | # CONFIG_NC_110_COMPAT is not set | 740 | # CONFIG_NC_110_COMPAT is not set |
734 | # CONFIG_PING is not set | 741 | CONFIG_PING=y |
735 | # CONFIG_PING6 is not set | 742 | # CONFIG_PING6 is not set |
736 | # CONFIG_FEATURE_FANCY_PING is not set | 743 | CONFIG_FEATURE_FANCY_PING=y |
737 | CONFIG_WHOIS=y | 744 | CONFIG_WHOIS=y |
738 | # CONFIG_FEATURE_IPV6 is not set | 745 | # CONFIG_FEATURE_IPV6 is not set |
739 | # CONFIG_FEATURE_UNIX_LOCAL is not set | 746 | # CONFIG_FEATURE_UNIX_LOCAL is not set |
@@ -817,18 +824,22 @@ CONFIG_PSCAN=y | |||
817 | CONFIG_ROUTE=y | 824 | CONFIG_ROUTE=y |
818 | # CONFIG_SLATTACH is not set | 825 | # CONFIG_SLATTACH is not set |
819 | CONFIG_TCPSVD=y | 826 | CONFIG_TCPSVD=y |
820 | # CONFIG_TELNET is not set | 827 | CONFIG_TELNET=y |
821 | # CONFIG_FEATURE_TELNET_TTYPE is not set | 828 | CONFIG_FEATURE_TELNET_TTYPE=y |
822 | # CONFIG_FEATURE_TELNET_AUTOLOGIN is not set | 829 | CONFIG_FEATURE_TELNET_AUTOLOGIN=y |
823 | # CONFIG_TELNETD is not set | 830 | CONFIG_TELNETD=y |
824 | # CONFIG_FEATURE_TELNETD_STANDALONE is not set | 831 | CONFIG_FEATURE_TELNETD_STANDALONE=y |
825 | # CONFIG_FEATURE_TELNETD_INETD_WAIT is not set | 832 | CONFIG_FEATURE_TELNETD_INETD_WAIT=y |
826 | # CONFIG_TFTP is not set | 833 | CONFIG_TFTP=y |
827 | # CONFIG_TFTPD is not set | 834 | CONFIG_TFTPD=y |
828 | # CONFIG_FEATURE_TFTP_GET is not set | 835 | |
829 | # CONFIG_FEATURE_TFTP_PUT is not set | 836 | # |
830 | # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set | 837 | # Common options for tftp/tftpd |
831 | # CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set | 838 | # |
839 | CONFIG_FEATURE_TFTP_GET=y | ||
840 | CONFIG_FEATURE_TFTP_PUT=y | ||
841 | CONFIG_FEATURE_TFTP_BLOCKSIZE=y | ||
842 | CONFIG_FEATURE_TFTP_PROGRESS_BAR=y | ||
832 | # CONFIG_TFTP_DEBUG is not set | 843 | # CONFIG_TFTP_DEBUG is not set |
833 | # CONFIG_TRACEROUTE is not set | 844 | # CONFIG_TRACEROUTE is not set |
834 | # CONFIG_TRACEROUTE6 is not set | 845 | # CONFIG_TRACEROUTE6 is not set |
@@ -852,8 +863,8 @@ CONFIG_FEATURE_UDHCP_8021Q=y | |||
852 | CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" | 863 | CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" |
853 | CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 | 864 | CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 |
854 | CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n" | 865 | CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n" |
855 | # CONFIG_UDPSVD is not set | 866 | CONFIG_UDPSVD=y |
856 | # CONFIG_VCONFIG is not set | 867 | CONFIG_VCONFIG=y |
857 | CONFIG_WGET=y | 868 | CONFIG_WGET=y |
858 | CONFIG_FEATURE_WGET_STATUSBAR=y | 869 | CONFIG_FEATURE_WGET_STATUSBAR=y |
859 | CONFIG_FEATURE_WGET_AUTHENTICATION=y | 870 | CONFIG_FEATURE_WGET_AUTHENTICATION=y |
@@ -890,7 +901,9 @@ CONFIG_POWERTOP=y | |||
890 | CONFIG_PSTREE=y | 901 | CONFIG_PSTREE=y |
891 | CONFIG_PWDX=y | 902 | CONFIG_PWDX=y |
892 | CONFIG_SMEMCAP=y | 903 | CONFIG_SMEMCAP=y |
893 | # CONFIG_FREE is not set | 904 | CONFIG_UPTIME=y |
905 | # CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set | ||
906 | CONFIG_FREE=y | ||
894 | CONFIG_FUSER=y | 907 | CONFIG_FUSER=y |
895 | # CONFIG_KILL is not set | 908 | # CONFIG_KILL is not set |
896 | # CONFIG_KILLALL is not set | 909 | # CONFIG_KILLALL is not set |
@@ -900,10 +913,11 @@ CONFIG_PIDOF=y | |||
900 | CONFIG_FEATURE_PIDOF_SINGLE=y | 913 | CONFIG_FEATURE_PIDOF_SINGLE=y |
901 | CONFIG_FEATURE_PIDOF_OMIT=y | 914 | CONFIG_FEATURE_PIDOF_OMIT=y |
902 | # CONFIG_PKILL is not set | 915 | # CONFIG_PKILL is not set |
903 | # CONFIG_PS is not set | 916 | CONFIG_PS=y |
904 | # CONFIG_FEATURE_PS_WIDE is not set | 917 | # CONFIG_FEATURE_PS_WIDE is not set |
905 | # CONFIG_FEATURE_PS_TIME is not set | 918 | # CONFIG_FEATURE_PS_LONG is not set |
906 | # CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set | 919 | CONFIG_FEATURE_PS_TIME=y |
920 | CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y | ||
907 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set | 921 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set |
908 | CONFIG_RENICE=y | 922 | CONFIG_RENICE=y |
909 | CONFIG_BB_SYSCTL=y | 923 | CONFIG_BB_SYSCTL=y |
@@ -915,7 +929,6 @@ CONFIG_FEATURE_TOP_DECIMALS=y | |||
915 | CONFIG_FEATURE_TOP_SMP_PROCESS=y | 929 | CONFIG_FEATURE_TOP_SMP_PROCESS=y |
916 | CONFIG_FEATURE_TOPMEM=y | 930 | CONFIG_FEATURE_TOPMEM=y |
917 | CONFIG_FEATURE_SHOW_THREADS=y | 931 | CONFIG_FEATURE_SHOW_THREADS=y |
918 | # CONFIG_UPTIME is not set | ||
919 | CONFIG_WATCH=y | 932 | CONFIG_WATCH=y |
920 | 933 | ||
921 | # | 934 | # |
diff --git a/configs/cygwin_defconfig b/configs/cygwin_defconfig index cc2d643e1..bdd0d66d0 100644 --- a/configs/cygwin_defconfig +++ b/configs/cygwin_defconfig | |||
@@ -92,7 +92,7 @@ CONFIG_PREFIX="./_install" | |||
92 | # CONFIG_FEATURE_SYSTEMD is not set | 92 | # CONFIG_FEATURE_SYSTEMD is not set |
93 | CONFIG_FEATURE_RTMINMAX=y | 93 | CONFIG_FEATURE_RTMINMAX=y |
94 | CONFIG_PASSWORD_MINLEN=6 | 94 | CONFIG_PASSWORD_MINLEN=6 |
95 | CONFIG_MD5_SIZE_VS_SPEED=2 | 95 | CONFIG_MD5_SMALL=1 |
96 | CONFIG_FEATURE_FAST_TOP=y | 96 | CONFIG_FEATURE_FAST_TOP=y |
97 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 97 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
98 | CONFIG_FEATURE_USE_TERMIOS=y | 98 | CONFIG_FEATURE_USE_TERMIOS=y |
diff --git a/configs/freebsd_defconfig b/configs/freebsd_defconfig index 5f2985be1..dcb5d953c 100644 --- a/configs/freebsd_defconfig +++ b/configs/freebsd_defconfig | |||
@@ -90,7 +90,7 @@ CONFIG_PREFIX="./_install" | |||
90 | # Busybox Library Tuning | 90 | # Busybox Library Tuning |
91 | # | 91 | # |
92 | CONFIG_PASSWORD_MINLEN=6 | 92 | CONFIG_PASSWORD_MINLEN=6 |
93 | CONFIG_MD5_SIZE_VS_SPEED=2 | 93 | CONFIG_MD5_SMALL=1 |
94 | CONFIG_FEATURE_FAST_TOP=y | 94 | CONFIG_FEATURE_FAST_TOP=y |
95 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 95 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
96 | CONFIG_FEATURE_USE_TERMIOS=y | 96 | CONFIG_FEATURE_USE_TERMIOS=y |
diff --git a/coreutils/Config.src b/coreutils/Config.src index cff2ce216..81be71993 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src | |||
@@ -269,13 +269,6 @@ config FEATURE_FANCY_HEAD | |||
269 | help | 269 | help |
270 | This enables the head options (-c, -q, and -v). | 270 | This enables the head options (-c, -q, and -v). |
271 | 271 | ||
272 | config HOSTID | ||
273 | bool "hostid" | ||
274 | default y | ||
275 | help | ||
276 | hostid prints the numeric identifier (in hexadecimal) for | ||
277 | the current host. | ||
278 | |||
279 | config INSTALL | 272 | config INSTALL |
280 | bool "install" | 273 | bool "install" |
281 | default y | 274 | default y |
diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src index 53d88b391..d6453f014 100644 --- a/coreutils/Kbuild.src +++ b/coreutils/Kbuild.src | |||
@@ -36,7 +36,6 @@ lib-$(CONFIG_FALSE) += false.o | |||
36 | lib-$(CONFIG_FOLD) += fold.o | 36 | lib-$(CONFIG_FOLD) += fold.o |
37 | lib-$(CONFIG_FSYNC) += fsync.o | 37 | lib-$(CONFIG_FSYNC) += fsync.o |
38 | lib-$(CONFIG_HEAD) += head.o | 38 | lib-$(CONFIG_HEAD) += head.o |
39 | lib-$(CONFIG_HOSTID) += hostid.o | ||
40 | lib-$(CONFIG_INSTALL) += install.o | 39 | lib-$(CONFIG_INSTALL) += install.o |
41 | #lib-$(CONFIG_LENGTH) += length.o | 40 | #lib-$(CONFIG_LENGTH) += length.o |
42 | lib-$(CONFIG_LN) += ln.o | 41 | lib-$(CONFIG_LN) += ln.o |
diff --git a/coreutils/du.c b/coreutils/du.c index b8bbe3d9e..34a549f02 100644 --- a/coreutils/du.c +++ b/coreutils/du.c | |||
@@ -88,6 +88,7 @@ struct globals { | |||
88 | dev_t dir_dev; | 88 | dev_t dir_dev; |
89 | } FIX_ALIASING; | 89 | } FIX_ALIASING; |
90 | #define G (*(struct globals*)&bb_common_bufsiz1) | 90 | #define G (*(struct globals*)&bb_common_bufsiz1) |
91 | #define INIT_G() do { } while (0) | ||
91 | 92 | ||
92 | 93 | ||
93 | static void print(unsigned long size, const char *filename) | 94 | static void print(unsigned long size, const char *filename) |
@@ -193,6 +194,8 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |||
193 | int slink_depth_save; | 194 | int slink_depth_save; |
194 | unsigned opt; | 195 | unsigned opt; |
195 | 196 | ||
197 | INIT_G(); | ||
198 | |||
196 | #if ENABLE_FEATURE_HUMAN_READABLE | 199 | #if ENABLE_FEATURE_HUMAN_READABLE |
197 | IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;) | 200 | IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;) |
198 | IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;) | 201 | IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;) |
diff --git a/coreutils/expr.c b/coreutils/expr.c index 24e75b556..c986f9327 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c | |||
@@ -100,6 +100,7 @@ struct globals { | |||
100 | char **args; | 100 | char **args; |
101 | } FIX_ALIASING; | 101 | } FIX_ALIASING; |
102 | #define G (*(struct globals*)&bb_common_bufsiz1) | 102 | #define G (*(struct globals*)&bb_common_bufsiz1) |
103 | #define INIT_G() do { } while (0) | ||
103 | 104 | ||
104 | /* forward declarations */ | 105 | /* forward declarations */ |
105 | static VALUE *eval(void); | 106 | static VALUE *eval(void); |
@@ -519,6 +520,8 @@ int expr_main(int argc UNUSED_PARAM, char **argv) | |||
519 | { | 520 | { |
520 | VALUE *v; | 521 | VALUE *v; |
521 | 522 | ||
523 | INIT_G(); | ||
524 | |||
522 | xfunc_error_retval = 2; /* coreutils compat */ | 525 | xfunc_error_retval = 2; /* coreutils compat */ |
523 | G.args = argv + 1; | 526 | G.args = argv + 1; |
524 | if (*G.args == NULL) { | 527 | if (*G.args == NULL) { |
diff --git a/coreutils/hostid.c b/coreutils/hostid.c index 49409b9de..5c1a4e086 100644 --- a/coreutils/hostid.c +++ b/coreutils/hostid.c | |||
@@ -9,6 +9,17 @@ | |||
9 | 9 | ||
10 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ | 10 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ |
11 | 11 | ||
12 | //config:config HOSTID | ||
13 | //config: bool "hostid" | ||
14 | //config: default y | ||
15 | //config: help | ||
16 | //config: hostid prints the numeric identifier (in hexadecimal) for | ||
17 | //config: the current host. | ||
18 | |||
19 | //applet:IF_HOSTID(APPLET_NOFORK(hostid, hostid, BB_DIR_USR_BIN, BB_SUID_DROP, hostid)) | ||
20 | |||
21 | //kbuild:lib-$(CONFIG_HOSTID) += hostid.o | ||
22 | |||
12 | //usage:#define hostid_trivial_usage | 23 | //usage:#define hostid_trivial_usage |
13 | //usage: "" | 24 | //usage: "" |
14 | //usage:#define hostid_full_usage "\n\n" | 25 | //usage:#define hostid_full_usage "\n\n" |
@@ -25,7 +36,7 @@ int hostid_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
25 | bb_show_usage(); | 36 | bb_show_usage(); |
26 | } | 37 | } |
27 | 38 | ||
28 | printf("%lx\n", gethostid()); | 39 | printf("%08lx\n", gethostid()); |
29 | 40 | ||
30 | return fflush_all(); | 41 | return fflush_all(); |
31 | } | 42 | } |
diff --git a/coreutils/pwd.c b/coreutils/pwd.c index 739b835b5..bb3ad04fc 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c | |||
@@ -20,13 +20,63 @@ | |||
20 | 20 | ||
21 | /* This is a NOFORK applet. Be very careful! */ | 21 | /* This is a NOFORK applet. Be very careful! */ |
22 | 22 | ||
23 | static int logical_getcwd(void) | ||
24 | { | ||
25 | struct stat st1; | ||
26 | struct stat st2; | ||
27 | char *wd; | ||
28 | char *p; | ||
29 | |||
30 | wd = getenv("PWD"); | ||
31 | if (!wd || wd[0] != '/') | ||
32 | return 0; | ||
33 | |||
34 | p = wd; | ||
35 | while (*p) { | ||
36 | /* doing strstr(p, "/.") by hand is smaller and faster... */ | ||
37 | if (*p++ != '/') | ||
38 | continue; | ||
39 | if (*p != '.') | ||
40 | continue; | ||
41 | /* we found "/.", skip to next char */ | ||
42 | p++; | ||
43 | if (*p == '.') | ||
44 | p++; /* we found "/.." */ | ||
45 | if (*p == '\0' || *p == '/') | ||
46 | return 0; /* "/./" or "/../" component: bad */ | ||
47 | } | ||
48 | |||
49 | if (stat(wd, &st1) != 0) | ||
50 | return 0; | ||
51 | if (stat(".", &st2) != 0) | ||
52 | return 0; | ||
53 | if (st1.st_ino != st2.st_ino) | ||
54 | return 0; | ||
55 | if (st1.st_dev != st2.st_dev) | ||
56 | return 0; | ||
57 | |||
58 | puts(wd); | ||
59 | return 1; | ||
60 | } | ||
61 | |||
23 | int pwd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 62 | int pwd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
24 | int pwd_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | 63 | int pwd_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) |
25 | { | 64 | { |
26 | char *buf; | 65 | char *buf; |
27 | 66 | ||
67 | if (ENABLE_DESKTOP) { | ||
68 | /* TODO: assume -L if $POSIXLY_CORRECT? (coreutils does that) | ||
69 | * Rationale: | ||
70 | * POSIX requires a default of -L, but most scripts expect -P | ||
71 | */ | ||
72 | unsigned opt = getopt32(argv, "LP"); | ||
73 | if ((opt & 1) && logical_getcwd()) | ||
74 | return fflush_all(); | ||
75 | } | ||
76 | |||
28 | buf = xrealloc_getcwd_or_warn(NULL); | 77 | buf = xrealloc_getcwd_or_warn(NULL); |
29 | if (buf != NULL) { | 78 | |
79 | if (buf) { | ||
30 | puts(buf); | 80 | puts(buf); |
31 | free(buf); | 81 | free(buf); |
32 | return fflush_all(); | 82 | return fflush_all(); |
diff --git a/coreutils/stty.c b/coreutils/stty.c index 7f057ead2..0668cf7be 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c | |||
@@ -1404,13 +1404,15 @@ int stty_main(int argc UNUSED_PARAM, char **argv) | |||
1404 | 1404 | ||
1405 | /* Specifying both -a and -g is an error */ | 1405 | /* Specifying both -a and -g is an error */ |
1406 | if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) == | 1406 | if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) == |
1407 | (STTY_verbose_output | STTY_recoverable_output)) | 1407 | (STTY_verbose_output | STTY_recoverable_output) |
1408 | bb_error_msg_and_die("verbose and stty-readable output styles are mutually exclusive"); | 1408 | ) { |
1409 | bb_error_msg_and_die("-a and -g are mutually exclusive"); | ||
1410 | } | ||
1409 | /* Specifying -a or -g with non-options is an error */ | 1411 | /* Specifying -a or -g with non-options is an error */ |
1410 | if (!(stty_state & STTY_noargs) | 1412 | if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) |
1411 | && (stty_state & (STTY_verbose_output | STTY_recoverable_output)) | 1413 | && !(stty_state & STTY_noargs) |
1412 | ) { | 1414 | ) { |
1413 | bb_error_msg_and_die("modes may not be set when specifying an output style"); | 1415 | bb_error_msg_and_die("modes may not be set when -a or -g is used"); |
1414 | } | 1416 | } |
1415 | 1417 | ||
1416 | /* Now it is safe to start doing things */ | 1418 | /* Now it is safe to start doing things */ |
diff --git a/coreutils/tail.c b/coreutils/tail.c index 454c25936..b376ec863 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
@@ -62,6 +62,7 @@ struct globals { | |||
62 | bool exitcode; | 62 | bool exitcode; |
63 | } FIX_ALIASING; | 63 | } FIX_ALIASING; |
64 | #define G (*(struct globals*)&bb_common_bufsiz1) | 64 | #define G (*(struct globals*)&bb_common_bufsiz1) |
65 | #define INIT_G() do { } while (0) | ||
65 | 66 | ||
66 | static void tail_xprint_header(const char *fmt, const char *filename) | 67 | static void tail_xprint_header(const char *fmt, const char *filename) |
67 | { | 68 | { |
@@ -120,6 +121,8 @@ int tail_main(int argc, char **argv) | |||
120 | int *fds; | 121 | int *fds; |
121 | const char *fmt; | 122 | const char *fmt; |
122 | 123 | ||
124 | INIT_G(); | ||
125 | |||
123 | #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL | 126 | #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL |
124 | /* Allow legacy syntax of an initial numeric option without -n. */ | 127 | /* Allow legacy syntax of an initial numeric option without -n. */ |
125 | if (argv[1] && (argv[1][0] == '+' || argv[1][0] == '-') | 128 | if (argv[1] && (argv[1][0] == '+' || argv[1][0] == '-') |
@@ -203,7 +206,7 @@ int tail_main(int argc, char **argv) | |||
203 | int fd = fds[i]; | 206 | int fd = fds[i]; |
204 | 207 | ||
205 | if (ENABLE_FEATURE_FANCY_TAIL && fd < 0) | 208 | if (ENABLE_FEATURE_FANCY_TAIL && fd < 0) |
206 | continue; /* may happen with -E */ | 209 | continue; /* may happen with -F */ |
207 | 210 | ||
208 | if (nfiles > header_threshhold) { | 211 | if (nfiles > header_threshhold) { |
209 | tail_xprint_header(fmt, argv[i]); | 212 | tail_xprint_header(fmt, argv[i]); |
@@ -252,14 +255,14 @@ int tail_main(int argc, char **argv) | |||
252 | * Used only by +N code ("start from Nth", 1-based): */ | 255 | * Used only by +N code ("start from Nth", 1-based): */ |
253 | seen = 1; | 256 | seen = 1; |
254 | newlines_seen = 0; | 257 | newlines_seen = 0; |
255 | while ((nread = tail_read(fd, buf, tailbufsize-taillen)) > 0) { | 258 | while ((nread = tail_read(fd, buf, tailbufsize - taillen)) > 0) { |
256 | if (G.from_top) { | 259 | if (G.from_top) { |
257 | int nwrite = nread; | 260 | int nwrite = nread; |
258 | if (seen < count) { | 261 | if (seen < count) { |
259 | /* We need to skip a few more bytes/lines */ | 262 | /* We need to skip a few more bytes/lines */ |
260 | if (COUNT_BYTES) { | 263 | if (COUNT_BYTES) { |
261 | nwrite -= (count - seen); | 264 | nwrite -= (count - seen); |
262 | seen = count; | 265 | seen += nread; |
263 | } else { | 266 | } else { |
264 | char *s = buf; | 267 | char *s = buf; |
265 | do { | 268 | do { |
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index 6ecfe6cef..23ff711fa 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c | |||
@@ -125,10 +125,11 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv) | |||
125 | mode = bb_strtou(line_ptr, NULL, 8); | 125 | mode = bb_strtou(line_ptr, NULL, 8); |
126 | if (outname == NULL) { | 126 | if (outname == NULL) { |
127 | outname = strchr(line_ptr, ' '); | 127 | outname = strchr(line_ptr, ' '); |
128 | if ((outname == NULL) || (*outname == '\0')) { | 128 | if (!outname) |
129 | break; | 129 | break; |
130 | } | ||
131 | outname++; | 130 | outname++; |
131 | if (!outname[0]) | ||
132 | break; | ||
132 | } | 133 | } |
133 | dst_stream = stdout; | 134 | dst_stream = stdout; |
134 | if (NOT_LONE_DASH(outname)) { | 135 | if (NOT_LONE_DASH(outname)) { |
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index 65cbfc338..8f08f6dc6 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c | |||
@@ -66,6 +66,7 @@ struct globals { | |||
66 | #define names (G.names) | 66 | #define names (G.names) |
67 | #define cur (G.cur ) | 67 | #define cur (G.cur ) |
68 | #define cmd (G.cmd ) | 68 | #define cmd (G.cmd ) |
69 | #define INIT_G() do { } while (0) | ||
69 | 70 | ||
70 | enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 }; | 71 | enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 }; |
71 | 72 | ||
@@ -143,6 +144,8 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv) | |||
143 | unsigned n; | 144 | unsigned n; |
144 | int ret; | 145 | int ret; |
145 | 146 | ||
147 | INIT_G(); | ||
148 | |||
146 | #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS | 149 | #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS |
147 | applet_long_options = runparts_longopts; | 150 | applet_long_options = runparts_longopts; |
148 | #endif | 151 | #endif |
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index bc61959d2..02609c04f 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
@@ -502,8 +502,16 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
502 | if (opt & OPT_c) { | 502 | if (opt & OPT_c) { |
503 | struct bb_uidgid_t ugid = { -1, -1 }; | 503 | struct bb_uidgid_t ugid = { -1, -1 }; |
504 | parse_chown_usergroup_or_die(&ugid, chuid); | 504 | parse_chown_usergroup_or_die(&ugid, chuid); |
505 | if (ugid.gid != (gid_t) -1) xsetgid(ugid.gid); | 505 | if (ugid.uid != (uid_t) -1) { |
506 | if (ugid.uid != (uid_t) -1) xsetuid(ugid.uid); | 506 | struct passwd *pw = xgetpwuid(ugid.uid); |
507 | if (ugid.gid != (gid_t) -1) | ||
508 | pw->pw_gid = ugid.gid; | ||
509 | /* initgroups, setgid, setuid: */ | ||
510 | change_identity(pw); | ||
511 | } else if (ugid.gid != (gid_t) -1) { | ||
512 | xsetgid(ugid.gid); | ||
513 | setgroups(1, &ugid.gid); | ||
514 | } | ||
507 | } | 515 | } |
508 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY | 516 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY |
509 | if (opt & OPT_NICELEVEL) { | 517 | if (opt & OPT_NICELEVEL) { |
diff --git a/docs/ctty.htm b/docs/ctty.htm index 8f466cdde..3cb2dd2bd 100644 --- a/docs/ctty.htm +++ b/docs/ctty.htm | |||
@@ -9,6 +9,8 @@ | |||
9 | 9 | ||
10 | <p>Before looking at the Linux implementation, first a general Unix | 10 | <p>Before looking at the Linux implementation, first a general Unix |
11 | description of threads, processes, process groups and sessions. | 11 | description of threads, processes, process groups and sessions. |
12 | </p><p> | ||
13 | (See also <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap11.html">General Terminal Interface</a>) | ||
12 | </p><p>A session contains a number of process groups, and a process group | 14 | </p><p>A session contains a number of process groups, and a process group |
13 | contains a number of processes, and a process contains a number | 15 | contains a number of processes, and a process contains a number |
14 | of threads. | 16 | of threads. |
@@ -277,6 +279,7 @@ and inspect it by | |||
277 | Again, if TOSTOP is set but the background process ignores or blocks | 279 | Again, if TOSTOP is set but the background process ignores or blocks |
278 | the SIGTTOU signal, or if its process group is orphaned (see below), | 280 | the SIGTTOU signal, or if its process group is orphaned (see below), |
279 | then the write() returns an EIO error, and no signal is sent. | 281 | then the write() returns an EIO error, and no signal is sent. |
282 | [vda: correction. SUS says that if SIGTTOU is blocked/ignored, write succeeds. ] | ||
280 | <p> | 283 | <p> |
281 | </p><h3>Orphaned process groups</h3> | 284 | </p><h3>Orphaned process groups</h3> |
282 | 285 | ||
diff --git a/docs/mdev.txt b/docs/mdev.txt index 2d03bd8b2..61f93c9df 100644 --- a/docs/mdev.txt +++ b/docs/mdev.txt | |||
@@ -51,19 +51,25 @@ device nodes if your system needs something more than the default root/root | |||
51 | 660 permissions. | 51 | 660 permissions. |
52 | 52 | ||
53 | The file has the format: | 53 | The file has the format: |
54 | <device regex> <uid>:<gid> <permissions> | 54 | [-]<device regex> <uid>:<gid> <permissions> |
55 | or @<maj[,min1[-min2]]> <uid>:<gid> <permissions> | 55 | or |
56 | @<maj[,min1[-min2]]> <uid>:<gid> <permissions> | ||
57 | or | ||
58 | $envvar=<regex> <uid>:<gid> <permissions> | ||
56 | 59 | ||
57 | For example: | 60 | For example: |
58 | hd[a-z][0-9]* 0:3 660 | 61 | hd[a-z][0-9]* 0:3 660 |
59 | 62 | ||
60 | The config file parsing stops at the first matching line. If no line is | 63 | The config file parsing stops at the first matching line. If no line is |
61 | matched, then the default of 0:0 660 is used. To set your own default, simply | 64 | matched, then the default of 0:0 660 is used. To set your own default, simply |
62 | create your own total match like so: | 65 | create your own total match like so: |
66 | |||
63 | .* 1:1 777 | 67 | .* 1:1 777 |
64 | 68 | ||
65 | You can rename/move device nodes by using the next optional field. | 69 | You can rename/move device nodes by using the next optional field. |
70 | |||
66 | <device regex> <uid>:<gid> <permissions> [=path] | 71 | <device regex> <uid>:<gid> <permissions> [=path] |
72 | |||
67 | So if you want to place the device node into a subdirectory, make sure the path | 73 | So if you want to place the device node into a subdirectory, make sure the path |
68 | has a trailing /. If you want to rename the device node, just place the name. | 74 | has a trailing /. If you want to rename the device node, just place the name. |
69 | hda 0:3 660 =drives/ | 75 | hda 0:3 660 =drives/ |
diff --git a/e2fsprogs/tune2fs.c b/e2fsprogs/tune2fs.c index 9daec542a..020bdaa33 100644 --- a/e2fsprogs/tune2fs.c +++ b/e2fsprogs/tune2fs.c | |||
@@ -28,12 +28,13 @@ do { \ | |||
28 | (sizeof(field) == 4 ? SWAP_LE32(field) : BUG_wrong_field_size()) | 28 | (sizeof(field) == 4 ? SWAP_LE32(field) : BUG_wrong_field_size()) |
29 | 29 | ||
30 | //usage:#define tune2fs_trivial_usage | 30 | //usage:#define tune2fs_trivial_usage |
31 | //usage: "[-c MOUNT_CNT] " | 31 | //usage: "[-c MAX_MOUNT_COUNT] " |
32 | ////usage: "[-e errors-behavior] [-g group] " | 32 | ////usage: "[-e errors-behavior] [-g group] " |
33 | //usage: "[-i DAYS] " | 33 | //usage: "[-i DAYS] " |
34 | ////usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] " | 34 | ////usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] " |
35 | ////usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] " | 35 | ////usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] " |
36 | ////usage: "[-r reserved-blocks-count] [-u user] [-C mount-count] " | 36 | ////usage: "[-r reserved-blocks-count] [-u user] " |
37 | //usage: "[-C MOUNT_COUNT] " | ||
37 | //usage: "[-L LABEL] " | 38 | //usage: "[-L LABEL] " |
38 | ////usage: "[-M last-mounted-dir] [-O [^]feature[,...]] " | 39 | ////usage: "[-M last-mounted-dir] [-O [^]feature[,...]] " |
39 | ////usage: "[-T last-check-time] [-U UUID] " | 40 | ////usage: "[-T last-check-time] [-U UUID] " |
@@ -46,18 +47,19 @@ enum { | |||
46 | OPT_L = 1 << 0, // label | 47 | OPT_L = 1 << 0, // label |
47 | OPT_c = 1 << 1, // max mount count | 48 | OPT_c = 1 << 1, // max mount count |
48 | OPT_i = 1 << 2, // check interval | 49 | OPT_i = 1 << 2, // check interval |
50 | OPT_C = 1 << 3, // current mount count | ||
49 | }; | 51 | }; |
50 | 52 | ||
51 | int tune2fs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 53 | int tune2fs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
52 | int tune2fs_main(int argc UNUSED_PARAM, char **argv) | 54 | int tune2fs_main(int argc UNUSED_PARAM, char **argv) |
53 | { | 55 | { |
54 | unsigned opts; | 56 | unsigned opts; |
55 | const char *label, *str_c, *str_i; | 57 | const char *label, *str_c, *str_i, *str_C; |
56 | struct ext2_super_block *sb; | 58 | struct ext2_super_block *sb; |
57 | int fd; | 59 | int fd; |
58 | 60 | ||
59 | opt_complementary = "=1"; | 61 | opt_complementary = "=1"; |
60 | opts = getopt32(argv, "L:c:i:", &label, &str_c, &str_i); | 62 | opts = getopt32(argv, "L:c:i:C:", &label, &str_c, &str_i, &str_C); |
61 | if (!opts) | 63 | if (!opts) |
62 | bb_show_usage(); | 64 | bb_show_usage(); |
63 | argv += optind; // argv[0] -- device | 65 | argv += optind; // argv[0] -- device |
@@ -71,6 +73,11 @@ int tune2fs_main(int argc UNUSED_PARAM, char **argv) | |||
71 | // mangle superblock | 73 | // mangle superblock |
72 | //STORE_LE(sb->s_wtime, time(NULL)); - why bother? | 74 | //STORE_LE(sb->s_wtime, time(NULL)); - why bother? |
73 | 75 | ||
76 | if (opts & OPT_C) { | ||
77 | int n = xatoi_range(str_C, 1, 0xfffe); | ||
78 | STORE_LE(sb->s_mnt_count, (unsigned)n); | ||
79 | } | ||
80 | |||
74 | // set the label | 81 | // set the label |
75 | if (opts & OPT_L) | 82 | if (opts & OPT_L) |
76 | safe_strncpy((char *)sb->s_volume_name, label, sizeof(sb->s_volume_name)); | 83 | safe_strncpy((char *)sb->s_volume_name, label, sizeof(sb->s_volume_name)); |
diff --git a/editors/awk.c b/editors/awk.c index 7685546e5..71abca215 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * to perform debug printfs to stderr: */ | 25 | * to perform debug printfs to stderr: */ |
26 | #define debug_printf_walker(...) do {} while (0) | 26 | #define debug_printf_walker(...) do {} while (0) |
27 | #define debug_printf_eval(...) do {} while (0) | 27 | #define debug_printf_eval(...) do {} while (0) |
28 | #define debug_printf_parse(...) do {} while (0) | ||
28 | 29 | ||
29 | #ifndef debug_printf_walker | 30 | #ifndef debug_printf_walker |
30 | # define debug_printf_walker(...) (fprintf(stderr, __VA_ARGS__)) | 31 | # define debug_printf_walker(...) (fprintf(stderr, __VA_ARGS__)) |
@@ -32,6 +33,9 @@ | |||
32 | #ifndef debug_printf_eval | 33 | #ifndef debug_printf_eval |
33 | # define debug_printf_eval(...) (fprintf(stderr, __VA_ARGS__)) | 34 | # define debug_printf_eval(...) (fprintf(stderr, __VA_ARGS__)) |
34 | #endif | 35 | #endif |
36 | #ifndef debug_printf_parse | ||
37 | # define debug_printf_parse(...) (fprintf(stderr, __VA_ARGS__)) | ||
38 | #endif | ||
35 | 39 | ||
36 | 40 | ||
37 | 41 | ||
@@ -238,6 +242,9 @@ typedef struct tsplitter_s { | |||
238 | * For builtins it has different meaning: n n s3 s2 s1 v3 v2 v1, | 242 | * For builtins it has different meaning: n n s3 s2 s1 v3 v2 v1, |
239 | * n - min. number of args, vN - resolve Nth arg to var, sN - resolve to string | 243 | * n - min. number of args, vN - resolve Nth arg to var, sN - resolve to string |
240 | */ | 244 | */ |
245 | #undef P | ||
246 | #undef PRIMASK | ||
247 | #undef PRIMASK2 | ||
241 | #define P(x) (x << 24) | 248 | #define P(x) (x << 24) |
242 | #define PRIMASK 0x7F000000 | 249 | #define PRIMASK 0x7F000000 |
243 | #define PRIMASK2 0x7E000000 | 250 | #define PRIMASK2 0x7E000000 |
@@ -432,13 +439,13 @@ struct globals { | |||
432 | smallint nextrec; | 439 | smallint nextrec; |
433 | smallint nextfile; | 440 | smallint nextfile; |
434 | smallint is_f0_split; | 441 | smallint is_f0_split; |
442 | smallint t_rollback; | ||
435 | }; | 443 | }; |
436 | struct globals2 { | 444 | struct globals2 { |
437 | uint32_t t_info; /* often used */ | 445 | uint32_t t_info; /* often used */ |
438 | uint32_t t_tclass; | 446 | uint32_t t_tclass; |
439 | char *t_string; | 447 | char *t_string; |
440 | int t_lineno; | 448 | int t_lineno; |
441 | int t_rollback; | ||
442 | 449 | ||
443 | var *intvar[NUM_INTERNAL_VARS]; /* often used */ | 450 | var *intvar[NUM_INTERNAL_VARS]; /* often used */ |
444 | 451 | ||
@@ -496,11 +503,11 @@ struct globals2 { | |||
496 | #define nextrec (G1.nextrec ) | 503 | #define nextrec (G1.nextrec ) |
497 | #define nextfile (G1.nextfile ) | 504 | #define nextfile (G1.nextfile ) |
498 | #define is_f0_split (G1.is_f0_split ) | 505 | #define is_f0_split (G1.is_f0_split ) |
506 | #define t_rollback (G1.t_rollback ) | ||
499 | #define t_info (G.t_info ) | 507 | #define t_info (G.t_info ) |
500 | #define t_tclass (G.t_tclass ) | 508 | #define t_tclass (G.t_tclass ) |
501 | #define t_string (G.t_string ) | 509 | #define t_string (G.t_string ) |
502 | #define t_lineno (G.t_lineno ) | 510 | #define t_lineno (G.t_lineno ) |
503 | #define t_rollback (G.t_rollback ) | ||
504 | #define intvar (G.intvar ) | 511 | #define intvar (G.intvar ) |
505 | #define fsplitter (G.fsplitter ) | 512 | #define fsplitter (G.fsplitter ) |
506 | #define rsplitter (G.rsplitter ) | 513 | #define rsplitter (G.rsplitter ) |
@@ -1008,6 +1015,7 @@ static uint32_t next_token(uint32_t expected) | |||
1008 | 1015 | ||
1009 | if (*p == '\0') { | 1016 | if (*p == '\0') { |
1010 | tc = TC_EOF; | 1017 | tc = TC_EOF; |
1018 | debug_printf_parse("%s: token found: TC_EOF\n", __func__); | ||
1011 | 1019 | ||
1012 | } else if (*p == '\"') { | 1020 | } else if (*p == '\"') { |
1013 | /* it's a string */ | 1021 | /* it's a string */ |
@@ -1023,6 +1031,7 @@ static uint32_t next_token(uint32_t expected) | |||
1023 | p++; | 1031 | p++; |
1024 | *s = '\0'; | 1032 | *s = '\0'; |
1025 | tc = TC_STRING; | 1033 | tc = TC_STRING; |
1034 | debug_printf_parse("%s: token found:'%s' TC_STRING\n", __func__, t_string); | ||
1026 | 1035 | ||
1027 | } else if ((expected & TC_REGEXP) && *p == '/') { | 1036 | } else if ((expected & TC_REGEXP) && *p == '/') { |
1028 | /* it's regexp */ | 1037 | /* it's regexp */ |
@@ -1045,6 +1054,7 @@ static uint32_t next_token(uint32_t expected) | |||
1045 | p++; | 1054 | p++; |
1046 | *s = '\0'; | 1055 | *s = '\0'; |
1047 | tc = TC_REGEXP; | 1056 | tc = TC_REGEXP; |
1057 | debug_printf_parse("%s: token found:'%s' TC_REGEXP\n", __func__, t_string); | ||
1048 | 1058 | ||
1049 | } else if (*p == '.' || isdigit(*p)) { | 1059 | } else if (*p == '.' || isdigit(*p)) { |
1050 | /* it's a number */ | 1060 | /* it's a number */ |
@@ -1054,6 +1064,7 @@ static uint32_t next_token(uint32_t expected) | |||
1054 | if (*p == '.') | 1064 | if (*p == '.') |
1055 | syntax_error(EMSG_UNEXP_TOKEN); | 1065 | syntax_error(EMSG_UNEXP_TOKEN); |
1056 | tc = TC_NUMBER; | 1066 | tc = TC_NUMBER; |
1067 | debug_printf_parse("%s: token found:%f TC_NUMBER\n", __func__, t_double); | ||
1057 | 1068 | ||
1058 | } else { | 1069 | } else { |
1059 | /* search for something known */ | 1070 | /* search for something known */ |
@@ -1076,6 +1087,7 @@ static uint32_t next_token(uint32_t expected) | |||
1076 | ) { | 1087 | ) { |
1077 | /* then this is what we are looking for */ | 1088 | /* then this is what we are looking for */ |
1078 | t_info = *ti; | 1089 | t_info = *ti; |
1090 | debug_printf_parse("%s: token found:'%.*s' t_info:%x\n", __func__, l, p, t_info); | ||
1079 | p += l; | 1091 | p += l; |
1080 | goto token_found; | 1092 | goto token_found; |
1081 | } | 1093 | } |
@@ -1099,14 +1111,17 @@ static uint32_t next_token(uint32_t expected) | |||
1099 | p = skip_spaces(p); | 1111 | p = skip_spaces(p); |
1100 | if (*p == '(') { | 1112 | if (*p == '(') { |
1101 | tc = TC_FUNCTION; | 1113 | tc = TC_FUNCTION; |
1114 | debug_printf_parse("%s: token found:'%s' TC_FUNCTION\n", __func__, t_string); | ||
1102 | } else { | 1115 | } else { |
1103 | if (*p == '[') { | 1116 | if (*p == '[') { |
1104 | p++; | 1117 | p++; |
1105 | tc = TC_ARRAY; | 1118 | tc = TC_ARRAY; |
1106 | } | 1119 | debug_printf_parse("%s: token found:'%s' TC_ARRAY\n", __func__, t_string); |
1120 | } else | ||
1121 | debug_printf_parse("%s: token found:'%s' TC_VARIABLE\n", __func__, t_string); | ||
1107 | } | 1122 | } |
1108 | token_found: ; | ||
1109 | } | 1123 | } |
1124 | token_found: | ||
1110 | g_pos = p; | 1125 | g_pos = p; |
1111 | 1126 | ||
1112 | /* skipping newlines in some cases */ | 1127 | /* skipping newlines in some cases */ |
@@ -1178,6 +1193,8 @@ static node *parse_expr(uint32_t iexp) | |||
1178 | uint32_t tc, xtc; | 1193 | uint32_t tc, xtc; |
1179 | var *v; | 1194 | var *v; |
1180 | 1195 | ||
1196 | debug_printf_parse("%s(%x)\n", __func__, iexp); | ||
1197 | |||
1181 | sn.info = PRIMASK; | 1198 | sn.info = PRIMASK; |
1182 | sn.r.n = glptr = NULL; | 1199 | sn.r.n = glptr = NULL; |
1183 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; | 1200 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; |
@@ -1186,12 +1203,14 @@ static node *parse_expr(uint32_t iexp) | |||
1186 | 1203 | ||
1187 | if (glptr && (t_info == (OC_COMPARE | VV | P(39) | 2))) { | 1204 | if (glptr && (t_info == (OC_COMPARE | VV | P(39) | 2))) { |
1188 | /* input redirection (<) attached to glptr node */ | 1205 | /* input redirection (<) attached to glptr node */ |
1206 | debug_printf_parse("%s: input redir\n", __func__); | ||
1189 | cn = glptr->l.n = new_node(OC_CONCAT | SS | P(37)); | 1207 | cn = glptr->l.n = new_node(OC_CONCAT | SS | P(37)); |
1190 | cn->a.n = glptr; | 1208 | cn->a.n = glptr; |
1191 | xtc = TC_OPERAND | TC_UOPPRE; | 1209 | xtc = TC_OPERAND | TC_UOPPRE; |
1192 | glptr = NULL; | 1210 | glptr = NULL; |
1193 | 1211 | ||
1194 | } else if (tc & (TC_BINOP | TC_UOPPOST)) { | 1212 | } else if (tc & (TC_BINOP | TC_UOPPOST)) { |
1213 | debug_printf_parse("%s: TC_BINOP | TC_UOPPOST\n", __func__); | ||
1195 | /* for binary and postfix-unary operators, jump back over | 1214 | /* for binary and postfix-unary operators, jump back over |
1196 | * previous operators with higher priority */ | 1215 | * previous operators with higher priority */ |
1197 | vn = cn; | 1216 | vn = cn; |
@@ -1221,6 +1240,7 @@ static node *parse_expr(uint32_t iexp) | |||
1221 | vn->a.n = cn; | 1240 | vn->a.n = cn; |
1222 | 1241 | ||
1223 | } else { | 1242 | } else { |
1243 | debug_printf_parse("%s: other\n", __func__); | ||
1224 | /* for operands and prefix-unary operators, attach them | 1244 | /* for operands and prefix-unary operators, attach them |
1225 | * to last node */ | 1245 | * to last node */ |
1226 | vn = cn; | 1246 | vn = cn; |
@@ -1228,12 +1248,14 @@ static node *parse_expr(uint32_t iexp) | |||
1228 | cn->a.n = vn; | 1248 | cn->a.n = vn; |
1229 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP; | 1249 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP; |
1230 | if (tc & (TC_OPERAND | TC_REGEXP)) { | 1250 | if (tc & (TC_OPERAND | TC_REGEXP)) { |
1251 | debug_printf_parse("%s: TC_OPERAND | TC_REGEXP\n", __func__); | ||
1231 | xtc = TC_UOPPRE | TC_UOPPOST | TC_BINOP | TC_OPERAND | iexp; | 1252 | xtc = TC_UOPPRE | TC_UOPPOST | TC_BINOP | TC_OPERAND | iexp; |
1232 | /* one should be very careful with switch on tclass - | 1253 | /* one should be very careful with switch on tclass - |
1233 | * only simple tclasses should be used! */ | 1254 | * only simple tclasses should be used! */ |
1234 | switch (tc) { | 1255 | switch (tc) { |
1235 | case TC_VARIABLE: | 1256 | case TC_VARIABLE: |
1236 | case TC_ARRAY: | 1257 | case TC_ARRAY: |
1258 | debug_printf_parse("%s: TC_VARIABLE | TC_ARRAY\n", __func__); | ||
1237 | cn->info = OC_VAR; | 1259 | cn->info = OC_VAR; |
1238 | v = hash_search(ahash, t_string); | 1260 | v = hash_search(ahash, t_string); |
1239 | if (v != NULL) { | 1261 | if (v != NULL) { |
@@ -1250,6 +1272,7 @@ static node *parse_expr(uint32_t iexp) | |||
1250 | 1272 | ||
1251 | case TC_NUMBER: | 1273 | case TC_NUMBER: |
1252 | case TC_STRING: | 1274 | case TC_STRING: |
1275 | debug_printf_parse("%s: TC_NUMBER | TC_STRING\n", __func__); | ||
1253 | cn->info = OC_VAR; | 1276 | cn->info = OC_VAR; |
1254 | v = cn->l.v = xzalloc(sizeof(var)); | 1277 | v = cn->l.v = xzalloc(sizeof(var)); |
1255 | if (tc & TC_NUMBER) | 1278 | if (tc & TC_NUMBER) |
@@ -1259,32 +1282,41 @@ static node *parse_expr(uint32_t iexp) | |||
1259 | break; | 1282 | break; |
1260 | 1283 | ||
1261 | case TC_REGEXP: | 1284 | case TC_REGEXP: |
1285 | debug_printf_parse("%s: TC_REGEXP\n", __func__); | ||
1262 | mk_re_node(t_string, cn, xzalloc(sizeof(regex_t)*2)); | 1286 | mk_re_node(t_string, cn, xzalloc(sizeof(regex_t)*2)); |
1263 | break; | 1287 | break; |
1264 | 1288 | ||
1265 | case TC_FUNCTION: | 1289 | case TC_FUNCTION: |
1290 | debug_printf_parse("%s: TC_FUNCTION\n", __func__); | ||
1266 | cn->info = OC_FUNC; | 1291 | cn->info = OC_FUNC; |
1267 | cn->r.f = newfunc(t_string); | 1292 | cn->r.f = newfunc(t_string); |
1268 | cn->l.n = condition(); | 1293 | cn->l.n = condition(); |
1269 | break; | 1294 | break; |
1270 | 1295 | ||
1271 | case TC_SEQSTART: | 1296 | case TC_SEQSTART: |
1297 | debug_printf_parse("%s: TC_SEQSTART\n", __func__); | ||
1272 | cn = vn->r.n = parse_expr(TC_SEQTERM); | 1298 | cn = vn->r.n = parse_expr(TC_SEQTERM); |
1299 | if (!cn) | ||
1300 | syntax_error("Empty sequence"); | ||
1273 | cn->a.n = vn; | 1301 | cn->a.n = vn; |
1274 | break; | 1302 | break; |
1275 | 1303 | ||
1276 | case TC_GETLINE: | 1304 | case TC_GETLINE: |
1305 | debug_printf_parse("%s: TC_GETLINE\n", __func__); | ||
1277 | glptr = cn; | 1306 | glptr = cn; |
1278 | xtc = TC_OPERAND | TC_UOPPRE | TC_BINOP | iexp; | 1307 | xtc = TC_OPERAND | TC_UOPPRE | TC_BINOP | iexp; |
1279 | break; | 1308 | break; |
1280 | 1309 | ||
1281 | case TC_BUILTIN: | 1310 | case TC_BUILTIN: |
1311 | debug_printf_parse("%s: TC_BUILTIN\n", __func__); | ||
1282 | cn->l.n = condition(); | 1312 | cn->l.n = condition(); |
1283 | break; | 1313 | break; |
1284 | } | 1314 | } |
1285 | } | 1315 | } |
1286 | } | 1316 | } |
1287 | } | 1317 | } |
1318 | |||
1319 | debug_printf_parse("%s() returns %p\n", __func__, sn.r.n); | ||
1288 | return sn.r.n; | 1320 | return sn.r.n; |
1289 | } | 1321 | } |
1290 | 1322 | ||
@@ -1353,18 +1385,25 @@ static void chain_group(void) | |||
1353 | } while (c & TC_NEWLINE); | 1385 | } while (c & TC_NEWLINE); |
1354 | 1386 | ||
1355 | if (c & TC_GRPSTART) { | 1387 | if (c & TC_GRPSTART) { |
1388 | debug_printf_parse("%s: TC_GRPSTART\n", __func__); | ||
1356 | while (next_token(TC_GRPSEQ | TC_GRPTERM) != TC_GRPTERM) { | 1389 | while (next_token(TC_GRPSEQ | TC_GRPTERM) != TC_GRPTERM) { |
1390 | debug_printf_parse("%s: !TC_GRPTERM\n", __func__); | ||
1357 | if (t_tclass & TC_NEWLINE) | 1391 | if (t_tclass & TC_NEWLINE) |
1358 | continue; | 1392 | continue; |
1359 | rollback_token(); | 1393 | rollback_token(); |
1360 | chain_group(); | 1394 | chain_group(); |
1361 | } | 1395 | } |
1396 | debug_printf_parse("%s: TC_GRPTERM\n", __func__); | ||
1362 | } else if (c & (TC_OPSEQ | TC_OPTERM)) { | 1397 | } else if (c & (TC_OPSEQ | TC_OPTERM)) { |
1398 | debug_printf_parse("%s: TC_OPSEQ | TC_OPTERM\n", __func__); | ||
1363 | rollback_token(); | 1399 | rollback_token(); |
1364 | chain_expr(OC_EXEC | Vx); | 1400 | chain_expr(OC_EXEC | Vx); |
1365 | } else { /* TC_STATEMNT */ | 1401 | } else { |
1402 | /* TC_STATEMNT */ | ||
1403 | debug_printf_parse("%s: TC_STATEMNT(?)\n", __func__); | ||
1366 | switch (t_info & OPCLSMASK) { | 1404 | switch (t_info & OPCLSMASK) { |
1367 | case ST_IF: | 1405 | case ST_IF: |
1406 | debug_printf_parse("%s: ST_IF\n", __func__); | ||
1368 | n = chain_node(OC_BR | Vx); | 1407 | n = chain_node(OC_BR | Vx); |
1369 | n->l.n = condition(); | 1408 | n->l.n = condition(); |
1370 | chain_group(); | 1409 | chain_group(); |
@@ -1379,12 +1418,14 @@ static void chain_group(void) | |||
1379 | break; | 1418 | break; |
1380 | 1419 | ||
1381 | case ST_WHILE: | 1420 | case ST_WHILE: |
1421 | debug_printf_parse("%s: ST_WHILE\n", __func__); | ||
1382 | n2 = condition(); | 1422 | n2 = condition(); |
1383 | n = chain_loop(NULL); | 1423 | n = chain_loop(NULL); |
1384 | n->l.n = n2; | 1424 | n->l.n = n2; |
1385 | break; | 1425 | break; |
1386 | 1426 | ||
1387 | case ST_DO: | 1427 | case ST_DO: |
1428 | debug_printf_parse("%s: ST_DO\n", __func__); | ||
1388 | n2 = chain_node(OC_EXEC); | 1429 | n2 = chain_node(OC_EXEC); |
1389 | n = chain_loop(NULL); | 1430 | n = chain_loop(NULL); |
1390 | n2->a.n = n->a.n; | 1431 | n2->a.n = n->a.n; |
@@ -1393,6 +1434,7 @@ static void chain_group(void) | |||
1393 | break; | 1434 | break; |
1394 | 1435 | ||
1395 | case ST_FOR: | 1436 | case ST_FOR: |
1437 | debug_printf_parse("%s: ST_FOR\n", __func__); | ||
1396 | next_token(TC_SEQSTART); | 1438 | next_token(TC_SEQSTART); |
1397 | n2 = parse_expr(TC_SEMICOL | TC_SEQTERM); | 1439 | n2 = parse_expr(TC_SEMICOL | TC_SEQTERM); |
1398 | if (t_tclass & TC_SEQTERM) { /* for-in */ | 1440 | if (t_tclass & TC_SEQTERM) { /* for-in */ |
@@ -1418,6 +1460,7 @@ static void chain_group(void) | |||
1418 | 1460 | ||
1419 | case OC_PRINT: | 1461 | case OC_PRINT: |
1420 | case OC_PRINTF: | 1462 | case OC_PRINTF: |
1463 | debug_printf_parse("%s: OC_PRINT[F]\n", __func__); | ||
1421 | n = chain_node(t_info); | 1464 | n = chain_node(t_info); |
1422 | n->l.n = parse_expr(TC_OPTERM | TC_OUTRDR | TC_GRPTERM); | 1465 | n->l.n = parse_expr(TC_OPTERM | TC_OUTRDR | TC_GRPTERM); |
1423 | if (t_tclass & TC_OUTRDR) { | 1466 | if (t_tclass & TC_OUTRDR) { |
@@ -1429,17 +1472,20 @@ static void chain_group(void) | |||
1429 | break; | 1472 | break; |
1430 | 1473 | ||
1431 | case OC_BREAK: | 1474 | case OC_BREAK: |
1475 | debug_printf_parse("%s: OC_BREAK\n", __func__); | ||
1432 | n = chain_node(OC_EXEC); | 1476 | n = chain_node(OC_EXEC); |
1433 | n->a.n = break_ptr; | 1477 | n->a.n = break_ptr; |
1434 | break; | 1478 | break; |
1435 | 1479 | ||
1436 | case OC_CONTINUE: | 1480 | case OC_CONTINUE: |
1481 | debug_printf_parse("%s: OC_CONTINUE\n", __func__); | ||
1437 | n = chain_node(OC_EXEC); | 1482 | n = chain_node(OC_EXEC); |
1438 | n->a.n = continue_ptr; | 1483 | n->a.n = continue_ptr; |
1439 | break; | 1484 | break; |
1440 | 1485 | ||
1441 | /* delete, next, nextfile, return, exit */ | 1486 | /* delete, next, nextfile, return, exit */ |
1442 | default: | 1487 | default: |
1488 | debug_printf_parse("%s: default\n", __func__); | ||
1443 | chain_expr(t_info); | 1489 | chain_expr(t_info); |
1444 | } | 1490 | } |
1445 | } | 1491 | } |
@@ -1457,19 +1503,24 @@ static void parse_program(char *p) | |||
1457 | while ((tclass = next_token(TC_EOF | TC_OPSEQ | TC_GRPSTART | | 1503 | while ((tclass = next_token(TC_EOF | TC_OPSEQ | TC_GRPSTART | |
1458 | TC_OPTERM | TC_BEGIN | TC_END | TC_FUNCDECL)) != TC_EOF) { | 1504 | TC_OPTERM | TC_BEGIN | TC_END | TC_FUNCDECL)) != TC_EOF) { |
1459 | 1505 | ||
1460 | if (tclass & TC_OPTERM) | 1506 | if (tclass & TC_OPTERM) { |
1507 | debug_printf_parse("%s: TC_OPTERM\n", __func__); | ||
1461 | continue; | 1508 | continue; |
1509 | } | ||
1462 | 1510 | ||
1463 | seq = &mainseq; | 1511 | seq = &mainseq; |
1464 | if (tclass & TC_BEGIN) { | 1512 | if (tclass & TC_BEGIN) { |
1513 | debug_printf_parse("%s: TC_BEGIN\n", __func__); | ||
1465 | seq = &beginseq; | 1514 | seq = &beginseq; |
1466 | chain_group(); | 1515 | chain_group(); |
1467 | 1516 | ||
1468 | } else if (tclass & TC_END) { | 1517 | } else if (tclass & TC_END) { |
1518 | debug_printf_parse("%s: TC_END\n", __func__); | ||
1469 | seq = &endseq; | 1519 | seq = &endseq; |
1470 | chain_group(); | 1520 | chain_group(); |
1471 | 1521 | ||
1472 | } else if (tclass & TC_FUNCDECL) { | 1522 | } else if (tclass & TC_FUNCDECL) { |
1523 | debug_printf_parse("%s: TC_FUNCDECL\n", __func__); | ||
1473 | next_token(TC_FUNCTION); | 1524 | next_token(TC_FUNCTION); |
1474 | g_pos++; | 1525 | g_pos++; |
1475 | f = newfunc(t_string); | 1526 | f = newfunc(t_string); |
@@ -1487,22 +1538,27 @@ static void parse_program(char *p) | |||
1487 | clear_array(ahash); | 1538 | clear_array(ahash); |
1488 | 1539 | ||
1489 | } else if (tclass & TC_OPSEQ) { | 1540 | } else if (tclass & TC_OPSEQ) { |
1541 | debug_printf_parse("%s: TC_OPSEQ\n", __func__); | ||
1490 | rollback_token(); | 1542 | rollback_token(); |
1491 | cn = chain_node(OC_TEST); | 1543 | cn = chain_node(OC_TEST); |
1492 | cn->l.n = parse_expr(TC_OPTERM | TC_EOF | TC_GRPSTART); | 1544 | cn->l.n = parse_expr(TC_OPTERM | TC_EOF | TC_GRPSTART); |
1493 | if (t_tclass & TC_GRPSTART) { | 1545 | if (t_tclass & TC_GRPSTART) { |
1546 | debug_printf_parse("%s: TC_GRPSTART\n", __func__); | ||
1494 | rollback_token(); | 1547 | rollback_token(); |
1495 | chain_group(); | 1548 | chain_group(); |
1496 | } else { | 1549 | } else { |
1550 | debug_printf_parse("%s: !TC_GRPSTART\n", __func__); | ||
1497 | chain_node(OC_PRINT); | 1551 | chain_node(OC_PRINT); |
1498 | } | 1552 | } |
1499 | cn->r.n = mainseq.last; | 1553 | cn->r.n = mainseq.last; |
1500 | 1554 | ||
1501 | } else /* if (tclass & TC_GRPSTART) */ { | 1555 | } else /* if (tclass & TC_GRPSTART) */ { |
1556 | debug_printf_parse("%s: TC_GRPSTART(?)\n", __func__); | ||
1502 | rollback_token(); | 1557 | rollback_token(); |
1503 | chain_group(); | 1558 | chain_group(); |
1504 | } | 1559 | } |
1505 | } | 1560 | } |
1561 | debug_printf_parse("%s: TC_EOF\n", __func__); | ||
1506 | } | 1562 | } |
1507 | 1563 | ||
1508 | 1564 | ||
@@ -2627,7 +2683,7 @@ static var *evaluate(node *op, var *res) | |||
2627 | rsm = iF; | 2683 | rsm = iF; |
2628 | } | 2684 | } |
2629 | 2685 | ||
2630 | if (!rsm->F) { | 2686 | if (!rsm || !rsm->F) { |
2631 | setvar_i(intvar[ERRNO], errno); | 2687 | setvar_i(intvar[ERRNO], errno); |
2632 | setvar_i(res, -1); | 2688 | setvar_i(res, -1); |
2633 | break; | 2689 | break; |
@@ -2961,7 +3017,7 @@ static rstream *next_input_file(void) | |||
2961 | #define rsm (G.next_input_file__rsm) | 3017 | #define rsm (G.next_input_file__rsm) |
2962 | #define files_happen (G.next_input_file__files_happen) | 3018 | #define files_happen (G.next_input_file__files_happen) |
2963 | 3019 | ||
2964 | FILE *F = NULL; | 3020 | FILE *F; |
2965 | const char *fname, *ind; | 3021 | const char *fname, *ind; |
2966 | 3022 | ||
2967 | if (rsm.F) | 3023 | if (rsm.F) |
@@ -2969,19 +3025,21 @@ static rstream *next_input_file(void) | |||
2969 | rsm.F = NULL; | 3025 | rsm.F = NULL; |
2970 | rsm.pos = rsm.adv = 0; | 3026 | rsm.pos = rsm.adv = 0; |
2971 | 3027 | ||
2972 | do { | 3028 | for (;;) { |
2973 | if (getvar_i(intvar[ARGIND])+1 >= getvar_i(intvar[ARGC])) { | 3029 | if (getvar_i(intvar[ARGIND])+1 >= getvar_i(intvar[ARGC])) { |
2974 | if (files_happen) | 3030 | if (files_happen) |
2975 | return NULL; | 3031 | return NULL; |
2976 | fname = "-"; | 3032 | fname = "-"; |
2977 | F = stdin; | 3033 | F = stdin; |
2978 | } else { | 3034 | break; |
2979 | ind = getvar_s(incvar(intvar[ARGIND])); | ||
2980 | fname = getvar_s(findvar(iamarray(intvar[ARGV]), ind)); | ||
2981 | if (fname && *fname && !is_assignment(fname)) | ||
2982 | F = xfopen_stdin(fname); | ||
2983 | } | 3035 | } |
2984 | } while (!F); | 3036 | ind = getvar_s(incvar(intvar[ARGIND])); |
3037 | fname = getvar_s(findvar(iamarray(intvar[ARGV]), ind)); | ||
3038 | if (fname && *fname && !is_assignment(fname)) { | ||
3039 | F = xfopen_stdin(fname); | ||
3040 | break; | ||
3041 | } | ||
3042 | } | ||
2985 | 3043 | ||
2986 | files_happen = TRUE; | 3044 | files_happen = TRUE; |
2987 | setvar_s(intvar[FILENAME], fname); | 3045 | setvar_s(intvar[FILENAME], fname); |
@@ -2995,7 +3053,7 @@ int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
2995 | int awk_main(int argc, char **argv) | 3053 | int awk_main(int argc, char **argv) |
2996 | { | 3054 | { |
2997 | unsigned opt; | 3055 | unsigned opt; |
2998 | char *opt_F, *opt_W; | 3056 | char *opt_F; |
2999 | llist_t *list_v = NULL; | 3057 | llist_t *list_v = NULL; |
3000 | llist_t *list_f = NULL; | 3058 | llist_t *list_f = NULL; |
3001 | int i, j; | 3059 | int i, j; |
@@ -3057,7 +3115,7 @@ int awk_main(int argc, char **argv) | |||
3057 | } | 3115 | } |
3058 | } | 3116 | } |
3059 | opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ | 3117 | opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ |
3060 | opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, &opt_W); | 3118 | opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, NULL); |
3061 | argv += optind; | 3119 | argv += optind; |
3062 | argc -= optind; | 3120 | argc -= optind; |
3063 | if (opt & 0x1) | 3121 | if (opt & 0x1) |
@@ -3091,7 +3149,7 @@ int awk_main(int argc, char **argv) | |||
3091 | parse_program(*argv++); | 3149 | parse_program(*argv++); |
3092 | } | 3150 | } |
3093 | if (opt & 0x8) // -W | 3151 | if (opt & 0x8) // -W |
3094 | bb_error_msg("warning: unrecognized option '-W %s' ignored", opt_W); | 3152 | bb_error_msg("warning: option -W is ignored"); |
3095 | 3153 | ||
3096 | /* fill in ARGV array */ | 3154 | /* fill in ARGV array */ |
3097 | setvar_i(intvar[ARGC], argc); | 3155 | setvar_i(intvar[ARGC], argc); |
diff --git a/editors/patch.c b/editors/patch.c index ec5b8e7ad..13785ef46 100644 --- a/editors/patch.c +++ b/editors/patch.c | |||
@@ -70,8 +70,7 @@ struct double_list { | |||
70 | 70 | ||
71 | // Free all the elements of a linked list | 71 | // Free all the elements of a linked list |
72 | // Call freeit() on each element before freeing it. | 72 | // Call freeit() on each element before freeing it. |
73 | static | 73 | static void dlist_free(struct double_list *list, void (*freeit)(void *data)) |
74 | void dlist_free(struct double_list *list, void (*freeit)(void *data)) | ||
75 | { | 74 | { |
76 | while (list) { | 75 | while (list) { |
77 | void *pop = list; | 76 | void *pop = list; |
@@ -83,8 +82,7 @@ void dlist_free(struct double_list *list, void (*freeit)(void *data)) | |||
83 | } | 82 | } |
84 | 83 | ||
85 | // Add an entry before "list" element in (circular) doubly linked list | 84 | // Add an entry before "list" element in (circular) doubly linked list |
86 | static | 85 | static struct double_list *dlist_add(struct double_list **list, char *data) |
87 | struct double_list *dlist_add(struct double_list **list, char *data) | ||
88 | { | 86 | { |
89 | struct double_list *llist; | 87 | struct double_list *llist; |
90 | struct double_list *line = xmalloc(sizeof(*line)); | 88 | struct double_list *line = xmalloc(sizeof(*line)); |
@@ -232,7 +230,7 @@ static int apply_one_hunk(void) | |||
232 | else matcheof = 0; | 230 | else matcheof = 0; |
233 | if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); | 231 | if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); |
234 | } | 232 | } |
235 | matcheof = matcheof < TT.context; | 233 | matcheof = !matcheof || matcheof < TT.context; |
236 | 234 | ||
237 | if (PATCH_DEBUG) fdprintf(2,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N'); | 235 | if (PATCH_DEBUG) fdprintf(2,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N'); |
238 | 236 | ||
@@ -476,19 +474,21 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
476 | 474 | ||
477 | // We're deleting oldname if new file is /dev/null (before -p) | 475 | // We're deleting oldname if new file is /dev/null (before -p) |
478 | // or if new hunk is empty (zero context) after patching | 476 | // or if new hunk is empty (zero context) after patching |
479 | if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) | 477 | if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) { |
480 | { | ||
481 | name = reverse ? newname : oldname; | 478 | name = reverse ? newname : oldname; |
482 | empty++; | 479 | empty++; |
483 | } | 480 | } |
484 | 481 | ||
485 | // handle -p path truncation. | 482 | // handle -p path truncation. |
486 | for (i=0, s = name; *s;) { | 483 | for (i = 0, s = name; *s;) { |
487 | if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break; | 484 | if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) |
488 | if (*(s++)=='/') { | 485 | break; |
489 | name = s; | 486 | if (*s++ != '/') |
490 | i++; | 487 | continue; |
491 | } | 488 | while (*s == '/') |
489 | s++; | ||
490 | i++; | ||
491 | name = s; | ||
492 | } | 492 | } |
493 | 493 | ||
494 | if (empty) { | 494 | if (empty) { |
diff --git a/editors/sed.c b/editors/sed.c index 5c4e9cc3b..c8bb503ea 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * add_input_file() adds a FILE* to the list of input files. We need to | 26 | * add_input_file() adds a FILE* to the list of input files. We need to |
27 | * know all input sources ahead of time to find the last line for the $ match. | 27 | * know all input sources ahead of time to find the last line for the $ match. |
28 | * | 28 | * |
29 | * process_files() does actual sedding, reading data lines from each input FILE * | 29 | * process_files() does actual sedding, reading data lines from each input FILE* |
30 | * (which could be stdin) and applying the sed command list (sed_cmd_head) to | 30 | * (which could be stdin) and applying the sed command list (sed_cmd_head) to |
31 | * each of the resulting lines. | 31 | * each of the resulting lines. |
32 | * | 32 | * |
@@ -57,7 +57,8 @@ | |||
57 | */ | 57 | */ |
58 | 58 | ||
59 | //usage:#define sed_trivial_usage | 59 | //usage:#define sed_trivial_usage |
60 | //usage: "[-efinr] SED_CMD [FILE]..." | 60 | //usage: "[-inr] [-f FILE]... [-e CMD]... [FILE]...\n" |
61 | //usage: "or: sed [-inr] CMD [FILE]..." | ||
61 | //usage:#define sed_full_usage "\n\n" | 62 | //usage:#define sed_full_usage "\n\n" |
62 | //usage: " -e CMD Add CMD to sed commands to be executed" | 63 | //usage: " -e CMD Add CMD to sed commands to be executed" |
63 | //usage: "\n -f FILE Add FILE contents to sed commands to be executed" | 64 | //usage: "\n -f FILE Add FILE contents to sed commands to be executed" |
@@ -75,6 +76,13 @@ | |||
75 | #include "libbb.h" | 76 | #include "libbb.h" |
76 | #include "xregex.h" | 77 | #include "xregex.h" |
77 | 78 | ||
79 | #if 0 | ||
80 | # define dbg(...) bb_error_msg(__VA_ARGS__) | ||
81 | #else | ||
82 | # define dbg(...) ((void)0) | ||
83 | #endif | ||
84 | |||
85 | |||
78 | enum { | 86 | enum { |
79 | OPT_in_place = 1 << 0, | 87 | OPT_in_place = 1 << 0, |
80 | }; | 88 | }; |
@@ -89,6 +97,7 @@ typedef struct sed_cmd_s { | |||
89 | regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */ | 97 | regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */ |
90 | regex_t *sub_match; /* For 's/sub_match/string/' */ | 98 | regex_t *sub_match; /* For 's/sub_match/string/' */ |
91 | int beg_line; /* 'sed 1p' 0 == apply commands to all lines */ | 99 | int beg_line; /* 'sed 1p' 0 == apply commands to all lines */ |
100 | int beg_line_orig; /* copy of the above, needed for -i */ | ||
92 | int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($) */ | 101 | int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($) */ |
93 | 102 | ||
94 | FILE *sw_file; /* File (sw) command writes to, -1 for none. */ | 103 | FILE *sw_file; /* File (sw) command writes to, -1 for none. */ |
@@ -123,7 +132,7 @@ struct globals { | |||
123 | regex_t *previous_regex_ptr; | 132 | regex_t *previous_regex_ptr; |
124 | 133 | ||
125 | /* linked list of sed commands */ | 134 | /* linked list of sed commands */ |
126 | sed_cmd_t sed_cmd_head, *sed_cmd_tail; | 135 | sed_cmd_t *sed_cmd_head, **sed_cmd_tail; |
127 | 136 | ||
128 | /* Linked list of append lines */ | 137 | /* Linked list of append lines */ |
129 | llist_t *append_head; | 138 | llist_t *append_head; |
@@ -148,7 +157,7 @@ struct BUG_G_too_big { | |||
148 | #if ENABLE_FEATURE_CLEAN_UP | 157 | #if ENABLE_FEATURE_CLEAN_UP |
149 | static void sed_free_and_close_stuff(void) | 158 | static void sed_free_and_close_stuff(void) |
150 | { | 159 | { |
151 | sed_cmd_t *sed_cmd = G.sed_cmd_head.next; | 160 | sed_cmd_t *sed_cmd = G.sed_cmd_head; |
152 | 161 | ||
153 | llist_free(G.append_head, free); | 162 | llist_free(G.append_head, free); |
154 | 163 | ||
@@ -599,6 +608,7 @@ static void add_cmd(const char *cmdstr) | |||
599 | 608 | ||
600 | /* first part (if present) is an address: either a '$', a number or a /regex/ */ | 609 | /* first part (if present) is an address: either a '$', a number or a /regex/ */ |
601 | cmdstr += get_address(cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); | 610 | cmdstr += get_address(cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); |
611 | sed_cmd->beg_line_orig = sed_cmd->beg_line; | ||
602 | 612 | ||
603 | /* second part (if present) will begin with a comma */ | 613 | /* second part (if present) will begin with a comma */ |
604 | if (*cmdstr == ',') { | 614 | if (*cmdstr == ',') { |
@@ -630,8 +640,8 @@ static void add_cmd(const char *cmdstr) | |||
630 | cmdstr = parse_cmd_args(sed_cmd, cmdstr); | 640 | cmdstr = parse_cmd_args(sed_cmd, cmdstr); |
631 | 641 | ||
632 | /* Add the command to the command array */ | 642 | /* Add the command to the command array */ |
633 | G.sed_cmd_tail->next = sed_cmd; | 643 | *G.sed_cmd_tail = sed_cmd; |
634 | G.sed_cmd_tail = G.sed_cmd_tail->next; | 644 | G.sed_cmd_tail = &sed_cmd->next; |
635 | } | 645 | } |
636 | 646 | ||
637 | /* If we glued multiple lines together, free the memory. */ | 647 | /* If we glued multiple lines together, free the memory. */ |
@@ -777,7 +787,7 @@ static sed_cmd_t *branch_to(char *label) | |||
777 | { | 787 | { |
778 | sed_cmd_t *sed_cmd; | 788 | sed_cmd_t *sed_cmd; |
779 | 789 | ||
780 | for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { | 790 | for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { |
781 | if (sed_cmd->cmd == ':' && sed_cmd->string && !strcmp(sed_cmd->string, label)) { | 791 | if (sed_cmd->cmd == ':' && sed_cmd->string && !strcmp(sed_cmd->string, label)) { |
782 | return sed_cmd; | 792 | return sed_cmd; |
783 | } | 793 | } |
@@ -953,24 +963,24 @@ static void process_files(void) | |||
953 | 963 | ||
954 | /* For every line, go through all the commands */ | 964 | /* For every line, go through all the commands */ |
955 | restart: | 965 | restart: |
956 | for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { | 966 | for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { |
957 | int old_matched, matched; | 967 | int old_matched, matched; |
958 | 968 | ||
959 | old_matched = sed_cmd->in_match; | 969 | old_matched = sed_cmd->in_match; |
960 | 970 | ||
961 | /* Determine if this command matches this line: */ | 971 | /* Determine if this command matches this line: */ |
962 | 972 | ||
963 | //bb_error_msg("match1:%d", sed_cmd->in_match); | 973 | dbg("match1:%d", sed_cmd->in_match); |
964 | //bb_error_msg("match2:%d", (!sed_cmd->beg_line && !sed_cmd->end_line | 974 | dbg("match2:%d", (!sed_cmd->beg_line && !sed_cmd->end_line |
965 | // && !sed_cmd->beg_match && !sed_cmd->end_match)); | 975 | && !sed_cmd->beg_match && !sed_cmd->end_match)); |
966 | //bb_error_msg("match3:%d", (sed_cmd->beg_line > 0 | 976 | dbg("match3:%d", (sed_cmd->beg_line > 0 |
967 | // && (sed_cmd->end_line || sed_cmd->end_match | 977 | && (sed_cmd->end_line || sed_cmd->end_match |
968 | // ? (sed_cmd->beg_line <= linenum) | 978 | ? (sed_cmd->beg_line <= linenum) |
969 | // : (sed_cmd->beg_line == linenum) | 979 | : (sed_cmd->beg_line == linenum) |
970 | // ) | 980 | ) |
971 | // ) | 981 | )); |
972 | //bb_error_msg("match4:%d", (beg_match(sed_cmd, pattern_space))); | 982 | dbg("match4:%d", (beg_match(sed_cmd, pattern_space))); |
973 | //bb_error_msg("match5:%d", (sed_cmd->beg_line == -1 && next_line == NULL)); | 983 | dbg("match5:%d", (sed_cmd->beg_line == -1 && next_line == NULL)); |
974 | 984 | ||
975 | /* Are we continuing a previous multi-line match? */ | 985 | /* Are we continuing a previous multi-line match? */ |
976 | sed_cmd->in_match = sed_cmd->in_match | 986 | sed_cmd->in_match = sed_cmd->in_match |
@@ -981,7 +991,14 @@ static void process_files(void) | |||
981 | || (sed_cmd->beg_line > 0 | 991 | || (sed_cmd->beg_line > 0 |
982 | && (sed_cmd->end_line || sed_cmd->end_match | 992 | && (sed_cmd->end_line || sed_cmd->end_match |
983 | /* note: even if end is numeric and is < linenum too, | 993 | /* note: even if end is numeric and is < linenum too, |
984 | * GNU sed matches! We match too */ | 994 | * GNU sed matches! We match too, therefore we don't |
995 | * check here that linenum <= end. | ||
996 | * Example: | ||
997 | * printf '1\n2\n3\n4\n' | sed -n '1{N;N;d};1p;2,3p;3p;4p' | ||
998 | * first three input lines are deleted; | ||
999 | * 4th line is matched and printed | ||
1000 | * by "2,3" (!) and by "4" ranges | ||
1001 | */ | ||
985 | ? (sed_cmd->beg_line <= linenum) /* N,end */ | 1002 | ? (sed_cmd->beg_line <= linenum) /* N,end */ |
986 | : (sed_cmd->beg_line == linenum) /* N */ | 1003 | : (sed_cmd->beg_line == linenum) /* N */ |
987 | ) | 1004 | ) |
@@ -994,16 +1011,14 @@ static void process_files(void) | |||
994 | /* Snapshot the value */ | 1011 | /* Snapshot the value */ |
995 | matched = sed_cmd->in_match; | 1012 | matched = sed_cmd->in_match; |
996 | 1013 | ||
997 | //bb_error_msg("cmd:'%c' matched:%d beg_line:%d end_line:%d linenum:%d", | 1014 | dbg("cmd:'%c' matched:%d beg_line:%d end_line:%d linenum:%d", |
998 | //sed_cmd->cmd, matched, sed_cmd->beg_line, sed_cmd->end_line, linenum); | 1015 | sed_cmd->cmd, matched, sed_cmd->beg_line, sed_cmd->end_line, linenum); |
999 | 1016 | ||
1000 | /* Is this line the end of the current match? */ | 1017 | /* Is this line the end of the current match? */ |
1001 | 1018 | ||
1002 | if (matched) { | 1019 | if (matched) { |
1003 | /* once matched, "n,xxx" range is dead, disabling it */ | 1020 | /* once matched, "n,xxx" range is dead, disabling it */ |
1004 | if (sed_cmd->beg_line > 0 | 1021 | if (sed_cmd->beg_line > 0) { |
1005 | && !(option_mask32 & OPT_in_place) /* but not for -i */ | ||
1006 | ) { | ||
1007 | sed_cmd->beg_line = -2; | 1022 | sed_cmd->beg_line = -2; |
1008 | } | 1023 | } |
1009 | sed_cmd->in_match = !( | 1024 | sed_cmd->in_match = !( |
@@ -1017,7 +1032,8 @@ static void process_files(void) | |||
1017 | /* or does this line matches our last address regex */ | 1032 | /* or does this line matches our last address regex */ |
1018 | || (sed_cmd->end_match && old_matched | 1033 | || (sed_cmd->end_match && old_matched |
1019 | && (regexec(sed_cmd->end_match, | 1034 | && (regexec(sed_cmd->end_match, |
1020 | pattern_space, 0, NULL, 0) == 0)) | 1035 | pattern_space, 0, NULL, 0) == 0) |
1036 | ) | ||
1021 | ); | 1037 | ); |
1022 | } | 1038 | } |
1023 | 1039 | ||
@@ -1407,11 +1423,12 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1407 | add_input_file(stdin); | 1423 | add_input_file(stdin); |
1408 | } else { | 1424 | } else { |
1409 | int i; | 1425 | int i; |
1410 | FILE *file; | ||
1411 | 1426 | ||
1412 | for (i = 0; argv[i]; i++) { | 1427 | for (i = 0; argv[i]; i++) { |
1413 | struct stat statbuf; | 1428 | struct stat statbuf; |
1414 | int nonstdoutfd; | 1429 | int nonstdoutfd; |
1430 | FILE *file; | ||
1431 | sed_cmd_t *sed_cmd; | ||
1415 | 1432 | ||
1416 | if (LONE_DASH(argv[i]) && !(opt & OPT_in_place)) { | 1433 | if (LONE_DASH(argv[i]) && !(opt & OPT_in_place)) { |
1417 | add_input_file(stdin); | 1434 | add_input_file(stdin); |
@@ -1423,11 +1440,13 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1423 | status = EXIT_FAILURE; | 1440 | status = EXIT_FAILURE; |
1424 | continue; | 1441 | continue; |
1425 | } | 1442 | } |
1443 | add_input_file(file); | ||
1426 | if (!(opt & OPT_in_place)) { | 1444 | if (!(opt & OPT_in_place)) { |
1427 | add_input_file(file); | ||
1428 | continue; | 1445 | continue; |
1429 | } | 1446 | } |
1430 | 1447 | ||
1448 | /* -i: process each FILE separately: */ | ||
1449 | |||
1431 | G.outname = xasprintf("%sXXXXXX", argv[i]); | 1450 | G.outname = xasprintf("%sXXXXXX", argv[i]); |
1432 | nonstdoutfd = xmkstemp(G.outname); | 1451 | nonstdoutfd = xmkstemp(G.outname); |
1433 | G.nonstdout = xfdopen_for_write(nonstdoutfd); | 1452 | G.nonstdout = xfdopen_for_write(nonstdoutfd); |
@@ -1438,15 +1457,20 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1438 | * but GNU sed 4.2.1 does not preserve them either */ | 1457 | * but GNU sed 4.2.1 does not preserve them either */ |
1439 | fchmod(nonstdoutfd, statbuf.st_mode); | 1458 | fchmod(nonstdoutfd, statbuf.st_mode); |
1440 | fchown(nonstdoutfd, statbuf.st_uid, statbuf.st_gid); | 1459 | fchown(nonstdoutfd, statbuf.st_uid, statbuf.st_gid); |
1441 | add_input_file(file); | 1460 | |
1442 | process_files(); | 1461 | process_files(); |
1443 | fclose(G.nonstdout); | 1462 | fclose(G.nonstdout); |
1444 | |||
1445 | G.nonstdout = stdout; | 1463 | G.nonstdout = stdout; |
1464 | |||
1446 | /* unlink(argv[i]); */ | 1465 | /* unlink(argv[i]); */ |
1447 | xrename(G.outname, argv[i]); | 1466 | xrename(G.outname, argv[i]); |
1448 | free(G.outname); | 1467 | free(G.outname); |
1449 | G.outname = NULL; | 1468 | G.outname = NULL; |
1469 | |||
1470 | /* Re-enable disabled range matches */ | ||
1471 | for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { | ||
1472 | sed_cmd->beg_line = sed_cmd->beg_line_orig; | ||
1473 | } | ||
1450 | } | 1474 | } |
1451 | /* Here, to handle "sed 'cmds' nonexistent_file" case we did: | 1475 | /* Here, to handle "sed 'cmds' nonexistent_file" case we did: |
1452 | * if (G.current_input_file >= G.input_file_count) | 1476 | * if (G.current_input_file >= G.input_file_count) |
diff --git a/editors/vi.c b/editors/vi.c index 9708679b4..d6d926e35 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -3072,7 +3072,6 @@ static void refresh(int full_screen) | |||
3072 | //----- Execute a Vi Command ----------------------------------- | 3072 | //----- Execute a Vi Command ----------------------------------- |
3073 | static void do_cmd(int c) | 3073 | static void do_cmd(int c) |
3074 | { | 3074 | { |
3075 | const char *msg = msg; // for compiler | ||
3076 | char *p, *q, *save_dot; | 3075 | char *p, *q, *save_dot; |
3077 | char buf[12]; | 3076 | char buf[12]; |
3078 | int dir; | 3077 | int dir; |
@@ -3081,8 +3080,8 @@ static void do_cmd(int c) | |||
3081 | 3080 | ||
3082 | // c1 = c; // quiet the compiler | 3081 | // c1 = c; // quiet the compiler |
3083 | // cnt = yf = 0; // quiet the compiler | 3082 | // cnt = yf = 0; // quiet the compiler |
3084 | // msg = p = q = save_dot = buf; // quiet the compiler | 3083 | // p = q = save_dot = buf; // quiet the compiler |
3085 | memset(buf, '\0', 12); | 3084 | memset(buf, '\0', sizeof(buf)); |
3086 | 3085 | ||
3087 | show_status_line(); | 3086 | show_status_line(); |
3088 | 3087 | ||
@@ -3198,19 +3197,18 @@ static void do_cmd(int c) | |||
3198 | case KEYCODE_LEFT: // cursor key Left | 3197 | case KEYCODE_LEFT: // cursor key Left |
3199 | case 8: // ctrl-H- move left (This may be ERASE char) | 3198 | case 8: // ctrl-H- move left (This may be ERASE char) |
3200 | case 0x7f: // DEL- move left (This may be ERASE char) | 3199 | case 0x7f: // DEL- move left (This may be ERASE char) |
3201 | if (--cmdcnt > 0) { | 3200 | do { |
3202 | do_cmd(c); | 3201 | dot_left(); |
3203 | } | 3202 | } while (--cmdcnt > 0); |
3204 | dot_left(); | ||
3205 | break; | 3203 | break; |
3206 | case 10: // Newline ^J | 3204 | case 10: // Newline ^J |
3207 | case 'j': // j- goto next line, same col | 3205 | case 'j': // j- goto next line, same col |
3208 | case KEYCODE_DOWN: // cursor key Down | 3206 | case KEYCODE_DOWN: // cursor key Down |
3209 | if (--cmdcnt > 0) { | 3207 | do { |
3210 | do_cmd(c); | 3208 | dot_next(); // go to next B-o-l |
3211 | } | 3209 | // try stay in same col |
3212 | dot_next(); // go to next B-o-l | 3210 | dot = move_to_col(dot, ccol + offset); |
3213 | dot = move_to_col(dot, ccol + offset); // try stay in same col | 3211 | } while (--cmdcnt > 0); |
3214 | break; | 3212 | break; |
3215 | case 12: // ctrl-L force redraw whole screen | 3213 | case 12: // ctrl-L force redraw whole screen |
3216 | case 18: // ctrl-R force redraw | 3214 | case 18: // ctrl-R force redraw |
@@ -3223,11 +3221,10 @@ static void do_cmd(int c) | |||
3223 | break; | 3221 | break; |
3224 | case 13: // Carriage Return ^M | 3222 | case 13: // Carriage Return ^M |
3225 | case '+': // +- goto next line | 3223 | case '+': // +- goto next line |
3226 | if (--cmdcnt > 0) { | 3224 | do { |
3227 | do_cmd(c); | 3225 | dot_next(); |
3228 | } | 3226 | dot_skip_over_ws(); |
3229 | dot_next(); | 3227 | } while (--cmdcnt > 0); |
3230 | dot_skip_over_ws(); | ||
3231 | break; | 3228 | break; |
3232 | case 21: // ctrl-U scroll up half screen | 3229 | case 21: // ctrl-U scroll up half screen |
3233 | dot_scroll((rows - 2) / 2, -1); | 3230 | dot_scroll((rows - 2) / 2, -1); |
@@ -3245,10 +3242,9 @@ static void do_cmd(int c) | |||
3245 | case ' ': // move right | 3242 | case ' ': // move right |
3246 | case 'l': // move right | 3243 | case 'l': // move right |
3247 | case KEYCODE_RIGHT: // Cursor Key Right | 3244 | case KEYCODE_RIGHT: // Cursor Key Right |
3248 | if (--cmdcnt > 0) { | 3245 | do { |
3249 | do_cmd(c); | 3246 | dot_right(); |
3250 | } | 3247 | } while (--cmdcnt > 0); |
3251 | dot_right(); | ||
3252 | break; | 3248 | break; |
3253 | #if ENABLE_FEATURE_VI_YANKMARK | 3249 | #if ENABLE_FEATURE_VI_YANKMARK |
3254 | case '"': // "- name a register to use for Delete/Yank | 3250 | case '"': // "- name a register to use for Delete/Yank |
@@ -3330,11 +3326,12 @@ static void do_cmd(int c) | |||
3330 | #endif /* FEATURE_VI_YANKMARK */ | 3326 | #endif /* FEATURE_VI_YANKMARK */ |
3331 | case '$': // $- goto end of line | 3327 | case '$': // $- goto end of line |
3332 | case KEYCODE_END: // Cursor Key End | 3328 | case KEYCODE_END: // Cursor Key End |
3333 | if (--cmdcnt > 0) { | 3329 | for (;;) { |
3330 | dot = end_line(dot); | ||
3331 | if (--cmdcnt > 0) | ||
3332 | break; | ||
3334 | dot_next(); | 3333 | dot_next(); |
3335 | do_cmd(c); | ||
3336 | } | 3334 | } |
3337 | dot = end_line(dot); | ||
3338 | break; | 3335 | break; |
3339 | case '%': // %- find matching char of pair () [] {} | 3336 | case '%': // %- find matching char of pair () [] {} |
3340 | for (q = dot; q < end && *q != '\n'; q++) { | 3337 | for (q = dot; q < end && *q != '\n'; q++) { |
@@ -3359,38 +3356,35 @@ static void do_cmd(int c) | |||
3359 | // | 3356 | // |
3360 | //**** fall through to ... ';' | 3357 | //**** fall through to ... ';' |
3361 | case ';': // ;- look at rest of line for last forward char | 3358 | case ';': // ;- look at rest of line for last forward char |
3362 | if (--cmdcnt > 0) { | 3359 | do { |
3363 | do_cmd(';'); | 3360 | if (last_forward_char == 0) |
3364 | } | 3361 | break; |
3365 | if (last_forward_char == 0) | 3362 | q = dot + 1; |
3366 | break; | 3363 | while (q < end - 1 && *q != '\n' && *q != last_forward_char) { |
3367 | q = dot + 1; | 3364 | q++; |
3368 | while (q < end - 1 && *q != '\n' && *q != last_forward_char) { | 3365 | } |
3369 | q++; | 3366 | if (*q == last_forward_char) |
3370 | } | 3367 | dot = q; |
3371 | if (*q == last_forward_char) | 3368 | } while (--cmdcnt > 0); |
3372 | dot = q; | ||
3373 | break; | 3369 | break; |
3374 | case ',': // repeat latest 'f' in opposite direction | 3370 | case ',': // repeat latest 'f' in opposite direction |
3375 | if (--cmdcnt > 0) { | ||
3376 | do_cmd(','); | ||
3377 | } | ||
3378 | if (last_forward_char == 0) | 3371 | if (last_forward_char == 0) |
3379 | break; | 3372 | break; |
3380 | q = dot - 1; | 3373 | do { |
3381 | while (q >= text && *q != '\n' && *q != last_forward_char) { | 3374 | q = dot - 1; |
3382 | q--; | 3375 | while (q >= text && *q != '\n' && *q != last_forward_char) { |
3383 | } | 3376 | q--; |
3384 | if (q >= text && *q == last_forward_char) | 3377 | } |
3385 | dot = q; | 3378 | if (q >= text && *q == last_forward_char) |
3379 | dot = q; | ||
3380 | } while (--cmdcnt > 0); | ||
3386 | break; | 3381 | break; |
3387 | 3382 | ||
3388 | case '-': // -- goto prev line | 3383 | case '-': // -- goto prev line |
3389 | if (--cmdcnt > 0) { | 3384 | do { |
3390 | do_cmd(c); | 3385 | dot_prev(); |
3391 | } | 3386 | dot_skip_over_ws(); |
3392 | dot_prev(); | 3387 | } while (--cmdcnt > 0); |
3393 | dot_skip_over_ws(); | ||
3394 | break; | 3388 | break; |
3395 | #if ENABLE_FEATURE_VI_DOT_CMD | 3389 | #if ENABLE_FEATURE_VI_DOT_CMD |
3396 | case '.': // .- repeat the last modifying command | 3390 | case '.': // .- repeat the last modifying command |
@@ -3422,9 +3416,6 @@ static void do_cmd(int c) | |||
3422 | // user changed mind and erased the "/"- do nothing | 3416 | // user changed mind and erased the "/"- do nothing |
3423 | break; | 3417 | break; |
3424 | case 'N': // N- backward search for last pattern | 3418 | case 'N': // N- backward search for last pattern |
3425 | if (--cmdcnt > 0) { | ||
3426 | do_cmd(c); | ||
3427 | } | ||
3428 | dir = BACK; // assume BACKWARD search | 3419 | dir = BACK; // assume BACKWARD search |
3429 | p = dot - 1; | 3420 | p = dot - 1; |
3430 | if (last_search_pattern[0] == '?') { | 3421 | if (last_search_pattern[0] == '?') { |
@@ -3436,41 +3427,41 @@ static void do_cmd(int c) | |||
3436 | case 'n': // n- repeat search for last pattern | 3427 | case 'n': // n- repeat search for last pattern |
3437 | // search rest of text[] starting at next char | 3428 | // search rest of text[] starting at next char |
3438 | // if search fails return orignal "p" not the "p+1" address | 3429 | // if search fails return orignal "p" not the "p+1" address |
3439 | if (--cmdcnt > 0) { | 3430 | do { |
3440 | do_cmd(c); | 3431 | const char *msg; |
3441 | } | ||
3442 | dc3: | 3432 | dc3: |
3443 | dir = FORWARD; // assume FORWARD search | 3433 | dir = FORWARD; // assume FORWARD search |
3444 | p = dot + 1; | 3434 | p = dot + 1; |
3445 | if (last_search_pattern[0] == '?') { | 3435 | if (last_search_pattern[0] == '?') { |
3446 | dir = BACK; | 3436 | dir = BACK; |
3447 | p = dot - 1; | 3437 | p = dot - 1; |
3448 | } | 3438 | } |
3449 | dc4: | 3439 | dc4: |
3450 | q = char_search(p, last_search_pattern + 1, dir, FULL); | 3440 | q = char_search(p, last_search_pattern + 1, dir, FULL); |
3451 | if (q != NULL) { | 3441 | if (q != NULL) { |
3452 | dot = q; // good search, update "dot" | 3442 | dot = q; // good search, update "dot" |
3453 | msg = ""; | 3443 | msg = NULL; |
3454 | goto dc2; | 3444 | goto dc2; |
3455 | } | 3445 | } |
3456 | // no pattern found between "dot" and "end"- continue at top | 3446 | // no pattern found between "dot" and "end"- continue at top |
3457 | p = text; | 3447 | p = text; |
3458 | if (dir == BACK) { | ||
3459 | p = end - 1; | ||
3460 | } | ||
3461 | q = char_search(p, last_search_pattern + 1, dir, FULL); | ||
3462 | if (q != NULL) { // found something | ||
3463 | dot = q; // found new pattern- goto it | ||
3464 | msg = "search hit BOTTOM, continuing at TOP"; | ||
3465 | if (dir == BACK) { | 3448 | if (dir == BACK) { |
3466 | msg = "search hit TOP, continuing at BOTTOM"; | 3449 | p = end - 1; |
3450 | } | ||
3451 | q = char_search(p, last_search_pattern + 1, dir, FULL); | ||
3452 | if (q != NULL) { // found something | ||
3453 | dot = q; // found new pattern- goto it | ||
3454 | msg = "search hit BOTTOM, continuing at TOP"; | ||
3455 | if (dir == BACK) { | ||
3456 | msg = "search hit TOP, continuing at BOTTOM"; | ||
3457 | } | ||
3458 | } else { | ||
3459 | msg = "Pattern not found"; | ||
3467 | } | 3460 | } |
3468 | } else { | ||
3469 | msg = "Pattern not found"; | ||
3470 | } | ||
3471 | dc2: | 3461 | dc2: |
3472 | if (*msg) | 3462 | if (msg) |
3473 | status_line_bold("%s", msg); | 3463 | status_line_bold("%s", msg); |
3464 | } while (--cmdcnt > 0); | ||
3474 | break; | 3465 | break; |
3475 | case '{': // {- move backward paragraph | 3466 | case '{': // {- move backward paragraph |
3476 | q = char_search(dot, "\n\n", BACK, FULL); | 3467 | q = char_search(dot, "\n\n", BACK, FULL); |
@@ -3589,18 +3580,17 @@ static void do_cmd(int c) | |||
3589 | case 'B': // B- back a blank-delimited Word | 3580 | case 'B': // B- back a blank-delimited Word |
3590 | case 'E': // E- end of a blank-delimited word | 3581 | case 'E': // E- end of a blank-delimited word |
3591 | case 'W': // W- forward a blank-delimited word | 3582 | case 'W': // W- forward a blank-delimited word |
3592 | if (--cmdcnt > 0) { | ||
3593 | do_cmd(c); | ||
3594 | } | ||
3595 | dir = FORWARD; | 3583 | dir = FORWARD; |
3596 | if (c == 'B') | 3584 | if (c == 'B') |
3597 | dir = BACK; | 3585 | dir = BACK; |
3598 | if (c == 'W' || isspace(dot[dir])) { | 3586 | do { |
3599 | dot = skip_thing(dot, 1, dir, S_TO_WS); | 3587 | if (c == 'W' || isspace(dot[dir])) { |
3600 | dot = skip_thing(dot, 2, dir, S_OVER_WS); | 3588 | dot = skip_thing(dot, 1, dir, S_TO_WS); |
3601 | } | 3589 | dot = skip_thing(dot, 2, dir, S_OVER_WS); |
3602 | if (c != 'W') | 3590 | } |
3603 | dot = skip_thing(dot, 1, dir, S_BEFORE_WS); | 3591 | if (c != 'W') |
3592 | dot = skip_thing(dot, 1, dir, S_BEFORE_WS); | ||
3593 | } while (--cmdcnt > 0); | ||
3604 | break; | 3594 | break; |
3605 | case 'C': // C- Change to e-o-l | 3595 | case 'C': // C- Change to e-o-l |
3606 | case 'D': // D- delete to e-o-l | 3596 | case 'D': // D- delete to e-o-l |
@@ -3651,20 +3641,19 @@ static void do_cmd(int c) | |||
3651 | case 'i': // i- insert before current char | 3641 | case 'i': // i- insert before current char |
3652 | case KEYCODE_INSERT: // Cursor Key Insert | 3642 | case KEYCODE_INSERT: // Cursor Key Insert |
3653 | dc_i: | 3643 | dc_i: |
3654 | cmd_mode = 1; // start insrting | 3644 | cmd_mode = 1; // start inserting |
3655 | break; | 3645 | break; |
3656 | case 'J': // J- join current and next lines together | 3646 | case 'J': // J- join current and next lines together |
3657 | if (--cmdcnt > 1) { | 3647 | do { |
3658 | do_cmd(c); | 3648 | dot_end(); // move to NL |
3659 | } | 3649 | if (dot < end - 1) { // make sure not last char in text[] |
3660 | dot_end(); // move to NL | 3650 | *dot++ = ' '; // replace NL with space |
3661 | if (dot < end - 1) { // make sure not last char in text[] | 3651 | file_modified++; |
3662 | *dot++ = ' '; // replace NL with space | 3652 | while (isblank(*dot)) { // delete leading WS |
3663 | file_modified++; | 3653 | dot_delete(); |
3664 | while (isblank(*dot)) { // delete leading WS | 3654 | } |
3665 | dot_delete(); | ||
3666 | } | 3655 | } |
3667 | } | 3656 | } while (--cmdcnt > 0); |
3668 | end_cmd_q(); // stop adding to q | 3657 | end_cmd_q(); // stop adding to q |
3669 | break; | 3658 | break; |
3670 | case 'L': // L- goto bottom line on screen | 3659 | case 'L': // L- goto bottom line on screen |
@@ -3708,20 +3697,19 @@ static void do_cmd(int c) | |||
3708 | case 'X': // X- delete char before dot | 3697 | case 'X': // X- delete char before dot |
3709 | case 'x': // x- delete the current char | 3698 | case 'x': // x- delete the current char |
3710 | case 's': // s- substitute the current char | 3699 | case 's': // s- substitute the current char |
3711 | if (--cmdcnt > 0) { | ||
3712 | do_cmd(c); | ||
3713 | } | ||
3714 | dir = 0; | 3700 | dir = 0; |
3715 | if (c == 'X') | 3701 | if (c == 'X') |
3716 | dir = -1; | 3702 | dir = -1; |
3717 | if (dot[dir] != '\n') { | 3703 | do { |
3718 | if (c == 'X') | 3704 | if (dot[dir] != '\n') { |
3719 | dot--; // delete prev char | 3705 | if (c == 'X') |
3720 | dot = yank_delete(dot, dot, 0, YANKDEL); // delete char | 3706 | dot--; // delete prev char |
3721 | } | 3707 | dot = yank_delete(dot, dot, 0, YANKDEL); // delete char |
3722 | if (c == 's') | 3708 | } |
3723 | goto dc_i; // start insrting | 3709 | } while (--cmdcnt > 0); |
3724 | end_cmd_q(); // stop adding to q | 3710 | end_cmd_q(); // stop adding to q |
3711 | if (c == 's') | ||
3712 | goto dc_i; // start inserting | ||
3725 | break; | 3713 | break; |
3726 | case 'Z': // Z- if modified, {write}; exit | 3714 | case 'Z': // Z- if modified, {write}; exit |
3727 | // ZZ means to save file (if necessary), then exit | 3715 | // ZZ means to save file (if necessary), then exit |
@@ -3752,23 +3740,22 @@ static void do_cmd(int c) | |||
3752 | break; | 3740 | break; |
3753 | case 'b': // b- back a word | 3741 | case 'b': // b- back a word |
3754 | case 'e': // e- end of word | 3742 | case 'e': // e- end of word |
3755 | if (--cmdcnt > 0) { | ||
3756 | do_cmd(c); | ||
3757 | } | ||
3758 | dir = FORWARD; | 3743 | dir = FORWARD; |
3759 | if (c == 'b') | 3744 | if (c == 'b') |
3760 | dir = BACK; | 3745 | dir = BACK; |
3761 | if ((dot + dir) < text || (dot + dir) > end - 1) | 3746 | do { |
3762 | break; | 3747 | if ((dot + dir) < text || (dot + dir) > end - 1) |
3763 | dot += dir; | 3748 | break; |
3764 | if (isspace(*dot)) { | 3749 | dot += dir; |
3765 | dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS); | 3750 | if (isspace(*dot)) { |
3766 | } | 3751 | dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS); |
3767 | if (isalnum(*dot) || *dot == '_') { | 3752 | } |
3768 | dot = skip_thing(dot, 1, dir, S_END_ALNUM); | 3753 | if (isalnum(*dot) || *dot == '_') { |
3769 | } else if (ispunct(*dot)) { | 3754 | dot = skip_thing(dot, 1, dir, S_END_ALNUM); |
3770 | dot = skip_thing(dot, 1, dir, S_END_PUNCT); | 3755 | } else if (ispunct(*dot)) { |
3771 | } | 3756 | dot = skip_thing(dot, 1, dir, S_END_PUNCT); |
3757 | } | ||
3758 | } while (--cmdcnt > 0); | ||
3772 | break; | 3759 | break; |
3773 | case 'c': // c- change something | 3760 | case 'c': // c- change something |
3774 | case 'd': // d- delete something | 3761 | case 'd': // d- delete something |
@@ -3853,11 +3840,10 @@ static void do_cmd(int c) | |||
3853 | } | 3840 | } |
3854 | case 'k': // k- goto prev line, same col | 3841 | case 'k': // k- goto prev line, same col |
3855 | case KEYCODE_UP: // cursor key Up | 3842 | case KEYCODE_UP: // cursor key Up |
3856 | if (--cmdcnt > 0) { | 3843 | do { |
3857 | do_cmd(c); | 3844 | dot_prev(); |
3858 | } | 3845 | dot = move_to_col(dot, ccol + offset); // try stay in same col |
3859 | dot_prev(); | 3846 | } while (--cmdcnt > 0); |
3860 | dot = move_to_col(dot, ccol + offset); // try stay in same col | ||
3861 | break; | 3847 | break; |
3862 | case 'r': // r- replace the current char with user input | 3848 | case 'r': // r- replace the current char with user input |
3863 | c1 = get_one_char(); // get the replacement char | 3849 | c1 = get_one_char(); // get the replacement char |
@@ -3875,19 +3861,18 @@ static void do_cmd(int c) | |||
3875 | last_forward_char = 0; | 3861 | last_forward_char = 0; |
3876 | break; | 3862 | break; |
3877 | case 'w': // w- forward a word | 3863 | case 'w': // w- forward a word |
3878 | if (--cmdcnt > 0) { | 3864 | do { |
3879 | do_cmd(c); | 3865 | if (isalnum(*dot) || *dot == '_') { // we are on ALNUM |
3880 | } | 3866 | dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM); |
3881 | if (isalnum(*dot) || *dot == '_') { // we are on ALNUM | 3867 | } else if (ispunct(*dot)) { // we are on PUNCT |
3882 | dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM); | 3868 | dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT); |
3883 | } else if (ispunct(*dot)) { // we are on PUNCT | 3869 | } |
3884 | dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT); | 3870 | if (dot < end - 1) |
3885 | } | 3871 | dot++; // move over word |
3886 | if (dot < end - 1) | 3872 | if (isspace(*dot)) { |
3887 | dot++; // move over word | 3873 | dot = skip_thing(dot, 2, FORWARD, S_OVER_WS); |
3888 | if (isspace(*dot)) { | 3874 | } |
3889 | dot = skip_thing(dot, 2, FORWARD, S_OVER_WS); | 3875 | } while (--cmdcnt > 0); |
3890 | } | ||
3891 | break; | 3876 | break; |
3892 | case 'z': // z- | 3877 | case 'z': // z- |
3893 | c1 = get_one_char(); // get the replacement char | 3878 | c1 = get_one_char(); // get the replacement char |
@@ -3903,17 +3888,16 @@ static void do_cmd(int c) | |||
3903 | dot = move_to_col(dot, cmdcnt - 1); // try to move to column | 3888 | dot = move_to_col(dot, cmdcnt - 1); // try to move to column |
3904 | break; | 3889 | break; |
3905 | case '~': // ~- flip the case of letters a-z -> A-Z | 3890 | case '~': // ~- flip the case of letters a-z -> A-Z |
3906 | if (--cmdcnt > 0) { | 3891 | do { |
3907 | do_cmd(c); | 3892 | if (islower(*dot)) { |
3908 | } | 3893 | *dot = toupper(*dot); |
3909 | if (islower(*dot)) { | 3894 | file_modified++; |
3910 | *dot = toupper(*dot); | 3895 | } else if (isupper(*dot)) { |
3911 | file_modified++; | 3896 | *dot = tolower(*dot); |
3912 | } else if (isupper(*dot)) { | 3897 | file_modified++; |
3913 | *dot = tolower(*dot); | 3898 | } |
3914 | file_modified++; | 3899 | dot_right(); |
3915 | } | 3900 | } while (--cmdcnt > 0); |
3916 | dot_right(); | ||
3917 | end_cmd_q(); // stop adding to q | 3901 | end_cmd_q(); // stop adding to q |
3918 | break; | 3902 | break; |
3919 | //----- The Cursor and Function Keys ----------------------------- | 3903 | //----- The Cursor and Function Keys ----------------------------- |
diff --git a/examples/android-build b/examples/android-build index f5fe49bda..89f3b637a 100755 --- a/examples/android-build +++ b/examples/android-build | |||
@@ -2,9 +2,10 @@ | |||
2 | # Build Busybox against Android's bionic | 2 | # Build Busybox against Android's bionic |
3 | # Originally by Dan Fandrich | 3 | # Originally by Dan Fandrich |
4 | # | 4 | # |
5 | # Configure with android_defconfig | 5 | # Configure with "make android_defconfig" |
6 | # | ||
6 | # This file has been tested on Android Froyo (the lack of ttyname_r in | 7 | # This file has been tested on Android Froyo (the lack of ttyname_r in |
7 | # the must be patched around) and Gingerbread. | 8 | # the android libc must be patched around) and Gingerbread. |
8 | 9 | ||
9 | # Point this to the Android root directory; it's used in the defconfig CFLAGS | 10 | # Point this to the Android root directory; it's used in the defconfig CFLAGS |
10 | export A="$HOME/android" | 11 | export A="$HOME/android" |
diff --git a/examples/depmod.pl b/examples/depmod.pl index f324b121a..809dc08b3 100755 --- a/examples/depmod.pl +++ b/examples/depmod.pl | |||
@@ -199,7 +199,7 @@ if ($stdout == 0) { | |||
199 | open(STDOUT, ">$basedir/modules.dep") | 199 | open(STDOUT, ">$basedir/modules.dep") |
200 | or die "cannot open $basedir/modules.dep: $!"; | 200 | or die "cannot open $basedir/modules.dep: $!"; |
201 | } | 201 | } |
202 | my $kseries = $basedir =~ m,/2\.6\.[^/]*, ? '2.6' : '2.4'; | 202 | my $kseries = $basedir =~ m,/2\.4\.[^/]*, ? '2.4' : 'others'; |
203 | 203 | ||
204 | foreach my $module ( keys %$mod ) { | 204 | foreach my $module ( keys %$mod ) { |
205 | if($kseries eq '2.4') { | 205 | if($kseries eq '2.4') { |
diff --git a/findutils/find.c b/findutils/find.c index 05f88d2f0..fc0fc5c9f 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -932,7 +932,10 @@ static action*** parse_params(char **argv) | |||
932 | * expression is reached. | 932 | * expression is reached. |
933 | */ | 933 | */ |
934 | /* Options */ | 934 | /* Options */ |
935 | if (0) { } | 935 | if (parm == OPT_FOLLOW) { |
936 | dbg("follow enabled: %d", __LINE__); | ||
937 | G.recurse_flags |= ACTION_FOLLOWLINKS | ACTION_DANGLING_OK; | ||
938 | } | ||
936 | #if ENABLE_FEATURE_FIND_XDEV | 939 | #if ENABLE_FEATURE_FIND_XDEV |
937 | else if (parm == OPT_XDEV) { | 940 | else if (parm == OPT_XDEV) { |
938 | dbg("%d", __LINE__); | 941 | dbg("%d", __LINE__); |
diff --git a/findutils/grep.c b/findutils/grep.c index fa3b8a3a9..f3463f94e 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -570,20 +570,20 @@ static char *add_grep_list_data(char *pattern) | |||
570 | 570 | ||
571 | static void load_regexes_from_file(llist_t *fopt) | 571 | static void load_regexes_from_file(llist_t *fopt) |
572 | { | 572 | { |
573 | char *line; | ||
574 | FILE *f; | ||
575 | |||
576 | while (fopt) { | 573 | while (fopt) { |
574 | char *line; | ||
575 | FILE *fp; | ||
577 | llist_t *cur = fopt; | 576 | llist_t *cur = fopt; |
578 | char *ffile = cur->data; | 577 | char *ffile = cur->data; |
579 | 578 | ||
580 | fopt = cur->link; | 579 | fopt = cur->link; |
581 | free(cur); | 580 | free(cur); |
582 | f = xfopen_stdin(ffile); | 581 | fp = xfopen_stdin(ffile); |
583 | while ((line = xmalloc_fgetline(f)) != NULL) { | 582 | while ((line = xmalloc_fgetline(fp)) != NULL) { |
584 | llist_add_to(&pattern_head, | 583 | llist_add_to(&pattern_head, |
585 | new_grep_list_data(line, ALLOCATED)); | 584 | new_grep_list_data(line, ALLOCATED)); |
586 | } | 585 | } |
586 | fclose_if_not_stdin(fp); | ||
587 | } | 587 | } |
588 | } | 588 | } |
589 | 589 | ||
@@ -667,15 +667,19 @@ int grep_main(int argc UNUSED_PARAM, char **argv) | |||
667 | #endif | 667 | #endif |
668 | invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */ | 668 | invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */ |
669 | 669 | ||
670 | if (pattern_head != NULL) { | 670 | { /* convert char **argv to grep_list_data_t */ |
671 | /* convert char **argv to grep_list_data_t */ | ||
672 | llist_t *cur; | 671 | llist_t *cur; |
673 | |||
674 | for (cur = pattern_head; cur; cur = cur->link) | 672 | for (cur = pattern_head; cur; cur = cur->link) |
675 | cur->data = new_grep_list_data(cur->data, 0); | 673 | cur->data = new_grep_list_data(cur->data, 0); |
676 | } | 674 | } |
677 | if (option_mask32 & OPT_f) | 675 | if (option_mask32 & OPT_f) { |
678 | load_regexes_from_file(fopt); | 676 | load_regexes_from_file(fopt); |
677 | if (!pattern_head) { /* -f EMPTY_FILE? */ | ||
678 | /* GNU grep treats it as "nothing matches" */ | ||
679 | llist_add_to(&pattern_head, new_grep_list_data((char*) "", 0)); | ||
680 | invert_search ^= 1; | ||
681 | } | ||
682 | } | ||
679 | 683 | ||
680 | if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f') | 684 | if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f') |
681 | option_mask32 |= OPT_F; | 685 | option_mask32 |= OPT_F; |
diff --git a/include/applets.src.h b/include/applets.src.h index 87d9cbb7b..252a060fb 100644 --- a/include/applets.src.h +++ b/include/applets.src.h | |||
@@ -176,7 +176,6 @@ IF_HD(APPLET_NOEXEC(hd, hexdump, BB_DIR_USR_BIN, BB_SUID_DROP, hd)) | |||
176 | IF_HDPARM(APPLET(hdparm, BB_DIR_SBIN, BB_SUID_DROP)) | 176 | IF_HDPARM(APPLET(hdparm, BB_DIR_SBIN, BB_SUID_DROP)) |
177 | IF_HEAD(APPLET_NOEXEC(head, head, BB_DIR_USR_BIN, BB_SUID_DROP, head)) | 177 | IF_HEAD(APPLET_NOEXEC(head, head, BB_DIR_USR_BIN, BB_SUID_DROP, head)) |
178 | IF_HEXDUMP(APPLET_NOEXEC(hexdump, hexdump, BB_DIR_USR_BIN, BB_SUID_DROP, hexdump)) | 178 | IF_HEXDUMP(APPLET_NOEXEC(hexdump, hexdump, BB_DIR_USR_BIN, BB_SUID_DROP, hexdump)) |
179 | IF_HOSTID(APPLET_NOFORK(hostid, hostid, BB_DIR_USR_BIN, BB_SUID_DROP, hostid)) | ||
180 | IF_HOSTNAME(APPLET(hostname, BB_DIR_BIN, BB_SUID_DROP)) | 179 | IF_HOSTNAME(APPLET(hostname, BB_DIR_BIN, BB_SUID_DROP)) |
181 | IF_HTTPD(APPLET(httpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 180 | IF_HTTPD(APPLET(httpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
182 | IF_HWCLOCK(APPLET(hwclock, BB_DIR_SBIN, BB_SUID_DROP)) | 181 | IF_HWCLOCK(APPLET(hwclock, BB_DIR_SBIN, BB_SUID_DROP)) |
@@ -240,7 +239,6 @@ IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP)) | |||
240 | IF_MAN(APPLET(man, BB_DIR_SBIN, BB_SUID_DROP)) | 239 | IF_MAN(APPLET(man, BB_DIR_SBIN, BB_SUID_DROP)) |
241 | IF_MATCHPATHCON(APPLET(matchpathcon, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 240 | IF_MATCHPATHCON(APPLET(matchpathcon, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
242 | IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum)) | 241 | IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum)) |
243 | IF_MDEV(APPLET(mdev, BB_DIR_SBIN, BB_SUID_DROP)) | ||
244 | IF_MICROCOM(APPLET(microcom, BB_DIR_USR_BIN, BB_SUID_DROP)) | 242 | IF_MICROCOM(APPLET(microcom, BB_DIR_USR_BIN, BB_SUID_DROP)) |
245 | IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) | 243 | IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) |
246 | IF_MKFS_VFAT(APPLET_ODDNAME(mkdosfs, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) | 244 | IF_MKFS_VFAT(APPLET_ODDNAME(mkdosfs, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) |
diff --git a/include/archive.h b/include/bb_archive.h index 9e176d335..9e176d335 100644 --- a/include/archive.h +++ b/include/bb_archive.h | |||
diff --git a/include/libbb.h b/include/libbb.h index 6e63e65f5..a6ecac932 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -32,6 +32,11 @@ | |||
32 | #include <stdarg.h> | 32 | #include <stdarg.h> |
33 | #include <stddef.h> | 33 | #include <stddef.h> |
34 | #include <string.h> | 34 | #include <string.h> |
35 | /* There are two incompatible basename's, let not use them! */ | ||
36 | /* See the dirname/basename man page for details */ | ||
37 | #include <libgen.h> /* dirname,basename */ | ||
38 | #undef basename | ||
39 | #define basename dont_use_basename | ||
35 | #include <sys/poll.h> | 40 | #include <sys/poll.h> |
36 | #include <sys/ioctl.h> | 41 | #include <sys/ioctl.h> |
37 | #include <sys/mman.h> | 42 | #include <sys/mman.h> |
@@ -142,12 +147,6 @@ int vdprintf(int d, const char *format, va_list ap); | |||
142 | #endif | 147 | #endif |
143 | /* klogctl is in libc's klog.h, but we cheat and not #include that */ | 148 | /* klogctl is in libc's klog.h, but we cheat and not #include that */ |
144 | int klogctl(int type, char *b, int len); | 149 | int klogctl(int type, char *b, int len); |
145 | /* This is declared here rather than #including <libgen.h> in order to avoid | ||
146 | * confusing the two versions of basename. See the dirname/basename man page | ||
147 | * for details. */ | ||
148 | #if !defined __FreeBSD__ | ||
149 | char *dirname(char *path); | ||
150 | #endif | ||
151 | #ifndef PATH_MAX | 150 | #ifndef PATH_MAX |
152 | # define PATH_MAX 256 | 151 | # define PATH_MAX 256 |
153 | #endif | 152 | #endif |
@@ -268,13 +267,6 @@ typedef unsigned long uoff_t; | |||
268 | #undef SKIP | 267 | #undef SKIP |
269 | #define SKIP ((int) 2) | 268 | #define SKIP ((int) 2) |
270 | 269 | ||
271 | /* for mtab.c */ | ||
272 | #define MTAB_GETMOUNTPT '1' | ||
273 | #define MTAB_GETDEVICE '2' | ||
274 | |||
275 | #define BUF_SIZE 8192 | ||
276 | #define EXPAND_ALLOC 1024 | ||
277 | |||
278 | /* Macros for min/max. */ | 270 | /* Macros for min/max. */ |
279 | #ifndef MIN | 271 | #ifndef MIN |
280 | #define MIN(a,b) (((a)<(b))?(a):(b)) | 272 | #define MIN(a,b) (((a)<(b))?(a):(b)) |
@@ -653,6 +645,7 @@ ssize_t recv_from_to(int fd, void *buf, size_t len, int flags, | |||
653 | struct sockaddr *to, | 645 | struct sockaddr *to, |
654 | socklen_t sa_size) FAST_FUNC; | 646 | socklen_t sa_size) FAST_FUNC; |
655 | 647 | ||
648 | uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC; | ||
656 | 649 | ||
657 | char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC; | 650 | char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC; |
658 | char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC; | 651 | char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC; |
@@ -697,10 +690,13 @@ void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC; | |||
697 | void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC; | 690 | void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC; |
698 | void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC; | 691 | void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC; |
699 | void *xrealloc(void *old, size_t size) FAST_FUNC; | 692 | void *xrealloc(void *old, size_t size) FAST_FUNC; |
700 | /* After xrealloc_vector(v, 4, idx) it's ok to use | 693 | /* After v = xrealloc_vector(v, SHIFT, idx) it's ok to use |
701 | * at least v[idx] and v[idx+1], for all idx values. | 694 | * at least v[idx] and v[idx+1], for all idx values. |
702 | * shift specifies how many new elements are added (1: 2, 2: 4... 8: 256...) | 695 | * SHIFT specifies how many new elements are added (1:2, 2:4, ..., 8:256...) |
703 | * when all elements are used up. New elements are zeroed out. */ | 696 | * when all elements are used up. New elements are zeroed out. |
697 | * xrealloc_vector(v, SHIFT, idx) *MUST* be called with consecutive IDXs - | ||
698 | * skipping an index is a bad bug - it may miss a realloc! | ||
699 | */ | ||
704 | #define xrealloc_vector(vector, shift, idx) \ | 700 | #define xrealloc_vector(vector, shift, idx) \ |
705 | xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx)) | 701 | xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx)) |
706 | void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC; | 702 | void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC; |
@@ -827,9 +823,9 @@ void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_F | |||
827 | const char *make_human_readable_str(unsigned long long size, | 823 | const char *make_human_readable_str(unsigned long long size, |
828 | unsigned long block_size, unsigned long display_unit) FAST_FUNC; | 824 | unsigned long block_size, unsigned long display_unit) FAST_FUNC; |
829 | /* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */ | 825 | /* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */ |
830 | char *bin2hex(char *buf, const char *cp, int count) FAST_FUNC; | 826 | char *bin2hex(char *dst, const char *src, int count) FAST_FUNC; |
831 | /* Reverse */ | 827 | /* Reverse */ |
832 | char* hex2bin(char *dst, const char *str, int count) FAST_FUNC; | 828 | char* hex2bin(char *dst, const char *src, int count) FAST_FUNC; |
833 | 829 | ||
834 | /* Generate a UUID */ | 830 | /* Generate a UUID */ |
835 | void generate_uuid(uint8_t *buf) FAST_FUNC; | 831 | void generate_uuid(uint8_t *buf) FAST_FUNC; |
@@ -1180,7 +1176,7 @@ extern int del_loop(const char *device) FAST_FUNC; | |||
1180 | /* If *devname is not NULL, use that name, otherwise try to find free one, | 1176 | /* If *devname is not NULL, use that name, otherwise try to find free one, |
1181 | * malloc and return it in *devname. | 1177 | * malloc and return it in *devname. |
1182 | * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */ | 1178 | * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */ |
1183 | extern int set_loop(char **devname, const char *file, unsigned long long offset) FAST_FUNC; | 1179 | extern int set_loop(char **devname, const char *file, unsigned long long offset, int ro) FAST_FUNC; |
1184 | 1180 | ||
1185 | /* Like bb_ask below, but asks on stdin with no timeout. */ | 1181 | /* Like bb_ask below, but asks on stdin with no timeout. */ |
1186 | char *bb_ask_stdin(const char * prompt) FAST_FUNC; | 1182 | char *bb_ask_stdin(const char * prompt) FAST_FUNC; |
@@ -1378,25 +1374,37 @@ enum { | |||
1378 | KEYCODE_DELETE = -9, | 1374 | KEYCODE_DELETE = -9, |
1379 | KEYCODE_PAGEUP = -10, | 1375 | KEYCODE_PAGEUP = -10, |
1380 | KEYCODE_PAGEDOWN = -11, | 1376 | KEYCODE_PAGEDOWN = -11, |
1381 | 1377 | // -12 is reserved for Alt/Ctrl/Shift-TAB | |
1382 | KEYCODE_CTRL_UP = KEYCODE_UP & ~0x40, | 1378 | #if 0 |
1383 | KEYCODE_CTRL_DOWN = KEYCODE_DOWN & ~0x40, | 1379 | KEYCODE_FUN1 = -13, |
1380 | KEYCODE_FUN2 = -14, | ||
1381 | KEYCODE_FUN3 = -15, | ||
1382 | KEYCODE_FUN4 = -16, | ||
1383 | KEYCODE_FUN5 = -17, | ||
1384 | KEYCODE_FUN6 = -18, | ||
1385 | KEYCODE_FUN7 = -19, | ||
1386 | KEYCODE_FUN8 = -20, | ||
1387 | KEYCODE_FUN9 = -21, | ||
1388 | KEYCODE_FUN10 = -22, | ||
1389 | KEYCODE_FUN11 = -23, | ||
1390 | KEYCODE_FUN12 = -24, | ||
1391 | #endif | ||
1392 | /* Be sure that last defined value is small enough | ||
1393 | * to not interfere with Alt/Ctrl/Shift bits. | ||
1394 | * So far we do not exceed -31 (0xfff..fffe1), | ||
1395 | * which gives us three upper bits in LSB to play with. | ||
1396 | */ | ||
1397 | //KEYCODE_SHIFT_TAB = (-12) & ~0x80, | ||
1398 | //KEYCODE_SHIFT_... = KEYCODE_... & ~0x80, | ||
1399 | //KEYCODE_CTRL_UP = KEYCODE_UP & ~0x40, | ||
1400 | //KEYCODE_CTRL_DOWN = KEYCODE_DOWN & ~0x40, | ||
1384 | KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40, | 1401 | KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40, |
1385 | KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40, | 1402 | KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40, |
1386 | #if 0 | 1403 | //KEYCODE_ALT_UP = KEYCODE_UP & ~0x20, |
1387 | KEYCODE_FUN1 = -12, | 1404 | //KEYCODE_ALT_DOWN = KEYCODE_DOWN & ~0x20, |
1388 | KEYCODE_FUN2 = -13, | 1405 | KEYCODE_ALT_RIGHT = KEYCODE_RIGHT & ~0x20, |
1389 | KEYCODE_FUN3 = -14, | 1406 | KEYCODE_ALT_LEFT = KEYCODE_LEFT & ~0x20, |
1390 | KEYCODE_FUN4 = -15, | 1407 | |
1391 | KEYCODE_FUN5 = -16, | ||
1392 | KEYCODE_FUN6 = -17, | ||
1393 | KEYCODE_FUN7 = -18, | ||
1394 | KEYCODE_FUN8 = -19, | ||
1395 | KEYCODE_FUN9 = -20, | ||
1396 | KEYCODE_FUN10 = -21, | ||
1397 | KEYCODE_FUN11 = -22, | ||
1398 | KEYCODE_FUN12 = -23, | ||
1399 | #endif | ||
1400 | KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */ | 1408 | KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */ |
1401 | /* How long is the longest ESC sequence we know? | 1409 | /* How long is the longest ESC sequence we know? |
1402 | * We want it big enough to be able to contain | 1410 | * We want it big enough to be able to contain |
@@ -1437,6 +1445,12 @@ typedef struct line_input_t { | |||
1437 | int cur_history; | 1445 | int cur_history; |
1438 | int max_history; /* must never be <= 0 */ | 1446 | int max_history; /* must never be <= 0 */ |
1439 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1447 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY |
1448 | /* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT: | ||
1449 | * if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are | ||
1450 | * in on-disk history" | ||
1451 | * if FEATURE_EDITING_SAVE_ON_EXIT: "how many in-memory lines are | ||
1452 | * also in on-disk history (and thus need to be skipped on save)" | ||
1453 | */ | ||
1440 | unsigned cnt_history_in_file; | 1454 | unsigned cnt_history_in_file; |
1441 | const char *hist_file; | 1455 | const char *hist_file; |
1442 | # endif | 1456 | # endif |
@@ -1444,13 +1458,12 @@ typedef struct line_input_t { | |||
1444 | # endif | 1458 | # endif |
1445 | } line_input_t; | 1459 | } line_input_t; |
1446 | enum { | 1460 | enum { |
1447 | DO_HISTORY = 1 * (MAX_HISTORY > 0), | 1461 | DO_HISTORY = 1 * (MAX_HISTORY > 0), |
1448 | SAVE_HISTORY = 2 * (MAX_HISTORY > 0) * ENABLE_FEATURE_EDITING_SAVEHISTORY, | 1462 | TAB_COMPLETION = 2 * ENABLE_FEATURE_TAB_COMPLETION, |
1449 | TAB_COMPLETION = 4 * ENABLE_FEATURE_TAB_COMPLETION, | 1463 | USERNAME_COMPLETION = 4 * ENABLE_FEATURE_USERNAME_COMPLETION, |
1450 | USERNAME_COMPLETION = 8 * ENABLE_FEATURE_USERNAME_COMPLETION, | 1464 | VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI, |
1451 | VI_MODE = 0x10 * ENABLE_FEATURE_EDITING_VI, | 1465 | WITH_PATH_LOOKUP = 0x10, |
1452 | WITH_PATH_LOOKUP = 0x20, | 1466 | FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION, |
1453 | FOR_SHELL = DO_HISTORY | SAVE_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION, | ||
1454 | }; | 1467 | }; |
1455 | line_input_t *new_line_input_t(int flags) FAST_FUNC; | 1468 | line_input_t *new_line_input_t(int flags) FAST_FUNC; |
1456 | /* So far static: void free_line_input_t(line_input_t *n) FAST_FUNC; */ | 1469 | /* So far static: void free_line_input_t(line_input_t *n) FAST_FUNC; */ |
@@ -1462,6 +1475,9 @@ line_input_t *new_line_input_t(int flags) FAST_FUNC; | |||
1462 | * >0 length of input string, including terminating '\n' | 1475 | * >0 length of input string, including terminating '\n' |
1463 | */ | 1476 | */ |
1464 | int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC; | 1477 | int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC; |
1478 | # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT | ||
1479 | void save_history(line_input_t *st); | ||
1480 | # endif | ||
1465 | #else | 1481 | #else |
1466 | #define MAX_HISTORY 0 | 1482 | #define MAX_HISTORY 0 |
1467 | int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; | 1483 | int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; |
@@ -1589,6 +1605,15 @@ int starts_with_cpu(const char *str) FAST_FUNC; | |||
1589 | unsigned get_cpu_count(void) FAST_FUNC; | 1605 | unsigned get_cpu_count(void) FAST_FUNC; |
1590 | 1606 | ||
1591 | 1607 | ||
1608 | /* Use strict=1 if you process input from untrusted source: | ||
1609 | * it will return NULL on invalid %xx (bad hex chars) | ||
1610 | * and str + 1 if decoded char is / or NUL. | ||
1611 | * In non-strict mode, it always succeeds (returns str), | ||
1612 | * and also it additionally decoded '+' to space. | ||
1613 | */ | ||
1614 | char *percent_decode_in_place(char *str, int strict) FAST_FUNC; | ||
1615 | |||
1616 | |||
1592 | extern const char bb_uuenc_tbl_base64[]; | 1617 | extern const char bb_uuenc_tbl_base64[]; |
1593 | extern const char bb_uuenc_tbl_std[]; | 1618 | extern const char bb_uuenc_tbl_std[]; |
1594 | void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC; | 1619 | void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC; |
@@ -1597,7 +1622,8 @@ enum { | |||
1597 | /* Sign-extends to a value which never matches fgetc result: */ | 1622 | /* Sign-extends to a value which never matches fgetc result: */ |
1598 | BASE64_FLAG_NO_STOP_CHAR = 0x80, | 1623 | BASE64_FLAG_NO_STOP_CHAR = 0x80, |
1599 | }; | 1624 | }; |
1600 | void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags); | 1625 | const char *decode_base64(char **pp_dst, const char *src) FAST_FUNC; |
1626 | void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC; | ||
1601 | 1627 | ||
1602 | typedef struct md5_ctx_t { | 1628 | typedef struct md5_ctx_t { |
1603 | uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ | 1629 | uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ |
diff --git a/include/platform.h b/include/platform.h index e22c42007..96c603c1f 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -383,7 +383,7 @@ typedef unsigned smalluint; | |||
383 | #if defined(__UCLIBC_MAJOR__) | 383 | #if defined(__UCLIBC_MAJOR__) |
384 | # if __UCLIBC_MAJOR__ == 0 \ | 384 | # if __UCLIBC_MAJOR__ == 0 \ |
385 | && ( __UCLIBC_MINOR__ < 9 \ | 385 | && ( __UCLIBC_MINOR__ < 9 \ |
386 | || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 31) \ | 386 | || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 32) \ |
387 | ) | 387 | ) |
388 | # undef HAVE_STRVERSCMP | 388 | # undef HAVE_STRVERSCMP |
389 | # endif | 389 | # endif |
@@ -451,6 +451,8 @@ typedef unsigned smalluint; | |||
451 | # undef HAVE_STRVERSCMP | 451 | # undef HAVE_STRVERSCMP |
452 | # undef HAVE_XTABS | 452 | # undef HAVE_XTABS |
453 | # undef HAVE_DPRINTF | 453 | # undef HAVE_DPRINTF |
454 | # undef HAVE_UNLOCKED_STDIO | ||
455 | # undef HAVE_UNLOCKED_LINE_OPS | ||
454 | #endif | 456 | #endif |
455 | 457 | ||
456 | #if defined(__FreeBSD__) | 458 | #if defined(__FreeBSD__) |
@@ -465,7 +467,7 @@ typedef unsigned smalluint; | |||
465 | # undef HAVE_STPCPY | 467 | # undef HAVE_STPCPY |
466 | #endif | 468 | #endif |
467 | 469 | ||
468 | #if defined(ANDROID) | 470 | #if defined(ANDROID) || defined(__ANDROID__) |
469 | # undef HAVE_DPRINTF | 471 | # undef HAVE_DPRINTF |
470 | # undef HAVE_GETLINE | 472 | # undef HAVE_GETLINE |
471 | # undef HAVE_STPCPY | 473 | # undef HAVE_STPCPY |
diff --git a/libbb/Config.src b/libbb/Config.src index aa442365a..ee1b66a45 100644 --- a/libbb/Config.src +++ b/libbb/Config.src | |||
@@ -14,9 +14,9 @@ config PASSWORD_MINLEN | |||
14 | help | 14 | help |
15 | Minimum allowable password length. | 15 | Minimum allowable password length. |
16 | 16 | ||
17 | config MD5_SIZE_VS_SPEED | 17 | config MD5_SMALL |
18 | int "MD5: Trade bytes for speed (0:fast, 3:slow)" | 18 | int "MD5: Trade bytes for speed (0:fast, 3:slow)" |
19 | default 2 | 19 | default 1 |
20 | range 0 3 | 20 | range 0 3 |
21 | help | 21 | help |
22 | Trade binary size versus speed for the md5sum algorithm. | 22 | Trade binary size versus speed for the md5sum algorithm. |
@@ -94,6 +94,13 @@ config FEATURE_EDITING_SAVEHISTORY | |||
94 | help | 94 | help |
95 | Enable history saving in shells. | 95 | Enable history saving in shells. |
96 | 96 | ||
97 | config FEATURE_EDITING_SAVE_ON_EXIT | ||
98 | bool "Save history on shell exit, not after every command" | ||
99 | default n | ||
100 | depends on FEATURE_EDITING_SAVEHISTORY | ||
101 | help | ||
102 | Save history on shell exit, not after every command. | ||
103 | |||
97 | config FEATURE_REVERSE_SEARCH | 104 | config FEATURE_REVERSE_SEARCH |
98 | bool "Reverse history search" | 105 | bool "Reverse history search" |
99 | default y | 106 | default y |
@@ -184,8 +191,8 @@ config FEATURE_SKIP_ROOTFS | |||
184 | 191 | ||
185 | However, some systems do not mount anything on /. | 192 | However, some systems do not mount anything on /. |
186 | If you need to configure busybox for one of these systems, | 193 | If you need to configure busybox for one of these systems, |
187 | you may find useful to turn this option off to make df show | 194 | you may find it useful to turn this option off to make df show |
188 | initramfs statistic. | 195 | initramfs statistics. |
189 | 196 | ||
190 | Otherwise, choose Y. | 197 | Otherwise, choose Y. |
191 | 198 | ||
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index b5e9afc78..4cb063f89 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
@@ -168,6 +168,12 @@ lib-$(CONFIG_IOSTAT) += get_cpu_count.o | |||
168 | lib-$(CONFIG_MPSTAT) += get_cpu_count.o | 168 | lib-$(CONFIG_MPSTAT) += get_cpu_count.o |
169 | lib-$(CONFIG_POWERTOP) += get_cpu_count.o | 169 | lib-$(CONFIG_POWERTOP) += get_cpu_count.o |
170 | 170 | ||
171 | lib-$(CONFIG_PING) += inet_cksum.o | ||
172 | lib-$(CONFIG_TRACEROUTE) += inet_cksum.o | ||
173 | lib-$(CONFIG_TRACEROUTE6) += inet_cksum.o | ||
174 | lib-$(CONFIG_UDHCPC) += inet_cksum.o | ||
175 | lib-$(CONFIG_UDHCPD) += inet_cksum.o | ||
176 | |||
171 | # We shouldn't build xregcomp.c if we don't need it - this ensures we don't | 177 | # We shouldn't build xregcomp.c if we don't need it - this ensures we don't |
172 | # require regex.h to be in the include dir even if we don't need it thereby | 178 | # require regex.h to be in the include dir even if we don't need it thereby |
173 | # allowing us to build busybox even if uclibc regex support is disabled. | 179 | # allowing us to build busybox even if uclibc regex support is disabled. |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 6d002b0dd..0c675db4d 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -62,7 +62,7 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; | |||
62 | #if ENABLE_FEATURE_COMPRESS_USAGE | 62 | #if ENABLE_FEATURE_COMPRESS_USAGE |
63 | 63 | ||
64 | static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; | 64 | static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; |
65 | # include "archive.h" | 65 | # include "bb_archive.h" |
66 | static const char *unpack_usage_messages(void) | 66 | static const char *unpack_usage_messages(void) |
67 | { | 67 | { |
68 | char *outbuf = NULL; | 68 | char *outbuf = NULL; |
diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c index 9a4188f52..fe2b50677 100644 --- a/libbb/bb_askpass.c +++ b/libbb/bb_askpass.c | |||
@@ -30,14 +30,23 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) | |||
30 | struct sigaction sa, oldsa; | 30 | struct sigaction sa, oldsa; |
31 | struct termios tio, oldtio; | 31 | struct termios tio, oldtio; |
32 | 32 | ||
33 | tcgetattr(fd, &oldtio); | 33 | fputs(prompt, stdout); |
34 | fflush_all(); | ||
34 | tcflush(fd, TCIFLUSH); | 35 | tcflush(fd, TCIFLUSH); |
36 | |||
37 | tcgetattr(fd, &oldtio); | ||
35 | tio = oldtio; | 38 | tio = oldtio; |
36 | #ifndef IUCLC | 39 | #if 0 |
37 | # define IUCLC 0 | 40 | /* Switch off UPPERCASE->lowercase conversion (never used since 198x) |
38 | #endif | 41 | * and XON/XOFF (why we want to mess with this??) |
42 | */ | ||
43 | # ifndef IUCLC | ||
44 | # define IUCLC 0 | ||
45 | # endif | ||
39 | tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); | 46 | tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); |
40 | tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); | 47 | #endif |
48 | /* Switch off echo */ | ||
49 | tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL); | ||
41 | tcsetattr(fd, TCSANOW, &tio); | 50 | tcsetattr(fd, TCSANOW, &tio); |
42 | 51 | ||
43 | memset(&sa, 0, sizeof(sa)); | 52 | memset(&sa, 0, sizeof(sa)); |
@@ -50,9 +59,6 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) | |||
50 | alarm(timeout); | 59 | alarm(timeout); |
51 | } | 60 | } |
52 | 61 | ||
53 | fputs(prompt, stdout); | ||
54 | fflush_all(); | ||
55 | |||
56 | if (!passwd) | 62 | if (!passwd) |
57 | passwd = xmalloc(sizeof_passwd); | 63 | passwd = xmalloc(sizeof_passwd); |
58 | ret = passwd; | 64 | ret = passwd; |
diff --git a/libbb/getpty.c b/libbb/getpty.c index 6a15cff2f..435e4d09f 100644 --- a/libbb/getpty.c +++ b/libbb/getpty.c | |||
@@ -19,20 +19,22 @@ int FAST_FUNC xgetpty(char *line) | |||
19 | if (p > 0) { | 19 | if (p > 0) { |
20 | grantpt(p); /* chmod+chown corresponding slave pty */ | 20 | grantpt(p); /* chmod+chown corresponding slave pty */ |
21 | unlockpt(p); /* (what does this do?) */ | 21 | unlockpt(p); /* (what does this do?) */ |
22 | #ifndef HAVE_PTSNAME_R | 22 | # ifndef HAVE_PTSNAME_R |
23 | const char *name; | 23 | { |
24 | name = ptsname(p); /* find out the name of slave pty */ | 24 | const char *name; |
25 | if (!name) { | 25 | name = ptsname(p); /* find out the name of slave pty */ |
26 | bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); | 26 | if (!name) { |
27 | bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); | ||
28 | } | ||
29 | safe_strncpy(line, name, GETPTY_BUFSIZE); | ||
27 | } | 30 | } |
28 | safe_strncpy(line, name, GETPTY_BUFSIZE); | 31 | # else |
29 | #else | ||
30 | /* find out the name of slave pty */ | 32 | /* find out the name of slave pty */ |
31 | if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) { | 33 | if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) { |
32 | bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); | 34 | bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); |
33 | } | 35 | } |
34 | line[GETPTY_BUFSIZE-1] = '\0'; | 36 | line[GETPTY_BUFSIZE-1] = '\0'; |
35 | #endif | 37 | # endif |
36 | return p; | 38 | return p; |
37 | } | 39 | } |
38 | #else | 40 | #else |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index b87d1dde8..a313c2a65 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -104,12 +104,12 @@ static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) | |||
104 | */ | 104 | */ |
105 | 105 | ||
106 | /* 0: fastest, 3: smallest */ | 106 | /* 0: fastest, 3: smallest */ |
107 | #if CONFIG_MD5_SIZE_VS_SPEED < 0 | 107 | #if CONFIG_MD5_SMALL < 0 |
108 | # define MD5_SIZE_VS_SPEED 0 | 108 | # define MD5_SMALL 0 |
109 | #elif CONFIG_MD5_SIZE_VS_SPEED > 3 | 109 | #elif CONFIG_MD5_SMALL > 3 |
110 | # define MD5_SIZE_VS_SPEED 3 | 110 | # define MD5_SMALL 3 |
111 | #else | 111 | #else |
112 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED | 112 | # define MD5_SMALL CONFIG_MD5_SMALL |
113 | #endif | 113 | #endif |
114 | 114 | ||
115 | /* These are the four functions used in the four steps of the MD5 algorithm | 115 | /* These are the four functions used in the four steps of the MD5 algorithm |
@@ -129,7 +129,7 @@ static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) | |||
129 | /* Hash a single block, 64 bytes long and 4-byte aligned */ | 129 | /* Hash a single block, 64 bytes long and 4-byte aligned */ |
130 | static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | 130 | static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) |
131 | { | 131 | { |
132 | #if MD5_SIZE_VS_SPEED > 0 | 132 | #if MD5_SMALL > 0 |
133 | /* Before we start, one word to the strange constants. | 133 | /* Before we start, one word to the strange constants. |
134 | They are defined in RFC 1321 as | 134 | They are defined in RFC 1321 as |
135 | T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 | 135 | T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 |
@@ -157,7 +157,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
157 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 | 157 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 |
158 | }; | 158 | }; |
159 | static const char P_array[] ALIGN1 = { | 159 | static const char P_array[] ALIGN1 = { |
160 | # if MD5_SIZE_VS_SPEED > 1 | 160 | # if MD5_SMALL > 1 |
161 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ | 161 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ |
162 | # endif | 162 | # endif |
163 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ | 163 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ |
@@ -171,7 +171,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
171 | uint32_t C = ctx->hash[2]; | 171 | uint32_t C = ctx->hash[2]; |
172 | uint32_t D = ctx->hash[3]; | 172 | uint32_t D = ctx->hash[3]; |
173 | 173 | ||
174 | #if MD5_SIZE_VS_SPEED >= 2 /* 2 or 3 */ | 174 | #if MD5_SMALL >= 2 /* 2 or 3 */ |
175 | 175 | ||
176 | static const char S_array[] ALIGN1 = { | 176 | static const char S_array[] ALIGN1 = { |
177 | 7, 12, 17, 22, | 177 | 7, 12, 17, 22, |
@@ -190,7 +190,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
190 | words[i] = SWAP_LE32(words[i]); | 190 | words[i] = SWAP_LE32(words[i]); |
191 | # endif | 191 | # endif |
192 | 192 | ||
193 | # if MD5_SIZE_VS_SPEED == 3 | 193 | # if MD5_SMALL == 3 |
194 | pc = C_array; | 194 | pc = C_array; |
195 | pp = P_array; | 195 | pp = P_array; |
196 | ps = S_array - 4; | 196 | ps = S_array - 4; |
@@ -220,7 +220,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
220 | C = B; | 220 | C = B; |
221 | B = temp; | 221 | B = temp; |
222 | } | 222 | } |
223 | # else /* MD5_SIZE_VS_SPEED == 2 */ | 223 | # else /* MD5_SMALL == 2 */ |
224 | pc = C_array; | 224 | pc = C_array; |
225 | pp = P_array; | 225 | pp = P_array; |
226 | ps = S_array; | 226 | ps = S_array; |
@@ -271,13 +271,13 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
271 | ctx->hash[2] += C; | 271 | ctx->hash[2] += C; |
272 | ctx->hash[3] += D; | 272 | ctx->hash[3] += D; |
273 | 273 | ||
274 | #else /* MD5_SIZE_VS_SPEED == 0 or 1 */ | 274 | #else /* MD5_SMALL == 0 or 1 */ |
275 | 275 | ||
276 | uint32_t A_save = A; | 276 | uint32_t A_save = A; |
277 | uint32_t B_save = B; | 277 | uint32_t B_save = B; |
278 | uint32_t C_save = C; | 278 | uint32_t C_save = C; |
279 | uint32_t D_save = D; | 279 | uint32_t D_save = D; |
280 | # if MD5_SIZE_VS_SPEED == 1 | 280 | # if MD5_SMALL == 1 |
281 | const uint32_t *pc; | 281 | const uint32_t *pc; |
282 | const char *pp; | 282 | const char *pp; |
283 | int i; | 283 | int i; |
@@ -299,7 +299,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
299 | } while (0) | 299 | } while (0) |
300 | 300 | ||
301 | /* Round 1 */ | 301 | /* Round 1 */ |
302 | # if MD5_SIZE_VS_SPEED == 1 | 302 | # if MD5_SMALL == 1 |
303 | pc = C_array; | 303 | pc = C_array; |
304 | for (i = 0; i < 4; i++) { | 304 | for (i = 0; i < 4; i++) { |
305 | OP(A, B, C, D, 7, *pc++); | 305 | OP(A, B, C, D, 7, *pc++); |
@@ -339,7 +339,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
339 | } while (0) | 339 | } while (0) |
340 | 340 | ||
341 | /* Round 2 */ | 341 | /* Round 2 */ |
342 | # if MD5_SIZE_VS_SPEED == 1 | 342 | # if MD5_SMALL == 1 |
343 | pp = P_array; | 343 | pp = P_array; |
344 | for (i = 0; i < 4; i++) { | 344 | for (i = 0; i < 4; i++) { |
345 | OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++); | 345 | OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++); |
@@ -367,7 +367,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
367 | # endif | 367 | # endif |
368 | 368 | ||
369 | /* Round 3 */ | 369 | /* Round 3 */ |
370 | # if MD5_SIZE_VS_SPEED == 1 | 370 | # if MD5_SMALL == 1 |
371 | for (i = 0; i < 4; i++) { | 371 | for (i = 0; i < 4; i++) { |
372 | OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); | 372 | OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); |
373 | OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++); | 373 | OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++); |
@@ -394,7 +394,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
394 | # endif | 394 | # endif |
395 | 395 | ||
396 | /* Round 4 */ | 396 | /* Round 4 */ |
397 | # if MD5_SIZE_VS_SPEED == 1 | 397 | # if MD5_SMALL == 1 |
398 | for (i = 0; i < 4; i++) { | 398 | for (i = 0; i < 4; i++) { |
399 | OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); | 399 | OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); |
400 | OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++); | 400 | OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++); |
diff --git a/libbb/hash_md5prime.c b/libbb/hash_md5prime.c index 7986f4d29..e089a15f5 100644 --- a/libbb/hash_md5prime.c +++ b/libbb/hash_md5prime.c | |||
@@ -59,7 +59,7 @@ | |||
59 | * Completely removed static PADDING array. | 59 | * Completely removed static PADDING array. |
60 | * | 60 | * |
61 | * Reintroduced the loop unrolling in md5_transform and added the | 61 | * Reintroduced the loop unrolling in md5_transform and added the |
62 | * MD5_SIZE_VS_SPEED option for configurability. Define below as: | 62 | * MD5_SMALL option for configurability. Define below as: |
63 | * 0 fully unrolled loops | 63 | * 0 fully unrolled loops |
64 | * 1 partially unrolled (4 ops per loop) | 64 | * 1 partially unrolled (4 ops per loop) |
65 | * 2 no unrolling -- introduces the need to swap 4 variables (slow) | 65 | * 2 no unrolling -- introduces the need to swap 4 variables (slow) |
@@ -75,12 +75,12 @@ | |||
75 | #include "libbb.h" | 75 | #include "libbb.h" |
76 | 76 | ||
77 | /* 1: fastest, 3: smallest */ | 77 | /* 1: fastest, 3: smallest */ |
78 | #if CONFIG_MD5_SIZE_VS_SPEED < 1 | 78 | #if CONFIG_MD5_SMALL < 1 |
79 | # define MD5_SIZE_VS_SPEED 1 | 79 | # define MD5_SMALL 1 |
80 | #elif CONFIG_MD5_SIZE_VS_SPEED > 3 | 80 | #elif CONFIG_MD5_SMALL > 3 |
81 | # define MD5_SIZE_VS_SPEED 3 | 81 | # define MD5_SMALL 3 |
82 | #else | 82 | #else |
83 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED | 83 | # define MD5_SMALL CONFIG_MD5_SMALL |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | #if BB_LITTLE_ENDIAN | 86 | #if BB_LITTLE_ENDIAN |
@@ -152,7 +152,7 @@ memcpy32_le2cpu(uint32_t *output, const unsigned char *input, unsigned len) | |||
152 | static void md5_transform(uint32_t state[4], const unsigned char block[64]) | 152 | static void md5_transform(uint32_t state[4], const unsigned char block[64]) |
153 | { | 153 | { |
154 | uint32_t a, b, c, d, x[16]; | 154 | uint32_t a, b, c, d, x[16]; |
155 | #if MD5_SIZE_VS_SPEED > 1 | 155 | #if MD5_SMALL > 1 |
156 | uint32_t temp; | 156 | uint32_t temp; |
157 | const unsigned char *ps; | 157 | const unsigned char *ps; |
158 | 158 | ||
@@ -162,9 +162,9 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) | |||
162 | 4, 11, 16, 23, | 162 | 4, 11, 16, 23, |
163 | 6, 10, 15, 21 | 163 | 6, 10, 15, 21 |
164 | }; | 164 | }; |
165 | #endif /* MD5_SIZE_VS_SPEED > 1 */ | 165 | #endif /* MD5_SMALL > 1 */ |
166 | 166 | ||
167 | #if MD5_SIZE_VS_SPEED > 0 | 167 | #if MD5_SMALL > 0 |
168 | const uint32_t *pc; | 168 | const uint32_t *pc; |
169 | const unsigned char *pp; | 169 | const unsigned char *pp; |
170 | int i; | 170 | int i; |
@@ -198,7 +198,7 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) | |||
198 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ | 198 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ |
199 | }; | 199 | }; |
200 | 200 | ||
201 | #endif /* MD5_SIZE_VS_SPEED > 0 */ | 201 | #endif /* MD5_SMALL > 0 */ |
202 | 202 | ||
203 | memcpy32_le2cpu(x, block, 64); | 203 | memcpy32_le2cpu(x, block, 64); |
204 | 204 | ||
@@ -207,7 +207,7 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) | |||
207 | c = state[2]; | 207 | c = state[2]; |
208 | d = state[3]; | 208 | d = state[3]; |
209 | 209 | ||
210 | #if MD5_SIZE_VS_SPEED > 2 | 210 | #if MD5_SMALL > 2 |
211 | pc = C; | 211 | pc = C; |
212 | pp = P; | 212 | pp = P; |
213 | ps = S - 4; | 213 | ps = S - 4; |
@@ -233,7 +233,7 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) | |||
233 | temp += b; | 233 | temp += b; |
234 | a = d; d = c; c = b; b = temp; | 234 | a = d; d = c; c = b; b = temp; |
235 | } | 235 | } |
236 | #elif MD5_SIZE_VS_SPEED > 1 | 236 | #elif MD5_SMALL > 1 |
237 | pc = C; | 237 | pc = C; |
238 | pp = P; | 238 | pp = P; |
239 | ps = S; | 239 | ps = S; |
@@ -260,7 +260,7 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) | |||
260 | II(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; | 260 | II(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; |
261 | temp = d; d = c; c = b; b = a; a = temp; | 261 | temp = d; d = c; c = b; b = a; a = temp; |
262 | } | 262 | } |
263 | #elif MD5_SIZE_VS_SPEED > 0 | 263 | #elif MD5_SMALL > 0 |
264 | pc = C; | 264 | pc = C; |
265 | pp = P; | 265 | pp = P; |
266 | /* Round 1 */ | 266 | /* Round 1 */ |
diff --git a/libbb/inet_cksum.c b/libbb/inet_cksum.c new file mode 100644 index 000000000..3d5dc3adf --- /dev/null +++ b/libbb/inet_cksum.c | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Checksum routine for Internet Protocol family headers (C Version) | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | |||
7 | #include "libbb.h" | ||
8 | |||
9 | uint16_t FAST_FUNC inet_cksum(uint16_t *addr, int nleft) | ||
10 | { | ||
11 | /* | ||
12 | * Our algorithm is simple, using a 32 bit accumulator, | ||
13 | * we add sequential 16 bit words to it, and at the end, fold | ||
14 | * back all the carry bits from the top 16 bits into the lower | ||
15 | * 16 bits. | ||
16 | */ | ||
17 | unsigned sum = 0; | ||
18 | while (nleft > 1) { | ||
19 | sum += *addr++; | ||
20 | nleft -= 2; | ||
21 | } | ||
22 | |||
23 | /* Mop up an odd byte, if necessary */ | ||
24 | if (nleft == 1) { | ||
25 | if (BB_LITTLE_ENDIAN) | ||
26 | sum += *(uint8_t*)addr; | ||
27 | else | ||
28 | sum += *(uint8_t*)addr << 8; | ||
29 | } | ||
30 | |||
31 | /* Add back carry outs from top 16 bits to low 16 bits */ | ||
32 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ | ||
33 | sum += (sum >> 16); /* add carry */ | ||
34 | |||
35 | return (uint16_t)~sum; | ||
36 | } | ||
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 1b97e8609..c89c829ed 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -1359,7 +1359,9 @@ static void load_history(line_input_t *st_parm) | |||
1359 | 1359 | ||
1360 | /* fill temp_h[], retaining only last MAX_HISTORY lines */ | 1360 | /* fill temp_h[], retaining only last MAX_HISTORY lines */ |
1361 | memset(temp_h, 0, sizeof(temp_h)); | 1361 | memset(temp_h, 0, sizeof(temp_h)); |
1362 | st_parm->cnt_history_in_file = idx = 0; | 1362 | idx = 0; |
1363 | if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) | ||
1364 | st_parm->cnt_history_in_file = 0; | ||
1363 | while ((line = xmalloc_fgetline(fp)) != NULL) { | 1365 | while ((line = xmalloc_fgetline(fp)) != NULL) { |
1364 | if (line[0] == '\0') { | 1366 | if (line[0] == '\0') { |
1365 | free(line); | 1367 | free(line); |
@@ -1367,7 +1369,8 @@ static void load_history(line_input_t *st_parm) | |||
1367 | } | 1369 | } |
1368 | free(temp_h[idx]); | 1370 | free(temp_h[idx]); |
1369 | temp_h[idx] = line; | 1371 | temp_h[idx] = line; |
1370 | st_parm->cnt_history_in_file++; | 1372 | if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) |
1373 | st_parm->cnt_history_in_file++; | ||
1371 | idx++; | 1374 | idx++; |
1372 | if (idx == st_parm->max_history) | 1375 | if (idx == st_parm->max_history) |
1373 | idx = 0; | 1376 | idx = 0; |
@@ -1397,15 +1400,62 @@ static void load_history(line_input_t *st_parm) | |||
1397 | st_parm->history[i++] = line; | 1400 | st_parm->history[i++] = line; |
1398 | } | 1401 | } |
1399 | st_parm->cnt_history = i; | 1402 | st_parm->cnt_history = i; |
1403 | if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) | ||
1404 | st_parm->cnt_history_in_file = i; | ||
1400 | } | 1405 | } |
1401 | } | 1406 | } |
1402 | 1407 | ||
1403 | /* state->flags is already checked to be nonzero */ | 1408 | # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT |
1409 | void save_history(line_input_t *st) | ||
1410 | { | ||
1411 | FILE *fp; | ||
1412 | |||
1413 | if (!st->hist_file) | ||
1414 | return; | ||
1415 | if (st->cnt_history <= st->cnt_history_in_file) | ||
1416 | return; | ||
1417 | |||
1418 | fp = fopen(st->hist_file, "a"); | ||
1419 | if (fp) { | ||
1420 | int i, fd; | ||
1421 | char *new_name; | ||
1422 | line_input_t *st_temp; | ||
1423 | |||
1424 | for (i = st->cnt_history_in_file; i < st->cnt_history; i++) | ||
1425 | fprintf(fp, "%s\n", st->history[i]); | ||
1426 | fclose(fp); | ||
1427 | |||
1428 | /* we may have concurrently written entries from others. | ||
1429 | * load them */ | ||
1430 | st_temp = new_line_input_t(st->flags); | ||
1431 | st_temp->hist_file = st->hist_file; | ||
1432 | st_temp->max_history = st->max_history; | ||
1433 | load_history(st_temp); | ||
1434 | |||
1435 | /* write out temp file and replace hist_file atomically */ | ||
1436 | new_name = xasprintf("%s.%u.new", st->hist_file, (int) getpid()); | ||
1437 | fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); | ||
1438 | if (fd >= 0) { | ||
1439 | fp = xfdopen_for_write(fd); | ||
1440 | for (i = 0; i < st_temp->cnt_history; i++) | ||
1441 | fprintf(fp, "%s\n", st_temp->history[i]); | ||
1442 | fclose(fp); | ||
1443 | if (rename(new_name, st->hist_file) == 0) | ||
1444 | st->cnt_history_in_file = st_temp->cnt_history; | ||
1445 | } | ||
1446 | free(new_name); | ||
1447 | free_line_input_t(st_temp); | ||
1448 | } | ||
1449 | } | ||
1450 | # else | ||
1404 | static void save_history(char *str) | 1451 | static void save_history(char *str) |
1405 | { | 1452 | { |
1406 | int fd; | 1453 | int fd; |
1407 | int len, len2; | 1454 | int len, len2; |
1408 | 1455 | ||
1456 | if (!state->hist_file) | ||
1457 | return; | ||
1458 | |||
1409 | fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600); | 1459 | fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600); |
1410 | if (fd < 0) | 1460 | if (fd < 0) |
1411 | return; | 1461 | return; |
@@ -1433,7 +1483,7 @@ static void save_history(char *str) | |||
1433 | 1483 | ||
1434 | /* write out temp file and replace hist_file atomically */ | 1484 | /* write out temp file and replace hist_file atomically */ |
1435 | new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid()); | 1485 | new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid()); |
1436 | fd = open(state->hist_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); | 1486 | fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); |
1437 | if (fd >= 0) { | 1487 | if (fd >= 0) { |
1438 | FILE *fp; | 1488 | FILE *fp; |
1439 | int i; | 1489 | int i; |
@@ -1449,6 +1499,7 @@ static void save_history(char *str) | |||
1449 | free_line_input_t(st_temp); | 1499 | free_line_input_t(st_temp); |
1450 | } | 1500 | } |
1451 | } | 1501 | } |
1502 | # endif | ||
1452 | # else | 1503 | # else |
1453 | # define load_history(a) ((void)0) | 1504 | # define load_history(a) ((void)0) |
1454 | # define save_history(a) ((void)0) | 1505 | # define save_history(a) ((void)0) |
@@ -1477,15 +1528,18 @@ static void remember_in_history(char *str) | |||
1477 | for (i = 0; i < state->max_history-1; i++) | 1528 | for (i = 0; i < state->max_history-1; i++) |
1478 | state->history[i] = state->history[i+1]; | 1529 | state->history[i] = state->history[i+1]; |
1479 | /* i == state->max_history-1 */ | 1530 | /* i == state->max_history-1 */ |
1531 | # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT | ||
1532 | if (state->cnt_history_in_file) | ||
1533 | state->cnt_history_in_file--; | ||
1534 | # endif | ||
1480 | } | 1535 | } |
1481 | /* i <= state->max_history-1 */ | 1536 | /* i <= state->max_history-1 */ |
1482 | state->history[i++] = xstrdup(str); | 1537 | state->history[i++] = xstrdup(str); |
1483 | /* i <= state->max_history */ | 1538 | /* i <= state->max_history */ |
1484 | state->cur_history = i; | 1539 | state->cur_history = i; |
1485 | state->cnt_history = i; | 1540 | state->cnt_history = i; |
1486 | # if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY | 1541 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT |
1487 | if ((state->flags & SAVE_HISTORY) && state->hist_file) | 1542 | save_history(str); |
1488 | save_history(str); | ||
1489 | # endif | 1543 | # endif |
1490 | IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) | 1544 | IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) |
1491 | } | 1545 | } |
@@ -2147,7 +2201,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2147 | state = st ? st : (line_input_t*) &const_int_0; | 2201 | state = st ? st : (line_input_t*) &const_int_0; |
2148 | #if MAX_HISTORY > 0 | 2202 | #if MAX_HISTORY > 0 |
2149 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY | 2203 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY |
2150 | if ((state->flags & SAVE_HISTORY) && state->hist_file) | 2204 | if (state->hist_file) |
2151 | if (state->cnt_history == 0) | 2205 | if (state->cnt_history == 0) |
2152 | load_history(state); | 2206 | load_history(state); |
2153 | # endif | 2207 | # endif |
@@ -2467,6 +2521,44 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2467 | vi_cmdmode = 1; | 2521 | vi_cmdmode = 1; |
2468 | input_backward(1); | 2522 | input_backward(1); |
2469 | } | 2523 | } |
2524 | /* Handle a few ESC-<key> combinations the same way | ||
2525 | * standard readline bindings (IOW: bash) do. | ||
2526 | * Often, Alt-<key> generates ESC-<key>. | ||
2527 | */ | ||
2528 | ic = lineedit_read_key(read_key_buffer, timeout); | ||
2529 | switch (ic) { | ||
2530 | //case KEYCODE_LEFT: - bash doesn't do this | ||
2531 | case 'b': | ||
2532 | ctrl_left(); | ||
2533 | break; | ||
2534 | //case KEYCODE_RIGHT: - bash doesn't do this | ||
2535 | case 'f': | ||
2536 | ctrl_right(); | ||
2537 | break; | ||
2538 | //case KEYCODE_DELETE: - bash doesn't do this | ||
2539 | case 'd': /* Alt-D */ | ||
2540 | { | ||
2541 | /* Delete word forward */ | ||
2542 | int nc, sc = cursor; | ||
2543 | ctrl_right(); | ||
2544 | nc = cursor; | ||
2545 | input_backward(cursor - sc); | ||
2546 | while (--nc >= cursor) | ||
2547 | input_delete(1); | ||
2548 | break; | ||
2549 | } | ||
2550 | case '\b': /* Alt-Backspace(?) */ | ||
2551 | case '\x7f': /* Alt-Backspace(?) */ | ||
2552 | //case 'w': - bash doesn't do this | ||
2553 | { | ||
2554 | /* Delete word backward */ | ||
2555 | int sc = cursor; | ||
2556 | ctrl_left(); | ||
2557 | while (sc-- > cursor) | ||
2558 | input_delete(1); | ||
2559 | break; | ||
2560 | } | ||
2561 | } | ||
2470 | break; | 2562 | break; |
2471 | #endif /* FEATURE_COMMAND_EDITING_VI */ | 2563 | #endif /* FEATURE_COMMAND_EDITING_VI */ |
2472 | 2564 | ||
@@ -2495,9 +2587,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2495 | input_backward(1); | 2587 | input_backward(1); |
2496 | break; | 2588 | break; |
2497 | case KEYCODE_CTRL_LEFT: | 2589 | case KEYCODE_CTRL_LEFT: |
2590 | case KEYCODE_ALT_LEFT: /* bash doesn't do it */ | ||
2498 | ctrl_left(); | 2591 | ctrl_left(); |
2499 | break; | 2592 | break; |
2500 | case KEYCODE_CTRL_RIGHT: | 2593 | case KEYCODE_CTRL_RIGHT: |
2594 | case KEYCODE_ALT_RIGHT: /* bash doesn't do it */ | ||
2501 | ctrl_right(); | 2595 | ctrl_right(); |
2502 | break; | 2596 | break; |
2503 | case KEYCODE_HOME: | 2597 | case KEYCODE_HOME: |
diff --git a/libbb/loop.c b/libbb/loop.c index b798932fa..b3a520848 100644 --- a/libbb/loop.c +++ b/libbb/loop.c | |||
@@ -84,7 +84,7 @@ int FAST_FUNC del_loop(const char *device) | |||
84 | search will re-use an existing loop device already bound to that | 84 | search will re-use an existing loop device already bound to that |
85 | file/offset if it finds one. | 85 | file/offset if it finds one. |
86 | */ | 86 | */ |
87 | int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset) | 87 | int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, int ro) |
88 | { | 88 | { |
89 | char dev[LOOP_NAMESIZE]; | 89 | char dev[LOOP_NAMESIZE]; |
90 | char *try; | 90 | char *try; |
@@ -93,11 +93,13 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse | |||
93 | int i, dfd, ffd, mode, rc = -1; | 93 | int i, dfd, ffd, mode, rc = -1; |
94 | 94 | ||
95 | /* Open the file. Barf if this doesn't work. */ | 95 | /* Open the file. Barf if this doesn't work. */ |
96 | mode = O_RDWR; | 96 | mode = ro ? O_RDONLY : O_RDWR; |
97 | ffd = open(file, mode); | 97 | ffd = open(file, mode); |
98 | if (ffd < 0) { | 98 | if (ffd < 0) { |
99 | mode = O_RDONLY; | 99 | if (mode != O_RDONLY) { |
100 | ffd = open(file, mode); | 100 | mode = O_RDONLY; |
101 | ffd = open(file, mode); | ||
102 | } | ||
101 | if (ffd < 0) | 103 | if (ffd < 0) |
102 | return -errno; | 104 | return -errno; |
103 | } | 105 | } |
diff --git a/libbb/match_fstype.c b/libbb/match_fstype.c index 83d6e6770..32c3d7f18 100644 --- a/libbb/match_fstype.c +++ b/libbb/match_fstype.c | |||
@@ -12,6 +12,8 @@ | |||
12 | 12 | ||
13 | #include "libbb.h" | 13 | #include "libbb.h" |
14 | 14 | ||
15 | #ifdef HAVE_MNTENT_H | ||
16 | |||
15 | int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) | 17 | int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) |
16 | { | 18 | { |
17 | int match = 1; | 19 | int match = 1; |
@@ -40,3 +42,5 @@ int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) | |||
40 | 42 | ||
41 | return !match; | 43 | return !match; |
42 | } | 44 | } |
45 | |||
46 | #endif /* HAVE_MNTENT_H */ | ||
diff --git a/libbb/percent_decode.c b/libbb/percent_decode.c new file mode 100644 index 000000000..9a9d80c4a --- /dev/null +++ b/libbb/percent_decode.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
4 | */ | ||
5 | |||
6 | //kbuild:lib-y += percent_decode.o | ||
7 | |||
8 | #include "libbb.h" | ||
9 | |||
10 | static unsigned hex_to_bin(unsigned char c) | ||
11 | { | ||
12 | unsigned v; | ||
13 | |||
14 | v = c - '0'; | ||
15 | if (v <= 9) | ||
16 | return v; | ||
17 | /* c | 0x20: letters to lower case, non-letters | ||
18 | * to (potentially different) non-letters */ | ||
19 | v = (unsigned)(c | 0x20) - 'a'; | ||
20 | if (v <= 5) | ||
21 | return v + 10; | ||
22 | return ~0; | ||
23 | /* For testing: | ||
24 | void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); } | ||
25 | int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f'); | ||
26 | t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; } | ||
27 | */ | ||
28 | } | ||
29 | |||
30 | char* FAST_FUNC percent_decode_in_place(char *str, int strict) | ||
31 | { | ||
32 | /* note that decoded string is always shorter than original */ | ||
33 | char *src = str; | ||
34 | char *dst = str; | ||
35 | char c; | ||
36 | |||
37 | while ((c = *src++) != '\0') { | ||
38 | unsigned v; | ||
39 | |||
40 | if (!strict && c == '+') { | ||
41 | *dst++ = ' '; | ||
42 | continue; | ||
43 | } | ||
44 | if (c != '%') { | ||
45 | *dst++ = c; | ||
46 | continue; | ||
47 | } | ||
48 | v = hex_to_bin(src[0]); | ||
49 | if (v > 15) { | ||
50 | bad_hex: | ||
51 | if (strict) | ||
52 | return NULL; | ||
53 | *dst++ = '%'; | ||
54 | continue; | ||
55 | } | ||
56 | v = (v * 16) | hex_to_bin(src[1]); | ||
57 | if (v > 255) | ||
58 | goto bad_hex; | ||
59 | if (strict && (v == '/' || v == '\0')) { | ||
60 | /* caller takes it as indication of invalid | ||
61 | * (dangerous wrt exploits) chars */ | ||
62 | return str + 1; | ||
63 | } | ||
64 | *dst++ = v; | ||
65 | src += 2; | ||
66 | } | ||
67 | *dst = '\0'; | ||
68 | return str; | ||
69 | } | ||
diff --git a/libbb/procps.c b/libbb/procps.c index b5582edfa..39ddd2c12 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -285,27 +285,25 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | |||
285 | void BUG_comm_size(void); | 285 | void BUG_comm_size(void); |
286 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | 286 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) |
287 | { | 287 | { |
288 | struct dirent *entry; | ||
289 | char buf[PROCPS_BUFSIZE]; | ||
290 | char filename[sizeof("/proc//cmdline") + sizeof(int)*3]; | ||
291 | char *filename_tail; | ||
292 | long tasknice; | ||
293 | unsigned pid; | ||
294 | int n; | ||
295 | struct stat sb; | ||
296 | |||
297 | if (!sp) | 288 | if (!sp) |
298 | sp = alloc_procps_scan(); | 289 | sp = alloc_procps_scan(); |
299 | 290 | ||
300 | for (;;) { | 291 | for (;;) { |
292 | struct dirent *entry; | ||
293 | char buf[PROCPS_BUFSIZE]; | ||
294 | long tasknice; | ||
295 | unsigned pid; | ||
296 | int n; | ||
297 | char filename[sizeof("/proc/%u/task/%u/cmdline") + sizeof(int)*3 * 2]; | ||
298 | char *filename_tail; | ||
299 | |||
301 | #if ENABLE_FEATURE_SHOW_THREADS | 300 | #if ENABLE_FEATURE_SHOW_THREADS |
302 | if ((flags & PSSCAN_TASKS) && sp->task_dir) { | 301 | if (sp->task_dir) { |
303 | entry = readdir(sp->task_dir); | 302 | entry = readdir(sp->task_dir); |
304 | if (entry) | 303 | if (entry) |
305 | goto got_entry; | 304 | goto got_entry; |
306 | closedir(sp->task_dir); | 305 | closedir(sp->task_dir); |
307 | sp->task_dir = NULL; | 306 | sp->task_dir = NULL; |
308 | sp->main_thread_pid = 0; | ||
309 | } | 307 | } |
310 | #endif | 308 | #endif |
311 | entry = readdir(sp->dir); | 309 | entry = readdir(sp->dir); |
@@ -322,9 +320,9 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
322 | /* We found another /proc/PID. Do not use it, | 320 | /* We found another /proc/PID. Do not use it, |
323 | * there will be /proc/PID/task/PID (same PID!), | 321 | * there will be /proc/PID/task/PID (same PID!), |
324 | * so just go ahead and dive into /proc/PID/task. */ | 322 | * so just go ahead and dive into /proc/PID/task. */ |
325 | char task_dir[sizeof("/proc/%u/task") + sizeof(int)*3]; | 323 | sprintf(filename, "/proc/%u/task", pid); |
326 | sprintf(task_dir, "/proc/%u/task", pid); | 324 | /* Note: if opendir fails, we just go to next /proc/XXX */ |
327 | sp->task_dir = xopendir(task_dir); | 325 | sp->task_dir = opendir(filename); |
328 | sp->main_thread_pid = pid; | 326 | sp->main_thread_pid = pid; |
329 | continue; | 327 | continue; |
330 | } | 328 | } |
@@ -348,9 +346,15 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
348 | } | 346 | } |
349 | #endif | 347 | #endif |
350 | 348 | ||
351 | filename_tail = filename + sprintf(filename, "/proc/%u/", pid); | 349 | #if ENABLE_FEATURE_SHOW_THREADS |
350 | if (sp->task_dir) | ||
351 | filename_tail = filename + sprintf(filename, "/proc/%u/task/%u/", sp->main_thread_pid, pid); | ||
352 | else | ||
353 | #endif | ||
354 | filename_tail = filename + sprintf(filename, "/proc/%u/", pid); | ||
352 | 355 | ||
353 | if (flags & PSSCAN_UIDGID) { | 356 | if (flags & PSSCAN_UIDGID) { |
357 | struct stat sb; | ||
354 | if (stat(filename, &sb)) | 358 | if (stat(filename, &sb)) |
355 | continue; /* process probably exited */ | 359 | continue; /* process probably exited */ |
356 | /* Effective UID/GID, not real */ | 360 | /* Effective UID/GID, not real */ |
diff --git a/libbb/read_key.c b/libbb/read_key.c index 5dcd19c3f..8d72d2a63 100644 --- a/libbb/read_key.c +++ b/libbb/read_key.c | |||
@@ -40,13 +40,14 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout) | |||
40 | '[','C' |0x80,KEYCODE_RIGHT , | 40 | '[','C' |0x80,KEYCODE_RIGHT , |
41 | '[','D' |0x80,KEYCODE_LEFT , | 41 | '[','D' |0x80,KEYCODE_LEFT , |
42 | /* ESC [ 1 ; 2 x, where x = A/B/C/D: Shift-<arrow> */ | 42 | /* ESC [ 1 ; 2 x, where x = A/B/C/D: Shift-<arrow> */ |
43 | /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt-<arrow> */ | 43 | /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt-<arrow> - implemented below */ |
44 | /* ESC [ 1 ; 4 x, where x = A/B/C/D: Alt-Shift-<arrow> */ | 44 | /* ESC [ 1 ; 4 x, where x = A/B/C/D: Alt-Shift-<arrow> */ |
45 | /* ESC [ 1 ; 5 x, where x = A/B/C/D: Ctrl-<arrow> - implemented below */ | 45 | /* ESC [ 1 ; 5 x, where x = A/B/C/D: Ctrl-<arrow> - implemented below */ |
46 | /* ESC [ 1 ; 6 x, where x = A/B/C/D: Ctrl-Shift-<arrow> */ | 46 | /* ESC [ 1 ; 6 x, where x = A/B/C/D: Ctrl-Shift-<arrow> */ |
47 | '[','H' |0x80,KEYCODE_HOME , /* xterm */ | 47 | '[','H' |0x80,KEYCODE_HOME , /* xterm */ |
48 | /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home */ | ||
49 | '[','F' |0x80,KEYCODE_END , /* xterm */ | 48 | '[','F' |0x80,KEYCODE_END , /* xterm */ |
49 | /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home (End similarly?) */ | ||
50 | /* '[','Z' |0x80,KEYCODE_SHIFT_TAB, */ | ||
50 | '[','1','~' |0x80,KEYCODE_HOME , /* vt100? linux vt? or what? */ | 51 | '[','1','~' |0x80,KEYCODE_HOME , /* vt100? linux vt? or what? */ |
51 | '[','2','~' |0x80,KEYCODE_INSERT , | 52 | '[','2','~' |0x80,KEYCODE_INSERT , |
52 | /* ESC [ 2 ; 3 ~ - Alt-Insert */ | 53 | /* ESC [ 2 ; 3 ~ - Alt-Insert */ |
@@ -86,8 +87,12 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout) | |||
86 | /* '[','1',';','5','B' |0x80,KEYCODE_CTRL_DOWN , - unused */ | 87 | /* '[','1',';','5','B' |0x80,KEYCODE_CTRL_DOWN , - unused */ |
87 | '[','1',';','5','C' |0x80,KEYCODE_CTRL_RIGHT, | 88 | '[','1',';','5','C' |0x80,KEYCODE_CTRL_RIGHT, |
88 | '[','1',';','5','D' |0x80,KEYCODE_CTRL_LEFT , | 89 | '[','1',';','5','D' |0x80,KEYCODE_CTRL_LEFT , |
90 | /* '[','1',';','3','A' |0x80,KEYCODE_ALT_UP , - unused */ | ||
91 | /* '[','1',';','3','B' |0x80,KEYCODE_ALT_DOWN , - unused */ | ||
92 | '[','1',';','3','C' |0x80,KEYCODE_ALT_RIGHT, | ||
93 | '[','1',';','3','D' |0x80,KEYCODE_ALT_LEFT , | ||
94 | /* '[','3',';','3','~' |0x80,KEYCODE_ALT_DELETE, - unused */ | ||
89 | 0 | 95 | 0 |
90 | /* ESC [ Z - Shift-Tab */ | ||
91 | }; | 96 | }; |
92 | 97 | ||
93 | pfd.fd = fd; | 98 | pfd.fd = fd; |
diff --git a/libbb/read_printf.c b/libbb/read_printf.c index 192f83d6e..0bbf7802a 100644 --- a/libbb/read_printf.c +++ b/libbb/read_printf.c | |||
@@ -15,7 +15,7 @@ | |||
15 | ) | 15 | ) |
16 | 16 | ||
17 | #if ZIPPED | 17 | #if ZIPPED |
18 | # include "archive.h" | 18 | # include "bb_archive.h" |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | 21 | ||
diff --git a/libbb/udp_io.c b/libbb/udp_io.c index b8fb6755d..7985a9723 100644 --- a/libbb/udp_io.c +++ b/libbb/udp_io.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * We don't check for errors here. Not supported == won't be used | 13 | * We don't check for errors here. Not supported == won't be used |
14 | */ | 14 | */ |
15 | void FAST_FUNC | 15 | void FAST_FUNC |
16 | socket_want_pktinfo(int fd) | 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(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); |
diff --git a/libbb/uuencode.c b/libbb/uuencode.c index 03e708fd5..f7b248492 100644 --- a/libbb/uuencode.c +++ b/libbb/uuencode.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | /* Conversion table. for base 64 */ | 12 | /* Conversion table. for base 64 */ |
13 | const char bb_uuenc_tbl_base64[65 + 2] ALIGN1 = { | 13 | const char bb_uuenc_tbl_base64[65 + 1] ALIGN1 = { |
14 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', | 14 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', |
15 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', | 15 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', |
16 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', | 16 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', |
@@ -20,7 +20,7 @@ const char bb_uuenc_tbl_base64[65 + 2] ALIGN1 = { | |||
20 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', | 20 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', |
21 | '4', '5', '6', '7', '8', '9', '+', '/', | 21 | '4', '5', '6', '7', '8', '9', '+', '/', |
22 | '=' /* termination character */, | 22 | '=' /* termination character */, |
23 | '\n', '\0' /* needed for uudecode.c */ | 23 | '\0' /* needed for uudecode.c only */ |
24 | }; | 24 | }; |
25 | 25 | ||
26 | const char bb_uuenc_tbl_std[65] ALIGN1 = { | 26 | const char bb_uuenc_tbl_std[65] ALIGN1 = { |
@@ -73,23 +73,23 @@ void FAST_FUNC bb_uuencode(char *p, const void *src, int length, const char *tbl | |||
73 | } | 73 | } |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * Decode base64 encoded stream. | 76 | * Decode base64 encoded string. Stops on '\0'. |
77 | * Can stop on EOF, specified char, or on uuencode-style "====" line: | 77 | * |
78 | * flags argument controls it. | 78 | * Returns: pointer to the undecoded part of source. |
79 | * If points to '\0', then the source was fully decoded. | ||
80 | * (*pp_dst): advanced past the last written byte. | ||
79 | */ | 81 | */ |
80 | void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags) | 82 | const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) |
81 | { | 83 | { |
82 | /* Note that EOF _can_ be passed as exit_char too */ | 84 | char *dst = *pp_dst; |
83 | #define exit_char ((int)(signed char)flags) | 85 | const char *src_tail; |
84 | #define uu_style_end (flags & BASE64_FLAG_UU_STOP) | ||
85 | |||
86 | int term_count = 0; | ||
87 | 86 | ||
88 | while (1) { | 87 | while (1) { |
89 | unsigned char translated[4]; | 88 | unsigned char six_bit[4]; |
90 | int count = 0; | 89 | int count = 0; |
91 | 90 | ||
92 | /* Process one group of 4 chars */ | 91 | /* Fetch up to four 6-bit values */ |
92 | src_tail = src; | ||
93 | while (count < 4) { | 93 | while (count < 4) { |
94 | char *table_ptr; | 94 | char *table_ptr; |
95 | int ch; | 95 | int ch; |
@@ -97,49 +97,128 @@ void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags) | |||
97 | /* Get next _valid_ character. | 97 | /* Get next _valid_ character. |
98 | * bb_uuenc_tbl_base64[] contains this string: | 98 | * bb_uuenc_tbl_base64[] contains this string: |
99 | * 0 1 2 3 4 5 6 | 99 | * 0 1 2 3 4 5 6 |
100 | * 012345678901234567890123456789012345678901234567890123456789012345 | 100 | * 01234567890123456789012345678901234567890123456789012345678901234 |
101 | * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n" | 101 | * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" |
102 | */ | 102 | */ |
103 | do { | 103 | do { |
104 | ch = fgetc(src_stream); | 104 | ch = *src; |
105 | if (ch == exit_char && count == 0) | 105 | if (ch == '\0') { |
106 | return; | 106 | if (count == 0) { |
107 | if (ch == EOF) | 107 | /* Example: |
108 | bb_error_msg_and_die("truncated base64 input"); | 108 | * If we decode "QUJD <NUL>", we want |
109 | * to return ptr to NUL, not to ' ', | ||
110 | * because we did fully decode | ||
111 | * the string (to "ABC"). | ||
112 | */ | ||
113 | src_tail = src; | ||
114 | } | ||
115 | goto ret; | ||
116 | } | ||
117 | src++; | ||
109 | table_ptr = strchr(bb_uuenc_tbl_base64, ch); | 118 | table_ptr = strchr(bb_uuenc_tbl_base64, ch); |
110 | //TODO: add BASE64_FLAG_foo to die on bad char? | 119 | //TODO: add BASE64_FLAG_foo to die on bad char? |
111 | //Note that then we may need to still allow '\r' (for mail processing) | ||
112 | } while (!table_ptr); | 120 | } while (!table_ptr); |
113 | 121 | ||
114 | /* Convert encoded character to decimal */ | 122 | /* Convert encoded character to decimal */ |
115 | ch = table_ptr - bb_uuenc_tbl_base64; | 123 | ch = table_ptr - bb_uuenc_tbl_base64; |
116 | 124 | ||
117 | if (ch == 65 /* '\n' */) { | ||
118 | /* Terminating "====" line? */ | ||
119 | if (uu_style_end && term_count == 4) | ||
120 | return; /* yes */ | ||
121 | term_count = 0; | ||
122 | continue; | ||
123 | } | ||
124 | /* ch is 64 if char was '=', otherwise 0..63 */ | 125 | /* ch is 64 if char was '=', otherwise 0..63 */ |
125 | translated[count] = ch & 63; /* 64 -> 0 */ | 126 | if (ch == 64) |
126 | if (ch == 64) { | ||
127 | term_count++; | ||
128 | break; | 127 | break; |
129 | } | 128 | six_bit[count] = ch; |
130 | count++; | 129 | count++; |
131 | term_count = 0; | ||
132 | } | 130 | } |
133 | 131 | ||
134 | /* Merge 6 bit chars to 8 bit. | 132 | /* Transform 6-bit values to 8-bit ones. |
135 | * count can be < 4 when we decode the tail: | 133 | * count can be < 4 when we decode the tail: |
136 | * "eQ==" -> "y", not "y NUL NUL" | 134 | * "eQ==" -> "y", not "y NUL NUL". |
135 | * Note that (count > 1) is always true, | ||
136 | * "x===" encoding is not valid: | ||
137 | * even a single zero byte encodes as "AA==". | ||
138 | * However, with current logic we come here with count == 1 | ||
139 | * when we decode "==" tail. | ||
137 | */ | 140 | */ |
138 | if (count > 1) | 141 | if (count > 1) |
139 | fputc(translated[0] << 2 | translated[1] >> 4, dst_stream); | 142 | *dst++ = six_bit[0] << 2 | six_bit[1] >> 4; |
140 | if (count > 2) | 143 | if (count > 2) |
141 | fputc(translated[1] << 4 | translated[2] >> 2, dst_stream); | 144 | *dst++ = six_bit[1] << 4 | six_bit[2] >> 2; |
142 | if (count > 3) | 145 | if (count > 3) |
143 | fputc(translated[2] << 6 | translated[3], dst_stream); | 146 | *dst++ = six_bit[2] << 6 | six_bit[3]; |
147 | /* Note that if we decode "AA==" and ate first '=', | ||
148 | * we just decoded one char (count == 2) and now we'll | ||
149 | * do the loop once more to decode second '='. | ||
150 | */ | ||
144 | } /* while (1) */ | 151 | } /* while (1) */ |
152 | ret: | ||
153 | *pp_dst = dst; | ||
154 | return src_tail; | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Decode base64 encoded stream. | ||
159 | * Can stop on EOF, specified char, or on uuencode-style "====" line: | ||
160 | * flags argument controls it. | ||
161 | */ | ||
162 | void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags) | ||
163 | { | ||
164 | /* Note that EOF _can_ be passed as exit_char too */ | ||
165 | #define exit_char ((int)(signed char)flags) | ||
166 | #define uu_style_end (flags & BASE64_FLAG_UU_STOP) | ||
167 | |||
168 | /* uuencoded files have 61 byte lines. Use 64 byte buffer | ||
169 | * to process line at a time. | ||
170 | */ | ||
171 | enum { BUFFER_SIZE = 64 }; | ||
172 | |||
173 | char in_buf[BUFFER_SIZE + 2]; | ||
174 | char out_buf[BUFFER_SIZE / 4 * 3 + 2]; | ||
175 | char *out_tail; | ||
176 | const char *in_tail; | ||
177 | int term_seen = 0; | ||
178 | int in_count = 0; | ||
179 | |||
180 | while (1) { | ||
181 | while (in_count < BUFFER_SIZE) { | ||
182 | int ch = fgetc(src_stream); | ||
183 | if (ch == exit_char) { | ||
184 | if (in_count == 0) | ||
185 | return; | ||
186 | term_seen = 1; | ||
187 | break; | ||
188 | } | ||
189 | if (ch == EOF) { | ||
190 | term_seen = 1; | ||
191 | break; | ||
192 | } | ||
193 | /* Prevent "====" line to be split: stop if we see '\n'. | ||
194 | * We can also skip other whitespace and skirt the problem | ||
195 | * of files with NULs by stopping on any control char or space: | ||
196 | */ | ||
197 | if (ch <= ' ') | ||
198 | break; | ||
199 | in_buf[in_count++] = ch; | ||
200 | } | ||
201 | in_buf[in_count] = '\0'; | ||
202 | |||
203 | /* Did we encounter "====" line? */ | ||
204 | if (uu_style_end && strcmp(in_buf, "====") == 0) | ||
205 | return; | ||
206 | |||
207 | out_tail = out_buf; | ||
208 | in_tail = decode_base64(&out_tail, in_buf); | ||
209 | |||
210 | fwrite(out_buf, (out_tail - out_buf), 1, dst_stream); | ||
211 | |||
212 | if (term_seen) { | ||
213 | /* Did we consume ALL characters? */ | ||
214 | if (*in_tail == '\0') | ||
215 | return; | ||
216 | /* No */ | ||
217 | bb_error_msg_and_die("truncated base64 input"); | ||
218 | } | ||
219 | |||
220 | /* It was partial decode */ | ||
221 | in_count = strlen(in_tail); | ||
222 | memmove(in_buf, in_tail, in_count); | ||
223 | } | ||
145 | } | 224 | } |
diff --git a/libbb/vdprintf.c b/libbb/vdprintf.c index feeb403a0..05426873e 100644 --- a/libbb/vdprintf.c +++ b/libbb/vdprintf.c | |||
@@ -12,10 +12,10 @@ | |||
12 | #if defined(__GLIBC__) && __GLIBC__ < 2 | 12 | #if defined(__GLIBC__) && __GLIBC__ < 2 |
13 | int FAST_FUNC vdprintf(int d, const char *format, va_list ap) | 13 | int FAST_FUNC vdprintf(int d, const char *format, va_list ap) |
14 | { | 14 | { |
15 | char buf[BUF_SIZE]; | 15 | char buf[8 * 1024]; |
16 | int len; | 16 | int len; |
17 | 17 | ||
18 | len = vsnprintf(buf, BUF_SIZE, format, ap); | 18 | len = vsnprintf(buf, sizeof(buf), format, ap); |
19 | return write(d, buf, len); | 19 | return write(d, buf, len); |
20 | } | 20 | } |
21 | #endif | 21 | #endif |
diff --git a/loginutils/Config.src b/loginutils/Config.src index 0d7f50cf1..14ce53434 100644 --- a/loginutils/Config.src +++ b/loginutils/Config.src | |||
@@ -205,6 +205,17 @@ config LOGIN | |||
205 | Note that Busybox binary must be setuid root for this applet to | 205 | Note that Busybox binary must be setuid root for this applet to |
206 | work properly. | 206 | work properly. |
207 | 207 | ||
208 | config LOGIN_SESSION_AS_CHILD | ||
209 | bool "Run logged in session in a child process" | ||
210 | default y if PAM | ||
211 | depends on LOGIN | ||
212 | help | ||
213 | Run the logged in session in a child process. This allows | ||
214 | login to clean up things such as utmp entries or PAM sessions | ||
215 | when the login session is complete. If you use PAM, you | ||
216 | almost always would want this to be set to Y, else PAM session | ||
217 | will not be cleaned up. | ||
218 | |||
208 | config PAM | 219 | config PAM |
209 | bool "Support for PAM (Pluggable Authentication Modules)" | 220 | bool "Support for PAM (Pluggable Authentication Modules)" |
210 | default n | 221 | default n |
diff --git a/loginutils/README b/loginutils/README new file mode 100644 index 000000000..ce8851097 --- /dev/null +++ b/loginutils/README | |||
@@ -0,0 +1,70 @@ | |||
1 | Getty | ||
2 | |||
3 | ??? Should getty open tty with or without O_NONBLOCK? | ||
4 | For serial lines, it means "should getty wait for Carrier Detect pin?" | ||
5 | I checked other getties: | ||
6 | |||
7 | - agetty always uses O_NONBLOCK | ||
8 | - mgetty uses O_NONBLOCK unless run with -b, or as "getty" | ||
9 | |||
10 | ??? If we decided to use O_NONBLOCK (perhaps optionally with -b), | ||
11 | when getty should send -I INITSTR data to tty? After open succeeds? | ||
12 | What if we also want to initialize *modem* with some AT commands? | ||
13 | |||
14 | ??? Should we check/create /var/lock/LCK..ttyPFX lockfiles? | ||
15 | |||
16 | ??? mgetty opens tty but does NOT lock it, then waits for input via | ||
17 | select/poll, and when input is available, it checks lock file. | ||
18 | If it exists, mgetty exits (it assumes someone else uses the line). | ||
19 | If no, it creates the file (lock the tty). Sounds like a good algorithm | ||
20 | to use if we are called with -w... | ||
21 | |||
22 | Getty should establish a new session and process group, and ensure | ||
23 | that tty is a ctty. | ||
24 | |||
25 | ??? Should getty ensure that other processes which might have opened | ||
26 | fds to this tty be dusconnected? agetty has a -R option which makes | ||
27 | agetty call vhangup() after tty is opened. (Then agetty opens it again, | ||
28 | since it probably vhangup'ed its own fd too). | ||
29 | |||
30 | Getty should leave the tty in approximately the same state as "stty sane" | ||
31 | before it execs login program. Minor things we do conditionally are: | ||
32 | c_iflag |= ICRNL; // if '\r' was used to end username | ||
33 | |||
34 | ??? mgetty uses per-tty file to ignore connects, /etc/nologin.ttyxx - | ||
35 | is it useful? | ||
36 | |||
37 | It should be possible to run "getty 0 -" from a shell prompt. | ||
38 | [This currently doesn't work from interactive shell since setsid() | ||
39 | fails in process group leader. The workaround is to run it as a child | ||
40 | of something. sh -c 'getty - 0; true' usually works. Should we fix this?] | ||
41 | It should leave tty in a sane state when it exits (Ctrl-D, -t SEC timeout): | ||
42 | echo should be on, speed, control chars properly set, etc. | ||
43 | (However, it can't restore ctty. The symptom is that "</dev/tty" | ||
44 | fails in the parent shell after getty exits: /dev/tty can't be opened). | ||
45 | |||
46 | Getty should write LOGIN_PROCESS utmp record before it starts waiting | ||
47 | for username to be entered. | ||
48 | |||
49 | Login | ||
50 | |||
51 | Login should not try to set up tty parameters - apart from switching echo | ||
52 | off while entering password, and switching it back on after. | ||
53 | |||
54 | Login should not leave "echo off" state when it times out reading password | ||
55 | or otherwise terminates (Ctrl-C, Ctrl-D etc). | ||
56 | |||
57 | ??? Should login establish a new session and/or process group, and ensure | ||
58 | that tty is a ctty? Without this, running login directly (not via getty) | ||
59 | from e.g. initscript will usually result with a login session without | ||
60 | ctty and without session/pgrp properly created... | ||
61 | |||
62 | It should be possible to run "login [USER]" from a shell prompt, | ||
63 | and it should work (not block/die/error out). | ||
64 | Similarly to getty, it should leave tty in the sane state when it exits. | ||
65 | |||
66 | ??? Should login write LOGIN_PROCESS utmp record before it starts waiting | ||
67 | for username/password to be entered? | ||
68 | |||
69 | Login should write USER_PROCESS utmp record just before it is about | ||
70 | to exec user's shell. | ||
diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index 2262b792a..b7df57e5d 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c | |||
@@ -33,9 +33,8 @@ static const char chpasswd_longopts[] ALIGN1 = | |||
33 | int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 33 | int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
34 | int chpasswd_main(int argc UNUSED_PARAM, char **argv) | 34 | int chpasswd_main(int argc UNUSED_PARAM, char **argv) |
35 | { | 35 | { |
36 | char *name, *pass; | 36 | char *name; |
37 | char salt[sizeof("$N$XXXXXXXX")]; | 37 | int opt; |
38 | int opt, rc; | ||
39 | 38 | ||
40 | if (getuid() != 0) | 39 | if (getuid() != 0) |
41 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | 40 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); |
@@ -45,6 +44,10 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) | |||
45 | opt = getopt32(argv, "em"); | 44 | opt = getopt32(argv, "em"); |
46 | 45 | ||
47 | while ((name = xmalloc_fgetline(stdin)) != NULL) { | 46 | while ((name = xmalloc_fgetline(stdin)) != NULL) { |
47 | char *free_me; | ||
48 | char *pass; | ||
49 | int rc; | ||
50 | |||
48 | pass = strchr(name, ':'); | 51 | pass = strchr(name, ':'); |
49 | if (!pass) | 52 | if (!pass) |
50 | bb_error_msg_and_die("missing new password"); | 53 | bb_error_msg_and_die("missing new password"); |
@@ -52,7 +55,10 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) | |||
52 | 55 | ||
53 | xuname2uid(name); /* dies if there is no such user */ | 56 | xuname2uid(name); /* dies if there is no such user */ |
54 | 57 | ||
58 | free_me = NULL; | ||
55 | if (!(opt & OPT_ENC)) { | 59 | if (!(opt & OPT_ENC)) { |
60 | char salt[sizeof("$N$XXXXXXXX")]; | ||
61 | |||
56 | crypt_make_salt(salt, 1); | 62 | crypt_make_salt(salt, 1); |
57 | if (opt & OPT_MD5) { | 63 | if (opt & OPT_MD5) { |
58 | salt[0] = '$'; | 64 | salt[0] = '$'; |
@@ -60,7 +66,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) | |||
60 | salt[2] = '$'; | 66 | salt[2] = '$'; |
61 | crypt_make_salt(salt + 3, 4); | 67 | crypt_make_salt(salt + 3, 4); |
62 | } | 68 | } |
63 | pass = pw_encrypt(pass, salt, 0); | 69 | free_me = pass = pw_encrypt(pass, salt, 0); |
64 | } | 70 | } |
65 | 71 | ||
66 | /* This is rather complex: if user is not found in /etc/shadow, | 72 | /* This is rather complex: if user is not found in /etc/shadow, |
@@ -81,8 +87,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) | |||
81 | bb_info_msg("Password for '%s' changed", name); | 87 | bb_info_msg("Password for '%s' changed", name); |
82 | logmode = LOGMODE_STDIO; | 88 | logmode = LOGMODE_STDIO; |
83 | free(name); | 89 | free(name); |
84 | if (!(opt & OPT_ENC)) | 90 | free(free_me); |
85 | free(pass); | ||
86 | } | 91 | } |
87 | return EXIT_SUCCESS; | 92 | return EXIT_SUCCESS; |
88 | } | 93 | } |
diff --git a/loginutils/getty.c b/loginutils/getty.c index 62456651b..1f417591b 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
@@ -63,18 +63,8 @@ static FILE *dbf; | |||
63 | */ | 63 | */ |
64 | #define ISSUE "/etc/issue" | 64 | #define ISSUE "/etc/issue" |
65 | 65 | ||
66 | /* Some shorthands for control characters */ | 66 | /* Macro to build Ctrl-LETTER. Assumes ASCII dialect */ |
67 | #define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */ | 67 | #define CTL(x) ((x) ^ 0100) |
68 | #define BS CTL('H') /* back space */ | ||
69 | #define DEL CTL('?') /* delete */ | ||
70 | |||
71 | /* Defaults for line-editing etc. characters; you may want to change this */ | ||
72 | #define DEF_INTR CTL('C') /* default interrupt character */ | ||
73 | #define DEF_QUIT CTL('\\') /* default quit char */ | ||
74 | #define DEF_KILL CTL('U') /* default kill char */ | ||
75 | #define DEF_EOF CTL('D') /* default EOF char */ | ||
76 | #define DEF_EOL '\n' | ||
77 | #define DEF_SWITCH 0 /* default switch char (none) */ | ||
78 | 68 | ||
79 | /* | 69 | /* |
80 | * When multiple baud rates are specified on the command line, | 70 | * When multiple baud rates are specified on the command line, |
@@ -83,16 +73,16 @@ static FILE *dbf; | |||
83 | #define MAX_SPEED 10 /* max. nr. of baud rates */ | 73 | #define MAX_SPEED 10 /* max. nr. of baud rates */ |
84 | 74 | ||
85 | struct globals { | 75 | struct globals { |
86 | unsigned timeout; /* time-out period */ | 76 | unsigned timeout; |
87 | const char *login; /* login program */ | 77 | const char *login; /* login program */ |
88 | const char *fakehost; | 78 | const char *fakehost; |
89 | const char *tty; /* name of tty */ | 79 | const char *tty_name; |
90 | char *initstring; /* modem init string */ | 80 | char *initstring; /* modem init string */ |
91 | const char *issue; /* alternative issue file */ | 81 | const char *issue; /* alternative issue file */ |
92 | int numspeed; /* number of baud rates to try */ | 82 | int numspeed; /* number of baud rates to try */ |
93 | int speeds[MAX_SPEED]; /* baud rates to be tried */ | 83 | int speeds[MAX_SPEED]; /* baud rates to be tried */ |
94 | unsigned char eol; /* end-of-line char seen (CR or NL) */ | 84 | unsigned char eol; /* end-of-line char seen (CR or NL) */ |
95 | struct termios termios; /* terminal mode bits */ | 85 | struct termios tty_attrs; |
96 | char line_buf[128]; | 86 | char line_buf[128]; |
97 | }; | 87 | }; |
98 | 88 | ||
@@ -104,7 +94,7 @@ struct globals { | |||
104 | //usage:#define getty_trivial_usage | 94 | //usage:#define getty_trivial_usage |
105 | //usage: "[OPTIONS] BAUD_RATE[,BAUD_RATE]... TTY [TERMTYPE]" | 95 | //usage: "[OPTIONS] BAUD_RATE[,BAUD_RATE]... TTY [TERMTYPE]" |
106 | //usage:#define getty_full_usage "\n\n" | 96 | //usage:#define getty_full_usage "\n\n" |
107 | //usage: "Open a tty, prompt for a login name, then invoke /bin/login\n" | 97 | //usage: "Open TTY, prompt for login name, then invoke /bin/login\n" |
108 | //usage: "\n -h Enable hardware RTS/CTS flow control" | 98 | //usage: "\n -h Enable hardware RTS/CTS flow control" |
109 | //usage: "\n -L Set CLOCAL (ignore Carrier Detect state)" | 99 | //usage: "\n -L Set CLOCAL (ignore Carrier Detect state)" |
110 | //usage: "\n -m Get baud rate from modem's CONNECT status message" | 100 | //usage: "\n -m Get baud rate from modem's CONNECT status message" |
@@ -181,15 +171,14 @@ static void parse_args(char **argv) | |||
181 | debug("after getopt\n"); | 171 | debug("after getopt\n"); |
182 | 172 | ||
183 | /* We loosen up a bit and accept both "baudrate tty" and "tty baudrate" */ | 173 | /* We loosen up a bit and accept both "baudrate tty" and "tty baudrate" */ |
184 | G.tty = argv[0]; /* tty name */ | 174 | G.tty_name = argv[0]; |
185 | ts = argv[1]; /* baud rate(s) */ | 175 | ts = argv[1]; /* baud rate(s) */ |
186 | if (isdigit(argv[0][0])) { | 176 | if (isdigit(argv[0][0])) { |
187 | /* A number first, assume it's a speed (BSD style) */ | 177 | /* A number first, assume it's a speed (BSD style) */ |
188 | G.tty = ts; /* tty name is in argv[1] */ | 178 | G.tty_name = ts; /* tty name is in argv[1] */ |
189 | ts = argv[0]; /* baud rate(s) */ | 179 | ts = argv[0]; /* baud rate(s) */ |
190 | } | 180 | } |
191 | parse_speeds(ts); | 181 | parse_speeds(ts); |
192 | applet_name = xasprintf("getty: %s", G.tty); | ||
193 | 182 | ||
194 | if (argv[2]) | 183 | if (argv[2]) |
195 | xsetenv("TERM", argv[2]); | 184 | xsetenv("TERM", argv[2]); |
@@ -201,42 +190,49 @@ static void parse_args(char **argv) | |||
201 | static void open_tty(void) | 190 | static void open_tty(void) |
202 | { | 191 | { |
203 | /* Set up new standard input, unless we are given an already opened port */ | 192 | /* Set up new standard input, unless we are given an already opened port */ |
204 | if (NOT_LONE_DASH(G.tty)) { | 193 | if (NOT_LONE_DASH(G.tty_name)) { |
205 | if (G.tty[0] != '/') | 194 | if (G.tty_name[0] != '/') |
206 | G.tty = xasprintf("/dev/%s", G.tty); /* will leak it */ | 195 | G.tty_name = xasprintf("/dev/%s", G.tty_name); /* will leak it */ |
207 | 196 | ||
208 | /* Open the tty as standard input */ | 197 | /* Open the tty as standard input */ |
209 | debug("open(2)\n"); | 198 | debug("open(2)\n"); |
210 | close(0); | 199 | close(0); |
211 | xopen(G.tty, O_RDWR | O_NONBLOCK); /* uses fd 0 */ | 200 | xopen(G.tty_name, O_RDWR | O_NONBLOCK); /* uses fd 0 */ |
212 | 201 | ||
213 | /* Set proper protections and ownership */ | 202 | /* Set proper protections and ownership */ |
214 | fchown(0, 0, 0); /* 0:0 */ | 203 | fchown(0, 0, 0); /* 0:0 */ |
215 | fchmod(0, 0620); /* crw--w---- */ | 204 | fchmod(0, 0620); /* crw--w---- */ |
216 | } else { | 205 | } else { |
206 | char *n; | ||
217 | /* | 207 | /* |
218 | * Standard input should already be connected to an open port. Make | 208 | * Standard input should already be connected to an open port. |
219 | * sure it is open for read/write. | 209 | * Make sure it is open for read/write. |
220 | */ | 210 | */ |
221 | if ((fcntl(0, F_GETFL) & (O_RDWR|O_RDONLY|O_WRONLY)) != O_RDWR) | 211 | if ((fcntl(0, F_GETFL) & (O_RDWR|O_RDONLY|O_WRONLY)) != O_RDWR) |
222 | bb_error_msg_and_die("stdin is not open for read/write"); | 212 | bb_error_msg_and_die("stdin is not open for read/write"); |
213 | |||
214 | /* Try to get real tty name instead of "-" */ | ||
215 | n = xmalloc_ttyname(0); | ||
216 | if (n) | ||
217 | G.tty_name = n; | ||
223 | } | 218 | } |
219 | applet_name = xasprintf("getty: %s", skip_dev_pfx(G.tty_name)); | ||
224 | } | 220 | } |
225 | 221 | ||
226 | static void set_termios(void) | 222 | static void set_tty_attrs(void) |
227 | { | 223 | { |
228 | if (tcsetattr_stdin_TCSANOW(&G.termios) < 0) | 224 | if (tcsetattr_stdin_TCSANOW(&G.tty_attrs) < 0) |
229 | bb_perror_msg_and_die("tcsetattr"); | 225 | bb_perror_msg_and_die("tcsetattr"); |
230 | } | 226 | } |
231 | 227 | ||
232 | /* We manipulate termios this way: | 228 | /* We manipulate tty_attrs this way: |
233 | * - first, we read existing termios settings | 229 | * - first, we read existing tty_attrs |
234 | * - termios_init modifies some parts and sets it | 230 | * - init_tty_attrs modifies some parts and sets it |
235 | * - auto_baud and/or BREAK processing can set different speed and set termios | 231 | * - auto_baud and/or BREAK processing can set different speed and set tty attrs |
236 | * - termios_final again modifies some parts and sets termios before | 232 | * - finalize_tty_attrs again modifies some parts and sets tty attrs before |
237 | * execing login | 233 | * execing login |
238 | */ | 234 | */ |
239 | static void termios_init(int speed) | 235 | static void init_tty_attrs(int speed) |
240 | { | 236 | { |
241 | /* Try to drain output buffer, with 5 sec timeout. | 237 | /* Try to drain output buffer, with 5 sec timeout. |
242 | * Added on request from users of ~600 baud serial interface | 238 | * Added on request from users of ~600 baud serial interface |
@@ -248,21 +244,20 @@ static void termios_init(int speed) | |||
248 | alarm(5); | 244 | alarm(5); |
249 | tcdrain(STDIN_FILENO); | 245 | tcdrain(STDIN_FILENO); |
250 | alarm(0); | 246 | alarm(0); |
251 | signal(SIGALRM, SIG_DFL); /* do not break -t TIMEOUT! */ | ||
252 | 247 | ||
253 | /* Flush input and output queues, important for modems! */ | 248 | /* Flush input and output queues, important for modems! */ |
254 | tcflush(STDIN_FILENO, TCIOFLUSH); | 249 | tcflush(STDIN_FILENO, TCIOFLUSH); |
255 | 250 | ||
256 | /* Set speed if it wasn't specified as "0" on command line */ | 251 | /* Set speed if it wasn't specified as "0" on command line */ |
257 | if (speed != B0) | 252 | if (speed != B0) |
258 | cfsetspeed(&G.termios, speed); | 253 | cfsetspeed(&G.tty_attrs, speed); |
259 | 254 | ||
260 | /* Initial termios settings: 8-bit characters, raw mode, blocking i/o. | 255 | /* Initial settings: 8-bit characters, raw mode, blocking i/o. |
261 | * Special characters are set after we have read the login name; all | 256 | * Special characters are set after we have read the login name; all |
262 | * reads will be done in raw mode anyway. | 257 | * reads will be done in raw mode anyway. |
263 | */ | 258 | */ |
264 | /* Clear all bits except: */ | 259 | /* Clear all bits except: */ |
265 | G.termios.c_cflag &= (0 | 260 | G.tty_attrs.c_cflag &= (0 |
266 | /* 2 stop bits (1 otherwise) | 261 | /* 2 stop bits (1 otherwise) |
267 | * Enable parity bit (both on input and output) | 262 | * Enable parity bit (both on input and output) |
268 | * Odd parity (else even) | 263 | * Odd parity (else even) |
@@ -271,7 +266,9 @@ static void termios_init(int speed) | |||
271 | #ifdef CMSPAR | 266 | #ifdef CMSPAR |
272 | | CMSPAR /* mark or space parity */ | 267 | | CMSPAR /* mark or space parity */ |
273 | #endif | 268 | #endif |
269 | #ifdef CBAUD | ||
274 | | CBAUD /* (output) baud rate */ | 270 | | CBAUD /* (output) baud rate */ |
271 | #endif | ||
275 | #ifdef CBAUDEX | 272 | #ifdef CBAUDEX |
276 | | CBAUDEX /* (output) baud rate */ | 273 | | CBAUDEX /* (output) baud rate */ |
277 | #endif | 274 | #endif |
@@ -280,42 +277,42 @@ static void termios_init(int speed) | |||
280 | #endif | 277 | #endif |
281 | ); | 278 | ); |
282 | /* Set: 8 bits; hang up (drop DTR) on last close; enable receive */ | 279 | /* Set: 8 bits; hang up (drop DTR) on last close; enable receive */ |
283 | G.termios.c_cflag |= CS8 | HUPCL | CREAD; | 280 | G.tty_attrs.c_cflag |= CS8 | HUPCL | CREAD; |
284 | if (option_mask32 & F_LOCAL) { | 281 | if (option_mask32 & F_LOCAL) { |
285 | /* ignore Carrier Detect pin: | 282 | /* ignore Carrier Detect pin: |
286 | * opens don't block when CD is low, | 283 | * opens don't block when CD is low, |
287 | * losing CD doesn't hang up processes whose ctty is this tty | 284 | * losing CD doesn't hang up processes whose ctty is this tty |
288 | */ | 285 | */ |
289 | G.termios.c_cflag |= CLOCAL; | 286 | G.tty_attrs.c_cflag |= CLOCAL; |
290 | } | 287 | } |
291 | #ifdef CRTSCTS | 288 | #ifdef CRTSCTS |
292 | if (option_mask32 & F_RTSCTS) | 289 | if (option_mask32 & F_RTSCTS) |
293 | G.termios.c_cflag |= CRTSCTS; /* flow control using RTS/CTS pins */ | 290 | G.tty_attrs.c_cflag |= CRTSCTS; /* flow control using RTS/CTS pins */ |
294 | #endif | 291 | #endif |
295 | G.termios.c_iflag = 0; | 292 | G.tty_attrs.c_iflag = 0; |
296 | G.termios.c_lflag = 0; | 293 | G.tty_attrs.c_lflag = 0; |
297 | /* non-raw output; add CR to each NL */ | 294 | /* non-raw output; add CR to each NL */ |
298 | G.termios.c_oflag = OPOST | ONLCR; | 295 | G.tty_attrs.c_oflag = OPOST | ONLCR; |
299 | 296 | ||
300 | G.termios.c_cc[VMIN] = 1; /* block reads if < 1 char is available */ | 297 | G.tty_attrs.c_cc[VMIN] = 1; /* block reads if < 1 char is available */ |
301 | G.termios.c_cc[VTIME] = 0; /* no timeout (reads block forever) */ | 298 | G.tty_attrs.c_cc[VTIME] = 0; /* no timeout (reads block forever) */ |
302 | #ifdef __linux__ | 299 | #ifdef __linux__ |
303 | G.termios.c_line = 0; | 300 | G.tty_attrs.c_line = 0; |
304 | #endif | 301 | #endif |
305 | 302 | ||
306 | set_termios(); | 303 | set_tty_attrs(); |
307 | 304 | ||
308 | debug("term_io 2\n"); | 305 | debug("term_io 2\n"); |
309 | } | 306 | } |
310 | 307 | ||
311 | static void termios_final(void) | 308 | static void finalize_tty_attrs(void) |
312 | { | 309 | { |
313 | /* software flow control on output (stop sending if XOFF is recvd); | 310 | /* software flow control on output (stop sending if XOFF is recvd); |
314 | * and on input (send XOFF when buffer is full) | 311 | * and on input (send XOFF when buffer is full) |
315 | */ | 312 | */ |
316 | G.termios.c_iflag |= IXON | IXOFF; | 313 | G.tty_attrs.c_iflag |= IXON | IXOFF; |
317 | if (G.eol == '\r') { | 314 | if (G.eol == '\r') { |
318 | G.termios.c_iflag |= ICRNL; /* map CR on input to NL */ | 315 | G.tty_attrs.c_iflag |= ICRNL; /* map CR on input to NL */ |
319 | } | 316 | } |
320 | /* Other bits in c_iflag: | 317 | /* Other bits in c_iflag: |
321 | * IXANY Any recvd char enables output (any char is also a XON) | 318 | * IXANY Any recvd char enables output (any char is also a XON) |
@@ -342,7 +339,7 @@ static void termios_final(void) | |||
342 | * echo kill char specially, not as ^c (ECHOKE controls how exactly); | 339 | * echo kill char specially, not as ^c (ECHOKE controls how exactly); |
343 | * erase all input via BS-SP-BS on kill char (else go to next line) | 340 | * erase all input via BS-SP-BS on kill char (else go to next line) |
344 | */ | 341 | */ |
345 | G.termios.c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHOKE; | 342 | G.tty_attrs.c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHOKE; |
346 | /* Other bits in c_lflag: | 343 | /* Other bits in c_lflag: |
347 | * XCASE Map uppercase to \lowercase [tried, doesn't work] | 344 | * XCASE Map uppercase to \lowercase [tried, doesn't work] |
348 | * ECHONL Echo NL even if ECHO is not set | 345 | * ECHONL Echo NL even if ECHO is not set |
@@ -360,17 +357,17 @@ static void termios_final(void) | |||
360 | * (why "stty sane" unsets this bit?) | 357 | * (why "stty sane" unsets this bit?) |
361 | */ | 358 | */ |
362 | 359 | ||
363 | G.termios.c_cc[VINTR] = DEF_INTR; | 360 | G.tty_attrs.c_cc[VINTR] = CTL('C'); |
364 | G.termios.c_cc[VQUIT] = DEF_QUIT; | 361 | G.tty_attrs.c_cc[VQUIT] = CTL('\\'); |
365 | G.termios.c_cc[VEOF] = DEF_EOF; | 362 | G.tty_attrs.c_cc[VEOF] = CTL('D'); |
366 | G.termios.c_cc[VEOL] = DEF_EOL; | 363 | G.tty_attrs.c_cc[VEOL] = '\n'; |
367 | #ifdef VSWTC | 364 | #ifdef VSWTC |
368 | G.termios.c_cc[VSWTC] = DEF_SWITCH; | 365 | G.tty_attrs.c_cc[VSWTC] = 0; |
369 | #endif | 366 | #endif |
370 | #ifdef VSWTCH | 367 | #ifdef VSWTCH |
371 | G.termios.c_cc[VSWTCH] = DEF_SWITCH; | 368 | G.tty_attrs.c_cc[VSWTCH] = 0; |
372 | #endif | 369 | #endif |
373 | G.termios.c_cc[VKILL] = DEF_KILL; | 370 | G.tty_attrs.c_cc[VKILL] = CTL('U'); |
374 | /* Other control chars: | 371 | /* Other control chars: |
375 | * VEOL2 | 372 | * VEOL2 |
376 | * VERASE, VWERASE - (word) erase. we may set VERASE in get_logname | 373 | * VERASE, VWERASE - (word) erase. we may set VERASE in get_logname |
@@ -380,7 +377,10 @@ static void termios_final(void) | |||
380 | * VSTART, VSTOP - chars used for IXON/IXOFF | 377 | * VSTART, VSTOP - chars used for IXON/IXOFF |
381 | */ | 378 | */ |
382 | 379 | ||
383 | set_termios(); | 380 | set_tty_attrs(); |
381 | |||
382 | /* Now the newline character should be properly written */ | ||
383 | full_write(STDOUT_FILENO, "\n", 1); | ||
384 | } | 384 | } |
385 | 385 | ||
386 | /* extract baud rate from modem status message */ | 386 | /* extract baud rate from modem status message */ |
@@ -403,8 +403,8 @@ static void auto_baud(void) | |||
403 | * modem status messages is enabled. | 403 | * modem status messages is enabled. |
404 | */ | 404 | */ |
405 | 405 | ||
406 | G.termios.c_cc[VMIN] = 0; /* don't block reads (min read is 0 chars) */ | 406 | G.tty_attrs.c_cc[VMIN] = 0; /* don't block reads (min read is 0 chars) */ |
407 | set_termios(); | 407 | set_tty_attrs(); |
408 | 408 | ||
409 | /* | 409 | /* |
410 | * Wait for a while, then read everything the modem has said so far and | 410 | * Wait for a while, then read everything the modem has said so far and |
@@ -420,15 +420,15 @@ static void auto_baud(void) | |||
420 | if (isdigit(*bp)) { | 420 | if (isdigit(*bp)) { |
421 | speed = bcode(bp); | 421 | speed = bcode(bp); |
422 | if (speed > 0) | 422 | if (speed > 0) |
423 | cfsetspeed(&G.termios, speed); | 423 | cfsetspeed(&G.tty_attrs, speed); |
424 | break; | 424 | break; |
425 | } | 425 | } |
426 | } | 426 | } |
427 | } | 427 | } |
428 | 428 | ||
429 | /* Restore terminal settings */ | 429 | /* Restore terminal settings */ |
430 | G.termios.c_cc[VMIN] = 1; /* restore to value set by termios_init */ | 430 | G.tty_attrs.c_cc[VMIN] = 1; /* restore to value set by init_tty_attrs */ |
431 | set_termios(); | 431 | set_tty_attrs(); |
432 | } | 432 | } |
433 | 433 | ||
434 | /* get user name, establish parity, speed, erase, kill, eol; | 434 | /* get user name, establish parity, speed, erase, kill, eol; |
@@ -444,42 +444,35 @@ static char *get_logname(void) | |||
444 | tcflush(STDIN_FILENO, TCIFLUSH); | 444 | tcflush(STDIN_FILENO, TCIFLUSH); |
445 | 445 | ||
446 | /* Prompt for and read a login name */ | 446 | /* Prompt for and read a login name */ |
447 | G.line_buf[0] = '\0'; | 447 | do { |
448 | while (!G.line_buf[0]) { | ||
449 | /* Write issue file and prompt */ | 448 | /* Write issue file and prompt */ |
450 | #ifdef ISSUE | 449 | #ifdef ISSUE |
451 | if (!(option_mask32 & F_NOISSUE)) | 450 | if (!(option_mask32 & F_NOISSUE)) |
452 | print_login_issue(G.issue, G.tty); | 451 | print_login_issue(G.issue, G.tty_name); |
453 | #endif | 452 | #endif |
454 | print_login_prompt(); | 453 | print_login_prompt(); |
455 | 454 | ||
456 | /* Read name, watch for break, parity, erase, kill, end-of-line */ | 455 | /* Read name, watch for break, erase, kill, end-of-line */ |
457 | bp = G.line_buf; | 456 | bp = G.line_buf; |
458 | G.eol = '\0'; | ||
459 | while (1) { | 457 | while (1) { |
460 | /* Do not report trivial EINTR/EIO errors */ | 458 | /* Do not report trivial EINTR/EIO errors */ |
461 | errno = EINTR; /* make read of 0 bytes be silent too */ | 459 | errno = EINTR; /* make read of 0 bytes be silent too */ |
462 | if (read(STDIN_FILENO, &c, 1) < 1) { | 460 | if (read(STDIN_FILENO, &c, 1) < 1) { |
461 | finalize_tty_attrs(); | ||
463 | if (errno == EINTR || errno == EIO) | 462 | if (errno == EINTR || errno == EIO) |
464 | exit(EXIT_SUCCESS); | 463 | exit(EXIT_SUCCESS); |
465 | bb_perror_msg_and_die(bb_msg_read_error); | 464 | bb_perror_msg_and_die(bb_msg_read_error); |
466 | } | 465 | } |
467 | 466 | ||
468 | /* BREAK. If we have speeds to try, | ||
469 | * return NULL (will switch speeds and return here) */ | ||
470 | if (c == '\0' && G.numspeed > 1) | ||
471 | return NULL; | ||
472 | |||
473 | /* Do erase, kill and end-of-line processing */ | ||
474 | switch (c) { | 467 | switch (c) { |
475 | case '\r': | 468 | case '\r': |
476 | case '\n': | 469 | case '\n': |
477 | *bp = '\0'; | 470 | *bp = '\0'; |
478 | G.eol = c; | 471 | G.eol = c; |
479 | goto got_logname; | 472 | goto got_logname; |
480 | case BS: | 473 | case CTL('H'): |
481 | case DEL: | 474 | case 0x7f: |
482 | G.termios.c_cc[VERASE] = c; | 475 | G.tty_attrs.c_cc[VERASE] = c; |
483 | if (bp > G.line_buf) { | 476 | if (bp > G.line_buf) { |
484 | full_write(STDOUT_FILENO, "\010 \010", 3); | 477 | full_write(STDOUT_FILENO, "\010 \010", 3); |
485 | bp--; | 478 | bp--; |
@@ -491,8 +484,16 @@ static char *get_logname(void) | |||
491 | bp--; | 484 | bp--; |
492 | } | 485 | } |
493 | break; | 486 | break; |
487 | case CTL('C'): | ||
494 | case CTL('D'): | 488 | case CTL('D'): |
489 | finalize_tty_attrs(); | ||
495 | exit(EXIT_SUCCESS); | 490 | exit(EXIT_SUCCESS); |
491 | case '\0': | ||
492 | /* BREAK. If we have speeds to try, | ||
493 | * return NULL (will switch speeds and return here) */ | ||
494 | if (G.numspeed > 1) | ||
495 | return NULL; | ||
496 | /* fall through and ignore it */ | ||
496 | default: | 497 | default: |
497 | if ((unsigned char)c < ' ') { | 498 | if ((unsigned char)c < ' ') { |
498 | /* ignore garbage characters */ | 499 | /* ignore garbage characters */ |
@@ -505,16 +506,22 @@ static char *get_logname(void) | |||
505 | } | 506 | } |
506 | } /* end of get char loop */ | 507 | } /* end of get char loop */ |
507 | got_logname: ; | 508 | got_logname: ; |
508 | } /* while logname is empty */ | 509 | } while (G.line_buf[0] == '\0'); /* while logname is empty */ |
509 | 510 | ||
510 | return G.line_buf; | 511 | return G.line_buf; |
511 | } | 512 | } |
512 | 513 | ||
514 | static void alarm_handler(int sig UNUSED_PARAM) | ||
515 | { | ||
516 | finalize_tty_attrs(); | ||
517 | _exit(EXIT_SUCCESS); | ||
518 | } | ||
519 | |||
513 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 520 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
514 | int getty_main(int argc UNUSED_PARAM, char **argv) | 521 | int getty_main(int argc UNUSED_PARAM, char **argv) |
515 | { | 522 | { |
516 | int n; | 523 | int n; |
517 | pid_t pid; | 524 | pid_t pid, tsid; |
518 | char *logname; | 525 | char *logname; |
519 | 526 | ||
520 | INIT_G(); | 527 | INIT_G(); |
@@ -527,14 +534,37 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
527 | /* Parse command-line arguments */ | 534 | /* Parse command-line arguments */ |
528 | parse_args(argv); | 535 | parse_args(argv); |
529 | 536 | ||
530 | logmode = LOGMODE_NONE; | 537 | /* Create new session and pgrp, lose controlling tty */ |
538 | pid = setsid(); /* this also gives us our pid :) */ | ||
539 | if (pid < 0) { | ||
540 | int fd; | ||
541 | /* :( | ||
542 | * docs/ctty.htm says: | ||
543 | * "This is allowed only when the current process | ||
544 | * is not a process group leader". | ||
545 | * Thus, setsid() will fail if we _already_ are | ||
546 | * a session leader - which is quite possible for getty! | ||
547 | */ | ||
548 | pid = getpid(); | ||
549 | if (getsid(0) != pid) | ||
550 | bb_perror_msg_and_die("setsid"); | ||
551 | /* Looks like we are already a session leader. | ||
552 | * In this case (setsid failed) we may still have ctty, | ||
553 | * and it may be different from tty we need to control! | ||
554 | * If we still have ctty, on Linux ioctl(TIOCSCTTY) | ||
555 | * (which we are going to use a bit later) always fails - | ||
556 | * even if we try to take ctty which is already ours! | ||
557 | * Try to drop old ctty now to prevent that. | ||
558 | * Use O_NONBLOCK: old ctty may be a serial line. | ||
559 | */ | ||
560 | fd = open("/dev/tty", O_RDWR | O_NONBLOCK); | ||
561 | if (fd >= 0) { | ||
562 | ioctl(fd, TIOCNOTTY); | ||
563 | close(fd); | ||
564 | } | ||
565 | } | ||
531 | 566 | ||
532 | /* Create new session, lose controlling tty, if any */ | 567 | /* Close stdio, and stray descriptors, just in case */ |
533 | /* docs/ctty.htm says: | ||
534 | * "This is allowed only when the current process | ||
535 | * is not a process group leader" - is this a problem? */ | ||
536 | setsid(); | ||
537 | /* close stdio, and stray descriptors, just in case */ | ||
538 | n = xopen(bb_dev_null, O_RDWR); | 568 | n = xopen(bb_dev_null, O_RDWR); |
539 | /* dup2(n, 0); - no, we need to handle "getty - 9600" too */ | 569 | /* dup2(n, 0); - no, we need to handle "getty - 9600" too */ |
540 | xdup2(n, 1); | 570 | xdup2(n, 1); |
@@ -558,13 +588,25 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
558 | #endif | 588 | #endif |
559 | 589 | ||
560 | /* Open the tty as standard input, if it is not "-" */ | 590 | /* Open the tty as standard input, if it is not "-" */ |
561 | /* If it's not "-" and not taken yet, it will become our ctty */ | ||
562 | debug("calling open_tty\n"); | 591 | debug("calling open_tty\n"); |
563 | open_tty(); | 592 | open_tty(); |
564 | ndelay_off(0); | 593 | ndelay_off(STDIN_FILENO); |
565 | debug("duping\n"); | 594 | debug("duping\n"); |
566 | xdup2(0, 1); | 595 | xdup2(STDIN_FILENO, 1); |
567 | xdup2(0, 2); | 596 | xdup2(STDIN_FILENO, 2); |
597 | |||
598 | /* Steal ctty if we don't have it yet */ | ||
599 | tsid = tcgetsid(STDIN_FILENO); | ||
600 | if (tsid < 0 || pid != tsid) { | ||
601 | if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) < 0) | ||
602 | bb_perror_msg_and_die("TIOCSCTTY"); | ||
603 | } | ||
604 | |||
605 | #ifdef __linux__ | ||
606 | /* Make ourself a foreground process group within our session */ | ||
607 | if (tcsetpgrp(STDIN_FILENO, pid) < 0) | ||
608 | bb_perror_msg_and_die("tcsetpgrp"); | ||
609 | #endif | ||
568 | 610 | ||
569 | /* | 611 | /* |
570 | * The following ioctl will fail if stdin is not a tty, but also when | 612 | * The following ioctl will fail if stdin is not a tty, but also when |
@@ -574,25 +616,15 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
574 | * by patching the SunOS kernel variable "zsadtrlow" to a larger value; | 616 | * by patching the SunOS kernel variable "zsadtrlow" to a larger value; |
575 | * 5 seconds seems to be a good value. | 617 | * 5 seconds seems to be a good value. |
576 | */ | 618 | */ |
577 | if (tcgetattr(STDIN_FILENO, &G.termios) < 0) | 619 | if (tcgetattr(STDIN_FILENO, &G.tty_attrs) < 0) |
578 | bb_perror_msg_and_die("tcgetattr"); | 620 | bb_perror_msg_and_die("tcgetattr"); |
579 | 621 | ||
580 | pid = getpid(); | ||
581 | #ifdef __linux__ | ||
582 | // FIXME: do we need this? Otherwise "-" case seems to be broken... | ||
583 | // /* Forcibly make fd 0 our controlling tty, even if another session | ||
584 | // * has it as a ctty. (Another session loses ctty). */ | ||
585 | // ioctl(STDIN_FILENO, TIOCSCTTY, (void*)1); | ||
586 | /* Make ourself a foreground process group within our session */ | ||
587 | tcsetpgrp(STDIN_FILENO, pid); | ||
588 | #endif | ||
589 | |||
590 | /* Update the utmp file. This tty is ours now! */ | 622 | /* Update the utmp file. This tty is ours now! */ |
591 | update_utmp(pid, LOGIN_PROCESS, G.tty, "LOGIN", G.fakehost); | 623 | update_utmp(pid, LOGIN_PROCESS, G.tty_name, "LOGIN", G.fakehost); |
592 | 624 | ||
593 | /* Initialize the termios settings (raw mode, eight-bit, blocking i/o) */ | 625 | /* Initialize tty attrs (raw mode, eight-bit, blocking i/o) */ |
594 | debug("calling termios_init\n"); | 626 | debug("calling init_tty_attrs\n"); |
595 | termios_init(G.speeds[0]); | 627 | init_tty_attrs(G.speeds[0]); |
596 | 628 | ||
597 | /* Write the modem init string and DON'T flush the buffers */ | 629 | /* Write the modem init string and DON'T flush the buffers */ |
598 | if (option_mask32 & F_INITSTRING) { | 630 | if (option_mask32 & F_INITSTRING) { |
@@ -606,8 +638,8 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
606 | auto_baud(); | 638 | auto_baud(); |
607 | 639 | ||
608 | /* Set the optional timer */ | 640 | /* Set the optional timer */ |
641 | signal(SIGALRM, alarm_handler); | ||
609 | alarm(G.timeout); /* if 0, alarm is not set */ | 642 | alarm(G.timeout); /* if 0, alarm is not set */ |
610 | //BUG: death by signal won't restore termios | ||
611 | 643 | ||
612 | /* Optionally wait for CR or LF before writing /etc/issue */ | 644 | /* Optionally wait for CR or LF before writing /etc/issue */ |
613 | if (option_mask32 & F_WAITCRLF) { | 645 | if (option_mask32 & F_WAITCRLF) { |
@@ -622,7 +654,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
622 | 654 | ||
623 | logname = NULL; | 655 | logname = NULL; |
624 | if (!(option_mask32 & F_NOPROMPT)) { | 656 | if (!(option_mask32 & F_NOPROMPT)) { |
625 | /* NB: termios_init already set line speed | 657 | /* NB: init_tty_attrs already set line speed |
626 | * to G.speeds[0] */ | 658 | * to G.speeds[0] */ |
627 | int baud_index = 0; | 659 | int baud_index = 0; |
628 | 660 | ||
@@ -634,19 +666,15 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
634 | break; | 666 | break; |
635 | /* We are here only if G.numspeed > 1 */ | 667 | /* We are here only if G.numspeed > 1 */ |
636 | baud_index = (baud_index + 1) % G.numspeed; | 668 | baud_index = (baud_index + 1) % G.numspeed; |
637 | cfsetspeed(&G.termios, G.speeds[baud_index]); | 669 | cfsetspeed(&G.tty_attrs, G.speeds[baud_index]); |
638 | set_termios(); | 670 | set_tty_attrs(); |
639 | } | 671 | } |
640 | } | 672 | } |
641 | 673 | ||
642 | /* Disable timer */ | 674 | /* Disable timer */ |
643 | alarm(0); | 675 | alarm(0); |
644 | 676 | ||
645 | /* Finalize the termios settings */ | 677 | finalize_tty_attrs(); |
646 | termios_final(); | ||
647 | |||
648 | /* Now the newline character should be properly written */ | ||
649 | full_write(STDOUT_FILENO, "\n", 1); | ||
650 | 678 | ||
651 | /* Let the login program take care of password validation */ | 679 | /* Let the login program take care of password validation */ |
652 | /* We use PATH because we trust that root doesn't set "bad" PATH, | 680 | /* We use PATH because we trust that root doesn't set "bad" PATH, |
diff --git a/loginutils/login.c b/loginutils/login.c index 2f7b9b212..73db8fa63 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -41,7 +41,12 @@ enum { | |||
41 | TTYNAME_SIZE = 32, | 41 | TTYNAME_SIZE = 32, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static char* short_tty; | 44 | struct globals { |
45 | struct termios tty_attrs; | ||
46 | } FIX_ALIASING; | ||
47 | #define G (*(struct globals*)&bb_common_bufsiz1) | ||
48 | #define INIT_G() do { } while (0) | ||
49 | |||
45 | 50 | ||
46 | #if ENABLE_FEATURE_NOLOGIN | 51 | #if ENABLE_FEATURE_NOLOGIN |
47 | static void die_if_nologin(void) | 52 | static void die_if_nologin(void) |
@@ -74,7 +79,7 @@ static void die_if_nologin(void) | |||
74 | #endif | 79 | #endif |
75 | 80 | ||
76 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM | 81 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM |
77 | static int check_securetty(void) | 82 | static int check_securetty(const char *short_tty) |
78 | { | 83 | { |
79 | char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ | 84 | char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ |
80 | parser_t *parser = config_open2("/etc/securetty", fopen_for_read); | 85 | parser_t *parser = config_open2("/etc/securetty", fopen_for_read); |
@@ -89,7 +94,7 @@ static int check_securetty(void) | |||
89 | return buf != NULL; | 94 | return buf != NULL; |
90 | } | 95 | } |
91 | #else | 96 | #else |
92 | static ALWAYS_INLINE int check_securetty(void) { return 1; } | 97 | static ALWAYS_INLINE int check_securetty(const char *short_tty UNUSED_PARAM) { return 1; } |
93 | #endif | 98 | #endif |
94 | 99 | ||
95 | #if ENABLE_SELINUX | 100 | #if ENABLE_SELINUX |
@@ -142,6 +147,29 @@ static void run_login_script(struct passwd *pw, char *full_tty) | |||
142 | void run_login_script(struct passwd *pw, char *full_tty); | 147 | void run_login_script(struct passwd *pw, char *full_tty); |
143 | #endif | 148 | #endif |
144 | 149 | ||
150 | #if ENABLE_LOGIN_SESSION_AS_CHILD && ENABLE_PAM | ||
151 | static void login_pam_end(pam_handle_t *pamh) | ||
152 | { | ||
153 | int pamret; | ||
154 | |||
155 | pamret = pam_setcred(pamh, PAM_DELETE_CRED); | ||
156 | if (pamret != PAM_SUCCESS) { | ||
157 | bb_error_msg("pam_%s failed: %s (%d)", "setcred", | ||
158 | pam_strerror(pamh, pamret), pamret); | ||
159 | } | ||
160 | pamret = pam_close_session(pamh, 0); | ||
161 | if (pamret != PAM_SUCCESS) { | ||
162 | bb_error_msg("pam_%s failed: %s (%d)", "close_session", | ||
163 | pam_strerror(pamh, pamret), pamret); | ||
164 | } | ||
165 | pamret = pam_end(pamh, pamret); | ||
166 | if (pamret != PAM_SUCCESS) { | ||
167 | bb_error_msg("pam_%s failed: %s (%d)", "end", | ||
168 | pam_strerror(pamh, pamret), pamret); | ||
169 | } | ||
170 | } | ||
171 | #endif /* ENABLE_PAM */ | ||
172 | |||
145 | static void get_username_or_die(char *buf, int size_buf) | 173 | static void get_username_or_die(char *buf, int size_buf) |
146 | { | 174 | { |
147 | int c, cntdown; | 175 | int c, cntdown; |
@@ -185,15 +213,21 @@ static void motd(void) | |||
185 | 213 | ||
186 | static void alarm_handler(int sig UNUSED_PARAM) | 214 | static void alarm_handler(int sig UNUSED_PARAM) |
187 | { | 215 | { |
188 | /* This is the escape hatch! Poor serial line users and the like | 216 | /* This is the escape hatch! Poor serial line users and the like |
189 | * arrive here when their connection is broken. | 217 | * arrive here when their connection is broken. |
190 | * We don't want to block here */ | 218 | * We don't want to block here */ |
191 | ndelay_on(1); | 219 | ndelay_on(STDOUT_FILENO); |
192 | printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT); | 220 | /* Test for correct attr restoring: |
221 | * run "getty 0 -" from a shell, enter bogus username, stop at | ||
222 | * password prompt, let it time out. Without the tcsetattr below, | ||
223 | * when you are back at shell prompt, echo will be still off. | ||
224 | */ | ||
225 | tcsetattr_stdin_TCSANOW(&G.tty_attrs); | ||
226 | printf("\r\nLogin timed out after %u seconds\r\n", TIMEOUT); | ||
193 | fflush_all(); | 227 | fflush_all(); |
194 | /* unix API is brain damaged regarding O_NONBLOCK, | 228 | /* unix API is brain damaged regarding O_NONBLOCK, |
195 | * we should undo it, or else we can affect other processes */ | 229 | * we should undo it, or else we can affect other processes */ |
196 | ndelay_off(1); | 230 | ndelay_off(STDOUT_FILENO); |
197 | _exit(EXIT_SUCCESS); | 231 | _exit(EXIT_SUCCESS); |
198 | } | 232 | } |
199 | 233 | ||
@@ -214,6 +248,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
214 | char *opt_host = NULL; | 248 | char *opt_host = NULL; |
215 | char *opt_user = opt_user; /* for compiler */ | 249 | char *opt_user = opt_user; /* for compiler */ |
216 | char *full_tty; | 250 | char *full_tty; |
251 | char *short_tty; | ||
217 | IF_SELINUX(security_context_t user_sid = NULL;) | 252 | IF_SELINUX(security_context_t user_sid = NULL;) |
218 | #if ENABLE_PAM | 253 | #if ENABLE_PAM |
219 | int pamret; | 254 | int pamret; |
@@ -224,10 +259,11 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
224 | char pwdbuf[256]; | 259 | char pwdbuf[256]; |
225 | char **pamenv; | 260 | char **pamenv; |
226 | #endif | 261 | #endif |
262 | #if ENABLE_LOGIN_SESSION_AS_CHILD | ||
263 | pid_t child_pid; | ||
264 | #endif | ||
227 | 265 | ||
228 | username[0] = '\0'; | 266 | INIT_G(); |
229 | signal(SIGALRM, alarm_handler); | ||
230 | alarm(TIMEOUT); | ||
231 | 267 | ||
232 | /* More of suid paranoia if called by non-root: */ | 268 | /* More of suid paranoia if called by non-root: */ |
233 | /* Clear dangerous stuff, set PATH */ | 269 | /* Clear dangerous stuff, set PATH */ |
@@ -239,6 +275,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
239 | * (The name of the function is misleading. Not daemonizing here.) */ | 275 | * (The name of the function is misleading. Not daemonizing here.) */ |
240 | bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE | DAEMON_CLOSE_EXTRA_FDS, NULL); | 276 | bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE | DAEMON_CLOSE_EXTRA_FDS, NULL); |
241 | 277 | ||
278 | username[0] = '\0'; | ||
242 | opt = getopt32(argv, "f:h:p", &opt_user, &opt_host); | 279 | opt = getopt32(argv, "f:h:p", &opt_user, &opt_host); |
243 | if (opt & LOGIN_OPT_f) { | 280 | if (opt & LOGIN_OPT_f) { |
244 | if (!run_by_root) | 281 | if (!run_by_root) |
@@ -249,9 +286,19 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
249 | if (argv[0]) /* user from command line (getty) */ | 286 | if (argv[0]) /* user from command line (getty) */ |
250 | safe_strncpy(username, argv[0], sizeof(username)); | 287 | safe_strncpy(username, argv[0], sizeof(username)); |
251 | 288 | ||
252 | /* Let's find out and memorize our tty */ | 289 | /* Save tty attributes - and by doing it, check that it's indeed a tty */ |
253 | if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO)) | 290 | if (tcgetattr(STDIN_FILENO, &G.tty_attrs) < 0 |
291 | || !isatty(STDOUT_FILENO) | ||
292 | /*|| !isatty(STDERR_FILENO) - no, guess some people might want to redirect this */ | ||
293 | ) { | ||
254 | return EXIT_FAILURE; /* Must be a terminal */ | 294 | return EXIT_FAILURE; /* Must be a terminal */ |
295 | } | ||
296 | |||
297 | /* We install timeout handler only _after_ we saved G.tty_attrs */ | ||
298 | signal(SIGALRM, alarm_handler); | ||
299 | alarm(TIMEOUT); | ||
300 | |||
301 | /* Find out and memorize our tty name */ | ||
255 | full_tty = xmalloc_ttyname(STDIN_FILENO); | 302 | full_tty = xmalloc_ttyname(STDIN_FILENO); |
256 | if (!full_tty) | 303 | if (!full_tty) |
257 | full_tty = xstrdup("UNKNOWN"); | 304 | full_tty = xstrdup("UNKNOWN"); |
@@ -359,14 +406,17 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
359 | if (opt & LOGIN_OPT_f) | 406 | if (opt & LOGIN_OPT_f) |
360 | break; /* -f USER: success without asking passwd */ | 407 | break; /* -f USER: success without asking passwd */ |
361 | 408 | ||
362 | if (pw->pw_uid == 0 && !check_securetty()) | 409 | if (pw->pw_uid == 0 && !check_securetty(short_tty)) |
363 | goto auth_failed; | 410 | goto auth_failed; |
364 | 411 | ||
365 | /* Don't check the password if password entry is empty (!) */ | 412 | /* Don't check the password if password entry is empty (!) */ |
366 | if (!pw->pw_passwd[0]) | 413 | if (!pw->pw_passwd[0]) |
367 | break; | 414 | break; |
368 | fake_it: | 415 | fake_it: |
369 | /* authorization takes place here */ | 416 | /* Password reading and authorization takes place here. |
417 | * Note that reads (in no-echo mode) trash tty attributes. | ||
418 | * If we get interrupted by SIGALRM, we need to restore attrs. | ||
419 | */ | ||
370 | if (correct_password(pw)) | 420 | if (correct_password(pw)) |
371 | break; | 421 | break; |
372 | #endif /* ENABLE_PAM */ | 422 | #endif /* ENABLE_PAM */ |
@@ -393,7 +443,22 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
393 | if (pw->pw_uid != 0) | 443 | if (pw->pw_uid != 0) |
394 | die_if_nologin(); | 444 | die_if_nologin(); |
395 | 445 | ||
396 | IF_SELINUX(initselinux(username, full_tty, &user_sid)); | 446 | #if ENABLE_LOGIN_SESSION_AS_CHILD |
447 | child_pid = vfork(); | ||
448 | if (child_pid != 0) { | ||
449 | if (child_pid < 0) | ||
450 | bb_perror_msg("vfork"); | ||
451 | else { | ||
452 | if (safe_waitpid(child_pid, NULL, 0) == -1) | ||
453 | bb_perror_msg("waitpid"); | ||
454 | update_utmp(child_pid, DEAD_PROCESS, NULL, NULL, NULL); | ||
455 | } | ||
456 | IF_PAM(login_pam_end(pamh);) | ||
457 | return 0; | ||
458 | } | ||
459 | #endif | ||
460 | |||
461 | IF_SELINUX(initselinux(username, full_tty, &user_sid);) | ||
397 | 462 | ||
398 | /* Try these, but don't complain if they fail. | 463 | /* Try these, but don't complain if they fail. |
399 | * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */ | 464 | * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */ |
diff --git a/mailutils/mail.c b/mailutils/mail.c index 66c79471f..f5260d9db 100644 --- a/mailutils/mail.c +++ b/mailutils/mail.c | |||
@@ -57,10 +57,13 @@ void FAST_FUNC launch_helper(const char **argv) | |||
57 | G.helper_pid = xvfork(); | 57 | G.helper_pid = xvfork(); |
58 | 58 | ||
59 | i = (!G.helper_pid) * 2; // for parent:0, for child:2 | 59 | i = (!G.helper_pid) * 2; // for parent:0, for child:2 |
60 | close(pipes[i + 1]); // 1 or 3 - closing one write end | 60 | close(pipes[i + 1]); // 1 or 3 - closing one write end |
61 | close(pipes[2 - i]); // 2 or 0 - closing one read end | 61 | close(pipes[2 - i]); // 2 or 0 - closing one read end |
62 | xmove_fd(pipes[i], STDIN_FILENO); // 0 or 2 - using other read end | 62 | xmove_fd(pipes[i], STDIN_FILENO); // 0 or 2 - using other read end |
63 | xmove_fd(pipes[3 - i], STDOUT_FILENO); // 3 or 1 - other write end | 63 | xmove_fd(pipes[3 - i], STDOUT_FILENO); // 3 or 1 - using other write end |
64 | // End result: | ||
65 | // parent stdout [3] -> child stdin [2] | ||
66 | // child stdout [1] -> parent stdin [0] | ||
64 | 67 | ||
65 | if (!G.helper_pid) { | 68 | if (!G.helper_pid) { |
66 | // child: try to execute connection helper | 69 | // child: try to execute connection helper |
diff --git a/mailutils/makemime.c b/mailutils/makemime.c index 4dc53a3b2..a9ff03d03 100644 --- a/mailutils/makemime.c +++ b/mailutils/makemime.c | |||
@@ -164,7 +164,7 @@ int makemime_main(int argc UNUSED_PARAM, char **argv) | |||
164 | // parse options | 164 | // parse options |
165 | opt_complementary = "a::"; | 165 | opt_complementary = "a::"; |
166 | opts = getopt32(argv, | 166 | opts = getopt32(argv, |
167 | "c:e:o:C:N:a", //:m:j:", | 167 | "c:e:o:C:N:a:", //:m:j:", |
168 | &G.content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers //, NULL, NULL | 168 | &G.content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers //, NULL, NULL |
169 | ); | 169 | ); |
170 | //argc -= optind; | 170 | //argc -= optind; |
diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index e0aff20fb..dbd491002 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c | |||
@@ -26,18 +26,18 @@ | |||
26 | //usage: "\n Examples:" | 26 | //usage: "\n Examples:" |
27 | //usage: "\n -H 'exec openssl s_client -quiet -tls1 -starttls smtp" | 27 | //usage: "\n -H 'exec openssl s_client -quiet -tls1 -starttls smtp" |
28 | //usage: "\n -connect smtp.gmail.com:25' <email.txt" | 28 | //usage: "\n -connect smtp.gmail.com:25' <email.txt" |
29 | //usage: "\n [4<username_and_passwd.txt | -au<username> -ap<password>]" | 29 | //usage: "\n [4<username_and_passwd.txt | -auUSER -apPASS]" |
30 | //usage: "\n -H 'exec openssl s_client -quiet -tls1" | 30 | //usage: "\n -H 'exec openssl s_client -quiet -tls1" |
31 | //usage: "\n -connect smtp.gmail.com:465' <email.txt" | 31 | //usage: "\n -connect smtp.gmail.com:465' <email.txt" |
32 | //usage: "\n [4<username_and_passwd.txt | -au<username> -ap<password>]" | 32 | //usage: "\n [4<username_and_passwd.txt | -auUSER -apPASS]" |
33 | //usage: "\n -S HOST[:PORT] Server" | 33 | //usage: "\n -S HOST[:PORT] Server" |
34 | //usage: "\n -au<username> Username for AUTH LOGIN" | 34 | //usage: "\n -auUSER Username for AUTH LOGIN" |
35 | //usage: "\n -ap<password> Password for AUTH LOGIN" | 35 | //usage: "\n -apPASS Password for AUTH LOGIN" |
36 | //usage: "\n -am<method> Authentication method. Ignored. LOGIN is implied" | 36 | ////usage: "\n -amMETHOD Authentication method. Ignored. LOGIN is implied" |
37 | //usage: "\n" | 37 | //usage: "\n" |
38 | //usage: "\nOther options are silently ignored; -oi -t is implied" | 38 | //usage: "\nOther options are silently ignored; -oi -t is implied" |
39 | //usage: IF_MAKEMIME( | 39 | //usage: IF_MAKEMIME( |
40 | //usage: "\nUse makemime applet to create message with attachments" | 40 | //usage: "\nUse makemime to create emails with attachments" |
41 | //usage: ) | 41 | //usage: ) |
42 | 42 | ||
43 | #include "libbb.h" | 43 | #include "libbb.h" |
@@ -66,7 +66,7 @@ static int smtp_checkp(const char *fmt, const char *param, int code) | |||
66 | // if not equal -> die saying msg | 66 | // if not equal -> die saying msg |
67 | while ((answer = xmalloc_fgetline(stdin)) != NULL) { | 67 | while ((answer = xmalloc_fgetline(stdin)) != NULL) { |
68 | if (verbose) | 68 | if (verbose) |
69 | bb_error_msg("recv:'%.*s' %d", (int)(strchrnul(answer, '\r') - answer), answer, verbose); | 69 | bb_error_msg("recv:'%.*s'", (int)(strchrnul(answer, '\r') - answer), answer); |
70 | if (strlen(answer) <= 3 || '-' != answer[3]) | 70 | if (strlen(answer) <= 3 || '-' != answer[3]) |
71 | break; | 71 | break; |
72 | free(answer); | 72 | free(answer); |
@@ -75,10 +75,11 @@ static int smtp_checkp(const char *fmt, const char *param, int code) | |||
75 | int n = atoi(answer); | 75 | int n = atoi(answer); |
76 | if (timeout) | 76 | if (timeout) |
77 | alarm(0); | 77 | alarm(0); |
78 | free(msg); | ||
79 | free(answer); | 78 | free(answer); |
80 | if (-1 == code || n == code) | 79 | if (-1 == code || n == code) { |
80 | free(msg); | ||
81 | return n; | 81 | return n; |
82 | } | ||
82 | } | 83 | } |
83 | bb_error_msg_and_die("%s failed", msg); | 84 | bb_error_msg_and_die("%s failed", msg); |
84 | } | 85 | } |
@@ -176,11 +177,35 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
176 | const char *args[] = { "sh", "-c", opt_connect, NULL }; | 177 | const char *args[] = { "sh", "-c", opt_connect, NULL }; |
177 | // plug it in | 178 | // plug it in |
178 | launch_helper(args); | 179 | launch_helper(args); |
179 | // vanilla connection | 180 | // Now: |
181 | // our stdout will go to helper's stdin, | ||
182 | // helper's stdout will be available on our stdin. | ||
183 | |||
184 | // Wait for initial server message. | ||
185 | // If helper (such as openssl) invokes STARTTLS, the initial 220 | ||
186 | // is swallowed by helper (and not repeated after TLS is initiated). | ||
187 | // We will send NOOP cmd to server and check the response. | ||
188 | // We should get 220+250 on plain connection, 250 on STARTTLSed session. | ||
189 | // | ||
190 | // The problem here is some servers delay initial 220 message, | ||
191 | // and consider client to be a spammer if it starts sending cmds | ||
192 | // before 220 reached it. The code below is unsafe in this regard: | ||
193 | // in non-STARTTLSed case, we potentially send NOOP before 220 | ||
194 | // is sent by server. | ||
195 | // Ideas? (--delay SECS opt? --assume-starttls-helper opt?) | ||
196 | code = smtp_check("NOOP", -1); | ||
197 | if (code == 220) | ||
198 | // we got 220 - this is not STARTTLSed connection, | ||
199 | // eat 250 response to our NOOP | ||
200 | smtp_check(NULL, 250); | ||
201 | else | ||
202 | if (code != 250) | ||
203 | bb_error_msg_and_die("SMTP init failed"); | ||
180 | } else { | 204 | } else { |
205 | // vanilla connection | ||
181 | int fd; | 206 | int fd; |
182 | // host[:port] not explicitly specified? -> use $SMTPHOST | 207 | // host[:port] not explicitly specified? -> use $SMTPHOST |
183 | // no $SMTPHOST ? -> use localhost | 208 | // no $SMTPHOST? -> use localhost |
184 | if (!(opts & OPT_S)) { | 209 | if (!(opts & OPT_S)) { |
185 | opt_connect = getenv("SMTPHOST"); | 210 | opt_connect = getenv("SMTPHOST"); |
186 | if (!opt_connect) | 211 | if (!opt_connect) |
@@ -191,25 +216,14 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
191 | // and make ourselves a simple IO filter | 216 | // and make ourselves a simple IO filter |
192 | xmove_fd(fd, STDIN_FILENO); | 217 | xmove_fd(fd, STDIN_FILENO); |
193 | xdup2(STDIN_FILENO, STDOUT_FILENO); | 218 | xdup2(STDIN_FILENO, STDOUT_FILENO); |
194 | } | ||
195 | // N.B. from now we know nothing about network :) | ||
196 | 219 | ||
197 | // wait for initial server OK | 220 | // Wait for initial server 220 message |
198 | // N.B. if we used openssl the initial 220 answer is already swallowed during openssl TLS init procedure | 221 | smtp_check(NULL, 220); |
199 | // so we need to kick the server to see whether we are ok | 222 | } |
200 | code = smtp_check("NOOP", -1); | ||
201 | // 220 on plain connection, 250 on openssl-helped TLS session | ||
202 | if (220 == code) | ||
203 | smtp_check(NULL, 250); // reread the code to stay in sync | ||
204 | else if (250 != code) | ||
205 | bb_error_msg_and_die("INIT failed"); | ||
206 | 223 | ||
207 | // we should start with modern EHLO | 224 | // we should start with modern EHLO |
208 | if (250 != smtp_checkp("EHLO %s", domain, -1)) { | 225 | if (250 != smtp_checkp("EHLO %s", domain, -1)) |
209 | smtp_checkp("HELO %s", domain, 250); | 226 | smtp_checkp("HELO %s", domain, 250); |
210 | } | ||
211 | if (ENABLE_FEATURE_CLEAN_UP) | ||
212 | free(domain); | ||
213 | 227 | ||
214 | // perform authentication | 228 | // perform authentication |
215 | if (opts & OPT_a) { | 229 | if (opts & OPT_a) { |
@@ -224,7 +238,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
224 | } | 238 | } |
225 | 239 | ||
226 | // set sender | 240 | // set sender |
227 | // N.B. we have here a very loosely defined algotythm | 241 | // N.B. we have here a very loosely defined algorythm |
228 | // since sendmail historically offers no means to specify secrets on cmdline. | 242 | // since sendmail historically offers no means to specify secrets on cmdline. |
229 | // 1) server can require no authentication -> | 243 | // 1) server can require no authentication -> |
230 | // we must just provide a (possibly fake) reply address. | 244 | // we must just provide a (possibly fake) reply address. |
@@ -241,8 +255,6 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
241 | // G.user = xuid2uname(getuid()); | 255 | // G.user = xuid2uname(getuid()); |
242 | // opt_from = xasprintf("%s@%s", G.user, domain); | 256 | // opt_from = xasprintf("%s@%s", G.user, domain); |
243 | //} | 257 | //} |
244 | //if (ENABLE_FEATURE_CLEAN_UP) | ||
245 | // free(domain); | ||
246 | smtp_checkp("MAIL FROM:<%s>", opt_from, 250); | 258 | smtp_checkp("MAIL FROM:<%s>", opt_from, 250); |
247 | 259 | ||
248 | // process message | 260 | // process message |
@@ -272,26 +284,26 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
272 | if (0 == strncasecmp("To:", s, 3) || 0 == strncasecmp("Bcc:" + 1, s, 3)) { | 284 | if (0 == strncasecmp("To:", s, 3) || 0 == strncasecmp("Bcc:" + 1, s, 3)) { |
273 | rcptto(sane_address(s+3)); | 285 | rcptto(sane_address(s+3)); |
274 | goto addheader; | 286 | goto addheader; |
287 | } | ||
275 | // Bcc: header adds blind copy (hidden) recipient | 288 | // Bcc: header adds blind copy (hidden) recipient |
276 | } else if (0 == strncasecmp("Bcc:", s, 4)) { | 289 | if (0 == strncasecmp("Bcc:", s, 4)) { |
277 | rcptto(sane_address(s+4)); | 290 | rcptto(sane_address(s+4)); |
278 | free(s); | 291 | free(s); |
279 | // N.B. Bcc: vanishes from headers! | 292 | // N.B. Bcc: vanishes from headers! |
280 | 293 | } else | |
281 | // other headers go verbatim | 294 | if (strchr(s, ':') || (list && skip_whitespace(s) != s)) { |
282 | 295 | // other headers go verbatim | |
283 | // N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines. | 296 | // N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines. |
284 | // Continuation is denoted by prefixing additional lines with whitespace(s). | 297 | // Continuation is denoted by prefixing additional lines with whitespace(s). |
285 | // Thanks (stefan.seyfried at googlemail.com) for pointing this out. | 298 | // Thanks (stefan.seyfried at googlemail.com) for pointing this out. |
286 | } else if (strchr(s, ':') || (list && skip_whitespace(s) != s)) { | ||
287 | addheader: | 299 | addheader: |
288 | // N.B. we allow MAX_HEADERS generic headers at most to prevent attacks | 300 | // N.B. we allow MAX_HEADERS generic headers at most to prevent attacks |
289 | if (MAX_HEADERS && ++nheaders >= MAX_HEADERS) | 301 | if (MAX_HEADERS && ++nheaders >= MAX_HEADERS) |
290 | goto bail; | 302 | goto bail; |
291 | llist_add_to_end(&list, s); | 303 | llist_add_to_end(&list, s); |
292 | // a line without ":" (an empty line too, by definition) doesn't look like a valid header | ||
293 | // so stop "analyze headers" mode | ||
294 | } else { | 304 | } else { |
305 | // a line without ":" (an empty line too, by definition) doesn't look like a valid header | ||
306 | // so stop "analyze headers" mode | ||
295 | reenter: | 307 | reenter: |
296 | // put recipients specified on cmdline | 308 | // put recipients specified on cmdline |
297 | while (*argv) { | 309 | while (*argv) { |
diff --git a/miscutils/bbconfig.c b/miscutils/bbconfig.c index e8be81352..e5f4eb379 100644 --- a/miscutils/bbconfig.c +++ b/miscutils/bbconfig.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | #include "bbconfigopts.h" | 11 | #include "bbconfigopts.h" |
12 | #if ENABLE_FEATURE_COMPRESS_BBCONFIG | 12 | #if ENABLE_FEATURE_COMPRESS_BBCONFIG |
13 | # include "archive.h" | 13 | # include "bb_archive.h" |
14 | # include "bbconfigopts_bz2.h" | 14 | # include "bbconfigopts_bz2.h" |
15 | #endif | 15 | #endif |
16 | 16 | ||
diff --git a/miscutils/conspy.c b/miscutils/conspy.c index 433c3e829..1a46a4340 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | //config:config CONSPY | 17 | //config:config CONSPY |
18 | //config: bool "conspy" | 18 | //config: bool "conspy" |
19 | //config: default n | 19 | //config: default y |
20 | //config: select PLATFORM_LINUX | 20 | //config: select PLATFORM_LINUX |
21 | //config: help | 21 | //config: help |
22 | //config: A text-mode VNC like program for Linux virtual terminals. | 22 | //config: A text-mode VNC like program for Linux virtual terminals. |
@@ -25,25 +25,31 @@ | |||
25 | //config: or conspy -cs NUM poor man's GNU screen like | 25 | //config: or conspy -cs NUM poor man's GNU screen like |
26 | 26 | ||
27 | //usage:#define conspy_trivial_usage | 27 | //usage:#define conspy_trivial_usage |
28 | //usage: "[-vcsndf] [-x COL] [-y LINE] [CONSOLE_NO]" | 28 | //usage: "[-vcsndfFQ] [-x COL] [-y LINE] [CONSOLE_NO]" |
29 | //usage:#define conspy_full_usage "\n\n" | 29 | //usage:#define conspy_full_usage "\n\n" |
30 | //usage: "A text-mode VNC like program for Linux virtual consoles." | 30 | //usage: "A text-mode VNC like program for Linux virtual consoles." |
31 | //usage: "\nTo exit, quickly press ESC 3 times." | 31 | //usage: "\nTo exit, quickly press ESC 3 times." |
32 | //usage: "\n" | 32 | //usage: "\n" |
33 | //usage: "\n -v Don't send keystrokes to the console" | 33 | //usage: "\n -v Don't send keystrokes to the console" |
34 | //usage: "\n -c Create missing devices in /dev" | 34 | //usage: "\n -c Create missing /dev/{tty,vcsa}N" |
35 | //usage: "\n -s Open a SHELL session" | 35 | //usage: "\n -s Open a SHELL session" |
36 | //usage: "\n -n Black & white" | 36 | //usage: "\n -n Black & white" |
37 | //usage: "\n -d Dump console to stdout" | 37 | //usage: "\n -d Dump console to stdout" |
38 | //usage: "\n -f Follow cursor" | 38 | //usage: "\n -f Follow cursor" |
39 | //usage: "\n -F Assume console is on a framebuffer device" | ||
40 | //usage: "\n -Q Disable exit on ESC-ESC-ESC" | ||
39 | //usage: "\n -x COL Starting column" | 41 | //usage: "\n -x COL Starting column" |
40 | //usage: "\n -y LINE Starting line" | 42 | //usage: "\n -y LINE Starting line" |
41 | 43 | ||
42 | #include "libbb.h" | 44 | #include "libbb.h" |
43 | #include <sys/kd.h> | 45 | #include <sys/kd.h> |
44 | 46 | ||
45 | |||
46 | #define ESC "\033" | 47 | #define ESC "\033" |
48 | #define CURSOR_ON -1 | ||
49 | #define CURSOR_OFF 1 | ||
50 | |||
51 | #define DEV_TTY "/dev/tty" | ||
52 | #define DEV_VCSA "/dev/vcsa" | ||
47 | 53 | ||
48 | struct screen_info { | 54 | struct screen_info { |
49 | unsigned char lines, cols, cursor_x, cursor_y; | 55 | unsigned char lines, cols, cursor_x, cursor_y; |
@@ -72,19 +78,17 @@ struct globals { | |||
72 | unsigned col; | 78 | unsigned col; |
73 | unsigned line; | 79 | unsigned line; |
74 | smallint curoff; // unknown:0 cursor on:-1 cursor off:1 | 80 | smallint curoff; // unknown:0 cursor on:-1 cursor off:1 |
75 | char attrbuf[sizeof(ESC"[0;1;5;30;40m")]; | 81 | char attrbuf[sizeof("0;1;5;30;40m")]; |
76 | // remote console | 82 | // remote console |
77 | struct screen_info remote; | 83 | struct screen_info remote; |
78 | // saved local tty terminfo | 84 | // saved local tty terminfo |
79 | struct termios term_orig; | 85 | struct termios term_orig; |
80 | char vcsa_name[sizeof("/dev/vcsaNN")]; | 86 | char vcsa_name[sizeof(DEV_VCSA "NN")]; |
81 | }; | 87 | }; |
82 | 88 | ||
83 | #define G (*ptr_to_globals) | 89 | #define G (*ptr_to_globals) |
84 | #define INIT_G() do { \ | 90 | #define INIT_G() do { \ |
85 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 91 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
86 | G.attrbuf[0] = '\033'; \ | ||
87 | G.attrbuf[1] = '['; \ | ||
88 | G.width = G.height = UINT_MAX; \ | 92 | G.width = G.height = UINT_MAX; \ |
89 | G.last_attr--; \ | 93 | G.last_attr--; \ |
90 | } while (0) | 94 | } while (0) |
@@ -92,18 +96,26 @@ struct globals { | |||
92 | enum { | 96 | enum { |
93 | FLAG_v, // view only | 97 | FLAG_v, // view only |
94 | FLAG_c, // create device if need | 98 | FLAG_c, // create device if need |
99 | FLAG_Q, // never exit | ||
95 | FLAG_s, // session | 100 | FLAG_s, // session |
96 | FLAG_n, // no colors | 101 | FLAG_n, // no colors |
97 | FLAG_d, // dump screen | 102 | FLAG_d, // dump screen |
98 | FLAG_f, // follow cursor | 103 | FLAG_f, // follow cursor |
104 | FLAG_F, // framebuffer | ||
99 | }; | 105 | }; |
100 | #define FLAG(x) (1 << FLAG_##x) | 106 | #define FLAG(x) (1 << FLAG_##x) |
101 | #define BW (option_mask32 & FLAG(n)) | 107 | #define BW (option_mask32 & FLAG(n)) |
102 | 108 | ||
109 | static void putcsi(const char *s) | ||
110 | { | ||
111 | fputs(ESC"[", stdout); | ||
112 | fputs(s, stdout); | ||
113 | } | ||
114 | |||
103 | static void clrscr(void) | 115 | static void clrscr(void) |
104 | { | 116 | { |
105 | // Home, clear till end of screen | 117 | // Home, clear till end of screen |
106 | fputs(ESC"[1;1H" ESC"[J", stdout); | 118 | putcsi("1;1H" ESC"[J"); |
107 | G.col = G.line = 0; | 119 | G.col = G.line = 0; |
108 | } | 120 | } |
109 | 121 | ||
@@ -111,7 +123,7 @@ static void set_cursor(int state) | |||
111 | { | 123 | { |
112 | if (G.curoff != state) { | 124 | if (G.curoff != state) { |
113 | G.curoff = state; | 125 | G.curoff = state; |
114 | fputs(ESC"[?25", stdout); | 126 | putcsi("?25"); |
115 | bb_putchar("h?l"[1 + state]); | 127 | bb_putchar("h?l"[1 + state]); |
116 | } | 128 | } |
117 | } | 129 | } |
@@ -125,18 +137,19 @@ static void gotoxy(int col, int line) | |||
125 | } | 137 | } |
126 | } | 138 | } |
127 | 139 | ||
140 | static void cleanup(int code) NORETURN; | ||
128 | static void cleanup(int code) | 141 | static void cleanup(int code) |
129 | { | 142 | { |
130 | set_cursor(-1); // cursor on | 143 | set_cursor(CURSOR_ON); |
131 | tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig); | 144 | tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig); |
132 | if (ENABLE_FEATURE_CLEAN_UP) { | 145 | if (ENABLE_FEATURE_CLEAN_UP) { |
133 | close(G.kbd_fd); | 146 | close(G.kbd_fd); |
134 | } | 147 | } |
135 | // Reset attributes | 148 | // Reset attributes |
136 | if (!BW) | 149 | if (!BW) |
137 | fputs(ESC"[0m", stdout); | 150 | putcsi("0m"); |
138 | bb_putchar('\n'); | 151 | bb_putchar('\n'); |
139 | if (code > 1) | 152 | if (code > EXIT_FAILURE) |
140 | kill_myself_with_sig(code); | 153 | kill_myself_with_sig(code); |
141 | exit(code); | 154 | exit(code); |
142 | } | 155 | } |
@@ -157,8 +170,8 @@ static void screen_read_close(void) | |||
157 | G.size = i; | 170 | G.size = i; |
158 | G.data = xzalloc(2 * i); | 171 | G.data = xzalloc(2 * i); |
159 | } | 172 | } |
160 | else if (G.size != i) { | 173 | if (G.size != i) { |
161 | cleanup(1); | 174 | cleanup(EXIT_FAILURE); |
162 | } | 175 | } |
163 | data = G.data + G.current; | 176 | data = G.data + G.current; |
164 | xread(vcsa_fd, data, G.size); | 177 | xread(vcsa_fd, data, G.size); |
@@ -168,10 +181,15 @@ static void screen_read_close(void) | |||
168 | unsigned x = j - G.x; // if will catch j < G.x too | 181 | unsigned x = j - G.x; // if will catch j < G.x too |
169 | unsigned y = i - G.y; // if will catch i < G.y too | 182 | unsigned y = i - G.y; // if will catch i < G.y too |
170 | 183 | ||
171 | if (CHAR(data) < ' ') | ||
172 | CHAR(data) = ' '; | ||
173 | if (y >= G.height || x >= G.width) | 184 | if (y >= G.height || x >= G.width) |
174 | DATA(data) = 0; | 185 | DATA(data) = 0; |
186 | else { | ||
187 | uint8_t ch = CHAR(data); | ||
188 | if (ch < ' ') | ||
189 | CHAR(data) = ch | 0x40; | ||
190 | else if (ch > 0x7e) | ||
191 | CHAR(data) = '?'; | ||
192 | } | ||
175 | } | 193 | } |
176 | } | 194 | } |
177 | } | 195 | } |
@@ -179,10 +197,13 @@ static void screen_read_close(void) | |||
179 | static void screen_char(char *data) | 197 | static void screen_char(char *data) |
180 | { | 198 | { |
181 | if (!BW) { | 199 | if (!BW) { |
200 | uint8_t attr_diff; | ||
182 | uint8_t attr = ATTR(data); | 201 | uint8_t attr = ATTR(data); |
183 | //uint8_t attr = ATTR(data) >> 1; // for framebuffer console | ||
184 | uint8_t attr_diff = G.last_attr ^ attr; | ||
185 | 202 | ||
203 | if (option_mask32 & FLAG(F)) { | ||
204 | attr >>= 1; | ||
205 | } | ||
206 | attr_diff = G.last_attr ^ attr; | ||
186 | if (attr_diff) { | 207 | if (attr_diff) { |
187 | // Attribute layout for VGA compatible text videobuffer: | 208 | // Attribute layout for VGA compatible text videobuffer: |
188 | // blinking text | 209 | // blinking text |
@@ -213,7 +234,7 @@ static void screen_char(char *data) | |||
213 | const uint8_t bg_mask = 0x70, blink_mask = 0x80; | 234 | const uint8_t bg_mask = 0x70, blink_mask = 0x80; |
214 | char *ptr; | 235 | char *ptr; |
215 | 236 | ||
216 | ptr = G.attrbuf + 2; // skip "ESC [" | 237 | ptr = G.attrbuf; |
217 | 238 | ||
218 | // (G.last_attr & ~attr) has 1 only where | 239 | // (G.last_attr & ~attr) has 1 only where |
219 | // G.last_attr has 1 but attr has 0. | 240 | // G.last_attr has 1 but attr has 0. |
@@ -244,12 +265,12 @@ static void screen_char(char *data) | |||
244 | if (attr_diff & bg_mask) { | 265 | if (attr_diff & bg_mask) { |
245 | *ptr++ = '4'; | 266 | *ptr++ = '4'; |
246 | *ptr++ = color[(attr & bg_mask) >> 4]; | 267 | *ptr++ = color[(attr & bg_mask) >> 4]; |
247 | *ptr++ = ';'; | 268 | ptr++; // last attribute |
248 | } | 269 | } |
249 | if (ptr != G.attrbuf + 2) { | 270 | if (ptr != G.attrbuf) { |
250 | ptr[-1] = 'm'; | 271 | ptr[-1] = 'm'; |
251 | *ptr = '\0'; | 272 | *ptr = '\0'; |
252 | fputs(G.attrbuf, stdout); | 273 | putcsi(G.attrbuf); |
253 | } | 274 | } |
254 | } | 275 | } |
255 | } | 276 | } |
@@ -292,11 +313,11 @@ static void curmove(void) | |||
292 | { | 313 | { |
293 | unsigned cx = G.remote.cursor_x - G.x; | 314 | unsigned cx = G.remote.cursor_x - G.x; |
294 | unsigned cy = G.remote.cursor_y - G.y; | 315 | unsigned cy = G.remote.cursor_y - G.y; |
295 | int cursor = 1; | 316 | int cursor = CURSOR_OFF; |
296 | 317 | ||
297 | if (cx < G.width && cy < G.height) { | 318 | if (cx < G.width && cy < G.height) { |
298 | gotoxy(cx, cy); | 319 | gotoxy(cx, cy); |
299 | cursor = -1; | 320 | cursor = CURSOR_ON; |
300 | } | 321 | } |
301 | set_cursor(cursor); | 322 | set_cursor(cursor); |
302 | } | 323 | } |
@@ -341,7 +362,7 @@ static NOINLINE void start_shell_in_child(const char* tty_name) | |||
341 | int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 362 | int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
342 | int conspy_main(int argc UNUSED_PARAM, char **argv) | 363 | int conspy_main(int argc UNUSED_PARAM, char **argv) |
343 | { | 364 | { |
344 | char tty_name[sizeof("/dev/ttyNN")]; | 365 | char tty_name[sizeof(DEV_TTY "NN")]; |
345 | #define keybuf bb_common_bufsiz1 | 366 | #define keybuf bb_common_bufsiz1 |
346 | struct termios termbuf; | 367 | struct termios termbuf; |
347 | unsigned opts; | 368 | unsigned opts; |
@@ -351,26 +372,28 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
351 | static const char getopt_longopts[] ALIGN1 = | 372 | static const char getopt_longopts[] ALIGN1 = |
352 | "viewonly\0" No_argument "v" | 373 | "viewonly\0" No_argument "v" |
353 | "createdevice\0" No_argument "c" | 374 | "createdevice\0" No_argument "c" |
375 | "neverquit\0" No_argument "Q" | ||
354 | "session\0" No_argument "s" | 376 | "session\0" No_argument "s" |
355 | "nocolors\0" No_argument "n" | 377 | "nocolors\0" No_argument "n" |
356 | "dump\0" No_argument "d" | 378 | "dump\0" No_argument "d" |
357 | "follow\0" No_argument "f" | 379 | "follow\0" No_argument "f" |
380 | "framebuffer\0" No_argument "F" | ||
358 | ; | 381 | ; |
359 | 382 | ||
360 | applet_long_options = getopt_longopts; | 383 | applet_long_options = getopt_longopts; |
361 | #endif | 384 | #endif |
362 | INIT_G(); | 385 | INIT_G(); |
363 | strcpy(G.vcsa_name, "/dev/vcsa"); | 386 | strcpy(G.vcsa_name, DEV_VCSA); |
364 | 387 | ||
365 | opt_complementary = "x+:y+"; // numeric params | 388 | opt_complementary = "x+:y+"; // numeric params |
366 | opts = getopt32(argv, "vcsndfx:y:", &G.x, &G.y); | 389 | opts = getopt32(argv, "vcQsndfFx:y:", &G.x, &G.y); |
367 | argv += optind; | 390 | argv += optind; |
368 | ttynum = 0; | 391 | ttynum = 0; |
369 | if (argv[0]) { | 392 | if (argv[0]) { |
370 | ttynum = xatou_range(argv[0], 0, 63); | 393 | ttynum = xatou_range(argv[0], 0, 63); |
371 | sprintf(G.vcsa_name + sizeof("/dev/vcsa")-1, "%u", ttynum); | 394 | sprintf(G.vcsa_name + sizeof(DEV_VCSA)-1, "%u", ttynum); |
372 | } | 395 | } |
373 | sprintf(tty_name, "%s%u", "/dev/tty", ttynum); | 396 | sprintf(tty_name, "%s%u", DEV_TTY, ttynum); |
374 | if (opts & FLAG(c)) { | 397 | if (opts & FLAG(c)) { |
375 | if ((opts & (FLAG(s)|FLAG(v))) != FLAG(v)) | 398 | if ((opts & (FLAG(s)|FLAG(v))) != FLAG(v)) |
376 | create_cdev_if_doesnt_exist(tty_name, makedev(4, ttynum)); | 399 | create_cdev_if_doesnt_exist(tty_name, makedev(4, ttynum)); |
@@ -481,7 +504,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
481 | char *k; | 504 | char *k; |
482 | case -1: | 505 | case -1: |
483 | if (errno != EINTR) | 506 | if (errno != EINTR) |
484 | cleanup(1); | 507 | goto abort; |
485 | break; | 508 | break; |
486 | case 0: | 509 | case 0: |
487 | if (++G.nokeys >= 4) | 510 | if (++G.nokeys >= 4) |
@@ -492,14 +515,16 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
492 | k = keybuf + G.key_count; | 515 | k = keybuf + G.key_count; |
493 | bytes_read = read(G.kbd_fd, k, sizeof(keybuf) - G.key_count); | 516 | bytes_read = read(G.kbd_fd, k, sizeof(keybuf) - G.key_count); |
494 | if (bytes_read < 0) | 517 | if (bytes_read < 0) |
495 | cleanup(1); | 518 | goto abort; |
496 | 519 | ||
497 | // Do exit processing | 520 | // Do exit processing |
498 | for (i = 0; i < bytes_read; i++) { | 521 | if (!(option_mask32 & FLAG(Q))) { |
499 | if (k[i] != '\033') | 522 | for (i = 0; i < bytes_read; i++) { |
500 | G.escape_count = 0; | 523 | if (k[i] != '\033') |
501 | else if (++G.escape_count >= 3) | 524 | G.escape_count = -1; |
502 | cleanup(0); | 525 | if (++G.escape_count >= 3) |
526 | cleanup(EXIT_SUCCESS); | ||
527 | } | ||
503 | } | 528 | } |
504 | } | 529 | } |
505 | poll_timeout_ms = 250; | 530 | poll_timeout_ms = 250; |
@@ -519,6 +544,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
519 | if (result >= 0) { | 544 | if (result >= 0) { |
520 | char *p = keybuf; | 545 | char *p = keybuf; |
521 | 546 | ||
547 | G.ioerror_count = 0; | ||
522 | if (kbd_mode != K_XLATE && kbd_mode != K_UNICODE) { | 548 | if (kbd_mode != K_XLATE && kbd_mode != K_UNICODE) { |
523 | G.key_count = 0; // scan code mode | 549 | G.key_count = 0; // scan code mode |
524 | } | 550 | } |
@@ -534,16 +560,18 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
534 | poll_timeout_ms = 20; | 560 | poll_timeout_ms = 20; |
535 | } | 561 | } |
536 | } | 562 | } |
563 | // We sometimes get spurious IO errors on the TTY | ||
564 | // as programs close and re-open it | ||
565 | else if (errno != EIO || ++G.ioerror_count > 4) { | ||
566 | if (ENABLE_FEATURE_CLEAN_UP) | ||
567 | close(handle); | ||
568 | goto abort; | ||
569 | } | ||
537 | // Close & re-open tty in case they have | 570 | // Close & re-open tty in case they have |
538 | // swapped virtual consoles | 571 | // swapped virtual consoles |
539 | close(handle); | 572 | close(handle); |
540 | |||
541 | // We sometimes get spurious IO errors on the TTY | ||
542 | // as programs close and re-open it | ||
543 | if (result >= 0) | ||
544 | G.ioerror_count = 0; | ||
545 | else if (errno != EIO || ++G.ioerror_count > 4) | ||
546 | cleanup(1); | ||
547 | } | 573 | } |
548 | } /* while (1) */ | 574 | } /* while (1) */ |
575 | abort: | ||
576 | cleanup(EXIT_FAILURE); | ||
549 | } | 577 | } |
diff --git a/miscutils/crond.c b/miscutils/crond.c index 014016fb6..a0b73c774 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c | |||
@@ -861,7 +861,8 @@ int crond_main(int argc UNUSED_PARAM, char **argv) | |||
861 | 861 | ||
862 | /* "-b after -f is ignored", and so on for every pair a-b */ | 862 | /* "-b after -f is ignored", and so on for every pair a-b */ |
863 | opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") | 863 | opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") |
864 | ":l+:d+"; /* -l and -d have numeric param */ | 864 | /* -l and -d have numeric param */ |
865 | ":l+" IF_FEATURE_CROND_D(":d+"); | ||
865 | opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"), | 866 | opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"), |
866 | &G.log_level, &G.log_filename, &G.crontab_dir_name | 867 | &G.log_level, &G.log_filename, &G.crontab_dir_name |
867 | IF_FEATURE_CROND_D(,&G.log_level)); | 868 | IF_FEATURE_CROND_D(,&G.log_level)); |
diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c index 51ba4729e..04d583df6 100644 --- a/miscutils/fbsplash.c +++ b/miscutils/fbsplash.c | |||
@@ -74,6 +74,43 @@ struct globals { | |||
74 | #define DEBUG_MESSAGE(...) ((void)0) | 74 | #define DEBUG_MESSAGE(...) ((void)0) |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | /** | ||
78 | * Configure palette for RGB:332 | ||
79 | */ | ||
80 | static void fb_setpal(int fd) | ||
81 | { | ||
82 | struct fb_cmap cmap; | ||
83 | /* fb colors are 16 bit */ | ||
84 | unsigned short red[256], green[256], blue[256]; | ||
85 | unsigned i; | ||
86 | |||
87 | /* RGB:332 */ | ||
88 | for (i = 0; i < 256; i++) { | ||
89 | /* Color is encoded in pixel value as rrrgggbb. | ||
90 | * 3-bit color is mapped to 16-bit one as: | ||
91 | * 000 -> 00000000 00000000 | ||
92 | * 001 -> 00100100 10010010 | ||
93 | * ... | ||
94 | * 011 -> 01101101 10110110 | ||
95 | * 100 -> 10010010 01001001 | ||
96 | * ... | ||
97 | * 111 -> 11111111 11111111 | ||
98 | */ | ||
99 | red[i] = (( i >> 5 ) * 0x9249) >> 2; // rrr * 00 10010010 01001001 >> 2 | ||
100 | green[i] = (((i >> 2) & 0x7) * 0x9249) >> 2; // ggg * 00 10010010 01001001 >> 2 | ||
101 | /* 2-bit color is easier: */ | ||
102 | blue[i] = ( i & 0x3) * 0x5555; // bb * 01010101 01010101 | ||
103 | } | ||
104 | |||
105 | cmap.start = 0; | ||
106 | cmap.len = 256; | ||
107 | cmap.red = red; | ||
108 | cmap.green = green; | ||
109 | cmap.blue = blue; | ||
110 | cmap.transp = 0; | ||
111 | |||
112 | xioctl(fd, FBIOPUTCMAP, &cmap); | ||
113 | } | ||
77 | 114 | ||
78 | /** | 115 | /** |
79 | * Open and initialize the framebuffer device | 116 | * Open and initialize the framebuffer device |
@@ -87,8 +124,21 @@ static void fb_open(const char *strfb_device) | |||
87 | xioctl(fbfd, FBIOGET_VSCREENINFO, &G.scr_var); | 124 | xioctl(fbfd, FBIOGET_VSCREENINFO, &G.scr_var); |
88 | xioctl(fbfd, FBIOGET_FSCREENINFO, &G.scr_fix); | 125 | xioctl(fbfd, FBIOGET_FSCREENINFO, &G.scr_fix); |
89 | 126 | ||
90 | if (G.scr_var.bits_per_pixel < 16 || G.scr_var.bits_per_pixel > 32) | 127 | switch (G.scr_var.bits_per_pixel) { |
128 | case 8: | ||
129 | fb_setpal(fbfd); | ||
130 | break; | ||
131 | |||
132 | case 16: | ||
133 | case 24: | ||
134 | case 32: | ||
135 | break; | ||
136 | |||
137 | default: | ||
91 | bb_error_msg_and_die("unsupported %u bpp", (int)G.scr_var.bits_per_pixel); | 138 | bb_error_msg_and_die("unsupported %u bpp", (int)G.scr_var.bits_per_pixel); |
139 | break; | ||
140 | } | ||
141 | |||
92 | G.bytes_per_pixel = (G.scr_var.bits_per_pixel + 7) >> 3; | 142 | G.bytes_per_pixel = (G.scr_var.bits_per_pixel + 7) >> 3; |
93 | 143 | ||
94 | // map the device in memory | 144 | // map the device in memory |
@@ -109,11 +159,17 @@ static void fb_open(const char *strfb_device) | |||
109 | */ | 159 | */ |
110 | static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) | 160 | static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) |
111 | { | 161 | { |
162 | if (G.bytes_per_pixel == 1) { | ||
163 | r = r & 0xe0; // 3-bit red | ||
164 | g = (g >> 3) & 0x1c; // 3-bit green | ||
165 | b = b >> 6; // 2-bit blue | ||
166 | return r + g + b; | ||
167 | } | ||
112 | if (G.bytes_per_pixel == 2) { | 168 | if (G.bytes_per_pixel == 2) { |
113 | r >>= 3; // 5-bit red | 169 | r = (r & 0xf8) << 8; // 5-bit red |
114 | g >>= 2; // 6-bit green | 170 | g = (g & 0xfc) << 3; // 6-bit green |
115 | b >>= 3; // 5-bit blue | 171 | b = b >> 3; // 5-bit blue |
116 | return b + (g << 5) + (r << (5+6)); | 172 | return r + g + b; |
117 | } | 173 | } |
118 | // RGB 888 | 174 | // RGB 888 |
119 | return b + (g << 8) + (r << 16); | 175 | return b + (g << 8) + (r << 16); |
@@ -125,6 +181,9 @@ static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) | |||
125 | static void fb_write_pixel(unsigned char *addr, unsigned pixel) | 181 | static void fb_write_pixel(unsigned char *addr, unsigned pixel) |
126 | { | 182 | { |
127 | switch (G.bytes_per_pixel) { | 183 | switch (G.bytes_per_pixel) { |
184 | case 1: | ||
185 | *addr = pixel; | ||
186 | break; | ||
128 | case 2: | 187 | case 2: |
129 | *(uint16_t *)addr = pixel; | 188 | *(uint16_t *)addr = pixel; |
130 | break; | 189 | break; |
@@ -213,14 +272,15 @@ static void fb_drawfullrectangle(int nx1pos, int ny1pos, int nx2pos, int ny2pos, | |||
213 | */ | 272 | */ |
214 | static void fb_drawprogressbar(unsigned percent) | 273 | static void fb_drawprogressbar(unsigned percent) |
215 | { | 274 | { |
216 | int i, left_x, top_y, width, height; | 275 | int left_x, top_y, pos_x; |
276 | unsigned width, height; | ||
217 | 277 | ||
218 | // outer box | 278 | // outer box |
219 | left_x = G.nbar_posx; | 279 | left_x = G.nbar_posx; |
220 | top_y = G.nbar_posy; | 280 | top_y = G.nbar_posy; |
221 | width = G.nbar_width - 1; | 281 | width = G.nbar_width - 1; |
222 | height = G.nbar_height - 1; | 282 | height = G.nbar_height - 1; |
223 | if ((height | width) < 0) | 283 | if ((int)(height | width) < 0) |
224 | return; | 284 | return; |
225 | // NB: "width" of 1 actually makes rect with width of 2! | 285 | // NB: "width" of 1 actually makes rect with width of 2! |
226 | fb_drawrectangle(); | 286 | fb_drawrectangle(); |
@@ -230,30 +290,37 @@ static void fb_drawprogressbar(unsigned percent) | |||
230 | top_y++; | 290 | top_y++; |
231 | width -= 2; | 291 | width -= 2; |
232 | height -= 2; | 292 | height -= 2; |
233 | if ((height | width) < 0) | 293 | if ((int)(height | width) < 0) |
234 | return; | 294 | return; |
235 | fb_drawfullrectangle( | ||
236 | left_x, top_y, | ||
237 | left_x + width, top_y + height, | ||
238 | G.nbar_colr, G.nbar_colg, G.nbar_colb); | ||
239 | 295 | ||
296 | pos_x = left_x; | ||
240 | if (percent > 0) { | 297 | if (percent > 0) { |
298 | int y; | ||
299 | unsigned i; | ||
300 | |||
241 | // actual progress bar | 301 | // actual progress bar |
242 | width = width * percent / 100; | 302 | pos_x += (unsigned)(width * percent) / 100; |
303 | |||
304 | y = top_y; | ||
243 | i = height; | 305 | i = height; |
244 | if (height == 0) | 306 | if (height == 0) |
245 | height++; // divide by 0 is bad | 307 | height++; // divide by 0 is bad |
246 | while (i >= 0) { | 308 | while (i >= 0) { |
247 | // draw one-line thick "rectangle" | 309 | // draw one-line thick "rectangle" |
248 | // top line will have gray lvl 200, bottom one 100 | 310 | // top line will have gray lvl 200, bottom one 100 |
249 | unsigned gray_level = 100 + i*100/height; | 311 | unsigned gray_level = 100 + i*100 / height; |
250 | fb_drawfullrectangle( | 312 | fb_drawfullrectangle( |
251 | left_x, top_y, left_x + width, top_y, | 313 | left_x, y, pos_x, y, |
252 | gray_level, gray_level, gray_level); | 314 | gray_level, gray_level, gray_level); |
253 | top_y++; | 315 | y++; |
254 | i--; | 316 | i--; |
255 | } | 317 | } |
256 | } | 318 | } |
319 | |||
320 | fb_drawfullrectangle( | ||
321 | pos_x, top_y, | ||
322 | left_x + width, top_y + height, | ||
323 | G.nbar_colr, G.nbar_colg, G.nbar_colb); | ||
257 | } | 324 | } |
258 | 325 | ||
259 | 326 | ||
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index f30e7dec6..a97f3e7b5 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c | |||
@@ -433,6 +433,7 @@ struct BUG_G_too_big { | |||
433 | #define hwif_data (G.hwif_data ) | 433 | #define hwif_data (G.hwif_data ) |
434 | #define hwif_ctrl (G.hwif_ctrl ) | 434 | #define hwif_ctrl (G.hwif_ctrl ) |
435 | #define hwif_irq (G.hwif_irq ) | 435 | #define hwif_irq (G.hwif_irq ) |
436 | #define INIT_G() do { } while (0) | ||
436 | 437 | ||
437 | 438 | ||
438 | /* Busybox messages and functions */ | 439 | /* Busybox messages and functions */ |
@@ -2059,6 +2060,8 @@ int hdparm_main(int argc, char **argv) | |||
2059 | int c; | 2060 | int c; |
2060 | int flagcount = 0; | 2061 | int flagcount = 0; |
2061 | 2062 | ||
2063 | INIT_G(); | ||
2064 | |||
2062 | while ((c = getopt(argc, argv, hdparm_options)) >= 0) { | 2065 | while ((c = getopt(argc, argv, hdparm_options)) >= 0) { |
2063 | flagcount++; | 2066 | flagcount++; |
2064 | IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I')); | 2067 | IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I')); |
diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c index b64e0abb9..7a1a6a2e5 100644 --- a/miscutils/inotifyd.c +++ b/miscutils/inotifyd.c | |||
@@ -33,6 +33,7 @@ | |||
33 | //usage: "Run PROG on filesystem changes." | 33 | //usage: "Run PROG on filesystem changes." |
34 | //usage: "\nWhen a filesystem event matching MASK occurs on FILEn," | 34 | //usage: "\nWhen a filesystem event matching MASK occurs on FILEn," |
35 | //usage: "\nPROG ACTUAL_EVENTS FILEn [SUBFILE] is run." | 35 | //usage: "\nPROG ACTUAL_EVENTS FILEn [SUBFILE] is run." |
36 | //usage: "\nIf PROG is -, events are sent to stdout." | ||
36 | //usage: "\nEvents:" | 37 | //usage: "\nEvents:" |
37 | //usage: "\n a File is accessed" | 38 | //usage: "\n a File is accessed" |
38 | //usage: "\n c File is modified" | 39 | //usage: "\n c File is modified" |
@@ -177,12 +178,20 @@ int inotifyd_main(int argc, char **argv) | |||
177 | *s++ = mask_names[i]; | 178 | *s++ = mask_names[i]; |
178 | } | 179 | } |
179 | *s = '\0'; | 180 | *s = '\0'; |
180 | // bb_error_msg("exec %s %08X\t%s\t%s\t%s", args[0], | 181 | if (LONE_CHAR(args[0], '-')) { |
181 | // ie->mask, events, watches[ie->wd], ie->len ? ie->name : ""); | 182 | /* "inotifyd - FILE": built-in echo */ |
182 | args[1] = events; | 183 | printf(ie->len ? "%s\t%s\t%s\n" : "%s\t%s\n", events, |
183 | args[2] = watches[ie->wd]; | 184 | watches[ie->wd], |
184 | args[3] = ie->len ? ie->name : NULL; | 185 | ie->name); |
185 | spawn_and_wait((char **)args); | 186 | fflush(stdout); |
187 | } else { | ||
188 | // bb_error_msg("exec %s %08X\t%s\t%s\t%s", args[0], | ||
189 | // ie->mask, events, watches[ie->wd], ie->len ? ie->name : ""); | ||
190 | args[1] = events; | ||
191 | args[2] = watches[ie->wd]; | ||
192 | args[3] = ie->len ? ie->name : NULL; | ||
193 | spawn_and_wait((char **)args); | ||
194 | } | ||
186 | // we are done if all files got final x event | 195 | // we are done if all files got final x event |
187 | if (ie->mask & 0x8000) { | 196 | if (ie->mask & 0x8000) { |
188 | if (--argc <= 0) | 197 | if (--argc <= 0) |
diff --git a/miscutils/less.c b/miscutils/less.c index 9543fb9f9..045fd2db3 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
@@ -721,8 +721,8 @@ static void print_found(const char *line) | |||
721 | while (match_status == 0) { | 721 | while (match_status == 0) { |
722 | char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, | 722 | char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, |
723 | growline ? growline : "", | 723 | growline ? growline : "", |
724 | match_structs.rm_so, str, | 724 | (int)match_structs.rm_so, str, |
725 | match_structs.rm_eo - match_structs.rm_so, | 725 | (int)(match_structs.rm_eo - match_structs.rm_so), |
726 | str + match_structs.rm_so); | 726 | str + match_structs.rm_so); |
727 | free(growline); | 727 | free(growline); |
728 | growline = new; | 728 | growline = new; |
@@ -990,7 +990,8 @@ static int64_t less_getch(int pos) | |||
990 | */ | 990 | */ |
991 | if (key >= 0 && key < ' ' && key != 0x0d && key != 8) | 991 | if (key >= 0 && key < ' ' && key != 0x0d && key != 8) |
992 | goto again; | 992 | goto again; |
993 | return key; | 993 | |
994 | return key64; | ||
994 | } | 995 | } |
995 | 996 | ||
996 | static char* less_gets(int sz) | 997 | static char* less_gets(int sz) |
diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c index 562a34278..2ba6e3fe5 100644 --- a/miscutils/nandwrite.c +++ b/miscutils/nandwrite.c | |||
@@ -8,26 +8,26 @@ | |||
8 | * TODO: add support for large (>4GB) MTD devices | 8 | * TODO: add support for large (>4GB) MTD devices |
9 | */ | 9 | */ |
10 | 10 | ||
11 | //applet:IF_NANDWRITE(APPLET(nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP)) | ||
12 | //applet:IF_NANDWRITE(APPLET_ODDNAME(nanddump, nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP, nanddump)) | ||
13 | |||
14 | //kbuild:lib-$(CONFIG_NANDWRITE) += nandwrite.o | ||
15 | //kbuild:lib-$(CONFIG_NANDDUMP) += nandwrite.o | ||
16 | |||
17 | //config:config NANDWRITE | 11 | //config:config NANDWRITE |
18 | //config: bool "nandwrite" | 12 | //config: bool "nandwrite" |
19 | //config: default n | 13 | //config: default y |
20 | //config: select PLATFORM_LINUX | 14 | //config: select PLATFORM_LINUX |
21 | //config: help | 15 | //config: help |
22 | //config: Write to the specified MTD device, with bad blocks awareness | 16 | //config: Write to the specified MTD device, with bad blocks awareness |
23 | //config: | 17 | //config: |
24 | //config:config NANDDUMP | 18 | //config:config NANDDUMP |
25 | //config: bool "nanddump" | 19 | //config: bool "nanddump" |
26 | //config: default n | 20 | //config: default y |
27 | //config: select PLATFORM_LINUX | 21 | //config: select PLATFORM_LINUX |
28 | //config: help | 22 | //config: help |
29 | //config: Dump the content of raw NAND chip | 23 | //config: Dump the content of raw NAND chip |
30 | 24 | ||
25 | //applet:IF_NANDWRITE(APPLET(nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP)) | ||
26 | //applet:IF_NANDWRITE(APPLET_ODDNAME(nanddump, nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP, nanddump)) | ||
27 | |||
28 | //kbuild:lib-$(CONFIG_NANDWRITE) += nandwrite.o | ||
29 | //kbuild:lib-$(CONFIG_NANDDUMP) += nandwrite.o | ||
30 | |||
31 | //usage:#define nandwrite_trivial_usage | 31 | //usage:#define nandwrite_trivial_usage |
32 | //usage: "[-p] [-s ADDR] MTD_DEVICE [FILE]" | 32 | //usage: "[-p] [-s ADDR] MTD_DEVICE [FILE]" |
33 | //usage:#define nandwrite_full_usage "\n\n" | 33 | //usage:#define nandwrite_full_usage "\n\n" |
diff --git a/miscutils/runlevel.c b/miscutils/runlevel.c index 9d38b791f..76231df22 100644 --- a/miscutils/runlevel.c +++ b/miscutils/runlevel.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * | 11 | * |
12 | * initially busyboxified by Bernhard Reutner-Fischer | 12 | * initially busyboxified by Bernhard Reutner-Fischer |
13 | */ | 13 | */ |
14 | 14 | ||
15 | //usage:#define runlevel_trivial_usage | 15 | //usage:#define runlevel_trivial_usage |
16 | //usage: "[FILE]" | 16 | //usage: "[FILE]" |
17 | //usage:#define runlevel_full_usage "\n\n" | 17 | //usage:#define runlevel_full_usage "\n\n" |
diff --git a/miscutils/rx.c b/miscutils/rx.c index e1225779e..c48a61fd0 100644 --- a/miscutils/rx.c +++ b/miscutils/rx.c | |||
@@ -108,12 +108,10 @@ static int receive(/*int read_fd, */int file_fd) | |||
108 | } | 108 | } |
109 | } | 109 | } |
110 | /* Write previously received block */ | 110 | /* Write previously received block */ |
111 | if (blockLength) { | 111 | errno = 0; |
112 | errno = 0; | 112 | if (full_write(file_fd, blockBuf, blockLength) != blockLength) { |
113 | if (full_write(file_fd, blockBuf, blockLength) != blockLength) { | 113 | bb_perror_msg(bb_msg_write_error); |
114 | bb_perror_msg("can't write to file"); | 114 | goto fatal; |
115 | goto fatal; | ||
116 | } | ||
117 | } | 115 | } |
118 | 116 | ||
119 | timeout = TIMEOUT; | 117 | timeout = TIMEOUT; |
@@ -155,23 +153,20 @@ static int receive(/*int read_fd, */int file_fd) | |||
155 | blockBuf[i] = cc; | 153 | blockBuf[i] = cc; |
156 | } | 154 | } |
157 | 155 | ||
156 | cksum_or_crc = read_byte(TIMEOUT); | ||
157 | if (cksum_or_crc < 0) | ||
158 | goto timeout; | ||
158 | if (do_crc) { | 159 | if (do_crc) { |
159 | cksum_or_crc = read_byte(TIMEOUT); | ||
160 | if (cksum_or_crc < 0) | ||
161 | goto timeout; | ||
162 | cksum_or_crc = (cksum_or_crc << 8) | read_byte(TIMEOUT); | 160 | cksum_or_crc = (cksum_or_crc << 8) | read_byte(TIMEOUT); |
163 | if (cksum_or_crc < 0) | 161 | if (cksum_or_crc < 0) |
164 | goto timeout; | 162 | goto timeout; |
165 | } else { | ||
166 | cksum_or_crc = read_byte(TIMEOUT); | ||
167 | if (cksum_or_crc < 0) | ||
168 | goto timeout; | ||
169 | } | 163 | } |
170 | 164 | ||
171 | if (blockNo == ((wantBlockNo - 1) & 0xff)) { | 165 | if (blockNo == ((wantBlockNo - 1) & 0xff)) { |
172 | /* a repeat of the last block is ok, just ignore it. */ | 166 | /* a repeat of the last block is ok, just ignore it. */ |
173 | /* this also ignores the initial block 0 which is */ | 167 | /* this also ignores the initial block 0 which is */ |
174 | /* meta data. */ | 168 | /* meta data. */ |
169 | blockLength = 0; | ||
175 | goto next; | 170 | goto next; |
176 | } | 171 | } |
177 | if (blockNo != (wantBlockNo & 0xff)) { | 172 | if (blockNo != (wantBlockNo & 0xff)) { |
diff --git a/modutils/modinfo.c b/modutils/modinfo.c index 410b6fbe4..c0910ffed 100644 --- a/modutils/modinfo.c +++ b/modutils/modinfo.c | |||
@@ -13,6 +13,7 @@ | |||
13 | //config:config MODINFO | 13 | //config:config MODINFO |
14 | //config: bool "modinfo" | 14 | //config: bool "modinfo" |
15 | //config: default y | 15 | //config: default y |
16 | //config: select PLATFORM_LINUX | ||
16 | //config: help | 17 | //config: help |
17 | //config: Show information about a Linux Kernel module | 18 | //config: Show information about a Linux Kernel module |
18 | 19 | ||
diff --git a/modutils/modutils-24.c b/modutils/modutils-24.c index bbc54e316..12cb75c54 100644 --- a/modutils/modutils-24.c +++ b/modutils/modutils-24.c | |||
@@ -60,7 +60,6 @@ | |||
60 | 60 | ||
61 | #include "libbb.h" | 61 | #include "libbb.h" |
62 | #include "modutils.h" | 62 | #include "modutils.h" |
63 | #include <libgen.h> | ||
64 | #include <sys/utsname.h> | 63 | #include <sys/utsname.h> |
65 | 64 | ||
66 | #if ENABLE_FEATURE_INSMOD_LOADINKMEM | 65 | #if ENABLE_FEATURE_INSMOD_LOADINKMEM |
diff --git a/networking/httpd.c b/networking/httpd.c index ba5eebad5..24482fe52 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -820,78 +820,6 @@ static char *encodeString(const char *string) | |||
820 | } | 820 | } |
821 | #endif | 821 | #endif |
822 | 822 | ||
823 | /* | ||
824 | * Given a URL encoded string, convert it to plain ascii. | ||
825 | * Since decoding always makes strings smaller, the decode is done in-place. | ||
826 | * Thus, callers should xstrdup() the argument if they do not want the | ||
827 | * argument modified. The return is the original pointer, allowing this | ||
828 | * function to be easily used as arguments to other functions. | ||
829 | * | ||
830 | * string The first string to decode. | ||
831 | * option_d 1 if called for httpd -d | ||
832 | * | ||
833 | * Returns a pointer to the decoded string (same as input). | ||
834 | */ | ||
835 | static unsigned hex_to_bin(unsigned char c) | ||
836 | { | ||
837 | unsigned v; | ||
838 | |||
839 | v = c - '0'; | ||
840 | if (v <= 9) | ||
841 | return v; | ||
842 | /* c | 0x20: letters to lower case, non-letters | ||
843 | * to (potentially different) non-letters */ | ||
844 | v = (unsigned)(c | 0x20) - 'a'; | ||
845 | if (v <= 5) | ||
846 | return v + 10; | ||
847 | return ~0; | ||
848 | /* For testing: | ||
849 | void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); } | ||
850 | int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f'); | ||
851 | t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; } | ||
852 | */ | ||
853 | } | ||
854 | static char *decodeString(char *orig, int option_d) | ||
855 | { | ||
856 | /* note that decoded string is always shorter than original */ | ||
857 | char *string = orig; | ||
858 | char *ptr = string; | ||
859 | char c; | ||
860 | |||
861 | while ((c = *ptr++) != '\0') { | ||
862 | unsigned v; | ||
863 | |||
864 | if (option_d && c == '+') { | ||
865 | *string++ = ' '; | ||
866 | continue; | ||
867 | } | ||
868 | if (c != '%') { | ||
869 | *string++ = c; | ||
870 | continue; | ||
871 | } | ||
872 | v = hex_to_bin(ptr[0]); | ||
873 | if (v > 15) { | ||
874 | bad_hex: | ||
875 | if (!option_d) | ||
876 | return NULL; | ||
877 | *string++ = '%'; | ||
878 | continue; | ||
879 | } | ||
880 | v = (v * 16) | hex_to_bin(ptr[1]); | ||
881 | if (v > 255) | ||
882 | goto bad_hex; | ||
883 | if (!option_d && (v == '/' || v == '\0')) { | ||
884 | /* caller takes it as indication of invalid | ||
885 | * (dangerous wrt exploits) chars */ | ||
886 | return orig + 1; | ||
887 | } | ||
888 | *string++ = v; | ||
889 | ptr += 2; | ||
890 | } | ||
891 | *string = '\0'; | ||
892 | return orig; | ||
893 | } | ||
894 | |||
895 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 823 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
896 | /* | 824 | /* |
897 | * Decode a base64 data stream as per rfc1521. | 825 | * Decode a base64 data stream as per rfc1521. |
@@ -1949,7 +1877,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
1949 | } | 1877 | } |
1950 | 1878 | ||
1951 | /* Decode URL escape sequences */ | 1879 | /* Decode URL escape sequences */ |
1952 | tptr = decodeString(urlcopy, 0); | 1880 | tptr = percent_decode_in_place(urlcopy, /*strict:*/ 1); |
1953 | if (tptr == NULL) | 1881 | if (tptr == NULL) |
1954 | send_headers_and_exit(HTTP_BAD_REQUEST); | 1882 | send_headers_and_exit(HTTP_BAD_REQUEST); |
1955 | if (tptr == urlcopy + 1) { | 1883 | if (tptr == urlcopy + 1) { |
@@ -2408,7 +2336,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
2408 | , &verbose | 2336 | , &verbose |
2409 | ); | 2337 | ); |
2410 | if (opt & OPT_DECODE_URL) { | 2338 | if (opt & OPT_DECODE_URL) { |
2411 | fputs(decodeString(url_for_decode, 1), stdout); | 2339 | fputs(percent_decode_in_place(url_for_decode, /*strict:*/ 0), stdout); |
2412 | return 0; | 2340 | return 0; |
2413 | } | 2341 | } |
2414 | #if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR | 2342 | #if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR |
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 382033038..5946323d0 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -87,7 +87,6 @@ struct mapping_defn_t { | |||
87 | 87 | ||
88 | char *script; | 88 | char *script; |
89 | 89 | ||
90 | int max_mappings; | ||
91 | int n_mappings; | 90 | int n_mappings; |
92 | char **mapping; | 91 | char **mapping; |
93 | }; | 92 | }; |
@@ -102,7 +101,6 @@ struct interface_defn_t { | |||
102 | const struct method_t *method; | 101 | const struct method_t *method; |
103 | 102 | ||
104 | char *iface; | 103 | char *iface; |
105 | int max_options; | ||
106 | int n_options; | 104 | int n_options; |
107 | struct variable_t *option; | 105 | struct variable_t *option; |
108 | }; | 106 | }; |
@@ -138,6 +136,16 @@ struct globals { | |||
138 | #define INIT_G() do { } while (0) | 136 | #define INIT_G() do { } while (0) |
139 | 137 | ||
140 | 138 | ||
139 | static const char keywords_up_down[] ALIGN1 = | ||
140 | "up\0" | ||
141 | "down\0" | ||
142 | "pre-up\0" | ||
143 | "pre-down\0" | ||
144 | "post-up\0" | ||
145 | "post-down\0" | ||
146 | ; | ||
147 | |||
148 | |||
141 | #if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6 | 149 | #if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6 |
142 | 150 | ||
143 | static void addstr(char **bufp, const char *str, size_t str_length) | 151 | static void addstr(char **bufp, const char *str, size_t str_length) |
@@ -803,7 +811,6 @@ static struct interfaces_file_t *read_interfaces(const char *filename) | |||
803 | currmap->match = xrealloc_vector(currmap->match, 4, currmap->n_matches); | 811 | currmap->match = xrealloc_vector(currmap->match, 4, currmap->n_matches); |
804 | currmap->match[currmap->n_matches++] = xstrdup(first_word); | 812 | currmap->match[currmap->n_matches++] = xstrdup(first_word); |
805 | } | 813 | } |
806 | /*currmap->max_mappings = 0; - done by xzalloc */ | ||
807 | /*currmap->n_mappings = 0;*/ | 814 | /*currmap->n_mappings = 0;*/ |
808 | /*currmap->mapping = NULL;*/ | 815 | /*currmap->mapping = NULL;*/ |
809 | /*currmap->script = NULL;*/ | 816 | /*currmap->script = NULL;*/ |
@@ -888,23 +895,16 @@ static struct interfaces_file_t *read_interfaces(const char *filename) | |||
888 | if (rest_of_line[0] == '\0') | 895 | if (rest_of_line[0] == '\0') |
889 | bb_error_msg_and_die("option with empty value \"%s\"", buf); | 896 | bb_error_msg_and_die("option with empty value \"%s\"", buf); |
890 | 897 | ||
891 | if (strcmp(first_word, "up") != 0 | 898 | /* If not one of "up", "down",... words... */ |
892 | && strcmp(first_word, "down") != 0 | 899 | if (index_in_strings(keywords_up_down, first_word) < 0) { |
893 | && strcmp(first_word, "pre-up") != 0 | ||
894 | && strcmp(first_word, "post-down") != 0 | ||
895 | ) { | ||
896 | int i; | 900 | int i; |
897 | for (i = 0; i < currif->n_options; i++) { | 901 | for (i = 0; i < currif->n_options; i++) { |
898 | if (strcmp(currif->option[i].name, first_word) == 0) | 902 | if (strcmp(currif->option[i].name, first_word) == 0) |
899 | bb_error_msg_and_die("duplicate option \"%s\"", buf); | 903 | bb_error_msg_and_die("duplicate option \"%s\"", buf); |
900 | } | 904 | } |
901 | } | 905 | } |
902 | if (currif->n_options >= currif->max_options) { | ||
903 | currif->max_options += 10; | ||
904 | currif->option = xrealloc(currif->option, | ||
905 | sizeof(*currif->option) * currif->max_options); | ||
906 | } | ||
907 | debug_noise("\t%s=%s\n", first_word, rest_of_line); | 906 | debug_noise("\t%s=%s\n", first_word, rest_of_line); |
907 | currif->option = xrealloc_vector(currif->option, 4, currif->n_options); | ||
908 | currif->option[currif->n_options].name = xstrdup(first_word); | 908 | currif->option[currif->n_options].name = xstrdup(first_word); |
909 | currif->option[currif->n_options].value = xstrdup(rest_of_line); | 909 | currif->option[currif->n_options].value = xstrdup(rest_of_line); |
910 | currif->n_options++; | 910 | currif->n_options++; |
@@ -916,11 +916,7 @@ static struct interfaces_file_t *read_interfaces(const char *filename) | |||
916 | bb_error_msg_and_die("duplicate script in mapping \"%s\"", buf); | 916 | bb_error_msg_and_die("duplicate script in mapping \"%s\"", buf); |
917 | currmap->script = xstrdup(next_word(&rest_of_line)); | 917 | currmap->script = xstrdup(next_word(&rest_of_line)); |
918 | } else if (strcmp(first_word, "map") == 0) { | 918 | } else if (strcmp(first_word, "map") == 0) { |
919 | if (currmap->n_mappings >= currmap->max_mappings) { | 919 | currmap->mapping = xrealloc_vector(currmap->mapping, 2, currmap->n_mappings); |
920 | currmap->max_mappings = currmap->max_mappings * 2 + 1; | ||
921 | currmap->mapping = xrealloc(currmap->mapping, | ||
922 | sizeof(char *) * currmap->max_mappings); | ||
923 | } | ||
924 | currmap->mapping[currmap->n_mappings] = xstrdup(next_word(&rest_of_line)); | 920 | currmap->mapping[currmap->n_mappings] = xstrdup(next_word(&rest_of_line)); |
925 | currmap->n_mappings++; | 921 | currmap->n_mappings++; |
926 | } else { | 922 | } else { |
@@ -984,11 +980,7 @@ static void set_environ(struct interface_defn_t *iface, const char *mode) | |||
984 | pp = G.my_environ; | 980 | pp = G.my_environ; |
985 | 981 | ||
986 | for (i = 0; i < iface->n_options; i++) { | 982 | for (i = 0; i < iface->n_options; i++) { |
987 | if (strcmp(iface->option[i].name, "up") == 0 | 983 | if (index_in_strings(keywords_up_down, iface->option[i].name) >= 0) { |
988 | || strcmp(iface->option[i].name, "down") == 0 | ||
989 | || strcmp(iface->option[i].name, "pre-up") == 0 | ||
990 | || strcmp(iface->option[i].name, "post-down") == 0 | ||
991 | ) { | ||
992 | continue; | 984 | continue; |
993 | } | 985 | } |
994 | *pp++ = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); | 986 | *pp++ = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); |
@@ -1056,6 +1048,7 @@ static int iface_up(struct interface_defn_t *iface) | |||
1056 | if (!execute_all(iface, "pre-up")) return 0; | 1048 | if (!execute_all(iface, "pre-up")) return 0; |
1057 | if (!iface->method->up(iface, doit)) return 0; | 1049 | if (!iface->method->up(iface, doit)) return 0; |
1058 | if (!execute_all(iface, "up")) return 0; | 1050 | if (!execute_all(iface, "up")) return 0; |
1051 | if (!execute_all(iface, "post-up")) return 0; | ||
1059 | return 1; | 1052 | return 1; |
1060 | } | 1053 | } |
1061 | 1054 | ||
@@ -1063,6 +1056,7 @@ static int iface_down(struct interface_defn_t *iface) | |||
1063 | { | 1056 | { |
1064 | if (!iface->method->down(iface,check)) return -1; | 1057 | if (!iface->method->down(iface,check)) return -1; |
1065 | set_environ(iface, "stop"); | 1058 | set_environ(iface, "stop"); |
1059 | if (!execute_all(iface, "pre-down")) return 0; | ||
1066 | if (!execute_all(iface, "down")) return 0; | 1060 | if (!execute_all(iface, "down")) return 0; |
1067 | if (!iface->method->down(iface, doit)) return 0; | 1061 | if (!iface->method->down(iface, doit)) return 0; |
1068 | if (!execute_all(iface, "post-down")) return 0; | 1062 | if (!execute_all(iface, "post-down")) return 0; |
diff --git a/networking/inetd.c b/networking/inetd.c index 873fd9528..26b66992d 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -357,10 +357,26 @@ struct BUG_G_too_big { | |||
357 | config_filename = "/etc/inetd.conf"; \ | 357 | config_filename = "/etc/inetd.conf"; \ |
358 | } while (0) | 358 | } while (0) |
359 | 359 | ||
360 | #if 1 | ||
361 | # define dbg(...) ((void)0) | ||
362 | #else | ||
363 | # define dbg(...) \ | ||
364 | do { \ | ||
365 | int dbg_fd = open("inetd_debug.log", O_WRONLY | O_CREAT | O_APPEND, 0666); \ | ||
366 | if (dbg_fd >= 0) { \ | ||
367 | fdprintf(dbg_fd, "%d: ", getpid()); \ | ||
368 | fdprintf(dbg_fd, __VA_ARGS__); \ | ||
369 | close(dbg_fd); \ | ||
370 | } \ | ||
371 | } while (0) | ||
372 | #endif | ||
373 | |||
360 | static void maybe_close(int fd) | 374 | static void maybe_close(int fd) |
361 | { | 375 | { |
362 | if (fd >= 0) | 376 | if (fd >= 0) { |
363 | close(fd); | 377 | close(fd); |
378 | dbg("closed fd:%d\n", fd); | ||
379 | } | ||
364 | } | 380 | } |
365 | 381 | ||
366 | // TODO: move to libbb? | 382 | // TODO: move to libbb? |
@@ -464,7 +480,9 @@ static void remove_fd_from_set(int fd) | |||
464 | { | 480 | { |
465 | if (fd >= 0) { | 481 | if (fd >= 0) { |
466 | FD_CLR(fd, &allsock); | 482 | FD_CLR(fd, &allsock); |
483 | dbg("stopped listening on fd:%d\n", fd); | ||
467 | maxsock = -1; | 484 | maxsock = -1; |
485 | dbg("maxsock:%d\n", maxsock); | ||
468 | } | 486 | } |
469 | } | 487 | } |
470 | 488 | ||
@@ -472,8 +490,10 @@ static void add_fd_to_set(int fd) | |||
472 | { | 490 | { |
473 | if (fd >= 0) { | 491 | if (fd >= 0) { |
474 | FD_SET(fd, &allsock); | 492 | FD_SET(fd, &allsock); |
493 | dbg("started listening on fd:%d\n", fd); | ||
475 | if (maxsock >= 0 && fd > maxsock) { | 494 | if (maxsock >= 0 && fd > maxsock) { |
476 | prev_maxsock = maxsock = fd; | 495 | prev_maxsock = maxsock = fd; |
496 | dbg("maxsock:%d\n", maxsock); | ||
477 | if ((rlim_t)fd > rlim_ofile_cur - FD_MARGIN) | 497 | if ((rlim_t)fd > rlim_ofile_cur - FD_MARGIN) |
478 | bump_nofile(); | 498 | bump_nofile(); |
479 | } | 499 | } |
@@ -492,6 +512,7 @@ static void recalculate_maxsock(void) | |||
492 | maxsock = fd; | 512 | maxsock = fd; |
493 | fd++; | 513 | fd++; |
494 | } | 514 | } |
515 | dbg("recalculated maxsock:%d\n", maxsock); | ||
495 | prev_maxsock = maxsock; | 516 | prev_maxsock = maxsock; |
496 | if ((rlim_t)maxsock > rlim_ofile_cur - FD_MARGIN) | 517 | if ((rlim_t)maxsock > rlim_ofile_cur - FD_MARGIN) |
497 | bump_nofile(); | 518 | bump_nofile(); |
@@ -549,8 +570,13 @@ static void prepare_socket_fd(servtab_t *sep) | |||
549 | rearm_alarm(); | 570 | rearm_alarm(); |
550 | return; | 571 | return; |
551 | } | 572 | } |
552 | if (sep->se_socktype == SOCK_STREAM) | 573 | |
574 | if (sep->se_socktype == SOCK_STREAM) { | ||
553 | listen(fd, global_queuelen); | 575 | listen(fd, global_queuelen); |
576 | dbg("new sep->se_fd:%d (stream)\n", fd); | ||
577 | } else { | ||
578 | dbg("new sep->se_fd:%d (!stream)\n", fd); | ||
579 | } | ||
554 | 580 | ||
555 | add_fd_to_set(fd); | 581 | add_fd_to_set(fd); |
556 | sep->se_fd = fd; | 582 | sep->se_fd = fd; |
@@ -1012,7 +1038,7 @@ static void reread_config_file(int sig UNUSED_PARAM) | |||
1012 | * new config file doesnt have them. */ | 1038 | * new config file doesnt have them. */ |
1013 | block_CHLD_HUP_ALRM(&omask); | 1039 | block_CHLD_HUP_ALRM(&omask); |
1014 | sepp = &serv_list; | 1040 | sepp = &serv_list; |
1015 | while ((sep = *sepp)) { | 1041 | while ((sep = *sepp) != NULL) { |
1016 | if (sep->se_checked) { | 1042 | if (sep->se_checked) { |
1017 | sepp = &sep->se_next; | 1043 | sepp = &sep->se_next; |
1018 | continue; | 1044 | continue; |
@@ -1206,11 +1232,13 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1206 | } | 1232 | } |
1207 | continue; | 1233 | continue; |
1208 | } | 1234 | } |
1235 | dbg("ready_fd_cnt:%d\n", ready_fd_cnt); | ||
1209 | 1236 | ||
1210 | for (sep = serv_list; ready_fd_cnt && sep; sep = sep->se_next) { | 1237 | for (sep = serv_list; ready_fd_cnt && sep; sep = sep->se_next) { |
1211 | if (sep->se_fd == -1 || !FD_ISSET(sep->se_fd, &readable)) | 1238 | if (sep->se_fd == -1 || !FD_ISSET(sep->se_fd, &readable)) |
1212 | continue; | 1239 | continue; |
1213 | 1240 | ||
1241 | dbg("ready fd:%d\n", sep->se_fd); | ||
1214 | ready_fd_cnt--; | 1242 | ready_fd_cnt--; |
1215 | ctrl = sep->se_fd; | 1243 | ctrl = sep->se_fd; |
1216 | accepted_fd = -1; | 1244 | accepted_fd = -1; |
@@ -1218,6 +1246,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1218 | if (!sep->se_wait) { | 1246 | if (!sep->se_wait) { |
1219 | if (sep->se_socktype == SOCK_STREAM) { | 1247 | if (sep->se_socktype == SOCK_STREAM) { |
1220 | ctrl = accepted_fd = accept(sep->se_fd, NULL, NULL); | 1248 | ctrl = accepted_fd = accept(sep->se_fd, NULL, NULL); |
1249 | dbg("accepted_fd:%d\n", accepted_fd); | ||
1221 | if (ctrl < 0) { | 1250 | if (ctrl < 0) { |
1222 | if (errno != EINTR) | 1251 | if (errno != EINTR) |
1223 | bb_perror_msg("accept (for %s)", sep->se_service); | 1252 | bb_perror_msg("accept (for %s)", sep->se_service); |
@@ -1238,19 +1267,22 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1238 | * (can create many copies of same child, etc). | 1267 | * (can create many copies of same child, etc). |
1239 | * Parent must create and use new socket instead. */ | 1268 | * Parent must create and use new socket instead. */ |
1240 | new_udp_fd = socket(sep->se_family, SOCK_DGRAM, 0); | 1269 | new_udp_fd = socket(sep->se_family, SOCK_DGRAM, 0); |
1270 | dbg("new_udp_fd:%d\n", new_udp_fd); | ||
1241 | if (new_udp_fd < 0) { /* error: eat packet, forget about it */ | 1271 | if (new_udp_fd < 0) { /* error: eat packet, forget about it */ |
1242 | udp_err: | 1272 | udp_err: |
1243 | recv(sep->se_fd, line, LINE_SIZE, MSG_DONTWAIT); | 1273 | recv(sep->se_fd, line, LINE_SIZE, MSG_DONTWAIT); |
1244 | continue; | 1274 | continue; |
1245 | } | 1275 | } |
1246 | setsockopt_reuseaddr(new_udp_fd); | 1276 | setsockopt_reuseaddr(new_udp_fd); |
1247 | /* TODO: better do bind after vfork in parent, | 1277 | /* TODO: better do bind after fork in parent, |
1248 | * so that we don't have two wildcard bound sockets | 1278 | * so that we don't have two wildcard bound sockets |
1249 | * even for a brief moment? */ | 1279 | * even for a brief moment? */ |
1250 | if (bind(new_udp_fd, &sep->se_lsa->u.sa, sep->se_lsa->len) < 0) { | 1280 | if (bind(new_udp_fd, &sep->se_lsa->u.sa, sep->se_lsa->len) < 0) { |
1281 | dbg("bind(new_udp_fd) failed\n"); | ||
1251 | close(new_udp_fd); | 1282 | close(new_udp_fd); |
1252 | goto udp_err; | 1283 | goto udp_err; |
1253 | } | 1284 | } |
1285 | dbg("bind(new_udp_fd) succeeded\n"); | ||
1254 | } | 1286 | } |
1255 | } | 1287 | } |
1256 | 1288 | ||
@@ -1278,6 +1310,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1278 | sep->se_count = 0; | 1310 | sep->se_count = 0; |
1279 | rearm_alarm(); /* will revive it in RETRYTIME sec */ | 1311 | rearm_alarm(); /* will revive it in RETRYTIME sec */ |
1280 | restore_sigmask(&omask); | 1312 | restore_sigmask(&omask); |
1313 | maybe_close(new_udp_fd); | ||
1281 | maybe_close(accepted_fd); | 1314 | maybe_close(accepted_fd); |
1282 | continue; /* -> check next fd in fd set */ | 1315 | continue; /* -> check next fd in fd set */ |
1283 | } | 1316 | } |
@@ -1298,17 +1331,18 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1298 | bb_perror_msg("vfork"+1); | 1331 | bb_perror_msg("vfork"+1); |
1299 | sleep(1); | 1332 | sleep(1); |
1300 | restore_sigmask(&omask); | 1333 | restore_sigmask(&omask); |
1334 | maybe_close(new_udp_fd); | ||
1301 | maybe_close(accepted_fd); | 1335 | maybe_close(accepted_fd); |
1302 | continue; /* -> check next fd in fd set */ | 1336 | continue; /* -> check next fd in fd set */ |
1303 | } | 1337 | } |
1304 | if (pid == 0) | 1338 | if (pid == 0) |
1305 | pid--; /* -1: "we did fork and we are child" */ | 1339 | pid--; /* -1: "we did fork and we are child" */ |
1306 | } | 1340 | } |
1307 | /* if pid == 0 here, we never forked */ | 1341 | /* if pid == 0 here, we didn't fork */ |
1308 | 1342 | ||
1309 | if (pid > 0) { /* parent */ | 1343 | if (pid > 0) { /* parent */ |
1310 | if (sep->se_wait) { | 1344 | if (sep->se_wait) { |
1311 | /* tcp wait: we passed listening socket to child, | 1345 | /* wait: we passed socket to child, |
1312 | * will wait for child to terminate */ | 1346 | * will wait for child to terminate */ |
1313 | sep->se_wait = pid; | 1347 | sep->se_wait = pid; |
1314 | remove_fd_from_set(sep->se_fd); | 1348 | remove_fd_from_set(sep->se_fd); |
@@ -1317,17 +1351,19 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1317 | /* udp nowait: child connected the socket, | 1351 | /* udp nowait: child connected the socket, |
1318 | * we created and will use new, unconnected one */ | 1352 | * we created and will use new, unconnected one */ |
1319 | xmove_fd(new_udp_fd, sep->se_fd); | 1353 | xmove_fd(new_udp_fd, sep->se_fd); |
1354 | dbg("moved new_udp_fd:%d to sep->se_fd:%d\n", new_udp_fd, sep->se_fd); | ||
1320 | } | 1355 | } |
1321 | restore_sigmask(&omask); | 1356 | restore_sigmask(&omask); |
1322 | maybe_close(accepted_fd); | 1357 | maybe_close(accepted_fd); |
1323 | continue; /* -> check next fd in fd set */ | 1358 | continue; /* -> check next fd in fd set */ |
1324 | } | 1359 | } |
1325 | 1360 | ||
1326 | /* we are either child or didn't vfork at all */ | 1361 | /* we are either child or didn't fork at all */ |
1327 | #ifdef INETD_BUILTINS_ENABLED | 1362 | #ifdef INETD_BUILTINS_ENABLED |
1328 | if (sep->se_builtin) { | 1363 | if (sep->se_builtin) { |
1329 | if (pid) { /* "pid" is -1: we did vfork */ | 1364 | if (pid) { /* "pid" is -1: we did fork */ |
1330 | close(sep->se_fd); /* listening socket */ | 1365 | close(sep->se_fd); /* listening socket */ |
1366 | dbg("closed sep->se_fd:%d\n", sep->se_fd); | ||
1331 | logmode = LOGMODE_NONE; /* make xwrite etc silent */ | 1367 | logmode = LOGMODE_NONE; /* make xwrite etc silent */ |
1332 | } | 1368 | } |
1333 | restore_sigmask(&omask); | 1369 | restore_sigmask(&omask); |
@@ -1335,7 +1371,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1335 | sep->se_builtin->bi_stream_fn(ctrl, sep); | 1371 | sep->se_builtin->bi_stream_fn(ctrl, sep); |
1336 | else | 1372 | else |
1337 | sep->se_builtin->bi_dgram_fn(ctrl, sep); | 1373 | sep->se_builtin->bi_dgram_fn(ctrl, sep); |
1338 | if (pid) /* we did vfork */ | 1374 | if (pid) /* we did fork */ |
1339 | _exit(EXIT_FAILURE); | 1375 | _exit(EXIT_FAILURE); |
1340 | maybe_close(accepted_fd); | 1376 | maybe_close(accepted_fd); |
1341 | continue; /* -> check next fd in fd set */ | 1377 | continue; /* -> check next fd in fd set */ |
@@ -1345,9 +1381,14 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1345 | setsid(); | 1381 | setsid(); |
1346 | /* "nowait" udp */ | 1382 | /* "nowait" udp */ |
1347 | if (new_udp_fd >= 0) { | 1383 | if (new_udp_fd >= 0) { |
1348 | len_and_sockaddr *lsa = xzalloc_lsa(sep->se_family); | 1384 | len_and_sockaddr *lsa; |
1385 | int r; | ||
1386 | |||
1387 | close(new_udp_fd); | ||
1388 | dbg("closed new_udp_fd:%d\n", new_udp_fd); | ||
1389 | lsa = xzalloc_lsa(sep->se_family); | ||
1349 | /* peek at the packet and remember peer addr */ | 1390 | /* peek at the packet and remember peer addr */ |
1350 | int r = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT, | 1391 | r = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT, |
1351 | &lsa->u.sa, &lsa->len); | 1392 | &lsa->u.sa, &lsa->len); |
1352 | if (r < 0) | 1393 | if (r < 0) |
1353 | goto do_exit1; | 1394 | goto do_exit1; |
@@ -1355,6 +1396,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1355 | * only packets from this peer will be recv'ed, | 1396 | * only packets from this peer will be recv'ed, |
1356 | * and bare write()/send() will work on it */ | 1397 | * and bare write()/send() will work on it */ |
1357 | connect(ctrl, &lsa->u.sa, lsa->len); | 1398 | connect(ctrl, &lsa->u.sa, lsa->len); |
1399 | dbg("connected ctrl:%d to remote peer\n", ctrl); | ||
1358 | free(lsa); | 1400 | free(lsa); |
1359 | } | 1401 | } |
1360 | /* prepare env and exec program */ | 1402 | /* prepare env and exec program */ |
@@ -1372,7 +1414,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1372 | bb_error_msg("non-root must run services as himself"); | 1414 | bb_error_msg("non-root must run services as himself"); |
1373 | goto do_exit1; | 1415 | goto do_exit1; |
1374 | } | 1416 | } |
1375 | if (pwd->pw_uid) { | 1417 | if (pwd->pw_uid != 0) { |
1376 | if (sep->se_group) | 1418 | if (sep->se_group) |
1377 | pwd->pw_gid = grp->gr_gid; | 1419 | pwd->pw_gid = grp->gr_gid; |
1378 | /* initgroups, setgid, setuid: */ | 1420 | /* initgroups, setgid, setuid: */ |
@@ -1391,6 +1433,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1391 | */ | 1433 | */ |
1392 | xmove_fd(ctrl, STDIN_FILENO); | 1434 | xmove_fd(ctrl, STDIN_FILENO); |
1393 | xdup2(STDIN_FILENO, STDOUT_FILENO); | 1435 | xdup2(STDIN_FILENO, STDOUT_FILENO); |
1436 | dbg("moved ctrl:%d to fd 0,1[,2]\n", ctrl); | ||
1394 | /* manpages of inetd I managed to find either say | 1437 | /* manpages of inetd I managed to find either say |
1395 | * that stderr is also redirected to the network, | 1438 | * that stderr is also redirected to the network, |
1396 | * or do not talk about redirection at all (!) */ | 1439 | * or do not talk about redirection at all (!) */ |
@@ -1403,6 +1446,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1403 | maybe_close(sep2->se_fd); | 1446 | maybe_close(sep2->se_fd); |
1404 | sigaction_set(SIGPIPE, &saved_pipe_handler); | 1447 | sigaction_set(SIGPIPE, &saved_pipe_handler); |
1405 | restore_sigmask(&omask); | 1448 | restore_sigmask(&omask); |
1449 | dbg("execing:'%s'\n", sep->se_program); | ||
1406 | BB_EXECVP(sep->se_program, sep->se_argv); | 1450 | BB_EXECVP(sep->se_program, sep->se_argv); |
1407 | bb_perror_msg("can't execute '%s'", sep->se_program); | 1451 | bb_perror_msg("can't execute '%s'", sep->se_program); |
1408 | do_exit1: | 1452 | do_exit1: |
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index 1daad1358..d184f689b 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c | |||
@@ -428,8 +428,7 @@ create new one, and bind() it. TODO */ | |||
428 | 428 | ||
429 | rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); | 429 | rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); |
430 | if (rr >= 0 && x) { /* we've got options, lessee em... */ | 430 | if (rr >= 0 && x) { /* we've got options, lessee em... */ |
431 | bin2hex(bigbuf_net, optbuf, x); | 431 | *bin2hex(bigbuf_net, optbuf, x) = '\0'; |
432 | bigbuf_net[2*x] = '\0'; | ||
433 | fprintf(stderr, "IP options: %s\n", bigbuf_net); | 432 | fprintf(stderr, "IP options: %s\n", bigbuf_net); |
434 | } | 433 | } |
435 | #endif | 434 | #endif |
diff --git a/networking/ping.c b/networking/ping.c index efd4f210b..b8a438ba8 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -149,31 +149,6 @@ enum { | |||
149 | PINGINTERVAL = 1, /* 1 second */ | 149 | PINGINTERVAL = 1, /* 1 second */ |
150 | }; | 150 | }; |
151 | 151 | ||
152 | /* Common routines */ | ||
153 | |||
154 | static int in_cksum(unsigned short *buf, int sz) | ||
155 | { | ||
156 | int nleft = sz; | ||
157 | int sum = 0; | ||
158 | unsigned short *w = buf; | ||
159 | unsigned short ans = 0; | ||
160 | |||
161 | while (nleft > 1) { | ||
162 | sum += *w++; | ||
163 | nleft -= 2; | ||
164 | } | ||
165 | |||
166 | if (nleft == 1) { | ||
167 | *(unsigned char *) (&ans) = *(unsigned char *) w; | ||
168 | sum += ans; | ||
169 | } | ||
170 | |||
171 | sum = (sum >> 16) + (sum & 0xFFFF); | ||
172 | sum += (sum >> 16); | ||
173 | ans = ~sum; | ||
174 | return ans; | ||
175 | } | ||
176 | |||
177 | #if !ENABLE_FEATURE_FANCY_PING | 152 | #if !ENABLE_FEATURE_FANCY_PING |
178 | 153 | ||
179 | /* Simple version */ | 154 | /* Simple version */ |
@@ -201,7 +176,7 @@ static void ping4(len_and_sockaddr *lsa) | |||
201 | pkt = (struct icmp *) G.packet; | 176 | pkt = (struct icmp *) G.packet; |
202 | memset(pkt, 0, sizeof(G.packet)); | 177 | memset(pkt, 0, sizeof(G.packet)); |
203 | pkt->icmp_type = ICMP_ECHO; | 178 | pkt->icmp_type = ICMP_ECHO; |
204 | pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(G.packet)); | 179 | pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet)); |
205 | 180 | ||
206 | xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len); | 181 | xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len); |
207 | 182 | ||
@@ -493,7 +468,7 @@ static void sendping4(int junk UNUSED_PARAM) | |||
493 | /* No hton: we'll read it back on the same machine */ | 468 | /* No hton: we'll read it back on the same machine */ |
494 | *(uint32_t*)&pkt->icmp_dun = monotonic_us(); | 469 | *(uint32_t*)&pkt->icmp_dun = monotonic_us(); |
495 | 470 | ||
496 | pkt->icmp_cksum = in_cksum((unsigned short *) pkt, datalen + ICMP_MINLEN); | 471 | pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, datalen + ICMP_MINLEN); |
497 | 472 | ||
498 | sendping_tail(sendping4, ICMP_MINLEN); | 473 | sendping_tail(sendping4, ICMP_MINLEN); |
499 | } | 474 | } |
@@ -512,7 +487,7 @@ static void sendping6(int junk UNUSED_PARAM) | |||
512 | /*if (datalen >= 4)*/ | 487 | /*if (datalen >= 4)*/ |
513 | *(uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us(); | 488 | *(uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us(); |
514 | 489 | ||
515 | //TODO? pkt->icmp_cksum = in_cksum(...); | 490 | //TODO? pkt->icmp_cksum = inet_cksum(...); |
516 | 491 | ||
517 | sendping_tail(sendping6, sizeof(struct icmp6_hdr)); | 492 | sendping_tail(sendping6, sizeof(struct icmp6_hdr)); |
518 | } | 493 | } |
@@ -638,7 +613,7 @@ static void unpack4(char *buf, int sz, struct sockaddr_in *from) | |||
638 | } | 613 | } |
639 | } | 614 | } |
640 | #if ENABLE_PING6 | 615 | #if ENABLE_PING6 |
641 | static void unpack6(char *packet, int sz, /*struct sockaddr_in6 *from,*/ int hoplimit) | 616 | static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit) |
642 | { | 617 | { |
643 | struct icmp6_hdr *icmppkt; | 618 | struct icmp6_hdr *icmppkt; |
644 | char buf[INET6_ADDRSTRLEN]; | 619 | char buf[INET6_ADDRSTRLEN]; |
@@ -658,7 +633,7 @@ static void unpack6(char *packet, int sz, /*struct sockaddr_in6 *from,*/ int hop | |||
658 | if (sz >= sizeof(struct icmp6_hdr) + sizeof(uint32_t)) | 633 | if (sz >= sizeof(struct icmp6_hdr) + sizeof(uint32_t)) |
659 | tp = (uint32_t *) &icmppkt->icmp6_data8[4]; | 634 | tp = (uint32_t *) &icmppkt->icmp6_data8[4]; |
660 | unpack_tail(sz, tp, | 635 | unpack_tail(sz, tp, |
661 | inet_ntop(AF_INET6, &pingaddr.sin6.sin6_addr, | 636 | inet_ntop(AF_INET6, &from->sin6_addr, |
662 | buf, sizeof(buf)), | 637 | buf, sizeof(buf)), |
663 | recv_seq, hoplimit); | 638 | recv_seq, hoplimit); |
664 | } else if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST) { | 639 | } else if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST) { |
@@ -808,7 +783,7 @@ static void ping6(len_and_sockaddr *lsa) | |||
808 | move_from_unaligned_int(hoplimit, CMSG_DATA(mp)); | 783 | move_from_unaligned_int(hoplimit, CMSG_DATA(mp)); |
809 | } | 784 | } |
810 | } | 785 | } |
811 | unpack6(G.rcv_packet, c, /*&from,*/ hoplimit); | 786 | unpack6(G.rcv_packet, c, &from, hoplimit); |
812 | if (pingcount && nreceived >= pingcount) | 787 | if (pingcount && nreceived >= pingcount) |
813 | break; | 788 | break; |
814 | } | 789 | } |
diff --git a/networking/tftp.c b/networking/tftp.c index 17485a527..043b879af 100644 --- a/networking/tftp.c +++ b/networking/tftp.c | |||
@@ -813,7 +813,8 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) | |||
813 | goto err; | 813 | goto err; |
814 | } | 814 | } |
815 | mode = local_file + strlen(local_file) + 1; | 815 | mode = local_file + strlen(local_file) + 1; |
816 | if (mode >= block_buf + result || strcmp(mode, "octet") != 0) { | 816 | /* RFC 1350 says mode string is case independent */ |
817 | if (mode >= block_buf + result || strcasecmp(mode, "octet") != 0) { | ||
817 | goto err; | 818 | goto err; |
818 | } | 819 | } |
819 | # if ENABLE_FEATURE_TFTP_BLOCKSIZE | 820 | # if ENABLE_FEATURE_TFTP_BLOCKSIZE |
diff --git a/networking/traceroute.c b/networking/traceroute.c index c32103519..d197e5410 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -418,39 +418,6 @@ wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to, unsigned *timest | |||
418 | return read_len; | 418 | return read_len; |
419 | } | 419 | } |
420 | 420 | ||
421 | /* | ||
422 | * Checksum routine for Internet Protocol family headers (C Version) | ||
423 | */ | ||
424 | static uint16_t | ||
425 | in_cksum(uint16_t *addr, int len) | ||
426 | { | ||
427 | int nleft = len; | ||
428 | uint16_t *w = addr; | ||
429 | uint16_t answer; | ||
430 | int sum = 0; | ||
431 | |||
432 | /* | ||
433 | * Our algorithm is simple, using a 32 bit accumulator (sum), | ||
434 | * we add sequential 16 bit words to it, and at the end, fold | ||
435 | * back all the carry bits from the top 16 bits into the lower | ||
436 | * 16 bits. | ||
437 | */ | ||
438 | while (nleft > 1) { | ||
439 | sum += *w++; | ||
440 | nleft -= 2; | ||
441 | } | ||
442 | |||
443 | /* mop up an odd byte, if necessary */ | ||
444 | if (nleft == 1) | ||
445 | sum += *(unsigned char *)w; | ||
446 | |||
447 | /* add back carry outs from top 16 bits to low 16 bits */ | ||
448 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ | ||
449 | sum += (sum >> 16); /* add carry */ | ||
450 | answer = ~sum; /* truncate to 16 bits */ | ||
451 | return answer; | ||
452 | } | ||
453 | |||
454 | static void | 421 | static void |
455 | send_probe(int seq, int ttl) | 422 | send_probe(int seq, int ttl) |
456 | { | 423 | { |
@@ -477,7 +444,7 @@ send_probe(int seq, int ttl) | |||
477 | 444 | ||
478 | /* Always calculate checksum for icmp packets */ | 445 | /* Always calculate checksum for icmp packets */ |
479 | outicmp->icmp_cksum = 0; | 446 | outicmp->icmp_cksum = 0; |
480 | outicmp->icmp_cksum = in_cksum((uint16_t *)outicmp, | 447 | outicmp->icmp_cksum = inet_cksum((uint16_t *)outicmp, |
481 | packlen - (sizeof(*outip) + optlen)); | 448 | packlen - (sizeof(*outip) + optlen)); |
482 | if (outicmp->icmp_cksum == 0) | 449 | if (outicmp->icmp_cksum == 0) |
483 | outicmp->icmp_cksum = 0xffff; | 450 | outicmp->icmp_cksum = 0xffff; |
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 70e34614c..2e6113627 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -36,6 +36,9 @@ const struct dhcp_optflag dhcp_optflags[] = { | |||
36 | { OPTION_STRING , 0x11 }, /* DHCP_ROOT_PATH */ | 36 | { OPTION_STRING , 0x11 }, /* DHCP_ROOT_PATH */ |
37 | { OPTION_U8 , 0x17 }, /* DHCP_IP_TTL */ | 37 | { OPTION_U8 , 0x17 }, /* DHCP_IP_TTL */ |
38 | { OPTION_U16 , 0x1a }, /* DHCP_MTU */ | 38 | { OPTION_U16 , 0x1a }, /* DHCP_MTU */ |
39 | //TODO: why do we request DHCP_BROADCAST? Can't we assume that | ||
40 | //in the unlikely case it is different from typical N.N.255.255, | ||
41 | //server would let us know anyway? | ||
39 | { OPTION_IP | OPTION_REQ, 0x1c }, /* DHCP_BROADCAST */ | 42 | { OPTION_IP | OPTION_REQ, 0x1c }, /* DHCP_BROADCAST */ |
40 | { OPTION_IP_PAIR | OPTION_LIST , 0x21 }, /* DHCP_ROUTES */ | 43 | { OPTION_IP_PAIR | OPTION_LIST , 0x21 }, /* DHCP_ROUTES */ |
41 | { OPTION_STRING , 0x28 }, /* DHCP_NIS_DOMAIN */ | 44 | { OPTION_STRING , 0x28 }, /* DHCP_NIS_DOMAIN */ |
@@ -59,6 +62,7 @@ const struct dhcp_optflag dhcp_optflags[] = { | |||
59 | { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */ | 62 | { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */ |
60 | { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ | 63 | { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ |
61 | #endif | 64 | #endif |
65 | { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ | ||
62 | { OPTION_STATIC_ROUTES , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ | 66 | { OPTION_STATIC_ROUTES , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ |
63 | { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ | 67 | { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ |
64 | 68 | ||
@@ -126,6 +130,7 @@ const char dhcp_option_strings[] ALIGN1 = | |||
126 | "vlanid" "\0" /* DHCP_VLAN_ID */ | 130 | "vlanid" "\0" /* DHCP_VLAN_ID */ |
127 | "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ | 131 | "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ |
128 | #endif | 132 | #endif |
133 | "ip6rd" "\0" /* DHCP_6RD */ | ||
129 | "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ | 134 | "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ |
130 | "wpad" "\0" /* DHCP_WPAD */ | 135 | "wpad" "\0" /* DHCP_WPAD */ |
131 | ; | 136 | ; |
@@ -154,6 +159,7 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { | |||
154 | [OPTION_S32] = 4, | 159 | [OPTION_S32] = 4, |
155 | /* Just like OPTION_STRING, we use minimum length here */ | 160 | /* Just like OPTION_STRING, we use minimum length here */ |
156 | [OPTION_STATIC_ROUTES] = 5, | 161 | [OPTION_STATIC_ROUTES] = 5, |
162 | [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */ | ||
157 | }; | 163 | }; |
158 | 164 | ||
159 | 165 | ||
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index ad6991c94..a7f9395b8 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -88,6 +88,7 @@ enum { | |||
88 | OPTION_S32, | 88 | OPTION_S32, |
89 | OPTION_BIN, | 89 | OPTION_BIN, |
90 | OPTION_STATIC_ROUTES, | 90 | OPTION_STATIC_ROUTES, |
91 | OPTION_6RD, | ||
91 | #if ENABLE_FEATURE_UDHCP_RFC3397 | 92 | #if ENABLE_FEATURE_UDHCP_RFC3397 |
92 | OPTION_DNS_STRING, /* RFC1035 compressed domain name list */ | 93 | OPTION_DNS_STRING, /* RFC1035 compressed domain name list */ |
93 | OPTION_SIP_SERVERS, | 94 | OPTION_SIP_SERVERS, |
@@ -103,7 +104,7 @@ enum { | |||
103 | /* DHCP option codes (partial list). See RFC 2132 and | 104 | /* DHCP option codes (partial list). See RFC 2132 and |
104 | * http://www.iana.org/assignments/bootp-dhcp-parameters/ | 105 | * http://www.iana.org/assignments/bootp-dhcp-parameters/ |
105 | * Commented out options are handled by common option machinery, | 106 | * Commented out options are handled by common option machinery, |
106 | * uncommented ones have spacial cases (grep for them to see). | 107 | * uncommented ones have special cases (grep for them to see). |
107 | */ | 108 | */ |
108 | #define DHCP_PADDING 0x00 | 109 | #define DHCP_PADDING 0x00 |
109 | #define DHCP_SUBNET 0x01 | 110 | #define DHCP_SUBNET 0x01 |
@@ -248,6 +249,7 @@ struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) | |||
248 | /*** Logging ***/ | 249 | /*** Logging ***/ |
249 | 250 | ||
250 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | 251 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 |
252 | # define IF_UDHCP_VERBOSE(...) __VA_ARGS__ | ||
251 | extern unsigned dhcp_verbose; | 253 | extern unsigned dhcp_verbose; |
252 | # define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) | 254 | # define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) |
253 | # if CONFIG_UDHCP_DEBUG >= 2 | 255 | # if CONFIG_UDHCP_DEBUG >= 2 |
@@ -263,6 +265,7 @@ void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; | |||
263 | # define log3(...) ((void)0) | 265 | # define log3(...) ((void)0) |
264 | # endif | 266 | # endif |
265 | #else | 267 | #else |
268 | # define IF_UDHCP_VERBOSE(...) | ||
266 | # define udhcp_dump_packet(...) ((void)0) | 269 | # define udhcp_dump_packet(...) ((void)0) |
267 | # define log1(...) ((void)0) | 270 | # define log1(...) ((void)0) |
268 | # define log2(...) ((void)0) | 271 | # define log2(...) ((void)0) |
@@ -277,8 +280,6 @@ int FAST_FUNC udhcp_str2nip(const char *str, void *arg); | |||
277 | /* 2nd param is "struct option_set**" */ | 280 | /* 2nd param is "struct option_set**" */ |
278 | int FAST_FUNC udhcp_str2optset(const char *str, void *arg); | 281 | int FAST_FUNC udhcp_str2optset(const char *str, void *arg); |
279 | 282 | ||
280 | uint16_t udhcp_checksum(void *addr, int count) FAST_FUNC; | ||
281 | |||
282 | void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC; | 283 | void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC; |
283 | 284 | ||
284 | int udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) FAST_FUNC; | 285 | int udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) FAST_FUNC; |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 4d755e6b8..3d4c397ff 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -100,6 +100,7 @@ static const uint8_t len_of_option_as_string[] = { | |||
100 | [OPTION_IP ] = sizeof("255.255.255.255 "), | 100 | [OPTION_IP ] = sizeof("255.255.255.255 "), |
101 | [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, | 101 | [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, |
102 | [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), | 102 | [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), |
103 | [OPTION_6RD ] = sizeof("32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "), | ||
103 | [OPTION_STRING ] = 1, | 104 | [OPTION_STRING ] = 1, |
104 | #if ENABLE_FEATURE_UDHCP_RFC3397 | 105 | #if ENABLE_FEATURE_UDHCP_RFC3397 |
105 | [OPTION_DNS_STRING ] = 1, /* unused */ | 106 | [OPTION_DNS_STRING ] = 1, /* unused */ |
@@ -123,6 +124,24 @@ static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) | |||
123 | return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); | 124 | return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); |
124 | } | 125 | } |
125 | 126 | ||
127 | static int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) | ||
128 | { | ||
129 | char hexstrbuf[16 * 2]; | ||
130 | bin2hex(hexstrbuf, (void*)ip, 16); | ||
131 | return sprintf(dest, /* "%s" */ | ||
132 | "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s", | ||
133 | /* pre, */ | ||
134 | hexstrbuf + 0 * 4, | ||
135 | hexstrbuf + 1 * 4, | ||
136 | hexstrbuf + 2 * 4, | ||
137 | hexstrbuf + 3 * 4, | ||
138 | hexstrbuf + 4 * 4, | ||
139 | hexstrbuf + 5 * 4, | ||
140 | hexstrbuf + 6 * 4, | ||
141 | hexstrbuf + 7 * 4 | ||
142 | ); | ||
143 | } | ||
144 | |||
126 | /* really simple implementation, just count the bits */ | 145 | /* really simple implementation, just count the bits */ |
127 | static int mton(uint32_t mask) | 146 | static int mton(uint32_t mask) |
128 | { | 147 | { |
@@ -142,27 +161,25 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ | |||
142 | int len, type, optlen; | 161 | int len, type, optlen; |
143 | char *dest, *ret; | 162 | char *dest, *ret; |
144 | 163 | ||
145 | /* option points to OPT_DATA, need to go back and get OPT_LEN */ | 164 | /* option points to OPT_DATA, need to go back to get OPT_LEN */ |
146 | len = option[OPT_LEN - OPT_DATA]; | 165 | len = option[-OPT_DATA + OPT_LEN]; |
147 | 166 | ||
148 | type = optflag->flags & OPTION_TYPE_MASK; | 167 | type = optflag->flags & OPTION_TYPE_MASK; |
149 | optlen = dhcp_option_lengths[type]; | 168 | optlen = dhcp_option_lengths[type]; |
150 | upper_length = len_of_option_as_string[type] * ((unsigned)len / (unsigned)optlen); | 169 | upper_length = len_of_option_as_string[type] |
170 | * ((unsigned)(len + optlen - 1) / (unsigned)optlen); | ||
151 | 171 | ||
152 | dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); | 172 | dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); |
153 | dest += sprintf(ret, "%s=", opt_name); | 173 | dest += sprintf(ret, "%s=", opt_name); |
154 | 174 | ||
155 | while (len >= optlen) { | 175 | while (len >= optlen) { |
156 | unsigned ip_ofs = 0; | ||
157 | |||
158 | switch (type) { | 176 | switch (type) { |
177 | case OPTION_IP: | ||
159 | case OPTION_IP_PAIR: | 178 | case OPTION_IP_PAIR: |
160 | dest += sprint_nip(dest, "", option); | 179 | dest += sprint_nip(dest, "", option); |
161 | *dest++ = '/'; | 180 | if (type == OPTION_IP) |
162 | ip_ofs = 4; | 181 | break; |
163 | /* fall through */ | 182 | dest += sprint_nip(dest, "/", option + 4); |
164 | case OPTION_IP: | ||
165 | dest += sprint_nip(dest, "", option + ip_ofs); | ||
166 | break; | 183 | break; |
167 | // case OPTION_BOOLEAN: | 184 | // case OPTION_BOOLEAN: |
168 | // dest += sprintf(dest, *option ? "yes" : "no"); | 185 | // dest += sprintf(dest, *option ? "yes" : "no"); |
@@ -184,10 +201,14 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ | |||
184 | dest += sprintf(dest, type == OPTION_U32 ? "%lu" : "%ld", (unsigned long) ntohl(val_u32)); | 201 | dest += sprintf(dest, type == OPTION_U32 ? "%lu" : "%ld", (unsigned long) ntohl(val_u32)); |
185 | break; | 202 | break; |
186 | } | 203 | } |
204 | /* Note: options which use 'return' instead of 'break' | ||
205 | * (for example, OPTION_STRING) skip the code which handles | ||
206 | * the case of list of options. | ||
207 | */ | ||
187 | case OPTION_STRING: | 208 | case OPTION_STRING: |
188 | memcpy(dest, option, len); | 209 | memcpy(dest, option, len); |
189 | dest[len] = '\0'; | 210 | dest[len] = '\0'; |
190 | return ret; /* Short circuit this case */ | 211 | return ret; |
191 | case OPTION_STATIC_ROUTES: { | 212 | case OPTION_STATIC_ROUTES: { |
192 | /* Option binary format: | 213 | /* Option binary format: |
193 | * mask [one byte, 0..32] | 214 | * mask [one byte, 0..32] |
@@ -232,6 +253,53 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ | |||
232 | 253 | ||
233 | return ret; | 254 | return ret; |
234 | } | 255 | } |
256 | case OPTION_6RD: | ||
257 | /* Option binary format (see RFC 5969): | ||
258 | * 0 1 2 3 | ||
259 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
260 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
261 | * | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen | | ||
262 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
263 | * | 6rdPrefix | | ||
264 | * ... (16 octets) ... | ||
265 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
266 | * ... 6rdBRIPv4Address(es) ... | ||
267 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
268 | * We convert it to a string | ||
269 | * "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address..." | ||
270 | * | ||
271 | * Sanity check: ensure that our length is at least 22 bytes, that | ||
272 | * IPv4MaskLen <= 32, | ||
273 | * 6rdPrefixLen <= 128, | ||
274 | * 6rdPrefixLen + (32 - IPv4MaskLen) <= 128 | ||
275 | * (2nd condition need no check - it follows from 1st and 3rd). | ||
276 | * Else, return envvar with empty value ("optname=") | ||
277 | */ | ||
278 | if (len >= (1 + 1 + 16 + 4) | ||
279 | && option[0] <= 32 | ||
280 | && (option[1] + 32 - option[0]) <= 128 | ||
281 | ) { | ||
282 | /* IPv4MaskLen */ | ||
283 | dest += sprintf(dest, "%u ", *option++); | ||
284 | /* 6rdPrefixLen */ | ||
285 | dest += sprintf(dest, "%u ", *option++); | ||
286 | /* 6rdPrefix */ | ||
287 | dest += sprint_nip6(dest, /* "", */ option); | ||
288 | option += 16; | ||
289 | len -= 1 + 1 + 16 + 4; | ||
290 | /* "+ 4" above corresponds to the length of IPv4 addr | ||
291 | * we consume in the loop below */ | ||
292 | while (1) { | ||
293 | /* 6rdBRIPv4Address(es) */ | ||
294 | dest += sprint_nip(dest, " ", option); | ||
295 | option += 4; | ||
296 | len -= 4; /* do we have yet another 4+ bytes? */ | ||
297 | if (len < 0) | ||
298 | break; /* no */ | ||
299 | } | ||
300 | } | ||
301 | |||
302 | return ret; | ||
235 | #if ENABLE_FEATURE_UDHCP_RFC3397 | 303 | #if ENABLE_FEATURE_UDHCP_RFC3397 |
236 | case OPTION_DNS_STRING: | 304 | case OPTION_DNS_STRING: |
237 | /* unpack option into dest; use ret for prefix (i.e., "optname=") */ | 305 | /* unpack option into dest; use ret for prefix (i.e., "optname=") */ |
@@ -271,16 +339,21 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ | |||
271 | return ret; | 339 | return ret; |
272 | #endif | 340 | #endif |
273 | } /* switch */ | 341 | } /* switch */ |
342 | |||
343 | /* If we are here, try to format any remaining data | ||
344 | * in the option as another, similarly-formatted option | ||
345 | */ | ||
274 | option += optlen; | 346 | option += optlen; |
275 | len -= optlen; | 347 | len -= optlen; |
276 | // TODO: it can be a list only if (optflag->flags & OPTION_LIST). | 348 | // TODO: it can be a list only if (optflag->flags & OPTION_LIST). |
277 | // Should we bail out/warn if we see multi-ip option which is | 349 | // Should we bail out/warn if we see multi-ip option which is |
278 | // not allowed to be such (for example, DHCP_BROADCAST)? - | 350 | // not allowed to be such (for example, DHCP_BROADCAST)? - |
279 | if (len <= 0 /* || !(optflag->flags & OPTION_LIST) */) | 351 | if (len < optlen /* || !(optflag->flags & OPTION_LIST) */) |
280 | break; | 352 | break; |
281 | *dest++ = ' '; | 353 | *dest++ = ' '; |
282 | *dest = '\0'; | 354 | *dest = '\0'; |
283 | } | 355 | } /* while */ |
356 | |||
284 | return ret; | 357 | return ret; |
285 | } | 358 | } |
286 | 359 | ||
@@ -320,7 +393,7 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
320 | if (i == DHCP_OPTION_OVERLOAD) | 393 | if (i == DHCP_OPTION_OVERLOAD) |
321 | overload = *temp; | 394 | overload = *temp; |
322 | else if (i == DHCP_SUBNET) | 395 | else if (i == DHCP_SUBNET) |
323 | envc++; /* for mton */ | 396 | envc++; /* for $mask */ |
324 | envc++; | 397 | envc++; |
325 | /*if (i != DHCP_MESSAGE_TYPE)*/ | 398 | /*if (i != DHCP_MESSAGE_TYPE)*/ |
326 | FOUND_OPTS(i) |= BMASK(i); | 399 | FOUND_OPTS(i) |= BMASK(i); |
@@ -335,10 +408,42 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
335 | if (!packet) | 408 | if (!packet) |
336 | return envp; | 409 | return envp; |
337 | 410 | ||
411 | /* Export BOOTP fields. Fields we don't (yet?) export: | ||
412 | * uint8_t op; // always BOOTREPLY | ||
413 | * uint8_t htype; // hardware address type. 1 = 10mb ethernet | ||
414 | * uint8_t hlen; // hardware address length | ||
415 | * uint8_t hops; // used by relay agents only | ||
416 | * uint32_t xid; | ||
417 | * uint16_t secs; // elapsed since client began acquisition/renewal | ||
418 | * uint16_t flags; // only one flag so far: bcast. Never set by server | ||
419 | * uint32_t ciaddr; // client IP (usually == yiaddr. can it be different | ||
420 | * // if during renew server wants to give us differn IP?) | ||
421 | * uint32_t gateway_nip; // relay agent IP address | ||
422 | * uint8_t chaddr[16]; // link-layer client hardware address (MAC) | ||
423 | * TODO: export gateway_nip as $giaddr? | ||
424 | */ | ||
425 | /* Most important one: yiaddr as $ip */ | ||
338 | *curr = xmalloc(sizeof("ip=255.255.255.255")); | 426 | *curr = xmalloc(sizeof("ip=255.255.255.255")); |
339 | sprint_nip(*curr, "ip=", (uint8_t *) &packet->yiaddr); | 427 | sprint_nip(*curr, "ip=", (uint8_t *) &packet->yiaddr); |
340 | putenv(*curr++); | 428 | putenv(*curr++); |
429 | if (packet->siaddr_nip) { | ||
430 | /* IP address of next server to use in bootstrap */ | ||
431 | *curr = xmalloc(sizeof("siaddr=255.255.255.255")); | ||
432 | sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip); | ||
433 | putenv(*curr++); | ||
434 | } | ||
435 | if (!(overload & FILE_FIELD) && packet->file[0]) { | ||
436 | /* watch out for invalid packets */ | ||
437 | *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); | ||
438 | putenv(*curr++); | ||
439 | } | ||
440 | if (!(overload & SNAME_FIELD) && packet->sname[0]) { | ||
441 | /* watch out for invalid packets */ | ||
442 | *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); | ||
443 | putenv(*curr++); | ||
444 | } | ||
341 | 445 | ||
446 | /* Export known DHCP options */ | ||
342 | opt_name = dhcp_option_strings; | 447 | opt_name = dhcp_option_strings; |
343 | i = 0; | 448 | i = 0; |
344 | while (*opt_name) { | 449 | while (*opt_name) { |
@@ -355,29 +460,14 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
355 | /* Subnet option: make things like "$ip/$mask" possible */ | 460 | /* Subnet option: make things like "$ip/$mask" possible */ |
356 | uint32_t subnet; | 461 | uint32_t subnet; |
357 | move_from_unaligned32(subnet, temp); | 462 | move_from_unaligned32(subnet, temp); |
358 | *curr = xasprintf("mask=%d", mton(subnet)); | 463 | *curr = xasprintf("mask=%u", mton(subnet)); |
359 | putenv(*curr++); | 464 | putenv(*curr++); |
360 | } | 465 | } |
361 | next: | 466 | next: |
362 | opt_name += strlen(opt_name) + 1; | 467 | opt_name += strlen(opt_name) + 1; |
363 | i++; | 468 | i++; |
364 | } | 469 | } |
365 | if (packet->siaddr_nip) { | 470 | /* Export unknown options */ |
366 | *curr = xmalloc(sizeof("siaddr=255.255.255.255")); | ||
367 | sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip); | ||
368 | putenv(*curr++); | ||
369 | } | ||
370 | if (!(overload & FILE_FIELD) && packet->file[0]) { | ||
371 | /* watch out for invalid packets */ | ||
372 | *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); | ||
373 | putenv(*curr++); | ||
374 | } | ||
375 | if (!(overload & SNAME_FIELD) && packet->sname[0]) { | ||
376 | /* watch out for invalid packets */ | ||
377 | *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); | ||
378 | putenv(*curr++); | ||
379 | } | ||
380 | /* Handle unknown options */ | ||
381 | for (i = 0; i < 256;) { | 471 | for (i = 0; i < 256;) { |
382 | BITMAP bitmap = FOUND_OPTS(i); | 472 | BITMAP bitmap = FOUND_OPTS(i); |
383 | if (!bitmap) { | 473 | if (!bitmap) { |
@@ -394,11 +484,12 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
394 | len = temp[-OPT_DATA + OPT_LEN]; | 484 | len = temp[-OPT_DATA + OPT_LEN]; |
395 | *curr = xmalloc(sizeof("optNNN=") + 1 + len*2); | 485 | *curr = xmalloc(sizeof("optNNN=") + 1 + len*2); |
396 | ofs = sprintf(*curr, "opt%u=", i); | 486 | ofs = sprintf(*curr, "opt%u=", i); |
397 | bin2hex(*curr + ofs, (void*) temp, len)[0] = '\0'; | 487 | *bin2hex(*curr + ofs, (void*) temp, len) = '\0'; |
398 | putenv(*curr++); | 488 | putenv(*curr++); |
399 | } | 489 | } |
400 | i++; | 490 | i++; |
401 | } | 491 | } |
492 | |||
402 | return envp; | 493 | return envp; |
403 | } | 494 | } |
404 | 495 | ||
@@ -726,7 +817,8 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) | |||
726 | bytes = ntohs(packet.ip.tot_len); | 817 | bytes = ntohs(packet.ip.tot_len); |
727 | 818 | ||
728 | /* make sure its the right packet for us, and that it passes sanity checks */ | 819 | /* make sure its the right packet for us, and that it passes sanity checks */ |
729 | if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION | 820 | if (packet.ip.protocol != IPPROTO_UDP |
821 | || packet.ip.version != IPVERSION | ||
730 | || packet.ip.ihl != (sizeof(packet.ip) >> 2) | 822 | || packet.ip.ihl != (sizeof(packet.ip) >> 2) |
731 | || packet.udp.dest != htons(CLIENT_PORT) | 823 | || packet.udp.dest != htons(CLIENT_PORT) |
732 | /* || bytes > (int) sizeof(packet) - can't happen */ | 824 | /* || bytes > (int) sizeof(packet) - can't happen */ |
@@ -739,7 +831,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) | |||
739 | /* verify IP checksum */ | 831 | /* verify IP checksum */ |
740 | check = packet.ip.check; | 832 | check = packet.ip.check; |
741 | packet.ip.check = 0; | 833 | packet.ip.check = 0; |
742 | if (check != udhcp_checksum(&packet.ip, sizeof(packet.ip))) { | 834 | if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) { |
743 | log1("Bad IP header checksum, ignoring"); | 835 | log1("Bad IP header checksum, ignoring"); |
744 | return -2; | 836 | return -2; |
745 | } | 837 | } |
@@ -750,20 +842,22 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) | |||
750 | packet.ip.tot_len = packet.udp.len; /* yes, this is needed */ | 842 | packet.ip.tot_len = packet.udp.len; /* yes, this is needed */ |
751 | check = packet.udp.check; | 843 | check = packet.udp.check; |
752 | packet.udp.check = 0; | 844 | packet.udp.check = 0; |
753 | if (check && check != udhcp_checksum(&packet, bytes)) { | 845 | if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { |
754 | log1("Packet with bad UDP checksum received, ignoring"); | 846 | log1("Packet with bad UDP checksum received, ignoring"); |
755 | return -2; | 847 | return -2; |
756 | } | 848 | } |
757 | 849 | ||
758 | memcpy(dhcp_pkt, &packet.data, bytes - (sizeof(packet.ip) + sizeof(packet.udp))); | 850 | if (packet.data.cookie != htonl(DHCP_MAGIC)) { |
759 | |||
760 | if (dhcp_pkt->cookie != htonl(DHCP_MAGIC)) { | ||
761 | bb_info_msg("Packet with bad magic, ignoring"); | 851 | bb_info_msg("Packet with bad magic, ignoring"); |
762 | return -2; | 852 | return -2; |
763 | } | 853 | } |
854 | |||
764 | log1("Got valid DHCP packet"); | 855 | log1("Got valid DHCP packet"); |
765 | udhcp_dump_packet(dhcp_pkt); | 856 | udhcp_dump_packet(&packet.data); |
766 | return bytes - (sizeof(packet.ip) + sizeof(packet.udp)); | 857 | |
858 | bytes -= sizeof(packet.ip) + sizeof(packet.udp); | ||
859 | memcpy(dhcp_pkt, &packet.data, bytes); | ||
860 | return bytes; | ||
767 | } | 861 | } |
768 | 862 | ||
769 | 863 | ||
@@ -1077,11 +1171,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1077 | 1171 | ||
1078 | /* Parse command line */ | 1172 | /* Parse command line */ |
1079 | /* O,x: list; -T,-t,-A take numeric param */ | 1173 | /* O,x: list; -T,-t,-A take numeric param */ |
1080 | opt_complementary = "O::x::T+:t+:A+" | 1174 | opt_complementary = "O::x::T+:t+:A+" IF_UDHCP_VERBOSE(":vv") ; |
1081 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | ||
1082 | ":vv" | ||
1083 | #endif | ||
1084 | ; | ||
1085 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) | 1175 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) |
1086 | opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" | 1176 | opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" |
1087 | USE_FOR_MMU("b") | 1177 | USE_FOR_MMU("b") |
@@ -1095,9 +1185,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1095 | , &list_O | 1185 | , &list_O |
1096 | , &list_x | 1186 | , &list_x |
1097 | IF_FEATURE_UDHCP_PORT(, &str_P) | 1187 | IF_FEATURE_UDHCP_PORT(, &str_P) |
1098 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | 1188 | IF_UDHCP_VERBOSE(, &dhcp_verbose) |
1099 | , &dhcp_verbose | ||
1100 | #endif | ||
1101 | ); | 1189 | ); |
1102 | if (opt & (OPT_h|OPT_H)) | 1190 | if (opt & (OPT_h|OPT_H)) |
1103 | client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); | 1191 | client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); |
@@ -1361,9 +1449,23 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1361 | switch (udhcp_sp_read(&rfds)) { | 1449 | switch (udhcp_sp_read(&rfds)) { |
1362 | case SIGUSR1: | 1450 | case SIGUSR1: |
1363 | client_config.first_secs = 0; /* make secs field count from 0 */ | 1451 | client_config.first_secs = 0; /* make secs field count from 0 */ |
1452 | already_waited_sec = 0; | ||
1364 | perform_renew(); | 1453 | perform_renew(); |
1365 | if (state == RENEW_REQUESTED) | 1454 | if (state == RENEW_REQUESTED) { |
1455 | /* We might be either on the same network | ||
1456 | * (in which case renew might work), | ||
1457 | * or we might be on a completely different one | ||
1458 | * (in which case renew won't ever succeed). | ||
1459 | * For the second case, must make sure timeout | ||
1460 | * is not too big, or else we can send | ||
1461 | * futile renew requests for hours. | ||
1462 | * (Ab)use -A TIMEOUT value (usually 20 sec) | ||
1463 | * as a cap on the timeout. | ||
1464 | */ | ||
1465 | if (timeout > tryagain_timeout) | ||
1466 | timeout = tryagain_timeout; | ||
1366 | goto case_RENEW_REQUESTED; | 1467 | goto case_RENEW_REQUESTED; |
1468 | } | ||
1367 | /* Start things over */ | 1469 | /* Start things over */ |
1368 | packet_num = 0; | 1470 | packet_num = 0; |
1369 | /* Kill any timeouts, user wants this to hurry along */ | 1471 | /* Kill any timeouts, user wants this to hurry along */ |
@@ -1431,7 +1533,25 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1431 | case INIT_SELECTING: | 1533 | case INIT_SELECTING: |
1432 | /* Must be a DHCPOFFER to one of our xid's */ | 1534 | /* Must be a DHCPOFFER to one of our xid's */ |
1433 | if (*message == DHCPOFFER) { | 1535 | if (*message == DHCPOFFER) { |
1434 | /* TODO: why we don't just fetch server's IP from IP header? */ | 1536 | /* What exactly is server's IP? There are several values. |
1537 | * Example DHCP offer captured with tchdump: | ||
1538 | * | ||
1539 | * 10.34.25.254:67 > 10.34.25.202:68 // IP header's src | ||
1540 | * BOOTP fields: | ||
1541 | * Your-IP 10.34.25.202 | ||
1542 | * Server-IP 10.34.32.125 // "next server" IP | ||
1543 | * Gateway-IP 10.34.25.254 // relay's address (if DHCP relays are in use) | ||
1544 | * DHCP options: | ||
1545 | * DHCP-Message Option 53, length 1: Offer | ||
1546 | * Server-ID Option 54, length 4: 10.34.255.7 // "server ID" | ||
1547 | * Default-Gateway Option 3, length 4: 10.34.25.254 // router | ||
1548 | * | ||
1549 | * We think that real server IP (one to use in renew/release) | ||
1550 | * is one in Server-ID option. But I am not 100% sure. | ||
1551 | * IP header's src and Gateway-IP (same in this example) | ||
1552 | * might work too. | ||
1553 | * "Next server" and router are definitely wrong ones to use, though... | ||
1554 | */ | ||
1435 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); | 1555 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); |
1436 | if (!temp) { | 1556 | if (!temp) { |
1437 | bb_error_msg("no server ID, ignoring packet"); | 1557 | bb_error_msg("no server ID, ignoring packet"); |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 747472d0c..dd55e70f4 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -314,9 +314,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
314 | #endif | 314 | #endif |
315 | opt = getopt32(argv, "fSv" | 315 | opt = getopt32(argv, "fSv" |
316 | IF_FEATURE_UDHCP_PORT("P:", &str_P) | 316 | IF_FEATURE_UDHCP_PORT("P:", &str_P) |
317 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | 317 | IF_UDHCP_VERBOSE(, &dhcp_verbose) |
318 | , &dhcp_verbose | ||
319 | #endif | ||
320 | ); | 318 | ); |
321 | if (!(opt & 1)) { /* no -f */ | 319 | if (!(opt & 1)) { /* no -f */ |
322 | bb_daemonize_or_rexec(0, argv); | 320 | bb_daemonize_or_rexec(0, argv); |
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 66b42c5e1..4d5ff0676 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c | |||
@@ -129,35 +129,6 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) | |||
129 | return bytes; | 129 | return bytes; |
130 | } | 130 | } |
131 | 131 | ||
132 | uint16_t FAST_FUNC udhcp_checksum(void *addr, int count) | ||
133 | { | ||
134 | /* Compute Internet Checksum for "count" bytes | ||
135 | * beginning at location "addr". | ||
136 | */ | ||
137 | int32_t sum = 0; | ||
138 | uint16_t *source = (uint16_t *) addr; | ||
139 | |||
140 | while (count > 1) { | ||
141 | /* This is the inner loop */ | ||
142 | sum += *source++; | ||
143 | count -= 2; | ||
144 | } | ||
145 | |||
146 | /* Add left-over byte, if any */ | ||
147 | if (count > 0) { | ||
148 | /* Make sure that the left-over byte is added correctly both | ||
149 | * with little and big endian hosts */ | ||
150 | uint16_t tmp = 0; | ||
151 | *(uint8_t*)&tmp = *(uint8_t*)source; | ||
152 | sum += tmp; | ||
153 | } | ||
154 | /* Fold 32-bit sum to 16 bits */ | ||
155 | while (sum >> 16) | ||
156 | sum = (sum & 0xffff) + (sum >> 16); | ||
157 | |||
158 | return ~sum; | ||
159 | } | ||
160 | |||
161 | /* Construct a ip/udp header for a packet, send packet */ | 132 | /* Construct a ip/udp header for a packet, send packet */ |
162 | int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, | 133 | int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, |
163 | uint32_t source_nip, int source_port, | 134 | uint32_t source_nip, int source_port, |
@@ -212,13 +183,14 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, | |||
212 | packet.udp.len = htons(UDP_DHCP_SIZE - padding); | 183 | packet.udp.len = htons(UDP_DHCP_SIZE - padding); |
213 | /* for UDP checksumming, ip.len is set to UDP packet len */ | 184 | /* for UDP checksumming, ip.len is set to UDP packet len */ |
214 | packet.ip.tot_len = packet.udp.len; | 185 | packet.ip.tot_len = packet.udp.len; |
215 | packet.udp.check = udhcp_checksum(&packet, IP_UDP_DHCP_SIZE - padding); | 186 | packet.udp.check = inet_cksum((uint16_t *)&packet, |
187 | IP_UDP_DHCP_SIZE - padding); | ||
216 | /* but for sending, it is set to IP packet len */ | 188 | /* but for sending, it is set to IP packet len */ |
217 | packet.ip.tot_len = htons(IP_UDP_DHCP_SIZE - padding); | 189 | packet.ip.tot_len = htons(IP_UDP_DHCP_SIZE - padding); |
218 | packet.ip.ihl = sizeof(packet.ip) >> 2; | 190 | packet.ip.ihl = sizeof(packet.ip) >> 2; |
219 | packet.ip.version = IPVERSION; | 191 | packet.ip.version = IPVERSION; |
220 | packet.ip.ttl = IPDEFTTL; | 192 | packet.ip.ttl = IPDEFTTL; |
221 | packet.ip.check = udhcp_checksum(&packet.ip, sizeof(packet.ip)); | 193 | packet.ip.check = inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip)); |
222 | 194 | ||
223 | udhcp_dump_packet(dhcp_pkt); | 195 | udhcp_dump_packet(dhcp_pkt); |
224 | result = sendto(fd, &packet, IP_UDP_DHCP_SIZE - padding, /*flags:*/ 0, | 196 | result = sendto(fd, &packet, IP_UDP_DHCP_SIZE - padding, /*flags:*/ 0, |
diff --git a/networking/wget.c b/networking/wget.c index eca673a86..4dd42de9d 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -298,8 +298,13 @@ static void parse_url(const char *src_url, struct host_info *h) | |||
298 | 298 | ||
299 | sp = strrchr(h->host, '@'); | 299 | sp = strrchr(h->host, '@'); |
300 | if (sp != NULL) { | 300 | if (sp != NULL) { |
301 | h->user = h->host; | 301 | // URL-decode "user:password" string before base64-encoding: |
302 | // wget http://test:my%20pass@example.com should send | ||
303 | // Authorization: Basic dGVzdDpteSBwYXNz | ||
304 | // which decodes to "test:my pass". | ||
305 | // Standard wget and curl do this too. | ||
302 | *sp = '\0'; | 306 | *sp = '\0'; |
307 | h->user = percent_decode_in_place(h->host, /*strict:*/ 0); | ||
303 | h->host = sp + 1; | 308 | h->host = sp + 1; |
304 | } | 309 | } |
305 | 310 | ||
@@ -660,12 +665,6 @@ static void download_one_url(const char *url) | |||
660 | 665 | ||
661 | #if ENABLE_FEATURE_WGET_AUTHENTICATION | 666 | #if ENABLE_FEATURE_WGET_AUTHENTICATION |
662 | if (target.user) { | 667 | if (target.user) { |
663 | //TODO: URL-decode "user:password" string before base64-encoding: | ||
664 | //wget http://test:my%20pass@example.com should send | ||
665 | // Authorization: Basic dGVzdDpteSBwYXNz | ||
666 | //which decodes to "test:my pass", instead of what we send now: | ||
667 | // Authorization: Basic dGVzdDpteSUyMHBhc3M= | ||
668 | //Can reuse decodeString() from httpd.c | ||
669 | fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6, | 668 | fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6, |
670 | base64enc(target.user)); | 669 | base64enc(target.user)); |
671 | } | 670 | } |
diff --git a/networking/zcip.c b/networking/zcip.c index 8a35eca5d..7314ff8db 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -91,6 +91,7 @@ struct globals { | |||
91 | #define G (*(struct globals*)&bb_common_bufsiz1) | 91 | #define G (*(struct globals*)&bb_common_bufsiz1) |
92 | #define saddr (G.saddr ) | 92 | #define saddr (G.saddr ) |
93 | #define eth_addr (G.eth_addr) | 93 | #define eth_addr (G.eth_addr) |
94 | #define INIT_G() do { } while (0) | ||
94 | 95 | ||
95 | 96 | ||
96 | /** | 97 | /** |
@@ -223,6 +224,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
223 | #define verbose (L.verbose ) | 224 | #define verbose (L.verbose ) |
224 | 225 | ||
225 | memset(&L, 0, sizeof(L)); | 226 | memset(&L, 0, sizeof(L)); |
227 | INIT_G(); | ||
226 | 228 | ||
227 | #define FOREGROUND (opts & 1) | 229 | #define FOREGROUND (opts & 1) |
228 | #define QUIT (opts & 2) | 230 | #define QUIT (opts & 2) |
diff --git a/procps/Config.src b/procps/Config.src index 570b026da..5cd47c84f 100644 --- a/procps/Config.src +++ b/procps/Config.src | |||
@@ -90,12 +90,20 @@ config PS | |||
90 | config FEATURE_PS_WIDE | 90 | config FEATURE_PS_WIDE |
91 | bool "Enable wide output option (-w)" | 91 | bool "Enable wide output option (-w)" |
92 | default y | 92 | default y |
93 | depends on PS | 93 | depends on PS && !DESKTOP |
94 | help | 94 | help |
95 | Support argument 'w' for wide output. | 95 | Support argument 'w' for wide output. |
96 | If given once, 132 chars are printed, and if given more | 96 | If given once, 132 chars are printed, and if given more |
97 | than once, the length is unlimited. | 97 | than once, the length is unlimited. |
98 | 98 | ||
99 | config FEATURE_PS_LONG | ||
100 | bool "Enable long output option (-l)" | ||
101 | default y | ||
102 | depends on PS && !DESKTOP | ||
103 | help | ||
104 | Support argument 'l' for long output. | ||
105 | Adds fields PPID, RSS, START, TIME & TTY | ||
106 | |||
99 | config FEATURE_PS_TIME | 107 | config FEATURE_PS_TIME |
100 | bool "Enable time and elapsed time output" | 108 | bool "Enable time and elapsed time output" |
101 | default y | 109 | default y |
diff --git a/procps/nmeter.c b/procps/nmeter.c index 999955982..ed5479024 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c | |||
@@ -274,30 +274,56 @@ static int rdval_loadavg(const char* p, ullong *vec, ...) | |||
274 | // 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 | 274 | // 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 |
275 | // 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933 | 275 | // 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933 |
276 | // 3 1 hda1 0 0 0 0 <- ignore if only 4 fields | 276 | // 3 1 hda1 0 0 0 0 <- ignore if only 4 fields |
277 | // Linux 3.0 (maybe earlier) started printing full stats for hda1 too. | ||
278 | // Had to add code which skips such devices. | ||
277 | static int rdval_diskstats(const char* p, ullong *vec) | 279 | static int rdval_diskstats(const char* p, ullong *vec) |
278 | { | 280 | { |
279 | ullong rd = rd; // for compiler | 281 | char devname[32]; |
280 | int indexline = 0; | 282 | unsigned devname_len = 0; |
283 | int value_idx = 0; | ||
284 | |||
281 | vec[0] = 0; | 285 | vec[0] = 0; |
282 | vec[1] = 0; | 286 | vec[1] = 0; |
283 | while (1) { | 287 | while (1) { |
284 | indexline++; | 288 | value_idx++; |
285 | while (*p == ' ' || *p == '\t') p++; | 289 | while (*p == ' ' || *p == '\t') |
286 | if (*p == '\0') break; | 290 | p++; |
291 | if (*p == '\0') | ||
292 | break; | ||
287 | if (*p == '\n') { | 293 | if (*p == '\n') { |
288 | indexline = 0; | 294 | value_idx = 0; |
289 | p++; | 295 | p++; |
290 | continue; | 296 | continue; |
291 | } | 297 | } |
292 | if (indexline == 6) { | 298 | if (value_idx == 3) { |
293 | rd = strtoull(p, NULL, 10); | 299 | char *end = strchrnul(p, ' '); |
294 | } else if (indexline == 10) { | 300 | /* If this a hda1-like device (same prefix as last one + digit)? */ |
295 | vec[0] += rd; // TODO: *sectorsize (don't know how to find out sectorsize) | 301 | if (devname_len && strncmp(devname, p, devname_len) == 0 && isdigit(p[devname_len])) { |
302 | p = end; | ||
303 | goto skip_line; /* skip entire line */ | ||
304 | } | ||
305 | /* It is not. Remember the name for future checks */ | ||
306 | devname_len = end - p; | ||
307 | if (devname_len > sizeof(devname)-1) | ||
308 | devname_len = sizeof(devname)-1; | ||
309 | strncpy(devname, p, devname_len); | ||
310 | /* devname[devname_len] = '\0'; - not really needed */ | ||
311 | p = end; | ||
312 | } else | ||
313 | if (value_idx == 6) { | ||
314 | // TODO: *sectorsize (don't know how to find out sectorsize) | ||
315 | vec[0] += strtoull(p, NULL, 10); | ||
316 | } else | ||
317 | if (value_idx == 10) { | ||
318 | // TODO: *sectorsize (don't know how to find out sectorsize) | ||
296 | vec[1] += strtoull(p, NULL, 10); | 319 | vec[1] += strtoull(p, NULL, 10); |
297 | while (*p != '\n' && *p != '\0') p++; | 320 | skip_line: |
321 | while (*p != '\n' && *p != '\0') | ||
322 | p++; | ||
298 | continue; | 323 | continue; |
299 | } | 324 | } |
300 | while (*p > ' ') p++; // skip over value | 325 | while ((unsigned char)(*p) > ' ') // skip over value |
326 | p++; | ||
301 | } | 327 | } |
302 | return 0; | 328 | return 0; |
303 | } | 329 | } |
diff --git a/procps/ps.c b/procps/ps.c index af57f7aee..aa004aa22 100644 --- a/procps/ps.c +++ b/procps/ps.c | |||
@@ -39,6 +39,12 @@ | |||
39 | //usage: IF_FEATURE_PS_WIDE( | 39 | //usage: IF_FEATURE_PS_WIDE( |
40 | //usage: "\n w Wide output" | 40 | //usage: "\n w Wide output" |
41 | //usage: ) | 41 | //usage: ) |
42 | //usage: IF_FEATURE_PS_LONG( | ||
43 | //usage: "\n l Long output" | ||
44 | //usage: ) | ||
45 | //usage: IF_FEATURE_SHOW_THREADS( | ||
46 | //usage: "\n T Show threads" | ||
47 | //usage: ) | ||
42 | //usage: | 48 | //usage: |
43 | //usage:#endif /* ENABLE_DESKTOP */ | 49 | //usage:#endif /* ENABLE_DESKTOP */ |
44 | //usage: | 50 | //usage: |
@@ -56,15 +62,15 @@ | |||
56 | //usage: " 2990 andersen andersen R ps\n" | 62 | //usage: " 2990 andersen andersen R ps\n" |
57 | 63 | ||
58 | #include "libbb.h" | 64 | #include "libbb.h" |
65 | #ifdef __linux__ | ||
66 | # include <sys/sysinfo.h> | ||
67 | #endif | ||
59 | 68 | ||
60 | /* Absolute maximum on output line length */ | 69 | /* Absolute maximum on output line length */ |
61 | enum { MAX_WIDTH = 2*1024 }; | 70 | enum { MAX_WIDTH = 2*1024 }; |
62 | 71 | ||
63 | #if ENABLE_DESKTOP | 72 | #if ENABLE_DESKTOP |
64 | 73 | ||
65 | #ifdef __linux__ | ||
66 | # include <sys/sysinfo.h> | ||
67 | #endif | ||
68 | #include <sys/times.h> /* for times() */ | 74 | #include <sys/times.h> /* for times() */ |
69 | #ifndef AT_CLKTCK | 75 | #ifndef AT_CLKTCK |
70 | # define AT_CLKTCK 17 | 76 | # define AT_CLKTCK 17 |
@@ -635,15 +641,21 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
635 | enum { | 641 | enum { |
636 | OPT_Z = (1 << 0) * ENABLE_SELINUX, | 642 | OPT_Z = (1 << 0) * ENABLE_SELINUX, |
637 | OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS, | 643 | OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS, |
644 | OPT_l = (1 << ENABLE_SELINUX) * (1 << ENABLE_FEATURE_SHOW_THREADS) * ENABLE_FEATURE_PS_LONG, | ||
638 | }; | 645 | }; |
646 | #if ENABLE_FEATURE_PS_LONG | ||
647 | time_t now = now; | ||
648 | struct sysinfo info; | ||
649 | #endif | ||
639 | int opts = 0; | 650 | int opts = 0; |
640 | /* If we support any options, parse argv */ | 651 | /* If we support any options, parse argv */ |
641 | #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE | 652 | #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG |
642 | # if ENABLE_FEATURE_PS_WIDE | 653 | # if ENABLE_FEATURE_PS_WIDE |
643 | /* -w is a bit complicated */ | 654 | /* -w is a bit complicated */ |
644 | int w_count = 0; | 655 | int w_count = 0; |
645 | opt_complementary = "-:ww"; | 656 | opt_complementary = "-:ww"; |
646 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")"w", &w_count); | 657 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l") |
658 | "w", &w_count); | ||
647 | /* if w is given once, GNU ps sets the width to 132, | 659 | /* if w is given once, GNU ps sets the width to 132, |
648 | * if w is given more than once, it is "unlimited" | 660 | * if w is given more than once, it is "unlimited" |
649 | */ | 661 | */ |
@@ -658,23 +670,51 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
658 | # else | 670 | # else |
659 | /* -w is not supported, only -Z and/or -T */ | 671 | /* -w is not supported, only -Z and/or -T */ |
660 | opt_complementary = "-"; | 672 | opt_complementary = "-"; |
661 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")); | 673 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")); |
662 | # endif | 674 | # endif |
663 | #endif | ||
664 | 675 | ||
665 | #if ENABLE_SELINUX | 676 | # if ENABLE_SELINUX |
666 | if ((opts & OPT_Z) && is_selinux_enabled()) { | 677 | if ((opts & OPT_Z) && is_selinux_enabled()) { |
667 | psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT | 678 | psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT |
668 | | PSSCAN_STATE | PSSCAN_COMM; | 679 | | PSSCAN_STATE | PSSCAN_COMM; |
669 | puts(" PID CONTEXT STAT COMMAND"); | 680 | puts(" PID CONTEXT STAT COMMAND"); |
670 | } else | 681 | } else |
682 | # endif | ||
683 | if (opts & OPT_l) { | ||
684 | psscan_flags = PSSCAN_STATE | PSSCAN_UIDGID | PSSCAN_PID | PSSCAN_PPID | ||
685 | | PSSCAN_TTY | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_COMM | ||
686 | | PSSCAN_VSZ | PSSCAN_RSS; | ||
687 | /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html | ||
688 | * mandates for -l: | ||
689 | * -F Flags (?) | ||
690 | * S State | ||
691 | * UID,PID,PPID | ||
692 | * -C CPU usage | ||
693 | * -PRI The priority of the process; higher numbers mean lower priority | ||
694 | * -NI Nice value | ||
695 | * -ADDR The address of the process (?) | ||
696 | * SZ The size in blocks of the core image | ||
697 | * -WCHAN The event for which the process is waiting or sleeping | ||
698 | * TTY | ||
699 | * TIME The cumulative execution time | ||
700 | * CMD | ||
701 | * We don't show fields marked with '-'. | ||
702 | * We show VSZ and RSS instead of SZ. | ||
703 | * We also show STIME (standard says that -f shows it, -l doesn't). | ||
704 | */ | ||
705 | puts("S UID PID PPID VSZ RSS TTY STIME TIME CMD"); | ||
706 | #if ENABLE_FEATURE_PS_LONG | ||
707 | now = time(NULL); | ||
708 | sysinfo(&info); | ||
671 | #endif | 709 | #endif |
672 | { | 710 | } |
711 | else { | ||
673 | puts(" PID USER VSZ STAT COMMAND"); | 712 | puts(" PID USER VSZ STAT COMMAND"); |
674 | } | 713 | } |
675 | if (opts & OPT_T) { | 714 | if (opts & OPT_T) { |
676 | psscan_flags |= PSSCAN_TASKS; | 715 | psscan_flags |= PSSCAN_TASKS; |
677 | } | 716 | } |
717 | #endif | ||
678 | 718 | ||
679 | p = NULL; | 719 | p = NULL; |
680 | while ((p = procps_scan(p, psscan_flags)) != NULL) { | 720 | while ((p = procps_scan(p, psscan_flags)) != NULL) { |
@@ -688,15 +728,49 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
688 | } else | 728 | } else |
689 | #endif | 729 | #endif |
690 | { | 730 | { |
691 | const char *user = get_cached_username(p->uid); | 731 | char buf6[6]; |
692 | //if (p->vsz == 0) | 732 | smart_ulltoa5(p->vsz, buf6, " mgtpezy"); |
693 | // len = printf("%5u %-8.8s %s ", | 733 | buf6[5] = '\0'; |
694 | // p->pid, user, p->state); | 734 | #if ENABLE_FEATURE_PS_LONG |
695 | //else | 735 | if (opts & OPT_l) { |
736 | char bufr[6], stime_str[6]; | ||
737 | char tty[2 * sizeof(int)*3 + 2]; | ||
738 | char *endp; | ||
739 | unsigned sut = (p->stime + p->utime) / 100; | ||
740 | unsigned elapsed = info.uptime - (p->start_time / 100); | ||
741 | time_t start = now - elapsed; | ||
742 | struct tm *tm = localtime(&start); | ||
743 | |||
744 | smart_ulltoa5(p->rss, bufr, " mgtpezy"); | ||
745 | bufr[5] = '\0'; | ||
746 | |||
747 | if (p->tty_major == 136) | ||
748 | /* It should be pts/N, not ptsN, but N > 9 | ||
749 | * will overflow field width... | ||
750 | */ | ||
751 | endp = stpcpy(tty, "pts"); | ||
752 | else | ||
753 | if (p->tty_major == 4) { | ||
754 | endp = stpcpy(tty, "tty"); | ||
755 | if (p->tty_minor >= 64) { | ||
756 | p->tty_minor -= 64; | ||
757 | *endp++ = 'S'; | ||
758 | } | ||
759 | } | ||
760 | else | ||
761 | endp = tty + sprintf(tty, "%d:", p->tty_major); | ||
762 | strcpy(endp, utoa(p->tty_minor)); | ||
763 | |||
764 | strftime(stime_str, 6, (elapsed >= (24 * 60 * 60)) ? "%b%d" : "%H:%M", tm); | ||
765 | stime_str[5] = '\0'; | ||
766 | // S UID PID PPID VSZ RSS TTY STIME TIME CMD | ||
767 | len = printf("%c %5u %5u %5u %5s %5s %-5s %s %02u:%02u:%02u ", | ||
768 | p->state[0], p->uid, p->pid, p->ppid, buf6, bufr, tty, | ||
769 | stime_str, sut / 3600, (sut % 3600) / 60, sut % 60); | ||
770 | } else | ||
771 | #endif | ||
696 | { | 772 | { |
697 | char buf6[6]; | 773 | const char *user = get_cached_username(p->uid); |
698 | smart_ulltoa5(p->vsz, buf6, " mgtpezy"); | ||
699 | buf6[5] = '\0'; | ||
700 | len = printf("%5u %-8.8s %s %s ", | 774 | len = printf("%5u %-8.8s %s %s ", |
701 | p->pid, user, buf6, p->state); | 775 | p->pid, user, buf6, p->state); |
702 | } | 776 | } |
diff --git a/procps/smemcap.c b/procps/smemcap.c index e108d88ad..9d1126a49 100644 --- a/procps/smemcap.c +++ b/procps/smemcap.c | |||
@@ -20,7 +20,7 @@ | |||
20 | //config: a memory usage statistic tool. | 20 | //config: a memory usage statistic tool. |
21 | 21 | ||
22 | #include "libbb.h" | 22 | #include "libbb.h" |
23 | #include "archive.h" | 23 | #include "bb_archive.h" |
24 | 24 | ||
25 | struct fileblock { | 25 | struct fileblock { |
26 | struct fileblock *next; | 26 | struct fileblock *next; |
diff --git a/procps/top.c b/procps/top.c index 011bbf183..15eb624cc 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -126,7 +126,6 @@ struct BUG_bad_size { | |||
126 | char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; | 126 | char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; |
127 | char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1]; | 127 | char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1]; |
128 | }; | 128 | }; |
129 | #define INIT_G() do { } while (0) | ||
130 | #define top (G.top ) | 129 | #define top (G.top ) |
131 | #define ntop (G.ntop ) | 130 | #define ntop (G.ntop ) |
132 | #define sort_field (G.sort_field ) | 131 | #define sort_field (G.sort_field ) |
@@ -143,6 +142,7 @@ struct BUG_bad_size { | |||
143 | #define num_cpus (G.num_cpus ) | 142 | #define num_cpus (G.num_cpus ) |
144 | #define total_pcpu (G.total_pcpu ) | 143 | #define total_pcpu (G.total_pcpu ) |
145 | #define line_buf (G.line_buf ) | 144 | #define line_buf (G.line_buf ) |
145 | #define INIT_G() do { } while (0) | ||
146 | 146 | ||
147 | enum { | 147 | enum { |
148 | OPT_d = (1 << 0), | 148 | OPT_d = (1 << 0), |
diff --git a/runit/chpst.c b/runit/chpst.c index 185706089..9b8c99bdd 100644 --- a/runit/chpst.c +++ b/runit/chpst.c | |||
@@ -405,19 +405,17 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) | |||
405 | if (opt & OPT_e) | 405 | if (opt & OPT_e) |
406 | edir(env_dir); | 406 | edir(env_dir); |
407 | 407 | ||
408 | // FIXME: chrooted jail must have /etc/passwd if we move this after chroot! | 408 | if (opt & (OPT_u|OPT_U)) |
409 | // OTOH chroot fails for non-roots! | 409 | xget_uidgid(&ugid, set_user); |
410 | // SOLUTION: cache uid/gid before chroot, apply uid/gid after | 410 | |
411 | // chrooted jail must have /etc/passwd if we move this after chroot. | ||
412 | // OTOH chroot fails for non-roots. | ||
413 | // Solution: cache uid/gid before chroot, apply uid/gid after. | ||
411 | if (opt & OPT_U) { | 414 | if (opt & OPT_U) { |
412 | xget_uidgid(&ugid, env_user); | ||
413 | xsetenv("GID", utoa(ugid.gid)); | 415 | xsetenv("GID", utoa(ugid.gid)); |
414 | xsetenv("UID", utoa(ugid.uid)); | 416 | xsetenv("UID", utoa(ugid.uid)); |
415 | } | 417 | } |
416 | 418 | ||
417 | if (opt & OPT_u) { | ||
418 | xget_uidgid(&ugid, set_user); | ||
419 | } | ||
420 | |||
421 | if (opt & OPT_root) { | 419 | if (opt & OPT_root) { |
422 | xchdir(root); | 420 | xchdir(root); |
423 | xchroot("."); | 421 | xchroot("."); |
diff --git a/runit/runsvdir.c b/runit/runsvdir.c index 9495a2a4f..32526cf4c 100644 --- a/runit/runsvdir.c +++ b/runit/runsvdir.c | |||
@@ -75,8 +75,7 @@ struct globals { | |||
75 | #define logpipe (G.logpipe ) | 75 | #define logpipe (G.logpipe ) |
76 | #define pfd (G.pfd ) | 76 | #define pfd (G.pfd ) |
77 | #define stamplog (G.stamplog ) | 77 | #define stamplog (G.stamplog ) |
78 | #define INIT_G() do { \ | 78 | #define INIT_G() do { } while (0) |
79 | } while (0) | ||
80 | 79 | ||
81 | static void fatal2_cannot(const char *m1, const char *m2) | 80 | static void fatal2_cannot(const char *m1, const char *m2) |
82 | { | 81 | { |
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index 0984e7d4b..b12569832 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <limits.h> | 39 | #include <limits.h> |
40 | #include <sys/types.h> | 40 | #include <sys/types.h> |
41 | #include <sys/wait.h> | 41 | #include <sys/wait.h> |
42 | #include <alloca.h> | ||
42 | 43 | ||
43 | /* exitstatus is used to keep track of any failing calls to kernel-doc, | 44 | /* exitstatus is used to keep track of any failing calls to kernel-doc, |
44 | * but execution continues. */ | 45 | * but execution continues. */ |
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index fd2e2375f..b7f9e0c2f 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c | |||
@@ -117,6 +117,7 @@ | |||
117 | #ifndef __MINGW32__ | 117 | #ifndef __MINGW32__ |
118 | #include <arpa/inet.h> | 118 | #include <arpa/inet.h> |
119 | #endif | 119 | #endif |
120 | #include <alloca.h> | ||
120 | 121 | ||
121 | /* bbox: not needed | 122 | /* bbox: not needed |
122 | #define INT_CONF ntohl(0x434f4e46) | 123 | #define INT_CONF ntohl(0x434f4e46) |
diff --git a/scripts/defconfig.tig b/scripts/defconfig.tig index 5da784617..2de0d8041 100644 --- a/scripts/defconfig.tig +++ b/scripts/defconfig.tig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.19.0 | 3 | # Busybox version: 1.20.0.git |
4 | # Thu Mar 22 15:45:17 2012 | 4 | # Fri Mar 23 10:48:09 2012 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -95,7 +95,7 @@ CONFIG_PREFIX="" | |||
95 | # CONFIG_FEATURE_SYSTEMD is not set | 95 | # CONFIG_FEATURE_SYSTEMD is not set |
96 | CONFIG_FEATURE_RTMINMAX=y | 96 | CONFIG_FEATURE_RTMINMAX=y |
97 | CONFIG_PASSWORD_MINLEN=6 | 97 | CONFIG_PASSWORD_MINLEN=6 |
98 | CONFIG_MD5_SIZE_VS_SPEED=2 | 98 | CONFIG_MD5_SMALL=1 |
99 | # CONFIG_FEATURE_FAST_TOP is not set | 99 | # CONFIG_FEATURE_FAST_TOP is not set |
100 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 100 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
101 | # CONFIG_FEATURE_USE_TERMIOS is not set | 101 | # CONFIG_FEATURE_USE_TERMIOS is not set |
@@ -104,6 +104,7 @@ CONFIG_FEATURE_EDITING_MAX_LEN=1024 | |||
104 | # CONFIG_FEATURE_EDITING_VI is not set | 104 | # CONFIG_FEATURE_EDITING_VI is not set |
105 | CONFIG_FEATURE_EDITING_HISTORY=255 | 105 | CONFIG_FEATURE_EDITING_HISTORY=255 |
106 | # CONFIG_FEATURE_EDITING_SAVEHISTORY is not set | 106 | # CONFIG_FEATURE_EDITING_SAVEHISTORY is not set |
107 | # CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set | ||
107 | # CONFIG_FEATURE_REVERSE_SEARCH is not set | 108 | # CONFIG_FEATURE_REVERSE_SEARCH is not set |
108 | CONFIG_FEATURE_TAB_COMPLETION=y | 109 | CONFIG_FEATURE_TAB_COMPLETION=y |
109 | # CONFIG_FEATURE_USERNAME_COMPLETION is not set | 110 | # CONFIG_FEATURE_USERNAME_COMPLETION is not set |
@@ -143,6 +144,7 @@ CONFIG_FEATURE_CPIO_P=y | |||
143 | CONFIG_GUNZIP=y | 144 | CONFIG_GUNZIP=y |
144 | CONFIG_GZIP=y | 145 | CONFIG_GZIP=y |
145 | CONFIG_FEATURE_GZIP_LONG_OPTIONS=y | 146 | CONFIG_FEATURE_GZIP_LONG_OPTIONS=y |
147 | CONFIG_GZIP_FAST=2 | ||
146 | CONFIG_LZOP=y | 148 | CONFIG_LZOP=y |
147 | # CONFIG_LZOP_COMPR_HIGH is not set | 149 | # CONFIG_LZOP_COMPR_HIGH is not set |
148 | CONFIG_RPM2CPIO=y | 150 | CONFIG_RPM2CPIO=y |
@@ -176,6 +178,7 @@ CONFIG_DATE=y | |||
176 | CONFIG_FEATURE_DATE_ISOFMT=y | 178 | CONFIG_FEATURE_DATE_ISOFMT=y |
177 | # CONFIG_FEATURE_DATE_NANO is not set | 179 | # CONFIG_FEATURE_DATE_NANO is not set |
178 | CONFIG_FEATURE_DATE_COMPAT=y | 180 | CONFIG_FEATURE_DATE_COMPAT=y |
181 | # CONFIG_HOSTID is not set | ||
179 | # CONFIG_ID is not set | 182 | # CONFIG_ID is not set |
180 | # CONFIG_GROUPS is not set | 183 | # CONFIG_GROUPS is not set |
181 | CONFIG_TEST=y | 184 | CONFIG_TEST=y |
@@ -223,7 +226,6 @@ CONFIG_FOLD=y | |||
223 | # CONFIG_FSYNC is not set | 226 | # CONFIG_FSYNC is not set |
224 | CONFIG_HEAD=y | 227 | CONFIG_HEAD=y |
225 | CONFIG_FEATURE_FANCY_HEAD=y | 228 | CONFIG_FEATURE_FANCY_HEAD=y |
226 | # CONFIG_HOSTID is not set | ||
227 | # CONFIG_INSTALL is not set | 229 | # CONFIG_INSTALL is not set |
228 | # CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set | 230 | # CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set |
229 | # CONFIG_LN is not set | 231 | # CONFIG_LN is not set |
@@ -460,6 +462,7 @@ CONFIG_LAST_SYSTEM_ID=0 | |||
460 | # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set | 462 | # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set |
461 | # CONFIG_GETTY is not set | 463 | # CONFIG_GETTY is not set |
462 | # CONFIG_LOGIN is not set | 464 | # CONFIG_LOGIN is not set |
465 | # CONFIG_LOGIN_SESSION_AS_CHILD is not set | ||
463 | # CONFIG_PAM is not set | 466 | # CONFIG_PAM is not set |
464 | # CONFIG_LOGIN_SCRIPTS is not set | 467 | # CONFIG_LOGIN_SCRIPTS is not set |
465 | # CONFIG_FEATURE_NOLOGIN is not set | 468 | # CONFIG_FEATURE_NOLOGIN is not set |
@@ -517,6 +520,12 @@ CONFIG_DEFAULT_DEPMOD_FILE="" | |||
517 | # Linux System Utilities | 520 | # Linux System Utilities |
518 | # | 521 | # |
519 | # CONFIG_BLOCKDEV is not set | 522 | # CONFIG_BLOCKDEV is not set |
523 | # CONFIG_MDEV is not set | ||
524 | # CONFIG_FEATURE_MDEV_CONF is not set | ||
525 | # CONFIG_FEATURE_MDEV_RENAME is not set | ||
526 | # CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set | ||
527 | # CONFIG_FEATURE_MDEV_EXEC is not set | ||
528 | # CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set | ||
520 | # CONFIG_REV is not set | 529 | # CONFIG_REV is not set |
521 | # CONFIG_ACPID is not set | 530 | # CONFIG_ACPID is not set |
522 | # CONFIG_FEATURE_ACPID_COMPAT is not set | 531 | # CONFIG_FEATURE_ACPID_COMPAT is not set |
@@ -560,12 +569,6 @@ CONFIG_HD=y | |||
560 | # CONFIG_LOSETUP is not set | 569 | # CONFIG_LOSETUP is not set |
561 | # CONFIG_LSPCI is not set | 570 | # CONFIG_LSPCI is not set |
562 | # CONFIG_LSUSB is not set | 571 | # CONFIG_LSUSB is not set |
563 | # CONFIG_MDEV is not set | ||
564 | # CONFIG_FEATURE_MDEV_CONF is not set | ||
565 | # CONFIG_FEATURE_MDEV_RENAME is not set | ||
566 | # CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set | ||
567 | # CONFIG_FEATURE_MDEV_EXEC is not set | ||
568 | # CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set | ||
569 | # CONFIG_MKSWAP is not set | 572 | # CONFIG_MKSWAP is not set |
570 | # CONFIG_FEATURE_MKSWAP_UUID is not set | 573 | # CONFIG_FEATURE_MKSWAP_UUID is not set |
571 | # CONFIG_MORE is not set | 574 | # CONFIG_MORE is not set |
@@ -889,6 +892,7 @@ CONFIG_FEATURE_PIDOF_OMIT=y | |||
889 | # CONFIG_PKILL is not set | 892 | # CONFIG_PKILL is not set |
890 | CONFIG_PS=y | 893 | CONFIG_PS=y |
891 | # CONFIG_FEATURE_PS_WIDE is not set | 894 | # CONFIG_FEATURE_PS_WIDE is not set |
895 | # CONFIG_FEATURE_PS_LONG is not set | ||
892 | # CONFIG_FEATURE_PS_TIME is not set | 896 | # CONFIG_FEATURE_PS_TIME is not set |
893 | # CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set | 897 | # CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set |
894 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set | 898 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set |
diff --git a/scripts/gen_build_files.sh b/scripts/gen_build_files.sh index e518a9008..c42fe9fbb 100755 --- a/scripts/gen_build_files.sh +++ b/scripts/gen_build_files.sh | |||
@@ -19,25 +19,20 @@ chk() { status "CHK" "$@"; } | |||
19 | 19 | ||
20 | generate() | 20 | generate() |
21 | { | 21 | { |
22 | local src="$1" dst="$2" header="$3" insert="$4" | 22 | # NB: data to be inserted at INSERT line is coming on stdin |
23 | local src="$1" dst="$2" header="$3" | ||
23 | #chk "${dst}" | 24 | #chk "${dst}" |
24 | ( | 25 | { |
25 | # Need to use printf: different shells have inconsistent | 26 | # Need to use printf: different shells have inconsistent |
26 | # rules re handling of "\n" in echo params, | 27 | # rules re handling of "\n" in echo params. |
27 | # and ${insert} definitely contains "\n". | ||
28 | # Therefore, echo "${header}" would not work: | ||
29 | printf "%s\n" "${header}" | 28 | printf "%s\n" "${header}" |
30 | if grep -qs '^INSERT$' "${src}"; then | 29 | # print everything up to INSERT line |
31 | sed -n '1,/^INSERT$/p' "${src}" | 30 | sed -n '/^INSERT$/ q; p' "${src}" |
32 | printf "%s\n" "${insert}" | 31 | # copy stdin to stdout |
33 | sed -n '/^INSERT$/,$p' "${src}" | 32 | cat |
34 | else | 33 | # print everything after INSERT line |
35 | if [ -n "${insert}" ]; then | 34 | sed -n '/^INSERT$/ { :l; n; p; bl }' "${src}" |
36 | printf "%s\n" "ERROR: INSERT line missing in: ${src}" 1>&2 | 35 | } >"${dst}.tmp" |
37 | fi | ||
38 | cat "${src}" | ||
39 | fi | ||
40 | ) | sed '/^INSERT$/d' > "${dst}.tmp" | ||
41 | if ! cmp -s "${dst}" "${dst}.tmp"; then | 36 | if ! cmp -s "${dst}" "${dst}.tmp"; then |
42 | gen "${dst}" | 37 | gen "${dst}" |
43 | mv "${dst}.tmp" "${dst}" | 38 | mv "${dst}.tmp" "${dst}" |
@@ -47,24 +42,21 @@ generate() | |||
47 | } | 42 | } |
48 | 43 | ||
49 | # (Re)generate include/applets.h | 44 | # (Re)generate include/applets.h |
50 | s=`sed -n 's@^//applet:@@p' "$srctree"/*/*.c "$srctree"/*/*/*.c` | 45 | sed -n 's@^//applet:@@p' "$srctree"/*/*.c "$srctree"/*/*/*.c \ |
51 | generate \ | 46 | | generate \ |
52 | "$srctree/include/applets.src.h" \ | 47 | "$srctree/include/applets.src.h" \ |
53 | "include/applets.h" \ | 48 | "include/applets.h" \ |
54 | "/* DO NOT EDIT. This file is generated from applets.src.h */" \ | 49 | "/* DO NOT EDIT. This file is generated from applets.src.h */" |
55 | "${s}" | ||
56 | 50 | ||
57 | # (Re)generate include/usage.h | 51 | # (Re)generate include/usage.h |
58 | # We add line continuation backslash after each line, | 52 | # We add line continuation backslash after each line, |
59 | # and insert empty line before each line which doesn't start | 53 | # and insert empty line before each line which doesn't start |
60 | # with space or tab | 54 | # with space or tab |
61 | # (note: we need to use \\\\ because of ``) | 55 | sed -n -e 's@^//usage:\([ \t].*\)$@\1 \\@p' -e 's@^//usage:\([^ \t].*\)$@\n\1 \\@p' "$srctree"/*/*.c "$srctree"/*/*/*.c \ |
62 | s=`sed -n -e 's@^//usage:\([ \t].*\)$@\1 \\\\@p' -e 's@^//usage:\([^ \t].*\)$@\n\1 \\\\@p' "$srctree"/*/*.c "$srctree"/*/*/*.c` | 56 | | generate \ |
63 | generate \ | ||
64 | "$srctree/include/usage.src.h" \ | 57 | "$srctree/include/usage.src.h" \ |
65 | "include/usage.h" \ | 58 | "include/usage.h" \ |
66 | "/* DO NOT EDIT. This file is generated from usage.src.h */" \ | 59 | "/* DO NOT EDIT. This file is generated from usage.src.h */" |
67 | "${s}" | ||
68 | 60 | ||
69 | # (Re)generate */Kbuild and */Config.in | 61 | # (Re)generate */Kbuild and */Config.in |
70 | { cd -- "$srctree" && find . -type d; } | while read -r d; do | 62 | { cd -- "$srctree" && find . -type d; } | while read -r d; do |
@@ -75,11 +67,10 @@ generate \ | |||
75 | if test -f "$src"; then | 67 | if test -f "$src"; then |
76 | mkdir -p -- "$d" 2>/dev/null | 68 | mkdir -p -- "$d" 2>/dev/null |
77 | 69 | ||
78 | s=`sed -n 's@^//kbuild:@@p' "$srctree/$d"/*.c` | 70 | sed -n 's@^//kbuild:@@p' "$srctree/$d"/*.c \ |
79 | generate \ | 71 | | generate \ |
80 | "${src}" "${dst}" \ | 72 | "${src}" "${dst}" \ |
81 | "# DO NOT EDIT. This file is generated from Kbuild.src" \ | 73 | "# DO NOT EDIT. This file is generated from Kbuild.src" |
82 | "${s}" | ||
83 | fi | 74 | fi |
84 | 75 | ||
85 | src="$srctree/$d/Config.src" | 76 | src="$srctree/$d/Config.src" |
@@ -87,11 +78,10 @@ generate \ | |||
87 | if test -f "$src"; then | 78 | if test -f "$src"; then |
88 | mkdir -p -- "$d" 2>/dev/null | 79 | mkdir -p -- "$d" 2>/dev/null |
89 | 80 | ||
90 | s=`sed -n 's@^//config:@@p' "$srctree/$d"/*.c` | 81 | sed -n 's@^//config:@@p' "$srctree/$d"/*.c \ |
91 | generate \ | 82 | | generate \ |
92 | "${src}" "${dst}" \ | 83 | "${src}" "${dst}" \ |
93 | "# DO NOT EDIT. This file is generated from Config.src" \ | 84 | "# DO NOT EDIT. This file is generated from Config.src" |
94 | "${s}" | ||
95 | fi | 85 | fi |
96 | done | 86 | done |
97 | 87 | ||
diff --git a/shell/ash.c b/shell/ash.c index a809bf181..a79099bc5 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -13431,6 +13431,10 @@ exitshell(void) | |||
13431 | char *p; | 13431 | char *p; |
13432 | int status; | 13432 | int status; |
13433 | 13433 | ||
13434 | #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT | ||
13435 | save_history(line_input_state); | ||
13436 | #endif | ||
13437 | |||
13434 | status = exitstatus; | 13438 | status = exitstatus; |
13435 | TRACE(("pid %d, exitshell(%d)\n", getpid(), status)); | 13439 | TRACE(("pid %d, exitshell(%d)\n", getpid(), status)); |
13436 | if (setjmp(loc.loc)) { | 13440 | if (setjmp(loc.loc)) { |
@@ -13816,7 +13820,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
13816 | } | 13820 | } |
13817 | 13821 | ||
13818 | if (sflag || minusc == NULL) { | 13822 | if (sflag || minusc == NULL) { |
13819 | #if defined MAX_HISTORY && MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY | 13823 | #if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY |
13820 | if (iflag) { | 13824 | if (iflag) { |
13821 | const char *hp = lookupvar("HISTFILE"); | 13825 | const char *hp = lookupvar("HISTFILE"); |
13822 | if (hp) | 13826 | if (hp) |
diff --git a/shell/cttyhack.c b/shell/cttyhack.c index 4261289b4..6ff867413 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c | |||
@@ -50,9 +50,12 @@ | |||
50 | //config: | 50 | //config: |
51 | //config: # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1' | 51 | //config: # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1' |
52 | //config: | 52 | //config: |
53 | //config: Starting getty on a controlling tty from a shell script: | ||
54 | //config: | ||
55 | //config: # getty 115200 $(cttyhack) | ||
53 | 56 | ||
54 | //usage:#define cttyhack_trivial_usage | 57 | //usage:#define cttyhack_trivial_usage |
55 | //usage: "PROG ARGS" | 58 | //usage: "[PROG ARGS]" |
56 | //usage:#define cttyhack_full_usage "\n\n" | 59 | //usage:#define cttyhack_full_usage "\n\n" |
57 | //usage: "Give PROG a controlling tty if possible." | 60 | //usage: "Give PROG a controlling tty if possible." |
58 | //usage: "\nExample for /etc/inittab (for busybox init):" | 61 | //usage: "\nExample for /etc/inittab (for busybox init):" |
@@ -108,59 +111,71 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) | |||
108 | char paranoia[sizeof(struct serial_struct) * 3]; | 111 | char paranoia[sizeof(struct serial_struct) * 3]; |
109 | } u; | 112 | } u; |
110 | 113 | ||
111 | if (!*++argv) { | ||
112 | bb_show_usage(); | ||
113 | } | ||
114 | |||
115 | strcpy(console, "/dev/tty"); | 114 | strcpy(console, "/dev/tty"); |
116 | fd = open(console, O_RDWR); | 115 | fd = open(console, O_RDWR); |
117 | if (fd >= 0) { | 116 | if (fd < 0) { |
118 | /* We already have ctty, nothing to do */ | ||
119 | close(fd); | ||
120 | } else { | ||
121 | /* We don't have ctty (or don't have "/dev/tty" node...) */ | 117 | /* We don't have ctty (or don't have "/dev/tty" node...) */ |
122 | do { | 118 | do { |
123 | #ifdef __linux__ | 119 | #ifdef __linux__ |
120 | /* Note that this method does not use _stdin_. | ||
121 | * Thus, "cttyhack </dev/something" can't be used. | ||
122 | * However, this method is more reliable than | ||
123 | * TIOCGSERIAL check, which assumes that all | ||
124 | * serial lines follow /dev/ttySn convention - | ||
125 | * which is not always the case. | ||
126 | * Therefore, we use this methos first: | ||
127 | */ | ||
124 | int s = open_read_close("/sys/class/tty/console/active", | 128 | int s = open_read_close("/sys/class/tty/console/active", |
125 | console + 5, sizeof(console) - 5 - 1); | 129 | console + 5, sizeof(console) - 5); |
126 | if (s > 0) { | 130 | if (s > 0) { |
127 | /* found active console via sysfs (Linux 2.6.38+) */ | 131 | /* found active console via sysfs (Linux 2.6.38+) |
128 | console[5 + s] = '\0'; | 132 | * sysfs string looks like "ttyS0\n" so zap the newline: |
133 | */ | ||
134 | console[4 + s] = '\0'; | ||
129 | break; | 135 | break; |
130 | } | 136 | } |
131 | 137 | ||
132 | if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { | 138 | if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { |
133 | /* this is linux virtual tty */ | 139 | /* this is linux virtual tty */ |
134 | sprintf(console + 8, "S%d" + 1, u.vt.v_active); | 140 | sprintf(console + 8, "S%u" + 1, (int)u.vt.v_active); |
135 | break; | 141 | break; |
136 | } | 142 | } |
137 | #endif | 143 | #endif |
138 | #ifdef TIOCGSERIAL | 144 | #ifdef TIOCGSERIAL |
139 | if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { | 145 | if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { |
140 | /* this is a serial console, asuming it is named /dev/ttySn */ | 146 | /* this is a serial console; assuming it is named /dev/ttySn */ |
141 | sprintf(console + 8, "S%d", u.sr.line); | 147 | sprintf(console + 8, "S%u", (int)u.sr.line); |
142 | break; | 148 | break; |
143 | } | 149 | } |
144 | #endif | 150 | #endif |
145 | /* nope, could not find it */ | 151 | /* nope, could not find it */ |
146 | goto ret; | 152 | console[0] = '\0'; |
147 | } while (0); | 153 | } while (0); |
154 | } | ||
155 | |||
156 | argv++; | ||
157 | if (!argv[0]) { | ||
158 | if (!console[0]) | ||
159 | return EXIT_FAILURE; | ||
160 | puts(console); | ||
161 | return EXIT_SUCCESS; | ||
162 | } | ||
148 | 163 | ||
164 | if (fd < 0) { | ||
149 | fd = open_or_warn(console, O_RDWR); | 165 | fd = open_or_warn(console, O_RDWR); |
150 | if (fd < 0) | 166 | if (fd < 0) |
151 | goto ret; | 167 | goto ret; |
152 | //bb_error_msg("switching to '%s'", console); | ||
153 | dup2(fd, 0); | ||
154 | dup2(fd, 1); | ||
155 | dup2(fd, 2); | ||
156 | while (fd > 2) | ||
157 | close(fd--); | ||
158 | /* Some other session may have it as ctty, | ||
159 | * steal it from them: | ||
160 | */ | ||
161 | ioctl(0, TIOCSCTTY, 1); | ||
162 | } | 168 | } |
163 | 169 | //bb_error_msg("switching to '%s'", console); | |
164 | ret: | 170 | dup2(fd, 0); |
171 | dup2(fd, 1); | ||
172 | dup2(fd, 2); | ||
173 | while (fd > 2) | ||
174 | close(fd--); | ||
175 | /* Some other session may have it as ctty, | ||
176 | * try to steal it from them: | ||
177 | */ | ||
178 | ioctl(0, TIOCSCTTY, 1); | ||
179 | ret: | ||
165 | BB_EXECVP_or_die(argv); | 180 | BB_EXECVP_or_die(argv); |
166 | } | 181 | } |
diff --git a/shell/hush.c b/shell/hush.c index e4138adf7..7a34f59ae 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1541,6 +1541,10 @@ static sighandler_t pick_sighandler(unsigned sig) | |||
1541 | static void hush_exit(int exitcode) NORETURN; | 1541 | static void hush_exit(int exitcode) NORETURN; |
1542 | static void hush_exit(int exitcode) | 1542 | static void hush_exit(int exitcode) |
1543 | { | 1543 | { |
1544 | #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT | ||
1545 | save_history(G.line_input_state); | ||
1546 | #endif | ||
1547 | |||
1544 | fflush_all(); | 1548 | fflush_all(); |
1545 | if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) { | 1549 | if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) { |
1546 | char *argv[3]; | 1550 | char *argv[3]; |
@@ -7817,22 +7821,6 @@ int hush_main(int argc, char **argv) | |||
7817 | 7821 | ||
7818 | #if ENABLE_FEATURE_EDITING | 7822 | #if ENABLE_FEATURE_EDITING |
7819 | G.line_input_state = new_line_input_t(FOR_SHELL); | 7823 | G.line_input_state = new_line_input_t(FOR_SHELL); |
7820 | # if defined MAX_HISTORY && MAX_HISTORY > 0 && ENABLE_HUSH_SAVEHISTORY | ||
7821 | { | ||
7822 | const char *hp = get_local_var_value("HISTFILE"); | ||
7823 | if (!hp) { | ||
7824 | hp = get_local_var_value("HOME"); | ||
7825 | if (hp) { | ||
7826 | G.line_input_state->hist_file = concat_path_file(hp, ".hush_history"); | ||
7827 | //set_local_var(xasprintf("HISTFILE=%s", ...)); | ||
7828 | } | ||
7829 | } | ||
7830 | # if ENABLE_FEATURE_SH_HISTFILESIZE | ||
7831 | hp = get_local_var_value("HISTFILESIZE"); | ||
7832 | G.line_input_state->max_history = size_from_HISTFILESIZE(hp); | ||
7833 | # endif | ||
7834 | } | ||
7835 | # endif | ||
7836 | #endif | 7824 | #endif |
7837 | 7825 | ||
7838 | /* Initialize some more globals to non-zero values */ | 7826 | /* Initialize some more globals to non-zero values */ |
@@ -8104,6 +8092,27 @@ int hush_main(int argc, char **argv) | |||
8104 | /* -1 is special - makes xfuncs longjmp, not exit | 8092 | /* -1 is special - makes xfuncs longjmp, not exit |
8105 | * (we reset die_sleep = 0 whereever we [v]fork) */ | 8093 | * (we reset die_sleep = 0 whereever we [v]fork) */ |
8106 | enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */ | 8094 | enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */ |
8095 | |||
8096 | # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 | ||
8097 | { | ||
8098 | const char *hp = get_local_var_value("HISTFILE"); | ||
8099 | if (!hp) { | ||
8100 | hp = get_local_var_value("HOME"); | ||
8101 | if (hp) | ||
8102 | hp = concat_path_file(hp, ".hush_history"); | ||
8103 | } else { | ||
8104 | hp = xstrdup(hp); | ||
8105 | } | ||
8106 | if (hp) { | ||
8107 | G.line_input_state->hist_file = hp; | ||
8108 | //set_local_var(xasprintf("HISTFILE=%s", ...)); | ||
8109 | } | ||
8110 | # if ENABLE_FEATURE_SH_HISTFILESIZE | ||
8111 | hp = get_local_var_value("HISTFILESIZE"); | ||
8112 | G.line_input_state->max_history = size_from_HISTFILESIZE(hp); | ||
8113 | # endif | ||
8114 | } | ||
8115 | # endif | ||
8107 | } else { | 8116 | } else { |
8108 | install_special_sighandlers(); | 8117 | install_special_sighandlers(); |
8109 | } | 8118 | } |
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 2f0ca6ac5..fc380d9f9 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c | |||
@@ -278,7 +278,7 @@ static void parse_syslogdcfg(const char *file) | |||
278 | parser_t *parser; | 278 | parser_t *parser; |
279 | 279 | ||
280 | parser = config_open2(file ? file : "/etc/syslog.conf", | 280 | parser = config_open2(file ? file : "/etc/syslog.conf", |
281 | file ? xfopen_for_read : fopen_or_warn_stdin); | 281 | file ? xfopen_for_read : fopen_for_read); |
282 | if (!parser) | 282 | if (!parser) |
283 | /* didn't find default /etc/syslog.conf */ | 283 | /* didn't find default /etc/syslog.conf */ |
284 | /* proceed as if we built busybox without config support */ | 284 | /* proceed as if we built busybox without config support */ |
@@ -594,6 +594,14 @@ static void log_locally(time_t now, char *msg, logFile_t *log_file) | |||
594 | } | 594 | } |
595 | /* newFile == "f.0" now */ | 595 | /* newFile == "f.0" now */ |
596 | rename(log_file->path, newFile); | 596 | rename(log_file->path, newFile); |
597 | /* Incredibly, if F and F.0 are hardlinks, POSIX | ||
598 | * _demands_ that rename returns 0 but does not | ||
599 | * remove F!!! | ||
600 | * (hardlinked F/F.0 pair was observed after | ||
601 | * power failure during rename()). | ||
602 | * Ensure old file is gone: | ||
603 | */ | ||
604 | unlink(log_file->path); | ||
597 | #ifdef SYSLOGD_WRLOCK | 605 | #ifdef SYSLOGD_WRLOCK |
598 | fl.l_type = F_UNLCK; | 606 | fl.l_type = F_UNLCK; |
599 | fcntl(log_file->fd, F_SETLKW, &fl); | 607 | fcntl(log_file->fd, F_SETLKW, &fl); |
@@ -678,7 +686,7 @@ static void timestamp_and_log(int pri, char *msg, int len) | |||
678 | if (LOG_PRI(pri) < G.logLevel) { | 686 | if (LOG_PRI(pri) < G.logLevel) { |
679 | #if ENABLE_FEATURE_IPC_SYSLOG | 687 | #if ENABLE_FEATURE_IPC_SYSLOG |
680 | if ((option_mask32 & OPT_circularlog) && G.shbuf) { | 688 | if ((option_mask32 & OPT_circularlog) && G.shbuf) { |
681 | log_to_shmem(msg); | 689 | log_to_shmem(G.printbuf); |
682 | return; | 690 | return; |
683 | } | 691 | } |
684 | #endif | 692 | #endif |
diff --git a/testsuite/awk.tests b/testsuite/awk.tests index 0afe9b9e7..5a323047d 100755 --- a/testsuite/awk.tests +++ b/testsuite/awk.tests | |||
@@ -202,4 +202,7 @@ end d | |||
202 | " \ | 202 | " \ |
203 | "" "" | 203 | "" "" |
204 | 204 | ||
205 | testing "awk handles empty ()" \ | ||
206 | "awk 'BEGIN {print()}' 2>&1" "awk: cmd. line:1: Empty sequence\n" "" "" | ||
207 | |||
205 | exit $FAILCOUNT | 208 | exit $FAILCOUNT |
diff --git a/testsuite/bzcat.tests b/testsuite/bzcat.tests index 5b4f3f4b3..1c1fd6563 100755 --- a/testsuite/bzcat.tests +++ b/testsuite/bzcat.tests | |||
@@ -51,4 +51,34 @@ prep; check "bzcat: dont delete src" "${bb}bzcat t2.bz2; test -f t2.bz2 && echo | |||
51 | ) | 51 | ) |
52 | rm -rf testdir | 52 | rm -rf testdir |
53 | 53 | ||
54 | |||
55 | |||
56 | # Copyright 2011 by Denys Vlasenko | ||
57 | # Licensed under GPLv2, see file LICENSE in this source tree. | ||
58 | |||
59 | . ./testing.sh | ||
60 | |||
61 | # testing "test name" "command" "expected result" "file input" "stdin" | ||
62 | |||
63 | # "input" file is bzipped file with "a\n" data | ||
64 | testing "bzcat can print many files" \ | ||
65 | "$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ | ||
66 | "\ | ||
67 | a | ||
68 | a | ||
69 | 0 | ||
70 | " "\ | ||
71 | \x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x63\x3e\xd6\xe2\x00\x00\ | ||
72 | \x00\xc1\x00\x00\x10\x20\x00\x20\x00\x21\x00\x82\xb1\x77\x24\x53\ | ||
73 | \x85\x09\x06\x33\xed\x6e\x20\ | ||
74 | " "" | ||
75 | |||
76 | # "input" file is bzipped zero byte file | ||
77 | testing "bzcat can handle compressed zero-length bzip2 files" \ | ||
78 | "$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ | ||
79 | "0\n" \ | ||
80 | "\x42\x5a\x68\x39\x17\x72\x45\x38\x50\x90\x00\x00\x00\x00" "" | ||
81 | |||
82 | |||
83 | |||
54 | exit $((FAILCOUNT <= 255 ? FAILCOUNT : 255)) | 84 | exit $((FAILCOUNT <= 255 ? FAILCOUNT : 255)) |
diff --git a/testsuite/grep.tests b/testsuite/grep.tests index ffce033e6..006a215e1 100755 --- a/testsuite/grep.tests +++ b/testsuite/grep.tests | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | . ./testing.sh | 8 | . ./testing.sh |
9 | 9 | ||
10 | # testing "test name" "options" "expected result" "file input" "stdin" | 10 | # testing "test name" "commands" "expected result" "file input" "stdin" |
11 | # file input will be file called "input" | 11 | # file input will be file called "input" |
12 | # test can create a file "actual" instead of writing to stdout | 12 | # test can create a file "actual" instead of writing to stdout |
13 | 13 | ||
@@ -103,4 +103,20 @@ testing "grep -o does not loop forever on zero-length match" \ | |||
103 | "" \ | 103 | "" \ |
104 | "" "test\n" | 104 | "" "test\n" |
105 | 105 | ||
106 | testing "grep -f EMPTY_FILE" \ | ||
107 | "grep -f input" \ | ||
108 | "" \ | ||
109 | "" \ | ||
110 | "test\n" | ||
111 | |||
112 | testing "grep -v -f EMPTY_FILE" \ | ||
113 | "grep -v -f input" \ | ||
114 | "test\n" \ | ||
115 | "" \ | ||
116 | "test\n" | ||
117 | |||
118 | # testing "test name" "commands" "expected result" "file input" "stdin" | ||
119 | # file input will be file called "input" | ||
120 | # test can create a file "actual" instead of writing to stdout | ||
121 | |||
106 | exit $FAILCOUNT | 122 | exit $FAILCOUNT |
diff --git a/testsuite/patch.tests b/testsuite/patch.tests index c604b9c1d..2759d2ad4 100755 --- a/testsuite/patch.tests +++ b/testsuite/patch.tests | |||
@@ -212,6 +212,36 @@ patching file input | |||
212 | 666 | 212 | 666 |
213 | " \ | 213 | " \ |
214 | 214 | ||
215 | # testing "test name" "command(s)" "expected result" "file input" "stdin" | ||
216 | testing "patch creates new file" \ | ||
217 | 'patch 2>&1; echo $?; cat testfile; rm testfile' \ | ||
218 | "\ | ||
219 | creating testfile | ||
220 | 0 | ||
221 | qwerty | ||
222 | " "" "\ | ||
223 | --- /dev/null | ||
224 | +++ testfile | ||
225 | @@ -0,0 +1 @@ | ||
226 | +qwerty | ||
227 | " | ||
228 | |||
229 | # testing "test name" "command(s)" "expected result" "file input" "stdin" | ||
230 | testing "patch understands ...dir///dir..." \ | ||
231 | 'patch -p1 2>&1; echo $?' \ | ||
232 | "\ | ||
233 | patching file dir2///file | ||
234 | patch: can't open 'dir2///file': No such file or directory | ||
235 | 1 | ||
236 | " "" "\ | ||
237 | --- bogus_dir///dir2///file | ||
238 | +++ bogus_dir///dir2///file | ||
239 | @@ -1,2 +1,3 @@ | ||
240 | qwe | ||
241 | +asd | ||
242 | zxc | ||
243 | " | ||
244 | |||
215 | rm input.orig 2>/dev/null | 245 | rm input.orig 2>/dev/null |
216 | 246 | ||
217 | exit $FAILCOUNT | 247 | exit $FAILCOUNT |
diff --git a/testsuite/sed.tests b/testsuite/sed.tests index e9d0ed601..ba163e9e9 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests | |||
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | . ./testing.sh | 7 | . ./testing.sh |
8 | 8 | ||
9 | # testing "description" "arguments" "result" "infile" "stdin" | 9 | # testing "description" "commands" "result" "infile" "stdin" |
10 | 10 | ||
11 | # Corner cases | 11 | # Corner cases |
12 | testing "sed no files (stdin)" 'sed ""' "hello\n" "" "hello\n" | 12 | testing "sed no files (stdin)" 'sed ""' "hello\n" "" "hello\n" |
@@ -225,7 +225,7 @@ testing "sed s/xxx/[/" "sed -e 's/xxx/[/'" "[\n" "" "xxx\n" | |||
225 | #testing "sed -g (exhaustive)" "sed -e 's/[[:space:]]*/,/g'" ",1,2,3,4,5," \ | 225 | #testing "sed -g (exhaustive)" "sed -e 's/[[:space:]]*/,/g'" ",1,2,3,4,5," \ |
226 | # "" "12345" | 226 | # "" "12345" |
227 | 227 | ||
228 | # testing "description" "arguments" "result" "infile" "stdin" | 228 | # testing "description" "commands" "result" "infile" "stdin" |
229 | 229 | ||
230 | testing "sed n command must reset 'substituted' bit" \ | 230 | testing "sed n command must reset 'substituted' bit" \ |
231 | "sed 's/1/x/;T;n;: next;s/3/y/;t quit;n;b next;: quit;q'" \ | 231 | "sed 's/1/x/;T;n;: next;s/3/y/;t quit;n;b next;: quit;q'" \ |
@@ -291,6 +291,10 @@ testing "sed understands \r" \ | |||
291 | "sed 's/r/\r/'" \ | 291 | "sed 's/r/\r/'" \ |
292 | "\rrr\n" "" "rrr\n" | 292 | "\rrr\n" "" "rrr\n" |
293 | 293 | ||
294 | # testing "description" "arguments" "result" "infile" "stdin" | 294 | testing "sed -i finishes ranges correctly" \ |
295 | "sed '1,2d' -i input; echo \$?; cat input" \ | ||
296 | "0\n3\n4\n" "1\n2\n3\n4\n" "" | ||
297 | |||
298 | # testing "description" "commands" "result" "infile" "stdin" | ||
295 | 299 | ||
296 | exit $FAILCOUNT | 300 | exit $FAILCOUNT |
diff --git a/testsuite/tail.tests b/testsuite/tail.tests index 7140da262..305a83b15 100755 --- a/testsuite/tail.tests +++ b/testsuite/tail.tests | |||
@@ -14,4 +14,12 @@ testing "tail: +N with N > file length" \ | |||
14 | "0\n" \ | 14 | "0\n" \ |
15 | "" "qw" | 15 | "" "qw" |
16 | 16 | ||
17 | testing "tail: -c +N with largish N" \ | ||
18 | " | ||
19 | dd if=/dev/zero bs=16k count=1 2>/dev/null | tail -c +8200 | wc -c; | ||
20 | dd if=/dev/zero bs=16k count=1 2>/dev/null | tail -c +8208 | wc -c; | ||
21 | " \ | ||
22 | "8185\n8177\n" \ | ||
23 | "" "" | ||
24 | |||
17 | exit $FAILCOUNT | 25 | exit $FAILCOUNT |
diff --git a/testsuite/uncompress.tests b/testsuite/uncompress.tests new file mode 100755 index 000000000..51a233493 --- /dev/null +++ b/testsuite/uncompress.tests | |||
@@ -0,0 +1,20 @@ | |||
1 | #!/bin/sh | ||
2 | # Copyright 2011 by Denys Vlasenko | ||
3 | # Licensed under GPLv2, see file LICENSE in this source tree. | ||
4 | |||
5 | . ./testing.sh | ||
6 | |||
7 | # testing "test name" "commands" "expected result" "file input" "stdin" | ||
8 | |||
9 | testing "uncompress < \x1f\x9d\x90 \x01 x N" \ | ||
10 | 'uncompress 2>&1 1>/dev/null; echo $?' \ | ||
11 | "\ | ||
12 | uncompress: corrupted data | ||
13 | 1 | ||
14 | " \ | ||
15 | "" "\ | ||
16 | \x1f\x9d\x90\ | ||
17 | \01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\ | ||
18 | " | ||
19 | |||
20 | exit $FAILCOUNT | ||
diff --git a/testsuite/uuencode.tests b/testsuite/uuencode.tests index cd6191b1b..6ce70f747 100755 --- a/testsuite/uuencode.tests +++ b/testsuite/uuencode.tests | |||
@@ -8,9 +8,9 @@ | |||
8 | 8 | ||
9 | . ./testing.sh | 9 | . ./testing.sh |
10 | 10 | ||
11 | # testing "test name" "options" "expected result" "file input" "stdin" | 11 | # testing "test name" "command(s)" "expected result" "file input" "stdin" |
12 | # file input will be file called "input" | 12 | # file input will be file called "input" |
13 | # test can create a file "actual" instead of writing to stdout | 13 | # test can create a file "actual" instead of writing to stdout |
14 | 14 | ||
15 | # Test setup of standard input | 15 | # Test setup of standard input |
16 | umask 0 | 16 | umask 0 |
@@ -24,4 +24,99 @@ testing "uuencode correct encoding" "uuencode bb_uuenc_test.out" \ | |||
24 | testing "uuencode correct base64 encoding" "uuencode -m bb_uuenc_test.out" \ | 24 | testing "uuencode correct base64 encoding" "uuencode -m bb_uuenc_test.out" \ |
25 | "begin-base64 644 bb_uuenc_test.out\nVGhlIGZhc3QgZ3JleSBmb3gganVtcGVkIG92ZXIgdGhlIGxhenkgYnJvd24g\nZG9nLgo=\n====\n" \ | 25 | "begin-base64 644 bb_uuenc_test.out\nVGhlIGZhc3QgZ3JleSBmb3gganVtcGVkIG92ZXIgdGhlIGxhenkgYnJvd24g\nZG9nLgo=\n====\n" \ |
26 | "" "The fast grey fox jumped over the lazy brown dog.\n" | 26 | "" "The fast grey fox jumped over the lazy brown dog.\n" |
27 | |||
28 | testing "uuencode empty file" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
29 | 'begin 644 FILE | ||
30 | ` | ||
31 | end | ||
32 | ' "" "" | ||
33 | testing "uuencode -m empty file" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
34 | 'begin-base64 644 FILE | ||
35 | ==== | ||
36 | ' "" "" | ||
37 | |||
38 | testing "uuencode file 'A'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
39 | 'begin 644 FILE | ||
40 | !00`` | ||
41 | ` | ||
42 | end | ||
43 | A' "" "A" | ||
44 | testing "uuencode -m file 'A'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
45 | 'begin-base64 644 FILE | ||
46 | QQ== | ||
47 | ==== | ||
48 | A' "" "A" | ||
49 | |||
50 | testing "uuencode file 'AB'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
51 | 'begin 644 FILE | ||
52 | "04(` | ||
53 | ` | ||
54 | end | ||
55 | AB' "" "AB" | ||
56 | testing "uuencode -m file 'AB'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
57 | 'begin-base64 644 FILE | ||
58 | QUI= | ||
59 | ==== | ||
60 | AB' "" "AB" | ||
61 | |||
62 | testing "uuencode file 'ABC'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
63 | 'begin 644 FILE | ||
64 | #04)# | ||
65 | ` | ||
66 | end | ||
67 | ABC' "" "ABC" | ||
68 | testing "uuencode -m file 'ABC'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
69 | 'begin-base64 644 FILE | ||
70 | QUJD | ||
71 | ==== | ||
72 | ABC' "" "ABC" | ||
73 | |||
74 | testing "uuencode file 'ABCD'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
75 | 'begin 644 FILE | ||
76 | $04)#1``` | ||
77 | ` | ||
78 | end | ||
79 | ABCD' "" "ABCD" | ||
80 | testing "uuencode -m file 'ABCD'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
81 | 'begin-base64 644 FILE | ||
82 | QUJDRA== | ||
83 | ==== | ||
84 | ABCD' "" "ABCD" | ||
85 | |||
86 | testing "uuencode file 'ABCDE'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
87 | 'begin 644 FILE | ||
88 | %04)#1$4` | ||
89 | ` | ||
90 | end | ||
91 | ABCDE' "" "ABCDE" | ||
92 | testing "uuencode -m file 'ABCDE'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
93 | 'begin-base64 644 FILE | ||
94 | QUJDREU= | ||
95 | ==== | ||
96 | ABCDE' "" "ABCDE" | ||
97 | |||
98 | testing "uuencode file 'ABCDEF'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
99 | 'begin 644 FILE | ||
100 | &04)#1$5& | ||
101 | ` | ||
102 | end | ||
103 | ABCDEF' "" "ABCDEF" | ||
104 | testing "uuencode -m file 'ABCDEF'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
105 | 'begin-base64 644 FILE | ||
106 | QUJDREVG | ||
107 | ==== | ||
108 | ABCDEF' "" "ABCDEF" | ||
109 | |||
110 | testing "uuencode file 'A<NUL><0xff>Z'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
111 | 'begin 644 FILE | ||
112 | $00#_6@`` | ||
113 | ` | ||
114 | end | ||
115 | A\x0\xffZ' "" "A\x0\xffZ" | ||
116 | testing "uuencode -m file 'A<NUL><0xff>Z'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ | ||
117 | 'begin-base64 644 FILE | ||
118 | QQD/Wg== | ||
119 | ==== | ||
120 | A\x0\xffZ' "" "A\x0\xffZ" | ||
121 | |||
27 | exit $FAILCOUNT | 122 | exit $FAILCOUNT |
diff --git a/util-linux/Config.src b/util-linux/Config.src index bb45705a9..888bc8f3b 100644 --- a/util-linux/Config.src +++ b/util-linux/Config.src | |||
@@ -404,64 +404,6 @@ config LSUSB | |||
404 | 404 | ||
405 | This version uses sysfs (/sys/bus/usb/devices) only. | 405 | This version uses sysfs (/sys/bus/usb/devices) only. |
406 | 406 | ||
407 | config MDEV | ||
408 | bool "mdev" | ||
409 | default y | ||
410 | select PLATFORM_LINUX | ||
411 | help | ||
412 | mdev is a mini-udev implementation for dynamically creating device | ||
413 | nodes in the /dev directory. | ||
414 | |||
415 | For more information, please see docs/mdev.txt | ||
416 | |||
417 | config FEATURE_MDEV_CONF | ||
418 | bool "Support /etc/mdev.conf" | ||
419 | default y | ||
420 | depends on MDEV | ||
421 | help | ||
422 | Add support for the mdev config file to control ownership and | ||
423 | permissions of the device nodes. | ||
424 | |||
425 | For more information, please see docs/mdev.txt | ||
426 | |||
427 | config FEATURE_MDEV_RENAME | ||
428 | bool "Support subdirs/symlinks" | ||
429 | default y | ||
430 | depends on FEATURE_MDEV_CONF | ||
431 | help | ||
432 | Add support for renaming devices and creating symlinks. | ||
433 | |||
434 | For more information, please see docs/mdev.txt | ||
435 | |||
436 | config FEATURE_MDEV_RENAME_REGEXP | ||
437 | bool "Support regular expressions substitutions when renaming device" | ||
438 | default y | ||
439 | depends on FEATURE_MDEV_RENAME | ||
440 | help | ||
441 | Add support for regular expressions substitutions when renaming | ||
442 | device. | ||
443 | |||
444 | config FEATURE_MDEV_EXEC | ||
445 | bool "Support command execution at device addition/removal" | ||
446 | default y | ||
447 | depends on FEATURE_MDEV_CONF | ||
448 | help | ||
449 | This adds support for an optional field to /etc/mdev.conf for | ||
450 | executing commands when devices are created/removed. | ||
451 | |||
452 | For more information, please see docs/mdev.txt | ||
453 | |||
454 | config FEATURE_MDEV_LOAD_FIRMWARE | ||
455 | bool "Support loading of firmwares" | ||
456 | default y | ||
457 | depends on MDEV | ||
458 | help | ||
459 | Some devices need to load firmware before they can be usable. | ||
460 | |||
461 | These devices will request userspace look up the files in | ||
462 | /lib/firmware/ and if it exists, send it to the kernel for | ||
463 | loading into the hardware. | ||
464 | |||
465 | config MKSWAP | 407 | config MKSWAP |
466 | bool "mkswap" | 408 | bool "mkswap" |
467 | default y | 409 | default y |
diff --git a/util-linux/Kbuild.src b/util-linux/Kbuild.src index c06d911ec..468fc6bc1 100644 --- a/util-linux/Kbuild.src +++ b/util-linux/Kbuild.src | |||
@@ -26,7 +26,6 @@ lib-$(CONFIG_IPCS) += ipcs.o | |||
26 | lib-$(CONFIG_LOSETUP) += losetup.o | 26 | lib-$(CONFIG_LOSETUP) += losetup.o |
27 | lib-$(CONFIG_LSPCI) += lspci.o | 27 | lib-$(CONFIG_LSPCI) += lspci.o |
28 | lib-$(CONFIG_LSUSB) += lsusb.o | 28 | lib-$(CONFIG_LSUSB) += lsusb.o |
29 | lib-$(CONFIG_MDEV) += mdev.o | ||
30 | lib-$(CONFIG_MKFS_EXT2) += mkfs_ext2.o | 29 | lib-$(CONFIG_MKFS_EXT2) += mkfs_ext2.o |
31 | lib-$(CONFIG_MKFS_MINIX) += mkfs_minix.o | 30 | lib-$(CONFIG_MKFS_MINIX) += mkfs_minix.o |
32 | lib-$(CONFIG_MKFS_REISER) += mkfs_reiser.o | 31 | lib-$(CONFIG_MKFS_REISER) += mkfs_reiser.o |
diff --git a/util-linux/losetup.c b/util-linux/losetup.c index 9b7c49f50..21108d0bf 100644 --- a/util-linux/losetup.c +++ b/util-linux/losetup.c | |||
@@ -8,11 +8,12 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | //usage:#define losetup_trivial_usage | 10 | //usage:#define losetup_trivial_usage |
11 | //usage: "[-o OFS] LOOPDEV FILE - associate loop devices\n" | 11 | //usage: "[-r] [-o OFS] LOOPDEV FILE - associate loop devices\n" |
12 | //usage: " losetup -d LOOPDEV - disassociate\n" | 12 | //usage: " losetup -d LOOPDEV - disassociate\n" |
13 | //usage: " losetup [-f] - show" | 13 | //usage: " losetup [-f] - show" |
14 | //usage:#define losetup_full_usage "\n\n" | 14 | //usage:#define losetup_full_usage "\n\n" |
15 | //usage: " -o OFS Start OFS bytes into FILE" | 15 | //usage: " -o OFS Start OFS bytes into FILE" |
16 | //usage: "\n -r Read-only" | ||
16 | //usage: "\n -f Show first free loop device" | 17 | //usage: "\n -f Show first free loop device" |
17 | //usage: | 18 | //usage: |
18 | //usage:#define losetup_notes_usage | 19 | //usage:#define losetup_notes_usage |
@@ -37,11 +38,12 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |||
37 | OPT_d = (1 << 0), | 38 | OPT_d = (1 << 0), |
38 | OPT_o = (1 << 1), | 39 | OPT_o = (1 << 1), |
39 | OPT_f = (1 << 2), | 40 | OPT_f = (1 << 2), |
41 | OPT_r = (1 << 3), /* must be last */ | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | /* max 2 args, all opts are mutually exclusive */ | 44 | /* max 2 args, -d,-o,-f opts are mutually exclusive */ |
43 | opt_complementary = "?2:d--of:o--df:f--do"; | 45 | opt_complementary = "?2:d--of:o--df:f--do"; |
44 | opt = getopt32(argv, "do:f", &opt_o); | 46 | opt = getopt32(argv, "do:fr", &opt_o); |
45 | argv += optind; | 47 | argv += optind; |
46 | 48 | ||
47 | if (opt == OPT_o) | 49 | if (opt == OPT_o) |
@@ -63,12 +65,12 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |||
63 | bb_show_usage(); | 65 | bb_show_usage(); |
64 | 66 | ||
65 | if (argv[1]) { | 67 | if (argv[1]) { |
66 | /* [-o OFS] BLOCKDEV FILE */ | 68 | /* [-r] [-o OFS] BLOCKDEV FILE */ |
67 | if (set_loop(&argv[0], argv[1], offset) < 0) | 69 | if (set_loop(&argv[0], argv[1], offset, (opt / OPT_r)) < 0) |
68 | bb_simple_perror_msg_and_die(argv[0]); | 70 | bb_simple_perror_msg_and_die(argv[0]); |
69 | return EXIT_SUCCESS; | 71 | return EXIT_SUCCESS; |
70 | } | 72 | } |
71 | /* [-o OFS] BLOCKDEV */ | 73 | /* [-r] [-o OFS] BLOCKDEV */ |
72 | s = query_loop(argv[0]); | 74 | s = query_loop(argv[0]); |
73 | if (!s) | 75 | if (!s) |
74 | bb_simple_perror_msg_and_die(argv[0]); | 76 | bb_simple_perror_msg_and_die(argv[0]); |
@@ -78,7 +80,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |||
78 | return EXIT_SUCCESS; | 80 | return EXIT_SUCCESS; |
79 | } | 81 | } |
80 | 82 | ||
81 | /* [-o OFS|-f] with no params */ | 83 | /* [-r] [-o OFS|-f] with no params */ |
82 | n = 0; | 84 | n = 0; |
83 | while (1) { | 85 | while (1) { |
84 | char *s; | 86 | char *s; |
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 7cabb1df6..c6be1b872 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -8,39 +8,91 @@ | |||
8 | * Licensed under GPLv2, see file LICENSE in this source tree. | 8 | * Licensed under GPLv2, see file LICENSE in this source tree. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | //config:config MDEV | ||
12 | //config: bool "mdev" | ||
13 | //config: default y | ||
14 | //config: select PLATFORM_LINUX | ||
15 | //config: help | ||
16 | //config: mdev is a mini-udev implementation for dynamically creating device | ||
17 | //config: nodes in the /dev directory. | ||
18 | //config: | ||
19 | //config: For more information, please see docs/mdev.txt | ||
20 | //config: | ||
21 | //config:config FEATURE_MDEV_CONF | ||
22 | //config: bool "Support /etc/mdev.conf" | ||
23 | //config: default y | ||
24 | //config: depends on MDEV | ||
25 | //config: help | ||
26 | //config: Add support for the mdev config file to control ownership and | ||
27 | //config: permissions of the device nodes. | ||
28 | //config: | ||
29 | //config: For more information, please see docs/mdev.txt | ||
30 | //config: | ||
31 | //config:config FEATURE_MDEV_RENAME | ||
32 | //config: bool "Support subdirs/symlinks" | ||
33 | //config: default y | ||
34 | //config: depends on FEATURE_MDEV_CONF | ||
35 | //config: help | ||
36 | //config: Add support for renaming devices and creating symlinks. | ||
37 | //config: | ||
38 | //config: For more information, please see docs/mdev.txt | ||
39 | //config: | ||
40 | //config:config FEATURE_MDEV_RENAME_REGEXP | ||
41 | //config: bool "Support regular expressions substitutions when renaming device" | ||
42 | //config: default y | ||
43 | //config: depends on FEATURE_MDEV_RENAME | ||
44 | //config: help | ||
45 | //config: Add support for regular expressions substitutions when renaming | ||
46 | //config: device. | ||
47 | //config: | ||
48 | //config:config FEATURE_MDEV_EXEC | ||
49 | //config: bool "Support command execution at device addition/removal" | ||
50 | //config: default y | ||
51 | //config: depends on FEATURE_MDEV_CONF | ||
52 | //config: help | ||
53 | //config: This adds support for an optional field to /etc/mdev.conf for | ||
54 | //config: executing commands when devices are created/removed. | ||
55 | //config: | ||
56 | //config: For more information, please see docs/mdev.txt | ||
57 | //config: | ||
58 | //config:config FEATURE_MDEV_LOAD_FIRMWARE | ||
59 | //config: bool "Support loading of firmwares" | ||
60 | //config: default y | ||
61 | //config: depends on MDEV | ||
62 | //config: help | ||
63 | //config: Some devices need to load firmware before they can be usable. | ||
64 | //config: | ||
65 | //config: These devices will request userspace look up the files in | ||
66 | //config: /lib/firmware/ and if it exists, send it to the kernel for | ||
67 | //config: loading into the hardware. | ||
68 | |||
69 | //applet:IF_MDEV(APPLET(mdev, BB_DIR_SBIN, BB_SUID_DROP)) | ||
70 | |||
71 | //kbuild:lib-$(CONFIG_MDEV) += mdev.o | ||
72 | |||
11 | //usage:#define mdev_trivial_usage | 73 | //usage:#define mdev_trivial_usage |
12 | //usage: "[-s]" | 74 | //usage: "[-s]" |
13 | //usage:#define mdev_full_usage "\n\n" | 75 | //usage:#define mdev_full_usage "\n\n" |
14 | //usage: " -s Scan /sys and populate /dev during system boot\n" | 76 | //usage: "mdev -s is to be run during boot to scan /sys and populate /dev.\n" |
15 | //usage: "\n" | 77 | //usage: "\n" |
16 | //usage: "It can be run by kernel as a hotplug helper. To activate it:\n" | 78 | //usage: "Bare mdev is a kernel hotplug helper. To activate it:\n" |
17 | //usage: " echo /sbin/mdev > /proc/sys/kernel/hotplug\n" | 79 | //usage: " echo /sbin/mdev >/proc/sys/kernel/hotplug\n" |
18 | //usage: IF_FEATURE_MDEV_CONF( | 80 | //usage: IF_FEATURE_MDEV_CONF( |
81 | //usage: "\n" | ||
19 | //usage: "It uses /etc/mdev.conf with lines\n" | 82 | //usage: "It uses /etc/mdev.conf with lines\n" |
20 | //usage: "[-]DEVNAME UID:GID PERM" | 83 | //usage: " [-]DEVNAME UID:GID PERM" |
21 | //usage: IF_FEATURE_MDEV_RENAME(" [>|=PATH]") | 84 | //usage: IF_FEATURE_MDEV_RENAME(" [>|=PATH]|[!]") |
22 | //usage: IF_FEATURE_MDEV_EXEC(" [@|$|*PROG]") | 85 | //usage: IF_FEATURE_MDEV_EXEC(" [@|$|*PROG]") |
86 | //usage: "\n" | ||
87 | //usage: "where DEVNAME is device name regex, @major,minor[-minor2], or\n" | ||
88 | //usage: "environment variable regex. A common use of the latter is\n" | ||
89 | //usage: "to load modules for hotplugged devices:\n" | ||
90 | //usage: " $MODALIAS=.* 0:0 660 @modprobe \"$MODALIAS\"\n" | ||
23 | //usage: ) | 91 | //usage: ) |
24 | //usage: | 92 | //usage: "\n" |
25 | //usage:#define mdev_notes_usage "" | 93 | //usage: "If /dev/mdev.seq file exists, mdev will wait for its value\n" |
26 | //usage: IF_FEATURE_MDEV_CONFIG( | 94 | //usage: "to match $SEQNUM variable. This prevents plug/unplug races.\n" |
27 | //usage: "The mdev config file contains lines that look like:\n" | 95 | //usage: "To activate this feature, create empty /dev/mdev.seq at boot." |
28 | //usage: " hd[a-z][0-9]* 0:3 660\n\n" | ||
29 | //usage: "That's device name (with regex match), uid:gid, and permissions.\n\n" | ||
30 | //usage: IF_FEATURE_MDEV_EXEC( | ||
31 | //usage: "Optionally, that can be followed (on the same line) by a special character\n" | ||
32 | //usage: "and a command line to run after creating/before deleting the corresponding\n" | ||
33 | //usage: "device(s). The environment variable $MDEV indicates the active device node\n" | ||
34 | //usage: "(which is useful if it's a regex match). For example:\n\n" | ||
35 | //usage: " hdc root:cdrom 660 *ln -s $MDEV cdrom\n\n" | ||
36 | //usage: "The special characters are @ (run after creating), $ (run before deleting),\n" | ||
37 | //usage: "and * (run both after creating and before deleting). The commands run in\n" | ||
38 | //usage: "the /dev directory, and use system() which calls /bin/sh.\n\n" | ||
39 | //usage: ) | ||
40 | //usage: "Config file parsing stops on the first matching line. If no config\n" | ||
41 | //usage: "entry is matched, devices are created with default 0:0 660. (Make\n" | ||
42 | //usage: "the last line match .* to override this.)\n\n" | ||
43 | //usage: ) | ||
44 | 96 | ||
45 | #include "libbb.h" | 97 | #include "libbb.h" |
46 | #include "xregex.h" | 98 | #include "xregex.h" |
@@ -62,20 +114,11 @@ | |||
62 | * (todo: explain "delete" and $FIRMWARE) | 114 | * (todo: explain "delete" and $FIRMWARE) |
63 | * | 115 | * |
64 | * If /etc/mdev.conf exists, it may modify /dev/device_name's properties. | 116 | * If /etc/mdev.conf exists, it may modify /dev/device_name's properties. |
65 | * /etc/mdev.conf file format: | ||
66 | * | ||
67 | * [-][subsystem/]device user:grp mode [>|=path] [@|$|*command args...] | ||
68 | * [-]@maj,min[-min2] user:grp mode [>|=path] [@|$|*command args...] | ||
69 | * [-]$envvar=val user:grp mode [>|=path] [@|$|*command args...] | ||
70 | * | 117 | * |
71 | * Leading minus in 1st field means "don't stop on this line", otherwise | 118 | * Leading minus in 1st field means "don't stop on this line", otherwise |
72 | * search is stopped after the matching line is encountered. | 119 | * search is stopped after the matching line is encountered. |
73 | * | 120 | * |
74 | * The device name or "subsystem/device" combo is matched against 1st field | 121 | * $envvar=regex format is useful for loading modules for hot-plugged devices |
75 | * (which is a regex), or maj,min is matched against 1st field, | ||
76 | * or specified environment variable (as regex) is matched against 1st field. | ||
77 | * | ||
78 | * $envvar=val format is useful for loading modules for hot-plugged devices | ||
79 | * which do not have driver loaded yet. In this case /sys/class/.../dev | 122 | * which do not have driver loaded yet. In this case /sys/class/.../dev |
80 | * does not exist, but $MODALIAS is set to needed module's name | 123 | * does not exist, but $MODALIAS is set to needed module's name |
81 | * (actually, an alias to it) by kernel. This rule instructs mdev | 124 | * (actually, an alias to it) by kernel. This rule instructs mdev |
@@ -96,11 +139,33 @@ | |||
96 | * This happens regardless of /sys/class/.../dev existence. | 139 | * This happens regardless of /sys/class/.../dev existence. |
97 | */ | 140 | */ |
98 | 141 | ||
142 | struct rule { | ||
143 | bool keep_matching; | ||
144 | bool regex_compiled; | ||
145 | bool regex_has_slash; | ||
146 | mode_t mode; | ||
147 | int maj, min0, min1; | ||
148 | struct bb_uidgid_t ugid; | ||
149 | char *envvar; | ||
150 | char *ren_mov; | ||
151 | IF_FEATURE_MDEV_EXEC(char *r_cmd;) | ||
152 | regex_t match; | ||
153 | }; | ||
154 | |||
99 | struct globals { | 155 | struct globals { |
100 | int root_major, root_minor; | 156 | int root_major, root_minor; |
101 | char *subsystem; | 157 | char *subsystem; |
158 | #if ENABLE_FEATURE_MDEV_CONF | ||
159 | const char *filename; | ||
160 | parser_t *parser; | ||
161 | struct rule **rule_vec; | ||
162 | unsigned rule_idx; | ||
163 | #endif | ||
164 | struct rule cur_rule; | ||
102 | } FIX_ALIASING; | 165 | } FIX_ALIASING; |
103 | #define G (*(struct globals*)&bb_common_bufsiz1) | 166 | #define G (*(struct globals*)&bb_common_bufsiz1) |
167 | #define INIT_G() do { } while (0) | ||
168 | |||
104 | 169 | ||
105 | /* Prevent infinite loops in /sys symlinks */ | 170 | /* Prevent infinite loops in /sys symlinks */ |
106 | #define MAX_SYSFS_DEPTH 3 | 171 | #define MAX_SYSFS_DEPTH 3 |
@@ -108,6 +173,165 @@ struct globals { | |||
108 | /* We use additional 64+ bytes in make_device() */ | 173 | /* We use additional 64+ bytes in make_device() */ |
109 | #define SCRATCH_SIZE 80 | 174 | #define SCRATCH_SIZE 80 |
110 | 175 | ||
176 | #if 0 | ||
177 | # define dbg(...) bb_error_msg(__VA_ARGS__) | ||
178 | #else | ||
179 | # define dbg(...) ((void)0) | ||
180 | #endif | ||
181 | |||
182 | |||
183 | #if ENABLE_FEATURE_MDEV_CONF | ||
184 | |||
185 | static void make_default_cur_rule(void) | ||
186 | { | ||
187 | memset(&G.cur_rule, 0, sizeof(G.cur_rule)); | ||
188 | G.cur_rule.maj = -1; /* "not a @major,minor rule" */ | ||
189 | G.cur_rule.mode = 0660; | ||
190 | } | ||
191 | |||
192 | static void clean_up_cur_rule(void) | ||
193 | { | ||
194 | free(G.cur_rule.envvar); | ||
195 | if (G.cur_rule.regex_compiled) | ||
196 | regfree(&G.cur_rule.match); | ||
197 | free(G.cur_rule.ren_mov); | ||
198 | IF_FEATURE_MDEV_EXEC(free(G.cur_rule.r_cmd);) | ||
199 | make_default_cur_rule(); | ||
200 | } | ||
201 | |||
202 | static void parse_next_rule(void) | ||
203 | { | ||
204 | /* Note: on entry, G.cur_rule is set to default */ | ||
205 | while (1) { | ||
206 | char *tokens[4]; | ||
207 | char *val; | ||
208 | |||
209 | if (!config_read(G.parser, tokens, 4, 3, "# \t", PARSE_NORMAL)) | ||
210 | break; | ||
211 | |||
212 | /* Fields: [-]regex uid:gid mode [alias] [cmd] */ | ||
213 | dbg("token1:'%s'", tokens[1]); | ||
214 | |||
215 | /* 1st field */ | ||
216 | val = tokens[0]; | ||
217 | G.cur_rule.keep_matching = ('-' == val[0]); | ||
218 | val += G.cur_rule.keep_matching; /* swallow leading dash */ | ||
219 | if (val[0] == '@') { | ||
220 | /* @major,minor[-minor2] */ | ||
221 | /* (useful when name is ambiguous: | ||
222 | * "/sys/class/usb/lp0" and | ||
223 | * "/sys/class/printer/lp0") | ||
224 | */ | ||
225 | int sc = sscanf(val, "@%u,%u-%u", &G.cur_rule.maj, &G.cur_rule.min0, &G.cur_rule.min1); | ||
226 | if (sc < 2 || G.cur_rule.maj < 0) { | ||
227 | bb_error_msg("bad @maj,min on line %d", G.parser->lineno); | ||
228 | goto next_rule; | ||
229 | } | ||
230 | if (sc == 2) | ||
231 | G.cur_rule.min1 = G.cur_rule.min0; | ||
232 | } else { | ||
233 | if (val[0] == '$') { | ||
234 | char *eq = strchr(++val, '='); | ||
235 | if (!eq) { | ||
236 | bb_error_msg("bad $envvar=regex on line %d", G.parser->lineno); | ||
237 | goto next_rule; | ||
238 | } | ||
239 | G.cur_rule.envvar = xstrndup(val, eq - val); | ||
240 | val = eq + 1; | ||
241 | } | ||
242 | xregcomp(&G.cur_rule.match, val, REG_EXTENDED); | ||
243 | G.cur_rule.regex_compiled = 1; | ||
244 | G.cur_rule.regex_has_slash = (strchr(val, '/') != NULL); | ||
245 | } | ||
246 | |||
247 | /* 2nd field: uid:gid - device ownership */ | ||
248 | if (get_uidgid(&G.cur_rule.ugid, tokens[1], /*allow_numeric:*/ 1) == 0) { | ||
249 | bb_error_msg("unknown user/group '%s' on line %d", tokens[1], G.parser->lineno); | ||
250 | goto next_rule; | ||
251 | } | ||
252 | |||
253 | /* 3rd field: mode - device permissions */ | ||
254 | bb_parse_mode(tokens[2], &G.cur_rule.mode); | ||
255 | |||
256 | /* 4th field (opt): ">|=alias" or "!" to not create the node */ | ||
257 | val = tokens[3]; | ||
258 | if (ENABLE_FEATURE_MDEV_RENAME && val && strchr(">=!", val[0])) { | ||
259 | char *s = skip_non_whitespace(val); | ||
260 | G.cur_rule.ren_mov = xstrndup(val, s - val); | ||
261 | val = skip_whitespace(s); | ||
262 | } | ||
263 | |||
264 | if (ENABLE_FEATURE_MDEV_EXEC && val && val[0]) { | ||
265 | const char *s = "$@*"; | ||
266 | const char *s2 = strchr(s, val[0]); | ||
267 | if (!s2) { | ||
268 | bb_error_msg("bad line %u", G.parser->lineno); | ||
269 | goto next_rule; | ||
270 | } | ||
271 | IF_FEATURE_MDEV_EXEC(G.cur_rule.r_cmd = xstrdup(val);) | ||
272 | } | ||
273 | |||
274 | return; | ||
275 | next_rule: | ||
276 | clean_up_cur_rule(); | ||
277 | } /* while (config_read) */ | ||
278 | |||
279 | dbg("config_close(G.parser)"); | ||
280 | config_close(G.parser); | ||
281 | G.parser = NULL; | ||
282 | |||
283 | return; | ||
284 | } | ||
285 | |||
286 | /* If mdev -s, we remember rules in G.rule_vec[]. | ||
287 | * Otherwise, there is no point in doing it, and we just | ||
288 | * save only one parsed rule in G.cur_rule. | ||
289 | */ | ||
290 | static const struct rule *next_rule(void) | ||
291 | { | ||
292 | struct rule *rule; | ||
293 | |||
294 | /* Open conf file if we didn't do it yet */ | ||
295 | if (!G.parser && G.filename) { | ||
296 | dbg("config_open('%s')", G.filename); | ||
297 | G.parser = config_open2(G.filename, fopen_for_read); | ||
298 | G.filename = NULL; | ||
299 | } | ||
300 | |||
301 | if (G.rule_vec) { | ||
302 | /* mdev -s */ | ||
303 | /* Do we have rule parsed already? */ | ||
304 | if (G.rule_vec[G.rule_idx]) { | ||
305 | dbg("< G.rule_vec[G.rule_idx:%d]=%p", G.rule_idx, G.rule_vec[G.rule_idx]); | ||
306 | return G.rule_vec[G.rule_idx++]; | ||
307 | } | ||
308 | make_default_cur_rule(); | ||
309 | } else { | ||
310 | /* not mdev -s */ | ||
311 | clean_up_cur_rule(); | ||
312 | } | ||
313 | |||
314 | /* Parse one more rule if file isn't fully read */ | ||
315 | rule = &G.cur_rule; | ||
316 | if (G.parser) { | ||
317 | parse_next_rule(); | ||
318 | if (G.rule_vec) { /* mdev -s */ | ||
319 | rule = memcpy(xmalloc(sizeof(G.cur_rule)), &G.cur_rule, sizeof(G.cur_rule)); | ||
320 | G.rule_vec = xrealloc_vector(G.rule_vec, 4, G.rule_idx); | ||
321 | G.rule_vec[G.rule_idx++] = rule; | ||
322 | dbg("> G.rule_vec[G.rule_idx:%d]=%p", G.rule_idx, G.rule_vec[G.rule_idx]); | ||
323 | } | ||
324 | } | ||
325 | |||
326 | return rule; | ||
327 | } | ||
328 | |||
329 | #else | ||
330 | |||
331 | # define next_rule() (&G.cur_rule) | ||
332 | |||
333 | #endif | ||
334 | |||
111 | /* Builds an alias path. | 335 | /* Builds an alias path. |
112 | * This function potentionally reallocates the alias parameter. | 336 | * This function potentionally reallocates the alias parameter. |
113 | * Only used for ENABLE_FEATURE_MDEV_RENAME | 337 | * Only used for ENABLE_FEATURE_MDEV_RENAME |
@@ -143,8 +367,8 @@ static void make_device(char *path, int delete) | |||
143 | { | 367 | { |
144 | char *device_name, *subsystem_slash_devname; | 368 | char *device_name, *subsystem_slash_devname; |
145 | int major, minor, type, len; | 369 | int major, minor, type, len; |
146 | mode_t mode; | 370 | |
147 | parser_t *parser; | 371 | dbg("%s('%s', delete:%d)", __func__, path, delete); |
148 | 372 | ||
149 | /* Try to read major/minor string. Note that the kernel puts \n after | 373 | /* Try to read major/minor string. Note that the kernel puts \n after |
150 | * the data, so we don't need to worry about null terminating the string | 374 | * the data, so we don't need to worry about null terminating the string |
@@ -197,246 +421,184 @@ static void make_device(char *path, int delete) | |||
197 | path = subsystem_slash_devname; | 421 | path = subsystem_slash_devname; |
198 | } | 422 | } |
199 | 423 | ||
200 | /* If we have config file, look up user settings */ | 424 | #if ENABLE_FEATURE_MDEV_CONF |
201 | if (ENABLE_FEATURE_MDEV_CONF) | 425 | G.rule_idx = 0; /* restart from the beginning (think mdev -s) */ |
202 | parser = config_open2("/etc/mdev.conf", fopen_for_read); | 426 | #endif |
203 | 427 | for (;;) { | |
204 | do { | 428 | const char *str_to_match; |
205 | int keep_matching; | 429 | regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP]; |
206 | struct bb_uidgid_t ugid; | 430 | char *command; |
207 | char *tokens[4]; | 431 | char *alias; |
208 | char *command = NULL; | ||
209 | char *alias = NULL; | ||
210 | char aliaslink = aliaslink; /* for compiler */ | 432 | char aliaslink = aliaslink; /* for compiler */ |
433 | const char *node_name; | ||
434 | const struct rule *rule; | ||
211 | 435 | ||
212 | /* Defaults in case we won't match any line */ | 436 | str_to_match = ""; |
213 | ugid.uid = ugid.gid = 0; | 437 | |
214 | keep_matching = 0; | 438 | rule = next_rule(); |
215 | mode = 0660; | 439 | |
216 | 440 | #if ENABLE_FEATURE_MDEV_CONF | |
217 | if (ENABLE_FEATURE_MDEV_CONF | 441 | if (rule->maj >= 0) { /* @maj,min rule */ |
218 | && config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL) | 442 | if (major != rule->maj) |
219 | ) { | 443 | continue; |
220 | char *val; | 444 | if (minor < rule->min0 || minor > rule->min1) |
221 | char *str_to_match; | 445 | continue; |
222 | regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP]; | 446 | memset(off, 0, sizeof(off)); |
223 | 447 | goto rule_matches; | |
224 | val = tokens[0]; | 448 | } |
225 | keep_matching = ('-' == val[0]); | 449 | if (rule->envvar) { /* $envvar=regex rule */ |
226 | val += keep_matching; /* swallow leading dash */ | 450 | str_to_match = getenv(rule->envvar); |
227 | 451 | dbg("getenv('%s'):'%s'", rule->envvar, str_to_match); | |
228 | /* Match against either "subsystem/device_name" | 452 | if (!str_to_match) |
229 | * or "device_name" alone */ | 453 | continue; |
230 | str_to_match = strchr(val, '/') ? path : device_name; | 454 | } else { |
231 | 455 | /* regex to match [subsystem/]device_name */ | |
232 | /* Fields: regex uid:gid mode [alias] [cmd] */ | 456 | str_to_match = (rule->regex_has_slash ? path : device_name); |
233 | 457 | } | |
234 | if (val[0] == '@') { | 458 | |
235 | /* @major,minor[-minor2] */ | 459 | if (rule->regex_compiled) { |
236 | /* (useful when name is ambiguous: | 460 | int regex_match = regexec(&rule->match, str_to_match, ARRAY_SIZE(off), off, 0); |
237 | * "/sys/class/usb/lp0" and | 461 | dbg("regex_match for '%s':%d", str_to_match, regex_match); |
238 | * "/sys/class/printer/lp0") */ | 462 | //bb_error_msg("matches:"); |
239 | int cmaj, cmin0, cmin1, sc; | 463 | //for (int i = 0; i < ARRAY_SIZE(off); i++) { |
240 | if (major < 0) | 464 | // if (off[i].rm_so < 0) continue; |
241 | continue; /* no dev, no match */ | 465 | // bb_error_msg("match %d: '%.*s'\n", i, |
242 | sc = sscanf(val, "@%u,%u-%u", &cmaj, &cmin0, &cmin1); | 466 | // (int)(off[i].rm_eo - off[i].rm_so), |
243 | if (sc < 1 | 467 | // device_name + off[i].rm_so); |
244 | || major != cmaj | 468 | //} |
245 | || (sc == 2 && minor != cmin0) | 469 | |
246 | || (sc == 3 && (minor < cmin0 || minor > cmin1)) | 470 | if (regex_match != 0 |
247 | ) { | 471 | /* regexec returns whole pattern as "range" 0 */ |
248 | continue; /* this line doesn't match */ | 472 | || off[0].rm_so != 0 |
249 | } | 473 | || (int)off[0].rm_eo != (int)strlen(str_to_match) |
250 | goto line_matches; | 474 | ) { |
251 | } | 475 | continue; /* this rule doesn't match */ |
252 | if (val[0] == '$') { | ||
253 | /* regex to match an environment variable */ | ||
254 | char *eq = strchr(++val, '='); | ||
255 | if (!eq) | ||
256 | continue; | ||
257 | *eq = '\0'; | ||
258 | str_to_match = getenv(val); | ||
259 | if (!str_to_match) | ||
260 | continue; | ||
261 | str_to_match -= strlen(val) + 1; | ||
262 | *eq = '='; | ||
263 | } | 476 | } |
264 | /* else: regex to match [subsystem/]device_name */ | 477 | } |
265 | 478 | /* else: it's final implicit "match-all" rule */ | |
266 | { | 479 | #endif |
267 | regex_t match; | 480 | |
268 | int result; | 481 | rule_matches: |
269 | 482 | dbg("rule matched"); | |
270 | xregcomp(&match, val, REG_EXTENDED); | 483 | |
271 | result = regexec(&match, str_to_match, ARRAY_SIZE(off), off, 0); | 484 | /* Build alias name */ |
272 | regfree(&match); | 485 | alias = NULL; |
273 | //bb_error_msg("matches:"); | 486 | if (ENABLE_FEATURE_MDEV_RENAME && rule->ren_mov) { |
274 | //for (int i = 0; i < ARRAY_SIZE(off); i++) { | 487 | aliaslink = rule->ren_mov[0]; |
275 | // if (off[i].rm_so < 0) continue; | 488 | if (aliaslink == '!') { |
276 | // bb_error_msg("match %d: '%.*s'\n", i, | 489 | /* "!": suppress node creation/deletion */ |
277 | // (int)(off[i].rm_eo - off[i].rm_so), | 490 | major = -2; |
278 | // device_name + off[i].rm_so); | ||
279 | //} | ||
280 | |||
281 | /* If no match, skip rest of line */ | ||
282 | /* (regexec returns whole pattern as "range" 0) */ | ||
283 | if (result | ||
284 | || off[0].rm_so | ||
285 | || ((int)off[0].rm_eo != (int)strlen(str_to_match)) | ||
286 | ) { | ||
287 | continue; /* this line doesn't match */ | ||
288 | } | ||
289 | } | 491 | } |
290 | line_matches: | 492 | else if (aliaslink == '>' || aliaslink == '=') { |
291 | /* This line matches. Stop parsing after parsing | 493 | if (ENABLE_FEATURE_MDEV_RENAME_REGEXP) { |
292 | * the rest the line unless keep_matching == 1 */ | 494 | char *s; |
293 | 495 | char *p; | |
294 | /* 2nd field: uid:gid - device ownership */ | 496 | unsigned n; |
295 | if (get_uidgid(&ugid, tokens[1], /*allow_numeric:*/ 1) == 0) | 497 | |
296 | bb_error_msg("unknown user/group %s on line %d", tokens[1], parser->lineno); | 498 | /* substitute %1..9 with off[1..9], if any */ |
297 | 499 | n = 0; | |
298 | /* 3rd field: mode - device permissions */ | 500 | s = rule->ren_mov; |
299 | bb_parse_mode(tokens[2], &mode); | 501 | while (*s) |
300 | 502 | if (*s++ == '%') | |
301 | val = tokens[3]; | 503 | n++; |
302 | /* 4th field (opt): ">|=alias" or "!" to not create the node */ | 504 | |
303 | 505 | p = alias = xzalloc(strlen(rule->ren_mov) + n * strlen(str_to_match)); | |
304 | if (ENABLE_FEATURE_MDEV_RENAME && val) { | 506 | s = rule->ren_mov + 1; |
305 | char *a, *s, *st; | 507 | while (*s) { |
306 | 508 | *p = *s; | |
307 | a = val; | 509 | if ('%' == *s) { |
308 | s = strchrnul(val, ' '); | 510 | unsigned i = (s[1] - '0'); |
309 | st = strchrnul(val, '\t'); | 511 | if (i <= 9 && off[i].rm_so >= 0) { |
310 | if (st < s) | 512 | n = off[i].rm_eo - off[i].rm_so; |
311 | s = st; | 513 | strncpy(p, str_to_match + off[i].rm_so, n); |
312 | st = (s[0] && s[1]) ? s+1 : NULL; | 514 | p += n - 1; |
313 | 515 | s++; | |
314 | aliaslink = a[0]; | ||
315 | if (aliaslink == '!' && s == a+1) { | ||
316 | val = st; | ||
317 | /* "!": suppress node creation/deletion */ | ||
318 | major = -2; | ||
319 | } | ||
320 | else if (aliaslink == '>' || aliaslink == '=') { | ||
321 | val = st; | ||
322 | s[0] = '\0'; | ||
323 | if (ENABLE_FEATURE_MDEV_RENAME_REGEXP) { | ||
324 | char *p; | ||
325 | unsigned i, n; | ||
326 | |||
327 | /* substitute %1..9 with off[1..9], if any */ | ||
328 | n = 0; | ||
329 | s = a; | ||
330 | while (*s) | ||
331 | if (*s++ == '%') | ||
332 | n++; | ||
333 | |||
334 | p = alias = xzalloc(strlen(a) + n * strlen(str_to_match)); | ||
335 | s = a + 1; | ||
336 | while (*s) { | ||
337 | *p = *s; | ||
338 | if ('%' == *s) { | ||
339 | i = (s[1] - '0'); | ||
340 | if (i <= 9 && off[i].rm_so >= 0) { | ||
341 | n = off[i].rm_eo - off[i].rm_so; | ||
342 | strncpy(p, str_to_match + off[i].rm_so, n); | ||
343 | p += n - 1; | ||
344 | s++; | ||
345 | } | ||
346 | } | 516 | } |
347 | p++; | ||
348 | s++; | ||
349 | } | 517 | } |
350 | } else { | 518 | p++; |
351 | alias = xstrdup(a + 1); | 519 | s++; |
352 | } | 520 | } |
521 | } else { | ||
522 | alias = xstrdup(rule->ren_mov + 1); | ||
353 | } | 523 | } |
354 | } | 524 | } |
525 | } | ||
526 | dbg("alias:'%s'", alias); | ||
355 | 527 | ||
356 | if (ENABLE_FEATURE_MDEV_EXEC && val) { | 528 | command = NULL; |
357 | const char *s = "$@*"; | 529 | IF_FEATURE_MDEV_EXEC(command = rule->r_cmd;) |
358 | const char *s2 = strchr(s, val[0]); | 530 | if (command) { |
359 | 531 | const char *s = "$@*"; | |
360 | if (!s2) { | 532 | const char *s2 = strchr(s, command[0]); |
361 | bb_error_msg("bad line %u", parser->lineno); | ||
362 | if (ENABLE_FEATURE_MDEV_RENAME) | ||
363 | free(alias); | ||
364 | continue; | ||
365 | } | ||
366 | 533 | ||
367 | /* Are we running this command now? | 534 | /* Are we running this command now? |
368 | * Run $cmd on delete, @cmd on create, *cmd on both | 535 | * Run $cmd on delete, @cmd on create, *cmd on both |
536 | */ | ||
537 | if (s2 - s != delete) { | ||
538 | /* We are here if: '*', | ||
539 | * or: '@' and delete = 0, | ||
540 | * or: '$' and delete = 1 | ||
369 | */ | 541 | */ |
370 | if (s2 - s != delete) { | 542 | command++; |
371 | /* We are here if: '*', | 543 | } else { |
372 | * or: '@' and delete = 0, | 544 | command = NULL; |
373 | * or: '$' and delete = 1 | ||
374 | */ | ||
375 | command = xstrdup(val + 1); | ||
376 | } | ||
377 | } | 545 | } |
378 | } | 546 | } |
379 | 547 | dbg("command:'%s'", command); | |
380 | /* End of field parsing */ | ||
381 | 548 | ||
382 | /* "Execute" the line we found */ | 549 | /* "Execute" the line we found */ |
383 | { | 550 | node_name = device_name; |
384 | const char *node_name; | 551 | if (ENABLE_FEATURE_MDEV_RENAME && alias) { |
385 | 552 | node_name = alias = build_alias(alias, device_name); | |
386 | node_name = device_name; | 553 | dbg("alias2:'%s'", alias); |
387 | if (ENABLE_FEATURE_MDEV_RENAME && alias) | 554 | } |
388 | node_name = alias = build_alias(alias, device_name); | ||
389 | |||
390 | if (!delete && major >= 0) { | ||
391 | if (mknod(node_name, mode | type, makedev(major, minor)) && errno != EEXIST) | ||
392 | bb_perror_msg("can't create '%s'", node_name); | ||
393 | if (major == G.root_major && minor == G.root_minor) | ||
394 | symlink(node_name, "root"); | ||
395 | if (ENABLE_FEATURE_MDEV_CONF) { | ||
396 | chmod(node_name, mode); | ||
397 | chown(node_name, ugid.uid, ugid.gid); | ||
398 | } | ||
399 | if (ENABLE_FEATURE_MDEV_RENAME && alias) { | ||
400 | if (aliaslink == '>') | ||
401 | symlink(node_name, device_name); | ||
402 | } | ||
403 | } | ||
404 | 555 | ||
405 | if (ENABLE_FEATURE_MDEV_EXEC && command) { | 556 | if (!delete && major >= 0) { |
406 | /* setenv will leak memory, use putenv/unsetenv/free */ | 557 | dbg("mknod('%s',%o,(%d,%d))", node_name, rule->mode | type, major, minor); |
407 | char *s = xasprintf("%s=%s", "MDEV", node_name); | 558 | if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST) |
408 | char *s1 = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); | 559 | bb_perror_msg("can't create '%s'", node_name); |
409 | putenv(s); | 560 | if (major == G.root_major && minor == G.root_minor) |
410 | putenv(s1); | 561 | symlink(node_name, "root"); |
411 | if (system(command) == -1) | 562 | if (ENABLE_FEATURE_MDEV_CONF) { |
412 | bb_perror_msg("can't run '%s'", command); | 563 | chmod(node_name, rule->mode); |
413 | bb_unsetenv_and_free(s1); | 564 | chown(node_name, rule->ugid.uid, rule->ugid.gid); |
414 | bb_unsetenv_and_free(s); | ||
415 | free(command); | ||
416 | } | 565 | } |
417 | 566 | if (ENABLE_FEATURE_MDEV_RENAME && alias) { | |
418 | if (delete && major >= -1) { | 567 | if (aliaslink == '>') |
419 | if (ENABLE_FEATURE_MDEV_RENAME && alias) { | 568 | symlink(node_name, device_name); |
420 | if (aliaslink == '>') | ||
421 | unlink(device_name); | ||
422 | } | ||
423 | unlink(node_name); | ||
424 | } | 569 | } |
570 | } | ||
571 | |||
572 | if (ENABLE_FEATURE_MDEV_EXEC && command) { | ||
573 | /* setenv will leak memory, use putenv/unsetenv/free */ | ||
574 | char *s = xasprintf("%s=%s", "MDEV", node_name); | ||
575 | char *s1 = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); | ||
576 | putenv(s); | ||
577 | putenv(s1); | ||
578 | if (system(command) == -1) | ||
579 | bb_perror_msg("can't run '%s'", command); | ||
580 | bb_unsetenv_and_free(s1); | ||
581 | bb_unsetenv_and_free(s); | ||
582 | } | ||
425 | 583 | ||
426 | if (ENABLE_FEATURE_MDEV_RENAME) | 584 | if (delete && major >= -1) { |
427 | free(alias); | 585 | if (ENABLE_FEATURE_MDEV_RENAME && alias) { |
586 | if (aliaslink == '>') | ||
587 | unlink(device_name); | ||
588 | } | ||
589 | unlink(node_name); | ||
428 | } | 590 | } |
429 | 591 | ||
592 | if (ENABLE_FEATURE_MDEV_RENAME) | ||
593 | free(alias); | ||
594 | |||
430 | /* We found matching line. | 595 | /* We found matching line. |
431 | * Stop unless it was prefixed with '-' */ | 596 | * Stop unless it was prefixed with '-' |
432 | if (ENABLE_FEATURE_MDEV_CONF && !keep_matching) | 597 | */ |
598 | if (!ENABLE_FEATURE_MDEV_CONF || !rule->keep_matching) | ||
433 | break; | 599 | break; |
600 | } /* for (;;) */ | ||
434 | 601 | ||
435 | /* end of "while line is read from /etc/mdev.conf" */ | ||
436 | } while (ENABLE_FEATURE_MDEV_CONF); | ||
437 | |||
438 | if (ENABLE_FEATURE_MDEV_CONF) | ||
439 | config_close(parser); | ||
440 | free(subsystem_slash_devname); | 602 | free(subsystem_slash_devname); |
441 | } | 603 | } |
442 | 604 | ||
@@ -541,6 +703,12 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
541 | { | 703 | { |
542 | RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); | 704 | RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); |
543 | 705 | ||
706 | INIT_G(); | ||
707 | |||
708 | #if ENABLE_FEATURE_MDEV_CONF | ||
709 | G.filename = "/etc/mdev.conf"; | ||
710 | #endif | ||
711 | |||
544 | /* We can be called as hotplug helper */ | 712 | /* We can be called as hotplug helper */ |
545 | /* Kernel cannot provide suitable stdio fds for us, do it ourself */ | 713 | /* Kernel cannot provide suitable stdio fds for us, do it ourself */ |
546 | bb_sanitize_stdio(); | 714 | bb_sanitize_stdio(); |
@@ -556,6 +724,10 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
556 | */ | 724 | */ |
557 | struct stat st; | 725 | struct stat st; |
558 | 726 | ||
727 | #if ENABLE_FEATURE_MDEV_CONF | ||
728 | /* Same as xrealloc_vector(NULL, 4, 0): */ | ||
729 | G.rule_vec = xzalloc((1 << 4) * sizeof(*G.rule_vec)); | ||
730 | #endif | ||
559 | xstat("/", &st); | 731 | xstat("/", &st); |
560 | G.root_major = major(st.st_dev); | 732 | G.root_major = major(st.st_dev); |
561 | G.root_minor = minor(st.st_dev); | 733 | G.root_minor = minor(st.st_dev); |
diff --git a/util-linux/mount.c b/util-linux/mount.c index 05e532cda..f94b6e643 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -38,7 +38,7 @@ | |||
38 | //usage: ) | 38 | //usage: ) |
39 | //usage: "\n -r Read-only mount" | 39 | //usage: "\n -r Read-only mount" |
40 | //usage: "\n -w Read-write mount (default)" | 40 | //usage: "\n -w Read-write mount (default)" |
41 | //usage: "\n -t FSTYPE Filesystem type" | 41 | //usage: "\n -t FSTYPE[,...] Filesystem type(s)" |
42 | //usage: "\n -O OPT Mount only filesystems with option OPT (-a only)" | 42 | //usage: "\n -O OPT Mount only filesystems with option OPT (-a only)" |
43 | //usage: "\n-o OPT:" | 43 | //usage: "\n-o OPT:" |
44 | //usage: IF_FEATURE_MOUNT_LOOP( | 44 | //usage: IF_FEATURE_MOUNT_LOOP( |
@@ -339,6 +339,7 @@ enum { GETMNTENT_BUFSIZE = COMMON_BUFSIZE - offsetof(struct globals, getmntent_b | |||
339 | #endif | 339 | #endif |
340 | #define fslist (G.fslist ) | 340 | #define fslist (G.fslist ) |
341 | #define getmntent_buf (G.getmntent_buf ) | 341 | #define getmntent_buf (G.getmntent_buf ) |
342 | #define INIT_G() do { } while (0) | ||
342 | 343 | ||
343 | #if ENABLE_FEATURE_MTAB_SUPPORT | 344 | #if ENABLE_FEATURE_MTAB_SUPPORT |
344 | /* | 345 | /* |
@@ -521,12 +522,13 @@ static llist_t *get_block_backed_filesystems(void) | |||
521 | 522 | ||
522 | while ((buf = xmalloc_fgetline(f)) != NULL) { | 523 | while ((buf = xmalloc_fgetline(f)) != NULL) { |
523 | if (strncmp(buf, "nodev", 5) == 0 && isspace(buf[5])) | 524 | if (strncmp(buf, "nodev", 5) == 0 && isspace(buf[5])) |
524 | continue; | 525 | goto next; |
525 | fs = skip_whitespace(buf); | 526 | fs = skip_whitespace(buf); |
526 | if (*fs == '#' || *fs == '*' || !*fs) | 527 | if (*fs == '#' || *fs == '*' || !*fs) |
527 | continue; | 528 | goto next; |
528 | 529 | ||
529 | llist_add_to_end(&list, xstrdup(fs)); | 530 | llist_add_to_end(&list, xstrdup(fs)); |
531 | next: | ||
530 | free(buf); | 532 | free(buf); |
531 | } | 533 | } |
532 | if (ENABLE_FEATURE_CLEAN_UP) fclose(f); | 534 | if (ENABLE_FEATURE_CLEAN_UP) fclose(f); |
@@ -1809,7 +1811,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
1809 | if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { | 1811 | if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { |
1810 | loopFile = bb_simplify_path(mp->mnt_fsname); | 1812 | loopFile = bb_simplify_path(mp->mnt_fsname); |
1811 | mp->mnt_fsname = NULL; // will receive malloced loop dev name | 1813 | mp->mnt_fsname = NULL; // will receive malloced loop dev name |
1812 | if (set_loop(&mp->mnt_fsname, loopFile, 0) < 0) { | 1814 | if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ 0) < 0) { |
1813 | if (errno == EPERM || errno == EACCES) | 1815 | if (errno == EPERM || errno == EACCES) |
1814 | bb_error_msg(bb_msg_perm_denied_are_you_root); | 1816 | bb_error_msg(bb_msg_perm_denied_are_you_root); |
1815 | else | 1817 | else |
@@ -1825,7 +1827,16 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
1825 | // If we know the fstype (or don't need to), jump straight | 1827 | // If we know the fstype (or don't need to), jump straight |
1826 | // to the actual mount. | 1828 | // to the actual mount. |
1827 | if (mp->mnt_type || (vfsflags & (MS_REMOUNT | MS_BIND | MS_MOVE))) { | 1829 | if (mp->mnt_type || (vfsflags & (MS_REMOUNT | MS_BIND | MS_MOVE))) { |
1828 | rc = mount_it_now(mp, vfsflags, filteropts); | 1830 | char *next; |
1831 | for (;;) { | ||
1832 | next = mp->mnt_type ? strchr(mp->mnt_type, ',') : NULL; | ||
1833 | if (next) | ||
1834 | *next = '\0'; | ||
1835 | rc = mount_it_now(mp, vfsflags, filteropts); | ||
1836 | if (rc == 0 || !next) | ||
1837 | break; | ||
1838 | mp->mnt_type = next + 1; | ||
1839 | } | ||
1829 | } else { | 1840 | } else { |
1830 | // Loop through filesystem types until mount succeeds | 1841 | // Loop through filesystem types until mount succeeds |
1831 | // or we run out | 1842 | // or we run out |
@@ -1842,7 +1853,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
1842 | for (fl = fslist; fl; fl = fl->link) { | 1853 | for (fl = fslist; fl; fl = fl->link) { |
1843 | mp->mnt_type = fl->data; | 1854 | mp->mnt_type = fl->data; |
1844 | rc = mount_it_now(mp, vfsflags, filteropts); | 1855 | rc = mount_it_now(mp, vfsflags, filteropts); |
1845 | if (!rc) | 1856 | if (rc == 0) |
1846 | break; | 1857 | break; |
1847 | } | 1858 | } |
1848 | } | 1859 | } |
@@ -1944,6 +1955,8 @@ int mount_main(int argc UNUSED_PARAM, char **argv) | |||
1944 | 1955 | ||
1945 | IF_DESKTOP(int nonroot = ) sanitize_env_if_suid(); | 1956 | IF_DESKTOP(int nonroot = ) sanitize_env_if_suid(); |
1946 | 1957 | ||
1958 | INIT_G(); | ||
1959 | |||
1947 | // Parse long options, like --bind and --move. Note that -o option | 1960 | // Parse long options, like --bind and --move. Note that -o option |
1948 | // and --option are synonymous. Yes, this means --remount,rw works. | 1961 | // and --option are synonymous. Yes, this means --remount,rw works. |
1949 | for (i = j = 1; argv[i]; i++) { | 1962 | for (i = j = 1; argv[i]; i++) { |
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index 43ddb4031..54867ec36 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include "libbb.h" | 25 | #include "libbb.h" |
26 | #include <mntent.h> | 26 | #include <mntent.h> |
27 | #include <sys/swap.h> | ||
28 | #ifndef __BIONIC__ | 27 | #ifndef __BIONIC__ |
29 | # include <sys/swap.h> | 28 | # include <sys/swap.h> |
30 | #endif | 29 | #endif |
@@ -48,6 +47,7 @@ struct globals { | |||
48 | #else | 47 | #else |
49 | #define g_flags 0 | 48 | #define g_flags 0 |
50 | #endif | 49 | #endif |
50 | #define INIT_G() do { } while (0) | ||
51 | 51 | ||
52 | static int swap_enable_disable(char *device) | 52 | static int swap_enable_disable(char *device) |
53 | { | 53 | { |
@@ -111,10 +111,13 @@ int swap_on_off_main(int argc UNUSED_PARAM, char **argv) | |||
111 | { | 111 | { |
112 | int ret; | 112 | int ret; |
113 | 113 | ||
114 | INIT_G(); | ||
115 | |||
114 | #if !ENABLE_FEATURE_SWAPON_PRI | 116 | #if !ENABLE_FEATURE_SWAPON_PRI |
115 | ret = getopt32(argv, "a"); | 117 | ret = getopt32(argv, "a"); |
116 | #else | 118 | #else |
117 | opt_complementary = "p+"; | 119 | if (applet_name[5] == 'n') |
120 | opt_complementary = "p+"; | ||
118 | ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags); | 121 | ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags); |
119 | 122 | ||
120 | if (ret & 2) { // -p | 123 | if (ret & 2) { // -p |