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

Defined functions

cat defined in line 467; used 3 times
fcmp defined in line 444; used 3 times
fmtentry defined in line 502; used 3 times
fmtinum defined in line 542; used 2 times
fmtlstuff defined in line 562; used 2 times
fmtmode defined in line 626; used 2 times
fmtsize defined in line 552; used 2 times
formatd defined in line 213; used 2 times
formatf defined in line 384; used 3 times
getdir defined in line 252; used 2 times
getgroup defined in line 679; used 2 times
getname defined in line 657; used 2 times
gstat defined in line 310; used 3 times
main defined in line 69; never used
savestr defined in line 487; used 4 times

Defined variables

Aflg defined in line 54; used 4 times
Cflg defined in line 54; used 6 times
Fflg defined in line 54; used 3 times
Lflg defined in line 54; used 2 times
Rflg defined in line 54; used 4 times
aflg defined in line 53; used 3 times
cflg defined in line 53; used 3 times
copyright defined in line 8; never used
dflg defined in line 53; used 3 times
dotp defined in line 58; used 1 times
fflg defined in line 53; used 6 times
gflg defined in line 53; used 3 times
iflg defined in line 53; used 2 times
lflg defined in line 53; used 12 times
m defined in line 624; used 4 times
  • in line 633(4)
m1 defined in line 614; used 1 times
m2 defined in line 615; used 1 times
m3 defined in line 616; used 1 times
m4 defined in line 617; used 1 times
m5 defined in line 618; used 1 times
m6 defined in line 619; used 1 times
m7 defined in line 620; used 1 times
m8 defined in line 621; used 1 times
m9 defined in line 622; used 1 times
now defined in line 56; used 4 times
oflg defined in line 54; used 5 times
qflg defined in line 54; used 4 times
rflg defined in line 53; used 4 times
sccsid defined in line 12; never used
sflg defined in line 53; used 5 times
sixmonthsago defined in line 56; used 2 times
subdirs defined in line 51; used 5 times
tflg defined in line 53; used 4 times
twidth defined in line 61; used 3 times
uflg defined in line 53; used 3 times
usetabs defined in line 54; used 4 times
utmp defined in line 650; used 1 times
win defined in line 60; used 3 times

Defined struct's

afile defined in line 31; used 50 times
ncache defined in line 683; used 4 times
subdirs defined in line 48; used 10 times

Defined macros

CAMASK defined in line 655; used 2 times
ISARG defined in line 46; used 5 times
NCACHE defined in line 654; used 3 times
NMAX defined in line 651; used 3 times
SCPYN defined in line 652; used 2 times
kbytes defined in line 29; used 2 times
Last modified: 1996-12-23
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5688
Valid CSS Valid XHTML 1.0 Strict