enum {
OPT_STDOUT = 0x1,
OPT_FORCE = 0x2,
-/* gunzip only: */
+/* gunzip and bunzip2 only: */
OPT_VERBOSE = 0x4,
OPT_DECOMPRESS = 0x8,
OPT_TEST = 0x10,
return 0;
}
-int bbunpack(char **argv,
+int FAST_FUNC bbunpack(char **argv,
char* (*make_new_name)(char *filename),
- USE_DESKTOP(long long) int (*unpacker)(void)
+ USE_DESKTOP(long long) int (*unpacker)(unpack_info_t *info)
)
{
struct stat stat_buf;
USE_DESKTOP(long long) int status;
char *filename, *new_name;
smallint exitcode = 0;
+ unpack_info_t info;
do {
/* NB: new_name is *maybe* malloc'ed! */
/* Open src */
if (filename) {
if (stat(filename, &stat_buf) != 0) {
- bb_perror_msg("%s", filename);
+ bb_simple_perror_msg(filename);
err:
exitcode = 1;
goto free_name;
bb_error_msg("%s: unknown suffix - ignored", filename);
goto err;
}
+
+ /* -f: overwrite existing output files */
+ if (option_mask32 & OPT_FORCE) {
+ unlink(new_name);
+ }
+
/* O_EXCL: "real" bunzip2 doesn't overwrite files */
- /* GNU gunzip goes not bail out, but goes to next file */
+ /* GNU gunzip does 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;
"use -f to force it");
}
- status = unpacker();
+ /* memset(&info, 0, sizeof(info)); */
+ info.mtime = 0; /* so far it has one member only */
+ status = unpacker(&info);
if (status < 0)
exitcode = 1;
if (filename) {
char *del = new_name;
if (status >= 0) {
- /* TODO: restore user/group/times here? */
+ /* TODO: restore other things? */
+ if (info.mtime) {
+ struct utimbuf times;
+
+ times.actime = info.mtime;
+ times.modtime = info.mtime;
+ /* Close first.
+ * On some systems calling utime
+ * then closing resets the mtime. */
+ close(STDOUT_FILENO);
+ /* Ignoring errors */
+ utime(new_name, ×);
+ }
+
/* Delete _compressed_ file */
del = filename;
/* restore extension (unless tgz -> tar case) */
/*
- * Modified for busybox by Glenn McGrath <bug1@iinet.net.au>
+ * Modified for busybox by Glenn McGrath
* Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
}
static
-USE_DESKTOP(long long) int unpack_bunzip2(void)
+USE_DESKTOP(long long) int unpack_bunzip2(unpack_info_t *info UNUSED_PARAM)
{
- return unpack_bz2_stream(STDIN_FILENO, STDOUT_FILENO);
+ return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO);
}
-int bunzip2_main(int argc, char **argv);
-int bunzip2_main(int argc, char **argv)
+int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int bunzip2_main(int argc UNUSED_PARAM, char **argv)
{
- getopt32(argc, argv, "cf");
+ getopt32(argv, "cfvdt");
argv += optind;
if (applet_name[2] == 'c')
option_mask32 |= OPT_STDOUT;
* handling.
*
* General cleanup to better adhere to the style guide and make use of standard
- * busybox functions by Glenn McGrath <bug1@iinet.net.au>
+ * busybox functions by Glenn McGrath
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*
extension++;
if (strcmp(extension, "tgz" + 1) == 0
-#ifdef CONFIG_FEATURE_GUNZIP_UNCOMPRESS
- || strcmp(extension, "Z") == 0
+#if ENABLE_FEATURE_SEAMLESS_Z
+ || (extension[0] == 'Z' && extension[1] == '\0')
#endif
) {
extension[-1] = '\0';
}
static
-USE_DESKTOP(long long) int unpack_gunzip(void)
+USE_DESKTOP(long long) int unpack_gunzip(unpack_info_t *info)
{
USE_DESKTOP(long long) int status = -1;
unsigned char magic2;
magic2 = xread_char(STDIN_FILENO);
- if (ENABLE_FEATURE_GUNZIP_UNCOMPRESS && magic2 == 0x9d) {
- status = uncompress(STDIN_FILENO, STDOUT_FILENO);
+ if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == 0x9d) {
+ status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO);
} else if (magic2 == 0x8b) {
- check_header_gzip_or_die(STDIN_FILENO);
- status = unpack_gz_stream(STDIN_FILENO, STDOUT_FILENO);
+ status = unpack_gz_stream_with_info(STDIN_FILENO, STDOUT_FILENO, info);
} else {
goto bad_magic;
}
return status;
}
-int gunzip_main(int argc, char **argv);
-int gunzip_main(int argc, char **argv)
+/*
+ * Linux kernel build uses gzip -d -n. We accept and ignore it.
+ * Man page says:
+ * -n --no-name
+ * gzip: do not save the original file name and time stamp.
+ * (The original name is always saved if the name had to be truncated.)
+ * gunzip: do not restore the original file name/time even if present
+ * (remove only the gzip suffix from the compressed file name).
+ * This option is the default when decompressing.
+ * -N --name
+ * gzip: always save the original file name and time stamp (this is the default)
+ * gunzip: restore the original file name and time stamp if present.
+ */
+
+int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int gunzip_main(int argc UNUSED_PARAM, char **argv)
{
- getopt32(argc, argv, "cfvdt");
+ getopt32(argv, "cfvdtn");
argv += optind;
/* if called as zcat */
if (applet_name[1] == 'c')
}
static
-USE_DESKTOP(long long) int unpack_unlzma(void)
+USE_DESKTOP(long long) int unpack_unlzma(unpack_info_t *info UNUSED_PARAM)
{
return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO);
}
-int unlzma_main(int argc, char **argv);
-int unlzma_main(int argc, char **argv)
+int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int unlzma_main(int argc UNUSED_PARAM, char **argv)
{
- getopt32(argc, argv, "c");
+ getopt32(argv, "cf");
argv += optind;
/* lzmacat? */
if (applet_name[4] == 'c')
}
static
-USE_DESKTOP(long long) int unpack_uncompress(void)
+USE_DESKTOP(long long) int unpack_uncompress(unpack_info_t *info UNUSED_PARAM)
{
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);
+ status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO);
}
return status;
}
-int uncompress_main(int argc, char **argv);
-int uncompress_main(int argc, char **argv)
+int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int uncompress_main(int argc UNUSED_PARAM, char **argv)
{
- getopt32(argc, argv, "cf");
+ getopt32(argv, "cf");
argv += optind;
return bbunpack(argv, make_new_name_uncompress, unpack_uncompress);