1: #define UCB         /* Controls output format for -F */
   2: 
   3: /*
   4:  * ls - list file or directory
   5:  *
   6:  * this version of ls is designed for graphic terminals and to
   7:  * list directories with lots of files in them compactly.
   8:  * It supports three variants for listings:
   9:  *
  10:  *	1) Columnar output.
  11:  *	2) Stream output.
  12:  *	3) Old one per line format.
  13:  *
  14:  * Columnar output is the default.
  15:  * If, however, the standard output is not a teletype, the default
  16:  * is one-per-line.
  17:  *
  18:  * With columnar output, the items are sorted down the columns.
  19:  * We use columns only for a directory we are interpreting.
  20:  * Thus, in particular, we do not use columns for
  21:  *
  22:  *	ls /usr/bin/p*
  23:  *
  24:  * This version of ls also prints non-printing characters as '?' if
  25:  * the standard output is a teletype.
  26:  *
  27:  * Flags relating to these and other new features are:
  28:  *
  29:  *	-m	force stream output.
  30:  *
  31:  *	-1	force one entry per line, e.g. to a teletype
  32:  *
  33:  *	-q	force non-printings to be '?'s, e.g. to a file
  34:  *
  35:  *	-C	force columnar output, e.g. into a file
  36:  *
  37:  *	-n	like -l, but user/group id's in decimal rather than
  38:  *		looking in /etc/passwd to save time
  39:  *
  40:  *	-F	turns on the "flagging" of executables and directories
  41:  *
  42:  *	-L	don't read symbolic links
  43:  *
  44:  *	-R	causes ls to recurse through the branches of the subtree
  45:  *		ala find
  46:  */
  47: 
  48: #include <sys/param.h>
  49: #include <sys/stat.h>
  50: #include <sys/dir.h>
  51: #include <stdio.h>
  52: #include <ctype.h>
  53: #include <pwd.h>
  54: #include <grp.h>
  55: #include <utmp.h>
  56: #include <sgtty.h>
  57: #include <varargs.h>
  58: #ifdef  UCB_QUOTAS
  59: #include <sys/inode.h>
  60: #include <sys/qstat.h>
  61: #endif
  62: 
  63: #ifndef NFILES
  64: #define NFILES  1024
  65: #endif
  66: #ifndef NUID
  67: #define NUID    512 /* must not be a multiple of 5 */
  68: #endif
  69: #ifndef NGID
  70: #define NGID    32  /* must not be a multiple of 5 */
  71: #endif
  72: 
  73: struct  utmp    utmp;
  74: #define NMAX    (sizeof (utmp.ut_name))
  75: 
  76: #define MAXFILEWIDTH 14
  77: FILE    *pwdf, *dirf;
  78: 
  79: struct lbuf {
  80:     union {
  81:         char    lname[DIRSIZ + 1];
  82:         char    *namep;
  83:     } ln;
  84:     char    ltype;
  85: #ifdef  UCB_SYMLINKS
  86:     char    *llinkto;
  87: #endif
  88:     ino_t   lnum;
  89:     short   lflags;
  90:     short   lnl;
  91:     short   luid;
  92:     short   lgid;
  93:     long    lsize;
  94:     long    lmtime;
  95: #ifdef  UCB_QUOTAS
  96:     long    lqused;
  97:     long    lqmax;
  98: #endif
  99: };
 100: 
 101: struct dchain {
 102:     char *dc_name;      /* the path name */
 103:     struct dchain *dc_next; /* the next directory on the chain */
 104: };
 105: 
 106: struct dchain *dfirst;      /* the start of the directory chain */
 107: struct dchain *cdfirst;     /* the start of the current directory chain */
 108: struct dchain *dtemp;       /* temporary used when linking */
 109: char *curdir;           /* the current directory */
 110: 
 111: int aflg, bflg, dflg, lflg, sflg, tflg, uflg, iflg, fflg, gflg, cflg;
 112: int Aflg, nflg, qflg, Fflg, Lflg, Rflg, across, Cflg;
 113: int nopad;
 114: int tabflg;
 115: int rflg    = 1;
 116: long    year;
 117: int flags;
 118: long    tblocks;
 119: int statreq;
 120: int xtraent;        /* for those switches which print out a total */
 121: struct  lbuf    *flist[NFILES];
 122: struct  lbuf    **lastp = flist;
 123: struct  lbuf    **firstp = flist;
 124: char    *dotp   = ".";
 125: 
 126: char    *makename();
 127: struct  lbuf *gstat();
 128: char    *ctime();
 129: long    nblock();
 130: char    *getname();
 131: char    *getgroup();
 132: 
 133: #define ISARG   0100000
 134: int colwidth;
 135: int filewidth;
 136: int fixedwidth;
 137: int outcol;
 138: 
 139: extern  char _sobuf[];
 140: 
 141: main(argc, argv)
 142: int argc;
 143: char *argv[];
 144: {
 145:     int i, width;
 146:     register struct lbuf *ep;
 147:     register struct lbuf **slastp;
 148:     struct lbuf **epp;
 149:     struct lbuf lb;
 150:     char *t;
 151:     char *cp;
 152:     int compar();
 153:     struct sgttyb sgbuf;
 154: 
 155:     Fflg = 0;
 156:     tabflg = 0;
 157:     Aflg = getuid() == 0;
 158:     setbuf(stdout, _sobuf);
 159:     time (&lb.lmtime);
 160:     year = lb.lmtime - 6L*30L*24L*60L*60L; /* 6 months ago */
 161:     qflg = gtty(1, &sgbuf) == 0;
 162: 
 163:     /* guarantee at least on column width */
 164:     fixedwidth = 2;
 165: 
 166:     /*
 167: 	 * If the standard output is not a teletype,
 168: 	 * then we default to one-per-line format
 169: 	 * otherwise decide between stream and
 170: 	 * columnar based on our name.
 171: 	 */
 172:     if (qflg) {
 173:         Cflg = 1;
 174:         if ((sgbuf.sg_flags & XTABS) == 0)
 175:             tabflg++;
 176:         for (cp = argv[0]; cp[0] && cp[1]; cp++)
 177:             continue;
 178:         /*
 179: 		 * Certain kinds of links (l, ll, lr, lf, lx) cause some
 180: 		 * various options to be turned on.
 181: 		 */
 182:         switch (cp[0]) {
 183:         case 'l':
 184:             if (cp[-1] == 'l') {
 185:                 /* ll => -l */
 186:                 lflg = 1;
 187:                 statreq++;
 188:                 xtraent++;
 189:             } else {
 190:                 /* l => -m */
 191:                 nopad = 1;
 192:                 Cflg = 0;
 193:             }
 194:             break;
 195:         case 'x':   /* lx => -x */
 196:             across = 1;
 197:             break;
 198:         case 'f':   /* lf => -F */
 199:             Fflg = 1;
 200:             break;
 201:         case 'r':   /* lr => -R */
 202:             Rflg = 1;
 203:             break;
 204:         }
 205:     } else {
 206:         tabflg++;
 207:     }
 208: 
 209:     while (--argc > 0 && *argv[1] == '-') {
 210:         argv++;
 211:         while (*++*argv) switch (**argv) {
 212:         /*
 213: 		 * C - force columnar output
 214: 		 */
 215:         case 'C':
 216:             Cflg = 1;
 217:             nopad = 0;
 218:             continue;
 219:         /*
 220: 		 * m - force stream output
 221: 		 */
 222:         case 'm':
 223:             Cflg = 0;
 224:             nopad = 1;
 225:             continue;
 226:         /*
 227: 		 * x - force sort across
 228: 		 */
 229:         case 'x':
 230:             across = 1;
 231:             nopad = 0;
 232:             Cflg = 1;
 233:             continue;
 234:         /*
 235: 		 * q - force ?'s in output
 236: 		 */
 237:         case 'q':
 238:             qflg = 1;
 239:             bflg = 0;
 240:             continue;
 241:         /*
 242: 		 * b - force octal value in output
 243: 		 */
 244:         case 'b':
 245:             bflg = 1;
 246:             qflg = 0;
 247:             continue;
 248:         /*
 249: 		 * 1 - force 1/line in output
 250: 		 */
 251:         case '1':
 252:             Cflg = 0;
 253:             nopad = 0;
 254:             continue;
 255:         /* STANDARD FLAGS */
 256:         case 'a':
 257:             aflg++;
 258:             continue;
 259: 
 260:         case 'A':
 261:             Aflg = !Aflg;
 262:             continue;
 263: 
 264:         case 'c':
 265:             cflg++;
 266:             continue;
 267: 
 268:         case 's':
 269:             fixedwidth += 5;
 270:             sflg++;
 271:             statreq++;
 272:             xtraent++;
 273:             continue;
 274: 
 275:         case 'd':
 276:             dflg++;
 277:             continue;
 278: 
 279:         /*
 280: 		 * n - don't look in password file
 281: 		 */
 282:         case 'n':
 283:             nflg++;
 284:         case 'l':
 285:             lflg++;
 286:             statreq++;
 287:             xtraent++;
 288:             continue;
 289: 
 290:         case 'r':
 291:             rflg = -1;
 292:             continue;
 293: 
 294:         case 't':
 295:             tflg++;
 296:             statreq++;
 297:             continue;
 298: 
 299:         case 'u':
 300:             uflg++;
 301:             continue;
 302: 
 303:         case 'i':
 304:             fixedwidth += 6;
 305:             iflg++;
 306:             continue;
 307: 
 308:         case 'f':
 309:             fflg++;
 310:             continue;
 311: 
 312:         case 'g':
 313:             gflg++;
 314:             continue;
 315: 
 316:         case 'F':
 317:             Fflg++;
 318:             continue;
 319: 
 320:         case 'L':
 321:             Lflg++;
 322:             continue;
 323: 
 324:         case 'R':
 325:             Rflg++;
 326:             continue;
 327: 
 328:         default:
 329:             fprintf (stderr, "usage: ls [-1ACFLRabcdfgilmnqrstux] [files]\n");
 330:             exit(1);
 331:         }
 332:     }
 333:     if (Fflg)
 334: #ifdef UCB
 335:         fixedwidth++;
 336: #else
 337:         fixedwidth += 2;
 338: #endif
 339:     if (fflg) {
 340:         aflg++;
 341:         lflg = 0;
 342:         sflg = 0;
 343:         tflg = 0;
 344:         statreq = 0;
 345:         xtraent = 0;
 346:     }
 347:     if(lflg) {
 348:         Cflg = 0;
 349:         t = "/etc/passwd";
 350:         if (gflg)
 351:             t = "/etc/group";
 352:         nopad = 0;
 353:         fixedwidth = 70;
 354:         pwdf = fopen(t, "r");
 355:     }
 356:     if (argc==0) {
 357:         argc++;
 358:         argv = &dotp - 1;
 359:     }
 360:     for (i=0; i < argc; i++) {
 361:         argv++;
 362:         if (Cflg) {
 363:             width = strlen (*argv);
 364:             if (width > filewidth)
 365:                 filewidth = width;
 366:         }
 367:         if ((ep = gstat(*argv, 1))==NULL)
 368:             continue;
 369:         ep->ln.namep = *argv;
 370:         ep->lflags |= ISARG;
 371:     }
 372:     if (!Cflg)
 373:         filewidth = MAXFILEWIDTH;
 374:     else
 375:     colwidth = fixedwidth + filewidth;
 376:     qsort(firstp, lastp - firstp, sizeof *lastp, compar);
 377:     slastp = lastp;
 378:     /* For each argument user typed */
 379:     for (epp=firstp; epp<slastp; epp++) {
 380:         ep = *epp;
 381:         if (ep->ltype=='d' && dflg==0 || fflg)
 382:             pdirectory(ep->ln.namep, (argc>1), slastp);
 383:         else
 384:             pentry(ep);
 385: 
 386:         /* -R: print subdirectories found */
 387:         while (dfirst || cdfirst) {
 388:             /* Place direct subdirs on front in right order */
 389:             while (cdfirst) {
 390:                 /* reverse cdfirst onto front of dfirst */
 391:                 dtemp = cdfirst;
 392:                 cdfirst = cdfirst -> dc_next;
 393:                 dtemp -> dc_next = dfirst;
 394:                 dfirst = dtemp;
 395:             }
 396:             /* take off first dir on dfirst & print it */
 397:             dtemp = dfirst;
 398:             dfirst = dfirst->dc_next;
 399:             pdirectory (dtemp->dc_name, 1, firstp);
 400:             cfree (dtemp->dc_name);
 401:             cfree (dtemp);
 402:         }
 403:     }
 404:     if (outcol)
 405:         putc('\n', stdout);
 406:     fflush(stdout);
 407: }
 408: 
 409: /*
 410:  * pdirectory: print the directory name, labelling it if title is
 411:  * nonzero, using lp as the place to start reading in the dir.
 412:  */
 413: pdirectory (name, title, lp)
 414: char *name;
 415: int title;
 416: struct lbuf **lp;
 417: {
 418:     register struct dchain *dp;
 419:     register struct lbuf *ap;
 420:     register char *pname;
 421:     struct lbuf **app;
 422: 
 423:     filewidth = 0;
 424:     curdir = name;
 425:     if (title)
 426:         printf("\n%s:\n", name);
 427:     lastp = lp;
 428:     readdir(name);
 429:     if (!Cflg)
 430:         filewidth = MAXFILEWIDTH;
 431:     colwidth = fixedwidth + filewidth;
 432: #ifdef notdef
 433:     /* Taken out because it appears this is done below in pem. */
 434:     if (tabflg) {
 435:         if (colwidth <= 8)
 436:             colwidth = 8;
 437:         else
 438:             if (colwidth <= 16)
 439:                 colwidth = 16;
 440:     }
 441: #endif
 442:     if (fflg==0)
 443:         qsort(lp,lastp - lp,sizeof *lastp,compar);
 444:     if (Rflg) for (app=lastp-1; app>=lp; app--) {
 445:         ap = *app;
 446:         if (ap->ltype == 'd' && strcmp(ap->ln.lname, ".") &&
 447:                 strcmp(ap->ln.lname, "..")) {
 448:             dp = (struct dchain *) calloc(1, sizeof(struct dchain));
 449:             pname = makename (curdir, ap->ln.lname);
 450:             dp->dc_name = (char *) calloc(1, strlen(pname)+1);
 451:             strcpy(dp->dc_name, pname);
 452:             dp -> dc_next = dfirst;
 453:             dfirst = dp;
 454:         }
 455:     }
 456:     if (lflg || sflg)
 457:         printf("total %D", tblocks);
 458:     pem(lp, lastp);
 459:     newline();
 460: }
 461: 
 462: /*
 463:  * pem: print 'em.  Print a list of files (e.g. a directory) bounded
 464:  * by slp and lp.
 465:  */
 466: pem(slp, lp)
 467:     register struct lbuf **slp, **lp;
 468: {
 469:     int ncols, nrows, row, col;
 470:     register struct lbuf **ep;
 471: 
 472:     if (tabflg) {
 473:         if (colwidth <= 9)
 474:             colwidth = 8;
 475:         else
 476:             if (colwidth <= 17)
 477:                 colwidth = 16;
 478:     }
 479:     ncols = 80 / colwidth;
 480:     if (ncols == 1 || Cflg == 0) {
 481:         for (ep = slp; ep < lp; ep++)
 482:             pentry(*ep);
 483:         return;
 484:     }
 485:     if (across) {
 486:         for (ep = slp; ep < lp; ep++)
 487:             pentry(*ep);
 488:         return;
 489:     }
 490:     if (xtraent)
 491:         slp--;
 492:     nrows = (lp - slp - 1) / ncols + 1;
 493:     for (row = 0; row < nrows; row++) {
 494:         col = row == 0 && xtraent;
 495:         for (; col < ncols; col++) {
 496:             ep = slp + (nrows * col) + row;
 497:             if (ep < lp)
 498:                 pentry(*ep);
 499:         }
 500:         if (outcol)
 501:             printf("\n");
 502:     }
 503: }
 504: 
 505: /*
 506:  * pputchar: like putchar but knows how to handle control chars.
 507:  * CAUTION: if you make ctrl chars print in ^x notation, or any
 508:  * other notation which is wider than one character, the column
 509:  * nature of things (such as files with 14 letter names) will be
 510:  * messed up.  Weigh this carefully!
 511:  */
 512: pputchar(c)
 513:     char c;
 514: {
 515:     char cc;
 516: 
 517:     switch (c) {
 518:         case '\t':
 519:             outcol = (outcol + 8) &~ 7;
 520:             break;
 521:         case '\n':
 522:             outcol = 0;
 523:             break;
 524:         default:
 525:             if (c < ' ' || c >= 0177) {
 526:                 if (qflg)
 527:                     c = '?';
 528:                 else if (bflg) {
 529:                     outcol += 3;
 530:                     putc ('\\', stdout);
 531:                     cc = '0' + (c>>6 & 07);
 532:                     putc (cc, stdout);
 533:                     cc = '0' + (c>>3 & 07);
 534:                     putc (cc, stdout);
 535:                     c = '0' + (c & 07);
 536:                 }
 537:             }
 538:             outcol++;
 539:             break;
 540:     }
 541:     putc(c, stdout);
 542: }
 543: 
 544: newline()
 545: {
 546:     if (outcol)
 547:         putc('\n', stdout);
 548:     outcol = 0;
 549: }
 550: 
 551: /*
 552:  * column: get to the beginning of the next column.
 553:  */
 554: column()
 555: {
 556: 
 557:     if (outcol == 0)
 558:         return;
 559:     if (nopad) {
 560:         putc(',', stdout);
 561:         outcol++;
 562:         if (outcol + colwidth + 2 > 80) {
 563:             putc('\n', stdout);
 564:             outcol = 0;
 565:             return;
 566:         }
 567:         putc(' ', stdout);
 568:         outcol++;
 569:         return;
 570:     }
 571:     if (Cflg == 0) {
 572:         putc('\n', stdout);
 573:         return;
 574:     }
 575:     if ((outcol / colwidth + 2) * colwidth > 80) {
 576:         putc('\n', stdout);
 577:         outcol = 0;
 578:         return;
 579:     }
 580:     if (tabflg && (colwidth <= 16)) {
 581:         if (colwidth > 8)
 582:             if ((outcol % 16) < 8) {
 583:                 outcol += 8 - (outcol % 8);
 584:                 putc ('\t', stdout);
 585:             }
 586:         outcol += 8 - (outcol % 8);
 587:         putc ('\t', stdout);
 588:         return;
 589:     }
 590:     do {
 591:         outcol++;
 592:         putc(' ', stdout);
 593:     } while (outcol % colwidth);
 594: }
 595: 
 596: 
 597: /*
 598:  * nblock: the number of 1024 byte blocks a size byte file takes up.
 599:  */
 600: long
 601: nblock(size)
 602: long size;
 603: {
 604:     return((size+1023)>>10);
 605: }
 606: 
 607: /*
 608:  * This code handles the rwx- business.
 609:  * You figure it out.
 610:  */
 611: int m1[] = { 1, S_IREAD>>0, 'r', '-' };
 612: int m2[] = { 1, S_IWRITE>>0, 'w', '-' };
 613: int m3[] = { 2, S_ISUID, 's', S_IEXEC>>0, 'x', '-' };
 614: int m4[] = { 1, S_IREAD>>3, 'r', '-' };
 615: int m5[] = { 1, S_IWRITE>>3, 'w', '-' };
 616: int m6[] = { 2, S_ISGID, 's', S_IEXEC>>3, 'x', '-' };
 617: int m7[] = { 1, S_IREAD>>6, 'r', '-' };
 618: int m8[] = { 1, S_IWRITE>>6, 'w', '-' };
 619: int m9[] = { 2, S_ISVTX, 't', S_IEXEC>>6, 'x', '-' };
 620: 
 621: int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
 622: 
 623: pmode(aflag)
 624: {
 625:     register int **mp;
 626: 
 627:     flags = aflag;
 628:     for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])];)
 629:         select(*mp++);
 630: }
 631: 
 632: select(pairp)
 633: register int *pairp;
 634: {
 635:     register int n;
 636: 
 637:     n = *pairp++;
 638:     while (--n>=0 && (flags&*pairp++)==0)
 639:         pairp++;
 640:     pputchar(*pairp);
 641: }
 642: 
 643: /*
 644:  * returns cat(dir, "/", file), unless dir ends in /, when it doesn't //
 645:  */
 646: char *
 647: makename(dir, file)
 648: char *dir, *file;
 649: {
 650:     static char dfile[100];
 651:     register char *dp, *fp;
 652:     register int i;
 653: 
 654:     dp = dfile;
 655:     fp = dir;
 656:     while (*fp)
 657:         *dp++ = *fp++;
 658:     if (*(dp-1) != '/')
 659:     *dp++ = '/';
 660:     fp = file;
 661:     for (i=0; i<DIRSIZ; i++)
 662:         *dp++ = *fp++;
 663:     *dp = 0;
 664:     return(dfile);
 665: }
 666: 
 667: /*
 668:  * readdir: read in the directory whose name is dir,
 669:  * starting at lastp.
 670:  */
 671: readdir(dir)
 672: char *dir;
 673: {
 674:     static struct direct dentry;
 675:     register int j, width;
 676:     register struct lbuf *ep;
 677: 
 678:     if ((dirf = fopen(dir, "r")) == NULL) {
 679:         printf("%s unreadable\n", dir);
 680:         return;
 681:     }
 682:     tblocks = 0;
 683:     for(;;) {
 684:         if (fread(&dentry, sizeof(dentry), 1, dirf) != 1)
 685:             break;
 686:         if (dentry.d_ino==0 ||
 687:             aflg==0 && dentry.d_name[0]=='.' && (
 688:             !Aflg ||
 689:             dentry.d_name[1]=='\0'
 690:             || dentry.d_name[1]=='.' && dentry.d_name[2]=='\0'))
 691:             continue;
 692:         if (Cflg) {
 693:             width = strlen (dentry.d_name);
 694:             if (width > filewidth)
 695:                 filewidth = width;
 696:         }
 697:         ep = gstat(makename(dir, dentry.d_name), Fflg || Rflg);
 698:         if (ep==NULL)
 699:             continue;
 700:         if (ep->lnum != -1)
 701:             ep->lnum = dentry.d_ino;
 702:         for (j=0; j<DIRSIZ; j++)
 703:             ep->ln.lname[j] = dentry.d_name[j];
 704:     }
 705:     fclose(dirf);
 706: }
 707: 
 708: /*
 709:  * stat the given file and return an lbuf containing it.
 710:  * argfl is nonzero if a stat is required because the file is
 711:  * an argument, rather than having been found in a directory.
 712:  */
 713: int stat(), lstat();
 714: 
 715: struct lbuf *
 716: gstat(file, argfl)
 717: char *file;
 718: {
 719:     struct stat statb;
 720: #ifdef  UCB_SYMLINKS
 721:     int (*statf)() = Lflg ?  stat : lstat;
 722:     char buf[BUFSIZ];
 723:     int cc;
 724: #else
 725:     int (*statf)() = stat;
 726: #endif
 727:     register struct lbuf *rep;
 728:     static int nomocore;
 729: #ifdef  UCB_QUOTAS
 730:     struct qstat qstatb;
 731: #endif
 732: 
 733:     if (nomocore)
 734:         return(NULL);
 735:     rep = (struct lbuf *)malloc(sizeof(struct lbuf));
 736:     if (rep==NULL) {
 737:         fprintf(stderr, "ls: out of memory\n");
 738:         nomocore = 1;
 739:         return(NULL);
 740:     }
 741:     if (lastp >= &flist[NFILES]) {
 742:         static int msg;
 743:         lastp--;
 744:         if (msg==0) {
 745:             fprintf(stderr, "ls: too many files\n");
 746:             msg++;
 747:         }
 748:     }
 749:     *lastp++ = rep;
 750:     rep->lflags = 0;
 751:     rep->lnum = 0;
 752:     rep->ltype = '-';
 753:     if (argfl || statreq) {
 754:         if ((*statf)(file, &statb)<0) {
 755:             printf("%s not found\n", file);
 756:             statb.st_ino = -1;
 757:             statb.st_size = 0;
 758:             statb.st_mode = 0;
 759:             if (argfl) {
 760:                 lastp--;
 761:                 return(0);
 762:             }
 763:         }
 764:         rep->lnum = statb.st_ino;
 765:         rep->lsize = statb.st_size;
 766:         switch(statb.st_mode&S_IFMT) {
 767: 
 768:         case S_IFDIR:
 769:             rep->ltype = 'd';
 770:             break;
 771: 
 772:         case S_IFBLK:
 773:             rep->ltype = 'b';
 774:             rep->lsize = statb.st_rdev;
 775:             break;
 776: 
 777:         case S_IFCHR:
 778:             rep->ltype = 'c';
 779:             rep->lsize = statb.st_rdev;
 780:             break;
 781: 
 782: #ifdef  UCB_QUOTAS
 783:         case S_IFQUOT:
 784:             qstat(file, &qstatb);
 785:             rep->ltype = 'q';
 786:             rep->lqused = qstatb.qs_un.qs_qused;
 787:             rep->lqmax = qstatb.qs_un.qs_qmax;
 788:             break;
 789: #endif
 790: 
 791: #ifdef  UCB_SYMLINKS
 792:         case S_IFLNK:
 793:             rep->ltype = 'l';
 794:             if (lflg) {
 795:                 cc = readlink(file, buf, BUFSIZ);
 796:                 if (cc >= 0) {
 797:                     buf[cc] = '\0';
 798:                     rep->llinkto = savestr(buf);
 799:                 }
 800:             }
 801:             break;
 802: #endif
 803: 
 804:         case S_IFMPB:
 805:             rep->ltype = 'M';
 806:             rep->lsize = statb.st_rdev;
 807:             break;
 808: 
 809:         case S_IFMPC:
 810:             rep->ltype = 'm';
 811:             rep->lsize = statb.st_rdev;
 812:             break;
 813:         }
 814:         rep->lflags = statb.st_mode & ~S_IFMT;
 815:         rep->luid = statb.st_uid;
 816:         rep->lgid = statb.st_gid;
 817:         rep->lnl = statb.st_nlink;
 818:         if(uflg)
 819:             rep->lmtime = statb.st_atime;
 820:         else if (cflg)
 821:             rep->lmtime = statb.st_ctime;
 822:         else
 823:             rep->lmtime = statb.st_mtime;
 824:         tblocks += nblock(statb.st_size);
 825:     }
 826:     return(rep);
 827: }
 828: 
 829: /*
 830:  * decide whether to print pp1 before or after pp2, based on their
 831:  * names, various times, and the r flag.
 832:  */
 833: compar(pp1, pp2)
 834: struct lbuf **pp1, **pp2;
 835: {
 836:     register struct lbuf *p1, *p2;
 837: 
 838:     p1 = *pp1;
 839:     p2 = *pp2;
 840:     if (dflg==0) {
 841:         if (p1->lflags&ISARG && p1->ltype=='d') {
 842:             if (!(p2->lflags&ISARG && p2->ltype=='d'))
 843:                 return(1);
 844:         } else {
 845:             if (p2->lflags&ISARG && p2->ltype=='d')
 846:                 return(-1);
 847:         }
 848:     }
 849:     if (tflg) {
 850:         if(p2->lmtime == p1->lmtime)
 851:             return(0);
 852:         if(p2->lmtime > p1->lmtime)
 853:             return(rflg);
 854:         return(-rflg);
 855:     }
 856:     return(rflg * strcmp(p1->lflags&ISARG? p1->ln.namep: p1->ln.lname,
 857:                 p2->lflags&ISARG? p2->ln.namep: p2->ln.lname));
 858: }
 859: 
 860: /*
 861:  * print the entry pointed at by ap
 862:  */
 863: pentry(ap)
 864: struct lbuf *ap;
 865: {
 866:     struct { char dminor, dmajor;};
 867:     register struct lbuf *p;
 868:     register char *cp;
 869:     char fname[100];
 870:     char *pname, *name;
 871:     struct passwd *getpwuid();
 872:     struct passwd *pwptr;
 873:     struct group *getgrgid();
 874: 
 875:     fname[0] = 0;
 876:     p = ap;
 877:     if (p->lnum == -1)
 878:         return;
 879:     column();
 880:     if (iflg)
 881:         if (nopad && !lflg)
 882:             printf("%d ", p->lnum);
 883:         else
 884:             printf("%5d ", p->lnum);
 885:     if (sflg)
 886:         switch (p->ltype) {
 887: 
 888:         case 'b':
 889:         case 'c':
 890:         case 'm':
 891:         case 'M':
 892:             if (nopad && !lflg)
 893:                 printf("%D ", 0);
 894:             else
 895:                 printf("%4D ", 0);
 896:             break;
 897: 
 898:         default:
 899:             if (nopad && !lflg)
 900:                 printf("%D ", nblock(p->lsize));
 901:             else
 902:                 printf("%4D ", nblock(p->lsize));
 903:             break;
 904:         }
 905:     if (lflg) {
 906:         pputchar(p->ltype);
 907:         pmode(p->lflags);
 908:         printf("%2d ", p->lnl);
 909:         if(gflg) {
 910:             name = getgroup(p->lgid);
 911:             if (nflg == 0 && name != 0)
 912:                 printf("%-9.9s", name);
 913:             else
 914:                 printf("%-9d", p->lgid);
 915:         } else {
 916: #ifndef UCB_PWHASH
 917:             if (nflg == 0 && (name = getname(p->luid))) {
 918:                 printf("%-9.9s", name);
 919:             }
 920: #else
 921:             pwptr = getpwuid(p->luid);
 922:             if (nflg == 0 && pwptr != 0)
 923:                 printf("%-9.9s", pwptr->pw_name);
 924: #endif
 925:             else
 926:                 printf("%-9d", p->luid);
 927:             name = getgroup(p->lgid);
 928:             if (nflg == 0 && name != 0)
 929:                 printf("%-9.9s", name);
 930:             else
 931:                 printf("%-9d", p->lgid);
 932:         }
 933:         switch (p->ltype) {
 934: 
 935:         case 'b':
 936:         case 'c':
 937:         case 'm':
 938:         case 'M':
 939:             printf("%3d,%3d",
 940:                 major((int)p->lsize), minor((int)p->lsize));
 941:             break;
 942: #ifdef  UCB_QUOTAS
 943:         case 'q':
 944:             printf("%4ld/%4ld", p->lqused, p->lqmax);
 945:             break;
 946: #endif
 947:         default:
 948:             printf("%7ld", p->lsize);
 949:         }
 950:         cp = ctime(&p->lmtime);
 951:         if(p->lmtime < year)
 952:             printf(" %-7.7s %-4.4s ", cp+4, cp+20); else
 953:             printf(" %-12.12s ", cp+4);
 954:     }
 955:     if (p->lflags & ISARG)
 956:         strncat (fname, p->ln.namep, 98);
 957:     else {
 958:         strncat (fname, p->ln.lname, DIRSIZ);
 959:     }
 960: #ifndef UCB
 961:     if (Fflg) {
 962:         if (p->ltype == 'd')
 963:         strcat (fname, "]");
 964:         else if (!nopad)
 965:         strcat (fname, " ");
 966:     }
 967: #else
 968:     if (Fflg) {
 969:         if (p->ltype == 'd')
 970:         strcat (fname, "/");
 971:         else if (p->ltype == 'l')
 972:         strcat (fname, "@");
 973:         else if (p->lflags & 0111)
 974:         strcat (fname, "*");
 975:         else if (!nopad)
 976:         strcat (fname, " ");
 977:     }
 978: #endif
 979: 
 980: #ifdef  UCB_SYMLINKS
 981:         if (lflg && (p->ln.llinkto != (char *) NULL)) {
 982:             strcat (fname, " -> ");
 983:             strcat(fname, p->ln.llinkto);
 984:         }
 985: #endif
 986:     printf ("%s", fname);
 987:     free(ap);
 988: }
 989: 
 990: /* char printf_id[] = "@(#) printf.c:2.2 6/5/79";*/
 991: 
 992: /*
 993:  * This version of printf is compatible with the Version 7 C
 994:  * printf. The differences are only minor except that this
 995:  * printf assumes it is to print through pputchar. Version 7
 996:  * printf is more general (and is much larger) and includes
 997:  * provisions for floating point.
 998:  */
 999: 
