OrionLibC
Barry Importing existing Orion LibC 03048a9 (3 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;
+}