|
|
1.1 root 1: #include "sys/param.h"
2: #include "sys/ino.h"
3: #include "sys/inode.h"
4: #include "sys/dir.h"
5: #include "sys/filsys.h"
6: #include "stdio.h"
7: #include "sys/stat.h"
8: #include <pwd.h>
9: #include <ctype.h>
10:
11: #define MONTH 3600*24L*7L*4L
12: #define DAY (3600*24L)
13: #define WEEK 3600*24L*7L
14: #define DAY3 3600*24L*3L
15: #define NUID 20000
16:
17: int uid = -2;
18: int nflag = 0;
19:
20: #define biton(x, n) x[(n)>>3] |= 1 << ((n)&7)
21: #define isdir(p) (((p)->di_mode & S_IFMT) == S_IFDIR)
22: #define isold(p) (p->di_mtime + WEEK < nowtime)
23: #define isvold(p) (p->di_mtime + MONTH < nowtime)
24: #define isuser(p) ((p->di_uid>=NUID||isbad[p->di_uid]) && (nflag==0 || p->di_mtime + DAY3 >= nowtime))
25: #define isnt(p) !(p->di_mode & S_IFMT)
26: #define istrue(x, n) x[(n)>>3] & (1<<((n)&7))
27:
28: extern int screen(), consider();
29: char dlist[8192], olist[8192], slist[8192], tlist[8192];
30: int szlist[65536];
31: int days[65536];
32: char curdir[256];
33: long nowtime;
34: char isbad[NUID];
35: struct stat origstat;
36:
37: main(argc, argv) char **argv;
38: {
39: int i;
40:
41: (void) time(&nowtime);
42: isbad[uid] = 1;
43: for (i = 1; i < argc; i++) {
44: if (strcmp(argv[i], "-n")==0) {
45: nflag++;
46: continue;
47: }
48: if (i < argc-2 && strcmp(argv[i], "-u")==0) {
49: isbad[uid] = 0;
50: uid = atoi(argv[i+1]);
51: isbad[uid] = 1;
52: i++;
53: continue;
54: }
55: if (strcmp(argv[i], "-f")==0) {
56: getbad();
57: continue;
58: }
59: break;
60: }
61: if (i>argc-2) {
62: fprintf(stderr, "findo /dev/device /place-it-is-mounted\n");
63: exit(1);
64: }
65: finit();
66: eachinode(argv[i], screen);
67: if (chdir(argv[++i])) {
68: perror(argv[i]);
69: exit(1);
70: }
71: strcpy(curdir, argv[i]);
72: stat(curdir, &origstat); /* where we started */
73: alldir(0, consider);
74: exit(0);
75: }
76:
77: finit()
78: { int i;
79: for (i = 0; i < sizeof(olist); i++)
80: olist[i] = 0;
81: for (i = 0; i < sizeof(dlist); i++)
82: dlist[i] = 0;
83: for (i = 0; i < sizeof(slist); i++)
84: slist[i] = 0;
85: for (i = 0; i<sizeof(tlist); i++)
86: tlist[i] = 0;
87: for (i = 0; i < sizeof(szlist)/sizeof(szlist[0]); i++)
88: szlist[i] = days[i] = 0;
89: }
90:
91: screen(n, p) struct dinode *p; unsigned int n;
92: {
93: if(isnt(p)) return;
94: szlist[n] = p->di_size;
95: days[n] = (nowtime - p->di_mtime) / DAY;
96: if(isdir(p)) {
97: biton(dlist, n);
98: }
99: if(isuser(p)) {
100: biton(slist, n);
101: return;
102: }
103: if(isitroff(p)) {
104: biton(tlist, n);
105: return;
106: }
107: if(isold(p)) {
108: biton(olist, n);
109: if (isvold(p))
110: biton(tlist, n);
111: return;
112: }
113: }
114:
115: newsys()
116: {
117: struct stat dot;
118:
119: stat(".", &dot);
120: return dot.st_dev != origstat.st_dev;
121: }
122:
123: consider(n, p) struct direct *p;
124: { int j;
125: char buf[DIRSIZ+1];
126: if(istrue(dlist, p->d_ino)) {
127: for(j = 0; j < DIRSIZ; j++)
128: buf[j] = p->d_name[j];
129: buf[j] = 0;
130: j = strlen(curdir);
131: if(strcmp(".", buf) == 0 || strcmp("..", buf) == 0)
132: return; /* of course this can't happen (ha) */
133: strcat(curdir, "/");
134: strcat(curdir, buf);
135: if(chdir(buf) == -1)
136: perror(curdir);
137: else {
138: if(!newsys())
139: alldir(n+1, consider);
140: if (chdir("..") < 0) {
141: fprintf(stderr, "bad '..' in %s\n", curdir);
142: curdir[j] = '\0';
143: chdir(curdir);
144: }
145: }
146: curdir[j] = 0;
147: }
148: if (istrue(slist, p->d_ino)) {
149: printf("user\t%8d %8d\t", szlist[p->d_ino], days[p->d_ino]);
150: file(p->d_name);
151: }
152: if (istrue(olist, p->d_ino)) {
153: if(badname(p->d_name, istrue(tlist, p->d_ino))) {
154: printf("old\t%8d %8d\t", szlist[p->d_ino], days[p->d_ino]);
155: file(p->d_name);
156: }
157: return;
158: }
159: if (istrue(tlist, p->d_ino)) {
160: printf("troff\t%8d %8d\t", szlist[p->d_ino], days[p->d_ino]);
161: file(p->d_name);
162: }
163: }
164:
165: badname(s, voflg)
166: register char *s;
167: {
168: register char *p;
169: register int k;
170:
171: if(strncmp("core", s, DIRSIZ) == 0)
172: return(1);
173: if(strncmp("a.out", s, DIRSIZ) == 0)
174: return(1);
175: if(strncmp("junk", s, DIRSIZ) == 0)
176: return(1);
177: if(strncmp("ed.hup", s, DIRSIZ) == 0)
178: return(1);
179: if(strncmp("jim.recover", s, DIRSIZ) == 0)
180: return(1);
181: if(strncmp("sam.save", s, DIRSIZ) == 0)
182: return(1);
183: if(strncmp("sam.err", s, DIRSIZ) == 0)
184: return(1);
185: if(strncmp("~~sam~~", s, DIRSIZ) == 0)
186: return(1);
187: if(strncmp(".pilog", s, DIRSIZ) == 0)
188: return(1);
189: if(strncmp("mon.out", s, DIRSIZ) == 0)
190: return(1);
191: if(strncmp("qed.hup:", s, 8) == 0)
192: return(1);
193: if(strncmp("x", s, DIRSIZ) == 0)
194: return(1);
195: if(strncmp("dead.letter", s, DIRSIZ) == 0)
196: return(1);
197: if (strend(".dvi", s))
198: return(1);
199: if (strncmp("junk", s, 4)==0 || strncmp("temp", s, 4)==0)
200: return 1;
201: if (strlen(s) == 1 && islower(s[0]))
202: return 1;
203: if (strncmp("foo", s, 3)==0 ||
204: (strncmp("rst", s, 3)==0 && strlen(s)>5)) {
205: p = s+3;
206: while (p < s+DIRSIZ) {
207: if (*p == 0)
208: return(1);
209: if (!isdigit(*p))
210: break;
211: p++;
212: }
213: }
214: if (strncmp(".jx", s, 3) == 0)
215: return(1);
216: if (s[5]=='.' && isdigit(s[3]) && isdigit(s[4]) && isdigit(s[7])
217: && isdigit(s[8]) && s[6]=='a')
218: return(1);
219: if (voflg==0)
220: return(0);
221: p = s+DIRSIZ;
222: if (strend(".o", s))
223: return(1);
224: return(0);
225: }
226:
227: strend(e, s) /* is e the end of s? */
228: register char *e, *s;
229: {
230: register char *t=s;
231: while(*t)
232: t++;
233: t-=strlen(e);
234: return(strcmp(e, t)==0);
235: }
236:
237: file(s) char *s;
238: { int i;
239: char buf[DIRSIZ+1];
240: for(i = 0; i < DIRSIZ; i++)
241: buf[i] = *s++;
242: buf[i] = 0;
243: printf("%s/%s\n", curdir, buf);
244: }
245:
246: isitroff(ip)
247: register struct dinode *ip;
248: {
249: long dska[13];
250: char tbuf[BSIZE(0)];
251: if ((ip->di_mode&IFMT) != IFREG)
252: return(0);
253: if (ip->di_mode&IEXEC)
254: return(0);
255: /* if (ip->di_size < 512)
256: /* return(0);
257: */
258: if (ip->di_mtime + DAY > nowtime)
259: return(0);
260: /* if (ip->di_mtime +(200*DAY) < nowtime)
261: /* return(0);
262: */
263: l3tol(dska, ip->di_addr, 13);
264: bread(dska[0], tbuf, BSIZE(0));
265: if (troffint(tbuf))
266: return(1);
267: return(0);
268: }
269:
270: char *troff[] = { /* troff intermediate lang */
271: "x T ", "x res ", "x init", "V0", "x font ", 0 };
272: int ntroff[] = {
273: 4, 6, 6, 2, 7 };
274:
275: troffint(bp)
276: register char *bp;
277: {
278: register char **tp;
279: register i, j, k = 0, oi, n;
280:
281: for (i = oi = n = 0; i < BSIZE(0) && k < 15; i++) {
282: if (bp[i] == '\n') {
283: k++;
284: bp[i] = '\0';
285: for (j = 0; troff[j]; j++)
286: if (strncmp(bp+oi, troff[j], ntroff[j]) == 0)
287: n++;
288: oi = i+1;
289: }
290: }
291: return n > 5;
292: }
293:
294: word(p1, p2)
295: register char *p1, *p2;
296: {
297: while (*p1++ == *p2++)
298: ;
299: if (*--p1 != '\0')
300: return(0);
301: if (*--p2 !=' ' && *p2!='\n')
302: return(0);
303: return(1);
304: }
305:
306: #define ITABSZ BUFSIZE/sizeof(long)
307: #define ISIZ (BUFSIZE/sizeof(struct dinode))
308: static struct filsys sblock;
309: static struct dinode itab[ITABSZ];
310: static fi;
311: struct stat stb;
312: int dev;
313:
314:
315: eachinode(file, func)
316: char *file;
317: int (*func)();
318: { unsigned ino;
319: int nfiles = 0;
320: register unsigned i, j;
321:
322: fi = open(file, 0);
323: if(fi < 0 || fstat(fi, &stb) != 0) {
324: fprintf(stderr, "cannot open %s\n", file);
325: return;
326: }
327: dev = stb.st_rdev;
328: bread((long)1, (char *)&sblock, sizeof sblock);
329: nfiles = (sblock.s_isize-2)*(BSIZE(dev)/sizeof(struct dinode));
330: ino = 1;
331: for(i=2+((ino-1)/INOPB(dev)); ino<nfiles; i ++) {
332: bread((long)i, (char *)itab, BSIZE(dev));
333: for (j=0; j<INOPB(dev) && ino<nfiles; j++) {
334: (*func)(ino, &itab[j]);
335: ino++;
336: }
337: }
338: }
339:
340: bread(bno, buf, cnt)
341: long bno;
342: char *buf;
343: { int i;
344:
345: lseek(fi, bno*BSIZE(dev), 0);
346: if (read(fi, buf, cnt) != cnt) {
347: printf("read error %u\n", bno);
348: for(i=0; i<cnt;i++)
349: buf[i] = 0;
350: }
351: }
352:
353: alldir(n, f) int (*f)();
354: { struct direct p;
355: FILE *fd;
356: fd = fopen(".", "r");
357: if(fd == NULL) {
358: perror(".");
359: return(0);
360: }
361: (void) fseek(fd, (long)2 * sizeof(p), 0); /* skip . and .. */
362: for(;;) {
363: (void) fread((char *)&p, 1, sizeof(p), fd);
364: if(feof(fd)) break;
365: if(p.d_name[0] != 0 && p.d_ino != 0)
366: (*f)(n, &p);
367: }
368: (void) fclose(fd);
369: return(1);
370: }
371:
372: getbad()
373: {
374: register struct passwd *p;
375: extern struct passwd *getpwent();
376: register i;
377:
378: for (i=0; i<NUID; i++)
379: isbad[i] = 1;
380: while (p = getpwent()) {
381: if (p->pw_uid>=0 && p->pw_uid<NUID)
382: isbad[p->pw_uid] = 0;
383: }
384: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.