comparison toys/id.c @ 542:06763d1a2f9d

Tighten up the code a bit, and use actual process group id instead of what /etc/passwd says.
author Rob Landley <rob@landley.net>
date Mon, 12 Mar 2012 20:56:56 -0500
parents 31215cc6c9f2
children 60b97ba66a70
comparison
equal deleted inserted replaced
541:ff71169e8440 542:06763d1a2f9d
34 #define FLAG_u 1 34 #define FLAG_u 1
35 35
36 void pretty_print(struct passwd *pw, struct group *grp, struct group **grps, 36 void pretty_print(struct passwd *pw, struct group *grp, struct group **grps,
37 int n) 37 int n)
38 { 38 {
39 int i; 39 int i = 0;
40 printf("uid= %d(%s) gid= %d(%s)", pw->pw_uid, pw->pw_name, 40
41 grp->gr_gid, grp->gr_name); 41 printf("uid=%u(%s) gid=%u(%s)", pw->pw_uid, pw->pw_name,
42 if (n) { 42 grp->gr_gid, grp->gr_name);
43 printf(" groups= "); 43 if (n) printf(" groups=");
44 while (i < n) {
45 printf("%d(%s)", grps[i]->gr_gid, grps[i]->gr_name);
46 if (++i<n) xputc(',');
44 } 47 }
45 for (i = 0; i < n; i++) { 48 xputc('\n');
46 printf("%d(%s)%s", grps[i]->gr_gid, grps[i]->gr_name,
47 (i < n-1) ? ",": "");
48 }
49 printf("\n");
50 } 49 }
51 50
52 void id_main(void) 51 void id_main(void)
53 { 52 {
54 int flags = toys.optflags; 53 int flags = toys.optflags, i, ngroups;
55
56 struct passwd *pw; 54 struct passwd *pw;
57 struct group *grp; 55 struct group *grp, **grps;
58 struct group **grps;
59 uid_t uid; 56 uid_t uid;
60 gid_t gid; 57 gid_t gid, *groups;
61 gid_t *groups;
62 int i;
63 int ngroups;
64 char *username;
65 58
66 /* check if a username is given */ 59 /* check if a username is given */
67 if (*toys.optargs) { 60 if (*toys.optargs) {
68 username = *(toys.optargs); 61 if (!(pw = getpwnam(*toys.optargs)))
69 pw = getpwnam(username); 62 error_exit("no such user '%s'", *toys.optargs);
70 if (!pw) {
71 printf("id: %s: no such user\n", username);
72 toys.exitval = 1;
73 return;
74 }
75 uid = pw->pw_uid; 63 uid = pw->pw_uid;
76 gid = pw->pw_gid; 64 gid = pw->pw_gid;
77 } else { 65 } else {
78 /* show effective, unless user specifies real */ 66 /* show effective, unless user specifies real */
79 if (flags & FLAG_r) { 67 if (flags & FLAG_r) {
83 uid = geteuid(); 71 uid = geteuid();
84 gid = getegid(); 72 gid = getegid();
85 } 73 }
86 } 74 }
87 75
88 pw = getpwuid(uid); 76 if (!(pw = getpwuid(uid)) || !(grp = getgrgid(gid)))
89 if (!pw) { 77 perror_exit(0);
90 perror("id"); 78
91 toys.exitval = 1; 79 if (flags & FLAG_u) {
80 if (flags & FLAG_n) xputs(pw->pw_name);
81 else printf("%d\n", pw->pw_uid);
82 return;
83 }
84 if (flags & FLAG_g) {
85 if (flags & FLAG_n) xputs(grp->gr_name);
86 else printf("%d\n", grp->gr_gid);
92 return; 87 return;
93 } 88 }
94 89
95 grp = getgrgid(pw->pw_gid); 90 ngroups = sysconf(_SC_NGROUPS_MAX);
96 if (!grp) { 91 if (ngroups<1) ngroups = 32;
97 perror("id"); 92 groups = xmalloc(ngroups * sizeof(gid_t));
98 toys.exitval = 1; 93 if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) < 0)
99 return; 94 perror_exit(0);
100 }
101
102 if (flags & FLAG_u) {
103 if (flags & FLAG_n)
104 printf("%s\n", pw->pw_name);
105 else
106 printf("%d\n", pw->pw_uid);
107 return;
108 }
109 if (flags & FLAG_g) {
110 if (flags & FLAG_n)
111 printf("%s\n", grp->gr_name);
112 else
113 printf("%d\n", grp->gr_gid);
114 return;
115 }
116
117 95
118 if (flags & FLAG_r) { 96 grps = xmalloc(ngroups * sizeof(struct group *));
119 printf("-r can only be used in combination with -u or -g\n");
120 toys.exitval = 1;
121 return;
122 }
123 ngroups = sysconf(_SC_NGROUPS_MAX);
124 /* fallback for number of groups to 32 */
125 if (ngroups < 0)
126 ngroups = 32;
127 groups = malloc(ngroups * sizeof(gid_t));
128 if (!groups) {
129 perror("id");
130 toys.exitval = 1;
131 return;
132 }
133 if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) < 0) {
134 perror("id");
135 toys.exitval = 1;
136 return;
137 }
138 grps = malloc(ngroups * sizeof(struct group *));
139 for (i = 0; i < ngroups; i++) { 97 for (i = 0; i < ngroups; i++) {
140 struct group *tmp; 98 struct group *tmp;
141 grps[i] = malloc(sizeof(struct group)); 99 grps[i] = xmalloc(sizeof(struct group));
142 size_t f = sysconf(_SC_GETGR_R_SIZE_MAX); 100 size_t f = sysconf(_SC_GETGR_R_SIZE_MAX);
143 char *buf = malloc(f); 101 char *buf = xmalloc(f);
144 if (getgrgid_r(groups[i], grps[i], buf, f, &tmp) < 0) { 102 if (getgrgid_r(groups[i], grps[i], buf, f, &tmp) < 0 || !tmp) {
145 perror("id"); 103 perror_msg(0);
146 continue;
147 }
148 if (tmp == NULL) {
149 perror("id");
150 continue; 104 continue;
151 } 105 }
152 } 106 }
153 107
154 if (flags & FLAG_G) { 108 if (flags & FLAG_G) {
155 for (i = 0; i < ngroups; i++) { 109 for (i = 0; i < ngroups; i++) {
156 if (flags & FLAG_n) 110 if (i) xputc(' ');
157 printf("%s%s", !i ? "" : " ", grps[i]->gr_name); 111 if (flags & FLAG_n) printf("%s", grps[i]->gr_name);
158 else 112 else printf("%d", grps[i]->gr_gid);
159 printf("%s%d", !i ? "" : " ", grps[i]->gr_gid);
160 } 113 }
161 printf("\n"); 114 printf("\n");
162 return; 115 return;
163 } 116 }
164 117