diff options
author | Ron Yorston <rmy@pobox.com> | 2012-03-23 12:12:03 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-03-23 12:12:03 +0000 |
commit | b0f54743e36af163ae2530c381c485bb29df13dc (patch) | |
tree | cda4cfeaae6e47fe4f14c1b566092be4da9affc4 /archival/libarchive | |
parent | 40514a0309939f2446f0d4ed9600cad5de396e7f (diff) | |
parent | ba88826c66411affc1da3614742b454654f7298a (diff) | |
download | busybox-w32-b0f54743e36af163ae2530c381c485bb29df13dc.tar.gz busybox-w32-b0f54743e36af163ae2530c381c485bb29df13dc.tar.bz2 busybox-w32-b0f54743e36af163ae2530c381c485bb29df13dc.zip |
Merge branch 'busybox' into merge
Conflicts:
Makefile.flags
Diffstat (limited to 'archival/libarchive')
-rw-r--r-- | archival/libarchive/Kbuild.src | 21 | ||||
-rw-r--r-- | archival/libarchive/data_extract_all.c | 8 | ||||
-rw-r--r-- | archival/libarchive/data_extract_to_command.c | 8 | ||||
-rw-r--r-- | archival/libarchive/decompress_bunzip2.c | 18 | ||||
-rw-r--r-- | archival/libarchive/decompress_gunzip.c (renamed from archival/libarchive/decompress_unzip.c) | 69 | ||||
-rw-r--r-- | archival/libarchive/decompress_uncompress.c | 15 | ||||
-rw-r--r-- | archival/libarchive/decompress_unlzma.c | 2 | ||||
-rw-r--r-- | archival/libarchive/decompress_unxz.c | 12 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar.c | 100 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_bz2.c | 2 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_gz.c | 17 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar_lzma.c | 2 | ||||
-rw-r--r-- | archival/libarchive/open_transformer.c | 193 |
13 files changed, 309 insertions, 158 deletions
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 | } | ||