bug-coreutils
[Top][All Lists]
Advanced

[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);
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]