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

unix.superglobalmegacorp.com

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