mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-22 10:36:24 +00:00
Utilities: Add shred utility
This commit is contained in:
parent
892da127d0
commit
f5cacf25e1
|
@ -143,6 +143,7 @@ target_link_libraries(run-tests PRIVATE LibCoredump LibDebug LibELF LibFileSyste
|
|||
target_link_libraries(rm PRIVATE LibFileSystem)
|
||||
target_link_libraries(sed PRIVATE LibRegex LibFileSystem)
|
||||
target_link_libraries(shot PRIVATE LibFileSystem LibGfx LibGUI LibIPC LibURL)
|
||||
target_link_libraries(shred PRIVATE LibFileSystem)
|
||||
target_link_libraries(slugify PRIVATE LibUnicode)
|
||||
target_link_libraries(sql PRIVATE LibFileSystem LibIPC LibLine LibSQL)
|
||||
target_link_libraries(su PRIVATE LibCrypt)
|
||||
|
|
75
Userland/Utilities/shred.cpp
Normal file
75
Userland/Utilities/shred.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Romain Chardiny <romain.chardiny@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibFileSystem/FileSystem.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
TRY(Core::System::pledge("stdio unix rpath wpath cpath"));
|
||||
|
||||
Vector<StringView> paths;
|
||||
bool remove_file = false;
|
||||
bool verbose = false;
|
||||
u32 iterations = 3;
|
||||
Optional<StringView> random_source;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(remove_file, "Deallocate and remove file after overwriting", nullptr, 'u');
|
||||
args_parser.add_option(verbose, "Show progress", "verbose", 'v');
|
||||
args_parser.add_option(iterations, "Overwrite N times instead of the default (3)", "iterations", 'n', "N");
|
||||
args_parser.add_option(random_source, "Get random bytes from FILE", "random-source", 0, "FILE");
|
||||
args_parser.add_positional_argument(paths, "Path(s) to overwrite", "FILE", Core::ArgsParser::Required::Yes);
|
||||
args_parser.parse(arguments);
|
||||
|
||||
auto rng_file = TRY(Core::File::open(random_source.value_or("/dev/random"sv), Core::File::OpenMode::Read));
|
||||
|
||||
for (auto& path : paths) {
|
||||
auto file = TRY(Core::File::open(path, Core::File::OpenMode::ReadWrite | Core::File::OpenMode::DontCreate));
|
||||
|
||||
off_t output_file_length = TRY(FileSystem::size_from_fstat(file->fd()));
|
||||
|
||||
for (u32 iter = 0; iter < iterations; iter++) {
|
||||
if (verbose)
|
||||
outln("shred: {}: pass {}/{} (random)", path, iter + 1, iterations);
|
||||
|
||||
Array<u8, BUFSIZ> buffer;
|
||||
off_t total_written = 0;
|
||||
ssize_t nread = 0;
|
||||
ssize_t nwritten = 0;
|
||||
|
||||
while (total_written < output_file_length) {
|
||||
auto buffer_span = buffer.span().trim(output_file_length - total_written);
|
||||
|
||||
nread = TRY(Core::System::read(rng_file->fd(), buffer_span));
|
||||
|
||||
if (nread == 0)
|
||||
break;
|
||||
|
||||
nwritten = TRY(Core::System::write(file->fd(), buffer_span));
|
||||
|
||||
if (nwritten == 0)
|
||||
break;
|
||||
|
||||
total_written += nwritten;
|
||||
}
|
||||
|
||||
TRY(Core::System::fsync(file->fd()));
|
||||
TRY(file->seek(0, SeekMode::SetPosition));
|
||||
}
|
||||
|
||||
if (remove_file) {
|
||||
TRY(Core::System::ftruncate(file->fd(), 0));
|
||||
TRY(Core::System::unlink(path));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue