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 <LibCore/ArgsParser.h>
8#include <LibCore/System.h>
9#include <LibMain/Main.h>
10#include <grp.h>
11
12ErrorOr<int> serenity_main(Main::Arguments arguments)
13{
14 TRY(Core::System::pledge("stdio rpath chown"));
15
16 StringView gid_arg;
17 StringView path {};
18 bool dont_follow_symlinks = false;
19
20 Core::ArgsParser args_parser;
21 args_parser.set_general_help("Change the owning group for a file or directory.");
22 args_parser.add_option(dont_follow_symlinks, "Don't follow symlinks", "no-dereference", 'h');
23 args_parser.add_positional_argument(gid_arg, "Group ID", "gid");
24 args_parser.add_positional_argument(path, "Path to file", "path");
25 args_parser.parse(arguments);
26
27 gid_t new_gid = -1;
28
29 if (gid_arg.is_empty()) {
30 warnln("Empty gid option");
31 return 1;
32 }
33
34 auto number = gid_arg.to_uint();
35 if (number.has_value()) {
36 new_gid = number.value();
37 } else {
38 auto group = TRY(Core::System::getgrnam(gid_arg));
39 if (!group.has_value()) {
40 warnln("Unknown group '{}'", gid_arg);
41 return 1;
42 }
43 new_gid = group->gr_gid;
44 }
45
46 if (dont_follow_symlinks) {
47 TRY(Core::System::lchown(path, -1, new_gid));
48 } else {
49 TRY(Core::System::chown(path, -1, new_gid));
50 }
51
52 return 0;
53}