diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index 1b0c424049..3a839c0b26 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/Userland/Utilities/CMakeLists.txt @@ -20,6 +20,7 @@ target_link_libraries(avol LibAudio) target_link_libraries(bt LibSymbolClient) target_link_libraries(checksum LibCrypto) target_link_libraries(chres LibGUI) +target_link_libraries(cksum LibCrypto) target_link_libraries(copy LibGUI) target_link_libraries(disasm LibX86) target_link_libraries(expr LibRegex) diff --git a/Userland/Utilities/cksum.cpp b/Userland/Utilities/cksum.cpp new file mode 100644 index 0000000000..3eb20d5f35 --- /dev/null +++ b/Userland/Utilities/cksum.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + Vector paths; + const char* opt_algorithm = nullptr; + + Core::ArgsParser args_parser; + args_parser.add_option(opt_algorithm, "Checksum algorithm (default 'crc32', use 'list' to list available algorithms)", "algorithm", '\0', nullptr); + args_parser.add_positional_argument(paths, "File", "file", Core::ArgsParser::Required::No); + args_parser.parse(argc, argv); + + auto algorithm = (opt_algorithm == nullptr) ? "crc32" : String(opt_algorithm).to_lowercase(); + + auto available_algorithms = Vector { "crc32", "adler32" }; + + if (algorithm == "list") { + outln("Available algorithms:"); + for (auto& available_algorithm : available_algorithms) { + outln(available_algorithm); + } + exit(0); + } + + if (!available_algorithms.contains_slow(algorithm)) { + warnln("{}: Unknown checksum algorithm: {}", argv[0], algorithm); + exit(1); + } + + if (paths.is_empty()) + paths.append("-"); + + bool fail = false; + for (auto& path : paths) { + auto file = Core::File::construct((StringView(path) == "-") ? "/dev/stdin" : path); + if (!file->open(Core::IODevice::ReadOnly)) { + warnln("{}: {}: {}", argv[0], path, file->error_string()); + fail = true; + continue; + } + auto file_buffer = file->read_all(); + auto bytes = file_buffer.bytes().size(); + if (algorithm == "crc32") { + outln("{} {} {}", Crypto::Checksum::CRC32 { file_buffer.bytes() }.digest(), bytes, path); + } else if (algorithm == "adler32") { + outln("{} {} {}", Crypto::Checksum::Adler32 { file_buffer.bytes() }.digest(), bytes, path); + } else { + warnln("{}: Unknown checksum algorithm: {}", argv[0], algorithm); + exit(1); + } + } + + return fail; +}