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 /libbb | |
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>
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/read.c | 53 |
1 files changed, 36 insertions, 17 deletions
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 | } |