merge with 1.8.1d
[coreutils.git] / src / id.c
blobdaa65c86cb7c9793acb2405e9bd589c40da5a897
1 /* id -- print real and effective UIDs and GIDs
2 Copyright (C) 1989, 1991 Free Software Foundation.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Written by Arnold Robbins, arnold@audiofax.com.
19 Major rewrite by David MacKenzie, djm@gnu.ai.mit.edu. */
21 #ifdef HAVE_CONFIG_H
22 #if defined (CONFIG_BROKETS)
23 /* We use <config.h> instead of "config.h" so that a compilation
24 using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
25 (which it would do because it found this file in $srcdir). */
26 #include <config.h>
27 #else
28 #include "config.h"
29 #endif
30 #endif
32 #include <stdio.h>
33 #include <getopt.h>
34 #include <sys/types.h>
35 #include <pwd.h>
36 #include <grp.h>
37 #include <getopt.h>
39 #include "version.h"
40 #include "system.h"
42 #ifdef _POSIX_VERSION
43 #include <limits.h>
44 #if !defined(NGROUPS_MAX) || NGROUPS_MAX < 1
45 #define NGROUPS_MAX sysconf (_SC_NGROUPS_MAX)
46 #endif /* !NGROUPS_MAX */
48 #else /* not _POSIX_VERSION */
49 struct passwd *getpwuid ();
50 struct group *getgrgid ();
51 uid_t getuid ();
52 gid_t getgid ();
53 uid_t geteuid ();
54 gid_t getegid ();
55 #include <sys/param.h>
56 #if !defined(NGROUPS_MAX) && defined(NGROUPS)
57 #define NGROUPS_MAX NGROUPS
58 #endif /* not NGROUPS_MAX and NGROUPS */
59 #endif /* not _POSIX_VERSION */
61 char *xmalloc ();
62 int getugroups ();
63 void error ();
65 static void print_user ();
66 static void print_group ();
67 static void print_group_list ();
68 static void print_full_info ();
69 static void usage ();
71 /* The name this program was run with. */
72 char *program_name;
74 /* If nonzero, output only the group ID(s). -g */
75 static int just_group = 0;
77 /* If nonzero, output user/group name instead of ID number. -n */
78 static int use_name = 0;
80 /* If nonzero, output real UID/GID instead of default effective UID/GID. -r */
81 static int use_real = 0;
83 /* If nonzero, output only the user ID(s). -u */
84 static int just_user = 0;
86 /* If nonzero, output only the supplementary groups. -G */
87 static int just_group_list = 0;
89 /* The real and effective IDs of the user to print. */
90 static uid_t ruid, euid;
91 static gid_t rgid, egid;
93 /* The number of errors encountered so far. */
94 static int problems = 0;
96 /* If non-zero, display usage information and exit. */
97 static int show_help;
99 /* If non-zero, print the version on standard output and exit. */
100 static int show_version;
102 static struct option const longopts[] =
104 {"group", no_argument, NULL, 'g'},
105 {"groups", no_argument, NULL, 'G'},
106 {"help", no_argument, &show_help, 1},
107 {"name", no_argument, NULL, 'n'},
108 {"real", no_argument, NULL, 'r'},
109 {"user", no_argument, NULL, 'u'},
110 {"version", no_argument, &show_version, 1},
111 {NULL, 0, NULL, 0}
114 void
115 main (argc, argv)
116 int argc;
117 char **argv;
119 int optc;
121 program_name = argv[0];
123 while ((optc = getopt_long (argc, argv, "gnruG", longopts, (int *) 0))
124 != EOF)
126 switch (optc)
128 case 0:
129 break;
130 case 'g':
131 just_group = 1;
132 break;
133 case 'n':
134 use_name = 1;
135 break;
136 case 'r':
137 use_real = 1;
138 break;
139 case 'u':
140 just_user = 1;
141 break;
142 case 'G':
143 just_group_list = 1;
144 break;
145 default:
146 usage ();
150 if (show_version)
152 printf ("%s\n", version_string);
153 exit (0);
156 if (show_help)
157 usage ();
159 if (just_user + just_group + just_group_list > 1)
160 error (1, 0, "cannot print only user and only group");
162 if (just_user + just_group + just_group_list == 0 && (use_real || use_name))
163 error (1, 0, "cannot print only names or real IDs in default format");
165 if (argc - optind > 1)
166 usage ();
168 if (argc - optind == 1)
170 struct passwd *pwd = getpwnam (argv[optind]);
171 if (pwd == NULL)
172 error (1, 0, "%s: No such user", argv[optind]);
173 ruid = euid = pwd->pw_uid;
174 rgid = egid = pwd->pw_gid;
176 else
178 euid = geteuid ();
179 ruid = getuid ();
180 egid = getegid ();
181 rgid = getgid ();
184 if (just_user)
185 print_user (use_real ? ruid : euid);
186 else if (just_group)
187 print_group (use_real ? rgid : egid);
188 else if (just_group_list)
189 print_group_list (argv[optind]);
190 else
191 print_full_info (argv[optind]);
192 putchar ('\n');
194 exit (problems != 0);
197 /* Print the name or value of user ID UID. */
199 static void
200 print_user (uid)
201 int uid;
203 struct passwd *pwd = NULL;
205 if (use_name)
207 pwd = getpwuid (uid);
208 if (pwd == NULL)
209 problems++;
212 if (pwd == NULL)
213 printf ("%u", (unsigned) uid);
214 else
215 printf ("%s", pwd->pw_name);
218 /* Print the name or value of group ID GID. */
220 static void
221 print_group (gid)
222 int gid;
224 struct group *grp = NULL;
226 if (use_name)
228 grp = getgrgid (gid);
229 if (grp == NULL)
230 problems++;
233 if (grp == NULL)
234 printf ("%u", (unsigned) gid);
235 else
236 printf ("%s", grp->gr_name);
239 /* Print all of the distinct groups the user is in . */
241 static void
242 print_group_list (username)
243 char *username;
245 print_group (rgid);
246 if (egid != rgid)
248 putchar (' ');
249 print_group (egid);
252 #ifdef NGROUPS_MAX
254 int ngroups;
255 GETGROUPS_T *groups;
256 register int i;
258 groups = (GETGROUPS_T *) xmalloc (NGROUPS_MAX * sizeof (GETGROUPS_T));
259 if (username == 0)
260 ngroups = getgroups (NGROUPS_MAX, groups);
261 else
262 ngroups = getugroups (NGROUPS_MAX, groups, username);
263 if (ngroups < 0)
265 error (0, errno, "cannot get supplemental group list");
266 problems++;
267 free (groups);
268 return;
271 for (i = 0; i < ngroups; i++)
272 if (groups[i] != rgid && groups[i] != egid)
274 putchar (' ');
275 print_group (groups[i]);
277 free (groups);
279 #endif
282 /* Print all of the info about the user's user and group IDs. */
284 static void
285 print_full_info (username)
286 char *username;
288 struct passwd *pwd;
289 struct group *grp;
291 printf ("uid=%u", (unsigned) ruid);
292 pwd = getpwuid (ruid);
293 if (pwd == NULL)
294 problems++;
295 else
296 printf ("(%s)", pwd->pw_name);
298 printf (" gid=%u", (unsigned) rgid);
299 grp = getgrgid (rgid);
300 if (grp == NULL)
301 problems++;
302 else
303 printf ("(%s)", grp->gr_name);
305 if (euid != ruid)
307 printf (" euid=%u", (unsigned) euid);
308 pwd = getpwuid (euid);
309 if (pwd == NULL)
310 problems++;
311 else
312 printf ("(%s)", pwd->pw_name);
315 if (egid != rgid)
317 printf (" egid=%u", (unsigned) egid);
318 grp = getgrgid (egid);
319 if (grp == NULL)
320 problems++;
321 else
322 printf ("(%s)", grp->gr_name);
325 #ifdef NGROUPS_MAX
327 int ngroups;
328 GETGROUPS_T *groups;
329 register int i;
331 groups = (GETGROUPS_T *) xmalloc (NGROUPS_MAX * sizeof (GETGROUPS_T));
332 if (username == 0)
333 ngroups = getgroups (NGROUPS_MAX, groups);
334 else
335 ngroups = getugroups (NGROUPS_MAX, groups, username);
336 if (ngroups < 0)
338 error (0, errno, "cannot get supplemental group list");
339 problems++;
340 free (groups);
341 return;
344 if (ngroups > 0)
345 fputs (" groups=", stdout);
346 for (i = 0; i < ngroups; i++)
348 if (i > 0)
349 putchar (',');
350 printf ("%u", (unsigned) groups[i]);
351 grp = getgrgid (groups[i]);
352 if (grp == NULL)
353 problems++;
354 else
355 printf ("(%s)", grp->gr_name);
357 free (groups);
359 #endif
362 static void
363 usage ()
365 fprintf (stderr, "\
366 Usage: %s [-gnruG] [--group] [--name] [--real] [--user] [--groups] [username]\n",
367 program_name);
368 exit (1);