update seamless uncompression code
No binary (build failed)
—
(log yok)
| @@ -33,7 +33,7 @@ char* FAST_FUNC append_ext(char *filename, const char *expected_ext) | |
| } | |
| int FAST_FUNC bbunpack(char **argv, | |
| - | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info), |
| + | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux), |
| char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), | |
| const char *expected_ext | |
| ) | |
| @@ -42,7 +42,7 @@ int FAST_FUNC bbunpack(char **argv, | |
| IF_DESKTOP(long long) int status; | |
| char *filename, *new_name; | |
| smallint exitcode = 0; | |
| - | unpack_info_t info; |
| + | transformer_aux_data_t aux; |
| do { | |
| /* NB: new_name is *maybe* malloc'ed! */ | |
| @@ -98,9 +98,9 @@ int FAST_FUNC bbunpack(char **argv, | |
| "use -f to force it"); | |
| } | |
| - | /* memset(&info, 0, sizeof(info)); */ |
| - | info.mtime = 0; /* so far it has one member only */ |
| - | status = unpacker(&info); |
| + | init_transformer_aux_data(&aux); |
| + | aux.check_signature = 1; |
| + | status = unpacker(&aux); |
| if (status < 0) | |
| exitcode = 1; | |
| @@ -111,10 +111,10 @@ int FAST_FUNC bbunpack(char **argv, | |
| char *del = new_name; | |
| if (status >= 0) { | |
| /* TODO: restore other things? */ | |
| - | if (info.mtime) { |
| + | if (aux.mtime != 0) { |
| struct timeval times[2]; | |
| - | times[1].tv_sec = times[0].tv_sec = info.mtime; |
| + | times[1].tv_sec = times[0].tv_sec = aux.mtime; |
| times[1].tv_usec = times[0].tv_usec = 0; | |
| /* Note: we closed it first. | |
| * On some systems calling utimes | |
| @@ -182,16 +182,9 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) | |
| #if ENABLE_UNCOMPRESS | |
| static | |
| - | IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(unpack_info_t *info UNUSED_PARAM) |
| + | IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(transformer_aux_data_t *aux) |
| { | |
| - | IF_DESKTOP(long long) int status = -1; |
| - | |
| - | if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) { |
| - | bb_error_msg("invalid magic"); |
| - | } else { |
| - | status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); |
| - | } |
| - | return status; |
| + | return unpack_Z_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
| } | |
| int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int uncompress_main(int argc UNUSED_PARAM, char **argv) | |
| @@ -279,30 +272,30 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN | |
| return filename; | |
| } | |
| static | |
| - | IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(unpack_info_t *info) |
| + | IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(transformer_aux_data_t *aux) |
| { | |
| IF_DESKTOP(long long) int status = -1; | |
| + | uint16_t magic2; |
| - | /* do the decompression, and cleanup */ |
| - | if (xread_char(STDIN_FILENO) == 0x1f) { |
| - | unsigned char magic2; |
| - | |
| - | magic2 = xread_char(STDIN_FILENO); |
| - | if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == 0x9d) { |
| - | status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); |
| - | } else if (magic2 == 0x8b) { |
| - | status = unpack_gz_stream_with_info(STDIN_FILENO, STDOUT_FILENO, info); |
| - | } else { |
| - | goto bad_magic; |
| - | } |
| - | if (status < 0) { |
| - | bb_error_msg("error inflating"); |
| - | } |
| + | //TODO: fold below into unpack_gz_stream? Then the whole level of indirection |
| + | // unpack_FOO() -> unpack_FOO_stream can be collapsed in this module! |
| + | |
| + | aux->check_signature = 0; /* we will check it here, not in unpack_*_stream */ |
| + | |
| + | if (full_read(STDIN_FILENO, &magic2, 2) != 2) |
| + | goto bad_magic; |
| + | if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == COMPRESS_MAGIC) { |
| + | status = unpack_Z_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
| + | } else if (magic2 == GZIP_MAGIC) { |
| + | status = unpack_gz_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
| } else { | |
| bad_magic: | |
| bb_error_msg("invalid magic"); | |
| /* status is still == -1 */ | |
| } | |
| + | if (status < 0) { |
| + | bb_error_msg("error inflating"); |
| + | } |
| return status; | |
| } | |
| /* | |
| @@ -352,9 +345,9 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |
| //applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) | |
| #if ENABLE_BUNZIP2 | |
| static | |
| - | IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(unpack_info_t *info UNUSED_PARAM) |
| + | IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(transformer_aux_data_t *aux) |
| { | |
| - | return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO); |
| + | return unpack_bz2_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
| } | |
| int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |
| @@ -420,9 +413,9 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |
| #if ENABLE_UNLZMA | |
| static | |
| - | IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(unpack_info_t *info UNUSED_PARAM) |
| + | IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(transformer_aux_data_t *aux) |
| { | |
| - | return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO); |
| + | return unpack_lzma_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
| } | |
| int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int unlzma_main(int argc UNUSED_PARAM, char **argv) | |
| @@ -445,18 +438,9 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |
| #if ENABLE_UNXZ | |
| static | |
| - | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM) |
| + | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(transformer_aux_data_t *aux) |
| { | |
| - | struct { |
| - | uint32_t v1; |
| - | uint16_t v2; |
| - | } magic; |
| - | xread(STDIN_FILENO, &magic, 6); |
| - | if (magic.v1 != XZ_MAGIC1a || magic.v2 != XZ_MAGIC2a) { |
| - | bb_error_msg("invalid magic"); |
| - | return -1; |
| - | } |
| - | return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO); |
| + | return unpack_xz_stream(aux, STDIN_FILENO, STDOUT_FILENO); |
| } | |
| int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int unxz_main(int argc UNUSED_PARAM, char **argv) | |
| @@ -111,7 +111,7 @@ IF_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, vo | |
| } | |
| static | |
| - | IF_DESKTOP(long long) int FAST_FUNC compressStream(unpack_info_t *info UNUSED_PARAM) |
| + | IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_aux_data_t *aux UNUSED_PARAM) |
| { | |
| IF_DESKTOP(long long) int total; | |
| ssize_t count; | |
| @@ -2015,7 +2015,7 @@ static void zip(ulg time_stamp) | |
| /* ======================================================================== */ | |
| static | |
| - | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(unpack_info_t *info UNUSED_PARAM) |
| + | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_aux_data_t *aux UNUSED_PARAM) |
| { | |
| struct stat s; | |
| @@ -721,7 +721,7 @@ void FAST_FUNC dealloc_bunzip(bunzip_data *bd) | |
| /* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */ | |
| IF_DESKTOP(long long) int FAST_FUNC | |
| - | unpack_bz2_stream(int src_fd, int dst_fd) |
| + | unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
| { | |
| IF_DESKTOP(long long total_written = 0;) | |
| bunzip_data *bd; | |
| @@ -729,6 +729,9 @@ unpack_bz2_stream(int src_fd, int dst_fd) | |
| int i; | |
| unsigned len; | |
| + | if (check_signature16(aux, src_fd, BZIP2_MAGIC)) |
| + | return -1; |
| + | |
| outbuf = xmalloc(IOBUF_SIZE); | |
| len = 0; | |
| while (1) { /* "Process one BZ... stream" loop */ | |
| @@ -794,17 +797,6 @@ unpack_bz2_stream(int src_fd, int dst_fd) | |
| return i ? i : IF_DESKTOP(total_written) + 0; | |
| } | |
| - | IF_DESKTOP(long long) int FAST_FUNC |
| - | unpack_bz2_stream_prime(int src_fd, int dst_fd) |
| - | { |
| - | uint16_t magic2; |
| - | xread(src_fd, &magic2, 2); |
| - | if (magic2 != BZIP2_MAGIC) { |
| - | bb_error_msg_and_die("invalid magic"); |
| - | } |
| - | return unpack_bz2_stream(src_fd, dst_fd); |
| - | } |
| - | |
| #ifdef TESTING | |
| static char *const bunzip_errors[] = { | |
| @@ -819,7 +811,7 @@ int main(int argc, char **argv) | |
| int i; | |
| char c; | |
| - | int i = unpack_bz2_stream_prime(0, 1); |
| + | int i = unpack_bz2_stream(0, 1); |
| if (i < 0) | |
| fprintf(stderr, "%s\n", bunzip_errors[-i]); | |
| else if (read(STDIN_FILENO, &c, 1)) | |
| @@ -1034,22 +1034,22 @@ inflate_unzip_internal(STATE_PARAM int in, int out) | |
| /* For unzip */ | |
| IF_DESKTOP(long long) int FAST_FUNC | |
| - | inflate_unzip(inflate_unzip_result *res, off_t compr_size, int in, int out) |
| + | inflate_unzip(transformer_aux_data_t *aux, int in, int out) |
| { | |
| IF_DESKTOP(long long) int n; | |
| DECLARE_STATE; | |
| ALLOC_STATE; | |
| - | to_read = compr_size; |
| + | to_read = aux->bytes_in; |
| // bytebuffer_max = 0x8000; | |
| bytebuffer_offset = 4; | |
| bytebuffer = xmalloc(bytebuffer_max); | |
| n = inflate_unzip_internal(PASS_STATE in, out); | |
| free(bytebuffer); | |
| - | res->crc = gunzip_crc; |
| - | res->bytes_out = gunzip_bytes_out; |
| + | aux->crc32 = gunzip_crc; |
| + | aux->bytes_out = gunzip_bytes_out; |
| DEALLOC_STATE; | |
| return n; | |
| } | |
| @@ -1107,7 +1107,7 @@ static uint32_t buffer_read_le_u32(STATE_PARAM_ONLY) | |
| return res; | |
| } | |
| - | static int check_header_gzip(STATE_PARAM unpack_info_t *info) |
| + | static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux) |
| { | |
| union { | |
| unsigned char raw[8]; | |
| @@ -1169,8 +1169,8 @@ static int check_header_gzip(STATE_PARAM unpack_info_t *info) | |
| } | |
| } | |
| - | if (info) |
| - | info->mtime = SWAP_LE32(header.formatted.mtime); |
| + | if (aux) |
| + | aux->mtime = SWAP_LE32(header.formatted.mtime); |
| /* Read the header checksum */ | |
| if (header.formatted.flags & 0x02) { | |
| @@ -1182,12 +1182,15 @@ static int check_header_gzip(STATE_PARAM unpack_info_t *info) | |
| } | |
| IF_DESKTOP(long long) int FAST_FUNC | |
| - | unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) |
| + | unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
| { | |
| uint32_t v32; | |
| IF_DESKTOP(long long) int total, n; | |
| DECLARE_STATE; | |
| + | if (check_signature16(aux, src_fd, GZIP_MAGIC)) |
| + | return -1; |
| + | |
| total = 0; | |
| ALLOC_STATE; | |
| @@ -1197,7 +1200,7 @@ unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) | |
| gunzip_src_fd = src_fd; | |
| again: | |
| - | if (!check_header_gzip(PASS_STATE info)) { |
| + | if (!check_header_gzip(PASS_STATE aux)) { |
| bb_error_msg("corrupted data"); | |
| total = -1; | |
| goto ret; | |
| @@ -1248,9 +1251,3 @@ unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) | |
| DEALLOC_STATE; | |
| return total; | |
| } | |
| - | |
| - | IF_DESKTOP(long long) int FAST_FUNC |
| - | unpack_gz_stream(int in, int out) |
| - | { |
| - | return unpack_gz_stream_with_info(in, out, NULL); |
| - | } |
| @@ -73,7 +73,7 @@ | |
| */ | |
| IF_DESKTOP(long long) int FAST_FUNC | |
| - | unpack_Z_stream(int src_fd, int dst_fd) |
| + | unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
| { | |
| IF_DESKTOP(long long total_written = 0;) | |
| IF_DESKTOP(long long) int retval = -1; | |
| @@ -103,6 +103,9 @@ unpack_Z_stream(int src_fd, int dst_fd) | |
| /* block compress mode -C compatible with 2.0 */ | |
| int block_mode; /* = BLOCK_MODE; */ | |
| + | if (check_signature16(aux, src_fd, COMPRESS_MAGIC)) |
| + | return -1; |
| + | |
| inbuf = xzalloc(IBUFSIZ + 64); | |
| outbuf = xzalloc(OBUFSIZ + 2048); | |
| htab = xzalloc(HSIZE); /* wasn't zeroed out before, maybe can xmalloc? */ | |
| @@ -213,7 +213,7 @@ enum { | |
| IF_DESKTOP(long long) int FAST_FUNC | |
| - | unpack_lzma_stream(int src_fd, int dst_fd) |
| + | unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst_fd) |
| { | |
| IF_DESKTOP(long long total_written = 0;) | |
| lzma_header_t header; | |
| @@ -38,7 +38,7 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) | |
| #include "unxz/xz_dec_stream.c" | |
| IF_DESKTOP(long long) int FAST_FUNC | |
| - | unpack_xz_stream(int src_fd, int dst_fd) |
| + | unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
| { | |
| struct xz_buf iobuf; | |
| struct xz_dec *state; | |
| @@ -49,13 +49,17 @@ unpack_xz_stream(int src_fd, int dst_fd) | |
| global_crc32_table = crc32_filltable(NULL, /*endian:*/ 0); | |
| memset(&iobuf, 0, sizeof(iobuf)); | |
| - | /* Preload XZ file signature */ |
| - | membuf = (void*) strcpy(xmalloc(2 * BUFSIZ), HEADER_MAGIC); |
| + | membuf = xmalloc(2 * BUFSIZ); |
| iobuf.in = membuf; | |
| - | iobuf.in_size = HEADER_MAGIC_SIZE; |
| iobuf.out = membuf + BUFSIZ; | |
| iobuf.out_size = BUFSIZ; | |
| + | if (!aux || aux->check_signature == 0) { |
| + | /* Preload XZ file signature */ |
| + | strcpy((char*)membuf, HEADER_MAGIC); |
| + | iobuf.in_size = HEADER_MAGIC_SIZE; |
| + | } /* else: let xz code read & check it */ |
| + | |
| /* Limit memory usage to about 64 MiB. */ | |
| state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024); | |
| @@ -235,43 +235,18 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |
| || memcmp(tar.magic, "\0\0\0\0", 5) != 0) | |
| ) { | |
| #if ENABLE_FEATURE_TAR_AUTODETECT | |
| - | char FAST_FUNC (*get_header_ptr)(archive_handle_t *); |
| - | uint16_t magic2; |
| - | |
| autodetect: | |
| - | magic2 = *(bb__aliased_uint16_t*)tar.name; |
| - | /* tar gz/bz autodetect: check for gz/bz2 magic. |
| - | * If we see the magic, and it is the very first block, |
| - | * we can switch to get_header_tar_gz/bz2/lzma(). |
| - | * Needs seekable fd. I wish recv(MSG_PEEK) works |
| - | * on any fd... */ |
| - | # if ENABLE_FEATURE_SEAMLESS_GZ |
| - | if (magic2 == GZIP_MAGIC) { |
| - | get_header_ptr = get_header_tar_gz; |
| - | } else |
| - | # endif |
| - | # if ENABLE_FEATURE_SEAMLESS_BZ2 |
| - | if (magic2 == BZIP2_MAGIC |
| - | && tar.name[2] == 'h' && isdigit(tar.name[3]) |
| - | ) { /* bzip2 */ |
| - | get_header_ptr = get_header_tar_bz2; |
| - | } else |
| - | # endif |
| - | # if ENABLE_FEATURE_SEAMLESS_XZ |
| - | //TODO: if (magic2 == XZ_MAGIC1)... |
| - | //else |
| - | # endif |
| - | goto err; |
| /* Two different causes for lseek() != 0: | |
| * unseekable fd (would like to support that too, but...), | |
| * or not first block (false positive, it's not .gz/.bz2!) */ | |
| if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0) | |
| goto err; | |
| - | while (get_header_ptr(archive_handle) == EXIT_SUCCESS) |
| - | continue; |
| - | return EXIT_FAILURE; |
| + | if (setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_detected:*/ 0) != 0) |
| err: | |
| - | #endif /* FEATURE_TAR_AUTODETECT */ |
| + | bb_error_msg_and_die("invalid tar magic"); |
| + | archive_handle->offset = 0; |
| + | goto again_after_align; |
| + | #endif |
| bb_error_msg_and_die("invalid tar magic"); | |
| } | |
| @@ -11,7 +11,7 @@ char FAST_FUNC get_header_tar_bz2(archive_handle_t *archive_handle) | |
| /* Can't lseek over pipes */ | |
| archive_handle->seek = seek_by_read; | |
| - | open_transformer(archive_handle->src_fd, unpack_bz2_stream_prime, "bunzip2"); |
| + | open_transformer_with_sig(archive_handle->src_fd, unpack_bz2_stream, "bunzip2"); |
| archive_handle->offset = 0; | |
| while (get_header_tar(archive_handle) == EXIT_SUCCESS) | |
| continue; | |
| @@ -8,25 +8,10 @@ | |
| char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) | |
| { | |
| - | #if BB_MMU |
| - | uint16_t magic; |
| - | #endif |
| - | |
| /* Can't lseek over pipes */ | |
| archive_handle->seek = seek_by_read; | |
| - | /* Check gzip magic only if open_transformer will invoke unpack_gz_stream (MMU case). |
| - | * Otherwise, it will invoke an external helper "gunzip -cf" (NOMMU case) which will |
| - | * need the header. */ |
| - | #if BB_MMU |
| - | xread(archive_handle->src_fd, &magic, 2); |
| - | /* Can skip this check, but error message will be less clear */ |
| - | if (magic != GZIP_MAGIC) { |
| - | bb_error_msg_and_die("invalid gzip magic"); |
| - | } |
| - | #endif |
| - | |
| - | open_transformer(archive_handle->src_fd, unpack_gz_stream, "gunzip"); |
| + | open_transformer_with_sig(archive_handle->src_fd, unpack_gz_stream, "gunzip"); |
| archive_handle->offset = 0; | |
| while (get_header_tar(archive_handle) == EXIT_SUCCESS) | |
| continue; | |
| @@ -14,7 +14,7 @@ char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle) | |
| /* Can't lseek over pipes */ | |
| archive_handle->seek = seek_by_read; | |
| - | open_transformer(archive_handle->src_fd, unpack_lzma_stream, "unlzma"); |
| + | open_transformer_with_sig(archive_handle->src_fd, unpack_lzma_stream, "unlzma"); |
| archive_handle->offset = 0; | |
| while (get_header_tar(archive_handle) == EXIT_SUCCESS) | |
| continue; | |
| @@ -6,24 +6,36 @@ | |
| #include "libbb.h" | |
| #include "bb_archive.h" | |
| - | #define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \ |
| - | || ENABLE_FEATURE_SEAMLESS_BZ2 \ |
| - | || ENABLE_FEATURE_SEAMLESS_GZ \ |
| - | /* || ENABLE_FEATURE_SEAMLESS_Z */ \ |
| - | ) |
| + | void FAST_FUNC init_transformer_aux_data(transformer_aux_data_t *aux) |
| + | { |
| + | memset(aux, 0, sizeof(*aux)); |
| + | } |
| - | #if ZIPPED |
| - | # include "bb_archive.h" |
| + | int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16) |
| + | { |
| + | if (aux && aux->check_signature) { |
| + | uint16_t magic2; |
| + | if (full_read(src_fd, &magic2, 2) != 2 || magic2 != magic16) { |
| + | bb_error_msg("invalid magic"); |
| + | #if 0 /* possible future extension */ |
| + | if (aux->check_signature > 1) |
| + | xfunc_die(); |
| #endif | |
| + | return -1; |
| + | } |
| + | } |
| + | return 0; |
| + | } |
| /* transformer(), more than meets the eye */ | |
| - | /* |
| - | * On MMU machine, the transform_prog is removed by macro magic |
| - | * in include/archive.h. On NOMMU, transformer is removed. |
| - | */ |
| + | #if BB_MMU |
| void FAST_FUNC open_transformer(int fd, | |
| - | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), |
| - | const char *transform_prog) |
| + | int check_signature, |
| + | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
| + | ) |
| + | #else |
| + | void FAST_FUNC open_transformer(int fd, const char *transform_prog) |
| + | #endif |
| { | |
| struct fd_pair fd_pipe; | |
| int pid; | |
| @@ -35,13 +47,18 @@ void FAST_FUNC open_transformer(int fd, | |
| close(fd_pipe.rd); /* we don't want to read from the parent */ | |
| // FIXME: error check? | |
| #if BB_MMU | |
| - | transformer(fd, fd_pipe.wr); |
| - | if (ENABLE_FEATURE_CLEAN_UP) { |
| - | close(fd_pipe.wr); /* send EOF */ |
| - | close(fd); |
| + | { |
| + | transformer_aux_data_t aux; |
| + | init_transformer_aux_data(&aux); |
| + | aux.check_signature = check_signature; |
| + | transformer(&aux, fd, fd_pipe.wr); |
| + | if (ENABLE_FEATURE_CLEAN_UP) { |
| + | close(fd_pipe.wr); /* send EOF */ |
| + | close(fd); |
| + | } |
| + | /* must be _exit! bug was actually seen here */ |
| + | _exit(EXIT_SUCCESS); |
| } | |
| - | /* must be _exit! bug was actually seen here */ |
| - | _exit(EXIT_SUCCESS); |
| #else | |
| { | |
| char *argv[4]; | |
| @@ -64,26 +81,21 @@ void FAST_FUNC open_transformer(int fd, | |
| } | |
| + | #if SEAMLESS_COMPRESSION |
| + | |
| /* Used by e.g. rpm which gives us a fd without filename, | |
| * thus we can't guess the format from filename's extension. | |
| */ | |
| - | #if ZIPPED |
| - | void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) |
| + | int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_detected) |
| { | |
| - | const int fail_if_not_detected = 1; |
| union { | |
| uint8_t b[4]; | |
| uint16_t b16[2]; | |
| uint32_t b32[1]; | |
| } magic; | |
| int offset = -2; | |
| - | # if BB_MMU |
| - | IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); |
| - | enum { xformer_prog = 0 }; |
| - | # else |
| - | enum { xformer = 0 }; |
| - | const char *xformer_prog; |
| - | # endif |
| + | USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) |
| + | USE_FOR_NOMMU(const char *xformer_prog;) |
| /* .gz and .bz2 both have 2-byte signature, and their | |
| * unpack_XXX_stream wants this header skipped. */ | |
| @@ -91,21 +103,15 @@ void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | |
| if (ENABLE_FEATURE_SEAMLESS_GZ | |
| && magic.b16[0] == GZIP_MAGIC | |
| ) { | |
| - | # if BB_MMU |
| - | xformer = unpack_gz_stream; |
| - | # else |
| - | xformer_prog = "gunzip"; |
| - | # endif |
| + | USE_FOR_MMU(xformer = unpack_gz_stream;) |
| + | USE_FOR_NOMMU(xformer_prog = "gunzip";) |
| goto found_magic; | |
| } | |
| if (ENABLE_FEATURE_SEAMLESS_BZ2 | |
| && magic.b16[0] == BZIP2_MAGIC | |
| ) { | |
| - | # if BB_MMU |
| - | xformer = unpack_bz2_stream; |
| - | # else |
| - | xformer_prog = "bunzip2"; |
| - | # endif |
| + | USE_FOR_MMU(xformer = unpack_bz2_stream;) |
| + | USE_FOR_NOMMU(xformer_prog = "bunzip2";) |
| goto found_magic; | |
| } | |
| if (ENABLE_FEATURE_SEAMLESS_XZ | |
| @@ -114,13 +120,8 @@ void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | |
| offset = -6; | |
| xread(fd, magic.b32, sizeof(magic.b32[0])); | |
| if (magic.b32[0] == XZ_MAGIC2) { | |
| - | # if BB_MMU |
| - | xformer = unpack_xz_stream; |
| - | /* unpack_xz_stream wants fd at position 6, no need to seek */ |
| - | //xlseek(fd, offset, SEEK_CUR); |
| - | # else |
| - | xformer_prog = "unxz"; |
| - | # endif |
| + | USE_FOR_MMU(xformer = unpack_xz_stream;) |
| + | USE_FOR_NOMMU(xformer_prog = "unxz";) |
| goto found_magic; | |
| } | |
| } | |
| @@ -132,24 +133,23 @@ void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | |
| IF_FEATURE_SEAMLESS_XZ("/xz") | |
| " magic"); | |
| xlseek(fd, offset, SEEK_CUR); | |
| - | return; |
| + | return 1; |
| found_magic: | |
| - | # if !BB_MMU |
| + | # if BB_MMU |
| + | open_transformer_with_no_sig(fd, xformer); |
| + | # else |
| /* NOMMU version of open_transformer execs | |
| * an external unzipper that wants | |
| * file position at the start of the file */ | |
| xlseek(fd, offset, SEEK_CUR); | |
| + | open_transformer_with_sig(fd, xformer, xformer_prog); |
| # endif | |
| - | open_transformer(fd, xformer, xformer_prog); |
| + | return 0; |
| } | |
| - | #endif /* ZIPPED */ |
| int FAST_FUNC open_zipped(const char *fname) | |
| { | |
| - | #if !ZIPPED |
| - | return open(fname, O_RDONLY); |
| - | #else |
| char *sfx; | |
| int fd; | |
| @@ -162,20 +162,21 @@ int FAST_FUNC open_zipped(const char *fname) | |
| sfx++; | |
| if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0) | |
| /* .lzma has no header/signature, just trust it */ | |
| - | open_transformer(fd, unpack_lzma_stream, "unlzma"); |
| + | open_transformer_with_sig(fd, unpack_lzma_stream, "unlzma"); |
| else | |
| if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0) | |
| || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0) | |
| || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0) | |
| ) { | |
| - | setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/); |
| + | setup_unzip_on_fd(fd, /*fail_if_not_detected:*/ 1); |
| } | |
| } | |
| return fd; | |
| - | #endif |
| } | |
| + | #endif /* SEAMLESS_COMPRESSION */ |
| + | |
| void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) | |
| { | |
| int fd; | |
| @@ -1077,7 +1077,7 @@ static char* FAST_FUNC make_new_name_lzop(char *filename, const char *expected_e | |
| return xasprintf("%s.lzo", filename); | |
| } | |
| - | static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(unpack_info_t *info UNUSED_PARAM) |
| + | static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(transformer_aux_data_t *aux UNUSED_PARAM) |
| { | |
| if (option_mask32 & OPT_DECOMPRESS) | |
| return do_lzo_decompress(); | |
| @@ -236,7 +236,7 @@ static void extract_cpio(int fd, const char *source_rpm) | |
| archive_handle->src_fd = fd; | |
| /*archive_handle->offset = 0; - init_handle() did it */ | |
| - | setup_unzip_on_fd(archive_handle->src_fd /*, fail_if_not_detected: 1*/); |
| + | setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_detected:*/ 1); |
| while (get_header_cpio(archive_handle) == EXIT_SUCCESS) | |
| continue; | |
| } | |
| @@ -42,6 +42,26 @@ static unsigned skip_header(void) | |
| return sizeof(header) + len; | |
| } | |
| + | #if SEAMLESS_COMPRESSION |
| + | static void handle_SIGCHLD(int signo UNUSED_PARAM) |
| + | { |
| + | int status; |
| + | |
| + | /* Wait for any child without blocking */ |
| + | for (;;) { |
| + | if (wait_any_nohang(&status) < 0) |
| + | /* wait failed?! I'm confused... */ |
| + | return; |
| + | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) |
| + | /* this child exited with 0 */ |
| + | continue; |
| + | /* Cannot happen? |
| + | if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */ |
| + | bb_got_signal = 1; |
| + | } |
| + | } |
| + | #endif |
| + | |
| /* No getopt required */ | |
| int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |
| @@ -66,54 +86,23 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |
| /* Skip the main header */ | |
| skip_header(); | |
| - | #if 0 |
| + | #if SEAMLESS_COMPRESSION |
| + | /* We need to know whether child (gzip/bzip/etc) exits abnormally */ |
| + | signal(SIGCHLD, handle_SIGCHLD); |
| + | #endif |
| + | |
| /* This works, but doesn't report uncompress errors (they happen in child) */ | |
| - | setup_unzip_on_fd(rpm_fd /*fail_if_not_detected: 1*/); |
| + | setup_unzip_on_fd(rpm_fd, /*fail_if_not_detected:*/ 1); |
| if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) | |
| bb_error_msg_and_die("error unpacking"); | |
| - | #else |
| - | /* BLOAT */ |
| - | { |
| - | union { |
| - | uint8_t b[4]; |
| - | uint16_t b16[2]; |
| - | uint32_t b32[1]; |
| - | } magic; |
| - | IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd); |
| - | |
| - | xread(rpm_fd, magic.b16, sizeof(magic.b16[0])); |
| - | if (magic.b16[0] == GZIP_MAGIC) { |
| - | unpack = unpack_gz_stream; |
| - | } else |
| - | if (ENABLE_FEATURE_SEAMLESS_BZ2 |
| - | && magic.b16[0] == BZIP2_MAGIC |
| - | ) { |
| - | unpack = unpack_bz2_stream; |
| - | } else |
| - | if (ENABLE_FEATURE_SEAMLESS_XZ |
| - | && magic.b16[0] == XZ_MAGIC1 |
| - | ) { |
| - | xread(rpm_fd, magic.b32, sizeof(magic.b32[0])); |
| - | if (magic.b32[0] != XZ_MAGIC2) |
| - | goto no_magic; |
| - | /* unpack_xz_stream wants fd at position 6, no need to seek */ |
| - | //xlseek(rpm_fd, -6, SEEK_CUR); |
| - | unpack = unpack_xz_stream; |
| - | } else { |
| - | no_magic: |
| - | bb_error_msg_and_die("no gzip" |
| - | IF_FEATURE_SEAMLESS_BZ2("/bzip2") |
| - | IF_FEATURE_SEAMLESS_XZ("/xz") |
| - | " magic"); |
| - | } |
| - | if (unpack(rpm_fd, STDOUT_FILENO) < 0) |
| - | bb_error_msg_and_die("error unpacking"); |
| - | } |
| - | #endif |
| if (ENABLE_FEATURE_CLEAN_UP) { | |
| close(rpm_fd); | |
| } | |
| - | return 0; |
| + | #if SEAMLESS_COMPRESSION |
| + | return bb_got_signal; |
| + | #else |
| + | return EXIT_SUCCESS; |
| + | #endif |
| } | |
| @@ -690,31 +690,6 @@ static llist_t *append_file_list_to_list(llist_t *list) | |
| # define append_file_list_to_list(x) 0 | |
| #endif | |
| - | #if ENABLE_FEATURE_SEAMLESS_Z |
| - | static char FAST_FUNC get_header_tar_Z(archive_handle_t *archive_handle) |
| - | { |
| - | /* Can't lseek over pipes */ |
| - | archive_handle->seek = seek_by_read; |
| - | |
| - | /* do the decompression, and cleanup */ |
| - | if (xread_char(archive_handle->src_fd) != 0x1f |
| - | || xread_char(archive_handle->src_fd) != 0x9d |
| - | ) { |
| - | bb_error_msg_and_die("invalid magic"); |
| - | } |
| - | |
| - | open_transformer(archive_handle->src_fd, unpack_Z_stream, "uncompress"); |
| - | archive_handle->offset = 0; |
| - | while (get_header_tar(archive_handle) == EXIT_SUCCESS) |
| - | continue; |
| - | |
| - | /* Can only do one file at a time */ |
| - | return EXIT_FAILURE; |
| - | } |
| - | #else |
| - | # define get_header_tar_Z NULL |
| - | #endif |
| - | |
| #ifdef CHECK_FOR_CHILD_EXITCODE | |
| /* Looks like it isn't needed - tar detects malformed (truncated) | |
| * archive if e.g. bunzip2 fails */ | |
| @@ -843,6 +818,8 @@ enum { | |
| OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner | |
| OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions | |
| OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite | |
| + | |
| + | OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_COMPRESS), |
| }; | |
| #if ENABLE_FEATURE_TAR_LONG_OPTIONS | |
| static const char tar_longopts[] ALIGN1 = | |
| @@ -901,7 +878,6 @@ static const char tar_longopts[] ALIGN1 = | |
| int tar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int tar_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| - | char FAST_FUNC (*get_header_ptr)(archive_handle_t *) = get_header_tar; |
| archive_handle_t *tar_handle; | |
| char *base_dir = NULL; | |
| const char *tar_filename = "-"; | |
| @@ -1017,18 +993,6 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |
| tar_handle->ah_flags |= ARCHIVE_O_TRUNC; | |
| } | |
| - | if (opt & OPT_GZIP) |
| - | get_header_ptr = get_header_tar_gz; |
| - | |
| - | if (opt & OPT_BZIP2) |
| - | get_header_ptr = get_header_tar_bz2; |
| - | |
| - | if (opt & OPT_LZMA) |
| - | get_header_ptr = get_header_tar_lzma; |
| - | |
| - | if (opt & OPT_COMPRESS) |
| - | get_header_ptr = get_header_tar_Z; |
| - | |
| if (opt & OPT_NOPRESERVE_TIME) | |
| tar_handle->ah_flags &= ~ARCHIVE_RESTORE_DATE; | |
| @@ -1081,7 +1045,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |
| } else { | |
| if (ENABLE_FEATURE_TAR_AUTODETECT | |
| && flags == O_RDONLY | |
| - | && get_header_ptr == get_header_tar |
| + | && !(opt & OPT_ANY_COMPRESS) |
| ) { | |
| tar_handle->src_fd = open_zipped(tar_filename); | |
| if (tar_handle->src_fd < 0) | |
| @@ -1115,7 +1079,30 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |
| tar_handle->reject, zipMode); | |
| } | |
| - | while (get_header_ptr(tar_handle) == EXIT_SUCCESS) |
| + | if (opt & OPT_ANY_COMPRESS) { |
| + | USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) |
| + | USE_FOR_NOMMU(const char *xformer_prog;) |
| + | |
| + | if (opt & OPT_COMPRESS) |
| + | USE_FOR_MMU(xformer = unpack_Z_stream;) |
| + | USE_FOR_NOMMU(xformer_prog = "uncompress";) |
| + | if (opt & OPT_GZIP) |
| + | USE_FOR_MMU(xformer = unpack_gz_stream;) |
| + | USE_FOR_NOMMU(xformer_prog = "gunzip";) |
| + | if (opt & OPT_BZIP2) |
| + | USE_FOR_MMU(xformer = unpack_bz2_stream;) |
| + | USE_FOR_NOMMU(xformer_prog = "bunzip2";) |
| + | if (opt & OPT_LZMA) |
| + | USE_FOR_MMU(xformer = unpack_lzma_stream;) |
| + | USE_FOR_NOMMU(xformer_prog = "unlzma";) |
| + | |
| + | open_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog); |
| + | /* Can't lseek over pipes */ |
| + | tar_handle->seek = seek_by_read; |
| + | /*tar_handle->offset = 0; - already is */ |
| + | } |
| + | |
| + | while (get_header_tar(tar_handle) == EXIT_SUCCESS) |
| continue; | |
| /* Check that every file that should have been extracted was */ | |
| @@ -1131,5 +1118,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |
| if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */) | |
| close(tar_handle->src_fd); | |
| + | #ifdef CHECK_FOR_CHILD_EXITCODE |
| + | return bb_got_signal; |
| + | #else |
| return EXIT_SUCCESS; | |
| + | #endif |
| } | |
| @@ -249,15 +249,17 @@ static void unzip_extract(zip_header_t *zip_header, int dst_fd) | |
| bb_copyfd_exact_size(zip_fd, dst_fd, size); | |
| } else { | |
| /* Method 8 - inflate */ | |
| - | inflate_unzip_result res; |
| - | if (inflate_unzip(&res, zip_header->formatted.cmpsize, zip_fd, dst_fd) < 0) |
| + | transformer_aux_data_t aux; |
| + | init_transformer_aux_data(&aux); |
| + | aux.bytes_in = zip_header->formatted.cmpsize; |
| + | if (inflate_unzip(&aux, zip_fd, dst_fd) < 0) |
| bb_error_msg_and_die("inflate error"); | |
| /* Validate decompression - crc */ | |
| - | if (zip_header->formatted.crc32 != (res.crc ^ 0xffffffffL)) { |
| + | if (zip_header->formatted.crc32 != (aux.crc32 ^ 0xffffffffL)) { |
| bb_error_msg_and_die("crc error"); | |
| } | |
| /* Validate decompression - size */ | |
| - | if (zip_header->formatted.ucmpsize != res.bytes_out) { |
| + | if (zip_header->formatted.ucmpsize != aux.bytes_out) { |
| /* Don't die. Who knows, maybe len calculation | |
| * was botched somewhere. After all, crc matched! */ | |
| bb_error_msg("bad length"); | |
| @@ -59,7 +59,7 @@ wait | |
| Example 1 | |
| One example how to reduce global data usage is in | |
| - | archival/libarchive/decompress_gunzip.c: |
| + | archival/libarchive/decompress_unzip.c: |
| /* This is somewhat complex-looking arrangement, but it allows | |
| * to place decompressor state either in bss or in | |
| @@ -156,12 +156,6 @@ struct BUG_tar_header { | |
| - | /* Info struct unpackers can fill out to inform users of thing like |
| - | * timestamps of unpacked files */ |
| - | typedef struct unpack_info_t { |
| - | time_t mtime; |
| - | } unpack_info_t; |
| - | |
| archive_handle_t *init_handle(void) FAST_FUNC; | |
| char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC; | |
| @@ -204,40 +198,46 @@ int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_ | |
| int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; | |
| void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; | |
| - | typedef struct inflate_unzip_result { |
| - | off_t bytes_out; |
| - | uint32_t crc; |
| - | } inflate_unzip_result; |
| - | |
| - | IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC; |
| - | /* xz unpacker takes .xz stream from offset 6 */ |
| - | IF_DESKTOP(long long) int unpack_xz_stream(int src_fd, int dst_fd) FAST_FUNC; |
| - | /* lzma unpacker takes .lzma stream from offset 0 */ |
| - | IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; |
| - | /* the rest wants 2 first bytes already skipped by the caller */ |
| - | IF_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC; |
| - | IF_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC; |
| - | IF_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC; |
| - | IF_DESKTOP(long long) int unpack_Z_stream(int src_fd, int dst_fd) FAST_FUNC; |
| - | /* wrapper which checks first two bytes to be "BZ" */ |
| - | IF_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC; |
| + | /* Meaning and direction (input/output) of the fields are transformer-specific */ |
| + | typedef struct transformer_aux_data_t { |
| + | smallint check_signature; /* most often referenced member */ |
| + | off_t bytes_out; |
| + | off_t bytes_in; /* used in unzip code only: needs to know packed size */ |
| + | uint32_t crc32; |
| + | time_t mtime; /* gunzip code may set this on exit */ |
| + | } transformer_aux_data_t; |
| + | |
| + | void init_transformer_aux_data(transformer_aux_data_t *aux) FAST_FUNC; |
| + | int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16) FAST_FUNC; |
| + | |
| + | IF_DESKTOP(long long) int inflate_unzip(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
| + | IF_DESKTOP(long long) int unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
| + | IF_DESKTOP(long long) int unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
| + | IF_DESKTOP(long long) int unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
| + | IF_DESKTOP(long long) int unpack_lzma_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
| + | IF_DESKTOP(long long) int unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) FAST_FUNC; |
| char* append_ext(char *filename, const char *expected_ext) FAST_FUNC; | |
| int bbunpack(char **argv, | |
| - | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info), |
| + | IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux), |
| char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), | |
| const char *expected_ext | |
| ) FAST_FUNC; | |
| #if BB_MMU | |
| void open_transformer(int fd, | |
| - | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC; |
| - | #define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transformer) |
| + | int check_signature, |
| + | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd) |
| + | ) FAST_FUNC; |
| + | #define open_transformer_with_sig(fd, transformer, transform_prog) open_transformer((fd), 1, (transformer)) |
| + | #define open_transformer_with_no_sig(fd, transformer) open_transformer((fd), 0, (transformer)) |
| #else | |
| - | void open_transformer(int src_fd, const char *transform_prog) FAST_FUNC; |
| - | #define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transform_prog) |
| + | void open_transformer(int fd, const char *transform_prog) FAST_FUNC; |
| + | #define open_transformer_with_sig(fd, transformer, transform_prog) open_transformer((fd), (transform_prog)) |
| + | /* open_transformer_with_no_sig() does not exist on NOMMU */ |
| #endif | |
| + | |
| POP_SAVED_FUNCTION_VISIBILITY | |
| #endif | |
| @@ -721,17 +721,15 @@ extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAS | |
| || ENABLE_FEATURE_SEAMLESS_GZ \ | |
| || ENABLE_FEATURE_SEAMLESS_Z) | |
| + | #if SEAMLESS_COMPRESSION |
| /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ | |
| - | #if ENABLE_FEATURE_SEAMLESS_LZMA \ |
| - | || ENABLE_FEATURE_SEAMLESS_BZ2 \ |
| - | || ENABLE_FEATURE_SEAMLESS_GZ \ |
| - | /* || ENABLE_FEATURE_SEAMLESS_Z */ |
| - | extern void setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) FAST_FUNC; |
| - | #else |
| - | # define setup_unzip_on_fd(...) ((void)0) |
| - | #endif |
| + | extern int setup_unzip_on_fd(int fd, int fail_if_not_detected) FAST_FUNC; |
| /* Autodetects .gz etc */ | |
| extern int open_zipped(const char *fname) FAST_FUNC; | |
| + | #else |
| + | # define setup_unzip_on_fd(...) (0) |
| + | # define open_zipped(fname) open((fname), O_RDONLY); |
| + | #endif |
| extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; | |
| extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC; | |