From 2c6b1568030754a9f49a031a58627a21d007b41a Mon Sep 17 00:00:00 2001 From: Valtteri Koskivuori Date: Mon, 3 Jul 2023 17:45:59 +0300 Subject: [PATCH] Userland: Teach the file utility about zip files It now shows a short description with a file and directory counts, and the total content size uncompressed. --- Meta/Lagom/CMakeLists.txt | 2 +- Userland/BuggieBox/CMakeLists.txt | 2 +- Userland/Utilities/CMakeLists.txt | 2 +- Userland/Utilities/file.cpp | 27 +++++++++++++++++++++++++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index 786b8fb3db..e0de29926a 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -512,7 +512,7 @@ if (BUILD_LAGOM) if (NOT EMSCRIPTEN) # LibELF is part of LibC in SerenityOS builds, but not in Lagom. add_executable(file ../../Userland/Utilities/file.cpp) - target_link_libraries(file LibAudio LibCompress LibCore LibELF LibGfx LibIPC LibMain) + target_link_libraries(file LibAudio LibArchive LibCompress LibCore LibELF LibGfx LibIPC LibMain) endif() add_executable(gml-format ../../Userland/Utilities/gml-format.cpp) diff --git a/Userland/BuggieBox/CMakeLists.txt b/Userland/BuggieBox/CMakeLists.txt index 2f2464e05b..66714a6ae3 100644 --- a/Userland/BuggieBox/CMakeLists.txt +++ b/Userland/BuggieBox/CMakeLists.txt @@ -41,7 +41,7 @@ set(utility_srcs serenity_bin(BuggieBox) target_sources(BuggieBox PRIVATE main.cpp) -target_link_libraries(BuggieBox PRIVATE LibMain LibShell LibCompress LibCore LibCrypto LibFileSystem LibGfx LibLine LibRegex LibAudio) +target_link_libraries(BuggieBox PRIVATE LibMain LibShell LibArchive LibCompress LibCore LibCrypto LibFileSystem LibGfx LibLine LibRegex LibAudio) foreach(file IN LISTS utility_srcs) buggiebox_utility(${file}) diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index 5ff7a4dc40..bbfc94a9fa 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/Userland/Utilities/CMakeLists.txt @@ -90,7 +90,7 @@ target_link_libraries(diff PRIVATE LibDiff) target_link_libraries(disasm PRIVATE LibX86) target_link_libraries(expr PRIVATE LibRegex) target_link_libraries(fdtdump PRIVATE LibDeviceTree) -target_link_libraries(file PRIVATE LibGfx LibIPC LibCompress LibAudio) +target_link_libraries(file PRIVATE LibGfx LibIPC LibArchive LibCompress LibAudio) target_link_libraries(functrace PRIVATE LibDebug LibX86) target_link_libraries(gml-format PRIVATE LibGUI) target_link_libraries(grep PRIVATE LibFileSystem LibRegex) diff --git a/Userland/Utilities/file.cpp b/Userland/Utilities/file.cpp index 710a4813ba..585caff098 100644 --- a/Userland/Utilities/file.cpp +++ b/Userland/Utilities/file.cpp @@ -4,8 +4,10 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include +#include #include #include #include @@ -104,6 +106,30 @@ static ErrorOr> gzip_details(StringView description, StringView return TRY(String::formatted("{}, {}", description, gzip_details.value())); } +static ErrorOr> zip_details(StringView description, StringView path) +{ + auto mapped_file = TRY(Core::MappedFile::map(path)); + auto zip_file = Archive::Zip::try_create(mapped_file->bytes()); + u32 files = 0; + u32 directories = 0; + u64 total_bytes = 0; + TRY(zip_file->for_each_member([&](auto zip_member) -> ErrorOr { + if (zip_member.is_directory) + directories++; + else + files++; + total_bytes += zip_member.uncompressed_size; + return IterationDecision::Continue; + })); + return TRY(String::formatted("{}, {} {}, {} {} totaling {} uncompressed", + description, + directories, + directories == 1 ? "directory" : "directories", + files, + files == 1 ? "file" : "files", + AK::human_readable_size(total_bytes))); +} + static ErrorOr> elf_details(StringView description, StringView path) { auto mapped_file = TRY(Core::MappedFile::map(path)); @@ -146,6 +172,7 @@ static ErrorOr> elf_details(StringView description, StringView __ENUMERATE_MIME_TYPE_DESCRIPTION("application/tar"sv, "tape archive"sv, description_only) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("application/wasm"sv, "WebAssembly bytecode"sv, description_only) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("application/x-7z-compressed"sv, "7-Zip archive"sv, description_only) \ + __ENUMERATE_MIME_TYPE_DESCRIPTION("application/zip"sv, "ZIP archive"sv, zip_details) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("audio/flac"sv, "FLAC audio"sv, audio_details) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("audio/midi"sv, "MIDI notes"sv, audio_details) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("audio/mpeg"sv, "MP3 audio"sv, audio_details) \