Annotation of 43BSD/bin/ls.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: char copyright[] =
                      9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
                     10:  All rights reserved.\n";
                     11: #endif not lint
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)ls.c       5.6 (Berkeley) 5/12/86";
                     15: #endif not lint
                     16: 
                     17: /*
                     18:  * ls
                     19:  *
                     20:  * 4.2bsd version for symbolic links, variable length
                     21:  * directory entries, block size in the inode, etc.
                     22:  */
                     23: #include <sys/param.h>
                     24: #include <sys/stat.h>
                     25: #include <sys/dir.h>
                     26: #include <stdio.h>
                     27: #include <sgtty.h>
                     28: 
                     29: #define        kbytes(size)    (((size) + 1023) / 1024)
                     30: 
                     31: struct afile {
                     32:        char    ftype;          /* file type, e.g. 'd', 'c', 'f' */
                     33:        ino_t   fnum;           /* inode number of file */
                     34:        short   fflags;         /* mode&~S_IFMT, perhaps ISARG */
                     35:        short   fnl;            /* number of links */
                     36:        short   fuid;           /* owner id */
                     37:        short   fgid;           /* group id */
                     38:        long    fsize;          /* file size */
                     39:        long    fblks;          /* number of blocks used */
                     40:        time_t  fmtime;         /* time (modify or access or create) */
                     41:        char    *fname;         /* file name */
                     42:        char    *flinkto;       /* symbolic link value */
                     43: };
                     44: 
                     45: #define ISARG  0x8000          /* extra ``mode'' */
                     46: 
                     47: struct subdirs {
                     48:        char    *sd_name;
                     49:        struct  subdirs *sd_next;
                     50: } *subdirs;
                     51: 
                     52: int    aflg, dflg, gflg, lflg, sflg, tflg, uflg, iflg, fflg, cflg, rflg = 1;
                     53: int    qflg, Aflg, Cflg, Fflg, Lflg, Rflg;
                     54: 
                     55: int    usetabs;
                     56: 
                     57: time_t now, sixmonthsago;
                     58: 
                     59: char   *dotp = ".";
                     60: 
                     61: struct winsize win;
                     62: int    twidth;
                     63: 
                     64: struct afile *gstat();
                     65: int    fcmp();
                     66: char   *cat(), *savestr();
                     67: char   *fmtentry();
                     68: char   *getname(), *getgroup();
                     69: 
                     70: char   *ctime();
                     71: char   *malloc(), *calloc(), *realloc();
                     72: char   *sprintf(), *strcpy(), *strcat();
                     73: 
                     74: main(argc, argv)
                     75:        int argc;
                     76:        char *argv[];
                     77: {
                     78:        int i;
                     79:        struct afile *fp0, *fplast;
                     80:        register struct afile *fp;
                     81:        struct sgttyb sgbuf;
                     82: 
                     83:        argc--, argv++;
                     84:        if (getuid() == 0)
                     85:                Aflg++;
                     86:        (void) time(&now); sixmonthsago = now - 6L*30L*24L*60L*60L; now += 60;
                     87:        twidth = 80;
                     88:        if (isatty(1)) {
                     89:                qflg = Cflg = 1;
                     90:                (void) gtty(1, &sgbuf);
                     91:                if (ioctl(1, TIOCGWINSZ, &win) != -1)
                     92:                        twidth = (win.ws_col == 0 ? 80 : win.ws_col);
                     93:                if ((sgbuf.sg_flags & XTABS) != XTABS)
                     94:                        usetabs = 1;
                     95:        } else
                     96:                usetabs = 1;
                     97:        while (argc > 0 && **argv == '-') {
                     98:                (*argv)++;
                     99:                while (**argv) switch (*(*argv)++) {
                    100: 
                    101:                case 'C':
                    102:                        Cflg = 1; break;
                    103:                case 'q':
                    104:                        qflg = 1; break;
                    105:                case '1':
                    106:                        Cflg = 0; break;
                    107:                case 'a':
                    108:                        aflg++; break;
                    109:                case 'A':
                    110:                        Aflg++; break;
                    111:                case 'c':
                    112:                        cflg++; break;
                    113:                case 's':
                    114:                        sflg++; break;
                    115:                case 'd':
                    116:                        dflg++; break;
                    117:                case 'g':
                    118:                        gflg++; break;
                    119:                case 'l':
                    120:                        lflg++; break;
                    121:                case 'r':
                    122:                        rflg = -1; break;
                    123:                case 't':
                    124:                        tflg++; break;
                    125:                case 'u':
                    126:                        uflg++; break;
                    127:                case 'i':
                    128:                        iflg++; break;
                    129:                case 'f':
                    130:                        fflg++; break;
                    131:                case 'L':
                    132:                        Lflg++; break;
                    133:                case 'F':
                    134:                        Fflg++; break;
                    135:                case 'R':
                    136:                        Rflg++; break;
                    137:                }
                    138:                argc--, argv++;
                    139:        }
                    140:        if (fflg) { 
                    141:                aflg++; lflg = 0; sflg = 0; tflg = 0;
                    142:        }
                    143:        if (lflg)
                    144:                Cflg = 0;
                    145:        if (argc == 0) {
                    146:                argc++;
                    147:                argv = &dotp;
                    148:        }
                    149:        fp = (struct afile *)calloc(argc, sizeof (struct afile));
                    150:        if (fp == 0) {
                    151:                fprintf(stderr, "ls: out of memory\n");
                    152:                exit(1);
                    153:        }
                    154:        fp0 = fp;
                    155:        for (i = 0; i < argc; i++) {
                    156:                if (gstat(fp, *argv, 1, (int *)0)) {
                    157:                        fp->fname = *argv;
                    158:                        fp->fflags |= ISARG;
                    159:                        fp++;
                    160:                }
                    161:                argv++;
                    162:        }
                    163:        fplast = fp;
                    164:        qsort(fp0, fplast - fp0, sizeof (struct afile), fcmp);
                    165:        if (dflg) {
                    166:                formatf(fp0, fplast);
                    167:                exit(0);
                    168:        }
                    169:        if (fflg)
                    170:                fp = fp0;
                    171:        else {
                    172:                for (fp = fp0; fp < fplast && fp->ftype != 'd'; fp++)
                    173:                        continue;
                    174:                formatf(fp0, fp);
                    175:        }
                    176:        if (fp < fplast) {
                    177:                if (fp > fp0)
                    178:                        printf("\n");
                    179:                for (;;) {
                    180:                        formatd(fp->fname, argc > 1);
                    181:                        while (subdirs) {
                    182:                                struct subdirs *t;
                    183: 
                    184:                                t = subdirs; subdirs = t->sd_next;
                    185:                                printf("\n");
                    186:                                formatd(t->sd_name, 1);
                    187:                                cfree(t->sd_name);
                    188:                                cfree((char *)t);
                    189:                        }
                    190:                        if (++fp == fplast)
                    191:                                break;
                    192:                        printf("\n");
                    193:                }
                    194:        }
                    195:        exit(0);
                    196: }
                    197: 
                    198: formatd(name, title)
                    199:        char *name;
                    200:        int title;
                    201: {
                    202:        register struct afile *fp;
                    203:        register struct subdirs *dp;
                    204:        struct afile *dfp0, *dfplast;
                    205:        int nkb;
                    206: 
                    207:        nkb = getdir(name, &dfp0, &dfplast);
                    208:        if (dfp0 == 0)
                    209:                return;
                    210:        if (fflg == 0)
                    211:                qsort(dfp0, dfplast - dfp0, sizeof (struct afile), fcmp);
                    212:        if (title)
                    213:                printf("%s:\n", name);
                    214:        if (lflg || sflg)
                    215:                printf("total %ld\n", nkb);
                    216:        formatf(dfp0, dfplast);
                    217:        if (Rflg)
                    218:                for (fp = dfplast - 1; fp >= dfp0; fp--) {
                    219:                        if (fp->ftype != 'd' ||
                    220:                            !strcmp(fp->fname, ".") ||
                    221:                            !strcmp(fp->fname, ".."))
                    222:                                continue;
                    223:                        dp = (struct subdirs *)malloc(sizeof (struct subdirs));
                    224:                        dp->sd_name = savestr(cat(name, fp->fname));
                    225:                        dp->sd_next = subdirs; subdirs = dp;
                    226:                }
                    227:        for (fp = dfp0; fp < dfplast; fp++) {
                    228:                if ((fp->fflags&ISARG) == 0 && fp->fname)
                    229:                        cfree(fp->fname);
                    230:                if (fp->flinkto)
                    231:                        cfree(fp->flinkto);
                    232:        }
                    233:        cfree((char *)dfp0);
                    234: }
                    235: 
                    236: getdir(dir, pfp0, pfplast)
                    237:        char *dir;
                    238:        struct afile **pfp0, **pfplast;
                    239: {
                    240:        register struct afile *fp;
                    241:        DIR *dirp;
                    242:        register struct direct *dp;
                    243:        int nb, nent = 20;
                    244: 
                    245:        dirp = opendir(dir);
                    246:        if (dirp == NULL) {
                    247:                *pfp0 = *pfplast = NULL;
                    248:                printf("%s unreadable\n", dir);         /* not stderr! */
                    249:                return (0);
                    250:        }
                    251:        fp = *pfp0 = (struct afile *)calloc(nent, sizeof (struct afile));
                    252:        *pfplast = *pfp0 + nent;
                    253:        nb = 0;
                    254:        while (dp = readdir(dirp)) {
                    255:                if (dp->d_ino == 0)
                    256:                        continue;
                    257:                if (aflg == 0 && dp->d_name[0]=='.' &&
                    258:                    (Aflg == 0 || dp->d_name[1]==0 ||
                    259:                     dp->d_name[1]=='.' && dp->d_name[2]==0))
                    260:                        continue;
                    261:                if (gstat(fp, cat(dir, dp->d_name), Fflg+Rflg, &nb) == 0)
                    262:                        continue;
                    263:                fp->fnum = dp->d_ino;
                    264:                fp->fname = savestr(dp->d_name);
                    265:                fp++;
                    266:                if (fp == *pfplast) {
                    267:                        *pfp0 = (struct afile *)realloc((char *)*pfp0,
                    268:                            2 * nent * sizeof (struct afile));
                    269:                        if (*pfp0 == 0) {
                    270:                                fprintf(stderr, "ls: out of memory\n");
                    271:                                exit(1);
                    272:                        }
                    273:                        fp = *pfp0 + nent;
                    274:                        *pfplast = fp + nent;
                    275:                        nent *= 2;
                    276:                }
                    277:        }
                    278:        closedir(dirp);
                    279:        *pfplast = fp;
                    280:        return (kbytes(dbtob(nb)));
                    281: }
                    282: 
                    283: int    stat(), lstat();
                    284: 
                    285: struct afile *
                    286: gstat(fp, file, statarg, pnb)
                    287:        register struct afile *fp;
                    288:        char *file;
                    289:        int statarg, *pnb;
                    290: {
                    291:        int (*statf)() = Lflg ? stat : lstat;
                    292:        char buf[BUFSIZ]; int cc;
                    293:        static struct afile azerofile;
                    294: 
                    295:        *fp = azerofile;
                    296:        fp->fflags = 0;
                    297:        fp->fnum = 0;
                    298:        fp->ftype = '-';
                    299:        if (statarg || sflg || lflg || tflg) {
                    300:                struct stat stb, stb1;
                    301: 
                    302:                if ((*statf)(file, &stb) < 0) {
                    303:                        if (statf == lstat || lstat(file, &stb) < 0) {
                    304:                                fprintf(stderr, "%s not found\n", file);
                    305:                                return (0);
                    306:                        }
                    307:                }
                    308:                fp->fblks = stb.st_blocks;
                    309:                fp->fsize = stb.st_size;
                    310:                switch (stb.st_mode & S_IFMT) {
                    311: 
                    312:                case S_IFDIR:
                    313:                        fp->ftype = 'd'; break;
                    314:                case S_IFBLK:
                    315:                        fp->ftype = 'b'; fp->fsize = stb.st_rdev; break;
                    316:                case S_IFCHR:
                    317:                        fp->ftype = 'c'; fp->fsize = stb.st_rdev; break;
                    318:                case S_IFSOCK:
                    319:                        fp->ftype = 's'; fp->fsize = 0; break;
                    320:                case S_IFLNK:
                    321:                        fp->ftype = 'l';
                    322:                        if (lflg) {
                    323:                                cc = readlink(file, buf, BUFSIZ);
                    324:                                if (cc >= 0) {
                    325:                                        buf[cc] = 0;
                    326:                                        fp->flinkto = savestr(buf);
                    327:                                }
                    328:                                break;
                    329:                        }
                    330:                        if (stat(file, &stb1) < 0)
                    331:                                break;
                    332:                        if ((stb1.st_mode & S_IFMT) == S_IFDIR) {
                    333:                                stb = stb1;
                    334:                                fp->ftype = 'd';
                    335:                                fp->fsize = stb.st_size;
                    336:                                fp->fblks = stb.st_blocks;
                    337:                        }
                    338:                        break;
                    339:                }
                    340:                fp->fnum = stb.st_ino;
                    341:                fp->fflags = stb.st_mode & ~S_IFMT;
                    342:                fp->fnl = stb.st_nlink;
                    343:                fp->fuid = stb.st_uid;
                    344:                fp->fgid = stb.st_gid;
                    345:                if (uflg)
                    346:                        fp->fmtime = stb.st_atime;
                    347:                else if (cflg)
                    348:                        fp->fmtime = stb.st_ctime;
                    349:                else
                    350:                        fp->fmtime = stb.st_mtime;
                    351:                if (pnb)
                    352:                        *pnb += stb.st_blocks;
                    353:        }
                    354:        return (fp);
                    355: }
                    356: 
                    357: formatf(fp0, fplast)
                    358:        struct afile *fp0, *fplast;
                    359: {
                    360:        register struct afile *fp;
                    361:        int width = 0, w, nentry = fplast - fp0;
                    362:        int i, j, columns, lines;
                    363:        char *cp;
                    364: 
                    365:        if (fp0 == fplast)
                    366:                return;
                    367:        if (lflg || Cflg == 0)
                    368:                columns = 1;
                    369:        else {
                    370:                for (fp = fp0; fp < fplast; fp++) {
                    371:                        int len = strlen(fmtentry(fp));
                    372: 
                    373:                        if (len > width)
                    374:                                width = len;
                    375:                }
                    376:                if (usetabs)
                    377:                        width = (width + 8) &~ 7;
                    378:                else
                    379:                        width += 2;
                    380:                columns = twidth / width;
                    381:                if (columns == 0)
                    382:                        columns = 1;
                    383:        }
                    384:        lines = (nentry + columns - 1) / columns;
                    385:        for (i = 0; i < lines; i++) {
                    386:                for (j = 0; j < columns; j++) {
                    387:                        fp = fp0 + j * lines + i;
                    388:                        cp = fmtentry(fp);
                    389:                        printf("%s", cp);
                    390:                        if (fp + lines >= fplast) {
                    391:                                printf("\n");
                    392:                                break;
                    393:                        }
                    394:                        w = strlen(cp);
                    395:                        while (w < width)
                    396:                                if (usetabs) {
                    397:                                        w = (w + 8) &~ 7;
                    398:                                        putchar('\t');
                    399:                                } else {
                    400:                                        w++;
                    401:                                        putchar(' ');
                    402:                                }
                    403:                }
                    404:        }
                    405: }
                    406: 
                    407: fcmp(f1, f2)
                    408:        register struct afile *f1, *f2;
                    409: {
                    410: 
                    411:        if (dflg == 0 && fflg == 0) {
                    412:                if ((f1->fflags&ISARG) && f1->ftype == 'd') {
                    413:                        if ((f2->fflags&ISARG) == 0 || f2->ftype != 'd')
                    414:                                return (1);
                    415:                } else {
                    416:                        if ((f2->fflags&ISARG) && f2->ftype == 'd')
                    417:                                return (-1);
                    418:                }
                    419:        }
                    420:        if (tflg) {
                    421:                if (f2->fmtime == f1->fmtime)
                    422:                        return (0);
                    423:                if (f2->fmtime > f1->fmtime)
                    424:                        return (rflg);
                    425:                return (-rflg);
                    426:        }
                    427:        return (rflg * strcmp(f1->fname, f2->fname));
                    428: }
                    429: 
                    430: char *
                    431: cat(dir, file)
                    432:        char *dir, *file;
                    433: {
                    434:        static char dfile[BUFSIZ];
                    435: 
                    436:        if (strlen(dir)+1+strlen(file)+1 > BUFSIZ) {
                    437:                fprintf(stderr, "ls: filename too long\n");
                    438:                exit(1);
                    439:        }
                    440:        if (!strcmp(dir, "") || !strcmp(dir, ".")) {
                    441:                (void) strcpy(dfile, file);
                    442:                return (dfile);
                    443:        }
                    444:        (void) strcpy(dfile, dir);
                    445:        if (dir[strlen(dir) - 1] != '/' && *file != '/')
                    446:                (void) strcat(dfile, "/");
                    447:        (void) strcat(dfile, file);
                    448:        return (dfile);
                    449: }
                    450: 
                    451: char *
                    452: savestr(str)
                    453:        char *str;
                    454: {
                    455:        char *cp = malloc(strlen(str) + 1);
                    456: 
                    457:        if (cp == NULL) {
                    458:                fprintf(stderr, "ls: out of memory\n");
                    459:                exit(1);
                    460:        }
                    461:        (void) strcpy(cp, str);
                    462:        return (cp);
                    463: }
                    464: 
                    465: char   *fmtinum(), *fmtsize(), *fmtlstuff(), *fmtmode();
                    466: 
                    467: char *
                    468: fmtentry(fp)
                    469:        register struct afile *fp;
                    470: {
                    471:        static char fmtres[BUFSIZ];
                    472:        register char *cp, *dp;
                    473: 
                    474:        (void) sprintf(fmtres, "%s%s%s",
                    475:            iflg ? fmtinum(fp) : "",
                    476:            sflg ? fmtsize(fp) : "",
                    477:            lflg ? fmtlstuff(fp) : "");
                    478:        dp = &fmtres[strlen(fmtres)];
                    479:        for (cp = fp->fname; *cp; cp++)
                    480:                if (qflg && (*cp < ' ' || *cp >= 0177))
                    481:                        *dp++ = '?';
                    482:                else
                    483:                        *dp++ = *cp;
                    484:        if (Fflg) {
                    485:                if (fp->ftype == 'd')
                    486:                        *dp++ = '/';
                    487:                else if (fp->ftype == 'l')
                    488:                        *dp++ = '@';
                    489:                else if (fp->ftype == 's')
                    490:                        *dp++ = '=';
                    491:                else if (fp->fflags & 0111)
                    492:                        *dp++ = '*';
                    493:        }
                    494:        if (lflg && fp->flinkto) {
                    495:                (void) strcpy(dp, " -> "); dp += 4;
                    496:                for (cp = fp->flinkto; *cp; cp++)
                    497:                        if (qflg && (*cp < ' ' || *cp >= 0177))
                    498:                                *dp++ = '?';
                    499:                        else
                    500:                                *dp++ = *cp;
                    501:        }
                    502:        *dp++ = 0;
                    503:        return (fmtres);
                    504: }
                    505: 
                    506: char *
                    507: fmtinum(p)
                    508:        register struct afile *p;
                    509: {
                    510:        static char inumbuf[8];
                    511: 
                    512:        (void) sprintf(inumbuf, "%6d ", p->fnum);
                    513:        return (inumbuf);
                    514: }
                    515: 
                    516: char *
                    517: fmtsize(p)
                    518:        register struct afile *p;
                    519: {
                    520:        static char sizebuf[32];
                    521: 
                    522:        (void) sprintf(sizebuf, "%4ld ", kbytes(dbtob(p->fblks)));
                    523:        return (sizebuf);
                    524: }
                    525: 
                    526: char *
                    527: fmtlstuff(p)
                    528:        register struct afile *p;
                    529: {
                    530:        static char lstuffbuf[256];
                    531:        char gname[32], uname[32], fsize[32], ftime[32];
                    532:        register char *lp = lstuffbuf;
                    533: 
                    534:        /* type mode uname gname fsize ftime */
                    535: /* get uname */
                    536:        { char *cp = getname(p->fuid);
                    537:          if (cp)
                    538:                (void) sprintf(uname, "%-9.9s", cp);
                    539:          else
                    540:                (void) sprintf(uname, "%-9d", p->fuid);
                    541:        }
                    542: /* get gname */
                    543:        if (gflg) {
                    544:          char *cp = getgroup(p->fgid);
                    545:          if (cp)
                    546:                (void) sprintf(gname, "%-9.9s", cp);
                    547:          else
                    548:                (void) sprintf(gname, "%-9d", p->fgid);
                    549:        }
                    550: /* get fsize */
                    551:        if (p->ftype == 'b' || p->ftype == 'c')
                    552:                (void) sprintf(fsize, "%3d,%4d",
                    553:                    major(p->fsize), minor(p->fsize));
                    554:        else if (p->ftype == 's')
                    555:                (void) sprintf(fsize, "%8ld", 0);
                    556:        else
                    557:                (void) sprintf(fsize, "%8ld", p->fsize);
                    558: /* get ftime */
                    559:        { char *cp = ctime(&p->fmtime);
                    560:          if ((p->fmtime < sixmonthsago) || (p->fmtime > now))
                    561:                (void) sprintf(ftime, " %-7.7s %-4.4s ", cp+4, cp+20);
                    562:          else
                    563:                (void) sprintf(ftime, " %-12.12s ", cp+4);
                    564:        }
                    565: /* splat */
                    566:        *lp++ = p->ftype;
                    567:        lp = fmtmode(lp, p->fflags);
                    568:        (void) sprintf(lp, "%3d %s%s%s%s",
                    569:            p->fnl, uname, gflg ? gname : "", fsize, ftime);
                    570:        return (lstuffbuf);
                    571: }
                    572: 
                    573: int    m1[] = { 1, S_IREAD>>0, 'r', '-' };
                    574: int    m2[] = { 1, S_IWRITE>>0, 'w', '-' };
                    575: int    m3[] = { 2, S_ISUID, 's', S_IEXEC>>0, 'x', '-' };
                    576: int    m4[] = { 1, S_IREAD>>3, 'r', '-' };
                    577: int    m5[] = { 1, S_IWRITE>>3, 'w', '-' };
                    578: int    m6[] = { 2, S_ISGID, 's', S_IEXEC>>3, 'x', '-' };
                    579: int    m7[] = { 1, S_IREAD>>6, 'r', '-' };
                    580: int    m8[] = { 1, S_IWRITE>>6, 'w', '-' };
                    581: int    m9[] = { 2, S_ISVTX, 't', S_IEXEC>>6, 'x', '-' };
                    582: 
                    583: int    *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
                    584: 
                    585: char *
                    586: fmtmode(lp, flags)
                    587:        char *lp;
                    588:        int flags;
                    589: {
                    590:        int **mp;
                    591: 
                    592:        for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])]; ) {
                    593:                register int *pairp = *mp++;
                    594:                register int n = *pairp++;
                    595: 
                    596:                while (--n >= 0 && (flags&*pairp++) == 0)
                    597:                        pairp++;
                    598:                *lp++ = *pairp;
                    599:        }
                    600:        return (lp);
                    601: }
                    602: 
                    603: /* rest should be done with nameserver or database */
                    604: 
                    605: #include <pwd.h>
                    606: #include <grp.h>
                    607: #include <utmp.h>
                    608: 
                    609: struct utmp utmp;
                    610: #define        NMAX    (sizeof (utmp.ut_name))
                    611: #define SCPYN(a, b)    strncpy(a, b, NMAX)
                    612: 
                    613: #define NUID   64      /* power of 2 */
                    614: #define UIDMASK        0x3f
                    615: #define NGID   300
                    616: 
                    617: struct ncache {
                    618:        int     uid;
                    619:        char    name[NMAX+1];
                    620: } nc[NUID];
                    621: char   outrangename[NMAX+1];
                    622: int    outrangeuid = -1;
                    623: char   groups[NGID][NMAX+1];
                    624: char   outrangegroup[NMAX+1];
                    625: int    outrangegid = -1;
                    626: 
                    627: char *
                    628: getname(uid)
                    629: {
                    630:        register struct passwd *pw;
                    631:        struct passwd *getpwent();
                    632:        extern int _pw_stayopen;
                    633:        register int cp;
                    634: 
                    635:        _pw_stayopen = 1;
                    636:        cp = uid & UIDMASK;
                    637:        if (uid >= 0 && nc[cp].uid == uid && nc[cp].name[0])
                    638:                return (nc[cp].name);
                    639:        pw = getpwuid(uid);
                    640:        if (!pw)
                    641:                return (0);
                    642:        nc[cp].uid = uid;
                    643:        SCPYN(nc[cp].name, pw->pw_name);
                    644:        return (nc[cp].name);
                    645: }
                    646: 
                    647: char *
                    648: getgroup(gid)
                    649: {
                    650:        register struct group *gr;
                    651:        static init;
                    652:        struct group *getgrent();
                    653: 
                    654:        if (gid >= 0 && gid < NGID && groups[gid][0])
                    655:                return (&groups[gid][0]);
                    656:        if (gid >= 0 && gid == outrangegid)
                    657:                return (outrangegroup);
                    658: rescan:
                    659:        if (init == 2) {
                    660:                if (gid < NGID)
                    661:                        return (0);
                    662:                setgrent();
                    663:                while (gr = getgrent()) {
                    664:                        if (gr->gr_gid != gid)
                    665:                                continue;
                    666:                        outrangegid = gr->gr_gid;
                    667:                        SCPYN(outrangegroup, gr->gr_name);
                    668:                        endgrent();
                    669:                        return (outrangegroup);
                    670:                }
                    671:                endgrent();
                    672:                return (0);
                    673:        }
                    674:        if (init == 0)
                    675:                setgrent(), init = 1;
                    676:        while (gr = getgrent()) {
                    677:                if (gr->gr_gid < 0 || gr->gr_gid >= NGID) {
                    678:                        if (gr->gr_gid == gid) {
                    679:                                outrangegid = gr->gr_gid;
                    680:                                SCPYN(outrangegroup, gr->gr_name);
                    681:                                return (outrangegroup);
                    682:                        }
                    683:                        continue;
                    684:                }
                    685:                if (groups[gr->gr_gid][0])
                    686:                        continue;
                    687:                SCPYN(groups[gr->gr_gid], gr->gr_name);
                    688:                if (gr->gr_gid == gid)
                    689:                        return (&groups[gid][0]);
                    690:        }
                    691:        init = 2;
                    692:        goto rescan;
                    693: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.