aboutsummaryrefslogtreecommitdiff
path: root/archival/libarchive
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2012-03-06 16:27:48 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2012-03-06 16:27:48 +0100
commit8a6a2f9c9c214b94bd945acd97ac8b28c25e194e (patch)
tree08b9a2af482bb50a7e369c01f9e9083680543fd4 /archival/libarchive
parent774bce8e8ba1e424c953e8f13aee8f0778c8a911 (diff)
downloadbusybox-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.c18
-rw-r--r--archival/libarchive/decompress_gunzip.c27
-rw-r--r--archival/libarchive/decompress_uncompress.c5
-rw-r--r--archival/libarchive/decompress_unlzma.c2
-rw-r--r--archival/libarchive/decompress_unxz.c12
-rw-r--r--archival/libarchive/get_header_tar.c35
-rw-r--r--archival/libarchive/get_header_tar_bz2.c2
-rw-r--r--archival/libarchive/get_header_tar_gz.c17
-rw-r--r--archival/libarchive/get_header_tar_lzma.c2
-rw-r--r--archival/libarchive/open_transformer.c113
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. */
723IF_DESKTOP(long long) int FAST_FUNC 723IF_DESKTOP(long long) int FAST_FUNC
724unpack_bz2_stream(int src_fd, int dst_fd) 724unpack_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
797IF_DESKTOP(long long) int FAST_FUNC
798unpack_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
810static char *const bunzip_errors[] = { 802static 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
1036IF_DESKTOP(long long) int FAST_FUNC 1036IF_DESKTOP(long long) int FAST_FUNC
1037inflate_unzip(inflate_unzip_result *res, off_t compr_size, int in, int out) 1037inflate_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
1110static int check_header_gzip(STATE_PARAM unpack_info_t *info) 1110static 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
1184IF_DESKTOP(long long) int FAST_FUNC 1184IF_DESKTOP(long long) int FAST_FUNC
1185unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) 1185unpack_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
1252IF_DESKTOP(long long) int FAST_FUNC
1253unpack_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
75IF_DESKTOP(long long) int FAST_FUNC 75IF_DESKTOP(long long) int FAST_FUNC
76unpack_Z_stream(int src_fd, int dst_fd) 76unpack_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
215IF_DESKTOP(long long) int FAST_FUNC 215IF_DESKTOP(long long) int FAST_FUNC
216unpack_lzma_stream(int src_fd, int dst_fd) 216unpack_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
40IF_DESKTOP(long long) int FAST_FUNC 40IF_DESKTOP(long long) int FAST_FUNC
41unpack_xz_stream(int src_fd, int dst_fd) 41unpack_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
9char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) 9char 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 \ 9void 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 14int 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 */
24void FAST_FUNC open_transformer(int fd, 32void 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
37void 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 89int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_detected)
71void 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
148int FAST_FUNC open_zipped(const char *fname) 151int 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
179void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) 180void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p)
180{ 181{
181 int fd; 182 int fd;