bunzip2/gunzip/uncompress/unlzma: merge into common code -

fix few corner cases, reduce size by 450 bytes. Update testsuite.
This commit is contained in:
Denis Vlasenko 2007-03-07 22:02:23 +00:00
parent 8e858e2700
commit ab9eef21a5
14 changed files with 494 additions and 405 deletions

View File

@ -8,15 +8,15 @@ libs-y += libunarchive/
lib-y:=
lib-$(CONFIG_AR) += ar.o
lib-$(CONFIG_BUNZIP2) += bunzip2.o
lib-$(CONFIG_UNLZMA) += unlzma.o
lib-$(CONFIG_BUNZIP2) += bbunzip.o ### bunzip2.o
lib-$(CONFIG_UNLZMA) += bbunzip.o ### unlzma.o
lib-$(CONFIG_CPIO) += cpio.o
lib-$(CONFIG_DPKG) += dpkg.o
lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o
lib-$(CONFIG_GUNZIP) += gunzip.o
lib-$(CONFIG_GUNZIP) += bbunzip.o ### gunzip.o
lib-$(CONFIG_GZIP) += gzip.o
lib-$(CONFIG_RPM2CPIO) += rpm2cpio.o
lib-$(CONFIG_RPM) += rpm.o
lib-$(CONFIG_TAR) += tar.o
lib-$(CONFIG_UNCOMPRESS) += uncompress.o
lib-$(CONFIG_UNCOMPRESS) += bbunzip.o ### uncompress.o
lib-$(CONFIG_UNZIP) += unzip.o

346
archival/bbunzip.c Normal file
View File

