Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libcmd / id.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: id.c /main/3 1995/11/01 19:06:11 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
29 *                          AT&T CORP.                          *
30 *                                                              *
31 *                Copyright (c) 1995 AT&T Corp.                 *
32 *                     All Rights Reserved                      *
33 *                                                              *
34 *           This software is licensed by AT&T Corp.            *
35 *       under the terms and conditions of the license in       *
36 *       http://www.research.att.com/orgs/ssr/book/reuse        *
37 *                                                              *
38 *               This software was created by the               *
39 *           Software Engineering Research Department           *
40 *                    AT&T Bell Laboratories                    *
41 *                                                              *
42 *               For further information contact                *
43 *                     gsf@research.att.com                     *
44 *                                                              *
45 ***************************************************************/
46
47 /* : : generated by proto : : */
48
49 #if !defined(__PROTO__)
50 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
51 #if defined(__cplusplus)
52 #define __MANGLE__      "C"
53 #else
54 #define __MANGLE__
55 #endif
56 #define __STDARG__
57 #define __PROTO__(x)    x
58 #define __OTORP__(x)
59 #define __PARAM__(n,o)  n
60 #if !defined(__STDC__) && !defined(__cplusplus)
61 #if !defined(c_plusplus)
62 #define const
63 #endif
64 #define signed
65 #define void            int
66 #define volatile
67 #define __V_            char
68 #else
69 #define __V_            void
70 #endif
71 #else
72 #define __PROTO__(x)    ()
73 #define __OTORP__(x)    x
74 #define __PARAM__(n,o)  o
75 #define __MANGLE__
76 #define __V_            char
77 #define const
78 #define signed
79 #define void            int
80 #define volatile
81 #endif
82 #if defined(__cplusplus) || defined(c_plusplus)
83 #define __VARARG__      ...
84 #else
85 #define __VARARG__
86 #endif
87 #if defined(__STDARG__)
88 #define __VA_START__(p,a)       va_start(p,a)
89 #else
90 #define __VA_START__(p,a)       va_start(p)
91 #endif
92 #endif
93 static const char id[] = "\n@(#)id (AT&T Bell Laboratories) 07/17/94\0\n";
94
95 #include <cmdlib.h>
96
97 #include "FEATURE/ids"
98
99 #include <grp.h>
100 #include <pwd.h>
101
102 #if _lib_fsid
103 #if _lib_getfsgid && ( _sys_fss || _hdr_fsg )
104 #define fss_grp         fs_grp
105 #define fss_id          fs_id
106 #define fss_mem         fs_mem
107 #define fss_passwd      fs_passwd
108 #define fss_shares      fs_shares
109 #if _sys_fss
110 #include <sys/fss.h>
111 #endif
112 #if _hdr_fsg
113 #include <fsg.h>
114 #endif
115 #if !_lib_isfsg && !defined(isfsg)
116 #define isfsg(p)        (!(p)->fs_id&&!(p)->fs_shares&&(!(p)->fs_passwd||!*(p)->fs_passwd))
117 #endif
118 #else
119 #undef _lib_fsid
120 #endif
121 #endif
122
123 #define power2(n)       (!((n)&((n)-1)))
124
125 #define GG_FLAG         (1<<0)
126 #define G_FLAG          (1<<1)
127 #define N_FLAG          (1<<2)
128 #define R_FLAG          (1<<3)
129 #define U_FLAG          (1<<4)
130 #define S_FLAG          (1<<5)
131 #define O_FLAG          (1<<6)
132 #define X_FLAG          (1<<7)
133
134 #if _lib_fsid
135 static void
136 getfsids __PARAM__((Sfio_t* sp, const char* name, int flags, register int lastchar), (sp, name, flags, lastchar)) __OTORP__(Sfio_t* sp; const char* name; int flags; register int lastchar;){
137         register struct fsg*    fs;
138         register char*          s;
139         register char**         p;
140         char**                  x;
141
142         if (lastchar)
143         {
144                 if (flags & O_FLAG) flags = 1;
145                 else flags = 0;
146         }
147         else if (flags & N_FLAG) flags = 1;
148         else flags = -1;
149         setfsgent();
150         while (fs = getfsgnam(name))
151                 if (!isfsg(fs))
152                 {
153                         if (p = fs->fs_mem)
154                         {
155                                 if (flags > 0) x = 0;
156                                 else
157                                 {
158                                         register char**         q;
159                                         register char*          t;
160                                         register int            n;
161
162                                         n = 0;
163                                         q = p;
164                                         while (s = *q++)
165                                                 n += strlen(s) + 1;
166                                         if (!(x = newof(0, char*, q - p, n)))
167                                                 break;
168                                         s = (char*)(x + (q - p));
169                                         q = x;
170                                         while (t = *p++)
171                                         {
172                                                 *q++ = s;
173                                                 while (*s++ = *t++);
174                                         }
175                                         *q = 0;
176                                         p = x;
177                                 }
178                                 while (s = *p++)
179                                 {
180                                         if (lastchar == '=')
181                                         {
182                                                 lastchar = ',';
183                                                 sfputr(sp, " fsid=", -1);
184                                         }
185                                         else if (!lastchar) lastchar = ' ';
186                                         else sfputc(sp, lastchar);
187                                         if (flags > 0) sfprintf(sp, "%s", s);
188                                         else
189                                         {
190                                                 setfsgent();
191                                                 while (fs = getfsgnam(s))
192                                                         if (isfsg(fs))
193                                                         {
194                                                                 if (flags < 0) sfprintf(sp, "%u", fs->fs_id);
195                                                                 else sfprintf(sp, "%u(%s)", fs->fs_id, s);
196                                                                 break;
197                                                         }
198                                         }
199                                 }
200                                 if (x) free(x);
201                         }
202                         break;
203                 }
204         endfsgent();
205         if (lastchar == ' ') sfputc(sp, '\n');
206 }
207 #endif
208
209 static void
210 putid __PARAM__((Sfio_t* sp, int flags, const char* label, const char* name, long number), (sp, flags, label, name, number)) __OTORP__(Sfio_t* sp; int flags; const char* label; const char* name; long number;){
211         sfprintf(sp, "%s=", label);
212         if (flags & O_FLAG)
213         {
214                 if (name) sfputr(sp, name, -1);
215                 else sfprintf(sp, "%lu", number);
216         }
217         else
218         {
219                 sfprintf(sp, "%u", number);
220                 if (name) sfprintf(sp, "(%s)", name);
221         }
222 }
223
224 static int
225 getids __PARAM__((Sfio_t* sp, const char* name, register int flags), (sp, name, flags)) __OTORP__(Sfio_t* sp; const char* name; register int flags;){
226         register struct passwd* pw;
227         register struct group*  grp;
228         register int            i;
229         register int            j;
230         register int            k;
231 #if _lib_fsid
232         register struct fsg*    fs;
233         const char*             fs_name;
234         int                     fs_id;
235 #endif
236         char**                  p;
237         char*                   s;
238         int                     lastchar;
239         int                     ngroups = 0;
240         const char*             gname;
241         uid_t                   user;
242         uid_t                   euid;
243         gid_t                   group;
244         gid_t                   egid;
245
246         static gid_t*           groups;
247
248         if (flags & GG_FLAG)
249         {
250                 static int      maxgroups;
251
252                 /*
253                  * get supplemental groups if required
254                  */
255
256                 if (!maxgroups)
257                 {
258                         /*
259                          * first time
260                          */
261
262                         if ((maxgroups = getgroups(0, groups)) <= 0)
263                                 maxgroups = NGROUPS_MAX;
264                         groups = newof(0, gid_t, maxgroups + 1, 0);
265                 }
266                 ngroups = getgroups(maxgroups, groups);
267                 for (i = j = 0; i < ngroups; i++)
268                 {
269                         for (k = 0; k < j && groups[k] != groups[i]; k++);
270                         if (k >= j) groups[j++] = groups[i];
271                 }
272                 ngroups = j;
273         }
274         if (name)
275         {
276                 flags |= X_FLAG;
277                 if (!(flags & N_FLAG) || (flags & (G_FLAG|GG_FLAG)))
278                 {
279                         if (!(pw = getpwnam(name)))
280                         {
281                                 user = strtol(name, &s, 0);
282                                 if (*s || !(pw = getpwuid(user)))
283                                         error(ERROR_exit(1), "%s: name not found", name);
284                                 name = pw->pw_name;
285                         }
286                         user = pw->pw_uid;
287                         group = pw->pw_gid;
288                 }
289 #if _lib_fsid
290                 if (!(flags & N_FLAG) || (flags & S_FLAG))
291                 {
292                         setfsgent();
293                         do
294                         {
295                                 if (!(fs = getfsgnam(name)))
296                                         error(ERROR_exit(1), "%u: fss name not found", name);
297                         } while (isfsg(fs));
298                         fs_id = fs->fs_id;
299                 }
300 #endif
301         }
302         else
303         {
304                 if (flags & G_FLAG)
305                         group = (flags & R_FLAG) ? getgid() : getegid();
306                 if (flags & (GG_FLAG|N_FLAG|U_FLAG))
307                         user = (flags & R_FLAG) ? getuid() : geteuid();
308 #if _lib_fsid
309                 if (flags & S_FLAG)
310                         fs_id = fsid(0);
311 #endif
312                 if (flags & N_FLAG)
313                         name = (pw = getpwuid(user)) ? pw->pw_name : (char*)0;
314         }
315         if (ngroups == 1 && groups[0] == group)
316                 ngroups = 0;
317         if ((flags & N_FLAG) && (flags & G_FLAG))
318                 gname = (grp = getgrgid(group)) ? grp->gr_name : (char*)0;
319 #if _lib_fsid
320         if ((flags & N_FLAG) && (flags & S_FLAG))
321         {
322                 setfsgent();
323                 fs_name = (fs = getfsgid(fs_id)) ? fs->fs_grp : (char*)0;
324         }
325 #endif
326         if ((flags & (U_FLAG|G_FLAG|S_FLAG)) == (U_FLAG|G_FLAG|S_FLAG))
327         {
328                 putid(sp, flags, "uid", name, user);
329                 putid(sp, flags, " gid", gname, group);
330                 if ((flags & X_FLAG) && name)
331                 {
332 #if _lib_getgrent
333 #if _lib_setgrent
334                         setgrent();
335 #endif
336                         lastchar = '=';
337                         while (grp = getgrent())
338                                 if (p = grp->gr_mem)
339                                         while (s = *p++)
340                                                 if (streq(s, name))
341                                                 {
342                                                         if (lastchar == '=')
343                                                                 sfputr(sp, " groups", -1);
344                                                         sfputc(sp, lastchar);
345                                                         lastchar = ',';
346                                                         if (flags & O_FLAG)
347                                                                 sfprintf(sp, "%s", grp->gr_name);
348                                                         else sfprintf(sp, "%u(%s)", grp->gr_gid, grp->gr_name);
349                                                 }
350 #if _lib_endgrent
351                         endgrent();
352 #endif
353 #endif
354 #if _lib_fsid
355                         getfsids(sp, name, flags, '=');
356 #endif
357                 }
358                 else
359                 {
360                         if ((euid = geteuid()) != user)
361                                 putid(sp, flags, " euid", (pw = getpwuid(euid)) ? pw->pw_name : (char*)0, euid);
362                         if ((egid = getegid()) != group)
363                                 putid(sp, flags, " egid", (grp = getgrgid(egid)) ? grp->gr_name : (char*)0, egid);
364                         if (ngroups > 0)
365                         {
366                                 sfputr(sp, " groups", -1);
367                                 lastchar = '=';
368                                 for (i = 0; i < ngroups; i++)
369                                 {
370                                         group = groups[i];
371                                         sfputc(sp, lastchar);
372                                         if (grp = getgrgid(group))
373                                         {
374                                                 if (flags & O_FLAG) sfprintf(sp, "%s", grp->gr_name);
375                                                 else sfprintf(sp, "%u(%s)", group, grp->gr_name);
376                                         }
377                                         else sfprintf(sp, "%u", group);
378                                         lastchar = ',';
379                                 }
380                         }
381 #if _lib_fsid
382                         putid(sp, flags, " fsid", fs_name, fs_id);
383 #endif
384                 }
385                 sfputc(sp,'\n');
386                 return(0);
387         }
388         if (flags & U_FLAG)
389         {
390                 if ((flags & N_FLAG) && name) sfputr(sp, name, '\n');
391                 else sfprintf(sp, "%u\n", user);
392         }
393         else if (flags & G_FLAG)
394         {
395                 if ((flags & N_FLAG) && gname) sfputr(sp, gname, '\n');
396                 else sfprintf(sp, "%u\n", group);
397         }
398         else if (flags & GG_FLAG)
399         {
400                 if ((flags & X_FLAG) && name)
401                 {
402 #if _lib_getgrent
403 #if _lib_setgrent
404                         setgrent();
405 #endif
406                         i = 0;
407                         while (grp = getgrent())
408                                 if (p = grp->gr_mem)
409                                         while (s = *p++)
410                                                 if (streq(s, name))
411                                                 {
412                                                         if (i++) sfputc(sp, ' ');
413                                                         if (flags & N_FLAG) sfprintf(sp, "%s", grp->gr_name);
414                                                         else sfprintf(sp, "%u", grp->gr_gid);
415                                                 }
416 #if _lib_endgrent
417                         endgrent();
418 #endif
419                         if (i) sfputc(sp, '\n');
420 #endif
421                 }
422                 else if (ngroups > 0)
423                 {
424                         for (i = 0;;)
425                         {
426                                 group = groups[i];
427                                 if ((flags & N_FLAG) && (grp = getgrgid(group)))
428                                         sfprintf(sp, "%s", grp->gr_name);
429                                 else sfprintf(sp, "%u", group);
430                                 if (++i >= ngroups) break;
431                                 sfputc(sp, ' ');
432                         }
433                         sfputc(sp, '\n');
434                 }
435         }
436 #if _lib_fsid
437         else if (flags & S_FLAG)
438         {
439                 if ((flags & X_FLAG) && name) getfsids(sp, name, flags, 0);
440                 else if ((flags & N_FLAG) && fs_name) sfputr(sp, fs_name, '\n');
441                 else sfprintf(sp, "%u\n", fs_id);
442         }
443 #endif
444         return(0);
445 }
446
447 int
448 b_id __PARAM__((int argc, char *argv[]), (argc, argv)) __OTORP__(int argc; char *argv[];){
449         register int    flags = 0;
450         register int    n;
451
452         NoP(id[0]);
453         cmdinit(argv);
454         while (n = optget(argv, "[Ggus]nr [user]")) switch (n)
455         {
456         case 'G':
457                 flags |= GG_FLAG;
458                 break;
459         case 'g':
460                 flags |= G_FLAG;
461                 break;
462         case 'n':
463                 flags |= N_FLAG;
464                 break;
465         case 'r':
466                 flags |= R_FLAG;
467                 break;
468         case 's':
469                 flags |= S_FLAG;
470                 break;
471         case 'u':
472                 flags |= U_FLAG;
473                 break;
474         case ':':
475                 error(2, opt_info.arg);
476                 break;
477         case '?':
478                 error(ERROR_usage(2), opt_info.arg);
479                 break;
480         }
481         argv += opt_info.index;
482         argc -= opt_info.index;
483         n = (flags & (GG_FLAG|G_FLAG|S_FLAG|U_FLAG));
484         if (!power2(n))
485                 error(2, "incompatible options selected");
486         if (error_info.errors || argc > 1)
487                 error(ERROR_usage(2), optusage(NiL));
488         if (!(flags & ~N_FLAG))
489         {
490                 if (flags & N_FLAG) flags |= O_FLAG;
491                 flags |= (U_FLAG|G_FLAG|N_FLAG|R_FLAG|S_FLAG|GG_FLAG);
492         }
493         error_info.errors = getids(sfstdout, *argv, flags);
494         return(error_info.errors);
495 }