diff options
Diffstat (limited to 'test/pwd_grp/getgroups.c')
-rw-r--r-- | test/pwd_grp/getgroups.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/test/pwd_grp/getgroups.c b/test/pwd_grp/getgroups.c new file mode 100644 index 000000000..ea31b5829 --- /dev/null +++ b/test/pwd_grp/getgroups.c @@ -0,0 +1,108 @@ +/* This test was ripped out of GNU 'id' from coreutils-5.0 + * by Erik Andersen. + * + * + * id is Copyright (C) 1989-2003 Free Software Foundation, Inc. + * and licensed under the GPL v2 or later, and was written by + * Arnold Robbins, with a major rewrite by David MacKenzie, + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> +#include <err.h> + +/* The number of errors encountered so far. */ +static int problems = 0; + +/* Print the name or value of group ID GID. */ +static void +print_group (gid_t gid) +{ + struct group *grp = NULL; + + grp = getgrgid (gid); + if (grp == NULL) + { + warn("cannot find name for group ID %u", gid); + problems++; + } + + if (grp == NULL) + printf ("%u", (unsigned) gid); + else + printf ("%s", grp->gr_name); +} + +static int +xgetgroups (gid_t gid, int *n_groups, gid_t **groups) +{ + int max_n_groups; + int ng; + gid_t *g; + int fail = 0; + + max_n_groups = getgroups (0, NULL); + + /* Add 1 just in case max_n_groups is zero. */ + g = (gid_t *) malloc (max_n_groups * sizeof (gid_t) + 1); + if (g==NULL) + err(EXIT_FAILURE, "out of memory"); + ng = getgroups (max_n_groups, g); + + if (ng < 0) + { + warn("cannot get supplemental group list"); + ++fail; + free (groups); + } + if (!fail) + { + *n_groups = ng; + *groups = g; + } + return fail; +} + +/* Print all of the distinct groups the user is in. */ +int main (int argc, char **argv) +{ + struct passwd *pwd; + + pwd = getpwuid (getuid()); + if (pwd == NULL) + problems++; + + print_group (getgid()); + if (getegid() != getgid()) + { + putchar (' '); + print_group (getegid()); + } + + { + int n_groups; + gid_t *groups; + register int i; + + if (xgetgroups ((pwd ? pwd->pw_gid : (gid_t) -1), + &n_groups, &groups)) + { + return ++problems; + } + + for (i = 0; i < n_groups; i++) + if (groups[i] != getgid() && groups[i] != getegid()) + { + putchar (' '); + print_group (groups[i]); + } + free (groups); + } + putchar('\n'); + return (problems != 0); +} + |