@ -0,0 +1,346 @@
/* vi: set sw=4 ts=4: */
/*
* Modified for busybox by Glenn McGrath <bug1@iinet.net.au>
* Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include "busybox.h"
#include "unarchive.h"
enum {
OPT_STDOUT = 1,
OPT_FORCE = 2,
/* gunzip only: */
OPT_TEST = 4,
OPT_DECOMPRESS = 8,
OPT_VERBOSE = 0x10,
};
static
int open_to_or_warn(int to_fd, const char *filename, int flags, int mode)
{
int fd = open(filename, flags, mode);
if (fd < 0) {
bb_perror_msg("%s", filename);
return 1;
}
if (fd != to_fd) {
if (dup2(fd, to_fd) < 0)
bb_perror_msg_and_die("cannot dup");
close(fd);
}
return 0;
}
static
int unpack(char **argv,
char* (*make_new_name)(char *filename),
USE_DESKTOP(long long) int (*unpacker)(void)
)
{
struct stat stat_buf;
USE_DESKTOP(long long) int status;
char *filename;
/* NB: new_name is *possibly* malloc'ed! */
smallint exitcode = 0;
do {
char *new_name = NULL;
filename = *argv; /* can be NULL - 'streaming' bunzip2 */
if (filename && LONE_DASH(filename))
filename = NULL;
/* Open src */
if (filename) {
if (stat(filename, &stat_buf) != 0) {
bb_perror_msg("%s", filename);
err:
exitcode = 1;
goto free_name;
}
if (open_to_or_warn(STDIN_FILENO, filename, O_RDONLY, 0))
goto err;
}
/* Special cases: test, stdout */
if (option_mask32 & (OPT_STDOUT|OPT_TEST)) {
if (option_mask32 & OPT_TEST)
if (open_to_or_warn(STDOUT_FILENO, bb_dev_null, O_WRONLY, 0))
goto err;
filename = NULL;
}
/* Open dst unless -c, "-" or called as bzcat */
if (filename) {
new_name = make_new_name(filename);
if (!new_name) {
bb_error_msg("%s: unknown suffix - ignored", filename);
goto err;
}
/* O_EXCL: "real" bunzip2 doesn't overwrite files too */
/* TODO: "real" gunzip goes not bail out, but goes
* to next file */
if (open_to_or_warn(STDOUT_FILENO, new_name, O_WRONLY | O_CREAT | O_EXCL,
stat_buf.st_mode))
goto err;
}
/* Check that the input is sane. */
if (isatty(STDIN_FILENO) && (option_mask32 & OPT_FORCE) == 0) {
bb_error_msg_and_die("compressed data not read from terminal, "
"use -f to force it");
}
status = unpacker();
if (status < 0)
exitcode = 1;
if (filename) {
char *del = new_name;
if (status >= 0) {
/* TODO: restore user/group/times here? */
/* delete _old_ file */
del = filename;
/* Restore extension (unless tgz -> tar case) */
if (new_name == filename)
filename[strlen(filename)] = '.';
}
if (unlink(del) < 0)
bb_perror_msg_and_die("cannot remove %s", del);
#if 0 /* Currently buggy - wrong name: "a.gz: 261% - replaced with a.gz" */
/* Extreme bloat for gunzip compat */
if (ENABLE_DESKTOP && (option_mask32 & OPT_VERBOSE) && status >= 0) {
fprintf(stderr, "%s: %u%% - replaced with %s\n",
filename, (unsigned)(stat_buf.st_size*100 / (status+1)), new_name);
}
#endif
free_name:
if (new_name != filename)
free(new_name);
}
} while (*argv && *++argv);
return exitcode;
}
#if ENABLE_BUNZIP2
static
char* make_new_name_bunzip2(char *filename)
{
char *extension = strrchr(filename, '.');
if (!extension || strcmp(extension, ".bz2") != 0) {
/* Mimic GNU gunzip ("real" bunzip2 tries to */
/* unpack file anyway, to file.out) */
return NULL;
}
*extension = '\0';
return filename;
}
static
USE_DESKTOP(long long) int unpack_bunzip2(void)
{
return uncompressStream(STDIN_FILENO, STDOUT_FILENO);
}
int bunzip2_main(int argc, char **argv);
int bunzip2_main(int argc, char **argv)
{
getopt32(argc, argv, "cf");
argv += optind;
if (applet_name[2] == 'c')
option_mask32 |= OPT_STDOUT;
return unpack(argv, make_new_name_bunzip2, unpack_bunzip2);
}
#endif
/*
* Gzip implementation for busybox
*
* Based on GNU gzip v1.2.4 Copyright (C) 1992-1993 Jean-loup Gailly.
*
* Originally adjusted for busybox by Sven Rudolph <sr1@inf.tu-dresden.de>
* based on gzip sources
*
* Adjusted further by Erik Andersen <andersen@codepoet.org> to support files as
* well as stdin/stdout, and to generally behave itself wrt command line
* handling.
*
* General cleanup to better adhere to the style guide and make use of standard
* busybox functions by Glenn McGrath <bug1@iinet.net.au>
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*
* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
* Copyright (C) 1992-1993 Jean-loup Gailly
* The unzip code was written and put in the public domain by Mark Adler.
* Portions of the lzw code are derived from the public domain 'compress'
* written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
* Ken Turkowski, Dave Mack and Peter Jannesen.
*
* See the license_msg below and the file COPYING for the software license.
* See the file algorithm.doc for the compression algorithms and file formats.
*/
#if ENABLE_GUNZIP
static
char* make_new_name_gunzip(char *filename)
{
char *extension = strrchr(filename, '.');
if (!extension)
return NULL;
if (strcmp(extension, ".gz") == 0
#ifdef CONFIG_FEATURE_GUNZIP_UNCOMPRESS
|| strcmp(extension, ".Z") == 0
#endif
) {
*extension = '\0';
} else if(strcmp(extension, ".tgz") == 0) {
filename = xstrdup(filename);
extension = strrchr(filename, '.');
extension[2] = 'a';
extension[3] = 'r';
} else {
return NULL;
}
return filename;
}
static
USE_DESKTOP(long long) int unpack_gunzip(void)
{
USE_DESKTOP(long long) int status = -1;
/* do the decompression, and cleanup */
if (xread_char(STDIN_FILENO) == 0x1f) {
unsigned char magic2;
magic2 = xread_char(STDIN_FILENO);
if (ENABLE_FEATURE_GUNZIP_UNCOMPRESS && magic2 == 0x9d) {
status = uncompress(STDIN_FILENO, STDOUT_FILENO);
} else if (magic2 == 0x8b) {
check_header_gzip_or_die(STDIN_FILENO);
status = inflate_gunzip(STDIN_FILENO, STDOUT_FILENO);
} else {
goto bad_magic;
}
if (status < 0) {
bb_error_msg("error inflating");
}
} else {
bad_magic:
bb_error_msg("invalid magic");
/* status is still == -1 */
}
return status;
}
int gunzip_main(int argc, char **argv);
int gunzip_main(int argc, char **argv)
{
getopt32(argc, argv, "cftdv");
argv += optind;
/* if called as zcat */
if (applet_name[1] == 'c')
option_mask32 |= OPT_STDOUT;
return unpack(argv, make_new_name_gunzip, unpack_gunzip);
}
#endif
/*
* Small lzma deflate implementation.
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* Based on bunzip.c from busybox
*
* Licensed under GPL v2, see file LICENSE in this tarball for details.
*/
#if ENABLE_UNLZMA
static
char* make_new_name_unlzma(char *filename)
{
char *extension = strrchr(filename, '.');
if (!extension || strcmp(extension, ".lzma") != 0)
return NULL;
*extension = '\0';
return filename;
}
static
USE_DESKTOP(long long) int unpack_unlzma(void)
{
return unlzma(STDIN_FILENO, STDOUT_FILENO);
}
int unlzma_main(int argc, char **argv);
int unlzma_main(int argc, char **argv)
{
getopt32(argc, argv, "c");
argv += optind;
/* lzmacat? */
if (applet_name[4] == 'c')
option_mask32 |= OPT_STDOUT;
return unpack(argv, make_new_name_unlzma, unpack_unlzma);
}
#endif
/* vi: set sw=4 ts=4: */
/*
* Uncompress applet for busybox (c) 2002 Glenn McGrath
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#if ENABLE_UNCOMPRESS
static
char* make_new_name_uncompress(char *filename)
{
char *extension = strrchr(filename, '.');
if (!extension || strcmp(extension, ".Z") != 0)
return NULL;
*extension = '\0';
return filename;
}
static
USE_DESKTOP(long long) int unpack_uncompress(void)
{
USE_DESKTOP(long long) int status = -1;
if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) {
bb_error_msg("invalid magic");
} else {
status = uncompress(STDIN_FILENO, STDOUT_FILENO);
}
return status;
}
int uncompress_main(int argc, char **argv);
int uncompress_main(int argc, char **argv)
{
getopt32(argc, argv, "cf");
argv += optind;
return unpack(argv, make_new_name_uncompress, unpack_uncompress);
}
#endif

View File

@ -1,67 +0,0 @@
/* vi: set sw=4 ts=4: */
/*
* Modified for busybox by Glenn McGrath <bug1@iinet.net.au>
* Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include "busybox.h"
#include "unarchive.h"
#define BUNZIP2_OPT_STDOUT 1
#define BUNZIP2_OPT_FORCE 2
int bunzip2_main(int argc, char **argv);
int bunzip2_main(int argc, char **argv)
{
USE_DESKTOP(long long) int status;
char *filename;
unsigned opt;
int src_fd, dst_fd;
opt = getopt32(argc, argv, "cf");
/* Set input filename and number */
filename = argv[optind];
if (filename && NOT_LONE_DASH(filename)) {
/* Open input file */
src_fd = xopen(filename, O_RDONLY);
} else {
src_fd = STDIN_FILENO;
filename = 0;
}
/* if called as bzcat force the stdout flag */
if ((opt & BUNZIP2_OPT_STDOUT) || applet_name[2] == 'c')
filename = 0;
/* Check that the input is sane. */
if (isatty(src_fd) && (opt & BUNZIP2_OPT_FORCE) == 0) {
bb_error_msg_and_die("compressed data not read from terminal, "
"use -f to force it");
}
if (filename) {
struct stat stat_buf;
/* extension = filename+strlen(filename)-4 is buggy:
* strlen may be less than 4 */
char *extension = strrchr(filename, '.');
if (!extension || strcmp(extension, ".bz2") != 0) {
bb_error_msg_and_die("invalid extension");
}
xstat(filename, &stat_buf);
*extension = '\0';
dst_fd = xopen3(filename, O_WRONLY | O_CREAT | O_TRUNC,
stat_buf.st_mode);
} else dst_fd = STDOUT_FILENO;
status = uncompressStream(src_fd, dst_fd);
if (filename) {
if (status >= 0) filename[strlen(filename)] = '.';
if (unlink(filename) < 0) {
bb_error_msg_and_die("cannot remove %s", filename);
}
}
return status;
}

