Annotation of researchv9/cmd/find.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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