diff options
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/Config.src | 15 | ||||
-rw-r--r-- | libbb/Kbuild.src | 6 | ||||
-rw-r--r-- | libbb/appletlib.c | 2 | ||||
-rw-r--r-- | libbb/bb_askpass.c | 22 | ||||
-rw-r--r-- | libbb/getpty.c | 18 | ||||
-rw-r--r-- | libbb/hash_md5_sha.c | 32 | ||||
-rw-r--r-- | libbb/hash_md5prime.c | 26 | ||||
-rw-r--r-- | libbb/inet_cksum.c | 36 | ||||
-rw-r--r-- | libbb/lineedit.c | 110 | ||||
-rw-r--r-- | libbb/loop.c | 10 | ||||
-rw-r--r-- | libbb/match_fstype.c | 4 | ||||
-rw-r--r-- | libbb/percent_decode.c | 69 | ||||
-rw-r--r-- | libbb/procps.c | 34 | ||||
-rw-r--r-- | libbb/read_key.c | 11 | ||||
-rw-r--r-- | libbb/read_printf.c | 2 | ||||
-rw-r--r-- | libbb/udp_io.c | 2 | ||||
-rw-r--r-- | libbb/uuencode.c | 155 | ||||
-rw-r--r-- | libbb/vdprintf.c | 4 |
18 files changed, 436 insertions, 122 deletions
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 |