]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add support for lzop.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sun, 7 Oct 2012 02:08:12 +0000 (11:08 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sun, 7 Oct 2012 03:08:31 +0000 (12:08 +0900)
30 files changed:
Makefile.am
cpio/bsdcpio.1
cpio/cmdline.c
cpio/cpio.c
cpio/cpio.h
cpio/test/CMakeLists.txt
cpio/test/main.c
cpio/test/test.h
cpio/test/test_option_lzop.c [new file with mode: 0644]
libarchive/CMakeLists.txt
libarchive/archive.h
libarchive/archive_read_private.h
libarchive/archive_read_support_filter_all.c
libarchive/archive_read_support_filter_lzop.c [new file with mode: 0644]
libarchive/archive_write_add_filter_lzop.c [new file with mode: 0644]
libarchive/test/CMakeLists.txt
libarchive/test/main.c
libarchive/test/test.h
libarchive/test/test_read_filter_lzop.c [new file with mode: 0644]
libarchive/test/test_read_filter_lzop.tar.lzo.uu [new file with mode: 0644]
libarchive/test/test_write_compress_lzop.c [new file with mode: 0644]
tar/bsdtar.1
tar/bsdtar.c
tar/bsdtar.h
tar/cmdline.c
tar/test/CMakeLists.txt
tar/test/main.c
tar/test/test.h
tar/test/test_option_lzop.c [new file with mode: 0644]
tar/write.c

index 43e6180cb30bb41d10e1659feabc43b784149e6c..a1310d6d3b52f561eb843f5ce654add12965a959 100644 (file)
@@ -135,6 +135,7 @@ libarchive_la_SOURCES=                                              \
        libarchive/archive_read_support_filter_compress.c       \
        libarchive/archive_read_support_filter_gzip.c           \
        libarchive/archive_read_support_filter_lrzip.c          \
+       libarchive/archive_read_support_filter_lzop.c           \
        libarchive/archive_read_support_filter_none.c           \
        libarchive/archive_read_support_filter_program.c        \
        libarchive/archive_read_support_filter_rpm.c            \
@@ -176,6 +177,7 @@ libarchive_la_SOURCES=                                              \
        libarchive/archive_write_add_filter_compress.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_xz.c                \
@@ -333,6 +335,7 @@ libarchive_test_SOURCES=                                    \
        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_lzop.c                 \
        libarchive/test/test_read_format_7zip.c                 \
        libarchive/test/test_read_format_ar.c                   \
        libarchive/test/test_read_format_cab.c                  \
@@ -403,6 +406,7 @@ libarchive_test_SOURCES=                                    \
        libarchive/test/test_write_compress_lrzip.c             \
        libarchive/test/test_write_compress_lzip.c              \
        libarchive/test/test_write_compress_lzma.c              \
+       libarchive/test/test_write_compress_lzop.c              \
        libarchive/test/test_write_compress_program.c           \
        libarchive/test/test_write_compress_xz.c                \
        libarchive/test/test_write_disk.c                       \
@@ -502,6 +506,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_lzop.tar.lzo.uu                \
        libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu           \
        libarchive/test/test_read_format_7zip_bcj_copy.7z.uu            \
        libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu         \
@@ -720,6 +725,7 @@ bsdtar_test_SOURCES=                                                \
        tar/test/test_option_gid_gname.c                        \
        tar/test/test_option_k.c                                \
        tar/test/test_option_keep_newer_files.c                 \
+       tar/test/test_option_lzop.c                             \
        tar/test/test_option_n.c                                \
        tar/test/test_option_newer_than.c                       \
        tar/test/test_option_nodump.c                           \
@@ -841,6 +847,7 @@ bsdcpio_test_SOURCES=                                               \
        cpio/test/test_option_help.c                            \
        cpio/test/test_option_l.c                               \
        cpio/test/test_option_lzma.c                            \
+       cpio/test/test_option_lzop.c                            \
        cpio/test/test_option_m.c                               \
        cpio/test/test_option_t.c                               \
        cpio/test/test_option_u.c                               \
index 5611b20e9aea117000fbd32bd304ac043ff33ba2..05f79d26ca3102c4293b14a368393692fc39eb51 100644 (file)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd December 24, 2011
+.Dd October 7, 2012
 .Dt CPIO 1
 .Os
 .Sh NAME
@@ -181,6 +181,11 @@ instead of copying.
 Compress the file with lzma-compatible compression before writing it.
 In input mode, this option is ignored; lzma compression is recognized
 automatically on input.
+.It Fl Fl lzop
+(o mode only)
+Compress the resulting archive with
+.Xr lzop 1 .
+In input mode, this option is ignored.
 .It Fl m , Fl Fl preserve-modification-time
 (i and p modes)
 Set file modification time on created files to match
index 438c27cf6a7703d6f91175bbfe50c7e4ab5292d0..91f6e1c486bd19031d8125152a7d9e9f56d6ff63 100644 (file)
@@ -71,6 +71,7 @@ static const struct option {
        { "link",                       0, 'l' },
        { "list",                       0, 't' },
        { "lzma",                       0, OPTION_LZMA },
+       { "lzop",                       0, OPTION_LZOP },
        { "make-directories",           0, 'd' },
        { "no-preserve-owner",          0, OPTION_NO_PRESERVE_OWNER },
        { "null",                       0, '0' },
index 21c77d0b1f7a78bb59ea5b2a063d8c4bc989f93a..db342318b535e6d2719e11b185f9a4ba3045a21a 100644 (file)
@@ -266,6 +266,7 @@ main(int argc, char *argv[])
                        cpio->option_link = 1;
                        break;
                case OPTION_LZMA: /* GNU tar, others */
+               case OPTION_LZOP: /* GNU tar, others */
                        cpio->compress = opt;
                        break;
                case 'm': /* POSIX 1997 */
@@ -523,6 +524,9 @@ mode_out(struct cpio *cpio)
        case OPTION_LZMA:
                r = archive_write_set_compression_lzma(cpio->archive);
                break;
+       case OPTION_LZOP:
+               r = archive_write_add_filter_lzop(cpio->archive);
+               break;
        case 'j': case 'y':
                r = archive_write_set_compression_bzip2(cpio->archive);
                break;
index 7e276bdbaf7921337978e309be4bd3161f7cc44b..af7ef8a893afd965e6370d29950d301e409dfdd8 100644 (file)
@@ -98,6 +98,7 @@ const char *owner_parse(const char *, int *, int *);
 enum {
        OPTION_INSECURE = 1,
        OPTION_LZMA,
+       OPTION_LZOP,
        OPTION_NO_PRESERVE_OWNER,
        OPTION_PRESERVE_OWNER,
        OPTION_QUIET,
index 662316425d938956f34e4880c6b7da6e08b4a05a..30aa9766e21bf6a1e23d7186ce8618efa2630274 100644 (file)
@@ -28,6 +28,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
     test_option_help.c
     test_option_l.c
     test_option_lzma.c
+    test_option_lzop.c
     test_option_m.c
     test_option_t.c
     test_option_u.c
index 36867725a6ac5f5c5333ece939707d1b73b2f183..12dc0cebd31695128bde68a445599a9d25eebcb6 100644 (file)
@@ -1932,6 +1932,21 @@ canUnlzma(void)
        return (value);
 }
 
+/*
+ * Can this platform run the lzop program?
+ */
+int
+canLzop(void)
+{
+       static int tested = 0, value = 0;
+       if (!tested) {
+               tested = 1;
+               if (systemf("lzop -V %s", redirectArgs) == 0)
+                       value = 1;
+       }
+       return (value);
+}
+
 /*
  * Can this platform run the unxz program?
  */
index 350eb33447f5f9f468cd0c0e7d0e116ec05c00af..01f902ef29d261a5d487f149a3834a9a93776dac 100644 (file)
@@ -284,6 +284,9 @@ int canLunzip(void);
 /* Return true if this platform can run the "unlzma" program. */
 int canUnlzma(void);
 
+/* Return true if this platform can run the "lzop" program. */
+int canLzop(void);
+
 /* Return true if this platform can run the "unxz" program. */
 int canUnxz(void);
 
diff --git a/cpio/test/test_option_lzop.c b/cpio/test/test_option_lzop.c
new file mode 100644 (file)
index 0000000..a1812d3
--- /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_lzop)
+{
+       char *p;
+       size_t s;
+
+       if (!canLzop()) {
+               skipping("lzop is not supported on this platform");
+               return;
+       }
+
+       /* Create a file. */
+       assertMakeFile("f", 0644, "a");
+
+       /* Archive it with lzop compression. */
+       assertEqualInt(0,
+           systemf("echo f | %s -o --lzop >archive.out 2>archive.err",
+           testprog));
+       p = slurpfile(&s, "archive.err");
+       p[s] = '\0';
+       /* Check that the archive file has an lzma signature. */
+       p = slurpfile(&s, "archive.out");
+       assert(s > 2);
+       assertEqualMem(p, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9);
+}
index cbb86728151a7898352e0a5b6541b6389bca4677..df7185011e8ce69057042c1bd66503e37ea8f0f2 100644 (file)
@@ -59,6 +59,7 @@ SET(libarchive_SOURCES
   archive_read_support_filter_compress.c
   archive_read_support_filter_gzip.c
   archive_read_support_filter_lrzip.c
+  archive_read_support_filter_lzop.c
   archive_read_support_filter_none.c
   archive_read_support_filter_program.c
   archive_read_support_filter_rpm.c
index d914ed43cfaf3da1fce9ee971b2b61b615676af5..b4da85ef9c99d1be954ccd4ec4e402a47858e9bb 100644 (file)
@@ -215,6 +215,7 @@ typedef int archive_switch_callback(struct archive *, void *_client_data1,
 #define        ARCHIVE_FILTER_RPM      8
 #define        ARCHIVE_FILTER_LZIP     9
 #define        ARCHIVE_FILTER_LRZIP    10
+#define        ARCHIVE_FILTER_LZOP     11
 
 #if ARCHIVE_VERSION_NUMBER < 4000000
 #define        ARCHIVE_COMPRESSION_NONE        ARCHIVE_FILTER_NONE
@@ -325,6 +326,7 @@ __LA_DECL int archive_read_support_filter_gzip(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 *);
+__LA_DECL int archive_read_support_filter_lzop(struct archive *);
 __LA_DECL int archive_read_support_filter_none(struct archive *);
 __LA_DECL int archive_read_support_filter_program(struct archive *,
                     const char *command);
@@ -611,6 +613,7 @@ __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 *);
 __LA_DECL int archive_write_add_filter_lzma(struct archive *);
+__LA_DECL int archive_write_add_filter_lzop(struct archive *);
 __LA_DECL int archive_write_add_filter_none(struct archive *);
 __LA_DECL int archive_write_add_filter_program(struct archive *,
                     const char *cmd);
index 9f580c94db6ff78fec69327b650cb37a3a9dfeca..2dc9645ca0a101e80258e9bcbbab0ec1ffd37ad6 100644 (file)
@@ -163,7 +163,7 @@ struct archive_read {
        struct archive_read_client client;
 
        /* Registered filter bidders. */
-       struct archive_read_filter_bidder bidders[10];
+       struct archive_read_filter_bidder bidders[14];
 
        /* Last filter in chain */
        struct archive_read_filter *filter;
index 6375332880fc6617aa01a05923970d9d4ab0310d..dcd77032524963119400ae1f11e030c19770037e 100644 (file)
@@ -65,6 +65,8 @@ archive_read_support_filter_all(struct archive *a)
        archive_read_support_filter_rpm(a);
        /* The decode code always uses "lrzip -d" command-line. */
        archive_read_support_filter_lrzip(a);
+       /* The decode code always uses "lzop -d" command-line. */
+       archive_read_support_filter_lzop(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_lzop.c b/libarchive/archive_read_support_filter_lzop.c
new file mode 100644 (file)
index 0000000..4c8e0e0
--- /dev/null
@@ -0,0 +1,119 @@
+/*-
+ * 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 "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"
+
+#define LZOP_HEADER_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a"
+#define LZOP_HEADER_MAGIC_LEN 9
+
+static int lzop_bidder_bid(struct archive_read_filter_bidder *,
+    struct archive_read_filter *);
+static int lzop_bidder_init(struct archive_read_filter *);
+static int lzop_reader_free(struct archive_read_filter_bidder *);
+
+int
+archive_read_support_filter_lzop(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_lzop");
+
+       if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
+               return (ARCHIVE_FATAL);
+
+       reader->data = NULL;
+       reader->bid = lzop_bidder_bid;
+       reader->init = lzop_bidder_init;
+       reader->options = NULL;
+       reader->free = lzop_reader_free;
+       /* Return ARCHIVE_WARN since this always uses an external program. */
+       return (ARCHIVE_WARN);
+}
+
+static int
+lzop_reader_free(struct archive_read_filter_bidder *self)
+{
+       (void)self; /* UNUSED */
+       return (ARCHIVE_OK);
+}
+
+/*
+ * Bidder just verifies the header and returns the number of verified bits.
+ */
+static int
+lzop_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, LZOP_HEADER_MAGIC_LEN, &avail);
+       if (p == NULL || avail == 0)
+               return (0);
+
+       if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN))
+               return (0);
+
+       return (LZOP_HEADER_MAGIC_LEN * 8);
+}
+
+static int
+lzop_bidder_init(struct archive_read_filter *self)
+{
+       int r;
+
+       r = __archive_read_programl(self, "lzop", "lzop", "-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_LZOP;
+       self->name = "lzop";
+       return (r);
+}
diff --git a/libarchive/archive_write_add_filter_lzop.c b/libarchive/archive_write_add_filter_lzop.c
new file mode 100644 (file)
index 0000000..3b963d8
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * 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$");
+
+#include "archive.h"
+
+int
+archive_write_add_filter_lzop(struct archive *a)
+{
+       int r;
+       r = archive_write_add_filter_programl(a, "lzop", "lzop", NULL);
+       /* Return ARCHIVE_WARN since this always uses an external program. */
+       if (r == ARCHIVE_OK)
+               r = ARCHIVE_WARN;
+       return (r);
+}
index f13adc9f3853fcb251e7ceb4f8ec5668c6dce046..3de15e2b2f921104bb6f2410f7357cffc626d24b 100644 (file)
@@ -78,6 +78,7 @@ IF(ENABLE_TEST)
     test_read_filter_program.c
     test_read_filter_program_signature.c
     test_read_filter_uudecode.c
+    test_read_filter_lzop.c
     test_read_format_7zip.c
     test_read_format_ar.c
     test_read_format_cab.c
@@ -148,6 +149,7 @@ IF(ENABLE_TEST)
     test_write_compress_lrzip.c
     test_write_compress_lzip.c
     test_write_compress_lzma.c
+    test_write_compress_lzop.c
     test_write_compress_program.c
     test_write_compress_xz.c
     test_write_disk.c
index 8ad8a782f9f93a0dedb4506c2f8b351e2105bdf5..1f2a733deb2538b0edf4a44eb706e9da959019c5 100644 (file)
@@ -1930,6 +1930,21 @@ canUnlzma(void)
        return (value);
 }
 
