bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] df: add `--total' option


From: Steven Schubiger
Subject: [PATCH] df: add `--total' option
Date: Thu, 10 Jan 2008 23:17:41 +0100
User-agent: Mutt/1.5.13 (2006-08-11)

Given that the attached patch works, except that the SIZE argument 
specified to -B/--block-size parameter doesn't currently make it 
into the totals, I'd like to hear some opinions how you would make it
happen (I have some ideas, but I'd certainly prefer to have some peer-
driven effort).

Steven Schubiger

diff --git a/src/df.c b/src/df.c
index f0fdcd7..e010f87 100644
--- a/src/df.c
+++ b/src/df.c
@@ -46,6 +46,20 @@ char *program_name;
 /* If true, show inode information. */
 static bool inode_format;
 
+/* 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;
+
 /* If true, show even file systems with zero size or
    uninteresting types. */
 static bool show_all_fs;
@@ -122,6 +136,7 @@ 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 +241,17 @@ 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 +291,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];
@@ -281,6 +307,10 @@ show_dev (char const *disk, char const *mount_point,
   uintmax_t used;
   bool negate_used;
   double pct = -1;
+  char *buf_readable[3];
+
+  if (show_summary)
+    goto output_numbers;
 
   if (me_remote & show_local_fs)
     return;
@@ -326,18 +356,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 +420,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;
@@ -384,15 +430,33 @@ show_dev (char const *disk, char const *mount_point,
       used = total - available_to_root;
       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));
+  
+  output_numbers:
+  if (!show_summary)
+    {
+      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);
+      printf (" %*s %*s %*s ",
+         width + col1_adjustment, buf_readable[0],
+         width, buf_readable[1],
+         width, buf_readable[2]);
+      summary.blocks += atol (buf_readable[0]);
+      summary.used += atol (buf_readable[1]);
+      summary.avail += atol (buf_readable[2]);
+      summary.width = width;
+      summary.adjustment = col1_adjustment;
+    }
+  else
+    {
+      printf ("%*s %*s%lu %*s%lu %*s%lu ",
+         summary.spacing, "",
+         (summary.width + summary.adjustment) - integer_length 
(summary.blocks), "", summary.blocks,
+         summary.width - integer_length (summary.used), "", summary.used,
+         summary.width - integer_length (summary.avail), "", summary.avail);
+      putchar ('\n');
+      return;
+    }
 
   if (used == UINTMAX_MAX || available == UINTMAX_MAX)
     ;
@@ -552,7 +616,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 +720,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 +731,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 +760,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 +815,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);
@@ -791,6 +862,7 @@ main (int argc, char **argv)
   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 +872,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;
@@ -818,6 +890,9 @@ main (int argc, char **argv)
              xstrtol_fatal (e, oi, c, long_options, optarg);
          }
          break;
+        case 'c':
+          summarize_total = true;
+          break;
        case 'i':
          inode_format = true;
          break;
@@ -964,5 +1039,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]