aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-09 10:58:37 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-09 10:58:37 +0100
commit2a0867a5ed277e4c3cf4c5e17e539d225286ef07 (patch)
treeca499f61df311e86638402e0db70c44ccdc4fbb0
parent6bf52b615d78542e41e684438c844af1fa4fb36e (diff)
downloadbusybox-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.c2
-rw-r--r--archival/libarchive/Kbuild.src2
-rw-r--r--archival/unzip.c93
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
53lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o 53lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o
54lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o 54lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o
55lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o 55lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o
56lib-$(CONFIG_FEATURE_UNZIP_BZIP2) += open_transformer.o decompress_bunzip2.o
56lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o 57lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o
57lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o 58lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o
58lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o 59lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o
60lib-$(CONFIG_FEATURE_UNZIP_LZMA) += open_transformer.o decompress_unlzma.o
59lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o 61lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o
60lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o 62lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o
61lib-$(CONFIG_XZ) += open_transformer.o decompress_unxz.o 63lib-$(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
320static void unzip_extract(zip_header_t *zip, int dst_fd) 332static 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
350static void my_fgets80(char *buf80) 387static 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,