# /* find -- find files in a pathname. Use of find is documented in /usr/man/man1/find.1 . In addition, find has a secret first arg "+" which causes each file name to be printed along with a period if the predicates succeed. */ int randlast; char *pathname; int verbose; struct anode { int (*F)(); struct anode *L, *R; } node[100]; int nn; /* number of nodes */ char *fname, *path; int now[2]; int ap, ac; char **av; struct ibuf { int idev; int inum; int iflags; char inl; char iuid; char igid; char isize0; char *isize; int iaddr[8]; int iatime[2]; int imtime[2]; } statb; /*** *** Buffers for directory blocks. *** *** Originally dentry[] was an array local to the descend() function. *** Since Interdata unix has no automatic stack growth, the buffers *** were moved out of the function and allocated explicitly. ***/ struct dentry { short dinode; /***/ char dname[14]; }; #define NDENTRY 32 /* no. of entries per block */ #define SDBUF (NDENTRY*sizeof(struct dentry)) struct dentry *dbuf = &end; /* first block allocated */ struct dentry *maxdentry = &end; /* end of last block allocated */ struct anode *exp(), *e1(), *e2(), *e3(), *mk(); main(argc,argv) char *argv[]; { struct anode *exlist; int find(); time(&now); ac = argc; av = argv; ap = 2; pathname = argv[1]; if(compstr(argv[1],"+")==0) { verbose++; ap++; pathname = argv[2]; } else verbose = 0; argv[argc] = 0; if(argc<3) { printf("Insufficient args\n"); exit(9); } if(!(exlist = exp())) { /* parse and compile the arguments */ printf("Odd usage\n"); exit(9); } if(ap=ac) return(""); return(av[ap++]); } find(exlist,fullname) /* execute predicat list with current file */ struct anode *exlist; char *fullname; { register int i; path = fullname; if(verbose) printf("%s",path); for(i=0;fullname[i];++i) if(fullname[i]=='/') fname = &fullname[i+1]; i = (*exlist->F)(exlist); if(verbose) if(i) printf(".\n"); else printf("\n"); } /* execution time functions */ and(p) struct anode *p; { return(((*p->L->F)(p->L)) && ((*p->R->F)(p->R))?1:0); } or(p) struct anode *p; { return(((*p->L->F)(p->L)) || ((*p->R->F)(p->R))?1:0); } not(p) struct anode *p; { return( !((*p->L->F)(p->L))); } glob(p) struct { int f; char *pat; } *p; { return(gmatch(fname,p->pat)); } print() { printf("%s\n",path); return(1); } mtime(p) struct { int f, t, s; } *p; { return(scomp((now[1]-statb.imtime[1])/86400,p->t,p->s)); /***/ } atime(p) struct { int f, t, s; } *p; { return(scomp((now[1]-statb.iatime[1])/86400,p->t,p->s)); /***/ } user(p) struct { int f, u, s; } *p; { return(scomp(statb.iuid,p->u,p->s)); } group(p) struct { int f, u; } *p; { return(p->u == statb.igid); } links(p) struct { int f, link, s; } *p; { return(scomp(statb.inl,p->link,p->s)); } size(p) struct { int f, sz, s; } *p; { register int i; i = statb.isize0 << 23; /***/ i = i | (statb.isize>>9); /***/ return(scomp(i,p->sz,p->s)); } perm(p) struct { int f, per, s; } *p; { int i; i = (p->s=='-') ? p->per : 03777; /* '-' means only arg bits */ return((statb.iflags & i & 017777) == p->per); } type(p)struct { int f, per, s; } *p; { return((statb.iflags&060000)==p->per); } exeq(p) struct { int f, com; } *p; { return(doex(p->com)); } ok(p) struct { int f, com; } *p; { char c; int yes; yes = 0; printf("%s ... %s ...? ",av[p->com],path); if((c=getchar())=='y') yes = 1; while(c!='\n') c = getchar(); if(yes) return(doex(p->com)); return(0); } /* support functions */ scomp(a,b,s) char s; { /* funny signed compare */ if(s == '+') return(a > b); if(s == '-') return(a < (b * -1)); return(a == b); } doex(com) { int ccode; int np, i, c; char *nargv[50], *ncom, *na; ccode = np = 0; while (na=av[com++]) { if(compstr(na,";")==0) break; if(compstr(na,"{}")==0) nargv[np++] = path; else nargv[np++] = na; } nargv[np] = 0; if (np==0) return(9); if(fork()) /*parent*/ wait(&ccode); else { /*child*/ execv(nargv[0], nargv, np); i = 0; ncom = "/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; while(c=nargv[0][i]) { ncom[9+i++] = c; } ncom[9+i] = '\0'; execv(ncom+4, nargv, np); execv(ncom, nargv, np); exit(9); } return(ccode ? 0:1); } extern fin; /***/ getunum(s) char *s; { /* find username in /etc/passwd &return num. */ int i; char str[20], *sp, c; i = -1; fin = open("/etc/passwd",0); while(c = getchar()) { if(c=='\n') { sp = str; while((*sp = getchar()) != ':') if(! *sp++) goto RET; *sp = '\0'; if(compstr(str,s)==0) { while((c=getchar()) != ':') if(! c) goto RET; sp = str; while((*sp = getchar()) != ':') sp++; *sp = '\0'; i = atoi(str); break; } } } RET: close(fin); fin = 0; return(i); } compstr(s1,s2) char s1[], s2[]; { /* compare strings: */ register char *c1, *c2; c1 = s1; c2 = s2; while(*c1 == *c2) if(*c1++ == '\0') return(0); /* s1 == s2 */ else c2++; return(*c1 > *c2 ? 1 : -1); } int descend(name,goal,func,arg, dentry) int (*func)(); char *name, goal; register struct dentry *dentry; { int dir /* open directory*/, offset /* in directory */; int dsize, top; register int i, j, k; char aname[128]; if(stat(name,&statb)<0) { printf("--bad status %s\n",name); return(0); } /* if((statb.iflags&060000)!=040000){ /*not a directory*/ /* if(goal=='f'||goal=='b') /* search goal for files */ /* (*func)(arg,name); return(1); }else if(goal=='d' || goal=='b') /* search goal is directories */ /* (*func)(arg,name); */ (*func)(arg,name); if((statb.iflags&060000)!=040000) return(1); /*** *** Allocate directory buffer space ***/ if (dentry >= maxdentry) { if (brk(maxdentry+NDENTRY) < 0) { printf("-- out of core\n"); return(0); } maxdentry += NDENTRY; } top = statb.isize; for(offset=0 ; offset < top ; offset =+ SDBUF) { /* each block */ dsize= SDBUF<(top-offset) ? SDBUF : (top-offset); if((dir=open(name,0))<0) { printf("--cannot open %s\n",name); return(0); } if(offset) seek(dir,offset,0); if(read(dir,dentry,dsize)<0) { printf("--cannot read %s\n",name); return(0); } close(dir); for(i = 0; i < (dsize>>4); ++i) { /* each dir. entry */ if (dentry[i].dinode == 0 || compstr(dentry[i].dname,".")==0 || compstr(dentry[i].dname,"..")==0) continue; if (dentry[i].dinode == -1) break; for(j=0;aname[j]=name[j];++j); if(aname[j-1]!='/') aname[j++] = '/'; for(k=0; (aname[j++]=dentry[i].dname[k]) && k<13; ++k); aname[j] = '\0'; if(descend(aname,goal,func,arg, dentry+NDENTRY)==0) printf("--%s\n",name); } } return(1); } gmatch(s, p) /* string match as in glob */ char *s, *p; { if (*s=='.' && *p!='.') return(0); return(amatch(s, p)); } amatch(s, p) char *s, *p; { register int cc, scc,k; int c, lc; scc = *s; lc = 077777; switch (c = *p) { case '[': k = 0; while (cc = *++p) { switch (cc) { case ']': if (k) return(amatch(++s, ++p)); else return(0); case '-': k =| lc <= scc & scc <= (cc=p[1]); } if (scc==(lc=cc)) k++; } return(0); case '?': caseq: if(scc) return(amatch(++s, ++p)); return(0); case '*': return(umatch(s, ++p)); case 0: return(!scc); } if (c==scc) goto caseq; return(0); } umatch(s, p) char *s, *p; { if(*p==0) return(1); while(*s) if (amatch(s++,p)) return(1); return(0); }