aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2013-08-27 16:10:53 +0100
committerRon Yorston <rmy@pobox.com>2013-08-27 16:10:53 +0100
commit3fd34651ea72ea1c335d3170f234cb0517fd897f (patch)
tree36e8fc40cffd464ffda4759020777dd3ca23ca31 /archival
parente3ac39098326de084a805d0dd31db9666b734f20 (diff)
parentd6ae4fb446daedfe3073d67be655942e9fa7eb18 (diff)
downloadbusybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.tar.gz
busybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.tar.bz2
busybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'archival')
-rw-r--r--archival/bbunzip.c36
-rw-r--r--archival/libarchive/Kbuild.src38
-rw-r--r--archival/libarchive/data_extract_to_command.c2
-rw-r--r--archival/tar.c6
-rw-r--r--archival/unzip.c64
5 files changed, 99 insertions, 47 deletions
diff --git a/archival/bbunzip.c b/archival/bbunzip.c
index f77ac8383..9d1cd9485 100644
--- a/archival/bbunzip.c
+++ b/archival/bbunzip.c
@@ -132,7 +132,10 @@ int FAST_FUNC bbunpack(char **argv,
132 132
133 if (filename) { 133 if (filename) {
134 char *del = new_name; 134 char *del = new_name;
135
135 if (status >= 0) { 136 if (status >= 0) {
137 unsigned new_name_len;
138
136 /* TODO: restore other things? */ 139 /* TODO: restore other things? */
137 if (aux.mtime != 0) { 140 if (aux.mtime != 0) {
138 struct timeval times[2]; 141 struct timeval times[2];
@@ -146,24 +149,31 @@ int FAST_FUNC bbunpack(char **argv,
146 utimes(new_name, times); /* ignoring errors */ 149 utimes(new_name, times); /* ignoring errors */
147 } 150 }
148 151
149 /* Delete _compressed_ file */ 152 if (ENABLE_DESKTOP)
153 new_name_len = strlen(new_name);
154 /* Restore source filename (unless tgz -> tar case) */
155 if (new_name == filename) {
156 new_name_len = strlen(filename);
157 filename[new_name_len] = '.';
158 }
159 /* Extreme bloat for gunzip compat */
160 /* Some users do want this info... */
161 if (ENABLE_DESKTOP && (option_mask32 & OPT_VERBOSE)) {
162 unsigned percent = status
163 ? ((uoff_t)stat_buf.st_size * 100u / (unsigned long long)status)
164 : 0;
165 fprintf(stderr, "%s: %u%% - replaced with %.*s\n",
166 filename,
167 100u - percent,
168 new_name_len, new_name
169 );
170 }
171 /* Delete _source_ file */
150 del = filename; 172 del = filename;
151 /* restore extension (unless tgz -> tar case) */
152 if (new_name == filename)
153 filename[strlen(filename)] = '.';
154 } 173 }
155 if (ENABLE_PLATFORM_MINGW32) 174 if (ENABLE_PLATFORM_MINGW32)
156 xclose(STDIN_FILENO); 175 xclose(STDIN_FILENO);
157 xunlink(del); 176 xunlink(del);
158
159#if 0 /* Currently buggy - wrong name: "a.gz: 261% - replaced with a.gz" */
160 /* Extreme bloat for gunzip compat */
161 if (ENABLE_DESKTOP && (option_mask32 & OPT_VERBOSE) && status >= 0) {
162 fprintf(stderr, "%s: %u%% - replaced with %s\n",
163 filename, (unsigned)(stat_buf.st_size*100 / (status+1)), new_name);
164 }
165#endif
166
167 free_name: 177 free_name:
168 if (new_name != filename) 178 if (new_name != filename)
169 free(new_name); 179 free(new_name);
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src
index 58457fc22..968fdf8ab 100644
--- a/archival/libarchive/Kbuild.src
+++ b/archival/libarchive/Kbuild.src
@@ -38,31 +38,45 @@ DPKG_FILES:= \
38 38
39INSERT 39INSERT
40 40
41lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o
42lib-$(CONFIG_BUNZIP2) += decompress_bunzip2.o
43lib-$(CONFIG_UNLZMA) += decompress_unlzma.o
44lib-$(CONFIG_UNXZ) += decompress_unxz.o
45lib-$(CONFIG_CPIO) += get_header_cpio.o
46lib-$(CONFIG_DPKG) += $(DPKG_FILES) 41lib-$(CONFIG_DPKG) += $(DPKG_FILES)
47lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) 42lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES)
48lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o 43
49lib-$(CONFIG_RPM2CPIO) += decompress_gunzip.o get_header_cpio.o 44lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o
50lib-$(CONFIG_RPM) += open_transformer.o decompress_gunzip.o get_header_cpio.o 45lib-$(CONFIG_CPIO) += get_header_cpio.o
51lib-$(CONFIG_TAR) += get_header_tar.o 46lib-$(CONFIG_TAR) += get_header_tar.o
52lib-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o 47lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o
53lib-$(CONFIG_UNZIP) += decompress_gunzip.o
54lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o 48lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o
55lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o 49lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o
50lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o
51lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o
52lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o
53lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o
54lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o
55lib-$(CONFIG_UNZIP) += open_transformer.o decompress_gunzip.o
56lib-$(CONFIG_RPM2CPIO) += open_transformer.o decompress_gunzip.o get_header_cpio.o
57lib-$(CONFIG_RPM) += open_transformer.o decompress_gunzip.o get_header_cpio.o
58
59lib-$(CONFIG_GZIP) += open_transformer.o
60lib-$(CONFIG_BZIP2) += open_transformer.o
61lib-$(CONFIG_LZOP) += open_transformer.o
62lib-$(CONFIG_MAN) += open_transformer.o
63lib-$(CONFIG_SETFONT) += open_transformer.o
64lib-$(CONFIG_FEATURE_2_4_MODULES) += open_transformer.o
56lib-$(CONFIG_MODINFO) += open_transformer.o 65lib-$(CONFIG_MODINFO) += open_transformer.o
57lib-$(CONFIG_INSMOD) += open_transformer.o 66lib-$(CONFIG_INSMOD) += open_transformer.o
67lib-$(CONFIG_DEPMOD) += open_transformer.o
68lib-$(CONFIG_RMMOD) += open_transformer.o
69lib-$(CONFIG_LSMOD) += open_transformer.o
70lib-$(CONFIG_MODPROBE) += open_transformer.o
71lib-$(CONFIG_MODPROBE_SMALL) += open_transformer.o
72
58lib-$(CONFIG_FEATURE_SEAMLESS_Z) += open_transformer.o decompress_uncompress.o 73lib-$(CONFIG_FEATURE_SEAMLESS_Z) += open_transformer.o decompress_uncompress.o
59lib-$(CONFIG_FEATURE_SEAMLESS_GZ) += open_transformer.o decompress_gunzip.o 74lib-$(CONFIG_FEATURE_SEAMLESS_GZ) += open_transformer.o decompress_gunzip.o
60lib-$(CONFIG_FEATURE_SEAMLESS_BZ2) += open_transformer.o decompress_bunzip2.o 75lib-$(CONFIG_FEATURE_SEAMLESS_BZ2) += open_transformer.o decompress_bunzip2.o
61lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma.o 76lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma.o
62lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o 77lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o
63lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o 78lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o
64lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += decompress_bunzip2.o 79lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o
65lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o
66 80
67ifneq ($(lib-y),) 81ifneq ($(lib-y),)
68lib-y += $(COMMON_FILES) 82lib-y += $(COMMON_FILES)
diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c
index a2ce33b51..5b32c2ec8 100644
--- a/archival/libarchive/data_extract_to_command.c
+++ b/archival/libarchive/data_extract_to_command.c
@@ -103,7 +103,7 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle)
103 archive_handle->tar__to_command_shell, 103 archive_handle->tar__to_command_shell,
104 "-c", 104 "-c",
105 archive_handle->tar__to_command, 105 archive_handle->tar__to_command,
106 NULL); 106 (char *)0);
107 bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell); 107 bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell);
108 } 108 }
109 close(p[0]); 109 close(p[0]);
diff --git a/archival/tar.c b/archival/tar.c
index 648d1256d..3129781d2 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -569,7 +569,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip)
569 xmove_fd(gzipDataPipe.rd, 0); 569 xmove_fd(gzipDataPipe.rd, 0);
570 xmove_fd(tar_fd, 1); 570 xmove_fd(tar_fd, 1);
571 /* exec gzip/bzip2 program/applet */ 571 /* exec gzip/bzip2 program/applet */
572 BB_EXECLP(zip_exec, zip_exec, "-f", NULL); 572 BB_EXECLP(zip_exec, zip_exec, "-f", (char *)0);
573 vfork_exec_errno = errno; 573 vfork_exec_errno = errno;
574 _exit(EXIT_FAILURE); 574 _exit(EXIT_FAILURE);
575 } 575 }
@@ -681,14 +681,12 @@ static llist_t *append_file_list_to_list(llist_t *list)
681 char *cp = last_char_is(line, '/'); 681 char *cp = last_char_is(line, '/');
682 if (cp > line) 682 if (cp > line)
683 *cp = '\0'; 683 *cp = '\0';
684 llist_add_to(&newlist, line); 684 llist_add_to_end(&newlist, line);
685 } 685 }
686 fclose(src_stream); 686 fclose(src_stream);
687 } 687 }
688 return newlist; 688 return newlist;
689} 689}
690#else
691# define append_file_list_to_list(x) 0
692#endif 690#endif
693 691
694//usage:#define tar_trivial_usage 692//usage:#define tar_trivial_usage
diff --git a/archival/unzip.c b/archival/unzip.c
index e4c824850..673e5fe08 100644
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -163,7 +163,17 @@ enum { zip_fd = 3 };
163 163
164#if ENABLE_DESKTOP 164#if ENABLE_DESKTOP
165 165
166#define PEEK_FROM_END 16384 166/* Seen in the wild:
167 * Self-extracting PRO2K3XP_32.exe contains 19078464 byte zip archive,
168 * where CDE was nearly 48 kbytes before EOF.
169 * (Surprisingly, it also apparently has *another* CDE structure
170 * closer to the end, with bogus cdf_offset).
171 * To make extraction work, bumped PEEK_FROM_END from 16k to 64k.
172 */
173#define PEEK_FROM_END (64*1024)
174
175/* This value means that we failed to find CDF */
176#define BAD_CDF_OFFSET ((uint32_t)0xffffffff)
167 177
168/* NB: does not preserve file position! */ 178/* NB: does not preserve file position! */
169static uint32_t find_cdf_offset(void) 179static uint32_t find_cdf_offset(void)
@@ -180,6 +190,7 @@ static uint32_t find_cdf_offset(void)
180 xlseek(zip_fd, end, SEEK_SET); 190 xlseek(zip_fd, end, SEEK_SET);
181 full_read(zip_fd, buf, PEEK_FROM_END); 191 full_read(zip_fd, buf, PEEK_FROM_END);
182 192
193 cde_header.formatted.cdf_offset = BAD_CDF_OFFSET;
183 p = buf; 194 p = buf;
184 while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) { 195 while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) {
185 if (*p != 'P') { 196 if (*p != 'P') {
@@ -195,11 +206,17 @@ static uint32_t find_cdf_offset(void)
195 /* we found CDE! */ 206 /* we found CDE! */
196 memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN); 207 memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN);
197 FIX_ENDIANNESS_CDE(cde_header); 208 FIX_ENDIANNESS_CDE(cde_header);
198 free(buf); 209 /*
199 return cde_header.formatted.cdf_offset; 210 * I've seen .ZIP files with seemingly valid CDEs
211 * where cdf_offset points past EOF - ??
212 * Ignore such CDEs:
213 */
214 if (cde_header.formatted.cdf_offset < end + (p - buf))
215 break;
216 cde_header.formatted.cdf_offset = BAD_CDF_OFFSET;
200 } 217 }
201 //free(buf); 218 free(buf);
202 bb_error_msg_and_die("can't find file table"); 219 return cde_header.formatted.cdf_offset;
203}; 220};
204 221
205static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) 222static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr)
@@ -211,13 +228,15 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr)
211 if (!cdf_offset) 228 if (!cdf_offset)
212 cdf_offset = find_cdf_offset(); 229 cdf_offset = find_cdf_offset();
213 230
214 xlseek(zip_fd, cdf_offset + 4, SEEK_SET); 231 if (cdf_offset != BAD_CDF_OFFSET) {
215 xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN); 232 xlseek(zip_fd, cdf_offset + 4, SEEK_SET);
216 FIX_ENDIANNESS_CDF(*cdf_ptr); 233 xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN);
217 cdf_offset += 4 + CDF_HEADER_LEN 234 FIX_ENDIANNESS_CDF(*cdf_ptr);
218 + cdf_ptr->formatted.file_name_length 235 cdf_offset += 4 + CDF_HEADER_LEN
219 + cdf_ptr->formatted.extra_field_length 236 + cdf_ptr->formatted.file_name_length
220 + cdf_ptr->formatted.file_comment_length; 237 + cdf_ptr->formatted.extra_field_length
238 + cdf_ptr->formatted.file_comment_length;
239 }
221 240
222 xlseek(zip_fd, org, SEEK_SET); 241 xlseek(zip_fd, org, SEEK_SET);
223 return cdf_offset; 242 return cdf_offset;
@@ -226,8 +245,9 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr)
226 245
227static void unzip_skip(off_t skip) 246static void unzip_skip(off_t skip)
228{ 247{
229 if (lseek(zip_fd, skip, SEEK_CUR) == (off_t)-1) 248 if (skip != 0)
230 bb_copyfd_exact_size(zip_fd, -1, skip); 249 if (lseek(zip_fd, skip, SEEK_CUR) == (off_t)-1)
250 bb_copyfd_exact_size(zip_fd, -1, skip);
231} 251}
232 252
233static void unzip_create_leading_dirs(const char *fn) 253static void unzip_create_leading_dirs(const char *fn)
@@ -528,21 +548,31 @@ int unzip_main(int argc, char **argv)
528 bb_error_msg_and_die("zip flag 1 (encryption) is not supported"); 548 bb_error_msg_and_die("zip flag 1 (encryption) is not supported");
529 } 549 }
530 550
531 { 551 if (cdf_offset != BAD_CDF_OFFSET) {
532 cdf_header_t cdf_header; 552 cdf_header_t cdf_header;
533 cdf_offset = read_next_cdf(cdf_offset, &cdf_header); 553 cdf_offset = read_next_cdf(cdf_offset, &cdf_header);
554 /*
555 * Note: cdf_offset can become BAD_CDF_OFFSET after the above call.
556 */
534 if (zip_header.formatted.zip_flags & SWAP_LE16(0x0008)) { 557 if (zip_header.formatted.zip_flags & SWAP_LE16(0x0008)) {
535 /* 0x0008 - streaming. [u]cmpsize can be reliably gotten 558 /* 0x0008 - streaming. [u]cmpsize can be reliably gotten
536 * only from Central Directory. See unzip_doc.txt */ 559 * only from Central Directory. See unzip_doc.txt
560 */
537 zip_header.formatted.crc32 = cdf_header.formatted.crc32; 561 zip_header.formatted.crc32 = cdf_header.formatted.crc32;
538 zip_header.formatted.cmpsize = cdf_header.formatted.cmpsize; 562 zip_header.formatted.cmpsize = cdf_header.formatted.cmpsize;
539 zip_header.formatted.ucmpsize = cdf_header.formatted.ucmpsize; 563 zip_header.formatted.ucmpsize = cdf_header.formatted.ucmpsize;
540 } 564 }
541 if ((cdf_header.formatted.version_made_by >> 8) == 3) { 565 if ((cdf_header.formatted.version_made_by >> 8) == 3) {
542 /* this archive is created on Unix */ 566 /* This archive is created on Unix */
543 dir_mode = file_mode = (cdf_header.formatted.external_file_attributes >> 16); 567 dir_mode = file_mode = (cdf_header.formatted.external_file_attributes >> 16);
544 } 568 }
545 } 569 }
570 if (cdf_offset == BAD_CDF_OFFSET
571 && (zip_header.formatted.zip_flags & SWAP_LE16(0x0008))
572 ) {
573 /* If it's a streaming zip, we _require_ CDF */
574 bb_error_msg_and_die("can't find file table");
575 }
546#endif 576#endif
547 577
548 /* Read filename */ 578 /* Read filename */