diff options
author | Denis Vlasenko | 2008-08-05 13:10:34 +0000 |
---|---|---|
committer | Denis Vlasenko | 2008-08-05 13:10:34 +0000 |
commit | e9ad84dfd4c7eb2936374f02989dacf7026a7276 (patch) | |
tree | 37412d21c0a2ccec7c162e0fb42833058f5934e3 /libbb/read.c | |
parent | 9b44613202a6f2f080ec23746d0680dcef88628d (diff) | |
download | busybox-e9ad84dfd4c7eb2936374f02989dacf7026a7276.zip busybox-e9ad84dfd4c7eb2936374f02989dacf7026a7276.tar.gz |
*: refactor handling of archived files. "tar f file.tar.lzma" now works too.
function old new delta
unpack_Z_stream - 1229 +1229
open_zipped - 176 +176
unpack_bz2_stream_prime - 60 +60
tar_main 642 677 +35
find_main 406 418 +12
sv_main 1222 1233 +11
decode_format_string 829 837 +8
cmp_main 641 649 +8
popstring 134 140 +6
filter_accept_list_reassign 120 125 +5
parse_and_put_prompt 800 804 +4
passwd_main 1053 1049 -4
make_new_name_gunzip 119 114 -5
rpm_main 1688 1670 -18
prepare 302 283 -19
xmalloc_open_zipped_read_close 135 61 -74
uncompress 1229 - -1229
------------------------------------------------------------------------------
(add/remove: 3/1 grow/shrink: 8/5 up/down: 1554/-1349) Total: 205 bytes
Diffstat (limited to 'libbb/read.c')
-rw-r--r-- | libbb/read.c | 89 |
1 files changed, 76 insertions, 13 deletions
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 |