|
|
1.1 root 1: static char *sccsid = "@(#)df.c 4.6 (Berkeley) 7/8/81";
2: #include <stdio.h>
3: #include <fstab.h>
4: #include <sys/param.h>
5: #include <sys/filsys.h>
6: #include <sys/fblk.h>
7: #include <sys/stat.h>
8: /*
9: * df
10: */
11:
12: #define NFS 32 /* Max number of filesystems */
13:
14: #define KBYTE 1024
15:
16: struct mtab {
17: char path[FSNMLG];
18: char spec[FSNMLG];
19: } mtab[NFS];
20: struct stat stb;
21: int dev;
22: #define L10BS 6
23: #define L10IS 5
24: #define PCTFW 3
25: int DEVNMLG; /* length of longest device name */
26: int DIRNMLG; /* length of longest mount point name */
27:
28: char *mpath();
29:
30: daddr_t blkno = 1;
31:
32: int lflag;
33: int iflag;
34:
35: struct filsys sblock;
36:
37: int fi;
38: daddr_t alloc();
39:
40: main(argc, argv)
41: register int argc;
42: register char **argv;
43: {
44: register int i;
45: register int r = 0;
46:
47: while (argc > 1 && argv[1][0]=='-') {
48: switch(argv[1][1]) {
49:
50: case 'l':
51: lflag++;
52: break;
53:
54: case 'i':
55: iflag++;
56: break;
57:
58: default:
59: fprintf(stderr, "usage: df [-i] [-l] [filsys...]\n");
60: exit(0);
61: }
62: argc--, argv++;
63: }
64:
65: if ((i=open("/etc/mtab", 0)) >= 0) {
66: r = read(i, mtab, sizeof mtab); /* Probably returns short */
67: (void) close(i);
68: r /= sizeof mtab[0];
69: }
70: devlen(r); /* reads in all of /etc/fstab, too */
71: printf("%-*.*s %-*.*s %*.*s %*.*s %*.*s",
72: DIRNMLG, DIRNMLG, "dir",
73: DEVNMLG, DEVNMLG, "dev",
74: L10BS, L10BS, "kbytes",
75: L10BS, L10BS, "used",
76: L10BS, L10BS, "free");
77: if (lflag)
78: printf(" %*.*s", L10BS, L10BS, "hardway");
79: printf(" %*.*s", PCTFW + 1, PCTFW + 1, "%use");
80: if (iflag)
81: printf(" %*.*s %*.*s %*.*s",
82: L10IS, L10IS, "iused",
83: L10IS, L10IS, "ifree",
84: PCTFW + 1, PCTFW + 1, "%ino");
85: putchar('\n');
86: if(argc <= 1) {
87: for (i = 0; i < NFS && mtab[i].spec[0]; ++i)
88: dfree(mtab[i].path);
89: return (0);
90: }
91:
92: for(i=1; i<argc; i++)
93: dfree(argv[i]);
94: return (0);
95: }
96:
97: dfree(file)
98: char *file;
99: {
100: register daddr_t i;
101: register char *mp;
102: long blocks;
103: long free;
104: long used;
105: long hardway;
106: struct stat stbuf;
107: static char specbuf[FSNMLG + sizeof "/dev/"] = "/dev/";
108:
109: if(stat(file, &stbuf) == 0 && (stbuf.st_mode&S_IFMT) == S_IFDIR)
110: {
111: struct stat mstbuf;
112:
113: for (i = 0; i < NFS && mtab[i].spec[0]; ++i)
114: {
115: strcpy(&specbuf[5], mtab[i].spec);
116: if(!stat(specbuf, &mstbuf) && mstbuf.st_rdev == stbuf.st_dev)
117: {
118: file = specbuf;
119: break;
120: }
121: }
122: if (i == NFS || mtab[i].spec[0] == '\0')
123: {
124: fprintf(stderr, "%s mounted on unknown device\n", file);
125: return;
126: }
127: }
128: else
129: if (strncmp("/dev/", file, sizeof "/dev/" - 1) != 0)
130: strcpy(&specbuf[5], file), file = specbuf;
131: fi = open(file, 0);
132: if(fi < 0)
133: {
134: fprintf(stderr,"cannot open %s\n", file);
135: return;
136: }
137: fstat(fi, &stb);
138: dev = stb.st_rdev;
139: if (lflag)
140: sync();
141: bread(1L, (char *)&sblock, sizeof(sblock));
142: blocks = (long) sblock.s_fsize - (long)sblock.s_isize;
143: free = sblock.s_tfree;
144: used = blocks - free;
145: blocks *= BSIZE(dev) / KBYTE;
146: free *= BSIZE(dev) / KBYTE;
147: used *= BSIZE(dev) / KBYTE;
148: printf("%-*.*s %-*.*s %*ld %*ld %*ld",
149: DIRNMLG, DIRNMLG, mp = mpath(file),
150: DEVNMLG, DEVNMLG, file + sizeof "/dev",
151: L10BS, blocks, L10BS, used, L10BS, free);
152:
153: if (lflag) {
154: hardway = 0;
155: if(BITFS(dev))
156: hardway = alloc();
157: else
158: while(alloc())
159: hardway++;
160: hardway *= BSIZE(dev) / KBYTE;
161: printf(" %*ld", L10BS, free = hardway);
162: }
163: printf(" %*.0f%%",
164: PCTFW, blocks == 0 ?
165: 0.0 : (double) used / (double) blocks * 100.0);
166: if (iflag) {
167: int inodes = (sblock.s_isize - 2) * INOPB(dev);
168: used = inodes - sblock.s_tinode;
169: printf(" %*ld %*ld %*.0f%%",
170: L10IS, used,
171: L10IS, sblock.s_tinode,
172: PCTFW, inodes == 0 ?
173: 0.0 : (double) used / (double) inodes * 100.0);
174: }
175: printf("\n");
176: close(fi);
177: }
178:
179: daddr_t
180: alloc()
181: {
182: int i, j, n;
183: daddr_t b;
184: struct fblk buf;
185:
186: if(!BITFS(dev)) {
187: i = --sblock.s_nfree;
188: if(i<0 || i>=NICFREE) {
189: printf("bad free count, b=%D\n", blkno);
190: return(0);
191: }
192: b = sblock.s_free[i];
193: if(b == 0)
194: return(0);
195: if(b<sblock.s_isize || b>=sblock.s_fsize) {
196: printf("bad free block (%D)\n", b);
197: return(0);
198: }
199: if(sblock.s_nfree <= 0) {
200: bread(b, (char *)&buf, sizeof(buf));
201: blkno = b;
202: sblock.s_nfree = buf.df_nfree;
203: for(i=0; i<NICFREE; i++)
204: sblock.s_free[i] = buf.df_free[i];
205: }
206: return(b);
207: }
208: n = 0;
209: for(i = 0; i < BITMAP; i++)
210: for(j = 0; j < 32; j++) /* 32: bits per int */
211: if(sblock.s_bfree[i] & (1 << j))
212: n++;
213: return(n);
214: }
215:
216: bread(bno, buf, cnt)
217: daddr_t bno;
218: char *buf;
219: {
220: register int n;
221: extern errno;
222:
223: lseek(fi, bno<<BSHIFT(dev), 0);
224: if((n=read(fi, buf, cnt)) != cnt) {
225: printf("\nread error bno = %ld\n", bno);
226: printf("count = %d; errno = %d\n", n, errno);
227: exit(0);
228: }
229: }
230:
231: /*
232: * Given a name like /dev/rrp0h, returns the mounted path, like /usr.
233: */
234: char *mpath(file)
235: char *file;
236: {
237: register int i;
238:
239: for (i=0; i<NFS; i++)
240: if (eq(file, mtab[i].spec))
241: return mtab[i].path;
242: return "";
243: }
244:
245: eq(f1, f2)
246: char *f1, *f2;
247: {
248: if (strncmp(f1, "/dev/", 5) == 0)
249: f1 += 5;
250: if (strncmp(f2, "/dev/", 5) == 0)
251: f2 += 5;
252: if (strcmp(f1, f2) == 0)
253: return 1;
254: if (*f1 == 'r' && strcmp(f1+1, f2) == 0)
255: return 1;
256: if (*f2 == 'r' && strcmp(f1, f2+1) == 0)
257: return 1;
258: if (*f1 == 'r' && *f2 == 'r' && strcmp(f1+1, f2+1) == 0)
259: return 1;
260: return 0;
261: }
262:
263: mtabcmp(mp0, mp1)
264: struct mtab *mp0;
265: struct mtab *mp1;
266: {
267: /*
268: * don't let empty mtab slots sort to the front
269: * as dfree will break
270: * the wrong way to fix it: the whole algorithm is wrong
271: */
272: if (mp0->path[0] == 0)
273: return (1);
274: if (mp1->path[0] == 0)
275: return (-1);
276: return (strncmp(mp0->path, mp1->path, sizeof (mp0->path)));
277: }
278:
279: devlen(r)
280: register int r;
281: {
282: register struct fstab *fsp;
283: register int i;
284:
285: DEVNMLG = 0;
286: DIRNMLG = 0;
287: if (setfsent() == 0)
288: perror(FSTAB), exit(1);
289: while( (fsp = getfsent()) != 0){
290: if ( (strcmp(fsp->fs_type, FSTAB_RW) != 0)
291: &&(strcmp(fsp->fs_type, FSTAB_RO) != 0) )
292: continue;
293: for (i = 0; mtab[i].spec[0]; ++i)
294: {
295: if (strncmp(mtab[i].spec, fsp->fs_spec + 5,
296: sizeof fsp->fs_spec - 5) == 0)
297: break;
298: }
299: if (i == r && i < NFS)
300: {
301: strncpy(mtab[r].spec, fsp->fs_spec + 5,
302: sizeof fsp->fs_spec - 5);
303: strncpy(mtab[r].path, fsp->fs_file, sizeof fsp->fs_file);
304: ++r;
305: }
306: if (DEVNMLG < (i = strlen(fsp->fs_spec)))
307: DEVNMLG = i;
308: if (DIRNMLG < (i = strlen(fsp->fs_file)))
309: DIRNMLG = i;
310: }
311: endfsent();
312: DEVNMLG -= sizeof "/dev";
313: if (DEVNMLG < sizeof "dev" - 1)
314: DEVNMLG = sizeof "dev" - 1;
315: if (DIRNMLG < sizeof "dir" - 1)
316: DIRNMLG = sizeof "dir" - 1;
317: qsort(&mtab[0], r, sizeof mtab[0], mtabcmp);
318: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.