|
|
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[BUFSIZE], name[BUFSIZE];
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: perror(*name? name: "/");
47: exit(1);
48: }
49: } else
50: np = path;
51: blocks = descend(path, *np? np: ".", 0);
52: if(Sflag)
53: printf("%ld\t%s\n", blocks, path);
54: } while(++i < argc);
55:
56: exit(0);
57: }
58:
59: long
60: descend(np, fname, depth)
61: char *np, *fname;
62: {
63: int dir = 0, /* open directory */
64: offset,
65: dsize,
66: entries,
67: dirsize;
68:
69: struct direct dentry[BUFSIZE/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(lstat(fname,&Statb)<0) {
77: perror(name);
78: fprintf(stderr, "--bad status < %s %s >\n", fname, 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: blocks = ((Statb.st_size+BSIZE(Statb.st_dev)-1)>>BSHIFT(Statb.st_dev)) *
95: (BSIZE(Statb.st_dev)/BSIZE(0));
96:
97: if((Statb.st_mode&S_IFMT)!=S_IFDIR) {
98: if(Aflag)
99: printf("%ld\t%s\n", blocks, np);
100: return(blocks);
101: }
102:
103: if(Aflag)
104: printf("%ld\t%s/\n", blocks, np);
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 += BUFSIZE) { /* each block */
113: dsize = BUFSIZE<(dirsize-offset)? BUFSIZE: (dirsize-offset);
114: if(!dir) {
115: if((dir=open(".",0))<0) {
116: perror(".");
117: fprintf(stderr, "--cannot open < %s >\n",
118: np);
119: goto ret;
120: }
121: if(offset) lseek(dir, (long)offset, 0);
122: if(read(dir, (char *)dentry, dsize)<0) {
123: perror("read");
124: fprintf(stderr, "--cannot read < %s >\n",
125: np);
126: goto ret;
127: }
128: if(dir > 15) {
129: close(dir);
130: dir = 0;
131: }
132: } else
133: if(read(dir, (char *)dentry, dsize)<0) {
134: perror("read");
135: fprintf(stderr, "--cannot read < %s >\n", np);
136: goto ret;
137: }
138: entries = dsize / sizeof(struct direct);
139: for(dp=dentry; entries; --entries, ++dp) {
140: /* each directory entry */
141: if(dp->d_ino==0 || EQ(dp->d_name, ".") || EQ(dp->d_name, ".."))
142: continue;
143: c1 = endofname;
144: *c1++ = '/';
145: c2 = dp->d_name;
146: for(i=0; i<DIRSIZ; ++i)
147: if(*c2)
148: *c1++ = *c2++;
149: else
150: break;
151: *c1 = '\0';
152: if(c1 == endofname) /* ?? */
153: return 0L;
154: blocks += descend(np, endofname+1, depth+1);
155: }
156: }
157: *endofname = '\0';
158: if(!Sflag)
159: printf("%ld\t%s\n", blocks, np);
160: ret:
161: if(dir)
162: close(dir);
163: if(chdir("..") == -1) {
164: *endofname = '\0';
165: perror("..");
166: fprintf(stderr, "Bad directory <%s>\n", np);
167: while(*--endofname != '/');
168: *endofname = '\0';
169: if(chdir(np) == -1)
170: exit(1);
171: }
172: return(blocks);
173: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.