miscellaneous minor fixups
[unix-history] / usr / src / bin / df / df.c
CommitLineData
df3e00cc 1static char *sccsid = "@(#)df.c 4.4 (Berkeley) %G%";
c7b72342
BJ
2#include <stdio.h>
3#include <fstab.h>
4#include <sys/param.h>
5#include <sys/filsys.h>
6#include <sys/fblk.h>
8d335f7d
BJ
7#include <sys/stat.h>
8/*
9 * df
10 */
c7b72342
BJ
11
12#define NFS 20 /* Max number of filesystems */
13
c7b72342
BJ
14struct {
15 char path[32];
16 char spec[32];
17} mtab[NFS];
18char root[32];
19
20char *mpath();
21
22daddr_t blkno = 1;
23
24int lflag;
25int iflag;
26
27struct filsys sblock;
28
29int fi;
30daddr_t alloc();
31
32main(argc, argv)
33char **argv;
34{
35 int i;
c7b72342 36 char buf[128];
c7b72342
BJ
37
38 while (argc >= 1 && argv[1][0]=='-') {
39 switch(argv[1][1]) {
40
41 case 'l':
42 lflag++;
43 break;
44
45 case 'i':
46 iflag++;
47 break;
48
49 default:
50 fprintf(stderr, "usage: df [ -il ] [ filsys... ]\n");
51 exit(0);
52 }
53 argc--, argv++;
54 }
55
56 if ((i=open("/etc/mtab", 0)) >= 0) {
57 read(i, mtab, sizeof mtab); /* Probably returns short */
58 close(i);
59 }
60 printf("Filesystem Mounted on blocks\t used\t free");
61 if (lflag)
62 printf("\thardway");
63 printf("\t%% used");
64 if (iflag)
65 printf("\tiused\tifree\t%%iused");
66 putchar('\n');
67 if(argc <= 1) {
8d335f7d
BJ
68 struct fstab *fsp;
69 if (setfsent() == 0)
c7b72342 70 perror(FSTAB), exit(1);
8d335f7d
BJ
71 while( (fsp = getfsent()) != 0){
72 if ( (strcmp(fsp->fs_type, FSTAB_RW) != 0)
73 &&(strcmp(fsp->fs_type, FSTAB_RO) != 0) )
f0861f40 74 continue;
c7b72342 75 if (root[0] == 0)
8d335f7d
BJ
76 strcpy(root, fsp->fs_spec);
77 dfree(fsp->fs_spec);
c7b72342 78 }
8d335f7d 79 endfsent();
c7b72342
BJ
80 exit(0);
81 }
82
c7b72342
BJ
83 for(i=1; i<argc; i++) {
84 dfree(argv[i]);
85 }
86}
87
88dfree(file)
89char *file;
90{
91 daddr_t i;
92 long blocks;
93 long free;
94 long used;
95 long hardway;
96 char *mp;
8d335f7d
BJ
97 struct stat stbuf;
98
99 if(stat(file, &stbuf) == 0 && (stbuf.st_mode&S_IFMT) != S_IFCHR
100 && (stbuf.st_mode&S_IFMT) != S_IFBLK) {
101 int mt = open("/etc/mtab", 0), len;
102 char *str = "/dev/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
103 char mtab[32];
104 struct stat mstbuf;
105 while((len = read(mt, mtab, 32)) == 32) {
106 read(mt, &str[5], 32);
107 if(stat(str, &mstbuf) == 0 && mstbuf.st_rdev == stbuf.st_dev) {
108 file = str;
109 break;
110 }
111 }
112 close(mt);
113 if(len == 0) {
114 fprintf(stderr, "%s: mounted on unknown device\n", file);
115 return;
116 }
117 }
c7b72342
BJ
118 fi = open(file, 0);
119 if(fi < 0) {
120 fprintf(stderr,"cannot open %s\n", file);
121 return;
122 }
123 sync();
124 bread(1L, (char *)&sblock, sizeof(sblock));
125 printf("%-12.12s%s", file, mp = mpath(file));
126 if (strlen(mp) < 4)
127 putchar('\t');
128
129 blocks = (long) sblock.s_fsize - (long)sblock.s_isize;
130 free = sblock.s_tfree;
131 used = blocks - free;
132
133 printf("\t%6ld", blocks);
134 printf("\t%6ld", used);
135 printf("\t%6ld", free);
136 if (lflag) {
137 hardway = 0;
138 while(alloc())
139 hardway++;
140 printf("\t%6ld", free=hardway);
141 }
df3e00cc
BJ
142 printf("\t%5.0f%%",
143 blocks == 0 ? 0.0 : (double) used / (double)blocks * 100.0);
c7b72342
BJ
144 if (iflag) {
145 int inodes = (sblock.s_isize - 2) * INOPB;
146 used = inodes - sblock.s_tinode;
df3e00cc
BJ
147 printf("\t%5ld\t%5ld\t%5.0f%%", used, sblock.s_tinode,
148 inodes == 0 ? 0.0 : (double)used/(double)inodes*100.0);
c7b72342
BJ
149 }
150 printf("\n");
151 close(fi);
152}
153
154daddr_t
155alloc()
156{
157 int i;
158 daddr_t b;
159 struct fblk buf;
160
161 i = --sblock.s_nfree;
162 if(i<0 || i>=NICFREE) {
163 printf("bad free count, b=%D\n", blkno);
164 return(0);
165 }
166 b = sblock.s_free[i];
167 if(b == 0)
168 return(0);
169 if(b<sblock.s_isize || b>=sblock.s_fsize) {
170 printf("bad free block (%D)\n", b);
171 return(0);
172 }
173 if(sblock.s_nfree <= 0) {
174 bread(b, (char *)&buf, sizeof(buf));
175 blkno = b;
176 sblock.s_nfree = buf.df_nfree;
177 for(i=0; i<NICFREE; i++)
178 sblock.s_free[i] = buf.df_free[i];
179 }
180 return(b);
181}
182
183bread(bno, buf, cnt)
184daddr_t bno;
185char *buf;
186{
187 int n;
188 extern errno;
189
190 lseek(fi, bno<<BSHIFT, 0);
191 if((n=read(fi, buf, cnt)) != cnt) {
192 printf("\nread error bno = %ld\n", bno);
193 printf("count = %d; errno = %d\n", n, errno);
194 exit(0);
195 }
196}
197
198/*
199 * Given a name like /dev/rrp0h, returns the mounted path, like /usr.
200 */
201char *mpath(file)
202char *file;
203{
204 register int i;
205
206 if (eq(file, root))
207 return "/";
208 for (i=0; i<NFS; i++)
209 if (eq(file, mtab[i].spec))
210 return mtab[i].path;
211 return "";
212}
213
214eq(f1, f2)
215char *f1, *f2;
216{
217 if (strncmp(f1, "/dev/", 5) == 0)
218 f1 += 5;
219 if (strncmp(f2, "/dev/", 5) == 0)
220 f2 += 5;
221 if (strcmp(f1, f2) == 0)
222 return 1;
223 if (*f1 == 'r' && strcmp(f1+1, f2) == 0)
224 return 1;
225 if (*f2 == 'r' && strcmp(f1, f2+1) == 0)
226 return 1;
227 if (*f1 == 'r' && *f2 == 'r' && strcmp(f1+1, f2+1) == 0)
228 return 1;
229 return 0;
230}