define DESTDIR, add forgotten dependencies
[unix-history] / usr / src / usr.bin / du / du.c
CommitLineData
fbdb528f 1#ifndef lint
16ac2913 2static char *sccsid = "@(#)du.c 4.8 (Berkeley) %G%";
fbdb528f
KM
3#endif
4
ca4a89e1
BJ
5#include <stdio.h>
6#include <sys/param.h>
7#include <sys/stat.h>
f4d092e2 8#include <dir.h>
fbdb528f 9
e29a75fd
BJ
10char path[BUFSIZ], name[BUFSIZ];
11int aflg;
12int sflg;
13char *dot = ".";
ca4a89e1 14
e29a75fd 15#define ML 1000
ca4a89e1 16struct {
e29a75fd
BJ
17 int dev;
18 ino_t ino;
ca4a89e1 19} ml[ML];
e29a75fd
BJ
20int mlx;
21
ca4a89e1 22long descend();
e29a75fd 23char *index(), *rindex(), *strcpy(), *sprintf();
ca4a89e1
BJ
24
25main(argc, argv)
e29a75fd
BJ
26 int argc;
27 char **argv;
ca4a89e1 28{
e29a75fd
BJ
29 long kbytes = 0;
30 register char *np;
dd610901 31 int pid;
ca4a89e1 32
e29a75fd
BJ
33 argc--, argv++;
34again:
35 if (argc && !strcmp(*argv, "-s")) {
36 sflg++;
37 argc--, argv++;
38 goto again;
39 }
40 if (argc && !strcmp(*argv, "-a")) {
41 aflg++;
42 argc--, argv++;
43 goto again;
44 }
45 if (argc == 0) {
46 argv = &dot;
47 argc = 1;
ca4a89e1 48 }
ca4a89e1 49 do {
dd610901
BJ
50 if (argc > 1) {
51 pid = fork();
52 if (pid == -1) {
53 fprintf(stderr, "No more processes.\n");
ca4a89e1
BJ
54 exit(1);
55 }
dd610901
BJ
56 if (pid != 0)
57 wait((int *)0);
58 }
59 if (argc == 1 || pid == 0) {
60 (void) strcpy(path, *argv);
61 (void) strcpy(name, *argv);
62 if (np = rindex(name, '/')) {
63 *np++ = '\0';
64 if (chdir(*name ? name : "/") < 0) {
65 perror(*name ? name : "/");
66 exit(1);
67 }
68 } else
69 np = path;
70 kbytes = descend(path, *np ? np : ".");
71 if (sflg)
72 printf("%ld\t%s\n", kbytes, path);
73 if (argc > 1)
74 exit(1);
75 }
e29a75fd
BJ
76 argc--, argv++;
77 } while (argc > 0);
ca4a89e1
BJ
78 exit(0);
79}
80
e29a75fd
BJ
81DIR *dirp = NULL;
82
ca4a89e1 83long
e29a75fd
BJ
84descend(base, name)
85 char *base, *name;
ca4a89e1 86{
e29a75fd
BJ
87 char *ebase0, *ebase;
88 struct stat stb;
ca4a89e1 89 int i;
e29a75fd 90 long kbytes = 0;
fbdb528f 91 long curoff = NULL;
e29a75fd 92 register struct direct *dp;
ca4a89e1 93
e29a75fd
BJ
94 ebase0 = ebase = index(base, 0);
95 if (ebase > base && ebase[-1] == '/')
96 ebase--;
97 if (lstat(name, &stb) < 0) {
98 perror(base);
99 *ebase0 = 0;
100 return (0);
ca4a89e1 101 }
e29a75fd
BJ
102 if (stb.st_nlink > 1 && (stb.st_mode&S_IFMT) != S_IFDIR) {
103 for (i = 0; i <= mlx; i++)
104 if (ml[i].ino == stb.st_ino && ml[i].dev == stb.st_dev)
105 return (0);
106 if (mlx < ML) {
107 ml[mlx].dev = stb.st_dev;
108 ml[mlx].ino = stb.st_ino;
109 mlx++;
ca4a89e1
BJ
110 }
111 }
e29a75fd
BJ
112 kbytes = howmany(stb.st_size, 1024);
113 if ((stb.st_mode&S_IFMT) != S_IFDIR) {
114 if (aflg)
115 printf("%ld\t%s\n", kbytes, base);
116 return (kbytes);
ca4a89e1 117 }
fbdb528f
KM
118 if (dirp != NULL)
119 closedir(dirp);
a1a73cfc 120 dirp = opendir(name);
e29a75fd
BJ
121 if (dirp == NULL) {
122 perror(base);
123 *ebase0 = 0;
124 return (0);
fbdb528f 125 }
a1a73cfc
KM
126 if (chdir(name) < 0) {
127 perror(base);
128 *ebase0 = 0;
16ac2913
KM
129 closedir(dirp);
130 dirp = NULL;
a1a73cfc
KM
131 return (0);
132 }
e29a75fd
BJ
133 while (dp = readdir(dirp)) {
134 if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
fbdb528f 135 continue;
e29a75fd 136 (void) sprintf(ebase, "/%s", dp->d_name);
fbdb528f 137 curoff = telldir(dirp);
e29a75fd
BJ
138 kbytes += descend(base, ebase+1);
139 *ebase = 0;
fbdb528f 140 if (dirp == NULL) {
fbdb528f 141 dirp = opendir(".");
a1a73cfc
KM
142 if (dirp == NULL) {
143 perror(".");
144 return (0);
145 }
fbdb528f 146 seekdir(dirp, curoff);
ca4a89e1
BJ
147 }
148 }
fbdb528f
KM
149 closedir(dirp);
150 dirp = NULL;
e29a75fd
BJ
151 if (sflg == 0)
152 printf("%ld\t%s\n", kbytes, base);
153 if (chdir("..") < 0) {
154 (void) sprintf(index(base, 0), "/..");
155 perror(base);
156 exit(1);
ca4a89e1 157 }
e29a75fd
BJ
158 *ebase0 = 0;
159 return (kbytes);
ca4a89e1 160}