Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/StringBuilder.h>
8#include <AK/Vector.h>
9#include <LibCore/ArgsParser.h>
10#include <LibCore/DeprecatedFile.h>
11#include <LibCore/System.h>
12#include <LibMain/Main.h>
13#include <stdio.h>
14#include <unistd.h>
15
16ErrorOr<int> serenity_main(Main::Arguments arguments)
17{
18 TRY(Core::System::pledge("stdio rpath cpath"));
19
20 bool recursive = false;
21 bool force = false;
22 bool verbose = false;
23 bool no_preserve_root = false;
24 Vector<StringView> paths;
25
26 Core::ArgsParser args_parser;
27 args_parser.add_option(recursive, "Delete directories recursively", "recursive", 'r');
28 args_parser.add_option(force, "Ignore nonexistent files", "force", 'f');
29 args_parser.add_option(verbose, "Verbose", "verbose", 'v');
30 args_parser.add_option(no_preserve_root, "Do not consider '/' specially", "no-preserve-root", 0);
31 args_parser.add_positional_argument(paths, "Path(s) to remove", "path", Core::ArgsParser::Required::No);
32 args_parser.parse(arguments);
33
34 if (!force && paths.is_empty()) {
35 args_parser.print_usage(stderr, arguments.strings[0]);
36 return 1;
37 }
38
39 bool had_errors = false;
40 for (auto& path : paths) {
41 if (!no_preserve_root && path == "/") {
42 warnln("rm: '/' is protected, try with --no-preserve-root to override this behavior");
43 continue;
44 }
45
46 auto result = Core::DeprecatedFile::remove(path, recursive ? Core::DeprecatedFile::RecursionMode::Allowed : Core::DeprecatedFile::RecursionMode::Disallowed);
47
48 if (result.is_error()) {
49 auto error = result.release_error();
50
51 if (force && error.is_errno() && error.code() == ENOENT)
52 continue;
53
54 warnln("rm: cannot remove '{}': {}", path, error);
55 had_errors = true;
56 }
57
58 if (verbose)
59 outln("removed '{}'", path);
60 }
61 return had_errors ? 1 : 0;
62}