diff options
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/read.c | 97 |
1 files changed, 55 insertions, 42 deletions
diff --git a/libbb/read.c b/libbb/read.c index 06ce29718..503216eb5 100644 --- a/libbb/read.c +++ b/libbb/read.c @@ -6,7 +6,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ - #include "libbb.h" #define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \ @@ -16,7 +15,7 @@ ) #if ZIPPED -#include "unarchive.h" +# include "unarchive.h" #endif 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) return buf; } -int FAST_FUNC open_zipped(const char *fname) +#if ZIPPED +int FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) { -#if !ZIPPED - return open(fname, O_RDONLY); -#else + const int fail_if_not_detected = 1; unsigned char magic[2]; - char *sfx; - int fd; #if BB_MMU IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); enum { xformer_prog = 0 }; @@ -322,6 +318,56 @@ int FAST_FUNC open_zipped(const char *fname) const char *xformer_prog; #endif + /* .gz and .bz2 both have 2-byte signature, and their + * unpack_XXX_stream wants this header skipped. */ + xread(fd, &magic, 2); +#if ENABLE_FEATURE_SEAMLESS_GZ +# if BB_MMU + xformer = unpack_gz_stream; +# else + xformer_prog = "gunzip"; +# endif +#endif + if (!ENABLE_FEATURE_SEAMLESS_GZ + || magic[0] != 0x1f || magic[1] != 0x8b + ) { + if (!ENABLE_FEATURE_SEAMLESS_BZ2 + || magic[0] != 'B' || magic[1] != 'Z' + ) { + if (fail_if_not_detected) + bb_error_msg_and_die("no gzip" + IF_FEATURE_SEAMLESS_BZ2("/bzip2") + " magic"); + xlseek(fd, -2, SEEK_CUR); + return fd; + } +#if BB_MMU + xformer = unpack_bz2_stream; +#else + xformer_prog = "bunzip2"; +#endif + } else { +#if !BB_MMU + /* NOMMU version of open_transformer execs + * an external unzipper that wants + * file position at the start of the file */ + xlseek(fd, -2, SEEK_CUR); +#endif + } + open_transformer(fd, xformer, xformer_prog); + + return fd; +} +#endif /* ZIPPED */ + +int FAST_FUNC open_zipped(const char *fname) +{ +#if !ZIPPED + return open(fname, O_RDONLY); +#else + char *sfx; + int fd; + fd = open(fname, O_RDONLY); if (fd < 0) return fd; @@ -335,40 +381,7 @@ int FAST_FUNC open_zipped(const char *fname) if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, ".gz") == 0) || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0) ) { - /* .gz and .bz2 both have 2-byte signature, and their - * unpack_XXX_stream wants this header skipped. */ - xread(fd, &magic, 2); -#if ENABLE_FEATURE_SEAMLESS_GZ -#if BB_MMU - xformer = unpack_gz_stream; -#else - xformer_prog = "gunzip"; -#endif -#endif - if (!ENABLE_FEATURE_SEAMLESS_GZ - || magic[0] != 0x1f || magic[1] != 0x8b - ) { - if (!ENABLE_FEATURE_SEAMLESS_BZ2 - || magic[0] != 'B' || magic[1] != 'Z' - ) { - bb_error_msg_and_die("no gzip" - IF_FEATURE_SEAMLESS_BZ2("/bzip2") - " magic"); - } -#if BB_MMU - xformer = unpack_bz2_stream; -#else - xformer_prog = "bunzip2"; -#endif - } else { -#if !BB_MMU - /* NOMMU version of open_transformer execs - * an external unzipper that wants - * file position at the start of the file */ - xlseek(fd, 0, SEEK_SET); -#endif - } - open_transformer(fd, xformer, xformer_prog); + setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/); } } |