about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-04-13 09:39:47 -0400
committerRich Felker <dalias@aerifal.cx>2011-04-13 09:39:47 -0400
commit91e836fda7d4e2a4ba38d5faec6e3876b1b5e179 (patch)
tree1ba65fb9d302f2f0c0a16ca9d3dfce1b91918a5a
parent3f44f298e46b78cb8fe80be76798e799589ae55e (diff)
downloadmusl-91e836fda7d4e2a4ba38d5faec6e3876b1b5e179.tar.gz
musl-91e836fda7d4e2a4ba38d5faec6e3876b1b5e179.tar.xz
musl-91e836fda7d4e2a4ba38d5faec6e3876b1b5e179.zip
implement getgrouplist (for initgroups), formerly dummied-out v0.7.8
-rw-r--r--src/misc/getgrouplist.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/misc/getgrouplist.c b/src/misc/getgrouplist.c
index 88f273d7..63557afe 100644
--- a/src/misc/getgrouplist.c
+++ b/src/misc/getgrouplist.c
@@ -1,11 +1,23 @@
 #include <grp.h>
-
-/* FIXME */
+#include <string.h>
+#include <limits.h>
 
 int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
 {
+	size_t n, i;
+	struct group *gr;
 	if (*ngroups<1) return -1;
-	*groups = gid;
+	n = *ngroups;
+	*groups++ = gid;
 	*ngroups = 1;
-	return 0;
+
+	setgrent();
+	while ((gr = getgrent()) && *ngroups < INT_MAX) {
+		for (i=0; gr->gr_mem[i] && strcmp(user, gr->gr_mem[i]); i++);
+		if (!gr->gr_mem[i]) continue;
+		if (++*ngroups <= n) *groups++ = gr->gr_gid;
+	}
+	endgrent();
+
+	return *ngroups > n ? -1 : *ngroups;
 }