From 1a9e9bdd93b06508b70bd29ef5eeb82f91d86222 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 1 Nov 2008 12:54:56 +0000 Subject: gunzip: restore mtime. approx +80 bytes of code rpm: make code more robust lsmod: small code shrink --- archival/bbunzip.c | 32 ++++++++++++++++++++++++-------- archival/bzip2.c | 3 ++- archival/gzip.c | 3 ++- archival/libunarchive/decompress_unzip.c | 26 +++++++++++++++++++------- archival/rpm.c | 15 +++++++++------ include/libbb.h | 5 +---- include/unarchive.h | 11 +++++++++++ modutils/lsmod.c | 2 +- 8 files changed, 69 insertions(+), 28 deletions(-) diff --git a/archival/bbunzip.c b/archival/bbunzip.c index c7962058e..75489f2a5 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -30,13 +30,14 @@ int open_to_or_warn(int to_fd, const char *filename, int flags, int mode) 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! */ @@ -92,14 +93,29 @@ int FAST_FUNC 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) */ @@ -159,7 +175,7 @@ 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_prime(STDIN_FILENO, STDOUT_FILENO); } @@ -235,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; @@ -247,7 +263,7 @@ USE_DESKTOP(long long) int unpack_gunzip(void) if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == 0x9d) { status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); } else if (magic2 == 0x8b) { - status = unpack_gz_stream(STDIN_FILENO, STDOUT_FILENO); + status = unpack_gz_stream_with_info(STDIN_FILENO, STDOUT_FILENO, info); } else { goto bad_magic; } @@ -309,7 +325,7 @@ 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); } @@ -344,7 +360,7 @@ 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; diff --git a/archival/bzip2.c b/archival/bzip2.c index 1149cad2a..8eb5ca9ae 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c @@ -8,6 +8,7 @@ */ #include "libbb.h" +#include "unarchive.h" #define CONFIG_BZIP2_FEATURE_SPEED 1 @@ -101,7 +102,7 @@ USE_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, v } static -USE_DESKTOP(long long) int compressStream(void) +USE_DESKTOP(long long) int compressStream(unpack_info_t *info UNUSED_PARAM) { USE_DESKTOP(long long) int total; ssize_t count; diff --git a/archival/gzip.c b/archival/gzip.c index ee051356e..43804b2e4 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -40,6 +40,7 @@ aa: 85.1% -- replaced with aa.gz */ #include "libbb.h" +#include "unarchive.h" /* =========================================================================== @@ -2014,7 +2015,7 @@ char* make_new_name_gzip(char *filename) } static -USE_DESKTOP(long long) int pack_gzip(void) +USE_DESKTOP(long long) int pack_gzip(unpack_info_t *info UNUSED_PARAM) { struct stat s; diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c index f25808a1a..e83cd4f45 100644 --- a/archival/libunarchive/decompress_unzip.c +++ b/archival/libunarchive/decompress_unzip.c @@ -1108,18 +1108,21 @@ static uint32_t buffer_read_le_u32(STATE_PARAM_ONLY) return res; } -static int check_header_gzip(STATE_PARAM_ONLY) +static int check_header_gzip(STATE_PARAM unpack_info_t *info) { union { unsigned char raw[8]; struct { uint8_t gz_method; uint8_t flags; - //uint32_t mtime; - unused fields - //uint8_t xtra_flags; - //uint8_t os_flags; - } formatted; /* packed */ + uint32_t mtime; + uint8_t xtra_flags_UNUSED; + uint8_t os_flags_UNUSED; + } __attribute__((packed)) formatted; } header; + struct BUG_header { + char BUG_header[sizeof(header) == 8 ? 1 : -1]; + }; /* * Rewind bytebuffer. We use the beginning because the header has 8 @@ -1167,6 +1170,9 @@ static int check_header_gzip(STATE_PARAM_ONLY) } } + if (info) + info->mtime = SWAP_LE32(header.formatted.mtime); + /* Read the header checksum */ if (header.formatted.flags & 0x02) { if (!top_up(PASS_STATE 2)) @@ -1177,7 +1183,7 @@ static int check_header_gzip(STATE_PARAM_ONLY) } USE_DESKTOP(long long) int FAST_FUNC -unpack_gz_stream(int in, int out) +unpack_gz_stream_with_info(int in, int out, unpack_info_t *info) { uint32_t v32; USE_DESKTOP(long long) int n; @@ -1192,7 +1198,7 @@ unpack_gz_stream(int in, int out) gunzip_src_fd = in; again: - if (!check_header_gzip(PASS_STATE_ONLY)) { + if (!check_header_gzip(PASS_STATE info)) { bb_error_msg("corrupted data"); n = -1; goto ret; @@ -1239,3 +1245,9 @@ unpack_gz_stream(int in, int out) DEALLOC_STATE; return n; } + +USE_DESKTOP(long long) int FAST_FUNC +unpack_gz_stream(int in, int out) +{ + return unpack_gz_stream_with_info(in, out, NULL); +} diff --git a/archival/rpm.c b/archival/rpm.c index 78568687e..4c36067c4 100644 --- a/archival/rpm.c +++ b/archival/rpm.c @@ -115,8 +115,8 @@ int rpm_main(int argc, char **argv) } } argv += optind; - argc -= optind; - if (!argc) bb_show_usage(); + //argc -= optind; + if (!argv[0]) bb_show_usage(); while (*argv) { rpm_fd = xopen(*argv++, O_RDONLY); @@ -251,7 +251,7 @@ static void extract_cpio_gz(int fd) static rpm_index **rpm_gettags(int fd, int *num_tags) { /* We should never need mode than 200, and realloc later */ - rpm_index **tags = xzalloc(200 * sizeof(struct rpmtag *)); + rpm_index **tags = xzalloc(200 * sizeof(tags[0])); int pass, tagindex = 0; xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */ @@ -265,6 +265,9 @@ static rpm_index **rpm_gettags(int fd, int *num_tags) uint32_t entries; /* Number of entries in header (4 bytes) */ uint32_t size; /* Size of store (4 bytes) */ } header; + struct BUG_header { + char BUG_header[sizeof(header) == 16 ? 1 : -1]; + }; rpm_index *tmpindex; int storepos; @@ -278,8 +281,8 @@ static rpm_index **rpm_gettags(int fd, int *num_tags) storepos = xlseek(fd,0,SEEK_CUR) + header.entries * 16; while (header.entries--) { - tmpindex = tags[tagindex++] = xmalloc(sizeof(rpm_index)); - xread(fd, tmpindex, sizeof(rpm_index)); + tmpindex = tags[tagindex++] = xmalloc(sizeof(*tmpindex)); + xread(fd, tmpindex, sizeof(*tmpindex)); tmpindex->tag = ntohl(tmpindex->tag); tmpindex->type = ntohl(tmpindex->type); tmpindex->count = ntohl(tmpindex->count); @@ -292,7 +295,7 @@ static rpm_index **rpm_gettags(int fd, int *num_tags) if (pass == 0) xlseek(fd, (8 - (xlseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR); } - tags = xrealloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */ + tags = xrealloc(tags, tagindex * sizeof(tags[0])); /* realloc tags to save space */ *num_tags = tagindex; return tags; /* All done, leave the file at the start of the gzipped cpio archive */ } diff --git a/include/libbb.h b/include/libbb.h index 2a8b18336..5b6a2dae1 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -912,10 +912,7 @@ int chown_main(int argc, char **argv) USE_CHOWN(MAIN_EXTERNALLY_VISIBLE); /* Don't need USE_xxx() guard for these */ int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int bbunpack(char **argv, - char* (*make_new_name)(char *filename), - USE_DESKTOP(long long) int (*unpacker)(void) -) FAST_FUNC; + #if ENABLE_ROUTE void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC; #endif diff --git a/include/unarchive.h b/include/unarchive.h index 7ff791be5..9077130a5 100644 --- a/include/unarchive.h +++ b/include/unarchive.h @@ -77,6 +77,12 @@ typedef struct archive_handle_t { } archive_handle_t; +/* Info struct unpackers can fill out to inform users of thing like + * timestamps of unpacked files */ +typedef struct unpack_info_t { + time_t mtime; +} unpack_info_t; + extern archive_handle_t *init_handle(void) FAST_FUNC; extern char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC; @@ -126,10 +132,15 @@ USE_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; /* the rest wants 2 first bytes already skipped by the caller */ USE_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC; USE_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC; +USE_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC; USE_DESKTOP(long long) int unpack_Z_stream(int fd_in, int fd_out) FAST_FUNC; /* wrapper which checks first two bytes to be "BZ" */ USE_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC; +int bbunpack(char **argv, + char* (*make_new_name)(char *filename), + USE_DESKTOP(long long) int (*unpacker)(unpack_info_t *info)) FAST_FUNC; + #if BB_MMU void open_transformer(int fd, USE_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC; diff --git a/modutils/lsmod.c b/modutils/lsmod.c index b66563693..87dd1fcba 100644 --- a/modutils/lsmod.c +++ b/modutils/lsmod.c @@ -46,7 +46,7 @@ int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) #if ENABLE_FEATURE_LSMOD_PRETTY_2_6_OUTPUT char *token[4]; parser_t *parser = config_open("/proc/modules"); - printf("Module Size Used by"); //vda! + printf("%-24sSize Used by", "Module"); check_tainted(); if (ENABLE_FEATURE_2_4_MODULES -- cgit v1.2.3