Serenity Operating System
1/*
2 * Copyright (c) 2020, Fei Wu <f.eiwu@yahoo.com>
3 * Copyright (c) 2021, Brandon Pruitt <brapru@pm.me>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <AK/DeprecatedString.h>
9#include <LibCore/Account.h>
10#include <LibCore/ArgsParser.h>
11#include <LibCore/DeprecatedFile.h>
12#include <LibCore/System.h>
13#include <LibMain/Main.h>
14#include <unistd.h>
15
16ErrorOr<int> serenity_main(Main::Arguments arguments)
17{
18 TRY(Core::System::pledge("stdio wpath rpath cpath fattr"));
19 TRY(Core::System::unveil("/etc/", "rwc"));
20
21 StringView username;
22 bool remove_home = false;
23
24 Core::ArgsParser args_parser;
25 args_parser.add_option(remove_home, "Remove home directory", "remove", 'r');
26 args_parser.add_positional_argument(username, "Login user identity (username)", "login");
27 args_parser.parse(arguments);
28
29 auto account_or_error = Core::Account::from_name(username);
30
31 if (account_or_error.is_error()) {
32 warnln("Core::Account::from_name: {}", account_or_error.error());
33 return 1;
34 }
35
36 auto& target_account = account_or_error.value();
37
38 if (remove_home)
39 TRY(Core::System::unveil(target_account.home_directory(), "c"sv));
40
41 TRY(Core::System::unveil(nullptr, nullptr));
42
43 target_account.set_deleted();
44 TRY(target_account.sync());
45
46 if (remove_home) {
47 if (access(target_account.home_directory().characters(), F_OK) == -1)
48 return 0;
49
50 auto const real_path = Core::DeprecatedFile::real_path_for(target_account.home_directory());
51
52 if (real_path == "/") {
53 warnln("home directory is /, not deleted!");
54 return 12;
55 }
56
57 if (auto result = Core::DeprecatedFile::remove(real_path, Core::DeprecatedFile::RecursionMode::Allowed); result.is_error()) {
58 warnln("{}", result.release_error());
59 return 12;
60 }
61 }
62
63 return 0;
64}