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 /archival/libarchive | |
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>
Diffstat (limited to 'archival/libarchive')
-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 |
10 files changed, 95 insertions, 138 deletions
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; |