diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2012-03-06 16:27:48 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2012-03-06 16:27:48 +0100 |
commit | 8a6a2f9c9c214b94bd945acd97ac8b28c25e194e (patch) | |
tree | 08b9a2af482bb50a7e369c01f9e9083680543fd4 | |
parent | 774bce8e8ba1e424c953e8f13aee8f0778c8a911 (diff) | |
download | busybox-w32-8a6a2f9c9c214b94bd945acd97ac8b28c25e194e.tar.gz busybox-w32-8a6a2f9c9c214b94bd945acd97ac8b28c25e194e.tar.bz2 busybox-w32-8a6a2f9c9c214b94bd945acd97ac8b28c25e194e.zip |
update seamless uncompression code
This change makes "tar tf hello_world.txz" work without
adding special-casing for ".txz" extension. It also removes
ever-growing magic checking code in rpm2cpio and get_header_tar -
we reuse one which lives in setup_unzip_on_fd.
function old new delta
unpack_gz_stream 7 566 +559
check_signature16 - 70 +70
setup_unzip_on_fd 99 142 +43
handle_SIGCHLD - 41 +41
unpack_bz2_stream 342 376 +34
unzip_main 2352 2385 +33
bbunpack 503 533 +30
open_transformer 74 102 +28
unpack_Z_stream 1278 1304 +26
unpack_gunzip 101 123 +22
init_transformer_aux_data - 18 +18
unpack_xz_stream 2388 2402 +14
open_zipped 131 141 +10
rpm_main 1358 1363 +5
get_header_tar_lzma 52 57 +5
get_header_tar_bz2 52 57 +5
unpack_lzma_stream 2698 2702 +4
hash_find 234 233 -1
get_header_tar 1759 1733 -26
get_header_tar_gz 92 57 -35
unpack_uncompress 51 12 -39
rpm2cpio_main 201 147 -54
unpack_unxz 67 12 -55
unpack_bz2_stream_prime 55 - -55
get_header_tar_Z 86 - -86
unpack_gz_stream_with_info 539 - -539
------------------------------------------------------------------------------
(add/remove: 3/3 grow/shrink: 14/6 up/down: 947/-890) Total: 57 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/bbunzip.c | 78 | ||||
-rw-r--r-- | archival/bzip2.c | 2 | ||||
-rw-r--r-- | archival/gzip.c | 2 | ||||
-rw-r--r-- | archival/libarchive/decompress_bunzip2.c | 18 | ||||
-rw-r--r-- | archival/libarchive/decompress_gunzip.c | 27 | ||||
-rw-r--r-- | archival/libarchive/decompress_uncompress.c | 5 | ||||
-rw-r--r-- | archival/libarchive/decompress_unlzma.c | 2 | ||||
-rw-r--r-- | archival/libarchive/decompress_unxz.c | 12 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar.c | 35 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_bz2.c | 2 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_gz.c | 17 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_lzma.c | 2 | ||||
-rw-r--r-- | archival/libarchive/open_transformer.c | 113 | ||||
-rw-r--r-- | archival/lzop.c | 2 | ||||
-rw-r--r-- | archival/rpm.c | 2 | ||||
-rw-r--r-- | archival/rpm2cpio.c | 73 | ||||
-rw-r--r-- | archival/tar.c | 71 | ||||
-rw-r--r-- | archival/unzip.c | 10 | ||||
-rw-r--r-- | docs/keep_data_small.txt | 2 | ||||
-rw-r--r-- | include/bb_archive.h | 56 | ||||
-rw-r--r-- | include/libbb.h | 14 |
21 files changed, 233 insertions, 312 deletions
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 853c653c0..1bc04ed33 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -33,7 +33,7 @@ char* FAST_FUNC append_ext(char *filename, const char *expected_ext) | |||
33 | } | 33 | } |
34 | 34 | ||
35 | int FAST_FUNC bbunpack(char **argv, | 35 | int FAST_FUNC bbunpack(char **argv, |
36 | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info), | 36 | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux), |
37 | char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), | 37 | char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), |
38 | const char *expected_ext | 38 | const char *expected_ext |
39 | ) | 39 | ) |
@@ -42,7 +42,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
42 | IF_DESKTOP(long long) int status; | 42 | IF_DESKTOP(long long) int status; |
43 | char *filename, *new_name; | 43 | char *filename, *new_name; |
44 | smallint exitcode = 0; | 44 | smallint exitcode = 0; |
45 | unpack_info_t info; | 45 | transformer_aux_data_t aux; |
46 | 46 | ||
47 | do { | 47 | do { |
48 | /* NB: new_name is *maybe* malloc'ed! */ | 48 | /* NB: new_name is *maybe* malloc'ed! */ |
@@ -98,9 +98,9 @@ int FAST_FUNC bbunpack(char **argv, | |||
98 | "use -f to force it"); | 98 | "use -f to force it"); |
99 | } | 99 | } |
100 | 100 | ||
101 | /* memset(&info, 0, sizeof(info)); */ | 101 | init_transformer_aux_data(&aux); |
102 | info.mtime = 0; /* so far it has one member only */ | 102 | aux.check_signature = 1; |
103 | status = unpacker(&info); | 103 | status = unpacker(&aux); |
104 | if (status < 0) | 104 | if (status < 0) |
105 | exitcode = 1; | 105 | exitcode = 1; |
106 | 106 | ||
@@ -111,10 +111,10 @@ int FAST_FUNC bbunpack(char **argv, | |||
111 | char *del = new_name; | 111 | char *del = new_name; |
112 | if (status >= 0) { | 112 | if (status >= 0) { |
113 | /* TODO: restore other things? */ | 113 | /* TODO: restore other things? */ |
114 | if (info.mtime) { | 114 | if (aux.mtime != 0) { |
115 | struct timeval times[2]; | 115 | struct timeval times[2]; |
116 | 116 | ||
117 | times[1].tv_sec = times[0].tv_sec = info.mtime; | 117 | times[1].tv_sec = times[0].tv_sec = aux.mtime; |
118 | times[1].tv_usec = times[0].tv_usec = 0; | 118 | times[1].tv_usec = times[0].tv_usec = 0; |
119 | /* Note: we closed it first. | 119 | /* Note: we closed it first. |
120 | * On some systems calling utimes | 120 | * On some systems calling utimes |
@@ -182,16 +182,9 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) | |||
182 | 182 | ||
183 | #if ENABLE_UNCOMPRESS | 183 | #if ENABLE_UNCOMPRESS |
184 | static | 184 | static |
185 | IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(unpack_info_t *info UNUSED_PARAM) | 185 | IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(transformer_aux_data_t *aux) |
186 | { | 186 | { |
187 | IF_DESKTOP(long long) int status = -1; | 187 | return unpack_Z_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
188 | |||
189 | if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) { | ||
190 | bb_error_msg("invalid magic"); | ||
191 | } else { | ||
192 | status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); | ||
193 | } | ||
194 | return status; | ||
195 | } | 188 | } |
196 | int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 189 | int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
197 | int uncompress_main(int argc UNUSED_PARAM, char **argv) | 190 | int uncompress_main(int argc UNUSED_PARAM, char **argv) |
@@ -279,30 +272,30 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN | |||
279 | return filename; | 272 | return filename; |
280 | } | 273 | } |
281 | static | 274 | static |
282 | IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(unpack_info_t *info) | 275 | IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(transformer_aux_data_t *aux) |
283 | { | 276 | { |
284 | IF_DESKTOP(long long) int status = -1; | 277 | IF_DESKTOP(long long) int status = -1; |
278 | uint16_t magic2; | ||
285 | 279 | ||
286 | /* do the decompression, and cleanup */ | 280 | //TODO: fold below into unpack_gz_stream? Then the whole level of indirection |
287 | if (xread_char(STDIN_FILENO) == 0x1f) { | 281 | // unpack_FOO() -> unpack_FOO_stream can be collapsed in this module! |
288 | unsigned char magic2; | 282 | |
289 | 283 | aux->check_signature = 0; /* we will check it here, not in unpack_*_stream */ | |
290 | magic2 = xread_char(STDIN_FILENO); | 284 | |
291 | if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == 0x9d) { | 285 | if (full_read(STDIN_FILENO, &magic2, 2) != 2) |
292 | status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); | 286 | goto bad_magic; |
293 | } else if (magic2 == 0x8b) { | 287 | if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == COMPRESS_MAGIC) { |
294 | status = unpack_gz_stream_with_info(STDIN_FILENO, STDOUT_FILENO, info); | 288 | status = unpack_Z_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
295 | } else { | 289 | } else if (magic2 == GZIP_MAGIC) { |
296 | goto bad_magic; | 290 | status = unpack_gz_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
297 | } | ||
298 | if (status < 0) { | ||
299 | bb_error_msg("error inflating"); | ||
300 | } | ||
301 | } else { | 291 | } else { |
302 | bad_magic: | 292 | bad_magic: |
303 | bb_error_msg("invalid magic"); | 293 | bb_error_msg("invalid magic"); |
304 | /* status is still == -1 */ | 294 | /* status is still == -1 */ |
305 | } | 295 | } |
296 | if (status < 0) { | ||
297 | bb_error_msg("error inflating"); | ||
298 | } | ||
306 | return status; | 299 | return status; |
307 | } | 300 | } |
308 | /* | 301 | /* |
@@ -352,9 +345,9 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
352 | //applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) | 345 | //applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) |
353 | #if ENABLE_BUNZIP2 | 346 | #if ENABLE_BUNZIP2 |
354 | static | 347 | static |
355 | IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(unpack_info_t *info UNUSED_PARAM) | 348 | IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(transformer_aux_data_t *aux) |
356 | { | 349 | { |
357 | return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO); | 350 | return unpack_bz2_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
358 | } | 351 | } |
359 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 352 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
360 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) | 353 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) |
@@ -420,9 +413,9 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
420 | 413 | ||
421 | #if ENABLE_UNLZMA | 414 | #if ENABLE_UNLZMA |
422 | static | 415 | static |
423 | IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(unpack_info_t *info UNUSED_PARAM) | 416 | IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(transformer_aux_data_t *aux) |
424 | { | 417 | { |
425 | return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO); | 418 | return unpack_lzma_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
426 | } | 419 | } |
427 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 420 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
428 | int unlzma_main(int argc UNUSED_PARAM, char **argv) | 421 | int unlzma_main(int argc UNUSED_PARAM, char **argv) |
@@ -445,18 +438,9 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |||
445 | 438 | ||
446 | #if ENABLE_UNXZ | 439 | #if ENABLE_UNXZ |
447 | static | 440 | static |
448 | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM) | 441 | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(transformer_aux_data_t *aux) |
449 | { | 442 | { |
450 | struct { | 443 | return unpack_xz_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
451 | uint32_t v1; | ||
452 | uint16_t v2; | ||
453 | } magic; | ||
454 | xread(STDIN_FILENO, &magic, 6); | ||
455 | if (magic.v1 != XZ_MAGIC1a || magic.v2 != XZ_MAGIC2a) { | ||
456 | bb_error_msg("invalid magic"); | ||
457 | return -1; | ||
458 | } | ||
459 | return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO); | ||
460 | } | 444 | } |
461 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 445 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
462 | int unxz_main(int argc UNUSED_PARAM, char **argv) | 446 | int unxz_main(int argc UNUSED_PARAM, char **argv) |
diff --git a/archival/bzip2.c b/archival/bzip2.c index 0716fa89b..dd77c8efc 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c | |||
@@ -111,7 +111,7 @@ IF_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, vo | |||
111 | } | 111 | } |
112 | 112 | ||
113 | static | 113 | static |
114 | IF_DESKTOP(long long) int FAST_FUNC compressStream(unpack_info_t *info UNUSED_PARAM) | 114 | IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_aux_data_t *aux UNUSED_PARAM) |
115 | { | 115 | { |
116 | IF_DESKTOP(long long) int total; | 116 | IF_DESKTOP(long long) int total; |
117 | ssize_t count; | 117 | ssize_t count; |
diff --git a/archival/gzip.c b/archival/gzip.c index 929107389..80db4f969 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -2015,7 +2015,7 @@ static void zip(ulg time_stamp) | |||
2015 | 2015 | ||
2016 | /* ======================================================================== */ | 2016 | /* ======================================================================== */ |
2017 | static | 2017 | static |
2018 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(unpack_info_t *info UNUSED_PARAM) | 2018 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_aux_data_t *aux UNUSED_PARAM) |
2019 | { | 2019 | { |
2020 | struct stat s; | 2020 | struct stat s; |
2021 | 2021 | ||
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index c4640d489..dc252bb82 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c | |||
@@ -721,7 +721,7 @@ void FAST_FUNC dealloc_bunzip(bunzip_data *bd) | |||
721 | 721 | ||
722 | /* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */ | 722 | /* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */ |
723 | IF_DESKTOP(long long) int FAST_FUNC | 723 | IF_DESKTOP(long long) int FAST_FUNC |
724 | unpack_bz2_stream(int src_fd, int dst_fd) | 724 | unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
725 | { | 725 | { |
726 | IF_DESKTOP(long long total_written = 0;) | 726 | IF_DESKTOP(long long total_written = 0;) |
727 | bunzip_data *bd; | 727 | bunzip_data *bd; |
@@ -729,6 +729,9 @@ unpack_bz2_stream(int src_fd, int dst_fd) | |||
729 | int i; | 729 | int i; |
730 | unsigned len; | 730 | unsigned len; |
731 | 731 | ||
732 | if (check_signature16(aux, src_fd, BZIP2_MAGIC)) | ||
733 | return -1; | ||
734 | |||
732 | outbuf = xmalloc(IOBUF_SIZE); | 735 | outbuf = xmalloc(IOBUF_SIZE); |
733 | len = 0; | 736 | len = 0; |
734 | while (1) { /* "Process one BZ... stream" loop */ | 737 | while (1) { /* "Process one BZ... stream" loop */ |
@@ -794,17 +797,6 @@ unpack_bz2_stream(int src_fd, int dst_fd) | |||
794 | return i ? i : IF_DESKTOP(total_written) + 0; | 797 | return i ? i : IF_DESKTOP(total_written) + 0; |
795 | } | 798 | } |
796 | 799 | ||
797 | IF_DESKTOP(long long) int FAST_FUNC | ||
798 | unpack_bz2_stream_prime(int src_fd, int dst_fd) | ||
799 | { | ||
800 | uint16_t magic2; | ||
801 | xread(src_fd, &magic2, 2); | ||
802 | if (magic2 != BZIP2_MAGIC) { | ||
803 | bb_error_msg_and_die("invalid magic"); | ||
804 | } | ||
805 | return unpack_bz2_stream(src_fd, dst_fd); | ||
806 | } | ||
807 | |||
808 | #ifdef TESTING | 800 | #ifdef TESTING |
809 | 801 | ||
810 | static char *const bunzip_errors[] = { | 802 | static char *const bunzip_errors[] = { |
@@ -819,7 +811,7 @@ int main(int argc, char **argv) | |||
819 | int i; | 811 | int i; |
820 | char c; | 812 | char c; |
821 | 813 | ||
822 | int i = unpack_bz2_stream_prime(0, 1); | 814 | int i = unpack_bz2_stream(0, 1); |
823 | if (i < 0) | 815 | if (i < 0) |
824 | fprintf(stderr, "%s\n", bunzip_errors[-i]); | 816 | fprintf(stderr, "%s\n", bunzip_errors[-i]); |
825 | else if (read(STDIN_FILENO, &c, 1)) | 817 | else if (read(STDIN_FILENO, &c, 1)) |
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 50873e3f6..f1c9a79e5 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -1034,22 +1034,22 @@ inflate_unzip_internal(STATE_PARAM int in, int out) | |||
1034 | /* For unzip */ | 1034 | /* For unzip */ |
1035 | 1035 | ||
1036 | IF_DESKTOP(long long) int FAST_FUNC | 1036 | IF_DESKTOP(long long) int FAST_FUNC |
1037 | inflate_unzip(inflate_unzip_result *res, off_t compr_size, int in, int out) | 1037 | inflate_unzip(transformer_aux_data_t *aux, int in, int out) |
1038 | { | 1038 | { |
1039 | IF_DESKTOP(long long) int n; | 1039 | IF_DESKTOP(long long) int n; |
1040 | DECLARE_STATE; | 1040 | DECLARE_STATE; |
1041 | 1041 | ||
1042 | ALLOC_STATE; | 1042 | ALLOC_STATE; |
1043 | 1043 | ||
1044 | to_read = compr_size; | 1044 | to_read = aux->bytes_in; |
1045 | // bytebuffer_max = 0x8000; | 1045 | // bytebuffer_max = 0x8000; |
1046 | bytebuffer_offset = 4; | 1046 | bytebuffer_offset = 4; |
1047 | bytebuffer = xmalloc(bytebuffer_max); | 1047 | bytebuffer = xmalloc(bytebuffer_max); |
1048 | n = inflate_unzip_internal(PASS_STATE in, out); | 1048 | n = inflate_unzip_internal(PASS_STATE in, out); |
1049 | free(bytebuffer); | 1049 | free(bytebuffer); |
1050 | 1050 | ||
1051 | res->crc = gunzip_crc; | 1051 | aux->crc32 = gunzip_crc; |
1052 | res->bytes_out = gunzip_bytes_out; | 1052 | aux->bytes_out = gunzip_bytes_out; |
1053 | DEALLOC_STATE; | 1053 | DEALLOC_STATE; |
1054 | return n; | 1054 | return n; |
1055 | } | 1055 | } |
@@ -1107,7 +1107,7 @@ static uint32_t buffer_read_le_u32(STATE_PARAM_ONLY) | |||
1107 | return res; | 1107 | return res; |
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | static int check_header_gzip(STATE_PARAM unpack_info_t *info) | 1110 | static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux) |
1111 | { | 1111 | { |
1112 | union { | 1112 | union { |
1113 | unsigned char raw[8]; | 1113 | unsigned char raw[8]; |
@@ -1169,8 +1169,8 @@ static int check_header_gzip(STATE_PARAM unpack_info_t *info) | |||
1169 | } | 1169 | } |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | if (info) | 1172 | if (aux) |
1173 | info->mtime = SWAP_LE32(header.formatted.mtime); | 1173 | aux->mtime = SWAP_LE32(header.formatted.mtime); |
1174 | 1174 | ||
1175 | /* Read the header checksum */ | 1175 | /* Read the header checksum */ |
1176 | if (header.formatted.flags & 0x02) { | 1176 | if (header.formatted.flags & 0x02) { |
@@ -1182,12 +1182,15 @@ static int check_header_gzip(STATE_PARAM unpack_info_t *info) | |||
1182 | } | 1182 | } |
1183 | 1183 | ||
1184 | IF_DESKTOP(long long) int FAST_FUNC | 1184 | IF_DESKTOP(long long) int FAST_FUNC |
1185 | unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) | 1185 | unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
1186 | { | 1186 | { |
1187 | uint32_t v32; | 1187 | uint32_t v32; |
1188 | IF_DESKTOP(long long) int total, n; | 1188 | IF_DESKTOP(long long) int total, n; |
1189 | DECLARE_STATE; | 1189 | DECLARE_STATE; |
1190 | 1190 | ||
1191 | if (check_signature16(aux, src_fd, GZIP_MAGIC)) | ||
1192 | return -1; | ||
1193 | |||
1191 | total = 0; | 1194 | total = 0; |
1192 | 1195 | ||
1193 | ALLOC_STATE; | 1196 | ALLOC_STATE; |
@@ -1197,7 +1200,7 @@ unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) | |||
1197 | gunzip_src_fd = src_fd; | 1200 | gunzip_src_fd = src_fd; |
1198 | 1201 | ||
1199 | again: | 1202 | again: |
1200 | if (!check_header_gzip(PASS_STATE info)) { | 1203 | if (!check_header_gzip(PASS_STATE aux)) { |
1201 | bb_error_msg("corrupted data"); | 1204 | bb_error_msg("corrupted data"); |
1202 | total = -1; | 1205 | total = -1; |
1203 | goto ret; | 1206 | goto ret; |
@@ -1248,9 +1251,3 @@ unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) | |||
1248 | DEALLOC_STATE; | 1251 | DEALLOC_STATE; |
1249 | return total; | 1252 | return total; |
1250 | } | 1253 | } |
1251 | |||
1252 | IF_DESKTOP(long long) int FAST_FUNC | ||
1253 | unpack_gz_stream(int in, int out) | ||
1254 | { | ||
1255 | return unpack_gz_stream_with_info(in, out, NULL); | ||
1256 | } | ||
diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c index 289f9e233..e9bbfb9bd 100644 --- a/archival/libarchive/decompress_uncompress.c +++ b/archival/libarchive/decompress_uncompress.c | |||
@@ -73,7 +73,7 @@ | |||
73 | */ | 73 | */ |
74 | 74 | ||
75 | IF_DESKTOP(long long) int FAST_FUNC | 75 | IF_DESKTOP(long long) int FAST_FUNC |
76 | unpack_Z_stream(int src_fd, int dst_fd) | 76 | unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
77 | { | 77 | { |
78 | IF_DESKTOP(long long total_written = 0;) | 78 | IF_DESKTOP(long long total_written = 0;) |
79 | IF_DESKTOP(long long) int retval = -1; | 79 | IF_DESKTOP(long long) int retval = -1; |
@@ -103,6 +103,9 @@ unpack_Z_stream(int src_fd, int dst_fd) | |||
103 | /* block compress mode -C compatible with 2.0 */ | 103 | /* block compress mode -C compatible with 2.0 */ |
104 | int block_mode; /* = BLOCK_MODE; */ | 104 | int block_mode; /* = BLOCK_MODE; */ |
105 | 105 | ||
106 | if (check_signature16(aux, src_fd, COMPRESS_MAGIC)) | ||
107 | return -1; | ||
108 | |||
106 | inbuf = xzalloc(IBUFSIZ + 64); | 109 | inbuf = xzalloc(IBUFSIZ + 64); |
107 | outbuf = xzalloc(OBUFSIZ + 2048); | 110 | outbuf = xzalloc(OBUFSIZ + 2048); |
108 | htab = xzalloc(HSIZE); /* wasn't zeroed out before, maybe can xmalloc? */ | 111 | htab = xzalloc(HSIZE); /* wasn't zeroed out before, maybe can xmalloc? */ |
diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index 3631b50cc..cfde8ea56 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c | |||
@@ -213,7 +213,7 @@ enum { | |||
213 | 213 | ||
214 | 214 | ||
215 | IF_DESKTOP(long long) int FAST_FUNC | 215 | IF_DESKTOP(long long) int FAST_FUNC |
216 | unpack_lzma_stream(int src_fd, int dst_fd) | 216 | unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst_fd) |
217 | { | 217 | { |
218 | IF_DESKTOP(long long total_written = 0;) | 218 | IF_DESKTOP(long long total_written = 0;) |
219 | lzma_header_t header; | 219 | lzma_header_t header; |
diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index 3e5d4edca..79b48a152 100644 --- a/archival/libarchive/decompress_unxz.c +++ b/archival/libarchive/decompress_unxz.c | |||
@@ -38,7 +38,7 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) | |||
38 | #include "unxz/xz_dec_stream.c" | 38 | #include "unxz/xz_dec_stream.c" |
39 | 39 | ||
40 | IF_DESKTOP(long long) int FAST_FUNC | 40 | IF_DESKTOP(long long) int FAST_FUNC |
41 | unpack_xz_stream(int src_fd, int dst_fd) | 41 | unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
42 | { | 42 | { |
43 | struct xz_buf iobuf; | 43 | struct xz_buf iobuf; |
44 | struct xz_dec *state; | 44 | struct xz_dec *state; |
@@ -49,13 +49,17 @@ unpack_xz_stream(int src_fd, int dst_fd) | |||
49 | global_crc32_table = crc32_filltable(NULL, /*endian:*/ 0); | 49 | global_crc32_table = crc32_filltable(NULL, /*endian:*/ 0); |
50 | 50 | ||
51 | memset(&iobuf, 0, sizeof(iobuf)); | 51 | memset(&iobuf, 0, sizeof(iobuf)); |
52 | /* Preload XZ file signature */ | 52 | membuf = xmalloc(2 * BUFSIZ); |
53 | membuf = (void*) strcpy(xmalloc(2 * BUFSIZ), HEADER_MAGIC); | ||
54 | iobuf.in = membuf; | 53 | iobuf.in = membuf; |
55 | iobuf.in_size = HEADER_MAGIC_SIZE; | ||
56 | iobuf.out = membuf + BUFSIZ; | 54 | iobuf.out = membuf + BUFSIZ; |
57 | iobuf.out_size = BUFSIZ; | 55 | iobuf.out_size = BUFSIZ; |
58 | 56 | ||
57 | if (!aux || aux->check_signature == 0) { | ||
58 | /* Preload XZ file signature */ | ||
59 | strcpy((char*)membuf, HEADER_MAGIC); | ||
60 | iobuf.in_size = HEADER_MAGIC_SIZE; | ||
61 | } /* else: let xz code read & check it */ | ||
62 | |||
59 | /* Limit memory usage to about 64 MiB. */ | 63 | /* Limit memory usage to about 64 MiB. */ |
60 | state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024); | 64 | state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024); |
61 | 65 | ||
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 8c699754b..80a709144 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -235,43 +235,18 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
235 | || memcmp(tar.magic, "\0\0\0\0", 5) != 0) | 235 | || memcmp(tar.magic, "\0\0\0\0", 5) != 0) |
236 | ) { | 236 | ) { |
237 | #if ENABLE_FEATURE_TAR_AUTODETECT | 237 | #if ENABLE_FEATURE_TAR_AUTODETECT |
238 | char FAST_FUNC (*get_header_ptr)(archive_handle_t *); | ||
239 | uint16_t magic2; | ||
240 | |||
241 | autodetect: | 238 | autodetect: |
242 | magic2 = *(bb__aliased_uint16_t*)tar.name; | ||
243 | /* tar gz/bz autodetect: check for gz/bz2 magic. | ||
244 | * If we see the magic, and it is the very first block, | ||
245 | * we can switch to get_header_tar_gz/bz2/lzma(). | ||
246 | * Needs seekable fd. I wish recv(MSG_PEEK) works | ||
247 | * on any fd... */ | ||
248 | # if ENABLE_FEATURE_SEAMLESS_GZ | ||
249 | if (magic2 == GZIP_MAGIC) { | ||
250 | get_header_ptr = get_header_tar_gz; | ||
251 | } else | ||
252 | # endif | ||
253 | # if ENABLE_FEATURE_SEAMLESS_BZ2 | ||
254 | if (magic2 == BZIP2_MAGIC | ||
255 | && tar.name[2] == 'h' && isdigit(tar.name[3]) | ||
256 | ) { /* bzip2 */ | ||
257 | get_header_ptr = get_header_tar_bz2; | ||
258 | } else | ||
259 | # endif | ||
260 | # if ENABLE_FEATURE_SEAMLESS_XZ | ||
261 | //TODO: if (magic2 == XZ_MAGIC1)... | ||
262 | //else | ||
263 | # endif | ||
264 | goto err; | ||
265 | /* Two different causes for lseek() != 0: | 239 | /* Two different causes for lseek() != 0: |
266 | * unseekable fd (would like to support that too, but...), | 240 | * unseekable fd (would like to support that too, but...), |
267 | * or not first block (false positive, it's not .gz/.bz2!) */ | 241 | * or not first block (false positive, it's not .gz/.bz2!) */ |
268 | if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0) | 242 | if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0) |
269 | goto err; | 243 | goto err; |
270 | while (get_header_ptr(archive_handle) == EXIT_SUCCESS) | 244 | if (setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_detected:*/ 0) != 0) |
271 | continue; | ||
272 | return EXIT_FAILURE; | ||
273 | err: | 245 | err: |
274 | #endif /* FEATURE_TAR_AUTODETECT */ | 246 | bb_error_msg_and_die("invalid tar magic"); |
247 | archive_handle->offset = 0; | ||
248 | goto again_after_align; | ||
249 | #endif | ||
275 | bb_error_msg_and_die("invalid tar magic"); | 250 | bb_error_msg_and_die("invalid tar magic"); |
276 | } | 251 | } |
277 | 252 | ||
diff --git a/archival/libarchive/get_header_tar_bz2.c b/archival/libarchive/get_header_tar_bz2.c index e012dec3b..0ee00df53 100644 --- a/archival/libarchive/get_header_tar_bz2.c +++ b/archival/libarchive/get_header_tar_bz2.c | |||
@@ -11,7 +11,7 @@ char FAST_FUNC get_header_tar_bz2(archive_handle_t *archive_handle) | |||
11 | /* Can't lseek over pipes */ | 11 | /* Can't lseek over pipes */ |
12 | archive_handle->seek = seek_by_read; | 12 | archive_handle->seek = seek_by_read; |
13 | 13 | ||
14 | open_transformer(archive_handle->src_fd, unpack_bz2_stream_prime, "bunzip2"); | 14 | open_transformer_with_sig(archive_handle->src_fd, unpack_bz2_stream, "bunzip2"); |
15 | archive_handle->offset = 0; | 15 | archive_handle->offset = 0; |
16 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) | 16 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) |
17 | continue; | 17 | continue; |
diff --git a/archival/libarchive/get_header_tar_gz.c b/archival/libarchive/get_header_tar_gz.c index b9679b0bd..03284342b 100644 --- a/archival/libarchive/get_header_tar_gz.c +++ b/archival/libarchive/get_header_tar_gz.c | |||
@@ -8,25 +8,10 @@ | |||
8 | 8 | ||
9 | char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) | 9 | char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) |
10 | { | 10 | { |
11 | #if BB_MMU | ||
12 | uint16_t magic; | ||
13 | #endif | ||
14 | |||
15 | /* Can't lseek over pipes */ | 11 | /* Can't lseek over pipes */ |
16 | archive_handle->seek = seek_by_read; | 12 | archive_handle->seek = seek_by_read; |
17 | 13 | ||
18 | /* Check gzip magic only if open_transformer will invoke unpack_gz_stream (MMU case). | 14 | open_transformer_with_sig(archive_handle->src_fd, unpack_gz_stream, "gunzip"); |
19 | * Otherwise, it will invoke an external helper "gunzip -cf" (NOMMU case) which will | ||
20 | * need the header. */ | ||
21 | #if BB_MMU | ||
22 | xread(archive_handle->src_fd, &magic, 2); | ||
23 | /* Can skip this check, but error message will be less clear */ | ||
24 | if (magic != GZIP_MAGIC) { | ||
25 | bb_error_msg_and_die("invalid gzip magic"); | ||
26 | } | ||
27 | #endif | ||
28 | |||
29 | open_transformer(archive_handle->src_fd, unpack_gz_stream, "gunzip"); | ||
30 | archive_handle->offset = 0; | 15 | archive_handle->offset = 0; |
31 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) | 16 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) |
32 | continue; | 17 | continue; |
diff --git a/archival/libarchive/get_header_tar_lzma.c b/archival/libarchive/get_header_tar_lzma.c index 666700729..d565a217d 100644 --- a/archival/libarchive/get_header_tar_lzma.c +++ b/archival/libarchive/get_header_tar_lzma.c | |||
@@ -14,7 +14,7 @@ char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle) | |||
14 | /* Can't lseek over pipes */ | 14 | /* Can't lseek over pipes */ |
15 | archive_handle->seek = seek_by_read; | 15 | archive_handle->seek = seek_by_read; |
16 | 16 | ||
17 | open_transformer(archive_handle->src_fd, unpack_lzma_stream, "unlzma"); | 17 | open_transformer_with_sig(archive_handle->src_fd, unpack_lzma_stream, "unlzma"); |
18 | archive_handle->offset = 0; | 18 | archive_handle->offset = 0; |
19 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) | 19 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) |
20 | continue; | 20 | continue; |
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 743ffee02..693ae9995 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
@@ -6,24 +6,36 @@ | |||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "bb_archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | #define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \ | 9 | void FAST_FUNC init_transformer_aux_data(transformer_aux_data_t *aux) |
10 | || ENABLE_FEATURE_SEAMLESS_BZ2 \ | 10 | { |
11 | || ENABLE_FEATURE_SEAMLESS_GZ \ | 11 | memset(aux, 0, sizeof(*aux)); |
12 | /* || ENABLE_FEATURE_SEAMLESS_Z */ \ | 12 | } |
13 | ) | ||
14 | 13 | ||
15 | #if ZIPPED | 14 | int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16) |
16 | # include "bb_archive.h" | 15 | { |
16 | if (aux && aux->check_signature) { | ||
17 | uint16_t magic2; | ||
18 | if (full_read(src_fd, &magic2, 2) != 2 || magic2 != magic16) { | ||
19 | bb_error_msg("invalid magic"); | ||
20 | #if 0 /* possible future extension */ | ||
21 | if (aux->check_signature > 1) | ||
22 | xfunc_die(); | ||
17 | #endif | 23 | #endif |
24 | return -1; | ||
25 | } | ||
26 | } | ||
27 | return 0; | ||
28 | } | ||
18 | 29 | ||
19 | /* transformer(), more than meets the eye */ | 30 | /* transformer(), more than meets the eye */ |
20 | /* | 31 | #if BB_MMU |
21 | * On MMU machine, the transform_prog is removed by macro magic | ||
22 | * in include/archive.h. On NOMMU, transformer is removed. | ||
23 | */ | ||
24 | void FAST_FUNC open_transformer(int fd, | 32 | void FAST_FUNC open_transformer(int fd, |
25 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), | 33 | int check_signature, |
26 | const char *transform_prog) | 34 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
35 | ) | ||
36 | #else | ||
37 | void FAST_FUNC open_transformer(int fd, const char *transform_prog) | ||
38 | #endif | ||
27 | { | 39 | { |
28 | struct fd_pair fd_pipe; | 40 | struct fd_pair fd_pipe; |
29 | int pid; | 41 | int pid; |
@@ -35,13 +47,18 @@ void FAST_FUNC open_transformer(int fd, | |||
35 | close(fd_pipe.rd); /* we don't want to read from the parent */ | 47 | close(fd_pipe.rd); /* we don't want to read from the parent */ |
36 | // FIXME: error check? | 48 | // FIXME: error check? |
37 | #if BB_MMU | 49 | #if BB_MMU |
38 | transformer(fd, fd_pipe.wr); | 50 | { |
39 | if (ENABLE_FEATURE_CLEAN_UP) { | 51 | transformer_aux_data_t aux; |
40 | close(fd_pipe.wr); /* send EOF */ | 52 | init_transformer_aux_data(&aux); |
41 | close(fd); | 53 | aux.check_signature = check_signature; |
54 | transformer(&aux, fd, fd_pipe.wr); | ||
55 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
56 | close(fd_pipe.wr); /* send EOF */ | ||
57 | close(fd); | ||
58 | } | ||
59 | /* must be _exit! bug was actually seen here */ | ||
60 | _exit(EXIT_SUCCESS); | ||
42 | } | 61 | } |
43 | /* must be _exit! bug was actually seen here */ | ||
44 | _exit(EXIT_SUCCESS); | ||
45 | #else | 62 | #else |
46 | { | 63 | { |
47 | char *argv[4]; | 64 | char *argv[4]; |
@@ -64,26 +81,21 @@ void FAST_FUNC open_transformer(int fd, | |||
64 | } | 81 | } |
65 | 82 | ||
66 | 83 | ||
84 | #if SEAMLESS_COMPRESSION | ||
85 | |||
67 | /* Used by e.g. rpm which gives us a fd without filename, | 86 | /* Used by e.g. rpm which gives us a fd without filename, |
68 | * thus we can't guess the format from filename's extension. | 87 | * thus we can't guess the format from filename's extension. |
69 | */ | 88 | */ |
70 | #if ZIPPED | 89 | int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_detected) |
71 | void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | ||
72 | { | 90 | { |
73 | const int fail_if_not_detected = 1; | ||
74 | union { | 91 | union { |
75 | uint8_t b[4]; | 92 | uint8_t b[4]; |
76 | uint16_t b16[2]; | 93 | uint16_t b16[2]; |
77 | uint32_t b32[1]; | 94 | uint32_t b32[1]; |
78 | } magic; | 95 | } magic; |
79 | int offset = -2; | 96 | int offset = -2; |
80 | # if BB_MMU | 97 | USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) |
81 | IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); | 98 | USE_FOR_NOMMU(const char *xformer_prog;) |
82 | enum { xformer_prog = 0 }; | ||
83 | # else | ||
84 | enum { xformer = 0 }; | ||
85 | const char *xformer_prog; | ||
86 | # endif | ||
87 | 99 | ||
88 | /* .gz and .bz2 both have 2-byte signature, and their | 100 | /* .gz and .bz2 both have 2-byte signature, and their |
89 | * unpack_XXX_stream wants this header skipped. */ | 101 | * unpack_XXX_stream wants this header skipped. */ |
@@ -91,21 +103,15 @@ void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | |||
91 | if (ENABLE_FEATURE_SEAMLESS_GZ | 103 | if (ENABLE_FEATURE_SEAMLESS_GZ |
92 | && magic.b16[0] == GZIP_MAGIC | 104 | && magic.b16[0] == GZIP_MAGIC |
93 | ) { | 105 | ) { |
94 | # if BB_MMU | 106 | USE_FOR_MMU(xformer = unpack_gz_stream;) |
95 | xformer = unpack_gz_stream; | 107 | USE_FOR_NOMMU(xformer_prog = "gunzip";) |
96 | # else | ||
97 | xformer_prog = "gunzip"; | ||
98 | # endif | ||
99 | goto found_magic; | 108 | goto found_magic; |
100 | } | 109 | } |
101 | if (ENABLE_FEATURE_SEAMLESS_BZ2 | 110 | if (ENABLE_FEATURE_SEAMLESS_BZ2 |
102 | && magic.b16[0] == BZIP2_MAGIC | 111 | && magic.b16[0] == BZIP2_MAGIC |
103 | ) { | 112 | ) { |
104 | # if BB_MMU | 113 | USE_FOR_MMU(xformer = unpack_bz2_stream;) |
105 | xformer = unpack_bz2_stream; | 114 | USE_FOR_NOMMU(xformer_prog = "bunzip2";) |
106 | # else | ||
107 | xformer_prog = "bunzip2"; | ||
108 | # endif | ||
109 | goto found_magic; | 115 | goto found_magic; |
110 | } | 116 | } |
111 | if (ENABLE_FEATURE_SEAMLESS_XZ | 117 | if (ENABLE_FEATURE_SEAMLESS_XZ |
@@ -114,13 +120,8 @@ void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | |||
114 | offset = -6; | 120 | offset = -6; |
115 | xread(fd, magic.b32, sizeof(magic.b32[0])); | 121 | xread(fd, magic.b32, sizeof(magic.b32[0])); |
116 | if (magic.b32[0] == XZ_MAGIC2) { | 122 | if (magic.b32[0] == XZ_MAGIC2) { |
117 | # if BB_MMU | 123 | USE_FOR_MMU(xformer = unpack_xz_stream;) |
118 | xformer = unpack_xz_stream; | 124 | USE_FOR_NOMMU(xformer_prog = "unxz";) |
119 | /* unpack_xz_stream wants fd at position 6, no need to seek */ | ||
120 | //xlseek(fd, offset, SEEK_CUR); | ||
121 | # else | ||
122 | xformer_prog = "unxz"; | ||
123 | # endif | ||
124 | goto found_magic; | 125 | goto found_magic; |
125 | } | 126 | } |
126 | } | 127 | } |
@@ -132,24 +133,23 @@ void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | |||
132 | IF_FEATURE_SEAMLESS_XZ("/xz") | 133 | IF_FEATURE_SEAMLESS_XZ("/xz") |
133 | " magic"); | 134 | " magic"); |
134 | xlseek(fd, offset, SEEK_CUR); | 135 | xlseek(fd, offset, SEEK_CUR); |
135 | return; | 136 | return 1; |
136 | 137 | ||
137 | found_magic: | 138 | found_magic: |
138 | # if !BB_MMU | 139 | # if BB_MMU |
140 | open_transformer_with_no_sig(fd, xformer); | ||
141 | # else | ||
139 | /* NOMMU version of open_transformer execs | 142 | /* NOMMU version of open_transformer execs |
140 | * an external unzipper that wants | 143 | * an external unzipper that wants |
141 | * file position at the start of the file */ | 144 | * file position at the start of the file */ |
142 | xlseek(fd, offset, SEEK_CUR); | 145 | xlseek(fd, offset, SEEK_CUR); |
146 | open_transformer_with_sig(fd, xformer, xformer_prog); | ||
143 | # endif | 147 | # endif |
144 | open_transformer(fd, xformer, xformer_prog); | 148 | return 0; |
145 | } | 149 | } |
146 | #endif /* ZIPPED */ | ||
147 | 150 | ||
148 | int FAST_FUNC open_zipped(const char *fname) | 151 | int FAST_FUNC open_zipped(const char *fname) |
149 | { | 152 | { |
150 | #if !ZIPPED | ||
151 | return open(fname, O_RDONLY); | ||
152 | #else | ||
153 | char *sfx; | 153 | char *sfx; |
154 | int fd; | 154 | int fd; |
155 | 155 | ||
@@ -162,20 +162,21 @@ int FAST_FUNC open_zipped(const char *fname) | |||
162 | sfx++; | 162 | sfx++; |
163 | if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0) | 163 | if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0) |
164 | /* .lzma has no header/signature, just trust it */ | 164 | /* .lzma has no header/signature, just trust it */ |
165 | open_transformer(fd, unpack_lzma_stream, "unlzma"); | 165 | open_transformer_with_sig(fd, unpack_lzma_stream, "unlzma"); |
166 | else | 166 | else |
167 | if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0) | 167 | if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0) |
168 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0) | 168 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0) |
169 | || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0) | 169 | || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0) |
170 | ) { | 170 | ) { |
171 | setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/); | 171 | setup_unzip_on_fd(fd, /*fail_if_not_detected:*/ 1); |
172 | } | 172 | } |
173 | } | 173 | } |
174 | 174 | ||
175 | return fd; | 175 | return fd; |
176 | #endif | ||
177 | } | 176 | } |
178 | 177 | ||
178 | #endif /* SEAMLESS_COMPRESSION */ | ||
179 | |||
179 | void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) | 180 | void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) |
180 | { | 181 | { |
181 | int fd; | 182 | int fd; |
diff --git a/archival/lzop.c b/archival/lzop.c index 67baeff7e..fbe08417d 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -1077,7 +1077,7 @@ static char* FAST_FUNC make_new_name_lzop(char *filename, const char *expected_e | |||
1077 | return xasprintf("%s.lzo", filename); | 1077 | return xasprintf("%s.lzo", filename); |
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(unpack_info_t *info UNUSED_PARAM) | 1080 | static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(transformer_aux_data_t *aux UNUSED_PARAM) |
1081 | { | 1081 | { |
1082 | if (option_mask32 & OPT_DECOMPRESS) | 1082 | if (option_mask32 & OPT_DECOMPRESS) |
1083 | return do_lzo_decompress(); | 1083 | return do_lzo_decompress(); |
diff --git a/archival/rpm.c b/archival/rpm.c index 089b68983..6757a6ceb 100644 --- a/archival/rpm.c +++ b/archival/rpm.c | |||
@@ -236,7 +236,7 @@ static void extract_cpio(int fd, const char *source_rpm) | |||
236 | archive_handle->src_fd = fd; | 236 | archive_handle->src_fd = fd; |
237 | /*archive_handle->offset = 0; - init_handle() did it */ | 237 | /*archive_handle->offset = 0; - init_handle() did it */ |
238 | 238 | ||
239 | setup_unzip_on_fd(archive_handle->src_fd /*, fail_if_not_detected: 1*/); | 239 | setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_detected:*/ 1); |
240 | while (get_header_cpio(archive_handle) == EXIT_SUCCESS) | 240 | while (get_header_cpio(archive_handle) == EXIT_SUCCESS) |
241 | continue; | 241 | continue; |
242 | } | 242 | } |
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index 28b43a181..7256aae6b 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c | |||
@@ -42,6 +42,26 @@ static unsigned skip_header(void) | |||
42 | return sizeof(header) + len; | 42 | return sizeof(header) + len; |
43 | } | 43 | } |
44 | 44 | ||
45 | #if SEAMLESS_COMPRESSION | ||
46 | static void handle_SIGCHLD(int signo UNUSED_PARAM) | ||
47 | { | ||
48 | int status; | ||
49 | |||
50 | /* Wait for any child without blocking */ | ||
51 | for (;;) { | ||
52 | if (wait_any_nohang(&status) < 0) | ||
53 | /* wait failed?! I'm confused... */ | ||
54 | return; | ||
55 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) | ||
56 | /* this child exited with 0 */ | ||
57 | continue; | ||
58 | /* Cannot happen? | ||
59 | if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */ | ||
60 | bb_got_signal = 1; | ||
61 | } | ||
62 | } | ||
63 | #endif | ||
64 | |||
45 | /* No getopt required */ | 65 | /* No getopt required */ |
46 | int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 66 | int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
47 | int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | 67 | int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) |
@@ -66,54 +86,23 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |||
66 | /* Skip the main header */ | 86 | /* Skip the main header */ |
67 | skip_header(); | 87 | skip_header(); |
68 | 88 | ||
69 | #if 0 | 89 | #if SEAMLESS_COMPRESSION |
90 | /* We need to know whether child (gzip/bzip/etc) exits abnormally */ | ||
91 | signal(SIGCHLD, handle_SIGCHLD); | ||
92 | #endif | ||
93 | |||
70 | /* This works, but doesn't report uncompress errors (they happen in child) */ | 94 | /* This works, but doesn't report uncompress errors (they happen in child) */ |
71 | setup_unzip_on_fd(rpm_fd /*fail_if_not_detected: 1*/); | 95 | setup_unzip_on_fd(rpm_fd, /*fail_if_not_detected:*/ 1); |
72 | if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) | 96 | if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) |
73 | bb_error_msg_and_die("error unpacking"); | 97 | bb_error_msg_and_die("error unpacking"); |
74 | #else | ||
75 | /* BLOAT */ | ||
76 | { | ||
77 | union { | ||
78 | uint8_t b[4]; | ||
79 | uint16_t b16[2]; | ||
80 | uint32_t b32[1]; | ||
81 | } magic; | ||
82 | IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd); | ||
83 | |||
84 | xread(rpm_fd, magic.b16, sizeof(magic.b16[0])); | ||
85 | if (magic.b16[0] == GZIP_MAGIC) { | ||
86 | unpack = unpack_gz_stream; | ||
87 | } else | ||
88 | if (ENABLE_FEATURE_SEAMLESS_BZ2 | ||
89 | && magic.b16[0] == BZIP2_MAGIC | ||
90 | ) { | ||
91 | unpack = unpack_bz2_stream; | ||
92 | } else | ||
93 | if (ENABLE_FEATURE_SEAMLESS_XZ | ||
94 | && magic.b16[0] == XZ_MAGIC1 | ||
95 | ) { | ||
96 | xread(rpm_fd, magic.b32, sizeof(magic.b32[0])); | ||
97 | if (magic.b32[0] != XZ_MAGIC2) | ||
98 | goto no_magic; | ||
99 | /* unpack_xz_stream wants fd at position 6, no need to seek */ | ||
100 | //xlseek(rpm_fd, -6, SEEK_CUR); | ||
101 | unpack = unpack_xz_stream; | ||
102 | } else { | ||
103 | no_magic: | ||
104 | bb_error_msg_and_die("no gzip" | ||
105 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | ||
106 | IF_FEATURE_SEAMLESS_XZ("/xz") | ||
107 | " magic"); | ||
108 | } | ||
109 | if (unpack(rpm_fd, STDOUT_FILENO) < 0) | ||
110 | bb_error_msg_and_die("error unpacking"); | ||
111 | } | ||
112 | #endif | ||
113 | 98 | ||
114 | if (ENABLE_FEATURE_CLEAN_UP) { | 99 | if (ENABLE_FEATURE_CLEAN_UP) { |
115 | close(rpm_fd); | 100 | close(rpm_fd); |
116 | } | 101 | } |
117 | 102 | ||
118 | return 0; | 103 | #if SEAMLESS_COMPRESSION |
104 | return bb_got_signal; | ||
105 | #else | ||
106 | return EXIT_SUCCESS; | ||
107 | #endif | ||
119 | } | 108 | } |
diff --git a/archival/tar.c b/archival/tar.c index 766b79b2b..af38ac59f 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -690,31 +690,6 @@ static llist_t *append_file_list_to_list(llist_t *list) | |||
690 | # define append_file_list_to_list(x) 0 | 690 | # define append_file_list_to_list(x) 0 |
691 | #endif | 691 | #endif |
692 | 692 | ||
693 | #if ENABLE_FEATURE_SEAMLESS_Z | ||
694 | static char FAST_FUNC get_header_tar_Z(archive_handle_t *archive_handle) | ||
695 | { | ||
696 | /* Can't lseek over pipes */ | ||
697 | archive_handle->seek = seek_by_read; | ||
698 | |||
699 | /* do the decompression, and cleanup */ | ||
700 | if (xread_char(archive_handle->src_fd) != 0x1f | ||
701 | || xread_char(archive_handle->src_fd) != 0x9d | ||
702 | ) { | ||
703 | bb_error_msg_and_die("invalid magic"); | ||
704 | } | ||
705 | |||
706 | open_transformer(archive_handle->src_fd, unpack_Z_stream, "uncompress"); | ||
707 | archive_handle->offset = 0; | ||
708 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) | ||
709 | continue; | ||
710 | |||
711 | /* Can only do one file at a time */ | ||
712 | return EXIT_FAILURE; | ||
713 | } | ||
714 | #else | ||
715 | # define get_header_tar_Z NULL | ||
716 | #endif | ||
717 | |||
718 | #ifdef CHECK_FOR_CHILD_EXITCODE | 693 | #ifdef CHECK_FOR_CHILD_EXITCODE |
719 | /* Looks like it isn't needed - tar detects malformed (truncated) | 694 | /* Looks like it isn't needed - tar detects malformed (truncated) |
720 | * archive if e.g. bunzip2 fails */ | 695 | * archive if e.g. bunzip2 fails */ |
@@ -843,6 +818,8 @@ enum { | |||
843 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner | 818 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
844 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions | 819 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions |
845 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite | 820 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite |
821 | |||
822 | OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_COMPRESS), | ||
846 | }; | 823 | }; |
847 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 824 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
848 | static const char tar_longopts[] ALIGN1 = | 825 | static const char tar_longopts[] ALIGN1 = |
@@ -901,7 +878,6 @@ static const char tar_longopts[] ALIGN1 = | |||
901 | int tar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 878 | int tar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
902 | int tar_main(int argc UNUSED_PARAM, char **argv) | 879 | int tar_main(int argc UNUSED_PARAM, char **argv) |
903 | { | 880 | { |
904 | char FAST_FUNC (*get_header_ptr)(archive_handle_t *) = get_header_tar; | ||
905 | archive_handle_t *tar_handle; | 881 | archive_handle_t *tar_handle; |
906 | char *base_dir = NULL; | 882 | char *base_dir = NULL; |
907 | const char *tar_filename = "-"; | 883 | const char *tar_filename = "-"; |
@@ -1017,18 +993,6 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1017 | tar_handle->ah_flags |= ARCHIVE_O_TRUNC; | 993 | tar_handle->ah_flags |= ARCHIVE_O_TRUNC; |
1018 | } | 994 | } |
1019 | 995 | ||
1020 | if (opt & OPT_GZIP) | ||
1021 | get_header_ptr = get_header_tar_gz; | ||
1022 | |||
1023 | if (opt & OPT_BZIP2) | ||
1024 | get_header_ptr = get_header_tar_bz2; | ||
1025 | |||
1026 | if (opt & OPT_LZMA) | ||
1027 | get_header_ptr = get_header_tar_lzma; | ||
1028 | |||
1029 | if (opt & OPT_COMPRESS) | ||
1030 | get_header_ptr = get_header_tar_Z; | ||
1031 | |||
1032 | if (opt & OPT_NOPRESERVE_TIME) | 996 | if (opt & OPT_NOPRESERVE_TIME) |
1033 | tar_handle->ah_flags &= ~ARCHIVE_RESTORE_DATE; | 997 | tar_handle->ah_flags &= ~ARCHIVE_RESTORE_DATE; |
1034 | 998 | ||
@@ -1081,7 +1045,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1081 | } else { | 1045 | } else { |
1082 | if (ENABLE_FEATURE_TAR_AUTODETECT | 1046 | if (ENABLE_FEATURE_TAR_AUTODETECT |
1083 | && flags == O_RDONLY | 1047 | && flags == O_RDONLY |
1084 | && get_header_ptr == get_header_tar | 1048 | && !(opt & OPT_ANY_COMPRESS) |
1085 | ) { | 1049 | ) { |
1086 | tar_handle->src_fd = open_zipped(tar_filename); | 1050 | tar_handle->src_fd = open_zipped(tar_filename); |
1087 | if (tar_handle->src_fd < 0) | 1051 | if (tar_handle->src_fd < 0) |
@@ -1115,7 +1079,30 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1115 | tar_handle->reject, zipMode); | 1079 | tar_handle->reject, zipMode); |
1116 | } | 1080 | } |
1117 | 1081 | ||
1118 | while (get_header_ptr(tar_handle) == EXIT_SUCCESS) | 1082 | if (opt & OPT_ANY_COMPRESS) { |
1083 | USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) | ||
1084 | USE_FOR_NOMMU(const char *xformer_prog;) | ||
1085 | |||
1086 | if (opt & OPT_COMPRESS) | ||
1087 | USE_FOR_MMU(xformer = unpack_Z_stream;) | ||
1088 | USE_FOR_NOMMU(xformer_prog = "uncompress";) | ||
1089 | if (opt & OPT_GZIP) | ||
1090 | USE_FOR_MMU(xformer = unpack_gz_stream;) | ||
1091 | USE_FOR_NOMMU(xformer_prog = "gunzip";) | ||
1092 | if (opt & OPT_BZIP2) | ||
1093 | USE_FOR_MMU(xformer = unpack_bz2_stream;) | ||
1094 | USE_FOR_NOMMU(xformer_prog = "bunzip2";) | ||
1095 | if (opt & OPT_LZMA) | ||
1096 | USE_FOR_MMU(xformer = unpack_lzma_stream;) | ||
1097 | USE_FOR_NOMMU(xformer_prog = "unlzma";) | ||
1098 | |||
1099 | open_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog); | ||
1100 | /* Can't lseek over pipes */ | ||
1101 | tar_handle->seek = seek_by_read; | ||
1102 | /*tar_handle->offset = 0; - already is */ | ||
1103 | } | ||
1104 | |||
1105 | while (get_header_tar(tar_handle) == EXIT_SUCCESS) | ||
1119 | continue; | 1106 | continue; |
1120 | 1107 | ||
1121 | /* Check that every file that should have been extracted was */ | 1108 | /* Check that every file that should have been extracted was */ |
@@ -1131,5 +1118,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1131 | if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */) | 1118 | if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */) |
1132 | close(tar_handle->src_fd); | 1119 | close(tar_handle->src_fd); |
1133 | 1120 | ||
1121 | #ifdef CHECK_FOR_CHILD_EXITCODE | ||
1122 | return bb_got_signal; | ||
1123 | #else | ||
1134 | return EXIT_SUCCESS; | 1124 | return EXIT_SUCCESS; |
1125 | #endif | ||
1135 | } | 1126 | } |
diff --git a/archival/unzip.c b/archival/unzip.c index 3a11f78a5..3c76cdafc 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -249,15 +249,17 @@ static void unzip_extract(zip_header_t *zip_header, int dst_fd) | |||
249 | bb_copyfd_exact_size(zip_fd, dst_fd, size); | 249 | bb_copyfd_exact_size(zip_fd, dst_fd, size); |
250 | } else { | 250 | } else { |
251 | /* Method 8 - inflate */ | 251 | /* Method 8 - inflate */ |
252 | inflate_unzip_result res; | 252 | transformer_aux_data_t aux; |
253 | if (inflate_unzip(&res, zip_header->formatted.cmpsize, zip_fd, dst_fd) < 0) | 253 | init_transformer_aux_data(&aux); |
254 | aux.bytes_in = zip_header->formatted.cmpsize; | ||
255 | if (inflate_unzip(&aux, zip_fd, dst_fd) < 0) | ||
254 | bb_error_msg_and_die("inflate error"); | 256 | bb_error_msg_and_die("inflate error"); |
255 | /* Validate decompression - crc */ | 257 | /* Validate decompression - crc */ |
256 | if (zip_header->formatted.crc32 != (res.crc ^ 0xffffffffL)) { | 258 | if (zip_header->formatted.crc32 != (aux.crc32 ^ 0xffffffffL)) { |
257 | bb_error_msg_and_die("crc error"); | 259 | bb_error_msg_and_die("crc error"); |
258 | } | 260 | } |
259 | /* Validate decompression - size */ | 261 | /* Validate decompression - size */ |
260 | if (zip_header->formatted.ucmpsize != res.bytes_out) { | 262 | if (zip_header->formatted.ucmpsize != aux.bytes_out) { |
261 | /* Don't die. Who knows, maybe len calculation | 263 | /* Don't die. Who knows, maybe len calculation |
262 | * was botched somewhere. After all, crc matched! */ | 264 | * was botched somewhere. After all, crc matched! */ |
263 | bb_error_msg("bad length"); | 265 | bb_error_msg("bad length"); |
diff --git a/docs/keep_data_small.txt b/docs/keep_data_small.txt index 9e77a9097..21d732674 100644 --- a/docs/keep_data_small.txt +++ b/docs/keep_data_small.txt | |||
@@ -59,7 +59,7 @@ wait | |||
59 | Example 1 | 59 | Example 1 |
60 | 60 | ||
61 | One example how to reduce global data usage is in | 61 | One example how to reduce global data usage is in |
62 | archival/libarchive/decompress_gunzip.c: | 62 | archival/libarchive/decompress_unzip.c: |
63 | 63 | ||
64 | /* This is somewhat complex-looking arrangement, but it allows | 64 | /* This is somewhat complex-looking arrangement, but it allows |
65 | * to place decompressor state either in bss or in | 65 | * to place decompressor state either in bss or in |
diff --git a/include/bb_archive.h b/include/bb_archive.h index 4987de6cf..bd08115da 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
@@ -156,12 +156,6 @@ struct BUG_tar_header { | |||
156 | 156 | ||
157 | 157 | ||
158 | 158 | ||
159 | /* Info struct unpackers can fill out to inform users of thing like | ||
160 | * timestamps of unpacked files */ | ||
161 | typedef struct unpack_info_t { | ||
162 | time_t mtime; | ||
163 | } unpack_info_t; | ||
164 | |||
165 | archive_handle_t *init_handle(void) FAST_FUNC; | 159 | archive_handle_t *init_handle(void) FAST_FUNC; |
166 | 160 | ||
167 | char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC; | 161 | char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC; |
@@ -204,40 +198,46 @@ int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_ | |||
204 | int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; | 198 | int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; |
205 | void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; | 199 | void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; |
206 | 200 | ||
207 | typedef struct inflate_unzip_result { | 201 | /* Meaning and direction (input/output) of the fields are transformer-specific */ |
208 | off_t bytes_out; | 202 | typedef struct transformer_aux_data_t { |
209 | uint32_t crc; | 203 | smallint check_signature; /* most often referenced member */ |
210 | } inflate_unzip_result; | 204 | off_t bytes_out; |
211 | 205 | off_t bytes_in; /* used in unzip code only: needs to know packed size */ | |
212 | IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC; | 206 | uint32_t crc32; |
213 | /* xz unpacker takes .xz stream from offset 6 */ | 207 | time_t mtime; /* gunzip code may set this on exit */ |
214 | IF_DESKTOP(long long) int unpack_xz_stream(int src_fd, int dst_fd) FAST_FUNC; | 208 | } transformer_aux_data_t; |
215 | /* lzma unpacker takes .lzma stream from offset 0 */ | 209 | |
216 | IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; | 210 | void init_transformer_aux_data(transformer_aux_data_t *aux) FAST_FUNC; |
217 | /* the rest wants 2 first bytes already skipped by the caller */ | 211 | int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16) FAST_FUNC; |
218 | IF_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC; | 212 | |
219 | IF_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC; | 213 | IF_DESKTOP(long long) int inflate_unzip(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
220 | IF_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC; | 214 | IF_DESKTOP(long long) int unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
221 | IF_DESKTOP(long long) int unpack_Z_stream(int src_fd, int dst_fd) FAST_FUNC; | 215 | IF_DESKTOP(long long) int unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
222 | /* wrapper which checks first two bytes to be "BZ" */ | 216 | IF_DESKTOP(long long) int unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
223 | IF_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC; | 217 | IF_DESKTOP(long long) int unpack_lzma_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
218 | IF_DESKTOP(long long) int unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; | ||
224 | 219 | ||
225 | char* append_ext(char *filename, const char *expected_ext) FAST_FUNC; | 220 | char* append_ext(char *filename, const char *expected_ext) FAST_FUNC; |
226 | int bbunpack(char **argv, | 221 | int bbunpack(char **argv, |
227 | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info), | 222 | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux), |
228 | char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), | 223 | char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), |
229 | const char *expected_ext | 224 | const char *expected_ext |
230 | ) FAST_FUNC; | 225 | ) FAST_FUNC; |
231 | 226 | ||
232 | #if BB_MMU | 227 | #if BB_MMU |
233 | void open_transformer(int fd, | 228 | void open_transformer(int fd, |
234 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC; | 229 | int check_signature, |
235 | #define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transformer) | 230 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
231 | ) FAST_FUNC; | ||
232 | #define open_transformer_with_sig(fd, transformer, transform_prog) open_transformer((fd), 1, (transformer)) | ||
233 | #define open_transformer_with_no_sig(fd, transformer) open_transformer((fd), 0, (transformer)) | ||
236 | #else | 234 | #else |
237 | void open_transformer(int src_fd, const char *transform_prog) FAST_FUNC; | 235 | void open_transformer(int fd, const char *transform_prog) FAST_FUNC; |
238 | #define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transform_prog) | 236 | #define open_transformer_with_sig(fd, transformer, transform_prog) open_transformer((fd), (transform_prog)) |
237 | /* open_transformer_with_no_sig() does not exist on NOMMU */ | ||
239 | #endif | 238 | #endif |
240 | 239 | ||
240 | |||
241 | POP_SAVED_FUNCTION_VISIBILITY | 241 | POP_SAVED_FUNCTION_VISIBILITY |
242 | 242 | ||
243 | #endif | 243 | #endif |
diff --git a/include/libbb.h b/include/libbb.h index c896e5484..2cc146631 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -721,17 +721,15 @@ extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAS | |||
721 | || ENABLE_FEATURE_SEAMLESS_GZ \ | 721 | || ENABLE_FEATURE_SEAMLESS_GZ \ |
722 | || ENABLE_FEATURE_SEAMLESS_Z) | 722 | || ENABLE_FEATURE_SEAMLESS_Z) |
723 | 723 | ||
724 | #if SEAMLESS_COMPRESSION | ||
724 | /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ | 725 | /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ |
725 | #if ENABLE_FEATURE_SEAMLESS_LZMA \ | 726 | extern int setup_unzip_on_fd(int fd, int fail_if_not_detected) FAST_FUNC; |
726 | || ENABLE_FEATURE_SEAMLESS_BZ2 \ | ||
727 | || ENABLE_FEATURE_SEAMLESS_GZ \ | ||
728 | /* || ENABLE_FEATURE_SEAMLESS_Z */ | ||
729 | extern void setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) FAST_FUNC; | ||
730 | #else | ||
731 | # define setup_unzip_on_fd(...) ((void)0) | ||
732 | #endif | ||
733 | /* Autodetects .gz etc */ | 727 | /* Autodetects .gz etc */ |
734 | extern int open_zipped(const char *fname) FAST_FUNC; | 728 | extern int open_zipped(const char *fname) FAST_FUNC; |
729 | #else | ||
730 | # define setup_unzip_on_fd(...) (0) | ||
731 | # define open_zipped(fname) open((fname), O_RDONLY); | ||
732 | #endif | ||
735 | extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; | 733 | extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; |
736 | 734 | ||
737 | extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC; | 735 | extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC; |