Additions to du, take 2

Kim Ahlström <[email protected]>
Newsgroups gmane.comp.gnu.fileutils.bugs
Message-ID <[email protected]>
Hi, i sent you some additions to du.c a few days ago.

I found an off-by-one malloc:ing error and one place were " were used 
instead of ' and have fixed this.

I have attached the new diff-file here. This diff should be applied to 
the 4.1.11 version availabe on your aplha-release server and not to a 
version patched with the earlier diff-file I sent you.

Here is the ChangeLog entry for the changes:
2002-09-22  Kim Ahlström  <[email protected]>

	* src/du.c: Changed " to ' for -p flag in long name initialization.
	(print_size): Off-by-one error in malloc:ing path fixed.

Best Regards
Kim Ahlstrom
[email protected]
http://kim.animanga.nu/ (Swedish only)
du.4111.c.diff (application/octet-stream, 6.1 KB)
--- du.4111.orig.c	Wed Jul 10 10:09:05 2002
+++ du.4111.c	Sun Sep 22 01:55:00 2002
@@ -99,6 +99,31 @@
 int stat ();
 int lstat ();
 
+/* Linked list structure to hold filepaths and n_blocks,
+   to be used with the -p flag for percentage.  */
+
+struct list_def
+{
+  char * path;				/* Filepath (dynamically allocated) */
+  uintmax_t size;			/* Number of n_blocks ( print_size()'s first argument ) */
+  struct list_def *next;	/* Next node */
+};
+
+/* Nodes in the linked list of filepaths and n_blocks.  */
+struct list_def *first_node, *last_node, *now_node = NULL;
+
+/* If nonzero, suppress printing.  */
+static int suppress = 0;
+
+/* If nonzero, calculate percentages (-p).  */
+static int display_percentage = 0;
+
+/* If nonzero, one of the -kmbB flags has been provided.  */
+static int display_byte_kilo_mega = 0;
+
+/* Holds the output_block_size for human numbers (-h or -H).  */
+static int h_block_size = 0;
+
 /* Name under which this program was invoked.  */
 char *program_name;
 
@@ -168,6 +193,7 @@
   {"kilobytes", no_argument, NULL, 'k'}, /* long form is obsolescent */
   {"max-depth", required_argument, NULL, MAX_DEPTH_OPTION},
   {"megabytes", no_argument, NULL, 'm'}, /* obsolescent */
+  {"percent", no_argument, NULL, 'p'},
   {"one-file-system", no_argument, NULL, 'x'},
   {"separate-dirs", no_argument, NULL, 'S'},
   {"summarize", no_argument, NULL, 's'},
@@ -353,20 +379,94 @@
     }
 }
 
