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 * 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> 55dd6d33e8SMichael Haro #include <math.h> 560bd9f151SIan Dowse #include <stdint.h> 574b88c807SRodney W. Grimes #include <stdio.h> 584b88c807SRodney W. Grimes #include <stdlib.h> 594b88c807SRodney W. Grimes #include <string.h> 60dd6d33e8SMichael Haro #include <sysexits.h> 614b88c807SRodney W. Grimes #include <unistd.h> 624b88c807SRodney W. Grimes 63532aff98SPoul-Henning Kamp #include "extern.h" 64532aff98SPoul-Henning Kamp 65dd6d33e8SMichael Haro #define UNITS_SI 1 66dd6d33e8SMichael Haro #define UNITS_2 2 67dd6d33e8SMichael Haro 68dd6d33e8SMichael Haro #define KILO_SZ(n) (n) 69dd6d33e8SMichael Haro #define MEGA_SZ(n) ((n) * (n)) 70dd6d33e8SMichael Haro #define GIGA_SZ(n) ((n) * (n) * (n)) 71dd6d33e8SMichael Haro #define TERA_SZ(n) ((n) * (n) * (n) * (n)) 72dd6d33e8SMichael Haro #define PETA_SZ(n) ((n) * (n) * (n) * (n) * (n)) 73dd6d33e8SMichael Haro 74dd6d33e8SMichael Haro #define KILO_2_SZ (KILO_SZ(1024ULL)) 75dd6d33e8SMichael Haro #define MEGA_2_SZ (MEGA_SZ(1024ULL)) 76dd6d33e8SMichael Haro #define GIGA_2_SZ (GIGA_SZ(1024ULL)) 77dd6d33e8SMichael Haro #define TERA_2_SZ (TERA_SZ(1024ULL)) 78dd6d33e8SMichael Haro #define PETA_2_SZ (PETA_SZ(1024ULL)) 79dd6d33e8SMichael Haro 80dd6d33e8SMichael Haro #define KILO_SI_SZ (KILO_SZ(1000ULL)) 81dd6d33e8SMichael Haro #define MEGA_SI_SZ (MEGA_SZ(1000ULL)) 82dd6d33e8SMichael Haro #define GIGA_SI_SZ (GIGA_SZ(1000ULL)) 83dd6d33e8SMichael Haro #define TERA_SI_SZ (TERA_SZ(1000ULL)) 84dd6d33e8SMichael Haro #define PETA_SI_SZ (PETA_SZ(1000ULL)) 85dd6d33e8SMichael Haro 8662edbd31SIan Dowse /* Maximum widths of various fields. */ 8762edbd31SIan Dowse struct maxwidths { 880bd9f151SIan Dowse int mntfrom; 890bd9f151SIan Dowse int total; 900bd9f151SIan Dowse int used; 910bd9f151SIan Dowse int avail; 920bd9f151SIan Dowse int iused; 930bd9f151SIan Dowse int ifree; 9462edbd31SIan Dowse }; 9562edbd31SIan Dowse 96b7dbd3e9SMark Murray static uintmax_t vals_si [] = { 97b7dbd3e9SMark Murray 1, 98b7dbd3e9SMark Murray KILO_SI_SZ, 99b7dbd3e9SMark Murray MEGA_SI_SZ, 100b7dbd3e9SMark Murray GIGA_SI_SZ, 101b7dbd3e9SMark Murray TERA_SI_SZ, 102b7dbd3e9SMark Murray PETA_SI_SZ 103b7dbd3e9SMark Murray }; 104b7dbd3e9SMark Murray static uintmax_t vals_base2[] = { 105b7dbd3e9SMark Murray 1, 106b7dbd3e9SMark Murray KILO_2_SZ, 107b7dbd3e9SMark Murray MEGA_2_SZ, 108b7dbd3e9SMark Murray GIGA_2_SZ, 109b7dbd3e9SMark Murray TERA_2_SZ, 110b7dbd3e9SMark Murray PETA_2_SZ 111b7dbd3e9SMark Murray }; 112b7dbd3e9SMark Murray static uintmax_t *valp; 113dd6d33e8SMichael Haro 114dd6d33e8SMichael Haro typedef enum { NONE, KILO, MEGA, GIGA, TERA, PETA, UNIT_MAX } unit_t; 115dd6d33e8SMichael Haro 116b7dbd3e9SMark Murray static unit_t unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA }; 117dd6d33e8SMichael Haro 118b7dbd3e9SMark Murray static char *getmntpt(const char *); 1190bd9f151SIan Dowse static int int64width(int64_t); 120532aff98SPoul-Henning Kamp static char *makenetvfslist(void); 121fde81c7dSKirk McKusick static void prthuman(const struct statfs *, int64_t); 122532aff98SPoul-Henning Kamp static void prthumanval(double); 123532aff98SPoul-Henning Kamp static void prtstat(struct statfs *, struct maxwidths *); 124076419d2SDavid E. O'Brien static void addstat(struct statfs *, struct statfs *); 125be2c4e54SDavid E. O'Brien static size_t regetmntinfo(struct statfs **, long, const char **); 126532aff98SPoul-Henning Kamp static unit_t unit_adjust(double *); 127b7dbd3e9SMark Murray static void update_maxwidths(struct maxwidths *, const struct statfs *); 128532aff98SPoul-Henning Kamp static void usage(void); 1294b88c807SRodney W. Grimes 1300bd9f151SIan Dowse static __inline int 1310bd9f151SIan Dowse imax(int a, int b) 13262edbd31SIan Dowse { 133b7dbd3e9SMark Murray return (a > b ? a : b); 13462edbd31SIan Dowse } 13562edbd31SIan Dowse 136076419d2SDavid E. O'Brien static int aflag = 0, cflag, hflag, iflag, nflag; 137532aff98SPoul-Henning Kamp static struct ufs_args mdev; 138532aff98SPoul-Henning Kamp 1394b88c807SRodney W. Grimes int 140f9bcb0beSWarner Losh main(int argc, char *argv[]) 1414b88c807SRodney W. Grimes { 1424b88c807SRodney W. Grimes struct stat stbuf; 143076419d2SDavid E. O'Brien struct statfs statfsbuf, totalbuf, *mntbuf; 14462edbd31SIan Dowse struct maxwidths maxwidths; 145a95a13bbSKris Kennaway const char *fstype; 146532aff98SPoul-Henning Kamp char *mntpath, *mntpt; 147532aff98SPoul-Henning Kamp const char **vfslist; 148be2c4e54SDavid E. O'Brien size_t i, mntsize; 149be2c4e54SDavid E. O'Brien int ch, rv; 150f3895a82SKris Kennaway 151f3895a82SKris Kennaway fstype = "ufs"; 1524b88c807SRodney W. Grimes 153076419d2SDavid E. O'Brien memset (&totalbuf, 0, sizeof (totalbuf)); 154076419d2SDavid E. O'Brien totalbuf.f_bsize = DEV_BSIZE; 155076419d2SDavid E. O'Brien strncpy (totalbuf.f_mntfromname, "total", MNAMELEN); 156a78192e3SBruce Evans vfslist = NULL; 157076419d2SDavid E. O'Brien while ((ch = getopt(argc, argv, "abcgHhiklmnPt:")) != -1) 1584b88c807SRodney W. Grimes switch (ch) { 1595b42dac8SJulian Elischer case 'a': 1605b42dac8SJulian Elischer aflag = 1; 1615b42dac8SJulian Elischer break; 162076419d2SDavid E. O'Brien case 'c': 163076419d2SDavid E. O'Brien cflag = 1; 164076419d2SDavid E. O'Brien break; 165dd6d33e8SMichael Haro case 'b': 166dd6d33e8SMichael Haro /* FALLTHROUGH */ 167dd6d33e8SMichael Haro case 'P': 168dd6d33e8SMichael Haro putenv("BLOCKSIZE=512"); 169dd6d33e8SMichael Haro hflag = 0; 170dd6d33e8SMichael Haro break; 17193a3fa19SJohn W. De Boskey case 'g': 17293a3fa19SJohn W. De Boskey putenv("BLOCKSIZE=1g"); 17393a3fa19SJohn W. De Boskey hflag = 0; 17493a3fa19SJohn W. De Boskey break; 175dd6d33e8SMichael Haro case 'H': 176dd6d33e8SMichael Haro hflag = UNITS_SI; 177dd6d33e8SMichael Haro valp = vals_si; 178dd6d33e8SMichael Haro break; 179dd6d33e8SMichael Haro case 'h': 180dd6d33e8SMichael Haro hflag = UNITS_2; 181dd6d33e8SMichael Haro valp = vals_base2; 182dd6d33e8SMichael Haro break; 1834b88c807SRodney W. Grimes case 'i': 1844b88c807SRodney W. Grimes iflag = 1; 1854b88c807SRodney W. Grimes break; 1867f0eabfdSGarrett Wollman case 'k': 1879d4081eeSDavid Greenman putenv("BLOCKSIZE=1k"); 188dd6d33e8SMichael Haro hflag = 0; 189dd6d33e8SMichael Haro break; 190a25695c3SJim Pirzyk case 'l': 191a25695c3SJim Pirzyk if (vfslist != NULL) 192a25695c3SJim Pirzyk errx(1, "-l and -t are mutually exclusive."); 193a25695c3SJim Pirzyk vfslist = makevfslist(makenetvfslist()); 194a25695c3SJim Pirzyk break; 195dd6d33e8SMichael Haro case 'm': 196dd6d33e8SMichael Haro putenv("BLOCKSIZE=1m"); 197dd6d33e8SMichael Haro hflag = 0; 1987f0eabfdSGarrett Wollman break; 1994b88c807SRodney W. Grimes case 'n': 2004b88c807SRodney W. Grimes nflag = 1; 2014b88c807SRodney W. Grimes break; 2024b88c807SRodney W. Grimes case 't': 203a78192e3SBruce Evans if (vfslist != NULL) 2047b3a12a8SPhilippe Charnier errx(1, "only one -t option may be specified"); 205f3895a82SKris Kennaway fstype = optarg; 206a78192e3SBruce Evans vfslist = makevfslist(optarg); 2074b88c807SRodney W. Grimes break; 2084b88c807SRodney W. Grimes case '?': 2094b88c807SRodney W. Grimes default: 2104b88c807SRodney W. Grimes usage(); 2114b88c807SRodney W. Grimes } 2124b88c807SRodney W. Grimes argc -= optind; 2134b88c807SRodney W. Grimes argv += optind; 2144b88c807SRodney W. Grimes 2154b88c807SRodney W. Grimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 21662edbd31SIan Dowse bzero(&maxwidths, sizeof(maxwidths)); 21762edbd31SIan Dowse for (i = 0; i < mntsize; i++) 21862edbd31SIan Dowse update_maxwidths(&maxwidths, &mntbuf[i]); 2194b88c807SRodney W. Grimes 220b8904f2aSJoerg Wunsch rv = 0; 2214b88c807SRodney W. Grimes if (!*argv) { 222a78192e3SBruce Evans mntsize = regetmntinfo(&mntbuf, mntsize, vfslist); 22362edbd31SIan Dowse bzero(&maxwidths, sizeof(maxwidths)); 2245b42dac8SJulian Elischer for (i = 0; i < mntsize; i++) { 225076419d2SDavid E. O'Brien if (cflag) 226076419d2SDavid E. O'Brien addstat(&totalbuf, &mntbuf[i]); 227076419d2SDavid E. O'Brien update_maxwidths(&maxwidths, &mntbuf[i]); 228076419d2SDavid E. O'Brien } 229076419d2SDavid E. O'Brien if (cflag) 230076419d2SDavid E. O'Brien update_maxwidths(&maxwidths, &totalbuf); 231076419d2SDavid E. O'Brien for (i = 0; i < mntsize; i++) 2325b42dac8SJulian Elischer if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) 23362edbd31SIan Dowse prtstat(&mntbuf[i], &maxwidths); 234076419d2SDavid E. O'Brien if (cflag) 235076419d2SDavid E. O'Brien prtstat(&totalbuf, &maxwidths); 236b8904f2aSJoerg Wunsch exit(rv); 2374b88c807SRodney W. Grimes } 2384b88c807SRodney W. Grimes 2394b88c807SRodney W. Grimes for (; *argv; argv++) { 2404b88c807SRodney W. Grimes if (stat(*argv, &stbuf) < 0) { 2414b88c807SRodney W. Grimes if ((mntpt = getmntpt(*argv)) == 0) { 2424b88c807SRodney W. Grimes warn("%s", *argv); 243b8904f2aSJoerg Wunsch rv = 1; 2444b88c807SRodney W. Grimes continue; 2454b88c807SRodney W. Grimes } 246f3895a82SKris Kennaway } else if (S_ISCHR(stbuf.st_mode)) { 247f3895a82SKris Kennaway if ((mntpt = getmntpt(*argv)) == 0) { 248f3895a82SKris Kennaway mdev.fspec = *argv; 249f3895a82SKris Kennaway mntpath = strdup("/tmp/df.XXXXXX"); 250f3895a82SKris Kennaway if (mntpath == NULL) { 251f3895a82SKris Kennaway warn("strdup failed"); 252f3895a82SKris Kennaway rv = 1; 2534b88c807SRodney W. Grimes continue; 254f3895a82SKris Kennaway } 255f3895a82SKris Kennaway mntpt = mkdtemp(mntpath); 256f3895a82SKris Kennaway if (mntpt == NULL) { 257f3895a82SKris Kennaway warn("mkdtemp(\"%s\") failed", mntpath); 258f3895a82SKris Kennaway rv = 1; 259f3895a82SKris Kennaway free(mntpath); 260f3895a82SKris Kennaway continue; 261f3895a82SKris Kennaway } 262f3895a82SKris Kennaway if (mount(fstype, mntpt, MNT_RDONLY, 263f3895a82SKris Kennaway &mdev) != 0) { 264532aff98SPoul-Henning Kamp warn("%s", *argv); 265532aff98SPoul-Henning Kamp rv = 1; 266f3895a82SKris Kennaway (void)rmdir(mntpt); 267f3895a82SKris Kennaway free(mntpath); 268f3895a82SKris Kennaway continue; 269f3895a82SKris Kennaway } else if (statfs(mntpt, &statfsbuf) == 0) { 270f3895a82SKris Kennaway statfsbuf.f_mntonname[0] = '\0'; 27162edbd31SIan Dowse prtstat(&statfsbuf, &maxwidths); 272076419d2SDavid E. O'Brien if (cflag) 273076419d2SDavid E. O'Brien addstat(&totalbuf, &statfsbuf); 274f3895a82SKris Kennaway } else { 275f3895a82SKris Kennaway warn("%s", *argv); 276f3895a82SKris Kennaway rv = 1; 277f3895a82SKris Kennaway } 278f3895a82SKris Kennaway (void)unmount(mntpt, 0); 279f3895a82SKris Kennaway (void)rmdir(mntpt); 280f3895a82SKris Kennaway free(mntpath); 281f3895a82SKris Kennaway continue; 282f3895a82SKris Kennaway } 2834b88c807SRodney W. Grimes } else 2844b88c807SRodney W. Grimes mntpt = *argv; 2850e7d023fSBruce Evans 2864b88c807SRodney W. Grimes /* 2874b88c807SRodney W. Grimes * Statfs does not take a `wait' flag, so we cannot 2884b88c807SRodney W. Grimes * implement nflag here. 2894b88c807SRodney W. Grimes */ 2904b88c807SRodney W. Grimes if (statfs(mntpt, &statfsbuf) < 0) { 2914b88c807SRodney W. Grimes warn("%s", mntpt); 292b8904f2aSJoerg Wunsch rv = 1; 2934b88c807SRodney W. Grimes continue; 2944b88c807SRodney W. Grimes } 2950e7d023fSBruce Evans 2960e7d023fSBruce Evans /* 2970e7d023fSBruce Evans * Check to make sure the arguments we've been given are 2980e7d023fSBruce Evans * satisfied. Return an error if we have been asked to 2990e7d023fSBruce Evans * list a mount point that does not match the other args 3000e7d023fSBruce Evans * we've been given (-l, -t, etc.). 301c22acefbSJordan K. Hubbard */ 302c22acefbSJordan K. Hubbard if (checkvfsname(statfsbuf.f_fstypename, vfslist)) { 3030e7d023fSBruce Evans rv = 1; 304c22acefbSJordan K. Hubbard continue; 305c22acefbSJordan K. Hubbard } 3060e7d023fSBruce Evans 30762edbd31SIan Dowse if (argc == 1) { 30862edbd31SIan Dowse bzero(&maxwidths, sizeof(maxwidths)); 30962edbd31SIan Dowse update_maxwidths(&maxwidths, &statfsbuf); 31062edbd31SIan Dowse } 31162edbd31SIan Dowse prtstat(&statfsbuf, &maxwidths); 312076419d2SDavid E. O'Brien if (cflag) 313076419d2SDavid E. O'Brien addstat(&totalbuf, &statfsbuf); 3144b88c807SRodney W. Grimes } 315076419d2SDavid E. O'Brien if (cflag) 316076419d2SDavid E. O'Brien prtstat(&totalbuf, &maxwidths); 317b8904f2aSJoerg Wunsch return (rv); 3184b88c807SRodney W. Grimes } 3194b88c807SRodney W. Grimes 320532aff98SPoul-Henning Kamp static char * 321b7dbd3e9SMark Murray getmntpt(const char *name) 3224b88c807SRodney W. Grimes { 323be2c4e54SDavid E. O'Brien size_t mntsize, i; 3244b88c807SRodney W. Grimes struct statfs *mntbuf; 3254b88c807SRodney W. Grimes 3264b88c807SRodney W. Grimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 3274b88c807SRodney W. Grimes for (i = 0; i < mntsize; i++) { 3284b88c807SRodney W. Grimes if (!strcmp(mntbuf[i].f_mntfromname, name)) 3294b88c807SRodney W. Grimes return (mntbuf[i].f_mntonname); 3304b88c807SRodney W. Grimes } 3314b88c807SRodney W. Grimes return (0); 3324b88c807SRodney W. Grimes } 3334b88c807SRodney W. Grimes 3344b88c807SRodney W. Grimes /* 3354b88c807SRodney W. Grimes * Make a pass over the file system info in ``mntbuf'' filtering out 336a78192e3SBruce Evans * file system types not in vfslist and possibly re-stating to get 3374b88c807SRodney W. Grimes * current (not cached) info. Returns the new count of valid statfs bufs. 3384b88c807SRodney W. Grimes */ 339be2c4e54SDavid E. O'Brien static size_t 340532aff98SPoul-Henning Kamp regetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist) 3414b88c807SRodney W. Grimes { 3424b88c807SRodney W. Grimes int i, j; 3434b88c807SRodney W. Grimes struct statfs *mntbuf; 3444b88c807SRodney W. Grimes 345a78192e3SBruce Evans if (vfslist == NULL) 3464b88c807SRodney W. Grimes return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT)); 3474b88c807SRodney W. Grimes 3484b88c807SRodney W. Grimes mntbuf = *mntbufp; 349a78192e3SBruce Evans for (j = 0, i = 0; i < mntsize; i++) { 350a78192e3SBruce Evans if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) 351a78192e3SBruce Evans continue; 3524b88c807SRodney W. Grimes if (!nflag) 3534b88c807SRodney W. Grimes (void)statfs(mntbuf[i].f_mntonname,&mntbuf[j]); 3544b88c807SRodney W. Grimes else if (i != j) 3554b88c807SRodney W. Grimes mntbuf[j] = mntbuf[i]; 3564b88c807SRodney W. Grimes j++; 3574b88c807SRodney W. Grimes } 3584b88c807SRodney W. Grimes return (j); 3594b88c807SRodney W. Grimes } 3604b88c807SRodney W. Grimes 3614b88c807SRodney W. Grimes /* 362dd6d33e8SMichael Haro * Output in "human-readable" format. Uses 3 digits max and puts 363dd6d33e8SMichael Haro * unit suffixes at the end. Makes output compact and easy to read, 364dd6d33e8SMichael Haro * especially on huge disks. 365dd6d33e8SMichael Haro * 366dd6d33e8SMichael Haro */ 367532aff98SPoul-Henning Kamp static unit_t 368f9bcb0beSWarner Losh unit_adjust(double *val) 369dd6d33e8SMichael Haro { 370dd6d33e8SMichael Haro double abval; 371dd6d33e8SMichael Haro unit_t unit; 372b7dbd3e9SMark Murray int unit_sz; 373dd6d33e8SMichael Haro 374dd6d33e8SMichael Haro abval = fabs(*val); 375dd6d33e8SMichael Haro 376dd6d33e8SMichael Haro unit_sz = abval ? ilogb(abval) / 10 : 0; 377dd6d33e8SMichael Haro 378b7dbd3e9SMark Murray if (unit_sz >= (int)UNIT_MAX) { 379dd6d33e8SMichael Haro unit = NONE; 380dd6d33e8SMichael Haro } else { 381dd6d33e8SMichael Haro unit = unitp[unit_sz]; 382dd6d33e8SMichael Haro *val /= (double)valp[unit_sz]; 383dd6d33e8SMichael Haro } 384dd6d33e8SMichael Haro 385dd6d33e8SMichael Haro return (unit); 386dd6d33e8SMichael Haro } 387dd6d33e8SMichael Haro 388532aff98SPoul-Henning Kamp static void 389fde81c7dSKirk McKusick prthuman(const struct statfs *sfsp, int64_t used) 390dd6d33e8SMichael Haro { 391dd6d33e8SMichael Haro 392dd6d33e8SMichael Haro prthumanval((double)sfsp->f_blocks * (double)sfsp->f_bsize); 393dd6d33e8SMichael Haro prthumanval((double)used * (double)sfsp->f_bsize); 394dd6d33e8SMichael Haro prthumanval((double)sfsp->f_bavail * (double)sfsp->f_bsize); 395dd6d33e8SMichael Haro } 396dd6d33e8SMichael Haro 397532aff98SPoul-Henning Kamp static void 398f9bcb0beSWarner Losh prthumanval(double bytes) 399dd6d33e8SMichael Haro { 400dd6d33e8SMichael Haro 401dd6d33e8SMichael Haro unit_t unit; 402dd6d33e8SMichael Haro unit = unit_adjust(&bytes); 403dd6d33e8SMichael Haro 404dd6d33e8SMichael Haro if (bytes == 0) 405dd6d33e8SMichael Haro (void)printf(" 0B"); 406dd6d33e8SMichael Haro else if (bytes > 10) 407076419d2SDavid E. O'Brien (void)printf(" % 6.0f%c", bytes, "BKMGTPE"[unit]); 408dd6d33e8SMichael Haro else 409076419d2SDavid E. O'Brien (void)printf(" % 6.1f%c", bytes, "BKMGTPE"[unit]); 410dd6d33e8SMichael Haro } 411dd6d33e8SMichael Haro 412dd6d33e8SMichael Haro /* 4134b88c807SRodney W. Grimes * Convert statfs returned file system size into BLOCKSIZE units. 4144b88c807SRodney W. Grimes * Attempts to avoid overflow for large file systems. 4154b88c807SRodney W. Grimes */ 4164b88c807SRodney W. Grimes #define fsbtoblk(num, fsbs, bs) \ 4174b88c807SRodney W. Grimes (((fsbs) != 0 && (fsbs) < (bs)) ? \ 418ae21f5adSLukas Ertl (num) / (intmax_t)((bs) / (fsbs)) : \ 419ae21f5adSLukas Ertl (num) * (intmax_t)((fsbs) / (bs))) 4204b88c807SRodney W. Grimes 4214b88c807SRodney W. Grimes /* 4224b88c807SRodney W. Grimes * Print out status about a file system. 4234b88c807SRodney W. Grimes */ 424532aff98SPoul-Henning Kamp static void 42562edbd31SIan Dowse prtstat(struct statfs *sfsp, struct maxwidths *mwp) 4264b88c807SRodney W. Grimes { 427fde81c7dSKirk McKusick static u_long blocksize; 428b7dbd3e9SMark Murray static int headerlen, timesthrough = 0; 429a95a13bbSKris Kennaway static const char *header; 430fde81c7dSKirk McKusick int64_t used, availblks, inodes; 431076419d2SDavid E. O'Brien int total; 4324b88c807SRodney W. Grimes 4334b88c807SRodney W. Grimes if (++timesthrough == 1) { 4340bd9f151SIan Dowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen("Filesystem")); 435dd6d33e8SMichael Haro if (hflag) { 436dd6d33e8SMichael Haro header = " Size"; 4370bd9f151SIan Dowse mwp->total = mwp->used = mwp->avail = 4380bd9f151SIan Dowse (int)strlen(header); 439dd6d33e8SMichael Haro } else { 440dd6d33e8SMichael Haro header = getbsize(&headerlen, &blocksize); 4410bd9f151SIan Dowse mwp->total = imax(mwp->total, headerlen); 442dd6d33e8SMichael Haro } 4430bd9f151SIan Dowse mwp->used = imax(mwp->used, (int)strlen("Used")); 4440bd9f151SIan Dowse mwp->avail = imax(mwp->avail, (int)strlen("Avail")); 44562edbd31SIan Dowse 446f694b8adSMark Murray (void)printf("%-*s %-*s %*s %*s Capacity", 4470bd9f151SIan Dowse mwp->mntfrom, "Filesystem", mwp->total, header, 4480bd9f151SIan Dowse mwp->used, "Used", mwp->avail, "Avail"); 44962edbd31SIan Dowse if (iflag) { 4500bd9f151SIan Dowse mwp->iused = imax(mwp->iused, (int)strlen(" iused")); 4510bd9f151SIan Dowse mwp->ifree = imax(mwp->ifree, (int)strlen("ifree")); 452f694b8adSMark Murray (void)printf(" %*s %*s %%iused", 4530bd9f151SIan Dowse mwp->iused - 2, "iused", mwp->ifree, "ifree"); 45462edbd31SIan Dowse } 4554b88c807SRodney W. Grimes (void)printf(" Mounted on\n"); 4564b88c807SRodney W. Grimes } 4570bd9f151SIan Dowse (void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname); 4584b88c807SRodney W. Grimes used = sfsp->f_blocks - sfsp->f_bfree; 4594b88c807SRodney W. Grimes availblks = sfsp->f_bavail + used; 460dd6d33e8SMichael Haro if (hflag) { 461dd6d33e8SMichael Haro prthuman(sfsp, used); 462dd6d33e8SMichael Haro } else { 463ea64ad77SKris Kennaway (void)printf(" %*jd %*jd %*jd", 4640bd9f151SIan Dowse mwp->total, (intmax_t)fsbtoblk(sfsp->f_blocks, 4650bd9f151SIan Dowse sfsp->f_bsize, blocksize), 4660bd9f151SIan Dowse mwp->used, (intmax_t)fsbtoblk(used, sfsp->f_bsize, 4670bd9f151SIan Dowse blocksize), 4680bd9f151SIan Dowse mwp->avail, (intmax_t)fsbtoblk(sfsp->f_bavail, 4690bd9f151SIan Dowse sfsp->f_bsize, blocksize)); 470dd6d33e8SMichael Haro } 4714b88c807SRodney W. Grimes (void)printf(" %5.0f%%", 4724b88c807SRodney W. Grimes availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0); 473076419d2SDavid E. O'Brien total = !*sfsp->f_mntonname && 474076419d2SDavid E. O'Brien strncmp(sfsp->f_mntfromname, "total", MNAMELEN) == 0; 4754b88c807SRodney W. Grimes if (iflag) { 4764b88c807SRodney W. Grimes inodes = sfsp->f_files; 4774b88c807SRodney W. Grimes used = inodes - sfsp->f_ffree; 4780bd9f151SIan Dowse (void)printf(" %*jd %*jd %4.0f%% ", mwp->iused, (intmax_t)used, 4790bd9f151SIan Dowse mwp->ifree, (intmax_t)sfsp->f_ffree, inodes == 0 ? 100.0 : 4800bd9f151SIan Dowse (double)used / (double)inodes * 100.0); 481cca108e6SDavid E. O'Brien } else 482cca108e6SDavid E. O'Brien (void)printf(" "); 483cca108e6SDavid E. O'Brien if (!total) 484076419d2SDavid E. O'Brien (void)printf(" %s", sfsp->f_mntonname); 485076419d2SDavid E. O'Brien (void)printf("\n"); 486076419d2SDavid E. O'Brien } 487076419d2SDavid E. O'Brien 488076419d2SDavid E. O'Brien void 489076419d2SDavid E. O'Brien addstat(struct statfs *totalfsp, struct statfs *statfsp) 490076419d2SDavid E. O'Brien { 491076419d2SDavid E. O'Brien double bsize = statfsp->f_bsize / totalfsp->f_bsize; 492076419d2SDavid E. O'Brien 493076419d2SDavid E. O'Brien totalfsp->f_blocks += statfsp->f_blocks * bsize; 494076419d2SDavid E. O'Brien totalfsp->f_bfree += statfsp->f_bfree * bsize; 495076419d2SDavid E. O'Brien totalfsp->f_bavail += statfsp->f_bavail * bsize; 496076419d2SDavid E. O'Brien totalfsp->f_files += statfsp->f_files; 497076419d2SDavid E. O'Brien totalfsp->f_ffree += statfsp->f_ffree; 4984b88c807SRodney W. Grimes } 4994b88c807SRodney W. Grimes 5004b88c807SRodney W. Grimes /* 50162edbd31SIan Dowse * Update the maximum field-width information in `mwp' based on 50262edbd31SIan Dowse * the file system specified by `sfsp'. 50362edbd31SIan Dowse */ 504532aff98SPoul-Henning Kamp static void 505b7dbd3e9SMark Murray update_maxwidths(struct maxwidths *mwp, const struct statfs *sfsp) 50662edbd31SIan Dowse { 507fde81c7dSKirk McKusick static u_long blocksize = 0; 508dc474219SMike Barcroft int dummy; 50962edbd31SIan Dowse 51062edbd31SIan Dowse if (blocksize == 0) 51162edbd31SIan Dowse getbsize(&dummy, &blocksize); 51262edbd31SIan Dowse 5130bd9f151SIan Dowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen(sfsp->f_mntfromname)); 5140bd9f151SIan Dowse mwp->total = imax(mwp->total, int64width( 515fde81c7dSKirk McKusick fsbtoblk((int64_t)sfsp->f_blocks, sfsp->f_bsize, blocksize))); 5160bd9f151SIan Dowse mwp->used = imax(mwp->used, 5170bd9f151SIan Dowse int64width(fsbtoblk((int64_t)sfsp->f_blocks - 518fde81c7dSKirk McKusick (int64_t)sfsp->f_bfree, sfsp->f_bsize, blocksize))); 5190bd9f151SIan Dowse mwp->avail = imax(mwp->avail, int64width(fsbtoblk(sfsp->f_bavail, 52062edbd31SIan Dowse sfsp->f_bsize, blocksize))); 5210bd9f151SIan Dowse mwp->iused = imax(mwp->iused, int64width((int64_t)sfsp->f_files - 52262edbd31SIan Dowse sfsp->f_ffree)); 5230bd9f151SIan Dowse mwp->ifree = imax(mwp->ifree, int64width(sfsp->f_ffree)); 52462edbd31SIan Dowse } 52562edbd31SIan Dowse 5260bd9f151SIan Dowse /* Return the width in characters of the specified value. */ 5270bd9f151SIan Dowse static int 528fde81c7dSKirk McKusick int64width(int64_t val) 52962edbd31SIan Dowse { 5300bd9f151SIan Dowse int len; 53162edbd31SIan Dowse 53262edbd31SIan Dowse len = 0; 53362edbd31SIan Dowse /* Negative or zero values require one extra digit. */ 53462edbd31SIan Dowse if (val <= 0) { 53562edbd31SIan Dowse val = -val; 53662edbd31SIan Dowse len++; 53762edbd31SIan Dowse } 53862edbd31SIan Dowse while (val > 0) { 53962edbd31SIan Dowse len++; 54062edbd31SIan Dowse val /= 10; 54162edbd31SIan Dowse } 54262edbd31SIan Dowse 54362edbd31SIan Dowse return (len); 54462edbd31SIan Dowse } 54562edbd31SIan Dowse 546532aff98SPoul-Henning Kamp static void 547f9bcb0beSWarner Losh usage(void) 5484b88c807SRodney W. Grimes { 549dd6d33e8SMichael Haro 550a78192e3SBruce Evans (void)fprintf(stderr, 551076419d2SDavid E. O'Brien "usage: df [-b | -H | -h | -k | -m | -P] [-aciln] [-t type] [file | filesystem ...]\n"); 552dd6d33e8SMichael Haro exit(EX_USAGE); 5534b88c807SRodney W. Grimes } 554a25695c3SJim Pirzyk 555532aff98SPoul-Henning Kamp static char * 556f9bcb0beSWarner Losh makenetvfslist(void) 557a25695c3SJim Pirzyk { 558a25695c3SJim Pirzyk char *str, *strptr, **listptr; 559b7dbd3e9SMark Murray struct xvfsconf *xvfsp, *keep_xvfsp; 5605965373eSMaxime Henrion size_t buflen; 5615965373eSMaxime Henrion int cnt, i, maxvfsconf; 562a25695c3SJim Pirzyk 5635965373eSMaxime Henrion if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) { 5645965373eSMaxime Henrion warn("sysctl(vfs.conflist)"); 565a25695c3SJim Pirzyk return (NULL); 566a25695c3SJim Pirzyk } 5675965373eSMaxime Henrion xvfsp = malloc(buflen); 5685965373eSMaxime Henrion if (xvfsp == NULL) { 5695965373eSMaxime Henrion warnx("malloc failed"); 5705965373eSMaxime Henrion return (NULL); 5715965373eSMaxime Henrion } 572b7dbd3e9SMark Murray keep_xvfsp = xvfsp; 5735965373eSMaxime Henrion if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) { 5745965373eSMaxime Henrion warn("sysctl(vfs.conflist)"); 575b7dbd3e9SMark Murray free(keep_xvfsp); 5765965373eSMaxime Henrion return (NULL); 5775965373eSMaxime Henrion } 5785965373eSMaxime Henrion maxvfsconf = buflen / sizeof(struct xvfsconf); 579a25695c3SJim Pirzyk 580a25695c3SJim Pirzyk if ((listptr = malloc(sizeof(char*) * maxvfsconf)) == NULL) { 581a25695c3SJim Pirzyk warnx("malloc failed"); 582b7dbd3e9SMark Murray free(keep_xvfsp); 583a25695c3SJim Pirzyk return (NULL); 584a25695c3SJim Pirzyk } 585a25695c3SJim Pirzyk 5865965373eSMaxime Henrion for (cnt = 0, i = 0; i < maxvfsconf; i++) { 5875965373eSMaxime Henrion if (xvfsp->vfc_flags & VFCF_NETWORK) { 5885965373eSMaxime Henrion listptr[cnt++] = strdup(xvfsp->vfc_name); 589a067aeceSGarrett Wollman if (listptr[cnt-1] == NULL) { 590a25695c3SJim Pirzyk warnx("malloc failed"); 591b7dbd3e9SMark Murray free(listptr); 592b7dbd3e9SMark Murray free(keep_xvfsp); 593a25695c3SJim Pirzyk return (NULL); 594a25695c3SJim Pirzyk } 595a25695c3SJim Pirzyk } 5965965373eSMaxime Henrion xvfsp++; 5975965373eSMaxime Henrion } 598a25695c3SJim Pirzyk 599cf5b29e1SRuslan Ermilov if (cnt == 0 || 600cf5b29e1SRuslan Ermilov (str = malloc(sizeof(char) * (32 * cnt + cnt + 2))) == NULL) { 601cf5b29e1SRuslan Ermilov if (cnt > 0) 602a25695c3SJim Pirzyk warnx("malloc failed"); 603a25695c3SJim Pirzyk free(listptr); 604b7dbd3e9SMark Murray free(keep_xvfsp); 605a25695c3SJim Pirzyk return (NULL); 606a25695c3SJim Pirzyk } 607a25695c3SJim Pirzyk 608a25695c3SJim Pirzyk *str = 'n'; *(str + 1) = 'o'; 609a25695c3SJim Pirzyk for (i = 0, strptr = str + 2; i < cnt; i++, strptr++) { 610a25695c3SJim Pirzyk strncpy(strptr, listptr[i], 32); 611a25695c3SJim Pirzyk strptr += strlen(listptr[i]); 612a25695c3SJim Pirzyk *strptr = ','; 613a25695c3SJim Pirzyk free(listptr[i]); 614a25695c3SJim Pirzyk } 61516fc3635SMark Murray *(--strptr) = '\0'; 616a25695c3SJim Pirzyk 617b7dbd3e9SMark Murray free(keep_xvfsp); 618a25695c3SJim Pirzyk free(listptr); 619a25695c3SJim Pirzyk return (str); 620a25695c3SJim Pirzyk } 621