diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-10 10:35:08 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-10 10:36:37 +0200 |
commit | 0cf64c8b5d86d603903397bfce87dea5a862caec (patch) | |
tree | 66ee79e6c9c2ff17c84b776b4ce36439cf9f94e0 | |
parent | 3c9b8fe25233dc52bbeec2ab29e49b8f62e4739b (diff) | |
download | busybox-0cf64c8b5d86d603903397bfce87dea5a862caec.tar.gz |
rpm2cpio: handle LZMA compressed rpms. closes 10166
function old new delta
rpm2cpio_main 78 120 +42
setup_lzma_on_fd - 29 +29
fork_transformer_and_free - 28 +28
...
setup_unzip_on_fd 56 32 -24
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 3/5 up/down: 104/-67) Total: 37 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/open_transformer.c | 38 | ||||
-rw-r--r-- | archival/rpm.c | 17 | ||||
-rw-r--r-- | include/libbb.h | 4 |
3 files changed, 43 insertions, 16 deletions
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index ac7e5db95..290dd130f 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -225,18 +225,8 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp return xstate; } -/* Used by e.g. rpm which gives us a fd without filename, - * thus we can't guess the format from filename's extension. - */ -int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) +static void fork_transformer_and_free(transformer_state_t *xstate) { - transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); - - if (!xstate || !xstate->xformer) { - free(xstate); - return 1; - } - # if BB_MMU fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); # else @@ -249,8 +239,34 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); # endif free(xstate); +} + +/* Used by e.g. rpm which gives us a fd without filename, + * thus we can't guess the format from filename's extension. + */ +int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) +{ + transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); + + if (!xstate->xformer) { + free(xstate); + return 1; + } + + fork_transformer_and_free(xstate); return 0; } +#if ENABLE_FEATURE_SEAMLESS_LZMA +/* ...and custom version for LZMA */ +void FAST_FUNC setup_lzma_on_fd(int fd) +{ + transformer_state_t *xstate = xzalloc(sizeof(*xstate)); + xstate->src_fd = fd; + xstate->xformer = unpack_lzma_stream; + USE_FOR_NOMMU(xstate->xformer_prog = "unlzma";) + fork_transformer_and_free(xstate); +} +#endif static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) { diff --git a/archival/rpm.c b/archival/rpm.c index f46d88b92..cca17da33 100644 --- a/archival/rpm.c +++ b/archival/rpm.c @@ -56,6 +56,8 @@ #define TAG_DIRINDEXES 1116 #define TAG_BASENAMES 1117 #define TAG_DIRNAMES 1118 +#define TAG_PAYLOADCOMPRESSOR 1125 + #define RPMFILE_CONFIG (1 << 0) #define RPMFILE_DOC (1 << 1) @@ -510,6 +512,7 @@ int rpm_main(int argc, char **argv) int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) { + const char *str; int rpm_fd; G.pagesize = getpagesize(); @@ -520,11 +523,17 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ // signal(SIGCHLD, check_errors_in_children); -//TODO: look for rpm tag RPMTAG_PAYLOADCOMPRESSOR (dec 1125, hex 0x465), -// if the value is "lzma", set up decompressor without detection -// (lzma can't be detected). + if (ENABLE_FEATURE_SEAMLESS_LZMA + && (str = rpm_getstr0(TAG_PAYLOADCOMPRESSOR)) != NULL + && strcmp(str, "lzma") == 0 + ) { + // lzma compression can't be detected + // set up decompressor without detection + setup_lzma_on_fd(rpm_fd); + } else { + setup_unzip_on_fd(rpm_fd, /*fail_if_not_compressed:*/ 1); + } - setup_unzip_on_fd(rpm_fd, /*fail_if_not_compressed:*/ 1); if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) bb_error_msg_and_die("error unpacking"); diff --git a/include/libbb.h b/include/libbb.h index 2eb1fef33..86ad0a057 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -863,7 +863,7 @@ unsigned bb_clk_tck(void) FAST_FUNC; #if SEAMLESS_COMPRESSION /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ -extern int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; +int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; /* Autodetects .gz etc */ extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; @@ -872,6 +872,8 @@ extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) # define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY); # define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p)) #endif +/* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */ +void setup_lzma_on_fd(int fd) FAST_FUNC; extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC; // NB: will return short write on error, not -1, |