diff options
Diffstat (limited to 'archival')
-rw-r--r-- | archival/bbunzip.c | 51 | ||||
-rw-r--r-- | archival/bzip2.c | 2 | ||||
-rw-r--r-- | archival/gzip.c | 2 | ||||
-rw-r--r-- | archival/libarchive/decompress_bunzip2.c | 11 | ||||
-rw-r--r-- | archival/libarchive/decompress_gunzip.c | 42 | ||||
-rw-r--r-- | archival/libarchive/decompress_uncompress.c | 12 | ||||
-rw-r--r-- | archival/libarchive/decompress_unlzma.c | 12 | ||||
-rw-r--r-- | archival/libarchive/decompress_unxz.c | 8 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_bz2.c | 2 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_gz.c | 2 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_lzma.c | 2 | ||||
-rw-r--r-- | archival/libarchive/open_transformer.c | 212 | ||||
-rw-r--r-- | archival/lzop.c | 2 | ||||
-rw-r--r-- | archival/tar.c | 70 | ||||
-rw-r--r-- | archival/unzip.c | 14 |
15 files changed, 267 insertions, 177 deletions
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 4d417f3f1..a859ef201 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -39,7 +39,7 @@ char* FAST_FUNC append_ext(char *filename, const char *expected_ext) | |||
39 | } | 39 | } |
40 | 40 | ||
41 | int FAST_FUNC bbunpack(char **argv, | 41 | int FAST_FUNC bbunpack(char **argv, |
42 | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux), | 42 | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_state_t *xstate), |
43 | char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), | 43 | char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), |
44 | const char *expected_ext | 44 | const char *expected_ext |
45 | ) | 45 | ) |
@@ -48,7 +48,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
48 | IF_DESKTOP(long long) int status = 0; | 48 | IF_DESKTOP(long long) int status = 0; |
49 | char *filename, *new_name; | 49 | char *filename, *new_name; |
50 | smallint exitcode = 0; | 50 | smallint exitcode = 0; |
51 | transformer_aux_data_t aux; | 51 | transformer_state_t xstate; |
52 | 52 | ||
53 | do { | 53 | do { |
54 | /* NB: new_name is *maybe* malloc'ed! */ | 54 | /* NB: new_name is *maybe* malloc'ed! */ |
@@ -120,9 +120,11 @@ int FAST_FUNC bbunpack(char **argv, | |||
120 | } | 120 | } |
121 | 121 | ||
122 | if (!(option_mask32 & SEAMLESS_MAGIC)) { | 122 | if (!(option_mask32 & SEAMLESS_MAGIC)) { |
123 | init_transformer_aux_data(&aux); | 123 | init_transformer_state(&xstate); |
124 | aux.check_signature = 1; | 124 | xstate.check_signature = 1; |
125 | status = unpacker(&aux); | 125 | /*xstate.src_fd = STDIN_FILENO; - already is */ |
126 | xstate.dst_fd = STDOUT_FILENO; | ||
127 | status = unpacker(&xstate); | ||
126 | if (status < 0) | 128 | if (status < 0) |
127 | exitcode = 1; | 129 | exitcode = 1; |
128 | } else { | 130 | } else { |
@@ -141,10 +143,10 @@ int FAST_FUNC bbunpack(char **argv, | |||
141 | unsigned new_name_len; | 143 | unsigned new_name_len; |
142 | 144 | ||
143 | /* TODO: restore other things? */ | 145 | /* TODO: restore other things? */ |
144 | if (aux.mtime != 0) { | 146 | if (xstate.mtime != 0) { |
145 | struct timeval times[2]; | 147 | struct timeval times[2]; |
146 | 148 | ||
147 | times[1].tv_sec = times[0].tv_sec = aux.mtime; | 149 | times[1].tv_sec = times[0].tv_sec = xstate.mtime; |
148 | times[1].tv_usec = times[0].tv_usec = 0; | 150 | times[1].tv_usec = times[0].tv_usec = 0; |
149 | /* Note: we closed it first. | 151 | /* Note: we closed it first. |
150 | * On some systems calling utimes | 152 | * On some systems calling utimes |
@@ -228,18 +230,13 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) | |||
228 | //applet:IF_UNCOMPRESS(APPLET(uncompress, BB_DIR_BIN, BB_SUID_DROP)) | 230 | //applet:IF_UNCOMPRESS(APPLET(uncompress, BB_DIR_BIN, BB_SUID_DROP)) |
229 | //kbuild:lib-$(CONFIG_UNCOMPRESS) += bbunzip.o | 231 | //kbuild:lib-$(CONFIG_UNCOMPRESS) += bbunzip.o |
230 | #if ENABLE_UNCOMPRESS | 232 | #if ENABLE_UNCOMPRESS |
231 | static | ||
232 | IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(transformer_aux_data_t *aux) | ||
233 | { | ||
234 | return unpack_Z_stream(aux, STDIN_FILENO, STDOUT_FILENO); | ||
235 | } | ||
236 | int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 233 | int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
237 | int uncompress_main(int argc UNUSED_PARAM, char **argv) | 234 | int uncompress_main(int argc UNUSED_PARAM, char **argv) |
238 | { | 235 | { |
239 | getopt32(argv, "cf"); | 236 | getopt32(argv, "cf"); |
240 | argv += optind; | 237 | argv += optind; |
241 | 238 | ||
242 | return bbunpack(argv, unpack_uncompress, make_new_name_generic, "Z"); | 239 | return bbunpack(argv, unpack_Z_stream, make_new_name_generic, "Z"); |
243 | } | 240 | } |
244 | #endif | 241 | #endif |
245 | 242 | ||
@@ -326,11 +323,6 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN | |||
326 | } | 323 | } |
327 | return filename; | 324 | return filename; |
328 | } | 325 | } |
329 | static | ||
330 | IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(transformer_aux_data_t *aux) | ||
331 | { | ||
332 | return unpack_gz_stream(aux, STDIN_FILENO, STDOUT_FILENO); | ||
333 | } | ||
334 | /* | 326 | /* |
335 | * Linux kernel build uses gzip -d -n. We accept and ignore it. | 327 | * Linux kernel build uses gzip -d -n. We accept and ignore it. |
336 | * Man page says: | 328 | * Man page says: |
@@ -357,7 +349,7 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
357 | if (applet_name[1] == 'c') | 349 | if (applet_name[1] == 'c') |
358 | option_mask32 |= OPT_STDOUT | SEAMLESS_MAGIC; | 350 | option_mask32 |= OPT_STDOUT | SEAMLESS_MAGIC; |
359 | 351 | ||
360 | return bbunpack(argv, unpack_gunzip, make_new_name_gunzip, /*unused:*/ NULL); | 352 | return bbunpack(argv, unpack_gz_stream, make_new_name_gunzip, /*unused:*/ NULL); |
361 | } | 353 | } |
362 | #endif | 354 | #endif |
363 | 355 | ||
@@ -397,11 +389,6 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
397 | //kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o | 389 | //kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o |
398 | //kbuild:lib-$(CONFIG_BUNZIP2) += bbunzip.o | 390 | //kbuild:lib-$(CONFIG_BUNZIP2) += bbunzip.o |
399 | #if ENABLE_BUNZIP2 | 391 | #if ENABLE_BUNZIP2 |
400 | static | ||
401 | IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(transformer_aux_data_t *aux) | ||
402 | { | ||
403 | return unpack_bz2_stream(aux, STDIN_FILENO, STDOUT_FILENO); | ||
404 | } | ||
405 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 392 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
406 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) | 393 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) |
407 | { | 394 | { |
@@ -410,7 +397,7 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
410 | if (applet_name[2] == 'c') /* bzcat */ | 397 | if (applet_name[2] == 'c') /* bzcat */ |
411 | option_mask32 |= OPT_STDOUT; | 398 | option_mask32 |= OPT_STDOUT; |
412 | 399 | ||
413 | return bbunpack(argv, unpack_bunzip2, make_new_name_generic, "bz2"); | 400 | return bbunpack(argv, unpack_bz2_stream, make_new_name_generic, "bz2"); |
414 | } | 401 | } |
415 | #endif | 402 | #endif |
416 | 403 | ||
@@ -496,11 +483,6 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
496 | //applet:IF_LZMA(APPLET_ODDNAME(lzma, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzma)) | 483 | //applet:IF_LZMA(APPLET_ODDNAME(lzma, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzma)) |
497 | //kbuild:lib-$(CONFIG_UNLZMA) += bbunzip.o | 484 | //kbuild:lib-$(CONFIG_UNLZMA) += bbunzip.o |
498 | #if ENABLE_UNLZMA | 485 | #if ENABLE_UNLZMA |
499 | static | ||
500 | IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(transformer_aux_data_t *aux) | ||
501 | { | ||
502 | return unpack_lzma_stream(aux, STDIN_FILENO, STDOUT_FILENO); | ||
503 | } | ||
504 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 486 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
505 | int unlzma_main(int argc UNUSED_PARAM, char **argv) | 487 | int unlzma_main(int argc UNUSED_PARAM, char **argv) |
506 | { | 488 | { |
@@ -515,7 +497,7 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |||
515 | option_mask32 |= OPT_STDOUT; | 497 | option_mask32 |= OPT_STDOUT; |
516 | 498 | ||
517 | argv += optind; | 499 | argv += optind; |
518 | return bbunpack(argv, unpack_unlzma, make_new_name_generic, "lzma"); | 500 | return bbunpack(argv, unpack_lzma_stream, make_new_name_generic, "lzma"); |
519 | } | 501 | } |
520 | #endif | 502 | #endif |
521 | 503 | ||
@@ -539,11 +521,6 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |||
539 | //applet:IF_XZ(APPLET_ODDNAME(xz, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xz)) | 521 | //applet:IF_XZ(APPLET_ODDNAME(xz, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xz)) |
540 | //kbuild:lib-$(CONFIG_UNXZ) += bbunzip.o | 522 | //kbuild:lib-$(CONFIG_UNXZ) += bbunzip.o |
541 | #if ENABLE_UNXZ | 523 | #if ENABLE_UNXZ |
542 | static | ||
543 | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(transformer_aux_data_t *aux) | ||
544 | { | ||
545 | return unpack_xz_stream(aux, STDIN_FILENO, STDOUT_FILENO); | ||
546 | } | ||
547 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 524 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
548 | int unxz_main(int argc UNUSED_PARAM, char **argv) | 525 | int unxz_main(int argc UNUSED_PARAM, char **argv) |
549 | { | 526 | { |
@@ -558,6 +535,6 @@ int unxz_main(int argc UNUSED_PARAM, char **argv) | |||
558 | option_mask32 |= OPT_STDOUT; | 535 | option_mask32 |= OPT_STDOUT; |
559 | 536 | ||
560 | argv += optind; | 537 | argv += optind; |
561 | return bbunpack(argv, unpack_unxz, make_new_name_generic, "xz"); | 538 | return bbunpack(argv, unpack_xz_stream, make_new_name_generic, "xz"); |
562 | } | 539 | } |
563 | #endif | 540 | #endif |
diff --git a/archival/bzip2.c b/archival/bzip2.c index f7718b411..47fa29af3 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c | |||
@@ -127,7 +127,7 @@ IF_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, vo | |||
127 | } | 127 | } |
128 | 128 | ||
129 | static | 129 | static |
130 | IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_aux_data_t *aux UNUSED_PARAM) | 130 | IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_state_t *xstate UNUSED_PARAM) |
131 | { | 131 | { |
132 | IF_DESKTOP(long long) int total; | 132 | IF_DESKTOP(long long) int total; |
133 | ssize_t count; | 133 | ssize_t count; |
diff --git a/archival/gzip.c b/archival/gzip.c index 1e779c9c3..a93d2175a 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -2042,7 +2042,7 @@ static void zip(ulg time_stamp) | |||
2042 | 2042 | ||
2043 | /* ======================================================================== */ | 2043 | /* ======================================================================== */ |
2044 | static | 2044 | static |
2045 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_aux_data_t *aux UNUSED_PARAM) | 2045 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM) |
2046 | { | 2046 | { |
2047 | struct stat s; | 2047 | struct stat s; |
2048 | 2048 | ||
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index 6396fe40d..fe5953da2 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c | |||
@@ -731,7 +731,7 @@ void FAST_FUNC dealloc_bunzip(bunzip_data *bd) | |||
731 | 731 | ||
732 | /* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */ | 732 | /* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */ |
733 | IF_DESKTOP(long long) int FAST_FUNC | 733 | IF_DESKTOP(long long) int FAST_FUNC |
734 | unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | 734 | unpack_bz2_stream(transformer_state_t *xstate) |
735 | { | 735 | { |
736 | IF_DESKTOP(long long total_written = 0;) | 736 | IF_DESKTOP(long long total_written = 0;) |
737 | bunzip_data *bd; | 737 | bunzip_data *bd; |
@@ -739,14 +739,14 @@ unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
739 | int i; | 739 | int i; |
740 | unsigned len; | 740 | unsigned len; |
741 | 741 | ||
742 | if (check_signature16(aux, src_fd, BZIP2_MAGIC)) | 742 | if (check_signature16(xstate, BZIP2_MAGIC)) |
743 | return -1; | 743 | return -1; |
744 | 744 | ||
745 | outbuf = xmalloc(IOBUF_SIZE); | 745 | outbuf = xmalloc(IOBUF_SIZE); |
746 | len = 0; | 746 | len = 0; |
747 | while (1) { /* "Process one BZ... stream" loop */ | 747 | while (1) { /* "Process one BZ... stream" loop */ |
748 | 748 | ||
749 | i = start_bunzip(&bd, src_fd, outbuf + 2, len); | 749 | i = start_bunzip(&bd, xstate->src_fd, outbuf + 2, len); |
750 | 750 | ||
751 | if (i == 0) { | 751 | if (i == 0) { |
752 | while (1) { /* "Produce some output bytes" loop */ | 752 | while (1) { /* "Produce some output bytes" loop */ |
@@ -756,8 +756,7 @@ unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
756 | i = IOBUF_SIZE - i; /* number of bytes produced */ | 756 | i = IOBUF_SIZE - i; /* number of bytes produced */ |
757 | if (i == 0) /* EOF? */ | 757 | if (i == 0) /* EOF? */ |
758 | break; | 758 | break; |
759 | if (i != full_write(dst_fd, outbuf, i)) { | 759 | if (i != transformer_write(xstate, outbuf, i)) { |
760 | bb_error_msg("short write"); | ||
761 | i = RETVAL_SHORT_WRITE; | 760 | i = RETVAL_SHORT_WRITE; |
762 | goto release_mem; | 761 | goto release_mem; |
763 | } | 762 | } |
@@ -790,7 +789,7 @@ unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
790 | len = bd->inbufCount - bd->inbufPos; | 789 | len = bd->inbufCount - bd->inbufPos; |
791 | memcpy(outbuf, &bd->inbuf[bd->inbufPos], len); | 790 | memcpy(outbuf, &bd->inbuf[bd->inbufPos], len); |
792 | if (len < 2) { | 791 | if (len < 2) { |
793 | if (safe_read(src_fd, outbuf + len, 2 - len) != 2 - len) | 792 | if (safe_read(xstate->src_fd, outbuf + len, 2 - len) != 2 - len) |
794 | break; | 793 | break; |
795 | len = 2; | 794 | len = 2; |
796 | } | 795 | } |
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 7c6f38ec3..1360abef7 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -971,7 +971,7 @@ static int inflate_get_next_window(STATE_PARAM_ONLY) | |||
971 | 971 | ||
972 | /* Called from unpack_gz_stream() and inflate_unzip() */ | 972 | /* Called from unpack_gz_stream() and inflate_unzip() */ |
973 | static IF_DESKTOP(long long) int | 973 | static IF_DESKTOP(long long) int |
974 | inflate_unzip_internal(STATE_PARAM int in, int out) | 974 | inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate) |
975 | { | 975 | { |
976 | IF_DESKTOP(long long) int n = 0; | 976 | IF_DESKTOP(long long) int n = 0; |
977 | ssize_t nwrote; | 977 | ssize_t nwrote; |
@@ -980,7 +980,7 @@ inflate_unzip_internal(STATE_PARAM int in, int out) | |||
980 | gunzip_window = xmalloc(GUNZIP_WSIZE); | 980 | gunzip_window = xmalloc(GUNZIP_WSIZE); |
981 | gunzip_outbuf_count = 0; | 981 | gunzip_outbuf_count = 0; |
982 | gunzip_bytes_out = 0; | 982 | gunzip_bytes_out = 0; |
983 | gunzip_src_fd = in; | 983 | gunzip_src_fd = xstate->src_fd; |
984 | 984 | ||
985 | /* (re) initialize state */ | 985 | /* (re) initialize state */ |
986 | method = -1; | 986 | method = -1; |
@@ -1002,9 +1002,8 @@ inflate_unzip_internal(STATE_PARAM int in, int out) | |||
1002 | 1002 | ||
1003 | while (1) { | 1003 | while (1) { |
1004 | int r = inflate_get_next_window(PASS_STATE_ONLY); | 1004 | int r = inflate_get_next_window(PASS_STATE_ONLY); |
1005 | nwrote = full_write(out, gunzip_window, gunzip_outbuf_count); | 1005 | nwrote = transformer_write(xstate, gunzip_window, gunzip_outbuf_count); |
1006 | if (nwrote != (ssize_t)gunzip_outbuf_count) { | 1006 | if (nwrote == (ssize_t)-1) { |
1007 | bb_perror_msg("write"); | ||
1008 | n = -1; | 1007 | n = -1; |
1009 | goto ret; | 1008 | goto ret; |
1010 | } | 1009 | } |
@@ -1034,22 +1033,22 @@ inflate_unzip_internal(STATE_PARAM int in, int out) | |||
1034 | /* For unzip */ | 1033 | /* For unzip */ |
1035 | 1034 | ||
1036 | IF_DESKTOP(long long) int FAST_FUNC | 1035 | IF_DESKTOP(long long) int FAST_FUNC |
1037 | inflate_unzip(transformer_aux_data_t *aux, int in, int out) | 1036 | inflate_unzip(transformer_state_t *xstate) |
1038 | { | 1037 | { |
1039 | IF_DESKTOP(long long) int n; | 1038 | IF_DESKTOP(long long) int n; |
1040 | DECLARE_STATE; | 1039 | DECLARE_STATE; |
1041 | 1040 | ||
1042 | ALLOC_STATE; | 1041 | ALLOC_STATE; |
1043 | 1042 | ||
1044 | to_read = aux->bytes_in; | 1043 | to_read = xstate->bytes_in; |
1045 | // bytebuffer_max = 0x8000; | 1044 | // bytebuffer_max = 0x8000; |
1046 | bytebuffer_offset = 4; | 1045 | bytebuffer_offset = 4; |
1047 | bytebuffer = xmalloc(bytebuffer_max); | 1046 | bytebuffer = xmalloc(bytebuffer_max); |
1048 | n = inflate_unzip_internal(PASS_STATE in, out); | 1047 | n = inflate_unzip_internal(PASS_STATE xstate); |
1049 | free(bytebuffer); | 1048 | free(bytebuffer); |
1050 | 1049 | ||
1051 | aux->crc32 = gunzip_crc; | 1050 | xstate->crc32 = gunzip_crc; |
1052 | aux->bytes_out = gunzip_bytes_out; | 1051 | xstate->bytes_out = gunzip_bytes_out; |
1053 | DEALLOC_STATE; | 1052 | DEALLOC_STATE; |
1054 | return n; | 1053 | return n; |
1055 | } | 1054 | } |
@@ -1107,7 +1106,7 @@ static uint32_t buffer_read_le_u32(STATE_PARAM_ONLY) | |||
1107 | return res; | 1106 | return res; |
1108 | } | 1107 | } |
1109 | 1108 | ||
1110 | static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux) | 1109 | static int check_header_gzip(STATE_PARAM transformer_state_t *xstate) |
1111 | { | 1110 | { |
1112 | union { | 1111 | union { |
1113 | unsigned char raw[8]; | 1112 | unsigned char raw[8]; |
@@ -1169,8 +1168,7 @@ static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux) | |||
1169 | } | 1168 | } |
1170 | } | 1169 | } |
1171 | 1170 | ||
1172 | if (aux) | 1171 | xstate->mtime = SWAP_LE32(header.formatted.mtime); |
1173 | aux->mtime = SWAP_LE32(header.formatted.mtime); | ||
1174 | 1172 | ||
1175 | /* Read the header checksum */ | 1173 | /* Read the header checksum */ |
1176 | if (header.formatted.flags & 0x02) { | 1174 | if (header.formatted.flags & 0x02) { |
@@ -1182,27 +1180,27 @@ static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux) | |||
1182 | } | 1180 | } |
1183 | 1181 | ||
1184 | IF_DESKTOP(long long) int FAST_FUNC | 1182 | IF_DESKTOP(long long) int FAST_FUNC |
1185 | unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | 1183 | unpack_gz_stream(transformer_state_t *xstate) |
1186 | { | 1184 | { |
1187 | uint32_t v32; | 1185 | uint32_t v32; |
1188 | IF_DESKTOP(long long) int total, n; | 1186 | IF_DESKTOP(long long) int total, n; |
1189 | DECLARE_STATE; | 1187 | DECLARE_STATE; |
1190 | 1188 | ||
1191 | #if !ENABLE_FEATURE_SEAMLESS_Z | 1189 | #if !ENABLE_FEATURE_SEAMLESS_Z |
1192 | if (check_signature16(aux, src_fd, GZIP_MAGIC)) | 1190 | if (check_signature16(xstate, GZIP_MAGIC)) |
1193 | return -1; | 1191 | return -1; |
1194 | #else | 1192 | #else |
1195 | if (aux && aux->check_signature) { | 1193 | if (xstate->check_signature) { |
1196 | uint16_t magic2; | 1194 | uint16_t magic2; |
1197 | 1195 | ||
1198 | if (full_read(src_fd, &magic2, 2) != 2) { | 1196 | if (full_read(xstate->src_fd, &magic2, 2) != 2) { |
1199 | bad_magic: | 1197 | bad_magic: |
1200 | bb_error_msg("invalid magic"); | 1198 | bb_error_msg("invalid magic"); |
1201 | return -1; | 1199 | return -1; |
1202 | } | 1200 | } |
1203 | if (magic2 == COMPRESS_MAGIC) { | 1201 | if (magic2 == COMPRESS_MAGIC) { |
1204 | aux->check_signature = 0; | 1202 | xstate->check_signature = 0; |
1205 | return unpack_Z_stream(aux, src_fd, dst_fd); | 1203 | return unpack_Z_stream(xstate); |
1206 | } | 1204 | } |
1207 | if (magic2 != GZIP_MAGIC) | 1205 | if (magic2 != GZIP_MAGIC) |
1208 | goto bad_magic; | 1206 | goto bad_magic; |
@@ -1215,16 +1213,16 @@ unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
1215 | to_read = -1; | 1213 | to_read = -1; |
1216 | // bytebuffer_max = 0x8000; | 1214 | // bytebuffer_max = 0x8000; |
1217 | bytebuffer = xmalloc(bytebuffer_max); | 1215 | bytebuffer = xmalloc(bytebuffer_max); |
1218 | gunzip_src_fd = src_fd; | 1216 | gunzip_src_fd = xstate->src_fd; |
1219 | 1217 | ||
1220 | again: | 1218 | again: |
1221 | if (!check_header_gzip(PASS_STATE aux)) { | 1219 | if (!check_header_gzip(PASS_STATE xstate)) { |
1222 | bb_error_msg("corrupted data"); | 1220 | bb_error_msg("corrupted data"); |
1223 | total = -1; | 1221 | total = -1; |
1224 | goto ret; | 1222 | goto ret; |
1225 | } | 1223 | } |
1226 | 1224 | ||
1227 | n = inflate_unzip_internal(PASS_STATE src_fd, dst_fd); | 1225 | n = inflate_unzip_internal(PASS_STATE xstate); |
1228 | if (n < 0) { | 1226 | if (n < 0) { |
1229 | total = -1; | 1227 | total = -1; |
1230 | goto ret; | 1228 | goto ret; |
diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c index 53c27080f..496d864a7 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(transformer_aux_data_t *aux, int src_fd, int dst_fd) | 76 | unpack_Z_stream(transformer_state_t *xstate) |
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; |
@@ -102,7 +102,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
102 | /* block compress mode -C compatible with 2.0 */ | 102 | /* block compress mode -C compatible with 2.0 */ |
103 | int block_mode; /* = BLOCK_MODE; */ | 103 | int block_mode; /* = BLOCK_MODE; */ |
104 | 104 | ||
105 | if (check_signature16(aux, src_fd, COMPRESS_MAGIC)) | 105 | if (check_signature16(xstate, COMPRESS_MAGIC)) |
106 | return -1; | 106 | return -1; |
107 | 107 | ||
108 | inbuf = xzalloc(IBUFSIZ + 64); | 108 | inbuf = xzalloc(IBUFSIZ + 64); |
@@ -114,7 +114,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
114 | 114 | ||
115 | /* xread isn't good here, we have to return - caller may want | 115 | /* xread isn't good here, we have to return - caller may want |
116 | * to do some cleanup (e.g. delete incomplete unpacked file etc) */ | 116 | * to do some cleanup (e.g. delete incomplete unpacked file etc) */ |
117 | if (full_read(src_fd, inbuf, 1) != 1) { | 117 | if (full_read(xstate->src_fd, inbuf, 1) != 1) { |
118 | bb_error_msg("short read"); | 118 | bb_error_msg("short read"); |
119 | goto err; | 119 | goto err; |
120 | } | 120 | } |
@@ -166,7 +166,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
166 | } | 166 | } |
167 | 167 | ||
168 | if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { | 168 | if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { |
169 | rsize = safe_read(src_fd, inbuf + insize, IBUFSIZ); | 169 | rsize = safe_read(xstate->src_fd, inbuf + insize, IBUFSIZ); |
170 | if (rsize < 0) | 170 | if (rsize < 0) |
171 | bb_error_msg_and_die(bb_msg_read_error); | 171 | bb_error_msg_and_die(bb_msg_read_error); |
172 | insize += rsize; | 172 | insize += rsize; |
@@ -274,7 +274,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
274 | } | 274 | } |
275 | 275 | ||
276 | if (outpos >= OBUFSIZ) { | 276 | if (outpos >= OBUFSIZ) { |
277 | xwrite(dst_fd, outbuf, outpos); | 277 | xtransformer_write(xstate, outbuf, outpos); |
278 | IF_DESKTOP(total_written += outpos;) | 278 | IF_DESKTOP(total_written += outpos;) |
279 | outpos = 0; | 279 | outpos = 0; |
280 | } | 280 | } |
@@ -301,7 +301,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
301 | } while (rsize > 0); | 301 | } while (rsize > 0); |
302 | 302 | ||
303 | if (outpos > 0) { | 303 | if (outpos > 0) { |
304 | xwrite(dst_fd, outbuf, outpos); | 304 | xtransformer_write(xstate, outbuf, outpos); |
305 | IF_DESKTOP(total_written += outpos;) | 305 | IF_DESKTOP(total_written += outpos;) |
306 | } | 306 | } |
307 | 307 | ||
diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index 3d99e1388..c8622f97b 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c | |||
@@ -206,7 +206,7 @@ enum { | |||
206 | 206 | ||
207 | 207 | ||
208 | IF_DESKTOP(long long) int FAST_FUNC | 208 | IF_DESKTOP(long long) int FAST_FUNC |
209 | unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst_fd) | 209 | unpack_lzma_stream(transformer_state_t *xstate) |
210 | { | 210 | { |
211 | IF_DESKTOP(long long total_written = 0;) | 211 | IF_DESKTOP(long long total_written = 0;) |
212 | lzma_header_t header; | 212 | lzma_header_t header; |
@@ -223,7 +223,7 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst | |||
223 | int state = 0; | 223 | int state = 0; |
224 | uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; | 224 | uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; |
225 | 225 | ||
226 | if (full_read(src_fd, &header, sizeof(header)) != sizeof(header) | 226 | if (full_read(xstate->src_fd, &header, sizeof(header)) != sizeof(header) |
227 | || header.pos >= (9 * 5 * 5) | 227 | || header.pos >= (9 * 5 * 5) |
228 | ) { | 228 | ) { |
229 | bb_error_msg("bad lzma header"); | 229 | bb_error_msg("bad lzma header"); |
@@ -258,7 +258,7 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst | |||
258 | p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; | 258 | p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; |
259 | } | 259 | } |
260 | 260 | ||
261 | rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */ | 261 | rc = rc_init(xstate->src_fd); /*, RC_BUFFER_SIZE); */ |
262 | 262 | ||
263 | while (global_pos + buffer_pos < header.dst_size) { | 263 | while (global_pos + buffer_pos < header.dst_size) { |
264 | int pos_state = (buffer_pos + global_pos) & pos_state_mask; | 264 | int pos_state = (buffer_pos + global_pos) & pos_state_mask; |
@@ -306,7 +306,7 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst | |||
306 | if (buffer_pos == header.dict_size) { | 306 | if (buffer_pos == header.dict_size) { |
307 | buffer_pos = 0; | 307 | buffer_pos = 0; |
308 | global_pos += header.dict_size; | 308 | global_pos += header.dict_size; |
309 | if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size) | 309 | if (transformer_write(xstate, buffer, header.dict_size) != (ssize_t)header.dict_size) |
310 | goto bad; | 310 | goto bad; |
311 | IF_DESKTOP(total_written += header.dict_size;) | 311 | IF_DESKTOP(total_written += header.dict_size;) |
312 | } | 312 | } |
@@ -440,7 +440,7 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst | |||
440 | if (buffer_pos == header.dict_size) { | 440 | if (buffer_pos == header.dict_size) { |
441 | buffer_pos = 0; | 441 | buffer_pos = 0; |
442 | global_pos += header.dict_size; | 442 | global_pos += header.dict_size; |
443 | if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size) | 443 | if (transformer_write(xstate, buffer, header.dict_size) != (ssize_t)header.dict_size) |
444 | goto bad; | 444 | goto bad; |
445 | IF_DESKTOP(total_written += header.dict_size;) | 445 | IF_DESKTOP(total_written += header.dict_size;) |
446 | } | 446 | } |
@@ -455,7 +455,7 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst | |||
455 | { | 455 | { |
456 | IF_NOT_DESKTOP(int total_written = 0; /* success */) | 456 | IF_NOT_DESKTOP(int total_written = 0; /* success */) |
457 | IF_DESKTOP(total_written += buffer_pos;) | 457 | IF_DESKTOP(total_written += buffer_pos;) |
458 | if (full_write(dst_fd, buffer, buffer_pos) != (ssize_t)buffer_pos) { | 458 | if (transformer_write(xstate, buffer, buffer_pos) != (ssize_t)buffer_pos) { |
459 | bad: | 459 | bad: |
460 | total_written = -1; /* failure */ | 460 | total_written = -1; /* failure */ |
461 | } | 461 | } |
diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index 986b7b191..1f408abfd 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(transformer_aux_data_t *aux, int src_fd, int dst_fd) | 41 | unpack_xz_stream(transformer_state_t *xstate) |
42 | { | 42 | { |
43 | enum xz_ret xz_result; | 43 | enum xz_ret xz_result; |
44 | struct xz_buf iobuf; | 44 | struct xz_buf iobuf; |
@@ -55,7 +55,7 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
55 | iobuf.out = membuf + BUFSIZ; | 55 | iobuf.out = membuf + BUFSIZ; |
56 | iobuf.out_size = BUFSIZ; | 56 | iobuf.out_size = BUFSIZ; |
57 | 57 | ||
58 | if (!aux || aux->check_signature == 0) { | 58 | if (!xstate || xstate->check_signature == 0) { |
59 | /* Preload XZ file signature */ | 59 | /* Preload XZ file signature */ |
60 | strcpy((char*)membuf, HEADER_MAGIC); | 60 | strcpy((char*)membuf, HEADER_MAGIC); |
61 | iobuf.in_size = HEADER_MAGIC_SIZE; | 61 | iobuf.in_size = HEADER_MAGIC_SIZE; |
@@ -67,7 +67,7 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
67 | xz_result = X_OK; | 67 | xz_result = X_OK; |
68 | while (1) { | 68 | while (1) { |
69 | if (iobuf.in_pos == iobuf.in_size) { | 69 | if (iobuf.in_pos == iobuf.in_size) { |
70 | int rd = safe_read(src_fd, membuf, BUFSIZ); | 70 | int rd = safe_read(xstate->src_fd, membuf, BUFSIZ); |
71 | if (rd < 0) { | 71 | if (rd < 0) { |
72 | bb_error_msg(bb_msg_read_error); | 72 | bb_error_msg(bb_msg_read_error); |
73 | total = -1; | 73 | total = -1; |
@@ -104,7 +104,7 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | |||
104 | // bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d", | 104 | // bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d", |
105 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, xz_result); | 105 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, xz_result); |
106 | if (iobuf.out_pos) { | 106 | if (iobuf.out_pos) { |
107 | xwrite(dst_fd, iobuf.out, iobuf.out_pos); | 107 | xtransformer_write(xstate, iobuf.out, iobuf.out_pos); |
108 | IF_DESKTOP(total += iobuf.out_pos;) | 108 | IF_DESKTOP(total += iobuf.out_pos;) |
109 | iobuf.out_pos = 0; | 109 | iobuf.out_pos = 0; |
110 | } | 110 | } |
diff --git a/archival/libarchive/get_header_tar_bz2.c b/archival/libarchive/get_header_tar_bz2.c index 0ee00df53..78f78a858 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_with_sig(archive_handle->src_fd, unpack_bz2_stream, "bunzip2"); | 14 | fork_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 03284342b..b11f503dc 100644 --- a/archival/libarchive/get_header_tar_gz.c +++ b/archival/libarchive/get_header_tar_gz.c | |||
@@ -11,7 +11,7 @@ char FAST_FUNC get_header_tar_gz(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_with_sig(archive_handle->src_fd, unpack_gz_stream, "gunzip"); | 14 | fork_transformer_with_sig(archive_handle->src_fd, unpack_gz_stream, "gunzip"); |
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_lzma.c b/archival/libarchive/get_header_tar_lzma.c index d565a217d..d228cbc13 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_with_sig(archive_handle->src_fd, unpack_lzma_stream, "unlzma"); | 17 | fork_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 7e0d1dd02..0a8c657b7 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
@@ -6,19 +6,19 @@ | |||
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) | 9 | void FAST_FUNC init_transformer_state(transformer_state_t *xstate) |
10 | { | 10 | { |
11 | memset(aux, 0, sizeof(*aux)); | 11 | memset(xstate, 0, sizeof(*xstate)); |
12 | } | 12 | } |
13 | 13 | ||
14 | int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16) | 14 | int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16) |
15 | { | 15 | { |
16 | if (aux && aux->check_signature) { | 16 | if (xstate->check_signature) { |
17 | uint16_t magic2; | 17 | uint16_t magic2; |
18 | if (full_read(src_fd, &magic2, 2) != 2 || magic2 != magic16) { | 18 | if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) { |
19 | bb_error_msg("invalid magic"); | 19 | bb_error_msg("invalid magic"); |
20 | #if 0 /* possible future extension */ | 20 | #if 0 /* possible future extension */ |
21 | if (aux->check_signature > 1) | 21 | if (xstate->check_signature > 1) |
22 | xfunc_die(); | 22 | xfunc_die(); |
23 | #endif | 23 | #endif |
24 | return -1; | 24 | return -1; |
@@ -27,9 +27,48 @@ int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigne | |||
27 | return 0; | 27 | return 0; |
28 | } | 28 | } |
29 | 29 | ||
30 | ssize_t FAST_FUNC transformer_write(transformer_state_t *xstate, const void *buf, size_t bufsize) | ||
31 | { | ||
32 | ssize_t nwrote; | ||
30 | 33 | ||
31 | #if SEAMLESS_COMPRESSION | 34 | if (xstate->mem_output_size_max != 0) { |
35 | size_t pos = xstate->mem_output_size; | ||
36 | size_t size; | ||
37 | |||
38 | size = (xstate->mem_output_size += bufsize); | ||
39 | if (size > xstate->mem_output_size_max) { | ||
40 | free(xstate->mem_output_buf); | ||
41 | xstate->mem_output_buf = NULL; | ||
42 | bb_perror_msg("buffer %u too small", (unsigned)xstate->mem_output_size_max); | ||
43 | nwrote = -1; | ||
44 | goto ret; | ||
45 | } | ||
46 | xstate->mem_output_buf = xrealloc(xstate->mem_output_buf, size + 1); | ||
47 | memcpy(xstate->mem_output_buf + pos, buf, bufsize); | ||
48 | xstate->mem_output_buf[size] = '\0'; | ||
49 | nwrote = bufsize; | ||
50 | } else { | ||
51 | nwrote = full_write(xstate->dst_fd, buf, bufsize); | ||
52 | if (nwrote != (ssize_t)bufsize) { | ||
53 | bb_perror_msg("write"); | ||
54 | nwrote = -1; | ||
55 | goto ret; | ||
56 | } | ||
57 | } | ||
58 | ret: | ||
59 | return nwrote; | ||
60 | } | ||
61 | |||
62 | ssize_t FAST_FUNC xtransformer_write(transformer_state_t *xstate, const void *buf, size_t bufsize) | ||
63 | { | ||
64 | ssize_t nwrote = transformer_write(xstate, buf, bufsize); | ||
65 | if (nwrote != (ssize_t)bufsize) { | ||
66 | xfunc_die(); | ||
67 | } | ||
68 | return nwrote; | ||
69 | } | ||
32 | 70 | ||
71 | #if SEAMLESS_COMPRESSION | ||
33 | void check_errors_in_children(int signo) | 72 | void check_errors_in_children(int signo) |
34 | { | 73 | { |
35 | int status; | 74 | int status; |
@@ -63,12 +102,12 @@ void check_errors_in_children(int signo) | |||
63 | 102 | ||
64 | /* transformer(), more than meets the eye */ | 103 | /* transformer(), more than meets the eye */ |
65 | #if BB_MMU | 104 | #if BB_MMU |
66 | void FAST_FUNC open_transformer(int fd, | 105 | void FAST_FUNC fork_transformer(int fd, |
67 | int check_signature, | 106 | int check_signature, |
68 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd) | 107 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate) |
69 | ) | 108 | ) |
70 | #else | 109 | #else |
71 | void FAST_FUNC open_transformer(int fd, const char *transform_prog) | 110 | void FAST_FUNC fork_transformer(int fd, const char *transform_prog) |
72 | #endif | 111 | #endif |
73 | { | 112 | { |
74 | struct fd_pair fd_pipe; | 113 | struct fd_pair fd_pipe; |
@@ -83,10 +122,12 @@ void FAST_FUNC open_transformer(int fd, const char *transform_prog) | |||
83 | #if BB_MMU | 122 | #if BB_MMU |
84 | { | 123 | { |
85 | IF_DESKTOP(long long) int r; | 124 | IF_DESKTOP(long long) int r; |
86 | transformer_aux_data_t aux; | 125 | transformer_state_t xstate; |
87 | init_transformer_aux_data(&aux); | 126 | init_transformer_state(&xstate); |
88 | aux.check_signature = check_signature; | 127 | xstate.check_signature = check_signature; |
89 | r = transformer(&aux, fd, fd_pipe.wr); | 128 | xstate.src_fd = fd; |
129 | xstate.dst_fd = fd_pipe.wr; | ||
130 | r = transformer(&xstate); | ||
90 | if (ENABLE_FEATURE_CLEAN_UP) { | 131 | if (ENABLE_FEATURE_CLEAN_UP) { |
91 | close(fd_pipe.wr); /* send EOF */ | 132 | close(fd_pipe.wr); /* send EOF */ |
92 | close(fd); | 133 | close(fd); |
@@ -118,16 +159,19 @@ void FAST_FUNC open_transformer(int fd, const char *transform_prog) | |||
118 | /* Used by e.g. rpm which gives us a fd without filename, | 159 | /* Used by e.g. rpm which gives us a fd without filename, |
119 | * thus we can't guess the format from filename's extension. | 160 | * thus we can't guess the format from filename's extension. |
120 | */ | 161 | */ |
121 | int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | 162 | static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed) |
122 | { | 163 | { |
123 | union { | 164 | union { |
124 | uint8_t b[4]; | 165 | uint8_t b[4]; |
125 | uint16_t b16[2]; | 166 | uint16_t b16[2]; |
126 | uint32_t b32[1]; | 167 | uint32_t b32[1]; |
127 | } magic; | 168 | } magic; |
128 | int offset = -2; | 169 | int offset; |
129 | USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) | 170 | transformer_state_t *xstate; |
130 | USE_FOR_NOMMU(const char *xformer_prog;) | 171 | |
172 | offset = -2; | ||
173 | xstate = xzalloc(sizeof(*xstate)); | ||
174 | xstate->src_fd = fd; | ||
131 | 175 | ||
132 | /* .gz and .bz2 both have 2-byte signature, and their | 176 | /* .gz and .bz2 both have 2-byte signature, and their |
133 | * unpack_XXX_stream wants this header skipped. */ | 177 | * unpack_XXX_stream wants this header skipped. */ |
@@ -135,15 +179,15 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | |||
135 | if (ENABLE_FEATURE_SEAMLESS_GZ | 179 | if (ENABLE_FEATURE_SEAMLESS_GZ |
136 | && magic.b16[0] == GZIP_MAGIC | 180 | && magic.b16[0] == GZIP_MAGIC |
137 | ) { | 181 | ) { |
138 | USE_FOR_MMU(xformer = unpack_gz_stream;) | 182 | xstate->xformer = unpack_gz_stream; |
139 | USE_FOR_NOMMU(xformer_prog = "gunzip";) | 183 | USE_FOR_NOMMU(xstate->xformer_prog = "gunzip";) |
140 | goto found_magic; | 184 | goto found_magic; |
141 | } | 185 | } |
142 | if (ENABLE_FEATURE_SEAMLESS_BZ2 | 186 | if (ENABLE_FEATURE_SEAMLESS_BZ2 |
143 | && magic.b16[0] == BZIP2_MAGIC | 187 | && magic.b16[0] == BZIP2_MAGIC |
144 | ) { | 188 | ) { |
145 | USE_FOR_MMU(xformer = unpack_bz2_stream;) | 189 | xstate->xformer = unpack_bz2_stream; |
146 | USE_FOR_NOMMU(xformer_prog = "bunzip2";) | 190 | USE_FOR_NOMMU(xstate->xformer_prog = "bunzip2";) |
147 | goto found_magic; | 191 | goto found_magic; |
148 | } | 192 | } |
149 | if (ENABLE_FEATURE_SEAMLESS_XZ | 193 | if (ENABLE_FEATURE_SEAMLESS_XZ |
@@ -152,8 +196,8 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | |||
152 | offset = -6; | 196 | offset = -6; |
153 | xread(fd, magic.b32, sizeof(magic.b32[0])); | 197 | xread(fd, magic.b32, sizeof(magic.b32[0])); |
154 | if (magic.b32[0] == XZ_MAGIC2) { | 198 | if (magic.b32[0] == XZ_MAGIC2) { |
155 | USE_FOR_MMU(xformer = unpack_xz_stream;) | 199 | xstate->xformer = unpack_xz_stream; |
156 | USE_FOR_NOMMU(xformer_prog = "unxz";) | 200 | USE_FOR_NOMMU(xstate->xformer_prog = "unxz";) |
157 | goto found_magic; | 201 | goto found_magic; |
158 | } | 202 | } |
159 | } | 203 | } |
@@ -164,52 +208,130 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | |||
164 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | 208 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") |
165 | IF_FEATURE_SEAMLESS_XZ("/xz") | 209 | IF_FEATURE_SEAMLESS_XZ("/xz") |
166 | " magic"); | 210 | " magic"); |
211 | |||
212 | /* Some callers expect this function to "consume" fd | ||
213 | * even if data is not compressed. In this case, | ||
214 | * we return a state with trivial transformer. | ||
215 | */ | ||
216 | // USE_FOR_MMU(xstate->xformer = copy_stream;) | ||
217 | // USE_FOR_NOMMU(xstate->xformer_prog = "cat";) | ||
218 | /* fall through to seeking bck over bytes we read earlier */ | ||
219 | |||
220 | USE_FOR_NOMMU(found_magic:) | ||
221 | /* NOMMU version of fork_transformer execs | ||
222 | * an external unzipper that wants | ||
223 | * file position at the start of the file. | ||
224 | */ | ||
167 | xlseek(fd, offset, SEEK_CUR); | 225 | xlseek(fd, offset, SEEK_CUR); |
168 | return 1; | ||
169 | 226 | ||
170 | found_magic: | 227 | USE_FOR_MMU(found_magic:) |
228 | /* In MMU case, if magic was found, seeking back is not necessary */ | ||
229 | |||
230 | return xstate; | ||
231 | } | ||
232 | |||
233 | /* Used by e.g. rpm which gives us a fd without filename, | ||
234 | * thus we can't guess the format from filename's extension. | ||
235 | */ | ||
236 | int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | ||
237 | { | ||
238 | transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); | ||
239 | |||
240 | if (!xstate || !xstate->xformer) { | ||
241 | free(xstate); | ||
242 | return 1; | ||
243 | } | ||
244 | |||
171 | # if BB_MMU | 245 | # if BB_MMU |
172 | open_transformer_with_no_sig(fd, xformer); | 246 | fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); |
173 | # else | 247 | # else |
174 | /* NOMMU version of open_transformer execs | 248 | fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); |
175 | * an external unzipper that wants | ||
176 | * file position at the start of the file */ | ||
177 | xlseek(fd, offset, SEEK_CUR); | ||
178 | open_transformer_with_sig(fd, xformer, xformer_prog); | ||
179 | # endif | 249 | # endif |
250 | free(xstate); | ||
180 | return 0; | 251 | return 0; |
181 | } | 252 | } |
182 | 253 | ||
183 | int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) | 254 | static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) |
184 | { | 255 | { |
256 | transformer_state_t *xstate; | ||
185 | int fd; | 257 | int fd; |
186 | 258 | ||
187 | fd = open(fname, O_RDONLY); | 259 | fd = open(fname, O_RDONLY); |
188 | if (fd < 0) | 260 | if (fd < 0) |
189 | return fd; | 261 | return NULL; |
190 | 262 | ||
191 | if (ENABLE_FEATURE_SEAMLESS_LZMA) { | 263 | if (ENABLE_FEATURE_SEAMLESS_LZMA) { |
192 | /* .lzma has no header/signature, can only detect it by extension */ | 264 | /* .lzma has no header/signature, can only detect it by extension */ |
193 | char *sfx = strrchr(fname, '.'); | 265 | char *sfx = strrchr(fname, '.'); |
194 | if (sfx && strcmp(sfx+1, "lzma") == 0) { | 266 | if (sfx && strcmp(sfx+1, "lzma") == 0) { |
195 | open_transformer_with_sig(fd, unpack_lzma_stream, "unlzma"); | 267 | xstate = xzalloc(sizeof(*xstate)); |
196 | return fd; | 268 | xstate->src_fd = fd; |
269 | xstate->xformer = unpack_lzma_stream; | ||
270 | USE_FOR_NOMMU(xstate->xformer_prog = "unlzma";) | ||
271 | return xstate; | ||
197 | } | 272 | } |
198 | } | 273 | } |
199 | if ((ENABLE_FEATURE_SEAMLESS_GZ) | 274 | |
200 | || (ENABLE_FEATURE_SEAMLESS_BZ2) | 275 | xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); |
201 | || (ENABLE_FEATURE_SEAMLESS_XZ) | 276 | |
202 | ) { | 277 | return xstate; |
203 | setup_unzip_on_fd(fd, fail_if_not_compressed); | 278 | } |
279 | |||
280 | int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) | ||
281 | { | ||
282 | int fd; | ||
283 | transformer_state_t *xstate; | ||
284 | |||
285 | xstate = open_transformer(fname, fail_if_not_compressed); | ||
286 | if (!xstate) | ||
287 | return -1; | ||
288 | |||
289 | fd = xstate->src_fd; | ||
290 | if (xstate->xformer) { | ||
291 | # if BB_MMU | ||
292 | fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); | ||
293 | # else | ||
294 | fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); | ||
295 | # endif | ||
204 | } | 296 | } |
297 | /* else: the file is not compressed */ | ||
205 | 298 | ||
299 | free(xstate); | ||
206 | return fd; | 300 | return fd; |
207 | } | 301 | } |
208 | 302 | ||
209 | #endif /* SEAMLESS_COMPRESSION */ | ||
210 | |||
211 | void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) | 303 | void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) |
212 | { | 304 | { |
305 | # if 1 | ||
306 | transformer_state_t *xstate; | ||
307 | char *image; | ||
308 | |||
309 | xstate = open_transformer(fname, /*fail_if_not_compressed:*/ 0); | ||
310 | if (!xstate) /* file open error */ | ||
311 | return NULL; | ||
312 | |||
313 | image = NULL; | ||
314 | if (xstate->xformer) { | ||
315 | /* In-memory decompression */ | ||
316 | xstate->mem_output_size_max = maxsz_p ? *maxsz_p : (size_t)(INT_MAX - 4095); | ||
317 | xstate->xformer(xstate); | ||
318 | if (xstate->mem_output_buf) { | ||
319 | image = xstate->mem_output_buf; | ||
320 | if (maxsz_p) | ||
321 | *maxsz_p = xstate->mem_output_size; | ||
322 | } | ||
323 | } else { | ||
324 | /* File is not compressed */ | ||
325 | image = xmalloc_read(xstate->src_fd, maxsz_p); | ||
326 | } | ||
327 | |||
328 | if (!image) | ||
329 | bb_perror_msg("read error from '%s'", fname); | ||
330 | close(xstate->src_fd); | ||
331 | free(xstate); | ||
332 | return image; | ||
333 | # else | ||
334 | /* This version forks a subprocess - much more expensive */ | ||
213 | int fd; | 335 | int fd; |
214 | char *image; | 336 | char *image; |
215 | 337 | ||
@@ -221,6 +343,8 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ | |||
221 | if (!image) | 343 | if (!image) |
222 | bb_perror_msg("read error from '%s'", fname); | 344 | bb_perror_msg("read error from '%s'", fname); |
223 | close(fd); | 345 | close(fd); |
224 | |||
225 | return image; | 346 | return image; |
347 | # endif | ||
226 | } | 348 | } |
349 | |||
350 | #endif /* SEAMLESS_COMPRESSION */ | ||
diff --git a/archival/lzop.c b/archival/lzop.c index 5062d9300..73d11a705 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -1099,7 +1099,7 @@ static char* FAST_FUNC make_new_name_lzop(char *filename, const char *expected_e | |||
1099 | return xasprintf("%s.lzo", filename); | 1099 | return xasprintf("%s.lzo", filename); |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(transformer_aux_data_t *aux UNUSED_PARAM) | 1102 | static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(transformer_state_t *xstate UNUSED_PARAM) |
1103 | { | 1103 | { |
1104 | if (option_mask32 & OPT_DECOMPRESS) | 1104 | if (option_mask32 & OPT_DECOMPRESS) |
1105 | return do_lzo_decompress(); | 1105 | return do_lzo_decompress(); |
diff --git a/archival/tar.c b/archival/tar.c index 63d844a3a..e00ed26a8 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -160,13 +160,6 @@ | |||
160 | #define block_buf bb_common_bufsiz1 | 160 | #define block_buf bb_common_bufsiz1 |
161 | 161 | ||
162 | 162 | ||
163 | #if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2 | ||
164 | /* Do not pass gzip flag to writeTarFile() */ | ||
165 | #define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \ | ||
166 | writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude) | ||
167 | #endif | ||
168 | |||
169 | |||
170 | #if ENABLE_FEATURE_TAR_CREATE | 163 | #if ENABLE_FEATURE_TAR_CREATE |
171 | 164 | ||
172 | /* | 165 | /* |
@@ -623,21 +616,12 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb | |||
623 | return TRUE; | 616 | return TRUE; |
624 | } | 617 | } |
625 | 618 | ||
626 | #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 | 619 | #if SEAMLESS_COMPRESSION |
627 | # if !(ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2) | ||
628 | # define vfork_compressor(tar_fd, gzip) vfork_compressor(tar_fd) | ||
629 | # endif | ||
630 | /* Don't inline: vfork scares gcc and pessimizes code */ | 620 | /* Don't inline: vfork scares gcc and pessimizes code */ |
631 | static void NOINLINE vfork_compressor(int tar_fd, int gzip) | 621 | static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) |
632 | { | 622 | { |
633 | pid_t gzipPid; | 623 | pid_t gzipPid; |
634 | # if ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2 | 624 | |
635 | const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2"; | ||
636 | # elif ENABLE_FEATURE_SEAMLESS_GZ | ||
637 | const char *zip_exec = "gzip"; | ||
638 | # else /* only ENABLE_FEATURE_SEAMLESS_BZ2 */ | ||
639 | const char *zip_exec = "bzip2"; | ||
640 | # endif | ||
641 | // On Linux, vfork never unpauses parent early, although standard | 625 | // On Linux, vfork never unpauses parent early, although standard |
642 | // allows for that. Do we want to waste bytes checking for it? | 626 | // allows for that. Do we want to waste bytes checking for it? |
643 | # define WAIT_FOR_CHILD 0 | 627 | # define WAIT_FOR_CHILD 0 |
@@ -651,11 +635,6 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip) | |||
651 | 635 | ||
652 | signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ | 636 | signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ |
653 | 637 | ||
654 | # if defined(__GNUC__) && __GNUC__ | ||
655 | /* Avoid vfork clobbering */ | ||
656 | (void) &zip_exec; | ||
657 | # endif | ||
658 | |||
659 | gzipPid = xvfork(); | 638 | gzipPid = xvfork(); |
660 | 639 | ||
661 | if (gzipPid == 0) { | 640 | if (gzipPid == 0) { |
@@ -671,7 +650,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip) | |||
671 | xmove_fd(gzipDataPipe.rd, 0); | 650 | xmove_fd(gzipDataPipe.rd, 0); |
672 | xmove_fd(tar_fd, 1); | 651 | xmove_fd(tar_fd, 1); |
673 | /* exec gzip/bzip2 program/applet */ | 652 | /* exec gzip/bzip2 program/applet */ |
674 | BB_EXECLP(zip_exec, zip_exec, "-f", (char *)0); | 653 | BB_EXECLP(gzip, gzip, "-f", (char *)0); |
675 | vfork_exec_errno = errno; | 654 | vfork_exec_errno = errno; |
676 | _exit(EXIT_FAILURE); | 655 | _exit(EXIT_FAILURE); |
677 | } | 656 | } |
@@ -694,16 +673,21 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip) | |||
694 | # endif | 673 | # endif |
695 | if (vfork_exec_errno) { | 674 | if (vfork_exec_errno) { |
696 | errno = vfork_exec_errno; | 675 | errno = vfork_exec_errno; |
697 | bb_perror_msg_and_die("can't execute '%s'", zip_exec); | 676 | bb_perror_msg_and_die("can't execute '%s'", gzip); |
698 | } | 677 | } |
699 | } | 678 | } |
700 | #endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */ | 679 | #endif /* SEAMLESS_COMPRESSION */ |
701 | 680 | ||
702 | 681 | ||
682 | #if !SEAMLESS_COMPRESSION | ||
683 | /* Do not pass gzip flag to writeTarFile() */ | ||
684 | #define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \ | ||
685 | writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude) | ||
686 | #endif | ||
703 | /* gcc 4.2.1 inlines it, making code bigger */ | 687 | /* gcc 4.2.1 inlines it, making code bigger */ |
704 | static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | 688 | static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, |
705 | int recurseFlags, const llist_t *include, | 689 | int recurseFlags, const llist_t *include, |
706 | const llist_t *exclude, int gzip) | 690 | const llist_t *exclude, const char *gzip) |
707 | { | 691 | { |
708 | int errorFlag = FALSE; | 692 | int errorFlag = FALSE; |
709 | struct TarBallInfo tbInfo; | 693 | struct TarBallInfo tbInfo; |
@@ -716,7 +700,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | |||
716 | * can avoid including the tarball into itself.... */ | 700 | * can avoid including the tarball into itself.... */ |
717 | xfstat(tbInfo.tarFd, &tbInfo.tarFileStatBuf, "can't stat tar file"); | 701 | xfstat(tbInfo.tarFd, &tbInfo.tarFileStatBuf, "can't stat tar file"); |
718 | 702 | ||
719 | #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 | 703 | #if SEAMLESS_COMPRESSION |
720 | if (gzip) | 704 | if (gzip) |
721 | vfork_compressor(tbInfo.tarFd, gzip); | 705 | vfork_compressor(tbInfo.tarFd, gzip); |
722 | #endif | 706 | #endif |
@@ -751,7 +735,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | |||
751 | if (errorFlag) | 735 | if (errorFlag) |
752 | bb_error_msg("error exit delayed from previous errors"); | 736 | bb_error_msg("error exit delayed from previous errors"); |
753 | 737 | ||
754 | #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 | 738 | #if SEAMLESS_COMPRESSION |
755 | if (gzip) { | 739 | if (gzip) { |
756 | int status; | 740 | int status; |
757 | if (safe_waitpid(-1, &status, 0) == -1) | 741 | if (safe_waitpid(-1, &status, 0) == -1) |
@@ -766,7 +750,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | |||
766 | #else | 750 | #else |
767 | int writeTarFile(int tar_fd, int verboseFlag, | 751 | int writeTarFile(int tar_fd, int verboseFlag, |
768 | int recurseFlags, const llist_t *include, | 752 | int recurseFlags, const llist_t *include, |
769 | const llist_t *exclude, int gzip); | 753 | const llist_t *exclude, const char *gzip); |
770 | #endif /* FEATURE_TAR_CREATE */ | 754 | #endif /* FEATURE_TAR_CREATE */ |
771 | 755 | ||
772 | #if ENABLE_FEATURE_TAR_FROM | 756 | #if ENABLE_FEATURE_TAR_FROM |
@@ -1151,18 +1135,24 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1151 | if (base_dir) | 1135 | if (base_dir) |
1152 | xchdir(base_dir); | 1136 | xchdir(base_dir); |
1153 | 1137 | ||
1154 | //if (SEAMLESS_COMPRESSION || OPT_COMPRESS) | 1138 | //if (SEAMLESS_COMPRESSION) |
1155 | // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ | 1139 | // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ |
1156 | // signal(SIGCHLD, check_errors_in_children); | 1140 | // signal(SIGCHLD, check_errors_in_children); |
1157 | 1141 | ||
1158 | /* Create an archive */ | 1142 | /* Create an archive */ |
1159 | if (opt & OPT_CREATE) { | 1143 | if (opt & OPT_CREATE) { |
1160 | #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 | 1144 | #if SEAMLESS_COMPRESSION |
1161 | int zipMode = 0; | 1145 | const char *zipMode = NULL; |
1162 | if (ENABLE_FEATURE_SEAMLESS_GZ && (opt & OPT_GZIP)) | 1146 | if (opt & OPT_COMPRESS) |
1163 | zipMode = 1; | 1147 | zipMode = "compress"; |
1164 | if (ENABLE_FEATURE_SEAMLESS_BZ2 && (opt & OPT_BZIP2)) | 1148 | if (opt & OPT_GZIP) |
1165 | zipMode = 2; | 1149 | zipMode = "gzip"; |
1150 | if (opt & OPT_BZIP2) | ||
1151 | zipMode = "bzip2"; | ||
1152 | if (opt & OPT_LZMA) | ||
1153 | zipMode = "lzma"; | ||
1154 | if (opt & OPT_XZ) | ||
1155 | zipMode = "xz"; | ||
1166 | #endif | 1156 | #endif |
1167 | /* NB: writeTarFile() closes tar_handle->src_fd */ | 1157 | /* NB: writeTarFile() closes tar_handle->src_fd */ |
1168 | return writeTarFile(tar_handle->src_fd, verboseFlag, | 1158 | return writeTarFile(tar_handle->src_fd, verboseFlag, |
@@ -1173,7 +1163,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1173 | } | 1163 | } |
1174 | 1164 | ||
1175 | if (opt & OPT_ANY_COMPRESS) { | 1165 | if (opt & OPT_ANY_COMPRESS) { |
1176 | USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) | 1166 | USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_state_t *xstate);) |
1177 | USE_FOR_NOMMU(const char *xformer_prog;) | 1167 | USE_FOR_NOMMU(const char *xformer_prog;) |
1178 | 1168 | ||
1179 | if (opt & OPT_COMPRESS) | 1169 | if (opt & OPT_COMPRESS) |
@@ -1192,7 +1182,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1192 | USE_FOR_MMU(xformer = unpack_xz_stream;) | 1182 | USE_FOR_MMU(xformer = unpack_xz_stream;) |
1193 | USE_FOR_NOMMU(xformer_prog = "unxz";) | 1183 | USE_FOR_NOMMU(xformer_prog = "unxz";) |
1194 | 1184 | ||
1195 | open_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog); | 1185 | fork_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog); |
1196 | /* Can't lseek over pipes */ | 1186 | /* Can't lseek over pipes */ |
1197 | tar_handle->seek = seek_by_read; | 1187 | tar_handle->seek = seek_by_read; |
1198 | /*tar_handle->offset = 0; - already is */ | 1188 | /*tar_handle->offset = 0; - already is */ |
diff --git a/archival/unzip.c b/archival/unzip.c index fcfc9a448..38a07e212 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -280,17 +280,19 @@ static void unzip_extract(zip_header_t *zip_header, int dst_fd) | |||
280 | bb_copyfd_exact_size(zip_fd, dst_fd, size); | 280 | bb_copyfd_exact_size(zip_fd, dst_fd, size); |
281 | } else { | 281 | } else { |
282 | /* Method 8 - inflate */ | 282 | /* Method 8 - inflate */ |
283 | transformer_aux_data_t aux; | 283 | transformer_state_t xstate; |
284 | init_transformer_aux_data(&aux); | 284 | init_transformer_state(&xstate); |
285 | aux.bytes_in = zip_header->formatted.cmpsize; | 285 | xstate.bytes_in = zip_header->formatted.cmpsize; |
286 | if (inflate_unzip(&aux, zip_fd, dst_fd) < 0) | 286 | xstate.src_fd = zip_fd; |
287 | xstate.dst_fd = dst_fd; | ||
288 | if (inflate_unzip(&xstate) < 0) | ||
287 | bb_error_msg_and_die("inflate error"); | 289 | bb_error_msg_and_die("inflate error"); |
288 | /* Validate decompression - crc */ | 290 | /* Validate decompression - crc */ |
289 | if (zip_header->formatted.crc32 != (aux.crc32 ^ 0xffffffffL)) { | 291 | if (zip_header->formatted.crc32 != (xstate.crc32 ^ 0xffffffffL)) { |
290 | bb_error_msg_and_die("crc error"); | 292 | bb_error_msg_and_die("crc error"); |
291 | } | 293 | } |
292 | /* Validate decompression - size */ | 294 | /* Validate decompression - size */ |
293 | if (zip_header->formatted.ucmpsize != aux.bytes_out) { | 295 | if (zip_header->formatted.ucmpsize != xstate.bytes_out) { |
294 | /* Don't die. Who knows, maybe len calculation | 296 | /* Don't die. Who knows, maybe len calculation |
295 | * was botched somewhere. After all, crc matched! */ | 297 | * was botched somewhere. After all, crc matched! */ |
296 | bb_error_msg("bad length"); | 298 | bb_error_msg("bad length"); |