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 4016cc192aSSteve Price static const 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 4616cc192aSSteve Price #if 0 4716cc192aSSteve Price static char sccsid[] = "@(#)df.c 8.9 (Berkeley) 5/8/95"; 4816cc192aSSteve Price #else 4916cc192aSSteve Price static const char rcsid[] = 502a456239SPeter Wemm "$FreeBSD$"; 5116cc192aSSteve Price #endif 524b88c807SRodney W. Grimes #endif /* not lint */ 534b88c807SRodney W. Grimes 5439661e26SMark Murray #include <sys/cdefs.h> 554b88c807SRodney W. Grimes #include <sys/param.h> 564b88c807SRodney W. Grimes #include <sys/stat.h> 574b88c807SRodney W. Grimes #include <sys/mount.h> 58a25695c3SJim Pirzyk #include <sys/sysctl.h> 59a78192e3SBruce Evans #include <ufs/ufs/ufsmount.h> 6039661e26SMark Murray #include <ufs/ffs/fs.h> 614b88c807SRodney W. Grimes 624b88c807SRodney W. Grimes #include <err.h> 634b88c807SRodney W. Grimes #include <errno.h> 644b88c807SRodney W. Grimes #include <fcntl.h> 6539661e26SMark Murray #include <fstab.h> 66dd6d33e8SMichael Haro #include <math.h> 674b88c807SRodney W. Grimes #include <stdio.h> 684b88c807SRodney W. Grimes #include <stdlib.h> 694b88c807SRodney W. Grimes #include <string.h> 70dd6d33e8SMichael Haro #include <sysexits.h> 714b88c807SRodney W. Grimes #include <unistd.h> 724b88c807SRodney W. Grimes 73dd6d33e8SMichael Haro #define UNITS_SI 1 74dd6d33e8SMichael Haro #define UNITS_2 2 75dd6d33e8SMichael Haro 76dd6d33e8SMichael Haro #define KILO_SZ(n) (n) 77dd6d33e8SMichael Haro #define MEGA_SZ(n) ((n) * (n)) 78dd6d33e8SMichael Haro #define GIGA_SZ(n) ((n) * (n) * (n)) 79dd6d33e8SMichael Haro #define TERA_SZ(n) ((n) * (n) * (n) * (n)) 80dd6d33e8SMichael Haro #define PETA_SZ(n) ((n) * (n) * (n) * (n) * (n)) 81dd6d33e8SMichael Haro 82dd6d33e8SMichael Haro #define KILO_2_SZ (KILO_SZ(1024ULL)) 83dd6d33e8SMichael Haro #define MEGA_2_SZ (MEGA_SZ(1024ULL)) 84dd6d33e8SMichael Haro #define GIGA_2_SZ (GIGA_SZ(1024ULL)) 85dd6d33e8SMichael Haro #define TERA_2_SZ (TERA_SZ(1024ULL)) 86dd6d33e8SMichael Haro #define PETA_2_SZ (PETA_SZ(1024ULL)) 87dd6d33e8SMichael Haro 88dd6d33e8SMichael Haro #define KILO_SI_SZ (KILO_SZ(1000ULL)) 89dd6d33e8SMichael Haro #define MEGA_SI_SZ (MEGA_SZ(1000ULL)) 90dd6d33e8SMichael Haro #define GIGA_SI_SZ (GIGA_SZ(1000ULL)) 91dd6d33e8SMichael Haro #define TERA_SI_SZ (TERA_SZ(1000ULL)) 92dd6d33e8SMichael Haro #define PETA_SI_SZ (PETA_SZ(1000ULL)) 93dd6d33e8SMichael Haro 9462edbd31SIan Dowse /* Maximum widths of various fields. */ 9562edbd31SIan Dowse struct maxwidths { 9662edbd31SIan Dowse int mntfrom; 9762edbd31SIan Dowse int total; 9862edbd31SIan Dowse int used; 9962edbd31SIan Dowse int avail; 10062edbd31SIan Dowse int iused; 10162edbd31SIan Dowse int ifree; 10262edbd31SIan Dowse }; 10362edbd31SIan Dowse 104dd6d33e8SMichael Haro unsigned long long vals_si [] = {1, KILO_SI_SZ, MEGA_SI_SZ, GIGA_SI_SZ, TERA_SI_SZ, PETA_SI_SZ}; 105dd6d33e8SMichael Haro unsigned long long vals_base2[] = {1, KILO_2_SZ, MEGA_2_SZ, GIGA_2_SZ, TERA_2_SZ, PETA_2_SZ}; 106dd6d33e8SMichael Haro unsigned long long *valp; 107dd6d33e8SMichael Haro 108dd6d33e8SMichael Haro typedef enum { NONE, KILO, MEGA, GIGA, TERA, PETA, UNIT_MAX } unit_t; 109dd6d33e8SMichael Haro 11039661e26SMark Murray unit_t unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA }; 111dd6d33e8SMichael Haro 112f9bcb0beSWarner Losh int bread(off_t, void *, int); 113f9bcb0beSWarner Losh int checkvfsname(const char *, char **); 114f9bcb0beSWarner Losh char *getmntpt(char *); 11562edbd31SIan Dowse int longwidth(long); 116f9bcb0beSWarner Losh char *makenetvfslist(void); 117f9bcb0beSWarner Losh char **makevfslist(char *); 118f9bcb0beSWarner Losh void prthuman(struct statfs *, long); 119f9bcb0beSWarner Losh void prthumanval(double); 12062edbd31SIan Dowse void prtstat(struct statfs *, struct maxwidths *); 121f9bcb0beSWarner Losh long regetmntinfo(struct statfs **, long, char **); 12262edbd31SIan Dowse int ufs_df(char *, struct maxwidths *); 123f9bcb0beSWarner Losh unit_t unit_adjust(double *); 12462edbd31SIan Dowse void update_maxwidths(struct maxwidths *, struct statfs *); 125f9bcb0beSWarner Losh void usage(void); 1264b88c807SRodney W. Grimes 127dd6d33e8SMichael Haro int aflag = 0, hflag, iflag, nflag; 1284b88c807SRodney W. Grimes struct ufs_args mdev; 1294b88c807SRodney W. Grimes 13062edbd31SIan Dowse static __inline int imax(int a, int b) 13162edbd31SIan Dowse { 13262edbd31SIan Dowse return (a > b ? a : b); 13362edbd31SIan Dowse } 13462edbd31SIan Dowse 1354b88c807SRodney W. Grimes int 136f9bcb0beSWarner Losh main(int argc, char *argv[]) 1374b88c807SRodney W. Grimes { 1384b88c807SRodney W. Grimes struct stat stbuf; 1394b88c807SRodney W. Grimes struct statfs statfsbuf, *mntbuf; 14062edbd31SIan Dowse struct maxwidths maxwidths; 141a95a13bbSKris Kennaway const char *fstype; 142a95a13bbSKris Kennaway char *mntpath, *mntpt, **vfslist; 143a78192e3SBruce Evans long mntsize; 14462edbd31SIan Dowse int ch, i, rv; 145f3895a82SKris Kennaway 146f3895a82SKris Kennaway fstype = "ufs"; 1474b88c807SRodney W. Grimes 148a78192e3SBruce Evans vfslist = NULL; 149a25695c3SJim Pirzyk while ((ch = getopt(argc, argv, "abgHhiklmnPt:")) != -1) 1504b88c807SRodney W. Grimes switch (ch) { 1515b42dac8SJulian Elischer case 'a': 1525b42dac8SJulian Elischer aflag = 1; 1535b42dac8SJulian Elischer break; 154dd6d33e8SMichael Haro case 'b': 155dd6d33e8SMichael Haro /* FALLTHROUGH */ 156dd6d33e8SMichael Haro case 'P': 157dd6d33e8SMichael Haro putenv("BLOCKSIZE=512"); 158dd6d33e8SMichael Haro hflag = 0; 159dd6d33e8SMichael Haro break; 16093a3fa19SJohn W. De Boskey case 'g': 16193a3fa19SJohn W. De Boskey putenv("BLOCKSIZE=1g"); 16293a3fa19SJohn W. De Boskey hflag = 0; 16393a3fa19SJohn W. De Boskey break; 164dd6d33e8SMichael Haro case 'H': 165dd6d33e8SMichael Haro hflag = UNITS_SI; 166dd6d33e8SMichael Haro valp = vals_si; 167dd6d33e8SMichael Haro break; 168dd6d33e8SMichael Haro case 'h': 169dd6d33e8SMichael Haro hflag = UNITS_2; 170dd6d33e8SMichael Haro valp = vals_base2; 171dd6d33e8SMichael Haro break; 1724b88c807SRodney W. Grimes case 'i': 1734b88c807SRodney W. Grimes iflag = 1; 1744b88c807SRodney W. Grimes break; 1757f0eabfdSGarrett Wollman case 'k': 1769d4081eeSDavid Greenman putenv("BLOCKSIZE=1k"); 177dd6d33e8SMichael Haro hflag = 0; 178dd6d33e8SMichael Haro break; 179a25695c3SJim Pirzyk case 'l': 180a25695c3SJim Pirzyk if (vfslist != NULL) 181a25695c3SJim Pirzyk errx(1, "-l and -t are mutually exclusive."); 182a25695c3SJim Pirzyk vfslist = makevfslist(makenetvfslist()); 183a25695c3SJim Pirzyk break; 184dd6d33e8SMichael Haro case 'm': 185dd6d33e8SMichael Haro putenv("BLOCKSIZE=1m"); 186dd6d33e8SMichael Haro hflag = 0; 1877f0eabfdSGarrett Wollman break; 1884b88c807SRodney W. Grimes case 'n': 1894b88c807SRodney W. Grimes nflag = 1; 1904b88c807SRodney W. Grimes break; 1914b88c807SRodney W. Grimes case 't': 192a78192e3SBruce Evans if (vfslist != NULL) 1937b3a12a8SPhilippe Charnier errx(1, "only one -t option may be specified"); 194f3895a82SKris Kennaway fstype = optarg; 195a78192e3SBruce Evans vfslist = makevfslist(optarg); 1964b88c807SRodney W. Grimes break; 1974b88c807SRodney W. Grimes case '?': 1984b88c807SRodney W. Grimes default: 1994b88c807SRodney W. Grimes usage(); 2004b88c807SRodney W. Grimes } 2014b88c807SRodney W. Grimes argc -= optind; 2024b88c807SRodney W. Grimes argv += optind; 2034b88c807SRodney W. Grimes 2044b88c807SRodney W. Grimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 20562edbd31SIan Dowse bzero(&maxwidths, sizeof(maxwidths)); 20662edbd31SIan Dowse for (i = 0; i < mntsize; i++) 20762edbd31SIan Dowse update_maxwidths(&maxwidths, &mntbuf[i]); 2084b88c807SRodney W. Grimes 209b8904f2aSJoerg Wunsch rv = 0; 2104b88c807SRodney W. Grimes if (!*argv) { 211a78192e3SBruce Evans mntsize = regetmntinfo(&mntbuf, mntsize, vfslist); 212a78192e3SBruce Evans if (vfslist != NULL) { 21362edbd31SIan Dowse bzero(&maxwidths, sizeof(maxwidths)); 21462edbd31SIan Dowse for (i = 0; i < mntsize; i++) 21562edbd31SIan Dowse update_maxwidths(&maxwidths, &mntbuf[i]); 2164b88c807SRodney W. Grimes } 2175b42dac8SJulian Elischer for (i = 0; i < mntsize; i++) { 2185b42dac8SJulian Elischer if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) 21962edbd31SIan Dowse prtstat(&mntbuf[i], &maxwidths); 2205b42dac8SJulian Elischer } 221b8904f2aSJoerg Wunsch exit(rv); 2224b88c807SRodney W. Grimes } 2234b88c807SRodney W. Grimes 2244b88c807SRodney W. Grimes for (; *argv; argv++) { 2254b88c807SRodney W. Grimes if (stat(*argv, &stbuf) < 0) { 2264b88c807SRodney W. Grimes if ((mntpt = getmntpt(*argv)) == 0) { 2274b88c807SRodney W. Grimes warn("%s", *argv); 228b8904f2aSJoerg Wunsch rv = 1; 2294b88c807SRodney W. Grimes continue; 2304b88c807SRodney W. Grimes } 231f3895a82SKris Kennaway } else if (S_ISCHR(stbuf.st_mode)) { 232f3895a82SKris Kennaway if ((mntpt = getmntpt(*argv)) == 0) { 233f3895a82SKris Kennaway mdev.fspec = *argv; 234f3895a82SKris Kennaway mntpath = strdup("/tmp/df.XXXXXX"); 235f3895a82SKris Kennaway if (mntpath == NULL) { 236f3895a82SKris Kennaway warn("strdup failed"); 237f3895a82SKris Kennaway rv = 1; 2384b88c807SRodney W. Grimes continue; 239f3895a82SKris Kennaway } 240f3895a82SKris Kennaway mntpt = mkdtemp(mntpath); 241f3895a82SKris Kennaway if (mntpt == NULL) { 242f3895a82SKris Kennaway warn("mkdtemp(\"%s\") failed", mntpath); 243f3895a82SKris Kennaway rv = 1; 244f3895a82SKris Kennaway free(mntpath); 245f3895a82SKris Kennaway continue; 246f3895a82SKris Kennaway } 247f3895a82SKris Kennaway if (mount(fstype, mntpt, MNT_RDONLY, 248f3895a82SKris Kennaway &mdev) != 0) { 24962edbd31SIan Dowse rv = ufs_df(*argv, &maxwidths) || rv; 250f3895a82SKris Kennaway (void)rmdir(mntpt); 251f3895a82SKris Kennaway free(mntpath); 252f3895a82SKris Kennaway continue; 253f3895a82SKris Kennaway } else if (statfs(mntpt, &statfsbuf) == 0) { 254f3895a82SKris Kennaway statfsbuf.f_mntonname[0] = '\0'; 25562edbd31SIan Dowse prtstat(&statfsbuf, &maxwidths); 256f3895a82SKris Kennaway } else { 257f3895a82SKris Kennaway warn("%s", *argv); 258f3895a82SKris Kennaway rv = 1; 259f3895a82SKris Kennaway } 260f3895a82SKris Kennaway (void)unmount(mntpt, 0); 261f3895a82SKris Kennaway (void)rmdir(mntpt); 262f3895a82SKris Kennaway free(mntpath); 263f3895a82SKris Kennaway continue; 264f3895a82SKris Kennaway } 2654b88c807SRodney W. Grimes } else 2664b88c807SRodney W. Grimes mntpt = *argv; 2674b88c807SRodney W. Grimes /* 2684b88c807SRodney W. Grimes * Statfs does not take a `wait' flag, so we cannot 2694b88c807SRodney W. Grimes * implement nflag here. 2704b88c807SRodney W. Grimes */ 2714b88c807SRodney W. Grimes if (statfs(mntpt, &statfsbuf) < 0) { 2724b88c807SRodney W. Grimes warn("%s", mntpt); 273b8904f2aSJoerg Wunsch rv = 1; 2744b88c807SRodney W. Grimes continue; 2754b88c807SRodney W. Grimes } 27662edbd31SIan Dowse if (argc == 1) { 27762edbd31SIan Dowse bzero(&maxwidths, sizeof(maxwidths)); 27862edbd31SIan Dowse update_maxwidths(&maxwidths, &statfsbuf); 27962edbd31SIan Dowse } 28062edbd31SIan Dowse prtstat(&statfsbuf, &maxwidths); 2814b88c807SRodney W. Grimes } 282b8904f2aSJoerg Wunsch return (rv); 2834b88c807SRodney W. Grimes } 2844b88c807SRodney W. Grimes 2854b88c807SRodney W. Grimes char * 286f9bcb0beSWarner Losh getmntpt(char *name) 2874b88c807SRodney W. Grimes { 2884b88c807SRodney W. Grimes long mntsize, i; 2894b88c807SRodney W. Grimes struct statfs *mntbuf; 2904b88c807SRodney W. Grimes 2914b88c807SRodney W. Grimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 2924b88c807SRodney W. Grimes for (i = 0; i < mntsize; i++) { 2934b88c807SRodney W. Grimes if (!strcmp(mntbuf[i].f_mntfromname, name)) 2944b88c807SRodney W. Grimes return (mntbuf[i].f_mntonname); 2954b88c807SRodney W. Grimes } 2964b88c807SRodney W. Grimes return (0); 2974b88c807SRodney W. Grimes } 2984b88c807SRodney W. Grimes 2994b88c807SRodney W. Grimes /* 3004b88c807SRodney W. Grimes * Make a pass over the filesystem info in ``mntbuf'' filtering out 301a78192e3SBruce Evans * filesystem types not in vfslist and possibly re-stating to get 3024b88c807SRodney W. Grimes * current (not cached) info. Returns the new count of valid statfs bufs. 3034b88c807SRodney W. Grimes */ 3044b88c807SRodney W. Grimes long 305f9bcb0beSWarner Losh regetmntinfo(struct statfs **mntbufp, long mntsize, char **vfslist) 3064b88c807SRodney W. Grimes { 3074b88c807SRodney W. Grimes int i, j; 3084b88c807SRodney W. Grimes struct statfs *mntbuf; 3094b88c807SRodney W. Grimes 310a78192e3SBruce Evans if (vfslist == NULL) 3114b88c807SRodney W. Grimes return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT)); 3124b88c807SRodney W. Grimes 3134b88c807SRodney W. Grimes mntbuf = *mntbufp; 314a78192e3SBruce Evans for (j = 0, i = 0; i < mntsize; i++) { 315a78192e3SBruce Evans if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) 316a78192e3SBruce Evans continue; 3174b88c807SRodney W. Grimes if (!nflag) 3184b88c807SRodney W. Grimes (void)statfs(mntbuf[i].f_mntonname,&mntbuf[j]); 3194b88c807SRodney W. Grimes else if (i != j) 3204b88c807SRodney W. Grimes mntbuf[j] = mntbuf[i]; 3214b88c807SRodney W. Grimes j++; 3224b88c807SRodney W. Grimes } 3234b88c807SRodney W. Grimes return (j); 3244b88c807SRodney W. Grimes } 3254b88c807SRodney W. Grimes 3264b88c807SRodney W. Grimes /* 327dd6d33e8SMichael Haro * Output in "human-readable" format. Uses 3 digits max and puts 328dd6d33e8SMichael Haro * unit suffixes at the end. Makes output compact and easy to read, 329dd6d33e8SMichael Haro * especially on huge disks. 330dd6d33e8SMichael Haro * 331dd6d33e8SMichael Haro */ 332dd6d33e8SMichael Haro unit_t 333f9bcb0beSWarner Losh unit_adjust(double *val) 334dd6d33e8SMichael Haro { 335dd6d33e8SMichael Haro double abval; 336dd6d33e8SMichael Haro unit_t unit; 337dd6d33e8SMichael Haro unsigned int unit_sz; 338dd6d33e8SMichael Haro 339dd6d33e8SMichael Haro abval = fabs(*val); 340dd6d33e8SMichael Haro 341dd6d33e8SMichael Haro unit_sz = abval ? ilogb(abval) / 10 : 0; 342dd6d33e8SMichael Haro 343dd6d33e8SMichael Haro if (unit_sz >= UNIT_MAX) { 344dd6d33e8SMichael Haro unit = NONE; 345dd6d33e8SMichael Haro } else { 346dd6d33e8SMichael Haro unit = unitp[unit_sz]; 347dd6d33e8SMichael Haro *val /= (double)valp[unit_sz]; 348dd6d33e8SMichael Haro } 349dd6d33e8SMichael Haro 350dd6d33e8SMichael Haro return (unit); 351dd6d33e8SMichael Haro } 352dd6d33e8SMichael Haro 353dd6d33e8SMichael Haro void 354f9bcb0beSWarner Losh prthuman(struct statfs *sfsp, long used) 355dd6d33e8SMichael Haro { 356dd6d33e8SMichael Haro 357dd6d33e8SMichael Haro prthumanval((double)sfsp->f_blocks * (double)sfsp->f_bsize); 358dd6d33e8SMichael Haro prthumanval((double)used * (double)sfsp->f_bsize); 359dd6d33e8SMichael Haro prthumanval((double)sfsp->f_bavail * (double)sfsp->f_bsize); 360dd6d33e8SMichael Haro } 361dd6d33e8SMichael Haro 362dd6d33e8SMichael Haro void 363f9bcb0beSWarner Losh prthumanval(double bytes) 364dd6d33e8SMichael Haro { 365dd6d33e8SMichael Haro 366dd6d33e8SMichael Haro unit_t unit; 367dd6d33e8SMichael Haro unit = unit_adjust(&bytes); 368dd6d33e8SMichael Haro 369dd6d33e8SMichael Haro if (bytes == 0) 370dd6d33e8SMichael Haro (void)printf(" 0B"); 371dd6d33e8SMichael Haro else if (bytes > 10) 372dd6d33e8SMichael Haro (void)printf(" %5.0f%c", bytes, "BKMGTPE"[unit]); 373dd6d33e8SMichael Haro else 374dd6d33e8SMichael Haro (void)printf(" %5.1f%c", bytes, "BKMGTPE"[unit]); 375dd6d33e8SMichael Haro } 376dd6d33e8SMichael Haro 377dd6d33e8SMichael Haro /* 3784b88c807SRodney W. Grimes * Convert statfs returned filesystem size into BLOCKSIZE units. 3794b88c807SRodney W. Grimes * Attempts to avoid overflow for large filesystems. 3804b88c807SRodney W. Grimes */ 3814b88c807SRodney W. Grimes #define fsbtoblk(num, fsbs, bs) \ 3824b88c807SRodney W. Grimes (((fsbs) != 0 && (fsbs) < (bs)) ? \ 3834b88c807SRodney W. Grimes (num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs))) 3844b88c807SRodney W. Grimes 3854b88c807SRodney W. Grimes /* 3864b88c807SRodney W. Grimes * Print out status about a filesystem. 3874b88c807SRodney W. Grimes */ 3884b88c807SRodney W. Grimes void 38962edbd31SIan Dowse prtstat(struct statfs *sfsp, struct maxwidths *mwp) 3904b88c807SRodney W. Grimes { 3914b88c807SRodney W. Grimes static long blocksize; 3924b88c807SRodney W. Grimes static int headerlen, timesthrough; 393a95a13bbSKris Kennaway static const char *header; 3944b88c807SRodney W. Grimes long used, availblks, inodes; 3954b88c807SRodney W. Grimes 3964b88c807SRodney W. Grimes if (++timesthrough == 1) { 39762edbd31SIan Dowse mwp->mntfrom = imax(mwp->mntfrom, strlen("Filesystem")); 398dd6d33e8SMichael Haro if (hflag) { 399dd6d33e8SMichael Haro header = " Size"; 40062edbd31SIan Dowse mwp->total = mwp->used = mwp->avail = strlen(header); 401dd6d33e8SMichael Haro } else { 402dd6d33e8SMichael Haro header = getbsize(&headerlen, &blocksize); 40362edbd31SIan Dowse mwp->total = imax(mwp->total, headerlen); 404dd6d33e8SMichael Haro } 40562edbd31SIan Dowse mwp->used = imax(mwp->used, strlen("Used")); 40662edbd31SIan Dowse mwp->avail = imax(mwp->avail, strlen("Avail")); 40762edbd31SIan Dowse 40862edbd31SIan Dowse (void)printf("%-*s %-*s %*s %*s Capacity", mwp->mntfrom, 40962edbd31SIan Dowse "Filesystem", mwp->total, header, mwp->used, "Used", 41062edbd31SIan Dowse mwp->avail, "Avail"); 41162edbd31SIan Dowse if (iflag) { 41262edbd31SIan Dowse mwp->iused = imax(mwp->iused, strlen(" iused")); 41362edbd31SIan Dowse mwp->ifree = imax(mwp->ifree, strlen("ifree")); 41462edbd31SIan Dowse (void)printf(" %*s %*s %%iused", mwp->iused - 2, 41562edbd31SIan Dowse "iused", mwp->ifree, "ifree"); 41662edbd31SIan Dowse } 4174b88c807SRodney W. Grimes (void)printf(" Mounted on\n"); 4184b88c807SRodney W. Grimes } 41962edbd31SIan Dowse (void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname); 4204b88c807SRodney W. Grimes used = sfsp->f_blocks - sfsp->f_bfree; 4214b88c807SRodney W. Grimes availblks = sfsp->f_bavail + used; 422dd6d33e8SMichael Haro if (hflag) { 423dd6d33e8SMichael Haro prthuman(sfsp, used); 424dd6d33e8SMichael Haro } else { 42562edbd31SIan Dowse (void)printf(" %*ld %*ld %*ld", mwp->total, 4264b88c807SRodney W. Grimes fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize), 42762edbd31SIan Dowse mwp->used, fsbtoblk(used, sfsp->f_bsize, blocksize), 42862edbd31SIan Dowse mwp->avail, fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, 42962edbd31SIan Dowse blocksize)); 430dd6d33e8SMichael Haro } 4314b88c807SRodney W. Grimes (void)printf(" %5.0f%%", 4324b88c807SRodney W. Grimes availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0); 4334b88c807SRodney W. Grimes if (iflag) { 4344b88c807SRodney W. Grimes inodes = sfsp->f_files; 4354b88c807SRodney W. Grimes used = inodes - sfsp->f_ffree; 43662edbd31SIan Dowse (void)printf(" %*ld %*ld %4.0f%% ", mwp->iused, used, 43762edbd31SIan Dowse mwp->ifree, sfsp->f_ffree, inodes == 0 ? 100.0 : 43862edbd31SIan Dowse (double)used / (double)inodes * 100.0); 4394b88c807SRodney W. Grimes } else 4404b88c807SRodney W. Grimes (void)printf(" "); 4414b88c807SRodney W. Grimes (void)printf(" %s\n", sfsp->f_mntonname); 4424b88c807SRodney W. Grimes } 4434b88c807SRodney W. Grimes 4444b88c807SRodney W. Grimes /* 44562edbd31SIan Dowse * Update the maximum field-width information in `mwp' based on 44662edbd31SIan Dowse * the filesystem specified by `sfsp'. 44762edbd31SIan Dowse */ 44862edbd31SIan Dowse void 44962edbd31SIan Dowse update_maxwidths(struct maxwidths *mwp, struct statfs *sfsp) 45062edbd31SIan Dowse { 45162edbd31SIan Dowse static long blocksize; 45262edbd31SIan Dowse int dummy; 45362edbd31SIan Dowse 45462edbd31SIan Dowse if (blocksize == 0) 45562edbd31SIan Dowse getbsize(&dummy, &blocksize); 45662edbd31SIan Dowse 45762edbd31SIan Dowse mwp->mntfrom = imax(mwp->mntfrom, strlen(sfsp->f_mntfromname)); 45862edbd31SIan Dowse mwp->total = imax(mwp->total, longwidth(fsbtoblk(sfsp->f_blocks, 45962edbd31SIan Dowse sfsp->f_bsize, blocksize))); 46062edbd31SIan Dowse mwp->used = imax(mwp->used, longwidth(fsbtoblk(sfsp->f_blocks - 46162edbd31SIan Dowse sfsp->f_bfree, sfsp->f_bsize, blocksize))); 46262edbd31SIan Dowse mwp->avail = imax(mwp->avail, longwidth(fsbtoblk(sfsp->f_bavail, 46362edbd31SIan Dowse sfsp->f_bsize, blocksize))); 46462edbd31SIan Dowse mwp->iused = imax(mwp->iused, longwidth(sfsp->f_files - 46562edbd31SIan Dowse sfsp->f_ffree)); 46662edbd31SIan Dowse mwp->ifree = imax(mwp->ifree, longwidth(sfsp->f_ffree)); 46762edbd31SIan Dowse } 46862edbd31SIan Dowse 46962edbd31SIan Dowse /* Return the width in characters of the specified long. */ 47062edbd31SIan Dowse int 47162edbd31SIan Dowse longwidth(long val) 47262edbd31SIan Dowse { 47362edbd31SIan Dowse int len; 47462edbd31SIan Dowse 47562edbd31SIan Dowse len = 0; 47662edbd31SIan Dowse /* Negative or zero values require one extra digit. */ 47762edbd31SIan Dowse if (val <= 0) { 47862edbd31SIan Dowse val = -val; 47962edbd31SIan Dowse len++; 48062edbd31SIan Dowse } 48162edbd31SIan Dowse while (val > 0) { 48262edbd31SIan Dowse len++; 48362edbd31SIan Dowse val /= 10; 48462edbd31SIan Dowse } 48562edbd31SIan Dowse 48662edbd31SIan Dowse return (len); 48762edbd31SIan Dowse } 48862edbd31SIan Dowse 48962edbd31SIan Dowse /* 4904b88c807SRodney W. Grimes * This code constitutes the pre-system call Berkeley df code for extracting 4914b88c807SRodney W. Grimes * information from filesystem superblocks. 4924b88c807SRodney W. Grimes */ 4934b88c807SRodney W. Grimes 4944b88c807SRodney W. Grimes union { 4954b88c807SRodney W. Grimes struct fs iu_fs; 4964b88c807SRodney W. Grimes char dummy[SBSIZE]; 4974b88c807SRodney W. Grimes } sb; 4984b88c807SRodney W. Grimes #define sblock sb.iu_fs 4994b88c807SRodney W. Grimes 5004b88c807SRodney W. Grimes int rfd; 5014b88c807SRodney W. Grimes 502b8904f2aSJoerg Wunsch int 50362edbd31SIan Dowse ufs_df(char *file, struct maxwidths *mwp) 5044b88c807SRodney W. Grimes { 5054b88c807SRodney W. Grimes struct statfs statfsbuf; 5064b88c807SRodney W. Grimes struct statfs *sfsp; 507a95a13bbSKris Kennaway const char *mntpt; 5084b88c807SRodney W. Grimes static int synced; 5094b88c807SRodney W. Grimes 5104b88c807SRodney W. Grimes if (synced++ == 0) 5114b88c807SRodney W. Grimes sync(); 5124b88c807SRodney W. Grimes 5134b88c807SRodney W. Grimes if ((rfd = open(file, O_RDONLY)) < 0) { 5144b88c807SRodney W. Grimes warn("%s", file); 51580214f04SJoerg Wunsch return (1); 5164b88c807SRodney W. Grimes } 5174b88c807SRodney W. Grimes if (bread((off_t)SBOFF, &sblock, SBSIZE) == 0) { 5184b88c807SRodney W. Grimes (void)close(rfd); 51980214f04SJoerg Wunsch return (1); 5204b88c807SRodney W. Grimes } 5214b88c807SRodney W. Grimes sfsp = &statfsbuf; 522a78192e3SBruce Evans sfsp->f_type = 1; 523a78192e3SBruce Evans strcpy(sfsp->f_fstypename, "ufs"); 5244b88c807SRodney W. Grimes sfsp->f_flags = 0; 5254b88c807SRodney W. Grimes sfsp->f_bsize = sblock.fs_fsize; 5264b88c807SRodney W. Grimes sfsp->f_iosize = sblock.fs_bsize; 5274b88c807SRodney W. Grimes sfsp->f_blocks = sblock.fs_dsize; 5284b88c807SRodney W. Grimes sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag + 5294b88c807SRodney W. Grimes sblock.fs_cstotal.cs_nffree; 53051ea8b57SBruce Evans sfsp->f_bavail = freespace(&sblock, sblock.fs_minfree); 5314b88c807SRodney W. Grimes sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg; 5324b88c807SRodney W. Grimes sfsp->f_ffree = sblock.fs_cstotal.cs_nifree; 5334b88c807SRodney W. Grimes sfsp->f_fsid.val[0] = 0; 5344b88c807SRodney W. Grimes sfsp->f_fsid.val[1] = 0; 5354b88c807SRodney W. Grimes if ((mntpt = getmntpt(file)) == 0) 5364b88c807SRodney W. Grimes mntpt = ""; 537a95a13bbSKris Kennaway memmove(&sfsp->f_mntonname[0], mntpt, (size_t)MNAMELEN); 538a95a13bbSKris Kennaway memmove(&sfsp->f_mntfromname[0], file, (size_t)MNAMELEN); 53962edbd31SIan Dowse prtstat(sfsp, mwp); 5404b88c807SRodney W. Grimes (void)close(rfd); 54180214f04SJoerg Wunsch return (0); 5424b88c807SRodney W. Grimes } 5434b88c807SRodney W. Grimes 5444b88c807SRodney W. Grimes int 545f9bcb0beSWarner Losh bread(off_t off, void *buf, int cnt) 5464b88c807SRodney W. Grimes { 547a95a13bbSKris Kennaway ssize_t nr; 5484b88c807SRodney W. Grimes 5494b88c807SRodney W. Grimes (void)lseek(rfd, off, SEEK_SET); 550a95a13bbSKris Kennaway if ((nr = read(rfd, buf, (size_t)cnt)) != (ssize_t)cnt) { 5514b88c807SRodney W. Grimes /* Probably a dismounted disk if errno == EIO. */ 5524b88c807SRodney W. Grimes if (errno != EIO) 553a95a13bbSKris Kennaway (void)fprintf(stderr, "\ndf: %lld: %s\n", 554a95a13bbSKris Kennaway (long long)off, strerror(nr > 0 ? EIO : errno)); 5554b88c807SRodney W. Grimes return (0); 5564b88c807SRodney W. Grimes } 5574b88c807SRodney W. Grimes return (1); 5584b88c807SRodney W. Grimes } 5594b88c807SRodney W. Grimes 5604b88c807SRodney W. Grimes void 561f9bcb0beSWarner Losh usage(void) 5624b88c807SRodney W. Grimes { 563dd6d33e8SMichael Haro 564a78192e3SBruce Evans (void)fprintf(stderr, 565a25695c3SJim Pirzyk "usage: df [-b | -H | -h | -k | -m | -P] [-ailn] [-t type] [file | filesystem ...]\n"); 566dd6d33e8SMichael Haro exit(EX_USAGE); 5674b88c807SRodney W. Grimes } 568a25695c3SJim Pirzyk 569a067aeceSGarrett Wollman char * 570f9bcb0beSWarner Losh makenetvfslist(void) 571a25695c3SJim Pirzyk { 572a25695c3SJim Pirzyk char *str, *strptr, **listptr; 573b3e8643fSMatt Jacob int mib[3], maxvfsconf, cnt=0, i; 574b3e8643fSMatt Jacob size_t miblen; 575a25695c3SJim Pirzyk struct ovfsconf *ptr; 576a25695c3SJim Pirzyk 577a25695c3SJim Pirzyk mib[0] = CTL_VFS; mib[1] = VFS_GENERIC; mib[2] = VFS_MAXTYPENUM; 578a25695c3SJim Pirzyk miblen=sizeof(maxvfsconf); 579cc66540eSJacques Vidrine if (sysctl(mib, (unsigned int)(sizeof(mib) / sizeof(mib[0])), 580cc66540eSJacques Vidrine &maxvfsconf, &miblen, NULL, 0)) { 581a25695c3SJim Pirzyk warnx("sysctl failed"); 582a25695c3SJim Pirzyk return (NULL); 583a25695c3SJim Pirzyk } 584a25695c3SJim Pirzyk 585a25695c3SJim Pirzyk if ((listptr = malloc(sizeof(char*) * maxvfsconf)) == NULL) { 586a25695c3SJim Pirzyk warnx("malloc failed"); 587a25695c3SJim Pirzyk return (NULL); 588a25695c3SJim Pirzyk } 589a25695c3SJim Pirzyk 590a25695c3SJim Pirzyk for (ptr = getvfsent(); ptr; ptr = getvfsent()) 591a25695c3SJim Pirzyk if (ptr->vfc_flags & VFCF_NETWORK) { 592a25695c3SJim Pirzyk listptr[cnt++] = strdup(ptr->vfc_name); 593a067aeceSGarrett Wollman if (listptr[cnt-1] == NULL) { 594a25695c3SJim Pirzyk warnx("malloc failed"); 595a25695c3SJim Pirzyk return (NULL); 596a25695c3SJim Pirzyk } 597a25695c3SJim Pirzyk } 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); 604a25695c3SJim Pirzyk return (NULL); 605a25695c3SJim Pirzyk } 606a25695c3SJim Pirzyk 607a25695c3SJim Pirzyk *str = 'n'; *(str + 1) = 'o'; 608a25695c3SJim Pirzyk for (i = 0, strptr = str + 2; i < cnt; i++, strptr++) { 609a25695c3SJim Pirzyk strncpy(strptr, listptr[i], 32); 610a25695c3SJim Pirzyk strptr += strlen(listptr[i]); 611a25695c3SJim Pirzyk *strptr = ','; 612a25695c3SJim Pirzyk free(listptr[i]); 613a25695c3SJim Pirzyk } 614a25695c3SJim Pirzyk *(--strptr) = NULL; 615a25695c3SJim Pirzyk 616a25695c3SJim Pirzyk free(listptr); 617a25695c3SJim Pirzyk return (str); 618a25695c3SJim Pirzyk } 619