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