xref: /illumos-gate/usr/src/contrib/ast/src/lib/libcmd/id.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1992-2012 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b30d1939SAndy Fiddaman *                                                                      *
20*b30d1939SAndy Fiddaman ***********************************************************************/
21*b30d1939SAndy Fiddaman #pragma prototyped
22*b30d1939SAndy Fiddaman /*
23*b30d1939SAndy Fiddaman  * David Korn
24*b30d1939SAndy Fiddaman  * Glenn Fowler
25*b30d1939SAndy Fiddaman  * AT&T Research
26*b30d1939SAndy Fiddaman  *
27*b30d1939SAndy Fiddaman  * id
28*b30d1939SAndy Fiddaman  */
29*b30d1939SAndy Fiddaman 
30*b30d1939SAndy Fiddaman static const char usage[] =
31*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: id (AT&T Research) 2004-06-11 $\n]"
32*b30d1939SAndy Fiddaman USAGE_LICENSE
33*b30d1939SAndy Fiddaman "[+NAME?id - return user identity]"
34*b30d1939SAndy Fiddaman "[+DESCRIPTION?If no \auser\a operand is specified \bid\b writes user and "
35*b30d1939SAndy Fiddaman 	"group IDs and the corresponding user and group names of the "
36*b30d1939SAndy Fiddaman 	"invoking process to standard output.  If the effective and "
37*b30d1939SAndy Fiddaman 	"real IDs do not match, both are written.  Any supplementary "
38*b30d1939SAndy Fiddaman 	"groups the current process belongs to will also be written.]"
39*b30d1939SAndy Fiddaman "[+?If a \auser\a operand is specified and the process has permission, "
40*b30d1939SAndy Fiddaman 	"the user and group IDs and any supplementary group IDs of the "
41*b30d1939SAndy Fiddaman 	"selected user will be written to standard output.]"
42*b30d1939SAndy Fiddaman "[+?If any options are specified, then only a portion of the information "
43*b30d1939SAndy Fiddaman 	"is written.]"
44*b30d1939SAndy Fiddaman "[n:name?Write the name instead of the numeric ID.]"
45*b30d1939SAndy Fiddaman "[r:real?Writes real ID instead of the effective ID.]"
46*b30d1939SAndy Fiddaman "[[a?This option is ignored.]"
47*b30d1939SAndy Fiddaman "[g:group?Writes only the group ID.]"
48*b30d1939SAndy Fiddaman "[u:user?Writes only the user ID.]"
49*b30d1939SAndy Fiddaman "[G:groups?Writes only the supplementary group IDs.]"
50*b30d1939SAndy Fiddaman "[s:fair-share?Writes fair share scheduler IDs and groups on systems that "
51*b30d1939SAndy Fiddaman 	"support fair share scheduling.]"
52*b30d1939SAndy Fiddaman "\n"
53*b30d1939SAndy Fiddaman "\n[user]\n"
54*b30d1939SAndy Fiddaman "\n"
55*b30d1939SAndy Fiddaman "[+EXIT STATUS?]{"
56*b30d1939SAndy Fiddaman         "[+0?Successful completion.]"
57*b30d1939SAndy Fiddaman         "[+>0?An error occurred.]"
58*b30d1939SAndy Fiddaman "}"
59*b30d1939SAndy Fiddaman "[+SEE ALSO?\blogname\b(1), \bwho\b(1), \bgetgroups\b(2)]"
60*b30d1939SAndy Fiddaman ;
61*b30d1939SAndy Fiddaman 
62*b30d1939SAndy Fiddaman #include <cmd.h>
63*b30d1939SAndy Fiddaman 
64*b30d1939SAndy Fiddaman #include "FEATURE/ids"
65*b30d1939SAndy Fiddaman 
66*b30d1939SAndy Fiddaman #include <grp.h>
67*b30d1939SAndy Fiddaman #include <pwd.h>
68*b30d1939SAndy Fiddaman 
69*b30d1939SAndy Fiddaman #if _lib_fsid
70*b30d1939SAndy Fiddaman #if _lib_getfsgid && ( _sys_fss || _hdr_fsg )
71*b30d1939SAndy Fiddaman #define fss_grp		fs_grp
72*b30d1939SAndy Fiddaman #define fss_id		fs_id
73*b30d1939SAndy Fiddaman #define fss_mem		fs_mem
74*b30d1939SAndy Fiddaman #define fss_passwd	fs_passwd
75*b30d1939SAndy Fiddaman #define fss_shares	fs_shares
76*b30d1939SAndy Fiddaman #if _sys_fss
77*b30d1939SAndy Fiddaman #include <sys/fss.h>
78*b30d1939SAndy Fiddaman #endif
79*b30d1939SAndy Fiddaman #if _hdr_fsg
80*b30d1939SAndy Fiddaman #include <fsg.h>
81*b30d1939SAndy Fiddaman #endif
82*b30d1939SAndy Fiddaman #if !_lib_isfsg && !defined(isfsg)
83*b30d1939SAndy Fiddaman #define isfsg(p)	(!(p)->fs_id&&!(p)->fs_shares&&(!(p)->fs_passwd||!*(p)->fs_passwd))
84*b30d1939SAndy Fiddaman #endif
85*b30d1939SAndy Fiddaman #else
86*b30d1939SAndy Fiddaman #undef _lib_fsid
87*b30d1939SAndy Fiddaman #endif
88*b30d1939SAndy Fiddaman #endif
89*b30d1939SAndy Fiddaman 
90*b30d1939SAndy Fiddaman #define power2(n)	(!((n)&((n)-1)))
91*b30d1939SAndy Fiddaman 
92*b30d1939SAndy Fiddaman #define GG_FLAG		(1<<0)
93*b30d1939SAndy Fiddaman #define G_FLAG		(1<<1)
94*b30d1939SAndy Fiddaman #define N_FLAG		(1<<2)
95*b30d1939SAndy Fiddaman #define R_FLAG		(1<<3)
96*b30d1939SAndy Fiddaman #define U_FLAG		(1<<4)
97*b30d1939SAndy Fiddaman #define S_FLAG		(1<<5)
98*b30d1939SAndy Fiddaman #define O_FLAG		(1<<6)
99*b30d1939SAndy Fiddaman #define X_FLAG		(1<<7)
100*b30d1939SAndy Fiddaman 
101*b30d1939SAndy Fiddaman #if _lib_fsid
102*b30d1939SAndy Fiddaman static void
getfsids(Sfio_t * sp,const char * name,int flags,register int lastchar)103*b30d1939SAndy Fiddaman getfsids(Sfio_t* sp, const char* name, int flags, register int lastchar)
104*b30d1939SAndy Fiddaman {
105*b30d1939SAndy Fiddaman 	register struct fsg*	fs;
106*b30d1939SAndy Fiddaman 	register char*		s;
107*b30d1939SAndy Fiddaman 	register char**		p;
108*b30d1939SAndy Fiddaman 	char**			x;
109*b30d1939SAndy Fiddaman 
110*b30d1939SAndy Fiddaman 	if (lastchar)
111*b30d1939SAndy Fiddaman 	{
112*b30d1939SAndy Fiddaman 		if (flags & O_FLAG) flags = 1;
113*b30d1939SAndy Fiddaman 		else flags = 0;
114*b30d1939SAndy Fiddaman 	}
115*b30d1939SAndy Fiddaman 	else if (flags & N_FLAG) flags = 1;
116*b30d1939SAndy Fiddaman 	else flags = -1;
117*b30d1939SAndy Fiddaman 	setfsgent();
118*b30d1939SAndy Fiddaman 	while (fs = getfsgnam(name))
119*b30d1939SAndy Fiddaman 		if (!isfsg(fs))
120*b30d1939SAndy Fiddaman 		{
121*b30d1939SAndy Fiddaman 			if (p = fs->fs_mem)
122*b30d1939SAndy Fiddaman 			{
123*b30d1939SAndy Fiddaman 				if (flags > 0) x = 0;
124*b30d1939SAndy Fiddaman 				else
125*b30d1939SAndy Fiddaman 				{
126*b30d1939SAndy Fiddaman 					register char**		q;
127*b30d1939SAndy Fiddaman 					register char*		t;
128*b30d1939SAndy Fiddaman 					register int		n;
129*b30d1939SAndy Fiddaman 
130*b30d1939SAndy Fiddaman 					n = 0;
131*b30d1939SAndy Fiddaman 					q = p;
132*b30d1939SAndy Fiddaman 					while (s = *q++)
133*b30d1939SAndy Fiddaman 						n += strlen(s) + 1;
134*b30d1939SAndy Fiddaman 					if (!(x = newof(0, char*, q - p, n)))
135*b30d1939SAndy Fiddaman 						break;
136*b30d1939SAndy Fiddaman 					s = (char*)(x + (q - p));
137*b30d1939SAndy Fiddaman 					q = x;
138*b30d1939SAndy Fiddaman 					while (t = *p++)
139*b30d1939SAndy Fiddaman 					{
140*b30d1939SAndy Fiddaman 						*q++ = s;
141*b30d1939SAndy Fiddaman 						while (*s++ = *t++);
142*b30d1939SAndy Fiddaman 					}
143*b30d1939SAndy Fiddaman 					*q = 0;
144*b30d1939SAndy Fiddaman 					p = x;
145*b30d1939SAndy Fiddaman 				}
146*b30d1939SAndy Fiddaman 				while (s = *p++)
147*b30d1939SAndy Fiddaman 				{
148*b30d1939SAndy Fiddaman 					if (lastchar == '=')
149*b30d1939SAndy Fiddaman 					{
150*b30d1939SAndy Fiddaman 						lastchar = ',';
151*b30d1939SAndy Fiddaman 						sfputr(sp, " fsid=", -1);
152*b30d1939SAndy Fiddaman 					}
153*b30d1939SAndy Fiddaman 					else if (!lastchar) lastchar = ' ';
154*b30d1939SAndy Fiddaman 					else sfputc(sp, lastchar);
155*b30d1939SAndy Fiddaman 					if (flags > 0) sfprintf(sp, "%s", s);
156*b30d1939SAndy Fiddaman 					else
157*b30d1939SAndy Fiddaman 					{
158*b30d1939SAndy Fiddaman 						setfsgent();
159*b30d1939SAndy Fiddaman 						while (fs = getfsgnam(s))
160*b30d1939SAndy Fiddaman 							if (isfsg(fs))
161*b30d1939SAndy Fiddaman 							{
162*b30d1939SAndy Fiddaman 								if (flags < 0) sfprintf(sp, "%u", fs->fs_id);
163*b30d1939SAndy Fiddaman 								else sfprintf(sp, "%u(%s)", fs->fs_id, s);
164*b30d1939SAndy Fiddaman 								break;
165*b30d1939SAndy Fiddaman 							}
166*b30d1939SAndy Fiddaman 					}
167*b30d1939SAndy Fiddaman 				}
168*b30d1939SAndy Fiddaman 				if (x) free(x);
169*b30d1939SAndy Fiddaman 			}
170*b30d1939SAndy Fiddaman 			break;
171*b30d1939SAndy Fiddaman 		}
172*b30d1939SAndy Fiddaman 	endfsgent();
173*b30d1939SAndy Fiddaman 	if (lastchar == ' ') sfputc(sp, '\n');
174*b30d1939SAndy Fiddaman }
175*b30d1939SAndy Fiddaman #endif
176*b30d1939SAndy Fiddaman 
177*b30d1939SAndy Fiddaman static void
putid(Sfio_t * sp,int flags,const char * label,const char * name,long number)178*b30d1939SAndy Fiddaman putid(Sfio_t* sp, int flags, const char* label, const char* name, long number)
179*b30d1939SAndy Fiddaman {
180*b30d1939SAndy Fiddaman 	sfprintf(sp, "%s=", label);
181*b30d1939SAndy Fiddaman 	if (flags & O_FLAG)
182*b30d1939SAndy Fiddaman 	{
183*b30d1939SAndy Fiddaman 		if (name) sfputr(sp, name, -1);
184*b30d1939SAndy Fiddaman 		else sfprintf(sp, "%lu", number);
185*b30d1939SAndy Fiddaman 	}
186*b30d1939SAndy Fiddaman 	else
187*b30d1939SAndy Fiddaman 	{
188*b30d1939SAndy Fiddaman 		sfprintf(sp, "%u", number);
189*b30d1939SAndy Fiddaman 		if (name) sfprintf(sp, "(%s)", name);
190*b30d1939SAndy Fiddaman 	}
191*b30d1939SAndy Fiddaman }
192*b30d1939SAndy Fiddaman 
193*b30d1939SAndy Fiddaman static int
getids(Sfio_t * sp,const char * name,register int flags)194*b30d1939SAndy Fiddaman getids(Sfio_t* sp, const char* name, register int flags)
195*b30d1939SAndy Fiddaman {
196*b30d1939SAndy Fiddaman 	register struct passwd*	pw;
197*b30d1939SAndy Fiddaman 	register struct group*	grp;
198*b30d1939SAndy Fiddaman 	register int		i;
199*b30d1939SAndy Fiddaman 	register int		j;
200*b30d1939SAndy Fiddaman 	register int		k;
201*b30d1939SAndy Fiddaman #if _lib_fsid
202*b30d1939SAndy Fiddaman 	register struct fsg*	fs;
203*b30d1939SAndy Fiddaman 	const char*		fs_name;
204*b30d1939SAndy Fiddaman 	int			fs_id;
205*b30d1939SAndy Fiddaman #endif
206*b30d1939SAndy Fiddaman 	char**			p;
207*b30d1939SAndy Fiddaman 	char*			s;
208*b30d1939SAndy Fiddaman 	int			lastchar;
209*b30d1939SAndy Fiddaman 	int			ngroups = 0;
210*b30d1939SAndy Fiddaman 	const char*		gname;
211*b30d1939SAndy Fiddaman 	uid_t			user;
212*b30d1939SAndy Fiddaman 	uid_t			euid;
213*b30d1939SAndy Fiddaman 	gid_t			group;
214*b30d1939SAndy Fiddaman 	gid_t			egid;
215*b30d1939SAndy Fiddaman 
216*b30d1939SAndy Fiddaman 	static gid_t*		groups;
217*b30d1939SAndy Fiddaman 
218*b30d1939SAndy Fiddaman 	if (flags & GG_FLAG)
219*b30d1939SAndy Fiddaman 	{
220*b30d1939SAndy Fiddaman 		static int	maxgroups;
221*b30d1939SAndy Fiddaman 
222*b30d1939SAndy Fiddaman 		/*
223*b30d1939SAndy Fiddaman 		 * get supplemental groups if required
224*b30d1939SAndy Fiddaman 		 */
225*b30d1939SAndy Fiddaman 
226*b30d1939SAndy Fiddaman 		if (!maxgroups)
227*b30d1939SAndy Fiddaman 		{
228*b30d1939SAndy Fiddaman 			/*
229*b30d1939SAndy Fiddaman 			 * first time
230*b30d1939SAndy Fiddaman 			 */
231*b30d1939SAndy Fiddaman 
232*b30d1939SAndy Fiddaman 			if ((maxgroups = getgroups(0, groups)) <= 0)
233*b30d1939SAndy Fiddaman 				maxgroups = NGROUPS_MAX;
234*b30d1939SAndy Fiddaman 			if (!(groups = newof(0, gid_t, maxgroups + 1, 0)))
235*b30d1939SAndy Fiddaman 				error(ERROR_exit(1), "out of space [group array]");
236*b30d1939SAndy Fiddaman 		}
237*b30d1939SAndy Fiddaman 		ngroups = getgroups(maxgroups, groups);
238*b30d1939SAndy Fiddaman 		for (i = j = 0; i < ngroups; i++)
239*b30d1939SAndy Fiddaman 		{
240*b30d1939SAndy Fiddaman 			for (k = 0; k < j && groups[k] != groups[i]; k++);
241*b30d1939SAndy Fiddaman 			if (k >= j) groups[j++] = groups[i];
242*b30d1939SAndy Fiddaman 		}
243*b30d1939SAndy Fiddaman 		ngroups = j;
244*b30d1939SAndy Fiddaman 	}
245*b30d1939SAndy Fiddaman 	if (name)
246*b30d1939SAndy Fiddaman 	{
247*b30d1939SAndy Fiddaman 		flags |= X_FLAG;
248*b30d1939SAndy Fiddaman 		if (!(flags & N_FLAG) || (flags & (G_FLAG|GG_FLAG)))
249*b30d1939SAndy Fiddaman 		{
250*b30d1939SAndy Fiddaman 			if (!(pw = getpwnam(name)))
251*b30d1939SAndy Fiddaman 			{
252*b30d1939SAndy Fiddaman 				user = strtol(name, &s, 0);
253*b30d1939SAndy Fiddaman 				if (*s || !(pw = getpwuid(user)))
254*b30d1939SAndy Fiddaman 					error(ERROR_exit(1), "%s: name not found", name);
255*b30d1939SAndy Fiddaman 				name = pw->pw_name;
256*b30d1939SAndy Fiddaman 			}
257*b30d1939SAndy Fiddaman 			user = pw->pw_uid;
258*b30d1939SAndy Fiddaman 			group = pw->pw_gid;
259*b30d1939SAndy Fiddaman 		}
260*b30d1939SAndy Fiddaman #if _lib_fsid
261*b30d1939SAndy Fiddaman 		if (!(flags & N_FLAG) || (flags & S_FLAG))
262*b30d1939SAndy Fiddaman 		{
263*b30d1939SAndy Fiddaman 			setfsgent();
264*b30d1939SAndy Fiddaman 			do
265*b30d1939SAndy Fiddaman                         {
266*b30d1939SAndy Fiddaman                                 if (!(fs = getfsgnam(name)))
267*b30d1939SAndy Fiddaman                                         error(ERROR_exit(1), "%u: fss name not found", name);
268*b30d1939SAndy Fiddaman                         } while (isfsg(fs));
269*b30d1939SAndy Fiddaman                         fs_id = fs->fs_id;
270*b30d1939SAndy Fiddaman 		}
271*b30d1939SAndy Fiddaman #endif
272*b30d1939SAndy Fiddaman 	}
273*b30d1939SAndy Fiddaman 	else
274*b30d1939SAndy Fiddaman 	{
275*b30d1939SAndy Fiddaman 		if (flags & G_FLAG)
276*b30d1939SAndy Fiddaman 			group = (flags & R_FLAG) ? getgid() : getegid();
277*b30d1939SAndy Fiddaman 		if (flags & (GG_FLAG|N_FLAG|U_FLAG))
278*b30d1939SAndy Fiddaman 			user = (flags & R_FLAG) ? getuid() : geteuid();
279*b30d1939SAndy Fiddaman #if _lib_fsid
280*b30d1939SAndy Fiddaman 		if (flags & S_FLAG)
281*b30d1939SAndy Fiddaman 			fs_id = fsid(0);
282*b30d1939SAndy Fiddaman #endif
283*b30d1939SAndy Fiddaman 		if (flags & N_FLAG)
284*b30d1939SAndy Fiddaman 			name = (pw = getpwuid(user)) ? pw->pw_name : (char*)0;
285*b30d1939SAndy Fiddaman 	}
286*b30d1939SAndy Fiddaman 	if (ngroups == 1 && groups[0] == group)
287*b30d1939SAndy Fiddaman 		ngroups = 0;
288*b30d1939SAndy Fiddaman 	if ((flags & N_FLAG) && (flags & G_FLAG))
289*b30d1939SAndy Fiddaman 		gname = (grp = getgrgid(group)) ? grp->gr_name : (char*)0;
290*b30d1939SAndy Fiddaman #if _lib_fsid
291*b30d1939SAndy Fiddaman 	if ((flags & N_FLAG) && (flags & S_FLAG))
292*b30d1939SAndy Fiddaman 	{
293*b30d1939SAndy Fiddaman 		setfsgent();
294*b30d1939SAndy Fiddaman 		fs_name = (fs = getfsgid(fs_id)) ? fs->fs_grp : (char*)0;
295*b30d1939SAndy Fiddaman 	}
296*b30d1939SAndy Fiddaman #endif
297*b30d1939SAndy Fiddaman 	if ((flags & (U_FLAG|G_FLAG|S_FLAG)) == (U_FLAG|G_FLAG|S_FLAG))
298*b30d1939SAndy Fiddaman 	{
299*b30d1939SAndy Fiddaman 		putid(sp, flags, "uid", name, user);
300*b30d1939SAndy Fiddaman 		putid(sp, flags, " gid", gname, group);
301*b30d1939SAndy Fiddaman 		if ((flags & X_FLAG) && name)
302*b30d1939SAndy Fiddaman 		{
303*b30d1939SAndy Fiddaman #if _lib_getgrent
304*b30d1939SAndy Fiddaman #if _lib_setgrent
305*b30d1939SAndy Fiddaman 			setgrent();
306*b30d1939SAndy Fiddaman #endif
307*b30d1939SAndy Fiddaman 			lastchar = '=';
308*b30d1939SAndy Fiddaman 			while (grp = getgrent())
309*b30d1939SAndy Fiddaman 				if (p = grp->gr_mem)
310*b30d1939SAndy Fiddaman 					while (s = *p++)
311*b30d1939SAndy Fiddaman 						if (streq(s, name))
312*b30d1939SAndy Fiddaman 						{
313*b30d1939SAndy Fiddaman 							if (lastchar == '=')
314*b30d1939SAndy Fiddaman 								sfputr(sp, " groups", -1);
315*b30d1939SAndy Fiddaman 							sfputc(sp, lastchar);
316*b30d1939SAndy Fiddaman 							lastchar = ',';
317*b30d1939SAndy Fiddaman 							if (flags & O_FLAG)
318*b30d1939SAndy Fiddaman 								sfprintf(sp, "%s", grp->gr_name);
319*b30d1939SAndy Fiddaman 							else sfprintf(sp, "%u(%s)", grp->gr_gid, grp->gr_name);
320*b30d1939SAndy Fiddaman 						}
321*b30d1939SAndy Fiddaman #if _lib_endgrent
322*b30d1939SAndy Fiddaman 			endgrent();
323*b30d1939SAndy Fiddaman #endif
324*b30d1939SAndy Fiddaman #endif
325*b30d1939SAndy Fiddaman #if _lib_fsid
326*b30d1939SAndy Fiddaman 			getfsids(sp, name, flags, '=');
327*b30d1939SAndy Fiddaman #endif
328*b30d1939SAndy Fiddaman 		}
329*b30d1939SAndy Fiddaman 		else
330*b30d1939SAndy Fiddaman 		{
331*b30d1939SAndy Fiddaman 			if ((euid = geteuid()) != user)
332*b30d1939SAndy Fiddaman 				putid(sp, flags, " euid", (pw = getpwuid(euid)) ? pw->pw_name : (char*)0, euid);
333*b30d1939SAndy Fiddaman 			if ((egid = getegid()) != group)
334*b30d1939SAndy Fiddaman 				putid(sp, flags, " egid", (grp = getgrgid(egid)) ? grp->gr_name : (char*)0, egid);
335*b30d1939SAndy Fiddaman 			if (ngroups > 0)
336*b30d1939SAndy Fiddaman 			{
337*b30d1939SAndy Fiddaman 				sfputr(sp, " groups", -1);
338*b30d1939SAndy Fiddaman 				lastchar = '=';
339*b30d1939SAndy Fiddaman 				for (i = 0; i < ngroups; i++)
340*b30d1939SAndy Fiddaman 				{
341*b30d1939SAndy Fiddaman 					group = groups[i];
342*b30d1939SAndy Fiddaman 					sfputc(sp, lastchar);
343*b30d1939SAndy Fiddaman 					if (grp = getgrgid(group))
344*b30d1939SAndy Fiddaman 					{
345*b30d1939SAndy Fiddaman 						if (flags & O_FLAG) sfprintf(sp, "%s", grp->gr_name);
346*b30d1939SAndy Fiddaman 						else sfprintf(sp, "%u(%s)", group, grp->gr_name);
347*b30d1939SAndy Fiddaman 					}
348*b30d1939SAndy Fiddaman 					else sfprintf(sp, "%u", group);
349*b30d1939SAndy Fiddaman 					lastchar = ',';
350*b30d1939SAndy Fiddaman 				}
351*b30d1939SAndy Fiddaman 			}
352*b30d1939SAndy Fiddaman #if _lib_fsid
353*b30d1939SAndy Fiddaman 			putid(sp, flags, " fsid", fs_name, fs_id);
354*b30d1939SAndy Fiddaman #endif
355*b30d1939SAndy Fiddaman 		}
356*b30d1939SAndy Fiddaman 		sfputc(sp,'\n');
357*b30d1939SAndy Fiddaman 		return(0);
358*b30d1939SAndy Fiddaman 	}
359*b30d1939SAndy Fiddaman 	if (flags & U_FLAG)
360*b30d1939SAndy Fiddaman 	{
361*b30d1939SAndy Fiddaman 		if ((flags & N_FLAG) && name) sfputr(sp, name, '\n');
362*b30d1939SAndy Fiddaman 		else sfprintf(sp, "%u\n", user);
363*b30d1939SAndy Fiddaman 	}
364*b30d1939SAndy Fiddaman 	else if (flags & G_FLAG)
365*b30d1939SAndy Fiddaman 	{
366*b30d1939SAndy Fiddaman 		if ((flags & N_FLAG) && gname) sfputr(sp, gname, '\n');
367*b30d1939SAndy Fiddaman 		else sfprintf(sp, "%u\n", group);
368*b30d1939SAndy Fiddaman 	}
369*b30d1939SAndy Fiddaman 	else if (flags & GG_FLAG)
370*b30d1939SAndy Fiddaman 	{
371*b30d1939SAndy Fiddaman 		if ((flags & X_FLAG) && name)
372*b30d1939SAndy Fiddaman 		{
373*b30d1939SAndy Fiddaman #if _lib_getgrent
374*b30d1939SAndy Fiddaman #if _lib_setgrent
375*b30d1939SAndy Fiddaman 			setgrent();
376*b30d1939SAndy Fiddaman #endif
377*b30d1939SAndy Fiddaman 			i = 0;
378*b30d1939SAndy Fiddaman 			while (grp = getgrent())
379*b30d1939SAndy Fiddaman 				if (p = grp->gr_mem)
380*b30d1939SAndy Fiddaman 					while (s = *p++)
381*b30d1939SAndy Fiddaman 						if (streq(s, name))
382*b30d1939SAndy Fiddaman 						{
383*b30d1939SAndy Fiddaman 							if (i++) sfputc(sp, ' ');
384*b30d1939SAndy Fiddaman 							if (flags & N_FLAG) sfprintf(sp, "%s", grp->gr_name);
385*b30d1939SAndy Fiddaman 							else sfprintf(sp, "%u", grp->gr_gid);
386*b30d1939SAndy Fiddaman 						}
387*b30d1939SAndy Fiddaman #if _lib_endgrent
388*b30d1939SAndy Fiddaman 			endgrent();
389*b30d1939SAndy Fiddaman #endif
390*b30d1939SAndy Fiddaman 			if (i) sfputc(sp, '\n');
391*b30d1939SAndy Fiddaman #endif
392*b30d1939SAndy Fiddaman 		}
393*b30d1939SAndy Fiddaman 		else if (ngroups > 0)
394*b30d1939SAndy Fiddaman 		{
395*b30d1939SAndy Fiddaman 			for (i = 0;;)
396*b30d1939SAndy Fiddaman 			{
397*b30d1939SAndy Fiddaman 				group = groups[i];
398*b30d1939SAndy Fiddaman 				if ((flags & N_FLAG) && (grp = getgrgid(group)))
399*b30d1939SAndy Fiddaman 					sfprintf(sp, "%s", grp->gr_name);
400*b30d1939SAndy Fiddaman 				else sfprintf(sp, "%u", group);
401*b30d1939SAndy Fiddaman 				if (++i >= ngroups) break;
402*b30d1939SAndy Fiddaman 				sfputc(sp, ' ');
403*b30d1939SAndy Fiddaman 			}
404*b30d1939SAndy Fiddaman 			sfputc(sp, '\n');
405*b30d1939SAndy Fiddaman 		}
406*b30d1939SAndy Fiddaman 	}
407*b30d1939SAndy Fiddaman #if _lib_fsid
408*b30d1939SAndy Fiddaman 	else if (flags & S_FLAG)
409*b30d1939SAndy Fiddaman 	{
410*b30d1939SAndy Fiddaman 		if ((flags & X_FLAG) && name) getfsids(sp, name, flags, 0);
411*b30d1939SAndy Fiddaman 		else if ((flags & N_FLAG) && fs_name) sfputr(sp, fs_name, '\n');
412*b30d1939SAndy Fiddaman 		else sfprintf(sp, "%u\n", fs_id);
413*b30d1939SAndy Fiddaman 	}
414*b30d1939SAndy Fiddaman #endif
415*b30d1939SAndy Fiddaman 	return(0);
416*b30d1939SAndy Fiddaman }
417*b30d1939SAndy Fiddaman 
418*b30d1939SAndy Fiddaman int
b_id(int argc,char ** argv,Shbltin_t * context)419*b30d1939SAndy Fiddaman b_id(int argc, char** argv, Shbltin_t* context)
420*b30d1939SAndy Fiddaman {
421*b30d1939SAndy Fiddaman 	register int	flags = 0;
422*b30d1939SAndy Fiddaman 	register int	n;
423*b30d1939SAndy Fiddaman 
424*b30d1939SAndy Fiddaman 	cmdinit(argc, argv, context, ERROR_CATALOG, 0);
425*b30d1939SAndy Fiddaman 	for (;;)
426*b30d1939SAndy Fiddaman 	{
427*b30d1939SAndy Fiddaman 		switch (optget(argv, usage))
428*b30d1939SAndy Fiddaman 		{
429*b30d1939SAndy Fiddaman 		case 'a':
430*b30d1939SAndy Fiddaman 			continue;
431*b30d1939SAndy Fiddaman 		case 'G':
432*b30d1939SAndy Fiddaman 			flags |= GG_FLAG;
433*b30d1939SAndy Fiddaman 			continue;
434*b30d1939SAndy Fiddaman 		case 'g':
435*b30d1939SAndy Fiddaman 			flags |= G_FLAG;
436*b30d1939SAndy Fiddaman 			continue;
437*b30d1939SAndy Fiddaman 		case 'n':
438*b30d1939SAndy Fiddaman 			flags |= N_FLAG;
439*b30d1939SAndy Fiddaman 			continue;
440*b30d1939SAndy Fiddaman 		case 'r':
441*b30d1939SAndy Fiddaman 			flags |= R_FLAG;
442*b30d1939SAndy Fiddaman 			continue;
443*b30d1939SAndy Fiddaman 		case 's':
444*b30d1939SAndy Fiddaman 			flags |= S_FLAG;
445*b30d1939SAndy Fiddaman 			continue;
446*b30d1939SAndy Fiddaman 		case 'u':
447*b30d1939SAndy Fiddaman 			flags |= U_FLAG;
448*b30d1939SAndy Fiddaman 			continue;
449*b30d1939SAndy Fiddaman 		case ':':
450*b30d1939SAndy Fiddaman 			error(2, "%s", opt_info.arg);
451*b30d1939SAndy Fiddaman 			break;
452*b30d1939SAndy Fiddaman 		case '?':
453*b30d1939SAndy Fiddaman 			error(ERROR_usage(2), "%s", opt_info.arg);
454*b30d1939SAndy Fiddaman 			break;
455*b30d1939SAndy Fiddaman 		}
456*b30d1939SAndy Fiddaman 		break;
457*b30d1939SAndy Fiddaman 	}
458*b30d1939SAndy Fiddaman 	argv += opt_info.index;
459*b30d1939SAndy Fiddaman 	argc -= opt_info.index;
460*b30d1939SAndy Fiddaman 	n = (flags & (GG_FLAG|G_FLAG|S_FLAG|U_FLAG));
461*b30d1939SAndy Fiddaman 	if (!power2(n))
462*b30d1939SAndy Fiddaman 		error(2, "incompatible options selected");
463*b30d1939SAndy Fiddaman 	if (error_info.errors || argc > 1)
464*b30d1939SAndy Fiddaman 		error(ERROR_usage(2), "%s", optusage(NiL));
465*b30d1939SAndy Fiddaman 	if (!(flags & ~(N_FLAG|R_FLAG)))
466*b30d1939SAndy Fiddaman 	{
467*b30d1939SAndy Fiddaman 		if (flags & N_FLAG) flags |= O_FLAG;
468*b30d1939SAndy Fiddaman 		flags |= (U_FLAG|G_FLAG|N_FLAG|R_FLAG|S_FLAG|GG_FLAG);
469*b30d1939SAndy Fiddaman 	}
470*b30d1939SAndy Fiddaman 	error_info.errors = getids(sfstdout, *argv, flags);
471*b30d1939SAndy Fiddaman 	return(error_info.errors);
472*b30d1939SAndy Fiddaman }
473