[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] df: add `--total' option
From: |
Steven Schubiger |
Subject: |
Re: [PATCH] df: add `--total' option |
Date: |
Fri, 11 Jan 2008 14:44:53 +0100 |
User-agent: |
Mutt/1.5.13 (2006-08-11) |
Jim Meyering <address@hidden> wrote:
> Thanks for the patch.
FTR (for the record), a second version which does some "magic"
to obtain the block-size argument and append it to the output.
I don't think, it'll be of much use now, but archiving doesn't hurt.
Steven Schubiger
diff --git a/src/df.c b/src/df.c
index f0fdcd7..c9a84a2 100644
--- a/src/df.c
+++ b/src/df.c
@@ -118,10 +118,34 @@ enum
SYNC_OPTION
};
+/* If true, output disk "usage" summary. */
+static bool summarize_total;
+
+/* The summary container. */
+struct summary_total
+{
+ unsigned long blocks;
+ unsigned long used;
+ unsigned long avail;
+ int spacing;
+ int width;
+ int adjustment;
+} summary;
+
+/* The buffer containing the readable disk-usage stats. */
+char *buf_readable[3];
+
+/* If true, block-size argument provided. */
+static bool block_size;
+
+/* The block-size description. */
+char *suffix = NULL;
+
static struct option const long_options[] =
{
{"all", no_argument, NULL, 'a'},
{"block-size", required_argument, NULL, 'B'},
+ {"total", no_argument, NULL, 'c' },
{"inodes", no_argument, NULL, 'i'},
{"human-readable", no_argument, NULL, 'h'},
{"si", no_argument, NULL, 'H'},
@@ -226,6 +250,15 @@ excluded_fstype (const char *fstype)
return false;
}
+static int
+integer_length (unsigned long num)
+{
+ int length = 1;
+ while ((num /= 10) >= 1)
+ length++;
+ return length;
+}
+
/* Like human_readable (N, BUF, human_output_opts, INPUT_UNITS, OUTPUT_UNITS),
except:
@@ -265,7 +298,7 @@ df_readable (bool negative, uintmax_t n, char *buf,
static void
show_dev (char const *disk, char const *mount_point,
char const *stat_file, char const *fstype,
- bool me_dummy, bool me_remote)
+ bool me_dummy, bool me_remote, bool show_summary)
{
struct fs_usage fsu;
char buf[3][LONGEST_HUMAN_READABLE + 2];
@@ -282,6 +315,9 @@ show_dev (char const *disk, char const *mount_point,
bool negate_used;
double pct = -1;
+ if (show_summary)
+ goto output_stats;
+
if (me_remote & show_local_fs)
return;
@@ -326,18 +362,33 @@ show_dev (char const *disk, char const *mount_point,
size_t disk_name_len = strlen (disk);
size_t fstype_len = strlen (fstype);
if (disk_name_len + fstype_len < 18)
- printf ("%s%*s ", disk, 18 - (int) disk_name_len, fstype);
+ {
+ printf ("%s%*s ", disk, 18 - (int) disk_name_len, fstype);
+ summary.spacing = disk_name_len + (18 - (int) disk_name_len + 2);
+ }
else if (!posix_format)
- printf ("%s\n%18s ", disk, fstype);
+ {
+ printf ("%s\n%18s ", disk, fstype);
+ summary.spacing = 20;
+ }
else
- printf ("%s %s", disk, fstype);
+ {
+ printf ("%s %s", disk, fstype);
+ summary.spacing = disk_name_len + 1 + fstype_len;
+ }
}
else
{
if (strlen (disk) > 20 && !posix_format)
- printf ("%s\n%20s", disk, "");
+ {
+ printf ("%s\n%20s", disk, "");
+ summary.spacing = 20;
+ }
else
- printf ("%-20s", disk);
+ {
+ printf ("%-20s", disk);
+ summary.spacing = 20;
+ }
}
if (inode_format)
@@ -375,6 +426,7 @@ show_dev (char const *disk, char const *mount_point,
negate_available = (fsu.fsu_bavail_top_bit_set
& (available != UINTMAX_MAX));
available_to_root = fsu.fsu_bfree;
+
}
used = UINTMAX_MAX;
@@ -385,14 +437,50 @@ show_dev (char const *disk, char const *mount_point,
negate_used = (total < available_to_root);
}
- printf (" %*s %*s %*s ",
- width + col1_adjustment,
- df_readable (false, total,
- buf[0], input_units, output_units),
- width, df_readable (negate_used, used,
- buf[1], input_units, output_units),
- width, df_readable (negate_available, available,
- buf[2], input_units, output_units));
+ buf_readable[0] = (char *) df_readable (false, total, buf[0], input_units,
output_units);
+ buf_readable[1] = (char *) df_readable (negate_used, used, buf[1],
input_units, output_units);
+ buf_readable[2] = (char *) df_readable (negate_available, available, buf[2],
input_units, output_units);
+
+ output_stats:
+ if (!show_summary)
+ {
+ printf (" %*s %*s %*s ",
+ width + col1_adjustment, buf_readable[0],
+ width, buf_readable[1],
+ width, buf_readable[2]);
+ if (summarize_total)
+ {
+ summary.blocks += (unsigned long) atol (buf_readable[0]);
+ summary.used += (unsigned long) atol (buf_readable[1]);
+ summary.avail += (unsigned long) atol (buf_readable[2]);
+ summary.width = width;
+ summary.adjustment = col1_adjustment;
+ }
+ if (block_size)
+ {
+ if (suffix == NULL)
+ {
+ suffix = buf_readable[0];
+ while (isdigit (*suffix++));
+ suffix--;
+ }
+ }
+ else
+ {
+ if (suffix == NULL)
+ suffix = "";
+ }
+ }
+ else
+ {
+ printf ("%*s %*s%lu%s %*s%lu%s %*s%lu%s ",
+ summary.spacing, "",
+ (summary.width + summary.adjustment) - integer_length
(summary.blocks) - strlen (suffix), "", summary.blocks, suffix,
+ summary.width - integer_length (summary.used) - strlen (suffix), "",
summary.used, suffix,
+ summary.width - integer_length (summary.avail) - strlen (suffix), "",
summary.avail, suffix);
+ putchar ('\n');
+ return;
+ }
if (used == UINTMAX_MAX || available == UINTMAX_MAX)
;
@@ -552,7 +640,7 @@ show_disk (char const *disk)
{
show_dev (best_match->me_devname, best_match->me_mountdir, NULL,
best_match->me_type, best_match->me_dummy,
- best_match->me_remote);
+ best_match->me_remote, false);
return true;
}
@@ -656,7 +744,7 @@ show_point (const char *point, const struct stat *statp)
if (best_match)
show_dev (best_match->me_devname, best_match->me_mountdir, point,
- best_match->me_type, best_match->me_dummy, best_match->me_remote);
+ best_match->me_type, best_match->me_dummy, best_match->me_remote,
false);
else
{
/* We couldn't find the mount entry corresponding to POINT. Go ahead and
@@ -667,7 +755,7 @@ show_point (const char *point, const struct stat *statp)
char *mp = find_mount_point (point, statp);
if (mp)
{
- show_dev (NULL, mp, NULL, NULL, false, false);
+ show_dev (NULL, mp, NULL, NULL, false, false, false);
free (mp);
}
}
@@ -696,7 +784,13 @@ show_all_entries (void)
for (me = mount_list; me; me = me->me_next)
show_dev (me->me_devname, me->me_mountdir, NULL, me->me_type,
- me->me_dummy, me->me_remote);
+ me->me_dummy, me->me_remote, false);
+}
+
+static void
+show_summary (void)
+{
+ show_dev (NULL, NULL, NULL, NULL, NULL, NULL, true);
}
/* Add FSTYPE to the list of file system types to display. */
@@ -745,6 +839,7 @@ Mandatory arguments to long options are mandatory for short
options too.\n\
fputs (_("\
-a, --all include dummy file systems\n\
-B, --block-size=SIZE use SIZE-byte blocks\n\
+ -c, --total summarize disk usage\n\
-h, --human-readable print sizes in human readable format (e.g., 1K 234M
2G)\n\
-H, --si likewise, but use powers of 1000 not 1024\n\
"), stdout);
@@ -786,11 +881,13 @@ main (int argc, char **argv)
atexit (close_stdout);
+ block_size = false;
fs_select_list = NULL;
fs_exclude_list = NULL;
inode_format = false;
show_all_fs = false;
show_listed_fs = false;
+ summarize_total = false;
human_output_opts = -1;
print_type = false;
file_systems_processed = false;
@@ -800,7 +897,7 @@ main (int argc, char **argv)
for (;;)
{
int oi = -1;
- int c = getopt_long (argc, argv, "aB:iF:hHklmPTt:vx:", long_options,
+ int c = getopt_long (argc, argv, "aB:ciF:hHklmPTt:vx:", long_options,
&oi);
if (c == -1)
break;
@@ -817,7 +914,11 @@ main (int argc, char **argv)
if (e != LONGINT_OK)
xstrtol_fatal (e, oi, c, long_options, optarg);
}
+ block_size = true;
break;
+ case 'c':
+ summarize_total = true;
+ break;
case 'i':
inode_format = true;
break;
@@ -964,5 +1065,8 @@ main (int argc, char **argv)
if (! file_systems_processed)
error (EXIT_FAILURE, 0, _("no file systems processed"));
+ if (summarize_total)
+ show_summary ();
+
exit (exit_status);
}