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