mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:07:35 +00:00
LibCore: Sync groups, getgrent to getgrent_r, fix gr_mem bug
This commit is contained in:
parent
8a09895bc1
commit
d8f25ad644
2 changed files with 70 additions and 1 deletions
|
@ -6,13 +6,71 @@
|
|||
|
||||
#include <AK/CharacterTypes.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/Group.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibCore/UmaskScope.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
ErrorOr<String> Group::generate_group_file() const
|
||||
{
|
||||
StringBuilder builder;
|
||||
|
||||
ScopeGuard grent_guard([] { endgrent(); });
|
||||
setgrent();
|
||||
errno = 0;
|
||||
#ifndef AK_OS_MACOS
|
||||
struct group group;
|
||||
struct group* gr = nullptr;
|
||||
char buffer[1024] = { 0 };
|
||||
while (getgrent_r(&group, buffer, sizeof(buffer), &gr) == 0 && gr) {
|
||||
#else
|
||||
for (auto const* gr = getgrent(); gr; gr = getgrent()) {
|
||||
#endif
|
||||
if (gr->gr_name == m_name)
|
||||
builder.appendff("{}:x:{}:{}\n", m_name, m_id, String::join(',', m_members));
|
||||
else {
|
||||
Vector<String> members;
|
||||
for (size_t i = 0; gr->gr_mem[i]; ++i)
|
||||
members.append(gr->gr_mem[i]);
|
||||
|
||||
builder.appendff("{}:x:{}:{}\n", gr->gr_name, gr->gr_gid, String::join(',', members));
|
||||
}
|
||||
}
|
||||
|
||||
if (errno)
|
||||
return Error::from_errno(errno);
|
||||
|
||||
return builder.to_string();
|
||||
}
|
||||
|
||||
ErrorOr<void> Group::sync()
|
||||
{
|
||||
Core::UmaskScope umask_scope(0777);
|
||||
|
||||
auto new_group_file_content = TRY(generate_group_file());
|
||||
|
||||
char new_group_name[] = "/etc/group.XXXXXX";
|
||||
size_t new_group_name_length = strlen(new_group_name);
|
||||
|
||||
{
|
||||
auto new_group_fd = TRY(Core::System::mkstemp({ new_group_name, new_group_name_length }));
|
||||
ScopeGuard new_group_fd_guard([new_group_fd] { close(new_group_fd); });
|
||||
TRY(Core::System::fchmod(new_group_fd, 0664));
|
||||
|
||||
auto nwritten = TRY(Core::System::write(new_group_fd, new_group_file_content.bytes()));
|
||||
VERIFY(static_cast<size_t>(nwritten) == new_group_file_content.length());
|
||||
}
|
||||
|
||||
TRY(Core::System::rename({ new_group_name, new_group_name_length }, "/etc/group"sv));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
#if !defined(AK_OS_BSD_GENERIC) && !defined(AK_OS_ANDROID)
|
||||
ErrorOr<void> Group::add_group(Group& group)
|
||||
{
|
||||
|
@ -69,10 +127,17 @@ ErrorOr<Vector<Group>> Group::all()
|
|||
ScopeGuard grent_guard([] { endgrent(); });
|
||||
setgrent();
|
||||
errno = 0;
|
||||
#ifndef AK_OS_MACOS
|
||||
struct group group;
|
||||
struct group* gr = nullptr;
|
||||
char buffer[1024] = { 0 };
|
||||
while (getgrent_r(&group, buffer, sizeof(buffer), &gr) == 0 && gr) {
|
||||
#else
|
||||
for (auto const* gr = getgrent(); gr; gr = getgrent()) {
|
||||
#endif
|
||||
Vector<String> members;
|
||||
for (size_t i = 0; gr->gr_mem[i]; ++i)
|
||||
members.append(*gr->gr_mem);
|
||||
members.append(gr->gr_mem[i]);
|
||||
|
||||
groups.append({ gr->gr_name, gr->gr_gid, members });
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue