|
|
1.1 root 1: #include <stdio.h>
2: #include <sys/param.h>
3: #include <sys/stat.h>
4: #include <sys/dir.h>
5: #define EQ(x,y) (strcmp(x,y)==0)
6: #define ML 1000
7:
8: struct stat Statb;
9: char path[256], name[256];
10: int Aflag = 0,
11: Sflag = 0,
12: Noarg = 0;
13: struct {
14: int dev,
15: ino;
16: } ml[ML];
17: long descend();
18: char *rindex();
19: char *strcpy();
20:
21: main(argc, argv)
22: char **argv;
23: {
24: register i = 1;
25: long blocks = 0;
26: register char *np;
27:
28: if (argc>1) {
29: if(EQ(argv[i], "-s")) {
30: ++i;
31: ++Sflag;
32: } else if(EQ(argv[i], "-a")) {
33: ++i;
34: ++Aflag;
35: }
36: }
37: if(i == argc)
38: ++Noarg;
39:
40: do {
41: strcpy(path, Noarg? ".": argv[i]);
42: strcpy(name, path);
43: if(np = rindex(name, '/')) {
44: *np++ = '\0';
45: if(chdir(*name? name: "/") == -1) {
46: fprintf(stderr, "cannot chdir()\n");
47: exit(1);
48: }
49: } else
50: np = path;
51: blocks = descend(path, *np? np: ".");
52: if(Sflag)
53: printf("%ld %s\n", blocks, path);
54: } while(++i < argc);
55:
56: exit(0);
57: }
58:
59: long
60: descend(np, fname)
61: char *np, *fname;
62: {
63: int dir = 0, /* open directory */
64: offset,
65: dsize,
66: entries,
67: dirsize;
68:
69: struct direct dentry[BUFSIZ / sizeof (struct direct)];
70: register struct direct *dp;
71: register char *c1, *c2;
72: int i;
73: char *endofname;
74: long blocks = 0;
75:
76: if(stat(fname,&Statb)<0) {
77: fprintf(stderr, "--bad status < %s >\n", name);
78: return 0L;
79: }
80: if(Statb.st_nlink > 1 && (Statb.st_mode&S_IFMT)!=S_IFDIR) {
81: static linked = 0;
82:
83: for(i = 0; i <= linked; ++i) {
84: if(ml[i].ino==Statb.st_ino && ml[i].dev==Statb.st_dev)
85: return 0;
86: }
87: if (linked < ML) {
88: ml[linked].dev = Statb.st_dev;
89: ml[linked].ino = Statb.st_ino;
90: ++linked;
91: }
92: }
93: /*
94: blocks = (Statb.st_size + BSIZE-1) >> BSHIFT;
95: */
96: blocks = (Statb.st_size + 511) >> 9;
97:
98: if((Statb.st_mode&S_IFMT)!=S_IFDIR) {
99: if(Aflag)
100: printf("%ld %s\n", blocks, np);
101: return(blocks);
102: }
103:
104: for(c1 = np; *c1; ++c1);
105: if(*(c1-1) == '/')
106: --c1;
107: endofname = c1;
108: dirsize = Statb.st_size;
109: if(chdir(fname) == -1)
110: return 0;
111: for(offset=0; offset < dirsize; offset += BUFSIZ) { /* each block */
112: dsize = BUFSIZ<(dirsize-offset)? BUFSIZ: (dirsize-offset);
113: if(!dir) {
114: if((dir=open(".",0))<0) {
115: fprintf(stderr, "--cannot open < %s >\n",
116: np);
117: goto ret;
118: }
119: if(offset) lseek(dir, (long)offset, 0);
120: if(read(dir, (char *)dentry, dsize)<0) {
121: fprintf(stderr, "--cannot read < %s >\n",
122: np);
123: goto ret;
124: }
125: if(dir > 10) {
126: close(dir);
127: dir = 0;
128: }
129: } else
130: if(read(dir, (char *)dentry, dsize)<0) {
131: fprintf(stderr, "--cannot read < %s >\n",
132: np);
133: goto ret;
134: }
135: for(dp=dentry, entries=dsize>>4; entries; --entries, ++dp) {
136: /* each directory entry */
137: if(dp->d_ino==0
138: || EQ(dp->d_name, ".")
139: || EQ(dp->d_name, ".."))
140: continue;
141: c1 = endofname;
142: *c1++ = '/';
143: c2 = dp->d_name;
144: for(i=0; i<DIRSIZ; ++i)
145: if(*c2)
146: *c1++ = *c2++;
147: else
148: break;
149: *c1 = '\0';
150: if(c1 == endofname) /* ?? */
151: return 0L;
152: blocks += descend(np, endofname+1);
153: }
154: }
155: *endofname = '\0';
156: if(!Sflag)
157: printf("%ld %s\n", blocks, np);
158: ret:
159: if(dir)
160: close(dir);
161: if(chdir("..") == -1) {
162: *endofname = '\0';
163: fprintf(stderr, "Bad directory <%s>\n", np);
164: while(*--endofname != '/');
165: *endofname = '\0';
166: if(chdir(np) == -1)
167: exit(1);
168: }
169: return(blocks);
170: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.