From 8a6a2f9c9c214b94bd945acd97ac8b28c25e194e Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Tue, 6 Mar 2012 16:27:48 +0100
Subject: update seamless uncompression code

This change makes "tar tf hello_world.txz" work without
adding special-casing for ".txz" extension. It also removes
ever-growing magic checking code in rpm2cpio and get_header_tar -
we reuse one which lives in setup_unzip_on_fd.

function                                             old     new   delta
unpack_gz_stream                                       7     566    +559
check_signature16                                      -      70     +70
setup_unzip_on_fd                                     99     142     +43
handle_SIGCHLD                                         -      41     +41
unpack_bz2_stream                                    342     376     +34
unzip_main                                          2352    2385     +33
bbunpack                                             503     533     +30
open_transformer                                      74     102     +28
unpack_Z_stream                                     1278    1304     +26
unpack_gunzip                                        101     123     +22
init_transformer_aux_data                              -      18     +18
unpack_xz_stream                                    2388    2402     +14
open_zipped                                          131     141     +10
rpm_main                                            1358    1363      +5
get_header_tar_lzma                                   52      57      +5
get_header_tar_bz2                                    52      57      +5
unpack_lzma_stream                                  2698    2702      +4
hash_find                                            234     233      -1
get_header_tar                                      1759    1733     -26
get_header_tar_gz                                     92      57     -35
unpack_uncompress                                     51      12     -39
rpm2cpio_main                                        201     147     -54
unpack_unxz                                           67      12     -55
unpack_bz2_stream_prime                               55       -     -55
get_header_tar_Z                                      86       -     -86
unpack_gz_stream_with_info                           539       -    -539
------------------------------------------------------------------------------
(add/remove: 3/3 grow/shrink: 14/6 up/down: 947/-890)          Total: 57 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 include/bb_archive.h | 56 ++++++++++++++++++++++++++--------------------------
 include/libbb.h      | 14 ++++++-------
 2 files changed, 34 insertions(+), 36 deletions(-)

(limited to 'include')

diff --git a/include/bb_archive.h b/include/bb_archive.h
index 4987de6cf..bd08115da 100644
--- a/include/bb_archive.h
+++ b/include/bb_archive.h
@@ -156,12 +156,6 @@ struct BUG_tar_header {
 
 
 
-/* Info struct unpackers can fill out to inform users of thing like
- * timestamps of unpacked files */
-typedef struct unpack_info_t {
-	time_t mtime;
-} unpack_info_t;
-
 archive_handle_t *init_handle(void) FAST_FUNC;
 
 char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC;
@@ -204,40 +198,46 @@ int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_
 int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC;
 void dealloc_bunzip(bunzip_data *bd) FAST_FUNC;
 
-typedef struct inflate_unzip_result {
-	off_t bytes_out;
-	uint32_t crc;
-} inflate_unzip_result;
-
-IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC;
-/* xz unpacker takes .xz stream from offset 6 */
-IF_DESKTOP(long long) int unpack_xz_stream(int src_fd, int dst_fd) FAST_FUNC;
-/* lzma unpacker takes .lzma stream from offset 0 */
-IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC;
-/* the rest wants 2 first bytes already skipped by the caller */
-IF_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC;
-IF_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC;
-IF_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC;
-IF_DESKTOP(long long) int unpack_Z_stream(int src_fd, int dst_fd) FAST_FUNC;
-/* wrapper which checks first two bytes to be "BZ" */
-IF_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC;
+/* Meaning and direction (input/output) of the fields are transformer-specific */
+typedef struct transformer_aux_data_t {
+	smallint check_signature; /* most often referenced member */
+	off_t    bytes_out;
+	off_t    bytes_in;  /* used in unzip code only: needs to know packed size */
+	uint32_t crc32;
+	time_t   mtime;     /* gunzip code may set this on exit */
+} transformer_aux_data_t;
+
+void init_transformer_aux_data(transformer_aux_data_t *aux) FAST_FUNC;
+int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16) FAST_FUNC;
+
+IF_DESKTOP(long long) int inflate_unzip(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC;
+IF_DESKTOP(long long) int unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC;
+IF_DESKTOP(long long) int unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC;
+IF_DESKTOP(long long) int unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC;
+IF_DESKTOP(long long) int unpack_lzma_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC;
+IF_DESKTOP(long long) int unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC;
 
 char* append_ext(char *filename, const char *expected_ext) FAST_FUNC;
 int bbunpack(char **argv,
-	    IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info),
+	    IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux),
 	    char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext),
 	    const char *expected_ext
 ) FAST_FUNC;
 
 #if BB_MMU
 void open_transformer(int fd,
-	IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC;
-#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transformer)
+	int check_signature,
+	IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd)
+) FAST_FUNC;
+#define open_transformer_with_sig(fd, transformer, transform_prog) open_transformer((fd), 1, (transformer))
+#define open_transformer_with_no_sig(fd, transformer)              open_transformer((fd), 0, (transformer))
 #else
-void open_transformer(int src_fd, const char *transform_prog) FAST_FUNC;
-#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transform_prog)
+void open_transformer(int fd, const char *transform_prog) FAST_FUNC;
+#define open_transformer_with_sig(fd, transformer, transform_prog) open_transformer((fd), (transform_prog))
+/* open_transformer_with_no_sig() does not exist on NOMMU */
 #endif
 
+
 POP_SAVED_FUNCTION_VISIBILITY
 
 #endif
diff --git a/include/libbb.h b/include/libbb.h
index c896e5484..2cc146631 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -721,17 +721,15 @@ extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAS
  || ENABLE_FEATURE_SEAMLESS_GZ \
  || ENABLE_FEATURE_SEAMLESS_Z)
 
+#if SEAMLESS_COMPRESSION
 /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */
-#if ENABLE_FEATURE_SEAMLESS_LZMA \
- || ENABLE_FEATURE_SEAMLESS_BZ2 \
- || ENABLE_FEATURE_SEAMLESS_GZ \
- /* || ENABLE_FEATURE_SEAMLESS_Z */
-extern void setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) FAST_FUNC;
-#else
-# define setup_unzip_on_fd(...) ((void)0)
-#endif
+extern int setup_unzip_on_fd(int fd, int fail_if_not_detected) FAST_FUNC;
 /* Autodetects .gz etc */
 extern int open_zipped(const char *fname) FAST_FUNC;
+#else
+# define setup_unzip_on_fd(...) (0)
+# define open_zipped(fname)     open((fname), O_RDONLY);
+#endif
 extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
 
 extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC;
-- 
cgit v1.2.3