rpm2cpio: handle LZMA compressed rpms. closes 10166
No binary (build failed)
—
(log yok)
| @@ -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) | |
| { | |
| @@ -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"); | |
| @@ -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, | |