]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Introduce gzip:timestamp option into gzip write filter to
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 22 Oct 2012 21:22:23 +0000 (06:22 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 22 Oct 2012 21:22:23 +0000 (06:22 +0900)
control recording timestamp.

Makefile.am
libarchive/archive_write_add_filter_gzip.c
libarchive/test/CMakeLists.txt
libarchive/test/test_write_filter_gzip_timestamp.c [new file with mode: 0644]
tar/bsdtar.1

index b37b7b8de9f58e3300ac385b424dfc32b8126d15..e7ddddd3df9cb1b966ebbb406ee20eb3c0f87c94 100644 (file)
@@ -426,6 +426,7 @@ libarchive_test_SOURCES=                                    \
        libarchive/test/test_write_filter_bzip2.c               \
        libarchive/test/test_write_filter_compress.c            \
        libarchive/test/test_write_filter_gzip.c                \
+       libarchive/test/test_write_filter_gzip_timestamp.c      \
        libarchive/test/test_write_filter_lrzip.c               \
        libarchive/test/test_write_filter_lzip.c                \
        libarchive/test/test_write_filter_lzma.c                \
index 7e119b98ff90eb4aa8ce63d0c5930f8b28867ac7..28fd8ebc9ae585ddbf336c89c90f521dbf406c09 100644 (file)
@@ -59,6 +59,7 @@ archive_write_set_compression_gzip(struct archive *a)
 
 struct private_data {
        int              compression_level;
+       int              timestamp;
 #ifdef HAVE_ZLIB_H
        z_stream         stream;
        int64_t          total_in;
@@ -162,6 +163,10 @@ archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
                data->compression_level = value[0] - '0';
                return (ARCHIVE_OK);
        }
+       if (strcmp(key, "timestamp") == 0) {
+               data->timestamp = (value == NULL)?-1:1;
+               return (ARCHIVE_OK);
+       }
 
        /* Note: The "warn" return is just to inform the options
         * supervisor that we didn't handle it.  It will generate
@@ -178,7 +183,6 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
 {
        struct private_data *data = (struct private_data *)f->data;
        int ret;
-       time_t t;
 
        ret = __archive_write_open_filter(f->next_filter);
        if (ret != ARCHIVE_OK)
@@ -210,15 +214,18 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
        data->stream.avail_out = data->compressed_buffer_size;
 
        /* Prime output buffer with a gzip header. */
-       t = time(NULL);
        data->compressed[0] = 0x1f; /* GZip signature bytes */
        data->compressed[1] = 0x8b;
        data->compressed[2] = 0x08; /* "Deflate" compression */
        data->compressed[3] = 0; /* No options */
-       data->compressed[4] = (uint8_t)(t)&0xff;  /* Timestamp */
-       data->compressed[5] = (uint8_t)(t>>8)&0xff;
-       data->compressed[6] = (uint8_t)(t>>16)&0xff;
-       data->compressed[7] = (uint8_t)(t>>24)&0xff;
+       if (data->timestamp >= 0) {
+               time_t t = time(NULL);
+               data->compressed[4] = (uint8_t)(t)&0xff;  /* Timestamp */
+               data->compressed[5] = (uint8_t)(t>>8)&0xff;
+               data->compressed[6] = (uint8_t)(t>>16)&0xff;
+               data->compressed[7] = (uint8_t)(t>>24)&0xff;
+       } else
+               memset(&data->compressed[4], 0, 4);
        data->compressed[8] = 0; /* No deflate options */
        data->compressed[9] = 3; /* OS=Unix */
        data->stream.next_out += 10;
@@ -401,6 +408,31 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
                archive_strcat(&as, " -");
                archive_strappend_char(&as, '0' + data->compression_level);
        }
