add additional flags parameter to getfsstat
[unix-history] / usr / src / bin / df / df.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18#ifndef lint
19char copyright[] =
20"@(#) Copyright (c) 1980 The Regents of the University of California.\n\
21 All rights reserved.\n";
22#endif /* not lint */
23
24#ifndef lint
25static char sccsid[] = "@(#)df.c 5.14 (Berkeley) %G%";
26#endif /* not lint */
27
28/*
29 * df
30 */
31#include <sys/param.h>
32#include <sys/stat.h>
33#include <sys/mount.h>
34#include <sys/file.h>
35#include <stdio.h>
36#include <strings.h>
37#include <unistd.h>
38
39char *getmntpt();
40int iflag, kflag;
41#ifdef COMPAT_43
42int oflag;
43#endif /* COMPAT_43 */
44
45main(argc, argv)
46 int argc;
47 char **argv;
48{
49 extern int errno, optind;
50 int err, ch, i;
51 long mntsize, getmntinfo();
52 char *mntpt, *mktemp();
53 struct stat stbuf;
54 struct statfs statfsbuf, *mntbuf;
55 struct ufs_args mdev;
56
57 while ((ch = getopt(argc, argv, "iko")) != EOF)
58 switch(ch) {
59 case 'i':
60 iflag = 1;
61 break;
62 case 'k':
63 kflag = 1;
64 break;
65#ifdef COMPAT_43
66 case 'o':
67 oflag = 1;
68 break;
69#endif /* COMPAT_43 */
70 case '?':
71 default:
72 fprintf(stderr,
73 "usage: df [-ik] [file | file_system ...]\n");
74 exit(1);
75 }
76 argc -= optind;
77 argv += optind;
78
79 printf("Filesystem %s used avail capacity",
80 kflag ? " kbytes" : "512-blks");
81 if (iflag)
82 printf(" iused ifree %%iused");
83 printf(" Mounted on\n");
84#ifdef COMPAT_43
85 if (oflag) {
86 olddf(argv);
87 exit(0);
88 }
89#endif /* COMPAT_43 */
90 if (!*argv) {
91 mntsize = getmntinfo(&mntbuf);
92 for (i = 0; i < mntsize; i++)
93 prtstat(&mntbuf[i]);
94 exit(0);
95 }
96 for (; *argv; argv++) {
97 if (stat(*argv, &stbuf) < 0) {
98 err = errno;
99 if ((mntpt = getmntpt(*argv)) == 0) {
100 fprintf(stderr, "df: %s: %s\n", *argv,
101 strerror(err));
102 continue;
103 }
104 } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
105 if ((mntpt = getmntpt(*argv)) == 0)
106 mntpt = mktemp("/df.XXXXXX");
107 mdev.fspec = *argv;
108 if (!mkdir(mntpt) &&
109 !mount(MOUNT_UFS, mntpt, M_RDONLY, &mdev) &&
110 !statfs(mntpt, &statfsbuf)) {
111 statfsbuf.f_mntonname[0] = '\0';
112 prtstat(&statfsbuf);
113 } else
114 fprintf(stderr, "df: %s: %s\n",
115 *argv, strerror(errno));
116 (void)unmount(mntpt, MNT_NOFORCE);
117 (void)rmdir(mntpt);
118 continue;
119 } else
120 mntpt = *argv;
121 if (statfs(mntpt, &statfsbuf) < 0) {
122 fprintf(stderr,
123 "df: %s: %s\n", mntpt, strerror(errno));
124 continue;
125 }
126 prtstat(&statfsbuf);
127 }
128 exit(0);
129}
130
131char *
132getmntpt(name)
133 char *name;
134{
135 long mntsize, i;
136 struct statfs *mntbuf;
137
138 mntsize = getmntinfo(&mntbuf);
139 for (i = 0; i < mntsize; i++) {
140 if (!strcmp(mntbuf[i].f_mntfromname, name))
141 return (mntbuf[i].f_mntonname);
142 }
143 return (0);
144}
145
146/*
147 * Print out status about a filesystem.
148 */
149prtstat(sfsp)
150 register struct statfs *sfsp;
151{
152 long used, availblks, inodes;
153
154 printf("%-12.12s", sfsp->f_mntfromname);
155 used = sfsp->f_blocks - sfsp->f_bfree;
156 availblks = sfsp->f_bavail + used;
157 printf("%8ld%8ld%8ld",
158 sfsp->f_blocks * sfsp->f_fsize / (kflag ? 1024 : 512),
159 used * sfsp->f_fsize / (kflag ? 1024 : 512),
160 sfsp->f_bavail * sfsp->f_fsize / (kflag ? 1024 : 512));
161 printf("%6.0f%%",
162 availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
163 if (iflag) {
164 inodes = sfsp->f_files;
165 used = inodes - sfsp->f_ffree;
166 printf("%8ld%8ld%6.0f%% ", used, sfsp->f_ffree,
167 inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
168 } else
169 printf(" ");
170 printf(" %s\n", sfsp->f_mntonname);
171}
172
173#ifdef COMPAT_43
174/*
175 * This code constitutes the old df code for extracting
176 * information from filesystem superblocks.
177 */
178#include <ufs/fs.h>
179#include <errno.h>
180#include <fstab.h>
181
182char root[MAXPATHLEN];
183
184union {
185 struct fs iu_fs;
186 char dummy[SBSIZE];
187} sb;
188#define sblock sb.iu_fs
189
190int fi;
191char *strcpy();
192
193olddf(argv)
194 char *argv[];
195{
196 struct fstab *fsp;
197
198 sync();
199 if (!*argv) {
200 if (setfsent() == 0)
201 perror(_PATH_FSTAB), exit(1);
202 while (fsp = getfsent()) {
203 if (strcmp(fsp->fs_type, FSTAB_RW) &&
204 strcmp(fsp->fs_type, FSTAB_RO) &&
205 strcmp(fsp->fs_type, FSTAB_RQ))
206 continue;
207 if (root[0] == 0)
208 (void) strcpy(root, fsp->fs_spec);
209 dfree(fsp->fs_spec, 1);
210 }
211 (void)endfsent();
212 exit(0);
213 }
214 while (*argv)
215 dfree(*argv++, 0);
216 exit(0);
217}
218
219dfree(file, infsent)
220 char *file;
221 int infsent;
222{
223 extern int errno;
224 struct stat stbuf;
225 struct statfs statfsbuf;
226 register struct statfs *sfsp;
227 struct fstab *fsp;
228 char *mntpt;
229
230 if (stat(file, &stbuf) == 0 &&
231 (stbuf.st_mode&S_IFMT) != S_IFCHR &&
232 (stbuf.st_mode&S_IFMT) != S_IFBLK) {
233 if (infsent) {
234 fprintf(stderr, "df: %s: screwy fstab entry\n", file);
235 return;
236 }
237 (void)setfsent();
238 while (fsp = getfsent()) {
239 struct stat stb;
240
241 if (stat(fsp->fs_spec, &stb) == 0 &&
242 stb.st_rdev == stbuf.st_dev) {
243 file = fsp->fs_spec;
244 (void)endfsent();
245 goto found;
246 }
247 }
248 (void)endfsent();
249 fprintf(stderr, "df: %s: mounted on unknown device\n", file);
250 return;
251 }
252found:
253 if ((fi = open(file, O_RDONLY)) < 0) {
254 fprintf(stderr, "df: %s: %s\n", file, strerror(errno));
255 return;
256 }
257 if (bread((long)SBOFF, (char *)&sblock, SBSIZE) == 0) {
258 (void) close(fi);
259 return;
260 }
261 sfsp = &statfsbuf;
262 sfsp->f_type = MOUNT_UFS;
263 sfsp->f_flags = 0;
264 sfsp->f_fsize = sblock.fs_fsize;
265 sfsp->f_bsize = sblock.fs_bsize;
266 sfsp->f_blocks = sblock.fs_dsize;
267 sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
268 sblock.fs_cstotal.cs_nffree;
269 sfsp->f_bavail = (sblock.fs_dsize * (100 - sblock.fs_minfree) / 100) -
270 (sblock.fs_dsize - sfsp->f_bfree);
271 if (sfsp->f_bavail < 0)
272 sfsp->f_bavail = 0;
273 sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg;
274 sfsp->f_ffree = sblock.fs_cstotal.cs_nifree;
275 sfsp->f_fsid.val[0] = 0;
276 sfsp->f_fsid.val[1] = 0;
277 if ((mntpt = getmntpt(file)) == 0)
278 mntpt = "";
279 bcopy((caddr_t)mntpt, (caddr_t)&sfsp->f_mntonname[0], MNAMELEN);
280 bcopy((caddr_t)file, (caddr_t)&sfsp->f_mntfromname[0], MNAMELEN);
281 prtstat(sfsp);
282 (void) close(fi);
283}
284
285long lseek();
286
287bread(off, buf, cnt)
288 long off;
289 char *buf;
290{
291 int n;
292 extern errno;
293
294 (void) lseek(fi, off, SEEK_SET);
295 if ((n=read(fi, buf, cnt)) != cnt) {
296 /* probably a dismounted disk if errno == EIO */
297 if (errno != EIO) {
298 printf("\nread error off = %ld\n", off);
299 printf("count = %d; errno = %d\n", n, errno);
300 }
301 return (0);
302 }
303 return (1);
304}
305#endif /* COMPAT_43 */