mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:17:34 +00:00
chmod: Port to LibMain :^)
This ports chmod to LibMain + changes input parameters on several functions from raw C strings to StringView.
This commit is contained in:
parent
0d76d15f9d
commit
d465d3a457
2 changed files with 41 additions and 39 deletions
|
@ -62,6 +62,7 @@ target_link_libraries(bt LibSymbolication LibMain)
|
||||||
target_link_libraries(blockdev LibMain)
|
target_link_libraries(blockdev LibMain)
|
||||||
target_link_libraries(cat LibMain)
|
target_link_libraries(cat LibMain)
|
||||||
target_link_libraries(checksum LibCrypto)
|
target_link_libraries(checksum LibCrypto)
|
||||||
|
target_link_libraries(chmod LibMain)
|
||||||
target_link_libraries(chres LibGUI)
|
target_link_libraries(chres LibGUI)
|
||||||
target_link_libraries(cksum LibCrypto)
|
target_link_libraries(cksum LibCrypto)
|
||||||
target_link_libraries(config LibConfig)
|
target_link_libraries(config LibConfig)
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2021, Kenneth Myhra <kennethmyhra@gmail.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Format.h>
|
#include <AK/Format.h>
|
||||||
#include <AK/Optional.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 <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
/* the new mode will be computed using the boolean function(for each bit):
|
/* 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; }
|
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);
|
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) {
|
TRY(Core::System::pledge("stdio rpath fattr", nullptr));
|
||||||
perror("pledge");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc < 3) {
|
if (arguments.strings.size() < 3) {
|
||||||
warnln("usage: chmod <octal-mode> <path...>");
|
warnln("usage: chmod <octal-mode> <path...>");
|
||||||
warnln(" chmod [[ugoa][+-=][rwx...],...] <path...>");
|
warnln(" chmod [[ugoa][+-=][rwx...],...] <path...>");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -67,41 +68,38 @@ int main(int argc, char** argv)
|
||||||
Mask mask;
|
Mask mask;
|
||||||
|
|
||||||
/* compute a 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");
|
perror("sscanf");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
mask.get_removal_mask() = ~mask.get_applying_mask();
|
mask.get_removal_mask() = ~mask.get_applying_mask();
|
||||||
} else {
|
} else {
|
||||||
const char* access_string = argv[1];
|
auto access_strings = arguments.strings[1].split_view(',');
|
||||||
|
for (auto access_string : access_strings) {
|
||||||
while (*access_string != '\0') {
|
|
||||||
Optional<Mask> tmp_mask;
|
Optional<Mask> tmp_mask;
|
||||||
switch (*access_string) {
|
switch (access_string[0]) {
|
||||||
case 'u':
|
case 'u':
|
||||||
tmp_mask = string_to_mode('u', ++access_string);
|
tmp_mask = string_to_mode('u', access_string);
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
tmp_mask = string_to_mode('g', ++access_string);
|
tmp_mask = string_to_mode('g', access_string);
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
tmp_mask = string_to_mode('o', ++access_string);
|
tmp_mask = string_to_mode('o', access_string);
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
tmp_mask = string_to_mode('a', ++access_string);
|
tmp_mask = string_to_mode('a', access_string);
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
tmp_mask = string_to_mode('a', access_string);
|
tmp_mask = string_to_mode('a', access_string);
|
||||||
break;
|
break;
|
||||||
case ',':
|
|
||||||
++access_string;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (!tmp_mask.has_value()) {
|
if (!tmp_mask.has_value()) {
|
||||||
warnln("chmod: invalid mode: {}", argv[1]);
|
warnln("chmod: invalid mode: {}", arguments.strings[1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
mask |= tmp_mask.value();
|
mask |= tmp_mask.value();
|
||||||
|
@ -109,29 +107,30 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the mask for each file's permissions */
|
/* set the mask for each file's permissions */
|
||||||
struct stat current_access;
|
size_t i = 2;
|
||||||
int i = 2;
|
while (i < arguments.strings.size()) {
|
||||||
while (i < argc) {
|
auto current_access = TRY(Core::System::stat(arguments.strings[i]));
|
||||||
if (stat(argv[i], ¤t_access) != 0) {
|
|
||||||
perror("stat");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/* found the minimal CNF by The Quine–McCluskey algorithm and use it */
|
/* found the minimal CNF by The Quine–McCluskey algorithm and use it */
|
||||||
mode_t mode = mask.get_applying_mask()
|
mode_t mode = mask.get_applying_mask()
|
||||||
| (current_access.st_mode & ~mask.get_removal_mask());
|
| (current_access.st_mode & ~mask.get_removal_mask());
|
||||||
if (chmod(argv[i++], mode) != 0) {
|
TRY(Core::System::chmod(arguments.strings[i++], mode));
|
||||||
perror("chmod");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,15 +155,17 @@ Optional<Mask> string_to_mode(char access_scope, const char*& access_string)
|
||||||
operation = '+';
|
operation = '+';
|
||||||
}
|
}
|
||||||
|
|
||||||
access_string++;
|
for (size_t i = 1; i < access_string.length(); i++) {
|
||||||
while (*access_string != '\0' && *access_string != ',') {
|
char permission = access_string[i];
|
||||||
|
if (permission == '+' || permission == '-' || permission == '=')
|
||||||
|
continue;
|
||||||
|
|
||||||
Optional<Mask> tmp_mask;
|
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()) {
|
if (!tmp_mask.has_value()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
mask |= tmp_mask.value();
|
mask |= tmp_mask.value();
|
||||||
access_string++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue