diff options
author | Ron Yorston <rmy@pobox.com> | 2017-01-08 08:56:43 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2017-01-08 08:56:43 +0000 |
commit | 3ef86d069577b8a44ebe3aa890c6e97ea31d0d56 (patch) | |
tree | 064587c9b2080dba963bf8d93861b8019cb306ed | |
parent | c66975af0b5335b9cdd156206767756237bd814b (diff) | |
parent | 86584e134eec1a81298149f8c04c77727f6dccb9 (diff) | |
download | busybox-w32-3ef86d069577b8a44ebe3aa890c6e97ea31d0d56.tar.gz busybox-w32-3ef86d069577b8a44ebe3aa890c6e97ea31d0d56.tar.bz2 busybox-w32-3ef86d069577b8a44ebe3aa890c6e97ea31d0d56.zip |
Merge branch 'busybox' into merge
-rwxr-xr-x | applets/usage_compressed | 3 | ||||
-rw-r--r-- | archival/unzip.c | 286 | ||||
-rw-r--r-- | libbb/appletlib.c | 26 | ||||
-rw-r--r-- | modutils/modprobe-small.c | 4 | ||||
-rw-r--r-- | modutils/modutils.c | 16 | ||||
-rw-r--r-- | networking/ntpd.c | 73 | ||||
-rw-r--r-- | networking/udhcp/Config.src | 54 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 2 | ||||
-rw-r--r-- | shell/Config.src | 27 | ||||
-rw-r--r-- | shell/ash.c | 18 | ||||
-rw-r--r-- | shell/ash_test/ash-redir/redir_leak.right | 6 | ||||
-rwxr-xr-x | shell/ash_test/ash-redir/redir_leak.tests | 10 | ||||
-rw-r--r-- | shell/hush_test/hush-redir/redir_leak.right | 6 | ||||
-rwxr-xr-x | shell/hush_test/hush-redir/redir_leak.tests | 10 | ||||
-rwxr-xr-x | testsuite/unzip.tests | 6 |
15 files changed, 337 insertions, 210 deletions
diff --git a/applets/usage_compressed b/applets/usage_compressed index 186fcde77..36fc2a007 100755 --- a/applets/usage_compressed +++ b/applets/usage_compressed | |||
@@ -36,6 +36,9 @@ echo '' | |||
36 | #0000040 114 105 135 040 133 055 141 040 101 103 124 111 117 116 106 111 | 36 | #0000040 114 105 135 040 133 055 141 040 101 103 124 111 117 116 106 111 |
37 | # 042514 020135 026533 020141 041501 044524 047117 044506 | 37 | # 042514 020135 026533 020141 041501 044524 047117 044506 |
38 | 38 | ||
39 | echo "#define UNPACKED_USAGE_LENGTH `$loc/usage | wc -c`" | ||
40 | echo | ||
41 | |||
39 | echo '#define PACKED_USAGE \' | 42 | echo '#define PACKED_USAGE \' |
40 | ## Breaks on big-endian systems! | 43 | ## Breaks on big-endian systems! |
41 | ## # Extra effort to avoid using "od -t x1": -t is not available | 44 | ## # Extra effort to avoid using "od -t x1": -t is not available |
diff --git a/archival/unzip.c b/archival/unzip.c index 27adb3420..7029f66c3 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * TODO | 16 | * TODO |
17 | * Zip64 + other methods | 17 | * Zip64 + other methods |
18 | */ | 18 | */ |
19 | |||
20 | //config:config UNZIP | 19 | //config:config UNZIP |
21 | //config: bool "unzip" | 20 | //config: bool "unzip" |
22 | //config: default y | 21 | //config: default y |
@@ -24,8 +23,17 @@ | |||
24 | //config: unzip will list or extract files from a ZIP archive, | 23 | //config: unzip will list or extract files from a ZIP archive, |
25 | //config: commonly found on DOS/WIN systems. The default behavior | 24 | //config: commonly found on DOS/WIN systems. The default behavior |
26 | //config: (with no options) is to extract the archive into the | 25 | //config: (with no options) is to extract the archive into the |
27 | //config: current directory. Use the `-d' option to extract to a | 26 | //config: current directory. |
28 | //config: directory of your choice. | 27 | //config: |
28 | //config:config FEATURE_UNZIP_CDF | ||
29 | //config: bool "Read and use Central Directory data" | ||
30 | //config: default y | ||
31 | //config: depends on UNZIP | ||
32 | //config: help | ||
33 | //config: If you know that you only need to deal with simple | ||
34 | //config: ZIP files without deleted/updated files, SFX archives etc, | ||
35 | //config: you can reduce code size by unselecting this option. | ||
36 | //config: To support less trivial ZIPs, say Y. | ||
29 | 37 | ||
30 | //applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP)) | 38 | //applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP)) |
31 | //kbuild:lib-$(CONFIG_UNZIP) += unzip.o | 39 | //kbuild:lib-$(CONFIG_UNZIP) += unzip.o |
@@ -83,30 +91,20 @@ typedef union { | |||
83 | uint32_t ucmpsize PACKED; /* 18-21 */ | 91 | uint32_t ucmpsize PACKED; /* 18-21 */ |
84 | uint16_t filename_len; /* 22-23 */ | 92 | uint16_t filename_len; /* 22-23 */ |
85 | uint16_t extra_len; /* 24-25 */ | 93 | uint16_t extra_len; /* 24-25 */ |
94 | /* filename follows (not NUL terminated) */ | ||
95 | /* extra field follows */ | ||
96 | /* data follows */ | ||
86 | } formatted PACKED; | 97 | } formatted PACKED; |
87 | } zip_header_t; /* PACKED - gcc 4.2.1 doesn't like it (spews warning) */ | 98 | } zip_header_t; /* PACKED - gcc 4.2.1 doesn't like it (spews warning) */ |
88 | 99 | ||
89 | /* Check the offset of the last element, not the length. This leniency | 100 | #define FIX_ENDIANNESS_ZIP(zip_header) \ |
90 | * allows for poor packing, whereby the overall struct may be too long, | 101 | do { if (BB_BIG_ENDIAN) { \ |
91 | * even though the elements are all in the right place. | ||
92 | */ | ||
93 | struct BUG_zip_header_must_be_26_bytes { | ||
94 | char BUG_zip_header_must_be_26_bytes[ | ||
95 | offsetof(zip_header_t, formatted.extra_len) + 2 | ||
96 | == ZIP_HEADER_LEN ? 1 : -1]; | ||
97 | }; | ||
98 | |||
99 | #define FIX_ENDIANNESS_ZIP(zip_header) do { \ | ||
100 | (zip_header).formatted.version = SWAP_LE16((zip_header).formatted.version ); \ | ||
101 | (zip_header).formatted.method = SWAP_LE16((zip_header).formatted.method ); \ | ||
102 | (zip_header).formatted.modtime = SWAP_LE16((zip_header).formatted.modtime ); \ | ||
103 | (zip_header).formatted.moddate = SWAP_LE16((zip_header).formatted.moddate ); \ | ||
104 | (zip_header).formatted.crc32 = SWAP_LE32((zip_header).formatted.crc32 ); \ | 102 | (zip_header).formatted.crc32 = SWAP_LE32((zip_header).formatted.crc32 ); \ |
105 | (zip_header).formatted.cmpsize = SWAP_LE32((zip_header).formatted.cmpsize ); \ | 103 | (zip_header).formatted.cmpsize = SWAP_LE32((zip_header).formatted.cmpsize ); \ |
106 | (zip_header).formatted.ucmpsize = SWAP_LE32((zip_header).formatted.ucmpsize ); \ | 104 | (zip_header).formatted.ucmpsize = SWAP_LE32((zip_header).formatted.ucmpsize ); \ |
107 | (zip_header).formatted.filename_len = SWAP_LE16((zip_header).formatted.filename_len); \ | 105 | (zip_header).formatted.filename_len = SWAP_LE16((zip_header).formatted.filename_len); \ |
108 | (zip_header).formatted.extra_len = SWAP_LE16((zip_header).formatted.extra_len ); \ | 106 | (zip_header).formatted.extra_len = SWAP_LE16((zip_header).formatted.extra_len ); \ |
109 | } while (0) | 107 | }} while (0) |
110 | 108 | ||
111 | #define CDF_HEADER_LEN 42 | 109 | #define CDF_HEADER_LEN 42 |
112 | 110 | ||
@@ -118,8 +116,8 @@ typedef union { | |||
118 | uint16_t version_needed; /* 2-3 */ | 116 | uint16_t version_needed; /* 2-3 */ |
119 | uint16_t cdf_flags; /* 4-5 */ | 117 | uint16_t cdf_flags; /* 4-5 */ |
120 | uint16_t method; /* 6-7 */ | 118 | uint16_t method; /* 6-7 */ |
121 | uint16_t mtime; /* 8-9 */ | 119 | uint16_t modtime; /* 8-9 */ |
122 | uint16_t mdate; /* 10-11 */ | 120 | uint16_t moddate; /* 10-11 */ |
123 | uint32_t crc32; /* 12-15 */ | 121 | uint32_t crc32; /* 12-15 */ |
124 | uint32_t cmpsize; /* 16-19 */ | 122 | uint32_t cmpsize; /* 16-19 */ |
125 | uint32_t ucmpsize; /* 20-23 */ | 123 | uint32_t ucmpsize; /* 20-23 */ |
@@ -130,27 +128,27 @@ typedef union { | |||
130 | uint16_t internal_file_attributes; /* 32-33 */ | 128 | uint16_t internal_file_attributes; /* 32-33 */ |
131 | uint32_t external_file_attributes PACKED; /* 34-37 */ | 129 | uint32_t external_file_attributes PACKED; /* 34-37 */ |
132 | uint32_t relative_offset_of_local_header PACKED; /* 38-41 */ | 130 | uint32_t relative_offset_of_local_header PACKED; /* 38-41 */ |
131 | /* filename follows (not NUL terminated) */ | ||
132 | /* extra field follows */ | ||
133 | /* comment follows */ | ||
133 | } formatted PACKED; | 134 | } formatted PACKED; |
134 | } cdf_header_t; | 135 | } cdf_header_t; |
135 | 136 | ||
136 | struct BUG_cdf_header_must_be_42_bytes { | 137 | #define FIX_ENDIANNESS_CDF(cdf_header) \ |
137 | char BUG_cdf_header_must_be_42_bytes[ | 138 | do { if (BB_BIG_ENDIAN) { \ |
138 | offsetof(cdf_header_t, formatted.relative_offset_of_local_header) + 4 | 139 | (cdf_header).formatted.version_made_by = SWAP_LE16((cdf_header).formatted.version_made_by); \ |
139 | == CDF_HEADER_LEN ? 1 : -1]; | 140 | (cdf_header).formatted.version_needed = SWAP_LE16((cdf_header).formatted.version_needed); \ |
140 | }; | 141 | (cdf_header).formatted.method = SWAP_LE16((cdf_header).formatted.method ); \ |
141 | 142 | (cdf_header).formatted.modtime = SWAP_LE16((cdf_header).formatted.modtime ); \ | |
142 | #define FIX_ENDIANNESS_CDF(cdf_header) do { \ | 143 | (cdf_header).formatted.moddate = SWAP_LE16((cdf_header).formatted.moddate ); \ |
143 | (cdf_header).formatted.crc32 = SWAP_LE32((cdf_header).formatted.crc32 ); \ | 144 | (cdf_header).formatted.crc32 = SWAP_LE32((cdf_header).formatted.crc32 ); \ |
144 | (cdf_header).formatted.cmpsize = SWAP_LE32((cdf_header).formatted.cmpsize ); \ | 145 | (cdf_header).formatted.cmpsize = SWAP_LE32((cdf_header).formatted.cmpsize ); \ |
145 | (cdf_header).formatted.ucmpsize = SWAP_LE32((cdf_header).formatted.ucmpsize ); \ | 146 | (cdf_header).formatted.ucmpsize = SWAP_LE32((cdf_header).formatted.ucmpsize ); \ |
146 | (cdf_header).formatted.file_name_length = SWAP_LE16((cdf_header).formatted.file_name_length); \ | 147 | (cdf_header).formatted.file_name_length = SWAP_LE16((cdf_header).formatted.file_name_length); \ |
147 | (cdf_header).formatted.extra_field_length = SWAP_LE16((cdf_header).formatted.extra_field_length); \ | 148 | (cdf_header).formatted.extra_field_length = SWAP_LE16((cdf_header).formatted.extra_field_length); \ |
148 | (cdf_header).formatted.file_comment_length = SWAP_LE16((cdf_header).formatted.file_comment_length); \ | 149 | (cdf_header).formatted.file_comment_length = SWAP_LE16((cdf_header).formatted.file_comment_length); \ |
149 | IF_DESKTOP( \ | ||
150 | (cdf_header).formatted.version_made_by = SWAP_LE16((cdf_header).formatted.version_made_by); \ | ||
151 | (cdf_header).formatted.external_file_attributes = SWAP_LE32((cdf_header).formatted.external_file_attributes); \ | 150 | (cdf_header).formatted.external_file_attributes = SWAP_LE32((cdf_header).formatted.external_file_attributes); \ |
152 | ) \ | 151 | }} while (0) |
153 | } while (0) | ||
154 | 152 | ||
155 | #define CDE_HEADER_LEN 16 | 153 | #define CDE_HEADER_LEN 16 |
156 | 154 | ||
@@ -169,20 +167,38 @@ typedef union { | |||
169 | } formatted PACKED; | 167 | } formatted PACKED; |
170 | } cde_header_t; | 168 | } cde_header_t; |
171 | 169 | ||
172 | struct BUG_cde_header_must_be_16_bytes { | 170 | #define FIX_ENDIANNESS_CDE(cde_header) \ |
171 | do { if (BB_BIG_ENDIAN) { \ | ||
172 | (cde_header).formatted.cdf_offset = SWAP_LE32((cde_header).formatted.cdf_offset); \ | ||
173 | }} while (0) | ||
174 | |||
175 | struct BUG { | ||
176 | /* Check the offset of the last element, not the length. This leniency | ||
177 | * allows for poor packing, whereby the overall struct may be too long, | ||
178 | * even though the elements are all in the right place. | ||
179 | */ | ||
180 | char BUG_zip_header_must_be_26_bytes[ | ||
181 | offsetof(zip_header_t, formatted.extra_len) + 2 | ||
182 | == ZIP_HEADER_LEN ? 1 : -1]; | ||
183 | char BUG_cdf_header_must_be_42_bytes[ | ||
184 | offsetof(cdf_header_t, formatted.relative_offset_of_local_header) + 4 | ||
185 | == CDF_HEADER_LEN ? 1 : -1]; | ||
173 | char BUG_cde_header_must_be_16_bytes[ | 186 | char BUG_cde_header_must_be_16_bytes[ |
174 | sizeof(cde_header_t) == CDE_HEADER_LEN ? 1 : -1]; | 187 | sizeof(cde_header_t) == CDE_HEADER_LEN ? 1 : -1]; |
175 | }; | 188 | }; |
176 | 189 | ||
177 | #define FIX_ENDIANNESS_CDE(cde_header) do { \ | ||
178 | (cde_header).formatted.cdf_offset = SWAP_LE32((cde_header).formatted.cdf_offset); \ | ||
179 | } while (0) | ||
180 | 190 | ||
181 | enum { zip_fd = 3 }; | 191 | enum { zip_fd = 3 }; |
182 | 192 | ||
183 | 193 | ||
184 | #if ENABLE_DESKTOP | 194 | /* This value means that we failed to find CDF */ |
195 | #define BAD_CDF_OFFSET ((uint32_t)0xffffffff) | ||
196 | |||
197 | #if !ENABLE_FEATURE_UNZIP_CDF | ||
198 | |||
199 | # define find_cdf_offset() BAD_CDF_OFFSET | ||
185 | 200 | ||
201 | #else | ||
186 | /* Seen in the wild: | 202 | /* Seen in the wild: |
187 | * Self-extracting PRO2K3XP_32.exe contains 19078464 byte zip archive, | 203 | * Self-extracting PRO2K3XP_32.exe contains 19078464 byte zip archive, |
188 | * where CDE was nearly 48 kbytes before EOF. | 204 | * where CDE was nearly 48 kbytes before EOF. |
@@ -191,25 +207,26 @@ enum { zip_fd = 3 }; | |||
191 | * To make extraction work, bumped PEEK_FROM_END from 16k to 64k. | 207 | * To make extraction work, bumped PEEK_FROM_END from 16k to 64k. |
192 | */ | 208 | */ |
193 | #define PEEK_FROM_END (64*1024) | 209 | #define PEEK_FROM_END (64*1024) |
194 | |||
195 | /* This value means that we failed to find CDF */ | ||
196 | #define BAD_CDF_OFFSET ((uint32_t)0xffffffff) | ||
197 | |||
198 | /* NB: does not preserve file position! */ | 210 | /* NB: does not preserve file position! */ |
199 | static uint32_t find_cdf_offset(void) | 211 | static uint32_t find_cdf_offset(void) |
200 | { | 212 | { |
201 | cde_header_t cde_header; | 213 | cde_header_t cde_header; |
214 | unsigned char *buf; | ||
202 | unsigned char *p; | 215 | unsigned char *p; |
203 | off_t end; | 216 | off_t end; |
204 | unsigned char *buf = xzalloc(PEEK_FROM_END); | ||
205 | uint32_t found; | 217 | uint32_t found; |
206 | 218 | ||
207 | end = xlseek(zip_fd, 0, SEEK_END); | 219 | end = lseek(zip_fd, 0, SEEK_END); |
220 | if (end == (off_t) -1) | ||
221 | return BAD_CDF_OFFSET; | ||
222 | |||
208 | end -= PEEK_FROM_END; | 223 | end -= PEEK_FROM_END; |
209 | if (end < 0) | 224 | if (end < 0) |
210 | end = 0; | 225 | end = 0; |
226 | |||
211 | dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end); | 227 | dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end); |
212 | xlseek(zip_fd, end, SEEK_SET); | 228 | xlseek(zip_fd, end, SEEK_SET); |
229 | buf = xzalloc(PEEK_FROM_END); | ||
213 | full_read(zip_fd, buf, PEEK_FROM_END); | 230 | full_read(zip_fd, buf, PEEK_FROM_END); |
214 | 231 | ||
215 | found = BAD_CDF_OFFSET; | 232 | found = BAD_CDF_OFFSET; |
@@ -254,31 +271,32 @@ static uint32_t find_cdf_offset(void) | |||
254 | 271 | ||
255 | static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) | 272 | static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) |
256 | { | 273 | { |
257 | off_t org; | 274 | uint32_t magic; |
258 | 275 | ||
259 | org = xlseek(zip_fd, 0, SEEK_CUR); | 276 | if (cdf_offset == BAD_CDF_OFFSET) |
260 | 277 | return cdf_offset; | |
261 | if (!cdf_offset) | 278 | |
262 | cdf_offset = find_cdf_offset(); | 279 | dbg("Reading CDF at 0x%x", (unsigned)cdf_offset); |
263 | 280 | xlseek(zip_fd, cdf_offset, SEEK_SET); | |
264 | if (cdf_offset != BAD_CDF_OFFSET) { | 281 | xread(zip_fd, &magic, 4); |
265 | dbg("Reading CDF at 0x%x", (unsigned)cdf_offset); | 282 | /* Central Directory End? */ |
266 | xlseek(zip_fd, cdf_offset + 4, SEEK_SET); | 283 | if (magic == ZIP_CDE_MAGIC) { |
267 | xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN); | 284 | dbg("got ZIP_CDE_MAGIC"); |
268 | FIX_ENDIANNESS_CDF(*cdf_ptr); | 285 | return 0; /* EOF */ |
269 | dbg(" file_name_length:%u extra_field_length:%u file_comment_length:%u", | ||
270 | (unsigned)cdf_ptr->formatted.file_name_length, | ||
271 | (unsigned)cdf_ptr->formatted.extra_field_length, | ||
272 | (unsigned)cdf_ptr->formatted.file_comment_length | ||
273 | ); | ||
274 | cdf_offset += 4 + CDF_HEADER_LEN | ||
275 | + cdf_ptr->formatted.file_name_length | ||
276 | + cdf_ptr->formatted.extra_field_length | ||
277 | + cdf_ptr->formatted.file_comment_length; | ||
278 | } | 286 | } |
287 | xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN); | ||
288 | |||
289 | FIX_ENDIANNESS_CDF(*cdf_ptr); | ||
290 | dbg(" file_name_length:%u extra_field_length:%u file_comment_length:%u", | ||
291 | (unsigned)cdf_ptr->formatted.file_name_length, | ||
292 | (unsigned)cdf_ptr->formatted.extra_field_length, | ||
293 | (unsigned)cdf_ptr->formatted.file_comment_length | ||
294 | ); | ||
295 | cdf_offset += 4 + CDF_HEADER_LEN | ||
296 | + cdf_ptr->formatted.file_name_length | ||
297 | + cdf_ptr->formatted.extra_field_length | ||
298 | + cdf_ptr->formatted.file_comment_length; | ||
279 | 299 | ||
280 | dbg("Returning file position to 0x%"OFF_FMT"x", org); | ||
281 | xlseek(zip_fd, org, SEEK_SET); | ||
282 | return cdf_offset; | 300 | return cdf_offset; |
283 | }; | 301 | }; |
284 | #endif | 302 | #endif |
@@ -327,6 +345,7 @@ static void unzip_extract(zip_header_t *zip_header, int dst_fd) | |||
327 | bb_error_msg("bad length"); | 345 | bb_error_msg("bad length"); |
328 | } | 346 | } |
329 | } | 347 | } |
348 | /* TODO? method 12: bzip2, method 14: LZMA */ | ||
330 | } | 349 | } |
331 | 350 | ||
332 | static void my_fgets80(char *buf80) | 351 | static void my_fgets80(char *buf80) |
@@ -342,15 +361,12 @@ int unzip_main(int argc, char **argv) | |||
342 | { | 361 | { |
343 | enum { O_PROMPT, O_NEVER, O_ALWAYS }; | 362 | enum { O_PROMPT, O_NEVER, O_ALWAYS }; |
344 | 363 | ||
345 | zip_header_t zip_header; | ||
346 | smallint quiet = 0; | 364 | smallint quiet = 0; |
347 | IF_NOT_DESKTOP(const) smallint verbose = 0; | 365 | IF_NOT_FEATURE_UNZIP_CDF(const) smallint verbose = 0; |
348 | smallint listing = 0; | 366 | smallint listing = 0; |
349 | smallint overwrite = O_PROMPT; | 367 | smallint overwrite = O_PROMPT; |
350 | smallint x_opt_seen; | 368 | smallint x_opt_seen; |
351 | #if ENABLE_DESKTOP | ||
352 | uint32_t cdf_offset; | 369 | uint32_t cdf_offset; |
353 | #endif | ||
354 | unsigned long total_usize; | 370 | unsigned long total_usize; |
355 | unsigned long total_size; | 371 | unsigned long total_size; |
356 | unsigned total_entries; | 372 | unsigned total_entries; |
@@ -433,7 +449,7 @@ int unzip_main(int argc, char **argv) | |||
433 | break; | 449 | break; |
434 | 450 | ||
435 | case 'v': /* Verbose list */ | 451 | case 'v': /* Verbose list */ |
436 | IF_DESKTOP(verbose++;) | 452 | IF_FEATURE_UNZIP_CDF(verbose++;) |
437 | listing = 1; | 453 | listing = 1; |
438 | break; | 454 | break; |
439 | 455 | ||
@@ -548,78 +564,102 @@ int unzip_main(int argc, char **argv) | |||
548 | total_usize = 0; | 564 | total_usize = 0; |
549 | total_size = 0; | 565 | total_size = 0; |
550 | total_entries = 0; | 566 | total_entries = 0; |
551 | #if ENABLE_DESKTOP | 567 | cdf_offset = find_cdf_offset(); /* try to seek to the end, find CDE and CDF start */ |
552 | cdf_offset = 0; | ||
553 | #endif | ||
554 | while (1) { | 568 | while (1) { |
555 | uint32_t magic; | 569 | zip_header_t zip_header; |
556 | mode_t dir_mode = 0777; | 570 | mode_t dir_mode = 0777; |
557 | #if ENABLE_DESKTOP | 571 | #if ENABLE_FEATURE_UNZIP_CDF |
558 | mode_t file_mode = 0666; | 572 | mode_t file_mode = 0666; |
559 | #endif | 573 | #endif |
560 | 574 | ||
561 | /* Check magic number */ | 575 | if (!ENABLE_FEATURE_UNZIP_CDF || cdf_offset == BAD_CDF_OFFSET) { |
562 | xread(zip_fd, &magic, 4); | 576 | /* Normally happens when input is unseekable. |
563 | /* Central directory? It's at the end, so exit */ | 577 | * |
564 | if (magic == ZIP_CDF_MAGIC) { | 578 | * Valid ZIP file has Central Directory at the end |
565 | dbg("got ZIP_CDF_MAGIC"); | 579 | * with central directory file headers (CDFs). |
566 | break; | 580 | * After it, there is a Central Directory End structure. |
567 | } | 581 | * CDFs identify what files are in the ZIP and where |
568 | #if ENABLE_DESKTOP | 582 | * they are located. This allows ZIP readers to load |
569 | /* Data descriptor? It was a streaming file, go on */ | 583 | * the list of files without reading the entire ZIP archive. |
570 | if (magic == ZIP_DD_MAGIC) { | 584 | * ZIP files may be appended to, only files specified in |
571 | dbg("got ZIP_DD_MAGIC"); | 585 | * the CD are valid. Scanning for local file headers is |
572 | /* skip over duplicate crc32, cmpsize and ucmpsize */ | 586 | * not a correct algorithm. |
573 | unzip_skip(3 * 4); | 587 | * |
574 | continue; | 588 | * We try to do the above, and resort to "linear" reading |
575 | } | 589 | * of ZIP file only if seek failed or CDE wasn't found. |
576 | #endif | 590 | */ |
577 | if (magic != ZIP_FILEHEADER_MAGIC) | 591 | uint32_t magic; |
578 | bb_error_msg_and_die("invalid zip magic %08X", (int)magic); | ||
579 | dbg("got ZIP_FILEHEADER_MAGIC"); | ||
580 | |||
581 | /* Read the file header */ | ||
582 | xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN); | ||
583 | FIX_ENDIANNESS_ZIP(zip_header); | ||
584 | if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) { | ||
585 | bb_error_msg_and_die("unsupported method %d", zip_header.formatted.method); | ||
586 | } | ||
587 | #if !ENABLE_DESKTOP | ||
588 | if (zip_header.formatted.zip_flags & SWAP_LE16(0x0009)) { | ||
589 | bb_error_msg_and_die("zip flags 1 and 8 are not supported"); | ||
590 | } | ||
591 | #else | ||
592 | if (zip_header.formatted.zip_flags & SWAP_LE16(0x0001)) { | ||
593 | /* 0x0001 - encrypted */ | ||
594 | bb_error_msg_and_die("zip flag 1 (encryption) is not supported"); | ||
595 | } | ||
596 | 592 | ||
597 | if (cdf_offset != BAD_CDF_OFFSET) { | 593 | /* Check magic number */ |
594 | xread(zip_fd, &magic, 4); | ||
595 | /* Central directory? It's at the end, so exit */ | ||
596 | if (magic == ZIP_CDF_MAGIC) { | ||
597 | dbg("got ZIP_CDF_MAGIC"); | ||
598 | break; | ||
599 | } | ||
600 | /* Data descriptor? It was a streaming file, go on */ | ||
601 | if (magic == ZIP_DD_MAGIC) { | ||
602 | dbg("got ZIP_DD_MAGIC"); | ||
603 | /* skip over duplicate crc32, cmpsize and ucmpsize */ | ||
604 | unzip_skip(3 * 4); | ||
605 | continue; | ||
606 | } | ||
607 | if (magic != ZIP_FILEHEADER_MAGIC) | ||
608 | bb_error_msg_and_die("invalid zip magic %08X", (int)magic); | ||
609 | dbg("got ZIP_FILEHEADER_MAGIC"); | ||
610 | |||
611 | xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN); | ||
612 | FIX_ENDIANNESS_ZIP(zip_header); | ||
613 | if ((zip_header.formatted.method != 0) | ||
614 | && (zip_header.formatted.method != 8) | ||
615 | ) { | ||
616 | /* TODO? method 12: bzip2, method 14: LZMA */ | ||
617 | bb_error_msg_and_die("unsupported method %d", zip_header.formatted.method); | ||
618 | } | ||
619 | if (zip_header.formatted.zip_flags & SWAP_LE16(0x0009)) { | ||
620 | bb_error_msg_and_die("zip flags 1 and 8 are not supported"); | ||
621 | } | ||
622 | } | ||
623 | #if ENABLE_FEATURE_UNZIP_CDF | ||
624 | else { | ||
625 | /* cdf_offset is valid (and we know the file is seekable) */ | ||
598 | cdf_header_t cdf_header; | 626 | cdf_header_t cdf_header; |
599 | cdf_offset = read_next_cdf(cdf_offset, &cdf_header); | 627 | cdf_offset = read_next_cdf(cdf_offset, &cdf_header); |
600 | /* | 628 | if (cdf_offset == 0) /* EOF? */ |
601 | * Note: cdf_offset can become BAD_CDF_OFFSET after the above call. | 629 | break; |
602 | */ | 630 | # if 0 |
631 | xlseek(zip_fd, | ||
632 | SWAP_LE32(cdf_header.formatted.relative_offset_of_local_header) + 4, | ||
633 | SEEK_SET); | ||
634 | xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN); | ||
635 | FIX_ENDIANNESS_ZIP(zip_header); | ||
603 | if (zip_header.formatted.zip_flags & SWAP_LE16(0x0008)) { | 636 | if (zip_header.formatted.zip_flags & SWAP_LE16(0x0008)) { |
604 | /* 0x0008 - streaming. [u]cmpsize can be reliably gotten | 637 | /* 0x0008 - streaming. [u]cmpsize can be reliably gotten |
605 | * only from Central Directory. See unzip_doc.txt | 638 | * only from Central Directory. |
606 | */ | 639 | */ |
607 | zip_header.formatted.crc32 = cdf_header.formatted.crc32; | 640 | zip_header.formatted.crc32 = cdf_header.formatted.crc32; |
608 | zip_header.formatted.cmpsize = cdf_header.formatted.cmpsize; | 641 | zip_header.formatted.cmpsize = cdf_header.formatted.cmpsize; |
609 | zip_header.formatted.ucmpsize = cdf_header.formatted.ucmpsize; | 642 | zip_header.formatted.ucmpsize = cdf_header.formatted.ucmpsize; |
610 | } | 643 | } |
644 | # else | ||
645 | /* CDF has the same data as local header, no need to read the latter */ | ||
646 | memcpy(&zip_header.formatted.version, | ||
647 | &cdf_header.formatted.version_needed, ZIP_HEADER_LEN); | ||
648 | xlseek(zip_fd, | ||
649 | SWAP_LE32(cdf_header.formatted.relative_offset_of_local_header) + 4 + ZIP_HEADER_LEN, | ||
650 | SEEK_SET); | ||
651 | # endif | ||
611 | if ((cdf_header.formatted.version_made_by >> 8) == 3) { | 652 | if ((cdf_header.formatted.version_made_by >> 8) == 3) { |
612 | /* This archive is created on Unix */ | 653 | /* This archive is created on Unix */ |
613 | dir_mode = file_mode = (cdf_header.formatted.external_file_attributes >> 16); | 654 | dir_mode = file_mode = (cdf_header.formatted.external_file_attributes >> 16); |
614 | } | 655 | } |
615 | } | 656 | } |
616 | if (cdf_offset == BAD_CDF_OFFSET | ||
617 | && (zip_header.formatted.zip_flags & SWAP_LE16(0x0008)) | ||
618 | ) { | ||
619 | /* If it's a streaming zip, we _require_ CDF */ | ||
620 | bb_error_msg_and_die("can't find file table"); | ||
621 | } | ||
622 | #endif | 657 | #endif |
658 | |||
659 | if (zip_header.formatted.zip_flags & SWAP_LE16(0x0001)) { | ||
660 | /* 0x0001 - encrypted */ | ||
661 | bb_error_msg_and_die("zip flag 1 (encryption) is not supported"); | ||
662 | } | ||
623 | dbg("File cmpsize:0x%x extra_len:0x%x ucmpsize:0x%x", | 663 | dbg("File cmpsize:0x%x extra_len:0x%x ucmpsize:0x%x", |
624 | (unsigned)zip_header.formatted.cmpsize, | 664 | (unsigned)zip_header.formatted.cmpsize, |
625 | (unsigned)zip_header.formatted.extra_len, | 665 | (unsigned)zip_header.formatted.extra_len, |
@@ -754,7 +794,7 @@ int unzip_main(int argc, char **argv) | |||
754 | overwrite = O_ALWAYS; | 794 | overwrite = O_ALWAYS; |
755 | case 'y': /* Open file and fall into unzip */ | 795 | case 'y': /* Open file and fall into unzip */ |
756 | unzip_create_leading_dirs(dst_fn); | 796 | unzip_create_leading_dirs(dst_fn); |
757 | #if ENABLE_DESKTOP | 797 | #if ENABLE_FEATURE_UNZIP_CDF |
758 | dst_fd = xopen3(dst_fn, O_WRONLY | O_CREAT | O_TRUNC, file_mode); | 798 | dst_fd = xopen3(dst_fn, O_WRONLY | O_CREAT | O_TRUNC, file_mode); |
759 | #else | 799 | #else |
760 | dst_fd = xopen(dst_fn, O_WRONLY | O_CREAT | O_TRUNC); | 800 | dst_fd = xopen(dst_fn, O_WRONLY | O_CREAT | O_TRUNC); |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index f11384962..6732f89a9 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -52,6 +52,32 @@ | |||
52 | 52 | ||
53 | #include "usage_compressed.h" | 53 | #include "usage_compressed.h" |
54 | 54 | ||
55 | |||
56 | /* "Do not compress usage text if uncompressed text is small | ||
57 | * and we don't include bunzip2 code for other reasons" | ||
58 | * | ||
59 | * Useful for mass one-applet rebuild (bunzip2 code is ~2.7k). | ||
60 | * | ||
61 | * Unlike BUNZIP2, if FEATURE_SEAMLESS_BZ2 is on, bunzip2 code is built but | ||
62 | * still may be unused if none of the selected applets calls open_zipped() | ||
63 | * or its friends; we test for (FEATURE_SEAMLESS_BZ2 && <APPLET>) instead. | ||
64 | * For example, only if TAR and FEATURE_SEAMLESS_BZ2 are both selected, | ||
65 | * then bunzip2 code will be linked in anyway, and disabling help compression | ||
66 | * would be not optimal: | ||
67 | */ | ||
68 | #if UNPACKED_USAGE_LENGTH < 4*1024 \ | ||
69 | && !(ENABLE_FEATURE_SEAMLESS_BZ2 && ENABLE_TAR) \ | ||
70 | && !(ENABLE_FEATURE_SEAMLESS_BZ2 && ENABLE_MODPROBE) \ | ||
71 | && !(ENABLE_FEATURE_SEAMLESS_BZ2 && ENABLE_INSMOD) \ | ||
72 | && !(ENABLE_FEATURE_SEAMLESS_BZ2 && ENABLE_DEPMOD) \ | ||
73 | && !(ENABLE_FEATURE_SEAMLESS_BZ2 && ENABLE_MAN) \ | ||
74 | && !ENABLE_BUNZIP2 \ | ||
75 | && !ENABLE_BZCAT | ||
76 | # undef ENABLE_FEATURE_COMPRESS_USAGE | ||
77 | # define ENABLE_FEATURE_COMPRESS_USAGE 0 | ||
78 | #endif | ||
79 | |||
80 | |||
55 | #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE | 81 | #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE |
56 | static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; | 82 | static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; |
57 | #else | 83 | #else |
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 652ff4dfa..0fc9ea454 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
@@ -39,8 +39,8 @@ | |||
39 | #include <fnmatch.h> | 39 | #include <fnmatch.h> |
40 | #include <sys/syscall.h> | 40 | #include <sys/syscall.h> |
41 | 41 | ||
42 | extern int init_module(void *module, unsigned long len, const char *options); | 42 | #define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) |
43 | extern int delete_module(const char *module, unsigned flags); | 43 | #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) |
44 | #ifdef __NR_finit_module | 44 | #ifdef __NR_finit_module |
45 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) | 45 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) |
46 | #endif | 46 | #endif |
diff --git a/modutils/modutils.c b/modutils/modutils.c index d36caaf68..4204f06fe 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c | |||
@@ -7,17 +7,13 @@ | |||
7 | */ | 7 | */ |
8 | #include "modutils.h" | 8 | #include "modutils.h" |
9 | 9 | ||
10 | #ifdef __UCLIBC__ | 10 | #include <sys/syscall.h> |
11 | extern int init_module(void *module, unsigned long len, const char *options); | 11 | |
12 | extern int delete_module(const char *module, unsigned int flags); | 12 | #define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) |
13 | #else | 13 | #if defined(__NR_finit_module) |
14 | # include <sys/syscall.h> | 14 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) |
15 | # define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) | ||
16 | # if defined(__NR_finit_module) | ||
17 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) | ||
18 | # endif | ||
19 | # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) | ||
20 | #endif | 15 | #endif |
16 | #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) | ||
21 | 17 | ||
22 | static module_entry *helper_get_module(module_db *db, const char *module, int create) | 18 | static module_entry *helper_get_module(module_db *db, const char *module, int create) |
23 | { | 19 | { |
diff --git a/networking/ntpd.c b/networking/ntpd.c index b7fa5dce9..bfd5705fc 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -155,6 +155,7 @@ | |||
155 | #define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */ | 155 | #define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */ |
156 | #define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */ | 156 | #define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */ |
157 | #define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */ | 157 | #define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */ |
158 | #define HOSTNAME_INTERVAL 5 /* hostname lookup failed. Wait N secs for next try */ | ||
158 | 159 | ||
159 | /* Step threshold (sec). std ntpd uses 0.128. | 160 | /* Step threshold (sec). std ntpd uses 0.128. |
160 | */ | 161 | */ |
@@ -790,28 +791,20 @@ reset_peer_stats(peer_t *p, double offset) | |||
790 | VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); | 791 | VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); |
791 | } | 792 | } |
792 | 793 | ||
793 | static void | 794 | static len_and_sockaddr* |
794 | resolve_peer_hostname(peer_t *p, int loop_on_fail) | 795 | resolve_peer_hostname(peer_t *p) |
795 | { | 796 | { |
796 | len_and_sockaddr *lsa; | 797 | len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123); |
797 | 798 | if (lsa) { | |
798 | again: | 799 | free(p->p_lsa); |
799 | lsa = host2sockaddr(p->p_hostname, 123); | 800 | free(p->p_dotted); |
800 | if (!lsa) { | 801 | p->p_lsa = lsa; |
801 | /* error message already emitted by host2sockaddr() */ | 802 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); |
802 | if (!loop_on_fail) | 803 | } else { |
803 | return; | 804 | /* error message is emitted by host2sockaddr() */ |
804 | //FIXME: do this to avoid infinite looping on typo in a hostname? | 805 | set_next(p, HOSTNAME_INTERVAL); |
805 | //well... in which case, what is a good value for loop_on_fail? | ||
806 | //if (--loop_on_fail == 0) | ||
807 | // xfunc_die(); | ||
808 | sleep(5); | ||
809 | goto again; | ||
810 | } | 806 | } |
811 | free(p->p_lsa); | 807 | return lsa; |
812 | free(p->p_dotted); | ||
813 | p->p_lsa = lsa; | ||
814 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); | ||
815 | } | 808 | } |
816 | 809 | ||
817 | static void | 810 | static void |
@@ -822,28 +815,28 @@ add_peers(const char *s) | |||
822 | 815 | ||
823 | p = xzalloc(sizeof(*p) + strlen(s)); | 816 | p = xzalloc(sizeof(*p) + strlen(s)); |
824 | strcpy(p->p_hostname, s); | 817 | strcpy(p->p_hostname, s); |
825 | resolve_peer_hostname(p, /*loop_on_fail=*/ 1); | 818 | p->p_fd = -1; |
819 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); | ||
820 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ | ||
821 | reset_peer_stats(p, STEP_THRESHOLD); | ||
826 | 822 | ||
827 | /* Names like N.<country2chars>.pool.ntp.org are randomly resolved | 823 | /* Names like N.<country2chars>.pool.ntp.org are randomly resolved |
828 | * to a pool of machines. Sometimes different N's resolve to the same IP. | 824 | * to a pool of machines. Sometimes different N's resolve to the same IP. |
829 | * It is not useful to have two peers with same IP. We skip duplicates. | 825 | * It is not useful to have two peers with same IP. We skip duplicates. |
830 | */ | 826 | */ |
831 | for (item = G.ntp_peers; item != NULL; item = item->link) { | 827 | if (resolve_peer_hostname(p)) { |
832 | peer_t *pp = (peer_t *) item->data; | 828 | for (item = G.ntp_peers; item != NULL; item = item->link) { |
833 | if (strcmp(p->p_dotted, pp->p_dotted) == 0) { | 829 | peer_t *pp = (peer_t *) item->data; |
834 | bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); | 830 | if (pp->p_dotted && strcmp(p->p_dotted, pp->p_dotted) == 0) { |
835 | free(p->p_lsa); | 831 | bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); |
836 | free(p->p_dotted); | 832 | free(p->p_lsa); |
837 | free(p); | 833 | free(p->p_dotted); |
838 | return; | 834 | free(p); |
835 | return; | ||
836 | } | ||
839 | } | 837 | } |
840 | } | 838 | } |
841 | 839 | ||
842 | p->p_fd = -1; | ||
843 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); | ||
844 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ | ||
845 | reset_peer_stats(p, STEP_THRESHOLD); | ||
846 | |||
847 | llist_add_to(&G.ntp_peers, p); | 840 | llist_add_to(&G.ntp_peers, p); |
848 | G.peer_cnt++; | 841 | G.peer_cnt++; |
849 | } | 842 | } |
@@ -871,6 +864,11 @@ do_sendto(int fd, | |||
871 | static void | 864 | static void |
872 | send_query_to_peer(peer_t *p) | 865 | send_query_to_peer(peer_t *p) |
873 | { | 866 | { |
867 | if (!p->p_lsa) { | ||
868 | if (!resolve_peer_hostname(p)) | ||
869 | return; | ||
870 | } | ||
871 | |||
874 | /* Why do we need to bind()? | 872 | /* Why do we need to bind()? |
875 | * See what happens when we don't bind: | 873 | * See what happens when we don't bind: |
876 | * | 874 | * |
@@ -2238,7 +2236,7 @@ static NOINLINE void ntp_init(char **argv) | |||
2238 | IF_FEATURE_NTPD_SERVER("I:") /* compat */ | 2236 | IF_FEATURE_NTPD_SERVER("I:") /* compat */ |
2239 | "d" /* compat */ | 2237 | "d" /* compat */ |
2240 | "46aAbgL", /* compat, ignored */ | 2238 | "46aAbgL", /* compat, ignored */ |
2241 | &peers,&G.script_name, | 2239 | &peers, &G.script_name, |
2242 | #if ENABLE_FEATURE_NTPD_SERVER | 2240 | #if ENABLE_FEATURE_NTPD_SERVER |
2243 | &G.if_name, | 2241 | &G.if_name, |
2244 | #endif | 2242 | #endif |
@@ -2263,9 +2261,6 @@ static NOINLINE void ntp_init(char **argv) | |||
2263 | if (opts & OPT_N) | 2261 | if (opts & OPT_N) |
2264 | setpriority(PRIO_PROCESS, 0, -15); | 2262 | setpriority(PRIO_PROCESS, 0, -15); |
2265 | 2263 | ||
2266 | /* add_peers() calls can retry DNS resolution (possibly forever). | ||
2267 | * Daemonize before them, or else boot can stall forever. | ||
2268 | */ | ||
2269 | if (!(opts & OPT_n)) { | 2264 | if (!(opts & OPT_n)) { |
2270 | bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv); | 2265 | bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv); |
2271 | logmode = LOGMODE_NONE; | 2266 | logmode = LOGMODE_NONE; |
@@ -2400,7 +2395,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
2400 | 2395 | ||
2401 | /* What if don't see it because it changed its IP? */ | 2396 | /* What if don't see it because it changed its IP? */ |
2402 | if (p->reachable_bits == 0) | 2397 | if (p->reachable_bits == 0) |
2403 | resolve_peer_hostname(p, /*loop_on_fail=*/ 0); | 2398 | resolve_peer_hostname(p); |
2404 | 2399 | ||
2405 | set_next(p, timeout); | 2400 | set_next(p, timeout); |
2406 | } | 2401 | } |
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index 90fb313b5..7bc13a719 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src | |||
@@ -6,29 +6,13 @@ | |||
6 | INSERT | 6 | INSERT |
7 | 7 | ||
8 | config UDHCPD | 8 | config UDHCPD |
9 | bool "udhcp server (udhcpd)" | 9 | bool "udhcpd (DHCP server)" |
10 | default y | 10 | default y |
11 | select PLATFORM_LINUX | 11 | select PLATFORM_LINUX |
12 | help | 12 | help |
13 | udhcpd is a DHCP server geared primarily toward embedded systems, | 13 | udhcpd is a DHCP server geared primarily toward embedded systems, |
14 | while striving to be fully functional and RFC compliant. | 14 | while striving to be fully functional and RFC compliant. |
15 | 15 | ||
16 | config DHCPRELAY | ||
17 | bool "dhcprelay" | ||
18 | default y | ||
19 | help | ||
20 | dhcprelay listens for dhcp requests on one or more interfaces | ||
21 | and forwards these requests to a different interface or dhcp | ||
22 | server. | ||
23 | |||
24 | config DUMPLEASES | ||
25 | bool "Lease display utility (dumpleases)" | ||
26 | default y | ||
27 | help | ||
28 | dumpleases displays the leases written out by the udhcpd server. | ||
29 | Lease times are stored in the file by time remaining in lease, or | ||
30 | by the absolute time that it expires in seconds from epoch. | ||
31 | |||
32 | config FEATURE_UDHCPD_WRITE_LEASES_EARLY | 16 | config FEATURE_UDHCPD_WRITE_LEASES_EARLY |
33 | bool "Rewrite the lease file at every new acknowledge" | 17 | bool "Rewrite the lease file at every new acknowledge" |
34 | default y | 18 | default y |
@@ -61,8 +45,24 @@ config DHCPD_LEASES_FILE | |||
61 | udhcpd stores addresses in a lease file. This is the absolute path | 45 | udhcpd stores addresses in a lease file. This is the absolute path |
62 | of the file. Normally it is safe to leave it untouched. | 46 | of the file. Normally it is safe to leave it untouched. |
63 | 47 | ||
48 | config DUMPLEASES | ||
49 | bool "dumpleases" | ||
50 | default y | ||
51 | help | ||
52 | dumpleases displays the leases written out by the udhcpd. | ||
53 | Lease times are stored in the file by time remaining in lease, or | ||
54 | by the absolute time that it expires in seconds from epoch. | ||
55 | |||
56 | config DHCPRELAY | ||
57 | bool "dhcprelay" | ||
58 | default y | ||
59 | help | ||
60 | dhcprelay listens for dhcp requests on one or more interfaces | ||
61 | and forwards these requests to a different interface or dhcp | ||
62 | server. | ||
63 | |||
64 | config UDHCPC | 64 | config UDHCPC |
65 | bool "udhcp client (udhcpc)" | 65 | bool "udhcpc (DHCP client)" |
66 | default y | 66 | default y |
67 | select PLATFORM_LINUX | 67 | select PLATFORM_LINUX |
68 | help | 68 | help |
@@ -93,6 +93,15 @@ config FEATURE_UDHCPC_SANITIZEOPT | |||
93 | they will be replaced with string "bad" when exporting | 93 | they will be replaced with string "bad" when exporting |
94 | to the environment. | 94 | to the environment. |
95 | 95 | ||
96 | config UDHCPC_DEFAULT_SCRIPT | ||
97 | string "Absolute path to config script" | ||
98 | default "/usr/share/udhcpc/default.script" | ||
99 | depends on UDHCPC | ||
100 | help | ||
101 | This script is called after udhcpc receives an answer. See | ||
102 | examples/udhcp for a working example. Normally it is safe | ||
103 | to leave this untouched. | ||
104 | |||
96 | config FEATURE_UDHCP_PORT | 105 | config FEATURE_UDHCP_PORT |
97 | bool "Enable '-P port' option for udhcpd and udhcpc" | 106 | bool "Enable '-P port' option for udhcpd and udhcpc" |
98 | default n | 107 | default n |
@@ -130,15 +139,6 @@ config FEATURE_UDHCP_8021Q | |||
130 | If selected, both client and server will support passing of VLAN | 139 | If selected, both client and server will support passing of VLAN |
131 | ID and priority via options 132 and 133 as per 802.1Q. | 140 | ID and priority via options 132 and 133 as per 802.1Q. |
132 | 141 | ||
133 | config UDHCPC_DEFAULT_SCRIPT | ||
134 | string "Absolute path to config script" | ||
135 | default "/usr/share/udhcpc/default.script" | ||
136 | depends on UDHCPC | ||
137 | help | ||
138 | This script is called after udhcpc receives an answer. See | ||
139 | examples/udhcp for a working example. Normally it is safe | ||
140 | to leave this untouched. | ||
141 | |||
142 | config UDHCPC_SLACK_FOR_BUGGY_SERVERS | 142 | config UDHCPC_SLACK_FOR_BUGGY_SERVERS |
143 | int "DHCP options slack buffer size" | 143 | int "DHCP options slack buffer size" |
144 | default 80 | 144 | default 80 |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index ddf3412a0..64339c9b5 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | //config:config UDHCPC6 | 14 | //config:config UDHCPC6 |
15 | //config: bool "udhcp client for DHCPv6 (udhcpc6)" | 15 | //config: bool "udhcpc6 (DHCPv6 client, NOT READY)" |
16 | //config: default n # not yet ready | 16 | //config: default n # not yet ready |
17 | //config: depends on FEATURE_IPV6 | 17 | //config: depends on FEATURE_IPV6 |
18 | //config: help | 18 | //config: help |
diff --git a/shell/Config.src b/shell/Config.src index 7f5f67050..3545f05dd 100644 --- a/shell/Config.src +++ b/shell/Config.src | |||
@@ -17,9 +17,19 @@ choice | |||
17 | config SH_IS_ASH | 17 | config SH_IS_ASH |
18 | depends on !NOMMU | 18 | depends on !NOMMU |
19 | bool "ash" | 19 | bool "ash" |
20 | help | ||
21 | Choose ash to be the shell executed by 'sh' name. | ||
22 | The ash code will be built into busybox. If you don't select | ||
23 | "ash" choice (CONFIG_ASH), this shell may only be invoked by | ||
24 | the name 'sh' (and not 'ash'). | ||
20 | 25 | ||
21 | config SH_IS_HUSH | 26 | config SH_IS_HUSH |
22 | bool "hush" | 27 | bool "hush" |
28 | help | ||
29 | Choose hush to be the shell executed by 'sh' name. | ||
30 | The hush code will be built into busybox. If you don't select | ||
31 | "hush" choice (CONFIG_HUSH), this shell may only be invoked by | ||
32 | the name 'sh' (and not 'hush'). | ||
23 | 33 | ||
24 | config SH_IS_NONE | 34 | config SH_IS_NONE |
25 | bool "none" | 35 | bool "none" |
@@ -31,7 +41,8 @@ choice | |||
31 | default BASH_IS_NONE | 41 | default BASH_IS_NONE |
32 | help | 42 | help |
33 | Choose which shell you want to be executed by 'bash' alias. | 43 | Choose which shell you want to be executed by 'bash' alias. |
34 | The ash shell is the most bash compatible and full featured one. | 44 | The ash shell is the most bash compatible and full featured one, |
45 | although compatibility is far from being complete. | ||
35 | 46 | ||
36 | Note that selecting this option does not switch on any bash | 47 | Note that selecting this option does not switch on any bash |
37 | compatibility code. It merely makes it possible to install | 48 | compatibility code. It merely makes it possible to install |
@@ -46,9 +57,19 @@ choice | |||
46 | config BASH_IS_ASH | 57 | config BASH_IS_ASH |
47 | depends on !NOMMU | 58 | depends on !NOMMU |
48 | bool "ash" | 59 | bool "ash" |
60 | help | ||
61 | Choose ash to be the shell executed by 'bash' name. | ||
62 | The ash code will be built into busybox. If you don't select | ||
63 | "ash" choice (CONFIG_ASH), this shell may only be invoked by | ||
64 | the name 'bash' (and not 'ash'). | ||
49 | 65 | ||
50 | config BASH_IS_HUSH | 66 | config BASH_IS_HUSH |
51 | bool "hush" | 67 | bool "hush" |
68 | help | ||
69 | Choose hush to be the shell executed by 'bash' name. | ||
70 | The hush code will be built into busybox. If you don't select | ||
71 | "hush" choice (CONFIG_HUSH), this shell may only be invoked by | ||
72 | the name 'bash' (and not 'hush'). | ||
52 | 73 | ||
53 | config BASH_IS_NONE | 74 | config BASH_IS_NONE |
54 | bool "none" | 75 | bool "none" |
@@ -59,6 +80,9 @@ endchoice | |||
59 | INSERT | 80 | INSERT |
60 | 81 | ||
61 | 82 | ||
83 | comment "Options common to all shells" | ||
84 | if ASH || HUSH || SH_IS_ASH || BASH_IS_ASH || SH_IS_HUSH || BASH_IS_HUSH | ||
85 | |||
62 | config FEATURE_SH_MATH | 86 | config FEATURE_SH_MATH |
63 | bool "POSIX math support" | 87 | bool "POSIX math support" |
64 | default y | 88 | default y |
@@ -142,5 +166,6 @@ config FEATURE_SH_HISTFILESIZE | |||
142 | to set shell history size. Note that its max value is capped | 166 | to set shell history size. Note that its max value is capped |
143 | by "History size" setting in library tuning section. | 167 | by "History size" setting in library tuning section. |
144 | 168 | ||
169 | endif # Options common to all shells | ||
145 | 170 | ||
146 | endmenu | 171 | endmenu |
diff --git a/shell/ash.c b/shell/ash.c index 35618937a..fe185f5d9 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -41,6 +41,11 @@ | |||
41 | //config: shell (by Herbert Xu), which was created by porting the 'ash' shell | 41 | //config: shell (by Herbert Xu), which was created by porting the 'ash' shell |
42 | //config: (written by Kenneth Almquist) from NetBSD. | 42 | //config: (written by Kenneth Almquist) from NetBSD. |
43 | //config: | 43 | //config: |
44 | //config:# ash options | ||
45 | //config:# note: Don't remove !NOMMU part in the next line; it would break | ||
46 | //config:# menuconfig's indenting. | ||
47 | //config:if !NOMMU && (ASH || SH_IS_ASH || BASH_IS_ASH) | ||
48 | //config: | ||
44 | //config:config ASH_OPTIMIZE_FOR_SIZE | 49 | //config:config ASH_OPTIMIZE_FOR_SIZE |
45 | //config: bool "Optimize for size instead of speed" | 50 | //config: bool "Optimize for size instead of speed" |
46 | //config: default y | 51 | //config: default y |
@@ -155,6 +160,8 @@ | |||
155 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 160 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
156 | //config: help | 161 | //config: help |
157 | //config: Enable "check for new mail" function in the ash shell. | 162 | //config: Enable "check for new mail" function in the ash shell. |
163 | //config: | ||
164 | //config:endif # ash options | ||
158 | 165 | ||
159 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) | 166 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) |
160 | //applet:IF_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, ash)) | 167 | //applet:IF_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, ash)) |
@@ -5778,11 +5785,11 @@ redirect(union node *redir, int flags) | |||
5778 | /* Careful to not accidentally "save" | 5785 | /* Careful to not accidentally "save" |
5779 | * to the same fd as right side fd in N>&M */ | 5786 | * to the same fd as right side fd in N>&M */ |
5780 | int minfd = right_fd < 10 ? 10 : right_fd + 1; | 5787 | int minfd = right_fd < 10 ? 10 : right_fd + 1; |
5788 | #if defined(F_DUPFD_CLOEXEC) | ||
5789 | i = fcntl(fd, F_DUPFD_CLOEXEC, minfd); | ||
5790 | #else | ||
5781 | i = fcntl(fd, F_DUPFD, minfd); | 5791 | i = fcntl(fd, F_DUPFD, minfd); |
5782 | /* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds | 5792 | #endif |
5783 | * are closed in popredir() in the child, preventing them from leaking | ||
5784 | * into child. (popredir() also cleans up the mess in case of failures) | ||
5785 | */ | ||
5786 | if (i == -1) { | 5793 | if (i == -1) { |
5787 | i = errno; | 5794 | i = errno; |
5788 | if (i != EBADF) { | 5795 | if (i != EBADF) { |
@@ -5797,6 +5804,9 @@ redirect(union node *redir, int flags) | |||
5797 | remember_to_close: | 5804 | remember_to_close: |
5798 | i = CLOSED; | 5805 | i = CLOSED; |
5799 | } else { /* fd is open, save its copy */ | 5806 | } else { /* fd is open, save its copy */ |
5807 | #if !defined(F_DUPFD_CLOEXEC) | ||
5808 | fcntl(i, F_SETFD, FD_CLOEXEC); | ||
5809 | #endif | ||
5800 | /* "exec fd>&-" should not close fds | 5810 | /* "exec fd>&-" should not close fds |
5801 | * which point to script file(s). | 5811 | * which point to script file(s). |
5802 | * Force them to be restored afterwards */ | 5812 | * Force them to be restored afterwards */ |
diff --git a/shell/ash_test/ash-redir/redir_leak.right b/shell/ash_test/ash-redir/redir_leak.right new file mode 100644 index 000000000..b1c48292b --- /dev/null +++ b/shell/ash_test/ash-redir/redir_leak.right | |||
@@ -0,0 +1,6 @@ | |||
1 | 4 | ||
2 | 4 | ||
3 | 4 | ||
4 | 4 | ||
5 | 4 | ||
6 | 4 | ||
diff --git a/shell/ash_test/ash-redir/redir_leak.tests b/shell/ash_test/ash-redir/redir_leak.tests new file mode 100755 index 000000000..c8a9c6343 --- /dev/null +++ b/shell/ash_test/ash-redir/redir_leak.tests | |||
@@ -0,0 +1,10 @@ | |||
1 | # Each of these should show only four lines: | ||
2 | # fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. | ||
3 | # This test detects bugs where redirects leave stray open fds. | ||
4 | |||
5 | ls -1 /proc/self/fd | wc -l | ||
6 | ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l | ||
7 | ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l | ||
8 | echo "`ls -1 /proc/self/fd `" | wc -l | ||
9 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l | ||
10 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l | ||
diff --git a/shell/hush_test/hush-redir/redir_leak.right b/shell/hush_test/hush-redir/redir_leak.right new file mode 100644 index 000000000..b1c48292b --- /dev/null +++ b/shell/hush_test/hush-redir/redir_leak.right | |||
@@ -0,0 +1,6 @@ | |||
1 | 4 | ||
2 | 4 | ||
3 | 4 | ||
4 | 4 | ||
5 | 4 | ||
6 | 4 | ||
diff --git a/shell/hush_test/hush-redir/redir_leak.tests b/shell/hush_test/hush-redir/redir_leak.tests new file mode 100755 index 000000000..c8a9c6343 --- /dev/null +++ b/shell/hush_test/hush-redir/redir_leak.tests | |||
@@ -0,0 +1,10 @@ | |||
1 | # Each of these should show only four lines: | ||
2 | # fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. | ||
3 | # This test detects bugs where redirects leave stray open fds. | ||
4 | |||
5 | ls -1 /proc/self/fd | wc -l | ||
6 | ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l | ||
7 | ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l | ||
8 | echo "`ls -1 /proc/self/fd `" | wc -l | ||
9 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l | ||
10 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l | ||
diff --git a/testsuite/unzip.tests b/testsuite/unzip.tests index d8738a3bd..d9c45242c 100755 --- a/testsuite/unzip.tests +++ b/testsuite/unzip.tests | |||
@@ -31,11 +31,10 @@ rmdir foo | |||
31 | rm foo.zip | 31 | rm foo.zip |
32 | 32 | ||
33 | # File containing some damaged encrypted stream | 33 | # File containing some damaged encrypted stream |
34 | optional FEATURE_UNZIP_CDF | ||
34 | testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \ | 35 | testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \ |
35 | "Archive: bad.zip | 36 | "Archive: bad.zip |
36 | inflating: ]3j½r«IK-%Ix | 37 | unzip: short read |
37 | unzip: corrupted data | ||
38 | unzip: inflate error | ||
39 | 1 | 38 | 1 |
40 | " \ | 39 | " \ |
41 | "" "\ | 40 | "" "\ |
@@ -49,6 +48,7 @@ BDYAAAAMAAEADQAAADIADQAAAEEAAAASw73Ct1DKokohPXQiNzA+FAI1HCcW | |||
49 | NzITNFBLBQUKAC4JAA04Cw0EOhZQSwUGAQAABAIAAgCZAAAAeQAAAAIALhM= | 48 | NzITNFBLBQUKAC4JAA04Cw0EOhZQSwUGAQAABAIAAgCZAAAAeQAAAAIALhM= |
50 | ==== | 49 | ==== |
51 | " | 50 | " |
51 | SKIP= | ||
52 | 52 | ||
53 | rm * | 53 | rm * |
54 | 54 | ||