BarryServer : Git

All the code for all my projects
// BarryServer : Git / OrionLibC / commit / 03048a95d88cc7a78171393371f5c22a0250a014 / grp / getgr.c

// Related

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;
+}