summaryrefslogtreecommitdiffstats
path: root/bin/df
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2002-03-26 20:32:37 +0000
committeriedowse <iedowse@FreeBSD.org>2002-03-26 20:32:37 +0000
commit87a3c1d1909b9c2c4e4e576330f91ef00235b24d (patch)
tree2c1416361664f78d6548d90c95b15f79019c1fac /bin/df
parentff7ea7dcf410ca603a84d690b7609c4b2c0bb516 (diff)
downloadFreeBSD-src-87a3c1d1909b9c2c4e4e576330f91ef00235b24d.zip
FreeBSD-src-87a3c1d1909b9c2c4e4e576330f91ef00235b24d.tar.gz
Make the columns in the output of df(1) line up, even for very large
filesystems. We now keep track of the maximum width required for every variable-width field instead of just the first one. PR: bin/15510 MFC after: 1 week
Diffstat (limited to 'bin/df')
-rw-r--r--bin/df/df.c145
1 files changed, 106 insertions, 39 deletions
diff --git a/bin/df/df.c b/bin/df/df.c
index e776f8b..951cecf 100644
--- a/bin/df/df.c
+++ b/bin/df/df.c
@@ -91,6 +91,16 @@ static const char rcsid[] =
#define TERA_SI_SZ (TERA_SZ(1000ULL))
#define PETA_SI_SZ (PETA_SZ(1000ULL))
+/* Maximum widths of various fields. */
+struct maxwidths {
+ int mntfrom;
+ int total;
+ int used;
+ int avail;
+ int iused;
+ int ifree;
+};
+
unsigned long long vals_si [] = {1, KILO_SI_SZ, MEGA_SI_SZ, GIGA_SI_SZ, TERA_SI_SZ, PETA_SI_SZ};
unsigned long long vals_base2[] = {1, KILO_2_SZ, MEGA_2_SZ, GIGA_2_SZ, TERA_2_SZ, PETA_2_SZ};
unsigned long long *valp;
@@ -102,28 +112,36 @@ unit_t unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA };
int bread(off_t, void *, int);
int checkvfsname(const char *, char **);
char *getmntpt(char *);
+int longwidth(long);
char *makenetvfslist(void);
char **makevfslist(char *);
void prthuman(struct statfs *, long);
void prthumanval(double);
-void prtstat(struct statfs *, int);
+void prtstat(struct statfs *, struct maxwidths *);
long regetmntinfo(struct statfs **, long, char **);
-int ufs_df(char *, int);
+int ufs_df(char *, struct maxwidths *);
unit_t unit_adjust(double *);
+void update_maxwidths(struct maxwidths *, struct statfs *);
void usage(void);
int aflag = 0, hflag, iflag, nflag;
struct ufs_args mdev;
+static __inline int imax(int a, int b)
+{
+ return (a > b ? a : b);
+}
+
int
main(int argc, char *argv[])
{
struct stat stbuf;
struct statfs statfsbuf, *mntbuf;
+ struct maxwidths maxwidths;
const char *fstype;
char *mntpath, *mntpt, **vfslist;
long mntsize;
- int ch, i, maxwidth, rv, width;
+ int ch, i, rv;
fstype = "ufs";
@@ -184,27 +202,21 @@ main(int argc, char *argv[])
argv += optind;
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
- maxwidth = 0;
- for (i = 0; i < mntsize; i++) {
- width = strlen(mntbuf[i].f_mntfromname);
- if (width > maxwidth)
- maxwidth = width;
- }
+ bzero(&maxwidths, sizeof(maxwidths));
+ for (i = 0; i < mntsize; i++)
+ update_maxwidths(&maxwidths, &mntbuf[i]);
rv = 0;
if (!*argv) {
mntsize = regetmntinfo(&mntbuf, mntsize, vfslist);
if (vfslist != NULL) {
- maxwidth = 0;
- for (i = 0; i < mntsize; i++) {
- width = strlen(mntbuf[i].f_mntfromname);
- if (width > maxwidth)
- maxwidth = width;
- }
+ bzero(&maxwidths, sizeof(maxwidths));
+ for (i = 0; i < mntsize; i++)
+ update_maxwidths(&maxwidths, &mntbuf[i]);
}
for (i = 0; i < mntsize; i++) {
if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0)
- prtstat(&mntbuf[i], maxwidth);
+ prtstat(&mntbuf[i], &maxwidths);
}
exit(rv);
}
@@ -234,13 +246,13 @@ main(int argc, char *argv[])
}
if (mount(fstype, mntpt, MNT_RDONLY,
&mdev) != 0) {
- rv = ufs_df(*argv, maxwidth) || rv;
+ rv = ufs_df(*argv, &maxwidths) || rv;
(void)rmdir(mntpt);
free(mntpath);
continue;
} else if (statfs(mntpt, &statfsbuf) == 0) {
statfsbuf.f_mntonname[0] = '\0';
- prtstat(&statfsbuf, maxwidth);
+ prtstat(&statfsbuf, &maxwidths);
} else {
warn("%s", *argv);
rv = 1;
@@ -261,9 +273,11 @@ main(int argc, char *argv[])
rv = 1;
continue;
}
- if (argc == 1)
- maxwidth = strlen(statfsbuf.f_mntfromname) + 1;
- prtstat(&statfsbuf, maxwidth);
+ if (argc == 1) {
+ bzero(&maxwidths, sizeof(maxwidths));
+ update_maxwidths(&maxwidths, &statfsbuf);
+ }
+ prtstat(&statfsbuf, &maxwidths);
}
return (rv);
}
@@ -372,54 +386,107 @@ prthumanval(double bytes)
* Print out status about a filesystem.
*/
void
-prtstat(struct statfs *sfsp, int maxwidth)
+prtstat(struct statfs *sfsp, struct maxwidths *mwp)
{
static long blocksize;
static int headerlen, timesthrough;
static const char *header;
long used, availblks, inodes;
- if (maxwidth < 11)
- maxwidth = 11;
if (++timesthrough == 1) {
+ mwp->mntfrom = imax(mwp->mntfrom, strlen("Filesystem"));
if (hflag) {
header = " Size";
- headerlen = strlen(header);
- (void)printf("%-*.*s %-s Used Avail Capacity",
- maxwidth, maxwidth, "Filesystem", header);
+ mwp->total = mwp->used = mwp->avail = strlen(header);
} else {
header = getbsize(&headerlen, &blocksize);
- (void)printf("%-*.*s %-s Used Avail Capacity",
- maxwidth, maxwidth, "Filesystem", header);
+ mwp->total = imax(mwp->total, headerlen);
+ }
+ mwp->used = imax(mwp->used, strlen("Used"));
+ mwp->avail = imax(mwp->avail, strlen("Avail"));
+
+ (void)printf("%-*s %-*s %*s %*s Capacity", mwp->mntfrom,
+ "Filesystem", mwp->total, header, mwp->used, "Used",
+ mwp->avail, "Avail");
+ if (iflag) {
+ mwp->iused = imax(mwp->iused, strlen(" iused"));
+ mwp->ifree = imax(mwp->ifree, strlen("ifree"));
+ (void)printf(" %*s %*s %%iused", mwp->iused - 2,
+ "iused", mwp->ifree, "ifree");
}
- if (iflag)
- (void)printf(" iused ifree %%iused");
(void)printf(" Mounted on\n");
}
- (void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
+ (void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname);
used = sfsp->f_blocks - sfsp->f_bfree;
availblks = sfsp->f_bavail + used;
if (hflag) {
prthuman(sfsp, used);
} else {
- (void)printf(" %*ld %8ld %8ld", headerlen,
+ (void)printf(" %*ld %*ld %*ld", mwp->total,
fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
- fsbtoblk(used, sfsp->f_bsize, blocksize),
- fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
+ mwp->used, fsbtoblk(used, sfsp->f_bsize, blocksize),
+ mwp->avail, fsbtoblk(sfsp->f_bavail, sfsp->f_bsize,
+ blocksize));
}
(void)printf(" %5.0f%%",
availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
if (iflag) {
inodes = sfsp->f_files;
used = inodes - sfsp->f_ffree;
- (void)printf(" %7ld %7ld %5.0f%% ", used, sfsp->f_ffree,
- inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
+ (void)printf(" %*ld %*ld %4.0f%% ", mwp->iused, used,
+ mwp->ifree, sfsp->f_ffree, inodes == 0 ? 100.0 :
+ (double)used / (double)inodes * 100.0);
} else
(void)printf(" ");
(void)printf(" %s\n", sfsp->f_mntonname);
}
/*
+ * Update the maximum field-width information in `mwp' based on
+ * the filesystem specified by `sfsp'.
+ */
+void
+update_maxwidths(struct maxwidths *mwp, struct statfs *sfsp)
+{
+ static long blocksize;
+ int dummy;
+
+ if (blocksize == 0)
+ getbsize(&dummy, &blocksize);
+
+ mwp->mntfrom = imax(mwp->mntfrom, strlen(sfsp->f_mntfromname));
+ mwp->total = imax(mwp->total, longwidth(fsbtoblk(sfsp->f_blocks,
+ sfsp->f_bsize, blocksize)));
+ mwp->used = imax(mwp->used, longwidth(fsbtoblk(sfsp->f_blocks -
+ sfsp->f_bfree, sfsp->f_bsize, blocksize)));
+ mwp->avail = imax(mwp->avail, longwidth(fsbtoblk(sfsp->f_bavail,
+ sfsp->f_bsize, blocksize)));
+ mwp->iused = imax(mwp->iused, longwidth(sfsp->f_files -
+ sfsp->f_ffree));
+ mwp->ifree = imax(mwp->ifree, longwidth(sfsp->f_ffree));
+}
+
+/* Return the width in characters of the specified long. */
+int
+longwidth(long val)
+{
+ int len;
+
+ len = 0;
+ /* Negative or zero values require one extra digit. */
+ if (val <= 0) {
+ val = -val;
+ len++;
+ }
+ while (val > 0) {
+ len++;
+ val /= 10;
+ }
+
+ return (len);
+}
+
+/*
* This code constitutes the pre-system call Berkeley df code for extracting
* information from filesystem superblocks.
*/
@@ -433,7 +500,7 @@ union {
int rfd;
int
-ufs_df(char *file, int maxwidth)
+ufs_df(char *file, struct maxwidths *mwp)
{
struct statfs statfsbuf;
struct statfs *sfsp;
@@ -469,7 +536,7 @@ ufs_df(char *file, int maxwidth)
mntpt = "";
memmove(&sfsp->f_mntonname[0], mntpt, (size_t)MNAMELEN);
memmove(&sfsp->f_mntfromname[0], file, (size_t)MNAMELEN);
- prtstat(sfsp, maxwidth);
+ prtstat(sfsp, mwp);
(void)close(rfd);
return (0);
}
OpenPOWER on IntegriCloud