1*da2e3ebdSchin /*********************************************************************** 2*da2e3ebdSchin * * 3*da2e3ebdSchin * This software is part of the ast package * 4*da2e3ebdSchin * Copyright (c) 1992-2007 AT&T Knowledge Ventures * 5*da2e3ebdSchin * and is licensed under the * 6*da2e3ebdSchin * Common Public License, Version 1.0 * 7*da2e3ebdSchin * by AT&T Knowledge Ventures * 8*da2e3ebdSchin * * 9*da2e3ebdSchin * A copy of the License is available at * 10*da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt * 11*da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*da2e3ebdSchin * * 13*da2e3ebdSchin * Information and Software Systems Research * 14*da2e3ebdSchin * AT&T Research * 15*da2e3ebdSchin * Florham Park NJ * 16*da2e3ebdSchin * * 17*da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18*da2e3ebdSchin * David Korn <dgk@research.att.com> * 19*da2e3ebdSchin * * 20*da2e3ebdSchin ***********************************************************************/ 21*da2e3ebdSchin #pragma prototyped 22*da2e3ebdSchin /* 23*da2e3ebdSchin * David Korn 24*da2e3ebdSchin * Glenn Fowler 25*da2e3ebdSchin * AT&T Research 26*da2e3ebdSchin * 27*da2e3ebdSchin * id 28*da2e3ebdSchin */ 29*da2e3ebdSchin 30*da2e3ebdSchin static const char usage[] = 31*da2e3ebdSchin "[-?\n@(#)$Id: id (AT&T Research) 2004-06-11 $\n]" 32*da2e3ebdSchin USAGE_LICENSE 33*da2e3ebdSchin "[+NAME?id - return user identity]" 34*da2e3ebdSchin "[+DESCRIPTION?If no \auser\a operand is specified \bid\b writes user and " 35*da2e3ebdSchin "group IDs and the corresponding user and group names of the " 36*da2e3ebdSchin "invoking process to standard output. If the effective and " 37*da2e3ebdSchin "real IDs do not match, both are written. Any supplementary " 38*da2e3ebdSchin "groups the current process belongs to will also be written.]" 39*da2e3ebdSchin "[+?If a \auser\a operand is specified and the process has permission, " 40*da2e3ebdSchin "the user and group IDs and any supplementary group IDs of the " 41*da2e3ebdSchin "selected user will be written to standard output.]" 42*da2e3ebdSchin "[+?If any options are specified, then only a portion of the information " 43*da2e3ebdSchin "is written.]" 44*da2e3ebdSchin "[n:name?Write the name instead of the numeric ID.]" 45*da2e3ebdSchin "[r:real?Writes real ID instead of the effective ID.]" 46*da2e3ebdSchin "[[a?This option is ignored.]" 47*da2e3ebdSchin "[g:group?Writes only the group ID.]" 48*da2e3ebdSchin "[u:user?Writes only the user ID.]" 49*da2e3ebdSchin "[G:groups?Writes only the supplementary group IDs.]" 50*da2e3ebdSchin "[s:fair-share?Writes fair share scheduler IDs and groups on systems that " 51*da2e3ebdSchin "support fair share scheduling.]" 52*da2e3ebdSchin "\n" 53*da2e3ebdSchin "\n[user]\n" 54*da2e3ebdSchin "\n" 55*da2e3ebdSchin "[+EXIT STATUS?]{" 56*da2e3ebdSchin "[+0?Successful completion.]" 57*da2e3ebdSchin "[+>0?An error occurred.]" 58*da2e3ebdSchin "}" 59*da2e3ebdSchin "[+SEE ALSO?\blogname\b(1), \bwho\b(1), \bgetgroups\b(2)]" 60*da2e3ebdSchin ; 61*da2e3ebdSchin 62*da2e3ebdSchin #include <cmd.h> 63*da2e3ebdSchin 64*da2e3ebdSchin #include "FEATURE/ids" 65*da2e3ebdSchin 66*da2e3ebdSchin #include <grp.h> 67*da2e3ebdSchin #include <pwd.h> 68*da2e3ebdSchin 69*da2e3ebdSchin #if _lib_fsid 70*da2e3ebdSchin #if _lib_getfsgid && ( _sys_fss || _hdr_fsg ) 71*da2e3ebdSchin #define fss_grp fs_grp 72*da2e3ebdSchin #define fss_id fs_id 73*da2e3ebdSchin #define fss_mem fs_mem 74*da2e3ebdSchin #define fss_passwd fs_passwd 75*da2e3ebdSchin #define fss_shares fs_shares 76*da2e3ebdSchin #if _sys_fss 77*da2e3ebdSchin #include <sys/fss.h> 78*da2e3ebdSchin #endif 79*da2e3ebdSchin #if _hdr_fsg 80*da2e3ebdSchin #include <fsg.h> 81*da2e3ebdSchin #endif 82*da2e3ebdSchin #if !_lib_isfsg && !defined(isfsg) 83*da2e3ebdSchin #define isfsg(p) (!(p)->fs_id&&!(p)->fs_shares&&(!(p)->fs_passwd||!*(p)->fs_passwd)) 84*da2e3ebdSchin #endif 85*da2e3ebdSchin #else 86*da2e3ebdSchin #undef _lib_fsid 87*da2e3ebdSchin #endif 88*da2e3ebdSchin #endif 89*da2e3ebdSchin 90*da2e3ebdSchin #define power2(n) (!((n)&((n)-1))) 91*da2e3ebdSchin 92*da2e3ebdSchin #define GG_FLAG (1<<0) 93*da2e3ebdSchin #define G_FLAG (1<<1) 94*da2e3ebdSchin #define N_FLAG (1<<2) 95*da2e3ebdSchin #define R_FLAG (1<<3) 96*da2e3ebdSchin #define U_FLAG (1<<4) 97*da2e3ebdSchin #define S_FLAG (1<<5) 98*da2e3ebdSchin #define O_FLAG (1<<6) 99*da2e3ebdSchin #define X_FLAG (1<<7) 100*da2e3ebdSchin 101*da2e3ebdSchin #if _lib_fsid 102*da2e3ebdSchin static void 103*da2e3ebdSchin getfsids(Sfio_t* sp, const char* name, int flags, register int lastchar) 104*da2e3ebdSchin { 105*da2e3ebdSchin register struct fsg* fs; 106*da2e3ebdSchin register char* s; 107*da2e3ebdSchin register char** p; 108*da2e3ebdSchin char** x; 109*da2e3ebdSchin 110*da2e3ebdSchin if (lastchar) 111*da2e3ebdSchin { 112*da2e3ebdSchin if (flags & O_FLAG) flags = 1; 113*da2e3ebdSchin else flags = 0; 114*da2e3ebdSchin } 115*da2e3ebdSchin else if (flags & N_FLAG) flags = 1; 116*da2e3ebdSchin else flags = -1; 117*da2e3ebdSchin setfsgent(); 118*da2e3ebdSchin while (fs = getfsgnam(name)) 119*da2e3ebdSchin if (!isfsg(fs)) 120*da2e3ebdSchin { 121*da2e3ebdSchin if (p = fs->fs_mem) 122*da2e3ebdSchin { 123*da2e3ebdSchin if (flags > 0) x = 0; 124*da2e3ebdSchin else 125*da2e3ebdSchin { 126*da2e3ebdSchin register char** q; 127*da2e3ebdSchin register char* t; 128*da2e3ebdSchin register int n; 129*da2e3ebdSchin 130*da2e3ebdSchin n = 0; 131*da2e3ebdSchin q = p; 132*da2e3ebdSchin while (s = *q++) 133*da2e3ebdSchin n += strlen(s) + 1; 134*da2e3ebdSchin if (!(x = newof(0, char*, q - p, n))) 135*da2e3ebdSchin break; 136*da2e3ebdSchin s = (char*)(x + (q - p)); 137*da2e3ebdSchin q = x; 138*da2e3ebdSchin while (t = *p++) 139*da2e3ebdSchin { 140*da2e3ebdSchin *q++ = s; 141*da2e3ebdSchin while (*s++ = *t++); 142*da2e3ebdSchin } 143*da2e3ebdSchin *q = 0; 144*da2e3ebdSchin p = x; 145*da2e3ebdSchin } 146*da2e3ebdSchin while (s = *p++) 147*da2e3ebdSchin { 148*da2e3ebdSchin if (lastchar == '=') 149*da2e3ebdSchin { 150*da2e3ebdSchin lastchar = ','; 151*da2e3ebdSchin sfputr(sp, " fsid=", -1); 152*da2e3ebdSchin } 153*da2e3ebdSchin else if (!lastchar) lastchar = ' '; 154*da2e3ebdSchin else sfputc(sp, lastchar); 155*da2e3ebdSchin if (flags > 0) sfprintf(sp, "%s", s); 156*da2e3ebdSchin else 157*da2e3ebdSchin { 158*da2e3ebdSchin setfsgent(); 159*da2e3ebdSchin while (fs = getfsgnam(s)) 160*da2e3ebdSchin if (isfsg(fs)) 161*da2e3ebdSchin { 162*da2e3ebdSchin if (flags < 0) sfprintf(sp, "%u", fs->fs_id); 163*da2e3ebdSchin else sfprintf(sp, "%u(%s)", fs->fs_id, s); 164*da2e3ebdSchin break; 165*da2e3ebdSchin } 166*da2e3ebdSchin } 167*da2e3ebdSchin } 168*da2e3ebdSchin if (x) free(x); 169*da2e3ebdSchin } 170*da2e3ebdSchin break; 171*da2e3ebdSchin } 172*da2e3ebdSchin endfsgent(); 173*da2e3ebdSchin if (lastchar == ' ') sfputc(sp, '\n'); 174*da2e3ebdSchin } 175*da2e3ebdSchin #endif 176*da2e3ebdSchin 177*da2e3ebdSchin static void 178*da2e3ebdSchin putid(Sfio_t* sp, int flags, const char* label, const char* name, long number) 179*da2e3ebdSchin { 180*da2e3ebdSchin sfprintf(sp, "%s=", label); 181*da2e3ebdSchin if (flags & O_FLAG) 182*da2e3ebdSchin { 183*da2e3ebdSchin if (name) sfputr(sp, name, -1); 184*da2e3ebdSchin else sfprintf(sp, "%lu", number); 185*da2e3ebdSchin } 186*da2e3ebdSchin else 187*da2e3ebdSchin { 188*da2e3ebdSchin sfprintf(sp, "%u", number); 189*da2e3ebdSchin if (name) sfprintf(sp, "(%s)", name); 190*da2e3ebdSchin } 191*da2e3ebdSchin } 192*da2e3ebdSchin 193*da2e3ebdSchin static int 194*da2e3ebdSchin getids(Sfio_t* sp, const char* name, register int flags) 195*da2e3ebdSchin { 196*da2e3ebdSchin register struct passwd* pw; 197*da2e3ebdSchin register struct group* grp; 198*da2e3ebdSchin register int i; 199*da2e3ebdSchin register int j; 200*da2e3ebdSchin register int k; 201*da2e3ebdSchin #if _lib_fsid 202*da2e3ebdSchin register struct fsg* fs; 203*da2e3ebdSchin const char* fs_name; 204*da2e3ebdSchin int fs_id; 205*da2e3ebdSchin #endif 206*da2e3ebdSchin char** p; 207*da2e3ebdSchin char* s; 208*da2e3ebdSchin int lastchar; 209*da2e3ebdSchin int ngroups = 0; 210*da2e3ebdSchin const char* gname; 211*da2e3ebdSchin uid_t user; 212*da2e3ebdSchin uid_t euid; 213*da2e3ebdSchin gid_t group; 214*da2e3ebdSchin gid_t egid; 215*da2e3ebdSchin 216*da2e3ebdSchin static gid_t* groups; 217*da2e3ebdSchin 218*da2e3ebdSchin if (flags & GG_FLAG) 219*da2e3ebdSchin { 220*da2e3ebdSchin static int maxgroups; 221*da2e3ebdSchin 222*da2e3ebdSchin /* 223*da2e3ebdSchin * get supplemental groups if required 224*da2e3ebdSchin */ 225*da2e3ebdSchin 226*da2e3ebdSchin if (!maxgroups) 227*da2e3ebdSchin { 228*da2e3ebdSchin /* 229*da2e3ebdSchin * first time 230*da2e3ebdSchin */ 231*da2e3ebdSchin 232*da2e3ebdSchin if ((maxgroups = getgroups(0, groups)) <= 0) 233*da2e3ebdSchin maxgroups = NGROUPS_MAX; 234*da2e3ebdSchin if (!(groups = newof(0, gid_t, maxgroups + 1, 0))) 235*da2e3ebdSchin error(ERROR_exit(1), "out of space [group array]"); 236*da2e3ebdSchin } 237*da2e3ebdSchin ngroups = getgroups(maxgroups, groups); 238*da2e3ebdSchin for (i = j = 0; i < ngroups; i++) 239*da2e3ebdSchin { 240*da2e3ebdSchin for (k = 0; k < j && groups[k] != groups[i]; k++); 241*da2e3ebdSchin if (k >= j) groups[j++] = groups[i]; 242*da2e3ebdSchin } 243*da2e3ebdSchin ngroups = j; 244*da2e3ebdSchin } 245*da2e3ebdSchin if (name) 246*da2e3ebdSchin { 247*da2e3ebdSchin flags |= X_FLAG; 248*da2e3ebdSchin if (!(flags & N_FLAG) || (flags & (G_FLAG|GG_FLAG))) 249*da2e3ebdSchin { 250*da2e3ebdSchin if (!(pw = getpwnam(name))) 251*da2e3ebdSchin { 252*da2e3ebdSchin user = strtol(name, &s, 0); 253*da2e3ebdSchin if (*s || !(pw = getpwuid(user))) 254*da2e3ebdSchin error(ERROR_exit(1), "%s: name not found", name); 255*da2e3ebdSchin name = pw->pw_name; 256*da2e3ebdSchin } 257*da2e3ebdSchin user = pw->pw_uid; 258*da2e3ebdSchin group = pw->pw_gid; 259*da2e3ebdSchin } 260*da2e3ebdSchin #if _lib_fsid 261*da2e3ebdSchin if (!(flags & N_FLAG) || (flags & S_FLAG)) 262*da2e3ebdSchin { 263*da2e3ebdSchin setfsgent(); 264*da2e3ebdSchin do 265*da2e3ebdSchin { 266*da2e3ebdSchin if (!(fs = getfsgnam(name))) 267*da2e3ebdSchin error(ERROR_exit(1), "%u: fss name not found", name); 268*da2e3ebdSchin } while (isfsg(fs)); 269*da2e3ebdSchin fs_id = fs->fs_id; 270*da2e3ebdSchin } 271*da2e3ebdSchin #endif 272*da2e3ebdSchin } 273*da2e3ebdSchin else 274*da2e3ebdSchin { 275*da2e3ebdSchin if (flags & G_FLAG) 276*da2e3ebdSchin group = (flags & R_FLAG) ? getgid() : getegid(); 277*da2e3ebdSchin if (flags & (GG_FLAG|N_FLAG|U_FLAG)) 278*da2e3ebdSchin user = (flags & R_FLAG) ? getuid() : geteuid(); 279*da2e3ebdSchin #if _lib_fsid 280*da2e3ebdSchin if (flags & S_FLAG) 281*da2e3ebdSchin fs_id = fsid(0); 282*da2e3ebdSchin #endif 283*da2e3ebdSchin if (flags & N_FLAG) 284*da2e3ebdSchin name = (pw = getpwuid(user)) ? pw->pw_name : (char*)0; 285*da2e3ebdSchin } 286*da2e3ebdSchin if (ngroups == 1 && groups[0] == group) 287*da2e3ebdSchin ngroups = 0; 288*da2e3ebdSchin if ((flags & N_FLAG) && (flags & G_FLAG)) 289*da2e3ebdSchin gname = (grp = getgrgid(group)) ? grp->gr_name : (char*)0; 290*da2e3ebdSchin #if _lib_fsid 291*da2e3ebdSchin if ((flags & N_FLAG) && (flags & S_FLAG)) 292*da2e3ebdSchin { 293*da2e3ebdSchin setfsgent(); 294*da2e3ebdSchin fs_name = (fs = getfsgid(fs_id)) ? fs->fs_grp : (char*)0; 295*da2e3ebdSchin } 296*da2e3ebdSchin #endif 297*da2e3ebdSchin if ((flags & (U_FLAG|G_FLAG|S_FLAG)) == (U_FLAG|G_FLAG|S_FLAG)) 298*da2e3ebdSchin { 299*da2e3ebdSchin putid(sp, flags, "uid", name, user); 300*da2e3ebdSchin putid(sp, flags, " gid", gname, group); 301*da2e3ebdSchin if ((flags & X_FLAG) && name) 302*da2e3ebdSchin { 303*da2e3ebdSchin #if _lib_getgrent 304*da2e3ebdSchin #if _lib_setgrent 305*da2e3ebdSchin setgrent(); 306*da2e3ebdSchin #endif 307*da2e3ebdSchin lastchar = '='; 308*da2e3ebdSchin while (grp = getgrent()) 309*da2e3ebdSchin if (p = grp->gr_mem) 310*da2e3ebdSchin while (s = *p++) 311*da2e3ebdSchin if (streq(s, name)) 312*da2e3ebdSchin { 313*da2e3ebdSchin if (lastchar == '=') 314*da2e3ebdSchin sfputr(sp, " groups", -1); 315*da2e3ebdSchin sfputc(sp, lastchar); 316*da2e3ebdSchin lastchar = ','; 317*da2e3ebdSchin if (flags & O_FLAG) 318*da2e3ebdSchin sfprintf(sp, "%s", grp->gr_name); 319*da2e3ebdSchin else sfprintf(sp, "%u(%s)", grp->gr_gid, grp->gr_name); 320*da2e3ebdSchin } 321*da2e3ebdSchin #if _lib_endgrent 322*da2e3ebdSchin endgrent(); 323*da2e3ebdSchin #endif 324*da2e3ebdSchin #endif 325*da2e3ebdSchin #if _lib_fsid 326*da2e3ebdSchin getfsids(sp, name, flags, '='); 327*da2e3ebdSchin #endif 328*da2e3ebdSchin } 329*da2e3ebdSchin else 330*da2e3ebdSchin { 331*da2e3ebdSchin if ((euid = geteuid()) != user) 332*da2e3ebdSchin putid(sp, flags, " euid", (pw = getpwuid(euid)) ? pw->pw_name : (char*)0, euid); 333*da2e3ebdSchin if ((egid = getegid()) != group) 334*da2e3ebdSchin putid(sp, flags, " egid", (grp = getgrgid(egid)) ? grp->gr_name : (char*)0, egid); 335*da2e3ebdSchin if (ngroups > 0) 336*da2e3ebdSchin { 337*da2e3ebdSchin sfputr(sp, " groups", -1); 338*da2e3ebdSchin lastchar = '='; 339*da2e3ebdSchin for (i = 0; i < ngroups; i++) 340*da2e3ebdSchin { 341*da2e3ebdSchin group = groups[i]; 342*da2e3ebdSchin sfputc(sp, lastchar); 343*da2e3ebdSchin if (grp = getgrgid(group)) 344*da2e3ebdSchin { 345*da2e3ebdSchin if (flags & O_FLAG) sfprintf(sp, "%s", grp->gr_name); 346*da2e3ebdSchin else sfprintf(sp, "%u(%s)", group, grp->gr_name); 347*da2e3ebdSchin } 348*da2e3ebdSchin else sfprintf(sp, "%u", group); 349*da2e3ebdSchin lastchar = ','; 350*da2e3ebdSchin } 351*da2e3ebdSchin } 352*da2e3ebdSchin #if _lib_fsid 353*da2e3ebdSchin putid(sp, flags, " fsid", fs_name, fs_id); 354*da2e3ebdSchin #endif 355*da2e3ebdSchin } 356*da2e3ebdSchin sfputc(sp,'\n'); 357*da2e3ebdSchin return(0); 358*da2e3ebdSchin } 359*da2e3ebdSchin if (flags & U_FLAG) 360*da2e3ebdSchin { 361*da2e3ebdSchin if ((flags & N_FLAG) && name) sfputr(sp, name, '\n'); 362*da2e3ebdSchin else sfprintf(sp, "%u\n", user); 363*da2e3ebdSchin } 364*da2e3ebdSchin else if (flags & G_FLAG) 365*da2e3ebdSchin { 366*da2e3ebdSchin if ((flags & N_FLAG) && gname) sfputr(sp, gname, '\n'); 367*da2e3ebdSchin else sfprintf(sp, "%u\n", group); 368*da2e3ebdSchin } 369*da2e3ebdSchin else if (flags & GG_FLAG) 370*da2e3ebdSchin { 371*da2e3ebdSchin if ((flags & X_FLAG) && name) 372*da2e3ebdSchin { 373*da2e3ebdSchin #if _lib_getgrent 374*da2e3ebdSchin #if _lib_setgrent 375*da2e3ebdSchin setgrent(); 376*da2e3ebdSchin #endif 377*da2e3ebdSchin i = 0; 378*da2e3ebdSchin while (grp = getgrent()) 379*da2e3ebdSchin if (p = grp->gr_mem) 380*da2e3ebdSchin while (s = *p++) 381*da2e3ebdSchin if (streq(s, name)) 382*da2e3ebdSchin { 383*da2e3ebdSchin if (i++) sfputc(sp, ' '); 384*da2e3ebdSchin if (flags & N_FLAG) sfprintf(sp, "%s", grp->gr_name); 385*da2e3ebdSchin else sfprintf(sp, "%u", grp->gr_gid); 386*da2e3ebdSchin } 387*da2e3ebdSchin #if _lib_endgrent 388*da2e3ebdSchin endgrent(); 389*da2e3ebdSchin #endif 390*da2e3ebdSchin if (i) sfputc(sp, '\n'); 391*da2e3ebdSchin #endif 392*da2e3ebdSchin } 393*da2e3ebdSchin else if (ngroups > 0) 394*da2e3ebdSchin { 395*da2e3ebdSchin for (i = 0;;) 396*da2e3ebdSchin { 397*da2e3ebdSchin group = groups[i]; 398*da2e3ebdSchin if ((flags & N_FLAG) && (grp = getgrgid(group))) 399*da2e3ebdSchin sfprintf(sp, "%s", grp->gr_name); 400*da2e3ebdSchin else sfprintf(sp, "%u", group); 401*da2e3ebdSchin if (++i >= ngroups) break; 402*da2e3ebdSchin sfputc(sp, ' '); 403*da2e3ebdSchin } 404*da2e3ebdSchin sfputc(sp, '\n'); 405*da2e3ebdSchin } 406*da2e3ebdSchin } 407*da2e3ebdSchin #if _lib_fsid 408*da2e3ebdSchin else if (flags & S_FLAG) 409*da2e3ebdSchin { 410*da2e3ebdSchin if ((flags & X_FLAG) && name) getfsids(sp, name, flags, 0); 411*da2e3ebdSchin else if ((flags & N_FLAG) && fs_name) sfputr(sp, fs_name, '\n'); 412*da2e3ebdSchin else sfprintf(sp, "%u\n", fs_id); 413*da2e3ebdSchin } 414*da2e3ebdSchin #endif 415*da2e3ebdSchin return(0); 416*da2e3ebdSchin } 417*da2e3ebdSchin 418*da2e3ebdSchin int 419*da2e3ebdSchin b_id(int argc, char *argv[], void* context) 420*da2e3ebdSchin { 421*da2e3ebdSchin register int flags = 0; 422*da2e3ebdSchin register int n; 423*da2e3ebdSchin 424*da2e3ebdSchin cmdinit(argc, argv, context, ERROR_CATALOG, 0); 425*da2e3ebdSchin while (n = optget(argv, usage)) switch (n) 426*da2e3ebdSchin { 427*da2e3ebdSchin case 'a': 428*da2e3ebdSchin break; 429*da2e3ebdSchin case 'G': 430*da2e3ebdSchin flags |= GG_FLAG; 431*da2e3ebdSchin break; 432*da2e3ebdSchin case 'g': 433*da2e3ebdSchin flags |= G_FLAG; 434*da2e3ebdSchin break; 435*da2e3ebdSchin case 'n': 436*da2e3ebdSchin flags |= N_FLAG; 437*da2e3ebdSchin break; 438*da2e3ebdSchin case 'r': 439*da2e3ebdSchin flags |= R_FLAG; 440*da2e3ebdSchin break; 441*da2e3ebdSchin case 's': 442*da2e3ebdSchin flags |= S_FLAG; 443*da2e3ebdSchin break; 444*da2e3ebdSchin case 'u': 445*da2e3ebdSchin flags |= U_FLAG; 446*da2e3ebdSchin break; 447*da2e3ebdSchin case ':': 448*da2e3ebdSchin error(2, "%s", opt_info.arg); 449*da2e3ebdSchin break; 450*da2e3ebdSchin case '?': 451*da2e3ebdSchin error(ERROR_usage(2), "%s", opt_info.arg); 452*da2e3ebdSchin break; 453*da2e3ebdSchin } 454*da2e3ebdSchin argv += opt_info.index; 455*da2e3ebdSchin argc -= opt_info.index; 456*da2e3ebdSchin n = (flags & (GG_FLAG|G_FLAG|S_FLAG|U_FLAG)); 457*da2e3ebdSchin if (!power2(n)) 458*da2e3ebdSchin error(2, "incompatible options selected"); 459*da2e3ebdSchin if (error_info.errors || argc > 1) 460*da2e3ebdSchin error(ERROR_usage(2), "%s", optusage(NiL)); 461*da2e3ebdSchin if (!(flags & ~(N_FLAG|R_FLAG))) 462*da2e3ebdSchin { 463*da2e3ebdSchin if (flags & N_FLAG) flags |= O_FLAG; 464*da2e3ebdSchin flags |= (U_FLAG|G_FLAG|N_FLAG|R_FLAG|S_FLAG|GG_FLAG); 465*da2e3ebdSchin } 466*da2e3ebdSchin error_info.errors = getids(sfstdout, *argv, flags); 467*da2e3ebdSchin return(error_info.errors); 468*da2e3ebdSchin } 469