From 5b57d28ffb6e1ef86b50f7d05d977826eae89bfe Mon Sep 17 00:00:00 2001 From: Kiyoshi Aman Date: Fri, 1 Feb 2019 22:55:37 +0000 Subject: initial population --- bin/df/df.1 | 206 ++++++++++++++++++++++++ bin/df/df.c | 520 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 726 insertions(+) create mode 100644 bin/df/df.1 create mode 100644 bin/df/df.c (limited to 'bin/df') diff --git a/bin/df/df.1 b/bin/df/df.1 new file mode 100644 index 0000000..6ac5ed0 --- /dev/null +++ b/bin/df/df.1 @@ -0,0 +1,206 @@ +.\" $NetBSD: df.1,v 1.49 2018/08/26 23:34:52 sevan Exp $ +.\" +.\" Copyright (c) 1989, 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)df.1 8.2 (Berkeley) 1/13/92 +.\" +.Dd August 27, 2018 +.Dt DF 1 +.Os +.Sh NAME +.Nm df +.Nd display free disk space +.Sh SYNOPSIS +.Nm +.Op Fl agln +.Op Fl Ghkm | Fl ihkm | Fl Pk +.Op Fl t Ar type +.Op Ar file | Ar file_system ... +.Sh DESCRIPTION +.Nm +displays statistics about the amount of free disk space on the specified +.Ar file_system +or on the file system of which +.Ar file +is a part. +By default, all sizes are reported in 512-byte block counts. +If neither a file or a +.Ar file_system +operand is specified, +statistics for all mounted file systems are displayed +(subject to the +.Fl l +and +.Fl t +options below). +.Pp +Note that the printed count of available blocks takes +.Va minfree +into account, and thus will be negative when the number of free blocks +on the filesystem is less than +.Va minfree . +.Pp +The following options are available: +.Bl -tag -width Ds +.It Fl a +Show all mount points, +including those that were mounted with the +.Dv MNT_IGNORE +flag. +.It Fl G +Display all the fields of the structure(s) returned by +.Xr statvfs 2 . +This option cannot be used with the +.Fl i +or +.Fl P +options, and it is modelled after the Solaris +.Fl g +option. +This option will override the +.Fl g , +.Fl h , +.Fl k , +and +.Fl m +options, as well as any setting of +.Ev BLOCKSIZE . +.It Fl g +The +.Fl g +option causes the numbers to be reported in gigabytes (1024*1024*1024 +bytes). +.It Fl h +"Human-readable" output. +Use unit suffixes: Byte, Kilobyte, Megabyte, +Gigabyte, Terabyte, Petabyte, Exabyte in order to reduce the number of +digits to four or less. +.It Fl i +Include statistics on the number of free inodes. +.It Fl k +By default, all sizes are reported in 512-byte block counts. +The +.Fl k +option causes the numbers to be reported in kilobytes (1024 bytes). +.It Fl l +Display statistics only about mounted file systems with the +.Dv MNT_LOCAL +flag set. +If a non-local file system is given as an argument, a +warning is issued and no information is given on that file system. +.It Fl m +The +.Fl m +option causes the numbers to be reported in megabytes (1024*1024 bytes). +.It Fl n +Print out the previously obtained statistics from the file systems. +This option should be used if it is possible that one or more +file systems are in a state such that they will not be able to provide +statistics without a long delay. +When this option is specified, +.Nm +will not request new statistics from the file systems, but will respond +with the possibly stale statistics that were previously obtained. +.It Fl P +Produce output in the following portable format: +.Pp +If both the +.Fl P +and +.Fl k +option are specified, the output will be preceded by the following header +line, formatted to match the data following it: +.Bd -literal +"Filesystem 1024-blocks Used Available Capacity Mounted on\en" +.Ed +.Pp +If the +.Fl P +option is specified without the +.Fl k +options, the output will be preceded by the following header line, +formatted to match the data following it: +.Bd -literal +"Filesystem -blocks Used Available Capacity Mounted on\en" +.Ed +.Pp +The header line is followed by data formatted as follows: +.Bd -literal +"%s %d %d %d %d%% %s\en", , , + , , , + +.Ed +.Pp +Note that the +.Fl i +option may not be specified with +.Fl P . +.It Fl t Ar type +Is used to indicate the actions should only be taken on +filesystems of the specified type. +More than one type may be specified in a comma-separated list. +The list of filesystem types can be prefixed with +.Dq no +to specify the filesystem types for which action should +.Em not +be taken. +If a file system is given on the command line that is not of +the specified type, a warning is issued and no information is given on +that file system. +.El +.Sh ENVIRONMENT +.Bl -tag -width BLOCKSIZE +.It Ev BLOCKSIZE +If the environment variable +.Ev BLOCKSIZE +is set, and the +.Fl g , +.Fl h , +.Fl k +and +.Fl m +options are not specified, the block counts will be displayed in units of that +size block. +.El +.Sh SEE ALSO +.Xr quota 1 , +.Xr fstatvfs 2 , +.Xr getvfsstat 2 , +.Xr statvfs 2 , +.Xr getbsize 3 , +.Xr getmntinfo 3 , +.Xr fs 5 , +.Xr fstab 5 , +.Xr mount 8 , +.Xr quot 8 , +.Xr tunefs 8 +.Sh HISTORY +A +.Nm +utility appeared in +.At v1 . diff --git a/bin/df/df.c b/bin/df/df.c new file mode 100644 index 0000000..9392d0c --- /dev/null +++ b/bin/df/df.c @@ -0,0 +1,520 @@ +/* $NetBSD: df.c,v 1.93 2018/08/26 23:34:52 sevan Exp $ */ + +/* + * Copyright (c) 1980, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +__COPYRIGHT( +"@(#) Copyright (c) 1980, 1990, 1993, 1994\ + The Regents of the University of California. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)df.c 8.7 (Berkeley) 4/2/94"; +#else +__RCSID("$NetBSD: df.c,v 1.93 2018/08/26 23:34:52 sevan Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *getmntpt(const char *); +static void prtstat(struct statvfs *, int); +static int selected(const char *, size_t); +static void maketypelist(char *); +static size_t regetmntinfo(struct statvfs **, size_t); +__dead static void usage(void); +static void prthumanval(int64_t, const char *); +static void prthuman(struct statvfs *, int64_t, int64_t); + +static int aflag, gflag, hflag, iflag, lflag, nflag, Pflag; +static long usize; +static char **typelist; + +int +main(int argc, char *argv[]) +{ + struct stat stbuf; + struct statvfs *mntbuf; + long mntsize; + int ch, i, maxwidth, width; + char *mntpt; + + setprogname(argv[0]); + (void)setlocale(LC_ALL, ""); + + while ((ch = getopt(argc, argv, "aGghiklmnPt:")) != -1) + switch (ch) { + case 'a': + aflag = 1; + break; + case 'g': + hflag = 0; + usize = 1024 * 1024 * 1024; + break; + case 'G': + gflag = 1; + break; + case 'h': + hflag = 1; + usize = 0; + break; + case 'i': + iflag = 1; + break; + case 'k': + hflag = 0; + usize = 1024; + break; + case 'l': + lflag = 1; + break; + case 'm': + hflag = 0; + usize = 1024 * 1024; + break; + case 'n': + nflag = 1; + break; + case 'P': + Pflag = 1; + break; + case 't': + if (typelist != NULL) + errx(EXIT_FAILURE, + "only one -t option may be specified."); + maketypelist(optarg); + break; + case '?': + default: + usage(); + } + + if (gflag && (Pflag || iflag)) + errx(EXIT_FAILURE, + "only one of -G and -P or -i may be specified"); + if (Pflag && iflag) + errx(EXIT_FAILURE, + "only one of -P and -i may be specified"); +#if 0 + /* + * The block size cannot be checked until after getbsize() is called. + */ + if (Pflag && (hflag || (usize != 1024 && usize != 512))) + errx(EXIT_FAILURE, + "non-standard block size incompatible with -P"); +#endif + argc -= optind; + argv += optind; + + mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); + if (mntsize == 0) + err(EXIT_FAILURE, + "retrieving information on mounted file systems"); + + if (*argv == NULL) { + mntsize = regetmntinfo(&mntbuf, mntsize); + } else { + if ((mntbuf = malloc(argc * sizeof(*mntbuf))) == NULL) + err(EXIT_FAILURE, "can't allocate statvfs array"); + mntsize = 0; + for (/*EMPTY*/; *argv != NULL; argv++) { + if (stat(*argv, &stbuf) < 0) { + if ((mntpt = getmntpt(*argv)) == 0) { + warn("%s", *argv); + continue; + } + } else if (S_ISBLK(stbuf.st_mode)) { + if ((mntpt = getmntpt(*argv)) == 0) + mntpt = *argv; + } else + mntpt = *argv; + /* + * Statfs does not take a `wait' flag, so we cannot + * implement nflag here. + */ + if (!statvfs(mntpt, &mntbuf[mntsize])) + if (lflag && + (mntbuf[mntsize].f_flag & MNT_LOCAL) == 0) + warnx("Warning: %s is not a local %s", + *argv, "file system"); + else if + (!selected(mntbuf[mntsize].f_fstypename, + sizeof(mntbuf[mntsize].f_fstypename))) + warnx("Warning: %s mounted as a %s %s", + *argv, + mntbuf[mntsize].f_fstypename, + "file system"); + else + ++mntsize; + else + warn("%s", *argv); + } + } + + maxwidth = 0; + for (i = 0; i < mntsize; i++) { + width = (int)strlen(mntbuf[i].f_mntfromname); + if (width > maxwidth) + maxwidth = width; + } + for (i = 0; i < mntsize; i++) + prtstat(&mntbuf[i], maxwidth); + return 0; +} + +static char * +getmntpt(const char *name) +{ + size_t mntsize, i; + struct statvfs *mntbuf; + + mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); + if (mntsize == 0) + err(EXIT_FAILURE, "Can't get mount information"); + for (i = 0; i < mntsize; i++) { + if (!strcmp(mntbuf[i].f_mntfromname, name)) + return mntbuf[i].f_mntonname; + } + return 0; +} + +static enum { IN_LIST, NOT_IN_LIST } which; + +static int +selected(const char *type, size_t len) +{ + char **av; + + /* If no type specified, it's always selected. */ + if (typelist == NULL) + return 1; + for (av = typelist; *av != NULL; ++av) + if (!strncmp(type, *av, len)) + return which == IN_LIST ? 1 : 0; + return which == IN_LIST ? 0 : 1; +} + +static void +maketypelist(char *fslist) +{ + size_t i; + char *nextcp, **av; + + if ((fslist == NULL) || (fslist[0] == '\0')) + errx(EXIT_FAILURE, "empty type list"); + + /* + * XXX + * Note: the syntax is "noxxx,yyy" for no xxx's and + * no yyy's, not the more intuitive "noyyy,noyyy". + */ + if (fslist[0] == 'n' && fslist[1] == 'o') { + fslist += 2; + which = NOT_IN_LIST; + } else + which = IN_LIST; + + /* Count the number of types. */ + for (i = 1, nextcp = fslist; + (nextcp = strchr(nextcp, ',')) != NULL; i++) + ++nextcp; + + /* Build an array of that many types. */ + if ((av = typelist = malloc((i + 1) * sizeof(*av))) == NULL) + err(EXIT_FAILURE, "can't allocate type array"); + av[0] = fslist; + for (i = 1, nextcp = fslist; + (nextcp = strchr(nextcp, ',')) != NULL; i++) { + *nextcp = '\0'; + av[i] = ++nextcp; + } + /* Terminate the array. */ + av[i] = NULL; +} + +/* + * Make a pass over the filesystem info in ``mntbuf'' filtering out + * filesystem types not in ``fsmask'' and possibly re-stating to get + * current (not cached) info. Returns the new count of valid statvfs bufs. + */ +static size_t +regetmntinfo(struct statvfs **mntbufp, size_t mntsize) +{ + size_t i, j; + struct statvfs *mntbuf; + + if (!lflag && typelist == NULL && aflag) + return nflag ? mntsize : (size_t)getmntinfo(mntbufp, MNT_WAIT); + + mntbuf = *mntbufp; + j = 0; + for (i = 0; i < mntsize; i++) { + if (!aflag && (mntbuf[i].f_flag & MNT_IGNORE) != 0) + continue; + if (lflag && (mntbuf[i].f_flag & MNT_LOCAL) == 0) + continue; + if (!selected(mntbuf[i].f_fstypename, + sizeof(mntbuf[i].f_fstypename))) + continue; + if (nflag) + mntbuf[j] = mntbuf[i]; + else { + struct statvfs layerbuf = mntbuf[i]; + (void)statvfs(mntbuf[i].f_mntonname, &mntbuf[j]); + /* + * If the FS name changed, then new data is for + * a different layer and we don't want it. + */ + if (memcmp(layerbuf.f_mntfromname, + mntbuf[j].f_mntfromname, MNAMELEN)) + mntbuf[j] = layerbuf; + } + j++; + } + return j; +} + +static void +prthumanval(int64_t bytes, const char *pad) +{ + char buf[6]; + + (void)humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), + bytes, "", HN_AUTOSCALE, + HN_B | HN_NOSPACE | HN_DECIMAL); + + (void)printf("%s %6s", pad, buf); +} + +static void +prthuman(struct statvfs *sfsp, int64_t used, int64_t bavail) +{ + + prthumanval((int64_t)(sfsp->f_blocks * sfsp->f_frsize), " "); + prthumanval((int64_t)(used * sfsp->f_frsize), " "); + prthumanval((int64_t)(bavail * sfsp->f_frsize), " "); +} + +/* + * Convert statvfs returned filesystem size into BLOCKSIZE units. + * Attempts to avoid overflow for large filesystems. + */ +#define fsbtoblk(num, fsbs, bs) \ + (((fsbs) != 0 && (uint64_t)(fsbs) < (uint64_t)(bs)) ? \ + (int64_t)(num) / (int64_t)((bs) / (fsbs)) : \ + (int64_t)(num) * (int64_t)((fsbs) / (bs))) + +/* + * Print out status about a filesystem. + */ +static void +prtstat(struct statvfs *sfsp, int maxwidth) +{ + static long blocksize; + static int headerlen, timesthrough; + static const char *header; + static const char full[] = "100"; + static const char empty[] = " 0"; + int64_t used, availblks, inodes; + int64_t bavail; + char pb[64]; + + if (gflag) { + /* + * From SunOS-5.6: + * + * /var (/dev/dsk/c0t0d0s3 ): 8192 block size 1024 frag size + * 984242 total blocks 860692 free blocks 859708 available 249984 total files + * 248691 free files 8388611 filesys id + * ufs fstype 0x00000004 flag 255 filename length + * + */ + (void)printf("%10s (%-12s): %7ld block size %12ld frag size\n", + sfsp->f_mntonname, sfsp->f_mntfromname, + sfsp->f_bsize, /* On UFS/FFS systems this is + * also called the "optimal + * transfer block size" but it + * is of course the file + * system's block size too. + */ + sfsp->f_frsize); /* not so surprisingly the + * "fundamental file system + * block size" is the frag + * size. + */ + (void)printf("%10" PRId64 " total blocks %10" PRId64 + " free blocks %10" PRId64 " available\n", + (uint64_t)sfsp->f_blocks, (uint64_t)sfsp->f_bfree, + (uint64_t)sfsp->f_bavail); + (void)printf("%10" PRId64 " total files %10" PRId64 + " free files %12lx filesys id\n", + (uint64_t)sfsp->f_ffree, (uint64_t)sfsp->f_files, + sfsp->f_fsid); + (void)printf("%10s fstype %#15lx flag %17ld filename " + "length\n", sfsp->f_fstypename, sfsp->f_flag, + sfsp->f_namemax); + (void)printf("%10lu owner %17" PRId64 " syncwrites %12" PRId64 + " asyncwrites\n\n", (unsigned long)sfsp->f_owner, + sfsp->f_syncwrites, sfsp->f_asyncwrites); + + /* + * a concession by the structured programming police to the + * indentation police.... + */ + return; + } + if (maxwidth < 12) + maxwidth = 12; + if (++timesthrough == 1) { + switch (blocksize = usize) { + case 1024: + header = Pflag ? "1024-blocks" : "1K-blocks"; + headerlen = (int)strlen(header); + break; + case 1024 * 1024: + header = "1M-blocks"; + headerlen = (int)strlen(header); + break; + case 1024 * 1024 * 1024: + header = "1G-blocks"; + headerlen = (int)strlen(header); + break; + default: + if (hflag) { + header = "Size"; + headerlen = (int)strlen(header); + } else + header = getbsize(&headerlen, &blocksize); + break; + } + if (Pflag) { + /* + * either: + * "Filesystem 1024-blocks Used Available Capacity Mounted on\n" + * or: + * "Filesystem 512-blocks Used Available Capacity Mounted on\n" + */ + if (blocksize != 1024 && blocksize != 512) + errx(EXIT_FAILURE, + "non-standard block size incompatible with -P"); + (void)printf("Filesystem %s Used Available Capacity " + "Mounted on\n", header); + } else { + (void)printf("%-*.*s %s Used Avail %%Cap", + maxwidth - (headerlen - 10), + maxwidth - (headerlen - 10), + "Filesystem", header); + if (iflag) + (void)printf(" iUsed iAvail %%iCap"); + (void)printf(" Mounted on\n"); + } + } + used = sfsp->f_blocks - sfsp->f_bfree; + bavail = sfsp->f_bfree - sfsp->f_bresvd; + availblks = bavail + used; + if (Pflag) { + assert(hflag == 0); + assert(blocksize > 0); + /* + * "%s %d %d %d %s %s\n", , , + * , , , + * + */ + (void)printf("%s %" PRId64 " %" PRId64 " %" PRId64 " %s%% %s\n", + sfsp->f_mntfromname, + fsbtoblk(sfsp->f_blocks, sfsp->f_frsize, blocksize), + fsbtoblk(used, sfsp->f_frsize, blocksize), + fsbtoblk(bavail, sfsp->f_frsize, blocksize), + availblks == 0 ? full : strspct(pb, sizeof(pb), used, + availblks, 0), sfsp->f_mntonname); + /* + * another concession by the structured programming police to + * the indentation police.... + * + * Note iflag cannot be set when Pflag is set. + */ + return; + } + + (void)printf("%-*.*s ", maxwidth, maxwidth, sfsp->f_mntfromname); + + if (hflag) + prthuman(sfsp, used, bavail); + else + (void)printf("%10" PRId64 " %10" PRId64 " %10" PRId64, + fsbtoblk(sfsp->f_blocks, sfsp->f_frsize, blocksize), + fsbtoblk(used, sfsp->f_frsize, blocksize), + fsbtoblk(bavail, sfsp->f_frsize, blocksize)); + (void)printf(" %3s%%", + availblks == 0 ? full : + strspct(pb, sizeof(pb), used, availblks, 0)); + if (iflag) { + inodes = sfsp->f_files; + used = inodes - sfsp->f_ffree; + (void)printf(" %8jd %8jd %4s%%", + (intmax_t)used, (intmax_t)sfsp->f_ffree, + inodes == 0 ? (used == 0 ? empty : full) : + strspct(pb, sizeof(pb), used, inodes, 0)); + } + (void)printf(" %s\n", sfsp->f_mntonname); +} + +static void +usage(void) +{ + + (void)fprintf(stderr, + "Usage: %s [-agln] [-Ghkm|-ihkm|-Pk] [-t type] [file | " + "file_system ...]\n", + getprogname()); + exit(1); + /* NOTREACHED */ +} -- cgit v1.2.3-60-g2f50