diff options
Diffstat (limited to 'libbb/read.c')
-rw-r--r-- | libbb/read.c | 103 |
1 files changed, 61 insertions, 42 deletions
diff --git a/libbb/read.c b/libbb/read.c index 06ce29718..f3af144f0 100644 --- a/libbb/read.c +++ b/libbb/read.c | |||
@@ -6,7 +6,6 @@ | |||
6 | * | 6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | |||
10 | #include "libbb.h" | 9 | #include "libbb.h" |
11 | 10 | ||
12 | #define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \ | 11 | #define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \ |
@@ -16,7 +15,7 @@ | |||
16 | ) | 15 | ) |
17 | 16 | ||
18 | #if ZIPPED | 17 | #if ZIPPED |
19 | #include "unarchive.h" | 18 | # include "unarchive.h" |
20 | #endif | 19 | #endif |
21 | 20 | ||
22 | ssize_t FAST_FUNC safe_read(int fd, void *buf, size_t count) | 21 | ssize_t FAST_FUNC safe_read(int fd, void *buf, size_t count) |
@@ -306,14 +305,11 @@ void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) | |||
306 | return buf; | 305 | return buf; |
307 | } | 306 | } |
308 | 307 | ||
309 | int FAST_FUNC open_zipped(const char *fname) | 308 | #if ZIPPED |
309 | int FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | ||
310 | { | 310 | { |
311 | #if !ZIPPED | 311 | const int fail_if_not_detected = 1; |
312 | return open(fname, O_RDONLY); | ||
313 | #else | ||
314 | unsigned char magic[2]; | 312 | unsigned char magic[2]; |
315 | char *sfx; | ||
316 | int fd; | ||
317 | #if BB_MMU | 313 | #if BB_MMU |
318 | IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); | 314 | IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); |
319 | enum { xformer_prog = 0 }; | 315 | enum { xformer_prog = 0 }; |
@@ -322,6 +318,62 @@ int FAST_FUNC open_zipped(const char *fname) | |||
322 | const char *xformer_prog; | 318 | const char *xformer_prog; |
323 | #endif | 319 | #endif |
324 | 320 | ||
321 | /* .gz and .bz2 both have 2-byte signature, and their | ||
322 | * unpack_XXX_stream wants this header skipped. */ | ||
323 | xread(fd, &magic, 2); | ||
324 | if (ENABLE_FEATURE_SEAMLESS_GZ | ||
325 | && magic[0] == 0x1f && magic[1] == 0x8b | ||
326 | ) { | ||
327 | # if BB_MMU | ||
328 | xformer = unpack_gz_stream; | ||
329 | # else | ||
330 | xformer_prog = "gunzip"; | ||
331 | # endif | ||
332 | goto found_magic; | ||
333 | } | ||
334 | if (ENABLE_FEATURE_SEAMLESS_BZ2 | ||
335 | && magic[0] == 'B' && magic[1] == 'Z' | ||
336 | ) { | ||
337 | # if BB_MMU | ||
338 | xformer = unpack_bz2_stream; | ||
339 | # else | ||
340 | xformer_prog = "bunzip2"; | ||
341 | # endif | ||
342 | goto found_magic; | ||
343 | } | ||
344 | // TODO: xz format support. rpm adopted it, "rpm -i FILE.rpm" badly needs this. | ||
345 | // Signature: 0xFD, '7', 'z', 'X', 'Z', 0x00 | ||
346 | // More info at: http://tukaani.org/xz/xz-file-format.txt | ||
347 | |||
348 | /* No known magic seen */ | ||
349 | if (fail_if_not_detected) | ||
350 | bb_error_msg_and_die("no gzip" | ||
351 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | ||
352 | " magic"); | ||
353 | xlseek(fd, -2, SEEK_CUR); | ||
354 | return fd; | ||
355 | |||
356 | found_magic: | ||
357 | # if !BB_MMU | ||
358 | /* NOMMU version of open_transformer execs | ||
359 | * an external unzipper that wants | ||
360 | * file position at the start of the file */ | ||
361 | xlseek(fd, -2, SEEK_CUR); | ||
362 | # endif | ||
363 | open_transformer(fd, xformer, xformer_prog); | ||
364 | |||
365 | return fd; | ||
366 | } | ||
367 | #endif /* ZIPPED */ | ||
368 | |||
369 | int FAST_FUNC open_zipped(const char *fname) | ||
370 | { | ||
371 | #if !ZIPPED | ||
372 | return open(fname, O_RDONLY); | ||
373 | #else | ||
374 | char *sfx; | ||
375 | int fd; | ||
376 | |||
325 | fd = open(fname, O_RDONLY); | 377 | fd = open(fname, O_RDONLY); |
326 | if (fd < 0) | 378 | if (fd < 0) |
327 | return fd; | 379 | return fd; |
@@ -335,40 +387,7 @@ int FAST_FUNC open_zipped(const char *fname) | |||
335 | if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, ".gz") == 0) | 387 | if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, ".gz") == 0) |
336 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0) | 388 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0) |
337 | ) { | 389 | ) { |
338 | /* .gz and .bz2 both have 2-byte signature, and their | 390 | setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/); |
339 | * unpack_XXX_stream wants this header skipped. */ | ||
340 | xread(fd, &magic, 2); | ||
341 | #if ENABLE_FEATURE_SEAMLESS_GZ | ||
342 | #if BB_MMU | ||
343 | xformer = unpack_gz_stream; | ||
344 | #else | ||
345 | xformer_prog = "gunzip"; | ||
346 | #endif | ||
347 | #endif | ||
348 | if (!ENABLE_FEATURE_SEAMLESS_GZ | ||
349 | || magic[0] != 0x1f || magic[1] != 0x8b | ||
350 | ) { | ||
351 | if (!ENABLE_FEATURE_SEAMLESS_BZ2 | ||
352 | || magic[0] != 'B' || magic[1] != 'Z' | ||
353 | ) { | ||
354 | bb_error_msg_and_die("no gzip" | ||
355 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | ||
356 | " magic"); | ||
357 | } | ||
358 | #if BB_MMU | ||
359 | xformer = unpack_bz2_stream; | ||
360 | #else | ||
361 | xformer_prog = "bunzip2"; | ||
362 | #endif | ||
363 | } else { | ||
364 | #if !BB_MMU | ||
365 | /* NOMMU version of open_transformer execs | ||
366 | * an external unzipper that wants | ||
367 | * file position at the start of the file */ | ||
368 | xlseek(fd, 0, SEEK_SET); | ||
369 | #endif | ||
370 | } | ||
371 | open_transformer(fd, xformer, xformer_prog); | ||
372 | } | 391 | } |
373 | } | 392 | } |
374 | 393 | ||