gunzip: restore mtime. approx +80 bytes of code
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 1 Nov 2008 12:54:56 +0000 (12:54 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 1 Nov 2008 12:54:56 +0000 (12:54 -0000)
rpm: make code more robust
lsmod: small code shrink

archival/bbunzip.c
archival/bzip2.c
archival/gzip.c
archival/libunarchive/decompress_unzip.c
archival/rpm.c
include/libbb.h
include/unarchive.h
modutils/lsmod.c

index c7962058e2594e441b652c0da268d99b99d59c22..75489f2a5a96519299c8c0321e5f2f3346547844 100644 (file)
@@ -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, &times);
+                               }
+
                                /* 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;
 
index 1149cad2a5460e6ccb2f3df99111c87209b2c7d1..8eb5ca9aef43b5d728800e021ac64f3f5767d390 100644 (file)
@@ -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;
index ee051356e5100832769bcb0c752ec0302cb1bf7a..43804b2e4060fd2a0cd447e501595e6338d0df51 100644 (file)
@@ -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;
 
index f25808a1a4848b488e3f9fcc15f894947b7eddda..e83cd4f45254e20f807899362b33a3d5fcedc4dd 100644 (file)
@@ -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);
+}
index 78568687ec68b47af1d991590e469aa7350d3eff..4c36067c4d1a011026ceccb7e6d3ed8ced9f6921 100644 (file)
@@ -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 */
 }
index 2a8b183365fec3f66216b5a99555a5b27f4f0230..5b6a2dae1d2db00a9fd1441632840cbf4931a000 100644 (file)
@@ -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
index 7ff791be532ec21cd5aadf040ed6cc71a7831f7f..9077130a52c948a891f836b41e35c6b2a8794e6a 100644 (file)
@@ -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;
index b6656369306b3e44b56775046e27d36250810db6..87dd1fcba929ae146f9601140d4249f6bf8380a4 100644 (file)
@@ -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