aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2011-01-04 19:56:15 +0700
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2011-01-04 19:56:15 +0700
commit5f6f2162512106adf120d4b528bb125e93e34429 (patch)
tree7d7449f755633c263be7125ad58d21cc3ca5b8a7 /archival
parent9db69882bee2d528d706d61d34ef7741122330be (diff)
parenta116552869db5e7793ae10968eb3c962c69b3d8c (diff)
downloadbusybox-w32-5f6f2162512106adf120d4b528bb125e93e34429.tar.gz
busybox-w32-5f6f2162512106adf120d4b528bb125e93e34429.tar.bz2
busybox-w32-5f6f2162512106adf120d4b528bb125e93e34429.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'archival')
-rw-r--r--archival/Kbuild.src5
-rw-r--r--archival/ar.c18
-rw-r--r--archival/bbunzip.c2
-rw-r--r--archival/bzip2.c20
-rw-r--r--archival/cpio.c107
-rw-r--r--archival/dpkg.c13
-rw-r--r--archival/dpkg_deb.c12
-rw-r--r--archival/gzip.c2
-rw-r--r--archival/libarchive/Kbuild.src (renamed from archival/libunarchive/Kbuild.src)2
-rw-r--r--archival/libarchive/bz/LICENSE (renamed from archival/bz/LICENSE)0
-rw-r--r--archival/libarchive/bz/README (renamed from archival/bz/README)0
-rw-r--r--archival/libarchive/bz/blocksort.c (renamed from archival/bz/blocksort.c)0
-rw-r--r--archival/libarchive/bz/bzlib.c (renamed from archival/bz/bzlib.c)6
-rw-r--r--archival/libarchive/bz/bzlib.h (renamed from archival/bz/bzlib.h)0
-rw-r--r--archival/libarchive/bz/bzlib_private.h (renamed from archival/bz/bzlib_private.h)0
-rw-r--r--archival/libarchive/bz/compress.c (renamed from archival/bz/compress.c)9
-rw-r--r--archival/libarchive/bz/huffman.c (renamed from archival/bz/huffman.c)0
-rw-r--r--archival/libarchive/data_align.c (renamed from archival/libunarchive/data_align.c)2
-rw-r--r--archival/libarchive/data_extract_all.c (renamed from archival/libunarchive/data_extract_all.c)2
-rw-r--r--archival/libarchive/data_extract_to_command.c (renamed from archival/libunarchive/data_extract_to_command.c)2
-rw-r--r--archival/libarchive/data_extract_to_stdout.c (renamed from archival/libunarchive/data_extract_to_stdout.c)2
-rw-r--r--archival/libarchive/data_skip.c (renamed from archival/libunarchive/data_skip.c)2
-rw-r--r--archival/libarchive/decompress_bunzip2.c (renamed from archival/libunarchive/decompress_bunzip2.c)426
-rw-r--r--archival/libarchive/decompress_uncompress.c (renamed from archival/libunarchive/decompress_uncompress.c)2
-rw-r--r--archival/libarchive/decompress_unlzma.c (renamed from archival/libunarchive/decompress_unlzma.c)2
-rw-r--r--archival/libarchive/decompress_unxz.c (renamed from archival/libunarchive/decompress_unxz.c)2
-rw-r--r--archival/libarchive/decompress_unzip.c (renamed from archival/libunarchive/decompress_unzip.c)2
-rw-r--r--archival/libarchive/filter_accept_all.c (renamed from archival/libunarchive/filter_accept_all.c)2
-rw-r--r--archival/libarchive/filter_accept_list.c (renamed from archival/libunarchive/filter_accept_list.c)2
-rw-r--r--archival/libarchive/filter_accept_list_reassign.c (renamed from archival/libunarchive/filter_accept_list_reassign.c)2
-rw-r--r--archival/libarchive/filter_accept_reject_list.c (renamed from archival/libunarchive/filter_accept_reject_list.c)2
-rw-r--r--archival/libarchive/find_list_entry.c (renamed from archival/libunarchive/find_list_entry.c)2
-rw-r--r--archival/libarchive/get_header_ar.c (renamed from archival/libunarchive/get_header_ar.c)2
-rw-r--r--archival/libarchive/get_header_cpio.c (renamed from archival/libunarchive/get_header_cpio.c)2
-rw-r--r--archival/libarchive/get_header_tar.c (renamed from archival/libunarchive/get_header_tar.c)2
-rw-r--r--archival/libarchive/get_header_tar_bz2.c (renamed from archival/libunarchive/get_header_tar_bz2.c)2
-rw-r--r--archival/libarchive/get_header_tar_gz.c (renamed from archival/libunarchive/get_header_tar_gz.c)2
-rw-r--r--archival/libarchive/get_header_tar_lzma.c (renamed from archival/libunarchive/get_header_tar_lzma.c)2
-rw-r--r--archival/libarchive/header_list.c (renamed from archival/libunarchive/header_list.c)2
-rw-r--r--archival/libarchive/header_skip.c (renamed from archival/libunarchive/header_skip.c)2
-rw-r--r--archival/libarchive/header_verbose_list.c (renamed from archival/libunarchive/header_verbose_list.c)2
-rw-r--r--archival/libarchive/init_handle.c (renamed from archival/libunarchive/init_handle.c)2
-rw-r--r--archival/libarchive/liblzo.h (renamed from archival/liblzo.h)0
-rw-r--r--archival/libarchive/lzo1x_1.c (renamed from archival/lzo1x_1.c)0
-rw-r--r--archival/libarchive/lzo1x_1o.c (renamed from archival/lzo1x_1o.c)0
-rw-r--r--archival/libarchive/lzo1x_9x.c (renamed from archival/lzo1x_9x.c)0
-rw-r--r--archival/libarchive/lzo1x_c.c (renamed from archival/lzo1x_c.c)0
-rw-r--r--archival/libarchive/lzo1x_d.c (renamed from archival/lzo1x_d.c)0
-rw-r--r--archival/libarchive/open_transformer.c (renamed from archival/libunarchive/open_transformer.c)4
-rw-r--r--archival/libarchive/seek_by_jump.c (renamed from archival/libunarchive/seek_by_jump.c)2
-rw-r--r--archival/libarchive/seek_by_read.c (renamed from archival/libunarchive/seek_by_read.c)2
-rw-r--r--archival/libarchive/unpack_ar_archive.c (renamed from archival/libunarchive/unpack_ar_archive.c)2
-rw-r--r--archival/libarchive/unxz/README (renamed from archival/libunarchive/unxz/README)0
-rw-r--r--archival/libarchive/unxz/xz.h (renamed from archival/libunarchive/unxz/xz.h)0
-rw-r--r--archival/libarchive/unxz/xz_config.h (renamed from archival/libunarchive/unxz/xz_config.h)0
-rw-r--r--archival/libarchive/unxz/xz_dec_bcj.c (renamed from archival/libunarchive/unxz/xz_dec_bcj.c)0
-rw-r--r--archival/libarchive/unxz/xz_dec_lzma2.c (renamed from archival/libunarchive/unxz/xz_dec_lzma2.c)0
-rw-r--r--archival/libarchive/unxz/xz_dec_stream.c (renamed from archival/libunarchive/unxz/xz_dec_stream.c)0
-rw-r--r--archival/libarchive/unxz/xz_lzma2.h (renamed from archival/libunarchive/unxz/xz_lzma2.h)0
-rw-r--r--archival/libarchive/unxz/xz_private.h (renamed from archival/libunarchive/unxz/xz_private.h)0
-rw-r--r--archival/libarchive/unxz/xz_stream.h (renamed from archival/libunarchive/unxz/xz_stream.h)0
-rw-r--r--archival/liblzo_interface.h71
-rw-r--r--archival/lzop.c2
-rw-r--r--archival/rpm.c2
-rw-r--r--archival/rpm2cpio.c2
-rw-r--r--archival/tar.c22
-rw-r--r--archival/unzip.c2
67 files changed, 427 insertions, 354 deletions
diff --git a/archival/Kbuild.src b/archival/Kbuild.src
index a0edb123d..3466452f7 100644
--- a/archival/Kbuild.src
+++ b/archival/Kbuild.src
@@ -4,7 +4,7 @@
4# 4#
5# Licensed under GPLv2, see file LICENSE in this source tree. 5# Licensed under GPLv2, see file LICENSE in this source tree.
6 6
7libs-y += libunarchive/ 7libs-y += libarchive/
8 8
9lib-y:= 9lib-y:=
10 10
@@ -19,8 +19,7 @@ lib-$(CONFIG_RPM) += rpm.o
19lib-$(CONFIG_TAR) += tar.o 19lib-$(CONFIG_TAR) += tar.o
20lib-$(CONFIG_UNZIP) += unzip.o 20lib-$(CONFIG_UNZIP) += unzip.o
21 21
22lib-$(CONFIG_LZOP) += lzop.o lzo1x_1.o lzo1x_1o.o lzo1x_d.o bbunzip.o 22lib-$(CONFIG_LZOP) += lzop.o bbunzip.o
23lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o
24lib-$(CONFIG_GZIP) += gzip.o bbunzip.o 23lib-$(CONFIG_GZIP) += gzip.o bbunzip.o
25lib-$(CONFIG_BZIP2) += bzip2.o bbunzip.o 24lib-$(CONFIG_BZIP2) += bzip2.o bbunzip.o
26 25
diff --git a/archival/ar.c b/archival/ar.c
index 05556c6cb..a2e3306ac 100644
--- a/archival/ar.c
+++ b/archival/ar.c
@@ -18,7 +18,7 @@
18 */ 18 */
19 19
20#include "libbb.h" 20#include "libbb.h"
21#include "unarchive.h" 21#include "archive.h"
22#include "ar.h" 22#include "ar.h"
23 23
24#if ENABLE_FEATURE_AR_CREATE 24#if ENABLE_FEATURE_AR_CREATE
@@ -179,17 +179,17 @@ static void FAST_FUNC header_verbose_list_ar(const file_header_t *file_header)
179 ); 179 );
180} 180}
181 181
182#define AR_OPT_VERBOSE (1 << 0) 182#define AR_OPT_VERBOSE (1 << 0)
183#define AR_OPT_PRESERVE_DATE (1 << 1) 183#define AR_OPT_PRESERVE_DATE (1 << 1)
184/* "ar r" implies create, but warns about it. c suppresses warning. 184/* "ar r" implies create, but warns about it. c suppresses warning.
185 * bbox accepts but ignores it: */ 185 * bbox accepts but ignores it: */
186#define AR_OPT_CREATE (1 << 2) 186#define AR_OPT_CREATE (1 << 2)
187 187
188#define AR_CMD_PRINT (1 << 3) 188#define AR_CMD_PRINT (1 << 3)
189#define FIRST_CMD AR_CMD_PRINT 189#define FIRST_CMD AR_CMD_PRINT
190#define AR_CMD_LIST (1 << 4) 190#define AR_CMD_LIST (1 << 4)
191#define AR_CMD_EXTRACT (1 << 5) 191#define AR_CMD_EXTRACT (1 << 5)
192#define AR_CMD_INSERT (1 << 6) 192#define AR_CMD_INSERT (1 << 6)
193 193
194int ar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 194int ar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
195int ar_main(int argc UNUSED_PARAM, char **argv) 195int ar_main(int argc UNUSED_PARAM, char **argv)
diff --git a/archival/bbunzip.c b/archival/bbunzip.c
index a195434e4..0f89443e0 100644
--- a/archival/bbunzip.c
+++ b/archival/bbunzip.c
@@ -5,7 +5,7 @@
5 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
6 */ 6 */
7#include "libbb.h" 7#include "libbb.h"
8#include "unarchive.h" 8#include "archive.h"
9 9
10enum { 10enum {
11 OPT_STDOUT = 1 << 0, 11 OPT_STDOUT = 1 << 0,
diff --git a/archival/bzip2.c b/archival/bzip2.c
index fdb8b9306..ab08ffc1a 100644
--- a/archival/bzip2.c
+++ b/archival/bzip2.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "libbb.h" 10#include "libbb.h"
11#include "unarchive.h" 11#include "archive.h"
12 12
13#define CONFIG_BZIP2_FEATURE_SPEED 1 13#define CONFIG_BZIP2_FEATURE_SPEED 1
14 14
@@ -33,14 +33,14 @@
33/* Takes ~300 bytes, detects corruption caused by bad RAM etc */ 33/* Takes ~300 bytes, detects corruption caused by bad RAM etc */
34#define BZ_LIGHT_DEBUG 0 34#define BZ_LIGHT_DEBUG 0
35 35
36#include "bz/bzlib.h" 36#include "libarchive/bz/bzlib.h"
37 37
38#include "bz/bzlib_private.h" 38#include "libarchive/bz/bzlib_private.h"
39 39
40#include "bz/blocksort.c" 40#include "libarchive/bz/blocksort.c"
41#include "bz/bzlib.c" 41#include "libarchive/bz/bzlib.c"
42#include "bz/compress.c" 42#include "libarchive/bz/compress.c"
43#include "bz/huffman.c" 43#include "libarchive/bz/huffman.c"
44 44
45/* No point in being shy and having very small buffer here. 45/* No point in being shy and having very small buffer here.
46 * bzip2 internal buffers are much bigger anyway, hundreds of kbytes. 46 * bzip2 internal buffers are much bigger anyway, hundreds of kbytes.
@@ -128,10 +128,12 @@ IF_DESKTOP(long long) int FAST_FUNC compressStream(unpack_info_t *info UNUSED_PA
128 break; 128 break;
129 } 129 }
130 130
131#if ENABLE_FEATURE_CLEAN_UP 131 /* Can't be conditional on ENABLE_FEATURE_CLEAN_UP -
132 * we are called repeatedly
133 */
132 BZ2_bzCompressEnd(strm); 134 BZ2_bzCompressEnd(strm);
133 free(iobuf); 135 free(iobuf);
134#endif 136
135 return total; 137 return total;
136} 138}
137 139
diff --git a/archival/cpio.c b/archival/cpio.c
index a2d74dc79..c746a71fa 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -12,7 +12,37 @@
12 * 12 *
13 */ 13 */
14#include "libbb.h" 14#include "libbb.h"
15#include "unarchive.h" 15#include "archive.h"
16
17//usage:#define cpio_trivial_usage
18//usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]")
19//usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]")
20//usage: " [EXTR_FILE]..."
21//usage:#define cpio_full_usage "\n\n"
22//usage: "Extract or list files from a cpio archive"
23//usage: IF_FEATURE_CPIO_O(", or"
24//usage: "\ncreate an archive" IF_FEATURE_CPIO_P(" (-o) or copy files (-p)")
25//usage: " using file list on stdin"
26//usage: )
27//usage: "\n"
28//usage: "\nMain operation mode:"
29//usage: "\n -t List"
30//usage: "\n -i Extract EXTR_FILEs (or all)"
31//usage: IF_FEATURE_CPIO_O(
32//usage: "\n -o Create (requires -H newc)"
33//usage: )
34//usage: IF_FEATURE_CPIO_P(
35//usage: "\n -p DIR Copy files to DIR"
36//usage: )
37//usage: "\nOptions:"
38//usage: "\n -d Make leading directories"
39//usage: "\n -m Preserve mtime"
40//usage: "\n -v Verbose"
41//usage: "\n -u Overwrite"
42//usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file"
43//usage: IF_FEATURE_CPIO_O(
44//usage: "\n -H newc Archive format"
45//usage: )
16 46
17/* GNU cpio 2.9 --help (abridged): 47/* GNU cpio 2.9 --help (abridged):
18 48
@@ -20,7 +50,7 @@
20 -t, --list List the archive 50 -t, --list List the archive
21 -i, --extract Extract files from an archive 51 -i, --extract Extract files from an archive
22 -o, --create Create the archive 52 -o, --create Create the archive
23 -p, --pass-through Copy-pass mode [was ist das?!] 53 -p, --pass-through Copy-pass mode
24 54
25 Options valid in any mode: 55 Options valid in any mode:
26 --block-size=SIZE I/O block size = SIZE * 512 bytes 56 --block-size=SIZE I/O block size = SIZE * 512 bytes
@@ -78,27 +108,28 @@
78 --sparse Write files with blocks of zeros as sparse files 108 --sparse Write files with blocks of zeros as sparse files
79 -u, --unconditional Replace all files unconditionally 109 -u, --unconditional Replace all files unconditionally
80 */ 110 */
111
81enum { 112enum {
82 CPIO_OPT_EXTRACT = (1 << 0), 113 OPT_EXTRACT = (1 << 0),
83 CPIO_OPT_TEST = (1 << 1), 114 OPT_TEST = (1 << 1),
84 CPIO_OPT_NUL_TERMINATED = (1 << 2), 115 OPT_NUL_TERMINATED = (1 << 2),
85 CPIO_OPT_UNCONDITIONAL = (1 << 3), 116 OPT_UNCONDITIONAL = (1 << 3),
86 CPIO_OPT_VERBOSE = (1 << 4), 117 OPT_VERBOSE = (1 << 4),
87 CPIO_OPT_CREATE_LEADING_DIR = (1 << 5), 118 OPT_CREATE_LEADING_DIR = (1 << 5),
88 CPIO_OPT_PRESERVE_MTIME = (1 << 6), 119 OPT_PRESERVE_MTIME = (1 << 6),
89 CPIO_OPT_DEREF = (1 << 7), 120 OPT_DEREF = (1 << 7),
90 CPIO_OPT_FILE = (1 << 8), 121 OPT_FILE = (1 << 8),
91 OPTBIT_FILE = 8, 122 OPTBIT_FILE = 8,
92 IF_FEATURE_CPIO_O(OPTBIT_CREATE ,) 123 IF_FEATURE_CPIO_O(OPTBIT_CREATE ,)
93 IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,) 124 IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,)
94 IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,) 125 IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,)
95 IF_LONG_OPTS( OPTBIT_QUIET ,) 126 IF_LONG_OPTS( OPTBIT_QUIET ,)
96 IF_LONG_OPTS( OPTBIT_2STDOUT ,) 127 IF_LONG_OPTS( OPTBIT_2STDOUT ,)
97 CPIO_OPT_CREATE = IF_FEATURE_CPIO_O((1 << OPTBIT_CREATE )) + 0, 128 OPT_CREATE = IF_FEATURE_CPIO_O((1 << OPTBIT_CREATE )) + 0,
98 CPIO_OPT_FORMAT = IF_FEATURE_CPIO_O((1 << OPTBIT_FORMAT )) + 0, 129 OPT_FORMAT = IF_FEATURE_CPIO_O((1 << OPTBIT_FORMAT )) + 0,
99 CPIO_OPT_PASSTHROUGH = IF_FEATURE_CPIO_P((1 << OPTBIT_PASSTHROUGH)) + 0, 130 OPT_PASSTHROUGH = IF_FEATURE_CPIO_P((1 << OPTBIT_PASSTHROUGH)) + 0,
100 CPIO_OPT_QUIET = IF_LONG_OPTS( (1 << OPTBIT_QUIET )) + 0, 131 OPT_QUIET = IF_LONG_OPTS( (1 << OPTBIT_QUIET )) + 0,
101 CPIO_OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0, 132 OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0,
102}; 133};
103 134
104#define OPTION_STR "it0uvdmLF:" 135#define OPTION_STR "it0uvdmLF:"
@@ -138,7 +169,7 @@ static NOINLINE int cpio_o(void)
138 char *line; 169 char *line;
139 struct stat st; 170 struct stat st;
140 171
141 line = (option_mask32 & CPIO_OPT_NUL_TERMINATED) 172 line = (option_mask32 & OPT_NUL_TERMINATED)
142 ? bb_get_chunk_from_file(stdin, NULL) 173 ? bb_get_chunk_from_file(stdin, NULL)
143 : xmalloc_fgetline(stdin); 174 : xmalloc_fgetline(stdin);
144 175
@@ -153,7 +184,7 @@ static NOINLINE int cpio_o(void)
153 free(line); 184 free(line);
154 continue; 185 continue;
155 } 186 }
156 if ((option_mask32 & CPIO_OPT_DEREF) 187 if ((option_mask32 & OPT_DEREF)
157 ? stat(name, &st) 188 ? stat(name, &st)
158 : lstat(name, &st) 189 : lstat(name, &st)
159 ) { 190 ) {
@@ -308,28 +339,24 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
308 /* -L makes sense only with -o or -p */ 339 /* -L makes sense only with -o or -p */
309 340
310#if !ENABLE_FEATURE_CPIO_O 341#if !ENABLE_FEATURE_CPIO_O
311 /* no parameters */
312 opt_complementary = "=0";
313 opt = getopt32(argv, OPTION_STR, &cpio_filename); 342 opt = getopt32(argv, OPTION_STR, &cpio_filename);
314 argv += optind; 343 argv += optind;
315 if (opt & CPIO_OPT_FILE) { /* -F */ 344 if (opt & OPT_FILE) { /* -F */
316 xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); 345 xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
317 } 346 }
318#else 347#else
319 /* _exactly_ one parameter for -p, thus <= 1 param if -p is allowed */
320 opt_complementary = ENABLE_FEATURE_CPIO_P ? "?1" : "=0";
321 opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); 348 opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt);
322 argv += optind; 349 argv += optind;
323 if ((opt & (CPIO_OPT_FILE|CPIO_OPT_CREATE)) == CPIO_OPT_FILE) { /* -F without -o */ 350 if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */
324 xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); 351 xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
325 } 352 }
326 if (opt & CPIO_OPT_PASSTHROUGH) { 353 if (opt & OPT_PASSTHROUGH) {
327 pid_t pid; 354 pid_t pid;
328 struct fd_pair pp; 355 struct fd_pair pp;
329 356
330 if (argv[0] == NULL) 357 if (argv[0] == NULL)
331 bb_show_usage(); 358 bb_show_usage();
332 if (opt & CPIO_OPT_CREATE_LEADING_DIR) 359 if (opt & OPT_CREATE_LEADING_DIR)
333 mkdir(argv[0], 0777); 360 mkdir(argv[0], 0777);
334 /* Crude existence check: 361 /* Crude existence check:
335 * close(xopen(argv[0], O_RDONLY | O_DIRECTORY)); 362 * close(xopen(argv[0], O_RDONLY | O_DIRECTORY));
@@ -361,15 +388,15 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
361 xchdir(*argv++); 388 xchdir(*argv++);
362 close(pp.wr); 389 close(pp.wr);
363 xmove_fd(pp.rd, STDIN_FILENO); 390 xmove_fd(pp.rd, STDIN_FILENO);
364 //opt &= ~CPIO_OPT_PASSTHROUGH; 391 //opt &= ~OPT_PASSTHROUGH;
365 opt |= CPIO_OPT_EXTRACT; 392 opt |= OPT_EXTRACT;
366 goto skip; 393 goto skip;
367 } 394 }
368 /* -o */ 395 /* -o */
369 if (opt & CPIO_OPT_CREATE) { 396 if (opt & OPT_CREATE) {
370 if (cpio_fmt[0] != 'n') /* we _require_ "-H newc" */ 397 if (cpio_fmt[0] != 'n') /* we _require_ "-H newc" */
371 bb_show_usage(); 398 bb_show_usage();
372 if (opt & CPIO_OPT_FILE) { 399 if (opt & OPT_FILE) {
373 xmove_fd(xopen(cpio_filename, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO); 400 xmove_fd(xopen(cpio_filename, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
374 } 401 }
375 dump: 402 dump:
@@ -379,35 +406,35 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
379#endif 406#endif
380 407
381 /* One of either extract or test options must be given */ 408 /* One of either extract or test options must be given */
382 if ((opt & (CPIO_OPT_TEST | CPIO_OPT_EXTRACT)) == 0) { 409 if ((opt & (OPT_TEST | OPT_EXTRACT)) == 0) {
383 bb_show_usage(); 410 bb_show_usage();
384 } 411 }
385 412
386 if (opt & CPIO_OPT_TEST) { 413 if (opt & OPT_TEST) {
387 /* if both extract and test options are given, ignore extract option */ 414 /* if both extract and test options are given, ignore extract option */
388 opt &= ~CPIO_OPT_EXTRACT; 415 opt &= ~OPT_EXTRACT;
389 archive_handle->action_header = header_list; 416 archive_handle->action_header = header_list;
390 } 417 }
391 if (opt & CPIO_OPT_EXTRACT) { 418 if (opt & OPT_EXTRACT) {
392 archive_handle->action_data = data_extract_all; 419 archive_handle->action_data = data_extract_all;
393 if (opt & CPIO_OPT_2STDOUT) 420 if (opt & OPT_2STDOUT)
394 archive_handle->action_data = data_extract_to_stdout; 421 archive_handle->action_data = data_extract_to_stdout;
395 } 422 }
396 if (opt & CPIO_OPT_UNCONDITIONAL) { 423 if (opt & OPT_UNCONDITIONAL) {
397 archive_handle->ah_flags |= ARCHIVE_UNLINK_OLD; 424 archive_handle->ah_flags |= ARCHIVE_UNLINK_OLD;
398 archive_handle->ah_flags &= ~ARCHIVE_EXTRACT_NEWER; 425 archive_handle->ah_flags &= ~ARCHIVE_EXTRACT_NEWER;
399 } 426 }
400 if (opt & CPIO_OPT_VERBOSE) { 427 if (opt & OPT_VERBOSE) {
401 if (archive_handle->action_header == header_list) { 428 if (archive_handle->action_header == header_list) {
402 archive_handle->action_header = header_verbose_list; 429 archive_handle->action_header = header_verbose_list;
403 } else { 430 } else {
404 archive_handle->action_header = header_list; 431 archive_handle->action_header = header_list;
405 } 432 }
406 } 433 }
407 if (opt & CPIO_OPT_CREATE_LEADING_DIR) { 434 if (opt & OPT_CREATE_LEADING_DIR) {
408 archive_handle->ah_flags |= ARCHIVE_CREATE_LEADING_DIRS; 435 archive_handle->ah_flags |= ARCHIVE_CREATE_LEADING_DIRS;
409 } 436 }
410 if (opt & CPIO_OPT_PRESERVE_MTIME) { 437 if (opt & OPT_PRESERVE_MTIME) {
411 archive_handle->ah_flags |= ARCHIVE_RESTORE_DATE; 438 archive_handle->ah_flags |= ARCHIVE_RESTORE_DATE;
412 } 439 }
413 440
@@ -423,7 +450,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
423 continue; 450 continue;
424 451
425 if (archive_handle->cpio__blocks != (off_t)-1 452 if (archive_handle->cpio__blocks != (off_t)-1
426 && !(opt & CPIO_OPT_QUIET) 453 && !(opt & OPT_QUIET)
427 ) { 454 ) {
428 fprintf(stderr, "%"OFF_FMT"u blocks\n", archive_handle->cpio__blocks); 455 fprintf(stderr, "%"OFF_FMT"u blocks\n", archive_handle->cpio__blocks);
429 } 456 }
diff --git a/archival/dpkg.c b/archival/dpkg.c
index 508b4297b..c37ae3349 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -30,7 +30,7 @@
30 30
31#include "libbb.h" 31#include "libbb.h"
32#include <fnmatch.h> 32#include <fnmatch.h>
33#include "unarchive.h" 33#include "archive.h"
34 34
35/* note: if you vary hash_prime sizes be aware, 35/* note: if you vary hash_prime sizes be aware,
36 * 1) tweaking these will have a big effect on how much memory this program uses. 36 * 1) tweaking these will have a big effect on how much memory this program uses.
@@ -939,8 +939,8 @@ static int package_satisfies_dependency(int package, int depend_type)
939 return 0; 939 return 0;
940 940
941 switch (depend_type) { 941 switch (depend_type) {
942 case EDGE_PRE_DEPENDS: return get_status(status_num, 3) == search_name_hashtable("installed"); 942 case EDGE_PRE_DEPENDS: return get_status(status_num, 3) == search_name_hashtable("installed");
943 case EDGE_DEPENDS: return get_status(status_num, 1) == search_name_hashtable("install"); 943 case EDGE_DEPENDS: return get_status(status_num, 1) == search_name_hashtable("install");
944 } 944 }
945 return 0; 945 return 0;
946} 946}
@@ -967,7 +967,7 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count
967 conflicts[conflicts_num] = package_num; 967 conflicts[conflicts_num] = package_num;
968 conflicts_num++; 968 conflicts_num++;
969 /* add provides to conflicts list */ 969 /* add provides to conflicts list */
970 for (j = 0; j < package_hashtable[package_num]->num_of_edges; j++) { 970 for (j = 0; j < package_hashtable[package_num]->num_of_edges; j++) {
971 if (package_hashtable[package_num]->edge[j]->type == EDGE_PROVIDES) { 971 if (package_hashtable[package_num]->edge[j]->type == EDGE_PROVIDES) {
972 const int conflicts_package_num = search_package_hashtable( 972 const int conflicts_package_num = search_package_hashtable(
973 package_hashtable[package_num]->edge[j]->name, 973 package_hashtable[package_num]->edge[j]->name,
@@ -1067,12 +1067,13 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count
1067 1067
1068 if (package_edge->type == EDGE_OR_PRE_DEPENDS 1068 if (package_edge->type == EDGE_OR_PRE_DEPENDS
1069 || package_edge->type == EDGE_OR_DEPENDS 1069 || package_edge->type == EDGE_OR_DEPENDS
1070 ) { /* start an EDGE_OR_ list */ 1070 ) {
1071 /* start an EDGE_OR_ list */
1071 number_of_alternatives = package_edge->version; 1072 number_of_alternatives = package_edge->version;
1072 root_of_alternatives = package_edge; 1073 root_of_alternatives = package_edge;
1073 continue; 1074 continue;
1074 } 1075 }
1075 if (number_of_alternatives == 0) { /* not in the middle of an EDGE_OR_ list */ 1076 if (number_of_alternatives == 0) { /* not in the middle of an EDGE_OR_ list */
1076 number_of_alternatives = 1; 1077 number_of_alternatives = 1;
1077 root_of_alternatives = NULL; 1078 root_of_alternatives = NULL;
1078 } 1079 }
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c
index 4c627e890..aee7b4cf5 100644
--- a/archival/dpkg_deb.c
+++ b/archival/dpkg_deb.c
@@ -5,13 +5,13 @@
5 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
6 */ 6 */
7#include "libbb.h" 7#include "libbb.h"
8#include "unarchive.h" 8#include "archive.h"
9 9
10#define DPKG_DEB_OPT_CONTENTS 1 10#define DPKG_DEB_OPT_CONTENTS 1
11#define DPKG_DEB_OPT_CONTROL 2 11#define DPKG_DEB_OPT_CONTROL 2
12#define DPKG_DEB_OPT_FIELD 4 12#define DPKG_DEB_OPT_FIELD 4
13#define DPKG_DEB_OPT_EXTRACT 8 13#define DPKG_DEB_OPT_EXTRACT 8
14#define DPKG_DEB_OPT_EXTRACT_VERBOSE 16 14#define DPKG_DEB_OPT_EXTRACT_VERBOSE 16
15 15
16int dpkg_deb_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 16int dpkg_deb_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
17int dpkg_deb_main(int argc, char **argv) 17int dpkg_deb_main(int argc, char **argv)
diff --git a/archival/gzip.c b/archival/gzip.c
index b573ed6ab..feeddf58f 100644
--- a/archival/gzip.c
+++ b/archival/gzip.c
@@ -40,7 +40,7 @@ aa: 85.1% -- replaced with aa.gz
40*/ 40*/
41 41
42#include "libbb.h" 42#include "libbb.h"
43#include "unarchive.h" 43#include "archive.h"
44 44
45 45
46/* =========================================================================== 46/* ===========================================================================
diff --git a/archival/libunarchive/Kbuild.src b/archival/libarchive/Kbuild.src
index e92b4aad2..b0bc4e5aa 100644
--- a/archival/libunarchive/Kbuild.src
+++ b/archival/libarchive/Kbuild.src
@@ -48,6 +48,8 @@ lib-$(CONFIG_RPM) += open_transformer.o decompress_unzip.o
48lib-$(CONFIG_TAR) += get_header_tar.o 48lib-$(CONFIG_TAR) += get_header_tar.o
49lib-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o 49lib-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o
50lib-$(CONFIG_UNZIP) += decompress_unzip.o 50lib-$(CONFIG_UNZIP) += decompress_unzip.o
51lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o
52lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o
51lib-$(CONFIG_FEATURE_SEAMLESS_Z) += open_transformer.o decompress_uncompress.o 53lib-$(CONFIG_FEATURE_SEAMLESS_Z) += open_transformer.o decompress_uncompress.o
52lib-$(CONFIG_FEATURE_SEAMLESS_GZ) += open_transformer.o decompress_unzip.o get_header_tar_gz.o 54lib-$(CONFIG_FEATURE_SEAMLESS_GZ) += open_transformer.o decompress_unzip.o get_header_tar_gz.o
53lib-$(CONFIG_FEATURE_SEAMLESS_BZ2) += open_transformer.o decompress_bunzip2.o get_header_tar_bz2.o 55lib-$(CONFIG_FEATURE_SEAMLESS_BZ2) += open_transformer.o decompress_bunzip2.o get_header_tar_bz2.o
diff --git a/archival/bz/LICENSE b/archival/libarchive/bz/LICENSE
index da4346520..da4346520 100644
--- a/archival/bz/LICENSE
+++ b/archival/libarchive/bz/LICENSE
diff --git a/archival/bz/README b/archival/libarchive/bz/README
index fffd47b8a..fffd47b8a 100644
--- a/archival/bz/README
+++ b/archival/libarchive/bz/README
diff --git a/archival/bz/blocksort.c b/archival/libarchive/bz/blocksort.c
index f70c3701d..f70c3701d 100644
--- a/archival/bz/blocksort.c
+++ b/archival/libarchive/bz/blocksort.c
diff --git a/archival/bz/bzlib.c b/archival/libarchive/bz/bzlib.c
index 834179403..5f7db747a 100644
--- a/archival/bz/bzlib.c
+++ b/archival/libarchive/bz/bzlib.c
@@ -28,7 +28,7 @@ in the file LICENSE.
28 * 0.9.0a/b -- no changes in this file. 28 * 0.9.0a/b -- no changes in this file.
29 * 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress(). 29 * 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress().
30 * fixed bzWrite/bzRead to ignore zero-length requests. 30 * fixed bzWrite/bzRead to ignore zero-length requests.
31 * fixed bzread to correctly handle read requests after EOF. 31 * fixed bzread to correctly handle read requests after EOF.
32 * wrong parameter order in call to bzDecompressInit in 32 * wrong parameter order in call to bzDecompressInit in
33 * bzBuffToBuffDecompress. Fixed. 33 * bzBuffToBuffDecompress. Fixed.
34 */ 34 */
@@ -361,7 +361,6 @@ int BZ2_bzCompress(bz_stream *strm, int action)
361 361
362 362
363/*---------------------------------------------------*/ 363/*---------------------------------------------------*/
364#if ENABLE_FEATURE_CLEAN_UP
365static 364static
366void BZ2_bzCompressEnd(bz_stream *strm) 365void BZ2_bzCompressEnd(bz_stream *strm)
367{ 366{
@@ -372,9 +371,8 @@ void BZ2_bzCompressEnd(bz_stream *strm)
372 free(s->arr2); 371 free(s->arr2);
373 free(s->ftab); 372 free(s->ftab);
374 free(s->crc32table); 373 free(s->crc32table);
375 free(strm->state); 374 free(s);
376} 375}
377#endif
378 376
379 377
380/*---------------------------------------------------*/ 378/*---------------------------------------------------*/
diff --git a/archival/bz/bzlib.h b/archival/libarchive/bz/bzlib.h
index 1bb811c4a..1bb811c4a 100644
--- a/archival/bz/bzlib.h
+++ b/archival/libarchive/bz/bzlib.h
diff --git a/archival/bz/bzlib_private.h b/archival/libarchive/bz/bzlib_private.h
index 6430ce407..6430ce407 100644
--- a/archival/bz/bzlib_private.h
+++ b/archival/libarchive/bz/bzlib_private.h
diff --git a/archival/bz/compress.c b/archival/libarchive/bz/compress.c
index b9b0949a9..6f1c70a08 100644
--- a/archival/bz/compress.c
+++ b/archival/libarchive/bz/compress.c
@@ -134,15 +134,14 @@ void generateMTFValues(EState* s)
134 * holds the original block data. 134 * holds the original block data.
135 * 135 *
136 * The first thing to do is generate the MTF values, 136 * The first thing to do is generate the MTF values,
137 * and put them in 137 * and put them in ((uint16_t*)s->arr1)[0 .. s->nblock-1].
138 * ((uint16_t*)s->arr1)[0 .. s->nblock-1]. 138 *
139 * Because there are strictly fewer or equal MTF values 139 * Because there are strictly fewer or equal MTF values
140 * than block values, ptr values in this area are overwritten 140 * than block values, ptr values in this area are overwritten
141 * with MTF values only when they are no longer needed. 141 * with MTF values only when they are no longer needed.
142 * 142 *
143 * The final compressed bitstream is generated into the 143 * The final compressed bitstream is generated into the
144 * area starting at 144 * area starting at &((uint8_t*)s->arr2)[s->nblock]
145 * &((uint8_t*)s->arr2)[s->nblock]
146 * 145 *
147 * These storage aliases are set up in bzCompressInit(), 146 * These storage aliases are set up in bzCompressInit(),
148 * except for the last one, which is arranged in 147 * except for the last one, which is arranged in
@@ -459,7 +458,7 @@ void sendMTFValues(EState* s)
459 } 458 }
460 459
461 AssertH(nGroups < 8, 3002); 460 AssertH(nGroups < 8, 3002);
462 AssertH(nSelectors < 32768 && nSelectors <= (2 + (900000 / BZ_G_SIZE)), 3003); 461 AssertH(nSelectors < 32768 && nSelectors <= (2 + (900000 / BZ_G_SIZE)), 3003);
463 462
464 /*--- Compute MTF values for the selectors. ---*/ 463 /*--- Compute MTF values for the selectors. ---*/
465 { 464 {
diff --git a/archival/bz/huffman.c b/archival/libarchive/bz/huffman.c
index 676b1af66..676b1af66 100644
--- a/archival/bz/huffman.c
+++ b/archival/libarchive/bz/huffman.c
diff --git a/archival/libunarchive/data_align.c b/archival/libarchive/data_align.c
index 4e21a36b3..2e56fa8ff 100644
--- a/archival/libunarchive/data_align.c
+++ b/archival/libarchive/data_align.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9void FAST_FUNC data_align(archive_handle_t *archive_handle, unsigned boundary) 9void FAST_FUNC data_align(archive_handle_t *archive_handle, unsigned boundary)
10{ 10{
diff --git a/archival/libunarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c
index 5fb1ab2ae..1b25c8bd6 100644
--- a/archival/libunarchive/data_extract_all.c
+++ b/archival/libarchive/data_extract_all.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) 9void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
10{ 10{
diff --git a/archival/libunarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c
index b54f7f215..2bbab7641 100644
--- a/archival/libunarchive/data_extract_to_command.c
+++ b/archival/libarchive/data_extract_to_command.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9enum { 9enum {
10 //TAR_FILETYPE, 10 //TAR_FILETYPE,
diff --git a/archival/libunarchive/data_extract_to_stdout.c b/archival/libarchive/data_extract_to_stdout.c
index ce0713ac4..91f3f3539 100644
--- a/archival/libunarchive/data_extract_to_stdout.c
+++ b/archival/libarchive/data_extract_to_stdout.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9void FAST_FUNC data_extract_to_stdout(archive_handle_t *archive_handle) 9void FAST_FUNC data_extract_to_stdout(archive_handle_t *archive_handle)
10{ 10{
diff --git a/archival/libunarchive/data_skip.c b/archival/libarchive/data_skip.c
index 06b74399d..a055424e2 100644
--- a/archival/libunarchive/data_skip.c
+++ b/archival/libarchive/data_skip.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9void FAST_FUNC data_skip(archive_handle_t *archive_handle) 9void FAST_FUNC data_skip(archive_handle_t *archive_handle)
10{ 10{
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c
index 22015683c..4e46e6849 100644
--- a/archival/libunarchive/decompress_bunzip2.c
+++ b/archival/libarchive/decompress_bunzip2.c
@@ -16,10 +16,21 @@
16 function, and various other tweaks. In (limited) tests, approximately 16 function, and various other tweaks. In (limited) tests, approximately
17 20% faster than bzcat on x86 and about 10% faster on arm. 17 20% faster than bzcat on x86 and about 10% faster on arm.
18 18
19 Note that about 2/3 of the time is spent in read_unzip() reversing 19 Note that about 2/3 of the time is spent in read_bunzip() reversing
20 the Burrows-Wheeler transformation. Much of that time is delay 20 the Burrows-Wheeler transformation. Much of that time is delay
21 resulting from cache misses. 21 resulting from cache misses.
22 22
23 (2010 update by vda: profiled "bzcat <84mbyte.bz2 >/dev/null"
24 on x86-64 CPU with L2 > 1M: get_next_block is hotter than read_bunzip:
25 %time seconds calls function
26 71.01 12.69 444 get_next_block
27 28.65 5.12 93065 read_bunzip
28 00.22 0.04 7736490 get_bits
29 00.11 0.02 47 dealloc_bunzip
30 00.00 0.00 93018 full_write
31 ...)
32
33
23 I would ask that anyone benefiting from this work, especially those 34 I would ask that anyone benefiting from this work, especially those
24 using it in commercial products, consider making a donation to my local 35 using it in commercial products, consider making a donation to my local
25 non-profit hospice organization (www.hospiceacadiana.com) in the name of 36 non-profit hospice organization (www.hospiceacadiana.com) in the name of
@@ -29,7 +40,7 @@
29 */ 40 */
30 41
31#include "libbb.h" 42#include "libbb.h"
32#include "unarchive.h" 43#include "archive.h"
33 44
34/* Constants for Huffman coding */ 45/* Constants for Huffman coding */
35#define MAX_GROUPS 6 46#define MAX_GROUPS 6
@@ -70,38 +81,41 @@ struct bunzip_data {
70 /* I/O tracking data (file handles, buffers, positions, etc.) */ 81 /* I/O tracking data (file handles, buffers, positions, etc.) */
71 unsigned inbufBitCount, inbufBits; 82 unsigned inbufBitCount, inbufBits;
72 int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/; 83 int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/;
73 unsigned char *inbuf /*,*outbuf*/; 84 uint8_t *inbuf /*,*outbuf*/;
74 85
75 /* State for interrupting output loop */ 86 /* State for interrupting output loop */
76 int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent; 87 int writeCopies, writePos, writeRunCountdown, writeCount;
88 int writeCurrent; /* actually a uint8_t */
77 89
78 /* The CRC values stored in the block header and calculated from the data */ 90 /* The CRC values stored in the block header and calculated from the data */
79 uint32_t headerCRC, totalCRC, writeCRC; 91 uint32_t headerCRC, totalCRC, writeCRC;
80 92
81 /* Intermediate buffer and its size (in bytes) */ 93 /* Intermediate buffer and its size (in bytes) */
82 unsigned *dbuf, dbufSize; 94 uint32_t *dbuf;
95 unsigned dbufSize;
83 96
84 /* For I/O error handling */ 97 /* For I/O error handling */
85 jmp_buf jmpbuf; 98 jmp_buf jmpbuf;
86 99
87 /* Big things go last (register-relative addressing can be larger for big offsets) */ 100 /* Big things go last (register-relative addressing can be larger for big offsets) */
88 uint32_t crc32Table[256]; 101 uint32_t crc32Table[256];
89 unsigned char selectors[32768]; /* nSelectors=15 bits */ 102 uint8_t selectors[32768]; /* nSelectors=15 bits */
90 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ 103 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
91}; 104};
92/* typedef struct bunzip_data bunzip_data; -- done in .h file */ 105/* typedef struct bunzip_data bunzip_data; -- done in .h file */
93 106
94 107
95/* Return the next nnn bits of input. All reads from the compressed input 108/* Return the next nnn bits of input. All reads from the compressed input
96 are done through this function. All reads are big endian */ 109 are done through this function. All reads are big endian */
97
98static unsigned get_bits(bunzip_data *bd, int bits_wanted) 110static unsigned get_bits(bunzip_data *bd, int bits_wanted)
99{ 111{
100 unsigned bits = 0; 112 unsigned bits = 0;
113 /* Cache bd->inbufBitCount in a CPU register (hopefully): */
114 int bit_count = bd->inbufBitCount;
101 115
102 /* If we need to get more data from the byte buffer, do so. (Loop getting 116 /* If we need to get more data from the byte buffer, do so. (Loop getting
103 one byte at a time to enforce endianness and avoid unaligned access.) */ 117 one byte at a time to enforce endianness and avoid unaligned access.) */
104 while ((int)(bd->inbufBitCount) < bits_wanted) { 118 while (bit_count < bits_wanted) {
105 119
106 /* If we need to read more data from file into byte buffer, do so */ 120 /* If we need to read more data from file into byte buffer, do so */
107 if (bd->inbufPos == bd->inbufCount) { 121 if (bd->inbufPos == bd->inbufCount) {
@@ -113,41 +127,47 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted)
113 } 127 }
114 128
115 /* Avoid 32-bit overflow (dump bit buffer to top of output) */ 129 /* Avoid 32-bit overflow (dump bit buffer to top of output) */
116 if (bd->inbufBitCount >= 24) { 130 if (bit_count >= 24) {
117 bits = bd->inbufBits & ((1 << bd->inbufBitCount) - 1); 131 bits = bd->inbufBits & ((1 << bit_count) - 1);
118 bits_wanted -= bd->inbufBitCount; 132 bits_wanted -= bit_count;
119 bits <<= bits_wanted; 133 bits <<= bits_wanted;
120 bd->inbufBitCount = 0; 134 bit_count = 0;
121 } 135 }
122 136
123 /* Grab next 8 bits of input from buffer. */ 137 /* Grab next 8 bits of input from buffer. */
124 bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++]; 138 bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++];
125 bd->inbufBitCount += 8; 139 bit_count += 8;
126 } 140 }
127 141
128 /* Calculate result */ 142 /* Calculate result */
129 bd->inbufBitCount -= bits_wanted; 143 bit_count -= bits_wanted;
130 bits |= (bd->inbufBits >> bd->inbufBitCount) & ((1 << bits_wanted) - 1); 144 bd->inbufBitCount = bit_count;
145 bits |= (bd->inbufBits >> bit_count) & ((1 << bits_wanted) - 1);
131 146
132 return bits; 147 return bits;
133} 148}
134 149
135/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */ 150/* Unpacks the next block and sets up for the inverse Burrows-Wheeler step. */
136static int get_next_block(bunzip_data *bd) 151static int get_next_block(bunzip_data *bd)
137{ 152{
138 struct group_data *hufGroup; 153 struct group_data *hufGroup;
139 int dbufCount, nextSym, dbufSize, groupCount, *base, *limit, selector, 154 int dbufCount, dbufSize, groupCount, *base, *limit, selector,
140 i, j, k, t, runPos, symCount, symTotal, nSelectors, byteCount[256]; 155 i, j, t, runPos, symCount, symTotal, nSelectors, byteCount[256];
141 unsigned char uc, symToByte[256], mtfSymbol[256], *selectors; 156 int runCnt = runCnt; /* for compiler */
142 unsigned *dbuf, origPtr; 157 uint8_t uc, symToByte[256], mtfSymbol[256], *selectors;
158 uint32_t *dbuf;
159 unsigned origPtr;
143 160
144 dbuf = bd->dbuf; 161 dbuf = bd->dbuf;
145 dbufSize = bd->dbufSize; 162 dbufSize = bd->dbufSize;
146 selectors = bd->selectors; 163 selectors = bd->selectors;
147 164
165/* In bbox, we are ok with aborting through setjmp which is set up in start_bunzip */
166#if 0
148 /* Reset longjmp I/O error handling */ 167 /* Reset longjmp I/O error handling */
149 i = setjmp(bd->jmpbuf); 168 i = setjmp(bd->jmpbuf);
150 if (i) return i; 169 if (i) return i;
170#endif
151 171
152 /* Read in header signature and CRC, then validate signature. 172 /* Read in header signature and CRC, then validate signature.
153 (last block signature means CRC is for whole file, return now) */ 173 (last block signature means CRC is for whole file, return now) */
@@ -169,16 +189,23 @@ static int get_next_block(bunzip_data *bd)
169 symbols to deal with, and writes a sparse bitfield indicating which 189 symbols to deal with, and writes a sparse bitfield indicating which
170 values were present. We make a translation table to convert the symbols 190 values were present. We make a translation table to convert the symbols
171 back to the corresponding bytes. */ 191 back to the corresponding bytes. */
172 t = get_bits(bd, 16);
173 symTotal = 0; 192 symTotal = 0;
174 for (i = 0; i < 16; i++) { 193 i = 0;
175 if (t & (1 << (15-i))) { 194 t = get_bits(bd, 16);
176 k = get_bits(bd, 16); 195 do {
177 for (j = 0; j < 16; j++) 196 if (t & (1 << 15)) {
178 if (k & (1 << (15-j))) 197 unsigned inner_map = get_bits(bd, 16);
179 symToByte[symTotal++] = (16*i) + j; 198 do {
199 if (inner_map & (1 << 15))
200 symToByte[symTotal++] = i;
201 inner_map <<= 1;
202 i++;
203 } while (i & 15);
204 i -= 16;
180 } 205 }
181 } 206 t <<= 1;
207 i += 16;
208 } while (i < 256);
182 209
183 /* How many different Huffman coding groups does this block use? */ 210 /* How many different Huffman coding groups does this block use? */
184 groupCount = get_bits(bd, 3); 211 groupCount = get_bits(bd, 3);
@@ -189,57 +216,63 @@ static int get_next_block(bunzip_data *bd)
189 group. Read in the group selector list, which is stored as MTF encoded 216 group. Read in the group selector list, which is stored as MTF encoded
190 bit runs. (MTF=Move To Front, as each value is used it's moved to the 217 bit runs. (MTF=Move To Front, as each value is used it's moved to the
191 start of the list.) */ 218 start of the list.) */
219 for (i = 0; i < groupCount; i++)
220 mtfSymbol[i] = i;
192 nSelectors = get_bits(bd, 15); 221 nSelectors = get_bits(bd, 15);
193 if (!nSelectors) return RETVAL_DATA_ERROR; 222 if (!nSelectors)
194 for (i = 0; i < groupCount; i++) mtfSymbol[i] = i; 223 return RETVAL_DATA_ERROR;
195 for (i = 0; i < nSelectors; i++) { 224 for (i = 0; i < nSelectors; i++) {
196 225 uint8_t tmp_byte;
197 /* Get next value */ 226 /* Get next value */
198 for (j = 0; get_bits(bd, 1); j++) 227 int n = 0;
199 if (j >= groupCount) return RETVAL_DATA_ERROR; 228 while (get_bits(bd, 1)) {
200 229 if (n >= groupCount) return RETVAL_DATA_ERROR;
230 n++;
231 }
201 /* Decode MTF to get the next selector */ 232 /* Decode MTF to get the next selector */
202 uc = mtfSymbol[j]; 233 tmp_byte = mtfSymbol[n];
203 for (;j;j--) mtfSymbol[j] = mtfSymbol[j-1]; 234 while (--n >= 0)
204 mtfSymbol[0] = selectors[i] = uc; 235 mtfSymbol[n + 1] = mtfSymbol[n];
236 mtfSymbol[0] = selectors[i] = tmp_byte;
205 } 237 }
206 238
207 /* Read the Huffman coding tables for each group, which code for symTotal 239 /* Read the Huffman coding tables for each group, which code for symTotal
208 literal symbols, plus two run symbols (RUNA, RUNB) */ 240 literal symbols, plus two run symbols (RUNA, RUNB) */
209 symCount = symTotal + 2; 241 symCount = symTotal + 2;
210 for (j = 0; j < groupCount; j++) { 242 for (j = 0; j < groupCount; j++) {
211 unsigned char length[MAX_SYMBOLS]; 243 uint8_t length[MAX_SYMBOLS];
212 /* 8 bits is ALMOST enough for temp[], see below */ 244 /* 8 bits is ALMOST enough for temp[], see below */
213 unsigned temp[MAX_HUFCODE_BITS+1]; 245 unsigned temp[MAX_HUFCODE_BITS+1];
214 int minLen, maxLen, pp; 246 int minLen, maxLen, pp, len_m1;
215 247
216 /* Read Huffman code lengths for each symbol. They're stored in 248 /* Read Huffman code lengths for each symbol. They're stored in
217 a way similar to mtf; record a starting value for the first symbol, 249 a way similar to mtf; record a starting value for the first symbol,
218 and an offset from the previous value for everys symbol after that. 250 and an offset from the previous value for every symbol after that.
219 (Subtracting 1 before the loop and then adding it back at the end is 251 (Subtracting 1 before the loop and then adding it back at the end is
220 an optimization that makes the test inside the loop simpler: symbol 252 an optimization that makes the test inside the loop simpler: symbol
221 length 0 becomes negative, so an unsigned inequality catches it.) */ 253 length 0 becomes negative, so an unsigned inequality catches it.) */
222 t = get_bits(bd, 5) - 1; 254 len_m1 = get_bits(bd, 5) - 1;
223 for (i = 0; i < symCount; i++) { 255 for (i = 0; i < symCount; i++) {
224 for (;;) { 256 for (;;) {
225 if ((unsigned)t > (MAX_HUFCODE_BITS-1)) 257 int two_bits;
258 if ((unsigned)len_m1 > (MAX_HUFCODE_BITS-1))
226 return RETVAL_DATA_ERROR; 259 return RETVAL_DATA_ERROR;
227 260
228 /* If first bit is 0, stop. Else second bit indicates whether 261 /* If first bit is 0, stop. Else second bit indicates whether
229 to increment or decrement the value. Optimization: grab 2 262 to increment or decrement the value. Optimization: grab 2
230 bits and unget the second if the first was 0. */ 263 bits and unget the second if the first was 0. */
231 k = get_bits(bd, 2); 264 two_bits = get_bits(bd, 2);
232 if (k < 2) { 265 if (two_bits < 2) {
233 bd->inbufBitCount++; 266 bd->inbufBitCount++;
234 break; 267 break;
235 } 268 }
236 269
237 /* Add one if second bit 1, else subtract 1. Avoids if/else */ 270 /* Add one if second bit 1, else subtract 1. Avoids if/else */
238 t += (((k+1) & 2) - 1); 271 len_m1 += (((two_bits+1) & 2) - 1);
239 } 272 }
240 273
241 /* Correct for the initial -1, to get the final symbol length */ 274 /* Correct for the initial -1, to get the final symbol length */
242 length[i] = t + 1; 275 length[i] = len_m1 + 1;
243 } 276 }
244 277
245 /* Find largest and smallest lengths in this group */ 278 /* Find largest and smallest lengths in this group */
@@ -265,17 +298,18 @@ static int get_next_block(bunzip_data *bd)
265 298
266 /* Note that minLen can't be smaller than 1, so we adjust the base 299 /* Note that minLen can't be smaller than 1, so we adjust the base
267 and limit array pointers so we're not always wasting the first 300 and limit array pointers so we're not always wasting the first
268 entry. We do this again when using them (during symbol decoding).*/ 301 entry. We do this again when using them (during symbol decoding). */
269 base = hufGroup->base - 1; 302 base = hufGroup->base - 1;
270 limit = hufGroup->limit - 1; 303 limit = hufGroup->limit - 1;
271 304
272 /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */ 305 /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */
273 pp = 0; 306 pp = 0;
274 for (i = minLen; i <= maxLen; i++) { 307 for (i = minLen; i <= maxLen; i++) {
308 int k;
275 temp[i] = limit[i] = 0; 309 temp[i] = limit[i] = 0;
276 for (t = 0; t < symCount; t++) 310 for (k = 0; k < symCount; k++)
277 if (length[t] == i) 311 if (length[k] == i)
278 hufGroup->permute[pp++] = t; 312 hufGroup->permute[pp++] = k;
279 } 313 }
280 314
281 /* Count symbols coded for at each bit length */ 315 /* Count symbols coded for at each bit length */
@@ -288,8 +322,10 @@ static int get_next_block(bunzip_data *bd)
288 * base[] (number of symbols to ignore at each bit length, which is 322 * base[] (number of symbols to ignore at each bit length, which is
289 * limit minus the cumulative count of symbols coded for already). */ 323 * limit minus the cumulative count of symbols coded for already). */
290 pp = t = 0; 324 pp = t = 0;
291 for (i = minLen; i < maxLen; i++) { 325 for (i = minLen; i < maxLen;) {
292 pp += temp[i]; 326 unsigned temp_i = temp[i];
327
328 pp += temp_i;
293 329
294 /* We read the largest possible symbol size and then unget bits 330 /* We read the largest possible symbol size and then unget bits
295 after determining how many we need, and those extra bits could 331 after determining how many we need, and those extra bits could
@@ -299,11 +335,11 @@ static int get_next_block(bunzip_data *bd)
299 don't affect the value>limit[length] comparison. */ 335 don't affect the value>limit[length] comparison. */
300 limit[i] = (pp << (maxLen - i)) - 1; 336 limit[i] = (pp << (maxLen - i)) - 1;
301 pp <<= 1; 337 pp <<= 1;
302 t += temp[i]; 338 t += temp_i;
303 base[i+1] = pp - t; 339 base[++i] = pp - t;
304 } 340 }
305 limit[maxLen+1] = INT_MAX; /* Sentinel value for reading next sym. */
306 limit[maxLen] = pp + temp[maxLen] - 1; 341 limit[maxLen] = pp + temp[maxLen] - 1;
342 limit[maxLen+1] = INT_MAX; /* Sentinel value for reading next sym. */
307 base[minLen] = 0; 343 base[minLen] = 0;
308 } 344 }
309 345
@@ -312,16 +348,17 @@ static int get_next_block(bunzip_data *bd)
312 and run length encoding, saving the result into dbuf[dbufCount++] = uc */ 348 and run length encoding, saving the result into dbuf[dbufCount++] = uc */
313 349
314 /* Initialize symbol occurrence counters and symbol Move To Front table */ 350 /* Initialize symbol occurrence counters and symbol Move To Front table */
315 memset(byteCount, 0, sizeof(byteCount)); /* smaller, maybe slower? */ 351 /*memset(byteCount, 0, sizeof(byteCount)); - smaller, but slower */
316 for (i = 0; i < 256; i++) { 352 for (i = 0; i < 256; i++) {
317 //byteCount[i] = 0; 353 byteCount[i] = 0;
318 mtfSymbol[i] = (unsigned char)i; 354 mtfSymbol[i] = (uint8_t)i;
319 } 355 }
320 356
321 /* Loop through compressed symbols. */ 357 /* Loop through compressed symbols. */
322 358
323 runPos = dbufCount = selector = 0; 359 runPos = dbufCount = selector = 0;
324 for (;;) { 360 for (;;) {
361 int nextSym;
325 362
326 /* Fetch next Huffman coding group from list. */ 363 /* Fetch next Huffman coding group from list. */
327 symCount = GROUP_SIZE - 1; 364 symCount = GROUP_SIZE - 1;
@@ -329,44 +366,49 @@ static int get_next_block(bunzip_data *bd)
329 hufGroup = bd->groups + selectors[selector++]; 366 hufGroup = bd->groups + selectors[selector++];
330 base = hufGroup->base - 1; 367 base = hufGroup->base - 1;
331 limit = hufGroup->limit - 1; 368 limit = hufGroup->limit - 1;
332 continue_this_group:
333 369
370 continue_this_group:
334 /* Read next Huffman-coded symbol. */ 371 /* Read next Huffman-coded symbol. */
335 372
336 /* Note: It is far cheaper to read maxLen bits and back up than it is 373 /* Note: It is far cheaper to read maxLen bits and back up than it is
337 to read minLen bits and then an additional bit at a time, testing 374 to read minLen bits and then add additional bit at a time, testing
338 as we go. Because there is a trailing last block (with file CRC), 375 as we go. Because there is a trailing last block (with file CRC),
339 there is no danger of the overread causing an unexpected EOF for a 376 there is no danger of the overread causing an unexpected EOF for a
340 valid compressed file. As a further optimization, we do the read 377 valid compressed file.
341 inline (falling back to a call to get_bits if the buffer runs
342 dry). The following (up to got_huff_bits:) is equivalent to
343 j = get_bits(bd, hufGroup->maxLen);
344 */ 378 */
345 while ((int)(bd->inbufBitCount) < hufGroup->maxLen) { 379 if (1) {
346 if (bd->inbufPos == bd->inbufCount) { 380 /* As a further optimization, we do the read inline
347 j = get_bits(bd, hufGroup->maxLen); 381 (falling back to a call to get_bits if the buffer runs dry).
348 goto got_huff_bits; 382 */
349 } 383 int new_cnt;
350 bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++]; 384 while ((new_cnt = bd->inbufBitCount - hufGroup->maxLen) < 0) {
351 bd->inbufBitCount += 8; 385 /* bd->inbufBitCount < hufGroup->maxLen */
352 }; 386 if (bd->inbufPos == bd->inbufCount) {
353 bd->inbufBitCount -= hufGroup->maxLen; 387 nextSym = get_bits(bd, hufGroup->maxLen);
354 j = (bd->inbufBits >> bd->inbufBitCount) & ((1 << hufGroup->maxLen) - 1); 388 goto got_huff_bits;
355 389 }
356 got_huff_bits: 390 bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++];
357 391 bd->inbufBitCount += 8;
358 /* Figure how how many bits are in next symbol and unget extras */ 392 };
393 bd->inbufBitCount = new_cnt; /* "bd->inbufBitCount -= hufGroup->maxLen;" */
394 nextSym = (bd->inbufBits >> new_cnt) & ((1 << hufGroup->maxLen) - 1);
395 got_huff_bits: ;
396 } else { /* unoptimized equivalent */
397 nextSym = get_bits(bd, hufGroup->maxLen);
398 }
399 /* Figure how many bits are in next symbol and unget extras */
359 i = hufGroup->minLen; 400 i = hufGroup->minLen;
360 while (j > limit[i]) ++i; 401 while (nextSym > limit[i]) ++i;
361 bd->inbufBitCount += (hufGroup->maxLen - i); 402 j = hufGroup->maxLen - i;
403 if (j < 0)
404 return RETVAL_DATA_ERROR;
405 bd->inbufBitCount += j;
362 406
363 /* Huffman decode value to get nextSym (with bounds checking) */ 407 /* Huffman decode value to get nextSym (with bounds checking) */
364 if (i > hufGroup->maxLen) 408 nextSym = (nextSym >> j) - base[i];
409 if ((unsigned)nextSym >= MAX_SYMBOLS)
365 return RETVAL_DATA_ERROR; 410 return RETVAL_DATA_ERROR;
366 j = (j >> (hufGroup->maxLen - i)) - base[i]; 411 nextSym = hufGroup->permute[nextSym];
367 if ((unsigned)j >= MAX_SYMBOLS)
368 return RETVAL_DATA_ERROR;
369 nextSym = hufGroup->permute[j];
370 412
371 /* We have now decoded the symbol, which indicates either a new literal 413 /* We have now decoded the symbol, which indicates either a new literal
372 byte, or a repeated run of the most recent literal byte. First, 414 byte, or a repeated run of the most recent literal byte. First,
@@ -375,9 +417,9 @@ static int get_next_block(bunzip_data *bd)
375 if ((unsigned)nextSym <= SYMBOL_RUNB) { /* RUNA or RUNB */ 417 if ((unsigned)nextSym <= SYMBOL_RUNB) { /* RUNA or RUNB */
376 418
377 /* If this is the start of a new run, zero out counter */ 419 /* If this is the start of a new run, zero out counter */
378 if (!runPos) { 420 if (runPos == 0) {
379 runPos = 1; 421 runPos = 1;
380 t = 0; 422 runCnt = 0;
381 } 423 }
382 424
383 /* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at 425 /* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
@@ -387,7 +429,7 @@ static int get_next_block(bunzip_data *bd)
387 the basic or 0/1 method (except all bits 0, which would use no 429 the basic or 0/1 method (except all bits 0, which would use no
388 symbols, but a run of length 0 doesn't mean anything in this 430 symbols, but a run of length 0 doesn't mean anything in this
389 context). Thus space is saved. */ 431 context). Thus space is saved. */
390 t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */ 432 runCnt += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
391 if (runPos < dbufSize) runPos <<= 1; 433 if (runPos < dbufSize) runPos <<= 1;
392 goto end_of_huffman_loop; 434 goto end_of_huffman_loop;
393 } 435 }
@@ -396,13 +438,13 @@ static int get_next_block(bunzip_data *bd)
396 how many times to repeat the last literal, so append that many 438 how many times to repeat the last literal, so append that many
397 copies to our buffer of decoded symbols (dbuf) now. (The last 439 copies to our buffer of decoded symbols (dbuf) now. (The last
398 literal used is the one at the head of the mtfSymbol array.) */ 440 literal used is the one at the head of the mtfSymbol array.) */
399 if (runPos) { 441 if (runPos != 0) {
442 uint8_t tmp_byte;
443 if (dbufCount + runCnt >= dbufSize) return RETVAL_DATA_ERROR;
444 tmp_byte = symToByte[mtfSymbol[0]];
445 byteCount[tmp_byte] += runCnt;
446 while (--runCnt >= 0) dbuf[dbufCount++] = (uint32_t)tmp_byte;
400 runPos = 0; 447 runPos = 0;
401 if (dbufCount + t >= dbufSize) return RETVAL_DATA_ERROR;
402
403 uc = symToByte[mtfSymbol[0]];
404 byteCount[uc] += t;
405 while (t--) dbuf[dbufCount++] = uc;
406 } 448 }
407 449
408 /* Is this the terminating symbol? */ 450 /* Is this the terminating symbol? */
@@ -431,12 +473,12 @@ static int get_next_block(bunzip_data *bd)
431 473
432 /* We have our literal byte. Save it into dbuf. */ 474 /* We have our literal byte. Save it into dbuf. */
433 byteCount[uc]++; 475 byteCount[uc]++;
434 dbuf[dbufCount++] = (unsigned)uc; 476 dbuf[dbufCount++] = (uint32_t)uc;
435 477
436 /* Skip group initialization if we're not done with this group. Done 478 /* Skip group initialization if we're not done with this group. Done
437 * this way to avoid compiler warning. */ 479 * this way to avoid compiler warning. */
438 end_of_huffman_loop: 480 end_of_huffman_loop:
439 if (symCount--) goto continue_this_group; 481 if (--symCount >= 0) goto continue_this_group;
440 } 482 }
441 483
442 /* At this point, we've read all the Huffman-coded symbols (and repeated 484 /* At this point, we've read all the Huffman-coded symbols (and repeated
@@ -449,26 +491,28 @@ static int get_next_block(bunzip_data *bd)
449 /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */ 491 /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
450 j = 0; 492 j = 0;
451 for (i = 0; i < 256; i++) { 493 for (i = 0; i < 256; i++) {
452 k = j + byteCount[i]; 494 int tmp_count = j + byteCount[i];
453 byteCount[i] = j; 495 byteCount[i] = j;
454 j = k; 496 j = tmp_count;
455 } 497 }
456 498
457 /* Figure out what order dbuf would be in if we sorted it. */ 499 /* Figure out what order dbuf would be in if we sorted it. */
458 for (i = 0; i < dbufCount; i++) { 500 for (i = 0; i < dbufCount; i++) {
459 uc = (unsigned char)(dbuf[i] & 0xff); 501 uint8_t tmp_byte = (uint8_t)dbuf[i];
460 dbuf[byteCount[uc]] |= (i << 8); 502 int tmp_count = byteCount[tmp_byte];
461 byteCount[uc]++; 503 dbuf[tmp_count] |= (i << 8);
504 byteCount[tmp_byte] = tmp_count + 1;
462 } 505 }
463 506
464 /* Decode first byte by hand to initialize "previous" byte. Note that it 507 /* Decode first byte by hand to initialize "previous" byte. Note that it
465 doesn't get output, and if the first three characters are identical 508 doesn't get output, and if the first three characters are identical
466 it doesn't qualify as a run (hence writeRunCountdown=5). */ 509 it doesn't qualify as a run (hence writeRunCountdown=5). */
467 if (dbufCount) { 510 if (dbufCount) {
511 uint32_t tmp;
468 if ((int)origPtr >= dbufCount) return RETVAL_DATA_ERROR; 512 if ((int)origPtr >= dbufCount) return RETVAL_DATA_ERROR;
469 bd->writePos = dbuf[origPtr]; 513 tmp = dbuf[origPtr];
470 bd->writeCurrent = (unsigned char)(bd->writePos & 0xff); 514 bd->writeCurrent = (uint8_t)tmp;
471 bd->writePos >>= 8; 515 bd->writePos = (tmp >> 8);
472 bd->writeRunCountdown = 5; 516 bd->writeRunCountdown = 5;
473 } 517 }
474 bd->writeCount = dbufCount; 518 bd->writeCount = dbufCount;
@@ -476,70 +520,84 @@ static int get_next_block(bunzip_data *bd)
476 return RETVAL_OK; 520 return RETVAL_OK;
477} 521}
478 522
479/* Undo burrows-wheeler transform on intermediate buffer to produce output. 523/* Undo Burrows-Wheeler transform on intermediate buffer to produce output.
480 If start_bunzip was initialized with out_fd=-1, then up to len bytes of 524 If start_bunzip was initialized with out_fd=-1, then up to len bytes of
481 data are written to outbuf. Return value is number of bytes written or 525 data are written to outbuf. Return value is number of bytes written or
482 error (all errors are negative numbers). If out_fd!=-1, outbuf and len 526 error (all errors are negative numbers). If out_fd!=-1, outbuf and len
483 are ignored, data is written to out_fd and return is RETVAL_OK or error. 527 are ignored, data is written to out_fd and return is RETVAL_OK or error.
528
529 NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes
530 in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0.
531 (Why? This allows to get rid of one local variable)
484*/ 532*/
485int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) 533int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
486{ 534{
487 const unsigned *dbuf; 535 const uint32_t *dbuf;
488 int pos, current, previous, gotcount; 536 int pos, current, previous;
537 uint32_t CRC;
489 538
490 /* If last read was short due to end of file, return last block now */ 539 /* If we already have error/end indicator, return it */
491 if (bd->writeCount < 0) return bd->writeCount; 540 if (bd->writeCount < 0)
541 return bd->writeCount;
492 542
493 gotcount = 0;
494 dbuf = bd->dbuf; 543 dbuf = bd->dbuf;
544
545 /* Register-cached state (hopefully): */
495 pos = bd->writePos; 546 pos = bd->writePos;
496 current = bd->writeCurrent; 547 current = bd->writeCurrent;
548 CRC = bd->writeCRC; /* small loss on x86-32 (not enough regs), win on x86-64 */
497 549
498 /* We will always have pending decoded data to write into the output 550 /* We will always have pending decoded data to write into the output
499 buffer unless this is the very first call (in which case we haven't 551 buffer unless this is the very first call (in which case we haven't
500 Huffman-decoded a block into the intermediate buffer yet). */ 552 Huffman-decoded a block into the intermediate buffer yet). */
501 if (bd->writeCopies) { 553 if (bd->writeCopies) {
502 554
555 dec_writeCopies:
503 /* Inside the loop, writeCopies means extra copies (beyond 1) */ 556 /* Inside the loop, writeCopies means extra copies (beyond 1) */
504 --bd->writeCopies; 557 --bd->writeCopies;
505 558
506 /* Loop outputting bytes */ 559 /* Loop outputting bytes */
507 for (;;) { 560 for (;;) {
508 561
509 /* If the output buffer is full, snapshot state and return */ 562 /* If the output buffer is full, save cached state and return */
510 if (gotcount >= len) { 563 if (--len < 0) {
511 bd->writePos = pos; 564 /* Unlikely branch.
512 bd->writeCurrent = current; 565 * Use of "goto" instead of keeping code here
513 bd->writeCopies++; 566 * helps compiler to realize this. */
514 return len; 567 goto outbuf_full;
515 } 568 }
516 569
517 /* Write next byte into output buffer, updating CRC */ 570 /* Write next byte into output buffer, updating CRC */
518 outbuf[gotcount++] = current; 571 *outbuf++ = current;
519 bd->writeCRC = (bd->writeCRC << 8) 572 CRC = (CRC << 8) ^ bd->crc32Table[(CRC >> 24) ^ current];
520 ^ bd->crc32Table[(bd->writeCRC >> 24) ^ current];
521 573
522 /* Loop now if we're outputting multiple copies of this byte */ 574 /* Loop now if we're outputting multiple copies of this byte */
523 if (bd->writeCopies) { 575 if (bd->writeCopies) {
524 --bd->writeCopies; 576 /* Unlikely branch */
525 continue; 577 /*--bd->writeCopies;*/
578 /*continue;*/
579 /* Same, but (ab)using other existing --writeCopies operation
580 * (and this if() compiles into just test+branch pair): */
581 goto dec_writeCopies;
526 } 582 }
527 decode_next_byte: 583 decode_next_byte:
528 if (!bd->writeCount--) break; 584 if (--bd->writeCount < 0)
585 break; /* input block is fully consumed, need next one */
586
529 /* Follow sequence vector to undo Burrows-Wheeler transform */ 587 /* Follow sequence vector to undo Burrows-Wheeler transform */
530 previous = current; 588 previous = current;
531 pos = dbuf[pos]; 589 pos = dbuf[pos];
532 current = pos & 0xff; 590 current = (uint8_t)pos;
533 pos >>= 8; 591 pos >>= 8;
534 592
535 /* After 3 consecutive copies of the same byte, the 4th 593 /* After 3 consecutive copies of the same byte, the 4th
536 * is a repeat count. We count down from 4 instead 594 * is a repeat count. We count down from 4 instead
537 * of counting up because testing for non-zero is faster */ 595 * of counting up because testing for non-zero is faster */
538 if (--bd->writeRunCountdown) { 596 if (--bd->writeRunCountdown != 0) {
539 if (current != previous) 597 if (current != previous)
540 bd->writeRunCountdown = 4; 598 bd->writeRunCountdown = 4;
541 } else { 599 } else {
542 600 /* Unlikely branch */
543 /* We have a repeated run, this byte indicates the count */ 601 /* We have a repeated run, this byte indicates the count */
544 bd->writeCopies = current; 602 bd->writeCopies = current;
545 current = previous; 603 current = previous;
@@ -551,30 +609,42 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
551 /* Subtract the 1 copy we'd output anyway to get extras */ 609 /* Subtract the 1 copy we'd output anyway to get extras */
552 --bd->writeCopies; 610 --bd->writeCopies;
553 } 611 }
554 } 612 } /* for(;;) */
555 613
556 /* Decompression of this block completed successfully */ 614 /* Decompression of this input block completed successfully */
557 bd->writeCRC = ~bd->writeCRC; 615 bd->writeCRC = CRC = ~CRC;
558 bd->totalCRC = ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ bd->writeCRC; 616 bd->totalCRC = ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ CRC;
559 617
560 /* If this block had a CRC error, force file level CRC error. */ 618 /* If this block had a CRC error, force file level CRC error */
561 if (bd->writeCRC != bd->headerCRC) { 619 if (CRC != bd->headerCRC) {
562 bd->totalCRC = bd->headerCRC + 1; 620 bd->totalCRC = bd->headerCRC + 1;
563 return RETVAL_LAST_BLOCK; 621 return RETVAL_LAST_BLOCK;
564 } 622 }
565 } 623 }
566 624
567 /* Refill the intermediate buffer by Huffman-decoding next block of input */ 625 /* Refill the intermediate buffer by Huffman-decoding next block of input */
568 /* (previous is just a convenient unused temp variable here) */ 626 {
569 previous = get_next_block(bd); 627 int r = get_next_block(bd);
570 if (previous) { 628 if (r) { /* error/end */
571 bd->writeCount = previous; 629 bd->writeCount = r;
572 return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount; 630 return (r != RETVAL_LAST_BLOCK) ? r : len;
631 }
573 } 632 }
574 bd->writeCRC = ~0; 633
634 CRC = ~0;
575 pos = bd->writePos; 635 pos = bd->writePos;
576 current = bd->writeCurrent; 636 current = bd->writeCurrent;
577 goto decode_next_byte; 637 goto decode_next_byte;
638
639 outbuf_full:
640 /* Output buffer is full, save cached state and return */
641 bd->writePos = pos;
642 bd->writeCurrent = current;
643 bd->writeCRC = CRC;
644
645 bd->writeCopies++;
646
647 return 0;
578} 648}
579 649
580/* Allocate the structure, read file header. If in_fd==-1, inbuf must contain 650/* Allocate the structure, read file header. If in_fd==-1, inbuf must contain
@@ -584,8 +654,8 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
584/* Because bunzip2 is used for help text unpacking, and because bb_show_usage() 654/* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
585 should work for NOFORK applets too, we must be extremely careful to not leak 655 should work for NOFORK applets too, we must be extremely careful to not leak
586 any allocations! */ 656 any allocations! */
587int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *inbuf, 657int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd,
588 int len) 658 const void *inbuf, int len)
589{ 659{
590 bunzip_data *bd; 660 bunzip_data *bd;
591 unsigned i; 661 unsigned i;
@@ -606,9 +676,11 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *in
606 if (-1 == in_fd) { 676 if (-1 == in_fd) {
607 /* in this case, bd->inbuf is read-only */ 677 /* in this case, bd->inbuf is read-only */
608 bd->inbuf = (void*)inbuf; /* cast away const-ness */ 678 bd->inbuf = (void*)inbuf; /* cast away const-ness */
609 bd->inbufCount = len; 679 } else {
610 } else 680 bd->inbuf = (uint8_t*)(bd + 1);
611 bd->inbuf = (unsigned char *)(bd + 1); 681 memcpy(bd->inbuf, inbuf, len);
682 }
683 bd->inbufCount = len;
612 684
613 /* Init the CRC32 table (big endian) */ 685 /* Init the CRC32 table (big endian) */
614 crc32_filltable(bd->crc32Table, 1); 686 crc32_filltable(bd->crc32Table, 1);
@@ -632,7 +704,7 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *in
632 bd->dbufSize = 100000 * (i - h0); 704 bd->dbufSize = 100000 * (i - h0);
633 705
634 /* Cannot use xmalloc - may leak bd in NOFORK case! */ 706 /* Cannot use xmalloc - may leak bd in NOFORK case! */
635 bd->dbuf = malloc_or_warn(bd->dbufSize * sizeof(int)); 707 bd->dbuf = malloc_or_warn(bd->dbufSize * sizeof(bd->dbuf[0]));
636 if (!bd->dbuf) { 708 if (!bd->dbuf) {
637 free(bd); 709 free(bd);
638 xfunc_die(); 710 xfunc_die();
@@ -652,37 +724,63 @@ IF_DESKTOP(long long) int FAST_FUNC
652unpack_bz2_stream(int src_fd, int dst_fd) 724unpack_bz2_stream(int src_fd, int dst_fd)
653{ 725{
654 IF_DESKTOP(long long total_written = 0;) 726 IF_DESKTOP(long long total_written = 0;)
655 char *outbuf;
656 bunzip_data *bd; 727 bunzip_data *bd;
728 char *outbuf;
657 int i; 729 int i;
730 unsigned len;
658 731
659 outbuf = xmalloc(IOBUF_SIZE); 732 outbuf = xmalloc(IOBUF_SIZE);
660 i = start_bunzip(&bd, src_fd, NULL, 0); 733 len = 0;
661 if (!i) { 734 while (1) { /* "Process one BZ... stream" loop */
662 for (;;) { 735
663 i = read_bunzip(bd, outbuf, IOBUF_SIZE); 736 i = start_bunzip(&bd, src_fd, outbuf + 2, len);
664 if (i <= 0) break; 737
665 if (i != full_write(dst_fd, outbuf, i)) { 738 if (i == 0) {
666 i = RETVAL_SHORT_WRITE; 739 while (1) { /* "Produce some output bytes" loop */
667 break; 740 i = read_bunzip(bd, outbuf, IOBUF_SIZE);
741 if (i < 0) /* error? */
742 break;
743 i = IOBUF_SIZE - i; /* number of bytes produced */
744 if (i == 0) /* EOF? */
745 break;
746 if (i != full_write(dst_fd, outbuf, i)) {
747 bb_error_msg("short write");
748 i = RETVAL_SHORT_WRITE;
749 goto release_mem;
750 }
751 IF_DESKTOP(total_written += i;)
668 } 752 }
669 IF_DESKTOP(total_written += i;)
670 } 753 }
671 }
672
673 /* Check CRC and release memory */
674 754
675 if (i == RETVAL_LAST_BLOCK) { 755 if (i != RETVAL_LAST_BLOCK) {
756 bb_error_msg("bunzip error %d", i);
757 break;
758 }
676 if (bd->headerCRC != bd->totalCRC) { 759 if (bd->headerCRC != bd->totalCRC) {
677 bb_error_msg("CRC error"); 760 bb_error_msg("CRC error");
678 } else { 761 break;
679 i = RETVAL_OK;
680 } 762 }
681 } else if (i == RETVAL_SHORT_WRITE) { 763
682 bb_error_msg("short write"); 764 /* Successfully unpacked one BZ stream */
683 } else { 765 i = RETVAL_OK;
684 bb_error_msg("bunzip error %d", i); 766
767 /* Do we have "BZ..." after last processed byte?
768 * pbzip2 (parallelized bzip2) produces such files.
769 */
770 len = bd->inbufCount - bd->inbufPos;
771 memcpy(outbuf, &bd->inbuf[bd->inbufPos], len);
772 if (len < 2) {
773 if (safe_read(src_fd, outbuf + len, 2 - len) != 2 - len)
774 break;
775 len = 2;
776 }
777 if (*(uint16_t*)outbuf != BZIP2_MAGIC) /* "BZ"? */
778 break;
779 dealloc_bunzip(bd);
780 len -= 2;
685 } 781 }
782
783 release_mem:
686 dealloc_bunzip(bd); 784 dealloc_bunzip(bd);
687 free(outbuf); 785 free(outbuf);
688 786
diff --git a/archival/libunarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c
index 285b4efeb..44d894244 100644
--- a/archival/libunarchive/decompress_uncompress.c
+++ b/archival/libarchive/decompress_uncompress.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "libbb.h" 27#include "libbb.h"
28#include "unarchive.h" 28#include "archive.h"
29 29
30 30
31/* Default input buffer size */ 31/* Default input buffer size */
diff --git a/archival/libunarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c
index 1a3a8f86b..a04714341 100644
--- a/archival/libunarchive/decompress_unlzma.c
+++ b/archival/libarchive/decompress_unlzma.c
@@ -9,7 +9,7 @@
9 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 9 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
10 */ 10 */
11#include "libbb.h" 11#include "libbb.h"
12#include "unarchive.h" 12#include "archive.h"
13 13
14#if ENABLE_FEATURE_LZMA_FAST 14#if ENABLE_FEATURE_LZMA_FAST
15# define speed_inline ALWAYS_INLINE 15# define speed_inline ALWAYS_INLINE
diff --git a/archival/libunarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c
index ca427231e..e90dfb06f 100644
--- a/archival/libunarchive/decompress_unxz.c
+++ b/archival/libarchive/decompress_unxz.c
@@ -10,7 +10,7 @@
10 * Licensed under GPLv2, see file LICENSE in this source tree. 10 * Licensed under GPLv2, see file LICENSE in this source tree.
11 */ 11 */
12#include "libbb.h" 12#include "libbb.h"
13#include "unarchive.h" 13#include "archive.h"
14 14
15#define XZ_FUNC FAST_FUNC 15#define XZ_FUNC FAST_FUNC
16#define XZ_EXTERN static 16#define XZ_EXTERN static
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libarchive/decompress_unzip.c
index cb8a3d737..a29eef837 100644
--- a/archival/libunarchive/decompress_unzip.c
+++ b/archival/libarchive/decompress_unzip.c
@@ -35,7 +35,7 @@
35 35
36#include <setjmp.h> 36#include <setjmp.h>
37#include "libbb.h" 37#include "libbb.h"
38#include "unarchive.h" 38#include "archive.h"
39 39
40typedef struct huft_t { 40typedef struct huft_t {
41 unsigned char e; /* number of extra bits or operation */ 41 unsigned char e; /* number of extra bits or operation */
diff --git a/archival/libunarchive/filter_accept_all.c b/archival/libarchive/filter_accept_all.c
index cb1f506c8..e69deb679 100644
--- a/archival/libunarchive/filter_accept_all.c
+++ b/archival/libarchive/filter_accept_all.c
@@ -6,7 +6,7 @@
6 */ 6 */
7 7
8#include "libbb.h" 8#include "libbb.h"
9#include "unarchive.h" 9#include "archive.h"
10 10
11/* Accept any non-null name, its not really a filter at all */ 11/* Accept any non-null name, its not really a filter at all */
12char FAST_FUNC filter_accept_all(archive_handle_t *archive_handle) 12char FAST_FUNC filter_accept_all(archive_handle_t *archive_handle)
diff --git a/archival/libunarchive/filter_accept_list.c b/archival/libarchive/filter_accept_list.c
index fe4414c85..a7640af79 100644
--- a/archival/libunarchive/filter_accept_list.c
+++ b/archival/libarchive/filter_accept_list.c
@@ -6,7 +6,7 @@
6 */ 6 */
7 7
8#include "libbb.h" 8#include "libbb.h"
9#include "unarchive.h" 9#include "archive.h"
10 10
11/* 11/*
12 * Accept names that are in the accept list, ignoring reject list. 12 * Accept names that are in the accept list, ignoring reject list.
diff --git a/archival/libunarchive/filter_accept_list_reassign.c b/archival/libarchive/filter_accept_list_reassign.c
index 891f58390..d80f71668 100644
--- a/archival/libunarchive/filter_accept_list_reassign.c
+++ b/archival/libarchive/filter_accept_list_reassign.c
@@ -6,7 +6,7 @@
6 */ 6 */
7 7
8#include "libbb.h" 8#include "libbb.h"
9#include "unarchive.h" 9#include "archive.h"
10 10
11/* Built and used only if ENABLE_DPKG || ENABLE_DPKG_DEB */ 11/* Built and used only if ENABLE_DPKG || ENABLE_DPKG_DEB */
12 12
diff --git a/archival/libunarchive/filter_accept_reject_list.c b/archival/libarchive/filter_accept_reject_list.c
index 89a5502d5..3e86cca65 100644
--- a/archival/libunarchive/filter_accept_reject_list.c
+++ b/archival/libarchive/filter_accept_reject_list.c
@@ -6,7 +6,7 @@
6 */ 6 */
7 7
8#include "libbb.h" 8#include "libbb.h"
9#include "unarchive.h" 9#include "archive.h"
10 10
11/* 11/*
12 * Accept names that are in the accept list and not in the reject list 12 * Accept names that are in the accept list and not in the reject list
diff --git a/archival/libunarchive/find_list_entry.c b/archival/libarchive/find_list_entry.c
index 5c0c85f09..5efd1af2e 100644
--- a/archival/libunarchive/find_list_entry.c
+++ b/archival/libarchive/find_list_entry.c
@@ -7,7 +7,7 @@
7 7
8#include <fnmatch.h> 8#include <fnmatch.h>
9#include "libbb.h" 9#include "libbb.h"
10#include "unarchive.h" 10#include "archive.h"
11 11
12/* Find a string in a shell pattern list */ 12/* Find a string in a shell pattern list */
13const llist_t* FAST_FUNC find_list_entry(const llist_t *list, const char *filename) 13const llist_t* FAST_FUNC find_list_entry(const llist_t *list, const char *filename)
diff --git a/archival/libunarchive/get_header_ar.c b/archival/libarchive/get_header_ar.c
index 6bfc6bc27..df603b111 100644
--- a/archival/libunarchive/get_header_ar.c
+++ b/archival/libarchive/get_header_ar.c
@@ -5,7 +5,7 @@
5 */ 5 */
6 6
7#include "libbb.h" 7#include "libbb.h"
8#include "unarchive.h" 8#include "archive.h"
9#include "ar.h" 9#include "ar.h"
10 10
11static unsigned read_num(const char *str, int base) 11static unsigned read_num(const char *str, int base)
diff --git a/archival/libunarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c
index 8cd1096ba..3d99b492a 100644
--- a/archival/libunarchive/get_header_cpio.c
+++ b/archival/libarchive/get_header_cpio.c
@@ -5,7 +5,7 @@
5 */ 5 */
6 6
7#include "libbb.h" 7#include "libbb.h"
8#include "unarchive.h" 8#include "archive.h"
9 9
10typedef struct hardlinks_t { 10typedef struct hardlinks_t {
11 struct hardlinks_t *next; 11 struct hardlinks_t *next;
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c
index cf6487207..78b0ae25f 100644
--- a/archival/libunarchive/get_header_tar.c
+++ b/archival/libarchive/get_header_tar.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "libbb.h" 14#include "libbb.h"
15#include "unarchive.h" 15#include "archive.h"
16 16
17typedef uint32_t aliased_uint32_t FIX_ALIASING; 17typedef uint32_t aliased_uint32_t FIX_ALIASING;
18typedef off_t aliased_off_t FIX_ALIASING; 18typedef off_t aliased_off_t FIX_ALIASING;
diff --git a/archival/libunarchive/get_header_tar_bz2.c b/archival/libarchive/get_header_tar_bz2.c
index 4ffc17086..60d32069f 100644
--- a/archival/libunarchive/get_header_tar_bz2.c
+++ b/archival/libarchive/get_header_tar_bz2.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9char FAST_FUNC get_header_tar_bz2(archive_handle_t *archive_handle) 9char FAST_FUNC get_header_tar_bz2(archive_handle_t *archive_handle)
10{ 10{
diff --git a/archival/libunarchive/get_header_tar_gz.c b/archival/libarchive/get_header_tar_gz.c
index a9af22e0e..b09f8691c 100644
--- a/archival/libunarchive/get_header_tar_gz.c
+++ b/archival/libarchive/get_header_tar_gz.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) 9char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle)
10{ 10{
diff --git a/archival/libunarchive/get_header_tar_lzma.c b/archival/libarchive/get_header_tar_lzma.c
index 9876b3827..da08e0c72 100644
--- a/archival/libunarchive/get_header_tar_lzma.c
+++ b/archival/libarchive/get_header_tar_lzma.c
@@ -7,7 +7,7 @@
7 */ 7 */
8 8
9#include "libbb.h" 9#include "libbb.h"
10#include "unarchive.h" 10#include "archive.h"
11 11
12char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle) 12char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle)
13{ 13{
diff --git a/archival/libunarchive/header_list.c b/archival/libarchive/header_list.c
index 902d6ebe0..c4fc75f38 100644
--- a/archival/libunarchive/header_list.c
+++ b/archival/libarchive/header_list.c
@@ -3,7 +3,7 @@
3 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
4 */ 4 */
5#include "libbb.h" 5#include "libbb.h"
6#include "unarchive.h" 6#include "archive.h"
7 7
8void FAST_FUNC header_list(const file_header_t *file_header) 8void FAST_FUNC header_list(const file_header_t *file_header)
9{ 9{
diff --git a/archival/libunarchive/header_skip.c b/archival/libarchive/header_skip.c
index 2af36ac9c..2bfc5253c 100644
--- a/archival/libunarchive/header_skip.c
+++ b/archival/libarchive/header_skip.c
@@ -3,7 +3,7 @@
3 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
4 */ 4 */
5#include "libbb.h" 5#include "libbb.h"
6#include "unarchive.h" 6#include "archive.h"
7 7
8void FAST_FUNC header_skip(const file_header_t *file_header UNUSED_PARAM) 8void FAST_FUNC header_skip(const file_header_t *file_header UNUSED_PARAM)
9{ 9{
diff --git a/archival/libunarchive/header_verbose_list.c b/archival/libarchive/header_verbose_list.c
index d863e6a29..bc4e4154b 100644
--- a/archival/libunarchive/header_verbose_list.c
+++ b/archival/libarchive/header_verbose_list.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9void FAST_FUNC header_verbose_list(const file_header_t *file_header) 9void FAST_FUNC header_verbose_list(const file_header_t *file_header)
10{ 10{
diff --git a/archival/libunarchive/init_handle.c b/archival/libarchive/init_handle.c
index de7021f78..6644ea13b 100644
--- a/archival/libunarchive/init_handle.c
+++ b/archival/libarchive/init_handle.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9archive_handle_t* FAST_FUNC init_handle(void) 9archive_handle_t* FAST_FUNC init_handle(void)
10{ 10{
diff --git a/archival/liblzo.h b/archival/libarchive/liblzo.h
index 843997cb9..843997cb9 100644
--- a/archival/liblzo.h
+++ b/archival/libarchive/liblzo.h
diff --git a/archival/lzo1x_1.c b/archival/libarchive/lzo1x_1.c
index a88839846..a88839846 100644
--- a/archival/lzo1x_1.c
+++ b/archival/libarchive/lzo1x_1.c
diff --git a/archival/lzo1x_1o.c b/archival/libarchive/lzo1x_1o.c
index 3c61253e0..3c61253e0 100644
--- a/archival/lzo1x_1o.c
+++ b/archival/libarchive/lzo1x_1o.c
diff --git a/archival/lzo1x_9x.c b/archival/libarchive/lzo1x_9x.c
index 483205155..483205155 100644
--- a/archival/lzo1x_9x.c
+++ b/archival/libarchive/lzo1x_9x.c
diff --git a/archival/lzo1x_c.c b/archival/libarchive/lzo1x_c.c
index cc86f74b1..cc86f74b1 100644
--- a/archival/lzo1x_c.c
+++ b/archival/libarchive/lzo1x_c.c
diff --git a/archival/lzo1x_d.c b/archival/libarchive/lzo1x_d.c
index 348a85510..348a85510 100644
--- a/archival/lzo1x_d.c
+++ b/archival/libarchive/lzo1x_d.c
diff --git a/archival/libunarchive/open_transformer.c b/archival/libarchive/open_transformer.c
index ed6a556bb..26ae565f5 100644
--- a/archival/libunarchive/open_transformer.c
+++ b/archival/libarchive/open_transformer.c
@@ -4,12 +4,12 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9/* transformer(), more than meets the eye */ 9/* transformer(), more than meets the eye */
10/* 10/*
11 * On MMU machine, the transform_prog is removed by macro magic 11 * On MMU machine, the transform_prog is removed by macro magic
12 * in include/unarchive.h. On NOMMU, transformer is removed. 12 * in include/archive.h. On NOMMU, transformer is removed.
13 */ 13 */
14void FAST_FUNC open_transformer(int fd, 14void FAST_FUNC open_transformer(int fd,
15 IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), 15 IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd),
diff --git a/archival/libunarchive/seek_by_jump.c b/archival/libarchive/seek_by_jump.c
index bda55e1b1..7c2c52ae1 100644
--- a/archival/libunarchive/seek_by_jump.c
+++ b/archival/libarchive/seek_by_jump.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9void FAST_FUNC seek_by_jump(int fd, off_t amount) 9void FAST_FUNC seek_by_jump(int fd, off_t amount)
10{ 10{
diff --git a/archival/libunarchive/seek_by_read.c b/archival/libarchive/seek_by_read.c
index 25b31365d..ad931a8de 100644
--- a/archival/libunarchive/seek_by_read.c
+++ b/archival/libarchive/seek_by_read.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8 8
9/* If we are reading through a pipe, or from stdin then we can't lseek, 9/* If we are reading through a pipe, or from stdin then we can't lseek,
10 * we must read and discard the data to skip over it. 10 * we must read and discard the data to skip over it.
diff --git a/archival/libunarchive/unpack_ar_archive.c b/archival/libarchive/unpack_ar_archive.c
index 4f68ba3d8..18dbfd54d 100644
--- a/archival/libunarchive/unpack_ar_archive.c
+++ b/archival/libarchive/unpack_ar_archive.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "libbb.h" 6#include "libbb.h"
7#include "unarchive.h" 7#include "archive.h"
8#include "ar.h" 8#include "ar.h"
9 9
10void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive) 10void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive)
diff --git a/archival/libunarchive/unxz/README b/archival/libarchive/unxz/README
index c5972f6b8..c5972f6b8 100644
--- a/archival/libunarchive/unxz/README
+++ b/archival/libarchive/unxz/README
diff --git a/archival/libunarchive/unxz/xz.h b/archival/libarchive/unxz/xz.h
index c6c071c4a..c6c071c4a 100644
--- a/archival/libunarchive/unxz/xz.h
+++ b/archival/libarchive/unxz/xz.h
diff --git a/archival/libunarchive/unxz/xz_config.h b/archival/libarchive/unxz/xz_config.h
index 187e1cbed..187e1cbed 100644
--- a/archival/libunarchive/unxz/xz_config.h
+++ b/archival/libarchive/unxz/xz_config.h
diff --git a/archival/libunarchive/unxz/xz_dec_bcj.c b/archival/libarchive/unxz/xz_dec_bcj.c
index 09162b51f..09162b51f 100644
--- a/archival/libunarchive/unxz/xz_dec_bcj.c
+++ b/archival/libarchive/unxz/xz_dec_bcj.c
diff --git a/archival/libunarchive/unxz/xz_dec_lzma2.c b/archival/libarchive/unxz/xz_dec_lzma2.c
index da71cb4d4..da71cb4d4 100644
--- a/archival/libunarchive/unxz/xz_dec_lzma2.c
+++ b/archival/libarchive/unxz/xz_dec_lzma2.c
diff --git a/archival/libunarchive/unxz/xz_dec_stream.c b/archival/libarchive/unxz/xz_dec_stream.c
index bdcbf1ba3..bdcbf1ba3 100644
--- a/archival/libunarchive/unxz/xz_dec_stream.c
+++ b/archival/libarchive/unxz/xz_dec_stream.c
diff --git a/archival/libunarchive/unxz/xz_lzma2.h b/archival/libarchive/unxz/xz_lzma2.h
index 47f21afbc..47f21afbc 100644
--- a/archival/libunarchive/unxz/xz_lzma2.h
+++ b/archival/libarchive/unxz/xz_lzma2.h
diff --git a/archival/libunarchive/unxz/xz_private.h b/archival/libarchive/unxz/xz_private.h
index 145649a83..145649a83 100644
--- a/archival/libunarchive/unxz/xz_private.h
+++ b/archival/libarchive/unxz/xz_private.h
diff --git a/archival/libunarchive/unxz/xz_stream.h b/archival/libarchive/unxz/xz_stream.h
index 36f2a7cbf..36f2a7cbf 100644
--- a/archival/libunarchive/unxz/xz_stream.h
+++ b/archival/libarchive/unxz/xz_stream.h
diff --git a/archival/liblzo_interface.h b/archival/liblzo_interface.h
deleted file mode 100644
index 9a84c0b6b..000000000
--- a/archival/liblzo_interface.h
+++ /dev/null
@@ -1,71 +0,0 @@
1/*
2 This file is part of the LZO real-time data compression library.
3
4 Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer
5 All Rights Reserved.
6
7 Markus F.X.J. Oberhumer <markus@oberhumer.com>
8 http://www.oberhumer.com/opensource/lzo/
9
10 The LZO library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of
13 the License, or (at your option) any later version.
14
15 The LZO library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with the LZO library; see the file COPYING.
22 If not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 */
25
26#define LZO1X
27#undef LZO1Y
28
29#undef assert
30/*
31static void die_at(int line)
32{
33 bb_error_msg_and_die("internal error at %d", line);
34}
35#define assert(v) if (!(v)) die_at(__LINE__)
36*/
37#define assert(v) ((void)0)
38
39int lzo1x_1_compress(const uint8_t* src, unsigned src_len,
40 uint8_t* dst, unsigned* dst_len,
41 void* wrkmem);
42int lzo1x_1_15_compress(const uint8_t* src, unsigned src_len,
43 uint8_t* dst, unsigned* dst_len,
44 void* wrkmem);
45int lzo1x_999_compress_level(const uint8_t* in, unsigned in_len,
46 uint8_t* out, unsigned* out_len,
47 void* wrkmem,
48 int compression_level);
49
50/* decompression */
51//int lzo1x_decompress(const uint8_t* src, unsigned src_len,
52// uint8_t* dst, unsigned* dst_len,
53// void* wrkmem /* NOT USED */);
54/* safe decompression with overrun testing */
55int lzo1x_decompress_safe(const uint8_t* src, unsigned src_len,
56 uint8_t* dst, unsigned* dst_len,
57 void* wrkmem /* NOT USED */);
58
59#define LZO_E_OK 0
60#define LZO_E_ERROR (-1)
61#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */
62#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
63#define LZO_E_INPUT_OVERRUN (-4)
64#define LZO_E_OUTPUT_OVERRUN (-5)
65#define LZO_E_LOOKBEHIND_OVERRUN (-6)
66#define LZO_E_EOF_NOT_FOUND (-7)
67#define LZO_E_INPUT_NOT_CONSUMED (-8)
68#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
69
70/* lzo-2.03/include/lzo/lzoconf.h */
71#define LZO_VERSION 0x2030
diff --git a/archival/lzop.c b/archival/lzop.c
index acb34fe14..094e78cf9 100644
--- a/archival/lzop.c
+++ b/archival/lzop.c
@@ -26,7 +26,7 @@
26*/ 26*/
27 27
28#include "libbb.h" 28#include "libbb.h"
29#include "unarchive.h" 29#include "archive.h"
30#include "liblzo_interface.h" 30#include "liblzo_interface.h"
31 31
32/* lzo-2.03/src/lzo_ptr.h */ 32/* lzo-2.03/src/lzo_ptr.h */
diff --git a/archival/rpm.c b/archival/rpm.c
index 7b316a5b8..380226f9b 100644
--- a/archival/rpm.c
+++ b/archival/rpm.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "libbb.h" 10#include "libbb.h"
11#include "unarchive.h" 11#include "archive.h"
12#include "rpm.h" 12#include "rpm.h"
13 13
14#define RPM_CHAR_TYPE 1 14#define RPM_CHAR_TYPE 1
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c
index 70021d539..ce8cd2c2c 100644
--- a/archival/rpm2cpio.c
+++ b/archival/rpm2cpio.c
@@ -7,7 +7,7 @@
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */ 8 */
9#include "libbb.h" 9#include "libbb.h"
10#include "unarchive.h" 10#include "archive.h"
11#include "rpm.h" 11#include "rpm.h"
12 12
13enum { rpm_fd = STDIN_FILENO }; 13enum { rpm_fd = STDIN_FILENO };
diff --git a/archival/tar.c b/archival/tar.c
index 1d6e63da0..150c6f393 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -23,9 +23,28 @@
23 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 23 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
24 */ 24 */
25 25
26/* TODO: security with -C DESTDIR option can be enhanced.
27 * Consider tar file created via:
28 * $ tar cvf bug.tar anything.txt
29 * $ ln -s /tmp symlink
30 * $ tar --append -f bug.tar symlink
31 * $ rm symlink
32 * $ mkdir symlink
33 * $ tar --append -f bug.tar symlink/evil.py
34 *
35 * This will result in an archive which contains:
36 * $ tar --list -f bug.tar
37 * anything.txt
38 * symlink
39 * symlink/evil.py
40 *
41 * Untarring it puts evil.py in '/tmp' even if the -C DESTDIR is given.
42 * This doesn't feel right, and IIRC GNU tar doesn't do that.
43 */
44
26#include <fnmatch.h> 45#include <fnmatch.h>
27#include "libbb.h" 46#include "libbb.h"
28#include "unarchive.h" 47#include "archive.h"
29/* FIXME: Stop using this non-standard feature */ 48/* FIXME: Stop using this non-standard feature */
30#ifndef FNM_LEADING_DIR 49#ifndef FNM_LEADING_DIR
31# define FNM_LEADING_DIR 0 50# define FNM_LEADING_DIR 0
@@ -884,7 +903,6 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
884 /* Prepend '-' to the first argument if required */ 903 /* Prepend '-' to the first argument if required */
885 opt_complementary = "--:" // first arg is options 904 opt_complementary = "--:" // first arg is options
886 "tt:vv:" // count -t,-v 905 "tt:vv:" // count -t,-v
887 "?:" // bail out with usage instead of error return
888 "X::T::" // cumulative lists 906 "X::T::" // cumulative lists
889#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 907#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
890 "\xff::" // cumulative lists for --exclude 908 "\xff::" // cumulative lists for --exclude
diff --git a/archival/unzip.c b/archival/unzip.c
index 204e34952..5d62c08cb 100644
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -20,7 +20,7 @@
20 */ 20 */
21 21
22#include "libbb.h" 22#include "libbb.h"
23#include "unarchive.h" 23#include "archive.h"
24 24
25enum { 25enum {
26#if BB_BIG_ENDIAN 26#if BB_BIG_ENDIAN