1139969Simp/*- 21556Srgrimes * Copyright (c) 1980, 1990, 1993, 1994 31556Srgrimes * The Regents of the University of California. All rights reserved. 41556Srgrimes * (c) UNIX System Laboratories, Inc. 51556Srgrimes * All or some portions of this file are derived from material licensed 61556Srgrimes * to the University of California by American Telephone and Telegraph 71556Srgrimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with 81556Srgrimes * the permission of UNIX System Laboratories, Inc. 91556Srgrimes * 101556Srgrimes * Redistribution and use in source and binary forms, with or without 111556Srgrimes * modification, are permitted provided that the following conditions 121556Srgrimes * are met: 131556Srgrimes * 1. Redistributions of source code must retain the above copyright 141556Srgrimes * notice, this list of conditions and the following disclaimer. 151556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161556Srgrimes * notice, this list of conditions and the following disclaimer in the 171556Srgrimes * documentation and/or other materials provided with the distribution. 181556Srgrimes * 4. Neither the name of the University nor the names of its contributors 191556Srgrimes * may be used to endorse or promote products derived from this software 201556Srgrimes * without specific prior written permission. 211556Srgrimes * 221556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321556Srgrimes * SUCH DAMAGE. 331556Srgrimes */ 341556Srgrimes 35114433Sobrien#if 0 361556Srgrimes#ifndef lint 3727962Sstevestatic const char copyright[] = 381556Srgrimes"@(#) Copyright (c) 1980, 1990, 1993, 1994\n\ 391556Srgrimes The Regents of the University of California. All rights reserved.\n"; 401556Srgrimes#endif /* not lint */ 411556Srgrimes 421556Srgrimes#ifndef lint 4327962Sstevestatic char sccsid[] = "@(#)df.c 8.9 (Berkeley) 5/8/95"; 44114433Sobrien#endif /* not lint */ 4527962Ssteve#endif 4699109Sobrien#include <sys/cdefs.h> 4799109Sobrien__FBSDID("$FreeBSD$"); 481556Srgrimes 491556Srgrimes#include <sys/param.h> 501556Srgrimes#include <sys/stat.h> 511556Srgrimes#include <sys/mount.h> 5277734Spirzyk#include <sys/sysctl.h> 5323852Sbde#include <ufs/ufs/ufsmount.h> 541556Srgrimes#include <err.h> 55129678Spjd#include <libutil.h> 56243049Sgrog#include <locale.h> 57125611Siedowse#include <stdint.h> 581556Srgrimes#include <stdio.h> 591556Srgrimes#include <stdlib.h> 601556Srgrimes#include <string.h> 6154621Smharo#include <sysexits.h> 621556Srgrimes#include <unistd.h> 631556Srgrimes 6496470Sphk#include "extern.h" 6596470Sphk 66129678Spjd#define UNITS_SI 1 67129678Spjd#define UNITS_2 2 6854621Smharo 6993246Siedowse/* Maximum widths of various fields. */ 7093246Siedowsestruct maxwidths { 71125611Siedowse int mntfrom; 72185200Spjd int fstype; 73125611Siedowse int total; 74125611Siedowse int used; 75125611Siedowse int avail; 76125611Siedowse int iused; 77125611Siedowse int ifree; 7893246Siedowse}; 7993246Siedowse 80128555Sobrienstatic void addstat(struct statfs *, struct statfs *); 81114579Smarkmstatic char *getmntpt(const char *); 82125611Siedowsestatic int int64width(int64_t); 8396470Sphkstatic char *makenetvfslist(void); 84122537Smckusickstatic void prthuman(const struct statfs *, int64_t); 85129678Spjdstatic void prthumanval(int64_t); 86130060Sdasstatic intmax_t fsbtoblk(int64_t, uint64_t, u_long); 8796470Sphkstatic void prtstat(struct statfs *, struct maxwidths *); 88120037Sobrienstatic size_t regetmntinfo(struct statfs **, long, const char **); 89114579Smarkmstatic void update_maxwidths(struct maxwidths *, const struct statfs *); 9096470Sphkstatic void usage(void); 911556Srgrimes 92125611Siedowsestatic __inline int 93125611Siedowseimax(int a, int b) 9493246Siedowse{ 95114579Smarkm return (a > b ? a : b); 9693246Siedowse} 9793246Siedowse 98185200Spjdstatic int aflag = 0, cflag, hflag, iflag, kflag, lflag = 0, nflag, Tflag; 99243049Sgrogstatic int thousands; 10096470Sphkstatic struct ufs_args mdev; 10196470Sphk 1021556Srgrimesint 10390108Simpmain(int argc, char *argv[]) 1041556Srgrimes{ 1051556Srgrimes struct stat stbuf; 106128555Sobrien struct statfs statfsbuf, totalbuf; 10793246Siedowse struct maxwidths maxwidths; 108128555Sobrien struct statfs *mntbuf; 10976873Skris const char *fstype; 11096470Sphk char *mntpath, *mntpt; 11196470Sphk const char **vfslist; 112226502Sdes int i, mntsize; 113120037Sobrien int ch, rv; 1141556Srgrimes 11576404Skris fstype = "ufs"; 116243049Sgrog (void)setlocale(LC_ALL, ""); 117249698Suqs memset(&maxwidths, 0, sizeof(maxwidths)); 118128555Sobrien memset(&totalbuf, 0, sizeof(totalbuf)); 119128410Sobrien totalbuf.f_bsize = DEV_BSIZE; 120161470Simp strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN); 12123852Sbde vfslist = NULL; 122243049Sgrog while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T,")) != -1) 1231556Srgrimes switch (ch) { 12452735Sjulian case 'a': 12552735Sjulian aflag = 1; 12652735Sjulian break; 12754621Smharo case 'b': 12854621Smharo /* FALLTHROUGH */ 12954621Smharo case 'P': 130162483Scsjp /* 131218909Sbrucec * POSIX specifically discusses the behavior of 132162483Scsjp * both -k and -P. It states that the blocksize should 133162483Scsjp * be set to 1024. Thus, if this occurs, simply break 134162483Scsjp * rather than clobbering the old blocksize. 135162483Scsjp */ 136162483Scsjp if (kflag) 137162483Scsjp break; 138171195Sscf setenv("BLOCKSIZE", "512", 1); 13954621Smharo hflag = 0; 14054621Smharo break; 141128555Sobrien case 'c': 142128555Sobrien cflag = 1; 143128555Sobrien break; 14461227Sjwd case 'g': 145171195Sscf setenv("BLOCKSIZE", "1g", 1); 14661227Sjwd hflag = 0; 14761227Sjwd break; 14854621Smharo case 'H': 14954621Smharo hflag = UNITS_SI; 15054621Smharo break; 15154621Smharo case 'h': 15254621Smharo hflag = UNITS_2; 15354621Smharo break; 1541556Srgrimes case 'i': 1551556Srgrimes iflag = 1; 1561556Srgrimes break; 1572008Swollman case 'k': 158162483Scsjp kflag++; 159171195Sscf setenv("BLOCKSIZE", "1024", 1); 16054621Smharo hflag = 0; 1612008Swollman break; 16277734Spirzyk case 'l': 16377734Spirzyk if (vfslist != NULL) 16477734Spirzyk errx(1, "-l and -t are mutually exclusive."); 16577734Spirzyk vfslist = makevfslist(makenetvfslist()); 166167326Swill lflag = 1; 16777734Spirzyk break; 16854621Smharo case 'm': 169171195Sscf setenv("BLOCKSIZE", "1m", 1); 17054621Smharo hflag = 0; 17154621Smharo break; 1721556Srgrimes case 'n': 1731556Srgrimes nflag = 1; 1741556Srgrimes break; 1751556Srgrimes case 't': 176167326Swill if (lflag) 177167326Swill errx(1, "-l and -t are mutually exclusive."); 17823852Sbde if (vfslist != NULL) 17987666Scharnier errx(1, "only one -t option may be specified"); 18080795Sobrien fstype = optarg; 18123852Sbde vfslist = makevfslist(optarg); 1821556Srgrimes break; 183185200Spjd case 'T': 184185200Spjd Tflag = 1; 185185200Spjd break; 186243049Sgrog case ',': 187243049Sgrog thousands = 1; 188243049Sgrog break; 1891556Srgrimes case '?': 1901556Srgrimes default: 1911556Srgrimes usage(); 1921556Srgrimes } 1931556Srgrimes argc -= optind; 1941556Srgrimes argv += optind; 1951556Srgrimes 19630340Sjoerg rv = 0; 1971556Srgrimes if (!*argv) { 198226502Sdes /* everything (modulo -t) */ 199226502Sdes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 20023852Sbde mntsize = regetmntinfo(&mntbuf, mntsize, vfslist); 201226502Sdes } else { 202226502Sdes /* just the filesystems specified on the command line */ 203226502Sdes mntbuf = malloc(argc * sizeof(*mntbuf)); 204249698Suqs if (mntbuf == NULL) 205226502Sdes err(1, "malloc()"); 206226502Sdes mntsize = 0; 207226502Sdes /* continued in for loop below */ 2081556Srgrimes } 2091556Srgrimes 210226502Sdes /* iterate through specified filesystems */ 2111556Srgrimes for (; *argv; argv++) { 2121556Srgrimes if (stat(*argv, &stbuf) < 0) { 213249698Suqs if ((mntpt = getmntpt(*argv)) == NULL) { 2141556Srgrimes warn("%s", *argv); 21530340Sjoerg rv = 1; 2161556Srgrimes continue; 2171556Srgrimes } 21876404Skris } else if (S_ISCHR(stbuf.st_mode)) { 219249698Suqs if ((mntpt = getmntpt(*argv)) == NULL) { 22076404Skris mdev.fspec = *argv; 22176404Skris mntpath = strdup("/tmp/df.XXXXXX"); 22276404Skris if (mntpath == NULL) { 22376404Skris warn("strdup failed"); 22476404Skris rv = 1; 22576404Skris continue; 22676404Skris } 22776404Skris mntpt = mkdtemp(mntpath); 22876404Skris if (mntpt == NULL) { 22976404Skris warn("mkdtemp(\"%s\") failed", mntpath); 23076404Skris rv = 1; 23176404Skris free(mntpath); 23276404Skris continue; 23376404Skris } 23476404Skris if (mount(fstype, mntpt, MNT_RDONLY, 23576404Skris &mdev) != 0) { 23696470Sphk warn("%s", *argv); 23796470Sphk rv = 1; 23876404Skris (void)rmdir(mntpt); 23976404Skris free(mntpath); 24076404Skris continue; 24176404Skris } else if (statfs(mntpt, &statfsbuf) == 0) { 24276404Skris statfsbuf.f_mntonname[0] = '\0'; 24393246Siedowse prtstat(&statfsbuf, &maxwidths); 244128410Sobrien if (cflag) 245128410Sobrien addstat(&totalbuf, &statfsbuf); 24676404Skris } else { 24776404Skris warn("%s", *argv); 24876404Skris rv = 1; 24976404Skris } 25076404Skris (void)unmount(mntpt, 0); 25176404Skris (void)rmdir(mntpt); 25276404Skris free(mntpath); 25376404Skris continue; 25476404Skris } 2551556Srgrimes } else 2561556Srgrimes mntpt = *argv; 257115769Sbde 2581556Srgrimes /* 2591556Srgrimes * Statfs does not take a `wait' flag, so we cannot 2601556Srgrimes * implement nflag here. 2611556Srgrimes */ 2621556Srgrimes if (statfs(mntpt, &statfsbuf) < 0) { 2631556Srgrimes warn("%s", mntpt); 26430340Sjoerg rv = 1; 2651556Srgrimes continue; 2661556Srgrimes } 267115769Sbde 268115769Sbde /* 269115769Sbde * Check to make sure the arguments we've been given are 270115769Sbde * satisfied. Return an error if we have been asked to 271115769Sbde * list a mount point that does not match the other args 272115769Sbde * we've been given (-l, -t, etc.). 273115744Sjkh */ 274115744Sjkh if (checkvfsname(statfsbuf.f_fstypename, vfslist)) { 275115769Sbde rv = 1; 276115744Sjkh continue; 277115744Sjkh } 278115769Sbde 279226502Sdes /* the user asked for it, so ignore the ignore flag */ 280226502Sdes statfsbuf.f_flags &= ~MNT_IGNORE; 281226502Sdes 282226502Sdes /* add to list */ 283226502Sdes mntbuf[mntsize++] = statfsbuf; 284226502Sdes } 285226502Sdes 286249698Suqs memset(&maxwidths, 0, sizeof(maxwidths)); 287226502Sdes for (i = 0; i < mntsize; i++) { 288226502Sdes if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) { 289226502Sdes update_maxwidths(&maxwidths, &mntbuf[i]); 290226502Sdes if (cflag) 291226502Sdes addstat(&totalbuf, &mntbuf[i]); 29293246Siedowse } 2931556Srgrimes } 294226502Sdes for (i = 0; i < mntsize; i++) 295226502Sdes if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) 296226502Sdes prtstat(&mntbuf[i], &maxwidths); 297128410Sobrien if (cflag) 298128410Sobrien prtstat(&totalbuf, &maxwidths); 29930340Sjoerg return (rv); 3001556Srgrimes} 3011556Srgrimes 30296470Sphkstatic char * 303114579Smarkmgetmntpt(const char *name) 3041556Srgrimes{ 305120037Sobrien size_t mntsize, i; 3061556Srgrimes struct statfs *mntbuf; 3071556Srgrimes 3081556Srgrimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 3091556Srgrimes for (i = 0; i < mntsize; i++) { 3101556Srgrimes if (!strcmp(mntbuf[i].f_mntfromname, name)) 3111556Srgrimes return (mntbuf[i].f_mntonname); 3121556Srgrimes } 313249698Suqs return (NULL); 3141556Srgrimes} 3151556Srgrimes 3161556Srgrimes/* 317102230Strhodes * Make a pass over the file system info in ``mntbuf'' filtering out 318102230Strhodes * file system types not in vfslist and possibly re-stating to get 3191556Srgrimes * current (not cached) info. Returns the new count of valid statfs bufs. 3201556Srgrimes */ 321120037Sobrienstatic size_t 32296470Sphkregetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist) 3231556Srgrimes{ 324132465Scsjp int error, i, j; 3251556Srgrimes struct statfs *mntbuf; 3261556Srgrimes 32723852Sbde if (vfslist == NULL) 3281556Srgrimes return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT)); 3291556Srgrimes 3301556Srgrimes mntbuf = *mntbufp; 33123852Sbde for (j = 0, i = 0; i < mntsize; i++) { 33223852Sbde if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) 33323852Sbde continue; 334132465Scsjp /* 335132465Scsjp * XXX statfs(2) can fail for various reasons. It may be 336132465Scsjp * possible that the user does not have access to the 337132465Scsjp * pathname, if this happens, we will fall back on 338132465Scsjp * "stale" filesystem statistics. 339132465Scsjp */ 340132465Scsjp error = statfs(mntbuf[i].f_mntonname, &mntbuf[j]); 341132465Scsjp if (nflag || error < 0) 342132465Scsjp if (i != j) { 343132465Scsjp if (error < 0) 344132465Scsjp warnx("%s stats possibly stale", 345132465Scsjp mntbuf[i].f_mntonname); 346132465Scsjp mntbuf[j] = mntbuf[i]; 347132465Scsjp } 34823852Sbde j++; 3491556Srgrimes } 3501556Srgrimes return (j); 3511556Srgrimes} 3521556Srgrimes 35396470Sphkstatic void 354122537Smckusickprthuman(const struct statfs *sfsp, int64_t used) 35554621Smharo{ 35654621Smharo 357129678Spjd prthumanval(sfsp->f_blocks * sfsp->f_bsize); 358129678Spjd prthumanval(used * sfsp->f_bsize); 359129678Spjd prthumanval(sfsp->f_bavail * sfsp->f_bsize); 36054621Smharo} 36154621Smharo 36296470Sphkstatic void 363129678Spjdprthumanval(int64_t bytes) 36454621Smharo{ 365129678Spjd char buf[6]; 366129678Spjd int flags; 36754621Smharo 368129678Spjd flags = HN_B | HN_NOSPACE | HN_DECIMAL; 369129678Spjd if (hflag == UNITS_SI) 370129678Spjd flags |= HN_DIVISOR_1000; 37154621Smharo 372129678Spjd humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), 373129678Spjd bytes, "", HN_AUTOSCALE, flags); 374129678Spjd 375129678Spjd (void)printf(" %6s", buf); 37654621Smharo} 37754621Smharo 37854621Smharo/* 379193629Ssimon * Print an inode count in "human-readable" format. 380193629Ssimon */ 381193629Ssimonstatic void 382193629Ssimonprthumanvalinode(int64_t bytes) 383193629Ssimon{ 384193629Ssimon char buf[6]; 385193629Ssimon int flags; 386193629Ssimon 387193629Ssimon flags = HN_NOSPACE | HN_DECIMAL | HN_DIVISOR_1000; 388193629Ssimon 389193629Ssimon humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), 390193629Ssimon bytes, "", HN_AUTOSCALE, flags); 391193629Ssimon 392193629Ssimon (void)printf(" %5s", buf); 393193629Ssimon} 394193629Ssimon 395193629Ssimon/* 396102230Strhodes * Convert statfs returned file system size into BLOCKSIZE units. 3971556Srgrimes */ 398130060Sdasstatic intmax_t 399130060Sdasfsbtoblk(int64_t num, uint64_t fsbs, u_long bs) 400130060Sdas{ 401244134Sgrog return (num * (intmax_t) fsbs / (int64_t) bs); 402130060Sdas} 403130060Sdas 4041556Srgrimes/* 405102230Strhodes * Print out status about a file system. 4061556Srgrimes */ 40796470Sphkstatic void 40893246Siedowseprtstat(struct statfs *sfsp, struct maxwidths *mwp) 4091556Srgrimes{ 410168428Skan static long blocksize; 411114579Smarkm static int headerlen, timesthrough = 0; 41276873Skris static const char *header; 413122537Smckusick int64_t used, availblks, inodes; 414243049Sgrog const char *format; 4151556Srgrimes 4161556Srgrimes if (++timesthrough == 1) { 417125611Siedowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen("Filesystem")); 418185200Spjd mwp->fstype = imax(mwp->fstype, (int)strlen("Type")); 419243049Sgrog if (thousands) { /* make space for commas */ 420243049Sgrog mwp->total += (mwp->total - 1) / 3; 421243049Sgrog mwp->used += (mwp->used - 1) / 3; 422243049Sgrog mwp->avail += (mwp->avail - 1) / 3; 423243049Sgrog mwp->iused += (mwp->iused - 1) / 3; 424243049Sgrog mwp->ifree += (mwp->ifree - 1) / 3; 425243049Sgrog } 42654621Smharo if (hflag) { 427128553Sobrien header = " Size"; 428125611Siedowse mwp->total = mwp->used = mwp->avail = 429125611Siedowse (int)strlen(header); 43054621Smharo } else { 43154621Smharo header = getbsize(&headerlen, &blocksize); 432125611Siedowse mwp->total = imax(mwp->total, headerlen); 43354621Smharo } 434125611Siedowse mwp->used = imax(mwp->used, (int)strlen("Used")); 435125611Siedowse mwp->avail = imax(mwp->avail, (int)strlen("Avail")); 43693246Siedowse 437185200Spjd (void)printf("%-*s", mwp->mntfrom, "Filesystem"); 438185200Spjd if (Tflag) 439185200Spjd (void)printf(" %-*s", mwp->fstype, "Type"); 440243049Sgrog (void)printf(" %*s %*s %*s Capacity", mwp->total, header, 441125611Siedowse mwp->used, "Used", mwp->avail, "Avail"); 44293246Siedowse if (iflag) { 443193629Ssimon mwp->iused = imax(hflag ? 0 : mwp->iused, 444193629Ssimon (int)strlen(" iused")); 445193629Ssimon mwp->ifree = imax(hflag ? 0 : mwp->ifree, 446193629Ssimon (int)strlen("ifree")); 447114582Smarkm (void)printf(" %*s %*s %%iused", 448125611Siedowse mwp->iused - 2, "iused", mwp->ifree, "ifree"); 44993246Siedowse } 4501556Srgrimes (void)printf(" Mounted on\n"); 4511556Srgrimes } 452243129Sgrog /* Check for 0 block size. Can this happen? */ 453243129Sgrog if (sfsp->f_bsize == 0) { 454243129Sgrog warnx ("File system %s does not have a block size, assuming 512.", 455243129Sgrog sfsp->f_mntonname); 456243129Sgrog sfsp->f_bsize = 512; 457243129Sgrog } 458125611Siedowse (void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname); 459185200Spjd if (Tflag) 460185200Spjd (void)printf(" %-*s", mwp->fstype, sfsp->f_fstypename); 4611556Srgrimes used = sfsp->f_blocks - sfsp->f_bfree; 4621556Srgrimes availblks = sfsp->f_bavail + used; 46354621Smharo if (hflag) { 46454621Smharo prthuman(sfsp, used); 46554621Smharo } else { 466243049Sgrog if (thousands) 467243049Sgrog format = " %*j'd %*j'd %*j'd"; 468243049Sgrog else 469243049Sgrog format = " %*jd %*jd %*jd"; 470243049Sgrog (void)printf(format, 471130060Sdas mwp->total, fsbtoblk(sfsp->f_blocks, 472125611Siedowse sfsp->f_bsize, blocksize), 473130060Sdas mwp->used, fsbtoblk(used, sfsp->f_bsize, blocksize), 474130060Sdas mwp->avail, fsbtoblk(sfsp->f_bavail, 475125611Siedowse sfsp->f_bsize, blocksize)); 47654621Smharo } 4771556Srgrimes (void)printf(" %5.0f%%", 4781556Srgrimes availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0); 4791556Srgrimes if (iflag) { 4801556Srgrimes inodes = sfsp->f_files; 4811556Srgrimes used = inodes - sfsp->f_ffree; 482193629Ssimon if (hflag) { 483193629Ssimon (void)printf(" "); 484193629Ssimon prthumanvalinode(used); 485193629Ssimon prthumanvalinode(sfsp->f_ffree); 486193629Ssimon } else { 487243049Sgrog if (thousands) 488243049Sgrog format = " %*j'd %*j'd"; 489243049Sgrog else 490243049Sgrog format = " %*jd %*jd"; 491243049Sgrog (void)printf(format, mwp->iused, (intmax_t)used, 492193629Ssimon mwp->ifree, (intmax_t)sfsp->f_ffree); 493193629Ssimon } 494193629Ssimon (void)printf(" %4.0f%% ", inodes == 0 ? 100.0 : 495125611Siedowse (double)used / (double)inodes * 100.0); 496128553Sobrien } else 497128553Sobrien (void)printf(" "); 498128555Sobrien if (strncmp(sfsp->f_mntfromname, "total", MNAMELEN) != 0) 499128410Sobrien (void)printf(" %s", sfsp->f_mntonname); 500128410Sobrien (void)printf("\n"); 5011556Srgrimes} 5021556Srgrimes 503194795Sdelphijstatic void 504128410Sobrienaddstat(struct statfs *totalfsp, struct statfs *statfsp) 505128410Sobrien{ 506128555Sobrien uint64_t bsize; 507128410Sobrien 508128555Sobrien bsize = statfsp->f_bsize / totalfsp->f_bsize; 509128410Sobrien totalfsp->f_blocks += statfsp->f_blocks * bsize; 510128410Sobrien totalfsp->f_bfree += statfsp->f_bfree * bsize; 511128410Sobrien totalfsp->f_bavail += statfsp->f_bavail * bsize; 512128410Sobrien totalfsp->f_files += statfsp->f_files; 513128410Sobrien totalfsp->f_ffree += statfsp->f_ffree; 514128410Sobrien} 515128410Sobrien 5161556Srgrimes/* 51793246Siedowse * Update the maximum field-width information in `mwp' based on 518102230Strhodes * the file system specified by `sfsp'. 51993246Siedowse */ 52096470Sphkstatic void 521114579Smarkmupdate_maxwidths(struct maxwidths *mwp, const struct statfs *sfsp) 52293246Siedowse{ 523168428Skan static long blocksize = 0; 524108452Smike int dummy; 52593246Siedowse 52693246Siedowse if (blocksize == 0) 52793246Siedowse getbsize(&dummy, &blocksize); 52893246Siedowse 529125611Siedowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen(sfsp->f_mntfromname)); 530185200Spjd mwp->fstype = imax(mwp->fstype, (int)strlen(sfsp->f_fstypename)); 531125611Siedowse mwp->total = imax(mwp->total, int64width( 532122537Smckusick fsbtoblk((int64_t)sfsp->f_blocks, sfsp->f_bsize, blocksize))); 533125611Siedowse mwp->used = imax(mwp->used, 534125611Siedowse int64width(fsbtoblk((int64_t)sfsp->f_blocks - 535122537Smckusick (int64_t)sfsp->f_bfree, sfsp->f_bsize, blocksize))); 536125611Siedowse mwp->avail = imax(mwp->avail, int64width(fsbtoblk(sfsp->f_bavail, 53793246Siedowse sfsp->f_bsize, blocksize))); 538125611Siedowse mwp->iused = imax(mwp->iused, int64width((int64_t)sfsp->f_files - 53993246Siedowse sfsp->f_ffree)); 540125611Siedowse mwp->ifree = imax(mwp->ifree, int64width(sfsp->f_ffree)); 54193246Siedowse} 54293246Siedowse 543125611Siedowse/* Return the width in characters of the specified value. */ 544125611Siedowsestatic int 545122537Smckusickint64width(int64_t val) 54693246Siedowse{ 547125611Siedowse int len; 54893246Siedowse 54993246Siedowse len = 0; 55093246Siedowse /* Negative or zero values require one extra digit. */ 55193246Siedowse if (val <= 0) { 55293246Siedowse val = -val; 55393246Siedowse len++; 55493246Siedowse } 55593246Siedowse while (val > 0) { 55693246Siedowse len++; 55793246Siedowse val /= 10; 55893246Siedowse } 55993246Siedowse 56093246Siedowse return (len); 56193246Siedowse} 56293246Siedowse 56396470Sphkstatic void 56490108Simpusage(void) 5651556Srgrimes{ 56654621Smharo 56723852Sbde (void)fprintf(stderr, 568245871Sdelphij"usage: df [-b | -g | -H | -h | -k | -m | -P] [-acilnT] [-t type] [-,]\n" 569245871Sdelphij" [file | filesystem ...]\n"); 57054621Smharo exit(EX_USAGE); 5711556Srgrimes} 57277734Spirzyk 57396470Sphkstatic char * 57490108Simpmakenetvfslist(void) 57577734Spirzyk{ 57677734Spirzyk char *str, *strptr, **listptr; 577114579Smarkm struct xvfsconf *xvfsp, *keep_xvfsp; 578101651Smux size_t buflen; 579101651Smux int cnt, i, maxvfsconf; 58077734Spirzyk 581101651Smux if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) { 582101651Smux warn("sysctl(vfs.conflist)"); 58377734Spirzyk return (NULL); 58477734Spirzyk } 585101651Smux xvfsp = malloc(buflen); 586101651Smux if (xvfsp == NULL) { 587101651Smux warnx("malloc failed"); 588101651Smux return (NULL); 589101651Smux } 590114579Smarkm keep_xvfsp = xvfsp; 591101651Smux if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) { 592101651Smux warn("sysctl(vfs.conflist)"); 593114579Smarkm free(keep_xvfsp); 594101651Smux return (NULL); 595101651Smux } 596101651Smux maxvfsconf = buflen / sizeof(struct xvfsconf); 59777734Spirzyk 59879791Swollman if ((listptr = malloc(sizeof(char*) * maxvfsconf)) == NULL) { 59977734Spirzyk warnx("malloc failed"); 600114579Smarkm free(keep_xvfsp); 60177734Spirzyk return (NULL); 60277734Spirzyk } 60377734Spirzyk 604101651Smux for (cnt = 0, i = 0; i < maxvfsconf; i++) { 605101651Smux if (xvfsp->vfc_flags & VFCF_NETWORK) { 606101651Smux listptr[cnt++] = strdup(xvfsp->vfc_name); 60779791Swollman if (listptr[cnt-1] == NULL) { 60877734Spirzyk warnx("malloc failed"); 609114579Smarkm free(listptr); 610114579Smarkm free(keep_xvfsp); 61177734Spirzyk return (NULL); 61277734Spirzyk } 61377734Spirzyk } 614101651Smux xvfsp++; 615101651Smux } 61677734Spirzyk 61788182Sru if (cnt == 0 || 61888182Sru (str = malloc(sizeof(char) * (32 * cnt + cnt + 2))) == NULL) { 61988182Sru if (cnt > 0) 62088182Sru warnx("malloc failed"); 62177734Spirzyk free(listptr); 622114579Smarkm free(keep_xvfsp); 62377734Spirzyk return (NULL); 62477734Spirzyk } 62577734Spirzyk 62679791Swollman *str = 'n'; *(str + 1) = 'o'; 62779791Swollman for (i = 0, strptr = str + 2; i < cnt; i++, strptr++) { 628161470Simp strlcpy(strptr, listptr[i], 32); 62979791Swollman strptr += strlen(listptr[i]); 63079791Swollman *strptr = ','; 63177734Spirzyk free(listptr[i]); 63277734Spirzyk } 633126643Smarkm *(--strptr) = '\0'; 63477734Spirzyk 635114579Smarkm free(keep_xvfsp); 63677734Spirzyk free(listptr); 63777734Spirzyk return (str); 63877734Spirzyk} 639