X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=archival%2Fbbunzip.c;h=75489f2a5a96519299c8c0321e5f2f3346547844;hb=4e12b1a2a9e68685dff61acaee1e1f6c377d978c;hp=bd1526b20d863e33f59a9ae606f3bd09931b4f14;hpb=c14d39e83a7f55ab9b92e98673a281fd6565c32d;p=oweals%2Fbusybox.git diff --git a/archival/bbunzip.c b/archival/bbunzip.c index bd1526b20..75489f2a5 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -11,7 +11,7 @@ enum { OPT_STDOUT = 0x1, OPT_FORCE = 0x2, -/* gunzip only: */ +/* gunzip and bunzip2 only: */ OPT_VERBOSE = 0x4, OPT_DECOMPRESS = 0x8, OPT_TEST = 0x10, @@ -28,15 +28,16 @@ int open_to_or_warn(int to_fd, const char *filename, int flags, int mode) 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! */ @@ -49,7 +50,7 @@ int bbunpack(char **argv, /* 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; @@ -73,8 +74,14 @@ int bbunpack(char **argv, 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; @@ -86,14 +93,29 @@ int bbunpack(char **argv, "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) */ @@ -138,7 +160,7 @@ char* make_new_name_generic(char *filename, const char *expected_ext) /* - * Modified for busybox by Glenn McGrath + * Modified for busybox by Glenn McGrath * Added support output to stdout by Thomas Lundquist * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. @@ -153,15 +175,15 @@ char* make_new_name_bunzip2(char *filename) } 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; @@ -185,7 +207,7 @@ int bunzip2_main(int argc, char **argv) * handling. * * General cleanup to better adhere to the style guide and make use of standard - * busybox functions by Glenn McGrath + * busybox functions by Glenn McGrath * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. * @@ -212,8 +234,8 @@ char* make_new_name_gunzip(char *filename) 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'; @@ -229,7 +251,7 @@ char* make_new_name_gunzip(char *filename) } 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; @@ -238,11 +260,10 @@ USE_DESKTOP(long long) int unpack_gunzip(void) 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; } @@ -257,10 +278,24 @@ USE_DESKTOP(long long) int unpack_gunzip(void) 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') @@ -290,15 +325,15 @@ char* make_new_name_unlzma(char *filename) } 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') @@ -325,22 +360,22 @@ char* make_new_name_uncompress(char *filename) } 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);