diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-30 04:18:13 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-30 04:18:13 +0200 |
commit | 6948f210ed443f8153e0ba751e77bec8a0c6c8d4 (patch) | |
tree | 134443f225a788cbb4fda7b4713ee2bc535fb126 | |
parent | fb6c76cb6eaade5693b7e99c33846c902689f1db (diff) | |
download | busybox-w32-6948f210ed443f8153e0ba751e77bec8a0c6c8d4.tar.gz busybox-w32-6948f210ed443f8153e0ba751e77bec8a0c6c8d4.tar.bz2 busybox-w32-6948f210ed443f8153e0ba751e77bec8a0c6c8d4.zip |
*: teach tar et. al. to understand .xz by heart
function old new delta
unpack_xz_stream - 4126 +4126
setup_unzip_on_fd 80 150 +70
open_zipped 113 131 +18
unpack_unxz 5 12 +7
send_tree 360 353 -7
unpack_xz_stream_stdin 3953 - -3953
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 3/1 up/down: 4221/-3960) Total: 261 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/bbunzip.c | 2 | ||||
-rw-r--r-- | archival/libunarchive/decompress_unxz.c | 9 | ||||
-rw-r--r-- | include/libbb.h | 2 | ||||
-rw-r--r-- | include/unarchive.h | 5 | ||||
-rw-r--r-- | libbb/read.c | 53 |
5 files changed, 46 insertions, 25 deletions
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 1c8d0ab55..86adb6e24 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -374,7 +374,7 @@ char* make_new_name_unxz(char *filename) | |||
374 | static | 374 | static |
375 | IF_DESKTOP(long long) int unpack_unxz(unpack_info_t *info UNUSED_PARAM) | 375 | IF_DESKTOP(long long) int unpack_unxz(unpack_info_t *info UNUSED_PARAM) |
376 | { | 376 | { |
377 | return unpack_xz_stream_stdin(); | 377 | return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO); |
378 | } | 378 | } |
379 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 379 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
380 | int unxz_main(int argc UNUSED_PARAM, char **argv) | 380 | int unxz_main(int argc UNUSED_PARAM, char **argv) |
diff --git a/archival/libunarchive/decompress_unxz.c b/archival/libunarchive/decompress_unxz.c index 0ae789160..9edc2461a 100644 --- a/archival/libunarchive/decompress_unxz.c +++ b/archival/libunarchive/decompress_unxz.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * by Lasse Collin <lasse.collin@tukaani.org> | 3 | * by Lasse Collin <lasse.collin@tukaani.org> |
4 | * and Igor Pavlov <http://7-zip.org/> | 4 | * and Igor Pavlov <http://7-zip.org/> |
5 | * | 5 | * |
6 | * See README file in unxzbz/ directory for more information. | 6 | * See README file in unxz/ directory for more information. |
7 | * | 7 | * |
8 | * This file is: | 8 | * This file is: |
9 | * Copyright (C) 2010 Denys Vlasenko <vda.linux@googlemail.com> | 9 | * Copyright (C) 2010 Denys Vlasenko <vda.linux@googlemail.com> |
@@ -48,7 +48,7 @@ static uint32_t xz_crc32(uint32_t *crc32_table, | |||
48 | #include "unxz/xz_stream.h" | 48 | #include "unxz/xz_stream.h" |
49 | 49 | ||
50 | IF_DESKTOP(long long) int FAST_FUNC | 50 | IF_DESKTOP(long long) int FAST_FUNC |
51 | unpack_xz_stream_stdin(void) | 51 | unpack_xz_stream(int src_fd, int dst_fd) |
52 | { | 52 | { |
53 | struct xz_buf iobuf; | 53 | struct xz_buf iobuf; |
54 | struct xz_dec *state; | 54 | struct xz_dec *state; |
@@ -79,7 +79,7 @@ unpack_xz_stream_stdin(void) | |||
79 | iobuf.in_pos = 0; | 79 | iobuf.in_pos = 0; |
80 | rd = IN_SIZE - insz; | 80 | rd = IN_SIZE - insz; |
81 | if (rd) { | 81 | if (rd) { |
82 | rd = safe_read(STDIN_FILENO, membuf + insz, rd); | 82 | rd = safe_read(src_fd, membuf + insz, rd); |
83 | if (rd < 0) { | 83 | if (rd < 0) { |
84 | bb_error_msg("read error"); | 84 | bb_error_msg("read error"); |
85 | total = -1; | 85 | total = -1; |
@@ -94,10 +94,11 @@ unpack_xz_stream_stdin(void) | |||
94 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r); | 94 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r); |
95 | outpos = iobuf.out_pos; | 95 | outpos = iobuf.out_pos; |
96 | if (outpos) { | 96 | if (outpos) { |
97 | xwrite(STDOUT_FILENO, iobuf.out, outpos); | 97 | xwrite(dst_fd, iobuf.out, outpos); |
98 | IF_DESKTOP(total += outpos;) | 98 | IF_DESKTOP(total += outpos;) |
99 | } | 99 | } |
100 | if (r == XZ_STREAM_END | 100 | if (r == XZ_STREAM_END |
101 | /* this happens even with well-formed files: */ | ||
101 | || (r == XZ_BUF_ERROR && insz == 0 && outpos == 0) | 102 | || (r == XZ_BUF_ERROR && insz == 0 && outpos == 0) |
102 | ) { | 103 | ) { |
103 | break; | 104 | break; |
diff --git a/include/libbb.h b/include/libbb.h index 2f67c7f72..326179b97 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -656,7 +656,7 @@ extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST | |||
656 | || ENABLE_FEATURE_SEAMLESS_BZ2 \ | 656 | || ENABLE_FEATURE_SEAMLESS_BZ2 \ |
657 | || ENABLE_FEATURE_SEAMLESS_GZ \ | 657 | || ENABLE_FEATURE_SEAMLESS_GZ \ |
658 | /* || ENABLE_FEATURE_SEAMLESS_Z */ | 658 | /* || ENABLE_FEATURE_SEAMLESS_Z */ |
659 | extern int setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) FAST_FUNC; | 659 | extern void setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) FAST_FUNC; |
660 | #else | 660 | #else |
661 | # define setup_unzip_on_fd(...) ((void)0) | 661 | # define setup_unzip_on_fd(...) ((void)0) |
662 | #endif | 662 | #endif |
diff --git a/include/unarchive.h b/include/unarchive.h index 14cd98e24..783a943b6 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
@@ -143,14 +143,15 @@ typedef struct inflate_unzip_result { | |||
143 | } inflate_unzip_result; | 143 | } inflate_unzip_result; |
144 | 144 | ||
145 | IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC; | 145 | IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC; |
146 | IF_DESKTOP(long long) int unpack_xz_stream_stdin(void) FAST_FUNC; | 146 | /* xz unpacker takes .xz stream from offset 0 */ |
147 | IF_DESKTOP(long long) int unpack_xz_stream(int src_fd, int dst_fd) FAST_FUNC; | ||
147 | /* lzma unpacker takes .lzma stream from offset 0 */ | 148 | /* lzma unpacker takes .lzma stream from offset 0 */ |
148 | IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; | 149 | IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; |
149 | /* the rest wants 2 first bytes already skipped by the caller */ | 150 | /* the rest wants 2 first bytes already skipped by the caller */ |
150 | IF_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC; | 151 | IF_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC; |
151 | IF_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC; | 152 | IF_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC; |
152 | IF_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC; | 153 | IF_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC; |
153 | IF_DESKTOP(long long) int unpack_Z_stream(int fd_in, int fd_out) FAST_FUNC; | 154 | IF_DESKTOP(long long) int unpack_Z_stream(int src_fd, int dst_fd) FAST_FUNC; |
154 | /* wrapper which checks first two bytes to be "BZ" */ | 155 | /* wrapper which checks first two bytes to be "BZ" */ |
155 | IF_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC; | 156 | IF_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC; |
156 | 157 | ||
diff --git a/libbb/read.c b/libbb/read.c index f3af144f0..cd6bbeb13 100644 --- a/libbb/read.c +++ b/libbb/read.c | |||
@@ -305,22 +305,26 @@ void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) | |||
305 | return buf; | 305 | return buf; |
306 | } | 306 | } |
307 | 307 | ||
308 | /* Used by e.g. rpm which gives us a fd without filename, | ||
309 | * thus we can't guess the format from filename's extension. | ||
310 | */ | ||
308 | #if ZIPPED | 311 | #if ZIPPED |
309 | int FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | 312 | void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) |
310 | { | 313 | { |
311 | const int fail_if_not_detected = 1; | 314 | const int fail_if_not_detected = 1; |
312 | unsigned char magic[2]; | 315 | unsigned char magic[8]; |
313 | #if BB_MMU | 316 | int offset = -2; |
317 | # if BB_MMU | ||
314 | IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); | 318 | IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); |
315 | enum { xformer_prog = 0 }; | 319 | enum { xformer_prog = 0 }; |
316 | #else | 320 | # else |
317 | enum { xformer = 0 }; | 321 | enum { xformer = 0 }; |
318 | const char *xformer_prog; | 322 | const char *xformer_prog; |
319 | #endif | 323 | # endif |
320 | 324 | ||
321 | /* .gz and .bz2 both have 2-byte signature, and their | 325 | /* .gz and .bz2 both have 2-byte signature, and their |
322 | * unpack_XXX_stream wants this header skipped. */ | 326 | * unpack_XXX_stream wants this header skipped. */ |
323 | xread(fd, &magic, 2); | 327 | xread(fd, magic, 2); |
324 | if (ENABLE_FEATURE_SEAMLESS_GZ | 328 | if (ENABLE_FEATURE_SEAMLESS_GZ |
325 | && magic[0] == 0x1f && magic[1] == 0x8b | 329 | && magic[0] == 0x1f && magic[1] == 0x8b |
326 | ) { | 330 | ) { |
@@ -341,28 +345,41 @@ int FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | |||
341 | # endif | 345 | # endif |
342 | goto found_magic; | 346 | goto found_magic; |
343 | } | 347 | } |
344 | // TODO: xz format support. rpm adopted it, "rpm -i FILE.rpm" badly needs this. | 348 | if (ENABLE_FEATURE_SEAMLESS_XZ |
345 | // Signature: 0xFD, '7', 'z', 'X', 'Z', 0x00 | 349 | && magic[0] == 0xfd && magic[1] == '7' |
346 | // More info at: http://tukaani.org/xz/xz-file-format.txt | 350 | ) { |
351 | /* .xz signature: 0xfd, '7', 'z', 'X', 'Z', 0x00 */ | ||
352 | /* More info at: http://tukaani.org/xz/xz-file-format.txt */ | ||
353 | offset = -6; | ||
354 | xread(fd, magic + 2, 4); | ||
355 | if (strcmp((char*)magic + 2, "zXZ") == 0) { | ||
356 | # if BB_MMU | ||
357 | xformer = unpack_xz_stream; | ||
358 | # else | ||
359 | xformer_prog = "unxz"; | ||
360 | # endif | ||
361 | xlseek(fd, offset, SEEK_CUR); | ||
362 | goto found_magic; | ||
363 | } | ||
364 | } | ||
347 | 365 | ||
348 | /* No known magic seen */ | 366 | /* No known magic seen */ |
349 | if (fail_if_not_detected) | 367 | if (fail_if_not_detected) |
350 | bb_error_msg_and_die("no gzip" | 368 | bb_error_msg_and_die("no gzip" |
351 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | 369 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") |
370 | IF_FEATURE_SEAMLESS_XZ("/xz") | ||
352 | " magic"); | 371 | " magic"); |
353 | xlseek(fd, -2, SEEK_CUR); | 372 | xlseek(fd, offset, SEEK_CUR); |
354 | return fd; | 373 | return; |
355 | 374 | ||
356 | found_magic: | 375 | found_magic: |
357 | # if !BB_MMU | 376 | # if !BB_MMU |
358 | /* NOMMU version of open_transformer execs | 377 | /* NOMMU version of open_transformer execs |
359 | * an external unzipper that wants | 378 | * an external unzipper that wants |
360 | * file position at the start of the file */ | 379 | * file position at the start of the file */ |
361 | xlseek(fd, -2, SEEK_CUR); | 380 | xlseek(fd, offset, SEEK_CUR); |
362 | # endif | 381 | # endif |
363 | open_transformer(fd, xformer, xformer_prog); | 382 | open_transformer(fd, xformer, xformer_prog); |
364 | |||
365 | return fd; | ||
366 | } | 383 | } |
367 | #endif /* ZIPPED */ | 384 | #endif /* ZIPPED */ |
368 | 385 | ||
@@ -380,12 +397,14 @@ int FAST_FUNC open_zipped(const char *fname) | |||
380 | 397 | ||
381 | sfx = strrchr(fname, '.'); | 398 | sfx = strrchr(fname, '.'); |
382 | if (sfx) { | 399 | if (sfx) { |
383 | if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, ".lzma") == 0) | 400 | sfx++; |
401 | if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0) | ||
384 | /* .lzma has no header/signature, just trust it */ | 402 | /* .lzma has no header/signature, just trust it */ |
385 | open_transformer(fd, unpack_lzma_stream, "unlzma"); | 403 | open_transformer(fd, unpack_lzma_stream, "unlzma"); |
386 | else | 404 | else |
387 | if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, ".gz") == 0) | 405 | if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0) |
388 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0) | 406 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0) |
407 | || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0) | ||
389 | ) { | 408 | ) { |
390 | setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/); | 409 | setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/); |
391 | } | 410 | } |