View File

@ -1,163 +0,0 @@
/* vi: set sw=4 ts=4: */
/*
* Gzip implementation for busybox
*
* Based on GNU gzip v1.2.4 Copyright (C) 1992-1993 Jean-loup Gailly.
*
* Originally adjusted for busybox by Sven Rudolph <sr1@inf.tu-dresden.de>
* based on gzip sources
*
* Adjusted further by Erik Andersen <andersen@codepoet.org> to support files as
* well as stdin/stdout, and to generally behave itself wrt command line
* handling.
*
* General cleanup to better adhere to the style guide and make use of standard
* busybox functions by Glenn McGrath <bug1@iinet.net.au>
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*
* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
* Copyright (C) 1992-1993 Jean-loup Gailly
* The unzip code was written and put in the public domain by Mark Adler.
* Portions of the lzw code are derived from the public domain 'compress'
* written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
* Ken Turkowski, Dave Mack and Peter Jannesen.
*
* See the license_msg below and the file COPYING for the software license.
* See the file algorithm.doc for the compression algorithms and file formats.
*/
#include "busybox.h"
#include "unarchive.h"
#define GUNZIP_OPT_STDOUT 1
#define GUNZIP_OPT_FORCE 2
#define GUNZIP_OPT_TEST 4
#define GUNZIP_OPT_DECOMPRESS 8
#define GUNZIP_OPT_VERBOSE 0x10
int gunzip_main(int argc, char **argv);
int gunzip_main(int argc, char **argv)
{
USE_DESKTOP(long long) int status;
int exitcode = 0;
unsigned opt;
opt = getopt32(argc, argv, "cftdv");
/* if called as zcat */
if (strcmp(applet_name, "zcat") == 0) {
opt |= GUNZIP_OPT_STDOUT;
}
do {
struct stat stat_buf;
char *old_path = argv[optind];
char *delete_path = NULL;
char *new_path = NULL;
int src_fd;
int dst_fd;
optind++;
if (old_path == NULL || LONE_DASH(old_path)) {
src_fd = STDIN_FILENO;
opt |= GUNZIP_OPT_STDOUT;
USE_DESKTOP(opt &= ~GUNZIP_OPT_VERBOSE;)
optind = argc; /* we don't handle "gunzip - a.gz b.gz" */
} else {
src_fd = xopen(old_path, O_RDONLY);
/* Get the time stamp on the input file. */
fstat(src_fd, &stat_buf);
}
/* Check that the input is sane. */
if (isatty(src_fd) && !(opt & GUNZIP_OPT_FORCE)) {
bb_error_msg_and_die
("compressed data not read from terminal, use -f to force it");
}
/* Set output filename and number */
if (opt & GUNZIP_OPT_TEST) {
dst_fd = xopen(bb_dev_null, O_WRONLY); /* why does test use filenum 2 ? */
} else if (opt & GUNZIP_OPT_STDOUT) {
dst_fd = STDOUT_FILENO;
} else {
char *extension;
new_path = xstrdup(old_path);
extension = strrchr(new_path, '.');
#ifdef CONFIG_FEATURE_GUNZIP_UNCOMPRESS
if (extension && (strcmp(extension, ".Z") == 0)) {
*extension = '\0';
} else
#endif
if (extension && (strcmp(extension, ".gz") == 0)) {
*extension = '\0';
} else if (extension && (strcmp(extension, ".tgz") == 0)) {
extension[2] = 'a';
extension[3] = 'r';
} else {
// FIXME: should we die or just skip to next?
bb_error_msg_and_die("invalid extension");
}
/* Open output file (with correct permissions) */
dst_fd = xopen3(new_path, O_WRONLY | O_CREAT | O_TRUNC,
stat_buf.st_mode);
/* If unzip succeeds remove the old file */
delete_path = old_path;
}
status = -1;
/* do the decompression, and cleanup */
if (xread_char(src_fd) == 0x1f) {
unsigned char magic2;
magic2 = xread_char(src_fd);
if (ENABLE_FEATURE_GUNZIP_UNCOMPRESS && magic2 == 0x9d) {
status = uncompress(src_fd, dst_fd);
} else if (magic2 == 0x8b) {
check_header_gzip(src_fd); // FIXME: xfunc? _or_die?
status = inflate_gunzip(src_fd, dst_fd);
} else {
bb_error_msg("invalid magic");
exitcode = 1;
}
if (status < 0) {
bb_error_msg("error inflating");
exitcode = 1;
}
else if (ENABLE_DESKTOP && (opt & GUNZIP_OPT_VERBOSE)) {
fprintf(stderr, "%s: %u%% - replaced with %s\n",
old_path, (unsigned)(stat_buf.st_size*100 / (status+1)), new_path);
}
} else {
bb_error_msg("invalid magic");
exitcode = 1;
}
if (status < 0 && new_path) {
/* Unzip failed, remove new path instead of old path */
delete_path = new_path;
}
if (dst_fd != STDOUT_FILENO) {
close(dst_fd);
}
if (src_fd != STDIN_FILENO) {
close(src_fd);
}
/* delete_path will be NULL if in test mode or from stdin */
if (delete_path && (unlink(delete_path) == -1)) {
bb_error_msg("cannot remove %s", delete_path);
exitcode = 1;
}
free(new_path);
} while (optind < argc);
return exitcode;
}

