From: Michihiro NAKAJIMA Date: Thu, 6 May 2010 02:32:28 +0000 (-0400) Subject: Add lzip write filter and --lzip option to bsdtar. X-Git-Tag: v3.0.0a~1022 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4295807f574e0dd0abd6069e0e5c119836fa9df5;p=thirdparty%2Flibarchive.git Add lzip write filter and --lzip option to bsdtar. SVN-Revision: 2373 --- diff --git a/Makefile.am b/Makefile.am index 0cddba7b2..928f12ae6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -318,6 +318,7 @@ libarchive_test_SOURCES= \ libarchive/test/test_write_compress.c \ libarchive/test/test_write_compress_bzip2.c \ libarchive/test/test_write_compress_gzip.c \ + libarchive/test/test_write_compress_lzip.c \ libarchive/test/test_write_compress_lzma.c \ libarchive/test/test_write_compress_program.c \ libarchive/test/test_write_compress_xz.c \ diff --git a/libarchive/archive.h b/libarchive/archive.h index fe0ca2264..4776249b0 100644 --- a/libarchive/archive.h +++ b/libarchive/archive.h @@ -555,6 +555,7 @@ __LA_DECL int archive_write_set_skip_file(struct archive *, __LA_DECL int archive_write_set_compression_bzip2(struct archive *); __LA_DECL int archive_write_set_compression_compress(struct archive *); __LA_DECL int archive_write_set_compression_gzip(struct archive *); +__LA_DECL int archive_write_set_compression_lzip(struct archive *); __LA_DECL int archive_write_set_compression_lzma(struct archive *); __LA_DECL int archive_write_set_compression_none(struct archive *); __LA_DECL int archive_write_set_compression_program(struct archive *, @@ -565,6 +566,7 @@ __LA_DECL int archive_write_set_compression_xz(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_gzip(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_none(struct archive *); __LA_DECL int archive_write_add_filter_program(struct archive *, diff --git a/libarchive/archive_write_add_filter_xz.c b/libarchive/archive_write_add_filter_xz.c index 984a0ceb5..3c0905dae 100644 --- a/libarchive/archive_write_add_filter_xz.c +++ b/libarchive/archive_write_add_filter_xz.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009 Michihiro NAKAJIMA + * Copyright (c) 2009,2010 Michihiro NAKAJIMA * Copyright (c) 2003-2010 Tim Kientzle * All rights reserved. * @@ -43,10 +43,18 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_xz.c 20110 #endif #include "archive.h" +#include "archive_endian.h" #include "archive_private.h" #include "archive_write_private.h" #if ARCHIVE_VERSION_NUMBER < 4000000 +int +archive_write_set_compression_lzip(struct archive *a) +{ + __archive_write_filters_free(a); + return (archive_write_add_filter_lzip(a)); +} + int archive_write_set_compression_lzma(struct archive *a) { @@ -60,6 +68,7 @@ archive_write_set_compression_xz(struct archive *a) __archive_write_filters_free(a); return (archive_write_add_filter_xz(a)); } + #endif #ifndef HAVE_LZMA_H @@ -78,6 +87,14 @@ archive_write_add_filter_lzma(struct archive *a) "lzma compression not supported on this platform"); return (ARCHIVE_FATAL); } + +int +archive_write_add_filter_lzip(struct archive *a) +{ + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "lzma compression not supported on this platform"); + return (ARCHIVE_FATAL); +} #else /* Don't compile this if we don't have liblzma. */ @@ -89,6 +106,9 @@ struct private_data { int64_t total_in; unsigned char *compressed; size_t compressed_buffer_size; + int64_t total_out; + /* the CRC32 value of uncompressed data for lzip */ + uint32_t crc32; }; static int archive_compressor_xz_options(struct archive_write_filter *, @@ -101,6 +121,23 @@ static int archive_compressor_xz_free(struct archive_write_filter *); static int drive_compressor(struct archive_write_filter *, struct private_data *, int finishing); +struct option_value { + uint32_t dict_size; + uint32_t nice_len; + lzma_match_finder mf; +}; +static const struct option_value option_values[] = { + { 1 << 16, 32, LZMA_MF_HC3}, + { 1 << 20, 32, LZMA_MF_HC3}, + { 3 << 19, 32, LZMA_MF_HC4}, + { 1 << 21, 32, LZMA_MF_BT4}, + { 3 << 20, 32, LZMA_MF_BT4}, + { 1 << 22, 32, LZMA_MF_BT4}, + { 1 << 23, 64, LZMA_MF_BT4}, + { 1 << 24, 64, LZMA_MF_BT4}, + { 3 << 23, 64, LZMA_MF_BT4}, + { 1 << 25, 64, LZMA_MF_BT4} +}; static int common_setup(struct archive_write_filter *f) @@ -161,6 +198,23 @@ archive_write_add_filter_lzma(struct archive *_a) return (r); } +int +archive_write_add_filter_lzip(struct archive *_a) +{ + struct archive_write_filter *f; + int r; + + archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, + ARCHIVE_STATE_NEW, "archive_write_add_filter_lzip"); + f = __archive_write_allocate_filter(_a); + r = common_setup(f); + if (r == ARCHIVE_OK) { + f->code = ARCHIVE_COMPRESSION_LZIP; + f->name = "lzip"; + } + return (r); +} + static int archive_compressor_xz_init_stream(struct archive_write_filter *f, struct private_data *data) @@ -174,8 +228,44 @@ archive_compressor_xz_init_stream(struct archive_write_filter *f, if (f->code == ARCHIVE_COMPRESSION_XZ) ret = lzma_stream_encoder(&(data->stream), data->lzmafilters, LZMA_CHECK_CRC64); - else + else if (f->code == ARCHIVE_COMPRESSION_LZMA) ret = lzma_alone_encoder(&(data->stream), &data->lzma_opt); + else { /* ARCHIVE_COMPRESSION_LZIP */ + int dict_size = data->lzma_opt.dict_size; + int ds, log2dic, wedges; + + /* Calculate a coded dictionary size */ + if (dict_size < (1 << 12) || dict_size > (1 << 27)) { + archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, + "Unacceptable dictionary dize for lzip: %d", + dict_size); + return (ARCHIVE_FATAL); + } + for (log2dic = 27; log2dic >= 12; log2dic--) { + if (dict_size & (1 << log2dic)) + break; + } + if (dict_size > (1 << log2dic)) { + log2dic++; + wedges = + ((1 << log2dic) - dict_size) / (1 << (log2dic - 4)); + } else + wedges = 0; + ds = ((wedges << 5) & 0xe0) | (log2dic & 0x1f); + + data->crc32 = 0; + /* Make a header */ + data->compressed[0] = 0x4C; + data->compressed[1] = 0x5A; + data->compressed[2] = 0x49; + data->compressed[3] = 0x50; + data->compressed[4] = 1;/* Version */ + data->compressed[5] = (unsigned char)ds; + data->stream.next_out += 6; + data->stream.avail_out -= 6; + + ret = lzma_raw_encoder(&(data->stream), data->lzmafilters); + } if (ret == LZMA_OK) return (ARCHIVE_OK); @@ -221,13 +311,33 @@ archive_compressor_xz_open(struct archive_write_filter *f) f->write = archive_compressor_xz_write; /* Initialize compression library. */ - if (lzma_lzma_preset(&data->lzma_opt, data->compression_level)) { - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library"); + if (f->code == ARCHIVE_COMPRESSION_LZIP) { + const struct option_value *val = + &option_values[data->compression_level]; + + data->lzma_opt.dict_size = val->dict_size; + data->lzma_opt.preset_dict = NULL; + data->lzma_opt.preset_dict_size = 0; + data->lzma_opt.lc = LZMA_LC_DEFAULT; + data->lzma_opt.lp = LZMA_LP_DEFAULT; + data->lzma_opt.pb = LZMA_PB_DEFAULT; + data->lzma_opt.mode = + data->compression_level<= 2? LZMA_MODE_FAST:LZMA_MODE_NORMAL; + data->lzma_opt.nice_len = val->nice_len; + data->lzma_opt.mf = val->mf; + data->lzma_opt.depth = 0; + data->lzmafilters[0].id = LZMA_FILTER_LZMA1; + data->lzmafilters[0].options = &data->lzma_opt; + data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ + } else { + if (lzma_lzma_preset(&data->lzma_opt, data->compression_level)) { + archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, + "Internal error initializing compression library"); + } + data->lzmafilters[0].id = LZMA_FILTER_LZMA2; + data->lzmafilters[0].options = &data->lzma_opt; + data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ } - data->lzmafilters[0].id = LZMA_FILTER_LZMA2; - data->lzmafilters[0].options = &data->lzma_opt; - data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ ret = archive_compressor_xz_init_stream(f, data); if (ret == LZMA_OK) { f->data = data; @@ -270,6 +380,8 @@ archive_compressor_xz_write(struct archive_write_filter *f, /* Update statistics */ data->total_in += length; + if (f->code == ARCHIVE_COMPRESSION_LZIP) + data->crc32 = lzma_crc32(buff, length, data->crc32); /* Compress input data to output buffer */ data->stream.next_in = buff; @@ -292,9 +404,18 @@ archive_compressor_xz_close(struct archive_write_filter *f) ret = drive_compressor(f, data, 1); if (ret == ARCHIVE_OK) { + data->total_out += + data->compressed_buffer_size - data->stream.avail_out; ret = __archive_write_filter(f->next_filter, data->compressed, data->compressed_buffer_size - data->stream.avail_out); + if (f->code == ARCHIVE_COMPRESSION_LZIP && ret == ARCHIVE_OK) { + archive_le32enc(data->compressed, data->crc32); + archive_le64enc(data->compressed+4, data->total_in); + archive_le64enc(data->compressed+12, data->total_out + 20); + ret = __archive_write_filter(f->next_filter, + data->compressed, 20); + } } lzma_end(&(data->stream)); r1 = __archive_write_close_filter(f->next_filter); @@ -326,6 +447,7 @@ drive_compressor(struct archive_write_filter *f, for (;;) { if (data->stream.avail_out == 0) { + data->total_out += data->compressed_buffer_size; ret = __archive_write_filter(f->next_filter, data->compressed, data->compressed_buffer_size); diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt index 7e948140a..8fb4bcca9 100644 --- a/libarchive/test/CMakeLists.txt +++ b/libarchive/test/CMakeLists.txt @@ -93,6 +93,7 @@ IF(ENABLE_TEST) test_write_compress.c test_write_compress_bzip2.c test_write_compress_gzip.c + test_write_compress_lzip.c test_write_compress_lzma.c test_write_compress_program.c test_write_compress_xz.c diff --git a/libarchive/test/test_write_compress_lzip.c b/libarchive/test/test_write_compress_lzip.c new file mode 100644 index 000000000..03d1f8427 --- /dev/null +++ b/libarchive/test/test_write_compress_lzip.c @@ -0,0 +1,247 @@ +/*- + * Copyright (c) 2010 Michihiro NAKAJIMA + * Copyright (c) 2007-2009 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 + * 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$"); + +/* + * A basic exercise of lzip reading and writing. + * + */ + +DEFINE_TEST(test_write_compress_lzip) +{ + struct archive_entry *ae; + struct archive* a; + char *buff, *data; + size_t buffsize, datasize; + char path[16]; + size_t used1, used2; + int i, r; + + buffsize = 2000000; + assert(NULL != (buff = (char *)malloc(buffsize))); + + datasize = 10000; + assert(NULL != (data = (char *)malloc(datasize))); + memset(data, 0, datasize); + + /* + * Write a 100 files and read them all back. + */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); + r = archive_write_set_compression_lzip(a); + if (r == ARCHIVE_FATAL) { + skipping("lzip writing not supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + return; + } + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_bytes_per_block(a, 10)); + assertEqualInt(ARCHIVE_COMPRESSION_LZIP, archive_compression(a)); + assertEqualString("lzip", archive_compression_name(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_open_memory(a, buff, buffsize, &used1)); + assertEqualInt(ARCHIVE_COMPRESSION_LZIP, archive_compression(a)); + assertEqualString("lzip", archive_compression_name(a)); + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_filetype(ae, AE_IFREG); + archive_entry_set_size(ae, datasize); + for (i = 0; i < 100; i++) { + sprintf(path, "file%03d", i); + archive_entry_copy_pathname(ae, path); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + assertA(datasize + == (size_t)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)); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + r = archive_read_support_compression_lzip(a); + if (r == ARCHIVE_WARN) { + skipping("Can't verify lzip writing by reading back;" + " lzip reading not fully supported on this platform"); + } else { + assertEqualIntA(a, ARCHIVE_OK, + archive_read_support_compression_all(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)); + + /* + * Repeat the cycle again, this time setting some compression + * options. + */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_bytes_per_block(a, 10)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzip(a)); + assertEqualIntA(a, ARCHIVE_WARN, + archive_write_set_compressor_options(a, "nonexistent-option=0")); + assertEqualIntA(a, ARCHIVE_WARN, + archive_write_set_compressor_options(a, "compression-level=abc")); + assertEqualIntA(a, ARCHIVE_WARN, + archive_write_set_compressor_options(a, "compression-level=99")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_compressor_options(a, "compression-level=9")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); + for (i = 0; i < 100; i++) { + sprintf(path, "file%03d", i); + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, path); + archive_entry_set_size(ae, datasize); + archive_entry_set_filetype(ae, AE_IFREG); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + assertA(datasize == (size_t)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)); + + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + r = archive_read_support_compression_lzip(a); + if (r == ARCHIVE_WARN) { + skipping("lzip reading not fully supported on this platform"); + } else { + assertEqualIntA(a, ARCHIVE_OK, + archive_read_support_compression_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, buff, used2)); + for (i = 0; i < 100; i++) { + sprintf(path, "file%03d", i); + failure("Trying to read %s", path); + if (!assertEqualIntA(a, 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)); + + /* + * Repeat again, with much lower compression. + */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_bytes_per_block(a, 10)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzip(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_compressor_options(a, "compression-level=0")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); + for (i = 0; i < 100; i++) { + sprintf(path, "file%03d", i); + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, path); + archive_entry_set_size(ae, datasize); + archive_entry_set_filetype(ae, AE_IFREG); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + failure("Writing file %s", path); + assertEqualIntA(a, datasize, + (size_t)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)); + + /* Level 0 really does result in larger data. */ + failure("Compression-level=0 wrote %d bytes; default wrote %d bytes", + (int)used2, (int)used1); + assert(used2 > used1); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); + r = archive_read_support_compression_lzip(a); + if (r == ARCHIVE_WARN) { + skipping("lzip reading not fully supported on this platform"); + } else { + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, buff, used2)); + 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_OK, archive_write_set_compression_lzip(a)); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzip(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_OK, archive_write_set_compression_lzip(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_OK, archive_write_set_compression_lzip(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); +} diff --git a/tar/bsdtar.c b/tar/bsdtar.c index f0690fa3b..f4d2392dc 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -356,6 +356,7 @@ main(int argc, char **argv) /* GNU tar 1.13 used -l for --one-file-system */ bsdtar->option_warn_links = 1; break; + case OPTION_LZIP: /* GNU tar beginning with 1.23 */ case OPTION_LZMA: /* GNU tar beginning with 1.20 */ if (bsdtar->create_compression != '\0') lafe_errc(1, 0, diff --git a/tar/bsdtar.h b/tar/bsdtar.h index 97826b288..b40bc4195 100644 --- a/tar/bsdtar.h +++ b/tar/bsdtar.h @@ -121,6 +121,7 @@ enum { OPTION_HELP, OPTION_INCLUDE, OPTION_KEEP_NEWER_FILES, + OPTION_LZIP, OPTION_LZMA, OPTION_NEWER_CTIME, OPTION_NEWER_CTIME_THAN, diff --git a/tar/cmdline.c b/tar/cmdline.c index 22346f154..efa9f2413 100644 --- a/tar/cmdline.c +++ b/tar/cmdline.c @@ -96,6 +96,7 @@ static struct option { { "keep-newer-files", 0, OPTION_KEEP_NEWER_FILES }, { "keep-old-files", 0, 'k' }, { "list", 0, 't' }, + { "lzip", 0, OPTION_LZIP }, { "lzma", 0, OPTION_LZMA }, { "modification-time", 0, 'm' }, { "newer", 1, OPTION_NEWER_CTIME }, diff --git a/tar/write.c b/tar/write.c index 359a097f5..65a5b0efc 100644 --- a/tar/write.c +++ b/tar/write.c @@ -224,6 +224,9 @@ tar_mode_c(struct bsdtar *bsdtar) case 'J': r = archive_write_set_compression_xz(a); break; + case OPTION_LZIP: + r = archive_write_set_compression_lzip(a); + break; case OPTION_LZMA: r = archive_write_set_compression_lzma(a); break;