Compare commits
No commits in common. "15b76f94f4630cbb9d55f755d83f639e4a7951d4" and "eb58b4acc83c27dcb8c2702a7915732dd344cfe7" have entirely different histories.
15b76f94f4
...
eb58b4acc8
@ -1,78 +1,24 @@
|
|||||||
#include <luna/String.h>
|
|
||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
#include <pwd.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
Result<int> luna_main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView user_and_group;
|
StringView user;
|
||||||
StringView path;
|
StringView path;
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
os::ArgumentParser parser;
|
||||||
parser.add_description("Change the owner and group of a file."_sv);
|
parser.add_description("Change the owner and group of a file."_sv);
|
||||||
parser.add_positional_argument(user_and_group, "owner"_sv, true);
|
parser.add_positional_argument(user, "user"_sv, true);
|
||||||
parser.add_positional_argument(path, "path"_sv, true);
|
parser.add_positional_argument(path, "path"_sv, true);
|
||||||
parser.parse(argc, argv);
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
u32 uid = -1;
|
u32 id = (u32)strtoul(user.chars(), NULL, 0);
|
||||||
Option<u32> gid = -1;
|
|
||||||
|
|
||||||
auto names = TRY(user_and_group.split_once(':'));
|
if (chown(path.chars(), id, id) < 0)
|
||||||
if (names.size() > 1)
|
|
||||||
{
|
|
||||||
auto& group = names[1];
|
|
||||||
if (group.is_empty()) { gid = {}; }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto rc = group.view().to_uint();
|
|
||||||
if (rc.has_value()) { gid = (u32)rc.value(); }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "FIXME: read entry from group file to determine GID for group %s\n", group.chars());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (names.size() > 0)
|
|
||||||
{
|
|
||||||
auto& owner = names[0];
|
|
||||||
if (!owner.is_empty())
|
|
||||||
{
|
|
||||||
auto rc = owner.view().to_uint();
|
|
||||||
if (rc.has_value()) { uid = (u32)rc.value(); }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct passwd* pw = getpwnam(owner.chars());
|
|
||||||
if (!pw)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s: unknown user %s!\n", argv[0], owner.chars());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uid = pw->pw_uid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gid.has_value())
|
|
||||||
{
|
|
||||||
struct passwd* pw = getpwuid(uid);
|
|
||||||
if (!pw)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s: unknown user id %u!\n", argv[0], uid);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
gid = pw->pw_gid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chown(path.chars(), uid, gid.value_or(-1)) < 0)
|
|
||||||
{
|
{
|
||||||
perror("chown");
|
perror("chown");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,6 @@ class String
|
|||||||
Result<String> substring(usize begin, usize size) const;
|
Result<String> substring(usize begin, usize size) const;
|
||||||
|
|
||||||
Result<Vector<String>> split(StringView delim) const;
|
Result<Vector<String>> split(StringView delim) const;
|
||||||
Result<Vector<String>> split_once(char delim) const
|
|
||||||
{
|
|
||||||
return view().split_once(delim);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Result<String> format(const String& fmt, ...);
|
static Result<String> format(const String& fmt, ...);
|
||||||
static Result<String> format(StringView fmt, ...);
|
static Result<String> format(StringView fmt, ...);
|
||||||
|
@ -41,9 +41,6 @@ class StringView
|
|||||||
bool operator==(StringView other) const;
|
bool operator==(StringView other) const;
|
||||||
|
|
||||||
Result<Vector<String>> split(StringView delim) const;
|
Result<Vector<String>> split(StringView delim) const;
|
||||||
Result<Vector<String>> split_once(char delim) const;
|
|
||||||
|
|
||||||
Result<usize> to_uint() const;
|
|
||||||
|
|
||||||
Iterator begin() const
|
Iterator begin() const
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#include <luna/CString.h>
|
#include <luna/CString.h>
|
||||||
#include <luna/NumberParsing.h>
|
|
||||||
#include <luna/ScopeGuard.h>
|
|
||||||
#include <luna/String.h>
|
#include <luna/String.h>
|
||||||
#include <luna/StringView.h>
|
#include <luna/StringView.h>
|
||||||
|
|
||||||
@ -64,10 +62,9 @@ Result<Vector<String>> StringView::split(StringView delim) const
|
|||||||
String str;
|
String str;
|
||||||
|
|
||||||
char* copy = strndup(m_string, m_length);
|
char* copy = strndup(m_string, m_length);
|
||||||
auto guard = make_scope_guard([copy] { free_impl(copy); });
|
|
||||||
|
|
||||||
char* segment = strtok(copy, delim.chars());
|
char* segment = strtok(copy, delim.chars());
|
||||||
if (!segment) return result;
|
if (!segment) goto end;
|
||||||
|
|
||||||
str = TRY(String::from_cstring(segment));
|
str = TRY(String::from_cstring(segment));
|
||||||
TRY(result.try_append(move(str)));
|
TRY(result.try_append(move(str)));
|
||||||
@ -75,46 +72,14 @@ Result<Vector<String>> StringView::split(StringView delim) const
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
segment = strtok(nullptr, delim.chars());
|
segment = strtok(nullptr, delim.chars());
|
||||||
if (!segment) return result;
|
if (!segment) goto end;
|
||||||
|
|
||||||
str = TRY(String::from_cstring(segment));
|
str = TRY(String::from_cstring(segment));
|
||||||
TRY(result.try_append(move(str)));
|
TRY(result.try_append(move(str)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
end:
|
||||||
}
|
free_impl(copy);
|
||||||
|
|
||||||
Result<Vector<String>> StringView::split_once(char delim) const
|
|
||||||
{
|
|
||||||
Vector<String> result;
|
|
||||||
|
|
||||||
char* copy = strndup(m_string, m_length);
|
|
||||||
auto guard = make_scope_guard([copy] { free_impl(copy); });
|
|
||||||
|
|
||||||
char* middle = strchr(copy, delim);
|
|
||||||
if (!middle)
|
|
||||||
{
|
|
||||||
auto str = TRY(String::from_cstring(copy));
|
|
||||||
TRY(result.try_append(move(str)));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
*middle = '\0';
|
|
||||||
|
|
||||||
auto begin = TRY(String::from_cstring(copy));
|
|
||||||
auto end = TRY(String::from_cstring(middle + 1));
|
|
||||||
|
|
||||||
TRY(result.try_append(move(begin)));
|
|
||||||
TRY(result.try_append(move(end)));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<usize> StringView::to_uint() const
|
|
||||||
{
|
|
||||||
const char* endptr = nullptr;
|
|
||||||
auto result = parse_unsigned_integer(m_string, &endptr, 0);
|
|
||||||
if (endptr == m_string) return err(EINVAL);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user