summaryrefslogtreecommitdiff
path: root/Userland/Utilities/chmod.cpp
diff options
context:
space:
mode:
authorKenneth Myhra <kennethmyhra@gmail.com>2021-11-27 15:55:40 +0100
committerBrian Gianforcaro <b.gianfo@gmail.com>2021-12-04 15:05:46 -0800
commitd465d3a4574cad4a8d41e5217e8f9c7d397e0711 (patch)
tree77569ffe2886b74333768118dbca0171893c8b07 /Userland/Utilities/chmod.cpp
parent0d76d15f9d17d7ca318a18eb69a0334a74d9d708 (diff)
downloadserenity-d465d3a4574cad4a8d41e5217e8f9c7d397e0711.zip
chmod: Port to LibMain :^)
This ports chmod to LibMain + changes input parameters on several functions from raw C strings to StringView.
Diffstat (limited to 'Userland/Utilities/chmod.cpp')
-rw-r--r--Userland/Utilities/chmod.cpp79
1 files changed, 40 insertions, 39 deletions
diff --git a/Userland/Utilities/chmod.cpp b/Userland/Utilities/chmod.cpp
index 5b23252fc2..322654b13f 100644
--- a/Userland/Utilities/chmod.cpp
+++ b/Userland/Utilities/chmod.cpp
@@ -1,15 +1,19 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Kenneth Myhra <kennethmyhra@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Format.h>
#include <AK/Optional.h>
+#include <AK/String.h>
+#include <AK/Vector.h>
+#include <LibCore/System.h>
+#include <LibMain/Main.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
-#include <unistd.h>
/* the new mode will be computed using the boolean function(for each bit):
@@ -48,17 +52,14 @@ public:
mode_t& get_applying_mask() { return applying_mask; }
};
-Optional<Mask> string_to_mode(char access_scope, const char*& access_string);
+Optional<Mask> string_to_mode(char access_scope, StringView access_string);
Optional<Mask> apply_permission(char access_scope, char permission, char operation);
-int main(int argc, char** argv)
+ErrorOr<int> serenity_main(Main::Arguments arguments)
{
- if (pledge("stdio rpath fattr", nullptr) < 0) {
- perror("pledge");
- return 1;
- }
+ TRY(Core::System::pledge("stdio rpath fattr", nullptr));
- if (argc < 3) {
+ if (arguments.strings.size() < 3) {
warnln("usage: chmod <octal-mode> <path...>");
warnln(" chmod [[ugoa][+-=][rwx...],...] <path...>");
return 1;
@@ -67,41 +68,38 @@ int main(int argc, char** argv)
Mask mask;
/* compute a mask */
- if (argv[1][0] >= '0' && argv[1][0] <= '7') {
- if (sscanf(argv[1], "%ho", &mask.get_applying_mask()) != 1) {
+
+ if (arguments.strings[1][0] >= '0' && arguments.strings[1][0] <= '7') {
+ if (sscanf(arguments.strings[1].to_string().characters(), "%ho", &mask.get_applying_mask()) != 1) {
perror("sscanf");
return 1;
}
mask.get_removal_mask() = ~mask.get_applying_mask();
} else {
- const char* access_string = argv[1];
-
- while (*access_string != '\0') {
+ auto access_strings = arguments.strings[1].split_view(',');
+ for (auto access_string : access_strings) {
Optional<Mask> tmp_mask;
- switch (*access_string) {
+ switch (access_string[0]) {
case 'u':
- tmp_mask = string_to_mode('u', ++access_string);
+ tmp_mask = string_to_mode('u', access_string);
break;
case 'g':
- tmp_mask = string_to_mode('g', ++access_string);
+ tmp_mask = string_to_mode('g', access_string);
break;
case 'o':
- tmp_mask = string_to_mode('o', ++access_string);
+ tmp_mask = string_to_mode('o', access_string);
break;
case 'a':
- tmp_mask = string_to_mode('a', ++access_string);
+ tmp_mask = string_to_mode('a', access_string);
break;
case '=':
case '+':
case '-':
tmp_mask = string_to_mode('a', access_string);
break;
- case ',':
- ++access_string;
- continue;
}
if (!tmp_mask.has_value()) {
- warnln("chmod: invalid mode: {}", argv[1]);
+ warnln("chmod: invalid mode: {}", arguments.strings[1]);
return 1;
}
mask |= tmp_mask.value();
@@ -109,29 +107,30 @@ int main(int argc, char** argv)
}
/* set the mask for each file's permissions */
- struct stat current_access;
- int i = 2;
- while (i < argc) {
- if (stat(argv[i], &current_access) != 0) {
- perror("stat");
- return 1;
- }
+ size_t i = 2;
+ while (i < arguments.strings.size()) {
+ auto current_access = TRY(Core::System::stat(arguments.strings[i]));
/* found the minimal CNF by The Quine–McCluskey algorithm and use it */
mode_t mode = mask.get_applying_mask()
| (current_access.st_mode & ~mask.get_removal_mask());
- if (chmod(argv[i++], mode) != 0) {
- perror("chmod");
- }
+ TRY(Core::System::chmod(arguments.strings[i++], mode));
}
return 0;
}
-Optional<Mask> string_to_mode(char access_scope, const char*& access_string)
+Optional<Mask> string_to_mode(char access_scope, StringView access_string)
{
- char operation = *access_string;
+ auto get_operation = [](StringView s) {
+ for (auto c : s) {
+ if (c == '+' || c == '-' || c == '=')
+ return c;
+ }
+ return ' ';
+ };
- if (operation != '+' && operation != '-' && operation != '=') {
+ auto operation = get_operation(access_string);
+ if (operation == ' ') {
return {};
}
@@ -156,15 +155,17 @@ Optional<Mask> string_to_mode(char access_scope, const char*& access_string)
operation = '+';
}
- access_string++;
- while (*access_string != '\0' && *access_string != ',') {
+ for (size_t i = 1; i < access_string.length(); i++) {
+ char permission = access_string[i];
+ if (permission == '+' || permission == '-' || permission == '=')
+ continue;
+
Optional<Mask> tmp_mask;
- tmp_mask = apply_permission(access_scope, *access_string, operation);
+ tmp_mask = apply_permission(access_scope, permission, operation);
if (!tmp_mask.has_value()) {
return {};
}
mask |= tmp_mask.value();
- access_string++;
}
return mask;