View File

@ -2,12 +2,11 @@
/*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include <stdlib.h>
#include <unistd.h>
#include "libbb.h"
#include "unarchive.h" /* for external decl of check_header_gzip */
void check_header_gzip(int src_fd)
#include "libbb.h"
#include "unarchive.h" /* for external decl of check_header_gzip_or_die */
void check_header_gzip_or_die(int src_fd)
{
union {
unsigned char raw[8];
@ -57,6 +56,4 @@ void check_header_gzip(int src_fd)
xread_char(src_fd);
xread_char(src_fd);
}
return;
}

View File

@ -20,7 +20,7 @@ char get_header_tar_gz(archive_handle_t *archive_handle)
bb_error_msg_and_die("invalid gzip magic");
}
check_header_gzip(archive_handle->src_fd);
check_header_gzip_or_die(archive_handle->src_fd);
archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip);
archive_handle->offset = 0;

View File

@ -203,7 +203,7 @@ static void extract_cpio_gz(int fd) {
if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) {
bb_error_msg_and_die("invalid gzip magic");
}
check_header_gzip(archive_handle->src_fd);
check_header_gzip_or_die(archive_handle->src_fd);
xchdir("/"); /* Install RPM's to root */
archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip);

View File

@ -79,7 +79,7 @@ int rpm2cpio_main(int argc, char **argv)
bb_error_msg_and_die("invalid gzip magic");
}
check_header_gzip(rpm_fd);
check_header_gzip_or_die(rpm_fd);
if (inflate_gunzip(rpm_fd, STDOUT_FILENO) < 0) {
bb_error_msg("error inflating");
}

