]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add support for grzip compression.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Tue, 9 Oct 2012 23:17:05 +0000 (08:17 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Wed, 10 Oct 2012 01:32:43 +0000 (10:32 +0900)
30 files changed:
Makefile.am
cpio/cmdline.c
cpio/cpio.c
cpio/cpio.h
cpio/test/CMakeLists.txt
cpio/test/main.c
cpio/test/test.h
cpio/test/test_extract.cpio.grz.uu [new file with mode: 0644]
cpio/test/test_extract_cpio_grz.c [new file with mode: 0644]
cpio/test/test_option_grzip.c [new file with mode: 0644]
libarchive/CMakeLists.txt
libarchive/archive.h
libarchive/archive_read_support_filter_all.c
libarchive/archive_read_support_filter_grzip.c [new file with mode: 0644]
libarchive/archive_write_add_filter_grzip.c [new file with mode: 0644]
libarchive/test/CMakeLists.txt
libarchive/test/main.c
libarchive/test/test.h
libarchive/test/test_read_filter_grzip.c [new file with mode: 0644]
libarchive/test/test_read_filter_grzip.tar.grz.uu [new file with mode: 0644]
tar/bsdtar.c
tar/bsdtar.h
tar/cmdline.c
tar/test/CMakeLists.txt
tar/test/main.c
tar/test/test.h
tar/test/test_extract.tar.grz.uu [new file with mode: 0644]
tar/test/test_extract_tar_grz.c [new file with mode: 0644]
tar/test/test_option_grzip.c [new file with mode: 0644]
tar/write.c

index 8814cbe95cd4961e490b1ceb0e95cca8e90a280c..5052643b67f86fbeb0d7fab8878571b026528d1f 100644 (file)
@@ -133,6 +133,7 @@ libarchive_la_SOURCES=                                              \
        libarchive/archive_read_support_filter_all.c            \
        libarchive/archive_read_support_filter_bzip2.c          \
        libarchive/archive_read_support_filter_compress.c       \
+       libarchive/archive_read_support_filter_grzip.c          \
        libarchive/archive_read_support_filter_gzip.c           \
        libarchive/archive_read_support_filter_lrzip.c          \
        libarchive/archive_read_support_filter_lzop.c           \
@@ -174,13 +175,14 @@ libarchive_la_SOURCES=                                            \
        libarchive/archive_write_private.h                      \
        libarchive/archive_write_add_filter.c                   \
        libarchive/archive_write_add_filter_b64encode.c         \
-       libarchive/archive_write_add_filter_bzip2.c     \
-       libarchive/archive_write_add_filter_compress.c  \
+       libarchive/archive_write_add_filter_bzip2.c             \
+       libarchive/archive_write_add_filter_compress.c          \
+       libarchive/archive_write_add_filter_grzip.c             \
        libarchive/archive_write_add_filter_gzip.c              \
        libarchive/archive_write_add_filter_lrzip.c             \
        libarchive/archive_write_add_filter_lzop.c              \
        libarchive/archive_write_add_filter_none.c              \
-       libarchive/archive_write_add_filter_program.c   \
+       libarchive/archive_write_add_filter_program.c           \
        libarchive/archive_write_add_filter_uuencode.c          \
        libarchive/archive_write_add_filter_xz.c                \
        libarchive/archive_write_set_format.c                   \
@@ -334,11 +336,12 @@ libarchive_test_SOURCES=                                  \
        libarchive/test/test_read_disk_entry_from_file.c        \
        libarchive/test/test_read_extract.c                     \
        libarchive/test/test_read_file_nonexistent.c            \
+       libarchive/test/test_read_filter_grzip.c                \
+       libarchive/test/test_read_filter_lrzip.c                \
+       libarchive/test/test_read_filter_lzop.c                 \
        libarchive/test/test_read_filter_program.c              \
        libarchive/test/test_read_filter_program_signature.c    \
        libarchive/test/test_read_filter_uudecode.c             \
-       libarchive/test/test_read_filter_lrzip.c                \
-       libarchive/test/test_read_filter_lzop.c                 \
        libarchive/test/test_read_format_7zip.c                 \
        libarchive/test/test_read_format_ar.c                   \
        libarchive/test/test_read_format_cab.c                  \
@@ -511,6 +514,7 @@ libarchive_test_EXTRA_DIST=\
        libarchive/test/test_rar_multivolume_single_file.part1.rar.uu   \
        libarchive/test/test_rar_multivolume_single_file.part2.rar.uu   \
        libarchive/test/test_rar_multivolume_single_file.part3.rar.uu   \
+       libarchive/test/test_read_filter_grzip.tar.grz.uu               \
        libarchive/test/test_read_filter_lrzip.tar.lrz.uu               \
        libarchive/test/test_read_filter_lzop.tar.lzo.uu                \
        libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu           \
@@ -713,6 +717,7 @@ bsdtar_test_SOURCES=                                                \
        tar/test/test_empty_mtree.c                             \
        tar/test/test_extract_tar_Z.c                           \
        tar/test/test_extract_tar_bz2.c                         \
+       tar/test/test_extract_tar_grz.c                         \
        tar/test/test_extract_tar_gz.c                          \
        tar/test/test_extract_tar_lrz.c                         \
        tar/test/test_extract_tar_lz.c                          \
@@ -732,6 +737,7 @@ bsdtar_test_SOURCES=                                                \
        tar/test/test_option_b64encode.c                        \
        tar/test/test_option_exclude.c                          \
        tar/test/test_option_gid_gname.c                        \
+       tar/test/test_option_grzip.c                            \
        tar/test/test_option_k.c                                \
        tar/test/test_option_keep_newer_files.c                 \
        tar/test/test_option_lrzip.c                            \
@@ -776,6 +782,7 @@ bsdtar_test_EXTRA_DIST=                     \
        tar/test/list.h \
        tar/test/test_extract.tar.Z.uu   \
        tar/test/test_extract.tar.bz2.uu \
+       tar/test/test_extract.tar.grz.uu \
        tar/test/test_extract.tar.gz.uu  \
        tar/test/test_extract.tar.lrz.uu \
        tar/test/test_extract.tar.lz.uu  \
@@ -855,6 +862,7 @@ bsdcpio_test_SOURCES=                                               \
        cpio/test/test_cmdline.c                                \
        cpio/test/test_extract_cpio_Z.c                         \
        cpio/test/test_extract_cpio_bz2.c                       \
+       cpio/test/test_extract_cpio_grz.c                       \
        cpio/test/test_extract_cpio_gz.c                        \
        cpio/test/test_extract_cpio_lrz.c                       \
        cpio/test/test_extract_cpio_lz.c                        \
@@ -874,6 +882,7 @@ bsdcpio_test_SOURCES=                                               \
        cpio/test/test_option_c.c                               \
        cpio/test/test_option_d.c                               \
        cpio/test/test_option_f.c                               \
+       cpio/test/test_option_grzip.c                           \
        cpio/test/test_option_help.c                            \
        cpio/test/test_option_l.c                               \
        cpio/test/test_option_lrzip.c                           \
@@ -913,6 +922,7 @@ bsdcpio_test_EXTRA_DIST=                    \
        cpio/test/list.h        \
        cpio/test/test_extract.cpio.Z.uu        \
        cpio/test/test_extract.cpio.bz2.uu      \
+       cpio/test/test_extract.cpio.grz.uu      \
        cpio/test/test_extract.cpio.gz.uu       \
        cpio/test/test_extract.cpio.lrz.uu      \
        cpio/test/test_extract.cpio.lz.uu       \
index 3dff0b6b377aff034872c831b4e0f976aa53d335..0121fd13937fd600f7fbd18930644cf290b9ae36 100644 (file)
@@ -67,6 +67,7 @@ static const struct option {
        { "extract",                    0, 'i' },
        { "file",                       1, 'F' },
        { "format",                     1, 'H' },
+       { "grzip",                      0, OPTION_GRZIP },
        { "help",                       0, 'h' },
        { "insecure",                   0, OPTION_INSECURE },
        { "link",                       0, 'l' },
index 89fc25bd08a4282f3c35e33b1e8f1270a1408e52..95e8e0806ce70f999dd3d8ea9ac370dbf4945796 100644 (file)
@@ -237,6 +237,9 @@ main(int argc, char *argv[])
                                lafe_errc(1, 0, "Error : %s",
                                    archive_error_string(cpio->matching));
                        break;
+               case OPTION_GRZIP:
+                       cpio->compress = opt;
+                       break;
                case 'H': /* GNU cpio (also --format) */
                        cpio->format = cpio->argument;
                        break;
@@ -525,6 +528,9 @@ mode_out(struct cpio *cpio)
        if (cpio->archive == NULL)
                lafe_errc(1, 0, "Failed to allocate archive object");
        switch (cpio->compress) {
+       case OPTION_GRZIP:
+               r = archive_write_add_filter_grzip(cpio->archive);
+               break;
        case 'J':
                r = archive_write_add_filter_xz(cpio->archive);
                break;
index b1d89427fa0e2da0babf3011ae7fdffdd14c54c5..3e951ce7403e25031c0bb4c7df3d28de26cd320b 100644 (file)
@@ -98,6 +98,7 @@ const char *owner_parse(const char *, int *, int *);
 /* Fake short equivalents for long options that otherwise lack them. */
 enum {
        OPTION_B64ENCODE = 1,
+       OPTION_GRZIP,
        OPTION_INSECURE,
        OPTION_LRZIP,
        OPTION_LZMA,
index 3713cd3d8fcaa6eeeddda05327624c6de7ff48d9..09ca2c7d96b3c19f6de197b0647b9abc3839b472 100644 (file)
@@ -15,6 +15,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
     test_cmdline.c
     test_extract_cpio_Z
     test_extract_cpio_bz2
+    test_extract_cpio_grz
     test_extract_cpio_gz
     test_extract_cpio_lrz
     test_extract_cpio_lz
@@ -34,6 +35,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
     test_option_c.c
     test_option_d.c
     test_option_f.c
+    test_option_grzip.c
     test_option_help.c
     test_option_l.c
     test_option_lrzip.c
index 12dc0cebd31695128bde68a445599a9d25eebcb6..1eb15ac10e0f69502a8b61095c01cb4adb94c8ac 100644 (file)
@@ -1887,6 +1887,21 @@ canGunzip(void)
        return (value);
 }
 
+/*
+ * Can this platform run the grzip program?
+ */
+int
+canGrzip(void)
+{
+       static int tested = 0, value = 0;
+       if (!tested) {
+               tested = 1;
+               if (systemf("grzip -V %s", redirectArgs) == 0)
+                       value = 1;
+       }
+       return (value);
+}
+
 /*
  * Can this platform run the lrzip program?
  */
index 01f902ef29d261a5d487f149a3834a9a93776dac..e218a155f8568e9b6894f825e2a169e70aa84669 100644 (file)
@@ -275,6 +275,9 @@ int canGzip(void);
 /* Return true if this platform can run the "gunzip" program. */
 int canGunzip(void);
 
+/* Return true if this platform can run the "grzip" program. */
+int canGrzip(void);
+
 /* Return true if this platform can run the "lrzip" program. */
 int canLrzip(void);
 
diff --git a/cpio/test/test_extract.cpio.grz.uu b/cpio/test/test_extract.cpio.grz.uu
new file mode 100644 (file)
index 0000000..19045a9
--- /dev/null
@@ -0,0 +1,7 @@
+begin 644 test_extract.cpio.grz
+M1U)::7!)20`"!#HI``(``*P-```&`0``"````&X````B%2.02C`PK`#__..F
+MI;8=99?N!6`:IQJ:XU/T"`W`B"?N/D9-0K6VN/D\.2>0,#J&)3G"\^YE?X_'
+M_K._F':0[`DL%IQ=<,Z-JH>V$S,?.[`&42C7]J^XQ@9OY!Z$!$^JLQPKZU[:
+/!M,+.$MY:Y(HS<<]U`&`
+`
+end
diff --git a/cpio/test/test_extract_cpio_grz.c b/cpio/test/test_extract_cpio_grz.c
new file mode 100644 (file)
index 0000000..f1a0805
--- /dev/null
@@ -0,0 +1,48 @@
+/*-
+ * 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.
+ * 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_extract_cpio_grz)
+{
+       const char *reffile = "test_extract.cpio.grz";
+       int f;
+
+       extract_reference_file(reffile);
+       f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
+       if (f == 0 || canGrzip()) {
+               assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
+                   testprog, reffile));
+
+               assertFileExists("file1");
+               assertTextFileContents("contents of file1.\n", "file1");
+               assertFileExists("file2");
+               assertTextFileContents("contents of file2.\n", "file2");
+               assertEmptyFile("test.out");
+               assertTextFileContents("1 block\n", "test.err");
+       } else {
+               skipping("It seems grzip is not supported on this platform");
+       }
+}
diff --git a/cpio/test/test_option_grzip.c b/cpio/test/test_option_grzip.c
new file mode 100644 (file)
index 0000000..dfce2e0
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2003-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.
+ * 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_option_grzip)
+{
+       char *p;
+       size_t s;
+
+       if (!canGrzip()) {
+               skipping("grzip is not supported on this platform");
+               return;
+       }
+
+       /* Create a file. */
+       assertMakeFile("f", 0644, "a");
+
+       /* Archive it with grzip compression. */
+       assertEqualInt(0,
+           systemf("echo f | %s -o --grzip >archive.out 2>archive.err",
+           testprog));
+       p = slurpfile(&s, "archive.err");
+       p[s] = '\0';
+       /* Check that the archive file has an grzip signature. */
+       p = slurpfile(&s, "archive.out");
+       assert(s > 2);
+       assertEqualMem(p, "GRZipII\x00\x02\x04:)", 12);
+}
index 3f0709e442173674ae07bb514a5b929ae21dd680..4bdb648e19dd12fabf201ee4c42637969583796d 100644 (file)
@@ -58,6 +58,7 @@ SET(libarchive_SOURCES
   archive_read_support_filter_bzip2.c
   archive_read_support_filter_compress.c
   archive_read_support_filter_gzip.c
+  archive_read_support_filter_grzip.c
   archive_read_support_filter_lrzip.c
   archive_read_support_filter_lzop.c
   archive_read_support_filter_none.c
@@ -100,6 +101,7 @@ SET(libarchive_SOURCES
   archive_write_add_filter_b64encode.c
   archive_write_add_filter_bzip2.c
   archive_write_add_filter_compress.c
+  archive_write_add_filter_grzip.c
   archive_write_add_filter_gzip.c
   archive_write_add_filter_lrzip.c
   archive_write_add_filter_lzop.c
index 53afb847cfd4eb13b6cf4316cace4e043df0481d..dd3e1906a00d08a8535f7c7899201d676b5a15be 100644 (file)
@@ -222,6 +222,7 @@ typedef int archive_switch_callback(struct archive *, void *_client_data1,
 #define        ARCHIVE_FILTER_LZIP     9
 #define        ARCHIVE_FILTER_LRZIP    10
 #define        ARCHIVE_FILTER_LZOP     11
+#define        ARCHIVE_FILTER_GRZIP    12
 
 #if ARCHIVE_VERSION_NUMBER < 4000000
 #define        ARCHIVE_COMPRESSION_NONE        ARCHIVE_FILTER_NONE
@@ -339,6 +340,7 @@ __LA_DECL int archive_read_support_filter_all(struct archive *);
 __LA_DECL int archive_read_support_filter_bzip2(struct archive *);
 __LA_DECL int archive_read_support_filter_compress(struct archive *);
 __LA_DECL int archive_read_support_filter_gzip(struct archive *);
+__LA_DECL int archive_read_support_filter_grzip(struct archive *);
 __LA_DECL int archive_read_support_filter_lrzip(struct archive *);
 __LA_DECL int archive_read_support_filter_lzip(struct archive *);
 __LA_DECL int archive_read_support_filter_lzma(struct archive *);
@@ -633,6 +635,7 @@ __LA_DECL int archive_write_add_filter(struct archive *, int filter_code);
 __LA_DECL int archive_write_add_filter_b64encode(struct archive *);
 __LA_DECL int archive_write_add_filter_bzip2(struct archive *);
 __LA_DECL int archive_write_add_filter_compress(struct archive *);
+__LA_DECL int archive_write_add_filter_grzip(struct archive *);
 __LA_DECL int archive_write_add_filter_gzip(struct archive *);
 __LA_DECL int archive_write_add_filter_lrzip(struct archive *);
 __LA_DECL int archive_write_add_filter_lzip(struct archive *);
index dcd77032524963119400ae1f11e030c19770037e..d38f1122a461665955c09c4486c8ffd5f5c23aae 100644 (file)
@@ -63,10 +63,12 @@ archive_read_support_filter_all(struct archive *a)
        archive_read_support_filter_uu(a);
        /* The decode code doesn't use an outside library. */
        archive_read_support_filter_rpm(a);
-       /* The decode code always uses "lrzip -d" command-line. */
+       /* The decode code always uses "lrzip -q -d" command-line. */
        archive_read_support_filter_lrzip(a);
        /* The decode code always uses "lzop -d" command-line. */
        archive_read_support_filter_lzop(a);
+       /* The decode code always uses "grzip -d" command-line. */
+       archive_read_support_filter_grzip(a);
 
        /* Note: We always return ARCHIVE_OK here, even if some of the
         * above return ARCHIVE_WARN.  The intent here is to enable
diff --git a/libarchive/archive_read_support_filter_grzip.c b/libarchive/archive_read_support_filter_grzip.c
new file mode 100644 (file)
index 0000000..7a132ab
--- /dev/null
@@ -0,0 +1,119 @@
+/*-
+ * 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.
+ * 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 "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+static const unsigned char grzip_magic[] = {
+       0x47, 0x52, 0x5a, 0x69, 0x70, 0x49, 0x49, 0x00,
+       0x02, 0x04, 0x3a, 0x29 };
+
+static int     grzip_bidder_bid(struct archive_read_filter_bidder *,
+                   struct archive_read_filter *);
+static int     grzip_bidder_init(struct archive_read_filter *);
+
+
+static int
+grzip_reader_free(struct archive_read_filter_bidder *self)
+{
+       (void)self; /* UNUSED */
+       return (ARCHIVE_OK);
+}
+
+int
+archive_read_support_filter_grzip(struct archive *_a)
+{
+       struct archive_read *a = (struct archive_read *)_a;
+       struct archive_read_filter_bidder *reader;
+
+       archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+           ARCHIVE_STATE_NEW, "archive_read_support_filter_grzip");
+
+       if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
+               return (ARCHIVE_FATAL);
+
+       reader->data = NULL;
+       reader->bid = grzip_bidder_bid;
+       reader->init = grzip_bidder_init;
+       reader->options = NULL;
+       reader->free = grzip_reader_free;
+       /* This filter always uses an external program. */
+       return (ARCHIVE_WARN);
+}
+
+/*
+ * Bidder just verifies the header and returns the number of verified bits.
+ */
+static int
+grzip_bidder_bid(struct archive_read_filter_bidder *self,
+    struct archive_read_filter *filter)
+{
+       const unsigned char *p;
+       ssize_t avail;
+
+       (void)self; /* UNUSED */
+
+       p = __archive_read_filter_ahead(filter, sizeof(grzip_magic), &avail);
+       if (p == NULL || avail == 0)
+               return (0);
+
+       if (memcmp(p, grzip_magic, sizeof(grzip_magic)))
+               return (0);
+
+       return (sizeof(grzip_magic) * 8);
+}
+
+static int
+grzip_bidder_init(struct archive_read_filter *self)
+{
+       int r;
+
+       r = __archive_read_programl(self, "grzip", "grzip", "-d", NULL);
+       /* Note: We set the format here even if __archive_read_programl()
+        * above fails.  We do, after all, know what the format is
+        * even if we weren't able to read it. */
+       self->code = ARCHIVE_FILTER_GRZIP;
+       self->name = "grzip";
+       return (r);
+}
diff --git a/libarchive/archive_write_add_filter_grzip.c b/libarchive/archive_write_add_filter_grzip.c
new file mode 100644 (file)
index 0000000..6c0478c
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * 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.
+ * 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 "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+#include "archive.h"
+#include "archive_write_private.h"
+
+int
+archive_write_add_filter_grzip(struct archive *a)
+{
+       char * const argv[] = { "grzip", NULL };
+       int r;
+
+       r = __archive_write_programv(a, "grzip", ARCHIVE_FILTER_GRZIP,
+               "grzip", argv);
+       if (r == ARCHIVE_OK)
+               /* This filter always uses an external program. */
+               r = ARCHIVE_WARN;
+       return (r);
+}
index 54e5bda7a2a99ed3ed527d6a54c34826612bab9a..e6471c714a6aed371472a68426592fce8fce81b4 100644 (file)
@@ -75,11 +75,12 @@ IF(ENABLE_TEST)
     test_read_disk_entry_from_file.c
     test_read_extract.c
     test_read_file_nonexistent.c
+    test_read_filter_grzip.c
+    test_read_filter_lrzip.c
+    test_read_filter_lzop.c
     test_read_filter_program.c
     test_read_filter_program_signature.c
     test_read_filter_uudecode.c
-    test_read_filter_lrzip.c
-    test_read_filter_lzop.c
     test_read_format_7zip.c
     test_read_format_ar.c
     test_read_format_cab.c
index 1f2a733deb2538b0edf4a44eb706e9da959019c5..ac77c7d58ec0c690cfc1ab7b0aeea00ac3322727 100644 (file)
@@ -1885,6 +1885,21 @@ canGunzip(void)
        return (value);
 }
 
+/*
+ * Can this platform run the grzip program?
+ */
+int
+canGrzip(void)
+{
+       static int tested = 0, value = 0;
+       if (!tested) {
+               tested = 1;
+               if (systemf("grzip -V %s", redirectArgs) == 0)
+                       value = 1;
+       }
+       return (value);
+}
+
 /*
  * Can this platform run the lrzip program?
  */
index bdd10672f2e962c857f0fca69ce7cefe825788fb..22942861e05151f01743135e225e49b030b719d5 100644 (file)
@@ -275,6 +275,9 @@ int canGzip(void);
 /* Return true if this platform can run the "gunzip" program. */
 int canGunzip(void);
 
+/* Return true if this platform can run the "grzip" program. */
+int canGrzip(void);
+
 /* Return true if this platform can run the "lrzip" program. */
 int canLrzip(void);
 
diff --git a/libarchive/test/test_read_filter_grzip.c b/libarchive/test/test_read_filter_grzip.c
new file mode 100644 (file)
index 0000000..43bd5bc
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2003-2008 Tim Kientzle
+ * 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.
+ * 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"
+
+DEFINE_TEST(test_read_filter_grzip)
+{
+       const char *name = "test_read_filter_grzip.tar.grz";
+       /* grzip tracks directories as files, ensure that we list everything */
+       const char *n[] = {
+               "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL };
+       struct archive_entry *ae;
+       struct archive *a;
+       int i;
+
+       if (!canGrzip()) {
+               skipping("grzip command-line program not found");
+               return;
+       }
+
+       assert((a = archive_read_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_WARN, archive_read_support_filter_grzip(a));
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+       extract_reference_file(name);
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_read_open_filename(a, name, 200));
+
+       /* Read entries, match up names with list above. */
+       for (i = 0; n[i] != NULL; ++i) {
+               failure("Could not read file %d (%s) from %s", i, n[i], name);
+               assertEqualIntA(a, ARCHIVE_OK,
+                   archive_read_next_header(a, &ae));
+               assertEqualString(n[i], archive_entry_pathname(ae));
+       }
+
+       /* Verify the end-of-archive. */
+       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+       /* Verify that the format detection worked. */
+       assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_GRZIP);
+       assertEqualString(archive_filter_name(a, 0), "grzip");
+       assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
+
+       assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
diff --git a/libarchive/test/test_read_filter_grzip.tar.grz.uu b/libarchive/test/test_read_filter_grzip.tar.grz.uu
new file mode 100644 (file)
index 0000000..3f55b93
--- /dev/null
@@ -0,0 +1,8 @@
+begin 644 test_read_filter_grzip.tar.grz
+M1U)::7!)20`"!#HI`!P``*P,```L`0``\````)D```#Y.$+F+B8PQP#^C=PP
+MI/#7H?$H,(_!0<=O!,4![T/;;'S,=B0_3(R1=9"=YKA%RKR-\,+PJIO2]!<!
+M\AP!@LM2^Y59+2"@**HBJMM-,M/UUOG7-KT;%6Y,M._"A*:Y_5*;A$^'S)81
+M+PF_/.REK[0F--T(I>I*2V31X]P[DN$GO</@P&.SJM'XHUSE;!A$5;1_%%ET
+-?<[O4AO)SBUM$I^[````
+`
+end
index 2b572315f4dcc1ae4a6b717d35e815a64a2406a3..7f19d837620a28ddad64ffcd718c0b8b6a560f62 100644 (file)
@@ -315,6 +315,13 @@ main(int argc, char **argv)
                case OPTION_GNAME: /* cpio */
                        bsdtar->gname = bsdtar->argument;
                        break;
+               case OPTION_GRZIP:
+                       if (bsdtar->create_compression != '\0')
+                               lafe_errc(1, 0,
+                                   "Can't specify both -%c and -%c", opt,
+                                   bsdtar->create_compression);
+                       bsdtar->create_compression = opt;
+                       break;
                case 'H': /* BSD convention */
                        bsdtar->symlink_mode = 'H';
                        break;
index 80e922ea2be95096cb25ba40e775b4adce7dc920..a21be3d0d0b82d8a61cde1101d08e5094027976f 100644 (file)
@@ -120,6 +120,7 @@ enum {
        OPTION_FORMAT,
        OPTION_GID,
        OPTION_GNAME,
+       OPTION_GRZIP,
        OPTION_HELP,
        OPTION_INCLUDE,
        OPTION_KEEP_NEWER_FILES,
index 684e28bfda7840681c426ca0b4e32da8cc42310c..e658ec8673182e840826c2b062906319eed80261 100644 (file)
@@ -88,6 +88,7 @@ static const struct bsdtar_option {
        { "format",               1, OPTION_FORMAT },
        { "gid",                  1, OPTION_GID },
        { "gname",                1, OPTION_GNAME },
+       { "grzip",                0, OPTION_GRZIP },
        { "gunzip",               0, 'z' },
        { "gzip",                 0, 'z' },
        { "help",                 0, OPTION_HELP },
index c14baf0a8a5bba9f10d77dd1994cf7095067f27f..1f6c5ca50e554495c187615dc5bc23d476f35c66 100644 (file)
@@ -14,6 +14,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
     test_empty_mtree.c
     test_extract_tar_Z.c
     test_extract_tar_bz2.c
+    test_extract_tar_grz.c
     test_extract_tar_gz.c
     test_extract_tar_lrz.c
     test_extract_tar_lz.c
@@ -33,6 +34,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
     test_option_b64encode.c
     test_option_exclude.c
     test_option_gid_gname.c
+    test_option_grzip.c
     test_option_k.c
     test_option_keep_newer_files.c
     test_option_lrzip.c
index 28275065a96c6aaea5bebb5837b5b76508fd7c5d..ccf83ba20c2bf7c9d56ab8bdb7206f5bdd9a0e9c 100644 (file)
@@ -1887,6 +1887,21 @@ canGunzip(void)
        return (value);
 }
 
+/*
+ * Can this platform run the grzip program?
+ */
+int
+canGrzip(void)
+{
+       static int tested = 0, value = 0;
+       if (!tested) {
+               tested = 1;
+               if (systemf("grzip -V %s", redirectArgs) == 0)
+                       value = 1;
+       }
+       return (value);
+}
+
 /*
  * Can this platform run the lrzip program?
  */
index 49fe9d97fb139c53244f4e8f5bc9da17bcca875c..36ff42e08df2a5236caf3c9df112639a8641768c 100644 (file)
@@ -277,6 +277,9 @@ int canGzip(void);
 /* Return true if this platform can run the "gunzip" program. */
 int canGunzip(void);
 
+/* Return true if this platform can run the "grzip" program. */
+int canGrzip(void);
+
 /* Return true if this platform can run the "lrzip" program. */
 int canLrzip(void);
 
diff --git a/tar/test/test_extract.tar.grz.uu b/tar/test/test_extract.tar.grz.uu
new file mode 100644 (file)
index 0000000..44651e1
--- /dev/null
@@ -0,0 +1,7 @@
+begin 644 test_extract.tar.grz
+M1U)::7!)20`"!#HI``P``*P,``#U````SP```'<````[-=0OM"R^UP#^C?Z<
+MFGU0]I:>SW7]H01)1\WY:59("M_=V4[N[R*'`H&:'E=O@5B(?T,0?@)%-:_D
+M;EUP)!JVN)@V_:ABYS3+[[6/R(NU,-::]'X&;,]:,HR[*3#R!@:W)IGC`,&G
+8L+IZ7]FP=8U_R?CZ2XPO)"H-ME3@P]$`
+`
+end
diff --git a/tar/test/test_extract_tar_grz.c b/tar/test/test_extract_tar_grz.c
new file mode 100644 (file)
index 0000000..9c0615e
--- /dev/null
@@ -0,0 +1,48 @@
+/*-
+ * 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.
+ * 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_extract_tar_grz)
+{
+       const char *reffile = "test_extract.tar.grz";
+       int f;
+
+       extract_reference_file(reffile);
+       f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile);
+       if (f == 0 || canGrzip()) {
+               assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err",
+                   testprog, reffile));
+
+               assertFileExists("file1");
+               assertTextFileContents("contents of file1.\n", "file1");
+               assertFileExists("file2");
+               assertTextFileContents("contents of file2.\n", "file2");
+               assertEmptyFile("test.out");
+               assertEmptyFile("test.err");
+       } else {
+               skipping("It seems grzip is not supported on this platform");
+       }
+}
diff --git a/tar/test/test_option_grzip.c b/tar/test/test_option_grzip.c
new file mode 100644 (file)
index 0000000..5132eee
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2003-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.
+ * 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_option_grzip)
+{
+       char *p;
+       size_t s;
+
+       if (!canGrzip()) {
+               skipping("grzip is not supported on this platform");
+               return;
+       }
+
+       /* Create a file. */
+       assertMakeFile("f", 0644, "a");
+
+       /* Archive it with grzip compression. */
+       assertEqualInt(0,
+           systemf("%s -cf - --grzip f >archive.out 2>archive.err",
+           testprog));
+       p = slurpfile(&s, "archive.err");
+       p[s] = '\0';
+       /* Check that the archive file has an grzip signature. */
+       p = slurpfile(&s, "archive.out");
+       assert(s > 2);
+       assertEqualMem(p, "GRZipII\x00\x02\x04:)", 12);
+}
index b6e1c58ff94f713e22dd687a273ade846475b13a..077f3625dff764de09795ecc78d3eefa87a2e7c0 100644 (file)
@@ -174,6 +174,9 @@ tar_mode_c(struct bsdtar *bsdtar)
                case 0:
                        r = ARCHIVE_OK;
                        break;
+               case OPTION_GRZIP:
+                       r = archive_write_add_filter_grzip(a);
+                       break;
                case 'j': case 'y':
                        r = archive_write_add_filter_bzip2(a);
                        break;