bunzip2/gunzip/uncompress/unlzma: merge into common code -
fix few corner cases, reduce size by 450 bytes. Update testsuite.
This commit is contained in:
parent
8e858e2700
commit
ab9eef21a5
@ -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
346
archival/bbunzip.c
Normal 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
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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
84
testsuite/bunzip2.tests
Executable 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
49
testsuite/bzcat.tests
Executable 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
3
testsuite/gunzip.tests
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
. bunzip2.tests
|
Loading…
Reference in New Issue
Block a user