diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 9156816..9e5fd65 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -75,6 +75,9 @@ pub fn compress_files( encoder, level.map_or(6, |l| (l as u32).clamp(0, 9)), )), + Lzip => return Err(crate::Error::UnsupportedFormat { + reason: "Lzip compression is not supported in ouch.".to_string(), + }), Snappy => Box::new( gzp::par::compress::ParCompress::::builder() .compression_level(gzp::par::compress::Compression::new( @@ -111,7 +114,7 @@ pub fn compress_files( } match first_format { - Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Snappy | Zstd | Brotli => { + Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Lzip | Snappy | Zstd | Brotli => { writer = chain_writer_encoder(&first_format, writer)?; let mut reader = fs::File::open(&files[0])?; diff --git a/src/commands/decompress.rs b/src/commands/decompress.rs index 011cc07..08d7e95 100644 --- a/src/commands/decompress.rs +++ b/src/commands/decompress.rs @@ -132,6 +132,10 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> { liblzma::stream::Stream::new_lzma_decoder(u64::MAX).unwrap() )), Xz => Box::new(liblzma::read::XzDecoder::new(decoder)), + Lzip => Box::new(liblzma::read::XzDecoder::new_stream( + decoder, + liblzma::stream::Stream::new_lzip_decoder(u64::MAX, 0).unwrap(), + )), Snappy => Box::new(snap::read::FrameDecoder::new(decoder)), Zstd => Box::new(zstd::stream::Decoder::new(decoder)?), Brotli => Box::new(brotli::Decompressor::new(decoder, BUFFER_CAPACITY)), @@ -147,7 +151,7 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> { } let files_unpacked = match first_extension { - Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Snappy | Zstd | Brotli => { + Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Lzip | Snappy | Zstd | Brotli => { reader = chain_reader_decoder(&first_extension, reader)?; let mut writer = match utils::ask_to_create_file( diff --git a/src/commands/list.rs b/src/commands/list.rs index 76b43ce..a2e7915 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs @@ -62,6 +62,10 @@ pub fn list_archive_contents( liblzma::stream::Stream::new_lzma_decoder(u64::MAX).unwrap(), )), Xz => Box::new(liblzma::read::XzDecoder::new(decoder)), + Lzip => Box::new(liblzma::read::XzDecoder::new_stream( + decoder, + liblzma::stream::Stream::new_lzip_decoder(u64::MAX, 0).unwrap(), + )), Snappy => Box::new(snap::read::FrameDecoder::new(decoder)), Zstd => Box::new(zstd::stream::Decoder::new(decoder)?), Brotli => Box::new(brotli::Decompressor::new(decoder, BUFFER_CAPACITY)), @@ -131,7 +135,7 @@ pub fn list_archive_contents( Box::new(archive::sevenz::list_archive(io::Cursor::new(vec), password)?) } - Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Snappy | Zstd | Brotli => { + Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Lzip | Snappy | Zstd | Brotli => { unreachable!("Not an archive, should be validated before calling this function."); } }; diff --git a/src/extension.rs b/src/extension.rs index b7fbe09..80405cf 100644 --- a/src/extension.rs +++ b/src/extension.rs @@ -89,6 +89,8 @@ pub enum CompressionFormat { Xz, /// .lzma Lzma, + /// .lzip + Lzip, /// .sz Snappy, /// tar, tgz, tbz, tbz2, tbz3, txz, tlz4, tlzma, tsz, tzst @@ -118,6 +120,7 @@ impl CompressionFormat { Lz4 => false, Lzma => false, Xz => false, + Lzip => false, Snappy => false, Zstd => false, Brotli => false, @@ -135,6 +138,7 @@ fn to_extension(ext: &[u8]) -> Option { b"tlz4" => &[Tar, Lz4], b"txz" => &[Tar, Xz], b"tlzma" => &[Tar, Lzma], + b"tlz" => &[Tar, Lzip], b"tsz" => &[Tar, Snappy], b"tzst" => &[Tar, Zstd], b"zip" => &[Zip], @@ -144,6 +148,7 @@ fn to_extension(ext: &[u8]) -> Option { b"lz4" => &[Lz4], b"xz" => &[Xz], b"lzma" => &[Lzma], + b"lz" => &[Lzip], b"sz" => &[Snappy], b"zst" => &[Zstd], b"rar" => &[Rar], diff --git a/src/utils/fs.rs b/src/utils/fs.rs index 2ddfa71..b12866e 100644 --- a/src/utils/fs.rs +++ b/src/utils/fs.rs @@ -144,6 +144,9 @@ pub fn try_infer_extension(path: &Path) -> Option { fn is_xz(buf: &[u8]) -> bool { buf.starts_with(&[0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00]) } + fn is_lzip(buf: &[u8]) -> bool { + buf.starts_with(&[0x4C, 0x5A, 0x49, 0x50]) + } fn is_lz4(buf: &[u8]) -> bool { buf.starts_with(&[0x04, 0x22, 0x4D, 0x18]) } @@ -193,6 +196,8 @@ pub fn try_infer_extension(path: &Path) -> Option { Some(Extension::new(&[Lzma], "lzma")) } else if is_xz(&buf) { Some(Extension::new(&[Xz], "xz")) + } else if is_lzip(&buf) { + Some(Extension::new(&[Lzip], "lzip")) } else if is_lz4(&buf) { Some(Extension::new(&[Lz4], "lz4")) } else if is_sz(&buf) {