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>
This commit is contained in:
Denys Vlasenko 2017-08-10 10:35:08 +02:00
parent 3c9b8fe252
commit 0cf64c8b5d
3 changed files with 43 additions and 16 deletions

View File

@ -225,18 +225,8 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp
return xstate; return xstate;
} }
/* Used by e.g. rpm which gives us a fd without filename, static void fork_transformer_and_free(transformer_state_t *xstate)
* 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 || !xstate->xformer) {
free(xstate);
return 1;
}
# if BB_MMU # if BB_MMU
fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer);
# else # 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); fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog);
# endif # endif
free(xstate); 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; 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) static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed)
{ {

View File

@ -56,6 +56,8 @@
#define TAG_DIRINDEXES 1116 #define TAG_DIRINDEXES 1116
#define TAG_BASENAMES 1117 #define TAG_BASENAMES 1117
#define TAG_DIRNAMES 1118 #define TAG_DIRNAMES 1118
#define TAG_PAYLOADCOMPRESSOR 1125
#define RPMFILE_CONFIG (1 << 0) #define RPMFILE_CONFIG (1 << 0)
#define RPMFILE_DOC (1 << 1) #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, char **argv) MAIN_EXTERNALLY_VISIBLE;
int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
{ {
const char *str;
int rpm_fd; int rpm_fd;
G.pagesize = getpagesize(); 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 */ // /* We need to know whether child (gzip/bzip/etc) exits abnormally */
// signal(SIGCHLD, check_errors_in_children); // signal(SIGCHLD, check_errors_in_children);
//TODO: look for rpm tag RPMTAG_PAYLOADCOMPRESSOR (dec 1125, hex 0x465), if (ENABLE_FEATURE_SEAMLESS_LZMA
// if the value is "lzma", set up decompressor without detection && (str = rpm_getstr0(TAG_PAYLOADCOMPRESSOR)) != NULL
// (lzma can't be detected). && 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) if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0)
bb_error_msg_and_die("error unpacking"); bb_error_msg_and_die("error unpacking");

View File

@ -863,7 +863,7 @@ unsigned bb_clk_tck(void) FAST_FUNC;
#if SEAMLESS_COMPRESSION #if SEAMLESS_COMPRESSION
/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ /* 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 */ /* Autodetects .gz etc */
extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; 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; 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 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)) # define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p))
#endif #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; extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC;
// NB: will return short write on error, not -1, // NB: will return short write on error, not -1,