⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 find.c

📁 Version 6 Unix 核心源代码 Version 6 Unix 核心源代码
💻 C
字号:
/* 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;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<argc) {		printf("Missing conjunction\n");		exit(9);	}	descend(pathname,'f',find,exlist); /* to find files that match  */}/* compile time functions:  priority is  exp()<e1()<e2()<e3()  */struct anode *exp() { /* parse -o ... */	int or();	int p1;	char *na;	p1 = e1() /* get left operand */ ;	if(compstr(na=nxtarg(),"-o")==0) {		randlast--;		return(mk(&or,p1,exp()));	}	else if(*na!=0) --ap;	return(p1);}struct anode *e1() { /* parse -a */	int and();	int p1;	char *na;	p1 = e2();	if(compstr(na=nxtarg(),"-a")==0) {		randlast--;		return(mk(&and,p1,e1()));	}	else if(*na!=0) --ap;	return(p1);}struct anode *e2() { /* parse not (!) */	int not();	char *na;	if(randlast) {		printf("operand follows operand.\n");		exit(9);	}	randlast++;	if(compstr(na=nxtarg(),"!")==0)		return(mk(&not,e3(),0));	else if(*na!=0) --ap;	return(e3());}struct anode *e3() { /* parse parens and predicates */	int exeq(), ok(), glob(),  mtime(), atime(), user(),		group(), size(), perm(), links(), print(),		type();	int p1, i;	char *a, *b, s;	a = nxtarg();	if(compstr(a,"(")==0) {		randlast--;		p1 = exp();		a = nxtarg();		if(compstr(a,")")!=0) goto err;		return(p1);	}	else if(compstr(a,"-print")==0) {		return(mk(&print,0,0));	}	b = nxtarg();	s = *b;	if(s=='+') b++;	if(compstr(a,"-name")==0)		return(mk(&glob,b,0));	else if(compstr(a,"-mtime")==0)		return(mk(&mtime,atoi(b),s));	else if(compstr(a,"-atime")==0)		return(mk(&atime,atoi(b),s));	else if(compstr(a,"-user")==0) {		if((i=getunum(b)) == -1) {			printf("Cannot find user \"%s\"\n",b);			exit(9);		}		return(mk(&user,i,s));	}	else if(compstr(a,"-group")==0)		return(mk(&group,atoi(b),s));	else if(compstr(a,"-size")==0)		return(mk(&size,atoi(b),s));	else if(compstr(a,"-links")==0)		return(mk(&links,atoi(b),s));	else if(compstr(a,"-perm")==0) {		for(i=0; *b ; ++b) {			if(*b=='-') continue;			i =<< 3;			i = i + (*b - '0');		}		return(mk(&perm,i,s));	}	else if(compstr(a,"-type")==0) {		i = s=='d' ? 040000 :		    s=='b' ? 060000 :		    s=='c' ? 020000 :		    000000;		return(mk(&type,i,0));	}	else if (compstr(a,"-exec")==0) {		i = ap - 1;		while(compstr(nxtarg(),";")!=0);		return(mk(&exeq,i,0));	}	else if (compstr(a,"-ok")==0) {		i = ap - 1;		while(compstr(nxtarg(),";")!=0);		return(mk(&ok,i,0));	}	err: printf("Bad option: \"%s\" \"%s\"\n",a,b);	exit(9);}struct anode *mk(f,l,r) struct anode *l,*r; { /*make an expression node*/	node[nn].F = f;	node[nn].L = l;	node[nn].R = r;	return(&(node[nn++]));}nxtarg() { /* get next arg from command line */	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[0]-statb.imtime[0])*3/4,p->t,p->s));}atime(p) struct { int f, t, s; } *p;  {	return(scomp((now[0]-statb.iatime[0])*3/4,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 << 7;	i = i | ((statb.isize>>9) & 0177);	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);}char fin[518];getunum(s) char *s; { /* find username in /etc/passwd & return num. */int i;char str[20], *sp, c;	i = -1;	fin[0] = 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] = 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)int (*func)();char *name, goal;{	int dir /* open directory */, offset /* in directory */;	int dsize, top;	struct {		int	dinode;		char	dname[14];	} dentry[32];	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);	top = statb.isize;	for(offset=0 ; offset < top ; offset =+ 512) { /* each block */		dsize = 512<(top-offset) ? 512 : (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)==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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -