📄 find.c
字号:
#ifndef lintstatic char *sccsid = "@(#)find.c 4.2 (ULTRIX) 4/11/91";#endif lint/************************************************************************ * * * Copyright (c) Digital Equipment Corporation, 1985, 1987, 1988, * * 1989-1990, 1991 * * * * All Rights Reserved. Unpublished rights reserved under the * * copyright laws of the United States. * * * * The software contained on this media is proprietary to and * * embodies the confidential technology of Digital Equipment * * Corporation. Possession, use, duplication or dissemination of * * the software and media is authorized only pursuant to a valid * * written license from Digital Equipment Corporation. * * * * RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by * * the U.S. Government is subject to restrictions as set forth in * * Subparagraph (c)(1)(ii) of DFARS 252.227-7013, or in FAR * * 52.227-19, as applicable. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * ************************************************************************//**//* static char *sccsid = "@(#)find.c 4.7 (Berkeley) 8/2/82"; *//* find COMPILE: cc -o find -s -O find.c *//* * Modification History * * 004 - 01 Apr 91 - AGK and GWS * changed cpio header structures used for -cpio to be same as V4.2 * cpio(1), to handle inodes > 64k * changed (pwd < 0) compare to (pwd < (FILE *) 0) to avoid MIPS C * compiler warnings * * 003 - Gary A. Gaudet, Wed May 24 16:57:19 EDT 1989 * POSIX 1003.2 compliance: added -ctime and -depth * * 002 - 15 Nov 85 - T.N. Cherng * The original pathname[] is allocated for 200 characters * instead of MAXPATHLEN+1. A core dump occurs if a file path * is over 200 characters. * * 001 - 15 Mar 85 -- funding * Added named pipe support (re. System V named pipes) */#include <stdio.h>#include <sys/param.h>#include <sys/dir.h>#include <sys/stat.h>#include <pwd.h>#include <grp.h>#include <sys/wait.h>#include <signal.h>#define A_DAY 86400L /* a day full of seconds */#define EQ(x, y) (strcmp(x, y)==0)int Randlast;char Pathname[MAXPATHLEN +1];struct anode { int (*F)(); struct anode *L, *R;} Node[100];int Nn; /* number of nodes */char *Fname;long Now;int Argc, Ai, Pi;char **Argv;/* cpio stuff */int Cpio;short *Buf, *Dbuf, *Wp;int Bufsize = 5120;int Wct = 2560;/* mount stuff */int do_mount = 1; /* go down mount points if true */int mount_dev = -1;/* file must reside here or we've crossed a mount point*/long Newer;struct stat Statb;/* * 003 GAG * preorder list is default; postorder when -depth is used */int Postorder = 0;struct anode *exp(), *e1(), *e2(), *e3(), *mk();char Home[MAXPATHLEN + 1];char *rindex(), *sbrk(), *strcpy(), *nxtarg();long Blocks, time();void exit(), perror();FILE *popen();int or(), and(), not();int exeq(), ok(), glob(), mtime(), atime(), ctime(), depth(), /* 003 GAG */ user(), group(), size(), perm(), links(), print(), type(), ino(), cpio(), newer(), ckmount();main(argc, argv)char *argv[];{ register struct anode *exlist; register char *cp, *sp = 0; register int paths; register FILE *pwd; (void) time(&Now); pwd = popen("/bin/pwd", "r"); if (pwd < (FILE *) 0) { /* 004 */ perror("/bin/pwd"); exit(1); } if (fgets(Home, sizeof Home, pwd) == NULL) { perror("fgets"); exit(1); } (void) pclose(pwd); Home[strlen(Home) - 1] = '\0'; Argc = argc; Argv = argv; if(argc<3) {usage: (void) 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 */ (void) fprintf(stderr, "find: parsing error\n"); exit(1); } if(Ai<argc) { (void) fprintf(stderr, "find: missing conjunction\n"); exit(1); } for(Pi = 1; Pi < paths; ++Pi) { mount_dev = -1; sp = 0; if (chdir(Home) == -1) { perror("chdir"); exit(1); } (void) strcpy(Pathname, Argv[Pi]); if(cp = rindex(Pathname, '/')) { sp = cp + 1; *cp = '\0'; if(chdir(*Pathname ? Pathname : "/") == -1) { (void) fprintf(stderr, "find: bad starting directory\n"); exit(2); } *cp = '/'; } Fname = sp ? sp : Pathname; (void) descend(Pathname, Fname, exlist); /* to find files that match */ } if(Cpio) { (void) strcpy(Pathname, "TRAILER!!!"); Statb.st_size = 0; cpio(); (void) printf("%D blocks\n", Blocks*10); } if (chdir(Home) == -1) { (void) fprintf(stderr,"Can't cd to %s\n",Home); exit(1); } exit(0);}/* compile time functions: priority is exp()<e1()<e2()<e3() */struct anode *exp(){ /* parse ALTERNATION (-o) */ 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) */ 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 (!) */ register struct anode *ptr; if(Randlast) { (void) fprintf(stderr, "find: operand follows operand\n"); exit(1); } Randlast++; if(EQ(nxtarg(), "!")) { ptr = e3(); if (ptr == NULL) { (void) fprintf(stderr,"find: bad (!) operand\n"); exit(1); } return(mk(not, ptr, (struct anode *)0)); } else if(Ai <= Argc) --Ai; ptr = e3(); if (ptr == NULL) { (void) fprintf(stderr,"find: bad (!) operand\n"); exit(1); } return(ptr);}struct anode *e3(){ /* parse parens and predicates */ register struct anode *p1; register struct passwd *pwd; register struct group *grp; register char *a; register char *b; register int i; char 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, "-mount")) { do_mount = 0; return(mk(ckmount, (struct anode *)0, (struct anode *)0)); } else if(EQ(a, "-depth")) { /* 003 GAG */ Postorder = 1; return(mk(depth, (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, "-ctime")) /* 003 GAG */ return(mk(ctime, (struct anode *)atoi(b), (struct anode *)s)); else if(EQ(a, "-user")) { if((pwd=getpwnam(b)) == NULL) { if(gmatch(b, "[0-9]*")) return mk(user, (struct anode *)atoi(b), (struct anode *)s); (void) fprintf(stderr,"find: cannot find -user name\n"); exit(1); } return(mk(user, (struct anode *)pwd->pw_uid,(struct anode *)s)); } else if(EQ(a, "-inum")) return(mk(ino, (struct anode *)atoi(b), (struct anode *)s)); else if(EQ(a, "-group")) { if((grp=getgrnam(b)) == NULL) { if(gmatch(b, "[0-9]*")) return(mk(group,(struct anode *)atoi(b), (struct anode *)s)); (void) fprintf(stderr, "find: cannot find -group name\n"); exit(1); } return(mk(group,(struct anode *)grp->gr_gid,(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 += (*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 : s=='p' ? S_IFPORT : /* 1 */ 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) { (void) 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) { (void) fprintf(stderr, "find: cannot access < %s >\n", b); exit(1); } Newer = Statb.st_mtime; return(mk(newer, (struct anode *)0, (struct anode *)0)); }err: (void) fprintf(stderr, "find: bad option < %s >\n", a); return(NULL);}struct anode *mk(f, l, r)int (*f)();struct anode *l, *r;{ Node[Nn].F = f; Node[Nn].L = l; Node[Nn].R = r; return(&(Node[Nn++]));}char *nxtarg(){ /* get next arg from command line */ static strikes = 0; if(strikes==3) { (void) fprintf(stderr, "find: incomplete statement\n"); exit(1); } if(Ai>=Argc) { strikes++; Ai = Argc + 1; return(""); } return(Argv[Ai++]);}/* execution time functions */and(p)register struct anode *p;{ return(((*p->L->F)(p->L)) && ((*p->R->F)(p->R)) ? 1 : 0);}or(p)register struct anode *p;{ return(((*p->L->F)(p->L)) || ((*p->R->F)(p->R)) ? 1 : 0);}not(p)register struct anode *p;{ return( !((*p->L->F)(p->L)));}glob(p)register struct { int f; char *pat; } *p; { return(gmatch(Fname, p->pat));}print(){ (void) puts(Pathname); return(1);}ckmount(){ if (mount_dev == -1) mount_dev = Statb.st_dev; /* first time through */ if (mount_dev == Statb.st_dev) return(1); return(0);}mtime(p)register struct { int f, t, s; } *p; { return(scomp((int)((Now - Statb.st_mtime) / A_DAY), p->t, p->s));}atime(p)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -