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