aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
Diffstat (limited to 'archival')
-rw-r--r--archival/cpio.c4
-rw-r--r--archival/libarchive/common.c2
-rw-r--r--archival/lzop.c7
-rw-r--r--archival/rpm.c5
-rw-r--r--archival/tar.c3
-rw-r--r--archival/unzip.c138
6 files changed, 110 insertions, 49 deletions
diff --git a/archival/cpio.c b/archival/cpio.c
index 30f66d1f7..d0cedd35c 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -11,6 +11,7 @@
11 * Only supports new ASCII and CRC formats 11 * Only supports new ASCII and CRC formats
12 */ 12 */
13#include "libbb.h" 13#include "libbb.h"
14#include "common_bufsiz.h"
14#include "bb_archive.h" 15#include "bb_archive.h"
15 16
16//config:config CPIO 17//config:config CPIO
@@ -170,9 +171,10 @@ enum {
170struct globals { 171struct globals {
171 struct bb_uidgid_t owner_ugid; 172 struct bb_uidgid_t owner_ugid;
172} FIX_ALIASING; 173} FIX_ALIASING;
173#define G (*(struct globals*)&bb_common_bufsiz1) 174#define G (*(struct globals*)bb_common_bufsiz1)
174void BUG_cpio_globals_too_big(void); 175void BUG_cpio_globals_too_big(void);
175#define INIT_G() do { \ 176#define INIT_G() do { \
177 setup_common_bufsiz(); \
176 G.owner_ugid.uid = -1L; \ 178 G.owner_ugid.uid = -1L; \
177 G.owner_ugid.gid = -1L; \ 179 G.owner_ugid.gid = -1L; \
178} while (0) 180} while (0)
diff --git a/archival/libarchive/common.c b/archival/libarchive/common.c
index dd69d2222..389cb7856 100644
--- a/archival/libarchive/common.c
+++ b/archival/libarchive/common.c
@@ -6,4 +6,4 @@
6#include "libbb.h" 6#include "libbb.h"
7#include "bb_archive.h" 7#include "bb_archive.h"
8 8
9const char cpio_TRAILER[] = "TRAILER!!!"; 9const char cpio_TRAILER[] ALIGN1 = "TRAILER!!!";
diff --git a/archival/lzop.c b/archival/lzop.c
index a5fc01941..202de4d03 100644
--- a/archival/lzop.c
+++ b/archival/lzop.c
@@ -71,6 +71,7 @@
71//usage: "\n -F Don't store or verify checksum" 71//usage: "\n -F Don't store or verify checksum"
72 72
73#include "libbb.h" 73#include "libbb.h"
74#include "common_bufsiz.h"
74#include "bb_archive.h" 75#include "bb_archive.h"
75#include "liblzo_interface.h" 76#include "liblzo_interface.h"
76 77
@@ -443,8 +444,8 @@ struct globals {
443 chksum_t chksum_in; 444 chksum_t chksum_in;
444 chksum_t chksum_out; 445 chksum_t chksum_out;
445} FIX_ALIASING; 446} FIX_ALIASING;
446#define G (*(struct globals*)&bb_common_bufsiz1) 447#define G (*(struct globals*)bb_common_bufsiz1)
447#define INIT_G() do { } while (0) 448#define INIT_G() do { setup_common_bufsiz(); } while (0)
448//#define G (*ptr_to_globals) 449//#define G (*ptr_to_globals)
449//#define INIT_G() do { 450//#define INIT_G() do {
450// SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); 451// SET_PTR_TO_GLOBALS(xzalloc(sizeof(G)));
@@ -895,7 +896,7 @@ static NOINLINE int lzo_decompress(const header_t *h)
895 * chksum_out 896 * chksum_out
896 * The rest is identical. 897 * The rest is identical.
897*/ 898*/
898static const unsigned char lzop_magic[9] = { 899static const unsigned char lzop_magic[9] ALIGN1 = {
899 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a 900 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a
900}; 901};
901 902
diff --git a/archival/rpm.c b/archival/rpm.c
index 105394481..83160f975 100644
--- a/archival/rpm.c
+++ b/archival/rpm.c
@@ -29,6 +29,7 @@
29//usage: "\n -qpc List config files" 29//usage: "\n -qpc List config files"
30 30
31#include "libbb.h" 31#include "libbb.h"
32#include "common_bufsiz.h"
32#include "bb_archive.h" 33#include "bb_archive.h"
33#include "rpm.h" 34#include "rpm.h"
34 35
@@ -93,8 +94,8 @@ struct globals {
93 rpm_index **mytags; 94 rpm_index **mytags;
94 int tagcount; 95 int tagcount;
95} FIX_ALIASING; 96} FIX_ALIASING;
96#define G (*(struct globals*)&bb_common_bufsiz1) 97#define G (*(struct globals*)bb_common_bufsiz1)
97#define INIT_G() do { } while (0) 98#define INIT_G() do { setup_common_bufsiz(); } while (0)
98 99
99static void extract_cpio(int fd, const char *source_rpm) 100static void extract_cpio(int fd, const char *source_rpm)
100{ 101{
diff --git a/archival/tar.c b/archival/tar.c
index adb0b934f..c88957734 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -146,6 +146,7 @@
146 146
147#include <fnmatch.h> 147#include <fnmatch.h>
148#include "libbb.h" 148#include "libbb.h"
149#include "common_bufsiz.h"
149#include "bb_archive.h" 150#include "bb_archive.h"
150/* FIXME: Stop using this non-standard feature */ 151/* FIXME: Stop using this non-standard feature */
151#ifndef FNM_LEADING_DIR 152#ifndef FNM_LEADING_DIR
@@ -161,6 +162,7 @@
161 162
162 163
163#define block_buf bb_common_bufsiz1 164#define block_buf bb_common_bufsiz1
165#define INIT_G() do { setup_common_bufsiz(); } while (0)
164 166
165 167
166#if ENABLE_FEATURE_TAR_CREATE 168#if ENABLE_FEATURE_TAR_CREATE
@@ -992,6 +994,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
992#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 994#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
993 llist_t *excludes = NULL; 995 llist_t *excludes = NULL;
994#endif 996#endif
997 INIT_G();
995 998
996 /* Initialise default values */ 999 /* Initialise default values */
997 tar_handle = init_handle(); 1000 tar_handle = init_handle();
diff --git a/archival/unzip.c b/archival/unzip.c
index 203073434..27adb3420 100644
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -48,6 +48,12 @@
48#pragma pack(2) 48#pragma pack(2)
49#endif 49#endif
50 50
51#if 0
52# define dbg(...) bb_error_msg(__VA_ARGS__)
53#else
54# define dbg(...) ((void)0)
55#endif
56
51enum { 57enum {
52#if BB_BIG_ENDIAN 58#if BB_BIG_ENDIAN
53 ZIP_FILEHEADER_MAGIC = 0x504b0304, 59 ZIP_FILEHEADER_MAGIC = 0x504b0304,
@@ -196,15 +202,17 @@ static uint32_t find_cdf_offset(void)
196 unsigned char *p; 202 unsigned char *p;
197 off_t end; 203 off_t end;
198 unsigned char *buf = xzalloc(PEEK_FROM_END); 204 unsigned char *buf = xzalloc(PEEK_FROM_END);
205 uint32_t found;
199 206
200 end = xlseek(zip_fd, 0, SEEK_END); 207 end = xlseek(zip_fd, 0, SEEK_END);
201 end -= PEEK_FROM_END; 208 end -= PEEK_FROM_END;
202 if (end < 0) 209 if (end < 0)
203 end = 0; 210 end = 0;
204 xlseek(zip_fd, end, SEEK_SET); 211 dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end);
212 xlseek(zip_fd, end, SEEK_SET);
205 full_read(zip_fd, buf, PEEK_FROM_END); 213 full_read(zip_fd, buf, PEEK_FROM_END);
206 214
207 cde_header.formatted.cdf_offset = BAD_CDF_OFFSET; 215 found = BAD_CDF_OFFSET;
208 p = buf; 216 p = buf;
209 while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) { 217 while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) {
210 if (*p != 'P') { 218 if (*p != 'P') {
@@ -223,14 +231,25 @@ static uint32_t find_cdf_offset(void)
223 /* 231 /*
224 * I've seen .ZIP files with seemingly valid CDEs 232 * I've seen .ZIP files with seemingly valid CDEs
225 * where cdf_offset points past EOF - ?? 233 * where cdf_offset points past EOF - ??
226 * Ignore such CDEs: 234 * This check ignores such CDEs:
227 */ 235 */
228 if (cde_header.formatted.cdf_offset < end + (p - buf)) 236 if (cde_header.formatted.cdf_offset < end + (p - buf)) {
229 break; 237 found = cde_header.formatted.cdf_offset;
230 cde_header.formatted.cdf_offset = BAD_CDF_OFFSET; 238 dbg("Possible cdf_offset:0x%x at 0x%"OFF_FMT"x",
239 (unsigned)found, end + (p-3 - buf));
240 dbg(" cdf_offset+cdf_size:0x%x",
241 (unsigned)(found + SWAP_LE32(cde_header.formatted.cdf_size)));
242 /*
243 * We do not "break" here because only the last CDE is valid.
244 * I've seen a .zip archive which contained a .zip file,
245 * uncompressed, and taking the first CDE was using
246 * the CDE inside that file!
247 */
248 }
231 } 249 }
232 free(buf); 250 free(buf);
233 return cde_header.formatted.cdf_offset; 251 dbg("Found cdf_offset:0x%x", (unsigned)found);
252 return found;
234}; 253};
235 254
236static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) 255static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr)
@@ -243,15 +262,22 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr)
243 cdf_offset = find_cdf_offset(); 262 cdf_offset = find_cdf_offset();
244 263
245 if (cdf_offset != BAD_CDF_OFFSET) { 264 if (cdf_offset != BAD_CDF_OFFSET) {
265 dbg("Reading CDF at 0x%x", (unsigned)cdf_offset);
246 xlseek(zip_fd, cdf_offset + 4, SEEK_SET); 266 xlseek(zip_fd, cdf_offset + 4, SEEK_SET);
247 xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN); 267 xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN);
248 FIX_ENDIANNESS_CDF(*cdf_ptr); 268 FIX_ENDIANNESS_CDF(*cdf_ptr);
269 dbg(" file_name_length:%u extra_field_length:%u file_comment_length:%u",
270 (unsigned)cdf_ptr->formatted.file_name_length,
271 (unsigned)cdf_ptr->formatted.extra_field_length,
272 (unsigned)cdf_ptr->formatted.file_comment_length
273 );
249 cdf_offset += 4 + CDF_HEADER_LEN 274 cdf_offset += 4 + CDF_HEADER_LEN
250 + cdf_ptr->formatted.file_name_length 275 + cdf_ptr->formatted.file_name_length
251 + cdf_ptr->formatted.extra_field_length 276 + cdf_ptr->formatted.extra_field_length
252 + cdf_ptr->formatted.file_comment_length; 277 + cdf_ptr->formatted.file_comment_length;
253 } 278 }
254 279
280 dbg("Returning file position to 0x%"OFF_FMT"x", org);
255 xlseek(zip_fd, org, SEEK_SET); 281 xlseek(zip_fd, org, SEEK_SET);
256 return cdf_offset; 282 return cdf_offset;
257}; 283};
@@ -464,7 +490,7 @@ int unzip_main(int argc, char **argv)
464 if (overwrite == O_PROMPT) 490 if (overwrite == O_PROMPT)
465 overwrite = O_NEVER; 491 overwrite = O_NEVER;
466 } else { 492 } else {
467 static const char extn[][5] = { ".zip", ".ZIP" }; 493 static const char extn[][5] ALIGN1 = { ".zip", ".ZIP" };
468 char *ext = src_fn + strlen(src_fn); 494 char *ext = src_fn + strlen(src_fn);
469 int src_fd; 495 int src_fd;
470 496
@@ -491,11 +517,11 @@ int unzip_main(int argc, char **argv)
491 printf("Archive: %s\n", src_fn); 517 printf("Archive: %s\n", src_fn);
492 if (listing) { 518 if (listing) {
493 puts(verbose ? 519 puts(verbose ?
494 " Length Method Size Ratio Date Time CRC-32 Name\n" 520 " Length Method Size Cmpr Date Time CRC-32 Name\n"
495 "-------- ------ ------- ----- ---- ---- ------ ----" 521 "-------- ------ ------- ---- ---------- ----- -------- ----"
496 : 522 :
497 " Length Date Time Name\n" 523 " Length Date Time Name\n"
498 " -------- ---- ---- ----" 524 "--------- ---------- ----- ----"
499 ); 525 );
500 } 526 }
501 } 527 }
@@ -535,11 +561,14 @@ int unzip_main(int argc, char **argv)
535 /* Check magic number */ 561 /* Check magic number */
536 xread(zip_fd, &magic, 4); 562 xread(zip_fd, &magic, 4);
537 /* Central directory? It's at the end, so exit */ 563 /* Central directory? It's at the end, so exit */
538 if (magic == ZIP_CDF_MAGIC) 564 if (magic == ZIP_CDF_MAGIC) {
565 dbg("got ZIP_CDF_MAGIC");
539 break; 566 break;
567 }
540#if ENABLE_DESKTOP 568#if ENABLE_DESKTOP
541 /* Data descriptor? It was a streaming file, go on */ 569 /* Data descriptor? It was a streaming file, go on */
542 if (magic == ZIP_DD_MAGIC) { 570 if (magic == ZIP_DD_MAGIC) {
571 dbg("got ZIP_DD_MAGIC");
543 /* skip over duplicate crc32, cmpsize and ucmpsize */ 572 /* skip over duplicate crc32, cmpsize and ucmpsize */
544 unzip_skip(3 * 4); 573 unzip_skip(3 * 4);
545 continue; 574 continue;
@@ -547,6 +576,7 @@ int unzip_main(int argc, char **argv)
547#endif 576#endif
548 if (magic != ZIP_FILEHEADER_MAGIC) 577 if (magic != ZIP_FILEHEADER_MAGIC)
549 bb_error_msg_and_die("invalid zip magic %08X", (int)magic); 578 bb_error_msg_and_die("invalid zip magic %08X", (int)magic);
579 dbg("got ZIP_FILEHEADER_MAGIC");
550 580
551 /* Read the file header */ 581 /* Read the file header */
552 xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN); 582 xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN);
@@ -590,6 +620,11 @@ int unzip_main(int argc, char **argv)
590 bb_error_msg_and_die("can't find file table"); 620 bb_error_msg_and_die("can't find file table");
591 } 621 }
592#endif 622#endif
623 dbg("File cmpsize:0x%x extra_len:0x%x ucmpsize:0x%x",
624 (unsigned)zip_header.formatted.cmpsize,
625 (unsigned)zip_header.formatted.extra_len,
626 (unsigned)zip_header.formatted.ucmpsize
627 );
593 628
594 /* Read filename */ 629 /* Read filename */
595 free(dst_fn); 630 free(dst_fn);
@@ -610,40 +645,55 @@ int unzip_main(int argc, char **argv)
610 } else { 645 } else {
611 if (listing) { 646 if (listing) {
612 /* List entry */ 647 /* List entry */
613 unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); 648 char dtbuf[sizeof("mm-dd-yyyy hh:mm")];
649 sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u",
650 (zip_header.formatted.moddate >> 5) & 0xf, // mm: 0x01e0
651 (zip_header.formatted.moddate) & 0x1f, // dd: 0x001f
652 (zip_header.formatted.moddate >> 9) + 1980, // yy: 0xfe00
653 (zip_header.formatted.modtime >> 11), // hh: 0xf800
654 (zip_header.formatted.modtime >> 5) & 0x3f // mm: 0x07e0
655 // seconds/2 are not shown, encoded in ----------- 0x001f
656 );
614 if (!verbose) { 657 if (!verbose) {
615 // " Length Date Time Name\n" 658 // " Length Date Time Name\n"
616 // " -------- ---- ---- ----" 659 // "--------- ---------- ----- ----"
617 printf( "%9u %02u-%02u-%02u %02u:%02u %s\n", 660 printf( "%9u " "%s " "%s\n",
618 (unsigned)zip_header.formatted.ucmpsize, 661 (unsigned)zip_header.formatted.ucmpsize,
619 (dostime & 0x01e00000) >> 21, 662 dtbuf,
620 (dostime & 0x001f0000) >> 16,
621 (((dostime & 0xfe000000) >> 25) + 1980) % 100,
622 (dostime & 0x0000f800) >> 11,
623 (dostime & 0x000007e0) >> 5,
624 dst_fn); 663 dst_fn);
625 total_usize += zip_header.formatted.ucmpsize;
626 } else { 664 } else {
627 unsigned long percents = zip_header.formatted.ucmpsize - zip_header.formatted.cmpsize; 665 unsigned long percents = zip_header.formatted.ucmpsize - zip_header.formatted.cmpsize;
666 if ((int32_t)percents < 0)
667 percents = 0; /* happens if ucmpsize < cmpsize */
628 percents = percents * 100; 668 percents = percents * 100;
629 if (zip_header.formatted.ucmpsize) 669 if (zip_header.formatted.ucmpsize)
630 percents /= zip_header.formatted.ucmpsize; 670 percents /= zip_header.formatted.ucmpsize;
631 // " Length Method Size Ratio Date Time CRC-32 Name\n" 671 // " Length Method Size Cmpr Date Time CRC-32 Name\n"
632 // "-------- ------ ------- ----- ---- ---- ------ ----" 672 // "-------- ------ ------- ---- ---------- ----- -------- ----"
633 printf( "%8u Defl:N" "%9u%4u%% %02u-%02u-%02u %02u:%02u %08x %s\n", 673 printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n",
634 (unsigned)zip_header.formatted.ucmpsize, 674 (unsigned)zip_header.formatted.ucmpsize,
675 zip_header.formatted.method == 0 ? "Stored" : "Defl:N", /* Defl is method 8 */
676/* TODO: show other methods?
677 * 1 - Shrunk
678 * 2 - Reduced with compression factor 1
679 * 3 - Reduced with compression factor 2
680 * 4 - Reduced with compression factor 3
681 * 5 - Reduced with compression factor 4
682 * 6 - Imploded
683 * 7 - Reserved for Tokenizing compression algorithm
684 * 9 - Deflate64
685 * 10 - PKWARE Data Compression Library Imploding
686 * 11 - Reserved by PKWARE
687 * 12 - BZIP2
688 */
635 (unsigned)zip_header.formatted.cmpsize, 689 (unsigned)zip_header.formatted.cmpsize,
636 (unsigned)percents, 690 (unsigned)percents,
637 (dostime & 0x01e00000) >> 21, 691 dtbuf,
638 (dostime & 0x001f0000) >> 16,
639 (((dostime & 0xfe000000) >> 25) + 1980) % 100,
640 (dostime & 0x0000f800) >> 11,
641 (dostime & 0x000007e0) >> 5,
642 zip_header.formatted.crc32, 692 zip_header.formatted.crc32,
643 dst_fn); 693 dst_fn);
644 total_usize += zip_header.formatted.ucmpsize;
645 total_size += zip_header.formatted.cmpsize; 694 total_size += zip_header.formatted.cmpsize;
646 } 695 }
696 total_usize += zip_header.formatted.ucmpsize;
647 i = 'n'; 697 i = 'n';
648 } else if (dst_fd == STDOUT_FILENO) { 698 } else if (dst_fd == STDOUT_FILENO) {
649 /* Extracting to STDOUT */ 699 /* Extracting to STDOUT */
@@ -746,21 +796,25 @@ int unzip_main(int argc, char **argv)
746 796
747 if (listing && quiet <= 1) { 797 if (listing && quiet <= 1) {
748 if (!verbose) { 798 if (!verbose) {
749 // " Length Date Time Name\n" 799 // " Length Date Time Name\n"
750 // " -------- ---- ---- ----" 800 // "--------- ---------- ----- ----"
751 printf( " -------- -------\n" 801 printf( " --------%21s" "-------\n"
752 "%9lu" " %u files\n", 802 "%9lu%21s" "%u files\n",
753 total_usize, total_entries); 803 "",
804 total_usize, "", total_entries);
754 } else { 805 } else {
755 unsigned long percents = total_usize - total_size; 806 unsigned long percents = total_usize - total_size;
807 if ((long)percents < 0)
808 percents = 0; /* happens if usize < size */
756 percents = percents * 100; 809 percents = percents * 100;
757 if (total_usize) 810 if (total_usize)
758 percents /= total_usize; 811 percents /= total_usize;
759 // " Length Method Size Ratio Date Time CRC-32 Name\n" 812 // " Length Method Size Cmpr Date Time CRC-32 Name\n"
760 // "-------- ------ ------- ----- ---- ---- ------ ----" 813 // "-------- ------ ------- ---- ---------- ----- -------- ----"
761 printf( "-------- ------- --- -------\n" 814 printf( "-------- ------- ----%28s" "----\n"
762 "%8lu" "%17lu%4u%% %u files\n", 815 "%8lu" "%17lu%4u%%%28s" "%u files\n",
763 total_usize, total_size, (unsigned)percents, 816 "",
817 total_usize, total_size, (unsigned)percents, "",
764 total_entries); 818 total_entries);
765 } 819 }
766 } 820 }