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>
This commit is contained in:
parent
6bf52b615d
commit
2a0867a5ed
@ -127,7 +127,7 @@ int FAST_FUNC bbunpack(char **argv,
|
|||||||
|
|
||||||
if (!(option_mask32 & SEAMLESS_MAGIC)) {
|
if (!(option_mask32 & SEAMLESS_MAGIC)) {
|
||||||
init_transformer_state(&xstate);
|
init_transformer_state(&xstate);
|
||||||
xstate.signature_skipped = 0;
|
/*xstate.signature_skipped = 0; - already is */
|
||||||
/*xstate.src_fd = STDIN_FILENO; - already is */
|
/*xstate.src_fd = STDIN_FILENO; - already is */
|
||||||
xstate.dst_fd = STDOUT_FILENO;
|
xstate.dst_fd = STDOUT_FILENO;
|
||||||
status = unpacker(&xstate);
|
status = unpacker(&xstate);
|
||||||
|
@ -53,9 +53,11 @@ lib-$(CONFIG_LZOPCAT) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o
|
|||||||
lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o
|
lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o
|
||||||
lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o
|
lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o
|
||||||
lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o
|
lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o
|
||||||
|
lib-$(CONFIG_FEATURE_UNZIP_BZIP2) += open_transformer.o decompress_bunzip2.o
|
||||||
lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o
|
lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o
|
||||||
lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o
|
lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o
|
||||||
lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o
|
lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o
|
||||||
|
lib-$(CONFIG_FEATURE_UNZIP_LZMA) += open_transformer.o decompress_unlzma.o
|
||||||
lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o
|
lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o
|
||||||
lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o
|
lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o
|
||||||
lib-$(CONFIG_XZ) += open_transformer.o decompress_unxz.o
|
lib-$(CONFIG_XZ) += open_transformer.o decompress_unxz.o
|
||||||
|
@ -34,6 +34,18 @@
|
|||||||
//config: ZIP files without deleted/updated files, SFX archives etc,
|
//config: ZIP files without deleted/updated files, SFX archives etc,
|
||||||
//config: you can reduce code size by unselecting this option.
|
//config: you can reduce code size by unselecting this option.
|
||||||
//config: To support less trivial ZIPs, say Y.
|
//config: To support less trivial ZIPs, say Y.
|
||||||
|
//config:
|
||||||
|
//config:config FEATURE_UNZIP_BZIP2
|
||||||
|
//config: bool "Support compression method 12 (bzip2)"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on FEATURE_UNZIP_CDF && DESKTOP
|
||||||
|
// FEATURE_UNZIP_CDF is needed, otherwise we can't find start of next file
|
||||||
|
// DESKTOP is needed to get back uncompressed length
|
||||||
|
//config:
|
||||||
|
//config:config FEATURE_UNZIP_LZMA
|
||||||
|
//config: bool "Support compression method 14 (lzma)"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on FEATURE_UNZIP_CDF && DESKTOP
|
||||||
|
|
||||||
//applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP))
|
//applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP))
|
||||||
//kbuild:lib-$(CONFIG_UNZIP) += unzip.o
|
//kbuild:lib-$(CONFIG_UNZIP) += unzip.o
|
||||||
@ -319,32 +331,57 @@ static void unzip_create_leading_dirs(const char *fn)
|
|||||||
|
|
||||||
static void unzip_extract(zip_header_t *zip, int dst_fd)
|
static void unzip_extract(zip_header_t *zip, int dst_fd)
|
||||||
{
|
{
|
||||||
|
transformer_state_t xstate;
|
||||||
|
|
||||||
if (zip->fmt.method == 0) {
|
if (zip->fmt.method == 0) {
|
||||||
/* Method 0 - stored (not compressed) */
|
/* Method 0 - stored (not compressed) */
|
||||||
off_t size = zip->fmt.ucmpsize;
|
off_t size = zip->fmt.ucmpsize;
|
||||||
if (size)
|
if (size)
|
||||||
bb_copyfd_exact_size(zip_fd, dst_fd, size);
|
bb_copyfd_exact_size(zip_fd, dst_fd, size);
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_transformer_state(&xstate);
|
||||||
|
xstate.bytes_in = zip->fmt.cmpsize;
|
||||||
|
xstate.src_fd = zip_fd;
|
||||||
|
xstate.dst_fd = dst_fd;
|
||||||
|
if (zip->fmt.method == 8) {
|
||||||
/* Method 8 - inflate */
|
/* Method 8 - inflate */
|
||||||
transformer_state_t xstate;
|
|
||||||
init_transformer_state(&xstate);
|
|
||||||
xstate.bytes_in = zip->fmt.cmpsize;
|
|
||||||
xstate.src_fd = zip_fd;
|
|
||||||
xstate.dst_fd = dst_fd;
|
|
||||||
if (inflate_unzip(&xstate) < 0)
|
if (inflate_unzip(&xstate) < 0)
|
||||||
bb_error_msg_and_die("inflate error");
|
bb_error_msg_and_die("inflate error");
|
||||||
/* Validate decompression - crc */
|
/* Validate decompression - crc */
|
||||||
if (zip->fmt.crc32 != (xstate.crc32 ^ 0xffffffffL)) {
|
if (zip->fmt.crc32 != (xstate.crc32 ^ 0xffffffffL)) {
|
||||||
bb_error_msg_and_die("crc error");
|
bb_error_msg_and_die("crc error");
|
||||||
}
|
}
|
||||||
/* Validate decompression - size */
|
|
||||||
if (zip->fmt.ucmpsize != xstate.bytes_out) {
|
|
||||||
/* Don't die. Who knows, maybe len calculation
|
|
||||||
* was botched somewhere. After all, crc matched! */
|
|
||||||
bb_error_msg("bad length");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* TODO? method 12: bzip2, method 14: LZMA */
|
#if ENABLE_FEATURE_UNZIP_BZIP2
|
||||||
|
else if (zip->fmt.method == 12) {
|
||||||
|
/* Tested. Unpacker reads too much, but we use CDF
|
||||||
|
* and will seek to the correct beginning of next file.
|
||||||
|
*/
|
||||||
|
xstate.bytes_out = unpack_bz2_stream(&xstate);
|
||||||
|
if (xstate.bytes_out < 0)
|
||||||
|
bb_error_msg_and_die("inflate error");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if ENABLE_FEATURE_UNZIP_LZMA
|
||||||
|
else if (zip->fmt.method == 14) {
|
||||||
|
/* Not tested yet */
|
||||||
|
xstate.bytes_out = unpack_lzma_stream(&xstate);
|
||||||
|
if (xstate.bytes_out < 0)
|
||||||
|
bb_error_msg_and_die("inflate error");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
bb_error_msg_and_die("unsupported method %u", zip->fmt.method);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate decompression - size */
|
||||||
|
if (zip->fmt.ucmpsize != xstate.bytes_out) {
|
||||||
|
/* Don't die. Who knows, maybe len calculation
|
||||||
|
* was botched somewhere. After all, crc matched! */
|
||||||
|
bb_error_msg("bad length");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void my_fgets80(char *buf80)
|
static void my_fgets80(char *buf80)
|
||||||
@ -609,12 +646,6 @@ int unzip_main(int argc, char **argv)
|
|||||||
|
|
||||||
xread(zip_fd, zip.raw, ZIP_HEADER_LEN);
|
xread(zip_fd, zip.raw, ZIP_HEADER_LEN);
|
||||||
FIX_ENDIANNESS_ZIP(zip);
|
FIX_ENDIANNESS_ZIP(zip);
|
||||||
if ((zip.fmt.method != 0)
|
|
||||||
&& (zip.fmt.method != 8)
|
|
||||||
) {
|
|
||||||
/* TODO? method 12: bzip2, method 14: LZMA */
|
|
||||||
bb_error_msg_and_die("unsupported method %d", zip.fmt.method);
|
|
||||||
}
|
|
||||||
if (zip.fmt.zip_flags & SWAP_LE16(0x0009)) {
|
if (zip.fmt.zip_flags & SWAP_LE16(0x0009)) {
|
||||||
bb_error_msg_and_die("zip flags 1 and 8 are not supported");
|
bb_error_msg_and_die("zip flags 1 and 8 are not supported");
|
||||||
}
|
}
|
||||||
@ -704,7 +735,11 @@ int unzip_main(int argc, char **argv)
|
|||||||
dtbuf,
|
dtbuf,
|
||||||
dst_fn);
|
dst_fn);
|
||||||
} else {
|
} else {
|
||||||
unsigned long percents = zip.fmt.ucmpsize - zip.fmt.cmpsize;
|
char method6[7];
|
||||||
|
unsigned long percents;
|
||||||
|
|
||||||
|
sprintf(method6, "%6u", zip.fmt.method);
|
||||||
|
percents = zip.fmt.ucmpsize - zip.fmt.cmpsize;
|
||||||
if ((int32_t)percents < 0)
|
if ((int32_t)percents < 0)
|
||||||
percents = 0; /* happens if ucmpsize < cmpsize */
|
percents = 0; /* happens if ucmpsize < cmpsize */
|
||||||
percents = percents * 100;
|
percents = percents * 100;
|
||||||
@ -714,21 +749,9 @@ int unzip_main(int argc, char **argv)
|
|||||||
// "-------- ------ ------- ---- ---------- ----- -------- ----"
|
// "-------- ------ ------- ---- ---------- ----- -------- ----"
|
||||||
printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n",
|
printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n",
|
||||||
(unsigned)zip.fmt.ucmpsize,
|
(unsigned)zip.fmt.ucmpsize,
|
||||||
zip.fmt.method == 0 ? "Stored" : "Defl:N", /* Defl is method 8 */
|
zip.fmt.method == 0 ? "Stored"
|
||||||
/* TODO: show other methods?
|
: zip.fmt.method == 8 ? "Defl:N"
|
||||||
* 1 - Shrunk
|
: method6,
|
||||||
* 2 - Reduced with compression factor 1
|
|
||||||
* 3 - Reduced with compression factor 2
|
|
||||||
* 4 - Reduced with compression factor 3
|
|
||||||
* 5 - Reduced with compression factor 4
|
|
||||||
* 6 - Imploded
|
|
||||||
* 7 - Reserved for Tokenizing compression algorithm
|
|
||||||
* 9 - Deflate64
|
|
||||||
* 10 - PKWARE Data Compression Library Imploding
|
|
||||||
* 11 - Reserved by PKWARE
|
|
||||||
* 12 - BZIP2
|
|
||||||
* 14 - LZMA
|
|
||||||
*/
|
|
||||||
(unsigned)zip.fmt.cmpsize,
|
(unsigned)zip.fmt.cmpsize,
|
||||||
(unsigned)percents,
|
(unsigned)percents,
|
||||||
dtbuf,
|
dtbuf,
|
||||||
|
Loading…
Reference in New Issue
Block a user