*: refactor handling of archived files. "tar f file.tar.lzma" now works too.

function                                             old     new   delta
unpack_Z_stream                                        -    1229   +1229
open_zipped                                            -     176    +176
unpack_bz2_stream_prime                                -      60     +60
tar_main                                             642     677     +35
find_main                                            406     418     +12
sv_main                                             1222    1233     +11
decode_format_string                                 829     837      +8
cmp_main                                             641     649      +8
popstring                                            134     140      +6
filter_accept_list_reassign                          120     125      +5
parse_and_put_prompt                                 800     804      +4
passwd_main                                         1053    1049      -4
make_new_name_gunzip                                 119     114      -5
rpm_main                                            1688    1670     -18
prepare                                              302     283     -19
xmalloc_open_zipped_read_close                       135      61     -74
uncompress                                          1229       -   -1229
------------------------------------------------------------------------------
(add/remove: 3/1 grow/shrink: 8/5 up/down: 1554/-1349)        Total: 205 bytes
This commit is contained in:
Denis Vlasenko
2008-08-05 13:10:34 +00:00
parent 9b44613202
commit e9ad84dfd4
21 changed files with 325 additions and 320 deletions

View File

@@ -5,6 +5,30 @@
menu "Archival Utilities"
config FEATURE_SEAMLESS_LZMA
bool "Make tar, rpm, man, modprobe etc understand .lzma data"
default n
help
Make tar, rpm, man, modprobe etc understand .lzma data.
config FEATURE_SEAMLESS_BZ2
bool "Make tar, rpm, man, modprobe etc understand .bz2 data"
default n
help
Make tar, rpm, man, modprobe etc understand .bz2 data.
config FEATURE_SEAMLESS_GZ
bool "Make tar, rpm, man, modprobe etc understand .gz data"
default n
help
Make tar, rpm, man, modprobe etc understand .gz data.
config FEATURE_SEAMLESS_Z
bool "Make tar and gunzip understand .Z data"
default n
help
Make tar and gunzip understand .Z data.
config AR
bool "ar"
default n
@@ -126,15 +150,6 @@ config GUNZIP
You can use the `-t' option to test the integrity of
an archive, without decompressing it.
config FEATURE_GUNZIP_UNCOMPRESS
bool "Uncompress support"
default n
depends on GUNZIP
help
Enable if you want gunzip to have the ability to decompress
archives created by the program compress (not much
used anymore).
config GZIP
bool "gzip"
default n
@@ -154,13 +169,6 @@ config RPM
help
Mini RPM applet - queries and extracts RPM packages.
config FEATURE_RPM_BZ2
bool "Enable handling of rpms with bzip2-compressed data inside"
default n
depends on RPM
help
Enable handling of rpms with bzip2-compressed data inside.
config TAR
bool "tar"
default n
@@ -179,42 +187,10 @@ config FEATURE_TAR_CREATE
If you enable this option you'll be able to create
tar archives using the `-c' option.
config FEATURE_TAR_GZIP
bool "Enable -z option"
default y
depends on TAR
help
If you enable this option tar will be able to call gzip,
when creating or extracting tar gziped archives.
config FEATURE_TAR_BZIP2
bool "Enable -j option to handle .tar.bz2 files"
default n
depends on TAR
help
If you enable this option you'll be able to extract
archives compressed with bzip2.
config FEATURE_TAR_LZMA
bool "Enable -a option to handle .tar.lzma files"
default n
depends on TAR
help
If you enable this option you'll be able to extract
archives compressed with lzma.
config FEATURE_TAR_COMPRESS
bool "Enable -Z option"
default n
depends on TAR
help
If you enable this option tar will be able to call uncompress,
when extracting .tar.Z archives.
config FEATURE_TAR_AUTODETECT
bool "Autodetect gz/bz2 compresses tarballs"
bool "Autodetect gz/bz2 compressed tarballs"
default n
depends on FEATURE_TAR_GZIP || FEATURE_TAR_BZIP2
depends on FEATURE_SEAMLESS_Z || FEATURE_SEAMLESS_GZ || FEATURE_SEAMLESS_BZ2 || FEATURE_SEAMLESS_LZMA
help
With this option tar can automatically detect gzip/bzip2 compressed
tarballs. Currently it works only on files (not pipes etc).
@@ -312,42 +288,4 @@ config UNZIP
current directory. Use the `-d' option to extract to a
directory of your choice.
comment "Common options for cpio and tar"
depends on CPIO || TAR
comment "Common options for dpkg and dpkg_deb"
depends on DPKG || DPKG_DEB
config FEATURE_DEB_TAR_GZ
bool "gzip debian packages (normal)"
default y if DPKG || DPKG_DEB
depends on DPKG || DPKG_DEB
help
This is the default compression method inside the debian ar file.
If you want compatibility with standard .deb's you should say yes
here.
config FEATURE_DEB_TAR_BZ2
bool "bzip2 debian packages"
default n
depends on DPKG || DPKG_DEB
help
This allows dpkg and dpkg-deb to extract deb's that are compressed
internally with bzip2 instead of gzip.
You only want this if you are creating your own custom debian
packages that use an internal control.tar.bz2 or data.tar.bz2.
config FEATURE_DEB_TAR_LZMA
bool "lzma debian packages"
default n
depends on DPKG || DPKG_DEB
help
This allows dpkg and dpkg-deb to extract deb's that are compressed
internally with lzma instead of gzip.
You only want this if you are creating your own custom debian
packages that use an internal control.tar.lzma or data.tar.lzma.
endmenu

View File

@@ -161,7 +161,7 @@ char* make_new_name_bunzip2(char *filename)
static
USE_DESKTOP(long long) int unpack_bunzip2(void)
{
return unpack_bz2_stream(STDIN_FILENO, STDOUT_FILENO);
return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO);
}
int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -218,8 +218,8 @@ char* make_new_name_gunzip(char *filename)
extension++;
if (strcmp(extension, "tgz" + 1) == 0
#if ENABLE_FEATURE_GUNZIP_UNCOMPRESS
|| strcmp(extension, "Z") == 0
#if ENABLE_FEATURE_SEAMLESS_Z
|| (extension[0] == 'Z' && extension[1] == '\0')
#endif
) {
extension[-1] = '\0';
@@ -244,8 +244,8 @@ USE_DESKTOP(long long) int unpack_gunzip(void)
unsigned char magic2;
magic2 = xread_char(STDIN_FILENO);
if (ENABLE_FEATURE_GUNZIP_UNCOMPRESS && magic2 == 0x9d) {
status = uncompress(STDIN_FILENO, STDOUT_FILENO);
if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == 0x9d) {
status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO);
} else if (magic2 == 0x8b) {
status = unpack_gz_stream(STDIN_FILENO, STDOUT_FILENO);
} else {
@@ -351,7 +351,7 @@ USE_DESKTOP(long long) int unpack_uncompress(void)
if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) {
bb_error_msg("invalid magic");
} else {
status = uncompress(STDIN_FILENO, STDOUT_FILENO);
status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO);
}
return status;
}

View File

@@ -1438,10 +1438,10 @@ static void init_archive_deb_control(archive_handle_t *ar_handle)
tar_handle->src_fd = ar_handle->src_fd;
/* We don't care about data.tar.* or debian-binary, just control.tar.* */
#if ENABLE_FEATURE_DEB_TAR_GZ
#if ENABLE_FEATURE_SEAMLESS_GZ
llist_add_to(&(ar_handle->accept), (char*)"control.tar.gz");
#endif
#if ENABLE_FEATURE_DEB_TAR_BZ2
#if ENABLE_FEATURE_SEAMLESS_BZ2
llist_add_to(&(ar_handle->accept), (char*)"control.tar.bz2");
#endif
@@ -1458,10 +1458,10 @@ static void init_archive_deb_data(archive_handle_t *ar_handle)
tar_handle->src_fd = ar_handle->src_fd;
/* We don't care about control.tar.* or debian-binary, just data.tar.* */
#if ENABLE_FEATURE_DEB_TAR_GZ
#if ENABLE_FEATURE_SEAMLESS_GZ
llist_add_to(&(ar_handle->accept), (char*)"data.tar.gz");
#endif
#if ENABLE_FEATURE_DEB_TAR_BZ2
#if ENABLE_FEATURE_SEAMLESS_BZ2
llist_add_to(&(ar_handle->accept), (char*)"data.tar.bz2");
#endif

View File

@@ -31,12 +31,12 @@ int dpkg_deb_main(int argc, char **argv)
ar_archive->sub_archive = tar_archive;
ar_archive->filter = filter_accept_list_reassign;
#if ENABLE_FEATURE_DEB_TAR_GZ
#if ENABLE_FEATURE_SEAMLESS_GZ
llist_add_to(&(ar_archive->accept), (char*)"data.tar.gz");
llist_add_to(&control_tar_llist, (char*)"control.tar.gz");
#endif
#if ENABLE_FEATURE_DEB_TAR_BZ2
#if ENABLE_FEATURE_SEAMLESS_BZ2
llist_add_to(&(ar_archive->accept), (char*)"data.tar.bz2");
llist_add_to(&control_tar_llist, (char*)"control.tar.bz2");
#endif

View File

@@ -32,36 +32,20 @@ DPKG_FILES:= \
get_header_tar.o \
filter_accept_list_reassign.o
lib-$(CONFIG_RPM) += open_transformer.o
lib-$(CONFIG_FEATURE_TAR_BZIP2) += open_transformer.o
lib-$(CONFIG_FEATURE_TAR_LZMA) += open_transformer.o
lib-$(CONFIG_FEATURE_TAR_GZIP) += open_transformer.o
lib-$(CONFIG_FEATURE_TAR_COMPRESS) += open_transformer.o
lib-$(CONFIG_FEATURE_DEB_TAR_GZ) += open_transformer.o
lib-$(CONFIG_FEATURE_DEB_TAR_BZ2) += open_transformer.o
lib-$(CONFIG_FEATURE_DEB_TAR_LZMA) += open_transformer.o
lib-$(CONFIG_FEATURE_MODPROBE_SMALL_ZIPPED) += open_transformer.o decompress_unzip.o decompress_bunzip2.o
lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o
lib-$(CONFIG_BUNZIP2) += decompress_bunzip2.o
lib-$(CONFIG_UNLZMA) += decompress_unlzma.o
lib-$(CONFIG_CPIO) += get_header_cpio.o
lib-$(CONFIG_DPKG) += $(DPKG_FILES)
lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES)
lib-$(CONFIG_FEATURE_DEB_TAR_GZ) += decompress_unzip.o get_header_tar_gz.o
lib-$(CONFIG_FEATURE_DEB_TAR_BZ2) += decompress_bunzip2.o get_header_tar_bz2.o
lib-$(CONFIG_FEATURE_DEB_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o
lib-$(CONFIG_GUNZIP) += decompress_unzip.o
lib-$(CONFIG_FEATURE_GUNZIP_UNCOMPRESS) += decompress_uncompress.o
lib-$(CONFIG_RPM2CPIO) += decompress_unzip.o get_header_cpio.o
lib-$(CONFIG_RPM) += decompress_unzip.o get_header_cpio.o
lib-$(CONFIG_FEATURE_RPM_BZ2) += decompress_bunzip2.o
lib-$(CONFIG_RPM) += open_transformer.o decompress_unzip.o get_header_cpio.o
lib-$(CONFIG_TAR) += get_header_tar.o
lib-$(CONFIG_FEATURE_TAR_BZIP2) += decompress_bunzip2.o get_header_tar_bz2.o
lib-$(CONFIG_FEATURE_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o
lib-$(CONFIG_FEATURE_TAR_GZIP) += decompress_unzip.o get_header_tar_gz.o
lib-$(CONFIG_FEATURE_TAR_COMPRESS) += decompress_uncompress.o
lib-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o
lib-$(CONFIG_UNZIP) += decompress_unzip.o
lib-$(CONFIG_FEATURE_SEAMLESS_Z) += open_transformer.o decompress_uncompress.o
lib-$(CONFIG_FEATURE_SEAMLESS_GZ) += open_transformer.o decompress_unzip.o get_header_tar_gz.o
lib-$(CONFIG_FEATURE_SEAMLESS_BZ2) += open_transformer.o decompress_bunzip2.o get_header_tar_bz2.o
lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma.o get_header_tar_lzma.o
lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += decompress_bunzip2.o

View File

@@ -590,7 +590,8 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *in
bunzip_data *bd;
unsigned i;
enum {
BZh0 = ('B' << 24) + ('Z' << 16) + ('h' << 8) + '0'
BZh0 = ('B' << 24) + ('Z' << 16) + ('h' << 8) + '0',
h0 = ('h' << 8) + '0',
};
/* Figure out how much data to allocate */
@@ -617,12 +618,18 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *in
if (i) return i;
/* Ensure that file starts with "BZh['1'-'9']." */
i = get_bits(bd, 32);
if ((unsigned)(i - BZh0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA;
/* Update: now caller verifies 1st two bytes, makes .gz/.bz2
* integration easier */
/* was: */
/* i = get_bits(bd, 32); */
/* if ((unsigned)(i - BZh0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA; */
i = get_bits(bd, 16);
if ((unsigned)(i - h0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA;
/* Fourth byte (ascii '1'-'9') indicates block size in units of 100k of
uncompressed data. Allocate intermediate buffer for block. */
bd->dbufSize = 100000 * (i - BZh0);
/* bd->dbufSize = 100000 * (i - BZh0); */
bd->dbufSize = 100000 * (i - h0);
/* Cannot use xmalloc - may leak bd in NOFORK case! */
bd->dbuf = malloc_or_warn(bd->dbufSize * sizeof(int));
@@ -682,6 +689,17 @@ unpack_bz2_stream(int src_fd, int dst_fd)
return i ? i : USE_DESKTOP(total_written) + 0;
}
USE_DESKTOP(long long) int FAST_FUNC
unpack_bz2_stream_prime(int src_fd, int dst_fd)
{
unsigned char magic[2];
xread(src_fd, magic, 2);
if (magic[0] != 'B' || magic[1] != 'Z') {
bb_error_msg_and_die("invalid magic");
}
return unpack_bz2_stream(src_fd, dst_fd);
}
#ifdef TESTING
static char *const bunzip_errors[] = {
@@ -693,9 +711,10 @@ static char *const bunzip_errors[] = {
/* Dumb little test thing, decompress stdin to stdout */
int main(int argc, char **argv)
{
int i = unpack_bz2_stream(0, 1);
int i;
char c;
int i = unpack_bz2_stream_prime(0, 1);
if (i < 0)
fprintf(stderr, "%s\n", bunzip_errors[-i]);
else if (read(STDIN_FILENO, &c, 1))

View File

@@ -1,6 +1,4 @@
/* vi: set sw=4 ts=4: */
#include "libbb.h"
/* uncompress for busybox -- (c) 2002 Robert Griebl
*
* based on the original compress42.c source
@@ -26,6 +24,10 @@
*
*/
#include "libbb.h"
#include "unarchive.h"
/* Default input buffer size */
#define IBUFSIZ 2048
@@ -71,7 +73,7 @@
*/
USE_DESKTOP(long long) int FAST_FUNC
uncompress(int fd_in, int fd_out)
unpack_Z_stream(int fd_in, int fd_out)
{
USE_DESKTOP(long long total_written = 0;)
USE_DESKTOP(long long) int retval = -1;

View File

@@ -23,22 +23,25 @@ char FAST_FUNC filter_accept_list_reassign(archive_handle_t *archive_handle)
/* Find extension */
name_ptr = strrchr(archive_handle->file_header->name, '.');
if (!name_ptr)
return EXIT_FAILURE;
name_ptr++;
/* Modify the subarchive handler based on the extension */
if (ENABLE_FEATURE_DEB_TAR_GZ
&& strcmp(name_ptr, ".gz") == 0
if (ENABLE_FEATURE_SEAMLESS_GZ
&& strcmp(name_ptr, "gz") == 0
) {
archive_handle->action_data_subarchive = get_header_tar_gz;
return EXIT_SUCCESS;
}
if (ENABLE_FEATURE_DEB_TAR_BZ2
&& strcmp(name_ptr, ".bz2") == 0
if (ENABLE_FEATURE_SEAMLESS_BZ2
&& strcmp(name_ptr, "bz2") == 0
) {
archive_handle->action_data_subarchive = get_header_tar_bz2;
return EXIT_SUCCESS;
}
if (ENABLE_FEATURE_DEB_TAR_LZMA
&& strcmp(name_ptr, ".lzma") == 0
if (ENABLE_FEATURE_SEAMLESS_LZMA
&& strcmp(name_ptr, "lzma") == 0
) {
archive_handle->action_data_subarchive = get_header_tar_lzma;
return EXIT_SUCCESS;

View File

@@ -148,12 +148,12 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
* 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_TAR_GZIP
#if ENABLE_FEATURE_SEAMLESS_GZ
if (tar.name[0] == 0x1f && tar.name[1] == (char)0x8b) { /* gzip */
get_header_ptr = get_header_tar_gz;
} else
#endif
#if ENABLE_FEATURE_TAR_BZIP2
#if ENABLE_FEATURE_SEAMLESS_BZ2
if (tar.name[0] == 'B' && tar.name[1] == 'Z'
&& tar.name[2] == 'h' && isdigit(tar.name[3])
) { /* bzip2 */

View File

@@ -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, "bunzip2");
open_transformer(archive_handle->src_fd, unpack_bz2_stream_prime, "bunzip2");
archive_handle->offset = 0;
while (get_header_tar(archive_handle) == EXIT_SUCCESS)
continue;

View File

@@ -206,27 +206,27 @@ static void extract_cpio_gz(int fd)
archive_handle->src_fd = fd;
/*archive_handle->offset = 0; - init_handle() did it */
// TODO: open_zipped does the same
xread(archive_handle->src_fd, &magic, 2);
#if BB_MMU
xformer = unpack_gz_stream;
#else
xformer_prog = "gunzip";
#endif
if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) {
if (ENABLE_FEATURE_RPM_BZ2
&& (magic[0] == 0x42) && (magic[1] == 0x5a)) {
#if BB_MMU
xformer = unpack_bz2_stream;
#else
xformer_prog = "bunzip2";
#endif
/* We can do better, need modifying unpack_bz2_stream to not require
* first 2 bytes. Not very hard to do... I mean, TODO :) */
xlseek(archive_handle->src_fd, -2, SEEK_CUR);
} else
if (magic[0] != 0x1f || magic[1] != 0x8b) {
if (!ENABLE_FEATURE_SEAMLESS_BZ2
|| magic[0] != 'B' || magic[1] != 'Z'
) {
bb_error_msg_and_die("no gzip"
USE_FEATURE_RPM_BZ2("/bzip")
USE_FEATURE_SEAMLESS_BZ2("/bzip2")
" magic");
}
#if BB_MMU
xformer = unpack_bz2_stream;
#else
xformer_prog = "bunzip2";
#endif
} else {
#if !BB_MMU
/* NOMMU version of open_transformer execs an external unzipper that should

View File

@@ -36,7 +36,7 @@
#define block_buf bb_common_bufsiz1
#if !ENABLE_FEATURE_TAR_GZIP && !ENABLE_FEATURE_TAR_BZIP2
#if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2
/* Do not pass gzip flag to writeTarFile() */
#define writeTarFile(tar_fd, verboseFlag, dereferenceFlag, include, exclude, gzip) \
writeTarFile(tar_fd, verboseFlag, dereferenceFlag, include, exclude)
@@ -503,19 +503,19 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb
return TRUE;
}
#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
#if !(ENABLE_FEATURE_TAR_GZIP && ENABLE_FEATURE_TAR_BZIP2)
#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
#if !(ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2)
#define vfork_compressor(tar_fd, gzip) vfork_compressor(tar_fd)
#endif
/* Don't inline: vfork scares gcc and pessimizes code */
static void NOINLINE vfork_compressor(int tar_fd, int gzip)
{
pid_t gzipPid;
#if ENABLE_FEATURE_TAR_GZIP && ENABLE_FEATURE_TAR_BZIP2
#if ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2
const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2";
#elif ENABLE_FEATURE_TAR_GZIP
#elif ENABLE_FEATURE_SEAMLESS_GZ
const char *zip_exec = "gzip";
#else /* only ENABLE_FEATURE_TAR_BZIP2 */
#else /* only ENABLE_FEATURE_SEAMLESS_BZ2 */
const char *zip_exec = "bzip2";
#endif
// On Linux, vfork never unpauses parent early, although standard
@@ -579,7 +579,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip)
bb_perror_msg_and_die("cannot exec %s", zip_exec);
}
}
#endif /* ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2 */
#endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */
/* gcc 4.2.1 inlines it, making code bigger */
@@ -601,7 +601,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)
bb_perror_msg_and_die("cannot stat tar file");
#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
if (gzip)
vfork_compressor(tbInfo.tarFd, gzip);
#endif
@@ -637,7 +637,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
if (errorFlag)
bb_error_msg("error exit delayed from previous errors");
#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
if (gzip) {
int status;
if (safe_waitpid(-1, &status, 0) == -1)
@@ -679,7 +679,7 @@ static llist_t *append_file_list_to_list(llist_t *list)
#define append_file_list_to_list(x) 0
#endif
#if ENABLE_FEATURE_TAR_COMPRESS
#if ENABLE_FEATURE_SEAMLESS_Z
static char FAST_FUNC get_header_tar_Z(archive_handle_t *archive_handle)
{
/* Can't lseek over pipes */
@@ -692,7 +692,7 @@ static char FAST_FUNC get_header_tar_Z(archive_handle_t *archive_handle)
bb_error_msg_and_die("invalid magic");
}
open_transformer(archive_handle->src_fd, uncompress, "uncompress");
open_transformer(archive_handle->src_fd, unpack_Z_stream, "uncompress");
archive_handle->offset = 0;
while (get_header_tar(archive_handle) == EXIT_SUCCESS)
continue;
@@ -729,14 +729,14 @@ static void handle_SIGCHLD(int status)
enum {
OPTBIT_KEEP_OLD = 7,
USE_FEATURE_TAR_CREATE( OPTBIT_CREATE ,)
USE_FEATURE_TAR_CREATE( OPTBIT_DEREFERENCE ,)
USE_FEATURE_TAR_BZIP2( OPTBIT_BZIP2 ,)
USE_FEATURE_TAR_LZMA( OPTBIT_LZMA ,)
USE_FEATURE_TAR_FROM( OPTBIT_INCLUDE_FROM,)
USE_FEATURE_TAR_FROM( OPTBIT_EXCLUDE_FROM,)
USE_FEATURE_TAR_GZIP( OPTBIT_GZIP ,)
USE_FEATURE_TAR_COMPRESS(OPTBIT_COMPRESS ,)
USE_FEATURE_TAR_CREATE( OPTBIT_CREATE ,)
USE_FEATURE_TAR_CREATE( OPTBIT_DEREFERENCE ,)
USE_FEATURE_SEAMLESS_BZ2( OPTBIT_BZIP2 ,)
USE_FEATURE_SEAMLESS_LZMA(OPTBIT_LZMA ,)
USE_FEATURE_TAR_FROM( OPTBIT_INCLUDE_FROM,)
USE_FEATURE_TAR_FROM( OPTBIT_EXCLUDE_FROM,)
USE_FEATURE_SEAMLESS_GZ( OPTBIT_GZIP ,)
USE_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,)
OPTBIT_NOPRESERVE_OWN,
OPTBIT_NOPRESERVE_PERM,
OPT_TEST = 1 << 0, // t
@@ -747,14 +747,14 @@ enum {
OPT_P = 1 << 5, // p
OPT_VERBOSE = 1 << 6, // v
OPT_KEEP_OLD = 1 << 7, // k
OPT_CREATE = USE_FEATURE_TAR_CREATE( (1<<OPTBIT_CREATE )) + 0, // c
OPT_DEREFERENCE = USE_FEATURE_TAR_CREATE( (1<<OPTBIT_DEREFERENCE )) + 0, // h
OPT_BZIP2 = USE_FEATURE_TAR_BZIP2( (1<<OPTBIT_BZIP2 )) + 0, // j
OPT_LZMA = USE_FEATURE_TAR_LZMA( (1<<OPTBIT_LZMA )) + 0, // a
OPT_INCLUDE_FROM = USE_FEATURE_TAR_FROM( (1<<OPTBIT_INCLUDE_FROM)) + 0, // T
OPT_EXCLUDE_FROM = USE_FEATURE_TAR_FROM( (1<<OPTBIT_EXCLUDE_FROM)) + 0, // X
OPT_GZIP = USE_FEATURE_TAR_GZIP( (1<<OPTBIT_GZIP )) + 0, // z
OPT_COMPRESS = USE_FEATURE_TAR_COMPRESS((1<<OPTBIT_COMPRESS )) + 0, // Z
OPT_CREATE = USE_FEATURE_TAR_CREATE( (1 << OPTBIT_CREATE )) + 0, // c
OPT_DEREFERENCE = USE_FEATURE_TAR_CREATE( (1 << OPTBIT_DEREFERENCE )) + 0, // h
OPT_BZIP2 = USE_FEATURE_SEAMLESS_BZ2( (1 << OPTBIT_BZIP2 )) + 0, // j
OPT_LZMA = USE_FEATURE_SEAMLESS_LZMA((1 << OPTBIT_LZMA )) + 0, // a
OPT_INCLUDE_FROM = USE_FEATURE_TAR_FROM( (1 << OPTBIT_INCLUDE_FROM)) + 0, // T
OPT_EXCLUDE_FROM = USE_FEATURE_TAR_FROM( (1 << OPTBIT_EXCLUDE_FROM)) + 0, // X
OPT_GZIP = USE_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z
OPT_COMPRESS = USE_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z
OPT_NOPRESERVE_OWN = 1 << OPTBIT_NOPRESERVE_OWN , // no-same-owner
OPT_NOPRESERVE_PERM = 1 << OPTBIT_NOPRESERVE_PERM, // no-same-permissions
};
@@ -772,20 +772,20 @@ static const char tar_longopts[] ALIGN1 =
"create\0" No_argument "c"
"dereference\0" No_argument "h"
# endif
# if ENABLE_FEATURE_TAR_BZIP2
# if ENABLE_FEATURE_SEAMLESS_BZ2
"bzip2\0" No_argument "j"
# endif
# if ENABLE_FEATURE_TAR_LZMA
# if ENABLE_FEATURE_SEAMLESS_LZMA
"lzma\0" No_argument "a"
# endif
# if ENABLE_FEATURE_TAR_FROM
"files-from\0" Required_argument "T"
"exclude-from\0" Required_argument "X"
# endif
# if ENABLE_FEATURE_TAR_GZIP
# if ENABLE_FEATURE_SEAMLESS_GZ
"gzip\0" No_argument "z"
# endif
# if ENABLE_FEATURE_TAR_COMPRESS
# if ENABLE_FEATURE_SEAMLESS_Z
"compress\0" No_argument "Z"
# endif
"no-same-owner\0" No_argument "\xfd"
@@ -834,12 +834,12 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
#endif
opt = getopt32(argv,
"txC:f:Opvk"
USE_FEATURE_TAR_CREATE( "ch" )
USE_FEATURE_TAR_BZIP2( "j" )
USE_FEATURE_TAR_LZMA( "a" )
USE_FEATURE_TAR_FROM( "T:X:")
USE_FEATURE_TAR_GZIP( "z" )
USE_FEATURE_TAR_COMPRESS("Z" )
USE_FEATURE_TAR_CREATE( "ch" )
USE_FEATURE_SEAMLESS_BZ2( "j" )
USE_FEATURE_SEAMLESS_LZMA("a" )
USE_FEATURE_TAR_FROM( "T:X:")
USE_FEATURE_SEAMLESS_GZ( "z" )
USE_FEATURE_SEAMLESS_Z( "Z" )
, &base_dir // -C dir
, &tar_filename // -f filename
USE_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T
@@ -922,8 +922,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
tar_stream = stdout;
/* Mimicking GNU tar 1.15.1: */
flags = O_WRONLY|O_CREAT|O_TRUNC;
/* was doing unlink; open(O_WRONLY|O_CREAT|O_EXCL); why? */
flags = O_WRONLY | O_CREAT | O_TRUNC;
} else {
tar_stream = stdin;
flags = O_RDONLY;
@@ -933,7 +932,14 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
tar_handle->src_fd = fileno(tar_stream);
tar_handle->seek = seek_by_read;
} else {
tar_handle->src_fd = xopen(tar_filename, flags);
if (ENABLE_FEATURE_TAR_AUTODETECT && flags == O_RDONLY) {
get_header_ptr = get_header_tar;
tar_handle->src_fd = open_zipped(tar_filename);
if (tar_handle->src_fd < 0)
bb_perror_msg_and_die("can't open '%s'", tar_filename);
} else {
tar_handle->src_fd = xopen(tar_filename, flags);
}
}
}
@@ -947,11 +953,11 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
/* create an archive */
if (opt & OPT_CREATE) {
#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
int zipMode = 0;
if (ENABLE_FEATURE_TAR_GZIP && (opt & OPT_GZIP))
if (ENABLE_FEATURE_SEAMLESS_GZ && (opt & OPT_GZIP))
zipMode = 1;
if (ENABLE_FEATURE_TAR_BZIP2 && (opt & OPT_BZIP2))
if (ENABLE_FEATURE_SEAMLESS_BZ2 && (opt & OPT_BZIP2))
zipMode = 2;
#endif
/* NB: writeTarFile() closes tar_handle->src_fd */