xref: /original-bsd/bin/df/df.c (revision 2301fdfb)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif /* not lint */
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)df.c	5.3 (Berkeley) 01/10/88";
15 #endif /* not lint */
16 
17 #include <sys/param.h>
18 #include <sys/fs.h>
19 #include <sys/stat.h>
20 #include <errno.h>
21 
22 #include <stdio.h>
23 #include <fstab.h>
24 #include <mtab.h>
25 
26 /*
27  * df
28  */
29 struct	mtab mtab[NMOUNT];
30 char	root[32];
31 char	*mpath();
32 
33 int	iflag;
34 
35 union {
36 	struct fs iu_fs;
37 	char dummy[SBSIZE];
38 } sb;
39 #define sblock sb.iu_fs
40 
41 int	fi;
42 daddr_t	alloc();
43 char	*strcpy();
44 
45 main(argc, argv)
46 	int argc;
47 	char **argv;
48 {
49 	int i;
50 
51 	while (argc > 1 && argv[1][0]=='-') {
52 		switch (argv[1][1]) {
53 
54 		case 'i':
55 			iflag++;
56 			break;
57 
58 		default:
59 			fprintf(stderr, "usage: df [ -i ] [ filsys... ]\n");
60 			exit(0);
61 		}
62 		argc--, argv++;
63 	}
64 	i = open("/etc/mtab", 0);
65 	if (i >= 0) {
66 		(void) read(i, (char *)mtab, sizeof (mtab));
67 		(void) close(i);
68 	}
69 	sync();
70 	printf("Filesystem    kbytes    used   avail capacity");
71 	if (iflag)
72 		printf(" iused   ifree  %%iused");
73 	printf("  Mounted on\n");
74 	if (argc <= 1) {
75 		struct fstab *fsp;
76 
77 		if (setfsent() == 0)
78 			perror(FSTAB), exit(1);
79 		while (fsp = getfsent()) {
80 			if (strcmp(fsp->fs_type, FSTAB_RW) &&
81 			    strcmp(fsp->fs_type, FSTAB_RO) &&
82 			    strcmp(fsp->fs_type, FSTAB_RQ))
83 				continue;
84 			if (root[0] == 0)
85 				(void) strcpy(root, fsp->fs_spec);
86 			dfree(fsp->fs_spec, 1);
87 		}
88 		(void)endfsent();
89 		exit(0);
90 	}
91 	for (i=1; i<argc; i++)
92 		dfree(argv[i], 0);
93 }
94 
95 dfree(file, infsent)
96 	char *file;
97 	int infsent;
98 {
99 	long totalblks, availblks, avail, free, used;
100 	struct stat stbuf;
101 	struct fstab *fsp;
102 
103 	if (stat(file, &stbuf) == 0 &&
104 	    (stbuf.st_mode&S_IFMT) != S_IFCHR &&
105 	    (stbuf.st_mode&S_IFMT) != S_IFBLK) {
106 		if (infsent) {
107 			fprintf(stderr, "%s: screwy /etc/fstab entry\n", file);
108 			return;
109 		}
110 		(void)setfsent();
111 		while (fsp = getfsent()) {
112 			struct stat stb;
113 
114 			if (stat(fsp->fs_spec, &stb) == 0 &&
115 			    stb.st_rdev == stbuf.st_dev) {
116 				file = fsp->fs_spec;
117 				(void)endfsent();
118 				goto found;
119 			}
120 		}
121 		(void)endfsent();
122 		fprintf(stderr, "%s: mounted on unknown device\n", file);
123 		return;
124 	}
125 found:
126 	fi = open(file, 0);
127 	if (fi < 0) {
128 		perror(file);
129 		return;
130 	}
131 	if (bread((long)SBOFF, (char *)&sblock, SBSIZE) == 0) {
132 		(void) close(fi);
133 		return;
134 	}
135 	printf("%-12.12s", file);
136 	totalblks = sblock.fs_dsize;
137 	free = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
138 	    sblock.fs_cstotal.cs_nffree;
139 	used = totalblks - free;
140 	availblks = totalblks * (100 - sblock.fs_minfree) / 100;
141 	avail = availblks > used ? availblks - used : 0;
142 	printf("%8d%8d%8d", totalblks * sblock.fs_fsize / 1024,
143 	    used * sblock.fs_fsize / 1024, avail * sblock.fs_fsize / 1024);
144 	printf("%6.0f%%",
145 	    availblks == 0 ? 0.0 : (double) used / (double) availblks * 100.0);
146 	if (iflag) {
147 		int inodes = sblock.fs_ncg * sblock.fs_ipg;
148 		used = inodes - sblock.fs_cstotal.cs_nifree;
149 		printf("%8ld%8ld%6.0f%% ", used, sblock.fs_cstotal.cs_nifree,
150 		    inodes == 0 ? 0.0 : (double)used / (double)inodes * 100.0);
151 	} else
152 		printf("  ");
153 	printf("  %s\n", mpath(file));
154 	(void) close(fi);
155 }
156 
157 long lseek();
158 
159 bread(off, buf, cnt)
160 	long off;
161 	char *buf;
162 {
163 	int n;
164 	extern errno;
165 
166 	(void) lseek(fi, off, 0);
167 	if ((n=read(fi, buf, cnt)) != cnt) {
168 		/* probably a dismounted disk if errno == EIO */
169 		if (errno != EIO) {
170 			printf("\nread error off = %ld\n", off);
171 			printf("count = %d; errno = %d\n", n, errno);
172 		}
173 		return (0);
174 	}
175 	return (1);
176 }
177 
178 /*
179  * Given a name like /dev/rrp0h, returns the mounted path, like /usr.
180  */
181 char *
182 mpath(file)
183 	char *file;
184 {
185 	register struct mtab *mp;
186 
187 	if (eq(file, root))
188 		return ("/");
189 	for (mp = mtab; mp < mtab + NMOUNT; mp++)
190 		if (eq(file, mp->m_dname))
191 			return (mp->m_path);
192 	return "";
193 }
194 
195 eq(f1, f2)
196 	char *f1, *f2;
197 {
198 
199 	if (strncmp(f1, "/dev/", 5) == 0)
200 		f1 += 5;
201 	if (strncmp(f2, "/dev/", 5) == 0)
202 		f2 += 5;
203 	if (!strcmp(f1, f2))
204 		return (1);
205 	if (*f1 == 'r' && !strcmp(f1+1, f2))
206 		return (1);
207 	if (*f2 == 'r' && !strcmp(f1, f2+1))
208 		return (1);
209 	if (*f1 == 'r' && *f2 == 'r' && strcmp(f1+1, f2+1) == 0)
210 		return (1);
211 	return (0);
212 }
213