OrionLibC
Barry Importing existing Orion LibC 03048a9 (2 years, 2 months ago)diff --git a/grp/getgr.c b/grp/getgr.c new file mode 100644 index 0000000..e77d50c --- /dev/null +++ b/grp/getgr.c @@ -0,0 +1,142 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <grp.h> + +/* Parts of a /etc/group line */ +enum GroupParts { + GROUP_NAME, + GROUP_GID, + GROUP_USERS, +}; + +static Group entry; +static char entryName[33]; +static char *entryMembers[64]; +static char entryUsers[64 * 33]; + +/* 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 Grouop */ +static Group * +line_to_group(char *line) +{ + if (!*line) + return NULL; + + char gidstr[8]; + get_part(line, GROUP_NAME, entryName); + get_part(line, GROUP_GID, gidstr); + get_part(line, GROUP_USERS, entryUsers); + + int i, j = 0; + char *prev = entryUsers; + for (i = 0; entryUsers[i]; i++) { + if (entryUsers[i] != ' ') + continue; + entryUsers[i] = '\0'; + entryMembers[j] = prev; + prev = entryUsers + 1; + j++; + } + + entry.name = entryName; + entry.gid = number(gidstr); + entry.members = entryMembers; + + return &entry; +} + +/* Get group file entry by name */ +Group * +getgrname(const char *name) +{ + int fd = open("/etc/group", O_RDONLY); + if (fd < 0) + return (Group *) 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, GROUP_NAME, tmp); + if (!strcmp(name, tmp)) + break; + } + + Group *res = line_to_group(line); + + free(buf); + return res; +} + +/* Get group file entry by ID */ +Group * +getgrgid(gid_t gid) +{ + int fd = open("/etc/group", O_RDONLY); + if (fd < 0) + return (Group *) 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]; + gid_t gidLine; + for (line = buf; *line; line = next_line(line)) { + get_part(line, GROUP_GID, tmp); + gidLine = number(tmp); + if (gid == gidLine) + break; + } + + Group *res = line_to_group(line); + + free(buf); + return res; +}