1000: #define MAXOCT  11      /* Maximum octal digits in a long */
1001: #define MAXINT  32767       /* largest normal length positive integer */
1002: #define BIG 1000000000  /* largest power of 10 less than an unsigned long */
1003: #define MAXDIGS 10      /* number of digits in BIG */
1004: 
1005: static int width, sign, fill;
1006: 
1007: char *b_dconv();
1008: 
1009: printf(va_alist)
1010:     va_dcl
1011: {
1012:     va_list ap;
1013:     register char *fmt;
1014:     char fcode;
1015:     int prec;
1016:     int length,mask1,nbits,n;
1017:     long int mask2, num;
1018:     register char *bptr;
1019:     char *ptr;
1020:     char buf[134];
1021: 
1022:     va_start(ap);
1023:     fmt = va_arg(ap,char *);
1024:     for (;;) {
1025:         /* process format string first */
1026:         while ((fcode = *fmt++)!='%') {
1027:             /* ordinary (non-%) character */
1028:             if (fcode=='\0')
1029:                 return;
1030:             pputchar(fcode);
1031:         }
1032:         /* length modifier: -1 for h, 1 for l, 0 for none */
1033:         length = 0;
1034:         /* check for a leading - sign */
1035:         sign = 0;
1036:         if (*fmt == '-') {
1037:             sign++;
1038:             fmt++;
1039:         }
1040:         /* a '0' may follow the - sign */
1041:         /* this is the requested fill character */
1042:         fill = 1;
1043:         if (*fmt == '0') {
1044:             fill--;
1045:             fmt++;
1046:         }
1047: 
1048:         /* Now comes a digit string which may be a '*' */
1049:         if (*fmt == '*') {
1050:             width = va_arg(ap, int);
1051:             if (width < 0) {
1052:                 width = -width;
1053:                 sign = !sign;
1054:             }
1055:             fmt++;
1056:         }
1057:         else {
1058:             width = 0;
1059:             while (*fmt>='0' && *fmt<='9')
1060:                 width = width * 10 + (*fmt++ - '0');
1061:         }
1062: 
1063:         /* maybe a decimal point followed by more digits (or '*') */
1064:         if (*fmt=='.') {
1065:             if (*++fmt == '*') {
1066:                 prec = va_arg(ap, int);
1067:                 fmt++;
1068:             }
1069:             else {
1070:                 prec = 0;
1071:                 while (*fmt>='0' && *fmt<='9')
1072:                     prec = prec * 10 + (*fmt++ - '0');
1073:             }
1074:         }
1075:         else
1076:             prec = -1;
1077: 
1078:         /*
1079: 		 * At this point, "sign" is nonzero if there was
1080: 		 * a sign, "fill" is 0 if there was a leading
1081: 		 * zero and 1 otherwise, "width" and "prec"
1082: 		 * contain numbers corresponding to the digit
1083: 		 * strings before and after the decimal point,
1084: 		 * respectively, and "fmt" addresses the next
1085: 		 * character after the whole mess. If there was
1086: 		 * no decimal point, "prec" will be -1.
1087: 		 */
1088:         switch (*fmt) {
1089:             case 'L':
1090:             case 'l':
1091:                 length = 2;
1092:                 /* no break!! */
1093:             case 'h':
1094:             case 'H':
1095:                 length--;
1096:                 fmt++;
1097:                 break;
1098:         }
1099: 
1100:         /*
1101: 		 * At exit from the following switch, we will
1102: 		 * emit the characters starting at "bptr" and
1103: 		 * ending at "ptr"-1, unless fcode is '\0'.
1104: 		 */
1105:         switch (fcode = *fmt++) {
1106:             /* process characters and strings first */
1107:             case 'c':
1108:                 buf[0] = va_arg(ap, int);
1109:                 ptr = bptr = &buf[0];
1110:                 if (buf[0] != '\0')
1111:                     ptr++;
1112:                 break;
1113:             case 's':
1114:                 bptr = va_arg(ap,char *);
1115:                 if (bptr==0)
1116:                     bptr = "(null pointer)";
1117:                 if (prec < 0)
1118:                     prec = MAXINT;
1119:                 for (n=0; *bptr++ && n < prec; n++) ;
1120:                 ptr = --bptr;
1121:                 bptr -= n;
1122:                 break;
1123:             case 'O':
1124:                 length = 1;
1125:                 fcode = 'o';
1126:                 /* no break */
1127:             case 'o':
1128:             case 'X':
1129:             case 'x':
1130:                 if (length > 0)
1131:                     num = va_arg(ap,long);
1132:                 else
1133:                     num = (unsigned)va_arg(ap,int);
1134:                 if (fcode=='o') {
1135:                     mask1 = 0x7;
1136:                     mask2 = 0x1fffffffL;
1137:                     nbits = 3;
1138:                 }
1139:                 else {
1140:                     mask1 = 0xf;
1141:                     mask2 = 0x0fffffffL;
1142:                     nbits = 4;
1143:                 }
1144:                 n = (num!=0);
1145:                 bptr = buf + MAXOCT + 3;
1146:                 /* shift and mask for speed */
1147:                 do
1148:                     if (((int) num & mask1) < 10)
1149:                     *--bptr = ((int) num & mask1) + 060;
1150:                     else
1151:                     *--bptr = ((int) num & mask1) + 0127;
1152:                 while (num = (num >> nbits) & mask2);
1153: 
1154:                 if (fcode=='o') {
1155:                     if (n)
1156:                         *--bptr = '0';
1157:                 }
1158:                 else
1159:                     if (!sign && fill <= 0) {
1160:                         pputchar('0');
1161:                         pputchar(fcode);
1162:                         width -= 2;
1163:                     }
1164:                     else {
1165:                         *--bptr = fcode;
1166:                         *--bptr = '0';
1167:                     }
1168:                 ptr = buf + MAXOCT + 3;
1169:                 break;
1170:             case 'D':
1171:             case 'U':
1172:             case 'I':
1173:                 length = 1;
1174: 
1175:               fcode = fcode + 'a' - 'A';
1176:                 /* no break */
1177:             case 'd':
1178:             case 'i':
1179:             case 'u':
1180:                 if (length > 0)
1181:                     num = va_arg(ap,long);
1182:                 else {
1183:                     n = va_arg(ap,int);
1184:                     if (fcode=='u')
1185:                         num = (unsigned) n;
1186:                     else
1187:                         num = (long) n;
1188:                 }
1189:                 if (n = (fcode != 'u' && num < 0))
1190:                     num = -num;
1191:                 /* now convert to digits */
1192:                 bptr = b_dconv(num, buf);
1193:                 if (n)
1194:                     *--bptr = '-';
1195:                 if (fill == 0)
1196:                     fill = -1;
1197:                 ptr = buf + MAXDIGS + 1;
1198:                 break;
1199:             default:
1200:                 /* not a control character,
1201: 				 * print it.
1202: 				 */
1203:                 ptr = bptr = &fcode;
1204:                 ptr++;
1205:                 break;
1206:             }
1207:             if (fcode != '\0')
1208:                 b_emit(bptr,ptr);
1209:     }
1210:     va_end(ap);
1211: }
1212: 
1213: /* b_dconv converts the unsigned long integer "value" to
1214:  * printable decimal and places it in "buffer", right-justified.
1215:  * The value returned is the address of the first non-zero character,
1216:  * or the address of the last character if all are zero.
1217:  * The result is NOT null terminated, and is MAXDIGS characters long,
1218:  * starting at buffer[1] (to allow for insertion of a sign).
1219:  *
1220:  * This program assumes it is running on 2's complement machine
1221:  * with reasonable overflow treatment.
1222:  */
1223: char *
1224: b_dconv(value, buffer)
1225:     long value;
1226:     char *buffer;
1227: {
1228:     register char *bp;
1229:     register int svalue;
1230:     int n;
1231:     long lval;
1232: 
1233:     bp = buffer;
1234: 
1235:     /* zero is a special case */
1236:     if (value == 0) {
1237:         bp += MAXDIGS;
1238:         *bp = '0';
1239:         return(bp);
1240:     }
1241: 
1242:     /* develop the leading digit of the value in "n" */
1243:     n = 0;
1244:     while (value < 0) {
1245:         value -= BIG;   /* will eventually underflow */
1246:         n++;
1247:     }
1248:     while ((lval = value - BIG) >= 0) {
1249:         value = lval;
1250:         n++;
1251:     }
1252: 
1253:     /* stash it in buffer[1] to allow for a sign */
1254:     bp[1] = n + '0';
1255:     /*
1256: 	 * Now develop the rest of the digits. Since speed counts here,
1257: 	 * we do it in two loops. The first gets "value" down until it
1258: 	 * is no larger than MAXINT. The second one uses integer divides
1259: 	 * rather than long divides to speed it up.
1260: 	 */
1261:     bp += MAXDIGS + 1;
1262:     while (value > MAXINT) {
1263:         *--bp = (int)(value % 10) + '0';
1264:         value /= 10;
1265:     }
1266: 
1267:     /* cannot lose precision */
1268:     svalue = value;
1269:     while (svalue > 0) {
1270:         *--bp = (svalue % 10) + '0';
1271:         svalue /= 10;
1272:     }
1273: 
1274:     /* fill in intermediate zeroes if needed */
1275:     if (buffer[1] != '0') {
1276:         while (bp > buffer + 2)
1277:             *--bp = '0';
1278:         --bp;
1279:     }
1280:     return(bp);
1281: }
1282: 
1283: /*
1284:  * This program sends string "s" to pputchar. The character after
1285:  * the end of "s" is given by "send". This allows the size of the
1286:  * field to be computed; it is stored in "alen". "width" contains the
1287:  * user specified length. If width<alen, the width will be taken to
1288:  * be alen. "sign" is zero if the string is to be right-justified
1289:  * in the field, nonzero if it is to be left-justified. "fill" is
1290:  * 0 if the string is to be padded with '0', positive if it is to be
1291:  * padded with ' ', and negative if an initial '-' should appear before
1292:  * any padding in right-justification (to avoid printing "-3" as
1293:  * "000-3" where "-0003" was intended).
1294:  */
1295: b_emit(s, send)
1296:     register char *s;
1297:     char *send;
1298: {
1299:     char cfill;
1300:     register int alen;
1301:     int npad;
1302: 
1303:     alen = send - s;
1304:     if (alen > width)
1305:         width = alen;
1306:     cfill = fill>0? ' ': '0';
1307: 
1308:     /* we may want to print a leading '-' before anything */
1309:     if (*s == '-' && fill < 0) {
1310:         pputchar(*s++);
1311:         alen--;
1312:         width--;
1313:     }
1314:     npad = width - alen;
1315: 
1316:     /* emit any leading pad characters */
1317:     if (!sign)
1318:         while (--npad >= 0)
1319:             pputchar(cfill);
1320: 
1321:     /* emit the string itself */
1322:     while (--alen >= 0)
1323:         pputchar(*s++);
1324: 
1325:     /* emit trailing pad characters */
1326:     if (sign)
1327:         while (--npad >= 0)
1328:             pputchar(cfill);
1329: }
1330: 
1331: #ifndef UCB_PWHASH
1332: 
1333: struct nametable {
1334:     char    nt_name[NMAX+1];
1335:     unsigned short  nt_id;
1336: };
1337: struct nametable    unames[NUID];
1338: struct nametable    gnames[NGID];
1339: 
1340: 
1341: struct nametable *
1342: findslot (id, tbl, len)
1343: unsigned short  id;
1344: struct nametable    *tbl;
1345: int     len;
1346: {
1347:     register struct nametable   *nt, *nt_start;
1348: 
1349:     /*
1350: 	 * find the id or an empty slot.
1351: 	 * return NULL if neither found.
1352: 	 */
1353: 
1354:     nt = nt_start = tbl + (id % (len - 20));
1355:     while (nt->nt_name[0] && nt->nt_id != id)
1356:     {
1357:         if ((nt += 5) >= &tbl[len])
1358:             nt -= len;
1359:         if (nt == nt_start)
1360:             return((struct nametable *)NULL);
1361:     }
1362:     return(nt);
1363: }
1364: 
1365: char *
1366: getname (uid)
1367: unsigned short  uid;
1368: {
1369:     register struct passwd      *pw;
1370:     static int          init = 0;
1371:     struct passwd           *getpwent();
1372:     register struct nametable   *n;
1373: 
1374:     /*
1375: 	 * find uid in hashed table; add it if not found.
1376: 	 * return pointer to name.
1377: 	 */
1378: 
1379:     if ((n = findslot(uid, unames, NUID)) == NULL)
1380:         return((char *)NULL);
1381: 
1382:     if (n->nt_name[0])  /* occupied? */
1383:         return(n->nt_name);
1384: 
1385:     switch (init) {
1386:         case 0:
1387:             setpwent();
1388:             init = 1;
1389:             /* intentional fall-thru */
1390:         case 1:
1391:             while (pw = getpwent()) {
1392:                 if (pw->pw_uid < 0)
1393:                     continue;
1394:                 n = findslot(pw->pw_uid, unames, NUID);
1395:                 if (n == NULL) {
1396:                     endpwent();
1397:                     init = 2;
1398:                     return((char *)NULL);
1399:                 }
1400:                 if (n->nt_name[0])
1401:                     continue;   /* duplicate, not uid */
1402:                 strncpy(n->nt_name, pw->pw_name, NMAX);
1403:                 n->nt_id = pw->pw_uid;
1404:                 if (pw->pw_uid == uid)
1405:                     return (n->nt_name);
1406:             }
1407:             endpwent();
1408:             init = 2;
1409:             /* intentional fall-thru */
1410:         case 2:
1411:             return ((char *)NULL);
1412:     }
1413: }
1414: 
1415: char *
1416: getgroup (gid)
1417: unsigned short  gid;
1418: {
1419:     register struct group   *gr;
1420:     static int  init = 0;
1421:     struct group    *getgrent();
1422:     register struct nametable   *n;
1423: 
1424:     /*
1425: 	 * find gid in hashed table; add it if not found.
1426: 	 * return pointer to name.
1427: 	 */
1428: 
1429:     if ((n = findslot(gid, gnames, NGID)) == NULL)
1430:         return((char *)NULL);
1431: 
1432:     if (n->nt_name[0])  /* occupied? */
1433:         return(n->nt_name);
1434: 
1435:     switch (init) {
1436:         case 0:
1437:             setgrent();
1438:             init = 1;
1439:             /* intentional fall-thru */
1440:         case 1:
1441:             while (gr = getgrent()) {
1442:                 if (gr->gr_gid < 0)
1443:                     continue;
1444:                 n = findslot(gr->gr_gid, gnames, NGID);
1445:                 if (n == NULL) {
1446:                     endgrent();
1447:                     init = 2;
1448:                     return((char *)NULL);
1449:                 }
1450:                 if (n->nt_name[0])
1451:                     continue;   /* duplicate, not gid */
1452:                 strncpy(n->nt_name, gr->gr_name, NMAX);
1453:                 n->nt_id = gr->gr_gid;
1454:                 if (gr->gr_gid == gid)
1455:                     return (n->nt_name);
1456:             }
1457:             endgrent();
1458:             init = 2;
1459:             /* intentional fall-thru */
1460:         case 2:
1461:             return ((char *)NULL);
1462:     }
1463: }
1464: #endif
1465: 
1466: #ifdef  UCB_SYMLINKS
1467: char *
1468: savestr(str)
1469:     char *str;
1470: {
1471:     char *cp = malloc(strlen(str) + 1);
1472: 
1473:     if (cp == NULL) {
1474:         fprintf(stderr, "ls: out of memory\n");
1475:         exit(1);
1476:     }
1477:     (void) strcpy(cp, str);
1478:     return(cp);
1479: }
1480: #endif

