On Wed, 30 Jul 2003 13:37, Austin wrote:
> Because not enough people are willing to put in enough time to write
> drivers and easy-to-use software for free.  That's why.

Hear! Hear!

Speaking of which, yesterday I found a client who needed enhancements to 
not one but two system tools, so I got to do some actual paid 
programming again. The attached (3.1kB and list manager permitting) 
patch to dd gives it three kinds of progress reporting (count, 
percentage, hash-bar), something I've been wanting for ages.

I threw it at bug-fileutils as well, but they may or may not include it 
and I found it very helpful for making decisions when big slabs of data 
were involved so you might too. The patch was originally against 
fileutils-4.0.36 (from RedHat 7.1, in fact) which Mandrake packages in 
coreutils but dd doesn't change much, so it applied nicely to 4.5.7 on 
my 9.1 system, the diff of which is attached.

The other tool is writevt, which I patched to allow escaped sequences in 
the text it forces into a VT, but I haven't tested that completely yet.

Cheers; Leon
*** dd.c.orig	2003-07-31 08:04:34.000000000 +0800
--- dd.c	2003-07-31 08:07:01.000000000 +0800
***************
*** 97,102 ****
--- 97,107 ----
  /* The number of bytes in which atomic writes are done. */
  static size_t output_blocksize = 0;
  
+ /* Keeping track of verbosity: time last updated, mode, target blocks */
+ static time_t verbositime = 0;
+ static char *verbosity = NULL;
+ static unsigned long blocks = 0;
+ 
  /* Conversion buffer size, in bytes.  0 prevents conversions. */
  static size_t conversion_blocksize = 0;
  
***************
*** 301,306 ****
--- 306,312 ----
    of=FILE         write to FILE instead of stdout\n\
    seek=BLOCKS     skip BLOCKS obs-sized blocks at start of output\n\
    skip=BLOCKS     skip BLOCKS ibs-sized blocks at start of input\n\
+   progress=type   report progress (none, count, %%/percentage, #/hashes)\n\
  "), stdout);
        fputs (HELP_OPTION_DESCRIPTION, stdout);
        fputs (VERSION_OPTION_DESCRIPTION, stdout);
***************
*** 359,364 ****
--- 365,372 ----
  print_stats (void)
  {
    char buf[2][INT_BUFSIZE_BOUND (uintmax_t)];
+   if (verbosity != NULL && * verbosity != 'n')
+     fprintf (stderr, "\r%63s\r", "");
    fprintf (stderr, _("%s+%s records in\n"),
  	   umaxtostr (r_full, buf[0]), umaxtostr (r_partial, buf[1]));
    fprintf (stderr, _("%s+%s records out\n"),
***************
*** 442,452 ****
--- 450,474 ----
  open_fd (int desired_fd, char const *filename, int options, mode_t mode)
  {
    int fd;
+   struct stat stats;
+ 
    close (desired_fd);
    fd = open (filename, options, mode);
    if (fd < 0)
      return -1;
  
+   if ((options & O_RDWR) == O_RDONLY)
+     {
+       fstat (fd, &stats);
+       if (stats.st_size == 0)
+ 	if (max_records == -1)
+ 	  blocks = 0;
+ 	else
+ 	  blocks = max_records;
+       else
+ 	blocks = stats.st_size / input_blocksize - skip_records;
+     }
+ 
    if (fd != desired_fd)
      {
        if (dup2 (fd, desired_fd) != desired_fd)
***************
*** 474,479 ****
--- 496,529 ----
    else
      w_full++;
    oc = 0;
+ 
+   if (verbosity != NULL && * verbosity != 'n')
+     {
+       time_t now;
+       now = time(NULL);
+       if (now > verbositime || w_full == blocks)
+ 	{
+ 	switch (blocks ? * verbosity : 'c')
+ 	  {
+ 	  case '%':	/* percentage */
+ 	  case 'p':
+ 	    fprintf (stderr, "\r %ld%% ", 100L * w_full / blocks);
+ 	    break;
+ 	  case '#':
+ 	  case 'h':
+ 	    fprintf (stderr, "\r [%s", 
+ 	      "############################################################" +
+ 	      59 - (int) (60L * w_full / blocks));
+ 	    break;
+ 	  default:
+ 	    if (blocks)
+ 	      fprintf (stderr, "\r %ld+%ld/%ld ", w_full, w_partial, blocks);
+ 	    else
+ 	      fprintf (stderr, "\r %ld+%ld ", w_full, w_partial);
+ 	  }
+ 	}
+       verbositime = now;
+     }
  }
  
  /* Interpret one "conv=..." option.
***************
*** 565,570 ****
--- 615,626 ----
  	output_file = val;
        else if (STREQ (name, "conv"))
  	parse_conversion (val);
+       else if (STREQ (name, "progress"))
+ 	{
+ 	  verbosity = val;
+ 	  if (* verbosity == 'h' || * verbosity == '#')
+ 	    fprintf (stderr, "\r [%60s] ", "");
+ 	}
        else
  	{
  	  int invalid = 0;

Reply via email to