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-w32-0cf64c8b5d86d603903397bfce87dea5a862caec.tar.gz busybox-w32-0cf64c8b5d86d603903397bfce87dea5a862caec.tar.bz2 busybox-w32-0cf64c8b5d86d603903397bfce87dea5a862caec.zip |
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 | |||
225 | return xstate; | 225 | return xstate; |
226 | } | 226 | } |
227 | 227 | ||
228 | /* Used by e.g. rpm which gives us a fd without filename, | 228 | static void fork_transformer_and_free(transformer_state_t *xstate) |
229 | * thus we can't guess the format from filename's extension. | ||
230 | */ | ||
231 | int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | ||
232 | { | 229 | { |
233 | transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); | ||
234 | |||
235 | if (!xstate || !xstate->xformer) { | ||
236 | free(xstate); | ||
237 | return 1; | ||
238 | } | ||
239 | |||
240 | # if BB_MMU | 230 | # if BB_MMU |
241 | fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); | 231 | fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); |
242 | # else | 232 | # else |
@@ -249,8 +239,34 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | |||
249 | fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); | 239 | fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); |
250 | # endif | 240 | # endif |
251 | free(xstate); | 241 | free(xstate); |
242 | } | ||
243 | |||
244 | /* Used by e.g. rpm which gives us a fd without filename, | ||
245 | * thus we can't guess the format from filename's extension. | ||
246 | */ | ||
247 | int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | ||
248 | { | ||
249 | transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); | ||
250 | |||
251 | if (!xstate->xformer) { | ||
252 | free(xstate); | ||
253 | return 1; | ||
254 | } | ||
255 | |||
256 | fork_transformer_and_free(xstate); | ||
252 | return 0; | 257 | return 0; |
253 | } | 258 | } |
259 | #if ENABLE_FEATURE_SEAMLESS_LZMA | ||
260 | /* ...and custom version for LZMA */ | ||
261 | void FAST_FUNC setup_lzma_on_fd(int fd) | ||
262 | { | ||
263 | transformer_state_t *xstate = xzalloc(sizeof(*xstate)); | ||
264 | xstate->src_fd = fd; | ||
265 | xstate->xformer = unpack_lzma_stream; | ||
266 | USE_FOR_NOMMU(xstate->xformer_prog = "unlzma";) | ||
267 | fork_transformer_and_free(xstate); | ||
268 | } | ||
269 | #endif | ||
254 | 270 | ||
255 | static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) | 271 | static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) |
256 | { | 272 | { |
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 @@ | |||
56 | #define TAG_DIRINDEXES 1116 | 56 | #define TAG_DIRINDEXES 1116 |
57 | #define TAG_BASENAMES 1117 | 57 | #define TAG_BASENAMES 1117 |
58 | #define TAG_DIRNAMES 1118 | 58 | #define TAG_DIRNAMES 1118 |
59 | #define TAG_PAYLOADCOMPRESSOR 1125 | ||
60 | |||
59 | 61 | ||
60 | #define RPMFILE_CONFIG (1 << 0) | 62 | #define RPMFILE_CONFIG (1 << 0) |
61 | #define RPMFILE_DOC (1 << 1) | 63 | #define RPMFILE_DOC (1 << 1) |
@@ -510,6 +512,7 @@ int rpm_main(int argc, char **argv) | |||
510 | int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 512 | int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
511 | int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | 513 | int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) |
512 | { | 514 | { |
515 | const char *str; | ||
513 | int rpm_fd; | 516 | int rpm_fd; |
514 | 517 | ||
515 | G.pagesize = getpagesize(); | 518 | G.pagesize = getpagesize(); |
@@ -520,11 +523,17 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |||
520 | // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ | 523 | // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ |
521 | // signal(SIGCHLD, check_errors_in_children); | 524 | // signal(SIGCHLD, check_errors_in_children); |
522 | 525 | ||
523 | //TODO: look for rpm tag RPMTAG_PAYLOADCOMPRESSOR (dec 1125, hex 0x465), | 526 | if (ENABLE_FEATURE_SEAMLESS_LZMA |
524 | // if the value is "lzma", set up decompressor without detection | 527 | && (str = rpm_getstr0(TAG_PAYLOADCOMPRESSOR)) != NULL |
525 | // (lzma can't be detected). | 528 | && strcmp(str, "lzma") == 0 |
529 | ) { | ||
530 | // lzma compression can't be detected | ||
531 | // set up decompressor without detection | ||
532 | setup_lzma_on_fd(rpm_fd); | ||
533 | } else { | ||
534 | setup_unzip_on_fd(rpm_fd, /*fail_if_not_compressed:*/ 1); | ||
535 | } | ||
526 | 536 | ||
527 | setup_unzip_on_fd(rpm_fd, /*fail_if_not_compressed:*/ 1); | ||
528 | if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) | 537 | if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) |
529 | bb_error_msg_and_die("error unpacking"); | 538 | bb_error_msg_and_die("error unpacking"); |
530 | 539 | ||
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; | |||
863 | 863 | ||
864 | #if SEAMLESS_COMPRESSION | 864 | #if SEAMLESS_COMPRESSION |
865 | /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ | 865 | /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ |
866 | extern int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; | 866 | int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; |
867 | /* Autodetects .gz etc */ | 867 | /* Autodetects .gz etc */ |
868 | extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; | 868 | extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; |
869 | extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; | 869 | 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) | |||
872 | # define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY); | 872 | # define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY); |
873 | # define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p)) | 873 | # define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p)) |
874 | #endif | 874 | #endif |
875 | /* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */ | ||
876 | void setup_lzma_on_fd(int fd) FAST_FUNC; | ||
875 | 877 | ||
876 | extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC; | 878 | extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC; |
877 | // NB: will return short write on error, not -1, | 879 | // NB: will return short write on error, not -1, |