-/* Print N_BLOCKS followed by STRING on a line.  NBLOCKS is the number of
-   ST_NBLOCKSIZE-byte blocks; convert it to OUTPUT_BLOCK_SIZE units before
-   printing.  If OUTPUT_BLOCK_SIZE is negative, use a human readable
-   notation instead.  */
+/* If -p flag was provided we start by accumulating file data and not printing.
+   Printing will be requested by the du_files function after accumulation.
+   Print N_BLOCKS[\thuman_readable\tpercentage]\tSTRING on a line.
+   N_BLOCKS is the number of ST_NBLOCKSIZE-byte blocks; convert it to
+   OUTPUT_BLOCK_SIZE units before printing.  If OUTPUT_BLOCK_SIZE is negative,
+   use a human readable notation instead.  */
 
 static void
 print_size (uintmax_t n_blocks, const char *string)
 {
   char buf[LONGEST_HUMAN_READABLE + 1];
-  printf ("%s\t%s\n",
-	  human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
-				  output_block_size, human_ceiling),
-	  string);
-  fflush (stdout);
+  double prcnt; /* Temporary variable to hold the percent.  */
+  
+  if (suppress != 0)
+    {
+      /* The p flag is on and we are accumulating file data.
+         Thus we don't want to print.  */
+      
+      now_node = malloc (sizeof (struct list_def));
+      if (now_node == NULL)
+        {
+          fprintf (stderr, "%s: %s", program_name, strerror (errno));
+          exit (1);
+        }
+    
+      if (first_node == NULL)
+        {
+          first_node = now_node;
+          now_node->next = NULL;
+        }
+      else
+        {
+          last_node->next = now_node;
+          now_node->next = NULL;
+        }
+    
+      last_node = now_node;
+    
+      now_node->path = malloc (strlen (string) + 1);
+      if (now_node->path == NULL)
+        {
+          fprintf (stderr, "%s: %s", program_name, strerror (errno));
+          exit (1);
+        }
+      
+      strncpy (now_node->path, string, strlen (string) + 1);
+      now_node->size = n_blocks;
+    }
+  else
+    {
+      /* Print.  */
+      if (display_byte_kilo_mega != 0)
+        {
+          /* Bytes, Kilobytes, Megabytes (-kmbB).  */
+          printf ("%s\t",
+            human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
+	  				output_block_size, human_ceiling));
+	    }
+	  if (h_block_size != 0)
+	    {
+	      /* Human form (-hH).  */
+          printf ("%s\t",
+	        human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
+	    			h_block_size, human_ceiling));
+        }
+      if (display_percentage != 0)
+        {
+          /* Percentage (-p).  */
+          prcnt = ( (double)n_blocks / (double)tot_size) * 100;
+          printf ("%.2f%%\t", prcnt);
+        }
+        
+      if (display_byte_kilo_mega == 0 && h_block_size == 0 && display_percentage == 0)
+        {
+          /* No output flags were provided.  */
+          printf ("%s\t%s\n",
+	        human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
+	      			output_block_size, human_ceiling),
+	        string);
+        }
+      else
+        {
+          /* Filepath.  */
+          printf ("%s\n", string);
+        }
+      
+      fflush (stdout);
+    }
 }
 
 /* Restore the previous working directory or exit.
@@ -553,6 +653,17 @@
       count_entry (arg, 1, 0, 0);
     }
 
+  /* If the -p flag was provided,
+     stop suppressing printing and print the accumulated data.  */
+  if (display_percentage != 0)
+    {
+      suppress = 0;
+      for (now_node = first_node; now_node != NULL; now_node = now_node->next)
+        {
+          print_size (now_node->size, now_node->path);
+        }
+    }
+
   if (print_totals)
     print_size (tot_size, _("total"));
 }
@@ -582,7 +693,7 @@
 
   human_block_size (getenv ("DU_BLOCK_SIZE"), 0, &output_block_size);
 
-  while ((c = getopt_long (argc, argv, "abchHklmsxB:DLSX:", long_options, NULL))
+  while ((c = getopt_long (argc, argv, "abchHklmpsxB:DLSX:", long_options, NULL))
 	 != -1)
     {
       long int tmp_long;
@@ -597,22 +708,33 @@
 
 	case 'b':
 	  output_block_size = 1;
+	  display_byte_kilo_mega = 1;
 	  break;
 
 	case 'c':
 	  print_totals = 1;
 	  break;
 
+	case 'p':
+	  suppress = 1;
+	  display_percentage = 1;
+	  break;
+
 	case 'h':
-	  output_block_size = -1024;
+	  h_block_size = -1024;
+	  if(!display_byte_kilo_mega)
+	    output_block_size = -1024;
 	  break;
 
 	case 'H':
-	  output_block_size = -1000;
+	  h_block_size = -1000;
+	  if(!display_byte_kilo_mega)
+	    output_block_size = -1000;
 	  break;
 
 	case 'k':
 	  output_block_size = 1024;
+	  display_byte_kilo_mega = 1;
 	  break;
 
 	case MAX_DEPTH_OPTION:		/* --max-depth=N */
@@ -626,6 +748,7 @@
 
 	case 'm': /* obsolescent */
 	  output_block_size = 1024 * 1024;
+	  display_byte_kilo_mega = 1;
 	  break;
 
 	case 'l':
@@ -642,6 +765,7 @@
 
 	case 'B':
 	  human_block_size (optarg, 1, &output_block_size);
+	  display_byte_kilo_mega = 1;
 	  break;
 
 	case 'D':
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.