diff --git a/archival/Makefile.in b/archival/Makefile.in index c53171eea..226cde690 100644 --- a/archival/Makefile.in +++ b/archival/Makefile.in @@ -23,6 +23,7 @@ ARCHIVAL_DIR:=$(TOPDIR)archival/ endif ARCHIVAL-y:= +ARCHIVAL-$(CONFIG_APT_GET) += ARCHIVAL-$(CONFIG_AR) += ar.o ARCHIVAL-$(CONFIG_BUNZIP2) += bunzip2.o ARCHIVAL-$(CONFIG_CPIO) += cpio.o @@ -32,6 +33,7 @@ ARCHIVAL-$(CONFIG_GUNZIP) += gunzip.o ARCHIVAL-$(CONFIG_GZIP) += gzip.o ARCHIVAL-$(CONFIG_RPM2CPIO) += rpm2cpio.o ARCHIVAL-$(CONFIG_TAR) += tar.o +ARCHIVAL-$(CONFIG_UNCOMPRESS) += uncompress.o ARCHIVAL-$(CONFIG_UNZIP) += unzip.o libraries-y+=$(ARCHIVAL_DIR)$(ARCHIVAL_AR) diff --git a/archival/config.in b/archival/config.in index dd97909f9..689561b8e 100644 --- a/archival/config.in +++ b/archival/config.in @@ -18,6 +18,9 @@ if [ "$CONFIG_DPKG_DEB" = "y" ] ; then bool ' -x support only' CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY fi bool 'gunzip' CONFIG_GUNZIP +if [ "$CONFIG_GUNZIP" = "y" ]; then + bool ' Uncompress support' CONFIG_FEATURE_GUNZIP_UNCOMPRESS +fi bool 'gzip' CONFIG_GZIP bool 'rpm2cpio' CONFIG_RPM2CPIO bool 'tar' CONFIG_TAR @@ -31,5 +34,6 @@ fi if [ "$CONFIG_CPIO" = "y" -o "$CONFIG_TAR" = "y" ] ; then bool ' Enable tape drive support' CONFIG_FEATURE_UNARCHIVE_TAPE fi +bool 'uncompress' CONFIG_UNCOMPRESS bool 'unzip' CONFIG_UNZIP endmenu diff --git a/archival/gunzip.c b/archival/gunzip.c index b6f3e08ea..e9963a8d2 100644 --- a/archival/gunzip.c +++ b/archival/gunzip.c @@ -143,7 +143,7 @@ extern int gunzip_main(int argc, char **argv) new_path = xstrdup(old_path); extension = strrchr(new_path, '.'); -#ifdef CONFIG_FEATURE_UNCOMPRESS +#ifdef CONFIG_FEATURE_GUNZIP_UNCOMPRESS if (extension && (strcmp(extension, ".Z") == 0)) { *extension = '\0'; } else @@ -172,7 +172,7 @@ extern int gunzip_main(int argc, char **argv) unsigned char magic2; magic2 = xread_char(src_fd); -#ifdef CONFIG_FEATURE_UNCOMPRESS +#ifdef CONFIG_FEATURE_GUNZIP_UNCOMPRESS if (magic2 == 0x9d) { status = uncompress(src_fd, dst_fd); } else diff --git a/archival/libunarchive/decompress_uncompress.c b/archival/libunarchive/decompress_uncompress.c index 02835cfce..302201fc0 100644 --- a/archival/libunarchive/decompress_uncompress.c +++ b/archival/libunarchive/decompress_uncompress.c @@ -1,7 +1,7 @@ #include "config.h" #include "libbb.h" -#ifdef CONFIG_FEATURE_UNCOMPRESS +#ifdef CONFIG_UNCOMPRESS || defined CONFIG_FEATURE_GUNZIP_UNCOMPRESS /* uncompress for busybox -- (c) 2002 Robert Griebl * diff --git a/archival/libunarchive/uncompress.c b/archival/libunarchive/uncompress.c index 02835cfce..302201fc0 100644 --- a/archival/libunarchive/uncompress.c +++ b/archival/libunarchive/uncompress.c @@ -1,7 +1,7 @@ #include "config.h" #include "libbb.h" -#ifdef CONFIG_FEATURE_UNCOMPRESS +#ifdef CONFIG_UNCOMPRESS || defined CONFIG_FEATURE_GUNZIP_UNCOMPRESS /* uncompress for busybox -- (c) 2002 Robert Griebl * diff --git a/archival/uncompress.c b/archival/uncompress.c new file mode 100644 index 000000000..877bcc784 --- /dev/null +++ b/archival/uncompress.c @@ -0,0 +1,133 @@ +/* vi: set sw=4 ts=4: */ +/* + * Uncompress applet for busybox (c) 2002 Glenn McGrath + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "libbb.h" +#include "unarchive.h" + +int uncompress_main(int argc, char **argv) +{ + const char gunzip_to_stdout = 1; + const char gunzip_force = 2; + char status = EXIT_SUCCESS; + char flags = 0; + int opt; + + while ((opt = getopt(argc, argv, "cfh")) != -1) { + switch (opt) { + case 'c': + flags |= gunzip_to_stdout; + break; + case 'f': + flags |= gunzip_force; + break; + default: + show_usage(); /* exit's inside usage */ + } + } + + do { + struct stat stat_buf; + const char *old_path = argv[optind]; + const char *delete_path = NULL; + char *new_path = NULL; + int src_fd; + int dst_fd; + + optind++; + + if (old_path == NULL || strcmp(old_path, "-") == 0) { + src_fd = fileno(stdin); + flags |= gunzip_to_stdout; + } else { + src_fd = xopen(old_path, O_RDONLY); + + /* Get the time stamp on the input file. */ + if (stat(old_path, &stat_buf) < 0) { + error_msg_and_die("Couldn't stat file %s", old_path); + } + } + + /* Check that the input is sane. */ + if (isatty(src_fd) && ((flags & gunzip_force) == 0)) { + 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 = fileno(stdout); + } else { + char *extension; + + new_path = xstrdup(old_path); + + extension = strrchr(new_path, '.'); + if (!extension || (strcmp(extension, ".Z") != 0)) { + error_msg_and_die("Invalid extension"); + } + *extension = '\0'; + + /* Open output file */ + dst_fd = xopen(new_path, O_WRONLY | O_CREAT); + + /* Set permissions on the file */ + chmod(new_path, stat_buf.st_mode); + + /* If unzip succeeds remove the old file */ + delete_path = old_path; + } + + /* do the decompression, and cleanup */ + if ((xread_char(src_fd) == 0x1f) && (xread_char(src_fd) == 0x9d)) { + status = uncompress(src_fd, dst_fd); + } else { + error_msg_and_die("Invalid magic"); + } + + if ((status != EXIT_SUCCESS) && (new_path)) { + /* Unzip failed, remove new path instead of old path */ + delete_path = new_path; + } + + if (dst_fd != fileno(stdout)) { + close(dst_fd); + } + if (src_fd != fileno(stdin)) { + close(src_fd); + } + + /* delete_path will be NULL if in test mode or from stdin */ + if (delete_path && (unlink(delete_path) == -1)) { + error_msg_and_die("Couldn't remove %s", delete_path); + } + + free(new_path); + + } while (optind < argc); + + return status; +} diff --git a/include/applets.h b/include/applets.h index 836ed9956..1660b11c5 100644 --- a/include/applets.h +++ b/include/applets.h @@ -515,10 +515,8 @@ #ifdef CONFIG_UNAME APPLET(uname, uname_main, _BB_DIR_BIN, _BB_SUID_NEVER) #endif -#ifdef CONFIG_GUNZIP -# ifdef CONFIG_FEATURE_UNCOMPRESS - APPLET_ODDNAME("uncompress", gunzip_main, _BB_DIR_BIN, _BB_SUID_NEVER, gunzip) -# endif +#ifdef CONFIG_UNCOMPRESS + APPLET(uncompress, uncompress_main, _BB_DIR_BIN, _BB_SUID_NEVER) #endif #ifdef CONFIG_UNIQ APPLET(uniq, uniq_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) diff --git a/include/usage.h b/include/usage.h index fb126a007..8ea8c5a92 100644 --- a/include/usage.h +++ b/include/usage.h @@ -2032,6 +2032,14 @@ "$ uname -a\n" \ "Linux debian 2.2.15pre13 #5 Tue Mar 14 16:03:50 MST 2000 i686 unknown\n" +#define uncompress_trivial_usage \ + "[-c] [-f] [ name ... ]" +#define uncompress_full_usage \ + "Uncompress .Z file[s]\n" \ + "Options:\n" \ + "\t-c\textract to stdout\n" \ + "\t-f\tforce overwrite an existing file\n" + #define uniq_trivial_usage \ "[OPTION]... [INPUT [OUTPUT]]" #define uniq_full_usage \ diff --git a/sysdeps/linux/config.in b/sysdeps/linux/config.in index c1860556d..ca7d97d4b 100644 --- a/sysdeps/linux/config.in +++ b/sysdeps/linux/config.in @@ -14,7 +14,6 @@ bool 'Show verbose applet usage messages' CONFIG_FEATURE_VERBOSE_USAGE bool 'Support --install [-s] to install applet links at runtime' CONFIG_FEATURE_INSTALLER bool 'Enable locale support (system needs locale for this to work)' CONFIG_LOCALE_SUPPORT bool 'Support for devfs' CONFIG_FEATURE_DEVFS -bool 'Support compress format (.Z) in unzip operations' CONFIG_FEATURE_UNCOMPRESS bool 'Clean up all memory before exiting (usually not needed)' CONFIG_FEATURE_CLEAN_UP bool 'Support for SUID/SGID handling' CONFIG_FEATURE_SUID if [ "$CONFIG_FEATURE_SUID" = "y" ]; then