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