diff options
Diffstat (limited to 'archival')
23 files changed, 393 insertions, 337 deletions
diff --git a/archival/Config.src b/archival/Config.src index f1d6d3511..13c33c795 100644 --- a/archival/Config.src +++ b/archival/Config.src | |||
@@ -32,10 +32,10 @@ config FEATURE_SEAMLESS_GZ | |||
32 | Make tar, rpm, modprobe etc understand .gz data. | 32 | Make tar, rpm, modprobe etc understand .gz data. |
33 | 33 | ||
34 | config FEATURE_SEAMLESS_Z | 34 | config FEATURE_SEAMLESS_Z |
35 | bool "Make tar and gunzip understand .Z data" | 35 | bool "tar, rpm, modprobe etc understand .Z data" |
36 | default n | 36 | default n |
37 | help | 37 | help |
38 | Make tar and gunzip understand .Z data. | 38 | Make tar, rpm, modprobe etc understand .Z data. |
39 | 39 | ||
40 | config AR | 40 | config AR |
41 | bool "ar" | 41 | bool "ar" |
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index c96e5396a..66a046052 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 |
@@ -184,16 +184,9 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) | |||
184 | 184 | ||
185 | #if ENABLE_UNCOMPRESS | 185 | #if ENABLE_UNCOMPRESS |
186 | static | 186 | static |
187 | IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(unpack_info_t *info UNUSED_PARAM) | 187 | IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(transformer_aux_data_t *aux) |
188 | { | 188 | { |
189 | IF_DESKTOP(long long) int status = -1; | 189 | return unpack_Z_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
190 | |||
191 | if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) { | ||
192 | bb_error_msg("invalid magic"); | ||
193 | } else { | ||
194 | status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); | ||
195 | } | ||
196 | return status; | ||
197 | } | 190 | } |
198 | int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 191 | int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
199 | int uncompress_main(int argc UNUSED_PARAM, char **argv) | 192 | int uncompress_main(int argc UNUSED_PARAM, char **argv) |
@@ -281,31 +274,9 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN | |||
281 | return filename; | 274 | return filename; |
282 | } | 275 | } |
283 | static | 276 | static |
284 | IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(unpack_info_t *info) | 277 | IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(transformer_aux_data_t *aux) |
285 | { | 278 | { |
286 | IF_DESKTOP(long long) int status = -1; | 279 | return unpack_gz_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
287 | |||
288 | /* do the decompression, and cleanup */ | ||
289 | if (xread_char(STDIN_FILENO) == 0x1f) { | ||
290 | unsigned char magic2; | ||
291 | |||
292 | magic2 = xread_char(STDIN_FILENO); | ||
293 | if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == 0x9d) { | ||
294 | status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); | ||
295 | } else if (magic2 == 0x8b) { | ||
296 | status = unpack_gz_stream_with_info(STDIN_FILENO, STDOUT_FILENO, info); | ||
297 | } else { | ||
298 | goto bad_magic; | ||
299 | } | ||
300 | if (status < 0) { | ||
301 | bb_error_msg("error inflating"); | ||
302 | } | ||
303 | } else { | ||
304 | bad_magic: | ||
305 | bb_error_msg("invalid magic"); | ||
306 | /* status is still == -1 */ | ||
307 | } | ||
308 | return status; | ||
309 | } | 280 | } |
310 | /* | 281 | /* |
311 | * Linux kernel build uses gzip -d -n. We accept and ignore it. | 282 | * Linux kernel build uses gzip -d -n. We accept and ignore it. |
@@ -354,9 +325,9 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
354 | //applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) | 325 | //applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) |
355 | #if ENABLE_BUNZIP2 | 326 | #if ENABLE_BUNZIP2 |
356 | static | 327 | static |
357 | IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(unpack_info_t *info UNUSED_PARAM) | 328 | IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(transformer_aux_data_t *aux) |
358 | { | 329 | { |
359 | return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO); | 330 | return unpack_bz2_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
360 | } | 331 | } |
361 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 332 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
362 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) | 333 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) |
@@ -422,9 +393,9 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
422 | 393 | ||
423 | #if ENABLE_UNLZMA | 394 | #if ENABLE_UNLZMA |
424 | static | 395 | static |
425 | IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(unpack_info_t *info UNUSED_PARAM) | 396 | IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(transformer_aux_data_t *aux) |
426 | { | 397 | { |
427 | return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO); | 398 | return unpack_lzma_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
428 | } | 399 | } |
429 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 400 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
430 | int unlzma_main(int argc UNUSED_PARAM, char **argv) | 401 | int unlzma_main(int argc UNUSED_PARAM, char **argv) |
@@ -447,18 +418,9 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |||
447 | 418 | ||
448 | #if ENABLE_UNXZ | 419 | #if ENABLE_UNXZ |
449 | static | 420 | static |
450 | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM) | 421 | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(transformer_aux_data_t *aux) |
451 | { | 422 | { |
452 | struct { | 423 | return unpack_xz_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
453 | uint32_t v1; | ||
454 | uint16_t v2; | ||
455 | } magic; | ||
456 | xread(STDIN_FILENO, &magic, 6); | ||
457 | if (magic.v1 != XZ_MAGIC1a || magic.v2 != XZ_MAGIC2a) { | ||
458 | bb_error_msg("invalid magic"); | ||
459 | return -1; | ||
460 | } | ||
461 | return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO); | ||
462 | } | 424 | } |
463 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 425 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
464 | int unxz_main(int argc UNUSED_PARAM, char **argv) | 426 | 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/cpio.c b/archival/cpio.c index c2a5b8ab9..98cc18fa0 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -384,6 +384,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
384 | goto dump; | 384 | goto dump; |
385 | } | 385 | } |
386 | /* parent */ | 386 | /* parent */ |
387 | USE_FOR_NOMMU(argv[-optind][0] &= 0x7f); /* undo fork_or_rexec() damage */ | ||
387 | xchdir(*argv++); | 388 | xchdir(*argv++); |
388 | close(pp.wr); | 389 | close(pp.wr); |
389 | xmove_fd(pp.rd, STDIN_FILENO); | 390 | xmove_fd(pp.rd, STDIN_FILENO); |
diff --git a/archival/gzip.c b/archival/gzip.c index f590fffa5..025e0a9f6 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/Kbuild.src b/archival/libarchive/Kbuild.src index b0bc4e5aa..39c18f264 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src | |||
@@ -28,10 +28,13 @@ COMMON_FILES:= \ | |||
28 | init_handle.o | 28 | init_handle.o |
29 | 29 | ||
30 | DPKG_FILES:= \ | 30 | DPKG_FILES:= \ |
31 | get_header_ar.o \ | ||
32 | unpack_ar_archive.o \ | 31 | unpack_ar_archive.o \ |
32 | filter_accept_list_reassign.o \ | ||
33 | get_header_ar.o \ | ||
33 | get_header_tar.o \ | 34 | get_header_tar.o \ |
34 | filter_accept_list_reassign.o | 35 | get_header_tar_gz.o \ |
36 | get_header_tar_bz2.o \ | ||
37 | get_header_tar_lzma.o \ | ||
35 | 38 | ||
36 | INSERT | 39 | INSERT |
37 | 40 | ||
@@ -42,18 +45,18 @@ lib-$(CONFIG_UNXZ) += decompress_unxz.o | |||
42 | lib-$(CONFIG_CPIO) += get_header_cpio.o | 45 | lib-$(CONFIG_CPIO) += get_header_cpio.o |
43 | lib-$(CONFIG_DPKG) += $(DPKG_FILES) | 46 | lib-$(CONFIG_DPKG) += $(DPKG_FILES) |
44 | lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) | 47 | lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) |
45 | lib-$(CONFIG_GUNZIP) += decompress_unzip.o | 48 | lib-$(CONFIG_GUNZIP) += decompress_gunzip.o |
46 | lib-$(CONFIG_RPM2CPIO) += decompress_unzip.o get_header_cpio.o | 49 | lib-$(CONFIG_RPM2CPIO) += decompress_gunzip.o get_header_cpio.o |
47 | lib-$(CONFIG_RPM) += open_transformer.o decompress_unzip.o get_header_cpio.o | 50 | lib-$(CONFIG_RPM) += open_transformer.o decompress_gunzip.o get_header_cpio.o |
48 | lib-$(CONFIG_TAR) += get_header_tar.o | 51 | lib-$(CONFIG_TAR) += get_header_tar.o |
49 | lib-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o | 52 | lib-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o |
50 | lib-$(CONFIG_UNZIP) += decompress_unzip.o | 53 | lib-$(CONFIG_UNZIP) += decompress_gunzip.o |
51 | lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | 54 | lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o |
52 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o | 55 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o |
53 | lib-$(CONFIG_FEATURE_SEAMLESS_Z) += open_transformer.o decompress_uncompress.o | 56 | lib-$(CONFIG_FEATURE_SEAMLESS_Z) += open_transformer.o decompress_uncompress.o |
54 | lib-$(CONFIG_FEATURE_SEAMLESS_GZ) += open_transformer.o decompress_unzip.o get_header_tar_gz.o | 57 | lib-$(CONFIG_FEATURE_SEAMLESS_GZ) += open_transformer.o decompress_gunzip.o |
55 | lib-$(CONFIG_FEATURE_SEAMLESS_BZ2) += open_transformer.o decompress_bunzip2.o get_header_tar_bz2.o | 58 | lib-$(CONFIG_FEATURE_SEAMLESS_BZ2) += open_transformer.o decompress_bunzip2.o |
56 | lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma.o get_header_tar_lzma.o | 59 | lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma.o |
57 | lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o | 60 | lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o |
58 | lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += decompress_bunzip2.o | 61 | lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += decompress_bunzip2.o |
59 | lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += decompress_bunzip2.o | 62 | lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += decompress_bunzip2.o |
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index f565e5471..3f67b835f 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c | |||
@@ -13,13 +13,13 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
13 | int res; | 13 | int res; |
14 | 14 | ||
15 | #if ENABLE_FEATURE_TAR_SELINUX | 15 | #if ENABLE_FEATURE_TAR_SELINUX |
16 | char *sctx = archive_handle->tar__next_file_sctx; | 16 | char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; |
17 | if (!sctx) | 17 | if (!sctx) |
18 | sctx = archive_handle->tar__global_sctx; | 18 | sctx = archive_handle->tar__sctx[PAX_GLOBAL]; |
19 | if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */ | 19 | if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */ |
20 | setfscreatecon(sctx); | 20 | setfscreatecon(sctx); |
21 | free(archive_handle->tar__next_file_sctx); | 21 | free(archive_handle->tar__sctx[PAX_NEXT_FILE]); |
22 | archive_handle->tar__next_file_sctx = NULL; | 22 | archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL; |
23 | } | 23 | } |
24 | #endif | 24 | #endif |
25 | 25 | ||
diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index cc2ff7798..a2ce33b51 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c | |||
@@ -64,13 +64,13 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle) | |||
64 | file_header_t *file_header = archive_handle->file_header; | 64 | file_header_t *file_header = archive_handle->file_header; |
65 | 65 | ||
66 | #if 0 /* do we need this? ENABLE_FEATURE_TAR_SELINUX */ | 66 | #if 0 /* do we need this? ENABLE_FEATURE_TAR_SELINUX */ |
67 | char *sctx = archive_handle->tar__next_file_sctx; | 67 | char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; |
68 | if (!sctx) | 68 | if (!sctx) |
69 | sctx = archive_handle->tar__global_sctx; | 69 | sctx = archive_handle->tar__sctx[PAX_GLOBAL]; |
70 | if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */ | 70 | if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */ |
71 | setfscreatecon(sctx); | 71 | setfscreatecon(sctx); |
72 | free(archive_handle->tar__next_file_sctx); | 72 | free(archive_handle->tar__sctx[PAX_NEXT_FILE]); |
73 | archive_handle->tar__next_file_sctx = NULL; | 73 | archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL; |
74 | } | 74 | } |
75 | #endif | 75 | #endif |
76 | 76 | ||
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_unzip.c b/archival/libarchive/decompress_gunzip.c index aa5d22d0a..2d5ab3eb3 100644 --- a/archival/libarchive/decompress_unzip.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,33 +1182,58 @@ 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 in, int out, 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 n; | 1188 | IF_DESKTOP(long long) int total, n; |
1189 | DECLARE_STATE; | 1189 | DECLARE_STATE; |
1190 | 1190 | ||
1191 | n = 0; | 1191 | #if !ENABLE_FEATURE_SEAMLESS_Z |
1192 | if (check_signature16(aux, src_fd, GZIP_MAGIC)) | ||
1193 | return -1; | ||
1194 | #else | ||
1195 | if (aux && aux->check_signature) { | ||
1196 | uint16_t magic2; | ||
1197 | |||
1198 | if (full_read(src_fd, &magic2, 2) != 2) { | ||
1199 | bad_magic: | ||
1200 | bb_error_msg("invalid magic"); | ||
1201 | return -1; | ||
1202 | } | ||
1203 | if (magic2 == COMPRESS_MAGIC) { | ||
1204 | aux->check_signature = 0; | ||
1205 | return unpack_Z_stream(aux, src_fd, dst_fd); | ||
1206 | } | ||
1207 | if (magic2 != GZIP_MAGIC) | ||
1208 | goto bad_magic; | ||
1209 | } | ||
1210 | #endif | ||
1211 | |||
1212 | total = 0; | ||
1192 | 1213 | ||
1193 | ALLOC_STATE; | 1214 | ALLOC_STATE; |
1194 | to_read = -1; | 1215 | to_read = -1; |
1195 | // bytebuffer_max = 0x8000; | 1216 | // bytebuffer_max = 0x8000; |
1196 | bytebuffer = xmalloc(bytebuffer_max); | 1217 | bytebuffer = xmalloc(bytebuffer_max); |
1197 | gunzip_src_fd = in; | 1218 | gunzip_src_fd = src_fd; |
1198 | 1219 | ||
1199 | again: | 1220 | again: |
1200 | if (!check_header_gzip(PASS_STATE info)) { | 1221 | if (!check_header_gzip(PASS_STATE aux)) { |
1201 | bb_error_msg("corrupted data"); | 1222 | bb_error_msg("corrupted data"); |
1202 | n = -1; | 1223 | total = -1; |
1203 | goto ret; | 1224 | goto ret; |
1204 | } | 1225 | } |
1205 | n += inflate_unzip_internal(PASS_STATE in, out); | 1226 | |
1206 | if (n < 0) | 1227 | n = inflate_unzip_internal(PASS_STATE src_fd, dst_fd); |
1228 | if (n < 0) { | ||
1229 | total = -1; | ||
1207 | goto ret; | 1230 | goto ret; |
1231 | } | ||
1232 | total += n; | ||
1208 | 1233 | ||
1209 | if (!top_up(PASS_STATE 8)) { | 1234 | if (!top_up(PASS_STATE 8)) { |
1210 | bb_error_msg("corrupted data"); | 1235 | bb_error_msg("corrupted data"); |
1211 | n = -1; | 1236 | total = -1; |
1212 | goto ret; | 1237 | goto ret; |
1213 | } | 1238 | } |
1214 | 1239 | ||
@@ -1216,7 +1241,7 @@ unpack_gz_stream_with_info(int in, int out, unpack_info_t *info) | |||
1216 | v32 = buffer_read_le_u32(PASS_STATE_ONLY); | 1241 | v32 = buffer_read_le_u32(PASS_STATE_ONLY); |
1217 | if ((~gunzip_crc) != v32) { | 1242 | if ((~gunzip_crc) != v32) { |
1218 | bb_error_msg("crc error"); | 1243 | bb_error_msg("crc error"); |
1219 | n = -1; | 1244 | total = -1; |
1220 | goto ret; | 1245 | goto ret; |
1221 | } | 1246 | } |
1222 | 1247 | ||
@@ -1224,7 +1249,7 @@ unpack_gz_stream_with_info(int in, int out, unpack_info_t *info) | |||
1224 | v32 = buffer_read_le_u32(PASS_STATE_ONLY); | 1249 | v32 = buffer_read_le_u32(PASS_STATE_ONLY); |
1225 | if ((uint32_t)gunzip_bytes_out != v32) { | 1250 | if ((uint32_t)gunzip_bytes_out != v32) { |
1226 | bb_error_msg("incorrect length"); | 1251 | bb_error_msg("incorrect length"); |
1227 | n = -1; | 1252 | total = -1; |
1228 | } | 1253 | } |
1229 | 1254 | ||
1230 | if (!top_up(PASS_STATE 2)) | 1255 | if (!top_up(PASS_STATE 2)) |
@@ -1242,11 +1267,5 @@ unpack_gz_stream_with_info(int in, int out, unpack_info_t *info) | |||
1242 | ret: | 1267 | ret: |
1243 | free(bytebuffer); | 1268 | free(bytebuffer); |
1244 | DEALLOC_STATE; | 1269 | DEALLOC_STATE; |
1245 | return n; | 1270 | return total; |
1246 | } | ||
1247 | |||
1248 | IF_DESKTOP(long long) int FAST_FUNC | ||
1249 | unpack_gz_stream(int in, int out) | ||
1250 | { | ||
1251 | return unpack_gz_stream_with_info(in, out, NULL); | ||
1252 | } | 1271 | } |
diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c index c6040d04b..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 fd_in, int fd_out) | 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,16 +103,19 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
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); /* wsn't zeroed out before, maybe can xmalloc? */ | 111 | htab = xzalloc(HSIZE); /* wasn't zeroed out before, maybe can xmalloc? */ |
109 | codetab = xzalloc(HSIZE * sizeof(codetab[0])); | 112 | codetab = xzalloc(HSIZE * sizeof(codetab[0])); |
110 | 113 | ||
111 | insize = 0; | 114 | insize = 0; |
112 | 115 | ||
113 | /* xread isn't good here, we have to return - caller may want | 116 | /* xread isn't good here, we have to return - caller may want |
114 | * to do some cleanup (e.g. delete incomplete unpacked file etc) */ | 117 | * to do some cleanup (e.g. delete incomplete unpacked file etc) */ |
115 | if (full_read(fd_in, inbuf, 1) != 1) { | 118 | if (full_read(src_fd, inbuf, 1) != 1) { |
116 | bb_error_msg("short read"); | 119 | bb_error_msg("short read"); |
117 | goto err; | 120 | goto err; |
118 | } | 121 | } |
@@ -162,7 +165,7 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
162 | } | 165 | } |
163 | 166 | ||
164 | if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { | 167 | if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { |
165 | rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); | 168 | rsize = safe_read(src_fd, inbuf + insize, IBUFSIZ); |
166 | if (rsize < 0) | 169 | if (rsize < 0) |
167 | bb_error_msg_and_die(bb_msg_read_error); | 170 | bb_error_msg_and_die(bb_msg_read_error); |
168 | insize += rsize; | 171 | insize += rsize; |
@@ -268,7 +271,7 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
268 | } | 271 | } |
269 | 272 | ||
270 | if (outpos >= OBUFSIZ) { | 273 | if (outpos >= OBUFSIZ) { |
271 | xwrite(fd_out, outbuf, outpos); | 274 | xwrite(dst_fd, outbuf, outpos); |
272 | IF_DESKTOP(total_written += outpos;) | 275 | IF_DESKTOP(total_written += outpos;) |
273 | outpos = 0; | 276 | outpos = 0; |
274 | } | 277 | } |
@@ -296,7 +299,7 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
296 | } while (rsize > 0); | 299 | } while (rsize > 0); |
297 | 300 | ||
298 | if (outpos > 0) { | 301 | if (outpos > 0) { |
299 | xwrite(fd_out, outbuf, outpos); | 302 | xwrite(dst_fd, outbuf, outpos); |
300 | IF_DESKTOP(total_written += outpos;) | 303 | IF_DESKTOP(total_written += outpos;) |
301 | } | 304 | } |
302 | 305 | ||
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 a63c0fb01..80a709144 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -90,23 +90,20 @@ static unsigned long long getOctal(char *str, int len) | |||
90 | } | 90 | } |
91 | #define GET_OCTAL(a) getOctal((a), sizeof(a)) | 91 | #define GET_OCTAL(a) getOctal((a), sizeof(a)) |
92 | 92 | ||
93 | #if ENABLE_FEATURE_TAR_SELINUX | 93 | /* "global" is 0 or 1 */ |
94 | /* Scan a PAX header for SELinux contexts, via "RHT.security.selinux" keyword. | 94 | static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int global) |
95 | * This is what Red Hat's patched version of tar uses. | ||
96 | */ | ||
97 | # define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux" | ||
98 | static char *get_selinux_sctx_from_pax_hdr(archive_handle_t *archive_handle, unsigned sz) | ||
99 | { | 95 | { |
100 | char *buf, *p; | 96 | char *buf, *p; |
101 | char *result; | 97 | unsigned blk_sz; |
98 | |||
99 | blk_sz = (sz + 511) & (~511); | ||
100 | p = buf = xmalloc(blk_sz + 1); | ||
101 | xread(archive_handle->src_fd, buf, blk_sz); | ||
102 | archive_handle->offset += blk_sz; | ||
102 | 103 | ||
103 | p = buf = xmalloc(sz + 1); | ||
104 | /* prevent bb_strtou from running off the buffer */ | 104 | /* prevent bb_strtou from running off the buffer */ |
105 | buf[sz] = '\0'; | 105 | buf[sz] = '\0'; |
106 | xread(archive_handle->src_fd, buf, sz); | ||
107 | archive_handle->offset += sz; | ||
108 | 106 | ||
109 | result = NULL; | ||
110 | while (sz != 0) { | 107 | while (sz != 0) { |
111 | char *end, *value; | 108 | char *end, *value; |
112 | unsigned len; | 109 | unsigned len; |
@@ -133,19 +130,33 @@ static char *get_selinux_sctx_from_pax_hdr(archive_handle_t *archive_handle, uns | |||
133 | * (we do not bother to check that it *was* a newline) | 130 | * (we do not bother to check that it *was* a newline) |
134 | */ | 131 | */ |
135 | p[-1] = '\0'; | 132 | p[-1] = '\0'; |
136 | /* Is it selinux security context? */ | ||
137 | value = end + 1; | 133 | value = end + 1; |
134 | |||
135 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | ||
136 | if (!global && strncmp(value, "path=", sizeof("path=") - 1) == 0) { | ||
137 | value += sizeof("path=") - 1; | ||
138 | free(archive_handle->tar__longname); | ||
139 | archive_handle->tar__longname = xstrdup(value); | ||
140 | continue; | ||
141 | } | ||
142 | #endif | ||
143 | |||
144 | #if ENABLE_FEATURE_TAR_SELINUX | ||
145 | /* Scan for SELinux contexts, via "RHT.security.selinux" keyword. | ||
146 | * This is what Red Hat's patched version of tar uses. | ||
147 | */ | ||
148 | # define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux" | ||
138 | if (strncmp(value, SELINUX_CONTEXT_KEYWORD"=", sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1) == 0) { | 149 | if (strncmp(value, SELINUX_CONTEXT_KEYWORD"=", sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1) == 0) { |
139 | value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1; | 150 | value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1; |
140 | result = xstrdup(value); | 151 | free(archive_handle->tar__sctx[global]); |
141 | break; | 152 | archive_handle->tar__sctx[global] = xstrdup(value); |
153 | continue; | ||
142 | } | 154 | } |
155 | #endif | ||
143 | } | 156 | } |
144 | 157 | ||
145 | free(buf); | 158 | free(buf); |
146 | return result; | ||
147 | } | 159 | } |
148 | #endif | ||
149 | 160 | ||
150 | char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | 161 | char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) |
151 | { | 162 | { |
@@ -224,43 +235,18 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
224 | || memcmp(tar.magic, "\0\0\0\0", 5) != 0) | 235 | || memcmp(tar.magic, "\0\0\0\0", 5) != 0) |
225 | ) { | 236 | ) { |
226 | #if ENABLE_FEATURE_TAR_AUTODETECT | 237 | #if ENABLE_FEATURE_TAR_AUTODETECT |
227 | char FAST_FUNC (*get_header_ptr)(archive_handle_t *); | ||
228 | uint16_t magic2; | ||
229 | |||
230 | autodetect: | 238 | autodetect: |
231 | magic2 = *(bb__aliased_uint16_t*)tar.name; | ||
232 | /* tar gz/bz autodetect: check for gz/bz2 magic. | ||
233 | * If we see the magic, and it is the very first block, | ||
234 | * we can switch to get_header_tar_gz/bz2/lzma(). | ||
235 | * Needs seekable fd. I wish recv(MSG_PEEK) works | ||
236 | * on any fd... */ | ||
237 | # if ENABLE_FEATURE_SEAMLESS_GZ | ||
238 | if (magic2 == GZIP_MAGIC) { | ||
239 | get_header_ptr = get_header_tar_gz; | ||
240 | } else | ||
241 | # endif | ||
242 | # if ENABLE_FEATURE_SEAMLESS_BZ2 | ||
243 | if (magic2 == BZIP2_MAGIC | ||
244 | && tar.name[2] == 'h' && isdigit(tar.name[3]) | ||
245 | ) { /* bzip2 */ | ||
246 | get_header_ptr = get_header_tar_bz2; | ||
247 | } else | ||
248 | # endif | ||
249 | # if ENABLE_FEATURE_SEAMLESS_XZ | ||
250 | //TODO: if (magic2 == XZ_MAGIC1)... | ||
251 | //else | ||
252 | # endif | ||
253 | goto err; | ||
254 | /* Two different causes for lseek() != 0: | 239 | /* Two different causes for lseek() != 0: |
255 | * unseekable fd (would like to support that too, but...), | 240 | * unseekable fd (would like to support that too, but...), |
256 | * or not first block (false positive, it's not .gz/.bz2!) */ | 241 | * or not first block (false positive, it's not .gz/.bz2!) */ |
257 | if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0) | 242 | if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0) |
258 | goto err; | 243 | goto err; |
259 | while (get_header_ptr(archive_handle) == EXIT_SUCCESS) | 244 | if (setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_detected:*/ 0) != 0) |
260 | continue; | ||
261 | return EXIT_FAILURE; | ||
262 | err: | 245 | err: |
263 | #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 | ||
264 | bb_error_msg_and_die("invalid tar magic"); | 250 | bb_error_msg_and_die("invalid tar magic"); |
265 | } | 251 | } |
266 | 252 | ||
@@ -418,12 +404,14 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
418 | case 'S': /* Sparse file */ | 404 | case 'S': /* Sparse file */ |
419 | case 'V': /* Volume header */ | 405 | case 'V': /* Volume header */ |
420 | #endif | 406 | #endif |
421 | #if !ENABLE_FEATURE_TAR_SELINUX | ||
422 | case 'g': /* pax global header */ | 407 | case 'g': /* pax global header */ |
423 | case 'x': /* pax extended header */ | 408 | case 'x': { /* pax extended header */ |
424 | #else | 409 | if ((uoff_t)file_header->size > 0xfffff) /* paranoia */ |
410 | goto skip_ext_hdr; | ||
411 | process_pax_hdr(archive_handle, file_header->size, (tar.typeflag == 'g')); | ||
412 | goto again_after_align; | ||
413 | } | ||
425 | skip_ext_hdr: | 414 | skip_ext_hdr: |
426 | #endif | ||
427 | { | 415 | { |
428 | off_t sz; | 416 | off_t sz; |
429 | bb_error_msg("warning: skipping header '%c'", tar.typeflag); | 417 | bb_error_msg("warning: skipping header '%c'", tar.typeflag); |
@@ -435,18 +423,6 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
435 | /* return get_header_tar(archive_handle); */ | 423 | /* return get_header_tar(archive_handle); */ |
436 | goto again_after_align; | 424 | goto again_after_align; |
437 | } | 425 | } |
438 | #if ENABLE_FEATURE_TAR_SELINUX | ||
439 | case 'g': /* pax global header */ | ||
440 | case 'x': { /* pax extended header */ | ||
441 | char **pp; | ||
442 | if ((uoff_t)file_header->size > 0xfffff) /* paranoia */ | ||
443 | goto skip_ext_hdr; | ||
444 | pp = (tar.typeflag == 'g') ? &archive_handle->tar__global_sctx : &archive_handle->tar__next_file_sctx; | ||
445 | free(*pp); | ||
446 | *pp = get_selinux_sctx_from_pax_hdr(archive_handle, file_header->size); | ||
447 | goto again; | ||
448 | } | ||
449 | #endif | ||
450 | default: | 426 | default: |
451 | bb_error_msg_and_die("unknown typeflag: 0x%x", tar.typeflag); | 427 | bb_error_msg_and_die("unknown typeflag: 0x%x", tar.typeflag); |
452 | } | 428 | } |
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 aa8c1021c..f2edc2a2b 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
@@ -6,14 +6,64 @@ | |||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "bb_archive.h" | 7 | #include "bb_archive.h" |
8 | 8 | ||
9 | void FAST_FUNC init_transformer_aux_data(transformer_aux_data_t *aux) | ||
10 | { | ||
11 | memset(aux, 0, sizeof(*aux)); | ||
12 | } | ||
13 | |||
14 | int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16) | ||
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(); | ||
23 | #endif | ||
24 | return -1; | ||
25 | } | ||
26 | } | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | #if !ENABLE_PLATFORM_MINGW32 | ||
31 | void check_errors_in_children(int signo) | ||
32 | { | ||
33 | int status; | ||
34 | |||
35 | if (!signo) { | ||
36 | /* block waiting for any child */ | ||
37 | if (wait(&status) < 0) | ||
38 | return; /* probably there are no children */ | ||
39 | goto check_status; | ||
40 | } | ||
41 | |||
42 | /* Wait for any child without blocking */ | ||
43 | for (;;) { | ||
44 | if (wait_any_nohang(&status) < 0) | ||
45 | /* wait failed?! I'm confused... */ | ||
46 | return; | ||
47 | check_status: | ||
48 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) | ||
49 | /* this child exited with 0 */ | ||
50 | continue; | ||
51 | /* Cannot happen? | ||
52 | if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */ | ||
53 | bb_got_signal = 1; | ||
54 | } | ||
55 | } | ||
56 | #endif | ||
57 | |||
9 | /* transformer(), more than meets the eye */ | 58 | /* transformer(), more than meets the eye */ |
10 | /* | 59 | #if BB_MMU |
11 | * On MMU machine, the transform_prog is removed by macro magic | ||
12 | * in include/archive.h. On NOMMU, transformer is removed. | ||
13 | */ | ||
14 | void FAST_FUNC open_transformer(int fd, | 60 | void FAST_FUNC open_transformer(int fd, |
15 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), | 61 | int check_signature, |
16 | const char *transform_prog) | 62 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
63 | ) | ||
64 | #else | ||
65 | void FAST_FUNC open_transformer(int fd, const char *transform_prog) | ||
66 | #endif | ||
17 | { | 67 | { |
18 | struct fd_pair fd_pipe; | 68 | struct fd_pair fd_pipe; |
19 | int pid; | 69 | int pid; |
@@ -25,13 +75,18 @@ void FAST_FUNC open_transformer(int fd, | |||
25 | close(fd_pipe.rd); /* we don't want to read from the parent */ | 75 | close(fd_pipe.rd); /* we don't want to read from the parent */ |
26 | // FIXME: error check? | 76 | // FIXME: error check? |
27 | #if BB_MMU | 77 | #if BB_MMU |
28 | transformer(fd, fd_pipe.wr); | 78 | { |
29 | if (ENABLE_FEATURE_CLEAN_UP) { | 79 | transformer_aux_data_t aux; |
30 | close(fd_pipe.wr); /* send EOF */ | 80 | init_transformer_aux_data(&aux); |
31 | close(fd); | 81 | aux.check_signature = check_signature; |
82 | transformer(&aux, fd, fd_pipe.wr); | ||
83 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
84 | close(fd_pipe.wr); /* send EOF */ | ||
85 | close(fd); | ||
86 | } | ||
87 | /* must be _exit! bug was actually seen here */ | ||
88 | _exit(EXIT_SUCCESS); | ||
32 | } | 89 | } |
33 | /* must be _exit! bug was actually seen here */ | ||
34 | _exit(EXIT_SUCCESS); | ||
35 | #else | 90 | #else |
36 | { | 91 | { |
37 | char *argv[4]; | 92 | char *argv[4]; |
@@ -52,3 +107,117 @@ void FAST_FUNC open_transformer(int fd, | |||
52 | close(fd_pipe.wr); /* don't want to write to the child */ | 107 | close(fd_pipe.wr); /* don't want to write to the child */ |
53 | xmove_fd(fd_pipe.rd, fd); | 108 | xmove_fd(fd_pipe.rd, fd); |
54 | } | 109 | } |
110 | |||
111 | |||
112 | #if SEAMLESS_COMPRESSION | ||
113 | |||
114 | /* Used by e.g. rpm which gives us a fd without filename, | ||
115 | * thus we can't guess the format from filename's extension. | ||
116 | */ | ||
117 | int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_detected) | ||
118 | { | ||
119 | union { | ||
120 | uint8_t b[4]; | ||
121 | uint16_t b16[2]; | ||
122 | uint32_t b32[1]; | ||
123 | } magic; | ||
124 | int offset = -2; | ||
125 | USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) | ||
126 | USE_FOR_NOMMU(const char *xformer_prog;) | ||
127 | |||
128 | /* .gz and .bz2 both have 2-byte signature, and their | ||
129 | * unpack_XXX_stream wants this header skipped. */ | ||
130 | xread(fd, magic.b16, sizeof(magic.b16[0])); | ||
131 | if (ENABLE_FEATURE_SEAMLESS_GZ | ||
132 | && magic.b16[0] == GZIP_MAGIC | ||
133 | ) { | ||
134 | USE_FOR_MMU(xformer = unpack_gz_stream;) | ||
135 | USE_FOR_NOMMU(xformer_prog = "gunzip";) | ||
136 | goto found_magic; | ||
137 | } | ||
138 | if (ENABLE_FEATURE_SEAMLESS_BZ2 | ||
139 | && magic.b16[0] == BZIP2_MAGIC | ||
140 | ) { | ||
141 | USE_FOR_MMU(xformer = unpack_bz2_stream;) | ||
142 | USE_FOR_NOMMU(xformer_prog = "bunzip2";) | ||
143 | goto found_magic; | ||
144 | } | ||
145 | if (ENABLE_FEATURE_SEAMLESS_XZ | ||
146 | && magic.b16[0] == XZ_MAGIC1 | ||
147 | ) { | ||
148 | offset = -6; | ||
149 | xread(fd, magic.b32, sizeof(magic.b32[0])); | ||
150 | if (magic.b32[0] == XZ_MAGIC2) { | ||
151 | USE_FOR_MMU(xformer = unpack_xz_stream;) | ||
152 | USE_FOR_NOMMU(xformer_prog = "unxz";) | ||
153 | goto found_magic; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | /* No known magic seen */ | ||
158 | if (fail_if_not_detected) | ||
159 | bb_error_msg_and_die("no gzip" | ||
160 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | ||
161 | IF_FEATURE_SEAMLESS_XZ("/xz") | ||
162 | " magic"); | ||
163 | xlseek(fd, offset, SEEK_CUR); | ||
164 | return 1; | ||
165 | |||
166 | found_magic: | ||
167 | # if BB_MMU | ||
168 | open_transformer_with_no_sig(fd, xformer); | ||
169 | # else | ||
170 | /* NOMMU version of open_transformer execs | ||
171 | * an external unzipper that wants | ||
172 | * file position at the start of the file */ | ||
173 | xlseek(fd, offset, SEEK_CUR); | ||
174 | open_transformer_with_sig(fd, xformer, xformer_prog); | ||
175 | # endif | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | int FAST_FUNC open_zipped(const char *fname) | ||
180 | { | ||
181 | char *sfx; | ||
182 | int fd; | ||
183 | |||
184 | fd = open(fname, O_RDONLY); | ||
185 | if (fd < 0) | ||
186 | return fd; | ||
187 | |||
188 | sfx = strrchr(fname, '.'); | ||
189 | if (sfx) { | ||
190 | sfx++; | ||
191 | if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0) | ||
192 | /* .lzma has no header/signature, just trust it */ | ||
193 | open_transformer_with_sig(fd, unpack_lzma_stream, "unlzma"); | ||
194 | else | ||
195 | if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0) | ||
196 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0) | ||
197 | || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0) | ||
198 | ) { | ||
199 | setup_unzip_on_fd(fd, /*fail_if_not_detected:*/ 1); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | return fd; | ||
204 | } | ||
205 | |||
206 | #endif /* SEAMLESS_COMPRESSION */ | ||
207 | |||
208 | void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) | ||
209 | { | ||
210 | int fd; | ||
211 | char *image; | ||
212 | |||
213 | fd = open_zipped(fname); | ||
214 | if (fd < 0) | ||
215 | return NULL; | ||
216 | |||
217 | image = xmalloc_read(fd, maxsz_p); | ||
218 | if (!image) | ||
219 | bb_perror_msg("read error from '%s'", fname); | ||
220 | close(fd); | ||
221 | |||
222 | return image; | ||
223 | } | ||
diff --git a/archival/lzop.c b/archival/lzop.c index 7e30091d9..fbe08417d 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -201,7 +201,7 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, | |||
201 | /* remove short run */ | 201 | /* remove short run */ |
202 | *litp &= ~3; | 202 | *litp &= ~3; |
203 | /* copy over the 2 literals that replace the match */ | 203 | /* copy over the 2 literals that replace the match */ |
204 | copy2(ip-3+1,m_pos,pd(op,m_pos)); | 204 | copy2(ip-3+1, m_pos, pd(op, m_pos)); |
205 | /* move literals 1 byte ahead */ | 205 | /* move literals 1 byte ahead */ |
206 | litp += 2; | 206 | litp += 2; |
207 | if (lit > 0) | 207 | if (lit > 0) |
@@ -211,7 +211,8 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, | |||
211 | *litp = (unsigned char)(lit - 3); | 211 | *litp = (unsigned char)(lit - 3); |
212 | 212 | ||
213 | o_m1_b++; | 213 | o_m1_b++; |
214 | *op++ = *m_pos++; *op++ = *m_pos++; | 214 | *op++ = *m_pos++; |
215 | *op++ = *m_pos++; | ||
215 | goto copy_literal_run; | 216 | goto copy_literal_run; |
216 | } | 217 | } |
217 | copy_m1: | 218 | copy_m1: |
@@ -240,7 +241,7 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, | |||
240 | ) { | 241 | ) { |
241 | t = *ip++; | 242 | t = *ip++; |
242 | /* copy over the 3 literals that replace the match */ | 243 | /* copy over the 3 literals that replace the match */ |
243 | copy3(ip-1-2,m_pos,pd(op,m_pos)); | 244 | copy3(ip-1-2, m_pos, pd(op, m_pos)); |
244 | /* set new length of previous literal run */ | 245 | /* set new length of previous literal run */ |
245 | lit += 3 + t + 3; | 246 | lit += 3 + t + 3; |
246 | *litp = (unsigned char)(lit - 3); | 247 | *litp = (unsigned char)(lit - 3); |
@@ -289,7 +290,7 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, | |||
289 | lit += 3; | 290 | lit += 3; |
290 | *litp = (unsigned char)((*litp & ~3) | lit); | 291 | *litp = (unsigned char)((*litp & ~3) | lit); |
291 | /* copy over the 3 literals that replace the match */ | 292 | /* copy over the 3 literals that replace the match */ |
292 | copy3(ip-3,m_pos,pd(op,m_pos)); | 293 | copy3(ip-3, m_pos, pd(op, m_pos)); |
293 | o_m3_a++; | 294 | o_m3_a++; |
294 | } | 295 | } |
295 | /* test if a literal run follows */ | 296 | /* test if a literal run follows */ |
@@ -300,7 +301,7 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, | |||
300 | /* remove short run */ | 301 | /* remove short run */ |
301 | *litp &= ~3; | 302 | *litp &= ~3; |
302 | /* copy over the 3 literals that replace the match */ | 303 | /* copy over the 3 literals that replace the match */ |
303 | copy3(ip-4+1,m_pos,pd(op,m_pos)); | 304 | copy3(ip-4+1, m_pos, pd(op, m_pos)); |
304 | /* move literals 1 byte ahead */ | 305 | /* move literals 1 byte ahead */ |
305 | litp += 2; | 306 | litp += 2; |
306 | if (lit > 0) | 307 | if (lit > 0) |
@@ -1076,7 +1077,7 @@ static char* FAST_FUNC make_new_name_lzop(char *filename, const char *expected_e | |||
1076 | return xasprintf("%s.lzo", filename); | 1077 | return xasprintf("%s.lzo", filename); |
1077 | } | 1078 | } |
1078 | 1079 | ||
1079 | 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) |
1080 | { | 1081 | { |
1081 | if (option_mask32 & OPT_DECOMPRESS) | 1082 | if (option_mask32 & OPT_DECOMPRESS) |
1082 | 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..898d4aca4 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c | |||
@@ -66,54 +66,24 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |||
66 | /* Skip the main header */ | 66 | /* Skip the main header */ |
67 | skip_header(); | 67 | skip_header(); |
68 | 68 | ||
69 | #if 0 | 69 | //if (SEAMLESS_COMPRESSION) |
70 | // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ | ||
71 | // signal(SIGCHLD, check_errors_in_children); | ||
72 | |||
70 | /* This works, but doesn't report uncompress errors (they happen in child) */ | 73 | /* This works, but doesn't report uncompress errors (they happen in child) */ |
71 | setup_unzip_on_fd(rpm_fd /*fail_if_not_detected: 1*/); | 74 | setup_unzip_on_fd(rpm_fd, /*fail_if_not_detected:*/ 1); |
72 | if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) | 75 | if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) |
73 | bb_error_msg_and_die("error unpacking"); | 76 | 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 | 77 | ||
114 | if (ENABLE_FEATURE_CLEAN_UP) { | 78 | if (ENABLE_FEATURE_CLEAN_UP) { |
115 | close(rpm_fd); | 79 | close(rpm_fd); |
116 | } | 80 | } |
117 | 81 | ||
118 | return 0; | 82 | #if !ENABLE_PLATFORM_MINGW32 |
83 | if (SEAMLESS_COMPRESSION) { | ||
84 | check_errors_in_children(0); | ||
85 | return bb_got_signal; | ||
86 | } | ||
87 | #endif | ||
88 | return EXIT_SUCCESS; | ||
119 | } | 89 | } |
diff --git a/archival/tar.c b/archival/tar.c index 2b752f640..fcd128a91 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -692,54 +692,6 @@ static llist_t *append_file_list_to_list(llist_t *list) | |||
692 | # define append_file_list_to_list(x) 0 | 692 | # define append_file_list_to_list(x) 0 |
693 | #endif | 693 | #endif |
694 | 694 | ||
695 | #if ENABLE_FEATURE_SEAMLESS_Z | ||
696 | static char FAST_FUNC get_header_tar_Z(archive_handle_t *archive_handle) | ||
697 | { | ||
698 | /* Can't lseek over pipes */ | ||
699 | archive_handle->seek = seek_by_read; | ||
700 | |||
701 | /* do the decompression, and cleanup */ | ||
702 | if (xread_char(archive_handle->src_fd) != 0x1f | ||
703 | || xread_char(archive_handle->src_fd) != 0x9d | ||
704 | ) { | ||
705 | bb_error_msg_and_die("invalid magic"); | ||
706 | } | ||
707 | |||
708 | open_transformer(archive_handle->src_fd, unpack_Z_stream, "uncompress"); | ||
709 | archive_handle->offset = 0; | ||
710 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) | ||
711 | continue; | ||
712 | |||
713 | /* Can only do one file at a time */ | ||
714 | return EXIT_FAILURE; | ||
715 | } | ||
716 | #else | ||
717 | # define get_header_tar_Z NULL | ||
718 | #endif | ||
719 | |||
720 | #ifdef CHECK_FOR_CHILD_EXITCODE | ||
721 | /* Looks like it isn't needed - tar detects malformed (truncated) | ||
722 | * archive if e.g. bunzip2 fails */ | ||
723 | static int child_error; | ||
724 | |||
725 | static void handle_SIGCHLD(int status) | ||
726 | { | ||
727 | /* Actually, 'status' is a signo. We reuse it for other needs */ | ||
728 | |||
729 | /* Wait for any child without blocking */ | ||
730 | if (wait_any_nohang(&status) < 0) | ||
731 | /* wait failed?! I'm confused... */ | ||
732 | return; | ||
733 | |||
734 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) | ||
735 | /* child exited with 0 */ | ||
736 | return; | ||
737 | /* Cannot happen? | ||
738 | if (!WIFSIGNALED(status) && !WIFEXITED(status)) return; */ | ||
739 | child_error = 1; | ||
740 | } | ||
741 | #endif | ||
742 | |||
743 | //usage:#define tar_trivial_usage | 695 | //usage:#define tar_trivial_usage |
744 | //usage: "-[" IF_FEATURE_TAR_CREATE("c") "xt" | 696 | //usage: "-[" IF_FEATURE_TAR_CREATE("c") "xt" |
745 | //usage: IF_FEATURE_SEAMLESS_Z("Z") | 697 | //usage: IF_FEATURE_SEAMLESS_Z("Z") |
@@ -845,6 +797,8 @@ enum { | |||
845 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner | 797 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
846 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions | 798 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions |
847 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite | 799 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite |
800 | |||
801 | OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_COMPRESS), | ||
848 | }; | 802 | }; |
849 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 803 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
850 | static const char tar_longopts[] ALIGN1 = | 804 | static const char tar_longopts[] ALIGN1 = |
@@ -903,7 +857,6 @@ static const char tar_longopts[] ALIGN1 = | |||
903 | int tar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 857 | int tar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
904 | int tar_main(int argc UNUSED_PARAM, char **argv) | 858 | int tar_main(int argc UNUSED_PARAM, char **argv) |
905 | { | 859 | { |
906 | char FAST_FUNC (*get_header_ptr)(archive_handle_t *) = get_header_tar; | ||
907 | archive_handle_t *tar_handle; | 860 | archive_handle_t *tar_handle; |
908 | char *base_dir = NULL; | 861 | char *base_dir = NULL; |
909 | const char *tar_filename = "-"; | 862 | const char *tar_filename = "-"; |
@@ -1019,18 +972,6 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1019 | tar_handle->ah_flags |= ARCHIVE_O_TRUNC; | 972 | tar_handle->ah_flags |= ARCHIVE_O_TRUNC; |
1020 | } | 973 | } |
1021 | 974 | ||
1022 | if (opt & OPT_GZIP) | ||
1023 | get_header_ptr = get_header_tar_gz; | ||
1024 | |||
1025 | if (opt & OPT_BZIP2) | ||
1026 | get_header_ptr = get_header_tar_bz2; | ||
1027 | |||
1028 | if (opt & OPT_LZMA) | ||
1029 | get_header_ptr = get_header_tar_lzma; | ||
1030 | |||
1031 | if (opt & OPT_COMPRESS) | ||
1032 | get_header_ptr = get_header_tar_Z; | ||
1033 | |||
1034 | if (opt & OPT_NOPRESERVE_TIME) | 975 | if (opt & OPT_NOPRESERVE_TIME) |
1035 | tar_handle->ah_flags &= ~ARCHIVE_RESTORE_DATE; | 976 | tar_handle->ah_flags &= ~ARCHIVE_RESTORE_DATE; |
1036 | 977 | ||
@@ -1083,7 +1024,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1083 | } else { | 1024 | } else { |
1084 | if (ENABLE_FEATURE_TAR_AUTODETECT | 1025 | if (ENABLE_FEATURE_TAR_AUTODETECT |
1085 | && flags == O_RDONLY | 1026 | && flags == O_RDONLY |
1086 | && get_header_ptr == get_header_tar | 1027 | && !(opt & OPT_ANY_COMPRESS) |
1087 | ) { | 1028 | ) { |
1088 | tar_handle->src_fd = open_zipped(tar_filename); | 1029 | tar_handle->src_fd = open_zipped(tar_filename); |
1089 | if (tar_handle->src_fd < 0) | 1030 | if (tar_handle->src_fd < 0) |
@@ -1097,10 +1038,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1097 | if (base_dir) | 1038 | if (base_dir) |
1098 | xchdir(base_dir); | 1039 | xchdir(base_dir); |
1099 | 1040 | ||
1100 | #ifdef CHECK_FOR_CHILD_EXITCODE | 1041 | //if (SEAMLESS_COMPRESSION || OPT_COMPRESS) |
1101 | /* We need to know whether child (gzip/bzip/etc) exits abnormally */ | 1042 | // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ |
1102 | signal(SIGCHLD, handle_SIGCHLD); | 1043 | // signal(SIGCHLD, check_errors_in_children); |
1103 | #endif | ||
1104 | 1044 | ||
1105 | /* Create an archive */ | 1045 | /* Create an archive */ |
1106 | if (opt & OPT_CREATE) { | 1046 | if (opt & OPT_CREATE) { |
@@ -1117,7 +1057,30 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1117 | tar_handle->reject, zipMode); | 1057 | tar_handle->reject, zipMode); |
1118 | } | 1058 | } |
1119 | 1059 | ||
1120 | while (get_header_ptr(tar_handle) == EXIT_SUCCESS) | 1060 | if (opt & OPT_ANY_COMPRESS) { |
1061 | USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) | ||
1062 | USE_FOR_NOMMU(const char *xformer_prog;) | ||
1063 | |||
1064 | if (opt & OPT_COMPRESS) | ||
1065 | USE_FOR_MMU(xformer = unpack_Z_stream;) | ||
1066 | USE_FOR_NOMMU(xformer_prog = "uncompress";) | ||
1067 | if (opt & OPT_GZIP) | ||
1068 | USE_FOR_MMU(xformer = unpack_gz_stream;) | ||
1069 | USE_FOR_NOMMU(xformer_prog = "gunzip";) | ||
1070 | if (opt & OPT_BZIP2) | ||
1071 | USE_FOR_MMU(xformer = unpack_bz2_stream;) | ||
1072 | USE_FOR_NOMMU(xformer_prog = "bunzip2";) | ||
1073 | if (opt & OPT_LZMA) | ||
1074 | USE_FOR_MMU(xformer = unpack_lzma_stream;) | ||
1075 | USE_FOR_NOMMU(xformer_prog = "unlzma";) | ||
1076 | |||
1077 | open_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog); | ||
1078 | /* Can't lseek over pipes */ | ||
1079 | tar_handle->seek = seek_by_read; | ||
1080 | /*tar_handle->offset = 0; - already is */ | ||
1081 | } | ||
1082 | |||
1083 | while (get_header_tar(tar_handle) == EXIT_SUCCESS) | ||
1121 | continue; | 1084 | continue; |
1122 | 1085 | ||
1123 | /* Check that every file that should have been extracted was */ | 1086 | /* Check that every file that should have been extracted was */ |
@@ -1133,5 +1096,11 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1133 | if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */) | 1096 | if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */) |
1134 | close(tar_handle->src_fd); | 1097 | close(tar_handle->src_fd); |
1135 | 1098 | ||
1099 | #if !ENABLE_PLATFORM_MINGW32 | ||
1100 | if (SEAMLESS_COMPRESSION || OPT_COMPRESS) { | ||
1101 | check_errors_in_children(0); | ||
1102 | return bb_got_signal; | ||
1103 | } | ||
1104 | #endif | ||
1136 | return EXIT_SUCCESS; | 1105 | return EXIT_SUCCESS; |
1137 | } | 1106 | } |
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"); |