diff options
Diffstat (limited to 'lib/libc/pwd')
| -rw-r--r-- | lib/libc/pwd/getgrgid.c | 15 | ||||
| -rw-r--r-- | lib/libc/pwd/getgrgid_r.c | 72 |
2 files changed, 87 insertions, 0 deletions
diff --git a/lib/libc/pwd/getgrgid.c b/lib/libc/pwd/getgrgid.c new file mode 100644 index 00000000..5e825c12 --- /dev/null +++ b/lib/libc/pwd/getgrgid.c @@ -0,0 +1,15 @@ +#include <pwd.h> +#include <stddef.h> +#include <limits.h> + +struct passwd *getpwuid(uid_t uid) +{ + static struct passwd pwd; + static char buf[LINE_MAX * 4]; + struct passwd *res; + + if (getpwuid_r(uid, &pwd, buf, sizeof(buf), &res) != 0) + return NULL; + + return res; +} diff --git a/lib/libc/pwd/getgrgid_r.c b/lib/libc/pwd/getgrgid_r.c new file mode 100644 index 00000000..33705fdf --- /dev/null +++ b/lib/libc/pwd/getgrgid_r.c @@ -0,0 +1,72 @@ +#include <pwd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <limits.h> + +static char *copy_str(const char *src, char **buf, size_t *buflen) +{ + size_t len = strlen(src) + 1; + if (len > *buflen) + return NULL; + char *dst = *buf; + memcpy(dst, src, len); + *buf += len; + *buflen -= len; + return dst; +} + +int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, + struct passwd **result) +{ + FILE *stream = fopen("/etc/passwd", "r"); + if (stream == NULL) { + *result = NULL; + return errno; + } + + char line[LINE_MAX]; + + while (fgets(line, sizeof(line), stream)) { + char *name = strtok(line, ":"); + char *passwd = strtok(NULL, ":"); + char *uid_str = strtok(NULL, ":"); + char *gid_str = strtok(NULL, ":"); + strtok(NULL, ":"); + char *dir = strtok(NULL, ":"); + char *shell = strtok(NULL, "\n"); + + if (name == NULL || passwd == NULL || uid_str == NULL || + gid_str == NULL) + continue; + + uid_t file_uid = (uid_t)strtoul(uid_str, NULL, 10); + if (file_uid != uid) + continue; + + size_t rem = buflen; + + pwd->pw_name = copy_str(name, &buf, &rem); + pwd->pw_dir = copy_str(dir ? dir : "", &buf, &rem); + pwd->pw_shell = copy_str(shell ? shell : "", &buf, &rem); + pwd->pw_uid = file_uid; + pwd->pw_gid = (gid_t)strtoul(gid_str, NULL, 10); + pwd->pw_uid = file_uid; + pwd->pw_gid = (gid_t)strtoul(gid_str, NULL, 10); + + if (pwd->pw_name == NULL || pwd->pw_dir == NULL || + pwd->pw_shell == NULL) { + fclose(stream); + return ERANGE; + } + + fclose(stream); + *result = pwd; + return 0; + } + + fclose(stream); + *result = NULL; + return 0; +} |
