diff options
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/appletlib.c | 3 | ||||
-rw-r--r-- | libbb/read.c | 89 |
2 files changed, 78 insertions, 14 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index beb1d6f..2bab0eb 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -73,7 +73,8 @@ static const char *unpack_usage_messages(void) i = start_bunzip(&bd, /* src_fd: */ -1, - /* inbuf: */ (void *)packed_usage, +//FIXME: can avoid storing these 2 bytes! + /* inbuf: */ (void *)packed_usage + 2, /* len: */ sizeof(packed_usage)); /* read_bunzip can longjmp to start_bunzip, and ultimately * end up here with i != 0 on read data errors! Not trivial */ diff --git a/libbb/read.c b/libbb/read.c index 18f6283..9f6bfcd 100644 --- a/libbb/read.c +++ b/libbb/read.c @@ -8,7 +8,14 @@ */ #include "libbb.h" -#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED + +#define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \ + || ENABLE_FEATURE_SEAMLESS_BZ2 \ + || ENABLE_FEATURE_SEAMLESS_GZ \ + /* || ENABLE_FEATURE_SEAMLESS_Z */ \ +) + +#if ZIPPED #include "unarchive.h" #endif @@ -299,24 +306,81 @@ void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) return buf; } -#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED +int FAST_FUNC open_zipped(const char *fname) +{ +#if !ZIPPED + return open(fname, O_RDONLY); +#else + unsigned char magic[2]; + char *sfx; + int fd; +#if BB_MMU + USE_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); + enum { xformer_prog = 0 }; +#else + enum { xformer = 0 }; + const char *xformer_prog; +#endif + + fd = open(fname, O_RDONLY); + if (fd < 0) + return fd; + + sfx = strrchr(fname, '.'); + if (sfx) { + if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, ".lzma") == 0) + /* .lzma has no header/signature, just trust it */ + open_transformer(fd, unpack_lzma_stream, "unlzma"); + else + 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 want this header skipped. */ + xread(fd, &magic, 2); +#if BB_MMU + xformer = unpack_gz_stream; +#else + xformer_prog = "gunzip"; +#endif + if (magic[0] != 0x1f || magic[1] != 0x8b) { + if (!ENABLE_FEATURE_SEAMLESS_BZ2 + || magic[0] != 'B' || magic[1] != 'Z' + ) { + bb_error_msg_and_die("no gzip" + USE_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); + } + } + + return fd; +#endif +} + void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) { + int fd; char *image; - char *suffix; - int fd = open(fname, O_RDONLY); + fd = open_zipped(fname); if (fd < 0) return NULL; - suffix = strrchr(fname, '.'); - if (suffix) { - if (strcmp(suffix, ".gz") == 0) - open_transformer(fd, unpack_gz_stream, "gunzip"); - else if (strcmp(suffix, ".bz2") == 0) - open_transformer(fd, unpack_bz2_stream, "bunzip2"); - } - image = xmalloc_read(fd, maxsz_p); if (!image) bb_perror_msg("read error from '%s'", fname); @@ -324,4 +388,3 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ return image; } -#endif |