Annotation of coherent/d/bin/find/find.y, revision 1.1

1.1     ! root        1: %{
        !             2: /*
        !             3:  * Find all files in the given
        !             4:  * directory hierarchies that
        !             5:  * satisfy the given expression
        !             6:  * primaries.
        !             7:  */
        !             8: 
        !             9: #include <stdio.h>
        !            10: #include <sys/stat.h>
        !            11: #include <sys/dir.h>
        !            12: #include <pwd.h>
        !            13: #include <grp.h>
        !            14: #include "findnode.h"
        !            15: 
        !            16: #define        NPRIM   (sizeof(primaries)/sizeof(primaries[0]))
        !            17: #define        NARG    50
        !            18: #define        NRECUR  14              /* Maximum recursion depth before forking */
        !            19: #define        NFNAME  600             /* size of filename buffer */
        !            20: #define        FILEARG ((char *)EOF)
        !            21: #define        DAYSEC  (60L*60L*24L)   /* seconds in a day */
        !            22: #define        inode(f,v)      lnode(FUN,f,v,NULL)
        !            23: #define        snode(f,s)      lnode(FUN,f,0,s)
        !            24: %}
        !            25: %start command
        !            26: 
        !            27: %union {
        !            28:        NODE  *nodeptr;
        !            29:        }
        !            30: 
        !            31: %left  OR
        !            32: %left  AND
        !            33: %left  '!'
        !            34: %token <nodeptr> NAME PERM TYPE LINKS USER GROUP SIZE INUM
        !            35: %token <nodeptr> ATIME CTIME MTIME EXEC OK PRINT NEWER FUN NOP
        !            36: %type  <nodeptr> exp
        !            37: 
        !            38: %%
        !            39: 
        !            40: command:
        !            41:        exp '\n'                { if (seflag)
        !            42:                                        code = $1; else
        !            43:                                        code = bnode(AND,$1,snode(xprint,NULL));
        !            44:                                  return;
        !            45:                                }
        !            46:       | '\n'                   { code = snode(xprint, NULL); return; }
        !            47:        ;
        !            48: 
        !            49: exp:
        !            50:         '(' exp ')'            { $$ = $2; }
        !            51:       | '!' exp                        { $$ = bnode('!', $2, NULL); }
        !            52:       | exp OR exp             { $$ = bnode(OR, $1, $3); }
        !            53:       | exp AND exp            { $$ = bnode(AND, $1, $3); }
        !            54:       | NAME                   { $$ = snode(xname, next()); }
        !            55:       | PERM                   { $$ = onode(xperm); }
        !            56:       | TYPE                   { $$ = snode(xtype, next()); }
        !            57:       | LINKS                  { $$ = nnode(xlinks); }
        !            58:       | USER                   { $$ = getuser(); }
        !            59:       | GROUP                  { $$ = getgroup(); }
        !            60:       | SIZE                   { $$ = nnode(xsize); }
        !            61:       | INUM                   { $$ = nnode(xinum); }
        !            62:       | ATIME                  { $$ = nnode(xatime); }
        !            63:       | CTIME                  { $$ = nnode(xctime); }
        !            64:       | MTIME                  { $$ = nnode(xmtime); }
        !            65:       | EXEC                   { $$ = enode(0); }
        !            66:       | OK                     { $$ = enode(1); }
        !            67:       | PRINT                  { $$ = snode(xprint, NULL); seflag++; }
        !            68:       | NEWER                  { $$ = getnewer(); }
        !            69:       | NOP                    { $$ = snode(xnop, NULL); seflag++; }
        !            70:        ;
        !            71: 
        !            72: %%
        !            73: struct primary {
        !            74:        char    *p_name;
        !            75:        int     p_lval;
        !            76: }      primaries[] = {
        !            77:        "-name", NAME,
        !            78:        "-perm", PERM,
        !            79:        "-type", TYPE,
        !            80:        "-links", LINKS,
        !            81:        "-user", USER,
        !            82:        "-group", GROUP,
        !            83:        "-size", SIZE,
        !            84:        "-inum", INUM,
        !            85:        "-atime", ATIME,
        !            86:        "-ctime", CTIME,
        !            87:        "-mtime", MTIME,
        !            88:        "-exec", EXEC,
        !            89:        "-ok", OK,
        !            90:        "-print", PRINT,
        !            91:        "-newer", NEWER,
        !            92:        "-nop", NOP,
        !            93:        "-o", OR,
        !            94:        "-a", AND,
        !            95: };
        !            96: 
        !            97: char   **gav;
        !            98: int    gac;
        !            99: int    depth;                  /* Recursive depth */
        !           100: 
        !           101: struct stat    sb;
        !           102: char   fname[NFNAME];
        !           103: char   *prompt;
        !           104: 
        !           105: char   toodeep[] = "directory structure too deep to traverse";
        !           106: char   nospace[] = "out of memory";
        !           107: 
        !           108: time_t curtime;
        !           109: 
        !           110: NODE   *code;
        !           111: int    seflag;                 /* Set if a side effect (print, exec) found */
        !           112: 
        !           113: char   *next();
        !           114: NODE   *bnode();
        !           115: NODE   *enode();
        !           116: NODE   *lnode();
        !           117: NODE   *nnode();
        !           118: NODE   *onode();
        !           119: NODE   *getuser();
        !           120: NODE   *getgroup();
        !           121: NODE   *getnewer();
        !           122: int    xname();
        !           123: int    xperm();
        !           124: int    xtype();
        !           125: int    xlinks();
        !           126: int    xuser();
        !           127: int    xgroup();
        !           128: int    xsize();
        !           129: int    xinum();
        !           130: int    xatime();
        !           131: int    xctime();
        !           132: int    xmtime();
        !           133: int    xnewer();
        !           134: int    xexec();
        !           135: int    xprint();
        !           136: int    xnop();
        !           137: char   *getenv();
        !           138: 
        !           139: main(argc, argv)
        !           140: char *argv[];
        !           141: {
        !           142:        register int i;
        !           143:        register char *ap;
        !           144:        register int eargc;
        !           145: 
        !           146:        for (i=1; i<argc; i++) {
        !           147:                ap = argv[i];
        !           148:                if (*ap == '-')
        !           149:                        break;
        !           150:                if (ap[1]=='\0' && (*ap=='!' || *ap=='('))
        !           151:                        break;
        !           152:        }
        !           153:        if ((eargc=i) < 2)
        !           154:                usage();
        !           155:        gav = argv+i;
        !           156:        gac = argc-i;
        !           157:        yyparse();
        !           158:        time(&curtime);
        !           159:        if ((prompt = getenv("PS1")) == NULL)
        !           160:                prompt = "> ";
        !           161:        for (i=1; i<eargc; i++)
        !           162:                find(argv[i]);
        !           163: }
        !           164: 
        !           165: /*
        !           166:  * Lexical analyser
        !           167:  */
        !           168: yylex()
        !           169: {
        !           170:        static int binop = 0;
        !           171:        static int ntoken = 0;
        !           172:        register char *ap;
        !           173:        struct primary *pp;
        !           174:        register int token;
        !           175: 
        !           176:        if (ntoken) {
        !           177:                token = ntoken;
        !           178:                ntoken = 0;
        !           179:        } else if ((ap = next()) == NULL)
        !           180:                token = '\n';
        !           181:        else if (ap[1] == '\0')
        !           182:                token = ap[0];
        !           183:        else if (*ap == '-') {
        !           184:                for (pp = primaries; pp < &primaries[NPRIM]; pp++)
        !           185:                        if (strcmp(pp->p_name, ap) == 0) {
        !           186:                                token = pp->p_lval;
        !           187:                                break;
        !           188:                        }
        !           189:                if (pp >= &primaries[NPRIM])
        !           190:                        ferr("`%s' is an illegal primary", ap);
        !           191:        } else
        !           192:                ferr("Illegal expression %s\n", ap);
        !           193:        if (binop && token!=')' && token!='\n' && token!=OR && token!=AND) {
        !           194:                binop = 0;
        !           195:                ntoken = token;
        !           196:                return (AND);
        !           197:        }
        !           198:        if (token!=OR && token!=AND && token!='!' && token!='\n' && token!='(')
        !           199:                binop = 1; else
        !           200:                binop = 0;
        !           201:        return (token);
        !           202: }
        !           203: 
        !           204: yyerror()
        !           205: {
        !           206:        fprintf(stderr, "Primary expression syntax error\n");
        !           207:        usage();
        !           208: }
        !           209: 
        !           210: /*
        !           211:  * Return the next argument from the arg list.
        !           212:  */
        !           213: char *
        !           214: next()
        !           215: {
        !           216:        if (gac < 1)
        !           217:                return (NULL);
        !           218:        gac--;
        !           219:        return (*gav++);
        !           220: }
        !           221: 
        !           222: /*
        !           223:  * Produce a node consisting
        !           224:  * of an octal number.
        !           225:  */
        !           226: NODE *
        !           227: onode(fun)
        !           228: int (*fun)();
        !           229: {
        !           230:        register char *ap;
        !           231:        register int num;
        !           232:        register NODE *np;
        !           233:        register int type;
        !           234:        char *aap;
        !           235: 
        !           236:        if ((ap = next()) == NULL)
        !           237:                ferr("Missing octal permission");
        !           238:        aap = ap;
        !           239:        if (*ap == '-') {
        !           240:                ap++;
        !           241:                type = -1;
        !           242:        } else
        !           243:                type = 0;
        !           244:        num = 0;
        !           245:        while (*ap>='0' && *ap<='7')
        !           246:                num = num*8 + *ap++-'0';
        !           247:        if (*ap != '\0')
        !           248:                ferr("%s: bad octal permission", aap);
        !           249:        np = inode(fun, num);
        !           250:        np->n_un.n_val = num;
        !           251:        np->n_type = type;
        !           252:        return (np);
        !           253: }
        !           254: 
        !           255: /*
        !           256:  * Get a number -- it also may be
        !           257:  * prefixed by `+' or `-' to
        !           258:  * represent quantities greater or
        !           259:  * less.
        !           260:  */
        !           261: NODE *
        !           262: nnode(fun)
        !           263: int (*fun);
        !           264: {
        !           265:        register char *ap;
        !           266:        register int num = 0;
        !           267:        register int type = 0;
        !           268:        register NODE *np;
        !           269:        char *aap;
        !           270: 
        !           271:        if ((ap = next()) == NULL)
        !           272:                ferr("Missing number");
        !           273:        aap = ap;
        !           274:        if (*ap == '+') {
        !           275:                type = 1;
        !           276:                ap++;
        !           277:        } else if (*ap == '-') {
        !           278:                type = -1;
        !           279:                ap++;
        !           280:        }
        !           281:        while (*ap>='0' && *ap<='9')
        !           282:                num = num*10 + *ap++ - '0';
        !           283:        if (*ap != '\0')
        !           284:                ferr("%s: invalid number", aap);
        !           285:        np = inode(fun, num);
        !           286:        np->n_type = type;
        !           287:        return (np);
        !           288: }
        !           289: 
        !           290: /*
        !           291:  * Get a user name or number.
        !           292:  */
        !           293: NODE *
        !           294: getuser()
        !           295: {
        !           296:        register struct passwd *pwp;
        !           297:        register char *cp;
        !           298:        register int uid;
        !           299: 
        !           300:        if ((cp = next()) == NULL)
        !           301:                ferr("Missing username");
        !           302:        if (*cp>='0' && *cp<='9')
        !           303:                uid = atoi(cp);
        !           304:        else {
        !           305:                if ((pwp = getpwnam(cp)) == NULL)
        !           306:                        ferr("%s: bad user name", cp);
        !           307:                uid = pwp->pw_uid;
        !           308:        }
        !           309:        return (lnode(FUN, xuser, uid, NULL));
        !           310: }
        !           311: 
        !           312: /*
        !           313:  * Get group
        !           314:  */
        !           315: NODE *
        !           316: getgroup()
        !           317: {
        !           318:        register struct group *grp;
        !           319:        register char *cp;
        !           320:        register int gid;
        !           321: 
        !           322:        if ((cp = next()) == NULL)
        !           323:                ferr("Missing group name");
        !           324:        if (*cp>='0' && *cp<='9')
        !           325:                gid = atoi(cp);
        !           326:        else {
        !           327:                if ((grp = getgrnam(cp)) == NULL)
        !           328:                        ferr("%s: bad group name", cp);
        !           329:                gid = grp->gr_gid;
        !           330:        }
        !           331:        return (lnode(FUN, xgroup, gid, NULL));
        !           332: }
        !           333: 
        !           334: /*
        !           335:  * Get the time for the file used in
        !           336:  * the `-newer' primary.
        !           337:  */
        !           338: NODE *
        !           339: getnewer()
        !           340: {
        !           341:        register NODE *np;
        !           342:        register char *fn;
        !           343: 
        !           344:        if ((fn = next()) == NULL)
        !           345:                ferr("Missing filename for `-newer'");
        !           346:        if (stat(fn, &sb) < 0)
        !           347:                ferr("%s: nonexistent", fn);
        !           348:        np = inode(xnewer, 0);
        !           349:        np->n_un.n_time = sb.st_mtime;
        !           350:        return (np);
        !           351: }
        !           352: 
        !           353: /*
        !           354:  * Build an expression tree node (non-leaf).
        !           355:  */
        !           356: NODE *
        !           357: bnode(op, left, right)
        !           358: int op;
        !           359: NODE *left, *right;
        !           360: {
        !           361:        register NODE *np;
        !           362: 
        !           363:        if ((np = malloc(sizeof (NODE))) == NULL)
        !           364:                ferr(nospace);
        !           365:        np->n_op = op;
        !           366:        np->n_left = left;
        !           367:        np->n_right = right;
        !           368:        np->n_un.n_val = 0;
        !           369:        return (np);
        !           370: }
        !           371: 
        !           372: /*
        !           373:  * Build a leaf node in expression tree.
        !           374:  */
        !           375: NODE *
        !           376: lnode(op, fn, val, str)
        !           377: int (*fn)();
        !           378: char *str;
        !           379: {
        !           380:        register NODE *np;
        !           381: 
        !           382:        if ((np = malloc(sizeof (NODE))) == NULL)
        !           383:                ferr(nospace);
        !           384:        np->n_left = np->n_right = NULL;
        !           385:        np->n_op = op;
        !           386:        np->n_fun = fn;
        !           387:        if (str != NULL)
        !           388:                np->n_un.n_str = str; else
        !           389:                np->n_un.n_val = val;
        !           390:        return (np);
        !           391: }
        !           392: 
        !           393: /*
        !           394:  * Build an execution node
        !           395:  * for -ok or -exec.
        !           396:  */
        !           397: NODE *
        !           398: enode(type)
        !           399: {
        !           400:        register NODE *np;
        !           401:        register char **app;
        !           402:        register char *ap;
        !           403: 
        !           404:        seflag++;
        !           405:        np = snode(xexec, NULL);
        !           406:        np->n_type = type;
        !           407:        if ((np->n_un.n_strp = (char**)malloc(sizeof(char*[NARG])))==NULL)
        !           408:                ferr(nospace);
        !           409:        app = np->n_un.n_strp;
        !           410:        for (;;) {
        !           411:                if ((ap = next()) == NULL)
        !           412:                        ferr("Non-terminated -exec or -ok command list");
        !           413:                if (strcmp(ap, "{}") == 0)
        !           414:                        ap = FILEARG;
        !           415:                else if (strcmp(ap, ";") == 0)
        !           416:                        break;
        !           417:                if (app-np->n_un.n_strp >= NARG-1)
        !           418:                        ferr("Too many -exec or -ok command arguments");
        !           419:                *app++ = ap;
        !           420:        }
        !           421:        *app = NULL;
        !           422:        return (np);
        !           423: }
        !           424: 
        !           425: /*
        !           426:  * Execute find on a single
        !           427:  * pathname hierarchy.
        !           428:  */
        !           429: find(dir)
        !           430: char *dir;
        !           431: {
        !           432:        register char *ep, *cp;
        !           433: 
        !           434:        cp = dir;
        !           435:        ep = fname;
        !           436:        while (*cp)
        !           437:                *ep++ = *cp++;
        !           438:        *ep = '\0';
        !           439:        if (stat(dir, &sb) < 0)
        !           440:                ferr("Cannot find directory `%s'", dir);
        !           441:        if ((sb.st_mode&S_IFMT) != S_IFDIR)
        !           442:                ferr("%s: not a directory", dir);
        !           443:        fentry(ep, &sb);
        !           444: }
        !           445: 
        !           446: /*
        !           447:  * The pointer is the end pointer
        !           448:  * into the fname buffer.
        !           449:  * And the stat buffer is passed to this
        !           450:  * which traverses the directory hierarchy.
        !           451:  */
        !           452: fentry(ep, sbp)
        !           453: char *ep;
        !           454: struct stat *sbp;
        !           455: {
        !           456:        char *buildname();
        !           457:        register char *np;
        !           458:        register struct direct *dp;
        !           459:        register int nb;
        !           460:        int fd;
        !           461:        int dirflag;
        !           462:        char *iobuf;
        !           463: 
        !           464:        if (sbp != NULL) {
        !           465:                dirflag = (sbp->st_mode&S_IFMT)==S_IFDIR;
        !           466:                execute(code);
        !           467:        } else
        !           468:                dirflag = 1;
        !           469:        if (dirflag) {
        !           470:                if (++depth >= NRECUR) {
        !           471:                        depth = 0;
        !           472:                        ffork(ep, sbp);
        !           473:                        return;
        !           474:                }
        !           475:                if ((fd = open(fname, 0)) < 0) {
        !           476:                        fmsg("%s: cannot open directory", fname);
        !           477:                        return;
        !           478:                }
        !           479:                if ((iobuf = malloc(BUFSIZ)) == NULL)
        !           480:                        ferr(nospace);
        !           481:                while ((nb = read(fd, iobuf, BUFSIZ)) > 0)
        !           482:                        for (dp = iobuf; dp < &iobuf[nb]; dp++) {
        !           483:                                if (dp->d_ino == 0)
        !           484:                                        continue;
        !           485:                                np = dp->d_name;
        !           486:                                if (*np++=='.'
        !           487:                                  && (*np=='\0' || (*np++=='.' && *np=='\0')))
        !           488:                                        continue;
        !           489:                                np = buildname(dp, ep);
        !           490:                                if (stat(fname, &sb) < 0) {
        !           491:                                        fmsg("%s: cannot stat", fname);
        !           492:                                        continue;
        !           493:                                }
        !           494:                                fentry(np, &sb);
        !           495:                        }
        !           496:                if (nb < 0)
        !           497:                        fmsg("%s: directory read error", fname);
        !           498:                free(iobuf);
        !           499:                *ep = '\0';
        !           500:                close(fd);
        !           501:                depth--;
        !           502:        }
        !           503: }
        !           504: 
        !           505: /*
        !           506:  * Fork to do a find on recursive directory
        !           507:  * structure that is too deep to fit into
        !           508:  * user's open files.
        !           509:  */
        !           510: ffork(ep, sbp)
        !           511: char *ep;
        !           512: struct stat *sbp;
        !           513: {
        !           514:        register int i;
        !           515:        register int pid;
        !           516:        int status;
        !           517: 
        !           518:        fflush(stdout);
        !           519:        if ((pid = fork()) < 0) {
        !           520:                fmsg(toodeep);
        !           521:                return;
        !           522:        }
        !           523:        if (pid) {
        !           524:                while (wait(&status) >= 0)
        !           525:                        ;
        !           526:                if (status)
        !           527:                        fmsg("panic: child failed: %o", status);
        !           528:                return;
        !           529:        }
        !           530:        for (i=3; i<_NFILE; i++)
        !           531:                close(i);
        !           532:        fentry(ep, (struct stat *)NULL);
        !           533:        fflush(stdout);
        !           534:        exit(0);
        !           535: }
        !           536: 
        !           537: /*
        !           538:  * Build up the next entry
        !           539:  * in the name.
        !           540:  */
        !           541: char *
        !           542: buildname(dp, ep)
        !           543: struct direct *dp;
        !           544: register char *ep;
        !           545: {
        !           546:        register char *cp = dp->d_name;
        !           547:        register unsigned n = DIRSIZ;
        !           548: 
        !           549:        if (ep+DIRSIZ+2 >= &fname[NFNAME]) {
        !           550:                fmsg(toodeep);
        !           551:                return (NULL);
        !           552:        }
        !           553:        if (ep>fname && ep[-1]!='/')
        !           554:                *ep++ = '/';
        !           555:        do {
        !           556:                if (*cp == '\0')
        !           557:                        break;
        !           558:                *ep++ = *cp++;
        !           559:        } while (--n);
        !           560:        *ep = '\0';
        !           561:        return (ep);
        !           562: }
        !           563: 
        !           564: /*
        !           565:  * Execute compiled code.
        !           566:  */
        !           567: execute(np)
        !           568: register NODE *np;
        !           569: {
        !           570:        switch (np->n_op) {
        !           571:        case AND:
        !           572:                if (execute(np->n_left) && execute(np->n_right))
        !           573:                        return (1);
        !           574:                return (0);
        !           575: 
        !           576:        case OR:
        !           577:                if (execute(np->n_left) || execute(np->n_right))
        !           578:                        return (1);
        !           579:                return (0);
        !           580: 
        !           581:        case '!':
        !           582:                return (!execute(np->n_left));
        !           583: 
        !           584:        case FUN:
        !           585:                return ((*np->n_fun)(np));
        !           586: 
        !           587:        default:
        !           588:                ferr("Panic: bad expression tree (op %d)", np->n_op);
        !           589:        }
        !           590:        /* NOTREACHED */
        !           591: }
        !           592: 
        !           593: /*
        !           594:  * Check for a match on the filename
        !           595:  */
        !           596: xname(np)
        !           597: NODE *np;
        !           598: {
        !           599:        register char *ep;
        !           600: 
        !           601:        ep = fname;
        !           602:        while (*ep != '\0')
        !           603:                ep++;
        !           604:        while (ep>fname && *--ep!='/')
        !           605:                ;
        !           606:        if (*ep == '/')
        !           607:                ep++;
        !           608:        return (pnmatch(ep, np->n_un.n_str, 0));
        !           609: }
        !           610: 
        !           611: /*
        !           612:  * Compare the mode for a match again
        !           613:  * octal number `np->n_un.n_val'.
        !           614:  */
        !           615: xperm(np)
        !           616: NODE *np;
        !           617: {
        !           618:        register int onum;
        !           619:        register int mode;
        !           620: 
        !           621:        mode = np->n_type<0 ? sb.st_mode&017777 : sb.st_mode&0777;
        !           622:        onum = np->n_un.n_val;
        !           623:        if (np->n_type < 0)
        !           624:                return ((mode&onum) == onum);
        !           625:        return (mode == onum);
        !           626: }
        !           627: 
        !           628: /*
        !           629:  * Compare again filetypes
        !           630:  */
        !           631: xtype(np)
        !           632: NODE *np;
        !           633: {
        !           634:        register char *type;
        !           635:        register int ftype;
        !           636: 
        !           637:        type = np->n_un.n_str;
        !           638:        ftype = sb.st_mode&S_IFMT;
        !           639:        if (type[1] == '\0')
        !           640:                switch (type[0]) {
        !           641:                case 'b':
        !           642:                        return (ftype == S_IFBLK);
        !           643:        
        !           644:                case 'c':
        !           645:                        return (ftype == S_IFCHR);
        !           646:        
        !           647:                case 'd':
        !           648:                        return (ftype == S_IFDIR);
        !           649:        
        !           650:                case 'f':
        !           651:                        return (ftype == S_IFREG);
        !           652:        
        !           653:                case 'm':
        !           654:                        return (ftype==S_IFMPB || ftype==S_IFMPC);
        !           655: 
        !           656:                case 'p':
        !           657:                        return (ftype == S_IFPIP);
        !           658:                }
        !           659:        ferr("Bad file type  `%s'", type);
        !           660: }
        !           661: 
        !           662: /*
        !           663:  * Compare link counts.
        !           664:  */
        !           665: xlinks(np)
        !           666: NODE *np;
        !           667: {
        !           668:        return (ncomp(np, sb.st_nlink));
        !           669: }
        !           670: 
        !           671: /*
        !           672:  * Compare uid.
        !           673:  */
        !           674: xuser(np)
        !           675: NODE *np;
        !           676: {
        !           677:        return (np->n_un.n_val == sb.st_uid);
        !           678: }
        !           679: 
        !           680: /*
        !           681:  * Compare group id of file
        !           682:  * with given one.
        !           683:  */
        !           684: xgroup(np)
        !           685: NODE *np;
        !           686: {
        !           687:        return (np->n_un.n_val == sb.st_gid);
        !           688: }
        !           689: 
        !           690: /*
        !           691:  * Compare size of file in blocks
        !           692:  * with given.
        !           693:  */
        !           694: xsize(np)
        !           695: NODE *np;
        !           696: {
        !           697:        register int fsize;
        !           698: 
        !           699:        fsize = (sb.st_size+BUFSIZ-1)/BUFSIZ;
        !           700:        return (ncomp(np, fsize));
        !           701: }
        !           702: 
        !           703: /*
        !           704:  * Compare the i-number of the file
        !           705:  * with that given.
        !           706:  */
        !           707: xinum(np)
        !           708: NODE *np;
        !           709: {
        !           710:        return (ncomp(np, sb.st_ino));
        !           711: }
        !           712: 
        !           713: /*
        !           714:  * Return true if file has been accessed
        !           715:  * in `n' days.
        !           716:  */
        !           717: xatime(np)
        !           718: NODE *np;
        !           719: {
        !           720:        return (ndays(np, sb.st_atime));
        !           721: }
        !           722: 
        !           723: /*
        !           724:  * Return non-zero if file has been created
        !           725:  * in `n' days.
        !           726:  */
        !           727: xctime(np)
        !           728: NODE *np;
        !           729: {
        !           730:        return (ndays(np, sb.st_ctime));
        !           731: }
        !           732: 
        !           733: /*
        !           734:  * Return true if file has been modified
        !           735:  * in `n' days.
        !           736:  */
        !           737: xmtime(np)
        !           738: NODE *np;
        !           739: {
        !           740:        return (ndays(np, sb.st_mtime));
        !           741: }
        !           742: 
        !           743: /*
        !           744:  * Execute a command based on the filename
        !           745:  */
        !           746: xexec(np)
        !           747: NODE *np;
        !           748: {
        !           749:        static char command[200];
        !           750:        register char *ap, **app;
        !           751:        register int c;
        !           752:        int ok;
        !           753: 
        !           754:        command[0] = '\0';
        !           755:        app = np->n_un.n_strp;
        !           756:        while (*app != NULL) {
        !           757:                if ((ap = *app++) == FILEARG)
        !           758:                        ap = fname;
        !           759:                strcat(command, ap);
        !           760:                if (*app != NULL)
        !           761:                        strcat(command, " ");
        !           762:        }
        !           763:        if (np->n_type) {
        !           764:                printf("%s%s? ", prompt, command);
        !           765:                ok = (c = getchar()) == 'y';
        !           766:                while (c!='\n' && c!=EOF)
        !           767:                        c = getchar();
        !           768:                if (!ok)
        !           769:                        return (0);
        !           770:        }
        !           771:        return (!system(command));
        !           772: }
        !           773: 
        !           774: /*
        !           775:  * Print the filename.
        !           776:  */
        !           777: /* ARGSUSED */
        !           778: xprint(np)
        !           779: NODE *np;
        !           780: {
        !           781:        printf("%s\n", fname);
        !           782:        return (1);
        !           783: }
        !           784: 
        !           785: xnop(np)
        !           786: NODE *np;
        !           787: {
        !           788:        return (1);
        !           789: }
        !           790: 
        !           791: /*
        !           792:  * Return true if the file is newer than
        !           793:  * the given one.
        !           794:  */
        !           795: xnewer(np)
        !           796: register NODE *np;
        !           797: {
        !           798:        return (sb.st_mtime > np->n_un.n_time);
        !           799: }
        !           800: 
        !           801: /*
        !           802:  * Do a numerical comparison on dates.
        !           803:  */
        !           804: ndays(np, t)
        !           805: register NODE *np;
        !           806: time_t t;
        !           807: {
        !           808:        register int days;
        !           809: 
        !           810:        days = (curtime-t+DAYSEC/2)/DAYSEC;
        !           811:        return (ncomp(np, days));
        !           812: }
        !           813: 
        !           814: /*
        !           815:  * Numerical compare.
        !           816:  */
        !           817: ncomp(np, val)
        !           818: register NODE *np;
        !           819: register unsigned val;
        !           820: {
        !           821:        if (np->n_type == 0)
        !           822:                return (np->n_un.n_val == val);
        !           823:        if (np->n_type > 0)
        !           824:                return (val > np->n_un.n_val);
        !           825:        return (val < np->n_un.n_val);
        !           826: }
        !           827: 
        !           828: /*
        !           829:  * Errors
        !           830:  */
        !           831: /* VARARGS */
        !           832: ferr(x)
        !           833: {
        !           834:        fprintf(stderr, "find: %r\n", &x);
        !           835:        exit (1);
        !           836: }
        !           837: 
        !           838: /* VARARGS */
        !           839: fmsg(x)
        !           840: {
        !           841:        fprintf(stderr, "find: %r\n", &x);
        !           842: }
        !           843: 
        !           844: usage()
        !           845: {
        !           846:        fprintf(stderr, "Usage: find directory ... [ expression ]\n");
        !           847: }

unix.superglobalmegacorp.com

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