diff options
Diffstat (limited to 'archival')
-rw-r--r-- | archival/Config.src | 9 | ||||
-rw-r--r-- | archival/bbunzip.c | 11 | ||||
-rw-r--r-- | archival/libunarchive/Kbuild.src | 2 | ||||
-rw-r--r-- | archival/libunarchive/data_extract_all.c | 1 | ||||
-rw-r--r-- | archival/libunarchive/data_extract_to_command.c | 134 | ||||
-rw-r--r-- | archival/libunarchive/decompress_bunzip2.c | 6 | ||||
-rw-r--r-- | archival/libunarchive/decompress_unxz.c | 52 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar.c | 56 | ||||
-rw-r--r-- | archival/libunarchive/open_transformer.c | 14 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz.h | 139 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_config.h | 2 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_dec_lzma2.c | 200 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_dec_stream.c | 17 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_private.h | 41 | ||||
-rw-r--r-- | archival/rpm2cpio.c | 10 | ||||
-rw-r--r-- | archival/tar.c | 121 | ||||
-rw-r--r-- | archival/unzip_doc.txt.bz2 | bin | 11359 -> 0 bytes |
17 files changed, 536 insertions, 279 deletions
diff --git a/archival/Config.src b/archival/Config.src index 3dbd3aea1..f64b3347b 100644 --- a/archival/Config.src +++ b/archival/Config.src | |||
@@ -280,6 +280,15 @@ config FEATURE_TAR_LONG_OPTIONS | |||
280 | help | 280 | help |
281 | Enable use of long options, increases size by about 400 Bytes | 281 | Enable use of long options, increases size by about 400 Bytes |
282 | 282 | ||
283 | config FEATURE_TAR_TO_COMMAND | ||
284 | bool "Support for writing to an external program" | ||
285 | default y | ||
286 | depends on TAR && FEATURE_TAR_LONG_OPTIONS | ||
287 | help | ||
288 | If you enable this option you'll be able to instruct tar to send | ||
289 | the contents of each extracted file to the standard input of an | ||
290 | external program. | ||
291 | |||
283 | config FEATURE_TAR_UNAME_GNAME | 292 | config FEATURE_TAR_UNAME_GNAME |
284 | bool "Enable use of user and group names" | 293 | bool "Enable use of user and group names" |
285 | default y | 294 | default y |
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index b243afb2e..c1259ac46 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -373,12 +373,21 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |||
373 | static | 373 | static |
374 | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM) | 374 | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM) |
375 | { | 375 | { |
376 | struct { | ||
377 | uint32_t v1; | ||
378 | uint16_t v2; | ||
379 | } magic; | ||
380 | xread(STDIN_FILENO, &magic, 6); | ||
381 | if (magic.v1 != XZ_MAGIC1a || magic.v2 != XZ_MAGIC2a) { | ||
382 | bb_error_msg("invalid magic"); | ||
383 | return -1; | ||
384 | } | ||
376 | return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO); | 385 | return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO); |
377 | } | 386 | } |
378 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 387 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
379 | int unxz_main(int argc UNUSED_PARAM, char **argv) | 388 | int unxz_main(int argc UNUSED_PARAM, char **argv) |
380 | { | 389 | { |
381 | int opts = getopt32(argv, "cfvdt"); | 390 | IF_XZ(int opts =) getopt32(argv, "cfvdt"); |
382 | # if ENABLE_XZ | 391 | # if ENABLE_XZ |
383 | /* xz without -d or -t? */ | 392 | /* xz without -d or -t? */ |
384 | if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) | 393 | if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) |
diff --git a/archival/libunarchive/Kbuild.src b/archival/libunarchive/Kbuild.src index 81854558b..a8549570e 100644 --- a/archival/libunarchive/Kbuild.src +++ b/archival/libunarchive/Kbuild.src | |||
@@ -38,6 +38,7 @@ INSERT | |||
38 | lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o | 38 | lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o |
39 | lib-$(CONFIG_BUNZIP2) += decompress_bunzip2.o | 39 | lib-$(CONFIG_BUNZIP2) += decompress_bunzip2.o |
40 | lib-$(CONFIG_UNLZMA) += decompress_unlzma.o | 40 | lib-$(CONFIG_UNLZMA) += decompress_unlzma.o |
41 | lib-$(CONFIG_UNXZ) += decompress_unxz.o | ||
41 | lib-$(CONFIG_CPIO) += get_header_cpio.o | 42 | lib-$(CONFIG_CPIO) += get_header_cpio.o |
42 | lib-$(CONFIG_DPKG) += $(DPKG_FILES) | 43 | lib-$(CONFIG_DPKG) += $(DPKG_FILES) |
43 | lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) | 44 | lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) |
@@ -53,6 +54,7 @@ lib-$(CONFIG_FEATURE_SEAMLESS_BZ2) += open_transformer.o decompress_bunzip2 | |||
53 | lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma.o get_header_tar_lzma.o | 54 | lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma.o get_header_tar_lzma.o |
54 | lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o | 55 | lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o |
55 | lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += decompress_bunzip2.o | 56 | lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += decompress_bunzip2.o |
57 | lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o | ||
56 | 58 | ||
57 | ifneq ($(lib-y),) | 59 | ifneq ($(lib-y),) |
58 | lib-y += $(COMMON_FILES) | 60 | lib-y += $(COMMON_FILES) |
diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c index c4ffe7ef8..00e67d405 100644 --- a/archival/libunarchive/data_extract_all.c +++ b/archival/libunarchive/data_extract_all.c | |||
@@ -127,6 +127,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
127 | break; | 127 | break; |
128 | case S_IFLNK: | 128 | case S_IFLNK: |
129 | /* Symlink */ | 129 | /* Symlink */ |
130 | //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) | ||
130 | res = symlink(file_header->link_target, file_header->name); | 131 | res = symlink(file_header->link_target, file_header->name); |
131 | if ((res == -1) | 132 | if ((res == -1) |
132 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 133 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) |
diff --git a/archival/libunarchive/data_extract_to_command.c b/archival/libunarchive/data_extract_to_command.c new file mode 100644 index 000000000..95f5bc864 --- /dev/null +++ b/archival/libunarchive/data_extract_to_command.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | ||
4 | */ | ||
5 | |||
6 | #include "libbb.h" | ||
7 | #include "unarchive.h" | ||
8 | |||
9 | enum { | ||
10 | //TAR_FILETYPE, | ||
11 | TAR_MODE, | ||
12 | TAR_FILENAME, | ||
13 | TAR_REALNAME, | ||
14 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | ||
15 | TAR_UNAME, | ||
16 | TAR_GNAME, | ||
17 | #endif | ||
18 | TAR_SIZE, | ||
19 | TAR_UID, | ||
20 | TAR_GID, | ||
21 | TAR_MAX, | ||
22 | }; | ||
23 | |||
24 | static const char *const tar_var[] = { | ||
25 | // "FILETYPE", | ||
26 | "MODE", | ||
27 | "FILENAME", | ||
28 | "REALNAME", | ||
29 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | ||
30 | "UNAME", | ||
31 | "GNAME", | ||
32 | #endif | ||
33 | "SIZE", | ||
34 | "UID", | ||
35 | "GID", | ||
36 | }; | ||
37 | |||
38 | static void xputenv(char *str) | ||
39 | { | ||
40 | if (putenv(str)) | ||
41 | bb_error_msg_and_die(bb_msg_memory_exhausted); | ||
42 | } | ||
43 | |||
44 | static void str2env(char *env[], int idx, const char *str) | ||
45 | { | ||
46 | env[idx] = xasprintf("TAR_%s=%s", tar_var[idx], str); | ||
47 | xputenv(env[idx]); | ||
48 | } | ||
49 | |||
50 | static void dec2env(char *env[], int idx, unsigned long long val) | ||
51 | { | ||
52 | env[idx] = xasprintf("TAR_%s=%llu", tar_var[idx], val); | ||
53 | xputenv(env[idx]); | ||
54 | } | ||
55 | |||
56 | static void oct2env(char *env[], int idx, unsigned long val) | ||
57 | { | ||
58 | env[idx] = xasprintf("TAR_%s=%lo", tar_var[idx], val); | ||
59 | xputenv(env[idx]); | ||
60 | } | ||
61 | |||
62 | void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle) | ||
63 | { | ||
64 | file_header_t *file_header = archive_handle->file_header; | ||
65 | |||
66 | #if 0 /* do we need this? ENABLE_FEATURE_TAR_SELINUX */ | ||
67 | char *sctx = archive_handle->tar__next_file_sctx; | ||
68 | if (!sctx) | ||
69 | sctx = archive_handle->tar__global_sctx; | ||
70 | if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */ | ||
71 | setfscreatecon(sctx); | ||
72 | free(archive_handle->tar__next_file_sctx); | ||
73 | archive_handle->tar__next_file_sctx = NULL; | ||
74 | } | ||
75 | #endif | ||
76 | |||
77 | if ((file_header->mode & S_IFMT) == S_IFREG) { | ||
78 | pid_t pid; | ||
79 | int p[2], status; | ||
80 | char *tar_env[TAR_MAX]; | ||
81 | |||
82 | memset(tar_env, 0, sizeof(tar_env)); | ||
83 | |||
84 | xpipe(p); | ||
85 | pid = BB_MMU ? xfork() : xvfork(); | ||
86 | if (pid == 0) { | ||
87 | /* Child */ | ||
88 | /* str2env(tar_env, TAR_FILETYPE, "f"); - parent should do it once */ | ||
89 | oct2env(tar_env, TAR_MODE, file_header->mode); | ||
90 | str2env(tar_env, TAR_FILENAME, file_header->name); | ||
91 | str2env(tar_env, TAR_REALNAME, file_header->name); | ||
92 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | ||
93 | str2env(tar_env, TAR_UNAME, file_header->tar__uname); | ||
94 | str2env(tar_env, TAR_GNAME, file_header->tar__gname); | ||
95 | #endif | ||
96 | dec2env(tar_env, TAR_SIZE, file_header->size); | ||
97 | dec2env(tar_env, TAR_UID, file_header->uid); | ||
98 | dec2env(tar_env, TAR_GID, file_header->gid); | ||
99 | close(p[1]); | ||
100 | xdup2(p[0], STDIN_FILENO); | ||
101 | signal(SIGPIPE, SIG_DFL); | ||
102 | execl(DEFAULT_SHELL, DEFAULT_SHELL_SHORT_NAME, "-c", archive_handle->tar__to_command, NULL); | ||
103 | bb_perror_msg_and_die("can't execute '%s'", DEFAULT_SHELL); | ||
104 | } | ||
105 | close(p[0]); | ||
106 | /* Our caller is expected to do signal(SIGPIPE, SIG_IGN) | ||
107 | * so that we don't die if child don't read all the input: */ | ||
108 | bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size); | ||
109 | close(p[1]); | ||
110 | |||
111 | if (safe_waitpid(pid, &status, 0) == -1) | ||
112 | bb_perror_msg_and_die("waitpid"); | ||
113 | if (WIFEXITED(status) && WEXITSTATUS(status)) | ||
114 | bb_error_msg_and_die("'%s' returned status %d", | ||
115 | archive_handle->tar__to_command, WEXITSTATUS(status)); | ||
116 | if (WIFSIGNALED(status)) | ||
117 | bb_error_msg_and_die("'%s' terminated on signal %d", | ||
118 | archive_handle->tar__to_command, WTERMSIG(status)); | ||
119 | |||
120 | if (!BB_MMU) { | ||
121 | int i; | ||
122 | for (i = 0; i < TAR_MAX; i++) { | ||
123 | if (tar_env[i]) | ||
124 | bb_unsetenv_and_free(tar_env[i]); | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | |||
129 | #if 0 /* ENABLE_FEATURE_TAR_SELINUX */ | ||
130 | if (sctx) | ||
131 | /* reset the context after creating an entry */ | ||
132 | setfscreatecon(NULL); | ||
133 | #endif | ||
134 | } | ||
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c index cd8df086e..bdbd39ac2 100644 --- a/archival/libunarchive/decompress_bunzip2.c +++ b/archival/libunarchive/decompress_bunzip2.c | |||
@@ -692,9 +692,9 @@ unpack_bz2_stream(int src_fd, int dst_fd) | |||
692 | IF_DESKTOP(long long) int FAST_FUNC | 692 | IF_DESKTOP(long long) int FAST_FUNC |
693 | unpack_bz2_stream_prime(int src_fd, int dst_fd) | 693 | unpack_bz2_stream_prime(int src_fd, int dst_fd) |
694 | { | 694 | { |
695 | unsigned char magic[2]; | 695 | uint16_t magic2; |
696 | xread(src_fd, magic, 2); | 696 | xread(src_fd, &magic2, 2); |
697 | if (magic[0] != 'B' || magic[1] != 'Z') { | 697 | if (magic2 != BZIP2_MAGIC) { |
698 | bb_error_msg_and_die("invalid magic"); | 698 | bb_error_msg_and_die("invalid magic"); |
699 | } | 699 | } |
700 | return unpack_bz2_stream(src_fd, dst_fd); | 700 | return unpack_bz2_stream(src_fd, dst_fd); |
diff --git a/archival/libunarchive/decompress_unxz.c b/archival/libunarchive/decompress_unxz.c index 1302e29fb..721acd907 100644 --- a/archival/libunarchive/decompress_unxz.c +++ b/archival/libunarchive/decompress_unxz.c | |||
@@ -12,10 +12,11 @@ | |||
12 | #include "libbb.h" | 12 | #include "libbb.h" |
13 | #include "unarchive.h" | 13 | #include "unarchive.h" |
14 | 14 | ||
15 | #define XZ_REALLOC_DICT_BUF(ptr, size) xrealloc(ptr, size) | ||
16 | #define XZ_FUNC FAST_FUNC | 15 | #define XZ_FUNC FAST_FUNC |
17 | #define XZ_EXTERN static | 16 | #define XZ_EXTERN static |
18 | 17 | ||
18 | #define XZ_DEC_DYNALLOC | ||
19 | |||
19 | /* Skip check (rather than fail) of unsupported hash functions */ | 20 | /* Skip check (rather than fail) of unsupported hash functions */ |
20 | #define XZ_DEC_ANY_CHECK 1 | 21 | #define XZ_DEC_ANY_CHECK 1 |
21 | 22 | ||
@@ -40,15 +41,9 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) | |||
40 | #define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val)) | 41 | #define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val)) |
41 | #define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val)) | 42 | #define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val)) |
42 | 43 | ||
43 | #include "unxz/xz.h" | ||
44 | #include "unxz/xz_config.h" | ||
45 | |||
46 | #include "unxz/xz_dec_bcj.c" | 44 | #include "unxz/xz_dec_bcj.c" |
47 | #include "unxz/xz_dec_lzma2.c" | 45 | #include "unxz/xz_dec_lzma2.c" |
48 | #include "unxz/xz_dec_stream.c" | 46 | #include "unxz/xz_dec_stream.c" |
49 | #include "unxz/xz_lzma2.h" | ||
50 | #include "unxz/xz_private.h" | ||
51 | #include "unxz/xz_stream.h" | ||
52 | 47 | ||
53 | IF_DESKTOP(long long) int FAST_FUNC | 48 | IF_DESKTOP(long long) int FAST_FUNC |
54 | unpack_xz_stream(int src_fd, int dst_fd) | 49 | unpack_xz_stream(int src_fd, int dst_fd) |
@@ -57,55 +52,45 @@ unpack_xz_stream(int src_fd, int dst_fd) | |||
57 | struct xz_dec *state; | 52 | struct xz_dec *state; |
58 | unsigned char *membuf; | 53 | unsigned char *membuf; |
59 | IF_DESKTOP(long long) int total = 0; | 54 | IF_DESKTOP(long long) int total = 0; |
60 | enum { | ||
61 | IN_SIZE = 4 * 1024, | ||
62 | OUT_SIZE = 60 * 1024, | ||
63 | }; | ||
64 | 55 | ||
65 | if (!crc32_table) | 56 | if (!crc32_table) |
66 | crc32_table = crc32_filltable(NULL, /*endian:*/ 0); | 57 | crc32_table = crc32_filltable(NULL, /*endian:*/ 0); |
67 | 58 | ||
68 | membuf = xmalloc(IN_SIZE + OUT_SIZE); | ||
69 | memset(&iobuf, 0, sizeof(iobuf)); | 59 | memset(&iobuf, 0, sizeof(iobuf)); |
60 | /* Preload XZ file signature */ | ||
61 | membuf = (void*) strcpy(xmalloc(2 * BUFSIZ), HEADER_MAGIC); | ||
70 | iobuf.in = membuf; | 62 | iobuf.in = membuf; |
71 | iobuf.out = membuf + IN_SIZE; | 63 | iobuf.in_size = HEADER_MAGIC_SIZE; |
72 | iobuf.out_size = OUT_SIZE; | 64 | iobuf.out = membuf + BUFSIZ; |
65 | iobuf.out_size = BUFSIZ; | ||
73 | 66 | ||
74 | state = xz_dec_init(64*1024); /* initial dict of 64k */ | 67 | /* Limit memory usage to about 64 MiB. */ |
68 | state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024); | ||
75 | 69 | ||
76 | while (1) { | 70 | while (1) { |
77 | enum xz_ret r; | 71 | enum xz_ret r; |
78 | int insz, rd, outpos; | ||
79 | 72 | ||
80 | iobuf.in_size -= iobuf.in_pos; | 73 | if (iobuf.in_pos == iobuf.in_size) { |
81 | insz = iobuf.in_size; | 74 | int rd = safe_read(src_fd, membuf, BUFSIZ); |
82 | if (insz) | ||
83 | memmove(membuf, membuf + iobuf.in_pos, insz); | ||
84 | iobuf.in_pos = 0; | ||
85 | rd = IN_SIZE - insz; | ||
86 | if (rd) { | ||
87 | rd = safe_read(src_fd, membuf + insz, rd); | ||
88 | if (rd < 0) { | 75 | if (rd < 0) { |
89 | bb_error_msg(bb_msg_read_error); | 76 | bb_error_msg(bb_msg_read_error); |
90 | total = -1; | 77 | total = -1; |
91 | break; | 78 | break; |
92 | } | 79 | } |
93 | iobuf.in_size = insz + rd; | 80 | iobuf.in_size = rd; |
81 | iobuf.in_pos = 0; | ||
94 | } | 82 | } |
95 | // bb_error_msg(">in pos:%d size:%d out pos:%d size:%d", | 83 | // bb_error_msg(">in pos:%d size:%d out pos:%d size:%d", |
96 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size); | 84 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size); |
97 | r = xz_dec_run(state, &iobuf); | 85 | r = xz_dec_run(state, &iobuf); |
98 | // bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d", | 86 | // bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d", |
99 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r); | 87 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r); |
100 | outpos = iobuf.out_pos; | 88 | if (iobuf.out_pos) { |
101 | if (outpos) { | 89 | xwrite(dst_fd, iobuf.out, iobuf.out_pos); |
102 | xwrite(dst_fd, iobuf.out, outpos); | 90 | IF_DESKTOP(total += iobuf.out_pos;) |
103 | IF_DESKTOP(total += outpos;) | 91 | iobuf.out_pos = 0; |
104 | } | 92 | } |
105 | if (r == XZ_STREAM_END | 93 | if (r == XZ_STREAM_END) { |
106 | /* this happens even with well-formed files: */ | ||
107 | || (r == XZ_BUF_ERROR && insz == 0 && outpos == 0) | ||
108 | ) { | ||
109 | break; | 94 | break; |
110 | } | 95 | } |
111 | if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) { | 96 | if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) { |
@@ -113,7 +98,6 @@ unpack_xz_stream(int src_fd, int dst_fd) | |||
113 | total = -1; | 98 | total = -1; |
114 | break; | 99 | break; |
115 | } | 100 | } |
116 | iobuf.out_pos = 0; | ||
117 | } | 101 | } |
118 | xz_dec_end(state); | 102 | xz_dec_end(state); |
119 | free(membuf); | 103 | free(membuf); |
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index fcddcb834..d5c92359c 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c | |||
@@ -118,34 +118,10 @@ static char *get_selinux_sctx_from_pax_hdr(archive_handle_t *archive_handle, uns | |||
118 | } | 118 | } |
119 | #endif | 119 | #endif |
120 | 120 | ||
121 | void BUG_tar_header_size(void); | ||
122 | char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | 121 | char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) |
123 | { | 122 | { |
124 | file_header_t *file_header = archive_handle->file_header; | 123 | file_header_t *file_header = archive_handle->file_header; |
125 | struct { | 124 | struct tar_header_t tar; |
126 | /* ustar header, Posix 1003.1 */ | ||
127 | char name[100]; /* 0-99 */ | ||
128 | char mode[8]; /* 100-107 */ | ||
129 | char uid[8]; /* 108-115 */ | ||
130 | char gid[8]; /* 116-123 */ | ||
131 | char size[12]; /* 124-135 */ | ||
132 | char mtime[12]; /* 136-147 */ | ||
133 | char chksum[8]; /* 148-155 */ | ||
134 | char typeflag; /* 156-156 */ | ||
135 | char linkname[100]; /* 157-256 */ | ||
136 | /* POSIX: "ustar" NUL "00" */ | ||
137 | /* GNU tar: "ustar " NUL */ | ||
138 | /* Normally it's defined as magic[6] followed by | ||
139 | * version[2], but we put them together to simplify code | ||
140 | */ | ||
141 | char magic[8]; /* 257-264 */ | ||
142 | char uname[32]; /* 265-296 */ | ||
143 | char gname[32]; /* 297-328 */ | ||
144 | char devmajor[8]; /* 329-336 */ | ||
145 | char devminor[8]; /* 337-344 */ | ||
146 | char prefix[155]; /* 345-499 */ | ||
147 | char padding[12]; /* 500-512 */ | ||
148 | } tar; | ||
149 | char *cp; | 125 | char *cp; |
150 | int i, sum_u, sum; | 126 | int i, sum_u, sum; |
151 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY | 127 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY |
@@ -162,9 +138,6 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
162 | # define p_linkname 0 | 138 | # define p_linkname 0 |
163 | #endif | 139 | #endif |
164 | 140 | ||
165 | if (sizeof(tar) != 512) | ||
166 | BUG_tar_header_size(); | ||
167 | |||
168 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS || ENABLE_FEATURE_TAR_SELINUX | 141 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS || ENABLE_FEATURE_TAR_SELINUX |
169 | again: | 142 | again: |
170 | #endif | 143 | #endif |
@@ -223,25 +196,31 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
223 | ) { | 196 | ) { |
224 | #if ENABLE_FEATURE_TAR_AUTODETECT | 197 | #if ENABLE_FEATURE_TAR_AUTODETECT |
225 | char FAST_FUNC (*get_header_ptr)(archive_handle_t *); | 198 | char FAST_FUNC (*get_header_ptr)(archive_handle_t *); |
199 | uint16_t magic2; | ||
226 | 200 | ||
227 | autodetect: | 201 | autodetect: |
202 | magic2 = *(uint16_t*)tar.name; | ||
228 | /* tar gz/bz autodetect: check for gz/bz2 magic. | 203 | /* tar gz/bz autodetect: check for gz/bz2 magic. |
229 | * If we see the magic, and it is the very first block, | 204 | * If we see the magic, and it is the very first block, |
230 | * we can switch to get_header_tar_gz/bz2/lzma(). | 205 | * we can switch to get_header_tar_gz/bz2/lzma(). |
231 | * Needs seekable fd. I wish recv(MSG_PEEK) works | 206 | * Needs seekable fd. I wish recv(MSG_PEEK) works |
232 | * on any fd... */ | 207 | * on any fd... */ |
233 | #if ENABLE_FEATURE_SEAMLESS_GZ | 208 | # if ENABLE_FEATURE_SEAMLESS_GZ |
234 | if (tar.name[0] == 0x1f && tar.name[1] == (char)0x8b) { /* gzip */ | 209 | if (magic2 == GZIP_MAGIC) { |
235 | get_header_ptr = get_header_tar_gz; | 210 | get_header_ptr = get_header_tar_gz; |
236 | } else | 211 | } else |
237 | #endif | 212 | # endif |
238 | #if ENABLE_FEATURE_SEAMLESS_BZ2 | 213 | # if ENABLE_FEATURE_SEAMLESS_BZ2 |
239 | if (tar.name[0] == 'B' && tar.name[1] == 'Z' | 214 | if (magic2 == BZIP2_MAGIC |
240 | && tar.name[2] == 'h' && isdigit(tar.name[3]) | 215 | && tar.name[2] == 'h' && isdigit(tar.name[3]) |
241 | ) { /* bzip2 */ | 216 | ) { /* bzip2 */ |
242 | get_header_ptr = get_header_tar_bz2; | 217 | get_header_ptr = get_header_tar_bz2; |
243 | } else | 218 | } else |
244 | #endif | 219 | # endif |
220 | # if ENABLE_FEATURE_SEAMLESS_XZ | ||
221 | //TODO: if (magic2 == XZ_MAGIC1)... | ||
222 | //else | ||
223 | # endif | ||
245 | goto err; | 224 | goto err; |
246 | /* Two different causes for lseek() != 0: | 225 | /* Two different causes for lseek() != 0: |
247 | * unseekable fd (would like to support that too, but...), | 226 | * unseekable fd (would like to support that too, but...), |
@@ -460,9 +439,11 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
460 | /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */ | 439 | /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */ |
461 | if (cp) | 440 | if (cp) |
462 | *cp = '\0'; | 441 | *cp = '\0'; |
463 | //archive_handle->ah_flags |= ARCHIVE_EXTRACT_QUIET; // why?? | ||
464 | archive_handle->action_data(archive_handle); | 442 | archive_handle->action_data(archive_handle); |
465 | llist_add_to(&(archive_handle->passed), file_header->name); | 443 | if (archive_handle->accept || archive_handle->reject) |
444 | llist_add_to(&archive_handle->passed, file_header->name); | ||
445 | else /* Caller isn't interested in list of unpacked files */ | ||
446 | free(file_header->name); | ||
466 | } else { | 447 | } else { |
467 | data_skip(archive_handle); | 448 | data_skip(archive_handle); |
468 | free(file_header->name); | 449 | free(file_header->name); |
@@ -470,7 +451,8 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
470 | archive_handle->offset += file_header->size; | 451 | archive_handle->offset += file_header->size; |
471 | 452 | ||
472 | free(file_header->link_target); | 453 | free(file_header->link_target); |
473 | /* Do not free(file_header->name)! (why?) */ | 454 | /* Do not free(file_header->name)! |
455 | * It might be inserted in archive_handle->passed - see above */ | ||
474 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | 456 | #if ENABLE_FEATURE_TAR_UNAME_GNAME |
475 | free(file_header->tar__uname); | 457 | free(file_header->tar__uname); |
476 | free(file_header->tar__gname); | 458 | free(file_header->tar__gname); |
diff --git a/archival/libunarchive/open_transformer.c b/archival/libunarchive/open_transformer.c index 47c13e6f4..cba049f1f 100644 --- a/archival/libunarchive/open_transformer.c +++ b/archival/libunarchive/open_transformer.c | |||
@@ -19,19 +19,9 @@ void FAST_FUNC open_transformer(int fd, | |||
19 | int pid; | 19 | int pid; |
20 | 20 | ||
21 | xpiped_pair(fd_pipe); | 21 | xpiped_pair(fd_pipe); |
22 | 22 | pid = BB_MMU ? xfork() : xvfork(); | |
23 | #if BB_MMU | ||
24 | pid = fork(); | ||
25 | if (pid == -1) | ||
26 | bb_perror_msg_and_die("vfork" + 1); | ||
27 | #else | ||
28 | pid = vfork(); | ||
29 | if (pid == -1) | ||
30 | bb_perror_msg_and_die("vfork"); | ||
31 | #endif | ||
32 | |||
33 | if (pid == 0) { | 23 | if (pid == 0) { |
34 | /* child process */ | 24 | /* Child */ |
35 | close(fd_pipe.rd); /* we don't want to read from the parent */ | 25 | close(fd_pipe.rd); /* we don't want to read from the parent */ |
36 | // FIXME: error check? | 26 | // FIXME: error check? |
37 | #if BB_MMU | 27 | #if BB_MMU |
diff --git a/archival/libunarchive/unxz/xz.h b/archival/libunarchive/unxz/xz.h index eb82706b9..c6c071c4a 100644 --- a/archival/libunarchive/unxz/xz.h +++ b/archival/libunarchive/unxz/xz.h | |||
@@ -30,9 +30,42 @@ | |||
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * enum xz_mode - Operation mode | ||
34 | * | ||
35 | * @XZ_SINGLE: Single-call mode. This uses less RAM than | ||
36 | * than multi-call modes, because the LZMA2 | ||
37 | * dictionary doesn't need to be allocated as | ||
38 | * part of the decoder state. All required data | ||
39 | * structures are allocated at initialization, | ||
40 | * so xz_dec_run() cannot return XZ_MEM_ERROR. | ||
41 | * @XZ_PREALLOC: Multi-call mode with preallocated LZMA2 | ||
42 | * dictionary buffer. All data structures are | ||
43 | * allocated at initialization, so xz_dec_run() | ||
44 | * cannot return XZ_MEM_ERROR. | ||
45 | * @XZ_DYNALLOC: Multi-call mode. The LZMA2 dictionary is | ||
46 | * allocated once the required size has been | ||
47 | * parsed from the stream headers. If the | ||
48 | * allocation fails, xz_dec_run() will return | ||
49 | * XZ_MEM_ERROR. | ||
50 | * | ||
51 | * It is possible to enable support only for a subset of the above | ||
52 | * modes at compile time by defining XZ_DEC_SINGLE, XZ_DEC_PREALLOC, | ||
53 | * or XZ_DEC_DYNALLOC. The xz_dec kernel module is always compiled | ||
54 | * with support for all operation modes, but the preboot code may | ||
55 | * be built with fewer features to minimize code size. | ||
56 | */ | ||
57 | enum xz_mode { | ||
58 | XZ_SINGLE, | ||
59 | XZ_PREALLOC, | ||
60 | XZ_DYNALLOC | ||
61 | }; | ||
62 | |||
63 | /** | ||
33 | * enum xz_ret - Return codes | 64 | * enum xz_ret - Return codes |
34 | * @XZ_OK: Everything is OK so far. More input or more | 65 | * @XZ_OK: Everything is OK so far. More input or more |
35 | * output space is required to continue. | 66 | * output space is required to continue. This |
67 | * return code is possible only in multi-call mode | ||
68 | * (XZ_PREALLOC or XZ_DYNALLOC). | ||
36 | * @XZ_STREAM_END: Operation finished successfully. | 69 | * @XZ_STREAM_END: Operation finished successfully. |
37 | * @XZ_UNSUPPORTED_CHECK: Integrity check type is not supported. Decoding | 70 | * @XZ_UNSUPPORTED_CHECK: Integrity check type is not supported. Decoding |
38 | * is still possible in multi-call mode by simply | 71 | * is still possible in multi-call mode by simply |
@@ -42,8 +75,17 @@ | |||
42 | * which is not used in the kernel. Unsupported | 75 | * which is not used in the kernel. Unsupported |
43 | * check types return XZ_OPTIONS_ERROR if | 76 | * check types return XZ_OPTIONS_ERROR if |
44 | * XZ_DEC_ANY_CHECK was not defined at build time. | 77 | * XZ_DEC_ANY_CHECK was not defined at build time. |
45 | * @XZ_MEMLIMIT_ERROR: Not enough memory was preallocated at decoder | 78 | * @XZ_MEM_ERROR: Allocating memory failed. This return code is |
46 | * initialization time. | 79 | * possible only if the decoder was initialized |
80 | * with XZ_DYNALLOC. The amount of memory that was | ||
81 | * tried to be allocated was no more than the | ||
82 | * dict_max argument given to xz_dec_init(). | ||
83 | * @XZ_MEMLIMIT_ERROR: A bigger LZMA2 dictionary would be needed than | ||
84 | * allowed by the dict_max argument given to | ||
85 | * xz_dec_init(). This return value is possible | ||
86 | * only in multi-call mode (XZ_PREALLOC or | ||
87 | * XZ_DYNALLOC); the single-call mode (XZ_SINGLE) | ||
88 | * ignores the dict_max argument. | ||
47 | * @XZ_FORMAT_ERROR: File format was not recognized (wrong magic | 89 | * @XZ_FORMAT_ERROR: File format was not recognized (wrong magic |
48 | * bytes). | 90 | * bytes). |
49 | * @XZ_OPTIONS_ERROR: This implementation doesn't support the requested | 91 | * @XZ_OPTIONS_ERROR: This implementation doesn't support the requested |
@@ -72,6 +114,7 @@ enum xz_ret { | |||
72 | XZ_OK, | 114 | XZ_OK, |
73 | XZ_STREAM_END, | 115 | XZ_STREAM_END, |
74 | XZ_UNSUPPORTED_CHECK, | 116 | XZ_UNSUPPORTED_CHECK, |
117 | XZ_MEM_ERROR, | ||
75 | XZ_MEMLIMIT_ERROR, | 118 | XZ_MEMLIMIT_ERROR, |
76 | XZ_FORMAT_ERROR, | 119 | XZ_FORMAT_ERROR, |
77 | XZ_OPTIONS_ERROR, | 120 | XZ_OPTIONS_ERROR, |
@@ -112,61 +155,67 @@ struct xz_dec; | |||
112 | 155 | ||
113 | /** | 156 | /** |
114 | * xz_dec_init() - Allocate and initialize a XZ decoder state | 157 | * xz_dec_init() - Allocate and initialize a XZ decoder state |
158 | * @mode: Operation mode | ||
115 | * @dict_max: Maximum size of the LZMA2 dictionary (history buffer) for | 159 | * @dict_max: Maximum size of the LZMA2 dictionary (history buffer) for |
116 | * multi-call decoding, or special value of zero to indicate | 160 | * multi-call decoding. This is ignored in single-call mode |
117 | * single-call decoding mode. | 161 | * (mode == XZ_SINGLE). LZMA2 dictionary is always 2^n bytes |
118 | * | 162 | * or 2^n + 2^(n-1) bytes (the latter sizes are less common |
119 | * If dict_max > 0, the decoder is initialized to work in multi-call mode. | 163 | * in practice), so other values for dict_max don't make sense. |
120 | * dict_max number of bytes of memory is preallocated for the LZMA2 | 164 | * In the kernel, dictionary sizes of 64 KiB, 128 KiB, 256 KiB, |
121 | * dictionary. This way there is no risk that xz_dec_run() could run out | 165 | * 512 KiB, and 1 MiB are probably the only reasonable values, |
122 | * of memory, since xz_dec_run() will never allocate any memory. Instead, | 166 | * except for kernel and initramfs images where a bigger |
123 | * if the preallocated dictionary is too small for decoding the given input | 167 | * dictionary can be fine and useful. |
124 | * stream, xz_dec_run() will return XZ_MEMLIMIT_ERROR. Thus, it is important | 168 | * |
125 | * to know what kind of data will be decoded to avoid allocating excessive | 169 | * Single-call mode (XZ_SINGLE): xz_dec_run() decodes the whole stream at |
126 | * amount of memory for the dictionary. | 170 | * once. The caller must provide enough output space or the decoding will |
127 | * | 171 | * fail. The output space is used as the dictionary buffer, which is why |
128 | * LZMA2 dictionary is always 2^n bytes or 2^n + 2^(n-1) bytes (the latter | 172 | * there is no need to allocate the dictionary as part of the decoder's |
129 | * sizes are less common in practice). In the kernel, dictionary sizes of | 173 | * internal state. |
130 | * 64 KiB, 128 KiB, 256 KiB, 512 KiB, and 1 MiB are probably the only | ||
131 | * reasonable values. | ||
132 | * | ||
133 | * If dict_max == 0, the decoder is initialized to work in single-call mode. | ||
134 | * In single-call mode, xz_dec_run() decodes the whole stream at once. The | ||
135 | * caller must provide enough output space or the decoding will fail. The | ||
136 | * output space is used as the dictionary buffer, which is why there is | ||
137 | * no need to allocate the dictionary as part of the decoder's internal | ||
138 | * state. | ||
139 | * | 174 | * |
140 | * Because the output buffer is used as the workspace, streams encoded using | 175 | * Because the output buffer is used as the workspace, streams encoded using |
141 | * a big dictionary are not a problem in single-call. It is enough that the | 176 | * a big dictionary are not a problem in single-call mode. It is enough that |
142 | * output buffer is big enough to hold the actual uncompressed data; it | 177 | * the output buffer is big enough to hold the actual uncompressed data; it |
143 | * can be smaller than the dictionary size stored in the stream headers. | 178 | * can be smaller than the dictionary size stored in the stream headers. |
144 | * | 179 | * |
180 | * Multi-call mode with preallocated dictionary (XZ_PREALLOC): dict_max bytes | ||
181 | * of memory is preallocated for the LZMA2 dictionary. This way there is no | ||
182 | * risk that xz_dec_run() could run out of memory, since xz_dec_run() will | ||
183 | * never allocate any memory. Instead, if the preallocated dictionary is too | ||
184 | * small for decoding the given input stream, xz_dec_run() will return | ||
185 | * XZ_MEMLIMIT_ERROR. Thus, it is important to know what kind of data will be | ||
186 | * decoded to avoid allocating excessive amount of memory for the dictionary. | ||
187 | * | ||
188 | * Multi-call mode with dynamically allocated dictionary (XZ_DYNALLOC): | ||
189 | * dict_max specifies the maximum allowed dictionary size that xz_dec_run() | ||
190 | * may allocate once it has parsed the dictionary size from the stream | ||
191 | * headers. This way excessive allocations can be avoided while still | ||
192 | * limiting the maximum memory usage to a sane value to prevent running the | ||
193 | * system out of memory when decompressing streams from untrusted sources. | ||
194 | * | ||
145 | * On success, xz_dec_init() returns a pointer to struct xz_dec, which is | 195 | * On success, xz_dec_init() returns a pointer to struct xz_dec, which is |
146 | * ready to be used with xz_dec_run(). On error, xz_dec_init() returns NULL. | 196 | * ready to be used with xz_dec_run(). If memory allocation fails, |
197 | * xz_dec_init() returns NULL. | ||
147 | */ | 198 | */ |
148 | XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init(uint32_t dict_max); | 199 | XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init( |
200 | enum xz_mode mode, uint32_t dict_max); | ||
149 | 201 | ||
150 | /** | 202 | /** |
151 | * xz_dec_run() - Run the XZ decoder | 203 | * xz_dec_run() - Run the XZ decoder |
152 | * @s: Decoder state allocated using xz_dec_init() | 204 | * @s: Decoder state allocated using xz_dec_init() |
153 | * @b: Input and output buffers | 205 | * @b: Input and output buffers |
154 | * | 206 | * |
155 | * In multi-call mode, this function may return any of the values listed in | 207 | * The possible return values depend on build options and operation mode. |
156 | * enum xz_ret. | 208 | * See enum xz_ret for details. |
157 | * | 209 | * |
158 | * In single-call mode, this function never returns XZ_OK. If an error occurs | 210 | * NOTE: If an error occurs in single-call mode (return value is not |
159 | * in single-call mode (return value is not XZ_STREAM_END), b->in_pos and | 211 | * XZ_STREAM_END), b->in_pos and b->out_pos are not modified, and the |
160 | * b->out_pos are not modified, and the contents of the output buffer from | 212 | * contents of the output buffer from b->out[b->out_pos] onward are |
161 | * b->out[b->out_pos] onward are undefined. | 213 | * undefined. This is true even after XZ_BUF_ERROR, because with some filter |
162 | * | 214 | * chains, there may be a second pass over the output buffer, and this pass |
163 | * NOTE: In single-call mode, the contents of the output buffer are undefined | 215 | * cannot be properly done if the output buffer is truncated. Thus, you |
164 | * also after XZ_BUF_ERROR. This is because with some filter chains, there | 216 | * cannot give the single-call decoder a too small buffer and then expect to |
165 | * may be a second pass over the output buffer, and this pass cannot be | 217 | * get that amount valid data from the beginning of the stream. You must use |
166 | * properly done if the output buffer is truncated. Thus, you cannot give | 218 | * the multi-call decoder if you don't want to uncompress the whole stream. |
167 | * the single-call decoder a too small buffer and then expect to get that | ||
168 | * amount valid data from the beginning of the stream. You must use the | ||
169 | * multi-call decoder if you don't want to uncompress the whole stream. | ||
170 | */ | 219 | */ |
171 | XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b); | 220 | XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b); |
172 | 221 | ||
diff --git a/archival/libunarchive/unxz/xz_config.h b/archival/libunarchive/unxz/xz_config.h index ff90eff26..187e1cbed 100644 --- a/archival/libunarchive/unxz/xz_config.h +++ b/archival/libunarchive/unxz/xz_config.h | |||
@@ -32,6 +32,8 @@ | |||
32 | #define memeq(a, b, size) (memcmp(a, b, size) == 0) | 32 | #define memeq(a, b, size) (memcmp(a, b, size) == 0) |
33 | #define memzero(buf, size) memset(buf, 0, size) | 33 | #define memzero(buf, size) memset(buf, 0, size) |
34 | 34 | ||
35 | #undef min | ||
36 | #undef min_t | ||
35 | #define min(x, y) ((x) < (y) ? (x) : (y)) | 37 | #define min(x, y) ((x) < (y) ? (x) : (y)) |
36 | #define min_t(type, x, y) min(x, y) | 38 | #define min_t(type, x, y) min(x, y) |
37 | 39 | ||
diff --git a/archival/libunarchive/unxz/xz_dec_lzma2.c b/archival/libunarchive/unxz/xz_dec_lzma2.c index 37de6fc32..da71cb4d4 100644 --- a/archival/libunarchive/unxz/xz_dec_lzma2.c +++ b/archival/libunarchive/unxz/xz_dec_lzma2.c | |||
@@ -34,7 +34,8 @@ | |||
34 | * | 34 | * |
35 | * In multi-call mode, also these are true: | 35 | * In multi-call mode, also these are true: |
36 | * end == size | 36 | * end == size |
37 | * size <= allocated | 37 | * size <= size_max |
38 | * allocated <= size | ||
38 | * | 39 | * |
39 | * Most of these variables are size_t to support single-call mode, | 40 | * Most of these variables are size_t to support single-call mode, |
40 | * in which the dictionary variables address the actual output | 41 | * in which the dictionary variables address the actual output |
@@ -74,11 +75,20 @@ struct dictionary { | |||
74 | uint32_t size; | 75 | uint32_t size; |
75 | 76 | ||
76 | /* | 77 | /* |
77 | * Amount of memory allocated for the dictionary. A special | 78 | * Maximum allowed dictionary size in multi-call mode. |
78 | * value of zero indicates that we are in single-call mode, | 79 | * This is ignored in single-call mode. |
79 | * where the output buffer works as the dictionary. | 80 | */ |
81 | uint32_t size_max; | ||
82 | |||
83 | /* | ||
84 | * Amount of memory currently allocated for the dictionary. | ||
85 | * This is used only with XZ_DYNALLOC. (With XZ_PREALLOC, | ||
86 | * size_max is always the same as the allocated size.) | ||
80 | */ | 87 | */ |
81 | uint32_t allocated; | 88 | uint32_t allocated; |
89 | |||
90 | /* Operation mode */ | ||
91 | enum xz_mode mode; | ||
82 | }; | 92 | }; |
83 | 93 | ||
84 | /* Range decoder */ | 94 | /* Range decoder */ |
@@ -120,31 +130,31 @@ struct lzma_len_dec { | |||
120 | }; | 130 | }; |
121 | 131 | ||
122 | struct lzma_dec { | 132 | struct lzma_dec { |
123 | /* | ||
124 | * LZMA properties or related bit masks (number of literal | ||
125 | * context bits, a mask dervied from the number of literal | ||
126 | * position bits, and a mask dervied from the number | ||
127 | * position bits) | ||
128 | */ | ||
129 | uint32_t lc; | ||
130 | uint32_t literal_pos_mask; /* (1 << lp) - 1 */ | ||
131 | uint32_t pos_mask; /* (1 << pb) - 1 */ | ||
132 | |||
133 | /* Types of the most recently seen LZMA symbols */ | ||
134 | enum lzma_state state; | ||
135 | |||
136 | /* Distances of latest four matches */ | 133 | /* Distances of latest four matches */ |
137 | uint32_t rep0; | 134 | uint32_t rep0; |
138 | uint32_t rep1; | 135 | uint32_t rep1; |
139 | uint32_t rep2; | 136 | uint32_t rep2; |
140 | uint32_t rep3; | 137 | uint32_t rep3; |
141 | 138 | ||
139 | /* Types of the most recently seen LZMA symbols */ | ||
140 | enum lzma_state state; | ||
141 | |||
142 | /* | 142 | /* |
143 | * Length of a match. This is updated so that dict_repeat can | 143 | * Length of a match. This is updated so that dict_repeat can |
144 | * be called again to finish repeating the whole match. | 144 | * be called again to finish repeating the whole match. |
145 | */ | 145 | */ |
146 | uint32_t len; | 146 | uint32_t len; |
147 | 147 | ||
148 | /* | ||
149 | * LZMA properties or related bit masks (number of literal | ||
150 | * context bits, a mask dervied from the number of literal | ||
151 | * position bits, and a mask dervied from the number | ||
152 | * position bits) | ||
153 | */ | ||
154 | uint32_t lc; | ||
155 | uint32_t literal_pos_mask; /* (1 << lp) - 1 */ | ||
156 | uint32_t pos_mask; /* (1 << pb) - 1 */ | ||
157 | |||
148 | /* If 1, it's a match. Otherwise it's a single 8-bit literal. */ | 158 | /* If 1, it's a match. Otherwise it's a single 8-bit literal. */ |
149 | uint16_t is_match[STATES][POS_STATES_MAX]; | 159 | uint16_t is_match[STATES][POS_STATES_MAX]; |
150 | 160 | ||
@@ -201,49 +211,59 @@ struct lzma_dec { | |||
201 | uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE]; | 211 | uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE]; |
202 | }; | 212 | }; |
203 | 213 | ||
214 | struct lzma2_dec { | ||
215 | /* Position in xz_dec_lzma2_run(). */ | ||
216 | enum lzma2_seq { | ||
217 | SEQ_CONTROL, | ||
218 | SEQ_UNCOMPRESSED_1, | ||
219 | SEQ_UNCOMPRESSED_2, | ||
220 | SEQ_COMPRESSED_0, | ||
221 | SEQ_COMPRESSED_1, | ||
222 | SEQ_PROPERTIES, | ||
223 | SEQ_LZMA_PREPARE, | ||
224 | SEQ_LZMA_RUN, | ||
225 | SEQ_COPY | ||
226 | } sequence; | ||
227 | |||
228 | /* Next position after decoding the compressed size of the chunk. */ | ||
229 | enum lzma2_seq next_sequence; | ||
230 | |||
231 | /* Uncompressed size of LZMA chunk (2 MiB at maximum) */ | ||
232 | uint32_t uncompressed; | ||
233 | |||
234 | /* | ||
235 | * Compressed size of LZMA chunk or compressed/uncompressed | ||
236 | * size of uncompressed chunk (64 KiB at maximum) | ||
237 | */ | ||
238 | uint32_t compressed; | ||
239 | |||
240 | /* | ||
241 | * True if dictionary reset is needed. This is false before | ||
242 | * the first chunk (LZMA or uncompressed). | ||
243 | */ | ||
244 | bool need_dict_reset; | ||
245 | |||
246 | /* | ||
247 | * True if new LZMA properties are needed. This is false | ||
248 | * before the first LZMA chunk. | ||
249 | */ | ||
250 | bool need_props; | ||
251 | }; | ||
252 | |||
204 | struct xz_dec_lzma2 { | 253 | struct xz_dec_lzma2 { |
205 | /* LZMA2 */ | 254 | /* |
206 | struct { | 255 | * The order below is important on x86 to reduce code size and |
207 | /* Position in xz_dec_lzma2_run(). */ | 256 | * it shouldn't hurt on other platforms. Everything up to and |
208 | enum lzma2_seq { | 257 | * including lzma.pos_mask are in the first 128 bytes on x86-32, |
209 | SEQ_CONTROL, | 258 | * which allows using smaller instructions to access those |
210 | SEQ_UNCOMPRESSED_1, | 259 | * variables. On x86-64, fewer variables fit into the first 128 |
211 | SEQ_UNCOMPRESSED_2, | 260 | * bytes, but this is still the best order without sacrificing |
212 | SEQ_COMPRESSED_0, | 261 | * the readability by splitting the structures. |
213 | SEQ_COMPRESSED_1, | 262 | */ |
214 | SEQ_PROPERTIES, | 263 | struct rc_dec rc; |
215 | SEQ_LZMA_PREPARE, | 264 | struct dictionary dict; |
216 | SEQ_LZMA_RUN, | 265 | struct lzma2_dec lzma2; |
217 | SEQ_COPY | 266 | struct lzma_dec lzma; |
218 | } sequence; | ||
219 | |||
220 | /* | ||
221 | * Next position after decoding the compressed size of | ||
222 | * the chunk. | ||
223 | */ | ||
224 | enum lzma2_seq next_sequence; | ||
225 | |||
226 | /* Uncompressed size of LZMA chunk (2 MiB at maximum) */ | ||
227 | uint32_t uncompressed; | ||
228 | |||
229 | /* | ||
230 | * Compressed size of LZMA chunk or compressed/uncompressed | ||
231 | * size of uncompressed chunk (64 KiB at maximum) | ||
232 | */ | ||
233 | uint32_t compressed; | ||
234 | |||
235 | /* | ||
236 | * True if dictionary reset is needed. This is false before | ||
237 | * the first chunk (LZMA or uncompressed). | ||
238 | */ | ||
239 | bool need_dict_reset; | ||
240 | |||
241 | /* | ||
242 | * True if new LZMA properties are needed. This is false | ||
243 | * before the first LZMA chunk. | ||
244 | */ | ||
245 | bool need_props; | ||
246 | } lzma2; | ||
247 | 267 | ||
248 | /* | 268 | /* |
249 | * Temporary buffer which holds small number of input bytes between | 269 | * Temporary buffer which holds small number of input bytes between |
@@ -253,10 +273,6 @@ struct xz_dec_lzma2 { | |||
253 | uint32_t size; | 273 | uint32_t size; |
254 | uint8_t buf[3 * LZMA_IN_REQUIRED]; | 274 | uint8_t buf[3 * LZMA_IN_REQUIRED]; |
255 | } temp; | 275 | } temp; |
256 | |||
257 | struct dictionary dict; | ||
258 | struct rc_dec rc; | ||
259 | struct lzma_dec lzma; | ||
260 | }; | 276 | }; |
261 | 277 | ||
262 | /************** | 278 | /************** |
@@ -269,7 +285,7 @@ struct xz_dec_lzma2 { | |||
269 | */ | 285 | */ |
270 | static void XZ_FUNC dict_reset(struct dictionary *dict, struct xz_buf *b) | 286 | static void XZ_FUNC dict_reset(struct dictionary *dict, struct xz_buf *b) |
271 | { | 287 | { |
272 | if (dict->allocated == 0) { | 288 | if (DEC_IS_SINGLE(dict->mode)) { |
273 | dict->buf = b->out + b->out_pos; | 289 | dict->buf = b->out + b->out_pos; |
274 | dict->end = b->out_size - b->out_pos; | 290 | dict->end = b->out_size - b->out_pos; |
275 | } | 291 | } |
@@ -379,7 +395,7 @@ static void XZ_FUNC dict_uncompressed( | |||
379 | if (dict->full < dict->pos) | 395 | if (dict->full < dict->pos) |
380 | dict->full = dict->pos; | 396 | dict->full = dict->pos; |
381 | 397 | ||
382 | if (dict->allocated != 0) { | 398 | if (DEC_IS_MULTI(dict->mode)) { |
383 | if (dict->pos == dict->end) | 399 | if (dict->pos == dict->end) |
384 | dict->pos = 0; | 400 | dict->pos = 0; |
385 | 401 | ||
@@ -404,7 +420,7 @@ static uint32_t XZ_FUNC dict_flush(struct dictionary *dict, struct xz_buf *b) | |||
404 | { | 420 | { |
405 | size_t copy_size = dict->pos - dict->start; | 421 | size_t copy_size = dict->pos - dict->start; |
406 | 422 | ||
407 | if (dict->allocated != 0) { | 423 | if (DEC_IS_MULTI(dict->mode)) { |
408 | if (dict->pos == dict->end) | 424 | if (dict->pos == dict->end) |
409 | dict->pos = 0; | 425 | dict->pos = 0; |
410 | 426 | ||
@@ -422,7 +438,7 @@ static uint32_t XZ_FUNC dict_flush(struct dictionary *dict, struct xz_buf *b) | |||
422 | *****************/ | 438 | *****************/ |
423 | 439 | ||
424 | /* Reset the range decoder. */ | 440 | /* Reset the range decoder. */ |
425 | static __always_inline void XZ_FUNC rc_reset(struct rc_dec *rc) | 441 | static void XZ_FUNC rc_reset(struct rc_dec *rc) |
426 | { | 442 | { |
427 | rc->range = (uint32_t)-1; | 443 | rc->range = (uint32_t)-1; |
428 | rc->code = 0; | 444 | rc->code = 0; |
@@ -1088,28 +1104,27 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run( | |||
1088 | return XZ_OK; | 1104 | return XZ_OK; |
1089 | } | 1105 | } |
1090 | 1106 | ||
1091 | XZ_EXTERN struct xz_dec_lzma2 * XZ_FUNC xz_dec_lzma2_create(uint32_t dict_max) | 1107 | XZ_EXTERN struct xz_dec_lzma2 * XZ_FUNC xz_dec_lzma2_create( |
1108 | enum xz_mode mode, uint32_t dict_max) | ||
1092 | { | 1109 | { |
1093 | struct xz_dec_lzma2 *s; | 1110 | struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL); |
1094 | |||
1095 | /* Maximum supported dictionary by this implementation is 3 GiB. */ | ||
1096 | if (dict_max > ((uint32_t)3 << 30)) | ||
1097 | return NULL; | ||
1098 | |||
1099 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
1100 | if (s == NULL) | 1111 | if (s == NULL) |
1101 | return NULL; | 1112 | return NULL; |
1102 | 1113 | ||
1103 | if (dict_max > 0) { | 1114 | s->dict.mode = mode; |
1115 | s->dict.size_max = dict_max; | ||
1116 | |||
1117 | if (DEC_IS_PREALLOC(mode)) { | ||
1104 | s->dict.buf = vmalloc(dict_max); | 1118 | s->dict.buf = vmalloc(dict_max); |
1105 | if (s->dict.buf == NULL) { | 1119 | if (s->dict.buf == NULL) { |
1106 | kfree(s); | 1120 | kfree(s); |
1107 | return NULL; | 1121 | return NULL; |
1108 | } | 1122 | } |
1123 | } else if (DEC_IS_DYNALLOC(mode)) { | ||
1124 | s->dict.buf = NULL; | ||
1125 | s->dict.allocated = 0; | ||
1109 | } | 1126 | } |
1110 | 1127 | ||
1111 | s->dict.allocated = dict_max; | ||
1112 | |||
1113 | return s; | 1128 | return s; |
1114 | } | 1129 | } |
1115 | 1130 | ||
@@ -1123,18 +1138,23 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_lzma2_reset( | |||
1123 | s->dict.size = 2 + (props & 1); | 1138 | s->dict.size = 2 + (props & 1); |
1124 | s->dict.size <<= (props >> 1) + 11; | 1139 | s->dict.size <<= (props >> 1) + 11; |
1125 | 1140 | ||
1126 | if (s->dict.allocated > 0 && s->dict.allocated < s->dict.size) { | 1141 | if (DEC_IS_MULTI(s->dict.mode)) { |
1127 | #ifdef XZ_REALLOC_DICT_BUF | 1142 | if (s->dict.size > s->dict.size_max) |
1128 | s->dict.buf = XZ_REALLOC_DICT_BUF(s->dict.buf, s->dict.size); | 1143 | return XZ_MEMLIMIT_ERROR; |
1129 | if (!s->dict.buf) | ||
1130 | return XZ_MEMLIMIT_ERROR; | ||
1131 | s->dict.allocated = s->dict.size; | ||
1132 | #else | ||
1133 | return XZ_MEMLIMIT_ERROR; | ||
1134 | #endif | ||
1135 | } | ||
1136 | 1144 | ||
1137 | s->dict.end = s->dict.size; | 1145 | s->dict.end = s->dict.size; |
1146 | |||
1147 | if (DEC_IS_DYNALLOC(s->dict.mode)) { | ||
1148 | if (s->dict.allocated < s->dict.size) { | ||
1149 | vfree(s->dict.buf); | ||
1150 | s->dict.buf = vmalloc(s->dict.size); | ||
1151 | if (s->dict.buf == NULL) { | ||
1152 | s->dict.allocated = 0; | ||
1153 | return XZ_MEM_ERROR; | ||
1154 | } | ||
1155 | } | ||
1156 | } | ||
1157 | } | ||
1138 | 1158 | ||
1139 | s->lzma.len = 0; | 1159 | s->lzma.len = 0; |
1140 | 1160 | ||
@@ -1148,7 +1168,7 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_lzma2_reset( | |||
1148 | 1168 | ||
1149 | XZ_EXTERN void XZ_FUNC xz_dec_lzma2_end(struct xz_dec_lzma2 *s) | 1169 | XZ_EXTERN void XZ_FUNC xz_dec_lzma2_end(struct xz_dec_lzma2 *s) |
1150 | { | 1170 | { |
1151 | if (s->dict.allocated > 0) | 1171 | if (DEC_IS_MULTI(s->dict.mode)) |
1152 | vfree(s->dict.buf); | 1172 | vfree(s->dict.buf); |
1153 | 1173 | ||
1154 | kfree(s); | 1174 | kfree(s); |
diff --git a/archival/libunarchive/unxz/xz_dec_stream.c b/archival/libunarchive/unxz/xz_dec_stream.c index 21db283fb..bdcbf1ba3 100644 --- a/archival/libunarchive/unxz/xz_dec_stream.c +++ b/archival/libunarchive/unxz/xz_dec_stream.c | |||
@@ -48,8 +48,8 @@ struct xz_dec { | |||
48 | /* Type of the integrity check calculated from uncompressed data */ | 48 | /* Type of the integrity check calculated from uncompressed data */ |
49 | enum xz_check check_type; | 49 | enum xz_check check_type; |
50 | 50 | ||
51 | /* True if we are operating in single-call mode. */ | 51 | /* Operation mode */ |
52 | bool single_call; | 52 | enum xz_mode mode; |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * True if the next call to xz_dec_run() is allowed to return | 55 | * True if the next call to xz_dec_run() is allowed to return |
@@ -737,14 +737,14 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b) | |||
737 | size_t out_start; | 737 | size_t out_start; |
738 | enum xz_ret ret; | 738 | enum xz_ret ret; |
739 | 739 | ||
740 | if (s->single_call) | 740 | if (DEC_IS_SINGLE(s->mode)) |
741 | xz_dec_reset(s); | 741 | xz_dec_reset(s); |
742 | 742 | ||
743 | in_start = b->in_pos; | 743 | in_start = b->in_pos; |
744 | out_start = b->out_pos; | 744 | out_start = b->out_pos; |
745 | ret = dec_main(s, b); | 745 | ret = dec_main(s, b); |
746 | 746 | ||
747 | if (s->single_call) { | 747 | if (DEC_IS_SINGLE(s->mode)) { |
748 | if (ret == XZ_OK) | 748 | if (ret == XZ_OK) |
749 | ret = b->in_pos == b->in_size | 749 | ret = b->in_pos == b->in_size |
750 | ? XZ_DATA_ERROR : XZ_BUF_ERROR; | 750 | ? XZ_DATA_ERROR : XZ_BUF_ERROR; |
@@ -767,21 +767,22 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b) | |||
767 | return ret; | 767 | return ret; |
768 | } | 768 | } |
769 | 769 | ||
770 | XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init(uint32_t dict_max) | 770 | XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init( |
771 | enum xz_mode mode, uint32_t dict_max) | ||
771 | { | 772 | { |
772 | struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL); | 773 | struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL); |
773 | if (s == NULL) | 774 | if (s == NULL) |
774 | return NULL; | 775 | return NULL; |
775 | 776 | ||
776 | s->single_call = dict_max == 0; | 777 | s->mode = mode; |
777 | 778 | ||
778 | #ifdef XZ_DEC_BCJ | 779 | #ifdef XZ_DEC_BCJ |
779 | s->bcj = xz_dec_bcj_create(s->single_call); | 780 | s->bcj = xz_dec_bcj_create(DEC_IS_SINGLE(mode)); |
780 | if (s->bcj == NULL) | 781 | if (s->bcj == NULL) |
781 | goto error_bcj; | 782 | goto error_bcj; |
782 | #endif | 783 | #endif |
783 | 784 | ||
784 | s->lzma2 = xz_dec_lzma2_create(dict_max); | 785 | s->lzma2 = xz_dec_lzma2_create(mode, dict_max); |
785 | if (s->lzma2 == NULL) | 786 | if (s->lzma2 == NULL) |
786 | goto error_lzma2; | 787 | goto error_lzma2; |
787 | 788 | ||
diff --git a/archival/libunarchive/unxz/xz_private.h b/archival/libunarchive/unxz/xz_private.h index f4e0b4010..145649a83 100644 --- a/archival/libunarchive/unxz/xz_private.h +++ b/archival/libunarchive/unxz/xz_private.h | |||
@@ -53,6 +53,45 @@ | |||
53 | # include "xz_config.h" | 53 | # include "xz_config.h" |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | /* If no specific decoding mode is requested, enable support for all modes. */ | ||
57 | #if !defined(XZ_DEC_SINGLE) && !defined(XZ_DEC_PREALLOC) \ | ||
58 | && !defined(XZ_DEC_DYNALLOC) | ||
59 | # define XZ_DEC_SINGLE | ||
60 | # define XZ_DEC_PREALLOC | ||
61 | # define XZ_DEC_DYNALLOC | ||
62 | #endif | ||
63 | |||
64 | /* | ||
65 | * The DEC_IS_foo(mode) macros are used in "if" statements. If only some | ||
66 | * of the supported modes are enabled, these macros will evaluate to true or | ||
67 | * false at compile time and thus allow the compiler to omit unneeded code. | ||
68 | */ | ||
69 | #ifdef XZ_DEC_SINGLE | ||
70 | # define DEC_IS_SINGLE(mode) ((mode) == XZ_SINGLE) | ||
71 | #else | ||
72 | # define DEC_IS_SINGLE(mode) (false) | ||
73 | #endif | ||
74 | |||
75 | #ifdef XZ_DEC_PREALLOC | ||
76 | # define DEC_IS_PREALLOC(mode) ((mode) == XZ_PREALLOC) | ||
77 | #else | ||
78 | # define DEC_IS_PREALLOC(mode) (false) | ||
79 | #endif | ||
80 | |||
81 | #ifdef XZ_DEC_DYNALLOC | ||
82 | # define DEC_IS_DYNALLOC(mode) ((mode) == XZ_DYNALLOC) | ||
83 | #else | ||
84 | # define DEC_IS_DYNALLOC(mode) (false) | ||
85 | #endif | ||
86 | |||
87 | #if !defined(XZ_DEC_SINGLE) | ||
88 | # define DEC_IS_MULTI(mode) (true) | ||
89 | #elif defined(XZ_DEC_PREALLOC) || defined(XZ_DEC_DYNALLOC) | ||
90 | # define DEC_IS_MULTI(mode) ((mode) != XZ_SINGLE) | ||
91 | #else | ||
92 | # define DEC_IS_MULTI(mode) (false) | ||
93 | #endif | ||
94 | |||
56 | /* | 95 | /* |
57 | * If any of the BCJ filter decoders are wanted, define XZ_DEC_BCJ. | 96 | * If any of the BCJ filter decoders are wanted, define XZ_DEC_BCJ. |
58 | * XZ_DEC_BCJ is used to enable generic support for BCJ decoders. | 97 | * XZ_DEC_BCJ is used to enable generic support for BCJ decoders. |
@@ -71,7 +110,7 @@ | |||
71 | * before calling xz_dec_lzma2_run(). | 110 | * before calling xz_dec_lzma2_run(). |
72 | */ | 111 | */ |
73 | XZ_EXTERN struct xz_dec_lzma2 * XZ_FUNC xz_dec_lzma2_create( | 112 | XZ_EXTERN struct xz_dec_lzma2 * XZ_FUNC xz_dec_lzma2_create( |
74 | uint32_t dict_max); | 113 | enum xz_mode mode, uint32_t dict_max); |
75 | 114 | ||
76 | /* | 115 | /* |
77 | * Decode the LZMA2 properties (one byte) and reset the decoder. Return | 116 | * Decode the LZMA2 properties (one byte) and reset the decoder. Return |
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index 1c67dcc6e..5bc50b88f 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c | |||
@@ -75,7 +75,7 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |||
75 | } magic; | 75 | } magic; |
76 | IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd); | 76 | IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd); |
77 | 77 | ||
78 | xread(rpm_fd, magic.b16, sizeof(magic.b16)); | 78 | xread(rpm_fd, magic.b16, sizeof(magic.b16[0])); |
79 | if (magic.b16[0] == GZIP_MAGIC) { | 79 | if (magic.b16[0] == GZIP_MAGIC) { |
80 | unpack = unpack_gz_stream; | 80 | unpack = unpack_gz_stream; |
81 | } else | 81 | } else |
@@ -87,13 +87,11 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |||
87 | if (ENABLE_FEATURE_SEAMLESS_XZ | 87 | if (ENABLE_FEATURE_SEAMLESS_XZ |
88 | && magic.b16[0] == XZ_MAGIC1 | 88 | && magic.b16[0] == XZ_MAGIC1 |
89 | ) { | 89 | ) { |
90 | /* .xz signature: 0xfd, '7', 'z', 'X', 'Z', 0x00 */ | 90 | xread(rpm_fd, magic.b32, sizeof(magic.b32[0])); |
91 | /* More info at: http://tukaani.org/xz/xz-file-format.txt */ | ||
92 | xread(rpm_fd, magic.b32, sizeof(magic.b32)); | ||
93 | if (magic.b32[0] != XZ_MAGIC2) | 91 | if (magic.b32[0] != XZ_MAGIC2) |
94 | goto no_magic; | 92 | goto no_magic; |
95 | /* unpack_xz_stream wants fd at position 0 */ | 93 | /* unpack_xz_stream wants fd at position 6, no need to seek */ |
96 | xlseek(rpm_fd, -6, SEEK_CUR); | 94 | //xlseek(rpm_fd, -6, SEEK_CUR); |
97 | unpack = unpack_xz_stream; | 95 | unpack = unpack_xz_stream; |
98 | } else { | 96 | } else { |
99 | no_magic: | 97 | no_magic: |
diff --git a/archival/tar.c b/archival/tar.c index 3a940128b..5ddff7fa5 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -48,37 +48,6 @@ | |||
48 | 48 | ||
49 | #if ENABLE_FEATURE_TAR_CREATE | 49 | #if ENABLE_FEATURE_TAR_CREATE |
50 | 50 | ||
51 | /* Tar file constants */ | ||
52 | |||
53 | #define TAR_BLOCK_SIZE 512 | ||
54 | |||
55 | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ | ||
56 | #define NAME_SIZE 100 | ||
57 | #define NAME_SIZE_STR "100" | ||
58 | typedef struct TarHeader { /* byte offset */ | ||
59 | char name[NAME_SIZE]; /* 0-99 */ | ||
60 | char mode[8]; /* 100-107 */ | ||
61 | char uid[8]; /* 108-115 */ | ||
62 | char gid[8]; /* 116-123 */ | ||
63 | char size[12]; /* 124-135 */ | ||
64 | char mtime[12]; /* 136-147 */ | ||
65 | char chksum[8]; /* 148-155 */ | ||
66 | char typeflag; /* 156-156 */ | ||
67 | char linkname[NAME_SIZE]; /* 157-256 */ | ||
68 | /* POSIX: "ustar" NUL "00" */ | ||
69 | /* GNU tar: "ustar " NUL */ | ||
70 | /* Normally it's defined as magic[6] followed by | ||
71 | * version[2], but we put them together to save code. | ||
72 | */ | ||
73 | char magic[8]; /* 257-264 */ | ||
74 | char uname[32]; /* 265-296 */ | ||
75 | char gname[32]; /* 297-328 */ | ||
76 | char devmajor[8]; /* 329-336 */ | ||
77 | char devminor[8]; /* 337-344 */ | ||
78 | char prefix[155]; /* 345-499 */ | ||
79 | char padding[12]; /* 500-512 (pad to exactly TAR_BLOCK_SIZE) */ | ||
80 | } TarHeader; | ||
81 | |||
82 | /* | 51 | /* |
83 | ** writeTarFile(), writeFileToTarball(), and writeTarHeader() are | 52 | ** writeTarFile(), writeFileToTarball(), and writeTarHeader() are |
84 | ** the only functions that deal with the HardLinkInfo structure. | 53 | ** the only functions that deal with the HardLinkInfo structure. |
@@ -193,7 +162,7 @@ static void putOctal(char *cp, int len, off_t value) | |||
193 | } | 162 | } |
194 | #define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) | 163 | #define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) |
195 | 164 | ||
196 | static void chksum_and_xwrite(int fd, struct TarHeader* hp) | 165 | static void chksum_and_xwrite(int fd, struct tar_header_t* hp) |
197 | { | 166 | { |
198 | /* POSIX says that checksum is done on unsigned bytes | 167 | /* POSIX says that checksum is done on unsigned bytes |
199 | * (Sun and HP-UX gets it wrong... more details in | 168 | * (Sun and HP-UX gets it wrong... more details in |
@@ -235,7 +204,7 @@ static void writeLongname(int fd, int type, const char *name, int dir) | |||
235 | "00000000000", | 204 | "00000000000", |
236 | "00000000000", | 205 | "00000000000", |
237 | }; | 206 | }; |
238 | struct TarHeader header; | 207 | struct tar_header_t header; |
239 | int size; | 208 | int size; |
240 | 209 | ||
241 | dir = !!dir; /* normalize: 0/1 */ | 210 | dir = !!dir; /* normalize: 0/1 */ |
@@ -262,16 +231,12 @@ static void writeLongname(int fd, int type, const char *name, int dir) | |||
262 | #endif | 231 | #endif |
263 | 232 | ||
264 | /* Write out a tar header for the specified file/directory/whatever */ | 233 | /* Write out a tar header for the specified file/directory/whatever */ |
265 | void BUG_tar_header_size(void); | ||
266 | static int writeTarHeader(struct TarBallInfo *tbInfo, | 234 | static int writeTarHeader(struct TarBallInfo *tbInfo, |
267 | const char *header_name, const char *fileName, struct stat *statbuf) | 235 | const char *header_name, const char *fileName, struct stat *statbuf) |
268 | { | 236 | { |
269 | struct TarHeader header; | 237 | struct tar_header_t header; |
270 | 238 | ||
271 | if (sizeof(header) != 512) | 239 | memset(&header, 0, sizeof(header)); |
272 | BUG_tar_header_size(); | ||
273 | |||
274 | memset(&header, 0, sizeof(struct TarHeader)); | ||
275 | 240 | ||
276 | strncpy(header.name, header_name, sizeof(header.name)); | 241 | strncpy(header.name, header_name, sizeof(header.name)); |
277 | 242 | ||
@@ -549,9 +514,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip) | |||
549 | (void) &zip_exec; | 514 | (void) &zip_exec; |
550 | # endif | 515 | # endif |
551 | 516 | ||
552 | gzipPid = vfork(); | 517 | gzipPid = xvfork(); |
553 | if (gzipPid < 0) | ||
554 | bb_perror_msg_and_die("vfork"); | ||
555 | 518 | ||
556 | if (gzipPid == 0) { | 519 | if (gzipPid == 0) { |
557 | /* child */ | 520 | /* child */ |
@@ -738,6 +701,68 @@ static void handle_SIGCHLD(int status) | |||
738 | } | 701 | } |
739 | #endif | 702 | #endif |
740 | 703 | ||
704 | //usage:#define tar_trivial_usage | ||
705 | //usage: "-[" IF_FEATURE_TAR_CREATE("c") "xt" IF_FEATURE_SEAMLESS_GZ("z") | ||
706 | //usage: IF_FEATURE_SEAMLESS_BZ2("j") IF_FEATURE_SEAMLESS_LZMA("a") | ||
707 | //usage: IF_FEATURE_SEAMLESS_Z("Z") IF_FEATURE_TAR_NOPRESERVE_TIME("m") "vO] " | ||
708 | //usage: IF_FEATURE_TAR_FROM("[-X FILE] ") | ||
709 | //usage: "[-f TARFILE] [-C DIR] [FILE]..." | ||
710 | //usage:#define tar_full_usage "\n\n" | ||
711 | //usage: IF_FEATURE_TAR_CREATE("Create, extract, ") | ||
712 | //usage: IF_NOT_FEATURE_TAR_CREATE("Extract ") | ||
713 | //usage: "or list files from a tar file\n" | ||
714 | //usage: "\nOperation:" | ||
715 | //usage: IF_FEATURE_TAR_CREATE( | ||
716 | //usage: "\n c Create" | ||
717 | //usage: ) | ||
718 | //usage: "\n x Extract" | ||
719 | //usage: "\n t List" | ||
720 | //usage: "\nOptions:" | ||
721 | //usage: "\n f Name of TARFILE ('-' for stdin/out)" | ||
722 | //usage: "\n C Change to DIR before operation" | ||
723 | //usage: "\n v Verbose" | ||
724 | //usage: IF_FEATURE_SEAMLESS_GZ( | ||
725 | //usage: "\n z (De)compress using gzip" | ||
726 | //usage: ) | ||
727 | //usage: IF_FEATURE_SEAMLESS_BZ2( | ||
728 | //usage: "\n j (De)compress using bzip2" | ||
729 | //usage: ) | ||
730 | //usage: IF_FEATURE_SEAMLESS_LZMA( | ||
731 | //usage: "\n a (De)compress using lzma" | ||
732 | //usage: ) | ||
733 | //usage: IF_FEATURE_SEAMLESS_Z( | ||
734 | //usage: "\n Z (De)compress using compress" | ||
735 | //usage: ) | ||
736 | //usage: "\n O Extract to stdout" | ||
737 | //usage: IF_FEATURE_TAR_CREATE( | ||
738 | //usage: "\n h Follow symlinks" | ||
739 | //usage: ) | ||
740 | //usage: IF_FEATURE_TAR_NOPRESERVE_TIME( | ||
741 | //usage: "\n m Don't restore mtime" | ||
742 | //usage: ) | ||
743 | //usage: IF_FEATURE_TAR_FROM( | ||
744 | //usage: IF_FEATURE_TAR_LONG_OPTIONS( | ||
745 | //usage: "\n exclude File to exclude" | ||
746 | //usage: ) | ||
747 | //usage: "\n X File with names to exclude" | ||
748 | //usage: "\n T File with names to include" | ||
749 | //usage: ) | ||
750 | //usage: | ||
751 | //usage:#define tar_example_usage | ||
752 | //usage: "$ zcat /tmp/tarball.tar.gz | tar -xf -\n" | ||
753 | //usage: "$ tar -cf /tmp/tarball.tar /usr/local\n" | ||
754 | |||
755 | // Supported but aren't in --help: | ||
756 | // o no-same-owner | ||
757 | // p same-permissions | ||
758 | // k keep-old | ||
759 | // numeric-owner | ||
760 | // no-same-permissions | ||
761 | // overwrite | ||
762 | //IF_FEATURE_TAR_TO_COMMAND( | ||
763 | // to-command | ||
764 | //) | ||
765 | |||
741 | enum { | 766 | enum { |
742 | OPTBIT_KEEP_OLD = 8, | 767 | OPTBIT_KEEP_OLD = 8, |
743 | IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) | 768 | IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) |
@@ -750,6 +775,7 @@ enum { | |||
750 | IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit | 775 | IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit |
751 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) | 776 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) |
752 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 777 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
778 | IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) | ||
753 | OPTBIT_NUMERIC_OWNER, | 779 | OPTBIT_NUMERIC_OWNER, |
754 | OPTBIT_NOPRESERVE_PERM, | 780 | OPTBIT_NOPRESERVE_PERM, |
755 | OPTBIT_OVERWRITE, | 781 | OPTBIT_OVERWRITE, |
@@ -772,6 +798,7 @@ enum { | |||
772 | OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z | 798 | OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z |
773 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z | 799 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z |
774 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m | 800 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m |
801 | OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command | ||
775 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner | 802 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
776 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions | 803 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions |
777 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite | 804 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite |
@@ -813,6 +840,9 @@ static const char tar_longopts[] ALIGN1 = | |||
813 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME | 840 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME |
814 | "touch\0" No_argument "m" | 841 | "touch\0" No_argument "m" |
815 | # endif | 842 | # endif |
843 | # if ENABLE_FEATURE_TAR_TO_COMMAND | ||
844 | "to-command\0" Required_argument "\xfb" | ||
845 | # endif | ||
816 | /* use numeric uid/gid from tar header, not textual */ | 846 | /* use numeric uid/gid from tar header, not textual */ |
817 | "numeric-owner\0" No_argument "\xfc" | 847 | "numeric-owner\0" No_argument "\xfc" |
818 | /* do not restore mode */ | 848 | /* do not restore mode */ |
@@ -904,6 +934,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
904 | , &tar_filename // -f filename | 934 | , &tar_filename // -f filename |
905 | IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T | 935 | IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T |
906 | IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X | 936 | IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X |
937 | IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command | ||
907 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM | 938 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
908 | , &excludes // --exclude | 939 | , &excludes // --exclude |
909 | #endif | 940 | #endif |
@@ -922,6 +953,12 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
922 | if (opt & OPT_2STDOUT) | 953 | if (opt & OPT_2STDOUT) |
923 | tar_handle->action_data = data_extract_to_stdout; | 954 | tar_handle->action_data = data_extract_to_stdout; |
924 | 955 | ||
956 | if (opt & OPT_2COMMAND) { | ||
957 | putenv((char*)"TAR_FILETYPE=f"); | ||
958 | signal(SIGPIPE, SIG_IGN); | ||
959 | tar_handle->action_data = data_extract_to_command; | ||
960 | } | ||
961 | |||
925 | if (opt & OPT_KEEP_OLD) | 962 | if (opt & OPT_KEEP_OLD) |
926 | tar_handle->ah_flags &= ~ARCHIVE_UNLINK_OLD; | 963 | tar_handle->ah_flags &= ~ARCHIVE_UNLINK_OLD; |
927 | 964 | ||
diff --git a/archival/unzip_doc.txt.bz2 b/archival/unzip_doc.txt.bz2 deleted file mode 100644 index ab77d10da..000000000 --- a/archival/unzip_doc.txt.bz2 +++ /dev/null | |||
Binary files differ | |||