diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-09 10:58:37 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-09 10:58:37 +0100 |
commit | 2a0867a5ed277e4c3cf4c5e17e539d225286ef07 (patch) | |
tree | ca499f61df311e86638402e0db70c44ccdc4fbb0 | |
parent | 6bf52b615d78542e41e684438c844af1fa4fb36e (diff) | |
download | busybox-w32-2a0867a5ed277e4c3cf4c5e17e539d225286ef07.tar.gz busybox-w32-2a0867a5ed277e4c3cf4c5e17e539d225286ef07.tar.bz2 busybox-w32-2a0867a5ed277e4c3cf4c5e17e539d225286ef07.zip |
unzip: optional support for bzip2 and lzma
function old new delta
unzip_main 2376 2476 +100
bbunpack 750 745 -5
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/bbunzip.c | 2 | ||||
-rw-r--r-- | archival/libarchive/Kbuild.src | 2 | ||||
-rw-r--r-- | archival/unzip.c | 93 |
3 files changed, 61 insertions, 36 deletions
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 12c82eba4..aa8453440 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -127,7 +127,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
127 | 127 | ||
128 | if (!(option_mask32 & SEAMLESS_MAGIC)) { | 128 | if (!(option_mask32 & SEAMLESS_MAGIC)) { |
129 | init_transformer_state(&xstate); | 129 | init_transformer_state(&xstate); |
130 | xstate.signature_skipped = 0; | 130 | /*xstate.signature_skipped = 0; - already is */ |
131 | /*xstate.src_fd = STDIN_FILENO; - already is */ | 131 | /*xstate.src_fd = STDIN_FILENO; - already is */ |
132 | xstate.dst_fd = STDOUT_FILENO; | 132 | xstate.dst_fd = STDOUT_FILENO; |
133 | status = unpacker(&xstate); | 133 | status = unpacker(&xstate); |
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index ad5c5c42d..84117fa85 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src | |||
@@ -53,9 +53,11 @@ lib-$(CONFIG_LZOPCAT) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | |||
53 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o | 53 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o |
54 | lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o | 54 | lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o |
55 | lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o | 55 | lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o |
56 | lib-$(CONFIG_FEATURE_UNZIP_BZIP2) += open_transformer.o decompress_bunzip2.o | ||
56 | lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o | 57 | lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o |
57 | lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o | 58 | lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o |
58 | lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o | 59 | lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o |
60 | lib-$(CONFIG_FEATURE_UNZIP_LZMA) += open_transformer.o decompress_unlzma.o | ||
59 | lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o | 61 | lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o |
60 | lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o | 62 | lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o |
61 | lib-$(CONFIG_XZ) += open_transformer.o decompress_unxz.o | 63 | lib-$(CONFIG_XZ) += open_transformer.o decompress_unxz.o |
diff --git a/archival/unzip.c b/archival/unzip.c index 921493591..997543c50 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -34,6 +34,18 @@ | |||
34 | //config: ZIP files without deleted/updated files, SFX archives etc, | 34 | //config: ZIP files without deleted/updated files, SFX archives etc, |
35 | //config: you can reduce code size by unselecting this option. | 35 | //config: you can reduce code size by unselecting this option. |
36 | //config: To support less trivial ZIPs, say Y. | 36 | //config: To support less trivial ZIPs, say Y. |
37 | //config: | ||
38 | //config:config FEATURE_UNZIP_BZIP2 | ||
39 | //config: bool "Support compression method 12 (bzip2)" | ||
40 | //config: default y | ||
41 | //config: depends on FEATURE_UNZIP_CDF && DESKTOP | ||
42 | // FEATURE_UNZIP_CDF is needed, otherwise we can't find start of next file | ||
43 | // DESKTOP is needed to get back uncompressed length | ||
44 | //config: | ||
45 | //config:config FEATURE_UNZIP_LZMA | ||
46 | //config: bool "Support compression method 14 (lzma)" | ||
47 | //config: default y | ||
48 | //config: depends on FEATURE_UNZIP_CDF && DESKTOP | ||
37 | 49 | ||
38 | //applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP)) | 50 | //applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP)) |
39 | //kbuild:lib-$(CONFIG_UNZIP) += unzip.o | 51 | //kbuild:lib-$(CONFIG_UNZIP) += unzip.o |
@@ -319,32 +331,57 @@ static void unzip_create_leading_dirs(const char *fn) | |||
319 | 331 | ||
320 | static void unzip_extract(zip_header_t *zip, int dst_fd) | 332 | static void unzip_extract(zip_header_t *zip, int dst_fd) |
321 | { | 333 | { |
334 | transformer_state_t xstate; | ||
335 | |||
322 | if (zip->fmt.method == 0) { | 336 | if (zip->fmt.method == 0) { |
323 | /* Method 0 - stored (not compressed) */ | 337 | /* Method 0 - stored (not compressed) */ |
324 | off_t size = zip->fmt.ucmpsize; | 338 | off_t size = zip->fmt.ucmpsize; |
325 | if (size) | 339 | if (size) |
326 | bb_copyfd_exact_size(zip_fd, dst_fd, size); | 340 | bb_copyfd_exact_size(zip_fd, dst_fd, size); |
327 | } else { | 341 | return; |
342 | } | ||
343 | |||
344 | init_transformer_state(&xstate); | ||
345 | xstate.bytes_in = zip->fmt.cmpsize; | ||
346 | xstate.src_fd = zip_fd; | ||
347 | xstate.dst_fd = dst_fd; | ||
348 | if (zip->fmt.method == 8) { | ||
328 | /* Method 8 - inflate */ | 349 | /* Method 8 - inflate */ |
329 | transformer_state_t xstate; | ||
330 | init_transformer_state(&xstate); | ||
331 | xstate.bytes_in = zip->fmt.cmpsize; | ||
332 | xstate.src_fd = zip_fd; | ||
333 | xstate.dst_fd = dst_fd; | ||
334 | if (inflate_unzip(&xstate) < 0) | 350 | if (inflate_unzip(&xstate) < 0) |
335 | bb_error_msg_and_die("inflate error"); | 351 | bb_error_msg_and_die("inflate error"); |
336 | /* Validate decompression - crc */ | 352 | /* Validate decompression - crc */ |
337 | if (zip->fmt.crc32 != (xstate.crc32 ^ 0xffffffffL)) { | 353 | if (zip->fmt.crc32 != (xstate.crc32 ^ 0xffffffffL)) { |
338 | bb_error_msg_and_die("crc error"); | 354 | bb_error_msg_and_die("crc error"); |
339 | } | 355 | } |
340 | /* Validate decompression - size */ | ||
341 | if (zip->fmt.ucmpsize != xstate.bytes_out) { | ||
342 | /* Don't die. Who knows, maybe len calculation | ||
343 | * was botched somewhere. After all, crc matched! */ | ||
344 | bb_error_msg("bad length"); | ||
345 | } | ||
346 | } | 356 | } |
347 | /* TODO? method 12: bzip2, method 14: LZMA */ | 357 | #if ENABLE_FEATURE_UNZIP_BZIP2 |
358 | else if (zip->fmt.method == 12) { | ||
359 | /* Tested. Unpacker reads too much, but we use CDF | ||
360 | * and will seek to the correct beginning of next file. | ||
361 | */ | ||
362 | xstate.bytes_out = unpack_bz2_stream(&xstate); | ||
363 | if (xstate.bytes_out < 0) | ||
364 | bb_error_msg_and_die("inflate error"); | ||
365 | } | ||
366 | #endif | ||
367 | #if ENABLE_FEATURE_UNZIP_LZMA | ||
368 | else if (zip->fmt.method == 14) { | ||
369 | /* Not tested yet */ | ||
370 | xstate.bytes_out = unpack_lzma_stream(&xstate); | ||
371 | if (xstate.bytes_out < 0) | ||
372 | bb_error_msg_and_die("inflate error"); | ||
373 | } | ||
374 | #endif | ||
375 | else { | ||
376 | bb_error_msg_and_die("unsupported method %u", zip->fmt.method); | ||
377 | } | ||
378 | |||
379 | /* Validate decompression - size */ | ||
380 | if (zip->fmt.ucmpsize != xstate.bytes_out) { | ||
381 | /* Don't die. Who knows, maybe len calculation | ||
382 | * was botched somewhere. After all, crc matched! */ | ||
383 | bb_error_msg("bad length"); | ||
384 | } | ||
348 | } | 385 | } |
349 | 386 | ||
350 | static void my_fgets80(char *buf80) | 387 | static void my_fgets80(char *buf80) |
@@ -609,12 +646,6 @@ int unzip_main(int argc, char **argv) | |||
609 | 646 | ||
610 | xread(zip_fd, zip.raw, ZIP_HEADER_LEN); | 647 | xread(zip_fd, zip.raw, ZIP_HEADER_LEN); |
611 | FIX_ENDIANNESS_ZIP(zip); | 648 | FIX_ENDIANNESS_ZIP(zip); |
612 | if ((zip.fmt.method != 0) | ||
613 | && (zip.fmt.method != 8) | ||
614 | ) { | ||
615 | /* TODO? method 12: bzip2, method 14: LZMA */ | ||
616 | bb_error_msg_and_die("unsupported method %d", zip.fmt.method); | ||
617 | } | ||
618 | if (zip.fmt.zip_flags & SWAP_LE16(0x0009)) { | 649 | if (zip.fmt.zip_flags & SWAP_LE16(0x0009)) { |
619 | bb_error_msg_and_die("zip flags 1 and 8 are not supported"); | 650 | bb_error_msg_and_die("zip flags 1 and 8 are not supported"); |
620 | } | 651 | } |
@@ -704,7 +735,11 @@ int unzip_main(int argc, char **argv) | |||
704 | dtbuf, | 735 | dtbuf, |
705 | dst_fn); | 736 | dst_fn); |
706 | } else { | 737 | } else { |
707 | unsigned long percents = zip.fmt.ucmpsize - zip.fmt.cmpsize; | 738 | char method6[7]; |
739 | unsigned long percents; | ||
740 | |||
741 | sprintf(method6, "%6u", zip.fmt.method); | ||
742 | percents = zip.fmt.ucmpsize - zip.fmt.cmpsize; | ||
708 | if ((int32_t)percents < 0) | 743 | if ((int32_t)percents < 0) |
709 | percents = 0; /* happens if ucmpsize < cmpsize */ | 744 | percents = 0; /* happens if ucmpsize < cmpsize */ |
710 | percents = percents * 100; | 745 | percents = percents * 100; |
@@ -714,21 +749,9 @@ int unzip_main(int argc, char **argv) | |||
714 | // "-------- ------ ------- ---- ---------- ----- -------- ----" | 749 | // "-------- ------ ------- ---- ---------- ----- -------- ----" |
715 | printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n", | 750 | printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n", |
716 | (unsigned)zip.fmt.ucmpsize, | 751 | (unsigned)zip.fmt.ucmpsize, |
717 | zip.fmt.method == 0 ? "Stored" : "Defl:N", /* Defl is method 8 */ | 752 | zip.fmt.method == 0 ? "Stored" |
718 | /* TODO: show other methods? | 753 | : zip.fmt.method == 8 ? "Defl:N" |
719 | * 1 - Shrunk | 754 | : method6, |
720 | * 2 - Reduced with compression factor 1 | ||
721 | * 3 - Reduced with compression factor 2 | ||
722 | * 4 - Reduced with compression factor 3 | ||
723 | * 5 - Reduced with compression factor 4 | ||
724 | * 6 - Imploded | ||
725 | * 7 - Reserved for Tokenizing compression algorithm | ||
726 | * 9 - Deflate64 | ||
727 | * 10 - PKWARE Data Compression Library Imploding | ||
728 | * 11 - Reserved by PKWARE | ||
729 | * 12 - BZIP2 | ||
730 | * 14 - LZMA | ||
731 | */ | ||
732 | (unsigned)zip.fmt.cmpsize, | 755 | (unsigned)zip.fmt.cmpsize, |
733 | (unsigned)percents, | 756 | (unsigned)percents, |
734 | dtbuf, | 757 | dtbuf, |