1: #include <stdio.h>
   2: #include <sys/param.h>
   3: #include <sys/dir.h>
   4: #include <sys/stat.h>
   5: #include <sys/file.h>
   6: 
   7: #define A_DAY   86400L /* a day full of seconds */
   8: #define EQ(x, y)    (strcmp(x, y)==0)
   9: 
  10: int Randlast;
  11: char    Pathname[200];
  12: 
  13: struct anode {
  14:     int (*F)();
  15:     struct anode *L, *R;
  16: } Node[100];
  17: int Nn;  /* number of nodes */
  18: char    *Fname;
  19: long    Now;
  20: int Argc,
  21:     Ai,
  22:     Pi;
  23: char    **Argv;
  24: /* cpio stuff */
  25: int Cpio;
  26: short   *Buf, *Dbuf, *Wp;
  27: int Bufsize = 5120;
  28: int Wct = 2560;
  29: 
  30: long    Newer;
  31: 
  32: struct stat Statb;
  33: 
  34: struct  anode   *exp(),
  35:         *e1(),
  36:         *e2(),
  37:         *e3(),
  38:         *mk();
  39: char    *nxtarg();
  40: char    Home[128];
  41: long    Blocks;
  42: char *rindex();
  43: char *sbrk();
  44: main(argc, argv) char *argv[];
  45: {
  46:     struct anode *exlist;
  47:     int paths;
  48:     register char *cp, *sp = 0;
  49:     FILE *pwd, *popen();
  50: 
  51:     time(&Now);
  52:     pwd = popen("pwd", "r");
  53:     fgets(Home, 128, pwd);
  54:     pclose(pwd);
  55:     Home[strlen(Home) - 1] = '\0';
  56:     Argc = argc; Argv = argv;
  57:     if(argc<3) {
  58: usage:
  59:         pr("Usage: find path-list predicate-list\n");
  60:         exit(1);
  61:     }
  62:     for(Ai = paths = 1; Ai < (argc-1); ++Ai, ++paths)
  63:         if(*Argv[Ai] == '-' || EQ(Argv[Ai], "(") || EQ(Argv[Ai], "!"))
  64:             break;
  65:     if(paths == 1) /* no path-list */
  66:         goto usage;
  67:     if(!(exlist = exp())) { /* parse and compile the arguments */
  68:         pr("find: parsing error\n");
  69:         exit(1);
  70:     }
  71:     if(Ai<argc) {
  72:         pr("find: missing conjunction\n");
  73:         exit(1);
  74:     }
  75:     for(Pi = 1; Pi < paths; ++Pi) {
  76:         sp = 0;
  77:         chdir(Home);
  78:         strcpy(Pathname, Argv[Pi]);
  79:         if(cp = rindex(Pathname, '/')) {
  80:             sp = cp + 1;
  81:             *cp = '\0';
  82:             if(chdir(*Pathname? Pathname: "/") == -1) {
  83:                 perror(*Pathname? Pathname: "/");
  84:                 exit(2);
  85:             }
  86:             *cp = '/';
  87:         }
  88:         Fname = sp? sp: Pathname;
  89:         descend(Pathname, Fname, exlist); /* to find files that match  */
  90:     }
  91:     if(Cpio) {
  92:         strcpy(Pathname, "TRAILER!!!");
  93:         Statb.st_size = 0;
  94:         cpio();
  95:     }
  96:     exit(0);
  97: }
  98: 
  99: /* compile time functions:  priority is  exp()<e1()<e2()<e3()  */
 100: 
 101: struct anode *exp() { /* parse ALTERNATION (-o)  */
 102:     int or();
 103:     register struct anode * p1;
 104: 
 105:     p1 = e1() /* get left operand */ ;
 106:     if(EQ(nxtarg(), "-o")) {
 107:         Randlast--;
 108:         return(mk(or, p1, exp()));
 109:     }
 110:     else if(Ai <= Argc) --Ai;
 111:     return(p1);
 112: }
 113: struct anode *e1() { /* parse CONCATENATION (formerly -a) */
 114:     int and();
 115:     register struct anode * p1;
 116:     register char *a;
 117: 
 118:     p1 = e2();
 119:     a = nxtarg();
 120:     if(EQ(a, "-a")) {
 121: And:
 122:         Randlast--;
 123:         return(mk(and, p1, e1()));
 124:     } else if(EQ(a, "(") || EQ(a, "!") || (*a=='-' && !EQ(a, "-o"))) {
 125:         --Ai;
 126:         goto And;
 127:     } else if(Ai <= Argc) --Ai;
 128:     return(p1);
 129: }
 130: struct anode *e2() { /* parse NOT (!) */
 131:     int not();
 132: 
 133:     if(Randlast) {
 134:         pr("find: operand follows operand\n");
 135:         exit(1);
 136:     }
 137:     Randlast++;
 138:     if(EQ(nxtarg(), "!"))
 139:         return(mk(not, e3(), (struct anode *)0));
 140:     else if(Ai <= Argc) --Ai;
 141:     return(e3());
 142: }
 143: struct anode *e3() { /* parse parens and predicates */
 144:     int exeq(), ok(), glob(),  mtime(), atime(), ctime(), user(),
 145:         group(), size(), perm(), links(), print(),
 146:         type(), ino(), cpio(), newer();
 147:     struct anode *p1;
 148:     int i;
 149:     register char *a, *b, s;
 150: 
 151:     a = nxtarg();
 152:     if(EQ(a, "(")) {
 153:         Randlast--;
 154:         p1 = exp();
 155:         a = nxtarg();
 156:         if(!EQ(a, ")")) goto err;
 157:         return(p1);
 158:     }
 159:     else if(EQ(a, "-print")) {
 160:         return(mk(print, (struct anode *)0, (struct anode *)0));
 161:     }
 162:     b = nxtarg();
 163:     s = *b;
 164:     if(s=='+') b++;
 165:     if(EQ(a, "-name"))
 166:         return(mk(glob, (struct anode *)b, (struct anode *)0));
 167:     else if(EQ(a, "-mtime"))
 168:         return(mk(mtime, (struct anode *)atoi(b), (struct anode *)s));
 169:     else if(EQ(a, "-atime"))
 170:         return(mk(atime, (struct anode *)atoi(b), (struct anode *)s));
 171:     else if(EQ(a, "-ctime"))
 172:         return(mk(ctime, (struct anode *)atoi(b), (struct anode *)s));
 173:     else if(EQ(a, "-user")) {
 174:         if((i=getunum("/etc/passwd", b)) == -1) {
 175:             if(gmatch(b, "[0-9][0-9][0-9]*")
 176:             || gmatch(b, "[0-9][0-9]")
 177:             || gmatch(b, "[0-9]"))
 178:                 return mk(user, (struct anode *)atoi(b), (struct anode *)s);
 179:             pr("find: cannot find -user name\n");
 180:             exit(1);
 181:         }
 182:         return(mk(user, (struct anode *)i, (struct anode *)s));
 183:     }
 184:     else if(EQ(a, "-inum"))
 185:         return(mk(ino, (struct anode *)atoi(b), (struct anode *)s));
 186:     else if(EQ(a, "-group")) {
 187:         if((i=getunum("/etc/group", b)) == -1) {
 188:             if(gmatch(b, "[0-9][0-9][0-9]*")
 189:             || gmatch(b, "[0-9][0-9]")
 190:             || gmatch(b, "[0-9]"))
 191:                 return mk(group, (struct anode *)atoi(b), (struct anode *)s);
 192:             pr("find: cannot find -group name\n");
 193:             exit(1);
 194:         }
 195:         return(mk(group, (struct anode *)i, (struct anode *)s));
 196:     } else if(EQ(a, "-size"))
 197:         return(mk(size, (struct anode *)atoi(b), (struct anode *)s));
 198:     else if(EQ(a, "-links"))
 199:         return(mk(links, (struct anode *)atoi(b), (struct anode *)s));
 200:     else if(EQ(a, "-perm")) {
 201:         for(i=0; *b ; ++b) {
 202:             if(*b=='-') continue;
 203:             i <<= 3;
 204:             i = i + (*b - '0');
 205:         }
 206:         return(mk(perm, (struct anode *)i, (struct anode *)s));
 207:     }
 208:     else if(EQ(a, "-type")) {
 209:         i = s=='d' ? S_IFDIR :
 210:             s=='b' ? S_IFBLK :
 211:             s=='c' ? S_IFCHR :
 212:             s=='l' ? S_IFLNK :
 213:             s=='q' ? S_IFQUOT :
 214:             s=='f' ? 0100000 :
 215:             0;
 216:         return(mk(type, (struct anode *)i, (struct anode *)0));
 217:     }
 218:     else if (EQ(a, "-exec")) {
 219:         i = Ai - 1;
 220:         while(!EQ(nxtarg(), ";"));
 221:         return(mk(exeq, (struct anode *)i, (struct anode *)0));
 222:     }
 223:     else if (EQ(a, "-ok")) {
 224:         i = Ai - 1;
 225:         while(!EQ(nxtarg(), ";"));
 226:         return(mk(ok, (struct anode *)i, (struct anode *)0));
 227:     }
 228:     else if(EQ(a, "-cpio")) {
 229:         if((Cpio = creat(b, 0666)) < 0) {
 230:             perror(s);
 231:             exit(1);
 232:         }
 233:         Buf = (short *)sbrk(512);
 234:         Wp = Dbuf = (short *)sbrk(5120);
 235:         return(mk(cpio, (struct anode *)0, (struct anode *)0));
 236:     }
 237:     else if(EQ(a, "-newer")) {
 238:         if(stat(b, &Statb) < 0) {
 239:             perror(b);
 240:             exit(1);
 241:         }
 242:         Newer = Statb.st_mtime;
 243:         return mk(newer, (struct anode *)0, (struct anode *)0);
 244:     }
 245: err:    pr("find: bad option "), pr(a), pr("\n");
 246:     exit(1);
 247: }
 248: struct anode *mk(f, l, r)
 249: int (*f)();
 250: struct anode *l, *r;
 251: {
 252:     Node[Nn].F = f;
 253:     Node[Nn].L = l;
 254:     Node[Nn].R = r;
 255:     return(&(Node[Nn++]));
 256: }
 257: 
 258: char *nxtarg() { /* get next arg from command line */
 259:     static strikes = 0;
 260: 
 261:     if(strikes==3) {
 262:         pr("find: incomplete statement\n");
 263:         exit(1);
 264:     }
 265:     if(Ai>=Argc) {
 266:         strikes++;
 267:         Ai = Argc + 1;
 268:         return("");
 269:     }
 270:     return(Argv[Ai++]);
 271: }
 272: 
 273: /* execution time functions */
 274: and(p)
 275: register struct anode *p;
 276: {
 277:     return(((*p->L->F)(p->L)) && ((*p->R->F)(p->R))?1:0);
 278: }
 279: or(p)
 280: register struct anode *p;
 281: {
 282:      return(((*p->L->F)(p->L)) || ((*p->R->F)(p->R))?1:0);
 283: }
 284: not(p)
 285: register struct anode *p;
 286: {
 287:     return( !((*p->L->F)(p->L)));
 288: }
 289: glob(p)
 290: register struct { int f; char *pat; } *p;
 291: {
 292:     return(gmatch(Fname, p->pat));
 293: }
 294: print()
 295: {
 296:     puts(Pathname);
 297:     return(1);
 298: }
 299: mtime(p)
 300: register struct { int f, t, s; } *p;
 301: {
 302:     return(scomp((int)((Now - Statb.st_mtime) / A_DAY), p->t, p->s));
 303: }
 304: atime(p)
 305: register struct { int f, t, s; } *p;
 306: {
 307:     return(scomp((int)((Now - Statb.st_atime) / A_DAY), p->t, p->s));
 308: }
 309: ctime(p)
 310: register struct { int f, t, s; } *p;
 311: {
 312:     return(scomp((int)((Now - Statb.st_ctime) / A_DAY), p->t, p->s));
 313: }
 314: user(p)
 315: register struct { int f, u, s; } *p;
 316: {
 317:     return(scomp(Statb.st_uid, p->u, p->s));
 318: }
 319: ino(p)
 320: register struct { int f, u, s; } *p;
 321: {
 322:     return(scomp((int)Statb.st_ino, p->u, p->s));
 323: }
 324: group(p)
 325: register struct { int f, u; } *p;
 326: {
 327:     return(p->u == Statb.st_gid);
 328: }
 329: links(p)
 330: register struct { int f, link, s; } *p;
 331: {
 332:     return(scomp(Statb.st_nlink, p->link, p->s));
 333: }
 334: size(p)
 335: register struct { int f, sz, s; } *p;
 336: {
 337:     return(scomp((int)((Statb.st_size + 1023) / 1024), p->sz, p->s));
 338: }
 339: perm(p)
 340: register struct { int f, per, s; } *p;
 341: {
 342:     register i;
 343:     i = (p->s=='-') ? p->per : 07777; /* '-' means only arg bits */
 344:     return((Statb.st_mode & i & 07777) == p->per);
 345: }
 346: type(p)
 347: register struct { int f, per, s; } *p;
 348: {
 349:     return((Statb.st_mode&S_IFMT)==p->per);
 350: }
 351: exeq(p)
 352: register struct { int f, com; } *p;
 353: {
 354:     fflush(stdout); /* to flush possible `-print' */
 355:     return(doex(p->com));
 356: }
 357: ok(p)
 358: struct { int f, com; } *p;
 359: {
 360:     int c;  int yes;
 361:     yes = 0;
 362:     fflush(stdout); /* to flush possible `-print' */
 363:     pr("< "), pr(Argv[p->com]), pr(" ... "), pr(Pathname), pr(" >?   ");
 364:     fflush(stderr);
 365:     if((c=getchar())=='y') yes = 1;
 366:     while(c!='\n')
 367:         if(c==EOF)
 368:             exit(2);
 369:         else
 370:             c = getchar();
 371:     if(yes) return(doex(p->com));
 372:     return(0);
 373: }
 374: 
 375: #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];}
 376: union { long l; short s[2]; char c[4]; } U;
 377: long mklong(v)
 378: short v[];
 379: {
 380:     U.l = 1;
 381:     if(U.c[0] /* VAX */)
 382:         U.s[0] = v[1], U.s[1] = v[0];
 383:     else
 384:         U.s[0] = v[0], U.s[1] = v[1];
 385:     return U.l;
 386: }
 387: cpio()
 388: {
 389: #define MAGIC 070707
 390:     struct header {
 391:         short   h_magic,
 392:             h_dev,
 393:             h_ino,
 394:             h_mode,
 395:             h_uid,
 396:             h_gid,
 397:             h_nlink,
 398:             h_rdev;
 399:         short   h_mtime[2];
 400:         short   h_namesize;
 401:         short   h_filesize[2];
 402:         char    h_name[256];
 403:     } hdr;
 404:     register ifile, ct;
 405:     static long fsz;
 406:     register i;
 407: 
 408:     hdr.h_magic = MAGIC;
 409:     strcpy(hdr.h_name, !strncmp(Pathname, "./", 2)? Pathname+2: Pathname);
 410:     hdr.h_namesize = strlen(hdr.h_name) + 1;
 411:     hdr.h_uid = Statb.st_uid;
 412:     hdr.h_gid = Statb.st_gid;
 413:     hdr.h_dev = Statb.st_dev;
 414:     hdr.h_ino = Statb.st_ino;
 415:     hdr.h_mode = Statb.st_mode;
 416:     MKSHORT(hdr.h_mtime, Statb.st_mtime);
 417:     hdr.h_nlink = Statb.st_nlink;
 418:     fsz = hdr.h_mode & S_IFREG? Statb.st_size: 0L;
 419:     MKSHORT(hdr.h_filesize, fsz);
 420:     hdr.h_rdev = Statb.st_rdev;
 421:     if(EQ(hdr.h_name, "TRAILER!!!")) {
 422:         bwrite((short *)&hdr, (sizeof hdr-256)+hdr.h_namesize);
 423:         for(i = 0; i < 10; ++i)
 424:             bwrite(Buf, 512);
 425:         return;
 426:     }
 427:     if(!mklong(hdr.h_filesize)) {
 428:         bwrite((short *)&hdr, (sizeof hdr-256)+hdr.h_namesize);
 429:         return;
 430:     }
 431:     if((ifile = open(Fname, FATT_RDONLY)) < 0) {
 432: cerror:
 433:         perror(hdr.h_name);
 434:         return;
 435:     }
 436:     bwrite((short *)&hdr, (sizeof hdr-256)+hdr.h_namesize);
 437:     for(fsz = mklong(hdr.h_filesize); fsz > 0; fsz -= 512) {
 438:         ct = fsz>512? 512: fsz;
 439:         if(read(ifile, (char *)Buf, ct) < 0)
 440:             goto cerror;
 441:         bwrite(Buf, ct);
 442:     }
 443:     close(ifile);
 444:     return;
 445: }
 446: newer()
 447: {
 448:     return Statb.st_mtime > Newer;
 449: }
 450: 
 451: /* support functions */
 452: scomp(a, b, s) /* funny signed compare */
 453: register a, b;
 454: register char s;
 455: {
 456:     if(s == '+')
 457:         return(a > b);
 458:     if(s == '-')
 459:         return(a < (b * -1));
 460:     return(a == b);
 461: }
 462: 
 463: doex(com)
 464: {
 465:     register np;
 466:     register char *na;
 467:     static char *nargv[50];
 468:     static ccode;
 469: 
 470:     ccode = np = 0;
 471:     while (na=Argv[com++]) {
 472:         if(strcmp(na, ";")==0) break;
 473:         if(strcmp(na, "{}")==0) nargv[np++] = Pathname;
 474:         else nargv[np++] = na;
 475:     }
 476:     nargv[np] = 0;
 477:     if (np==0) return(9);
 478:     if(fork()) /*parent*/ wait(&ccode);
 479:     else { /*child*/
 480:         chdir(Home);
 481:         execvp(nargv[0], nargv, np);
 482:         exit(1);
 483:     }
 484:     return(ccode ? 0:1);
 485: }
 486: 
 487: getunum(f, s) char *f, *s; { /* find user/group name and return number */
 488:     register i;
 489:     register char *sp;
 490:     register c;
 491:     char str[20];
 492:     FILE *pin;
 493: 
 494:     i = -1;
 495:     pin = fopen(f, "r");
 496:     c = '\n'; /* prime with a CR */
 497:     do {
 498:         if(c=='\n') {
 499:             sp = str;
 500:             while((c = *sp++ = getc(pin)) != ':')
 501:                 if(c == EOF) goto RET;
 502:             *--sp = '\0';
 503:             if(EQ(str, s)) {
 504:                 while((c=getc(pin)) != ':')
 505:                     if(c == EOF) goto RET;
 506:                 sp = str;
 507:                 while((*sp = getc(pin)) != ':') sp++;
 508:                 *sp = '\0';
 509:                 i = atoi(str);
 510:                 goto RET;
 511:             }
 512:         }
 513:     } while((c = getc(pin)) != EOF);
 514:  RET:
 515:     fclose(pin);
 516:     return(i);
 517: }
 518: 
 519: descend(name, fname, exlist)
 520: struct anode *exlist;
 521: char *name, *fname;
 522: {
 523:     int dir = 0, /* open directory */
 524:         dsize,
 525:         entries,
 526:         dirsize;
 527:     off_t   offset;
 528:     struct direct dentry[BSIZE / sizeof (struct direct)];
 529:     register struct direct  *dp;
 530:     register char *c1, *c2;
 531:     int i;
 532:     int rv = 0;
 533:     char *endofname;
 534: 
 535: #ifdef  UCB_SYMLINKS
 536:     if(lstat(fname, &Statb)<0)
 537: #else
 538:     if(stat(fname, &Statb)<0)
 539: #endif
 540:     {
 541:         perror(name);
 542:         return(0);
 543:     }
 544:     (*exlist->F)(exlist);
 545:     if((Statb.st_mode&S_IFMT)!=S_IFDIR)
 546:         return(1);
 547: 
 548:     for(c1 = name; *c1; ++c1);
 549:     if(*(c1-1) == '/')
 550:         --c1;
 551:     endofname = c1;
 552:     dirsize = Statb.st_size;
 553: 
 554:     if(chdir(fname) == -1)
 555:         return(0);
 556:     for(offset=0 ; offset < dirsize ; offset += BSIZE) { /* each block */
 557:         dsize = BSIZE<(dirsize-offset)? BSIZE: (dirsize-offset);
 558:         if(!dir) {
 559:             if((dir=open(".", FATT_RDONLY))<0) {
 560:                 perror(name);
 561:                 rv = 0;
 562:                 goto ret;
 563:             }
 564:             if(offset) lseek(dir, offset, FSEEK_ABSOLUTE);
 565:             if(read(dir, (char *)dentry, dsize)<0) {
 566:                 perror(name);
 567:                 rv = 0;
 568:                 goto ret;
 569:             }
 570:             if(dir > 10) {
 571:                 close(dir);
 572:                 dir = 0;
 573:             }
 574:         } else
 575:             if(read(dir, (char *)dentry, dsize)<0) {
 576:                 perror(name);
 577:                 rv = 0;
 578:                 goto ret;
 579:             }
 580:         for(dp=dentry, entries=dsize>>4; entries; --entries, ++dp) { /* each directory entry */
 581:             if(dp->d_ino==0
 582:             || (dp->d_name[0]=='.' && dp->d_name[1]=='\0')
 583:             || (dp->d_name[0]=='.' && dp->d_name[1]=='.' && dp->d_name[2]=='\0'))
 584:                 continue;
 585:             c1 = endofname;
 586:             *c1++ = '/';
 587:             c2 = dp->d_name;
 588:             for(i=0; i<14; ++i)
 589:                 if(*c2)
 590:                     *c1++ = *c2++;
 591:                 else
 592:                     break;
 593:             *c1 = '\0';
 594:             if(c1 == endofname) { /* ?? */
 595:                 rv = 0;
 596:                 goto ret;
 597:             }
 598:             Fname = endofname+1;
 599:             if(!descend(name, Fname, exlist)) {
 600:                 *endofname = '\0';
 601:                 chdir(Home);
 602:                 if(chdir(Pathname) == -1) {
 603:                     perror(Pathname);
 604:                     exit(1);
 605:                 }
 606:             }
 607:         }
 608:     }
 609:     rv = 1;
 610: ret:
 611:     if(dir)
 612:         close(dir);
 613:     if(chdir("..") == -1) {
 614:         *endofname = '\0';
 615:         perror(name);
 616:         rv = 1;
 617:     }
 618:     return(rv);
 619: }
 620: 
 621: gmatch(s, p) /* string match as in glob */
 622: register char *s, *p;
 623: {
 624:     if (*s=='.' && *p!='.') return(0);
 625:     return amatch(s, p);
 626: }
 627: 
 628: amatch(s, p)
 629: register char *s, *p;
 630: {
 631:     register cc;
 632:     int scc, k;
 633:     int c, lc;
 634: 
 635:     scc = *s;
 636:     lc = 077777;
 637:     switch (c = *p) {
 638: 
 639:     case '[':
 640:         k = 0;
 641:         while (cc = *++p) {
 642:             switch (cc) {
 643: 
 644:             case ']':
 645:                 if (k)
 646:                     return(amatch(++s, ++p));
 647:                 else
 648:                     return(0);
 649: 
 650:             case '-':
 651:                 k |= lc <= scc & scc <= (cc=p[1]);
 652:             }
 653:             if (scc==(lc=cc)) k++;
 654:         }
 655:         return(0);
 656: 
 657:     case '?':
 658:     caseq:
 659:         if(scc) return(amatch(++s, ++p));
 660:         return(0);
 661:     case '*':
 662:         return(umatch(s, ++p));
 663:     case 0:
 664:         return(!scc);
 665:     }
 666:     if (c==scc) goto caseq;
 667:     return(0);
 668: }
 669: 
 670: umatch(s, p)
 671: register char *s, *p;
 672: {
 673:     if(*p==0) return(1);
 674:     while(*s)
 675:         if (amatch(s++, p)) return(1);
 676:     return(0);
 677: }
 678: 
 679: bwrite(rp, c)
 680: register short *rp;
 681: register c;
 682: {
 683:     register short *wp = Wp;
 684: 
 685:     c = (c+1) >> 1;
 686:     while(c--) {
 687:         if(!Wct) {
 688: again:
 689:             if(write(Cpio, (char *)Dbuf, Bufsize)<0) {
 690:                 Cpio = chgreel(1, Cpio);
 691:                 goto again;
 692:             }
 693:             Wct = Bufsize >> 1;
 694:             wp = Dbuf;
 695:             ++Blocks;
 696:         }
 697:         *wp++ = *rp++;
 698:         --Wct;
 699:     }
 700:     Wp = wp;
 701: }
 702: chgreel(x, fl)
 703: {
 704:     register f;
 705:     char str[22];
 706:     FILE *devtty;
 707:     struct stat statb;
 708: 
 709:     pr("find: can't "), pr(x? "write output": "read input"), pr("\n");
 710:     fstat(fl, &statb);
 711:     if((statb.st_mode&S_IFMT) != S_IFCHR)
 712:         exit(1);
 713: again:
 714:     pr("If you want to go on, type device/file name when ready\n");
 715:     devtty = fopen("/dev/tty", "r");
 716:     fgets(str, 20, devtty);
 717:     str[strlen(str) - 1] = '\0';
 718:     if(!*str)
 719:         exit(1);
 720:     close(fl);
 721:     if((f = open(str, x? FATT_WRONLY: FATT_RDONLY)) < 0) {
 722:         pr("That didn't work");
 723:         fclose(devtty);
 724:         goto again;
 725:     }
 726:     return f;
 727: }
 728: pr(s)
 729: char *s;
 730: {
 731:     fputs(s, stderr);
 732: }

