# 2.11BSD#431 - /usr/src/usr.bin/find/find.c

##### Functions

    amatch            X
    and               X
    atime             X
    bwrite            X
    chgreel           X
    cpio              X
    descend           X
    doex              X
    dummy             X
    e1                X
    e2                X
    e3                X
    exeq              X
    exp               X
    fastfind          X
    getgid            X
    getgroup          X
    getname           X
    getuid            X
    getunum           X
    glob              X
    gmatch            X
    group             X
    ino               X
    links             X
    list              X
    ls                X
    main              X
    mk                X
    mklong            X
    mtime             X
    newer             X
    nogroup           X
    not               X
    nouser            X
    nxtarg            X
    ok                X
    or                X
    patprep           X
    perm              X
    print             X
    scomp             X
    size              X
    type              X
    umatch            X
    user              X

##### Variables

    Ai                X
    Argc              X
    Argv              X
    Blocks            X
    Buf               X
    Bufsize           X
    Cpio              X
    Dbuf              X
    Devstat           X
    Fname             X
    Home              X
    Newer             X
    Nn                X
    Node              X
    Now               X
    Pathname          X
    Pi                X
    Randlast          X
    Statb             X
    Wct               X
    Wp                X
    Xdev              X
    groups            X
    nc                X
    outrangegid       X
    outrangegroup     X
    outrangename      X
    outrangeuid       X
    utmp              X

##### Macros

    AMES              X
    A_DAY             X
    EQ                X
    ESCCODE           X
    FCODES            X
    MAGIC             X
    MAXNODES          X
    MKSHORT           X
    NGID              X
    NMAX              X
    NO                X
    NUID              X
    OFFSET            X
    SCPYN             X
    YES               X
    kbytes            X
    permission        X
    permoffset        X