View File

@ -1,95 +0,0 @@
/* vi: set sw=4 ts=4: */
/*
* Uncompress applet for busybox (c) 2002 Glenn McGrath
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include "busybox.h"
#include "unarchive.h"
#define GUNZIP_TO_STDOUT 1
#define GUNZIP_FORCE 2
int uncompress_main(int argc, char **argv);
int uncompress_main(int argc, char **argv)
{
int status = EXIT_SUCCESS;
unsigned long flags;
flags = getopt32(argc, argv, "cf");
while (optind < argc) {
char *compressed_file = argv[optind++];
char *delete_path = NULL;
char *uncompressed_file = NULL;
int src_fd;
int dst_fd;
if (LONE_DASH(compressed_file)) {
src_fd = STDIN_FILENO;
flags |= GUNZIP_TO_STDOUT;
} else {
src_fd = xopen(compressed_file, O_RDONLY);
}
/* Check that the input is sane. */
if (isatty(src_fd) && ((flags & GUNZIP_FORCE) == 0)) {
bb_error_msg_and_die
("compressed data not read from terminal. Use -f to force it.");
}
/* Set output filename and number */
if (flags & GUNZIP_TO_STDOUT) {
dst_fd = STDOUT_FILENO;
} else {
struct stat stat_buf;
char *extension;
uncompressed_file = xstrdup(compressed_file);
extension = strrchr(uncompressed_file, '.');
if (!extension || (strcmp(extension, ".Z") != 0)) {
bb_error_msg_and_die("invalid extension");
}
*extension = '\0';
/* Open output file */
xstat(compressed_file, &stat_buf);
dst_fd = xopen3(uncompressed_file,
O_WRONLY | O_CREAT | O_TRUNC,
stat_buf.st_mode);
/* If unzip succeeds remove the old file */
delete_path = compressed_file;
}
/* do the decompression, and cleanup */
if ((xread_char(src_fd) != 0x1f) || (xread_char(src_fd) != 0x9d)) {
bb_error_msg_and_die("invalid magic");
}
status = uncompress(src_fd, dst_fd);
if ((status != EXIT_SUCCESS) && (uncompressed_file)) {
/* Unzip failed, remove the uncomressed file instead of compressed file */
delete_path = uncompressed_file;
}
if (dst_fd != STDOUT_FILENO) {
close(dst_fd);
}
if (src_fd != STDIN_FILENO) {
close(src_fd);
}
/* delete_path will be NULL if in test mode or from stdin */
if (delete_path && (unlink(delete_path) == -1)) {
bb_error_msg_and_die("cannot remove %s", delete_path);
}
free(uncompressed_file);
}
return status;
}

