diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-11-15 23:19:05 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-11-15 23:19:05 +0000 |
commit | 5699b8525e855a0e851725980964e8755e365f5b (patch) | |
tree | fe3d7ead1f80f5b56e44e52a651f368adf92c91d /archival | |
parent | 54ac057c0016ac23b7367342f4834e33cf7d47d7 (diff) | |
download | busybox-w32-5699b8525e855a0e851725980964e8755e365f5b.tar.gz busybox-w32-5699b8525e855a0e851725980964e8755e365f5b.tar.bz2 busybox-w32-5699b8525e855a0e851725980964e8755e365f5b.zip |
Move from read_gz to the pipe()+fork() method.
open_transformer(), common code for pipe+fork.
Function pointer for read() no longer needed.
Allow inflate to be initialised with a specified buffer size to avoid
over-reading.
Reset static variables in inflate_get_next_window to fix a bug where
only the first file in a .zip would be be extracted.
Diffstat (limited to 'archival')
-rw-r--r-- | archival/gunzip.c | 3 | ||||
-rw-r--r-- | archival/libunarchive/Makefile.in | 1 | ||||
-rw-r--r-- | archival/libunarchive/archive_xread.c | 2 | ||||
-rw-r--r-- | archival/libunarchive/data_align.c | 1 | ||||
-rw-r--r-- | archival/libunarchive/decompress_bunzip2.c | 4 | ||||
-rw-r--r-- | archival/libunarchive/decompress_unzip.c | 140 | ||||
-rw-r--r-- | archival/libunarchive/filter_accept_list_reassign.c | 2 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar_bz2.c | 42 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar_gz.c | 17 | ||||
-rw-r--r-- | archival/libunarchive/init_handle.c | 1 | ||||
-rw-r--r-- | archival/libunarchive/open_transformer.c | 50 | ||||
-rw-r--r-- | archival/libunarchive/unzip.c | 140 | ||||
-rw-r--r-- | archival/rpm.c | 7 | ||||
-rw-r--r-- | archival/rpm2cpio.c | 3 | ||||
-rw-r--r-- | archival/unzip.c | 9 |
15 files changed, 150 insertions, 272 deletions
diff --git a/archival/gunzip.c b/archival/gunzip.c index 7d382b895..f229ae524 100644 --- a/archival/gunzip.c +++ b/archival/gunzip.c | |||
@@ -179,11 +179,10 @@ extern int gunzip_main(int argc, char **argv) | |||
179 | #endif | 179 | #endif |
180 | if (magic2 == 0x8b) { | 180 | if (magic2 == 0x8b) { |
181 | check_header_gzip(src_fd); | 181 | check_header_gzip(src_fd); |
182 | status = inflate(src_fd, dst_fd); | 182 | status = inflate_gunzip(src_fd, dst_fd); |
183 | if (status != 0) { | 183 | if (status != 0) { |
184 | bb_error_msg_and_die("Error inflating"); | 184 | bb_error_msg_and_die("Error inflating"); |
185 | } | 185 | } |
186 | check_trailer_gzip(src_fd); | ||
187 | } else { | 186 | } else { |
188 | bb_error_msg_and_die("Invalid magic"); | 187 | bb_error_msg_and_die("Invalid magic"); |
189 | } | 188 | } |
diff --git a/archival/libunarchive/Makefile.in b/archival/libunarchive/Makefile.in index 3d7bdef6b..d449c193e 100644 --- a/archival/libunarchive/Makefile.in +++ b/archival/libunarchive/Makefile.in | |||
@@ -49,6 +49,7 @@ LIBUNARCHIVE-y:= \ | |||
49 | \ | 49 | \ |
50 | data_align.o \ | 50 | data_align.o \ |
51 | find_list_entry.o \ | 51 | find_list_entry.o \ |
52 | open_transformer.o \ | ||
52 | init_handle.o | 53 | init_handle.o |
53 | 54 | ||
54 | GUNZIP_FILES:= check_header_gzip.o unzip.o | 55 | GUNZIP_FILES:= check_header_gzip.o unzip.o |
diff --git a/archival/libunarchive/archive_xread.c b/archival/libunarchive/archive_xread.c index d63d0d5a2..59b4d77a8 100644 --- a/archival/libunarchive/archive_xread.c +++ b/archival/libunarchive/archive_xread.c | |||
@@ -24,7 +24,7 @@ extern ssize_t archive_xread(const archive_handle_t *archive_handle, unsigned ch | |||
24 | { | 24 | { |
25 | ssize_t size; | 25 | ssize_t size; |
26 | 26 | ||
27 | size = archive_handle->read(archive_handle->src_fd, buf, count); | 27 | size = bb_full_read(archive_handle->src_fd, buf, count); |
28 | if (size < 0) { | 28 | if (size < 0) { |
29 | bb_perror_msg_and_die("Read error"); | 29 | bb_perror_msg_and_die("Read error"); |
30 | } | 30 | } |
diff --git a/archival/libunarchive/data_align.c b/archival/libunarchive/data_align.c index 037242f25..1d433957d 100644 --- a/archival/libunarchive/data_align.c +++ b/archival/libunarchive/data_align.c | |||
@@ -27,7 +27,6 @@ extern void data_align(archive_handle_t *archive_handle, const unsigned short bo | |||
27 | const unsigned short skip_amount = (boundary - (archive_handle->offset % boundary)) % boundary; | 27 | const unsigned short skip_amount = (boundary - (archive_handle->offset % boundary)) % boundary; |
28 | 28 | ||
29 | archive_handle->seek(archive_handle, skip_amount); | 29 | archive_handle->seek(archive_handle, skip_amount); |
30 | |||
31 | archive_handle->offset += skip_amount; | 30 | archive_handle->offset += skip_amount; |
32 | 31 | ||
33 | return; | 32 | return; |
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c index 83232fbe8..3e6138c95 100644 --- a/archival/libunarchive/decompress_bunzip2.c +++ b/archival/libunarchive/decompress_bunzip2.c | |||
@@ -424,7 +424,7 @@ got_huff_bits: | |||
424 | are ignored, data is written to out_fd and return is RETVAL_OK or error. | 424 | are ignored, data is written to out_fd and return is RETVAL_OK or error. |
425 | */ | 425 | */ |
426 | 426 | ||
427 | extern int read_bunzip(bunzip_data *bd, char *outbuf, int len) | 427 | static int read_bunzip(bunzip_data *bd, char *outbuf, int len) |
428 | { | 428 | { |
429 | const unsigned int *dbuf; | 429 | const unsigned int *dbuf; |
430 | int pos,current,previous,gotcount; | 430 | int pos,current,previous,gotcount; |
@@ -511,7 +511,7 @@ decode_next_byte: | |||
511 | /* Allocate the structure, read file header. If in_fd==-1, inbuf must contain | 511 | /* Allocate the structure, read file header. If in_fd==-1, inbuf must contain |
512 | a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are | 512 | a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are |
513 | ignored, and data is read from file handle into temporary buffer. */ | 513 | ignored, and data is read from file handle into temporary buffer. */ |
514 | extern int start_bunzip(bunzip_data **bdp, int in_fd, char *inbuf, int len) | 514 | static int start_bunzip(bunzip_data **bdp, int in_fd, char *inbuf, int len) |
515 | { | 515 | { |
516 | bunzip_data *bd; | 516 | bunzip_data *bd; |
517 | unsigned int i,j,c; | 517 | unsigned int i,j,c; |
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c index 2b16db3c3..29929c282 100644 --- a/archival/libunarchive/decompress_unzip.c +++ b/archival/libunarchive/decompress_unzip.c | |||
@@ -103,7 +103,7 @@ static unsigned int gunzip_bb; /* bit buffer */ | |||
103 | static unsigned char gunzip_bk; /* bits in bit buffer */ | 103 | static unsigned char gunzip_bk; /* bits in bit buffer */ |
104 | 104 | ||
105 | /* These control the size of the bytebuffer */ | 105 | /* These control the size of the bytebuffer */ |
106 | #define BYTEBUFFER_MAX 0x8000 | 106 | static unsigned int bytebuffer_max = 0x8000; |
107 | static unsigned char *bytebuffer = NULL; | 107 | static unsigned char *bytebuffer = NULL; |
108 | static unsigned int bytebuffer_offset = 0; | 108 | static unsigned int bytebuffer_offset = 0; |
109 | static unsigned int bytebuffer_size = 0; | 109 | static unsigned int bytebuffer_size = 0; |
@@ -144,21 +144,16 @@ static const unsigned char border[] = { | |||
144 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 | 144 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 |
145 | }; | 145 | }; |
146 | 146 | ||
147 | static void fill_bytebuffer(void) | ||
148 | { | ||
149 | if (bytebuffer_offset >= bytebuffer_size) { | ||
150 | /* Leave the first 4 bytes empty so we can always unwind the bitbuffer | ||
151 | * to the front of the bytebuffer, leave 4 bytes free at end of tail | ||
152 | * so we can easily top up buffer in check_trailer_gzip() */ | ||
153 | bytebuffer_size = 4 + bb_xread(gunzip_src_fd, &bytebuffer[4], BYTEBUFFER_MAX - 8); | ||
154 | bytebuffer_offset = 4; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) | 147 | static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) |
159 | { | 148 | { |
160 | while (*current < required) { | 149 | while (*current < required) { |
161 | fill_bytebuffer(); | 150 | if (bytebuffer_offset >= bytebuffer_size) { |
151 | /* Leave the first 4 bytes empty so we can always unwind the bitbuffer | ||
152 | * to the front of the bytebuffer, leave 4 bytes free at end of tail | ||
153 | * so we can easily top up buffer in check_trailer_gzip() */ | ||
154 | bytebuffer_size = 4 + bb_xread(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8); | ||
155 | bytebuffer_offset = 4; | ||
156 | } | ||
162 | bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current; | 157 | bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current; |
163 | bytebuffer_offset++; | 158 | bytebuffer_offset++; |
164 | *current += 8; | 159 | *current += 8; |
@@ -861,9 +856,9 @@ static void calculate_gunzip_crc(void) | |||
861 | 856 | ||
862 | static int inflate_get_next_window(void) | 857 | static int inflate_get_next_window(void) |
863 | { | 858 | { |
864 | static int needAnotherBlock = 1; | ||
865 | static int method = -1; // Method == -1 for stored, -2 for codes | 859 | static int method = -1; // Method == -1 for stored, -2 for codes |
866 | static int e = 0; | 860 | static int e = 0; |
861 | static int needAnotherBlock = 1; | ||
867 | 862 | ||
868 | gunzip_outbuf_count = 0; | 863 | gunzip_outbuf_count = 0; |
869 | 864 | ||
@@ -873,6 +868,8 @@ static int inflate_get_next_window(void) | |||
873 | if (needAnotherBlock) { | 868 | if (needAnotherBlock) { |
874 | if(e) { | 869 | if(e) { |
875 | calculate_gunzip_crc(); | 870 | calculate_gunzip_crc(); |
871 | e = 0; | ||
872 | needAnotherBlock = 1; | ||
876 | return 0; | 873 | return 0; |
877 | } // Last block | 874 | } // Last block |
878 | method = inflate_block(&e); | 875 | method = inflate_block(&e); |
@@ -895,54 +892,25 @@ static int inflate_get_next_window(void) | |||
895 | /* Doesnt get here */ | 892 | /* Doesnt get here */ |
896 | } | 893 | } |
897 | 894 | ||
898 | /* | 895 | /* Initialise bytebuffer, be carefull not to overfill the buffer */ |
899 | * User functions | 896 | extern void inflate_init(unsigned int bufsize) |
900 | * | ||
901 | * read_gz, GZ_gzReadOpen, GZ_gzReadClose, inflate | ||
902 | */ | ||
903 | |||
904 | extern ssize_t read_gz(int fd, void *buf, size_t count) | ||
905 | { | 897 | { |
906 | static int morebytes = 0, finished = 0; | 898 | /* Set the bytebuffer size, default is same as gunzip_wsize */ |
907 | 899 | bytebuffer_max = bufsize + 8; | |
908 | if (morebytes) { | 900 | bytebuffer_offset = 4; |
909 | int bytesRead = morebytes > count ? count : morebytes; | 901 | bytebuffer_size = 0; |
910 | memcpy(buf, gunzip_window + (gunzip_outbuf_count - morebytes), bytesRead); | ||
911 | morebytes -= bytesRead; | ||
912 | return bytesRead; | ||
913 | } else if (finished) { | ||
914 | return 0; | ||
915 | } else if (count >= 0x8000) { // We can decompress direcly to the buffer, 32k at a time | ||
916 | // Could decompress to larger buffer, but it must be a power of 2, and calculating that is probably more expensive than the benefit | ||
917 | unsigned char *old_gunzip_window = gunzip_window; // Save old window | ||
918 | gunzip_window = buf; | ||
919 | if (inflate_get_next_window() == 0) finished = 1; | ||
920 | gunzip_window = old_gunzip_window; // Restore old window | ||
921 | return gunzip_outbuf_count; | ||
922 | } else { // Oh well, need to split up the gunzip_window | ||
923 | int bytesRead; | ||
924 | if (inflate_get_next_window() == 0) finished = 1; | ||
925 | morebytes = gunzip_outbuf_count; | ||
926 | bytesRead = morebytes > count ? count : morebytes; | ||
927 | memcpy(buf, gunzip_window, bytesRead); | ||
928 | morebytes -= bytesRead; | ||
929 | return bytesRead; | ||
930 | } | ||
931 | |||
932 | } | 902 | } |
933 | 903 | ||
934 | extern void GZ_gzReadOpen(int fd, void *unused, int nUnused) | 904 | extern int inflate_unzip(int in, int out) |
935 | { | 905 | { |
906 | ssize_t nwrote; | ||
936 | typedef void (*sig_type) (int); | 907 | typedef void (*sig_type) (int); |
937 | 908 | ||
938 | /* Allocate all global buffers (for DYN_ALLOC option) */ | 909 | /* Allocate all global buffers (for DYN_ALLOC option) */ |
939 | gunzip_window = xmalloc(gunzip_wsize); | 910 | gunzip_window = xmalloc(gunzip_wsize); |
940 | gunzip_outbuf_count = 0; | 911 | gunzip_outbuf_count = 0; |
941 | gunzip_bytes_out = 0; | 912 | gunzip_bytes_out = 0; |
942 | gunzip_src_fd = fd; | 913 | gunzip_src_fd = in; |
943 | |||
944 | /* Input buffer */ | ||
945 | bytebuffer = xmalloc(BYTEBUFFER_MAX); | ||
946 | 914 | ||
947 | /* initialize gunzip_window, bit buffer */ | 915 | /* initialize gunzip_window, bit buffer */ |
948 | gunzip_bk = 0; | 916 | gunzip_bk = 0; |
@@ -950,10 +918,20 @@ extern void GZ_gzReadOpen(int fd, void *unused, int nUnused) | |||
950 | 918 | ||
951 | /* Create the crc table */ | 919 | /* Create the crc table */ |
952 | make_gunzip_crc_table(); | 920 | make_gunzip_crc_table(); |
953 | } | ||
954 | 921 | ||
955 | extern void GZ_gzReadClose(void) | 922 | /* Allocate space for buffer */ |
956 | { | 923 | bytebuffer = xmalloc(bytebuffer_max); |
924 | |||
925 | while(1) { | ||
926 | int ret = inflate_get_next_window(); | ||
927 | nwrote = bb_full_write(out, gunzip_window, gunzip_outbuf_count); | ||
928 | if (nwrote == -1) { | ||
929 | bb_perror_msg("write"); | ||
930 | return -1; | ||
931 | } | ||
932 | if (ret == 0) break; | ||
933 | } | ||
934 | |||
957 | /* Cleanup */ | 935 | /* Cleanup */ |
958 | free(gunzip_window); | 936 | free(gunzip_window); |
959 | free(gunzip_crc_table); | 937 | free(gunzip_crc_table); |
@@ -967,57 +945,20 @@ extern void GZ_gzReadClose(void) | |||
967 | gunzip_bb >>= 8; | 945 | gunzip_bb >>= 8; |
968 | gunzip_bk -= 8; | 946 | gunzip_bk -= 8; |
969 | } | 947 | } |
970 | } | ||
971 | |||
972 | /*extern int inflate(int in, int out) // Useful for testing read_gz | ||
973 | { | ||
974 | char buf[8192]; | ||
975 | ssize_t nread, nwrote; | ||
976 | |||
977 | GZ_gzReadOpen(in, 0, 0); | ||
978 | while(1) { // Robbed from bb_copyfd.c | ||
979 | nread = read_gz(in, buf, sizeof(buf)); | ||
980 | if (nread == 0) break; // no data to write | ||
981 | else if (nread == -1) { | ||
982 | bb_perror_msg("read"); | ||
983 | return -1; | ||
984 | } | ||
985 | nwrote = bb_full_write(out, buf, nread); | ||
986 | if (nwrote == -1) { | ||
987 | bb_perror_msg("write"); | ||
988 | return -1; | ||
989 | } | ||
990 | } | ||
991 | GZ_gzReadClose(); | ||
992 | return 0; | ||
993 | }*/ | ||
994 | |||
995 | extern int inflate(int in, int out) | ||
996 | { | ||
997 | ssize_t nwrote; | ||
998 | GZ_gzReadOpen(in, 0, 0); | ||
999 | while(1) { | ||
1000 | int ret = inflate_get_next_window(); | ||
1001 | nwrote = bb_full_write(out, gunzip_window, gunzip_outbuf_count); | ||
1002 | if (nwrote == -1) { | ||
1003 | bb_perror_msg("write"); | ||
1004 | return -1; | ||
1005 | } | ||
1006 | if (ret == 0) break; | ||
1007 | } | ||
1008 | GZ_gzReadClose(); | ||
1009 | return 0; | 948 | return 0; |
1010 | } | 949 | } |
1011 | 950 | ||
1012 | extern void check_trailer_gzip(int src_fd) | 951 | extern int inflate_gunzip(int in, int out) |
1013 | { | 952 | { |
1014 | unsigned int stored_crc = 0; | 953 | unsigned int stored_crc = 0; |
1015 | unsigned char count; | 954 | unsigned char count; |
1016 | 955 | ||
956 | inflate_unzip(in, out); | ||
957 | |||
1017 | /* top up the input buffer with the rest of the trailer */ | 958 | /* top up the input buffer with the rest of the trailer */ |
1018 | count = bytebuffer_size - bytebuffer_offset; | 959 | count = bytebuffer_size - bytebuffer_offset; |
1019 | if (count < 8) { | 960 | if (count < 8) { |
1020 | bb_xread_all(src_fd, &bytebuffer[bytebuffer_size], 8 - count); | 961 | bb_xread_all(in, &bytebuffer[bytebuffer_size], 8 - count); |
1021 | bytebuffer_size += 8 - count; | 962 | bytebuffer_size += 8 - count; |
1022 | } | 963 | } |
1023 | for (count = 0; count != 4; count++) { | 964 | for (count = 0; count != 4; count++) { |
@@ -1027,14 +968,15 @@ extern void check_trailer_gzip(int src_fd) | |||
1027 | 968 | ||
1028 | /* Validate decompression - crc */ | 969 | /* Validate decompression - crc */ |
1029 | if (stored_crc != (gunzip_crc ^ 0xffffffffL)) { | 970 | if (stored_crc != (gunzip_crc ^ 0xffffffffL)) { |
1030 | bb_error_msg_and_die("crc error"); | 971 | bb_error_msg("crc error"); |
1031 | } | 972 | } |
1032 | 973 | ||
1033 | /* Validate decompression - size */ | 974 | /* Validate decompression - size */ |
1034 | if (gunzip_bytes_out != | 975 | if (gunzip_bytes_out != |
1035 | (bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) | | 976 | (bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) | |
1036 | (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))) { | 977 | (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))) { |
1037 | bb_error_msg_and_die("Incorrect length, but crc is correct"); | 978 | bb_error_msg("Incorrect length"); |
1038 | } | 979 | } |
1039 | 980 | ||
981 | return 0; | ||
1040 | } | 982 | } |
diff --git a/archival/libunarchive/filter_accept_list_reassign.c b/archival/libunarchive/filter_accept_list_reassign.c index f34a23c33..1e9da0f2b 100644 --- a/archival/libunarchive/filter_accept_list_reassign.c +++ b/archival/libunarchive/filter_accept_list_reassign.c | |||
@@ -40,14 +40,12 @@ extern char filter_accept_list_reassign(archive_handle_t *archive_handle) | |||
40 | /* Modify the subarchive handler based on the extension */ | 40 | /* Modify the subarchive handler based on the extension */ |
41 | #ifdef CONFIG_FEATURE_DEB_TAR_GZ | 41 | #ifdef CONFIG_FEATURE_DEB_TAR_GZ |
42 | if (strcmp(name_ptr, ".gz") == 0) { | 42 | if (strcmp(name_ptr, ".gz") == 0) { |
43 | archive_handle->sub_archive->read = read; | ||
44 | archive_handle->action_data_subarchive = get_header_tar_gz; | 43 | archive_handle->action_data_subarchive = get_header_tar_gz; |
45 | return(EXIT_SUCCESS); | 44 | return(EXIT_SUCCESS); |
46 | } | 45 | } |
47 | #endif | 46 | #endif |
48 | #ifdef CONFIG_FEATURE_DEB_TAR_BZ2 | 47 | #ifdef CONFIG_FEATURE_DEB_TAR_BZ2 |
49 | if (strcmp(name_ptr, ".bz2") == 0) { | 48 | if (strcmp(name_ptr, ".bz2") == 0) { |
50 | archive_handle->sub_archive->read = read; | ||
51 | archive_handle->action_data_subarchive = get_header_tar_bz2; | 49 | archive_handle->action_data_subarchive = get_header_tar_bz2; |
52 | return(EXIT_SUCCESS); | 50 | return(EXIT_SUCCESS); |
53 | } | 51 | } |
diff --git a/archival/libunarchive/get_header_tar_bz2.c b/archival/libunarchive/get_header_tar_bz2.c index 6354648fc..d49d6b96a 100644 --- a/archival/libunarchive/get_header_tar_bz2.c +++ b/archival/libunarchive/get_header_tar_bz2.c | |||
@@ -26,53 +26,13 @@ | |||
26 | 26 | ||
27 | extern char get_header_tar_bz2(archive_handle_t *archive_handle) | 27 | extern char get_header_tar_bz2(archive_handle_t *archive_handle) |
28 | { | 28 | { |
29 | int fd_pipe[2]; | ||
30 | int pid; | ||
31 | |||
32 | /* Cant lseek over pipe's */ | 29 | /* Cant lseek over pipe's */ |
33 | archive_handle->read = safe_read; | ||
34 | archive_handle->seek = seek_by_char; | 30 | archive_handle->seek = seek_by_char; |
35 | 31 | ||
36 | if (pipe(fd_pipe) != 0) { | 32 | archive_handle->src_fd = open_transformer(archive_handle->src_fd, uncompressStream); |
37 | bb_error_msg_and_die("Can't create pipe"); | ||
38 | } | ||
39 | |||
40 | pid = fork(); | ||
41 | if (pid == -1) { | ||
42 | bb_error_msg_and_die("Fork failed\n"); | ||
43 | } | ||
44 | |||
45 | if (pid == 0) { | ||
46 | /* child process */ | ||
47 | int status; | ||
48 | |||
49 | close(fd_pipe[0]); /* We don't wan't to read from the pipe */ | ||
50 | uncompressStream(archive_handle->src_fd, fd_pipe[1]); | ||
51 | close(fd_pipe[1]); /* Send EOF */ | ||
52 | exit(status); | ||
53 | /* notreached */ | ||
54 | } | ||
55 | /* parent process */ | ||
56 | close(fd_pipe[1]); /* Don't want to write down the pipe */ | ||
57 | close(archive_handle->src_fd); | ||
58 | |||
59 | archive_handle->src_fd = fd_pipe[0]; | ||
60 | |||
61 | archive_handle->offset = 0; | 33 | archive_handle->offset = 0; |
62 | while (get_header_tar(archive_handle) == EXIT_SUCCESS); | 34 | while (get_header_tar(archive_handle) == EXIT_SUCCESS); |
63 | 35 | ||
64 | close(fd_pipe[0]); | ||
65 | #if 0 | ||
66 | if (kill(pid, SIGTERM) == -1) { | ||
67 | bb_error_msg_and_die("Couldnt kill gunzip process"); | ||
68 | } | ||
69 | #endif | ||
70 | |||
71 | /* I dont think this is needed */ | ||
72 | if (waitpid(pid, NULL, 0) == -1) { | ||
73 | bb_error_msg("Couldnt wait ?"); | ||
74 | } | ||
75 | |||
76 | /* Can only do one file at a time */ | 36 | /* Can only do one file at a time */ |
77 | return(EXIT_FAILURE); | 37 | return(EXIT_FAILURE); |
78 | } | 38 | } |
diff --git a/archival/libunarchive/get_header_tar_gz.c b/archival/libunarchive/get_header_tar_gz.c index 64d08f7a7..9c708a951 100644 --- a/archival/libunarchive/get_header_tar_gz.c +++ b/archival/libunarchive/get_header_tar_gz.c | |||
@@ -23,6 +23,9 @@ extern char get_header_tar_gz(archive_handle_t *archive_handle) | |||
23 | { | 23 | { |
24 | unsigned char magic[2]; | 24 | unsigned char magic[2]; |
25 | 25 | ||
26 | /* Cant lseek over pipe's */ | ||
27 | archive_handle->seek = seek_by_char; | ||
28 | |||
26 | archive_xread_all(archive_handle, &magic, 2); | 29 | archive_xread_all(archive_handle, &magic, 2); |
27 | if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { | 30 | if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { |
28 | bb_error_msg_and_die("Invalid gzip magic"); | 31 | bb_error_msg_and_die("Invalid gzip magic"); |
@@ -30,20 +33,10 @@ extern char get_header_tar_gz(archive_handle_t *archive_handle) | |||
30 | 33 | ||
31 | check_header_gzip(archive_handle->src_fd); | 34 | check_header_gzip(archive_handle->src_fd); |
32 | 35 | ||
33 | GZ_gzReadOpen(archive_handle->src_fd, 0, 0); | 36 | archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip); |
34 | |||
35 | archive_handle->read = read_gz; | ||
36 | archive_handle->seek = seek_by_char; | ||
37 | |||
38 | archive_handle->offset = 0; | 37 | archive_handle->offset = 0; |
39 | while (get_header_tar(archive_handle) == EXIT_SUCCESS); | 38 | while (get_header_tar(archive_handle) == EXIT_SUCCESS); |
40 | 39 | ||
41 | /* Cleanup */ | 40 | /* Can only do one file at a time */ |
42 | GZ_gzReadClose(); | ||
43 | |||
44 | check_trailer_gzip(archive_handle->src_fd); | ||
45 | |||
46 | /* Can only do one tar.gz per archive */ | ||
47 | return(EXIT_FAILURE); | 41 | return(EXIT_FAILURE); |
48 | } | 42 | } |
49 | |||
diff --git a/archival/libunarchive/init_handle.c b/archival/libunarchive/init_handle.c index 2659aa3eb..3cee84f67 100644 --- a/archival/libunarchive/init_handle.c +++ b/archival/libunarchive/init_handle.c | |||
@@ -30,7 +30,6 @@ archive_handle_t *init_handle(void) | |||
30 | archive_handle->action_header = header_skip; | 30 | archive_handle->action_header = header_skip; |
31 | archive_handle->action_data = data_skip; | 31 | archive_handle->action_data = data_skip; |
32 | archive_handle->filter = filter_accept_all; | 32 | archive_handle->filter = filter_accept_all; |
33 | archive_handle->read = bb_full_read; | ||
34 | archive_handle->seek = seek_by_jump; | 33 | archive_handle->seek = seek_by_jump; |
35 | 34 | ||
36 | return(archive_handle); | 35 | return(archive_handle); |
diff --git a/archival/libunarchive/open_transformer.c b/archival/libunarchive/open_transformer.c new file mode 100644 index 000000000..c1007f982 --- /dev/null +++ b/archival/libunarchive/open_transformer.c | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License as published by | ||
4 | * the Free Software Foundation; either version 2 of the License, or | ||
5 | * (at your option) any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU Library General Public License for more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * along with this program; if not, write to the Free Software | ||
14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
15 | */ | ||
16 | |||
17 | #include <stdlib.h> | ||
18 | #include <unistd.h> | ||
19 | |||
20 | #include "libbb.h" | ||
21 | |||
22 | /* transformer(), more than meets the eye */ | ||
23 | extern int open_transformer(int src_fd, int (*transformer)(int src_fd, int dst_fd)) | ||
24 | { | ||
25 | int fd_pipe[2]; | ||
26 | int pid; | ||
27 | |||
28 | if (pipe(fd_pipe) != 0) { | ||
29 | bb_perror_msg_and_die("Can't create pipe"); | ||
30 | } | ||
31 | |||
32 | pid = fork(); | ||
33 | if (pid == -1) { | ||
34 | bb_perror_msg_and_die("Fork failed"); | ||
35 | } | ||
36 | |||
37 | if (pid == 0) { | ||
38 | /* child process */ | ||
39 | close(fd_pipe[0]); /* We don't wan't to read from the pipe */ | ||
40 | transformer(src_fd, fd_pipe[1]); | ||
41 | close(fd_pipe[1]); /* Send EOF */ | ||
42 | exit(0); | ||
43 | /* notreached */ | ||
44 | } | ||
45 | /* parent process */ | ||
46 | close(fd_pipe[1]); /* Don't want to write down the pipe */ | ||
47 | close(src_fd); | ||
48 | |||
49 | return(fd_pipe[0]); | ||
50 | } | ||
diff --git a/archival/libunarchive/unzip.c b/archival/libunarchive/unzip.c index 2b16db3c3..29929c282 100644 --- a/archival/libunarchive/unzip.c +++ b/archival/libunarchive/unzip.c | |||
@@ -103,7 +103,7 @@ static unsigned int gunzip_bb; /* bit buffer */ | |||
103 | static unsigned char gunzip_bk; /* bits in bit buffer */ | 103 | static unsigned char gunzip_bk; /* bits in bit buffer */ |
104 | 104 | ||
105 | /* These control the size of the bytebuffer */ | 105 | /* These control the size of the bytebuffer */ |
106 | #define BYTEBUFFER_MAX 0x8000 | 106 | static unsigned int bytebuffer_max = 0x8000; |
107 | static unsigned char *bytebuffer = NULL; | 107 | static unsigned char *bytebuffer = NULL; |
108 | static unsigned int bytebuffer_offset = 0; | 108 | static unsigned int bytebuffer_offset = 0; |
109 | static unsigned int bytebuffer_size = 0; | 109 | static unsigned int bytebuffer_size = 0; |
@@ -144,21 +144,16 @@ static const unsigned char border[] = { | |||
144 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 | 144 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 |
145 | }; | 145 | }; |
146 | 146 | ||
147 | static void fill_bytebuffer(void) | ||
148 | { | ||
149 | if (bytebuffer_offset >= bytebuffer_size) { | ||
150 | /* Leave the first 4 bytes empty so we can always unwind the bitbuffer | ||
151 | * to the front of the bytebuffer, leave 4 bytes free at end of tail | ||
152 | * so we can easily top up buffer in check_trailer_gzip() */ | ||
153 | bytebuffer_size = 4 + bb_xread(gunzip_src_fd, &bytebuffer[4], BYTEBUFFER_MAX - 8); | ||
154 | bytebuffer_offset = 4; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) | 147 | static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required) |
159 | { | 148 | { |
160 | while (*current < required) { | 149 | while (*current < required) { |
161 | fill_bytebuffer(); | 150 | if (bytebuffer_offset >= bytebuffer_size) { |
151 | /* Leave the first 4 bytes empty so we can always unwind the bitbuffer | ||
152 | * to the front of the bytebuffer, leave 4 bytes free at end of tail | ||
153 | * so we can easily top up buffer in check_trailer_gzip() */ | ||
154 | bytebuffer_size = 4 + bb_xread(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8); | ||
155 | bytebuffer_offset = 4; | ||
156 | } | ||
162 | bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current; | 157 | bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current; |
163 | bytebuffer_offset++; | 158 | bytebuffer_offset++; |
164 | *current += 8; | 159 | *current += 8; |
@@ -861,9 +856,9 @@ static void calculate_gunzip_crc(void) | |||
861 | 856 | ||
862 | static int inflate_get_next_window(void) | 857 | static int inflate_get_next_window(void) |
863 | { | 858 | { |
864 | static int needAnotherBlock = 1; | ||
865 | static int method = -1; // Method == -1 for stored, -2 for codes | 859 | static int method = -1; // Method == -1 for stored, -2 for codes |
866 | static int e = 0; | 860 | static int e = 0; |
861 | static int needAnotherBlock = 1; | ||
867 | 862 | ||
868 | gunzip_outbuf_count = 0; | 863 | gunzip_outbuf_count = 0; |
869 | 864 | ||
@@ -873,6 +868,8 @@ static int inflate_get_next_window(void) | |||
873 | if (needAnotherBlock) { | 868 | if (needAnotherBlock) { |
874 | if(e) { | 869 | if(e) { |
875 | calculate_gunzip_crc(); | 870 | calculate_gunzip_crc(); |
871 | e = 0; | ||
872 | needAnotherBlock = 1; | ||
876 | return 0; | 873 | return 0; |
877 | } // Last block | 874 | } // Last block |
878 | method = inflate_block(&e); | 875 | method = inflate_block(&e); |
@@ -895,54 +892,25 @@ static int inflate_get_next_window(void) | |||
895 | /* Doesnt get here */ | 892 | /* Doesnt get here */ |
896 | } | 893 | } |
897 | 894 | ||
898 | /* | 895 | /* Initialise bytebuffer, be carefull not to overfill the buffer */ |
899 | * User functions | 896 | extern void inflate_init(unsigned int bufsize) |
900 | * | ||
901 | * read_gz, GZ_gzReadOpen, GZ_gzReadClose, inflate | ||
902 | */ | ||
903 | |||
904 | extern ssize_t read_gz(int fd, void *buf, size_t count) | ||
905 | { | 897 | { |
906 | static int morebytes = 0, finished = 0; | 898 | /* Set the bytebuffer size, default is same as gunzip_wsize */ |
907 | 899 | bytebuffer_max = bufsize + 8; | |
908 | if (morebytes) { | 900 | bytebuffer_offset = 4; |
909 | int bytesRead = morebytes > count ? count : morebytes; | 901 | bytebuffer_size = 0; |
910 | memcpy(buf, gunzip_window + (gunzip_outbuf_count - morebytes), bytesRead); | ||
911 | morebytes -= bytesRead; | ||
912 | return bytesRead; | ||
913 | } else if (finished) { | ||
914 | return 0; | ||
915 | } else if (count >= 0x8000) { // We can decompress direcly to the buffer, 32k at a time | ||
916 | // Could decompress to larger buffer, but it must be a power of 2, and calculating that is probably more expensive than the benefit | ||
917 | unsigned char *old_gunzip_window = gunzip_window; // Save old window | ||
918 | gunzip_window = buf; | ||
919 | if (inflate_get_next_window() == 0) finished = 1; | ||
920 | gunzip_window = old_gunzip_window; // Restore old window | ||
921 | return gunzip_outbuf_count; | ||
922 | } else { // Oh well, need to split up the gunzip_window | ||
923 | int bytesRead; | ||
924 | if (inflate_get_next_window() == 0) finished = 1; | ||
925 | morebytes = gunzip_outbuf_count; | ||
926 | bytesRead = morebytes > count ? count : morebytes; | ||
927 | memcpy(buf, gunzip_window, bytesRead); | ||
928 | morebytes -= bytesRead; | ||
929 | return bytesRead; | ||
930 | } | ||
931 | |||
932 | } | 902 | } |
933 | 903 | ||
934 | extern void GZ_gzReadOpen(int fd, void *unused, int nUnused) | 904 | extern int inflate_unzip(int in, int out) |
935 | { | 905 | { |
906 | ssize_t nwrote; | ||
936 | typedef void (*sig_type) (int); | 907 | typedef void (*sig_type) (int); |
937 | 908 | ||
938 | /* Allocate all global buffers (for DYN_ALLOC option) */ | 909 | /* Allocate all global buffers (for DYN_ALLOC option) */ |
939 | gunzip_window = xmalloc(gunzip_wsize); | 910 | gunzip_window = xmalloc(gunzip_wsize); |
940 | gunzip_outbuf_count = 0; | 911 | gunzip_outbuf_count = 0; |
941 | gunzip_bytes_out = 0; | 912 | gunzip_bytes_out = 0; |
942 | gunzip_src_fd = fd; | 913 | gunzip_src_fd = in; |
943 | |||
944 | /* Input buffer */ | ||
945 | bytebuffer = xmalloc(BYTEBUFFER_MAX); | ||
946 | 914 | ||
947 | /* initialize gunzip_window, bit buffer */ | 915 | /* initialize gunzip_window, bit buffer */ |
948 | gunzip_bk = 0; | 916 | gunzip_bk = 0; |
@@ -950,10 +918,20 @@ extern void GZ_gzReadOpen(int fd, void *unused, int nUnused) | |||
950 | 918 | ||
951 | /* Create the crc table */ | 919 | /* Create the crc table */ |
952 | make_gunzip_crc_table(); | 920 | make_gunzip_crc_table(); |
953 | } | ||
954 | 921 | ||
955 | extern void GZ_gzReadClose(void) | 922 | /* Allocate space for buffer */ |
956 | { | 923 | bytebuffer = xmalloc(bytebuffer_max); |
924 | |||
925 | while(1) { | ||
926 | int ret = inflate_get_next_window(); | ||
927 | nwrote = bb_full_write(out, gunzip_window, gunzip_outbuf_count); | ||
928 | if (nwrote == -1) { | ||
929 | bb_perror_msg("write"); | ||
930 | return -1; | ||
931 | } | ||
932 | if (ret == 0) break; | ||
933 | } | ||
934 | |||
957 | /* Cleanup */ | 935 | /* Cleanup */ |
958 | free(gunzip_window); | 936 | free(gunzip_window); |
959 | free(gunzip_crc_table); | 937 | free(gunzip_crc_table); |
@@ -967,57 +945,20 @@ extern void GZ_gzReadClose(void) | |||
967 | gunzip_bb >>= 8; | 945 | gunzip_bb >>= 8; |
968 | gunzip_bk -= 8; | 946 | gunzip_bk -= 8; |
969 | } | 947 | } |
970 | } | ||
971 | |||
972 | /*extern int inflate(int in, int out) // Useful for testing read_gz | ||
973 | { | ||
974 | char buf[8192]; | ||
975 | ssize_t nread, nwrote; | ||
976 | |||
977 | GZ_gzReadOpen(in, 0, 0); | ||
978 | while(1) { // Robbed from bb_copyfd.c | ||
979 | nread = read_gz(in, buf, sizeof(buf)); | ||
980 | if (nread == 0) break; // no data to write | ||
981 | else if (nread == -1) { | ||
982 | bb_perror_msg("read"); | ||
983 | return -1; | ||
984 | } | ||
985 | nwrote = bb_full_write(out, buf, nread); | ||
986 | if (nwrote == -1) { | ||
987 | bb_perror_msg("write"); | ||
988 | return -1; | ||
989 | } | ||
990 | } | ||
991 | GZ_gzReadClose(); | ||
992 | return 0; | ||
993 | }*/ | ||
994 | |||
995 | extern int inflate(int in, int out) | ||
996 | { | ||
997 | ssize_t nwrote; | ||
998 | GZ_gzReadOpen(in, 0, 0); | ||
999 | while(1) { | ||
1000 | int ret = inflate_get_next_window(); | ||
1001 | nwrote = bb_full_write(out, gunzip_window, gunzip_outbuf_count); | ||
1002 | if (nwrote == -1) { | ||
1003 | bb_perror_msg("write"); | ||
1004 | return -1; | ||
1005 | } | ||
1006 | if (ret == 0) break; | ||
1007 | } | ||
1008 | GZ_gzReadClose(); | ||
1009 | return 0; | 948 | return 0; |
1010 | } | 949 | } |
1011 | 950 | ||
1012 | extern void check_trailer_gzip(int src_fd) | 951 | extern int inflate_gunzip(int in, int out) |
1013 | { | 952 | { |
1014 | unsigned int stored_crc = 0; | 953 | unsigned int stored_crc = 0; |
1015 | unsigned char count; | 954 | unsigned char count; |
1016 | 955 | ||
956 | inflate_unzip(in, out); | ||
957 | |||
1017 | /* top up the input buffer with the rest of the trailer */ | 958 | /* top up the input buffer with the rest of the trailer */ |
1018 | count = bytebuffer_size - bytebuffer_offset; | 959 | count = bytebuffer_size - bytebuffer_offset; |
1019 | if (count < 8) { | 960 | if (count < 8) { |
1020 | bb_xread_all(src_fd, &bytebuffer[bytebuffer_size], 8 - count); | 961 | bb_xread_all(in, &bytebuffer[bytebuffer_size], 8 - count); |
1021 | bytebuffer_size += 8 - count; | 962 | bytebuffer_size += 8 - count; |
1022 | } | 963 | } |
1023 | for (count = 0; count != 4; count++) { | 964 | for (count = 0; count != 4; count++) { |
@@ -1027,14 +968,15 @@ extern void check_trailer_gzip(int src_fd) | |||
1027 | 968 | ||
1028 | /* Validate decompression - crc */ | 969 | /* Validate decompression - crc */ |
1029 | if (stored_crc != (gunzip_crc ^ 0xffffffffL)) { | 970 | if (stored_crc != (gunzip_crc ^ 0xffffffffL)) { |
1030 | bb_error_msg_and_die("crc error"); | 971 | bb_error_msg("crc error"); |
1031 | } | 972 | } |
1032 | 973 | ||
1033 | /* Validate decompression - size */ | 974 | /* Validate decompression - size */ |
1034 | if (gunzip_bytes_out != | 975 | if (gunzip_bytes_out != |
1035 | (bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) | | 976 | (bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) | |
1036 | (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))) { | 977 | (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))) { |
1037 | bb_error_msg_and_die("Incorrect length, but crc is correct"); | 978 | bb_error_msg("Incorrect length"); |
1038 | } | 979 | } |
1039 | 980 | ||
981 | return 0; | ||
1040 | } | 982 | } |
diff --git a/archival/rpm.c b/archival/rpm.c index 5bde53285..e3f20ca35 100644 --- a/archival/rpm.c +++ b/archival/rpm.c | |||
@@ -197,7 +197,6 @@ void extract_cpio_gz(int fd) { | |||
197 | 197 | ||
198 | /* Initialise */ | 198 | /* Initialise */ |
199 | archive_handle = init_handle(); | 199 | archive_handle = init_handle(); |
200 | archive_handle->read = read_gz; | ||
201 | archive_handle->seek = seek_by_char; | 200 | archive_handle->seek = seek_by_char; |
202 | //archive_handle->action_header = header_list; | 201 | //archive_handle->action_header = header_list; |
203 | archive_handle->action_data = data_extract_all; | 202 | archive_handle->action_data = data_extract_all; |
@@ -213,11 +212,9 @@ void extract_cpio_gz(int fd) { | |||
213 | check_header_gzip(archive_handle->src_fd); | 212 | check_header_gzip(archive_handle->src_fd); |
214 | chdir("/"); // Install RPM's to root | 213 | chdir("/"); // Install RPM's to root |
215 | 214 | ||
216 | GZ_gzReadOpen(archive_handle->src_fd, 0, 0); | 215 | archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip); |
216 | archive_handle->offset = 0; | ||
217 | while (get_header_cpio(archive_handle) == EXIT_SUCCESS); | 217 | while (get_header_cpio(archive_handle) == EXIT_SUCCESS); |
218 | GZ_gzReadClose(); | ||
219 | |||
220 | check_trailer_gzip(archive_handle->src_fd); | ||
221 | } | 218 | } |
222 | 219 | ||
223 | 220 | ||
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index bb9f69573..47f4e73cd 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c | |||
@@ -96,10 +96,9 @@ extern int rpm2cpio_main(int argc, char **argv) | |||
96 | } | 96 | } |
97 | 97 | ||
98 | check_header_gzip(rpm_fd); | 98 | check_header_gzip(rpm_fd); |
99 | if (inflate(rpm_fd, fileno(stdout)) != 0) { | 99 | if (inflate_gunzip(rpm_fd, fileno(stdout)) != 0) { |
100 | bb_error_msg("Error inflating"); | 100 | bb_error_msg("Error inflating"); |
101 | } | 101 | } |
102 | check_trailer_gzip(rpm_fd); | ||
103 | 102 | ||
104 | close(rpm_fd); | 103 | close(rpm_fd); |
105 | 104 | ||
diff --git a/archival/unzip.c b/archival/unzip.c index f2d7f4918..c670073f4 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -199,7 +199,8 @@ extern int unzip_main(int argc, char **argv) | |||
199 | archive_handle->action_data(archive_handle); | 199 | archive_handle->action_data(archive_handle); |
200 | } else { | 200 | } else { |
201 | dst_fd = bb_xopen(archive_handle->file_header->name, O_WRONLY | O_CREAT); | 201 | dst_fd = bb_xopen(archive_handle->file_header->name, O_WRONLY | O_CREAT); |
202 | inflate(archive_handle->src_fd, dst_fd); | 202 | inflate_init(zip_header.formated.cmpsize); |
203 | inflate_unzip(archive_handle->src_fd, dst_fd); | ||
203 | close(dst_fd); | 204 | close(dst_fd); |
204 | chmod(archive_handle->file_header->name, archive_handle->file_header->mode); | 205 | chmod(archive_handle->file_header->name, archive_handle->file_header->mode); |
205 | 206 | ||
@@ -227,10 +228,8 @@ extern int unzip_main(int argc, char **argv) | |||
227 | /* Data descriptor section */ | 228 | /* Data descriptor section */ |
228 | if (zip_header.formated.flags & 4) { | 229 | if (zip_header.formated.flags & 4) { |
229 | /* skip over duplicate crc, compressed size and uncompressed size */ | 230 | /* skip over duplicate crc, compressed size and uncompressed size */ |
230 | unsigned short i; | 231 | unsigned char data_description[12]; |
231 | for (i = 0; i != 12; i++) { | 232 | archive_xread_all(archive_handle, data_description, 12); |
232 | archive_xread_char(archive_handle); | ||
233 | } | ||
234 | archive_handle->offset += 12; | 233 | archive_handle->offset += 12; |
235 | } | 234 | } |
236 | } | 235 | } |