fixed order of tgoto args, zapped reliance on former isprint bug
[unix-history] / usr / src / usr.bin / du / du.c
CommitLineData
fbdb528f 1#ifndef lint
6521d648 2static char *sccsid = "@(#)du.c 4.12 (Berkeley) %G%";
fbdb528f
KM
3#endif
4
ca4a89e1
BJ
5#include <stdio.h>
6#include <sys/param.h>
7#include <sys/stat.h>
cb7715be 8#include <sys/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();
6521d648 23char *index(), *rindex(), *strcpy();
ca4a89e1 24
905d30b9
SL
25#define kb(n) (howmany(dbtob(n), 1024))
26
ca4a89e1 27main(argc, argv)
e29a75fd
BJ
28 int argc;
29 char **argv;
ca4a89e1 30{
905d30b9 31 long blocks = 0;
e29a75fd 32 register char *np;
dd610901 33 int pid;
ca4a89e1 34
e29a75fd
BJ
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;
ca4a89e1 50 }
ca4a89e1 51 do {
dd610901
BJ
52 if (argc > 1) {
53 pid = fork();
54 if (pid == -1) {
55 fprintf(stderr, "No more processes.\n");
ca4a89e1
BJ
56 exit(1);
57 }
dd610901
BJ
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;
905d30b9 72 blocks = descend(path, *np ? np : ".");
dd610901 73 if (sflg)
905d30b9 74 printf("%ld\t%s\n", kb(blocks), path);
dd610901
BJ
75 if (argc > 1)
76 exit(1);
77 }
e29a75fd
BJ
78 argc--, argv++;
79 } while (argc > 0);
ca4a89e1
BJ
80 exit(0);
81}
82
e29a75fd
BJ
83DIR *dirp = NULL;
84
ca4a89e1 85long
e29a75fd
BJ
86descend(base, name)
87 char *base, *name;
ca4a89e1 88{
e29a75fd
BJ
89 char *ebase0, *ebase;
90 struct stat stb;
ca4a89e1 91 int i;
905d30b9 92 long blocks = 0;
fbdb528f 93 long curoff = NULL;
e29a75fd 94 register struct direct *dp;
ca4a89e1 95
e29a75fd
BJ
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);
ca4a89e1 103 }
e29a75fd
BJ
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++;
ca4a89e1
BJ
112 }
113 }
905d30b9 114 blocks = stb.st_blocks;
e29a75fd
BJ
115 if ((stb.st_mode&S_IFMT) != S_IFDIR) {
116 if (aflg)
905d30b9
SL
117 printf("%ld\t%s\n", kb(blocks), base);
118 return (blocks);
ca4a89e1 119 }
fbdb528f
KM
120 if (dirp != NULL)
121 closedir(dirp);
a1a73cfc 122 dirp = opendir(name);
e29a75fd
BJ
123 if (dirp == NULL) {
124 perror(base);
125 *ebase0 = 0;
126 return (0);
fbdb528f 127 }
a1a73cfc
KM
128 if (chdir(name) < 0) {
129 perror(base);
130 *ebase0 = 0;
16ac2913
KM
131 closedir(dirp);
132 dirp = NULL;
a1a73cfc
KM
133 return (0);
134 }
e29a75fd
BJ
135 while (dp = readdir(dirp)) {
136 if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
fbdb528f 137 continue;
e29a75fd 138 (void) sprintf(ebase, "/%s", dp->d_name);
fbdb528f 139 curoff = telldir(dirp);
905d30b9 140 blocks += descend(base, ebase+1);
e29a75fd 141 *ebase = 0;
fbdb528f 142 if (dirp == NULL) {
fbdb528f 143 dirp = opendir(".");
a1a73cfc
KM
144 if (dirp == NULL) {
145 perror(".");
146 return (0);
147 }
fbdb528f 148 seekdir(dirp, curoff);
ca4a89e1
BJ
149 }
150 }
fbdb528f
KM
151 closedir(dirp);
152 dirp = NULL;
e29a75fd 153 if (sflg == 0)
905d30b9 154 printf("%ld\t%s\n", kb(blocks), base);
e29a75fd
BJ
155 if (chdir("..") < 0) {
156 (void) sprintf(index(base, 0), "/..");
157 perror(base);
158 exit(1);
ca4a89e1 159 }
e29a75fd 160 *ebase0 = 0;
905d30b9 161 return (blocks);
ca4a89e1 162}