xref: /freebsd/bin/df/df.c (revision 7f0eabfd0a2d683c310017254ac58daee048bf2d)
14b88c807SRodney W. Grimes /*
24b88c807SRodney W. Grimes  * Copyright (c) 1980, 1990, 1993, 1994
34b88c807SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
44b88c807SRodney W. Grimes  * (c) UNIX System Laboratories, Inc.
54b88c807SRodney W. Grimes  * All or some portions of this file are derived from material licensed
64b88c807SRodney W. Grimes  * to the University of California by American Telephone and Telegraph
74b88c807SRodney W. Grimes  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
84b88c807SRodney W. Grimes  * the permission of UNIX System Laboratories, Inc.
94b88c807SRodney W. Grimes  *
104b88c807SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
114b88c807SRodney W. Grimes  * modification, are permitted provided that the following conditions
124b88c807SRodney W. Grimes  * are met:
134b88c807SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
144b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
154b88c807SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
164b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
174b88c807SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
184b88c807SRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
194b88c807SRodney W. Grimes  *    must display the following acknowledgement:
204b88c807SRodney W. Grimes  *	This product includes software developed by the University of
214b88c807SRodney W. Grimes  *	California, Berkeley and its contributors.
224b88c807SRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
234b88c807SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
244b88c807SRodney W. Grimes  *    without specific prior written permission.
254b88c807SRodney W. Grimes  *
264b88c807SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
274b88c807SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
284b88c807SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
294b88c807SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
304b88c807SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
314b88c807SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
324b88c807SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
334b88c807SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
344b88c807SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
354b88c807SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
364b88c807SRodney W. Grimes  * SUCH DAMAGE.
374b88c807SRodney W. Grimes  */
384b88c807SRodney W. Grimes 
394b88c807SRodney W. Grimes #ifndef lint
404b88c807SRodney W. Grimes static char copyright[] =
414b88c807SRodney W. Grimes "@(#) Copyright (c) 1980, 1990, 1993, 1994\n\
424b88c807SRodney W. Grimes 	The Regents of the University of California.  All rights reserved.\n";
434b88c807SRodney W. Grimes #endif /* not lint */
444b88c807SRodney W. Grimes 
454b88c807SRodney W. Grimes #ifndef lint
464b88c807SRodney W. Grimes static char sccsid[] = "@(#)df.c	8.7 (Berkeley) 4/2/94";
474b88c807SRodney W. Grimes #endif /* not lint */
484b88c807SRodney W. Grimes 
494b88c807SRodney W. Grimes #include <sys/param.h>
504b88c807SRodney W. Grimes #include <sys/stat.h>
514b88c807SRodney W. Grimes #include <sys/mount.h>
524b88c807SRodney W. Grimes 
534b88c807SRodney W. Grimes #include <err.h>
544b88c807SRodney W. Grimes #include <errno.h>
554b88c807SRodney W. Grimes #include <fcntl.h>
564b88c807SRodney W. Grimes #include <stdio.h>
574b88c807SRodney W. Grimes #include <stdlib.h>
584b88c807SRodney W. Grimes #include <string.h>
594b88c807SRodney W. Grimes #include <unistd.h>
604b88c807SRodney W. Grimes 
614b88c807SRodney W. Grimes /* XXX assumes MOUNT_MAXTYPE < 32 */
624b88c807SRodney W. Grimes #define MT(m)		(1 << (m))
634b88c807SRodney W. Grimes 
644b88c807SRodney W. Grimes /* fixed values */
654b88c807SRodney W. Grimes #define MT_NONE		(0)
664b88c807SRodney W. Grimes #define MT_ALL		(MT(MOUNT_MAXTYPE+1)-1)
674b88c807SRodney W. Grimes 
684b88c807SRodney W. Grimes /* subject to change */
694b88c807SRodney W. Grimes #define MT_LOCAL \
704b88c807SRodney W. Grimes     (MT(MOUNT_UFS)|MT(MOUNT_MFS)|MT(MOUNT_LFS)|MT(MOUNT_MSDOS)|MT(MOUNT_CD9660))
714b88c807SRodney W. Grimes #define MT_DEFAULT	MT_ALL
724b88c807SRodney W. Grimes 
734b88c807SRodney W. Grimes struct typetab {
744b88c807SRodney W. Grimes 	char *str;
754b88c807SRodney W. Grimes 	long types;
764b88c807SRodney W. Grimes } typetab[] = {
774b88c807SRodney W. Grimes 	"ufs",		MT(MOUNT_UFS),
784b88c807SRodney W. Grimes 	"local",	MT_LOCAL,
794b88c807SRodney W. Grimes 	"all",		MT_ALL,
804b88c807SRodney W. Grimes 	"nfs",		MT(MOUNT_NFS),
814b88c807SRodney W. Grimes 	"mfs",		MT(MOUNT_MFS),
824b88c807SRodney W. Grimes 	"lfs",		MT(MOUNT_LFS),
834b88c807SRodney W. Grimes 	"msdos",	MT(MOUNT_MSDOS),
844b88c807SRodney W. Grimes 	"fdesc",	MT(MOUNT_FDESC),
854b88c807SRodney W. Grimes 	"portal",	MT(MOUNT_PORTAL),
864b88c807SRodney W. Grimes #if 0
874b88c807SRodney W. Grimes 	/* return fsid of underlying FS */
884b88c807SRodney W. Grimes 	"lofs",		MT(MOUNT_LOFS),
894b88c807SRodney W. Grimes 	"null",		MT(MOUNT_NULL),
904b88c807SRodney W. Grimes 	"umap",		MT(MOUNT_UMAP),
914b88c807SRodney W. Grimes #endif
924b88c807SRodney W. Grimes 	"kernfs",	MT(MOUNT_KERNFS),
934b88c807SRodney W. Grimes 	"procfs",	MT(MOUNT_PROCFS),
944b88c807SRodney W. Grimes 	"afs",		MT(MOUNT_AFS),
954b88c807SRodney W. Grimes 	"iso9660fs",	MT(MOUNT_CD9660),
964b88c807SRodney W. Grimes 	"cdfs",		MT(MOUNT_CD9660),
974b88c807SRodney W. Grimes 	"misc",		MT(MOUNT_LOFS)|MT(MOUNT_FDESC)|MT(MOUNT_PORTAL)|
984b88c807SRodney W. Grimes 			MT(MOUNT_KERNFS)|MT(MOUNT_PROCFS),
994b88c807SRodney W. Grimes 	NULL,		0
1004b88c807SRodney W. Grimes };
1014b88c807SRodney W. Grimes 
1024b88c807SRodney W. Grimes long	addtype __P((long, char *));
1034b88c807SRodney W. Grimes long	regetmntinfo __P((struct statfs **, long, long));
1044b88c807SRodney W. Grimes int	 bread __P((off_t, void *, int));
1054b88c807SRodney W. Grimes char	*getmntpt __P((char *));
1064b88c807SRodney W. Grimes void	 prtstat __P((struct statfs *, int));
1074b88c807SRodney W. Grimes void	 ufs_df __P((char *, int));
1084b88c807SRodney W. Grimes void	 usage __P((void));
1094b88c807SRodney W. Grimes 
1104b88c807SRodney W. Grimes int	iflag, nflag, tflag;
1114b88c807SRodney W. Grimes struct	ufs_args mdev;
1124b88c807SRodney W. Grimes 
1134b88c807SRodney W. Grimes int
1144b88c807SRodney W. Grimes main(argc, argv)
1154b88c807SRodney W. Grimes 	int argc;
1164b88c807SRodney W. Grimes 	char *argv[];
1174b88c807SRodney W. Grimes {
1184b88c807SRodney W. Grimes 	struct stat stbuf;
1194b88c807SRodney W. Grimes 	struct statfs statfsbuf, *mntbuf;
1204b88c807SRodney W. Grimes 	long fsmask, mntsize;
1214b88c807SRodney W. Grimes 	int ch, err, i, maxwidth, width;
1224b88c807SRodney W. Grimes 	char *mntpt;
1234b88c807SRodney W. Grimes 
1247f0eabfdSGarrett Wollman 	while ((ch = getopt(argc, argv, "iknt:")) != EOF)
1254b88c807SRodney W. Grimes 		switch (ch) {
1264b88c807SRodney W. Grimes 		case 'i':
1274b88c807SRodney W. Grimes 			iflag = 1;
1284b88c807SRodney W. Grimes 			break;
1297f0eabfdSGarrett Wollman 		case 'k':
1307f0eabfdSGarrett Wollman 			putenv("BLOCKSIZE=1024");
1317f0eabfdSGarrett Wollman 			break;
1324b88c807SRodney W. Grimes 		case 'n':
1334b88c807SRodney W. Grimes 			nflag = 1;
1344b88c807SRodney W. Grimes 			break;
1354b88c807SRodney W. Grimes 		case 't':
1364b88c807SRodney W. Grimes 			fsmask = addtype(fsmask, optarg);
1374b88c807SRodney W. Grimes 			tflag = 1;
1384b88c807SRodney W. Grimes 			break;
1394b88c807SRodney W. Grimes 		case '?':
1404b88c807SRodney W. Grimes 		default:
1414b88c807SRodney W. Grimes 			usage();
1424b88c807SRodney W. Grimes 		}
1434b88c807SRodney W. Grimes 	argc -= optind;
1444b88c807SRodney W. Grimes 	argv += optind;
1454b88c807SRodney W. Grimes 
1464b88c807SRodney W. Grimes 	mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
1474b88c807SRodney W. Grimes 	maxwidth = 0;
1484b88c807SRodney W. Grimes 	for (i = 0; i < mntsize; i++) {
1494b88c807SRodney W. Grimes 		width = strlen(mntbuf[i].f_mntfromname);
1504b88c807SRodney W. Grimes 		if (width > maxwidth)
1514b88c807SRodney W. Grimes 			maxwidth = width;
1524b88c807SRodney W. Grimes 	}
1534b88c807SRodney W. Grimes 
1544b88c807SRodney W. Grimes 	if (!*argv) {
1554b88c807SRodney W. Grimes 		if (!tflag)
1564b88c807SRodney W. Grimes 			fsmask = MT_DEFAULT;
1574b88c807SRodney W. Grimes 		mntsize = regetmntinfo(&mntbuf, mntsize, fsmask);
1584b88c807SRodney W. Grimes 		if (fsmask != MT_ALL) {
1594b88c807SRodney W. Grimes 			maxwidth = 0;
1604b88c807SRodney W. Grimes 			for (i = 0; i < mntsize; i++) {
1614b88c807SRodney W. Grimes 				width = strlen(mntbuf[i].f_mntfromname);
1624b88c807SRodney W. Grimes 				if (width > maxwidth)
1634b88c807SRodney W. Grimes 					maxwidth = width;
1644b88c807SRodney W. Grimes 			}
1654b88c807SRodney W. Grimes 		}
1664b88c807SRodney W. Grimes 		for (i = 0; i < mntsize; i++)
1674b88c807SRodney W. Grimes 			prtstat(&mntbuf[i], maxwidth);
1684b88c807SRodney W. Grimes 		exit(0);
1694b88c807SRodney W. Grimes 	}
1704b88c807SRodney W. Grimes 
1714b88c807SRodney W. Grimes 	for (; *argv; argv++) {
1724b88c807SRodney W. Grimes 		if (stat(*argv, &stbuf) < 0) {
1734b88c807SRodney W. Grimes 			err = errno;
1744b88c807SRodney W. Grimes 			if ((mntpt = getmntpt(*argv)) == 0) {
1754b88c807SRodney W. Grimes 				warn("%s", *argv);
1764b88c807SRodney W. Grimes 				continue;
1774b88c807SRodney W. Grimes 			}
1784b88c807SRodney W. Grimes 		} else if ((stbuf.st_mode & S_IFMT) == S_IFCHR) {
1794b88c807SRodney W. Grimes 			ufs_df(*argv, maxwidth);
1804b88c807SRodney W. Grimes 			continue;
1814b88c807SRodney W. Grimes 		} else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
1824b88c807SRodney W. Grimes 			if ((mntpt = getmntpt(*argv)) == 0) {
1834b88c807SRodney W. Grimes 				mntpt = mktemp(strdup("/tmp/df.XXXXXX"));
1844b88c807SRodney W. Grimes 				mdev.fspec = *argv;
1854b88c807SRodney W. Grimes 				if (mkdir(mntpt, DEFFILEMODE) != 0) {
1864b88c807SRodney W. Grimes 					warn("%s", mntpt);
1874b88c807SRodney W. Grimes 					continue;
1884b88c807SRodney W. Grimes 				}
1894b88c807SRodney W. Grimes 				if (mount(MOUNT_UFS, mntpt, MNT_RDONLY,
1904b88c807SRodney W. Grimes 				    &mdev) != 0) {
1914b88c807SRodney W. Grimes 					ufs_df(*argv, maxwidth);
1924b88c807SRodney W. Grimes 					(void)rmdir(mntpt);
1934b88c807SRodney W. Grimes 					continue;
1944b88c807SRodney W. Grimes 				} else if (statfs(mntpt, &statfsbuf)) {
1954b88c807SRodney W. Grimes 					statfsbuf.f_mntonname[0] = '\0';
1964b88c807SRodney W. Grimes 					prtstat(&statfsbuf, maxwidth);
1974b88c807SRodney W. Grimes 				} else
1984b88c807SRodney W. Grimes 					warn("%s", *argv);
1994b88c807SRodney W. Grimes 				(void)unmount(mntpt, 0);
2004b88c807SRodney W. Grimes 				(void)rmdir(mntpt);
2014b88c807SRodney W. Grimes 				continue;
2024b88c807SRodney W. Grimes 			}
2034b88c807SRodney W. Grimes 		} else
2044b88c807SRodney W. Grimes 			mntpt = *argv;
2054b88c807SRodney W. Grimes 		/*
2064b88c807SRodney W. Grimes 		 * Statfs does not take a `wait' flag, so we cannot
2074b88c807SRodney W. Grimes 		 * implement nflag here.
2084b88c807SRodney W. Grimes 		 */
2094b88c807SRodney W. Grimes 		if (statfs(mntpt, &statfsbuf) < 0) {
2104b88c807SRodney W. Grimes 			warn("%s", mntpt);
2114b88c807SRodney W. Grimes 			continue;
2124b88c807SRodney W. Grimes 		}
2134b88c807SRodney W. Grimes 		if (argc == 1)
2144b88c807SRodney W. Grimes 			maxwidth = strlen(statfsbuf.f_mntfromname) + 1;
2154b88c807SRodney W. Grimes 		prtstat(&statfsbuf, maxwidth);
2164b88c807SRodney W. Grimes 	}
2174b88c807SRodney W. Grimes 	return (0);
2184b88c807SRodney W. Grimes }
2194b88c807SRodney W. Grimes 
2204b88c807SRodney W. Grimes char *
2214b88c807SRodney W. Grimes getmntpt(name)
2224b88c807SRodney W. Grimes 	char *name;
2234b88c807SRodney W. Grimes {
2244b88c807SRodney W. Grimes 	long mntsize, i;
2254b88c807SRodney W. Grimes 	struct statfs *mntbuf;
2264b88c807SRodney W. Grimes 
2274b88c807SRodney W. Grimes 	mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
2284b88c807SRodney W. Grimes 	for (i = 0; i < mntsize; i++) {
2294b88c807SRodney W. Grimes 		if (!strcmp(mntbuf[i].f_mntfromname, name))
2304b88c807SRodney W. Grimes 			return (mntbuf[i].f_mntonname);
2314b88c807SRodney W. Grimes 	}
2324b88c807SRodney W. Grimes 	return (0);
2334b88c807SRodney W. Grimes }
2344b88c807SRodney W. Grimes 
2354b88c807SRodney W. Grimes long
2364b88c807SRodney W. Grimes addtype(omask, str)
2374b88c807SRodney W. Grimes 	long omask;
2384b88c807SRodney W. Grimes 	char *str;
2394b88c807SRodney W. Grimes {
2404b88c807SRodney W. Grimes 	struct typetab *tp;
2414b88c807SRodney W. Grimes 
2424b88c807SRodney W. Grimes 	/*
2434b88c807SRodney W. Grimes 	 * If it is one of our known types, add it to the current mask
2444b88c807SRodney W. Grimes 	 */
2454b88c807SRodney W. Grimes 	for (tp = typetab; tp->str; tp++)
2464b88c807SRodney W. Grimes 		if (strcmp(str, tp->str) == 0)
2474b88c807SRodney W. Grimes 			return (tp->types | (tflag ? omask : MT_NONE));
2484b88c807SRodney W. Grimes 	/*
2494b88c807SRodney W. Grimes 	 * See if it is the negation of one of the known values
2504b88c807SRodney W. Grimes 	 */
2514b88c807SRodney W. Grimes 	if (strlen(str) > 2 && str[0] == 'n' && str[1] == 'o')
2524b88c807SRodney W. Grimes 		for (tp = typetab; tp->str; tp++)
2534b88c807SRodney W. Grimes 			if (strcmp(str+2, tp->str) == 0)
2544b88c807SRodney W. Grimes 				return (~tp->types & (tflag ? omask : MT_ALL));
2554b88c807SRodney W. Grimes 	errx(1, "unknown type `%s'", str);
2564b88c807SRodney W. Grimes }
2574b88c807SRodney W. Grimes 
2584b88c807SRodney W. Grimes /*
2594b88c807SRodney W. Grimes  * Make a pass over the filesystem info in ``mntbuf'' filtering out
2604b88c807SRodney W. Grimes  * filesystem types not in ``fsmask'' and possibly re-stating to get
2614b88c807SRodney W. Grimes  * current (not cached) info.  Returns the new count of valid statfs bufs.
2624b88c807SRodney W. Grimes  */
2634b88c807SRodney W. Grimes long
2644b88c807SRodney W. Grimes regetmntinfo(mntbufp, mntsize, fsmask)
2654b88c807SRodney W. Grimes 	struct statfs **mntbufp;
2664b88c807SRodney W. Grimes 	long mntsize, fsmask;
2674b88c807SRodney W. Grimes {
2684b88c807SRodney W. Grimes 	int i, j;
2694b88c807SRodney W. Grimes 	struct statfs *mntbuf;
2704b88c807SRodney W. Grimes 
2714b88c807SRodney W. Grimes 	if (fsmask == MT_ALL)
2724b88c807SRodney W. Grimes 		return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT));
2734b88c807SRodney W. Grimes 
2744b88c807SRodney W. Grimes 	mntbuf = *mntbufp;
2754b88c807SRodney W. Grimes 	j = 0;
2764b88c807SRodney W. Grimes 	for (i = 0; i < mntsize; i++) {
2774b88c807SRodney W. Grimes 		if (fsmask & MT(mntbuf[i].f_type)) {
2784b88c807SRodney W. Grimes 			if (!nflag)
2794b88c807SRodney W. Grimes 				(void)statfs(mntbuf[i].f_mntonname,&mntbuf[j]);
2804b88c807SRodney W. Grimes 			else if (i != j)
2814b88c807SRodney W. Grimes 				mntbuf[j] = mntbuf[i];
2824b88c807SRodney W. Grimes 			j++;
2834b88c807SRodney W. Grimes 		}
2844b88c807SRodney W. Grimes 	}
2854b88c807SRodney W. Grimes 	return (j);
2864b88c807SRodney W. Grimes }
2874b88c807SRodney W. Grimes 
2884b88c807SRodney W. Grimes /*
2894b88c807SRodney W. Grimes  * Convert statfs returned filesystem size into BLOCKSIZE units.
2904b88c807SRodney W. Grimes  * Attempts to avoid overflow for large filesystems.
2914b88c807SRodney W. Grimes  */
2924b88c807SRodney W. Grimes #define fsbtoblk(num, fsbs, bs) \
2934b88c807SRodney W. Grimes 	(((fsbs) != 0 && (fsbs) < (bs)) ? \
2944b88c807SRodney W. Grimes 		(num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
2954b88c807SRodney W. Grimes 
2964b88c807SRodney W. Grimes /*
2974b88c807SRodney W. Grimes  * Print out status about a filesystem.
2984b88c807SRodney W. Grimes  */
2994b88c807SRodney W. Grimes void
3004b88c807SRodney W. Grimes prtstat(sfsp, maxwidth)
3014b88c807SRodney W. Grimes 	struct statfs *sfsp;
3024b88c807SRodney W. Grimes 	int maxwidth;
3034b88c807SRodney W. Grimes {
3044b88c807SRodney W. Grimes 	static long blocksize;
3054b88c807SRodney W. Grimes 	static int headerlen, timesthrough;
3064b88c807SRodney W. Grimes 	static char *header;
3074b88c807SRodney W. Grimes 	long used, availblks, inodes;
3084b88c807SRodney W. Grimes 
3094b88c807SRodney W. Grimes 	if (maxwidth < 11)
3104b88c807SRodney W. Grimes 		maxwidth = 11;
3114b88c807SRodney W. Grimes 	if (++timesthrough == 1) {
3124b88c807SRodney W. Grimes 		header = getbsize(&headerlen, &blocksize);
3134b88c807SRodney W. Grimes 		(void)printf("%-*.*s %s     Used    Avail Capacity",
3144b88c807SRodney W. Grimes 		    maxwidth, maxwidth, "Filesystem", header);
3154b88c807SRodney W. Grimes 		if (iflag)
3164b88c807SRodney W. Grimes 			(void)printf(" iused   ifree  %%iused");
3174b88c807SRodney W. Grimes 		(void)printf("  Mounted on\n");
3184b88c807SRodney W. Grimes 	}
3194b88c807SRodney W. Grimes 	(void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
3204b88c807SRodney W. Grimes 	used = sfsp->f_blocks - sfsp->f_bfree;
3214b88c807SRodney W. Grimes 	availblks = sfsp->f_bavail + used;
3224b88c807SRodney W. Grimes 	(void)printf(" %*ld %8ld %8ld", headerlen,
3234b88c807SRodney W. Grimes 	    fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
3244b88c807SRodney W. Grimes 	    fsbtoblk(used, sfsp->f_bsize, blocksize),
3254b88c807SRodney W. Grimes 	    fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
3264b88c807SRodney W. Grimes 	(void)printf(" %5.0f%%",
3274b88c807SRodney W. Grimes 	    availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
3284b88c807SRodney W. Grimes 	if (iflag) {
3294b88c807SRodney W. Grimes 		inodes = sfsp->f_files;
3304b88c807SRodney W. Grimes 		used = inodes - sfsp->f_ffree;
3314b88c807SRodney W. Grimes 		(void)printf(" %7ld %7ld %5.0f%% ", used, sfsp->f_ffree,
3324b88c807SRodney W. Grimes 		   inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
3334b88c807SRodney W. Grimes 	} else
3344b88c807SRodney W. Grimes 		(void)printf("  ");
3354b88c807SRodney W. Grimes 	(void)printf("  %s\n", sfsp->f_mntonname);
3364b88c807SRodney W. Grimes }
3374b88c807SRodney W. Grimes 
3384b88c807SRodney W. Grimes /*
3394b88c807SRodney W. Grimes  * This code constitutes the pre-system call Berkeley df code for extracting
3404b88c807SRodney W. Grimes  * information from filesystem superblocks.
3414b88c807SRodney W. Grimes  */
3424b88c807SRodney W. Grimes #include <ufs/ffs/fs.h>
3434b88c807SRodney W. Grimes #include <errno.h>
3444b88c807SRodney W. Grimes #include <fstab.h>
3454b88c807SRodney W. Grimes 
3464b88c807SRodney W. Grimes union {
3474b88c807SRodney W. Grimes 	struct fs iu_fs;
3484b88c807SRodney W. Grimes 	char dummy[SBSIZE];
3494b88c807SRodney W. Grimes } sb;
3504b88c807SRodney W. Grimes #define sblock sb.iu_fs
3514b88c807SRodney W. Grimes 
3524b88c807SRodney W. Grimes int	rfd;
3534b88c807SRodney W. Grimes 
3544b88c807SRodney W. Grimes void
3554b88c807SRodney W. Grimes ufs_df(file, maxwidth)
3564b88c807SRodney W. Grimes 	char *file;
3574b88c807SRodney W. Grimes 	int maxwidth;
3584b88c807SRodney W. Grimes {
3594b88c807SRodney W. Grimes 	struct statfs statfsbuf;
3604b88c807SRodney W. Grimes 	struct statfs *sfsp;
3614b88c807SRodney W. Grimes 	char *mntpt;
3624b88c807SRodney W. Grimes 	static int synced;
3634b88c807SRodney W. Grimes 
3644b88c807SRodney W. Grimes 	if (synced++ == 0)
3654b88c807SRodney W. Grimes 		sync();
3664b88c807SRodney W. Grimes 
3674b88c807SRodney W. Grimes 	if ((rfd = open(file, O_RDONLY)) < 0) {
3684b88c807SRodney W. Grimes 		warn("%s", file);
3694b88c807SRodney W. Grimes 		return;
3704b88c807SRodney W. Grimes 	}
3714b88c807SRodney W. Grimes 	if (bread((off_t)SBOFF, &sblock, SBSIZE) == 0) {
3724b88c807SRodney W. Grimes 		(void)close(rfd);
3734b88c807SRodney W. Grimes 		return;
3744b88c807SRodney W. Grimes 	}
3754b88c807SRodney W. Grimes 	sfsp = &statfsbuf;
3764b88c807SRodney W. Grimes 	sfsp->f_type = MOUNT_UFS;
3774b88c807SRodney W. Grimes 	sfsp->f_flags = 0;
3784b88c807SRodney W. Grimes 	sfsp->f_bsize = sblock.fs_fsize;
3794b88c807SRodney W. Grimes 	sfsp->f_iosize = sblock.fs_bsize;
3804b88c807SRodney W. Grimes 	sfsp->f_blocks = sblock.fs_dsize;
3814b88c807SRodney W. Grimes 	sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
3824b88c807SRodney W. Grimes 		sblock.fs_cstotal.cs_nffree;
3834b88c807SRodney W. Grimes 	sfsp->f_bavail = (sblock.fs_dsize * (100 - sblock.fs_minfree) / 100) -
3844b88c807SRodney W. Grimes 		(sblock.fs_dsize - sfsp->f_bfree);
3854b88c807SRodney W. Grimes 	if (sfsp->f_bavail < 0)
3864b88c807SRodney W. Grimes 		sfsp->f_bavail = 0;
3874b88c807SRodney W. Grimes 	sfsp->f_files =  sblock.fs_ncg * sblock.fs_ipg;
3884b88c807SRodney W. Grimes 	sfsp->f_ffree = sblock.fs_cstotal.cs_nifree;
3894b88c807SRodney W. Grimes 	sfsp->f_fsid.val[0] = 0;
3904b88c807SRodney W. Grimes 	sfsp->f_fsid.val[1] = 0;
3914b88c807SRodney W. Grimes 	if ((mntpt = getmntpt(file)) == 0)
3924b88c807SRodney W. Grimes 		mntpt = "";
3934b88c807SRodney W. Grimes 	memmove(&sfsp->f_mntonname[0], mntpt, MNAMELEN);
3944b88c807SRodney W. Grimes 	memmove(&sfsp->f_mntfromname[0], file, MNAMELEN);
3954b88c807SRodney W. Grimes 	prtstat(sfsp, maxwidth);
3964b88c807SRodney W. Grimes 	(void)close(rfd);
3974b88c807SRodney W. Grimes }
3984b88c807SRodney W. Grimes 
3994b88c807SRodney W. Grimes int
4004b88c807SRodney W. Grimes bread(off, buf, cnt)
4014b88c807SRodney W. Grimes 	off_t off;
4024b88c807SRodney W. Grimes 	void *buf;
4034b88c807SRodney W. Grimes 	int cnt;
4044b88c807SRodney W. Grimes {
4054b88c807SRodney W. Grimes 	int nr;
4064b88c807SRodney W. Grimes 
4074b88c807SRodney W. Grimes 	(void)lseek(rfd, off, SEEK_SET);
4084b88c807SRodney W. Grimes 	if ((nr = read(rfd, buf, cnt)) != cnt) {
4094b88c807SRodney W. Grimes 		/* Probably a dismounted disk if errno == EIO. */
4104b88c807SRodney W. Grimes 		if (errno != EIO)
4114b88c807SRodney W. Grimes 			(void)fprintf(stderr, "\ndf: %qd: %s\n",
4124b88c807SRodney W. Grimes 			    off, strerror(nr > 0 ? EIO : errno));
4134b88c807SRodney W. Grimes 		return (0);
4144b88c807SRodney W. Grimes 	}
4154b88c807SRodney W. Grimes 	return (1);
4164b88c807SRodney W. Grimes }
4174b88c807SRodney W. Grimes 
4184b88c807SRodney W. Grimes void
4194b88c807SRodney W. Grimes usage()
4204b88c807SRodney W. Grimes {
4217f0eabfdSGarrett Wollman 	fprintf(stderr,
4227f0eabfdSGarrett Wollman 		"usage: df [-ikn] [-t fstype] [file | file_system ...]\n");
4234b88c807SRodney W. Grimes 	exit(1);
4244b88c807SRodney W. Grimes }
425