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