19ddb49cbSWarner Losh /*- 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 * 4. Neither the name of the University nor the names of its contributors 194b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 204b88c807SRodney W. Grimes * without specific prior written permission. 214b88c807SRodney W. Grimes * 224b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 234b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 244b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 254b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 264b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 274b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 284b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 294b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 304b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 314b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 324b88c807SRodney W. Grimes * SUCH DAMAGE. 334b88c807SRodney W. Grimes */ 344b88c807SRodney W. Grimes 3509a80d48SDavid E. O'Brien #if 0 364b88c807SRodney W. Grimes #ifndef lint 3716cc192aSSteve Price static const char copyright[] = 384b88c807SRodney W. Grimes "@(#) Copyright (c) 1980, 1990, 1993, 1994\n\ 394b88c807SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 404b88c807SRodney W. Grimes #endif /* not lint */ 414b88c807SRodney W. Grimes 424b88c807SRodney W. Grimes #ifndef lint 4316cc192aSSteve Price static char sccsid[] = "@(#)df.c 8.9 (Berkeley) 5/8/95"; 444b88c807SRodney W. Grimes #endif /* not lint */ 4509a80d48SDavid E. O'Brien #endif 465eb43ac2SDavid E. O'Brien #include <sys/cdefs.h> 475eb43ac2SDavid E. O'Brien __FBSDID("$FreeBSD$"); 484b88c807SRodney W. Grimes 494b88c807SRodney W. Grimes #include <sys/param.h> 504b88c807SRodney W. Grimes #include <sys/stat.h> 514b88c807SRodney W. Grimes #include <sys/mount.h> 52a25695c3SJim Pirzyk #include <sys/sysctl.h> 53a78192e3SBruce Evans #include <ufs/ufs/ufsmount.h> 544b88c807SRodney W. Grimes #include <err.h> 557d3940bbSPawel Jakub Dawidek #include <libutil.h> 56*019e4a53SGreg Lehey #include <locale.h> 570bd9f151SIan Dowse #include <stdint.h> 584b88c807SRodney W. Grimes #include <stdio.h> 594b88c807SRodney W. Grimes #include <stdlib.h> 604b88c807SRodney W. Grimes #include <string.h> 61dd6d33e8SMichael Haro #include <sysexits.h> 624b88c807SRodney W. Grimes #include <unistd.h> 634b88c807SRodney W. Grimes 64532aff98SPoul-Henning Kamp #include "extern.h" 65532aff98SPoul-Henning Kamp 66dd6d33e8SMichael Haro #define UNITS_SI 1 67dd6d33e8SMichael Haro #define UNITS_2 2 68dd6d33e8SMichael Haro 6962edbd31SIan Dowse /* Maximum widths of various fields. */ 7062edbd31SIan Dowse struct maxwidths { 710bd9f151SIan Dowse int mntfrom; 72b56ca465SPawel Jakub Dawidek int fstype; 730bd9f151SIan Dowse int total; 740bd9f151SIan Dowse int used; 750bd9f151SIan Dowse int avail; 760bd9f151SIan Dowse int iused; 770bd9f151SIan Dowse int ifree; 7862edbd31SIan Dowse }; 7962edbd31SIan Dowse 80c6f13844SDavid E. O'Brien static void addstat(struct statfs *, struct statfs *); 81b7dbd3e9SMark Murray static char *getmntpt(const char *); 820bd9f151SIan Dowse static int int64width(int64_t); 83532aff98SPoul-Henning Kamp static char *makenetvfslist(void); 84fde81c7dSKirk McKusick static void prthuman(const struct statfs *, int64_t); 857d3940bbSPawel Jakub Dawidek static void prthumanval(int64_t); 86841fe8e8SDavid Schultz static intmax_t fsbtoblk(int64_t, uint64_t, u_long); 87532aff98SPoul-Henning Kamp static void prtstat(struct statfs *, struct maxwidths *); 88be2c4e54SDavid E. O'Brien static size_t regetmntinfo(struct statfs **, long, const char **); 89b7dbd3e9SMark Murray static void update_maxwidths(struct maxwidths *, const struct statfs *); 90532aff98SPoul-Henning Kamp static void usage(void); 914b88c807SRodney W. Grimes 920bd9f151SIan Dowse static __inline int 930bd9f151SIan Dowse imax(int a, int b) 9462edbd31SIan Dowse { 95b7dbd3e9SMark Murray return (a > b ? a : b); 9662edbd31SIan Dowse } 9762edbd31SIan Dowse 98b56ca465SPawel Jakub Dawidek static int aflag = 0, cflag, hflag, iflag, kflag, lflag = 0, nflag, Tflag; 99*019e4a53SGreg Lehey static int thousands; 100532aff98SPoul-Henning Kamp static struct ufs_args mdev; 101532aff98SPoul-Henning Kamp 1024b88c807SRodney W. Grimes int 103f9bcb0beSWarner Losh main(int argc, char *argv[]) 1044b88c807SRodney W. Grimes { 1054b88c807SRodney W. Grimes struct stat stbuf; 106c6f13844SDavid E. O'Brien struct statfs statfsbuf, totalbuf; 10762edbd31SIan Dowse struct maxwidths maxwidths; 108c6f13844SDavid E. O'Brien struct statfs *mntbuf; 109a95a13bbSKris Kennaway const char *fstype; 110532aff98SPoul-Henning Kamp char *mntpath, *mntpt; 111532aff98SPoul-Henning Kamp const char **vfslist; 1127b0514faSDag-Erling Smørgrav int i, mntsize; 113be2c4e54SDavid E. O'Brien int ch, rv; 114f3895a82SKris Kennaway 115f3895a82SKris Kennaway fstype = "ufs"; 116*019e4a53SGreg Lehey (void)setlocale(LC_ALL, ""); 117076419d2SDavid E. O'Brien memset(&totalbuf, 0, sizeof(totalbuf)); 118076419d2SDavid E. O'Brien totalbuf.f_bsize = DEV_BSIZE; 119d7c881e8SWarner Losh strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN); 120a78192e3SBruce Evans vfslist = NULL; 121*019e4a53SGreg Lehey while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T,")) != -1) 1224b88c807SRodney W. Grimes switch (ch) { 1235b42dac8SJulian Elischer case 'a': 1245b42dac8SJulian Elischer aflag = 1; 1255b42dac8SJulian Elischer break; 126dd6d33e8SMichael Haro case 'b': 127dd6d33e8SMichael Haro /* FALLTHROUGH */ 128dd6d33e8SMichael Haro case 'P': 129df464e43SChristian S.J. Peron /* 1306bccea7cSRebecca Cran * POSIX specifically discusses the behavior of 131df464e43SChristian S.J. Peron * both -k and -P. It states that the blocksize should 132df464e43SChristian S.J. Peron * be set to 1024. Thus, if this occurs, simply break 133df464e43SChristian S.J. Peron * rather than clobbering the old blocksize. 134df464e43SChristian S.J. Peron */ 135df464e43SChristian S.J. Peron if (kflag) 136df464e43SChristian S.J. Peron break; 1372966d28cSSean Farley setenv("BLOCKSIZE", "512", 1); 138dd6d33e8SMichael Haro hflag = 0; 139dd6d33e8SMichael Haro break; 140c6f13844SDavid E. O'Brien case 'c': 141c6f13844SDavid E. O'Brien cflag = 1; 142c6f13844SDavid E. O'Brien break; 14393a3fa19SJohn W. De Boskey case 'g': 1442966d28cSSean Farley setenv("BLOCKSIZE", "1g", 1); 14593a3fa19SJohn W. De Boskey hflag = 0; 14693a3fa19SJohn W. De Boskey break; 147dd6d33e8SMichael Haro case 'H': 148dd6d33e8SMichael Haro hflag = UNITS_SI; 149dd6d33e8SMichael Haro break; 150dd6d33e8SMichael Haro case 'h': 151dd6d33e8SMichael Haro hflag = UNITS_2; 152dd6d33e8SMichael Haro break; 1534b88c807SRodney W. Grimes case 'i': 1544b88c807SRodney W. Grimes iflag = 1; 1554b88c807SRodney W. Grimes break; 1567f0eabfdSGarrett Wollman case 'k': 157df464e43SChristian S.J. Peron kflag++; 1582966d28cSSean Farley setenv("BLOCKSIZE", "1024", 1); 159dd6d33e8SMichael Haro hflag = 0; 160dd6d33e8SMichael Haro break; 161a25695c3SJim Pirzyk case 'l': 162a25695c3SJim Pirzyk if (vfslist != NULL) 163a25695c3SJim Pirzyk errx(1, "-l and -t are mutually exclusive."); 164a25695c3SJim Pirzyk vfslist = makevfslist(makenetvfslist()); 16527f82335SWill Andrews lflag = 1; 166a25695c3SJim Pirzyk break; 167dd6d33e8SMichael Haro case 'm': 1682966d28cSSean Farley setenv("BLOCKSIZE", "1m", 1); 169dd6d33e8SMichael Haro hflag = 0; 1707f0eabfdSGarrett Wollman break; 1714b88c807SRodney W. Grimes case 'n': 1724b88c807SRodney W. Grimes nflag = 1; 1734b88c807SRodney W. Grimes break; 1744b88c807SRodney W. Grimes case 't': 17527f82335SWill Andrews if (lflag) 17627f82335SWill Andrews errx(1, "-l and -t are mutually exclusive."); 177a78192e3SBruce Evans if (vfslist != NULL) 1787b3a12a8SPhilippe Charnier errx(1, "only one -t option may be specified"); 179f3895a82SKris Kennaway fstype = optarg; 180a78192e3SBruce Evans vfslist = makevfslist(optarg); 1814b88c807SRodney W. Grimes break; 182b56ca465SPawel Jakub Dawidek case 'T': 183b56ca465SPawel Jakub Dawidek Tflag = 1; 184b56ca465SPawel Jakub Dawidek break; 185*019e4a53SGreg Lehey case ',': 186*019e4a53SGreg Lehey thousands = 1; 187*019e4a53SGreg Lehey break; 1884b88c807SRodney W. Grimes case '?': 1894b88c807SRodney W. Grimes default: 1904b88c807SRodney W. Grimes usage(); 1914b88c807SRodney W. Grimes } 1924b88c807SRodney W. Grimes argc -= optind; 1934b88c807SRodney W. Grimes argv += optind; 1944b88c807SRodney W. Grimes 195b8904f2aSJoerg Wunsch rv = 0; 1964b88c807SRodney W. Grimes if (!*argv) { 1977b0514faSDag-Erling Smørgrav /* everything (modulo -t) */ 1987b0514faSDag-Erling Smørgrav mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 199a78192e3SBruce Evans mntsize = regetmntinfo(&mntbuf, mntsize, vfslist); 2007b0514faSDag-Erling Smørgrav } else { 2017b0514faSDag-Erling Smørgrav /* just the filesystems specified on the command line */ 2027b0514faSDag-Erling Smørgrav mntbuf = malloc(argc * sizeof(*mntbuf)); 2037b0514faSDag-Erling Smørgrav if (mntbuf == 0) 2047b0514faSDag-Erling Smørgrav err(1, "malloc()"); 2057b0514faSDag-Erling Smørgrav mntsize = 0; 2067b0514faSDag-Erling Smørgrav /* continued in for loop below */ 2074b88c807SRodney W. Grimes } 2084b88c807SRodney W. Grimes 2097b0514faSDag-Erling Smørgrav /* iterate through specified filesystems */ 2104b88c807SRodney W. Grimes for (; *argv; argv++) { 2114b88c807SRodney W. Grimes if (stat(*argv, &stbuf) < 0) { 2124b88c807SRodney W. Grimes if ((mntpt = getmntpt(*argv)) == 0) { 2134b88c807SRodney W. Grimes warn("%s", *argv); 214b8904f2aSJoerg Wunsch rv = 1; 2154b88c807SRodney W. Grimes continue; 2164b88c807SRodney W. Grimes } 217f3895a82SKris Kennaway } else if (S_ISCHR(stbuf.st_mode)) { 218f3895a82SKris Kennaway if ((mntpt = getmntpt(*argv)) == 0) { 219f3895a82SKris Kennaway mdev.fspec = *argv; 220f3895a82SKris Kennaway mntpath = strdup("/tmp/df.XXXXXX"); 221f3895a82SKris Kennaway if (mntpath == NULL) { 222f3895a82SKris Kennaway warn("strdup failed"); 223f3895a82SKris Kennaway rv = 1; 2244b88c807SRodney W. Grimes continue; 225f3895a82SKris Kennaway } 226f3895a82SKris Kennaway mntpt = mkdtemp(mntpath); 227f3895a82SKris Kennaway if (mntpt == NULL) { 228f3895a82SKris Kennaway warn("mkdtemp(\"%s\") failed", mntpath); 229f3895a82SKris Kennaway rv = 1; 230f3895a82SKris Kennaway free(mntpath); 231f3895a82SKris Kennaway continue; 232f3895a82SKris Kennaway } 233f3895a82SKris Kennaway if (mount(fstype, mntpt, MNT_RDONLY, 234f3895a82SKris Kennaway &mdev) != 0) { 235532aff98SPoul-Henning Kamp warn("%s", *argv); 236532aff98SPoul-Henning Kamp rv = 1; 237f3895a82SKris Kennaway (void)rmdir(mntpt); 238f3895a82SKris Kennaway free(mntpath); 239f3895a82SKris Kennaway continue; 240f3895a82SKris Kennaway } else if (statfs(mntpt, &statfsbuf) == 0) { 241f3895a82SKris Kennaway statfsbuf.f_mntonname[0] = '\0'; 24262edbd31SIan Dowse prtstat(&statfsbuf, &maxwidths); 243076419d2SDavid E. O'Brien if (cflag) 244076419d2SDavid E. O'Brien addstat(&totalbuf, &statfsbuf); 245f3895a82SKris Kennaway } else { 246f3895a82SKris Kennaway warn("%s", *argv); 247f3895a82SKris Kennaway rv = 1; 248f3895a82SKris Kennaway } 249f3895a82SKris Kennaway (void)unmount(mntpt, 0); 250f3895a82SKris Kennaway (void)rmdir(mntpt); 251f3895a82SKris Kennaway free(mntpath); 252f3895a82SKris Kennaway continue; 253f3895a82SKris Kennaway } 2544b88c807SRodney W. Grimes } else 2554b88c807SRodney W. Grimes mntpt = *argv; 2560e7d023fSBruce Evans 2574b88c807SRodney W. Grimes /* 2584b88c807SRodney W. Grimes * Statfs does not take a `wait' flag, so we cannot 2594b88c807SRodney W. Grimes * implement nflag here. 2604b88c807SRodney W. Grimes */ 2614b88c807SRodney W. Grimes if (statfs(mntpt, &statfsbuf) < 0) { 2624b88c807SRodney W. Grimes warn("%s", mntpt); 263b8904f2aSJoerg Wunsch rv = 1; 2644b88c807SRodney W. Grimes continue; 2654b88c807SRodney W. Grimes } 2660e7d023fSBruce Evans 2670e7d023fSBruce Evans /* 2680e7d023fSBruce Evans * Check to make sure the arguments we've been given are 2690e7d023fSBruce Evans * satisfied. Return an error if we have been asked to 2700e7d023fSBruce Evans * list a mount point that does not match the other args 2710e7d023fSBruce Evans * we've been given (-l, -t, etc.). 272c22acefbSJordan K. Hubbard */ 273c22acefbSJordan K. Hubbard if (checkvfsname(statfsbuf.f_fstypename, vfslist)) { 2740e7d023fSBruce Evans rv = 1; 275c22acefbSJordan K. Hubbard continue; 276c22acefbSJordan K. Hubbard } 2770e7d023fSBruce Evans 2787b0514faSDag-Erling Smørgrav /* the user asked for it, so ignore the ignore flag */ 2797b0514faSDag-Erling Smørgrav statfsbuf.f_flags &= ~MNT_IGNORE; 2807b0514faSDag-Erling Smørgrav 2817b0514faSDag-Erling Smørgrav /* add to list */ 2827b0514faSDag-Erling Smørgrav mntbuf[mntsize++] = statfsbuf; 2837b0514faSDag-Erling Smørgrav } 2847b0514faSDag-Erling Smørgrav 28562edbd31SIan Dowse bzero(&maxwidths, sizeof(maxwidths)); 2867b0514faSDag-Erling Smørgrav for (i = 0; i < mntsize; i++) { 2877b0514faSDag-Erling Smørgrav if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) { 2887b0514faSDag-Erling Smørgrav update_maxwidths(&maxwidths, &mntbuf[i]); 289076419d2SDavid E. O'Brien if (cflag) 2907b0514faSDag-Erling Smørgrav addstat(&totalbuf, &mntbuf[i]); 2914b88c807SRodney W. Grimes } 2927b0514faSDag-Erling Smørgrav } 2937b0514faSDag-Erling Smørgrav for (i = 0; i < mntsize; i++) 2947b0514faSDag-Erling Smørgrav if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) 2957b0514faSDag-Erling Smørgrav prtstat(&mntbuf[i], &maxwidths); 296076419d2SDavid E. O'Brien if (cflag) 297076419d2SDavid E. O'Brien prtstat(&totalbuf, &maxwidths); 298b8904f2aSJoerg Wunsch return (rv); 2994b88c807SRodney W. Grimes } 3004b88c807SRodney W. Grimes 301532aff98SPoul-Henning Kamp static char * 302b7dbd3e9SMark Murray getmntpt(const char *name) 3034b88c807SRodney W. Grimes { 304be2c4e54SDavid E. O'Brien size_t mntsize, i; 3054b88c807SRodney W. Grimes struct statfs *mntbuf; 3064b88c807SRodney W. Grimes 3074b88c807SRodney W. Grimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 3084b88c807SRodney W. Grimes for (i = 0; i < mntsize; i++) { 3094b88c807SRodney W. Grimes if (!strcmp(mntbuf[i].f_mntfromname, name)) 3104b88c807SRodney W. Grimes return (mntbuf[i].f_mntonname); 3114b88c807SRodney W. Grimes } 3124b88c807SRodney W. Grimes return (0); 3134b88c807SRodney W. Grimes } 3144b88c807SRodney W. Grimes 3154b88c807SRodney W. Grimes /* 3164b88c807SRodney W. Grimes * Make a pass over the file system info in ``mntbuf'' filtering out 317a78192e3SBruce Evans * file system types not in vfslist and possibly re-stating to get 3184b88c807SRodney W. Grimes * current (not cached) info. Returns the new count of valid statfs bufs. 3194b88c807SRodney W. Grimes */ 320be2c4e54SDavid E. O'Brien static size_t 321532aff98SPoul-Henning Kamp regetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist) 3224b88c807SRodney W. Grimes { 323239c9e60SChristian S.J. Peron int error, i, j; 3244b88c807SRodney W. Grimes struct statfs *mntbuf; 3254b88c807SRodney W. Grimes 326a78192e3SBruce Evans if (vfslist == NULL) 3274b88c807SRodney W. Grimes return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT)); 3284b88c807SRodney W. Grimes 3294b88c807SRodney W. Grimes mntbuf = *mntbufp; 330a78192e3SBruce Evans for (j = 0, i = 0; i < mntsize; i++) { 331a78192e3SBruce Evans if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) 332a78192e3SBruce Evans continue; 333239c9e60SChristian S.J. Peron /* 334239c9e60SChristian S.J. Peron * XXX statfs(2) can fail for various reasons. It may be 335239c9e60SChristian S.J. Peron * possible that the user does not have access to the 336239c9e60SChristian S.J. Peron * pathname, if this happens, we will fall back on 337239c9e60SChristian S.J. Peron * "stale" filesystem statistics. 338239c9e60SChristian S.J. Peron */ 339239c9e60SChristian S.J. Peron error = statfs(mntbuf[i].f_mntonname, &mntbuf[j]); 340239c9e60SChristian S.J. Peron if (nflag || error < 0) 341239c9e60SChristian S.J. Peron if (i != j) { 342239c9e60SChristian S.J. Peron if (error < 0) 343239c9e60SChristian S.J. Peron warnx("%s stats possibly stale", 344239c9e60SChristian S.J. Peron mntbuf[i].f_mntonname); 3454b88c807SRodney W. Grimes mntbuf[j] = mntbuf[i]; 346239c9e60SChristian S.J. Peron } 3474b88c807SRodney W. Grimes j++; 3484b88c807SRodney W. Grimes } 3494b88c807SRodney W. Grimes return (j); 3504b88c807SRodney W. Grimes } 3514b88c807SRodney W. Grimes 352532aff98SPoul-Henning Kamp static void 353fde81c7dSKirk McKusick prthuman(const struct statfs *sfsp, int64_t used) 354dd6d33e8SMichael Haro { 355dd6d33e8SMichael Haro 3567d3940bbSPawel Jakub Dawidek prthumanval(sfsp->f_blocks * sfsp->f_bsize); 3577d3940bbSPawel Jakub Dawidek prthumanval(used * sfsp->f_bsize); 3587d3940bbSPawel Jakub Dawidek prthumanval(sfsp->f_bavail * sfsp->f_bsize); 359dd6d33e8SMichael Haro } 360dd6d33e8SMichael Haro 361532aff98SPoul-Henning Kamp static void 3627d3940bbSPawel Jakub Dawidek prthumanval(int64_t bytes) 363dd6d33e8SMichael Haro { 3647d3940bbSPawel Jakub Dawidek char buf[6]; 3657d3940bbSPawel Jakub Dawidek int flags; 366dd6d33e8SMichael Haro 3677d3940bbSPawel Jakub Dawidek flags = HN_B | HN_NOSPACE | HN_DECIMAL; 3687d3940bbSPawel Jakub Dawidek if (hflag == UNITS_SI) 3697d3940bbSPawel Jakub Dawidek flags |= HN_DIVISOR_1000; 370dd6d33e8SMichael Haro 3717d3940bbSPawel Jakub Dawidek humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), 3727d3940bbSPawel Jakub Dawidek bytes, "", HN_AUTOSCALE, flags); 3737d3940bbSPawel Jakub Dawidek 3747d3940bbSPawel Jakub Dawidek (void)printf(" %6s", buf); 375dd6d33e8SMichael Haro } 376dd6d33e8SMichael Haro 377dd6d33e8SMichael Haro /* 378b93ce3b7SSimon L. B. Nielsen * Print an inode count in "human-readable" format. 379b93ce3b7SSimon L. B. Nielsen */ 380b93ce3b7SSimon L. B. Nielsen static void 381b93ce3b7SSimon L. B. Nielsen prthumanvalinode(int64_t bytes) 382b93ce3b7SSimon L. B. Nielsen { 383b93ce3b7SSimon L. B. Nielsen char buf[6]; 384b93ce3b7SSimon L. B. Nielsen int flags; 385b93ce3b7SSimon L. B. Nielsen 386b93ce3b7SSimon L. B. Nielsen flags = HN_NOSPACE | HN_DECIMAL | HN_DIVISOR_1000; 387b93ce3b7SSimon L. B. Nielsen 388b93ce3b7SSimon L. B. Nielsen humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), 389b93ce3b7SSimon L. B. Nielsen bytes, "", HN_AUTOSCALE, flags); 390b93ce3b7SSimon L. B. Nielsen 391b93ce3b7SSimon L. B. Nielsen (void)printf(" %5s", buf); 392b93ce3b7SSimon L. B. Nielsen } 393b93ce3b7SSimon L. B. Nielsen 394b93ce3b7SSimon L. B. Nielsen /* 3954b88c807SRodney W. Grimes * Convert statfs returned file system size into BLOCKSIZE units. 3964b88c807SRodney W. Grimes * Attempts to avoid overflow for large file systems. 3974b88c807SRodney W. Grimes */ 398841fe8e8SDavid Schultz static intmax_t 399841fe8e8SDavid Schultz fsbtoblk(int64_t num, uint64_t fsbs, u_long bs) 400841fe8e8SDavid Schultz { 401841fe8e8SDavid Schultz 402841fe8e8SDavid Schultz if (fsbs != 0 && fsbs < bs) 403841fe8e8SDavid Schultz return (num / (intmax_t)(bs / fsbs)); 404841fe8e8SDavid Schultz else 405841fe8e8SDavid Schultz return (num * (intmax_t)(fsbs / bs)); 406841fe8e8SDavid Schultz } 4074b88c807SRodney W. Grimes 4084b88c807SRodney W. Grimes /* 4094b88c807SRodney W. Grimes * Print out status about a file system. 4104b88c807SRodney W. Grimes */ 411532aff98SPoul-Henning Kamp static void 41262edbd31SIan Dowse prtstat(struct statfs *sfsp, struct maxwidths *mwp) 4134b88c807SRodney W. Grimes { 4142897dce8SAlexander Kabaev static long blocksize; 415b7dbd3e9SMark Murray static int headerlen, timesthrough = 0; 416a95a13bbSKris Kennaway static const char *header; 417fde81c7dSKirk McKusick int64_t used, availblks, inodes; 418*019e4a53SGreg Lehey const char *format; 4194b88c807SRodney W. Grimes 4204b88c807SRodney W. Grimes if (++timesthrough == 1) { 4210bd9f151SIan Dowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen("Filesystem")); 422b56ca465SPawel Jakub Dawidek mwp->fstype = imax(mwp->fstype, (int)strlen("Type")); 423*019e4a53SGreg Lehey if (thousands) { /* make space for commas */ 424*019e4a53SGreg Lehey mwp->total += (mwp->total - 1) / 3; 425*019e4a53SGreg Lehey mwp->used += (mwp->used - 1) / 3; 426*019e4a53SGreg Lehey mwp->avail += (mwp->avail - 1) / 3; 427*019e4a53SGreg Lehey mwp->iused += (mwp->iused - 1) / 3; 428*019e4a53SGreg Lehey mwp->ifree += (mwp->ifree - 1) / 3; 429*019e4a53SGreg Lehey } 430dd6d33e8SMichael Haro if (hflag) { 431dd6d33e8SMichael Haro header = " Size"; 4320bd9f151SIan Dowse mwp->total = mwp->used = mwp->avail = 4330bd9f151SIan Dowse (int)strlen(header); 434dd6d33e8SMichael Haro } else { 435dd6d33e8SMichael Haro header = getbsize(&headerlen, &blocksize); 4360bd9f151SIan Dowse mwp->total = imax(mwp->total, headerlen); 437dd6d33e8SMichael Haro } 4380bd9f151SIan Dowse mwp->used = imax(mwp->used, (int)strlen("Used")); 4390bd9f151SIan Dowse mwp->avail = imax(mwp->avail, (int)strlen("Avail")); 44062edbd31SIan Dowse 441b56ca465SPawel Jakub Dawidek (void)printf("%-*s", mwp->mntfrom, "Filesystem"); 442b56ca465SPawel Jakub Dawidek if (Tflag) 443b56ca465SPawel Jakub Dawidek (void)printf(" %-*s", mwp->fstype, "Type"); 444*019e4a53SGreg Lehey (void)printf(" %*s %*s %*s Capacity", mwp->total, header, 4450bd9f151SIan Dowse mwp->used, "Used", mwp->avail, "Avail"); 44662edbd31SIan Dowse if (iflag) { 447b93ce3b7SSimon L. B. Nielsen mwp->iused = imax(hflag ? 0 : mwp->iused, 448b93ce3b7SSimon L. B. Nielsen (int)strlen(" iused")); 449b93ce3b7SSimon L. B. Nielsen mwp->ifree = imax(hflag ? 0 : mwp->ifree, 450b93ce3b7SSimon L. B. Nielsen (int)strlen("ifree")); 451f694b8adSMark Murray (void)printf(" %*s %*s %%iused", 4520bd9f151SIan Dowse mwp->iused - 2, "iused", mwp->ifree, "ifree"); 45362edbd31SIan Dowse } 4544b88c807SRodney W. Grimes (void)printf(" Mounted on\n"); 4554b88c807SRodney W. Grimes } 4560bd9f151SIan Dowse (void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname); 457b56ca465SPawel Jakub Dawidek if (Tflag) 458b56ca465SPawel Jakub Dawidek (void)printf(" %-*s", mwp->fstype, sfsp->f_fstypename); 4594b88c807SRodney W. Grimes used = sfsp->f_blocks - sfsp->f_bfree; 4604b88c807SRodney W. Grimes availblks = sfsp->f_bavail + used; 461dd6d33e8SMichael Haro if (hflag) { 462dd6d33e8SMichael Haro prthuman(sfsp, used); 463dd6d33e8SMichael Haro } else { 464*019e4a53SGreg Lehey if (thousands) 465*019e4a53SGreg Lehey format = " %*j'd %*j'd %*j'd"; 466*019e4a53SGreg Lehey else 467*019e4a53SGreg Lehey format = " %*jd %*jd %*jd"; 468*019e4a53SGreg Lehey (void)printf(format, 469841fe8e8SDavid Schultz mwp->total, fsbtoblk(sfsp->f_blocks, 4700bd9f151SIan Dowse sfsp->f_bsize, blocksize), 471841fe8e8SDavid Schultz mwp->used, fsbtoblk(used, sfsp->f_bsize, blocksize), 472841fe8e8SDavid Schultz mwp->avail, fsbtoblk(sfsp->f_bavail, 4730bd9f151SIan Dowse sfsp->f_bsize, blocksize)); 474dd6d33e8SMichael Haro } 4754b88c807SRodney W. Grimes (void)printf(" %5.0f%%", 4764b88c807SRodney W. Grimes availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0); 4774b88c807SRodney W. Grimes if (iflag) { 4784b88c807SRodney W. Grimes inodes = sfsp->f_files; 4794b88c807SRodney W. Grimes used = inodes - sfsp->f_ffree; 480b93ce3b7SSimon L. B. Nielsen if (hflag) { 481b93ce3b7SSimon L. B. Nielsen (void)printf(" "); 482b93ce3b7SSimon L. B. Nielsen prthumanvalinode(used); 483b93ce3b7SSimon L. B. Nielsen prthumanvalinode(sfsp->f_ffree); 484b93ce3b7SSimon L. B. Nielsen } else { 485*019e4a53SGreg Lehey if (thousands) 486*019e4a53SGreg Lehey format = " %*j'd %*j'd"; 487*019e4a53SGreg Lehey else 488*019e4a53SGreg Lehey format = " %*jd %*jd"; 489*019e4a53SGreg Lehey (void)printf(format, mwp->iused, (intmax_t)used, 490b93ce3b7SSimon L. B. Nielsen mwp->ifree, (intmax_t)sfsp->f_ffree); 491b93ce3b7SSimon L. B. Nielsen } 492b93ce3b7SSimon L. B. Nielsen (void)printf(" %4.0f%% ", inodes == 0 ? 100.0 : 4930bd9f151SIan Dowse (double)used / (double)inodes * 100.0); 494cca108e6SDavid E. O'Brien } else 495cca108e6SDavid E. O'Brien (void)printf(" "); 496c6f13844SDavid E. O'Brien if (strncmp(sfsp->f_mntfromname, "total", MNAMELEN) != 0) 497076419d2SDavid E. O'Brien (void)printf(" %s", sfsp->f_mntonname); 498076419d2SDavid E. O'Brien (void)printf("\n"); 499076419d2SDavid E. O'Brien } 500076419d2SDavid E. O'Brien 501431586a8SXin LI static void 502076419d2SDavid E. O'Brien addstat(struct statfs *totalfsp, struct statfs *statfsp) 503076419d2SDavid E. O'Brien { 504c6f13844SDavid E. O'Brien uint64_t bsize; 505076419d2SDavid E. O'Brien 506c6f13844SDavid E. O'Brien bsize = statfsp->f_bsize / totalfsp->f_bsize; 507076419d2SDavid E. O'Brien totalfsp->f_blocks += statfsp->f_blocks * bsize; 508076419d2SDavid E. O'Brien totalfsp->f_bfree += statfsp->f_bfree * bsize; 509076419d2SDavid E. O'Brien totalfsp->f_bavail += statfsp->f_bavail * bsize; 510076419d2SDavid E. O'Brien totalfsp->f_files += statfsp->f_files; 511076419d2SDavid E. O'Brien totalfsp->f_ffree += statfsp->f_ffree; 5124b88c807SRodney W. Grimes } 5134b88c807SRodney W. Grimes 5144b88c807SRodney W. Grimes /* 51562edbd31SIan Dowse * Update the maximum field-width information in `mwp' based on 51662edbd31SIan Dowse * the file system specified by `sfsp'. 51762edbd31SIan Dowse */ 518532aff98SPoul-Henning Kamp static void 519b7dbd3e9SMark Murray update_maxwidths(struct maxwidths *mwp, const struct statfs *sfsp) 52062edbd31SIan Dowse { 5212897dce8SAlexander Kabaev static long blocksize = 0; 522dc474219SMike Barcroft int dummy; 52362edbd31SIan Dowse 52462edbd31SIan Dowse if (blocksize == 0) 52562edbd31SIan Dowse getbsize(&dummy, &blocksize); 52662edbd31SIan Dowse 5270bd9f151SIan Dowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen(sfsp->f_mntfromname)); 528b56ca465SPawel Jakub Dawidek mwp->fstype = imax(mwp->fstype, (int)strlen(sfsp->f_fstypename)); 5290bd9f151SIan Dowse mwp->total = imax(mwp->total, int64width( 530fde81c7dSKirk McKusick fsbtoblk((int64_t)sfsp->f_blocks, sfsp->f_bsize, blocksize))); 5310bd9f151SIan Dowse mwp->used = imax(mwp->used, 5320bd9f151SIan Dowse int64width(fsbtoblk((int64_t)sfsp->f_blocks - 533fde81c7dSKirk McKusick (int64_t)sfsp->f_bfree, sfsp->f_bsize, blocksize))); 5340bd9f151SIan Dowse mwp->avail = imax(mwp->avail, int64width(fsbtoblk(sfsp->f_bavail, 53562edbd31SIan Dowse sfsp->f_bsize, blocksize))); 5360bd9f151SIan Dowse mwp->iused = imax(mwp->iused, int64width((int64_t)sfsp->f_files - 53762edbd31SIan Dowse sfsp->f_ffree)); 5380bd9f151SIan Dowse mwp->ifree = imax(mwp->ifree, int64width(sfsp->f_ffree)); 53962edbd31SIan Dowse } 54062edbd31SIan Dowse 5410bd9f151SIan Dowse /* Return the width in characters of the specified value. */ 5420bd9f151SIan Dowse static int 543fde81c7dSKirk McKusick int64width(int64_t val) 54462edbd31SIan Dowse { 5450bd9f151SIan Dowse int len; 54662edbd31SIan Dowse 54762edbd31SIan Dowse len = 0; 54862edbd31SIan Dowse /* Negative or zero values require one extra digit. */ 54962edbd31SIan Dowse if (val <= 0) { 55062edbd31SIan Dowse val = -val; 55162edbd31SIan Dowse len++; 55262edbd31SIan Dowse } 55362edbd31SIan Dowse while (val > 0) { 55462edbd31SIan Dowse len++; 55562edbd31SIan Dowse val /= 10; 55662edbd31SIan Dowse } 55762edbd31SIan Dowse 55862edbd31SIan Dowse return (len); 55962edbd31SIan Dowse } 56062edbd31SIan Dowse 561532aff98SPoul-Henning Kamp static void 562f9bcb0beSWarner Losh usage(void) 5634b88c807SRodney W. Grimes { 564dd6d33e8SMichael Haro 565a78192e3SBruce Evans (void)fprintf(stderr, 566*019e4a53SGreg Lehey "usage: df [-b | -g | -H | -h | -k | -m | -P] [-acilnT] [-t type] [-,] [file | filesystem ...]\n"); 567dd6d33e8SMichael Haro exit(EX_USAGE); 5684b88c807SRodney W. Grimes } 569a25695c3SJim Pirzyk 570532aff98SPoul-Henning Kamp static char * 571f9bcb0beSWarner Losh makenetvfslist(void) 572a25695c3SJim Pirzyk { 573a25695c3SJim Pirzyk char *str, *strptr, **listptr; 574b7dbd3e9SMark Murray struct xvfsconf *xvfsp, *keep_xvfsp; 5755965373eSMaxime Henrion size_t buflen; 5765965373eSMaxime Henrion int cnt, i, maxvfsconf; 577a25695c3SJim Pirzyk 5785965373eSMaxime Henrion if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) { 5795965373eSMaxime Henrion warn("sysctl(vfs.conflist)"); 580a25695c3SJim Pirzyk return (NULL); 581a25695c3SJim Pirzyk } 5825965373eSMaxime Henrion xvfsp = malloc(buflen); 5835965373eSMaxime Henrion if (xvfsp == NULL) { 5845965373eSMaxime Henrion warnx("malloc failed"); 5855965373eSMaxime Henrion return (NULL); 5865965373eSMaxime Henrion } 587b7dbd3e9SMark Murray keep_xvfsp = xvfsp; 5885965373eSMaxime Henrion if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) { 5895965373eSMaxime Henrion warn("sysctl(vfs.conflist)"); 590b7dbd3e9SMark Murray free(keep_xvfsp); 5915965373eSMaxime Henrion return (NULL); 5925965373eSMaxime Henrion } 5935965373eSMaxime Henrion maxvfsconf = buflen / sizeof(struct xvfsconf); 594a25695c3SJim Pirzyk 595a25695c3SJim Pirzyk if ((listptr = malloc(sizeof(char*) * maxvfsconf)) == NULL) { 596a25695c3SJim Pirzyk warnx("malloc failed"); 597b7dbd3e9SMark Murray free(keep_xvfsp); 598a25695c3SJim Pirzyk return (NULL); 599a25695c3SJim Pirzyk } 600a25695c3SJim Pirzyk 6015965373eSMaxime Henrion for (cnt = 0, i = 0; i < maxvfsconf; i++) { 6025965373eSMaxime Henrion if (xvfsp->vfc_flags & VFCF_NETWORK) { 6035965373eSMaxime Henrion listptr[cnt++] = strdup(xvfsp->vfc_name); 604a067aeceSGarrett Wollman if (listptr[cnt-1] == NULL) { 605a25695c3SJim Pirzyk warnx("malloc failed"); 606b7dbd3e9SMark Murray free(listptr); 607b7dbd3e9SMark Murray free(keep_xvfsp); 608a25695c3SJim Pirzyk return (NULL); 609a25695c3SJim Pirzyk } 610a25695c3SJim Pirzyk } 6115965373eSMaxime Henrion xvfsp++; 6125965373eSMaxime Henrion } 613a25695c3SJim Pirzyk 614cf5b29e1SRuslan Ermilov if (cnt == 0 || 615cf5b29e1SRuslan Ermilov (str = malloc(sizeof(char) * (32 * cnt + cnt + 2))) == NULL) { 616cf5b29e1SRuslan Ermilov if (cnt > 0) 617a25695c3SJim Pirzyk warnx("malloc failed"); 618a25695c3SJim Pirzyk free(listptr); 619b7dbd3e9SMark Murray free(keep_xvfsp); 620a25695c3SJim Pirzyk return (NULL); 621a25695c3SJim Pirzyk } 622a25695c3SJim Pirzyk 623a25695c3SJim Pirzyk *str = 'n'; *(str + 1) = 'o'; 624a25695c3SJim Pirzyk for (i = 0, strptr = str + 2; i < cnt; i++, strptr++) { 625d7c881e8SWarner Losh strlcpy(strptr, listptr[i], 32); 626a25695c3SJim Pirzyk strptr += strlen(listptr[i]); 627a25695c3SJim Pirzyk *strptr = ','; 628a25695c3SJim Pirzyk free(listptr[i]); 629a25695c3SJim Pirzyk } 63016fc3635SMark Murray *(--strptr) = '\0'; 631a25695c3SJim Pirzyk 632b7dbd3e9SMark Murray free(keep_xvfsp); 633a25695c3SJim Pirzyk free(listptr); 634a25695c3SJim Pirzyk return (str); 635a25695c3SJim Pirzyk } 636