OrionLibC
Barry Importing existing Orion LibC 03048a9 (2 years, 3 months ago)diff --git a/pwd/getpw.c b/pwd/getpw.c new file mode 100644 index 0000000..116cf97 --- /dev/null +++ b/pwd/getpw.c @@ -0,0 +1,148 @@ +#include <sys/limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <pwd.h> + +#include <stdio.h> + +/* Parts of a /etc/passwd line */ +enum PasswordParts { + PASSWD_USERNAME, + PASSWD_PASSWORD, + PASSWD_UID, + PASSWD_GID, + PASSWD_INFO, + PASSWD_HOMEDIR, + PASSWD_SHELL, +}; + +static Passwd entry; +static char entryUsername[33]; +static char entryPassword[128]; +static char entryInfo[1024]; +static char entryHomeDir[PATH_MAX]; +static char entryShell[PATH_MAX]; + +/* Get part of a password line */ +static char * +get_part(char *line, int index, char *buf) +{ + int i, len = 0; + char *start; + for (i = 0; i < index; i++) + while (*line++ != ':'); + start = line; + while (*line != ':' && *line != '\n') { + line++; + len++; + } + memcpy(buf, start, len); + buf[len] = '\0'; + return buf; +} + +/* Convert a string to a number */ +static int +number(char *str) +{ + int num = 0, col = 1, len; + for (len = 0; str[len] >= '0' && str[len] <= '9'; len++); + while (len--) { + num += (str[len] - '0') * col; + col *= 10; + } + return num; +} + +/* Move to next line */ +static char * +next_line(char *line) +{ + while (*line++ != '\n'); + return line; +} + +/* Convert line to Passwd */ +static Passwd * +line_to_passwd(char *line) +{ + if (!*line) + return NULL; + + char uidstr[8], gidstr[8]; + get_part(line, PASSWD_USERNAME, entryUsername); + get_part(line, PASSWD_PASSWORD, entryPassword); + get_part(line, PASSWD_UID, uidstr); + get_part(line, PASSWD_GID, gidstr); + get_part(line, PASSWD_INFO, entryInfo); + get_part(line, PASSWD_HOMEDIR, entryHomeDir); + get_part(line, PASSWD_SHELL, entryShell); + + entry.username = entryUsername; + entry.password = entryPassword; + entry.uid = number(uidstr); + entry.gid = number(gidstr); + entry.info = entryInfo; + entry.homedir = entryHomeDir; + entry.shell = entryShell; + + return &entry; +} + +/* Get password file entry by name */ +Passwd * +getpwname(const char *username) +{ + + int fd = open("/etc/passwd", O_RDONLY); + if (fd < 0) + return (Passwd *) fd; + size_t sz = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + char *buf = malloc(sz); + read(fd, buf, sz); + close(fd); + + char *line, tmp[33]; + for (line = buf; *line; line = next_line(line)) { + get_part(line, PASSWD_USERNAME, tmp); + if (!strcmp(username, tmp)) + break; + } + + Passwd *res = line_to_passwd(line); + + free(buf); + return res; +} + +/* Get password file entry by ID */ +Passwd * +getpwuid(uid_t uid) +{ + int fd = open("/etc/passwd", O_RDONLY); + if (fd < 0) + return (Passwd *) fd; + size_t sz = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + char *buf = malloc(sz); + read(fd, buf, sz); + close(fd); + + char *line, tmp[8]; + uid_t uidLine; + for (line = buf; *line; line = next_line(line)) { + get_part(line, PASSWD_UID, tmp); + uidLine = number(tmp); + if (uid == uidLine) + break; + } + + Passwd *res = line_to_passwd(line); + + free(buf); + return res; +}