+/*
+ * Can this platform run the lzop program?
+ */
+int
+canLzop(void)
+{
+       static int tested = 0, value = 0;
+       if (!tested) {
+               tested = 1;
+               if (systemf("lzop -V %s", redirectArgs) == 0)
+                       value = 1;
+       }
+       return (value);
+}
+
 /*
  * Can this platform run the unxz program?
  */
index 457346b795d5f724abd65db3ea6052a6f35ce7a9..bdd10672f2e962c857f0fca69ce7cefe825788fb 100644 (file)
@@ -284,6 +284,9 @@ int canLunzip(void);
 /* Return true if this platform can run the "unlzma" program. */
 int canUnlzma(void);
 
+/* Return true if this platform can run the "lzop" program. */
+int canLzop(void);
+
 /* Return true if this platform can run the "unxz" program. */
 int canUnxz(void);
 
diff --git a/libarchive/test/test_read_filter_lzop.c b/libarchive/test/test_read_filter_lzop.c
new file mode 100644 (file)
index 0000000..885fbae
--- /dev/null
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2003-2008 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"
+
+DEFINE_TEST(test_read_filter_lzop)
+{
+       const char *reference = "test_read_filter_lzop.tar.lzo";
+       /* lrzip tracks directories as files, ensure that we list everything */
+       const char *n[] = {
+               "d1/", "d1/f2", "d1/f3", "d1/f1", "f1", "f2", "f3", NULL };
+       struct archive_entry *ae;
+       struct archive *a;
+       int i;
+
+       if (!canLzop()) {
+               skipping("lzop command-line program not found");
+       }
+
+       extract_reference_file(reference);
+       assert((a = archive_read_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_WARN, archive_read_support_filter_lzop(a));
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+       assertEqualIntA(a, ARCHIVE_OK,
+               archive_read_open_filename(a, reference, 10240));
+
+       /* 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], reference);
+               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_count(a), 2);
+       assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZOP);
+       assertEqualString(archive_filter_name(a, 0), "lzop");
+       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_lzop.tar.lzo.uu b/libarchive/test/test_read_filter_lzop.tar.lzo.uu
new file mode 100644 (file)
index 0000000..d5fcc30
--- /dev/null
@@ -0,0 +1,11 @@
+begin 664 test_read_filter_lzop.tar.lzo
+MB4Q:3P`-"AH*$#`@8`E``04#```!``"!M%!PQ.T`````&71E<W1?<F5A9%]F
+M:6QT97)?;'IO<"YT87(T@P\,```2`````/]:XH">`V0Q+P```"`]```+,#`P
+M-S<U(``P,#$W-3`J'0`PX```!"`Q,C`S-#$T,C,Q-2`P,3`W-3$`(#4@/5@"
+MM`L(=7-T87(`,#!C=66@`C44`#Y\`*09<!ME`2`U%`$@<%@``F0Q+V8R(#Y4
+M`@,P,#`V-C1H(R`'_`<$,3$W,0`@,"`^7`*8"R#B_0<S@"$@.1``(!3]!S(@
+M`$K]!S$@.>@'A`L@%/T',"``1OT'9B`_\P<````@#?T'-W__-C8V(`!'_`<@
+M/_`?(!?]!S<@`$?\!R`_\!\@%OT'-R``1_P7@/0@````RA````$`````````
+3````````````````$0``````````
+`
+end
diff --git a/libarchive/test/test_write_compress_lzop.c b/libarchive/test/test_write_compress_lzop.c
new file mode 100644 (file)
index 0000000..d984b81
--- /dev/null
@@ -0,0 +1,135 @@
+/*-
+ * 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"
+
+/*
+ * A basic exercise of lzop reading and writing.
+ */
+
+DEFINE_TEST(test_write_compress_lzop)
+{
+       struct archive_entry *ae;
+       struct archive* a;
+       char *buff, *data;
+       size_t buffsize, datasize;
+       char path[16];
+       size_t used1, used2;
+       int blocksize = 1024;
+       int i;
+
+       if (!canLzop()) {
+               skipping("lzop command-line program not found");
+               return;
+       }
+
+       buffsize = 2000000;
+       assert(NULL != (buff = (char *)malloc(buffsize)));
+
+       datasize = 10000;
+       assert(NULL != (data = (char *)malloc(datasize)));
+       memset(data, 0, datasize);
+
+       /*
+        * Write 100 files and read them all back.
+        */
+       assert((a = archive_write_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+       assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lzop(a));
+       assertEqualIntA(a, ARCHIVE_OK,
+               archive_write_set_bytes_per_block(a, blocksize));
+       assertEqualIntA(a, ARCHIVE_OK,
+               archive_write_set_bytes_in_last_block(a, blocksize));
+       assertEqualInt(blocksize, archive_write_get_bytes_in_last_block(a));
+       assertEqualInt(ARCHIVE_FILTER_PROGRAM, archive_filter_code(a, 0));
+       assertEqualString("Program: lzop lzop", archive_filter_name(a, 0));
+       assertEqualIntA(a, ARCHIVE_OK,
+               archive_write_open_memory(a, buff, buffsize, &used1));
+       assertEqualInt(blocksize, archive_write_get_bytes_in_last_block(a));
+
+       for (i = 0; i < 100; i++) {
+               sprintf(path, "file%03d", i);
+               assert((ae = archive_entry_new()) != NULL);
+               archive_entry_set_filetype(ae, AE_IFREG);
+               archive_entry_set_size(ae, datasize);
+               archive_entry_copy_pathname(ae, path);
+               assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+               archive_entry_free(ae);
+               assertA(datasize
+                   == (size_t)archive_write_data(a, data, datasize));
+       }
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+       assert((a = archive_read_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+       assertEqualIntA(a, ARCHIVE_WARN, archive_read_support_filter_lzop(a));
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_read_open_memory(a, buff, used1));
+       for (i = 0; i < 100; i++) {
+               sprintf(path, "file%03d", i);
+               if (!assertEqualInt(ARCHIVE_OK,
+                       archive_read_next_header(a, &ae)))
+                       break;
+               assertEqualString(path, archive_entry_pathname(ae));
+               assertEqualInt((int)datasize, archive_entry_size(ae));
+       }
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+       /*
+        * Test various premature shutdown scenarios to make sure we
+        * don't crash or leak memory.
+        */
+       assert((a = archive_write_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lzop(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+       assert((a = archive_write_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lzop(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+       assert((a = archive_write_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+       assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lzop(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+       assert((a = archive_write_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+       assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lzop(a));
+       assertEqualIntA(a, ARCHIVE_OK,
+               archive_write_open_memory(a, buff, buffsize, &used2));
+       assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+       /*
+        * Clean up.
+        */
+       free(data);
+       free(buff);
+}
index efa55c8744b01fab2a2f907c357016a092e74a83..cd3e8fbce3140421e069f5af466337189939f75b 100644 (file)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 3, 2012
+.Dd October 7, 2012
 .Dt TAR 1
 .Os
 .Sh NAME
@@ -295,6 +295,15 @@ Note that, unlike other
 .Nm tar
 implementations, this implementation recognizes LZMA compression
 automatically when reading archives.
+.It Fl Fl lzop
+(c mode only)
+Compress the resulting archive with
+.Xr lzop 1 .
+In extract or list modes, this option is ignored.
+Note that, unlike other
+.Nm tar
+implementations, this implementation recognizes lzop compression
+automatically when reading archives.
 .It Fl m , Fl Fl modification-time
 (x mode only)
 Do not extract modification time.
index 2c83d0bf7cb9cf966b4a7d8032296538a61e4cbc..f8e7e5d87c9fd6d23789b5a1770ea57979eaa229 100644 (file)
@@ -374,6 +374,7 @@ main(int argc, char **argv)
                        break;
                case OPTION_LZIP: /* GNU tar beginning with 1.23 */
                case OPTION_LZMA: /* GNU tar beginning with 1.20 */
+               case OPTION_LZOP: /* GNU tar beginning with 1.21 */
                        if (bsdtar->create_compression != '\0')
                                lafe_errc(1, 0,
                                    "Can't specify both -%c and -%c", opt,
index 8a11b1e16c714b5ef59268fc8391788fef0a0596..810ddc390de088baa7003cb86027234519311cf9 100644 (file)
@@ -123,6 +123,7 @@ enum {
        OPTION_KEEP_NEWER_FILES,
        OPTION_LZIP,
        OPTION_LZMA,
+       OPTION_LZOP,
        OPTION_NEWER_CTIME,
        OPTION_NEWER_CTIME_THAN,
        OPTION_NEWER_MTIME,
index 329d8e5c76f0b5a05dbdf71a6c7eb2058a3a5711..3ee00e098ef79f0853aaa3dfc6030c6d74572b4e 100644 (file)
@@ -98,6 +98,7 @@ static const struct bsdtar_option {
        { "list",                 0, 't' },
        { "lzip",                 0, OPTION_LZIP },
        { "lzma",                 0, OPTION_LZMA },
+       { "lzop",                 0, OPTION_LZOP },
        { "modification-time",    0, 'm' },
        { "newer",                1, OPTION_NEWER_CTIME },
        { "newer-ctime",          1, OPTION_NEWER_CTIME },
index ffa8dcd11c34b2dd7d9e6dd7680142d79186c024..22568d5253247ea1e8de8c8eaf9e3a71bf77f5e1 100644 (file)
@@ -32,6 +32,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
     test_option_gid_gname.c
     test_option_k.c
     test_option_keep_newer_files.c
+    test_option_lzop.c
     test_option_n.c
     test_option_newer_than.c
     test_option_nodump.c
index caf75e9584dd373557a40c4e8ea42b88cf564ed4..28275065a96c6aaea5bebb5837b5b76508fd7c5d 100644 (file)
@@ -1932,6 +1932,21 @@ canUnlzma(void)
        return (value);
 }
 
+/*
+ * Can this platform run the lzop program?
+ */
+int
+canLzop(void)
+{
+       static int tested = 0, value = 0;
+       if (!tested) {
+               tested = 1;
+               if (systemf("lzop -V %s", redirectArgs) == 0)
+                       value = 1;
+       }
+       return (value);
+}
+
 /*
  * Can this platform run the unxz program?
  */
index e5463e1ea2b41448e1dd161f8c2806a19ec6b95f..49fe9d97fb139c53244f4e8f5bc9da17bcca875c 100644 (file)
@@ -286,6 +286,9 @@ int canLunzip(void);
 /* Return true if this platform can run the "unlzma" program. */
 int canUnlzma(void);
 
+/* Return true if this platform can run the "lzop" program. */
+int canLzop(void);
+
 /* Return true if this platform can run the "unxz" program. */
 int canUnxz(void);
 
diff --git a/tar/test/test_option_lzop.c b/tar/test/test_option_lzop.c
new file mode 100644 (file)
index 0000000..cf4f8a0
--- /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_lzop)
+{
+       char *p;
+       size_t s;
+
+       if (!canLzop()) {
+               skipping("lzop is not supported on this platform");
+               return;
+       }
+
+       /* Create a file. */
+       assertMakeFile("f", 0644, "a");
+
+       /* Archive it with lzop compression. */
+       assertEqualInt(0,
+           systemf("%s -cf - --lzop f >archive.out 2>archive.err",
+           testprog));
+       p = slurpfile(&s, "archive.err");
+       p[s] = '\0';
+       /* Check that the archive file has an lzma signature. */
+       p = slurpfile(&s, "archive.out");
+       assert(s > 2);
+       assertEqualMem(p, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9);
+}
index 659b412ce8b917643d237a5f33c51ecf88be97de..25aaa184e3f9e25f2cf1fefcd9121f6483736a23 100644 (file)
@@ -184,6 +184,9 @@ tar_mode_c(struct bsdtar *bsdtar)
                case OPTION_LZMA:
                        r = archive_write_set_compression_lzma(a);
                        break;
+               case OPTION_LZOP:
+                       r = archive_write_add_filter_lzop(a);
+                       break;
                case 'z':
                        r = archive_write_set_compression_gzip(a);
                        break;
@@ -195,7 +198,7 @@ tar_mode_c(struct bsdtar *bsdtar)
                            "Unrecognized compression option -%c",
                            bsdtar->create_compression);
                }
-               if (r != ARCHIVE_OK) {
+               if (r < ARCHIVE_WARN) {
                        lafe_errc(1, 0,
                            "Unsupported compression option -%c",
                            bsdtar->create_compression);