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