OSDN Git Service

Make groups handle multiple usernames on command line.
[android-x86/external-toybox.git] / toys / posix / id.c
1 /* id.c - print real and effective user and group IDs
2  *
3  * Copyright 2012 Sony Network Entertainment, Inc.
4  *
5  * by Tim Bird <tim.bird@am.sony.com>
6  *
7  * See http://opengroup.org/onlinepubs/9699919799/utilities/id.html
8
9 USE_ID(NEWTOY(id, ">1nGgru[!Ggu]", TOYFLAG_BIN))
10 USE_ID_GROUPS(OLDTOY(groups, id, NULL, TOYFLAG_USR|TOYFLAG_BIN))
11
12 config ID
13   bool "id"
14   default y
15   help
16     usage: id [-nGgru]
17
18     Print user and group ID.
19
20     -n  print names instead of numeric IDs (to be used with -Ggu)
21     -G  Show only the group IDs
22     -g  Show only the effective group ID
23     -r  Show real ID instead of effective ID
24     -u  Show only the effective user ID
25
26 config ID_GROUPS
27   bool "groups"
28   default y
29   depends on ID
30   help
31     usage: groups [user]
32
33     Print the groups a user is in.
34
35 */
36
37 #define FOR_id
38 #include "toys.h"
39
40 static void s_or_u(char *s, unsigned u, int done)
41 {
42   if (toys.optflags & FLAG_n) printf("%s", s);
43   else printf("%u", u);
44   if (done) {
45     xputc('\n');
46     exit(0);
47   }
48 }
49
50 static void showid(char *header, unsigned u, char *s)
51 {
52   printf("%s%u(%s)", header, u, s);
53 }
54
55 struct passwd *xgetpwuid(uid_t uid)
56 {
57   struct passwd *pwd = getpwuid(uid);
58   if (!pwd) error_exit(NULL);
59   return pwd;
60 }
61
62 struct group *xgetgrgid(gid_t gid)
63 {
64   struct group *group = getgrgid(gid);
65   if (!group) error_exit(NULL);
66   return group;
67 }
68
69 void do_id(char *username)
70 {
71   int flags, i, ngroups, cmd_groups = toys.which->name[0] == 'g';
72   struct passwd *pw;
73   struct group *grp;
74   uid_t uid = getuid(), euid = geteuid();
75   gid_t gid = getgid(), egid = getegid(), *groups;
76
77   if (cmd_groups)
78       toys.optflags |= FLAG_G | FLAG_n;
79
80   flags = toys.optflags;
81
82   // check if a username is given
83   if (username) {
84     if (!(pw = getpwnam(username)))
85       error_exit("no such user '%s'", username);
86     uid = euid = pw->pw_uid;
87     gid = egid = pw->pw_gid;
88     if (cmd_groups)
89       printf("%s : ", pw->pw_name);
90   }
91
92   i = flags & FLAG_r;
93   pw = xgetpwuid(i ? uid : euid);
94   if (flags & FLAG_u) s_or_u(pw->pw_name, pw->pw_uid, 1);
95
96   grp = xgetgrgid(i ? gid : egid);
97   if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);
98
99   if (!(flags & FLAG_G)) {
100     showid("uid=", pw->pw_uid, pw->pw_name);
101     showid(" gid=", grp->gr_gid, grp->gr_name);
102
103     if (!i) {
104       if (uid != euid) {
105         pw = xgetpwuid(euid);
106         showid(" euid=", pw->pw_uid, pw->pw_name);
107       }
108       if (gid != egid) {
109         grp = xgetgrgid(egid);
110         showid(" egid=", grp->gr_gid, grp->gr_name);
111       }
112     }
113
114     showid(" groups=", grp->gr_gid, grp->gr_name);
115   }
116
117   groups = (gid_t *)toybuf;
118   i = sizeof(toybuf)/sizeof(gid_t);
119   ngroups = username ? getgrouplist(username, gid, groups, &i)
120     : getgroups(i, groups);
121   if (0 >= ngroups) perror_exit(0);
122
123   for (i = 0;;) {
124     if (!(grp = getgrgid(groups[i]))) perror_msg(0);
125     else if (flags & FLAG_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
126     else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name);
127     if (++i >= ngroups) break;
128     xputc(' ');
129   }
130   xputc('\n');
131 }
132
133 void id_main(void)
134 {
135   if (toys.optc) while(*toys.optargs) do_id(*toys.optargs++);
136   else do_id(NULL);
137 }