+       if (data->timestamp < 0)
+               /* Do not save timestamp. */
+               archive_strcat(&as, " -n");
+       else if (data->timestamp > 0)
+               /* Save timestamp. */
+               archive_strcat(&as, " -N");
+
+       f->write = archive_compressor_gzip_write;
+       r = __archive_write_program_open(f, data->pdata, as.s);
+       archive_string_free(&as);
+       return (r);
+}
+
+static int
+archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff,
+    size_t length)
+{
+       struct private_data *data = (struct private_data *)f->data;
+
+       return __archive_write_program_write(f, data->pdata, buff, length);
+}
+
+static int
+archive_compressor_gzip_close(struct archive_write_filter *f)
+{
 
        f->write = archive_compressor_gzip_write;
        r = __archive_write_program_open(f, data->pdata, as.s);
index efbe7b0898fdfd39c7612c53a580b4ff017b2458..346eaf4b2a97082f0a22da74a691c6f17221fb6c 100644 (file)
@@ -161,6 +161,7 @@ IF(ENABLE_TEST)
     test_write_filter_bzip2.c
     test_write_filter_compress.c
     test_write_filter_gzip.c
+    test_write_filter_gzip_timestamp.c
     test_write_filter_lrzip.c
     test_write_filter_lzip.c
     test_write_filter_lzma.c
diff --git a/libarchive/test/test_write_filter_gzip_timestamp.c b/libarchive/test/test_write_filter_gzip_timestamp.c
new file mode 100644 (file)
index 0000000..ce5ebb9
--- /dev/null
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2007 Tim Kientzle
+ * Copyright (c) 2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_write_filter_gzip_timestamp)
+{
+       struct archive_entry *ae;
+       struct archive* a;
+       char *buff, *data;
+       size_t buffsize, datasize;
+       size_t used1;
+       int r, use_prog = 0;
+
+       buffsize = 10000;
+       assert(NULL != (buff = (char *)malloc(buffsize)));
+
+       datasize = 10000;
+       assert(NULL != (data = (char *)malloc(datasize)));
+       memset(data, 0, datasize);
+
+       /* Test1: set "gzip:timestamp" option. */
+       assert((a = archive_write_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+       r = archive_write_add_filter_gzip(a);
+       if (r != ARCHIVE_OK) {
+               if (canGzip() && r == ARCHIVE_WARN)
+                       use_prog = 1;
+               else {
+                       skipping("gzip writing not supported on this platform");
+                       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+                       return;
+               }
+       }
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_write_set_options(a, "gzip:timestamp"));
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_write_set_bytes_per_block(a, 10));
+       assertEqualInt(ARCHIVE_FILTER_GZIP, archive_filter_code(a, 0));
+       assertEqualString("gzip", archive_filter_name(a, 0));
+       assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
+           archive_write_open_memory(a, buff, buffsize, &used1));
+       assert((ae = archive_entry_new()) != NULL);
+       archive_entry_set_filetype(ae, AE_IFREG);
+       archive_entry_set_size(ae, datasize);
+       archive_entry_copy_pathname(ae, "file");
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+       assertEqualIntA(a, datasize, archive_write_data(a, data, datasize));
+       archive_entry_free(ae);
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+       failure("Timestamp should be recorded");
+       assert(memcmp(buff + 4, "\x00\x00\x00\x00", 4) != 0);
+
+       /* Test2: set "gzip:!timestamp" option. */
+       assert((a = archive_write_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+       assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
+           archive_write_add_filter_gzip(a));
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_write_set_options(a, "gzip:!timestamp"));
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_write_set_bytes_per_block(a, 10));
+       assertEqualInt(ARCHIVE_FILTER_GZIP, archive_filter_code(a, 0));
+       assertEqualString("gzip", archive_filter_name(a, 0));
+       assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
+           archive_write_open_memory(a, buff, buffsize, &used1));
+       assert((ae = archive_entry_new()) != NULL);
+       archive_entry_set_filetype(ae, AE_IFREG);
+       archive_entry_set_size(ae, datasize);
+       archive_entry_copy_pathname(ae, "file");
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+       assertEqualIntA(a, datasize, archive_write_data(a, data, datasize));
+       archive_entry_free(ae);
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+       failure("Timestamp should not be recorded");
+       assertEqualMem(buff + 4, "\x00\x00\x00\x00", 4);
+
+       /*
+        * Clean up.
+        */
+       free(data);
+       free(buff);
+}
index 2297c35068e5854d9f42990cbfc133f3f128800a..3fd2d9b3e4cf4a39ec3d8408966a2a64ff29292f 100644 (file)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 22, 2012
+.Dd October 23, 2012
 .Dt TAR 1
 .Os
 .Sh NAME
@@ -472,6 +472,12 @@ or
 to disable.
 .It Cm gzip:compression-level
 A decimal integer from 0 to 9 specifying the gzip compression level.
+.It Cm gzip:timestamp
+Store timestamp. This is enabled by default, use
+.Cm !timestamp
+or
+.Cm gzip:!timestamp
+to disable.
 .It Cm xz:compression-level
 A decimal integer from 0 to 9 specifying the xz compression level.
 .It Cm mtree: Ns Ar keyword