View File

@ -1,65 +0,0 @@
/* vi: set sw=4 ts=4: */
/*
* Small lzma deflate implementation.
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* Based on bunzip.c from busybox
*
* Licensed under GPL v2, see file LICENSE in this tarball for details.
*/
/* Why our g[un]zip/bunzip2 are so ugly compared to this beauty? */
#include "busybox.h"
#include "unarchive.h"
#define UNLZMA_OPT_STDOUT 1
int unlzma_main(int argc, char **argv);
int unlzma_main(int argc, char **argv)
{
USE_DESKTOP(long long) int status;
char *filename;
unsigned opt;
int src_fd, dst_fd;
opt = getopt32(argc, argv, "c");
/* Set input filename and number */
filename = argv[optind];
if (filename && NOT_LONE_DASH(filename)) {
/* Open input file */
src_fd = xopen(filename, O_RDONLY);
} else {
src_fd = STDIN_FILENO;
filename = 0;
}
/* if called as lzmacat force the stdout flag */
if ((opt & UNLZMA_OPT_STDOUT) || applet_name[4] == 'c')
filename = 0;
if (filename) {
struct stat stat_buf;
/* bug: char *extension = filename + strlen(filename) - 5; */
char *extension = strrchr(filename, '.');
if (!extension || strcmp(extension, ".lzma") != 0) {
bb_error_msg_and_die("invalid extension");
}
xstat(filename, &stat_buf);
*extension = '\0';
dst_fd = xopen3(filename, O_WRONLY | O_CREAT | O_TRUNC,
stat_buf.st_mode);
} else
dst_fd = STDOUT_FILENO;
status = unlzma(src_fd, dst_fd);
if (filename) {
if (status >= 0) /* if success delete src, else delete dst */
filename[strlen(filename)] = '.';
if (unlink(filename) < 0) {
bb_error_msg_and_die("cannot remove %s", filename);
}
}
return (status < 0);
}

View File

@ -83,7 +83,7 @@ extern void header_skip(const file_header_t *file_header);
extern void header_list(const file_header_t *file_header);
extern void header_verbose_list(const file_header_t *file_header);
extern void check_header_gzip(int src_fd);
extern void check_header_gzip_or_die(int src_fd);
extern char get_header_ar(archive_handle_t *archive_handle);
extern char get_header_cpio(archive_handle_t *archive_handle);

84
testsuite/bunzip2.tests Executable file
View File

