bunzip2/gunzip/uncompress/unlzma: merge into common code -
authorDenis Vlasenko <vda.linux@googlemail.com>
Wed, 7 Mar 2007 22:02:23 +0000 (22:02 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Wed, 7 Mar 2007 22:02:23 +0000 (22:02 -0000)
fix few corner cases, reduce size by 450 bytes. Update testsuite.

14 files changed:
archival/Kbuild
archival/bbunzip.c [new file with mode: 0644]
archival/bunzip2.c [deleted file]
archival/gunzip.c [deleted file]
archival/libunarchive/check_header_gzip.c
archival/libunarchive/get_header_tar_gz.c
archival/rpm.c
archival/rpm2cpio.c
archival/uncompress.c [deleted file]
archival/unlzma.c [deleted file]
include/unarchive.h
testsuite/bunzip2.tests [new file with mode: 0755]
testsuite/bzcat.tests [new file with mode: 0755]
testsuite/gunzip.tests [new file with mode: 0755]

index f85e0c2..50b90fa 100644 (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
diff --git a/archival/bbunzip.c b/archival/bbunzip.c
new file mode 100644 (file)
index 0000000..7ec8f4f
--- /dev/null
@@ -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
diff --git a/archival/bunzip2.c b/archival/bunzip2.c
deleted file mode 100644 (file)
index 1deac7b..0000000
+++ /dev/null
@@ -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;
-}
diff --git a/archival/gunzip.c b/archival/gunzip.c
deleted file mode 100644 (file)
index 3d99fe5..0000000
+++ /dev/null
@@ -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;
-}
index 0cfa944..09cd6a9 100644 (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 */
+#include "unarchive.h" /* for external decl of check_header_gzip_or_die */
 
-void check_header_gzip(int src_fd)
+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;
 }
index 41c02e1..1f07e4e 100644 (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;
index 9ab12df..a48dda3 100644 (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);
index 7a2e64b..307d1a0 100644 (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");
        }
diff --git a/archival/uncompress.c b/archival/uncompress.c
deleted file mode 100644 (file)
index b16c353..0000000
+++ /dev/null
@@ -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;
-}
diff --git a/archival/unlzma.c b/archival/unlzma.c
deleted file mode 100644 (file)
index 24632c4..0000000
+++ /dev/null
@@ -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);
-}
index 5e87d08..36b56a9 100644 (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);
diff --git a/testsuite/bunzip2.tests b/testsuite/bunzip2.tests
new file mode 100755 (executable)
index 0000000..83c365d
--- /dev/null
@@ -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
\ No newline at end of file
diff --git a/testsuite/bzcat.tests b/testsuite/bzcat.tests
new file mode 100755 (executable)
index 0000000..16fa3c2
--- /dev/null
@@ -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
diff --git a/testsuite/gunzip.tests b/testsuite/gunzip.tests
new file mode 100755 (executable)
index 0000000..d781004
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+. bunzip2.tests