|
|
1.1 root 1: /*
2: * Copyright (c) 1989 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Chris Newcomb.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that: (1) source distributions retain this entire copyright
10: * notice and comment, and (2) distributions including binaries display
11: * the following acknowledgement: ``This product includes software
12: * developed by the University of California, Berkeley and its contributors''
13: * in the documentation or other materials provided with the distribution
14: * and in all advertising materials mentioning features or use of this
15: * software. Neither the name of the University nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: char copyright[] =
25: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
26: All rights reserved.\n";
27: #endif /* not lint */
28:
29: #ifndef lint
30: static char sccsid[] = "@(#)du.c 5.6 (Berkeley) 6/1/90";
31: #endif /* not lint */
32:
33: #include <sys/param.h>
34: #include <sys/stat.h>
35: #include <dirent.h>
36: #include <string.h>
37: #include <stdio.h>
38:
39: typedef struct _ID {
40: dev_t dev;
41: ino_t inode;
42: } ID;
43:
44: ID *files;
45: dev_t device;
46: int crossmounts, kvalue, listdirs, listfiles, maxfiles, numfiles;
47: char path[MAXPATHLEN + 1];
48:
49: main(argc, argv)
50: int argc;
51: char **argv;
52: {
53: extern int optind, errno;
54: int ch;
55: char *malloc(), top[MAXPATHLEN + 1];
56:
57: listdirs = crossmounts = 1;
58: while ((ch = getopt(argc, argv, "aksx")) != EOF)
59: switch(ch) {
60: case 'a':
61: listfiles = 1;
62: break;
63: case 'k':
64: kvalue = 1;
65: break;
66: case 's':
67: listfiles = listdirs = 0;
68: break;
69: case 'x':
70: crossmounts = 0;
71: break;
72: case '?':
73: default:
74: (void)fprintf(stderr,
75: "usage: du [-aksx] [name ...]\n");
76: exit(1);
77: }
78: argv += optind;
79:
80: files = (ID *)malloc((u_int)(sizeof(ID) * (maxfiles = 128)));
81:
82: if (!*argv)
83: du(".");
84: else {
85: if (argv[1])
86: (void)getwd(top);
87: for (;;) {
88: du(*argv);
89: if (!*++argv)
90: break;
91: if (chdir(top)) {
92: (void)fprintf(stderr, "du: %s: %s\n",
93: top, strerror(errno));
94: exit(1);
95: }
96: }
97: }
98: exit(0);
99: }
100:
101: struct stat info;
102:
103: du(arg)
104: register char *arg;
105: {
106: extern int errno;
107: u_long total, descend();
108:
109: if (lstat(arg, &info)) {
110: (void)fprintf(stderr, "du: %s: %s\n", arg, strerror(errno));
111: return;
112: }
113: if ((info.st_mode&S_IFMT) != S_IFDIR) {
114: (void)printf("%ld\t%s\n", kvalue ?
115: howmany(info.st_blocks, 2) : info.st_blocks, arg);
116: return;
117: }
118: device = info.st_dev;
119: (void)strcpy(path, arg);
120: total = descend(path);
121: if (!listfiles && !listdirs)
122: (void)printf("%lu\t%s\n",
123: kvalue ? howmany(total, 2) : total, path);
124: }
125:
126: u_long
127: descend(endp)
128: register char *endp;
129: {
130: extern int errno;
131: register DIR *dir;
132: register ID *fp;
133: register struct dirent *dp;
134: u_long total;
135: char *realloc();
136:
137: if (info.st_nlink > 1) {
138: for (fp = files + numfiles - 1; fp >= files; --fp)
139: if (info.st_ino == fp->inode &&
140: info.st_dev == fp->dev)
141: return(0L);
142: if (numfiles == maxfiles)
143: files = (ID *)realloc((char *)files,
144: (u_int)(sizeof(ID) * (maxfiles += 128)));
145: files[numfiles].inode = info.st_ino;
146: files[numfiles].dev = info.st_dev;
147: ++numfiles;
148: }
149: total = info.st_blocks;
150: if ((info.st_mode&S_IFMT) == S_IFDIR) {
151: if (info.st_dev != device && !crossmounts)
152: return(0L);
153: if (chdir(endp) || !(dir = opendir("."))) {
154: (void)fprintf(stderr, "du: %s: %s\n",
155: path, strerror(errno));
156: return(total);
157: }
158: for (; *endp; ++endp);
159: if (endp[-1] != '/')
160: *endp++ = '/';
161: while (dp = readdir(dir)) {
162: if (dp->d_name[0] == '.' && (!dp->d_name[1] ||
163: dp->d_name[1] == '.' && !dp->d_name[2]))
164: continue;
165: bcopy(dp->d_name, endp, dp->d_namlen + 1);
166: if (lstat(dp->d_name, &info)) {
167: (void)fprintf(stderr, "du: %s: %s\n", path,
168: strerror(errno));
169: continue;
170: }
171: total += descend(endp);
172: }
173: closedir(dir);
174: if (chdir("..")) {
175: (void)fprintf(stderr, "du: ..: %s\n", strerror(errno));
176: exit(1);
177: }
178: *--endp = '\0';
179: if (listdirs)
180: (void)printf("%lu\t%s\n",
181: kvalue ? howmany(total, 2) : total, path);
182: }
183: else if (listfiles)
184: (void)printf("%lu\t%s\n",
185: kvalue ? howmany(total, 2) : total, path);
186: return(total);
187: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.