Blame


1 bc7cb1a1 2003-11-23 devnull #include <u.h>
2 bc7cb1a1 2003-11-23 devnull #include <libc.h>
3 bc7cb1a1 2003-11-23 devnull
4 bc7cb1a1 2003-11-23 devnull extern vlong du(char*, Dir*);
5 bc7cb1a1 2003-11-23 devnull extern vlong k(vlong);
6 bc7cb1a1 2003-11-23 devnull extern void err(char*);
7 bc7cb1a1 2003-11-23 devnull extern int warn(char*);
8 bc7cb1a1 2003-11-23 devnull extern int seen(Dir*);
9 bc7cb1a1 2003-11-23 devnull
10 bc7cb1a1 2003-11-23 devnull int aflag;
11 bc7cb1a1 2003-11-23 devnull int fflag;
12 bc7cb1a1 2003-11-23 devnull int nflag;
13 bc7cb1a1 2003-11-23 devnull int sflag;
14 bc7cb1a1 2003-11-23 devnull int tflag;
15 bc7cb1a1 2003-11-23 devnull int uflag;
16 bc7cb1a1 2003-11-23 devnull int qflag;
17 bc7cb1a1 2003-11-23 devnull char *fmt = "%llud\t%s\n";
18 bc7cb1a1 2003-11-23 devnull vlong blocksize = 1024LL;
19 bc7cb1a1 2003-11-23 devnull
20 bc7cb1a1 2003-11-23 devnull void
21 bc7cb1a1 2003-11-23 devnull main(int argc, char *argv[])
22 bc7cb1a1 2003-11-23 devnull {
23 bc7cb1a1 2003-11-23 devnull int i;
24 bc7cb1a1 2003-11-23 devnull char *s, *ss;
25 bc7cb1a1 2003-11-23 devnull
26 bc7cb1a1 2003-11-23 devnull ARGBEGIN {
27 bc7cb1a1 2003-11-23 devnull case 'a': /* all files */
28 bc7cb1a1 2003-11-23 devnull aflag = 1;
29 bc7cb1a1 2003-11-23 devnull break;
30 bc7cb1a1 2003-11-23 devnull case 's': /* only top level */
31 bc7cb1a1 2003-11-23 devnull sflag = 1;
32 bc7cb1a1 2003-11-23 devnull break;
33 bc7cb1a1 2003-11-23 devnull case 'f': /* ignore errors */
34 bc7cb1a1 2003-11-23 devnull fflag = 1;
35 bc7cb1a1 2003-11-23 devnull break;
36 bc7cb1a1 2003-11-23 devnull case 'n': /* all files, number of bytes */
37 bc7cb1a1 2003-11-23 devnull aflag = 1;
38 bc7cb1a1 2003-11-23 devnull nflag = 1;
39 bc7cb1a1 2003-11-23 devnull break;
40 bc7cb1a1 2003-11-23 devnull case 't': /* return modified/accessed time */
41 bc7cb1a1 2003-11-23 devnull tflag = 1;
42 bc7cb1a1 2003-11-23 devnull break;
43 bc7cb1a1 2003-11-23 devnull case 'u': /* accessed time */
44 bc7cb1a1 2003-11-23 devnull uflag = 1;
45 bc7cb1a1 2003-11-23 devnull break;
46 bc7cb1a1 2003-11-23 devnull case 'q': /* qid */
47 bc7cb1a1 2003-11-23 devnull fmt = "%.16llux\t%s\n";
48 bc7cb1a1 2003-11-23 devnull qflag = 1;
49 bc7cb1a1 2003-11-23 devnull break;
50 bc7cb1a1 2003-11-23 devnull case 'b': /* block size */
51 bc7cb1a1 2003-11-23 devnull s = ARGF();
52 bc7cb1a1 2003-11-23 devnull if(s) {
53 bc7cb1a1 2003-11-23 devnull blocksize = strtoul(s, &ss, 0);
54 bc7cb1a1 2003-11-23 devnull if(s == ss)
55 bc7cb1a1 2003-11-23 devnull blocksize = 1;
56 bc7cb1a1 2003-11-23 devnull if(*ss == 'k')
57 bc7cb1a1 2003-11-23 devnull blocksize *= 1024;
58 bc7cb1a1 2003-11-23 devnull }
59 bc7cb1a1 2003-11-23 devnull break;
60 bc7cb1a1 2003-11-23 devnull } ARGEND
61 bc7cb1a1 2003-11-23 devnull if(argc==0)
62 bc7cb1a1 2003-11-23 devnull print(fmt, du(".", dirstat(".")), ".");
63 bc7cb1a1 2003-11-23 devnull else
64 bc7cb1a1 2003-11-23 devnull for(i=0; i<argc; i++)
65 bc7cb1a1 2003-11-23 devnull print(fmt, du(argv[i], dirstat(argv[i])), argv[i]);
66 bc7cb1a1 2003-11-23 devnull exits(0);
67 bc7cb1a1 2003-11-23 devnull }
68 bc7cb1a1 2003-11-23 devnull
69 bc7cb1a1 2003-11-23 devnull vlong
70 bc7cb1a1 2003-11-23 devnull du(char *name, Dir *dir)
71 bc7cb1a1 2003-11-23 devnull {
72 bc7cb1a1 2003-11-23 devnull int fd, i, n;
73 bc7cb1a1 2003-11-23 devnull Dir *buf, *d;
74 bc7cb1a1 2003-11-23 devnull char file[256];
75 bc7cb1a1 2003-11-23 devnull vlong nk, t;
76 bc7cb1a1 2003-11-23 devnull
77 bc7cb1a1 2003-11-23 devnull if(dir == nil)
78 bc7cb1a1 2003-11-23 devnull return warn(name);
79 bc7cb1a1 2003-11-23 devnull
80 bc7cb1a1 2003-11-23 devnull fd = open(name, OREAD);
81 bc7cb1a1 2003-11-23 devnull if(fd < 0)
82 bc7cb1a1 2003-11-23 devnull return warn(name);
83 bc7cb1a1 2003-11-23 devnull
84 bc7cb1a1 2003-11-23 devnull if((dir->qid.type&QTDIR) == 0)
85 bc7cb1a1 2003-11-23 devnull nk = k(dir->length);
86 bc7cb1a1 2003-11-23 devnull else{
87 bc7cb1a1 2003-11-23 devnull nk = 0;
88 bc7cb1a1 2003-11-23 devnull while((n=dirread(fd, &buf)) > 0) {
89 bc7cb1a1 2003-11-23 devnull d = buf;
90 bc7cb1a1 2003-11-23 devnull for(i=0; i<n; i++, d++) {
91 bc7cb1a1 2003-11-23 devnull if((d->qid.type&QTDIR) == 0) {
92 bc7cb1a1 2003-11-23 devnull t = k(d->length);
93 bc7cb1a1 2003-11-23 devnull nk += t;
94 bc7cb1a1 2003-11-23 devnull if(aflag) {
95 bc7cb1a1 2003-11-23 devnull sprint(file, "%s/%s", name, d->name);
96 bc7cb1a1 2003-11-23 devnull if(tflag) {
97 bc7cb1a1 2003-11-23 devnull t = d->mtime;
98 bc7cb1a1 2003-11-23 devnull if(uflag)
99 bc7cb1a1 2003-11-23 devnull t = d->atime;
100 bc7cb1a1 2003-11-23 devnull }
101 bc7cb1a1 2003-11-23 devnull if(qflag)
102 bc7cb1a1 2003-11-23 devnull t = d->qid.path;
103 bc7cb1a1 2003-11-23 devnull print(fmt, t, file);
104 bc7cb1a1 2003-11-23 devnull }
105 bc7cb1a1 2003-11-23 devnull continue;
106 bc7cb1a1 2003-11-23 devnull }
107 bc7cb1a1 2003-11-23 devnull if(strcmp(d->name, ".") == 0 ||
108 bc7cb1a1 2003-11-23 devnull strcmp(d->name, "..") == 0 ||
109 bc7cb1a1 2003-11-23 devnull seen(d))
110 bc7cb1a1 2003-11-23 devnull continue;
111 bc7cb1a1 2003-11-23 devnull sprint(file, "%s/%s", name, d->name);
112 bc7cb1a1 2003-11-23 devnull t = du(file, d);
113 bc7cb1a1 2003-11-23 devnull nk += t;
114 bc7cb1a1 2003-11-23 devnull if(tflag) {
115 bc7cb1a1 2003-11-23 devnull t = d->mtime;
116 bc7cb1a1 2003-11-23 devnull if(uflag)
117 bc7cb1a1 2003-11-23 devnull t = d->atime;
118 bc7cb1a1 2003-11-23 devnull }
119 bc7cb1a1 2003-11-23 devnull if(qflag)
120 bc7cb1a1 2003-11-23 devnull t = d->qid.path;
121 bc7cb1a1 2003-11-23 devnull if(!sflag)
122 bc7cb1a1 2003-11-23 devnull print(fmt, t, file);
123 bc7cb1a1 2003-11-23 devnull }
124 bc7cb1a1 2003-11-23 devnull free(buf);
125 bc7cb1a1 2003-11-23 devnull }
126 bc7cb1a1 2003-11-23 devnull if(n < 0)
127 bc7cb1a1 2003-11-23 devnull warn(name);
128 bc7cb1a1 2003-11-23 devnull }
129 bc7cb1a1 2003-11-23 devnull close(fd);
130 bc7cb1a1 2003-11-23 devnull if(tflag) {
131 bc7cb1a1 2003-11-23 devnull if(uflag)
132 bc7cb1a1 2003-11-23 devnull return dir->atime;
133 bc7cb1a1 2003-11-23 devnull return dir->mtime;
134 bc7cb1a1 2003-11-23 devnull }
135 bc7cb1a1 2003-11-23 devnull if(qflag)
136 bc7cb1a1 2003-11-23 devnull return dir->qid.path;
137 bc7cb1a1 2003-11-23 devnull return nk;
138 bc7cb1a1 2003-11-23 devnull }
139 bc7cb1a1 2003-11-23 devnull
140 bc7cb1a1 2003-11-23 devnull #define NCACHE 128 /* must be power of two */
141 bc7cb1a1 2003-11-23 devnull typedef struct Cache Cache;
142 bc7cb1a1 2003-11-23 devnull struct Cache
143 bc7cb1a1 2003-11-23 devnull {
144 bc7cb1a1 2003-11-23 devnull Dir* cache;
145 bc7cb1a1 2003-11-23 devnull int n;
146 bc7cb1a1 2003-11-23 devnull int max;
147 bc7cb1a1 2003-11-23 devnull } cache[NCACHE];
148 bc7cb1a1 2003-11-23 devnull
149 bc7cb1a1 2003-11-23 devnull int
150 bc7cb1a1 2003-11-23 devnull seen(Dir *dir)
151 bc7cb1a1 2003-11-23 devnull {
152 bc7cb1a1 2003-11-23 devnull Dir *dp;
153 bc7cb1a1 2003-11-23 devnull int i;
154 bc7cb1a1 2003-11-23 devnull Cache *c;
155 bc7cb1a1 2003-11-23 devnull
156 bc7cb1a1 2003-11-23 devnull c = &cache[dir->qid.path&(NCACHE-1)];
157 bc7cb1a1 2003-11-23 devnull dp = c->cache;
158 bc7cb1a1 2003-11-23 devnull for(i=0; i<c->n; i++, dp++)
159 bc7cb1a1 2003-11-23 devnull if(dir->qid.path == dp->qid.path &&
160 bc7cb1a1 2003-11-23 devnull dir->type == dp->type &&
161 bc7cb1a1 2003-11-23 devnull dir->dev == dp->dev)
162 bc7cb1a1 2003-11-23 devnull return 1;
163 bc7cb1a1 2003-11-23 devnull if(c->n == c->max){
164 bc7cb1a1 2003-11-23 devnull c->cache = realloc(c->cache, (c->max+=20)*sizeof(Dir));
165 bc7cb1a1 2003-11-23 devnull if(cache == 0)
166 bc7cb1a1 2003-11-23 devnull err("malloc failure");
167 bc7cb1a1 2003-11-23 devnull }
168 bc7cb1a1 2003-11-23 devnull c->cache[c->n++] = *dir;
169 bc7cb1a1 2003-11-23 devnull return 0;
170 bc7cb1a1 2003-11-23 devnull }
171 bc7cb1a1 2003-11-23 devnull
172 bc7cb1a1 2003-11-23 devnull void
173 bc7cb1a1 2003-11-23 devnull err(char *s)
174 bc7cb1a1 2003-11-23 devnull {
175 bc7cb1a1 2003-11-23 devnull fprint(2, "du: %s: %r\n", s);
176 bc7cb1a1 2003-11-23 devnull exits(s);
177 bc7cb1a1 2003-11-23 devnull }
178 bc7cb1a1 2003-11-23 devnull
179 bc7cb1a1 2003-11-23 devnull int
180 bc7cb1a1 2003-11-23 devnull warn(char *s)
181 bc7cb1a1 2003-11-23 devnull {
182 bc7cb1a1 2003-11-23 devnull if(fflag == 0)
183 bc7cb1a1 2003-11-23 devnull fprint(2, "du: %s: %r\n", s);
184 bc7cb1a1 2003-11-23 devnull return 0;
185 bc7cb1a1 2003-11-23 devnull }
186 bc7cb1a1 2003-11-23 devnull
187 bc7cb1a1 2003-11-23 devnull vlong
188 bc7cb1a1 2003-11-23 devnull k(vlong n)
189 bc7cb1a1 2003-11-23 devnull {
190 bc7cb1a1 2003-11-23 devnull if(nflag)
191 bc7cb1a1 2003-11-23 devnull return n;
192 bc7cb1a1 2003-11-23 devnull n = (n+blocksize-1)/blocksize;
193 bc7cb1a1 2003-11-23 devnull return n*blocksize/1024LL;
194 bc7cb1a1 2003-11-23 devnull }