-#define AMES 1
-
-main(argc, argv)
- int argc;
- char *argv[];
-{
- struct anode *exlist;
- int paths;
- register char *cp, *sp = 0;
-#ifdef SUID_PWD
- FILE *pwd, *popen();
-#endif
-
-#ifdef AMES
- if (argc < 2) {
- fprintf(stderr,
- "Usage: find name, or find path-list predicate-list\n");
- exit(1);
- }
- if (argc == 2) {
- fastfind(argv[1]);
- exit(0);
- }
-#endif
- time(&Now);
- setpassent(1);
- setgroupent(1);
-#ifdef SUID_PWD
- pwd = popen("pwd", "r");
- fgets(Home, sizeof Home, pwd);
- pclose(pwd);
- Home[strlen(Home) - 1] = '\0';
-#else
- if (getwd(Home) == NULL) {
- fprintf(stderr, "find: Can't get current working directory\n");
- exit(1);
- }
-#endif
- Argc = argc; Argv = argv;
- if(argc<3) {
-usage: fprintf(stderr, "Usage: find path-list predicate-list\n");
- exit(1);
- }
- for(Ai = paths = 1; Ai < (argc-1); ++Ai, ++paths)
- if(*Argv[Ai] == '-' || EQ(Argv[Ai], "(") || EQ(Argv[Ai], "!"))
- break;
- if(paths == 1) /* no path-list */
- goto usage;
- if(!(exlist = exp())) { /* parse and compile the arguments */
- fprintf(stderr, "find: parsing error\n");
- exit(1);
- }
- if(Ai<argc) {
- fprintf(stderr, "find: missing conjunction\n");
- exit(1);
- }
- for(Pi = 1; Pi < paths; ++Pi) {
- sp = 0;
- chdir(Home);
- strcpy(Pathname, Argv[Pi]);
- if(cp = rindex(Pathname, '/')) {
- sp = cp + 1;
- *cp = '\0';
- if(chdir(*Pathname? Pathname: "/") == -1) {
- fprintf(stderr, "find: bad starting directory\n");
- exit(2);
- }
- *cp = '/';
- }
- Fname = sp? sp: Pathname;
- if (!Xdev)
- stat(Pathname, &Devstat);
- descend(Pathname, Fname, exlist); /* to find files that match */
- }
- if(Cpio) {
- strcpy(Pathname, "TRAILER!!!");
- Statb.st_size = 0;
- cpio();
- printf("%D blocks\n", Blocks*10);
- }
- exit(0);
-}
-
-/* compile time functions: priority is exp()<e1()<e2()<e3() */
-
-struct anode *exp() { /* parse ALTERNATION (-o) */
- int or();
- register struct anode * p1;
-
- p1 = e1() /* get left operand */ ;
- if(EQ(nxtarg(), "-o")) {
- Randlast--;
- return(mk(or, p1, exp()));
- }
- else if(Ai <= Argc) --Ai;
- return(p1);
-}
-struct anode *e1() { /* parse CONCATENATION (formerly -a) */
- int and();
- register struct anode * p1;
- register char *a;
-
- p1 = e2();
- a = nxtarg();
- if(EQ(a, "-a")) {
-And:
- Randlast--;
- return(mk(and, p1, e1()));
- } else if(EQ(a, "(") || EQ(a, "!") || (*a=='-' && !EQ(a, "-o"))) {
- --Ai;
- goto And;
- } else if(Ai <= Argc) --Ai;
- return(p1);
-}
-struct anode *e2() { /* parse NOT (!) */
- int not();
-
- if(Randlast) {
- fprintf(stderr, "find: operand follows operand\n");
- exit(1);
- }
- Randlast++;
- if(EQ(nxtarg(), "!"))
- return(mk(not, e3(), (struct anode *)0));
- else if(Ai <= Argc) --Ai;
- return(e3());
-}
-struct anode *e3() { /* parse parens and predicates */
- int exeq(), ok(), glob(), mtime(), atime(), user(),
- group(), size(), perm(), links(), print(),
- type(), ino(), cpio(), newer(),
- nouser(), nogroup(), ls(), dummy();
- struct anode *p1;
- int i;
- register char *a, *b;
- register int s;
-
- a = nxtarg();
- if(EQ(a, "(")) {
- Randlast--;
- p1 = exp();
- a = nxtarg();
- if(!EQ(a, ")")) goto err;
- return(p1);
- }
- else if(EQ(a, "-print")) {
- return(mk(print, (struct anode *)0, (struct anode *)0));
- }
- else if (EQ(a, "-nouser")) {
- return (mk(nouser, (struct anode *)0, (struct anode *)0));
- }
- else if (EQ(a, "-nogroup")) {
- return (mk(nogroup, (struct anode *)0, (struct anode *)0));
- }
- else if (EQ(a, "-ls")) {
- return (mk(ls, (struct anode *)0, (struct anode *)0));
- }
- else if (EQ(a, "-xdev")) {
- Xdev = 0;
- return (mk(dummy, (struct anode *)0, (struct anode *)0));
- }
- else if (EQ(a, "-follow")) {
- follow=1;
- return mk(dummy, (struct anode *)0, (struct anode *)0);
- }
- b = nxtarg();
- s = *b;
- if(s=='+') b++;
- if(EQ(a, "-name"))
- return(mk(glob, (struct anode *)b, (struct anode *)0));
- else if(EQ(a, "-mtime"))
- return(mk(mtime, (struct anode *)atoi(b), (struct anode *)s));
- else if(EQ(a, "-atime"))
- return(mk(atime, (struct anode *)atoi(b), (struct anode *)s));
- else if(EQ(a, "-user")) {
- if((i=getuid(b)) == -1) {
- if(gmatch(b, "[0-9]*"))
- return mk(user, (struct anode *)atoi(b), (struct anode *)s);
- fprintf(stderr, "find: cannot find -user name\n");
- exit(1);
- }
- return(mk(user, (struct anode *)i, (struct anode *)s));
- }
- else if(EQ(a, "-inum"))
- return(mk(ino, (struct anode *)atoi(b), (struct anode *)s));
- else if(EQ(a, "-group")) {
- if((i=getgid(b)) == -1) {
- if(gmatch(b, "[0-9]*"))
- return mk(group, (struct anode *)atoi(b), (struct anode *)s);
- fprintf(stderr, "find: cannot find -group name\n");
- exit(1);
- }
- return(mk(group, (struct anode *)i, (struct anode *)s));
- } else if(EQ(a, "-size"))
- return(mk(size, (struct anode *)atoi(b), (struct anode *)s));
- else if(EQ(a, "-links"))
- return(mk(links, (struct anode *)atoi(b), (struct anode *)s));
- else if(EQ(a, "-perm")) {
- for(i=0; *b ; ++b) {
- if(*b=='-') continue;
- i <<= 3;
- i = i + (*b - '0');
- }
- return(mk(perm, (struct anode *)i, (struct anode *)s));
- }
- else if(EQ(a, "-type")) {
- i = s=='d' ? S_IFDIR :
- s=='b' ? S_IFBLK :
- s=='c' ? S_IFCHR :
- s=='f' ? S_IFREG :
- s=='l' ? S_IFLNK :
- s=='s' ? S_IFSOCK :
- 0;
- return(mk(type, (struct anode *)i, (struct anode *)0));
- }
- else if (EQ(a, "-exec")) {
- i = Ai - 1;
- while(!EQ(nxtarg(), ";"));
- return(mk(exeq, (struct anode *)i, (struct anode *)0));
- }
- else if (EQ(a, "-ok")) {
- i = Ai - 1;
- while(!EQ(nxtarg(), ";"));
- return(mk(ok, (struct anode *)i, (struct anode *)0));
- }
- else if(EQ(a, "-cpio")) {
- if((Cpio = creat(b, 0666)) < 0) {
- fprintf(stderr, "find: cannot create < %s >\n", s);
- exit(1);
- }
- Buf = (short *)sbrk(512);
- Wp = Dbuf = (short *)sbrk(5120);
- return(mk(cpio, (struct anode *)0, (struct anode *)0));
- }
- else if(EQ(a, "-newer")) {
- if(stat(b, &Statb) < 0) {
- fprintf(stderr, "find: cannot access < %s >\n", b);
- exit(1);
- }
- Newer = Statb.st_mtime;
- return mk(newer, (struct anode *)0, (struct anode *)0);
- }
-err: fprintf(stderr, "find: bad option < %s >\n", a);
- exit(1);
-}
-struct anode *mk(f, l, r)
-int (*f)();
-struct anode *l, *r;
-{
- if (Nn >= MAXNODES) {
- fprintf(stderr, "find: Too many options\n");
- exit(1);
- }
-
- Node[Nn].F = f;
- Node[Nn].L = l;
- Node[Nn].R = r;
- return(&(Node[Nn++]));
-}