Defined functions

b_dconv defined in line 1223; used 2 times
b_emit defined in line 1295; used 1 times
column defined in line 554; used 1 times
compar defined in line 833; used 3 times
findslot defined in line 1341; used 4 times
getgroup defined in line 1415; used 3 times
getname defined in line 1365; used 2 times
gstat defined in line 715; used 3 times
main defined in line 141; never used
makename defined in line 646; used 3 times
nblock defined in line 600; used 4 times
newline defined in line 544; used 1 times
pdirectory defined in line 413; used 2 times
pem defined in line 466; used 1 times
pentry defined in line 863; used 4 times
pmode defined in line 623; used 1 times
pputchar defined in line 512; used 9 times
printf defined in line 1009; used 25 times
readdir defined in line 671; used 1 times
savestr defined in line 1467; used 1 times
select defined in line 632; used 1 times

Defined variables

Aflg defined in line 112; used 4 times
Cflg defined in line 112; used 13 times
Fflg defined in line 112; used 7 times
Lflg defined in line 112; used 2 times
Rflg defined in line 112; used 4 times
across defined in line 112; used 3 times
aflg defined in line 111; used 3 times
bflg defined in line 111; used 3 times
cdfirst defined in line 107; used 5 times
cflg defined in line 111; used 2 times
colwidth defined in line 134; used 17 times
curdir defined in line 109; used 2 times
dfirst defined in line 106; used 8 times
dflg defined in line 111; used 3 times
dotp defined in line 124; used 1 times
dtemp defined in line 108; used 7 times
fflg defined in line 111; used 4 times
filewidth defined in line 135; used 9 times
fill defined in line 1005; used 7 times
firstp defined in line 123; used 4 times
fixedwidth defined in line 136; used 8 times
flags defined in line 117; used 2 times
flist defined in line 121; used 3 times
gflg defined in line 111; used 3 times
gnames defined in line 1338; used 2 times
iflg defined in line 111; used 2 times
lastp defined in line 122; used 12 times
lflg defined in line 111; used 11 times
m defined in line 621; used 4 times
  • in line 628(4)