Defined functions

amatch defined in line 628; used 4 times
and defined in line 274; used 2 times
atime defined in line 304; used 2 times
bwrite defined in line 679; used 5 times
chgreel defined in line 702; used 1 times
cpio defined in line 387; used 3 times
ctime defined in line 309; used 2 times
descend defined in line 519; used 2 times
doex defined in line 463; used 2 times
e1 defined in line 113; used 3 times
e2 defined in line 130; used 2 times
e3 defined in line 143; used 3 times
exeq defined in line 351; used 2 times
exp defined in line 101; used 4 times
getunum defined in line 487; used 2 times
glob defined in line 289; used 2 times
gmatch defined in line 621; used 7 times
group defined in line 324; used 3 times
ino defined in line 319; used 2 times
links defined in line 329; used 2 times
main defined in line 44; never used
mk defined in line 248; used 22 times
mklong defined in line 377; used 2 times
mtime defined in line 299; used 2 times
newer defined in line 446; used 2 times
not defined in line 284; used 2 times
nxtarg defined in line 258; used 9 times
ok defined in line 357; used 2 times
or defined in line 279; used 2 times
perm defined in line 339; used 2 times
pr defined in line 728; used 20 times
print defined in line 294; used 2 times
scomp defined in line 452; used 7 times
size defined in line 334; used 2 times
type defined in line 346; used 2 times
umatch defined in line 670; used 1 times
user defined in line 314; used 3 times

Defined variables

Ai defined in line 21; used 19 times
Argc defined in line 20; used 6 times
Argv defined in line 23; used 8 times
Blocks defined in line 41; used 1 times
Buf defined in line 26; used 4 times
Bufsize defined in line 27; used 2 times
Cpio defined in line 25; used 5 times
Dbuf defined in line 26; used 3 times
Fname defined in line 18; used 6 times
Home defined in line 40; used 6 times
Newer defined in line 30; used 2 times
Nn defined in line 17; used 4 times
Node defined in line 16; used 4 times
Now defined in line 19; used 4 times
Pathname defined in line 11; used 17 times
Pi defined in line 22; used 4 times
Randlast defined in line 10; used 5 times
Statb defined in line 32; used 27 times
Wct defined in line 28; used 3 times
Wp defined in line 26; used 3 times

Defined struct's

anode defined in line 13; used 106 times
header defined in line 390; never used

Defined macros

A_DAY defined in line 7; used 3 times
EQ defined in line 8; used 30 times
MAGIC defined in line 389; used 1 times
MKSHORT defined in line 375; used 2 times
Last modified: 1983-08-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2537
Valid CSS Valid XHTML 1.0 Strict