From f5cddbc0f3ec03a2b5aeee960db03e4dc481a411 Mon Sep 17 00:00:00 2001 From: Armin Friedl Date: Sun, 14 Feb 2021 11:46:03 +0100 Subject: [PATCH] Cleanup --- meson.build | 2 + src/archive.cpp | 128 ---------- src/archive.hpp | 53 ---- src/archive_sys.cpp | 297 ---------------------- src/archive_sys.hpp | 119 --------- src/argparse.cpp | 84 ++++++ src/argparse.hpp | 45 ++++ src/fileformats.hpp | 149 ----------- src/main.cpp | 71 ------ src/meson.build | 3 +- src/spec.hpp | 132 ---------- src/util/argparse.cpp | 26 -- src/util/argparse.hpp | 79 ------ src/util/log.hpp | 77 ------ test/archive_test.cpp | 12 - test/fileformats_test.cpp | 64 ----- tests/ahaahm.tar.gz | Bin 0 -> 213 bytes tests/ahaahm/äh🦔~öhm/ähä~öhm.txt | 1 + tests/ahaahm/äh🦔~öhm/ähä~öhm/ähä~öhm.txt | 1 + tests/root.tar.gz | Bin 0 -> 153 bytes tests/runtests/run.py | 17 ++ tests/test-1.23.7z | Bin 0 -> 183 bytes tests/test-1.23.arj | Bin 0 -> 251 bytes tests/test-1.23.cpio | Bin 0 -> 512 bytes tests/test-1.23.lzh | Bin 0 -> 314 bytes tests/test-1.23.rar | Bin 0 -> 272 bytes tests/test-1.23.tar | Bin 0 -> 10240 bytes tests/test-1.23.tar.bz2 | Bin 0 -> 197 bytes tests/test-1.23.tar.gz | Bin 0 -> 220 bytes tests/test-1.23.tar.lrz | Bin 0 -> 315 bytes tests/test-1.23.tar.lzma | Bin 0 -> 193 bytes tests/test-1.23.zip | Bin 0 -> 380 bytes tests/test-1.23_all.deb | Bin 0 -> 604 bytes tests/test-2_all.deb | Bin 0 -> 590 bytes tests/test-deep-recursion.tar | Bin 0 -> 10240 bytes tests/test-dot-first-bomb.tar.gz | Bin 0 -> 145 bytes tests/test-dot-first-onedir.tar.gz | Bin 0 -> 151 bytes tests/test-empty.tar.bz2 | Bin 0 -> 46 bytes tests/test-one-archive.tar.gz | Bin 0 -> 175 bytes tests/test-onedir.tar.bz2 | Bin 0 -> 160 bytes tests/test-onedir.tar.gz | Bin 0 -> 158 bytes tests/test-onefile.tar.gz | Bin 0 -> 125 bytes tests/test-recursive-badperms.tar.bz2 | Bin 0 -> 206 bytes tests/test-recursive-no-prompt.tar.bz2 | Bin 0 -> 295 bytes tests/test-tar-with-node.tar.gz | Bin 0 -> 166 bytes tests/test-text.bz2 | Bin 0 -> 40 bytes tests/test-text.gz | Bin 0 -> 23 bytes tests/test-text.lrz | Bin 0 -> 72 bytes tests/test-text.lz | Bin 0 -> 39 bytes tests/test-text.xz | Bin 0 -> 60 bytes tests/xwim-0.5.0-x86_64-linux.tar.gz | Bin 0 -> 63854 bytes 51 files changed, 152 insertions(+), 1208 deletions(-) delete mode 100644 src/archive.cpp delete mode 100644 src/archive.hpp delete mode 100644 src/archive_sys.cpp delete mode 100644 src/archive_sys.hpp create mode 100644 src/argparse.cpp create mode 100644 src/argparse.hpp delete mode 100644 src/fileformats.hpp delete mode 100644 src/spec.hpp delete mode 100644 src/util/argparse.cpp delete mode 100644 src/util/argparse.hpp delete mode 100644 src/util/log.hpp delete mode 100644 test/archive_test.cpp delete mode 100644 test/fileformats_test.cpp create mode 100644 tests/ahaahm.tar.gz create mode 100644 tests/ahaahm/äh🦔~öhm/ähä~öhm.txt create mode 100644 tests/ahaahm/äh🦔~öhm/ähä~öhm/ähä~öhm.txt create mode 100644 tests/root.tar.gz create mode 100755 tests/runtests/run.py create mode 100644 tests/test-1.23.7z create mode 100644 tests/test-1.23.arj create mode 100644 tests/test-1.23.cpio create mode 100644 tests/test-1.23.lzh create mode 100644 tests/test-1.23.rar create mode 100644 tests/test-1.23.tar create mode 100644 tests/test-1.23.tar.bz2 create mode 100644 tests/test-1.23.tar.gz create mode 100644 tests/test-1.23.tar.lrz create mode 100644 tests/test-1.23.tar.lzma create mode 100644 tests/test-1.23.zip create mode 100644 tests/test-1.23_all.deb create mode 100644 tests/test-2_all.deb create mode 100644 tests/test-deep-recursion.tar create mode 100644 tests/test-dot-first-bomb.tar.gz create mode 100644 tests/test-dot-first-onedir.tar.gz create mode 100644 tests/test-empty.tar.bz2 create mode 100644 tests/test-one-archive.tar.gz create mode 100644 tests/test-onedir.tar.bz2 create mode 100644 tests/test-onedir.tar.gz create mode 100644 tests/test-onefile.tar.gz create mode 100644 tests/test-recursive-badperms.tar.bz2 create mode 100644 tests/test-recursive-no-prompt.tar.bz2 create mode 100644 tests/test-tar-with-node.tar.gz create mode 100644 tests/test-text.bz2 create mode 100644 tests/test-text.gz create mode 100644 tests/test-text.lrz create mode 100644 tests/test-text.lz create mode 100644 tests/test-text.xz create mode 100644 tests/xwim-0.5.0-x86_64-linux.tar.gz diff --git a/meson.build b/meson.build index fa8aedd..0b2df58 100644 --- a/meson.build +++ b/meson.build @@ -4,6 +4,8 @@ project('xwim', 'cpp', 'warning_level=3', 'b_ndebug=if-release']) +add_global_arguments('-DVERSION='+meson.version(), language: 'cpp') + subdir('src') subdir('doc') subdir('test') diff --git a/src/archive.cpp b/src/archive.cpp deleted file mode 100644 index 831c5e9..0000000 --- a/src/archive.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include -#include - -namespace logger = spdlog; - -#include -#include - -#include -#include -#include -#include - -#include "archive_sys.hpp" -#include "archive.hpp" -#include "spec.hpp" -#include "fileformats.hpp" - -namespace xwim { - -static void _spec_is_root_filename(ArchiveSpec* spec, - ArchiveEntryView entry, - std::filesystem::path* filepath) { - auto entry_path = entry.path(); - auto norm_stem = filepath->filename(); - norm_stem = xwim::stem(norm_stem); - - if (*entry_path.begin() != norm_stem) { - logger::debug("Archive root does not match archive name"); - spec->is_root_filename = false; - } else { - logger::debug("Archive root matches archive name"); - spec->is_root_filename = true; - } - logger::debug("\t-> Archive root: {}", entry_path.begin()->string()); - logger::debug("\t-> Archive stem: {}", norm_stem.string()); -} - -static void _spec_is_root_dir(ArchiveSpec* spec, ArchiveEntryView entry) { - if (entry.is_directory()) { - logger::debug("Archive root is directory"); - spec->is_root_dir = true; - } else { - logger::debug("Archive root is not a directory"); - spec->is_root_dir = false; - } - logger::debug("\t-> Archive mode_t: {0:o}", entry.file_type()); -} - -static void _spec_has_single_root(ArchiveSpec* spec, - ArchiveEntryView first_entry, - ArchiveReaderSys& archive_reader) { - std::filesystem::path first_entry_root = *(first_entry.path().begin()); - logger::trace("Testing roots"); - - spec->has_single_root = true; - - while (archive_reader.advance()) { - ArchiveEntryView entry = archive_reader.cur(); - - auto next_entry = entry.path(); - logger::trace("Path: {}, Root: {}", next_entry.string(), - next_entry.begin()->string()); - - if (first_entry_root != *next_entry.begin()) { - logger::debug("Archive has multiple roots"); - logger::debug("\t-> Archive root I: {}", - first_entry_root.begin()->string()); - logger::debug("\t-> Archive root II: {}", next_entry.begin()->string()); - - spec->has_single_root = false; - break; - } - } - - if (spec->has_single_root) - logger::debug("Archive has single root: {}", first_entry_root.string()); -} - -Archive::Archive(std::filesystem::path path) : path{path} {} - -ArchiveSpec Archive::check() { - logger::trace("Creating archive spec for {}", this->path.string()); - - ArchiveReaderSys archive_reader {this->path}; - - ArchiveSpec archive_spec; - - if (!archive_reader.advance()) { // can't advance even once, archive is empty - logger::debug("Archive is empty"); - return {false, false, false}; - } - - ArchiveEntryView first_entry = archive_reader.cur(); - - logger::trace("Found archive entry {}", first_entry.path_name()); - - _spec_is_root_filename(&archive_spec, first_entry, &this->path); - _spec_is_root_dir(&archive_spec, first_entry); - _spec_has_single_root(&archive_spec, first_entry, archive_reader); - - return archive_spec; -} - -void Archive::extract(ExtractSpec extract_spec) { - std::filesystem::path abs_path = std::filesystem::absolute(this->path); - - std::unique_ptr extractor; - - if(extract_spec.make_dir) { - logger::trace("Creating extract directory {}", extract_spec.dirname.string()); - extractor = std::unique_ptr(new ArchiveExtractorSys{extract_spec.dirname}); - } else { - extractor = std::unique_ptr(new ArchiveExtractorSys{}); - } - - ArchiveReaderSys reader{abs_path}; - extractor->extract_all(reader); -} - -void Archive::compress(CompressSpec compress_spec) { - std::filesystem::path abs_path = std::filesystem::absolute(this->path); - - ArchiveCompressorSys compressor{abs_path, compress_spec}; - compressor.compress(); -} - -} // namespace xwim diff --git a/src/archive.hpp b/src/archive.hpp deleted file mode 100644 index fccd250..0000000 --- a/src/archive.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include -#include - -#include "spec.hpp" - -namespace xwim { - -/** Class for interacting with archives */ -class Archive { - private: - std::filesystem::path path; - - public: - explicit Archive(std::filesystem::path path); - - /** Generate an ArchiveSpec by analysing the archive at `path` - * - * @returns ArchiveSpec for the archive - */ - ArchiveSpec check(); - - /** Extract the archive at `path` according to given ExtractSpec */ - void extract(ExtractSpec extract_spec); - - /** Compress the archive at `path` according to given CompressSpec */ - void compress(CompressSpec compress_spec); -}; - -class ArchiveException : public std::exception { - private: - std::string _what; - - public: - ArchiveException(std::string what, archive* archive) { - if (archive_error_string(archive)) { - _what = fmt::format("{}: {}", what, archive_error_string(archive)); - } else { - _what = fmt::format("{}", what); - } - } - - virtual const char* what() const noexcept - { return this->_what.c_str(); } -}; - -} // namespace xwim diff --git a/src/archive_sys.cpp b/src/archive_sys.cpp deleted file mode 100644 index e46b1bc..0000000 --- a/src/archive_sys.cpp +++ /dev/null @@ -1,297 +0,0 @@ -#include -#include -#include - -#include "archive.hpp" -#include "fileformats.hpp" -#include "spec.hpp" -namespace logger = spdlog; - -#include - -#include -#include - -#include "archive_sys.hpp" - -namespace fs = std::filesystem; - -bool xwim::ArchiveEntryView::is_empty() { return (this->ae == nullptr); } - -std::string xwim::ArchiveEntryView::path_name() { - if (!this->ae) throw ArchiveSysException{"Access to invalid archive entry"}; - - return archive_entry_pathname(this->ae); -} - -fs::path xwim::ArchiveEntryView::path() { - if (!this->ae) throw ArchiveSysException{"Access to invalid archive entry"}; - return fs::path{this->path_name()}; -} - -mode_t xwim::ArchiveEntryView::file_type() { - if (!this->ae) throw ArchiveSysException{"Access to invalid archive entry"}; - return archive_entry_filetype(this->ae); -} - -bool xwim::ArchiveEntryView::is_directory() { - return S_ISDIR(this->file_type()); -} - -xwim::ArchiveReaderSys::ArchiveReaderSys(fs::path &path) { - int r; // libarchive error handling - - logger::trace("Setting up archive reader"); - this->ar = archive_read_new(); - archive_read_support_filter_all(this->ar); - archive_read_support_format_all(this->ar); - - logger::trace("Reading archive at {}", path.c_str()); - r = archive_read_open_filename(this->ar, path.c_str(), 10240); - if (r != ARCHIVE_OK) - throw ArchiveSysException{"Could not open archive file", this->ar}; - - logger::trace("Archive read succesfully"); -} - -xwim::ArchiveReaderSys::~ArchiveReaderSys() { - logger::trace("Destructing ArchiveReaderSys"); - - if (this->ar) archive_read_free(this->ar); -} - -bool xwim::ArchiveReaderSys::advance() { - int r; // libarchive error handling - logger::trace("Advancing reader to next archive entry"); - - r = archive_read_next_header(this->ar, &this->ae); - if (r == ARCHIVE_EOF) { - this->ae = nullptr; - return false; - } - if (r != ARCHIVE_OK) - throw(ArchiveSysException{"Could not list archive", this->ar}); - - logger::trace("Got entry {}", archive_entry_pathname(ae)); - return true; -} - -const xwim::ArchiveEntryView xwim::ArchiveReaderSys::cur() { - return ArchiveEntryView{this->ae}; -} - -xwim::ArchiveExtractorSys::ArchiveExtractorSys(fs::path &root) { - logger::trace("Constructing ArchiveExtractorSys with path {}", root.string()); - - fs::create_directories(root); - fs::current_path(root); - - this->writer = archive_write_disk_new(); - archive_write_disk_set_standard_lookup(this->writer); - - logger::trace("Constructed ArchiveExtractorSys at {:p}", - (void *)this->writer); -} - -xwim::ArchiveExtractorSys::ArchiveExtractorSys() { - logger::trace("Construction ArchiveExtractorSys without root"); - - this->writer = archive_write_disk_new(); - archive_write_disk_set_standard_lookup(this->writer); - logger::trace("Constructed ArchiveExtractorSys at {:p}", - (void *)this->writer); -} - -void xwim::ArchiveExtractorSys::extract_all(xwim::ArchiveReaderSys &reader) { - while (reader.advance()) { - this->extract_entry(reader); - } -} - -// forward declared -static int copy_data(struct archive *ar, struct archive *aw); - -void xwim::ArchiveExtractorSys::extract_entry(xwim::ArchiveReaderSys &reader) { - int r; - r = archive_write_header(this->writer, reader.ae); - if (r != ARCHIVE_OK) { - throw(ArchiveSysException("Could not extract entry", reader.ar)); - } - - r = copy_data(reader.ar, this->writer); - if (r != ARCHIVE_OK) { - throw(ArchiveSysException("Could not extract entry", reader.ar)); - } -} - -xwim::ArchiveExtractorSys::~ArchiveExtractorSys() { - logger::trace("Destructing ArchiveExtractorSys at {:p}", - (void *)this->writer); - if (this->writer) { - archive_write_close(this->writer); - archive_write_free(this->writer); - } -} - -xwim::ArchiveCompressorSys::ArchiveCompressorSys( - fs::path &root, xwim::CompressSpec compress_spec) - : root{root}, compress_spec{compress_spec} { - this->new_archive = archive_write_new(); - - for (xwim::archive_filter filter : this->compress_spec.filters) { - archive_write_add_filter(this->new_archive, filter); - } - - archive_write_set_format(this->new_archive, this->compress_spec.format); -} - -// forward declared -static fs::path archive_path_norm(const fs::path &root, - const xwim::CompressSpec &compress_spec); - -void xwim::ArchiveCompressorSys::compress() { - fs::path archive_path = archive_path_norm(this->root, this->compress_spec); - - logger::debug("Writing archive at: {}", archive_path.filename().c_str()); - - archive_write_open_filename(this->new_archive, - archive_path.filename().c_str()); - - archive *disk = archive_read_disk_new(); - archive_read_disk_set_standard_lookup(disk); - - int r; - - r = archive_read_disk_open(disk, fs::relative(this->root).c_str()); - if (r != ARCHIVE_OK) { - throw ArchiveSysException("Could not open path for archiving", disk); - } - - archive_entry *entry; - char buff[16384]; - - for (;;) { - entry = archive_entry_new(); - r = archive_read_next_header2(disk, entry); - if (r == ARCHIVE_EOF) break; - if (r != ARCHIVE_OK) { - throw ArchiveSysException("Could not read next archive entry", disk); - } - - archive_read_disk_descend(disk); - - const char* ae_path = archive_entry_pathname(entry); - fs::path ae_rel_path = fs::relative(fs::path(ae_path), this->root.parent_path()); - archive_entry_set_pathname(entry, ae_rel_path.c_str()); - logger::trace("Processing entry {}", archive_entry_pathname(entry)); - - r = archive_write_header(this->new_archive, entry); - if (r < ARCHIVE_OK) { - throw ArchiveSysException("Could not write header for archive entry", - this->new_archive); - } - - if (r > ARCHIVE_FAILED) { - int fd = open(archive_entry_sourcepath(entry), O_RDONLY); - ssize_t len = read(fd, buff, sizeof(buff)); - while (len > 0) { - archive_write_data(this->new_archive, buff, len); - len = read(fd, buff, sizeof(buff)); - } - close(fd); - } - logger::trace("Entry written {}", archive_entry_pathname(entry)); - archive_entry_free(entry); - } -} - -xwim::ArchiveCompressorSys::~ArchiveCompressorSys() { - logger::trace("Destructing ArchiveExtractorSys at {:p}", - (void *)this->new_archive); - if (this->new_archive) { - archive_write_close(this->new_archive); - archive_write_free(this->new_archive); - } -} - -/** Creates an archive path from the path to compress and normalizes it - * - * Note that currently only single arguments are allowed for `xwim` to - * minimize ambiguity. - * - * The archive path is determined from the argument file/directory by: - * 1. If file: - * 1.1. Stem the filename - * 1.2. Append an extension appropriate for the archive format (from the - * spec) - * 2. If directory: - * 2.1. Remove any trailing '/' - * 2.2. Append an extension appropriate for the archive format (from the - * spec) - */ -static fs::path archive_path_norm(const fs::path &root, - const xwim::CompressSpec &compress_spec) { - fs::path archive_path{root}; - fs::file_status archive_path_stat = fs::status(archive_path); - - std::set known_types = {fs::file_type::directory, fs::file_type::regular}; - fs::perms flag_mask = - fs::perms::owner_read | fs::perms::group_read | fs::perms::others_read; - - if (!fs::exists(archive_path)) { - logger::error("Non-existing path: {}", archive_path.string()); - throw xwim::ArchiveSysException{"Path does not exists"}; - } - - if (!known_types.count(archive_path_stat.type())) { - logger::error("Unknown path type: {}", archive_path_stat.type()); - throw xwim::ArchiveSysException{"Unknown path type"}; - } - - if ((archive_path_stat.permissions() & flag_mask) == fs::perms::none) { - logger::error("Cannot read path with permissions: {}", - archive_path_stat.permissions()); - throw xwim::ArchiveSysException{"Unreadable path"}; - } - - if (archive_path_stat.type() == fs::file_type::regular) { - while (archive_path.has_extension()) { - archive_path.replace_extension(); - } - } - - if (archive_path_stat.type() == fs::file_type::directory) { - if (archive_path.string().back() == '/') { - logger::trace("Found trailing / in path"); - std::string ps = archive_path.string(); - ps.erase(ps.size() - 1, 1); - - archive_path = fs::path{ps}; - logger::trace("Normalized path to {}", archive_path.string()); - } - } - - archive_path.concat(compress_spec.extension); - return archive_path; -} - -static int copy_data(struct archive *ar, struct archive *aw) { - int r; - const void *buff; - size_t size; - int64_t offset; - - for (;;) { - r = archive_read_data_block(ar, &buff, &size, &offset); - if (r == ARCHIVE_EOF) { - return (ARCHIVE_OK); - } - if (r != ARCHIVE_OK) { - return (r); - } - r = archive_write_data_block(aw, buff, size, offset); - if (r != ARCHIVE_OK) { - return (r); - } - } -} diff --git a/src/archive_sys.hpp b/src/archive_sys.hpp deleted file mode 100644 index 2818d17..0000000 --- a/src/archive_sys.hpp +++ /dev/null @@ -1,119 +0,0 @@ -#pragma once - -#include - -#include -#include -#include "spec.hpp" -#include - -namespace xwim { - -/** A view into an archive entry - * - * The view is non-owning and the caller must guarantee - * that the parent archive entry is valid when the view - * is accessed. - */ -class ArchiveEntryView { - private: - archive_entry* ae; - - public: - ArchiveEntryView() = default; - ArchiveEntryView(archive_entry* entry) : ae{entry} {} - - bool is_empty(); - std::string path_name(); - std::filesystem::path path(); - mode_t file_type(); - bool is_directory(); -}; - -/** A reader for archive files - * - * Shim for `libarchive`. Iterates through - * entries of an archive with `next()` - */ -class ArchiveReaderSys { - private: - archive* ar; - archive_entry* ae; - friend class ArchiveExtractorSys; - - public: - ArchiveReaderSys(std::filesystem::path& path); - ~ArchiveReaderSys(); - - /** Advances the internal entry pointer - * - * @return true if the pointer advanced to the next entry - * false if the end of the archive was reached - */ - bool advance(); - - /** Returns a non-owning view of the current entry - * - * ArchiveEntryView is a non-owning view of the currently - * active entry in this reader. A retrieved archive entry - * may not be used after another call to advance in the - * same reader. - * - * @return a view to the archive entry this reader currently - * points to - */ - const ArchiveEntryView cur(); -}; - -/** A extractor for archive files - * - * Shim for `libarchive`. - */ -class ArchiveExtractorSys { - private: - archive* writer; - - public: - ArchiveExtractorSys(std::filesystem::path& root); - ArchiveExtractorSys(); - ~ArchiveExtractorSys(); - - void extract_all(ArchiveReaderSys& reader); - void extract_entry(ArchiveReaderSys& reader); -}; - -/** A compressor for archive files - * - * Shim for `libarchive` - */ -class ArchiveCompressorSys { -private: - archive* new_archive; - std::filesystem::path root; - xwim::CompressSpec compress_spec; - -public: - ArchiveCompressorSys(std::filesystem::path& root, xwim::CompressSpec compress_spec); - ~ArchiveCompressorSys(); - - void compress(); -}; - -class ArchiveSysException : public std::exception { - private: - std::string _what; - - public: - ArchiveSysException(std::string what, archive* archive) { - if (archive_error_string(archive)) { - _what = fmt::format("{}: {}", what, archive_error_string(archive)); - } else { - _what = fmt::format("{}", what); - } - } - ArchiveSysException(std::string what) { _what = fmt::format("{}", what); } - - virtual const char* what() const noexcept { return this->_what.c_str(); } -}; - -} // namespace xwim diff --git a/src/argparse.cpp b/src/argparse.cpp new file mode 100644 index 0000000..3f78e08 --- /dev/null +++ b/src/argparse.cpp @@ -0,0 +1,84 @@ +#include "argparse.hpp" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "archivinfo.hpp" +#include "fileformats.hpp" + +using namespace TCLAP; +using namespace xwim; +namespace fs = std::filesystem; + +template <> +struct TCLAP::ArgTraits { + typedef ValueLike ValueCategory; +}; + +ArgParse::ArgParse() + : cmd{"xwim - Do What I Mean Extractor", ' ', "0.3.0"}, + arg_compress{"c", "compress", "Compress ", false}, + arg_extract{"x", "extract", "Extract ", false}, + arg_outfile{"o", "out", "Out ", + false, fs::path{}, "A path on the filesystem"}, + arg_infiles{"Files", "Archive to extract or files to compress", true, + "A path on the filesystem"} { + cmd.xorAdd(arg_compress, arg_extract); + cmd.add(arg_outfile); + cmd.add(arg_infiles); +}; + +void ArgParse::parse(int argc, char** argv) { + try { + cmd.parse(argc, argv); + } catch (ArgException& e) { + throw new xwim::ArgParseException(e.error()); + } + + this->extract = parse_extract(); + this->outfile = arg_outfile.getValue(); + this->infiles = arg_infiles.getValue(); +} + +bool ArgParse::parse_extract() { + // extract/compress explicitly given; xor ensured in `cmd` + if (this->arg_compress.getValue()) { + return false; + } else if (this->arg_extract.getValue()) { + return true; + } + + // Not explicitly given, check if we can guess from input + + // An outfile is given + if (this->arg_outfile.isSet()) { + // outfile looks like an archive + if (xwim::archivinfo::has_known_extension(this->arg_outfile.getValue())) { + return false; + } + + // outfile is not a known archive, assume it meant as folder for extraction + else { + return true; + } + } + + // one infile which is an archive, so intention is probably to extract this + if (this->arg_infiles.getValue().size() == 1 && + xwim::archivinfo::is_archive(this->arg_infiles.getValue().at(0))) { + return true; + } + + // all other cases, in particular multiple infiles, assume we want to compress + return false; +} +bool ArgParse::compressp() { return !this->extract; } +bool ArgParse::extractp() { return this->extract; } diff --git a/src/argparse.hpp b/src/argparse.hpp new file mode 100644 index 0000000..dd0a372 --- /dev/null +++ b/src/argparse.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +namespace xwim { +class ArgParse { + private: + bool extract; + std::filesystem::path outfile; + std::vector infiles; + + TCLAP::CmdLine cmd; + TCLAP::SwitchArg arg_compress; + TCLAP::SwitchArg arg_extract; + TCLAP::ValueArg arg_outfile; + TCLAP::UnlabeledMultiArg arg_infiles; + + protected: + bool parse_extract(); + + public: + ArgParse(); + void parse(int argc, char** argv); + bool compressp(); + bool extractp(); +}; + +class ArgParseException : public std::exception { + private: + std::string _what; + + public: + ArgParseException(std::string what) : _what{what} {}; + template + ArgParseException(std::string fmt_string, Args&&... args) : _what{fmt::format(fmt_string, args...)} {}; + virtual const char* what() const noexcept { return this->_what.c_str(); } +}; +} // namespace xwim diff --git a/src/fileformats.hpp b/src/fileformats.hpp deleted file mode 100644 index 32bf011..0000000 --- a/src/fileformats.hpp +++ /dev/null @@ -1,149 +0,0 @@ -/** @file fileformats.hpp - * @brief Handle archive extensions - */ -#pragma once - -#include -#include -namespace logger = spdlog; - -#include -#include -#include - -namespace xwim { - -/** Common archive formats understood by xwim - * - * The underlying libarchive backend retrieves format information by a process - * called `bidding`. Hence, this information is mainly used to strip extensions. - * - * Stripping extensions via `std::filesystem::path` does not work reliably since - * it gets easily confused by dots in the regular file name. - */ -const std::set fileformats{".7z", ".7zip", ".jar", ".tgz", - ".bz2", ".bzip2", ".gz", ".gzip", - ".rar", ".tar", ".xz", ".zip"}; - -/** Archive filters - * - * Archive filters are essentially either data compression algorithms or data - * encodings. Filters are used on archives after an archiving program created - * the archive out of files and folders. Multiple filters can be applied to an - * archive. The order is significant. - * - * The simplest way to understand the distinction between filters and formats is - * to visualize the traditional `tar.gz` format. Tar creates the archive (an - * archive format). Gzip compresses the archive (an archive filter). In theory - * one could create a `tar.gz.lz.uu` tarball. That is, a `tar` archive - * filter-compressed with `gzip`, filter-compressed with `lzip`, filter-encoded - * with `uuencode`. - * - * Note that while this abstraction works in many cases it is not perfect. For - * example `.zip` files are traditionally archives where every entry is - * compressed separately and then bundled them together into an archive. In - * those cases the archive format is ZIP with no (external) filters. - */ -enum archive_filter { - NONE = 0, - GZIP = 1, - BZIP2 = 2, - COMPRESS = 3, - PROGRAM = 4, - LZMA = 5, - XZ = 6, - UU = 7, - RPM = 8, - LZIP = 9, - LRZIP = 10, - LZOP = 11, - GRZIP = 12, - LZ4 = 13, - ZSTD = 14 -}; - -/** Archive formats - * - * Archive formats are the specifications for bundling together multiple files - * and folders (including metadata) into a single file (the archive). See also - * `archive_filter` for more details on the difference between archive formats - * and archive filters. - */ -enum archive_format { - BASE_MASK = 0xff0000, - CPIO = 0x10000, - CPIO_POSIX = (CPIO | 1), - CPIO_BIN_LE = (CPIO | 2), - CPIO_BIN_BE = (CPIO | 3), - CPIO_SVR4_NOCRC = (CPIO | 4), - CPIO_SVR4_CRC = (CPIO | 5), - CPIO_AFIO_LARGE = (CPIO | 6), - SHAR = 0x20000, - SHAR_BASE = (SHAR | 1), - SHAR_DUMP = (SHAR | 2), - TAR = 0x30000, - TAR_USTAR = (TAR | 1), - TAR_PAX_INTERCHANGE = (TAR | 2), - TAR_PAX_RESTRICTED = (TAR | 3), - TAR_GNUTAR = (TAR | 4), - ISO9660 = 0x40000, - ISO9660_ROCKRIDGE = (ISO9660 | 1), - ZIP = 0x50000, - EMPTY = 0x60000, - AR = 0x70000, - AR_GNU = (AR | 1), - AR_BSD = (AR | 2), - MTREE = 0x80000, - RAW = 0x90000, - XAR = 0xA0000, - LHA = 0xB0000, - CAB = 0xC0000, - RAR = 0xD0000, - SEVENZIP = 0xE0000, - WARC = 0xF0000, - RAR_V5 = 0x100000 -}; - -/** Strip archive extensions from a path - * - * @returns Base filename without archive extensions - */ -inline std::filesystem::path -stem(const std::filesystem::path& path) { - std::filesystem::path p_stem{path}; - logger::trace("Stemming {}", p_stem.string()); - - p_stem = p_stem.filename(); - - while (fileformats.find(p_stem.extension().string()) != fileformats.end()) { - p_stem = p_stem.stem(); - logger::trace("Stemmed to {}", p_stem.string()); - } - - logger::trace("Finished stemming {}", p_stem.string()); - return p_stem; -} - -/** Get the archive extension of a path. - * - * The archive extension may be a combination of supported fileformats in which - * case all of them are returned. - * - * @returns Archive extension of the archive or path() if no (known) extension - * exists. - */ -inline std::filesystem::path ext(const std::filesystem::path& path) { - std::filesystem::path p_ext{path}; - logger::trace("Extracting extension of {}", p_ext.string()); - - std::filesystem::path p_ext_collector; - while (fileformats.find(p_ext.extension().string()) != fileformats.end()) { - // path extension() const - p_ext_collector = p_ext.extension().concat(p_ext_collector.string()); - p_ext.replace_extension(); - } - - return p_ext_collector; -} - -} // namespace xwim diff --git a/src/main.cpp b/src/main.cpp index fddf13a..5c970cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,77 +1,6 @@ #include #include -#include -#include -#include -#include - -#include "util/log.hpp" -#include "util/argparse.hpp" -#include "archive.hpp" -#include "spec.hpp" -#include "fileformats.hpp" - -namespace logger = spdlog; -using namespace xwim::argparse; - -void extract(const XwimPath& xwim_path) { - try { - xwim::Archive archive{xwim_path.path()}; - xwim::ArchiveSpec archive_spec = archive.check(); - - logger::info("{}", archive_spec); - - xwim::ExtractSpec extract_spec{}; - - if (!archive_spec.has_single_root || !archive_spec.is_root_filename) { - extract_spec.make_dir = true; - - std::filesystem::path stem = xwim::stem(xwim_path.path()); - - extract_spec.dirname = stem; - } - - if (archive_spec.has_subarchive) { - extract_spec.extract_subarchive = true; - } - - logger::info("{}", extract_spec); - - archive.extract(extract_spec); - - } catch (xwim::ArchiveException& ae) { - logger::error("{}", ae.what()); - } -} - -void compress(const XwimPath& xwim_path) { - try { - xwim::Archive archive{xwim_path.path()}; - xwim::CompressSpec compress_spec{}; - - archive.compress(compress_spec); - - } catch (xwim::ArchiveException& ae) { - logger::error("{}", ae.what()); - } -} - -XwimPath parse_args(int argc, char** argv) { - try { - return parse(argc, argv); - } catch (ArgParseException& ex) { - logger::error("{}\n", ex.what()); - std::cout << usage(); - std::exit(1); - } -} - int main(int argc, char** argv) { - xwim::log::init(); - XwimPath xwim_path = parse_args(argc, argv); - - if(xwim_path.is_archive()) { extract(xwim_path); } - else { compress(xwim_path); } } diff --git a/src/meson.build b/src/meson.build index ab44dda..69ad6da 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,6 +5,7 @@ xwim_src = ['main.cpp', xwim_libs = [dependency('libarchive', required: true), dependency('fmt', required: true), - dependency('spdlog', required: true)] + dependency('spdlog', required: true), + dependency('tclap', required: true)] executable('xwim', xwim_src, dependencies: xwim_libs) diff --git a/src/spec.hpp b/src/spec.hpp deleted file mode 100644 index da164ca..0000000 --- a/src/spec.hpp +++ /dev/null @@ -1,132 +0,0 @@ -#pragma once - -#include -#include - -#include -#include - -#include "fileformats.hpp" - -namespace xwim { - -/** Properties of an archive - * - * These properties can be retrieved by analyzing the - * archive. There is no outside-knowledge. All information - * is in the archive. - */ -struct ArchiveSpec { - bool has_single_root = false; /** There is only a single file xor a single - folder at the archive's root */ - bool is_root_filename = false; /** the name of the (single) root is the same - as the stemmed archive file name. Cannot be - true if `has_single_root` is false */ - bool is_root_dir = false; /** The (single) root is a folder. Cannot be true if - `has_single_root` is false */ - bool has_subarchive = false; /** Whether the archive contains sub-archives */ -}; - -/** Properties influencing the extraction process - * - * These properties can be set to influence the extraction - * process accordingly. - */ -struct ExtractSpec { - bool make_dir = false; /** Create a new directory for extraction at `dirname` */ - std::filesystem::path dirname{}; /** The path to a directory for extraction */ - bool extract_subarchive = false; /** Recursively extract sub-archives */ -}; - - -/** Compile time definitions for platform-dependent files and filters */ -#if defined(unix) || defined(__unix__) || defined(__unix) -#define XWIM_COMPRESS_FORMAT xwim::archive_format::TAR_USTAR -#define XWIM_COMPRESS_FILTER { xwim::archive_filter::GZIP } -#define XWIM_COMPRESS_EXTENSION ".tar.gz" -#elif defined(_win32) || defined(__win32__) || defined(__windows__) -#define XWIM_COMPRESS_FORMAT xwim::archive_format::ZIP -#define XWIM_COMPRESS_FILTER {} -#define XWIM_COMPRESS_EXTENSION ".zip" -#else -#define XWIM_COMPRESS_FORMAT xwim::fileformats::archive_format::ZIP -#define XWIM_COMPRESS_FILTER {} -#define XWIM_COMPRESS_EXTENSION ".zip" -#endif - -/** Properties influencing the compression process - * - * These properties can be set to influence the compression process - * accordingly. - * - * Per default, the compress spec is platform dependent to accommodate for the - * expected format on that platform. On Windows this is zip, on Unix this is - * tar.gz - */ -struct CompressSpec { - xwim::archive_format format = - XWIM_COMPRESS_FORMAT; /** The archiving format, e.g. tar */ - std::vector filters = - XWIM_COMPRESS_FILTER; /** Filters applied to the archive, - e.g. gzip */ - std::string extension = - XWIM_COMPRESS_EXTENSION; /** Archive extension, e.g. .tar.gz */ -}; - -} // namespace xwim - -#if FMT_VERSION < 50300 -typedef fmt::basic_parse_context format_parse_context; -#endif - -template <> -struct fmt::formatter { - constexpr auto parse(format_parse_context & ctx) { - return ctx.begin(); - } - - template - auto format(const xwim::ArchiveSpec& spec, FormatContext& ctx) { - return format_to(ctx.out(), - "Archive[" - " .has_single_root={}," - " .is_root_filename={}" - " .is_root_dir={}" - " .has_subarchive={}" - " ]", - spec.has_single_root, spec.is_root_filename, - spec.is_root_dir, spec.has_subarchive); - } -}; - -template <> -struct fmt::formatter { - constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } - - template - auto format(const xwim::ExtractSpec& spec, FormatContext& ctx) { - return format_to(ctx.out(), - "Extract[" - " .make_dir={}," - " .dirname={}" - " .extract_subarchive={}" - " ]", - spec.make_dir, spec.dirname.string(), - spec.extract_subarchive); - } -}; - -template <> -struct fmt::formatter { - constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } - - template - auto format(const xwim::CompressSpec& spec, FormatContext& ctx) { - return format_to(ctx.out(), - "Compress[" - " .format={}," - " .filters={}" - " ]", - spec.format, spec.filters); - } -}; diff --git a/src/util/argparse.cpp b/src/util/argparse.cpp deleted file mode 100644 index 30966a4..0000000 --- a/src/util/argparse.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "argparse.hpp" - -namespace xwim { -namespace argparse { - XwimPath parse(int argc, char** argv) { - return XwimPath{argc, argv}; - } - - // contructs XwimPath{} first so that destructurs may running - // http://www.vishalchovatiya.com/7-best-practices-for-exception-handling-in-cpp-with-example/ - XwimPath::XwimPath(int argc, char** argv) : XwimPath{} { - if (argc < 2) throw ArgParseException{"No argument provided"}; - if (argc > 2) throw ArgParseException{"Too many arguments provided"}; - - this->_path = std::filesystem::path{argv[1]}; - } - - bool XwimPath::is_archive() { - return !xwim::ext(_path).empty(); - } - - std::filesystem::path XwimPath::path() const { - return std::filesystem::path{_path}; - } -} -} diff --git a/src/util/argparse.hpp b/src/util/argparse.hpp deleted file mode 100644 index 740761e..0000000 --- a/src/util/argparse.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "../fileformats.hpp" - -namespace xwim { -/** - * xwim allows for - * 1. an archive - * 2. a file or folder - * - * In case of (1) the archive will be extracted according to the xwim - * do-what-i-mean rules. - * - * In case of (2) the file or folder will be compressed into a "platform native" - * format, i.e. what appears to be the most widely used format on that platform. - * In case of unix this is tar.gz. In case of windows this is zip. The archive - * gets the same name as the file or folder and a proper extension. - * - * A list of files or folders is unsupported as it would be too ambigious to - * choose a name for the archive. A list of archives is unsupported for - * consistency reasons. Any mixture is unsupported as it would be too ambigious - * what the user wants. This is subject to change in the future. - */ -namespace argparse { - -class XwimPath { - private: - std::filesystem::path _path; - - public: - XwimPath() : _path{} {}; - XwimPath(int argc, char** argv); - - bool is_archive(); - std::filesystem::path path() const; -}; - -class ArgParseException : public std::exception { - private: - std::string _what; - - public: - ArgParseException(std::string what) : _what{what} {}; - - virtual const char* what() const noexcept { return this->_what.c_str(); } -}; - -XwimPath parse(int argc, char** argv); - -inline std::string usage() { - std::stringstream s; - s << "USAGE:" - << "\t xwim \n" - << "\n" - - << "PARAMS:" << std::left << std::setfill('.') << std::setw(10) - << "\t path " - << " Archive\n" - << "\n" - - << "FORMATS:\n" - << "\t .7z, .7zip .jar, .tgz, .bz2, .bzip2\n" - << "\t .gz, .gzip, .rar, .tar, .xz, .zip\n" - << "\n" - - << "EXAMPLES:\n" - << "\t Extract archive archive.tar.gz:\n" - << "\t xwim archive.tar.gz\n" - << std::endl; - - return s.str(); -} - -} // namespace argparse -} // namespace xwim diff --git a/src/util/log.hpp b/src/util/log.hpp deleted file mode 100644 index fbb3abe..0000000 --- a/src/util/log.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include -#include -#include - -#ifdef NDEBUG -#define XWIM_LOGLEVEL SPDLOG_LEVEL_ERROR -#else -#define XWIM_LOGLEVEL SPDLOG_LEVEL_DEBUG -#endif - -namespace xwim::log { - -/** - * Get log level from XWIM_LOGLEVEL environment variable. - * For valid values see SPDLOG_LEVEL_NAMES in spdlog/common.h - * - * @returns spdlog::level::level_enum::off if no valid XWIM_LOGLEVEL defined - */ -spdlog::level::level_enum _init_from_env() { - char* env_lvl = std::getenv("XWIM_LOGLEVEL"); - if (!env_lvl) { - return spdlog::level::level_enum::off; - } - - spdlog::level::level_enum lvl = spdlog::level::from_str(env_lvl); - - //`::from_str` returns `off` if no match found - if (spdlog::level::level_enum::off == lvl) { - spdlog::debug("No environment definition for log level"); // uses default - // logger/level - } - - return lvl; -} - -/** - * Get log level from compile time definition. - * - * @return spdlog::level::level_enum::error for release builds (-DNDEBUG) - * spdlog::level::level_enum::debug for debug builds - */ -spdlog::level::level_enum _init_from_compile() { - return static_cast(XWIM_LOGLEVEL); -} - -/** - * Determine the log level from various sources at runtime. - * - * The log level is determined from sources in the following order (first - * wins): - * 1. The `level` argument - * 2. The XWIM_LOGLEVEL environment variable - * 3. The default for the build type (-DNDEBUG) - * -> ERROR for release builds - * -> DEBUG for debug builds - * - * The determined level is then set for the default logger via - * `spdlog::set_level`. - */ -void init(spdlog::level::level_enum level = spdlog::level::level_enum::off) { - if (spdlog::level::level_enum::off != level) { - spdlog::set_level(level); - return; - } - - level = _init_from_env(); - if (spdlog::level::level_enum::off != level) { - spdlog::set_level(level); - return; - } - - spdlog::set_level(_init_from_compile()); -} - -} // namespace xwim::log diff --git a/test/archive_test.cpp b/test/archive_test.cpp deleted file mode 100644 index f548415..0000000 --- a/test/archive_test.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include - -#include -#include -#include - -TEST(ArchiveTest, ArchiveSpecDetectsSingleRoot) { - xwim::Archive archive("test/archives/root.tar.gz"); - - xwim::ArchiveSpec spec = archive.check(); - ASSERT_TRUE(spec.has_single_root); -} diff --git a/test/fileformats_test.cpp b/test/fileformats_test.cpp deleted file mode 100644 index acd6e1d..0000000 --- a/test/fileformats_test.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include - -#include -#include - -TEST(FileformatsTest, StemStripsSingleKnownExtension) { - std::filesystem::path archive_path {"/some/path/to/file.rar"}; - - ASSERT_EQ(xwim::stem(archive_path), std::filesystem::path{"file"}); -} - -TEST(FileformatsTest, StemStripsMultipleKnownExtensions) { - std::filesystem::path archive_path{"/some/path/to/file.tar.rar.gz.7z.rar"}; - - ASSERT_EQ(xwim::stem(archive_path), std::filesystem::path{"file"}); -} - -TEST(FileformatsTest, StemStripsOnlyKnownExtension) { - std::filesystem::path archive_path{"/some/path/to/file.ukn.rar"}; - - ASSERT_EQ(xwim::stem(archive_path), std::filesystem::path{"file.ukn"}); -} - -TEST(FileformatsTest, StemStripsNothingWithoutKnownExtension) { - std::filesystem::path archive_path{"/some/path/to/file.ukn"}; - - ASSERT_EQ(xwim::stem(archive_path), std::filesystem::path{"file.ukn"}); -} - -TEST(FileformatsTest, StemStripsNothingWithoutExtension) { - std::filesystem::path archive_path{"/some/path/to/filerar"}; - - ASSERT_EQ(xwim::stem(archive_path), std::filesystem::path{"filerar"}); -} - -TEST(FileExtTest, ExtGetsKnownExtension) { - std::filesystem::path archive_path{"/some/path/to/file.rar"}; - - ASSERT_EQ(xwim::ext(archive_path), std::filesystem::path{".rar"}); -} - -TEST(FileExtTest, CombinedExtensionGetsAll) { - std::filesystem::path archive_path{"/some/path/to/file.tar.gz"}; - - ASSERT_EQ(xwim::ext(archive_path), std::filesystem::path{".tar.gz"}); -} - -TEST(FileExtTest, ExtEmptyForUnknownExtension) { - std::filesystem::path archive_path{"/some/path/to/file.ukn"}; - - ASSERT_TRUE(xwim::ext(archive_path).empty()); -} - -TEST(FileExtTest, CombinedExtensionGetsKnown) { - std::filesystem::path archive_path{"/some/path/to/file.ukn.tar.gz"}; - - ASSERT_EQ(xwim::ext(archive_path), std::filesystem::path{".tar.gz"}); -} - -TEST(FileExtTest, CombinedExtensionLastUnknownEmpty) { - std::filesystem::path archive_path{"/some/path/to/file.tar.gz.ukn"}; - - ASSERT_TRUE(xwim::ext(archive_path).empty()); -} diff --git a/tests/ahaahm.tar.gz b/tests/ahaahm.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c35f252d95e641102f1c7ecaf21978f821eece32 GIT binary patch literal 213 zcmV;`04o0nT$|}b7{HZZ^JovVc zskFV@?GxvI?Z4hJ#y=qp-Q#+@oWs3ybCp8Ae~m_v{~CPwkBcyrFNJLX0)&#}zXlWj z8-Mb}?uh?kj7s=N@$Em>3*%5Mg9NMh-$v(QaGRwwA(mij{+ApD`Tegz8|wcWQ2!GI PL9CM}Ojyph01^NIXd7jP literal 0 HcmV?d00001 diff --git a/tests/ahaahm/äh🦔~öhm/ähä~öhm.txt b/tests/ahaahm/äh🦔~öhm/ähä~öhm.txt new file mode 100644 index 0000000..eac8994 --- /dev/null +++ b/tests/ahaahm/äh🦔~öhm/ähä~öhm.txt @@ -0,0 +1 @@ +äahääm diff --git a/tests/ahaahm/äh🦔~öhm/ähä~öhm/ähä~öhm.txt b/tests/ahaahm/äh🦔~öhm/ähä~öhm/ähä~öhm.txt new file mode 100644 index 0000000..eac8994 --- /dev/null +++ b/tests/ahaahm/äh🦔~öhm/ähä~öhm/ähä~öhm.txt @@ -0,0 +1 @@ +äahääm diff --git a/tests/root.tar.gz b/tests/root.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..79ced2b1ba3da4b934918aaeb13d9eff542e2834 GIT binary patch literal 153 zcmb2|=HTGz_Kag-u1M4^$t}<;Ni1S`d(n{ZumX=mVBaC$ET;p{Pfl3qEZjNaH@ni- zQ&(0oGoPyOW>-#pxxDl&|K({Ss}}k#cU<@Rtc860LGKSzy%y@Jxz3Mw`~9A_JZ0_7 zORsm 1 and not fnmatch(f, sys.argv[1]): + continue; + + print(f"Running {f}") + print(f"{os.path.join(root,f)}") + r = subprocess.run(["../../../target/src/xwim", os.path.join(root, f)], capture_output=True, encoding='utf-8') + print(f"{r.stdout}") + print(f"{r.stderr}", file=sys.stderr) diff --git a/tests/test-1.23.7z b/tests/test-1.23.7z new file mode 100644 index 0000000000000000000000000000000000000000..b3e1ea738c88c6a9f97b5fd78adb90bfd1bb51d3 GIT binary patch literal 183 zcmXr7+Ou9=hJi_N{__WA3=p6QrClsl*cccZtJ_Wn7k+&@!@%^{(SsKM4rD&_On)r- zc0#eU>7%X`i8od|*W1k5GpBLEz0RuD^WJpK-1c%&gZ+7H*;y{G@^iC=*2;g}>@>Ao zLwVP&2J`hxK5%bjdL*jj%AU&4!u$FGhl#{)Z!9dLp>v7y~Ls{1_qXRy*&&J39pP9^nhA{ zs^{-q?CgrHi-}>0AcU`d)Y(-KYG|T<5(C4I>^Cz&noZ%Fx1ece!K&F%-$>t>fkFS; l(fuIpW?=0CK)ZLNX=lKyJuN>!DY1xwVXt3TIY>VP0|1MrFxCJ7 literal 0 HcmV?d00001 diff --git a/tests/test-1.23.cpio b/tests/test-1.23.cpio new file mode 100644 index 0000000000000000000000000000000000000000..07777391b618803c1be87a8cde1cfdccc0a40e99 GIT binary patch literal 512 zcmX?J$jGrt@U7zu<`>K?3=9m;uDcg=0ci$?lGNf7T|+%1V}|2EHJhPon89k+FXlm2 zqi+aSwFRn*39M?%Vm@?L`bJ=N+XR<1f^1}jsuRFerw_4rD~gFbG3-qQo3|asyqy^K zCh8}F)$Kr0w|lW5n!RcH`ALaI3_!JD2`~Y2BM5MV$&esNPaoGHMMXt0cgPa}>ljV? literal 0 HcmV?d00001 diff --git a/tests/test-1.23.lzh b/tests/test-1.23.lzh new file mode 100644 index 0000000000000000000000000000000000000000..942e2cb61db47ade450b3f849aba6d92ec35835f GIT binary patch literal 314 zcmb1~tDBRNqAS4w0j`b3_6m$Zb|@=DzyU{ghQJrhFPK>wm<<23GlUpPpYUT~kemm7ZSdTE&M>oNG*wXUzlM;*2Gy+3mH&_n?0QFTy761SM literal 0 HcmV?d00001 diff --git a/tests/test-1.23.rar b/tests/test-1.23.rar new file mode 100644 index 0000000000000000000000000000000000000000..b12fa1e4d7cb4940fea2518c25df05ba0b5a70c7 GIT binary patch literal 272 zcmWGaEK-zWXE;Bhn1O+p0RmREl_)f*GH^h-%pm&Onix}AV^)SGjSLKiF-9@Q4EsCM zzpea##p`*A!UQzMH^7RS!HN@Ok{Axa6nF3f6>FfHd=spg4XijVKR+q42%-M8NXY}B z;V=MpiJCyOy@&xb!&^tNOBfE69{?&+hN)pdQp5;R#BkvFJN!x#84et=t!8jwX8-_$ Cu|XXG literal 0 HcmV?d00001 diff --git a/tests/test-1.23.tar b/tests/test-1.23.tar new file mode 100644 index 0000000000000000000000000000000000000000..7374619c15086e5781b444dccee76647e0381256 GIT binary patch literal 10240 zcmeH}O%8(~5JowQ7ieXWpYvd1w_1ow|L6N3M3!X#J`2s&e*WM5n>|2-l8tCK3y{N(@Gk0L8P{Wr(|=0C@Oe*YoY%CIzaj8qGbl+@@7WMH`XyY)Z=LxTgu{{{y6VupDP42%o{3>*dwH`ojq7#P3= zlct)0n#VDh^p$_?Hg6XwG49Zs&f4SZzRvoV*%28YB`&`}kt#fw}m0w#c*4FJfrM^gX* literal 0 HcmV?d00001 diff --git a/tests/test-1.23.tar.gz b/tests/test-1.23.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..b32be494e2f006dff04901f22e5eb9014b23c9f3 GIT binary patch literal 220 zcmV<203-h&iwFSKutP-v1MSvJ4uUWgK+!IR4XAznt_KpFl0e+N`_M0=y7kr1uYBF82M%-4@B5p1f@*Y? z-Mpaxt$+I)?|+o#{SU(Z-@~?lS80u+`@i&`@4w~#?_uqK9)_+RYphY$KmY%mU>yAc W0000000000fKpeG0=6CiC;$L1g>-cQ literal 0 HcmV?d00001 diff --git a/tests/test-1.23.tar.lrz b/tests/test-1.23.tar.lrz new file mode 100644 index 0000000000000000000000000000000000000000..e24711bf82eba8430ea8edc9342444513ee4aaf8 GIT binary patch literal 315 zcmeYXit=P&W6)rLf>7hbBeR>#%2*%F=F++kdYhv5J;>~+tPka> zD2zCo)AY7eDoCKG<#Cc=#vJCn%7&a}-IK2s+voLUI9yVU%3?M3NsZ4lnp`@WL$dDO zCaLSM=cpuY>*{|l`t3(Y^V-FqTLbSjx=*>^v3cVGtEOA~=Q!woI{Z)nT64<79{bL?7t@S#l~hW5 Hc1jumDH?`X literal 0 HcmV?d00001 diff --git a/tests/test-1.23.tar.lzma b/tests/test-1.23.tar.lzma new file mode 100644 index 0000000000000000000000000000000000000000..27d783c551b10fab1c480722b83f6e4deb2afcc2 GIT binary patch literal 193 zcmV;y06za+004jh04M+e0000006G~;&K-QxuJA6hTRj5$Urq)b&XVUsIACm|~L^x=H6GZy|RP0Nbrv0NAFI zobVW%amiycsb9LG+RLfS)+5MS#eZT=x7do@R_05Y-*f|cq^0{DL{VA0Woi$7OB@!J vA_-{la%(;1n+o4BF1cyaz3;PXax(y3+5Nh0dRdc z(eyC`^(E>jfpzV~sp}S+E;gX9wEX;}#3Hc9-544fnZ%iKIg}Uf?j?;NCe+!i5NC&0 zFfasoBlKfB7+JpsP(RrDK;0ncqwB_WII`|Mpl+BqfChlP0WpA;4dgIpAlwh6mxDMA E0GEwJdl&uQ|7HIB{ZIeBPkdW1*S1bJdrjaq`~UxEC&>I|WPpN(pzsMy+vFHD7#LC# zOA_IM0`xB|TrCWdLKG6Z;BYmx1WF)#B0UuW6AGZa(l_O z-`rBd;ZkBIQvYvn$e677v-Q=Jw#izvw}x&$`TEzB5FHObtLU;tLX#}>A8&tl=j*2F zXREj8EU&Hqd~f-4d#~jNf4E<~vR{79-gD7^!KnWh6>i)%%dcGBAIBWW_Wt#|^S`I( z@BY7e+do5%=l?lUquS2Du=?Ns@1zot_q;Urlv$Zu{QrpG*(>%l{$hstoWY@8`hoYP JDb3H& zsQtT+U1-iEhr9cytXROjwOPpb-OLh)$!0rqonI|4nXq`HdT8%F*Y}?_F1~(SvD~G4 z@#2XBYcDCCi@f@yDmp55*_A%u#k)58zdXCg|Nj4wsxQ;C)EBJS-@mi|!n}XgH@=xq z^>YaP|Dfpq3z@&)Kis(=7OBk6SA609@7a}2StV2N?pg4EZT)ZQ_w`er{^dXP_x|B+ z_2HSli+=C_GXMSlr~lq3zO9#QTPK^nCh(g5|NpZSWd1TTKtV%L_yneHats;_3@M2v ziQquVsme_xB3up4E#To2%fQgU05Sv&B)a#=)G|gbJ&{wHTgg+p^7nb+z{>TChnRb> zovT=;@0~Zj<$qciPgeRWVOIvh`D^z#>m{;Xzfu%gIOU(kRmPPW$#?YiIK}2iy!gI; zz43vqmqZU(sxV|RIO$Z0m+%$*3OqRXMacW$$~-l3ug4#llfngZ-~V=-zCHNEySb~_ s?W}h2a|XG;@Ub#!vAaBPUD5AU?mK~t?$k|M@M&_f*Cip1Nevem03{3TDgXcg literal 0 HcmV?d00001 diff --git a/tests/test-deep-recursion.tar b/tests/test-deep-recursion.tar new file mode 100644 index 0000000000000000000000000000000000000000..aa6216472c46c1e58e5bad91b240b80830653195 GIT binary patch literal 10240 zcmeIzJr05}7zW@kvUm$So2ad{ba(I)P7;Z6GJ%p9uHeN?yoRfHu#GT?jXw#EQQr;} zN@&XS(vPA{SDSo7Ase?%b56DsTHW;SmTM%qmQpEuki>QPl~&yhz7Lq94|?|<9XX93>R?f=*7e`4!@EZzP`{SOdEYs$O)1N;fztN$*4 zrMdn8qyD$T3UG<~9{?3oLI45~fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= I5cq(=1vP+c(EtDd literal 0 HcmV?d00001 diff --git a/tests/test-dot-first-bomb.tar.gz b/tests/test-dot-first-bomb.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3f81d5c718dd082f13dfc1dd284464f68ce640fb GIT binary patch literal 145 zcmb2|=3wZM({f{AetX%L>#zY&TjE*ER{seeKR2G6?68?F=KH_WTY9lkRy!0w*mbjU zstCm2UVB@uG*dA2dzRhatJ4F07Jps5^QS`AtG(VAPLJaXqf6Kd#gyee`Gq*Za*U zl^R(NUH`h=``!7|N^dhnL*=gqRjl@p^I6P$Z_?7mDU8esp&yariL-T*)+5P?V{``0TYx9$x0Re7ov_9Yb+L=LvfdK#% CS4f)x literal 0 HcmV?d00001 diff --git a/tests/test-empty.tar.bz2 b/tests/test-empty.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..a70463740ad1149f75a68a13fc3c0fc7b22c68fd GIT binary patch literal 46 zcmZ>Y%CIzaj8qGbjI7@Agn>aMfZ+fG3j+g(0)xRBR?TI?N$TA@mF8%8=kY5~ literal 0 HcmV?d00001 diff --git a/tests/test-one-archive.tar.gz b/tests/test-one-archive.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..5799800734e25d94a6634624093d83fdd364b67a GIT binary patch literal 175 zcmb2|=HO^sROZ3JT#{N`qMM(Ws+(ApoRL|Us#lU&#PIfM!KvMPG{|F~!p_X5o8BoCCcMA&JS2AcYFaQ9`R!fBd literal 0 HcmV?d00001 diff --git a/tests/test-onedir.tar.bz2 b/tests/test-onedir.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..7e734c1e07c536c0f0743645ab5b9bf2b55640cb GIT binary patch literal 160 zcmV;R0AK$?T4*^jL0KkKS>NMXmjD3H`-H%N0DwRM|9}FBa{#_T00BSEB!s znT9hBnZZbqa Oi@744C`fPdtjmBNDM$1G literal 0 HcmV?d00001 diff --git a/tests/test-onedir.tar.gz b/tests/test-onedir.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a7b3ee12a1188981ebcaf0f57423135356542776 GIT binary patch literal 158 zcmb2|=3uBuJLk&4{Pwap*I@+_hrsEN_#WN=sxraP`K<7+KUsF7+3;oM`uN^;NUH78?&;L0_e;FANpuyO`WHXC9 Ig9ZZw06RWM%>V!Z literal 0 HcmV?d00001 diff --git a/tests/test-onefile.tar.gz b/tests/test-onefile.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e4fed682bc55aeed31ef50634135448b28ba23ac GIT binary patch literal 125 zcmb2|=3sb|;O5T2{Puz)SF?kF%f-0ruAL1RY!{!a6k&T57X9Ie6i1UZGvmYq^|Pa{ zEYr~6d_68~`tKL(f@_yQ{WeA3)2G({{e}vhP0DwRP|9}txz(99qULXJg00=MuxuJ}j zWDJ@a21b|>g?f!l(KG-6004@aN$O<}Nt&LZJww!K>56FYr{6CV8nrirp+C9Ubv`w!znvU%;MGx_JBvXY6 I2v#G~P#G&yxBvhE literal 0 HcmV?d00001 diff --git a/tests/test-recursive-no-prompt.tar.bz2 b/tests/test-recursive-no-prompt.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..ff439e5266648c68488e3ce18837ca0604a3a6fb GIT binary patch literal 295 zcmZ>Y%CIzaj8qGbT&CA3$G~vz|NmnLcp3tq*FP|D^f3736lcM}!N9`Ez>ws?%E02n zz`$X^D8YD!0RrF*hOU;Z4FABzS90AP7%uSgO0KAymz95WzZ}oD4gL^*EcEMhSgf0bDF|w{f;jHRK9d9^+cC5oGm%cXM#1r)F8d@60c0t6%-e zik=dz#F#XJ)n>2DT?Z9SMq?)qm!Kq9&-zf02|->?N&!nmEx-BAD)0&xYU6U4E-R$4 zBx%iJJwwlxsyfSzjx1SvGGIw>V1LW+lB$SN|t`=L#&E n$`!+Bv!yGxX!5GFRp09B{@uRIs^9v-;lFs1t3|*BP{05H*`0Gw literal 0 HcmV?d00001 diff --git a/tests/test-tar-with-node.tar.gz b/tests/test-tar-with-node.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..f12ba42cbefb6e86f7b8509214f4cd87310a9e98 GIT binary patch literal 166 zcmb2|=3scGD(S(%{PvO~*I@;L*2MlttWj51SoRBWHEt6#{hqHBJ9AQ5pm^*5+dT%% zeKzMm*Xn8B(fb*av?uLiV^n2!cI?)z^R~vNPx-u9vgOjTem{?^$uqA_^7aVo5=pk4 z_4~^I;KWn?_sXyQsh#}$!M*4E{|e_$F?8bFD}K9Xc74P$OSvzvjknZ?{(h{>$bbYA Po^uu*Y%CIzaj8qGbl#PqL%D}*IkbyyfAwhvbafW0|V!29iD<|XCr*i`U*#ir( literal 0 HcmV?d00001 diff --git a/tests/test-text.gz b/tests/test-text.gz new file mode 100644 index 0000000000000000000000000000000000000000..e4275622cbbf121343c0698765c01e27df77e956 GIT binary patch literal 23 ecmb2|=3t0+(sE;9K7HZ|6GK&1{##}S1_l65F9weQ literal 0 HcmV?d00001 diff --git a/tests/test-text.lrz b/tests/test-text.lrz new file mode 100644 index 0000000000000000000000000000000000000000..92b32d5a2eed6a4f0f80118af9e27e5c01d6796c GIT binary patch literal 72 zcmeYXit=P&V`e}Bj0_Bnj0`|Q4j>j|=Hg-iaTpjf7V8NyGcz+}WO9}H{pzs2B`0{> LJzd7jdha{{)i(;v literal 0 HcmV?d00001 diff --git a/tests/test-text.lz b/tests/test-text.lz new file mode 100644 index 0000000000000000000000000000000000000000..b1d0f2fdc8d5d98625d787fdf9b34c8b57d81963 GIT binary patch literal 39 kcmeZ?@(f_)VK9-h4bZ;-|Njpr28ODt{I|>u5TFjF0o-^9qyPW_ literal 0 HcmV?d00001 diff --git a/tests/test-text.xz b/tests/test-text.xz new file mode 100644 index 0000000000000000000000000000000000000000..75ef86164ea1ea02da3d26f0cdda878475938fa9 GIT binary patch literal 60 zcmexsUKJ6=z`*kC+7>q^21Q0O1_p)_{ill=8JIFMxfmFJSHF0n72)j9z$nekt-n)1 Pe%t3-MxYu7mdGdoCdd%i literal 0 HcmV?d00001 diff --git a/tests/xwim-0.5.0-x86_64-linux.tar.gz b/tests/xwim-0.5.0-x86_64-linux.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..4fa6b6f367c2d5261213b3e079f28e8576a2d668 GIT binary patch literal 63854 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≷o?QGnq&j^7ZL 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 Xf8PGQ{dxQIllJ*PIT|>000aX7Ryt`K literal 0 HcmV?d00001