1/*
2 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 */
5
6/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
7/*	  All Rights Reserved  	*/
8
9
10/*
11 * Copyright (c) 1980 Regents of the University of California.
12 * All rights reserved. The Berkeley software License Agreement
13 * specifies the terms and conditions for redistribution.
14 */
15
16/*
17 * groups
18 */
19
20#include <sys/types.h>
21#include <sys/param.h>
22#include <alloca.h>
23#include <grp.h>
24#include <pwd.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <unistd.h>
28#include <string.h>
29
30static void showgroups(char *user);
31
32int
33main(int argc, char *argv[])
34{
35	int ngroups, i;
36	char *sep = "";
37	struct group *gr;
38	gid_t *groups;
39	int maxgrp = sysconf(_SC_NGROUPS_MAX);
40
41	groups = alloca(maxgrp * sizeof (gid_t));
42
43	if (argc > 1) {
44		for (i = 1; i < argc; i++)
45			showgroups(argv[i]);
46		exit(0);
47	}
48
49	ngroups = getgroups(maxgrp, groups);
50	if (getpwuid(getuid()) == NULL) {
51		(void) fprintf(stderr, "groups: could not find passwd entry\n");
52		exit(1);
53	}
54
55	for (i = 0; i < ngroups; i++) {
56		gr = getgrgid(groups[i]);
57		if (gr == NULL) {
58			(void) printf("%s%u", sep, groups[i]);
59			sep = " ";
60			continue;
61		}
62		(void) printf("%s%s", sep, gr->gr_name);
63		sep = " ";
64	}
65
66	(void) printf("\n");
67	return (0);
68}
69
70static void
71showgroups(char *user)
72{
73	struct group *gr;
74	struct passwd *pw;
75	char **cp;
76	char *sep = "";
77	int pwgid_printed = 0;
78
79	if ((pw = getpwnam(user)) == NULL) {
80		(void) fprintf(stderr, "groups: %s : No such user\n", user);
81		return;
82	}
83	setgrent();
84	(void) printf("%s : ", user);
85	while (gr = getgrent()) {
86		if (pw->pw_gid == gr->gr_gid) {
87			/*
88			 * To avoid duplicate group entries
89			 */
90			if (pwgid_printed == 0) {
91				(void) printf("%s%s", sep, gr->gr_name);
92				sep = " ";
93				pwgid_printed = 1;
94			}
95			continue;
96		}
97		for (cp = gr->gr_mem; cp && *cp; cp++)
98			if (strcmp(*cp, user) == 0) {
99				(void) printf("%s%s", sep, gr->gr_name);
100				sep = " ";
101				break;
102			}
103	}
104	(void) printf("\n");
105	endgrent();
106}
107