diff --git a/Userland/Utilities/cksum.cpp b/Userland/Utilities/cksum.cpp index 4710c9ab8d..b432af7973 100644 --- a/Userland/Utilities/cksum.cpp +++ b/Userland/Utilities/cksum.cpp @@ -41,18 +41,39 @@ int main(int argc, char** argv) bool fail = false; for (auto& path : paths) { - auto file = Core::File::construct((StringView(path) == "-") ? "/dev/stdin" : path); + auto filepath = (StringView(path) == "-") ? "/dev/stdin" : path; + auto file = Core::File::construct(filepath); if (!file->open(Core::OpenMode::ReadOnly)) { warnln("{}: {}: {}", argv[0], path, file->error_string()); fail = true; continue; } - auto file_buffer = file->read_all(); - auto bytes = file_buffer.bytes().size(); + struct stat st; + if (fstat(file->fd(), &st) < 0) { + warnln("{}: Failed to fstat {}: {}", argv[0], filepath, strerror(errno)); + fail = true; + continue; + } if (algorithm == "crc32") { - outln("{} {} {}", Crypto::Checksum::CRC32 { file_buffer.bytes() }.digest(), bytes, path); + Crypto::Checksum::CRC32 crc32; + while (!file->eof() && !file->has_error()) + crc32.update(file->read(PAGE_SIZE)); + if (file->has_error()) { + warnln("Failed to read {}: {}", filepath, file->error_string()); + fail = true; + continue; + } + outln("{} {} {}", crc32.digest(), st.st_size, path); } else if (algorithm == "adler32") { - outln("{} {} {}", Crypto::Checksum::Adler32 { file_buffer.bytes() }.digest(), bytes, path); + Crypto::Checksum::Adler32 adler32; + while (!file->eof() && !file->has_error()) + adler32.update(file->read(PAGE_SIZE)); + if (file->has_error()) { + warnln("Failed to read {}: {}", filepath, file->error_string()); + fail = true; + continue; + } + outln("{} {} {}", adler32.digest(), st.st_size, path); } else { warnln("{}: Unknown checksum algorithm: {}", argv[0], algorithm); exit(1);