diff options
Diffstat (limited to 'archival/bbunzip.c')
-rw-r--r-- | archival/bbunzip.c | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 66a046052..f77ac8383 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -7,13 +7,16 @@ | |||
7 | #include "libbb.h" | 7 | #include "libbb.h" |
8 | #include "bb_archive.h" | 8 | #include "bb_archive.h" |
9 | 9 | ||
10 | /* Note: must be kept in sync with archival/lzop.c */ | ||
10 | enum { | 11 | enum { |
11 | OPT_STDOUT = 1 << 0, | 12 | OPT_STDOUT = 1 << 0, |
12 | OPT_FORCE = 1 << 1, | 13 | OPT_FORCE = 1 << 1, |
13 | /* only some decompressors: */ | 14 | /* only some decompressors: */ |
14 | OPT_VERBOSE = 1 << 2, | 15 | OPT_VERBOSE = 1 << 2, |
15 | OPT_DECOMPRESS = 1 << 3, | 16 | OPT_QUIET = 1 << 3, |
16 | OPT_TEST = 1 << 4, | 17 | OPT_DECOMPRESS = 1 << 4, |
18 | OPT_TEST = 1 << 5, | ||
19 | SEAMLESS_MAGIC = (1 << 31) * SEAMLESS_COMPRESSION, | ||
17 | }; | 20 | }; |
18 | 21 | ||
19 | static | 22 | static |
@@ -39,7 +42,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
39 | ) | 42 | ) |
40 | { | 43 | { |
41 | struct stat stat_buf; | 44 | struct stat stat_buf; |
42 | IF_DESKTOP(long long) int status; | 45 | IF_DESKTOP(long long) int status = 0; |
43 | char *filename, *new_name; | 46 | char *filename, *new_name; |
44 | smallint exitcode = 0; | 47 | smallint exitcode = 0; |
45 | transformer_aux_data_t aux; | 48 | transformer_aux_data_t aux; |
@@ -54,13 +57,27 @@ int FAST_FUNC bbunpack(char **argv, | |||
54 | 57 | ||
55 | /* Open src */ | 58 | /* Open src */ |
56 | if (filename) { | 59 | if (filename) { |
57 | if (stat(filename, &stat_buf) != 0) { | 60 | if (!(option_mask32 & SEAMLESS_MAGIC)) { |
58 | bb_simple_perror_msg(filename); | 61 | if (stat(filename, &stat_buf) != 0) { |
62 | err_name: | ||
63 | bb_simple_perror_msg(filename); | ||
59 | err: | 64 | err: |
60 | exitcode = 1; | 65 | exitcode = 1; |
61 | goto free_name; | 66 | goto free_name; |
67 | } | ||
68 | if (open_to_or_warn(STDIN_FILENO, filename, O_RDONLY, 0)) | ||
69 | goto err; | ||
70 | } else { | ||
71 | /* "clever zcat" with FILE */ | ||
72 | int fd = open_zipped(filename); | ||
73 | if (fd < 0) | ||
74 | goto err_name; | ||
75 | xmove_fd(fd, STDIN_FILENO); | ||
62 | } | 76 | } |
63 | if (open_to_or_warn(STDIN_FILENO, filename, O_RDONLY, 0)) | 77 | } else |
78 | if (option_mask32 & SEAMLESS_MAGIC) { | ||
79 | /* "clever zcat" on stdin */ | ||
80 | if (setup_unzip_on_fd(STDIN_FILENO, /*fail_if_not_detected*/ 0)) | ||
64 | goto err; | 81 | goto err; |
65 | } | 82 | } |
66 | 83 | ||
@@ -68,7 +85,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
68 | if (option_mask32 & (OPT_STDOUT|OPT_TEST)) { | 85 | if (option_mask32 & (OPT_STDOUT|OPT_TEST)) { |
69 | if (option_mask32 & OPT_TEST) | 86 | if (option_mask32 & OPT_TEST) |
70 | if (open_to_or_warn(STDOUT_FILENO, bb_dev_null, O_WRONLY, 0)) | 87 | if (open_to_or_warn(STDOUT_FILENO, bb_dev_null, O_WRONLY, 0)) |
71 | goto err; | 88 | xfunc_die(); |
72 | filename = NULL; | 89 | filename = NULL; |
73 | } | 90 | } |
74 | 91 | ||
@@ -93,16 +110,22 @@ int FAST_FUNC bbunpack(char **argv, | |||
93 | } | 110 | } |
94 | 111 | ||
95 | /* Check that the input is sane */ | 112 | /* Check that the input is sane */ |
96 | if (isatty(STDIN_FILENO) && (option_mask32 & OPT_FORCE) == 0) { | 113 | if (!(option_mask32 & OPT_FORCE) && isatty(STDIN_FILENO)) { |
97 | bb_error_msg_and_die("compressed data not read from terminal, " | 114 | bb_error_msg_and_die("compressed data not read from terminal, " |
98 | "use -f to force it"); | 115 | "use -f to force it"); |
99 | } | 116 | } |
100 | 117 | ||
101 | init_transformer_aux_data(&aux); | 118 | if (!(option_mask32 & SEAMLESS_MAGIC)) { |
102 | aux.check_signature = 1; | 119 | init_transformer_aux_data(&aux); |
103 | status = unpacker(&aux); | 120 | aux.check_signature = 1; |
104 | if (status < 0) | 121 | status = unpacker(&aux); |
105 | exitcode = 1; | 122 | if (status < 0) |
123 | exitcode = 1; | ||
124 | } else { | ||
125 | if (bb_copyfd_eof(STDIN_FILENO, STDOUT_FILENO) < 0) | ||
126 | /* Disk full, tty closed, etc. No point in continuing */ | ||
127 | xfunc_die(); | ||
128 | } | ||
106 | 129 | ||
107 | if (!(option_mask32 & OPT_STDOUT)) | 130 | if (!(option_mask32 & OPT_STDOUT)) |
108 | xclose(STDOUT_FILENO); /* with error check! */ | 131 | xclose(STDOUT_FILENO); /* with error check! */ |
@@ -243,7 +266,7 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) | |||
243 | //usage: "-rw-rw-r-- 1 andersen andersen 1761280 Apr 14 17:47 /tmp/BusyBox-0.43.tar\n" | 266 | //usage: "-rw-rw-r-- 1 andersen andersen 1761280 Apr 14 17:47 /tmp/BusyBox-0.43.tar\n" |
244 | //usage: | 267 | //usage: |
245 | //usage:#define zcat_trivial_usage | 268 | //usage:#define zcat_trivial_usage |
246 | //usage: "FILE" | 269 | //usage: "[FILE]..." |
247 | //usage:#define zcat_full_usage "\n\n" | 270 | //usage:#define zcat_full_usage "\n\n" |
248 | //usage: "Decompress to stdout" | 271 | //usage: "Decompress to stdout" |
249 | 272 | ||
@@ -294,11 +317,15 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(transformer_aux_data_t *aux) | |||
294 | int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 317 | int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
295 | int gunzip_main(int argc UNUSED_PARAM, char **argv) | 318 | int gunzip_main(int argc UNUSED_PARAM, char **argv) |
296 | { | 319 | { |
297 | getopt32(argv, "cfvdtn"); | 320 | getopt32(argv, "cfvqdtn"); |
298 | argv += optind; | 321 | argv += optind; |
299 | /* if called as zcat */ | 322 | |
323 | /* If called as zcat... | ||
324 | * Normally, "zcat" is just "gunzip -c". | ||
325 | * But if seamless magic is enabled, then we are much more clever. | ||
326 | */ | ||
300 | if (applet_name[1] == 'c') | 327 | if (applet_name[1] == 'c') |
301 | option_mask32 |= OPT_STDOUT; | 328 | option_mask32 |= OPT_STDOUT | SEAMLESS_MAGIC; |
302 | 329 | ||
303 | return bbunpack(argv, unpack_gunzip, make_new_name_gunzip, /*unused:*/ NULL); | 330 | return bbunpack(argv, unpack_gunzip, make_new_name_gunzip, /*unused:*/ NULL); |
304 | } | 331 | } |
@@ -318,7 +345,7 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
318 | //usage: "\n -c Write to stdout" | 345 | //usage: "\n -c Write to stdout" |
319 | //usage: "\n -f Force" | 346 | //usage: "\n -f Force" |
320 | //usage:#define bzcat_trivial_usage | 347 | //usage:#define bzcat_trivial_usage |
321 | //usage: "FILE" | 348 | //usage: "[FILE]..." |
322 | //usage:#define bzcat_full_usage "\n\n" | 349 | //usage:#define bzcat_full_usage "\n\n" |
323 | //usage: "Decompress to stdout" | 350 | //usage: "Decompress to stdout" |
324 | //applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) | 351 | //applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) |
@@ -332,7 +359,7 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(transformer_aux_data_t *aux) | |||
332 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 359 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
333 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) | 360 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) |
334 | { | 361 | { |
335 | getopt32(argv, "cfvdt"); | 362 | getopt32(argv, "cfvqdt"); |
336 | argv += optind; | 363 | argv += optind; |
337 | if (applet_name[2] == 'c') /* bzcat */ | 364 | if (applet_name[2] == 'c') /* bzcat */ |
338 | option_mask32 |= OPT_STDOUT; | 365 | option_mask32 |= OPT_STDOUT; |
@@ -367,7 +394,7 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
367 | //usage: "\n -f Force" | 394 | //usage: "\n -f Force" |
368 | //usage: | 395 | //usage: |
369 | //usage:#define lzcat_trivial_usage | 396 | //usage:#define lzcat_trivial_usage |
370 | //usage: "FILE" | 397 | //usage: "[FILE]..." |
371 | //usage:#define lzcat_full_usage "\n\n" | 398 | //usage:#define lzcat_full_usage "\n\n" |
372 | //usage: "Decompress to stdout" | 399 | //usage: "Decompress to stdout" |
373 | //usage: | 400 | //usage: |
@@ -387,7 +414,7 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
387 | //usage: "\n -f Force" | 414 | //usage: "\n -f Force" |
388 | //usage: | 415 | //usage: |
389 | //usage:#define xzcat_trivial_usage | 416 | //usage:#define xzcat_trivial_usage |
390 | //usage: "FILE" | 417 | //usage: "[FILE]..." |
391 | //usage:#define xzcat_full_usage "\n\n" | 418 | //usage:#define xzcat_full_usage "\n\n" |
392 | //usage: "Decompress to stdout" | 419 | //usage: "Decompress to stdout" |
393 | 420 | ||
@@ -400,7 +427,7 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(transformer_aux_data_t *aux) | |||
400 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 427 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
401 | int unlzma_main(int argc UNUSED_PARAM, char **argv) | 428 | int unlzma_main(int argc UNUSED_PARAM, char **argv) |
402 | { | 429 | { |
403 | IF_LZMA(int opts =) getopt32(argv, "cfvdt"); | 430 | IF_LZMA(int opts =) getopt32(argv, "cfvqdt"); |
404 | # if ENABLE_LZMA | 431 | # if ENABLE_LZMA |
405 | /* lzma without -d or -t? */ | 432 | /* lzma without -d or -t? */ |
406 | if (applet_name[2] == 'm' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) | 433 | if (applet_name[2] == 'm' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) |
@@ -425,7 +452,7 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(transformer_aux_data_t *aux) | |||
425 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 452 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
426 | int unxz_main(int argc UNUSED_PARAM, char **argv) | 453 | int unxz_main(int argc UNUSED_PARAM, char **argv) |
427 | { | 454 | { |
428 | IF_XZ(int opts =) getopt32(argv, "cfvdt"); | 455 | IF_XZ(int opts =) getopt32(argv, "cfvqdt"); |
429 | # if ENABLE_XZ | 456 | # if ENABLE_XZ |
430 | /* xz without -d or -t? */ | 457 | /* xz without -d or -t? */ |
431 | if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) | 458 | if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) |