|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.