-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdu.c
76 lines (69 loc) · 1.56 KB
/
du.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include "util.h"
enum {
aFlag = 1,
sFlag = 2,
};
int notAllDots (struct dirent *e) {
int ii;
for (ii = 0; e -> d_name[ii]; ii++) if (e -> d_name[ii] != '.') return 1;
return 0;
}
int grief = 0;
int du (int top, int bs, int flags, char *path) {
struct stat s;
struct dirent **es;
if (lstat (path, &s) < 0) {
fprintf (stderr, "du: %s: %s\n", path, strerror (errno));
grief = 1;
return 0;
}
if (s.st_mode & S_IFDIR) {
int ii, n;
n = scandir (path, &es, notAllDots, 0);
if (n < 0) {
fprintf (stderr, "du: %s: %s\n", path, strerror (errno));
grief = 1;
}
else
for (ii = 0; ii < n; ii++) {
char *subpath;
if (asprintf (&subpath, "%s/%s", path, es[ii] -> d_name) < 0) eprintf ("du:");
s.st_size += du (0, bs, flags, subpath);
free (subpath);
}
}
if (top || (flags & aFlag || s.st_mode & S_IFDIR) && !(flags & sFlag)) printf ("%16d\t%s\n", s.st_size / bs, path);
return s.st_size;
}
int main (int argc, char *argu[]) {
int flags = 0;
int bs = 512;
int ii;
for (ii = 1; ii < argc; ii++) {
int jj;
if (argu[ii][0] != '-' || argu[ii][1] == 0) break;
if (argu[ii][1] == '-' && argu[ii][2] == 0) {
ii++;
break;
}
for (jj = 1; argu[ii][jj]; jj++) switch (argu[ii][jj]) {
case 'a':
flags |= aFlag;
break;
case 's':
flags |= sFlag;
break;
case 'k':
bs = 1024;
break;
}
}
if (ii < argc) for (; ii < argc; ii++) du (1, bs, flags, argu[ii]);
else du (1, bs, flags, ".");
return grief;
}