aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-08-10 10:35:08 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-08-10 10:36:37 +0200
commit0cf64c8b5d86d603903397bfce87dea5a862caec (patch)
tree66ee79e6c9c2ff17c84b776b4ce36439cf9f94e0
parent3c9b8fe25233dc52bbeec2ab29e49b8f62e4739b (diff)
downloadbusybox-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.c38
-rw-r--r--archival/rpm.c17
-rw-r--r--include/libbb.h4
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, 228static void fork_transformer_and_free(transformer_state_t *xstate)
229 * thus we can't guess the format from filename's extension.
230 */
231int 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 */
247int 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 */
261void 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
255static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) 271static 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)
510int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 512int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
511int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) 513int 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! */
866extern int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; 866int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC;
867/* Autodetects .gz etc */ 867/* Autodetects .gz etc */
868extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; 868extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC;
869extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; 869extern 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 */
876void setup_lzma_on_fd(int fd) FAST_FUNC;
875 877
876extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC; 878extern 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,