@ -0,0 +1,84 @@
#!/bin/sh
if test "${0##*/}" = "gunzip.tests"; then
unpack=gunzip
ext=gz
elif test "${0##*/}" = "bunzip2.tests"; then
unpack=bunzip2
ext=bz2
else
echo "WTF? argv0='$0'"
exit 1
fi
bb="busybox "
unset LC_ALL
unset LC_MESSAGES
unset LANG
unset LANGUAGE
hello_gz() {
# Gzipped "HELLO\n"
#_________________________ vvv vvv vvv vvv - mtime
echo -ne "\x1f\x8b\x08\x00\x85\x1d\xef\x45\x02\x03\xf3\x70\xf5\xf1\xf1\xe7"
echo -ne "\x02\x00\x6e\xd7\xac\xfd\x06\x00\x00\x00"
}
hello_bz2() {
# Bzipped "HELLO\n"
echo -ne "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x5b\xb8\xe8\xa3\x00\x00"
echo -ne "\x01\x44\x00\x00\x10\x02\x44\xa0\x00\x30\xcd\x00\xc3\x46\x29\x97"
echo -ne "\x17\x72\x45\x38\x50\x90\x5b\xb8\xe8\xa3"
}
prep() {
rm -f t*
hello_$ext >t1.$ext
hello_$ext >t2.$ext
}
check() {
eval $2 >t_actual 2>&1
if echo -ne "$expected" | cmp - t_actual; then
echo "$1: PASS"
else
echo "$1: FAIL"
fi
}
mkdir testdir 2>/dev/null
(
cd testdir || { echo "cannot cd testdir!"; exit 1; }
expected="$unpack: z: No such file or directory
1
HELLO
"
prep; check "$unpack: doesnt exist" "${bb}$unpack z t1.$ext; echo \$?; cat t1"
expected="$unpack: t.zz: unknown suffix - ignored
1
HELLO
"
prep; >t.zz; check "$unpack: unknown suffix" "${bb}$unpack t.zz t1.$ext; echo \$?; cat t1"
# In this case file "t1" exists, and we skip t1.gz and unpack t2.gz
expected="$unpack: t1: File exists
1
HELLO
"
prep; >t1; check "$unpack: already exists" "${bb}$unpack t1.$ext t2.$ext; echo \$?; cat t1 t2"
# From old testsuite
expected="HELLO\n0\n"
prep; check "$unpack: stream unpack" "cat t1.$ext | ${bb}$unpack; echo $?"
expected="ok\n"
prep; check "$unpack: delete src" "${bb}$unpack t2.$ext; test ! -f t2.$ext && echo ok"
)
rm -rf testdir

49
testsuite/bzcat.tests Executable file
View File

@ -0,0 +1,49 @@
#!/bin/sh
ext=bz2
bb="busybox "
unset LC_ALL
unset LC_MESSAGES
unset LANG
unset LANGUAGE
hello_gz() {
# Gzipped "HELLO\n"
#_________________________ vvv vvv vvv vvv - mtime
echo -ne "\x1f\x8b\x08\x00\x85\x1d\xef\x45\x02\x03\xf3\x70\xf5\xf1\xf1\xe7"
echo -ne "\x02\x00\x6e\xd7\xac\xfd\x06\x00\x00\x00"
}
hello_bz2() {
# Bzipped "HELLO\n"
echo -ne "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x5b\xb8\xe8\xa3\x00\x00"
echo -ne "\x01\x44\x00\x00\x10\x02\x44\xa0\x00\x30\xcd\x00\xc3\x46\x29\x97"
echo -ne "\x17\x72\x45\x38\x50\x90\x5b\xb8\xe8\xa3"
}
prep() {
rm -f t*
hello_$ext >t1.$ext
hello_$ext >t2.$ext
}
check() {
eval $2 >t_actual 2>&1
if echo -ne "$expected" | cmp - t_actual; then
echo "$1: PASS"
else
echo "$1: FAIL"
fi
}
mkdir testdir 2>/dev/null
(
cd testdir || { echo "cannot cd testdir!"; exit 1; }
expected="HELLO\nok\n"
prep; check "bzcat: dont delete src" "${bb}bzcat t2.bz2; test -f t2.bz2 && echo ok"
)
rm -rf testdir

3
testsuite/gunzip.tests Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
. bunzip2.tests