BuildSystem: Move all userpace libraries under the userspace directory
As the number of libraries is increasing, root directory starts to expand. This adds better organization for libraries
This commit is contained in:
140
userspace/libraries/LibC/pwd.cpp
Normal file
140
userspace/libraries/LibC/pwd.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include <BAN/Assert.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static FILE* s_pwent_fp = nullptr;
|
||||
static passwd s_pwent_struct;
|
||||
|
||||
static bool open_pwent()
|
||||
{
|
||||
if (s_pwent_fp)
|
||||
return true;
|
||||
s_pwent_fp = fopen("/etc/passwd", "r");
|
||||
return s_pwent_fp;
|
||||
}
|
||||
|
||||
static void clear_pwent(passwd& passwd)
|
||||
{
|
||||
if (passwd.pw_name)
|
||||
free(passwd.pw_name);
|
||||
passwd.pw_name = nullptr;
|
||||
if (passwd.pw_dir)
|
||||
free(passwd.pw_dir);
|
||||
passwd.pw_dir = nullptr;
|
||||
if (passwd.pw_shell)
|
||||
free(passwd.pw_shell);
|
||||
passwd.pw_shell = nullptr;
|
||||
}
|
||||
|
||||
void endpwent(void)
|
||||
{
|
||||
if (!s_pwent_fp)
|
||||
return;
|
||||
fclose(s_pwent_fp);
|
||||
s_pwent_fp = nullptr;
|
||||
clear_pwent(s_pwent_struct);
|
||||
}
|
||||
|
||||
struct passwd* getpwent(void)
|
||||
{
|
||||
if (!s_pwent_fp)
|
||||
if (!open_pwent())
|
||||
return nullptr;
|
||||
clear_pwent(s_pwent_struct);
|
||||
|
||||
static char buffer[4096];
|
||||
if (!fgets(buffer, sizeof(buffer), s_pwent_fp))
|
||||
return nullptr;
|
||||
|
||||
size_t buffer_len = strlen(buffer);
|
||||
|
||||
ASSERT(buffer[buffer_len - 1] == '\n');
|
||||
buffer[buffer_len - 1] = '\0';
|
||||
buffer_len--;
|
||||
|
||||
const char* ptr = buffer;
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
char* end = strchr(ptr, ':');
|
||||
ASSERT((i < 6) ? end != nullptr : end == nullptr);
|
||||
if (!end)
|
||||
end = buffer + buffer_len;
|
||||
*end = '\0';
|
||||
|
||||
const size_t field_len = end - ptr;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
s_pwent_struct.pw_name = (char*)malloc(field_len + 1);
|
||||
if (!s_pwent_struct.pw_name)
|
||||
return nullptr;
|
||||
strcpy(s_pwent_struct.pw_name, ptr);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
ASSERT(1 <= field_len && field_len <= 9);
|
||||
for (size_t j = 0; j < field_len; j++)
|
||||
ASSERT(isdigit(ptr[j]));
|
||||
s_pwent_struct.pw_uid = atoi(ptr);
|
||||
break;
|
||||
case 3:
|
||||
ASSERT(1 <= field_len && field_len <= 9);
|
||||
for (size_t j = 0; j < field_len; j++)
|
||||
ASSERT(isdigit(ptr[j]));
|
||||
s_pwent_struct.pw_uid = atoi(ptr);
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
s_pwent_struct.pw_dir = (char*)malloc(field_len + 1);
|
||||
if (!s_pwent_struct.pw_dir)
|
||||
return nullptr;
|
||||
strcpy(s_pwent_struct.pw_dir, ptr);
|
||||
break;
|
||||
case 6:
|
||||
s_pwent_struct.pw_shell = (char*)malloc(field_len + 1);
|
||||
if (!s_pwent_struct.pw_shell)
|
||||
return nullptr;
|
||||
strcpy(s_pwent_struct.pw_shell, ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = end + 1;
|
||||
}
|
||||
|
||||
return &s_pwent_struct;
|
||||
}
|
||||
|
||||
struct passwd* getpwnam(const char* name)
|
||||
{
|
||||
passwd* pwd;
|
||||
setpwent();
|
||||
while ((pwd = getpwent()))
|
||||
if (strcmp(pwd->pw_name, name) == 0)
|
||||
return pwd;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct passwd* getpwuid(uid_t uid)
|
||||
{
|
||||
passwd* pwd;
|
||||
setpwent();
|
||||
while ((pwd = getpwent()))
|
||||
if (pwd->pw_uid == uid)
|
||||
return pwd;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void setpwent(void)
|
||||
{
|
||||
if (!s_pwent_fp)
|
||||
return;
|
||||
fseek(s_pwent_fp, 0, SEEK_SET);
|
||||
}
|
||||
Reference in New Issue
Block a user