btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / bin / id.c
blob222a7270375bef27939625f6be1da0f7a190ef85
1 /*
2 ** Copyright (c) 2004 OBOS
3 ** Permission is hereby granted, free of charge, to any person obtaining a copy
4 ** of this software and associated documentation files (the "Software"), to deal
5 ** in the Software without restriction, including without limitation the rights
6 ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 ** copies of the Software, and to permit persons to whom the Software is
8 ** furnished to do so, subject to the following conditions:
9 **
10 ** The above copyright notice and this permission notice shall be included in all
11 ** copies or substantial portions of the Software.
12 **
13 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 ** SOFTWARE.
23 #include <sys/stat.h>
24 #include <errno.h>
25 #include <getopt.h>
26 #include <grp.h>
27 #include <pwd.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
33 static void print_user_info(int userID, char *suffix);
34 static void print_group_info(int groupID, char *suffix);
35 static void print_group_list(int listID);
36 static void print_combined_info(void);
37 static void suggest_help(void);
38 static void usage(void);
39 static void version(void);
41 char *progName;
42 static int gFlag, glFlag, nFlag, rFlag, uFlag;
43 struct passwd *euidName;
44 struct passwd *ruidName;
45 struct group *egidName;
46 struct group *rgidName;
47 uid_t eUID;
48 uid_t rUID;
49 gid_t eGID;
50 gid_t rGID;
51 gid_t groupList;
52 char *suffix;
55 static void
56 print_user_info(int userID, char *suffix) {
57 struct stat statBuffer;
58 struct passwd *userIDName;
59 if ((userIDName = getpwuid(userID)) != NULL) {
60 if (nFlag)
61 fprintf(stdout, "%s%s", userIDName->pw_name, suffix);
62 else
63 fprintf(stdout, "%u%s", eUID, suffix);
64 } else
65 fprintf(stdout, "%-8d%s", statBuffer.st_uid, suffix);
69 static void
70 print_group_info(int groupID, char *suffix) {
71 struct stat statBuffer;
72 struct group *groupIDName;
73 if ((groupIDName = getgrgid(groupID)) != NULL) {
74 if (nFlag)
75 fprintf(stdout, "%s%s", groupIDName->gr_name, suffix);
76 else
77 fprintf(stdout, "%u%s", groupID, suffix);
78 } else
79 fprintf(stdout, " %-8d%s", statBuffer.st_gid, suffix);
82 static void
83 print_group_list(int groupID) {
84 int cnt, id, lastID, nGroups;
85 gid_t *groups;
86 long ngroups_max;
88 ngroups_max = sysconf(NGROUPS_MAX) + 1;
89 groups = (gid_t *)malloc(ngroups_max *sizeof(gid_t));
91 nGroups = getgroups(ngroups_max, groups);
93 suffix = "";
94 print_group_info(groupID, suffix);
95 for (lastID = -1, cnt = 0; cnt < ngroups_max; ++cnt) {
96 if (lastID == (id = groups[cnt]))
97 continue;
98 suffix = " ";
99 print_group_info(id, suffix);
100 lastID = id;
102 fprintf(stdout, "\n");
106 static void
107 print_combined_info() {
108 if ( eUID != rUID ) {
109 suffix = "";
110 rFlag = 1;
111 fprintf(stdout, "uid=");
112 print_user_info(rUID, suffix);
113 fprintf(stdout, "(");
114 nFlag = 1;
115 print_user_info(rUID, suffix);
116 fprintf(stdout, ") gid=");
117 rFlag = 1; nFlag = 0;
118 print_group_info(rGID, suffix);
119 fprintf(stdout, "(");
120 rFlag = 0; nFlag = 1;
121 print_group_info(eGID, suffix);
122 fprintf(stdout, ") euid=");
123 rFlag = 0; nFlag = 0;
124 print_user_info(eUID, suffix);
125 fprintf(stdout, "(");
126 rFlag = 0; nFlag = 1;
127 print_user_info(eUID, suffix);
128 fprintf(stdout, ")\n");
129 } else {
130 suffix = "";
131 rFlag = 1;
132 fprintf(stdout, "uid=");
133 print_user_info(rUID, suffix);
134 fprintf(stdout, "(");
135 nFlag = 1;
136 print_user_info(rUID, suffix);
137 fprintf(stdout, ") gid=");
138 rFlag = 1; nFlag = 0;
139 print_group_info(rGID, suffix);
140 fprintf(stdout, "(");
141 rFlag = 1; nFlag = 1;
142 print_group_info(rGID, suffix);
143 fprintf(stdout, ")\n");
148 static void
149 suggest_help(void)
151 (void)fprintf(stdout, "Try `%s --help' for more information.\n", progName);
155 static void
156 usage(void)
158 fprintf(stdout,
159 "%s OBOS (http://www.openbeos.org/)
161 Usage: %s [OPTION]... [USERNAME]
163 -g, --group print only the group ID
164 -G, --groups print only the supplementary groups
165 -n, --name print a name instead of a number, for -ugG
166 -r, --real print the real ID instead of effective ID, for -ugG
167 -u, --user print only the user ID
168 --help display this help and exit
169 --version output version information and exit
171 Print information for USERNAME, or the current user.
173 ", progName, progName );
177 static void
178 version(void)
180 fprintf(stdout, "%s OBOS (http://www.openbeos.org/)\n", progName);
185 main(int argc, char *argv[])
187 int argOption;
188 int indexptr = 0;
189 char * const * optargv = argv;
191 struct option groupOption = { "group", no_argument, 0, 1 } ;
192 struct option groupsOption = { "groups", no_argument, 0, 2 } ;
193 struct option nameOption = { "name", no_argument, 0, 3 } ;
194 struct option realOption = { "real", no_argument, 0, 4 } ;
195 struct option userOption = { "user", no_argument, 0, 5 } ;
196 struct option helpOption = { "help", no_argument, 0, 6 } ;
197 struct option versionOption = { "version", no_argument, 0, 7 } ;
199 struct option options[] = {
200 groupOption, groupsOption, nameOption, realOption, userOption, helpOption, versionOption, {0}
203 struct passwd *suppliedName;
205 gFlag = glFlag = nFlag = rFlag = uFlag = 0;
206 progName = argv[0]; // don't put this before or between structs! werrry bad things happen. ;)
208 while ((argOption = getopt_long(argc, optargv, "gGnru", options, &indexptr)) != -1) {
210 switch (argOption) {
211 case 'g':
212 gFlag = 1;
213 break;
214 case 'G':
215 glFlag = 1;
216 break;
217 case 'n':
218 nFlag = 1;
219 break;
220 case 'r':
221 rFlag = 1;
222 break;
223 case 'u':
224 uFlag = 1;
225 break;
226 default:
227 switch (options[indexptr].val) {
228 case 6: // help
229 usage();
230 exit(0);
231 case 7: // version
232 version();
233 exit(0);
234 default:
235 suggest_help();
236 exit(0);
238 break;
242 if (argc - optind > 1)
243 usage();
245 if (argc - optind == 1) {
246 suppliedName = getpwnam(argv[optind]);
248 if (suppliedName == NULL) {
249 fprintf(stderr, "%s: %s: No such user\n", progName, argv[optind]);
250 suggest_help();
251 exit(1);
253 rUID = eUID = suppliedName->pw_uid;
254 rGID = eGID = suppliedName->pw_gid;
255 } else {
256 eUID = geteuid ();
257 rUID = getuid ();
258 eGID = getegid ();
259 rGID = getgid ();
261 euidName = getpwuid(eUID);
262 ruidName = getpwuid(rUID);
263 egidName = getgrgid(eGID);
264 rgidName = getgrgid(rGID);
267 if ( gFlag + glFlag + uFlag > 1 ) {
268 fprintf(stderr, "%s: cannot print only user and only group\n", progName);
269 suggest_help();
270 exit(1);
273 if ( gFlag + glFlag + uFlag == 0 && (rFlag || nFlag)) {
274 fprintf(stderr, "%s: cannot print only names or real IDs in default format\n", progName);
275 suggest_help();
276 exit(1);
279 if (gFlag) {
280 // group information
281 suffix = "\n";
282 if (rFlag)
283 print_group_info(rUID, suffix);
284 else
285 print_group_info(eUID, suffix);
286 exit(0);
289 if (glFlag) {
290 // group list
291 if (rFlag)
292 print_group_list(rUID);
293 else
294 print_group_list(eUID);
295 exit(0);
298 if (uFlag) {
299 // user information
300 suffix = "\n";
301 if (rFlag)
302 print_user_info(rUID, suffix);
303 else
304 print_user_info(eUID, suffix);
305 exit(0);
308 // no arguments? print combined info.
309 print_combined_info();
311 return B_NO_ERROR;