m1 defined in line 611; used 1 times
m2 defined in line 612; used 1 times
m3 defined in line 613; used 1 times
m4 defined in line 614; used 1 times
m5 defined in line 615; used 1 times
m6 defined in line 616; used 1 times
m7 defined in line 617; used 1 times
m8 defined in line 618; used 1 times
m9 defined in line 619; used 1 times
nflg defined in line 112; used 5 times
nopad defined in line 113; used 12 times
outcol defined in line 137; used 23 times
qflg defined in line 112; used 5 times
rflg defined in line 115; used 4 times
sflg defined in line 111; used 4 times
sign defined in line 1005; used 7 times
statreq defined in line 119; used 6 times
tabflg defined in line 114; used 6 times
tblocks defined in line 118; used 3 times
tflg defined in line 111; used 3 times
uflg defined in line 111; used 2 times
unames defined in line 1337; used 2 times
utmp defined in line 73; used 1 times
  • in line 74
width defined in line 1005; used 20 times
xtraent defined in line 120; used 6 times
year defined in line 116; used 2 times

Defined struct's

dchain defined in line 101; used 14 times
lbuf defined in line 79; used 44 times
nametable defined in line 1333; used 16 times

Defined macros

BIG defined in line 1002; used 2 times
ISARG defined in line 133; used 7 times
MAXDIGS defined in line 1003; used 3 times
MAXFILEWIDTH defined in line 76; used 2 times
MAXINT defined in line 1001; used 2 times
MAXOCT defined in line 1000; used 2 times
NFILES defined in line 64; used 3 times
NGID defined in line 70; used 4 times
NMAX defined in line 74; used 3 times
NUID defined in line 67; used 4 times
UCB defined in line 1; used 2 times
Last modified: 1984-01-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2911
Valid CSS Valid XHTML 1.0 Strict