##### struct's

    anode             X
    header            X
    ncache            X

       1: #if defined(DOSCCS) && !defined(lint)
       2: static char *sccsid = "@(#)find.c	4.17.3 (2.11BSD GTE) 1996/10/23";
       3: #endif
       4:
       5: #include <stdio.h>
       6: #include <fcntl.h>
       7: #include <sys/param.h>
       8: #include <sys/dir.h>
       9: #include <sys/stat.h>
      10:
      11: #define A_DAY   86400L /* a day full of seconds */
      12: #define EQ(x, y)    (strcmp(x, y)==0)
      13:
      14: int Randlast;
      15: char    Pathname[MAXPATHLEN+1];
      16:
      17: #define MAXNODES    100
      18:
      19: struct anode {
      20:     int (*F)();
      21:     struct anode *L, *R;
      22: } Node[MAXNODES];
      23: int Nn;  /* number of nodes */
      24: char    *Fname;
      25: long    Now;
      26: int Argc,
      27:     Ai,
      28:     Pi;
      29: char    **Argv;
      30: /* cpio stuff */
      31: int Cpio;
      32: short   *Buf, *Dbuf, *Wp;
      33: int Bufsize = 5120;
      34: int Wct = 2560;
      35:
      36: long    Newer;
      37:
      38: int Xdev = 1;   /* true if SHOULD cross devices (file systems) */
      39: struct  stat Devstat;   /* stats of each argument path's file system */
      40:
      41: struct stat Statb;
      42:
      43: struct  anode   *exp(),
      44:         *e1(),
      45:         *e2(),
      46:         *e3(),
      47:         *mk();
      48: char    *nxtarg();
      49: int Home;
      50: long    Blocks;
      51: char *rindex();
      52: char *sbrk();
      53:
      54: /*
      55:  * SEE ALSO:	updatedb, bigram.c, code.c
      56:  *		Usenix ;login:, February/March, 1983, p. 8.
      57:  *
      58:  * REVISIONS: 	James A. Woods, Informatics General Corporation,
      59:  *		NASA Ames Research Center, 6/81.
      60:  *
      61:  *		The second form searches a pre-computed filelist
      62:  *		(constructed nightly by 'cron') which is
      63:  *		compressed by updatedb (v.i.z.)  The effect of
      64:  *			find <name>
      65:  *		is similar to
      66:  *			find / +0 -name "*<name>*" -print
      67:  *		but much faster.
      68:  *
      69:  *		8/82 faster yet + incorporation of bigram coding -- jaw
      70:  *
      71:  *		1/83 incorporate glob-style matching -- jaw
      72:  */
      73: #define AMES    1
      74:
      75: main(argc, argv)
      76:     int argc;
      77:     char *argv[];
      78: {
      79:     struct anode *exlist;
      80:     int paths;
      81:     register char *cp, *sp = 0;
      82: #ifdef  SUID_PWD
      83:     FILE *pwd, *popen();
      84: #endif
      85:
      86: #ifdef  AMES
      87:     if (argc < 2) {
      88:         fprintf(stderr,
      89:             "Usage: find name, or find path-list predicate-list\n");
      90:         exit(1);
      91:     }
      92:     if (argc == 2) {
      93:         fastfind(argv[1]);
      94:         exit(0);
      95:     }
      96: #endif
      97:     time(&Now);
      98:     Home = open(".", O_RDONLY);
      99:     if (Home < 0) {
     100:         fprintf(stderr, "Can't open .\n");
     101:         exit(1);
     102:     }
     103:     Argc = argc; Argv = argv;
     104:     if(argc<3) {
     105: usage:      fprintf(stderr, "Usage: find path-list predicate-list\n");
     106:         exit(1);
     107:     }
     108:     for(Ai = paths = 1; Ai < (argc-1); ++Ai, ++paths)
     109:         if(*Argv[Ai] == '-' || EQ(Argv[Ai], "(") || EQ(Argv[Ai], "!"))
     110:             break;
     111:     if(paths == 1) /* no path-list */
     112:         goto usage;
     113:     if(!(exlist = exp())) { /* parse and compile the arguments */
     114:         fprintf(stderr, "find: parsing error\n");
     115:         exit(1);
     116:     }
     117:     if(Ai<argc) {
     118:         fprintf(stderr, "find: missing conjunction\n");
     119:         exit(1);
     120:     }
     121:     for(Pi = 1; Pi < paths; ++Pi) {
     122:         sp = 0;
     123:         fchdir(Home);
     124:         strcpy(Pathname, Argv[Pi]);
     125:         if(cp = rindex(Pathname, '/')) {
     126:             sp = cp + 1;
     127:             *cp = '\0';
     128:             if(chdir(*Pathname? Pathname: "/") == -1) {
     129:                 fprintf(stderr, "find: bad starting directory\n");
     130:                 exit(2);
     131:             }
     132:             *cp = '/';
     133:         }
     134:         Fname = sp? sp: Pathname;
     135:         if (!Xdev)
     136:             stat(Pathname, &Devstat);
     137:         descend(Pathname, Fname, exlist); /* to find files that match  */
     138:     }
     139:     if(Cpio) {
     140:         strcpy(Pathname, "TRAILER!!!");
     141:         Statb.st_size = 0;
     142:         cpio();
     143:         printf("%D blocks\n", Blocks*10);
     144:     }
     145:     exit(0);
     146: }
     147:
     148: /* compile time functions:  priority is  exp()<e1()<e2()<e3()  */
     149:
     150: struct anode *exp() { /* parse ALTERNATION (-o)  */
     151:     int or();
     152:     register struct anode * p1;
     153:
     154:     p1 = e1() /* get left operand */ ;
     155:     if(EQ(nxtarg(), "-o")) {
     156:         Randlast--;
     157:         return(mk(or, p1, exp()));
     158:     }
     159:     else if(Ai <= Argc) --Ai;
     160:     return(p1);
     161: }
     162: struct anode *e1() { /* parse CONCATENATION (formerly -a) */
     163:     int and();
     164:     register struct anode * p1;
     165:     register char *a;
     166:
     167:     p1 = e2();
     168:     a = nxtarg();
     169:     if(EQ(a, "-a")) {
     170: And:
     171:         Randlast--;
     172:         return(mk(and, p1, e1()));
     173:     } else if(EQ(a, "(") || EQ(a, "!") || (*a=='-' && !EQ(a, "-o"))) {
     174:         --Ai;
     175:         goto And;
     176:     } else if(Ai <= Argc) --Ai;
     177:     return(p1);
     178: }
     179: struct anode *e2() { /* parse NOT (!) */
     180:     int not();
     181:
     182:     if(Randlast) {
     183:         fprintf(stderr, "find: operand follows operand\n");
     184:         exit(1);
     185:     }
     186:     Randlast++;
     187:     if(EQ(nxtarg(), "!"))
     188:         return(mk(not, e3(), (struct anode *)0));
     189:     else if(Ai <= Argc) --Ai;
     190:     return(e3());
     191: }
     192: struct anode *e3() { /* parse parens and predicates */
     193:     int exeq(), ok(), glob(),  mtime(), atime(), user(),
     194:         group(), size(), perm(), links(), print(),
     195:         type(), ino(), cpio(), newer(),
     196:         nouser(), nogroup(), ls(), dummy();
     197:     struct anode *p1;
     198:     int i;
     199:     register char *a, *b;
     200:     register int s;
     201:
     202:     a = nxtarg();
     203:     if(EQ(a, "(")) {
     204:         Randlast--;
     205:         p1 = exp();
     206:         a = nxtarg();
     207:         if(!EQ(a, ")")) goto err;
     208:         return(p1);
     209:     }
     210:     else if(EQ(a, "-print")) {
     211:         return(mk(print, (struct anode *)0, (struct anode *)0));
     212:     }
     213:     else if (EQ(a, "-nouser")) {
     214:         return (mk(nouser, (struct anode *)0, (struct anode *)0));
     215:     }
     216:     else if (EQ(a, "-nogroup")) {
     217:         return (mk(nogroup, (struct anode *)0, (struct anode *)0));
     218:     }
     219:     else if (EQ(a, "-ls")) {
     220:         return (mk(ls, (struct anode *)0, (struct anode *)0));
     221:     }
     222:     else if (EQ(a, "-xdev")) {
     223:         Xdev = 0;
     224:         return (mk(dummy, (struct anode *)0, (struct anode *)0));
     225:     }
     226:     b = nxtarg();
     227:     s = *b;
     228:     if(s=='+') b++;
     229:     if(EQ(a, "-name"))
     230:         return(mk(glob, (struct anode *)b, (struct anode *)0));
     231:     else if(EQ(a, "-mtime"))
     232:         return(mk(mtime, (struct anode *)atoi(b), (struct anode *)s));
     233:     else if(EQ(a, "-atime"))
     234:         return(mk(atime, (struct anode *)atoi(b), (struct anode *)s));
     235:     else if(EQ(a, "-user")) {
     236:         if((i=getuid(b)) == -1) {
     237:             if(gmatch(b, "[0-9]*"))
     238:                 return mk(user, (struct anode *)atoi(b), (struct anode *)s);
     239:             fprintf(stderr, "find: cannot find -user name\n");
     240:             exit(1);
     241:         }
     242:         return(mk(user, (struct anode *)i, (struct anode *)s));
     243:     }
     244:     else if(EQ(a, "-inum"))
     245:         return(mk(ino, (struct anode *)atoi(b), (struct anode *)s));
     246:     else if(EQ(a, "-group")) {
     247:         if((i=getgid(b)) == -1) {
     248:             if(gmatch(b, "[0-9]*"))
     249:                 return mk(group, (struct anode *)atoi(b), (struct anode *)s);
     250:             fprintf(stderr, "find: cannot find -group name\n");
     251:             exit(1);
     252:         }
     253:         return(mk(group, (struct anode *)i, (struct anode *)s));
     254:     } else if(EQ(a, "-size"))
     255:         return(mk(size, (struct anode *)atoi(b), (struct anode *)s));
     256:     else if(EQ(a, "-links"))
     257:         return(mk(links, (struct anode *)atoi(b), (struct anode *)s));
     258:     else if(EQ(a, "-perm")) {
     259:         for(i=0; *b ; ++b) {
     260:             if(*b=='-') continue;
     261:             i <<= 3;
     262:             i = i + (*b - '0');
     263:         }
     264:         return(mk(perm, (struct anode *)i, (struct anode *)s));
     265:     }
     266:     else if(EQ(a, "-type")) {
     267:         i = s=='d' ? S_IFDIR :
     268:             s=='b' ? S_IFBLK :
     269:             s=='c' ? S_IFCHR :
     270:             s=='f' ? S_IFREG :
     271:             s=='l' ? S_IFLNK :
     272:             s=='s' ? S_IFSOCK :
     273:             0;
     274:         return(mk(type, (struct anode *)i, (struct anode *)0));
     275:     }
     276:     else if (EQ(a, "-exec")) {
     277:         i = Ai - 1;
     278:         while(!EQ(nxtarg(), ";"));
     279:         return(mk(exeq, (struct anode *)i, (struct anode *)0));
     280:     }
     281:     else if (EQ(a, "-ok")) {
     282:         i = Ai - 1;
     283:         while(!EQ(nxtarg(), ";"));
     284:         return(mk(ok, (struct anode *)i, (struct anode *)0));
     285:     }
     286:     else if(EQ(a, "-cpio")) {
     287:         if((Cpio = creat(b, 0666)) < 0) {
     288:             fprintf(stderr, "find: cannot create < %s >\n", s);
     289:             exit(1);
     290:         }
     291:         Buf = (short *)sbrk(512);
     292:         Wp = Dbuf = (short *)sbrk(5120);
     293:         return(mk(cpio, (struct anode *)0, (struct anode *)0));
     294:     }
     295:     else if(EQ(a, "-newer")) {
     296:         if(stat(b, &Statb) < 0) {
     297:             fprintf(stderr, "find: cannot access < %s >\n", b);
     298:             exit(1);
     299:         }
     300:         Newer = Statb.st_mtime;
     301:         return mk(newer, (struct anode *)0, (struct anode *)0);
     302:     }
     303: err:    fprintf(stderr, "find: bad option < %s >\n", a);
     304:     exit(1);
     305: }
     306: struct anode *mk(f, l, r)
     307: int (*f)();
     308: struct anode *l, *r;
     309: {
     310:     if (Nn >= MAXNODES) {
     311:         fprintf(stderr, "find: Too many options\n");
     312:         exit(1);
     313:     }
     314:
     315:     Node[Nn].F = f;
     316:     Node[Nn].L = l;
     317:     Node[Nn].R = r;
     318:     return(&(Node[Nn++]));
     319: }
     320:
     321: char *nxtarg() { /* get next arg from command line */
     322:     static strikes = 0;
     323:
     324:     if(strikes==3) {
     325:         fprintf(stderr, "find: incomplete statement\n");
     326:         exit(1);
     327:     }
     328:     if(Ai>=Argc) {
     329:         strikes++;
     330:         Ai = Argc + 1;
     331:         return("");
     332:     }
     333:     return(Argv[Ai++]);
     334: }
     335:
     336: /* execution time functions */
     337: and(p)
     338: register struct anode *p;
     339: {
     340:     return(((*p->L->F)(p->L)) && ((*p->R->F)(p->R))?1:0);
     341: }
     342: or(p)
     343: register struct anode *p;
     344: {
     345:      return(((*p->L->F)(p->L)) || ((*p->R->F)(p->R))?1:0);
     346: }
     347: not(p)
     348: register struct anode *p;
     349: {
     350:     return( !((*p->L->F)(p->L)));
     351: }
     352: glob(p)
     353: register struct { int f; char *pat; } *p;
     354: {
     355:     return(gmatch(Fname, p->pat));
     356: }
     357: print(p)
     358: struct anode *p;
     359: {
     360:     puts(Pathname);
     361:     return(1);
     362: }
     363: mtime(p)
     364: register struct { int f, t, s; } *p;
     365: {
     366:     return(scomp((int)((Now - Statb.st_mtime) / A_DAY), p->t, p->s));
     367: }
     368: atime(p)
     369: register struct { int f, t, s; } *p;
     370: {
     371:     return(scomp((int)((Now - Statb.st_atime) / A_DAY), p->t, p->s));
     372: }
     373: user(p)
     374: register struct { int f, u, s; } *p;
     375: {
     376:     return(scomp(Statb.st_uid, p->u, p->s));
     377: }
     378: nouser(p)
     379: struct anode *p;
     380: {
     381:     char *getname();
     382:
     383:     return (getname(Statb.st_uid) == NULL);
     384: }
     385: ino(p)
     386: register struct { int f, u, s; } *p;
     387: {
     388:     return(scomp((int)Statb.st_ino, p->u, p->s));
     389: }
     390: group(p)
     391: register struct { int f, u; } *p;
     392: {
     393:     return(p->u == Statb.st_gid);
     394: }
     395: nogroup(p)
     396: struct anode *p;
     397: {
     398:     char *getgroup();
     399:
     400:     return (getgroup(Statb.st_gid) == NULL);
     401: }
     402: links(p)
     403: register struct { int f, link, s; } *p;
     404: {
     405:     return(scomp(Statb.st_nlink, p->link, p->s));
     406: }
     407: size(p)
     408: register struct { int f, sz, s; } *p;
     409: {
     410:     return(scomp((int)((Statb.st_size+511)>>9), p->sz, p->s));
     411: }
     412: perm(p)
     413: register struct { int f, per, s; } *p;
     414: {
     415:     register i;
     416:     i = (p->s=='-') ? p->per : 07777; /* '-' means only arg bits */
     417:     return((Statb.st_mode & i & 07777) == p->per);
     418: }
     419: type(p)
     420: register struct { int f, per, s; } *p;
     421: {
     422:     return((Statb.st_mode&S_IFMT)==p->per);
     423: }
     424: exeq(p)
     425: register struct { int f, com; } *p;
     426: {
     427:     fflush(stdout); /* to flush possible `-print' */
     428:     return(doex(p->com));
     429: }
     430: ok(p)
     431: struct { int f, com; } *p;
     432: {
     433:     char c;  int yes;
     434:     yes = 0;
     435:     fflush(stdout); /* to flush possible `-print' */
     436:     fprintf(stderr, "< %s ... %s > ?   ", Argv[p->com], Pathname);
     437:     fflush(stderr);
     438:     if((c=getchar())=='y') yes = 1;
     439:     while(c!='\n') c = getchar();
     440:     if(yes) return(doex(p->com));
     441:     return(0);
     442: }
     443:
     444: #define MKSHORT(v, lv) {U.l=1L;if(U.c[0]) U.l=lv, v[0]=U.s[1], v[1]=U.s[0]; else U.l=lv, v[0]=U.s[0], v[1]=U.s[1];}
     445: union { long l; short s[2]; char c[4]; } U;
     446: long mklong(v)
     447: short v[];
     448: {
     449:     U.l = 1;
     450:     if(U.c[0] /* VAX */)
     451:         U.s[0] = v[1], U.s[1] = v[0];
     452:     else
     453:         U.s[0] = v[0], U.s[1] = v[1];
     454:     return U.l;
     455: }
     456: cpio(p)
     457: struct anode *p;
     458: {
     459: #define MAGIC 070707
     460:     struct header {
     461:         short   h_magic,
     462:             h_dev,
     463:             h_ino,
     464:             h_mode,
     465:             h_uid,
     466:             h_gid,
     467:             h_nlink,
     468:             h_rdev;
     469:         short   h_mtime[2];
     470:         short   h_namesize;
     471:         short   h_filesize[2];
     472:         char    h_name[256];
     473:     } hdr;
     474:     register ifile, ct;
     475:     static long fsz;
     476:     register i;
     477:
     478:     hdr.h_magic = MAGIC;
     479:     strcpy(hdr.h_name, !strncmp(Pathname, "./", 2)? Pathname+2: Pathname);
     480:     hdr.h_namesize = strlen(hdr.h_name) + 1;
     481:     hdr.h_uid = Statb.st_uid;
     482:     hdr.h_gid = Statb.st_gid;
     483:     hdr.h_dev = Statb.st_dev;
     484:     hdr.h_ino = Statb.st_ino;
     485:     hdr.h_mode = Statb.st_mode;
     486:     MKSHORT(hdr.h_mtime, Statb.st_mtime);
     487:     hdr.h_nlink = Statb.st_nlink;
     488:     fsz = hdr.h_mode & S_IFREG? Statb.st_size: 0L;
     489:     MKSHORT(hdr.h_filesize, fsz);
     490:     hdr.h_rdev = Statb.st_rdev;
     491:     if(EQ(hdr.h_name, "TRAILER!!!")) {
     492:         bwrite((short *)&hdr, (sizeof hdr-256)+hdr.h_namesize);
     493:         for(i = 0; i < 10; ++i)
     494:             bwrite(Buf, 512);
     495:         return;
     496:     }
     497:     if(!mklong(hdr.h_filesize))
     498:         return;
     499:     if((ifile = open(Fname, 0)) < 0) {
     500: cerror:
     501:         fprintf(stderr, "find: cannot copy < %s >\n", hdr.h_name);
     502:         return;
     503:     }
     504:     bwrite((short *)&hdr, (sizeof hdr-256)+hdr.h_namesize);
     505:     for(fsz = mklong(hdr.h_filesize); fsz > 0; fsz -= 512) {
     506:         ct = fsz>512? 512: fsz;
     507:         if(read(ifile, (char *)Buf, ct) < 0)
     508:             goto cerror;
     509:         bwrite(Buf, ct);
     510:     }
     511:     close(ifile);
     512:     return;
     513: }
     514: newer(p)
     515: struct anode *p;
     516: {
     517:     return Statb.st_mtime > Newer;
     518: }
     519: ls(p)
     520: struct anode *p;
     521: {
     522:     list(Pathname, &Statb);
     523:     return (1);
     524: }
     525: dummy(p)
     526: struct anode *p;
     527: {
     528:     /* dummy */
     529:     return (1);
     530: }
     531:
     532: /* support functions */
     533: scomp(a, b, s) /* funny signed compare */
     534: register a, b;
     535: register char s;
     536: {
     537:     if(s == '+')
     538:         return(a > b);
     539:     if(s == '-')
     540:         return(a < (b * -1));
     541:     return(a == b);
     542: }
     543:
     544: doex(com)
     545: {
     546:     register np;
     547:     register char *na;
     548:     static char *nargv[50];
     549:     static ccode;
     550:     register int w, pid;
     551:     long omask;
     552:
     553:     ccode = np = 0;
     554:     while (na=Argv[com++]) {
     555:         if(np >= sizeof nargv / sizeof *nargv - 1) break;
     556:         if(strcmp(na, ";")==0) break;
     557:         if(strcmp(na, "{}")==0) nargv[np++] = Pathname;
     558:         else nargv[np++] = na;
     559:     }
     560:     nargv[np] = 0;
     561:     if (np==0) return(9);
     562:     switch (pid = vfork()) {
     563:     case -1:
     564:         perror("find: Can't fork");
     565:         exit(1);
     566:         break;
     567:
     568:     case 0:
     569:         fchdir(Home);
     570:         execvp(nargv[0], nargv, np);
     571:         write(2, "find: Can't execute ", 20);
     572:         perror(nargv[0]);
     573:         /*
     574: 		 * Kill ourselves; our exit status will be a suicide
     575: 		 * note indicating we couldn't do the "exec".
     576: 		 */
     577:         kill(getpid(), SIGUSR1);
     578:         break;
     579:
     580:     default:
     581:         omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT));
     582:         while ((w = wait(&ccode)) != pid && w != -1)
     583:             ;
     584:         (void) sigsetmask(omask);
     585:         if ((ccode & 0177) == SIGUSR1)
     586:             exit(1);
     587:         return (ccode != 0 ? 0 : 1);
     588:     }
     589: }
     590:
     591: getunum(f, s) char *f, *s; { /* find user/group name and return number */
     592:     register i;
     593:     register char *sp;
     594:     register c;
     595:     char str[20];
     596:     FILE *pin;
     597:
     598:     i = -1;
     599:     pin = fopen(f, "r");
     600:     c = '\n'; /* prime with a CR */
     601:     do {
     602:         if(c=='\n') {
     603:             sp = str;
     604:             while((c = *sp++ = getc(pin)) != ':')
     605:                 if(c == EOF) goto RET;
     606:             *--sp = '\0';
     607:             if(EQ(str, s)) {
     608:                 while((c=getc(pin)) != ':')
     609:                     if(c == EOF) goto RET;
     610:                 sp = str;
     611:                 while((*sp = getc(pin)) != ':') sp++;
     612:                 *sp = '\0';
     613:                 i = atoi(str);
     614:                 goto RET;
     615:             }
     616:         }
     617:     } while((c = getc(pin)) != EOF);
     618:  RET:
     619:     fclose(pin);
     620:     return(i);
     621: }
     622:
     623: descend(name, fname, exlist)
     624:     struct anode *exlist;
     625:     char *name, *fname;
     626: {
     627:     DIR *dir = NULL;
     628:     register struct direct  *dp;
     629:     register char *c1;
     630:     int rv = 0;
     631:     char *endofname;
     632:
     633:     if (lstat(fname, &Statb)<0) {
     634:         fprintf(stderr, "find: bad status < %s >\n", name);
     635:         return(0);
     636:     }
     637:     (*exlist->F)(exlist);
     638:     if((Statb.st_mode&S_IFMT)!=S_IFDIR ||
     639:        !Xdev && Devstat.st_dev != Statb.st_dev)
     640:         return(1);
     641:
     642:     for (c1 = name; *c1; ++c1);
     643:     if (*(c1-1) == '/')
     644:         --c1;
     645:     endofname = c1;
     646:
     647:     if (chdir(fname) == -1)
     648:         return(0);
     649:     if ((dir = opendir(".")) == NULL) {
     650:         fprintf(stderr, "find: cannot open < %s >\n", name);
     651:         rv = 0;
     652:         goto ret;
     653:     }
     654:     for (dp = readdir(dir); dp != NULL; dp = readdir(dir)) {
     655:         if ((dp->d_name[0]=='.' && dp->d_name[1]=='\0') ||
     656:             (dp->d_name[0]=='.' && dp->d_name[1]=='.' && dp->d_name[2]=='\0'))
     657:             continue;
     658:         c1 = endofname;
     659:         *c1++ = '/';
     660:         strcpy(c1, dp->d_name);
     661:         Fname = endofname+1;
     662:         if(!descend(name, Fname, exlist)) {
     663:             *endofname = '\0';
     664:             fchdir(Home);
     665:             if(chdir(Pathname) == -1) {
     666:                 fprintf(stderr, "find: bad directory tree\n");
     667:                 exit(1);
     668:             }
     669:         }
     670:     }
     671:     rv = 1;
     672: ret:
     673:     if(dir)
     674:         closedir(dir);
     675:     if(chdir("..") == -1) {
     676:         *endofname = '\0';
     677:         fprintf(stderr, "find: bad directory <%s>\n", name);
     678:         rv = 1;
     679:     }
     680:     return(rv);
     681: }
     682:
     683: gmatch(s, p) /* string match as in glob */
     684: register char *s, *p;
     685: {
     686:     if (*s=='.' && *p!='.') return(0);
     687:     return amatch(s, p);
     688: }
     689:
     690: amatch(s, p)
     691: register char *s, *p;
     692: {
     693:     register cc;
     694:     int scc, k;
     695:     int c, lc;
     696:
     697:     scc = *s;
     698:     lc = 077777;
     699:     switch (c = *p) {
     700:
     701:     case '[':
     702:         k = 0;
     703:         while (cc = *++p) {
     704:             switch (cc) {
     705:
     706:             case ']':
     707:                 if (k)
     708:                     return(amatch(++s, ++p));
     709:                 else
     710:                     return(0);
     711:
     712:             case '-':
     713:                 cc = p[1];
     714:                 k |= lc <= scc && scc <= cc;
     715:             }
     716:             if (scc==(lc=cc)) k++;
     717:         }
     718:         return(0);
     719:
     720:     case '?':
     721:     caseq:
     722:         if(scc) return(amatch(++s, ++p));
     723:         return(0);
     724:     case '*':
     725:         return(umatch(s, ++p));
     726:     case 0:
     727:         return(!scc);
     728:     }
     729:     if (c==scc) goto caseq;
     730:     return(0);
     731: }
     732:
     733: umatch(s, p)
     734: register char *s, *p;
     735: {
     736:     if(*p==0) return(1);
     737:     while(*s)
     738:         if (amatch(s++, p)) return(1);
     739:     return(0);
     740: }
     741:
     742: bwrite(rp, c)
     743: register short *rp;
     744: register c;
     745: {
     746:     register short *wp = Wp;
     747:
     748:     c = (c+1) >> 1;
     749:     while(c--) {
     750:         if(!Wct) {
     751: again:
     752:             if(write(Cpio, (char *)Dbuf, Bufsize)<0) {
     753:                 Cpio = chgreel(1, Cpio);
     754:                 goto again;
     755:             }
     756:             Wct = Bufsize >> 1;
     757:             wp = Dbuf;
     758:             ++Blocks;
     759:         }
     760:         *wp++ = *rp++;
     761:         --Wct;
     762:     }
     763:     Wp = wp;
     764: }
     765: chgreel(x, fl)
     766: {
     767:     register f;
     768:     char str[22];
     769:     FILE *devtty;
     770:     struct stat statb;
     771:     extern errno;
     772:
     773:     fprintf(stderr, "find: errno: %d, ", errno);
     774:     fprintf(stderr, "find: can't %s\n", x? "write output": "read input");
     775:     fstat(fl, &statb);
     776:     if((statb.st_mode&S_IFMT) != S_IFCHR)
     777:         exit(1);
     778: again:
     779:     fprintf(stderr, "If you want to go on, type device/file name %s\n",
     780:         "when ready");
     781:     devtty = fopen("/dev/tty", "r");
     782:     fgets(str, 20, devtty);
     783:     str[strlen(str) - 1] = '\0';
     784:     if(!*str)
     785:         exit(1);
     786:     close(fl);
     787:     if((f = open(str, x? 1: 0)) < 0) {
     788:         fprintf(stderr, "That didn't work");
     789:         fclose(devtty);
     790:         goto again;
     791:     }
     792:     return f;
     793: }
     794:
     795: #ifdef  AMES
     796: /*
     797:  * 'fastfind' scans a file list for the full pathname of a file
     798:  * given only a piece of the name.  The list has been processed with
     799:  * with "front-compression" and bigram coding.  Front compression reduces
     800:  * space by a factor of 4-5, bigram coding by a further 20-25%.
     801:  * The codes are:
     802:  *
     803:  *	0-28	likeliest differential counts + offset to make nonnegative
     804:  *	30	escape code for out-of-range count to follow in next word
     805:  *	128-255 bigram codes, (128 most common, as determined by 'updatedb')
     806:  *	32-127  single character (printable) ascii residue
     807:  *
     808:  * A novel two-tiered string search technique is employed:
     809:  *
     810:  * First, a metacharacter-free subpattern and partial pathname is
     811:  * matched BACKWARDS to avoid full expansion of the pathname list.
     812:  * The time savings is 40-50% over forward matching, which cannot efficiently
     813:  * handle overlapped search patterns and compressed path residue.
     814:  *
     815:  * Then, the actual shell glob-style regular expression (if in this form)
     816:  * is matched against the candidate pathnames using the slower routines
     817:  * provided in the standard 'find'.
     818:  */
     819:
     820: #define FCODES  "/var/db/find.codes"
     821: #define YES 1
     822: #define NO  0
     823: #define OFFSET  14
     824: #define ESCCODE 30
     825:
     826: fastfind ( pathpart )
     827:     char pathpart[];
     828: {
     829:     register char *p, *s;
     830:     register int c;
     831:     char *q, *index(), *patprep();
     832:     int i, count = 0, globflag;
     833:     FILE *fp, *fopen();
     834:     char *patend, *cutoff;
     835:     char path[1024];
     836:     char bigram1[128], bigram2[128];
     837:     int found = NO;
     838:
     839:     if ( (fp = fopen ( FCODES, "r" )) == NULL ) {
     840:         fprintf ( stderr, "find: can't open %s\n", FCODES );
     841:         exit ( 1 );
     842:     }
     843:     for ( i = 0; i < 128; i++ )
     844:         bigram1[i] = getc ( fp ),  bigram2[i] = getc ( fp );
     845:
     846:     if ( index ( pathpart, '*' ) || index ( pathpart, '?' ) || index ( pathpart, '[' ) )
     847:         globflag = YES;
     848:     patend = patprep ( pathpart );
     849:
     850:     c = getc ( fp );
     851:     for ( ; ; ) {
     852:
     853:         count += ( (c == ESCCODE) ? getw ( fp ) : c ) - OFFSET;
     854:
     855:         for ( p = path + count; (c = getc ( fp )) > ESCCODE; )  /* overlay old path */
     856:             if ( c < 0200 )
     857:                 *p++ = c;
     858:             else        /* bigrams are parity-marked */
     859:                 *p++ = bigram1[c & 0177],  *p++ = bigram2[c & 0177];
     860:         if ( c == EOF )
     861:             break;
     862:         *p-- = NULL;
     863:         cutoff = ( found ? path : path + count);
     864:
     865:         for ( found = NO, s = p; s >= cutoff; s-- )
     866:             if ( *s == *patend ) {      /* fast first char check */
     867:                 for ( p = patend - 1, q = s - 1; *p != NULL; p--, q-- )
     868:                     if ( *q != *p )
     869:                         break;
     870:                 if ( *p == NULL ) { /* success on fast match */
     871:                     found = YES;
     872:                     if ( globflag == NO || amatch ( path, pathpart ) )
     873:                         puts ( path );
     874:                     break;
     875:                 }
     876:             }
     877:     }
     878: }
     879:
     880: /*
     881:     extract last glob-free subpattern in name for fast pre-match;
     882:     prepend '\0' for backwards match; return end of new pattern
     883: */
     884: static char globfree[100];
     885:
     886: char *
     887: patprep ( name )
     888:     char *name;
     889: {
     890:     register char *p, *endmark;
     891:     register char *subp = globfree;
     892:
     893:     *subp++ = '\0';
     894:     p = name + strlen ( name ) - 1;
     895:     /*
     896: 	   skip trailing metacharacters (and [] ranges)
     897: 	*/
     898:     for ( ; p >= name; p-- )
     899:         if ( index ( "*?", *p ) == 0 )
     900:             break;
     901:     if ( p < name )
     902:         p = name;
     903:     if ( *p == ']' )
     904:         for ( p--; p >= name; p-- )
     905:             if ( *p == '[' ) {
     906:                 p--;
     907:                 break;
     908:             }
     909:     if ( p < name )
     910:         p = name;
     911:     /*
     912: 	   if pattern has only metacharacters,
     913: 	   check every path (force '/' search)
     914: 	*/
     915:     if ( (p == name) && index ( "?*[]", *p ) != 0 )
     916:         *subp++ = '/';
     917:     else {
     918:         for ( endmark = p; p >= name; p-- )
     919:             if ( index ( "]*?", *p ) != 0 )
     920:                 break;
     921:         for ( ++p; (p <= endmark) && subp < (globfree + sizeof ( globfree )); )
     922:             *subp++ = *p++;
     923:     }
     924:     *subp = '\0';
     925:     return ( --subp );
     926: }
     927: #endif
     928:
     929: /* rest should be done with nameserver or database */
     930:
     931: #include <pwd.h>
     932: #include <grp.h>
     933: #include <utmp.h>
     934:
     935: struct  utmp utmp;
     936: #define NMAX    (sizeof (utmp.ut_name))
     937: #define SCPYN(a, b) strncpy(a, b, NMAX)
     938:
     939: #define NUID    64
     940: #define NGID    300
     941:
     942: struct ncache {
     943:     int uid;
     944:     char    name[NMAX+1];
     945: } nc[NUID];
     946: char    outrangename[NMAX+1];
     947: int outrangeuid = -1;
     948: char    groups[NGID][NMAX+1];
     949: char    outrangegroup[NMAX+1];
     950: int outrangegid = -1;
     951:
     952: /*
     953:  * This function assumes that the password file is hashed
     954:  * (or some such) to allow fast access based on a name key.
     955:  * If this isn't true, duplicate the code for getgroup().
     956:  */
     957: char *
     958: getname(uid)
     959: {
     960:     register struct passwd *pw;
     961:     struct passwd *getpwent();
     962:     register int cp;
     963:
     964:     setpassent(1);
     965:
     966: #if (((NUID) & ((NUID) - 1)) != 0)
     967:     cp = uid % (NUID);
     968: #else
     969:     cp = uid & ((NUID) - 1);
     970: #endif
     971:     if (uid >= 0 && nc[cp].uid == uid && nc[cp].name[0])
     972:         return (nc[cp].name);
     973:     pw = getpwuid(uid);
     974:     if (!pw)
     975:         return (0);
     976:     nc[cp].uid = uid;
     977:     SCPYN(nc[cp].name, pw->pw_name);
     978:     return (nc[cp].name);
     979: }
     980:
     981: char *
     982: getgroup(gid)
     983: {
     984:     register struct group *gr;
     985:     static init;
     986:     struct group *getgrent();
     987:
     988:     if (gid >= 0 && gid < NGID && groups[gid][0])
     989:         return (&groups[gid][0]);
     990:     if (gid >= 0 && gid == outrangegid)
     991:         return (outrangegroup);
     992: rescan:
     993:     if (init == 2) {
     994:         if (gid < NGID)
     995:             return (0);
     996:         setgrent();
     997:         while (gr = getgrent()) {
     998:             if (gr->gr_gid != gid)
     999:                 continue;
    1000:             outrangegid = gr->gr_gid;
    1001:             SCPYN(outrangegroup, gr->gr_name);
    1002:             endgrent();
    1003:             return (outrangegroup);
    1004:         }
    1005:         endgrent();
    1006:         return (0);
    1007:     }
    1008:     if (init == 0)
    1009:         setgrent(), init = 1;
    1010:     while (gr = getgrent()) {
    1011:         if (gr->gr_gid < 0 || gr->gr_gid >= NGID) {
    1012:             if (gr->gr_gid == gid) {
    1013:                 outrangegid = gr->gr_gid;
    1014:                 SCPYN(outrangegroup, gr->gr_name);
    1015:                 return (outrangegroup);
    1016:             }
    1017:             continue;
    1018:         }
    1019:         if (groups[gr->gr_gid][0])
    1020:             continue;
    1021:         SCPYN(groups[gr->gr_gid], gr->gr_name);
    1022:         if (gr->gr_gid == gid)
    1023:             return (&groups[gid][0]);
    1024:     }
    1025:     init = 2;
    1026:     goto rescan;
    1027: }
    1028:
    1029: int
    1030: getuid(username)
    1031:     char *username;
    1032: {
    1033:     register struct passwd *pw;
    1034:     struct passwd *getpwnam();
    1035: #ifndef NO_PW_STAYOPEN
    1036:
    1037:     setpassent(1);
    1038: #endif
    1039:
    1040:     pw = getpwnam(username);
    1041:     if (pw != NULL)
    1042:         return (pw->pw_uid);
    1043:     else
    1044:         return (-1);
    1045: }
    1046:
    1047: int
    1048: getgid(groupname)
    1049:     char *groupname;
    1050: {
    1051:     register struct group *gr;
    1052:     struct group *getgrnam();
    1053:
    1054:     gr = getgrnam(groupname);
    1055:     if (gr != NULL)
    1056:         return (gr->gr_gid);
    1057:     else
    1058:         return (-1);
    1059: }
    1060:
    1061: #define permoffset(who)     ((who) * 3)
    1062: #define permission(who, type)   ((type) >> permoffset(who))
    1063: #define kbytes(bytes)       (((bytes) + 1023) / 1024)
    1064:
    1065: list(file, stp)
    1066:     char *file;
    1067:     register struct stat *stp;
    1068: {
    1069:     char pmode[32], uname[32], gname[32], fsize[32], ftime[32];
    1070:     char *getname(), *getgroup(), *ctime();
    1071:     static long special[] = { S_ISUID, 's', S_ISGID, 's', S_ISVTX, 't' };
    1072:     static time_t sixmonthsago = -1;
    1073: #ifdef  S_IFLNK
    1074:     char flink[MAXPATHLEN + 1];
    1075: #endif
    1076:     register int who;
    1077:     register char *cp;
    1078:     time_t now;
    1079:
    1080:     if (file == NULL || stp == NULL)
    1081:         return (-1);
    1082:
    1083:     time(&now);
    1084:     if (sixmonthsago == -1)
    1085:         sixmonthsago = now - 6L*30L*24L*60L*60L;
    1086:
    1087:     switch (stp->st_mode & S_IFMT) {
    1088: #ifdef  S_IFDIR
    1089:     case S_IFDIR:   /* directory */
    1090:         pmode[0] = 'd';
    1091:         break;
    1092: #endif
    1093: #ifdef  S_IFCHR
    1094:     case S_IFCHR:   /* character special */
    1095:         pmode[0] = 'c';
    1096:         break;
    1097: #endif
    1098: #ifdef  S_IFBLK
    1099:     case S_IFBLK:   /* block special */
    1100:         pmode[0] = 'b';
    1101:         break;
    1102: #endif
    1103: #ifdef  S_IFLNK
    1104:     case S_IFLNK:   /* symbolic link */
    1105:         pmode[0] = 'l';
    1106:         break;
    1107: #endif
    1108: #ifdef  S_IFSOCK
    1109:     case S_IFSOCK:  /* socket */
    1110:         pmode[0] = 's';
    1111:         break;
    1112: #endif
    1113: #ifdef  S_IFREG
    1114:     case S_IFREG:   /* regular */
    1115: #endif
    1116:     default:
    1117:         pmode[0] = '-';
    1118:         break;
    1119:     }
    1120:
    1121:     for (who = 0; who < 3; who++) {
    1122:         if (stp->st_mode & permission(who, S_IREAD))
    1123:             pmode[permoffset(who) + 1] = 'r';
    1124:         else
    1125:             pmode[permoffset(who) + 1] = '-';
    1126:
    1127:         if (stp->st_mode & permission(who, S_IWRITE))
    1128:             pmode[permoffset(who) + 2] = 'w';
    1129:         else
    1130:             pmode[permoffset(who) + 2] = '-';
    1131:
    1132:         if (stp->st_mode & special[who * 2])
    1133:             pmode[permoffset(who) + 3] = special[who * 2 + 1];
    1134:         else if (stp->st_mode & permission(who, S_IEXEC))
    1135:             pmode[permoffset(who) + 3] = 'x';
    1136:         else
    1137:             pmode[permoffset(who) + 3] = '-';
    1138:     }
    1139:     pmode[permoffset(who) + 1] = '\0';
    1140:
    1141:     cp = getname(stp->st_uid);
    1142:     if (cp != NULL)
    1143:         sprintf(uname, "%-9.9s", cp);
    1144:     else
    1145:         sprintf(uname, "%-9d", stp->st_uid);
    1146:
    1147:     cp = getgroup(stp->st_gid);
    1148:     if (cp != NULL)
    1149:         sprintf(gname, "%-9.9s", cp);
    1150:     else
    1151:         sprintf(gname, "%-9d", stp->st_gid);
    1152:
    1153:     if (pmode[0] == 'b' || pmode[0] == 'c')
    1154:         sprintf(fsize, "%3d,%4d",
    1155:             major(stp->st_rdev), minor(stp->st_rdev));
    1156:     else {
    1157:         sprintf(fsize, "%8ld", stp->st_size);
    1158: #ifdef  S_IFLNK
    1159:         if (pmode[0] == 'l') {
    1160:             /*
    1161: 			 * Need to get the tail of the file name, since we have
    1162: 			 * already chdir()ed into the directory of the file
    1163: 			 */
    1164:             cp = rindex(file, '/');
    1165:             if (cp == NULL)
    1166:                 cp = file;
    1167:             else
    1168:                 cp++;
    1169:             who = readlink(cp, flink, sizeof flink - 1);
    1170:             if (who >= 0)
    1171:                 flink[who] = '\0';
    1172:             else
    1173:                 flink[0] = '\0';
    1174:         }
    1175: #endif
    1176:     }
    1177:
    1178:     cp = ctime(&stp->st_mtime);
    1179:     if (stp->st_mtime < sixmonthsago || stp->st_mtime > now)
    1180:         sprintf(ftime, "%-7.7s %-4.4s", cp + 4, cp + 20);
    1181:     else
    1182:         sprintf(ftime, "%-12.12s", cp + 4);
    1183:
    1184: #ifdef pdp11
    1185:     printf("%5u %4ld %s %2d %s%s%s %s %s%s%s\n",
    1186: #else
    1187:     printf("%5lu %4ld %s %2d %s%s%s %s %s%s%s\n",
    1188: #endif
    1189:         stp->st_ino,                /* inode #	*/
    1190: #ifdef  S_IFSOCK
    1191:         (long) kbytes(dbtob(stp->st_blocks)),   /* kbytes       */
    1192: #else
    1193:         (long) kbytes(stp->st_size),        /* kbytes       */
    1194: #endif
    1195:         pmode,                  /* protection	*/
    1196:         stp->st_nlink,              /* # of links	*/
    1197:         uname,                  /* owner	*/
    1198:         gname,                  /* group	*/
    1199:         fsize,                  /* # of bytes	*/
    1200:         ftime,                  /* modify time	*/
    1201:         file,                   /* name		*/
    1202: #ifdef  S_IFLNK
    1203:         (pmode[0] == 'l') ? " -> " : "",
    1204:         (pmode[0] == 'l') ? flink  : ""     /* symlink	*/
    1205: #else
    1206:         "",
    1207:         ""
    1208: #endif
    1209:     );
    1210:
    1211:     return (0);
    1212: }

#### Defined functions

amatch defined in line 690; used 5 times

- in line 687, 708, 722, 738, 872

and defined in line 337; used 2 times

- in line 163, 172

atime defined in line 368; used 2 times

- in line 193, 234

bwrite defined in line 742; used 4 times

- in line 492-494(2), 504-509(2)

chgreel defined in line 765; used 1 times

- in line 753

cpio defined in line 456; used 3 times

- in line 142, 195, 293

descend defined in line 623; used 2 times

- in line 137, 662

doex defined in line 544; used 2 times

- in line 428, 440

dummy defined in line 525; used 2 times

- in line 196, 224

e1 defined in line 162; used 3 times

- in line 44, 154, 172

e2 defined in line 179; used 2 times

- in line 45, 167

e3 defined in line 192; used 3 times

- in line 46, 188-190(2)

exeq defined in line 424; used 2 times

- in line 193, 279

exp defined in line 150; used 4 times

- in line 43, 113, 157, 205

fastfind defined in line 826; used 1 times

- in line 93

getgid defined in line 1047; used 1 times

- in line 247

getgroup defined in line 981; used 4 times

- in line 398-400(2), 1070, 1147

getname defined in line 957; used 4 times

- in line 381-383(2), 1070, 1141

getuid defined in line 1029; used 1 times

- in line 236

getunum defined in line 591; never used
glob defined in line 352; used 2 times

- in line 193, 230

gmatch defined in line 683; used 3 times

- in line 237, 248, 355

group defined in line 390; used 3 times

- in line 194, 249-253(2)

ino defined in line 385; used 2 times

- in line 195, 245

links defined in line 402; used 2 times

- in line 194, 257

list defined in line 1065; used 1 times

- in line 522

ls defined in line 519; used 2 times

- in line 196, 220

main defined in line 75; never used
mk defined in line 306; used 25 times

- in line 47, 157, 172, 188, 211-224(5), 230-257(10), 264, 274-284(3), 293, 301

mklong defined in line 446; used 2 times

- in line 497, 505

mtime defined in line 363; used 2 times

- in line 193, 232

newer defined in line 514; used 2 times

- in line 195, 301

nogroup defined in line 395; used 2 times

- in line 196, 217

not defined in line 347; used 2 times

- in line 180, 188

nouser defined in line 378; used 2 times

- in line 196, 214

nxtarg defined in line 321; used 9 times

- in line 48, 155, 168, 187, 202-206(2), 226, 278-283(2)

ok defined in line 430; used 2 times

- in line 193, 284

or defined in line 342; used 2 times

- in line 151, 157

patprep defined in line 886; used 2 times

- in line 831, 848

perm defined in line 412; used 2 times

- in line 194, 264

print defined in line 357; used 2 times

- in line 194, 211

scomp defined in line 533; used 6 times

- in line 366-376(3), 388, 405-410(2)

size defined in line 407; used 2 times

- in line 194, 255

type defined in line 419; used 4 times

- in line 195, 274, 1062(2)

umatch defined in line 733; used 1 times

- in line 725

user defined in line 373; used 3 times

- in line 193, 238-242(2)

#### Defined variables

Ai defined in line 27; used 19 times

- in line 108-109(6), 117, 159(2), 174-176(3), 189(2), 277-282(2), 328-333(3)

Argc defined in line 26; used 6 times

- in line 103, 159, 176, 189, 328-330(2)

Argv defined in line 29; used 8 times

- in line 103, 109(3), 124, 333, 436, 554

Blocks defined in line 50; used 2 times

- in line 143, 758

Buf defined in line 32; used 4 times

- in line 291, 494, 507-509(2)

Bufsize defined in line 33; used 2 times

- in line 752-756(2)

Cpio defined in line 31; used 5 times

- in line 139, 287, 752-753(3)

Dbuf defined in line 32; used 3 times

- in line 292, 752-757(2)

Devstat defined in line 39; used 2 times

- in line 136, 639

Fname defined in line 24; used 6 times

- in line 134-137(2), 355, 499, 661-662(2)

Home defined in line 49; used 5 times

- in line 98-99(2), 123, 569, 664

Newer defined in line 36; used 2 times

- in line 300, 517

Nn defined in line 23; used 5 times

- in line 310-318(5)

Node defined in line 22; used 4 times

- in line 315-318(4)

Now defined in line 25; used 3 times

- in line 97, 366-371(2)

Pathname defined in line 15; used 16 times

- in line 124-128(4), 134-140(4), 360, 436, 479(3), 522, 557, 665

Pi defined in line 28; used 4 times

- in line 121-124(4)

Randlast defined in line 14; used 5 times

- in line 156, 171, 182-186(2), 204

Statb defined in line 41; used 28 times

- in line 141, 296-300(2), 366-376(3), 383-393(3), 400-410(3), 417-422(2), 481-490(9), 517-522(2), 633-639(3)

Wct defined in line 34; used 3 times

- in line 750, 756-761(2)

Wp defined in line 32; used 3 times

- in line 292, 746, 763

Xdev defined in line 38; used 3 times

- in line 135, 223, 639

globfree defined in line 884; used 3 times

- in line 891, 921(2)

groups defined in line 948; used 5 times

- in line 988-989(2), 1019-1023(3)

nc defined in line 945; used 6 times

- in line 971-978(6)

outrangegid defined in line 950; used 3 times

- in line 990, 1000, 1013

outrangegroup defined in line 949; used 5 times

- in line 991, 1001-1003(2), 1014-1015(2)

outrangename defined in line 946; never used
outrangeuid defined in line 947; never used
sccsid defined in line 2; never used
utmp defined in line 935; used 1 times

- in line 936

#### Defined struct's

anode defined in line 19; used 132 times

- in line 21(2), 43(2), 79(2), 150-152(4), 162-164(4), 179(2), 188-197(6), 211-224(20), 230-257(40), 264(4), 274-284(12), 293(4), 301-308(8), 338-348(6), 358(2), 379(2), 396(2), 457(2), 515-520(4), 526(2), 624(2)

header defined in line 460; never used
ncache defined in line 942; never used

#### Defined macros

AMES defined in line 73; used 2 times

- in line 86, 795

A_DAY defined in line 11; used 2 times

- in line 366-371(2)

EQ defined in line 12; used 33 times

- in line 109(2), 155, 169-173(4), 187, 203-222(7), 229-235(4), 244-246(2), 254-258(3), 266, 276-286(5), 295, 491, 607

ESCCODE defined in line 824; used 2 times

- in line 853-855(2)

FCODES defined in line 820; used 2 times

- in line 839-840(2)

MAGIC defined in line 459; used 1 times

- in line 478

MAXNODES defined in line 17; used 2 times

- in line 22, 310

MKSHORT defined in line 444; used 2 times

- in line 486-489(2)

NGID defined in line 940; used 4 times

- in line 948, 988, 994, 1011

NMAX defined in line 936; used 5 times

- in line 937, 944-949(4)

NO defined in line 822; used 3 times

- in line 837, 865, 872

NUID defined in line 939; used 5 times

- in line 945, 966-969(4)

OFFSET defined in line 823; used 1 times

- in line 853

SCPYN defined in line 937; used 4 times

- in line 977, 1001, 1014, 1021

YES defined in line 821; used 2 times

- in line 847, 871

kbytes defined in line 1063; used 2 times

- in line 1191-1193(2)

permission defined in line 1062; used 3 times

- in line 1122-1127(2), 1134

permoffset defined in line 1061; used 9 times

- in line 1062, 1123-1139(8)

Last modified: 1996-11-02 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 5497 |