diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index bb59a8bcb2b..8ba04b797d1 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -455,11 +455,6 @@ if (ENABLE_GUI_TARGETS) endif() lagom_utility(js SOURCES ../../Utilities/js.cpp LIBS LibCrypto LibJS LibLine LibUnicode LibMain LibTextCodec LibGC Threads::Threads) - -lagom_utility(gzip SOURCES ../../Utilities/gzip.cpp LIBS LibCompress LibMain) -lagom_utility(lzcat SOURCES ../../Utilities/lzcat.cpp LIBS LibCompress LibMain) - -lagom_utility(tar SOURCES ../../Utilities/tar.cpp LIBS LibArchive LibCompress LibFileSystem LibMain) lagom_utility(test262-runner SOURCES ../../Tests/LibJS/test262-runner.cpp LIBS LibJS LibFileSystem LibGC) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") @@ -481,7 +476,6 @@ endif() lagom_utility(wasm SOURCES ../../Utilities/wasm.cpp LIBS LibFileSystem LibWasm LibLine LibMain LibJS) lagom_utility(xml SOURCES ../../Utilities/xml.cpp LIBS LibFileSystem LibMain LibXML LibURL) -lagom_utility(xzcat SOURCES ../../Utilities/xzcat.cpp LIBS LibCompress LibMain) include(CTest) if (BUILD_TESTING) diff --git a/Utilities/gzip.cpp b/Utilities/gzip.cpp deleted file mode 100644 index c8d789eb58c..00000000000 --- a/Utilities/gzip.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2021, Idan Horowitz - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -ErrorOr serenity_main(Main::Arguments arguments) -{ - Vector filenames; - bool keep_input_files { false }; - bool write_to_stdout { false }; - bool decompress { false }; - - Core::ArgsParser args_parser; - args_parser.add_option(keep_input_files, "Keep (don't delete) input files", "keep", 'k'); - args_parser.add_option(write_to_stdout, "Write to stdout, keep original files unchanged", "stdout", 'c'); - args_parser.add_option(decompress, "Decompress", "decompress", 'd'); - args_parser.add_positional_argument(filenames, "Files", "FILES", Core::ArgsParser::Required::No); - args_parser.parse(arguments); - - auto program_name = LexicalPath::basename(arguments.strings[0]); - - // NOTE: If the user run this program via the /bin/zcat or /bin/gunzip symlink, - // then emulate gzip decompression. - if (program_name == "zcat"sv || program_name == "gunzip"sv) - decompress = true; - - if (program_name == "zcat"sv) - write_to_stdout = true; - - if (filenames.is_empty()) { - filenames.append("-"sv); - write_to_stdout = true; - } - - if (write_to_stdout) - keep_input_files = true; - - for (auto const& input_filename : filenames) { - OwnPtr output_stream; - - if (write_to_stdout) { - output_stream = TRY(Core::File::standard_output()); - } else if (decompress) { - if (!input_filename.ends_with(".gz"sv)) { - warnln("unknown suffix for: {}, skipping", input_filename); - continue; - } - - auto output_filename = input_filename.substring_view(0, input_filename.length() - ".gz"sv.length()); - output_stream = TRY(Core::File::open(output_filename, Core::File::OpenMode::Write)); - } else { - auto output_filename = ByteString::formatted("{}.gz", input_filename); - output_stream = TRY(Core::File::open(output_filename, Core::File::OpenMode::Write)); - } - - VERIFY(output_stream); - - NonnullOwnPtr input_file = TRY(Core::File::open_file_or_standard_stream(input_filename, Core::File::OpenMode::Read)); - - // Buffer reads, which yields a significant performance improvement. - NonnullOwnPtr input_stream = TRY(Core::InputBufferedFile::create(move(input_file), 1 * MiB)); - - if (decompress) { - input_stream = TRY(try_make(move(input_stream))); - } else { - output_stream = TRY(try_make(output_stream.release_nonnull())); - } - - auto buffer = TRY(ByteBuffer::create_uninitialized(1 * MiB)); - - while (!input_stream->is_eof()) { - auto span = TRY(input_stream->read_some(buffer)); - TRY(output_stream->write_until_depleted(span)); - } - - if (!keep_input_files) - TRY(Core::System::unlink(input_filename)); - } - - return 0; -} diff --git a/Utilities/lzcat.cpp b/Utilities/lzcat.cpp deleted file mode 100644 index d0e48f96c7b..00000000000 --- a/Utilities/lzcat.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2023, Tim Schumacher - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include - -ErrorOr serenity_main(Main::Arguments arguments) -{ - StringView filename; - - Core::ArgsParser args_parser; - args_parser.set_general_help("Decompress and print an LZMA archive"); - args_parser.add_positional_argument(filename, "File to decompress", "file"); - args_parser.parse(arguments); - - auto file = TRY(Core::File::open_file_or_standard_stream(filename, Core::File::OpenMode::Read)); - auto buffered_file = TRY(Core::InputBufferedFile::create(move(file))); - auto stream = TRY(Compress::LzmaDecompressor::create_from_container(move(buffered_file))); - - // Arbitrarily chosen buffer size. - Array buffer; - while (!stream->is_eof()) { - auto slice = TRY(stream->read_some(buffer)); - out("{:s}", slice); - } - - return 0; -} diff --git a/Utilities/tar.cpp b/Utilities/tar.cpp deleted file mode 100644 index c1e57b5e5c5..00000000000 --- a/Utilities/tar.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) 2020, Peter Elliott - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -constexpr size_t buffer_size = 4096; - -ErrorOr serenity_main(Main::Arguments arguments) -{ - bool create = false; - bool extract = false; - bool list = false; - bool verbose = false; - bool gzip = false; - bool lzma = false; - bool xz = false; - bool no_auto_compress = false; - StringView archive_file; - bool dereference = false; - StringView directory; - Vector paths; - - Core::ArgsParser args_parser; - args_parser.add_option(create, "Create archive", "create", 'c'); - args_parser.add_option(extract, "Extract archive", "extract", 'x'); - args_parser.add_option(list, "List contents", "list", 't'); - args_parser.add_option(verbose, "Print paths", "verbose", 'v'); - args_parser.add_option(gzip, "Compress or decompress file using gzip", "gzip", 'z'); - args_parser.add_option(lzma, "Compress or decompress file using lzma", "lzma"); - args_parser.add_option(xz, "Compress or decompress file using xz", "xz", 'J'); - args_parser.add_option(no_auto_compress, "Do not use the archive suffix to select the compression algorithm", "no-auto-compress"); - args_parser.add_option(directory, "Directory to extract to/create from", "directory", 'C', "DIRECTORY"); - args_parser.add_option(archive_file, "Archive file", "file", 'f', "FILE"); - args_parser.add_option(dereference, "Follow symlinks", "dereference", 'h'); - args_parser.add_positional_argument(paths, "Paths", "PATHS", Core::ArgsParser::Required::No); - args_parser.parse(arguments); - - if (create + extract + list != 1) { - warnln("exactly one of -c, -x, and -t can be used"); - return 1; - } - - if (!no_auto_compress && !archive_file.is_empty()) { - if (archive_file.ends_with(".gz"sv) || archive_file.ends_with(".tgz"sv)) - gzip = true; - if (archive_file.ends_with(".lzma"sv)) - lzma = true; - if (archive_file.ends_with(".xz"sv)) - xz = true; - } - - if (list || extract) { - NonnullOwnPtr input_stream = TRY(Core::InputBufferedFile::create(TRY(Core::File::open_file_or_standard_stream(archive_file, Core::File::OpenMode::Read)))); - - if (!directory.is_empty()) - TRY(Core::System::chdir(directory)); - - if (gzip) - input_stream = make(move(input_stream)); - - if (lzma) - input_stream = TRY(Compress::LzmaDecompressor::create_from_container(move(input_stream))); - - if (xz) - input_stream = TRY(Compress::XzDecompressor::create(move(input_stream))); - - auto tar_stream = TRY(Archive::TarInputStream::construct(move(input_stream))); - - HashMap global_overrides; - HashMap local_overrides; - - auto get_override = [&](StringView key) -> Optional { - Optional maybe_local = local_overrides.get(key); - - if (maybe_local.has_value()) - return maybe_local; - - Optional maybe_global = global_overrides.get(key); - - if (maybe_global.has_value()) - return maybe_global; - - return {}; - }; - - while (!tar_stream->finished()) { - Archive::TarFileHeader const& header = tar_stream->header(); - - // Handle meta-entries earlier to avoid consuming the file content stream. - if (header.content_is_like_extended_header()) { - switch (header.type_flag()) { - case Archive::TarFileType::GlobalExtendedHeader: { - TRY(tar_stream->for_each_extended_header([&](StringView key, StringView value) { - if (value.length() == 0) - global_overrides.remove(key); - else - global_overrides.set(key, value); - })); - break; - } - case Archive::TarFileType::ExtendedHeader: { - TRY(tar_stream->for_each_extended_header([&](StringView key, StringView value) { - local_overrides.set(key, value); - })); - break; - } - default: - warnln("Unknown extended header type '{}' of {}", (char)header.type_flag(), header.filename()); - VERIFY_NOT_REACHED(); - } - - TRY(tar_stream->advance()); - continue; - } - - Archive::TarFileStream file_stream = tar_stream->file_contents(); - - // Handle other header types that don't just have an effect on extraction. - switch (header.type_flag()) { - case Archive::TarFileType::LongName: { - StringBuilder long_name; - - Array buffer; - - while (!file_stream.is_eof()) { - auto slice = TRY(file_stream.read_some(buffer)); - long_name.append(reinterpret_cast(slice.data()), slice.size()); - } - - local_overrides.set("path", long_name.to_byte_string()); - TRY(tar_stream->advance()); - continue; - } - default: - // None of the relevant headers, so continue as normal. - break; - } - - LexicalPath path = LexicalPath(header.filename()); - if (!header.prefix().is_empty()) - path = path.prepend(header.prefix()); - ByteString filename = get_override("path"sv).value_or(path.string()); - - if (list || verbose) - outln("{}", filename); - - if (extract) { - auto absolute_path = TRY(FileSystem::absolute_path(filename)); - auto parent_path = LexicalPath(absolute_path).parent(); - auto header_mode = TRY(header.mode()); - - switch (header.type_flag()) { - case Archive::TarFileType::NormalFile: - case Archive::TarFileType::AlternateNormalFile: { - MUST(Core::Directory::create(parent_path, Core::Directory::CreateDirectories::Yes)); - - int fd = TRY(Core::System::open(absolute_path, O_CREAT | O_WRONLY, header_mode)); - - Array buffer; - while (!file_stream.is_eof()) { - auto slice = TRY(file_stream.read_some(buffer)); - TRY(Core::System::write(fd, slice)); - } - - TRY(Core::System::close(fd)); - break; - } - case Archive::TarFileType::SymLink: { - MUST(Core::Directory::create(parent_path, Core::Directory::CreateDirectories::Yes)); - - TRY(Core::System::symlink(header.link_name(), absolute_path)); - break; - } - case Archive::TarFileType::Directory: { - MUST(Core::Directory::create(parent_path, Core::Directory::CreateDirectories::Yes)); - - auto result_or_error = Core::System::mkdir(absolute_path, header_mode); - if (result_or_error.is_error() && result_or_error.error().code() != EEXIST) - return result_or_error.release_error(); - break; - } - default: - // FIXME: Implement other file types - warnln("file type '{}' of {} is not yet supported", (char)header.type_flag(), header.filename()); - VERIFY_NOT_REACHED(); - } - } - - // Non-global headers should be cleared after every file. - local_overrides.clear(); - - TRY(tar_stream->advance()); - } - - return 0; - } - - if (create) { - if (paths.size() == 0) { - warnln("you must provide at least one path to be archived"); - return 1; - } - - NonnullOwnPtr output_stream = TRY(Core::File::standard_output()); - - if (!archive_file.is_empty()) - output_stream = TRY(Core::File::open(archive_file, Core::File::OpenMode::Write)); - - if (!directory.is_empty()) - TRY(Core::System::chdir(directory)); - - if (gzip) - output_stream = TRY(try_make(move(output_stream))); - - if (lzma) - output_stream = TRY(Compress::LzmaCompressor::create_container(move(output_stream), {})); - - if (xz) - TODO(); - - Archive::TarOutputStream tar_stream(move(output_stream)); - - auto add_file = [&](ByteString path) -> ErrorOr { - auto file_or_error = Core::File::open(path, Core::File::OpenMode::Read); - if (file_or_error.is_error()) { - warnln("Failed to open {}: {}", path, file_or_error.error()); - return {}; - } - auto file = file_or_error.release_value(); - - auto statbuf = TRY(Core::System::lstat(path)); - auto canonicalized_path = LexicalPath::canonicalized_path(path); - // FIXME: We should stream instead of reading the entire file in one go, but TarOutputStream does not have any interface to do so. - auto file_content = TRY(file->read_until_eof()); - TRY(tar_stream.add_file(canonicalized_path, statbuf.st_mode, file_content)); - if (verbose) - outln("{}", canonicalized_path); - - return {}; - }; - - auto add_link = [&](ByteString path) -> ErrorOr { - auto statbuf = TRY(Core::System::lstat(path)); - - auto canonicalized_path = LexicalPath::canonicalized_path(path); - TRY(tar_stream.add_link(canonicalized_path, statbuf.st_mode, TRY(Core::System::readlink(path)))); - if (verbose) - outln("{}", canonicalized_path); - - return {}; - }; - - auto add_directory = [&](ByteString path, auto handle_directory) -> ErrorOr { - auto statbuf = TRY(Core::System::lstat(path)); - - auto canonicalized_path = LexicalPath::canonicalized_path(path); - TRY(tar_stream.add_directory(canonicalized_path, statbuf.st_mode)); - if (verbose) - outln("{}", canonicalized_path); - - Core::DirIterator it(path, Core::DirIterator::Flags::SkipParentAndBaseDir); - while (it.has_next()) { - auto child_path = it.next_full_path(); - if (!dereference && FileSystem::is_link(child_path)) { - TRY(add_link(child_path)); - } else if (!FileSystem::is_directory(child_path)) { - TRY(add_file(child_path)); - } else { - TRY(handle_directory(child_path, handle_directory)); - } - } - - return {}; - }; - - for (auto const& path : paths) { - if (FileSystem::is_directory(path)) { - TRY(add_directory(path, add_directory)); - } else { - TRY(add_file(path)); - } - } - - TRY(tar_stream.finish()); - - return 0; - } - - return 0; -} diff --git a/Utilities/xzcat.cpp b/Utilities/xzcat.cpp deleted file mode 100644 index 7063ef02794..00000000000 --- a/Utilities/xzcat.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2023, Tim Schumacher - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include - -ErrorOr serenity_main(Main::Arguments arguments) -{ - StringView filename; - - Core::ArgsParser args_parser; - args_parser.set_general_help("Decompress and print an XZ archive"); - args_parser.add_positional_argument(filename, "File to decompress", "file"); - args_parser.parse(arguments); - - auto file = TRY(Core::File::open_file_or_standard_stream(filename, Core::File::OpenMode::Read)); - auto buffered_file = TRY(Core::InputBufferedFile::create(move(file))); - auto stream = TRY(Compress::XzDecompressor::create(move(buffered_file))); - - // Arbitrarily chosen buffer size. - Array buffer; - while (!stream->is_eof()) { - auto slice = TRY(stream->read_some(buffer)); - out("{:s}", slice); - } - - return 0; -}