|
|
1.1 root 1: #include <stdio.h>
2: #include <fstab.h>
3: #include <libc.h>
4: #include <sys/param.h>
5: #include <sys/filsys.h>
6: #include <sys/stat.h>
7: /*
8: * df
9: */
10:
11: #define NFS 64 /* Max number of filesystems */
12:
13: struct mtab mtab[NFS];
14: int nmtab;
15: #define L10BS 7
16: #define L10IS 6
17: #define PCTFW 3
18: int DEVNMLG = 3; /* length of longest device name */
19: int DIRNMLG = 3; /* length of longest mount point name */
20:
21: #define BUNIT 1024 /* report in units of this size */
22:
23: char *mpath();
24:
25: int iflag;
26: struct filsys sblock;
27: int fi;
28:
29: main(argc, argv)
30: register int argc;
31: register char **argv;
32: {
33: register int i;
34:
35: nochk(1,0); /* for secure unix */
36: nochk(2,0);
37: while (argc >= 1 && argv[1][0]=='-') {
38: switch(argv[1][1]) {
39:
40: case 'i':
41: iflag++;
42: break;
43:
44: default:
45: fprintf(stderr, "usage: df [-i] [filsys...]\n");
46: exit(0);
47: }
48: argc--, argv++;
49: }
50: readtab();
51: printf("%-*.*s %-*.*s %*.*s %*.*s %*.*s",
52: DIRNMLG, DIRNMLG, "dir",
53: DEVNMLG, DEVNMLG, "dev",
54: L10BS, L10BS, "kbytes",
55: L10BS, L10BS, "used",
56: L10BS, L10BS, "free");
57: printf(" %*.*s", PCTFW + 1, PCTFW + 1, "%use");
58: if (iflag)
59: printf(" %*.*s %*.*s %*.*s",
60: L10IS, L10IS, "iused",
61: L10IS, L10IS, "ifree",
62: PCTFW + 1, PCTFW + 1, "%ino");
63: putchar('\n');
64: if(argc <= 1) {
65: for (i = 0; i < nmtab; ++i)
66: dfree(mtab[i].spec);
67: exit(0);
68: }
69: for(i=1; i<argc; i++)
70: dfree(argv[i]);
71: exit(0);
72: }
73:
74: dfree(file)
75: char *file;
76: {
77: register daddr_t i;
78: long blocks;
79: long free;
80: long used;
81: struct stat stbuf;
82: dev_t dev;
83: char *spec;
84:
85: if (stat(file, &stbuf) < 0) {
86: perror(file);
87: return;
88: }
89: if ((stbuf.st_mode & S_IFMT) == S_IFBLK)
90: spec = file;
91: else {
92: dev = stbuf.st_dev;
93: for (i = 0; i < nmtab; i++) {
94: spec = mtab[i].spec;
95: if (stat(spec, &stbuf) < 0)
96: continue;
97: if (stbuf.st_rdev == dev)
98: break;
99: }
100: if (i == nmtab) {
101: fprintf(stderr, "%s: can't find filesystem\n", file);
102: return;
103: }
104: }
105: if((fi = open(spec, 0)) < 0) {
106: perror(spec); /* but we already did a stat! */
107: return;
108: }
109: lseek(fi, SUPERB*BSIZE(stbuf.st_rdev), 0);
110: if (read(fi, (char *)&sblock, sizeof(sblock)) != sizeof(sblock)) {
111: perror(spec);
112: memset((char *)&sblock, 0, sizeof(sblock));
113: }
114: blocks = (long) sblock.s_fsize - (long)sblock.s_isize;
115: free = sblock.s_tfree;
116: used = blocks - free;
117: blocks *= BSIZE(stbuf.st_rdev) / BUNIT;
118: free *= BSIZE(stbuf.st_rdev) / BUNIT;
119: used *= BSIZE(stbuf.st_rdev) / BUNIT;
120: printf("%-*.*s %-*.*s %*ld %*ld %*ld",
121: DIRNMLG, DIRNMLG, mpath(spec),
122: DEVNMLG, DEVNMLG, spec,
123: L10BS, blocks, L10BS, used, L10BS, free);
124: printf(" %*.0f%%",
125: PCTFW, blocks == 0 ?
126: 0.0 : (double) used / (double) blocks * 100.0);
127: if (iflag) {
128: int inodes = (sblock.s_isize - 2) * INOPB(stbuf.st_rdev);
129: used = inodes - sblock.s_tinode;
130: printf(" %*ld %*ld %*.0f%%",
131: L10IS, used,
132: L10IS, sblock.s_tinode,
133: PCTFW, inodes == 0 ?
134: 0.0 : (double) used / (double) inodes * 100.0);
135: }
136: printf("\n");
137: close(fi);
138: }
139:
140: /*
141: * Given a name like /dev/rp0h, returns the mount point, like /usr.
142: */
143: char *mpath(spec)
144: char *spec;
145: {
146: register int i;
147:
148: for (i=0; i<nmtab; i++)
149: if (strcmp(spec, mtab[i].spec) == 0)
150: return mtab[i].file;
151: return "";
152: }
153:
154: /*
155: * hack: uninteresting mtab slots (empty or not type 0)
156: * always sort to the end. they were also omitted from the count.
157: * hence they are ignored.
158: */
159: mtabcmp(mp0, mp1)
160: struct mtab *mp0;
161: struct mtab *mp1;
162: {
163: if (mp0->file[0] == 0 || mp0->type != 0)
164: return (1);
165: if (mp1->file[0] == 0 || mp1->type != 0)
166: return (-1);
167: return (strncmp(mp0->file, mp1->file, sizeof (mp0->file)));
168: }
169:
170: /*
171: * read the list of filesystems, and sort it
172: * assumes type 0 is the only interesting filesystem
173: */
174: readtab()
175: {
176: register int i, n;
177: int f;
178: register struct fstab *fsp;
179:
180: mtab[0].file[0] = '/';
181: /*
182: * cheap hack because root isn't in mtab
183: */
184: if ((fsp = getfsfile(mtab[0].file)) != NULL)
185: strcpy(mtab[0].spec, fsp->fs_spec);
186: if ((f = open(MTAB, 0)) < 0) {
187: nmtab = 1;
188: return;
189: }
190: n = read(f, (char *)&mtab[1], sizeof(mtab)-sizeof(mtab[0]));
191: close(f);
192: n /= sizeof(mtab[0]);
193: nmtab = 0;
194: for (i = 0; i <= n; i++) {
195: if (mtab[i].file[0] == 0 || mtab[i].type != 0)
196: continue;
197: nmtab++;
198: if (DEVNMLG < (f = strlen(mtab[i].spec)))
199: DEVNMLG = f;
200: if (DIRNMLG < (f = strlen(mtab[i].file)))
201: DIRNMLG = f;
202: }
203: qsort((char *)&mtab[0], n+1, sizeof(mtab[0]), mtabcmp);
204: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.