df.c revision 226502
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: head/bin/df/df.c 226502 2011-10-18 08:18:26Z des $"); 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> 56125611Siedowse#include <stdint.h> 571556Srgrimes#include <stdio.h> 581556Srgrimes#include <stdlib.h> 591556Srgrimes#include <string.h> 6054621Smharo#include <sysexits.h> 611556Srgrimes#include <unistd.h> 621556Srgrimes 6396470Sphk#include "extern.h" 6496470Sphk 65129678Spjd#define UNITS_SI 1 66129678Spjd#define UNITS_2 2 6754621Smharo 6893246Siedowse/* Maximum widths of various fields. */ 6993246Siedowsestruct maxwidths { 70125611Siedowse int mntfrom; 71185200Spjd int fstype; 72125611Siedowse int total; 73125611Siedowse int used; 74125611Siedowse int avail; 75125611Siedowse int iused; 76125611Siedowse int ifree; 7793246Siedowse}; 7893246Siedowse 79128555Sobrienstatic void addstat(struct statfs *, struct statfs *); 80114579Smarkmstatic char *getmntpt(const char *); 81125611Siedowsestatic int int64width(int64_t); 8296470Sphkstatic char *makenetvfslist(void); 83122537Smckusickstatic void prthuman(const struct statfs *, int64_t); 84129678Spjdstatic void prthumanval(int64_t); 85130060Sdasstatic intmax_t fsbtoblk(int64_t, uint64_t, u_long); 8696470Sphkstatic void prtstat(struct statfs *, struct maxwidths *); 87120037Sobrienstatic size_t regetmntinfo(struct statfs **, long, const char **); 88114579Smarkmstatic void update_maxwidths(struct maxwidths *, const struct statfs *); 8996470Sphkstatic void usage(void); 901556Srgrimes 91125611Siedowsestatic __inline int 92125611Siedowseimax(int a, int b) 9393246Siedowse{ 94114579Smarkm return (a > b ? a : b); 9593246Siedowse} 9693246Siedowse 97185200Spjdstatic int aflag = 0, cflag, hflag, iflag, kflag, lflag = 0, nflag, Tflag; 9896470Sphkstatic struct ufs_args mdev; 9996470Sphk 1001556Srgrimesint 10190108Simpmain(int argc, char *argv[]) 1021556Srgrimes{ 1031556Srgrimes struct stat stbuf; 104128555Sobrien struct statfs statfsbuf, totalbuf; 10593246Siedowse struct maxwidths maxwidths; 106128555Sobrien struct statfs *mntbuf; 10776873Skris const char *fstype; 10896470Sphk char *mntpath, *mntpt; 10996470Sphk const char **vfslist; 110226502Sdes int i, mntsize; 111120037Sobrien int ch, rv; 1121556Srgrimes 11376404Skris fstype = "ufs"; 11476404Skris 115128555Sobrien memset(&totalbuf, 0, sizeof(totalbuf)); 116128410Sobrien totalbuf.f_bsize = DEV_BSIZE; 117161470Simp strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN); 11823852Sbde vfslist = NULL; 119185200Spjd while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T")) != -1) 1201556Srgrimes switch (ch) { 12152735Sjulian case 'a': 12252735Sjulian aflag = 1; 12352735Sjulian break; 12454621Smharo case 'b': 12554621Smharo /* FALLTHROUGH */ 12654621Smharo case 'P': 127162483Scsjp /* 128218909Sbrucec * POSIX specifically discusses the behavior of 129162483Scsjp * both -k and -P. It states that the blocksize should 130162483Scsjp * be set to 1024. Thus, if this occurs, simply break 131162483Scsjp * rather than clobbering the old blocksize. 132162483Scsjp */ 133162483Scsjp if (kflag) 134162483Scsjp break; 135171195Sscf setenv("BLOCKSIZE", "512", 1); 13654621Smharo hflag = 0; 13754621Smharo break; 138128555Sobrien case 'c': 139128555Sobrien cflag = 1; 140128555Sobrien break; 14161227Sjwd case 'g': 142171195Sscf setenv("BLOCKSIZE", "1g", 1); 14361227Sjwd hflag = 0; 14461227Sjwd break; 14554621Smharo case 'H': 14654621Smharo hflag = UNITS_SI; 14754621Smharo break; 14854621Smharo case 'h': 14954621Smharo hflag = UNITS_2; 15054621Smharo break; 1511556Srgrimes case 'i': 1521556Srgrimes iflag = 1; 1531556Srgrimes break; 1542008Swollman case 'k': 155162483Scsjp kflag++; 156171195Sscf setenv("BLOCKSIZE", "1024", 1); 15754621Smharo hflag = 0; 1582008Swollman break; 15977734Spirzyk case 'l': 16077734Spirzyk if (vfslist != NULL) 16177734Spirzyk errx(1, "-l and -t are mutually exclusive."); 16277734Spirzyk vfslist = makevfslist(makenetvfslist()); 163167326Swill lflag = 1; 16477734Spirzyk break; 16554621Smharo case 'm': 166171195Sscf setenv("BLOCKSIZE", "1m", 1); 16754621Smharo hflag = 0; 16854621Smharo break; 1691556Srgrimes case 'n': 1701556Srgrimes nflag = 1; 1711556Srgrimes break; 1721556Srgrimes case 't': 173167326Swill if (lflag) 174167326Swill errx(1, "-l and -t are mutually exclusive."); 17523852Sbde if (vfslist != NULL) 17687666Scharnier errx(1, "only one -t option may be specified"); 17780795Sobrien fstype = optarg; 17823852Sbde vfslist = makevfslist(optarg); 1791556Srgrimes break; 180185200Spjd case 'T': 181185200Spjd Tflag = 1; 182185200Spjd break; 1831556Srgrimes case '?': 1841556Srgrimes default: 1851556Srgrimes usage(); 1861556Srgrimes } 1871556Srgrimes argc -= optind; 1881556Srgrimes argv += optind; 1891556Srgrimes 19030340Sjoerg rv = 0; 1911556Srgrimes if (!*argv) { 192226502Sdes /* everything (modulo -t) */ 193226502Sdes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 19423852Sbde mntsize = regetmntinfo(&mntbuf, mntsize, vfslist); 195226502Sdes } else { 196226502Sdes /* just the filesystems specified on the command line */ 197226502Sdes mntbuf = malloc(argc * sizeof(*mntbuf)); 198226502Sdes if (mntbuf == 0) 199226502Sdes err(1, "malloc()"); 200226502Sdes mntsize = 0; 201226502Sdes /* continued in for loop below */ 2021556Srgrimes } 2031556Srgrimes 204226502Sdes /* iterate through specified filesystems */ 2051556Srgrimes for (; *argv; argv++) { 2061556Srgrimes if (stat(*argv, &stbuf) < 0) { 2071556Srgrimes if ((mntpt = getmntpt(*argv)) == 0) { 2081556Srgrimes warn("%s", *argv); 20930340Sjoerg rv = 1; 2101556Srgrimes continue; 2111556Srgrimes } 21276404Skris } else if (S_ISCHR(stbuf.st_mode)) { 21376404Skris if ((mntpt = getmntpt(*argv)) == 0) { 21476404Skris mdev.fspec = *argv; 21576404Skris mntpath = strdup("/tmp/df.XXXXXX"); 21676404Skris if (mntpath == NULL) { 21776404Skris warn("strdup failed"); 21876404Skris rv = 1; 21976404Skris continue; 22076404Skris } 22176404Skris mntpt = mkdtemp(mntpath); 22276404Skris if (mntpt == NULL) { 22376404Skris warn("mkdtemp(\"%s\") failed", mntpath); 22476404Skris rv = 1; 22576404Skris free(mntpath); 22676404Skris continue; 22776404Skris } 22876404Skris if (mount(fstype, mntpt, MNT_RDONLY, 22976404Skris &mdev) != 0) { 23096470Sphk warn("%s", *argv); 23196470Sphk rv = 1; 23276404Skris (void)rmdir(mntpt); 23376404Skris free(mntpath); 23476404Skris continue; 23576404Skris } else if (statfs(mntpt, &statfsbuf) == 0) { 23676404Skris statfsbuf.f_mntonname[0] = '\0'; 23793246Siedowse prtstat(&statfsbuf, &maxwidths); 238128410Sobrien if (cflag) 239128410Sobrien addstat(&totalbuf, &statfsbuf); 24076404Skris } else { 24176404Skris warn("%s", *argv); 24276404Skris rv = 1; 24376404Skris } 24476404Skris (void)unmount(mntpt, 0); 24576404Skris (void)rmdir(mntpt); 24676404Skris free(mntpath); 24776404Skris continue; 24876404Skris } 2491556Srgrimes } else 2501556Srgrimes mntpt = *argv; 251115769Sbde 2521556Srgrimes /* 2531556Srgrimes * Statfs does not take a `wait' flag, so we cannot 2541556Srgrimes * implement nflag here. 2551556Srgrimes */ 2561556Srgrimes if (statfs(mntpt, &statfsbuf) < 0) { 2571556Srgrimes warn("%s", mntpt); 25830340Sjoerg rv = 1; 2591556Srgrimes continue; 2601556Srgrimes } 261115769Sbde 262115769Sbde /* 263115769Sbde * Check to make sure the arguments we've been given are 264115769Sbde * satisfied. Return an error if we have been asked to 265115769Sbde * list a mount point that does not match the other args 266115769Sbde * we've been given (-l, -t, etc.). 267115744Sjkh */ 268115744Sjkh if (checkvfsname(statfsbuf.f_fstypename, vfslist)) { 269115769Sbde rv = 1; 270115744Sjkh continue; 271115744Sjkh } 272115769Sbde 273226502Sdes /* the user asked for it, so ignore the ignore flag */ 274226502Sdes statfsbuf.f_flags &= ~MNT_IGNORE; 275226502Sdes 276226502Sdes /* add to list */ 277226502Sdes mntbuf[mntsize++] = statfsbuf; 278226502Sdes } 279226502Sdes 280226502Sdes bzero(&maxwidths, sizeof(maxwidths)); 281226502Sdes for (i = 0; i < mntsize; i++) { 282226502Sdes if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) { 283226502Sdes update_maxwidths(&maxwidths, &mntbuf[i]); 284226502Sdes if (cflag) 285226502Sdes addstat(&totalbuf, &mntbuf[i]); 28693246Siedowse } 2871556Srgrimes } 288226502Sdes for (i = 0; i < mntsize; i++) 289226502Sdes if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) 290226502Sdes prtstat(&mntbuf[i], &maxwidths); 291128410Sobrien if (cflag) 292128410Sobrien prtstat(&totalbuf, &maxwidths); 29330340Sjoerg return (rv); 2941556Srgrimes} 2951556Srgrimes 29696470Sphkstatic char * 297114579Smarkmgetmntpt(const char *name) 2981556Srgrimes{ 299120037Sobrien size_t mntsize, i; 3001556Srgrimes struct statfs *mntbuf; 3011556Srgrimes 3021556Srgrimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 3031556Srgrimes for (i = 0; i < mntsize; i++) { 3041556Srgrimes if (!strcmp(mntbuf[i].f_mntfromname, name)) 3051556Srgrimes return (mntbuf[i].f_mntonname); 3061556Srgrimes } 3071556Srgrimes return (0); 3081556Srgrimes} 3091556Srgrimes 3101556Srgrimes/* 311102230Strhodes * Make a pass over the file system info in ``mntbuf'' filtering out 312102230Strhodes * file system types not in vfslist and possibly re-stating to get 3131556Srgrimes * current (not cached) info. Returns the new count of valid statfs bufs. 3141556Srgrimes */ 315120037Sobrienstatic size_t 31696470Sphkregetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist) 3171556Srgrimes{ 318132465Scsjp int error, i, j; 3191556Srgrimes struct statfs *mntbuf; 3201556Srgrimes 32123852Sbde if (vfslist == NULL) 3221556Srgrimes return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT)); 3231556Srgrimes 3241556Srgrimes mntbuf = *mntbufp; 32523852Sbde for (j = 0, i = 0; i < mntsize; i++) { 32623852Sbde if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) 32723852Sbde continue; 328132465Scsjp /* 329132465Scsjp * XXX statfs(2) can fail for various reasons. It may be 330132465Scsjp * possible that the user does not have access to the 331132465Scsjp * pathname, if this happens, we will fall back on 332132465Scsjp * "stale" filesystem statistics. 333132465Scsjp */ 334132465Scsjp error = statfs(mntbuf[i].f_mntonname, &mntbuf[j]); 335132465Scsjp if (nflag || error < 0) 336132465Scsjp if (i != j) { 337132465Scsjp if (error < 0) 338132465Scsjp warnx("%s stats possibly stale", 339132465Scsjp mntbuf[i].f_mntonname); 340132465Scsjp mntbuf[j] = mntbuf[i]; 341132465Scsjp } 34223852Sbde j++; 3431556Srgrimes } 3441556Srgrimes return (j); 3451556Srgrimes} 3461556Srgrimes 34796470Sphkstatic void 348122537Smckusickprthuman(const struct statfs *sfsp, int64_t used) 34954621Smharo{ 35054621Smharo 351129678Spjd prthumanval(sfsp->f_blocks * sfsp->f_bsize); 352129678Spjd prthumanval(used * sfsp->f_bsize); 353129678Spjd prthumanval(sfsp->f_bavail * sfsp->f_bsize); 35454621Smharo} 35554621Smharo 35696470Sphkstatic void 357129678Spjdprthumanval(int64_t bytes) 35854621Smharo{ 359129678Spjd char buf[6]; 360129678Spjd int flags; 36154621Smharo 362129678Spjd flags = HN_B | HN_NOSPACE | HN_DECIMAL; 363129678Spjd if (hflag == UNITS_SI) 364129678Spjd flags |= HN_DIVISOR_1000; 36554621Smharo 366129678Spjd humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), 367129678Spjd bytes, "", HN_AUTOSCALE, flags); 368129678Spjd 369129678Spjd (void)printf(" %6s", buf); 37054621Smharo} 37154621Smharo 37254621Smharo/* 373193629Ssimon * Print an inode count in "human-readable" format. 374193629Ssimon */ 375193629Ssimonstatic void 376193629Ssimonprthumanvalinode(int64_t bytes) 377193629Ssimon{ 378193629Ssimon char buf[6]; 379193629Ssimon int flags; 380193629Ssimon 381193629Ssimon flags = HN_NOSPACE | HN_DECIMAL | HN_DIVISOR_1000; 382193629Ssimon 383193629Ssimon humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), 384193629Ssimon bytes, "", HN_AUTOSCALE, flags); 385193629Ssimon 386193629Ssimon (void)printf(" %5s", buf); 387193629Ssimon} 388193629Ssimon 389193629Ssimon/* 390102230Strhodes * Convert statfs returned file system size into BLOCKSIZE units. 391102230Strhodes * Attempts to avoid overflow for large file systems. 3921556Srgrimes */ 393130060Sdasstatic intmax_t 394130060Sdasfsbtoblk(int64_t num, uint64_t fsbs, u_long bs) 395130060Sdas{ 3961556Srgrimes 397130060Sdas if (fsbs != 0 && fsbs < bs) 398130060Sdas return (num / (intmax_t)(bs / fsbs)); 399130060Sdas else 400130060Sdas return (num * (intmax_t)(fsbs / bs)); 401130060Sdas} 402130060Sdas 4031556Srgrimes/* 404102230Strhodes * Print out status about a file system. 4051556Srgrimes */ 40696470Sphkstatic void 40793246Siedowseprtstat(struct statfs *sfsp, struct maxwidths *mwp) 4081556Srgrimes{ 409168428Skan static long blocksize; 410114579Smarkm static int headerlen, timesthrough = 0; 41176873Skris static const char *header; 412122537Smckusick int64_t used, availblks, inodes; 4131556Srgrimes 4141556Srgrimes if (++timesthrough == 1) { 415125611Siedowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen("Filesystem")); 416185200Spjd mwp->fstype = imax(mwp->fstype, (int)strlen("Type")); 41754621Smharo if (hflag) { 418128553Sobrien header = " Size"; 419125611Siedowse mwp->total = mwp->used = mwp->avail = 420125611Siedowse (int)strlen(header); 42154621Smharo } else { 42254621Smharo header = getbsize(&headerlen, &blocksize); 423125611Siedowse mwp->total = imax(mwp->total, headerlen); 42454621Smharo } 425125611Siedowse mwp->used = imax(mwp->used, (int)strlen("Used")); 426125611Siedowse mwp->avail = imax(mwp->avail, (int)strlen("Avail")); 42793246Siedowse 428185200Spjd (void)printf("%-*s", mwp->mntfrom, "Filesystem"); 429185200Spjd if (Tflag) 430185200Spjd (void)printf(" %-*s", mwp->fstype, "Type"); 431185200Spjd (void)printf(" %-*s %*s %*s Capacity", mwp->total, header, 432125611Siedowse mwp->used, "Used", mwp->avail, "Avail"); 43393246Siedowse if (iflag) { 434193629Ssimon mwp->iused = imax(hflag ? 0 : mwp->iused, 435193629Ssimon (int)strlen(" iused")); 436193629Ssimon mwp->ifree = imax(hflag ? 0 : mwp->ifree, 437193629Ssimon (int)strlen("ifree")); 438114582Smarkm (void)printf(" %*s %*s %%iused", 439125611Siedowse mwp->iused - 2, "iused", mwp->ifree, "ifree"); 44093246Siedowse } 4411556Srgrimes (void)printf(" Mounted on\n"); 4421556Srgrimes } 443125611Siedowse (void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname); 444185200Spjd if (Tflag) 445185200Spjd (void)printf(" %-*s", mwp->fstype, sfsp->f_fstypename); 4461556Srgrimes used = sfsp->f_blocks - sfsp->f_bfree; 4471556Srgrimes availblks = sfsp->f_bavail + used; 44854621Smharo if (hflag) { 44954621Smharo prthuman(sfsp, used); 45054621Smharo } else { 451122582Skris (void)printf(" %*jd %*jd %*jd", 452130060Sdas mwp->total, fsbtoblk(sfsp->f_blocks, 453125611Siedowse sfsp->f_bsize, blocksize), 454130060Sdas mwp->used, fsbtoblk(used, sfsp->f_bsize, blocksize), 455130060Sdas mwp->avail, fsbtoblk(sfsp->f_bavail, 456125611Siedowse sfsp->f_bsize, blocksize)); 45754621Smharo } 4581556Srgrimes (void)printf(" %5.0f%%", 4591556Srgrimes availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0); 4601556Srgrimes if (iflag) { 4611556Srgrimes inodes = sfsp->f_files; 4621556Srgrimes used = inodes - sfsp->f_ffree; 463193629Ssimon if (hflag) { 464193629Ssimon (void)printf(" "); 465193629Ssimon prthumanvalinode(used); 466193629Ssimon prthumanvalinode(sfsp->f_ffree); 467193629Ssimon } else { 468193629Ssimon (void)printf(" %*jd %*jd", mwp->iused, (intmax_t)used, 469193629Ssimon mwp->ifree, (intmax_t)sfsp->f_ffree); 470193629Ssimon } 471193629Ssimon (void)printf(" %4.0f%% ", inodes == 0 ? 100.0 : 472125611Siedowse (double)used / (double)inodes * 100.0); 473128553Sobrien } else 474128553Sobrien (void)printf(" "); 475128555Sobrien if (strncmp(sfsp->f_mntfromname, "total", MNAMELEN) != 0) 476128410Sobrien (void)printf(" %s", sfsp->f_mntonname); 477128410Sobrien (void)printf("\n"); 4781556Srgrimes} 4791556Srgrimes 480194795Sdelphijstatic void 481128410Sobrienaddstat(struct statfs *totalfsp, struct statfs *statfsp) 482128410Sobrien{ 483128555Sobrien uint64_t bsize; 484128410Sobrien 485128555Sobrien bsize = statfsp->f_bsize / totalfsp->f_bsize; 486128410Sobrien totalfsp->f_blocks += statfsp->f_blocks * bsize; 487128410Sobrien totalfsp->f_bfree += statfsp->f_bfree * bsize; 488128410Sobrien totalfsp->f_bavail += statfsp->f_bavail * bsize; 489128410Sobrien totalfsp->f_files += statfsp->f_files; 490128410Sobrien totalfsp->f_ffree += statfsp->f_ffree; 491128410Sobrien} 492128410Sobrien 4931556Srgrimes/* 49493246Siedowse * Update the maximum field-width information in `mwp' based on 495102230Strhodes * the file system specified by `sfsp'. 49693246Siedowse */ 49796470Sphkstatic void 498114579Smarkmupdate_maxwidths(struct maxwidths *mwp, const struct statfs *sfsp) 49993246Siedowse{ 500168428Skan static long blocksize = 0; 501108452Smike int dummy; 50293246Siedowse 50393246Siedowse if (blocksize == 0) 50493246Siedowse getbsize(&dummy, &blocksize); 50593246Siedowse 506125611Siedowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen(sfsp->f_mntfromname)); 507185200Spjd mwp->fstype = imax(mwp->fstype, (int)strlen(sfsp->f_fstypename)); 508125611Siedowse mwp->total = imax(mwp->total, int64width( 509122537Smckusick fsbtoblk((int64_t)sfsp->f_blocks, sfsp->f_bsize, blocksize))); 510125611Siedowse mwp->used = imax(mwp->used, 511125611Siedowse int64width(fsbtoblk((int64_t)sfsp->f_blocks - 512122537Smckusick (int64_t)sfsp->f_bfree, sfsp->f_bsize, blocksize))); 513125611Siedowse mwp->avail = imax(mwp->avail, int64width(fsbtoblk(sfsp->f_bavail, 51493246Siedowse sfsp->f_bsize, blocksize))); 515125611Siedowse mwp->iused = imax(mwp->iused, int64width((int64_t)sfsp->f_files - 51693246Siedowse sfsp->f_ffree)); 517125611Siedowse mwp->ifree = imax(mwp->ifree, int64width(sfsp->f_ffree)); 51893246Siedowse} 51993246Siedowse 520125611Siedowse/* Return the width in characters of the specified value. */ 521125611Siedowsestatic int 522122537Smckusickint64width(int64_t val) 52393246Siedowse{ 524125611Siedowse int len; 52593246Siedowse 52693246Siedowse len = 0; 52793246Siedowse /* Negative or zero values require one extra digit. */ 52893246Siedowse if (val <= 0) { 52993246Siedowse val = -val; 53093246Siedowse len++; 53193246Siedowse } 53293246Siedowse while (val > 0) { 53393246Siedowse len++; 53493246Siedowse val /= 10; 53593246Siedowse } 53693246Siedowse 53793246Siedowse return (len); 53893246Siedowse} 53993246Siedowse 54096470Sphkstatic void 54190108Simpusage(void) 5421556Srgrimes{ 54354621Smharo 54423852Sbde (void)fprintf(stderr, 545185200Spjd"usage: df [-b | -g | -H | -h | -k | -m | -P] [-acilnT] [-t type] [file | filesystem ...]\n"); 54654621Smharo exit(EX_USAGE); 5471556Srgrimes} 54877734Spirzyk 54996470Sphkstatic char * 55090108Simpmakenetvfslist(void) 55177734Spirzyk{ 55277734Spirzyk char *str, *strptr, **listptr; 553114579Smarkm struct xvfsconf *xvfsp, *keep_xvfsp; 554101651Smux size_t buflen; 555101651Smux int cnt, i, maxvfsconf; 55677734Spirzyk 557101651Smux if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) { 558101651Smux warn("sysctl(vfs.conflist)"); 55977734Spirzyk return (NULL); 56077734Spirzyk } 561101651Smux xvfsp = malloc(buflen); 562101651Smux if (xvfsp == NULL) { 563101651Smux warnx("malloc failed"); 564101651Smux return (NULL); 565101651Smux } 566114579Smarkm keep_xvfsp = xvfsp; 567101651Smux if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) { 568101651Smux warn("sysctl(vfs.conflist)"); 569114579Smarkm free(keep_xvfsp); 570101651Smux return (NULL); 571101651Smux } 572101651Smux maxvfsconf = buflen / sizeof(struct xvfsconf); 57377734Spirzyk 57479791Swollman if ((listptr = malloc(sizeof(char*) * maxvfsconf)) == NULL) { 57577734Spirzyk warnx("malloc failed"); 576114579Smarkm free(keep_xvfsp); 57777734Spirzyk return (NULL); 57877734Spirzyk } 57977734Spirzyk 580101651Smux for (cnt = 0, i = 0; i < maxvfsconf; i++) { 581101651Smux if (xvfsp->vfc_flags & VFCF_NETWORK) { 582101651Smux listptr[cnt++] = strdup(xvfsp->vfc_name); 58379791Swollman if (listptr[cnt-1] == NULL) { 58477734Spirzyk warnx("malloc failed"); 585114579Smarkm free(listptr); 586114579Smarkm free(keep_xvfsp); 58777734Spirzyk return (NULL); 58877734Spirzyk } 58977734Spirzyk } 590101651Smux xvfsp++; 591101651Smux } 59277734Spirzyk 59388182Sru if (cnt == 0 || 59488182Sru (str = malloc(sizeof(char) * (32 * cnt + cnt + 2))) == NULL) { 59588182Sru if (cnt > 0) 59688182Sru warnx("malloc failed"); 59777734Spirzyk free(listptr); 598114579Smarkm free(keep_xvfsp); 59977734Spirzyk return (NULL); 60077734Spirzyk } 60177734Spirzyk 60279791Swollman *str = 'n'; *(str + 1) = 'o'; 60379791Swollman for (i = 0, strptr = str + 2; i < cnt; i++, strptr++) { 604161470Simp strlcpy(strptr, listptr[i], 32); 60579791Swollman strptr += strlen(listptr[i]); 60679791Swollman *strptr = ','; 60777734Spirzyk free(listptr[i]); 60877734Spirzyk } 609126643Smarkm *(--strptr) = '\0'; 61077734Spirzyk 611114579Smarkm free(keep_xvfsp); 61277734Spirzyk free(listptr); 61377734Spirzyk return (str); 61477734Spirzyk} 615