bug-coreutils
[Top][All Lists]
Advanced

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

du improvement?


From: Marcel Ibes
Subject: du improvement?
Date: Sun, 30 Oct 2005 22:34:13 +0100

Hi maintainers,

I always use the "du" utility when I'm cleaning-up my harddrive.
Although this utility has always helped my a lot, it lacked the ability
to show the directory usage as a percentage of the total disk usage. For
my own convenience I've modified the CVS du and added these two options:

  -p, --percentages     print percentages
      --min-perc=PERC   only print sizes over PERC percentage

When the "-p --min-perc=5" options are used, it produces an output like:

Processing
files: 
................................................................................................
24,3%   [####                ]  ./linux-headers-2.6.12-8/include
28,2%   [#####               ]  ./linux-headers-2.6.12-8
6,5%
[#                   ]  ./linux-headers-2.6.12-8-686/include/config
6,6%    [#                   ]  ./linux-headers-2.6.12-8-686/include
8,1%    [#                   ]  ./linux-headers-2.6.12-8-686
24,3%   [####                ]  ./linux-headers-2.6.12-9/include
28,3%   [#####               ]  ./linux-headers-2.6.12-9
6,5%
[#                   ]  ./linux-headers-2.6.12-9-686/include/config
6,6%    [#                   ]  ./linux-headers-2.6.12-9-686/include
8,1%    [#                   ]  ./linux-headers-2.6.12-9-686
100,0%  [####################]  .


Maybe you find this a nice addition to the du capabilities.

Please let me know what you think of this functionality and if you will
evaluate this code?


Kind regards,

Marcel Ibes
e-mail: address@hidden



PATCH CODE (diff -u):

--- coreutils/src/du.c  2005-10-15 12:14:13.000000000 +0200
+++ ./coreutils-mi/src/du.c     2005-10-30 22:11:36.159653832 +0100
@@ -52,7 +52,7 @@
 #define PROGRAM_NAME "du"
 
 #define AUTHORS \
-  "Torbjorn Granlund", "David MacKenzie, Paul Eggert", "Jim Meyering"
+  "Torbjorn Granlund", "David MacKenzie, Paul Eggert", "Jim Meyering",
"Marcel Ibes"
 
 #if DU_DEBUG
 # define FTS_CROSS_CHECK(Fts) fts_cross_check (Fts)
@@ -74,6 +74,27 @@
   dev_t st_dev;
 };
 
+/* MI: Initialy the perc_entries will hold up to 1024 entries */
+#define INIT_PERC_SIZE 1024
+
+/* MI: The total amount of entries in the perc_entries array */
+static int total_perc_entries = 0;
+static int max_perc_entries = INIT_PERC_SIZE;
+
+/* MI: If nonzero, print percentages.  */
+static int print_perc = 0;
+static int min_perc = 0;
+
+/* MI: structure to hold the file and its size */
+struct perc_entry
+{
+       char *file_name;
+       uintmax_t size;
+};
+
+/* MI: Dynamic array that can hold all the files */
+struct perc_entry *perc_entries;
+
 /* A set of dev/ino pairs.  */
 static Hash_table *htab;
 
@@ -206,7 +227,8 @@
   MEGABYTES_LONG_OPTION,
 
   TIME_OPTION,
-  TIME_STYLE_OPTION
+  TIME_STYLE_OPTION,
+  MIN_PERC_OPTION
 };
 
 static struct option const long_options[] =
@@ -228,6 +250,8 @@
   {"null", no_argument, NULL, '0'},
   {"megabytes", no_argument, NULL, MEGABYTES_LONG_OPTION},
   {"no-dereference", no_argument, NULL, 'P'},
+  {"percentages", no_argument, NULL, 'p'},
+  {"min-perc", required_argument, 0, MIN_PERC_OPTION},
   {"one-file-system", no_argument, NULL, 'x'},
   {"separate-dirs", no_argument, NULL, 'S'},
   {"summarize", no_argument, NULL, 's'},
@@ -313,6 +337,8 @@
       fputs (_("\
   -L, --dereference     dereference all symbolic links\n\
   -P, --no-dereference  don't follow any symbolic links (this is the
default)\n\
+  -p, --percentages     print percentages\n\
+      --min-perc=PERC  only print sizes over PERC percentage\n\
   -0, --null            end each output line with 0 byte rather than
newline\n\
   -S, --separate-dirs   do not include size of subdirectories\n\
   -s, --summarize       display only a total for each argument\n\
@@ -346,6 +372,109 @@
   exit (status);
 }
 
+/* MI: Add an entry to the perc_entries array */
+static void add_perc_entry(FTSENT *ent, uintmax_t filesize)
+{
+       if (total_perc_entries == max_perc_entries)
+       {
+               // Need to allocate more memory
+               max_perc_entries *= 2;
+               
+           // fputc ('R', stdout);
+        // fflush (stdout);
+               
+               perc_entries = xrealloc(perc_entries, 
+                               max_perc_entries * sizeof(struct perc_entry));
+                                       
+               if (perc_entries == NULL)
+               {
+                       // Oops, not enough memory
+               error (0, 0, _("error: not enough available memory."));
+                       exit(EXIT_FAILURE);
+               }
+       }
+
+       struct perc_entry *p;
+               
+       p = perc_entries;
+       p += total_perc_entries;
+
+       p->file_name = xcalloc(1, ent->fts_pathlen + 1);
+       memcpy(p->file_name, ent->fts_path, ent->fts_pathlen);
+       
+       p->size = filesize;
+       total_perc_entries++;
+}
+
+/* MI: Create the percentage progress bar */
+char* perc_bar(double perc)
+{
+       static char ret_val[23];
+       int hashes;
+
+       sprintf(ret_val, "[                    ]\0");
+       
+       if (perc > 0)
+       {
+               hashes = (int) (perc / 5);
+       }
+       else
+       {
+               hashes = 0;
+       }
+       
+       hashes += 1;
+       
+       int i;
+       
+       for (i = 1; i < hashes; i++)
+       {
+               ret_val[i] = '#';
+       }
+
+       return (char*) &ret_val;        
+}
+
+/* MI: Process and write the procentages to the screen */
+static void process_perc(uintmax_t total_size)
+{
+       int i;
+       double perc;
+       
+       struct perc_entry *p;
+       
+       printf("\n\n");
+       
+       // printf("\n\nFound a total of %d files\n", total_perc_entries);
+       // printf("With a total size of %d\n\n", total_size);
+       
+       p = perc_entries;
+       
+       for (i = 0; i < total_perc_entries; i++)
+       {
+               if (total_size > 0)
+               {
+                       // We don't want a divide by zero!
+                       perc = (( (double) p->size / (double) total_size) * 
100);
+               }
+               else
+               {
+                       perc = 0;
+               }
+
+               if (perc >= min_perc)
+               {                       
+                       printf("%0.1f%\t%s\t%s\n", perc, perc_bar(perc), 
p->file_name);
+               }
+
+               free(p->file_name);
+               
+               p++;
+       }
+       
+       free(perc_entries);
+}
+
 static size_t
 entry_hash (void const *x, size_t table_size)
 {
@@ -618,8 +747,20 @@
 
   if ((IS_DIR_TYPE (ent->fts_info) && level <= max_depth)
       || ((opt_all && level <= max_depth) || level == 0))
-    print_size (&dui_to_print, file);
-
+  {
+         if (print_perc)
+         {
+                 /* MI: Add file to perc_entries */
+                 fputc ('.', stdout);
+          fflush (stdout);
+                 add_perc_entry(ent, dui_to_print.size);
+         }
+         else
+         {
+            print_size (&dui_to_print, file);
+         }
+  }
+  
   return ok;
 }
 
@@ -636,6 +777,9 @@
   if (*files)
     {
       FTS *fts = xfts_open (files, bit_flags, NULL);
+         
+      if (print_perc)
+         printf("%s", _("Processing files: "));
 
       while (1)
        {
@@ -663,6 +807,10 @@
       fts_close (fts);
     }
 
+  /* MI: Show percentages */
+  if (print_perc)
+         process_perc(tot_dui.size);
+
   if (print_grand_total)
     print_size (&tot_dui, _("total"));
 
@@ -695,6 +843,17 @@
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
+  /* MI: Allocate some space to hold the perc_entries */
+  perc_entries = (struct perc_entry*) xmalloc(max_perc_entries *
sizeof(struct perc_entry));
+         
+  if (perc_entries == NULL)
+  {
+         // Oops, no memory to allocate array
+      error (0, 0,
+            _("error: not enough available memory."));
+         exit(EXIT_FAILURE);
+  }
+  
   atexit (close_stdout);
 
   exclude = new_exclude ();
@@ -702,7 +861,7 @@
   human_output_opts = human_options (getenv ("DU_BLOCK_SIZE"), false,
                                     &output_block_size);
 
-  while ((c = getopt_long (argc, argv, DEBUG_OPT "0abchHklmsxB:DLPSX:",
+  while ((c = getopt_long (argc, argv, DEBUG_OPT
"0abchHklmsxB:DLPpSX:",
                           long_options, NULL)) != -1)
     {
       switch (c)
@@ -814,6 +973,14 @@
          bit_flags = FTS_PHYSICAL;
          break;
 
+       case 'p': /* --percentage */
+      print_perc = 1;
+         break;
+       
+       case MIN_PERC_OPTION:
+         min_perc = atoi(optarg);
+         break;
+
        case 'S':
          opt_separate_dirs = true;
          break;







reply via email to

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