Re: movemail: needs more verbosity

Sergey Poznyakoff <[email protected]>
Newsgroups gmane.comp.gnu.mailutils.bugs
Organization GNU.org.ua
Message-ID <[email protected]>
Jean Louis <[email protected]> ha escrit:

> Yes, a progress meter would be nice.

Please try the attached patch.  It implements the -m (--progress-meter)
option for movemail, which does what you proposed.  The patch is against
the recent stable version.  Let me know if it works for you.

Regards,
Sergey

_______________________________________________
Bug-mailutils mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-mailutils
progress_meter.diff (text/x-diff, 7.9 KB)
diff --git a/include/mailutils/iterator.h b/include/mailutils/iterator.h
index 35ccf6c..52f8f24 100644
--- a/include/mailutils/iterator.h
+++ b/include/mailutils/iterator.h
@@ -35,7 +35,8 @@ enum mu_itrctl_req
     mu_itrctl_insert,        /* Insert new element in the current position */
     mu_itrctl_insert_list,   /* Insert a list of elements */
     mu_itrctl_qry_direction, /* Query iteration direction */
-    mu_itrctl_set_direction  /* Set iteration direction */
+    mu_itrctl_set_direction, /* Set iteration direction */
+    mu_itrctl_count          /* Get number of elements */
   };
 
 extern int mu_iterator_create   (mu_iterator_t *, void *);
diff --git a/libmailutils/base/assoc.c b/libmailutils/base/assoc.c
index 5b27afd..a1ded87 100644
--- a/libmailutils/base/assoc.c
+++ b/libmailutils/base/assoc.c
@@ -514,6 +514,11 @@ itrctl (void *owner, enum mu_itrctl_req req, void *arg)
       else
 	itr->backwards = !!*(int*)arg;
       break;
+
+    case mu_itrctl_count:
+      if (!arg)
+	return EINVAL;
+      return mu_assoc_count (assoc, arg);
       
     default:
       return ENOSYS;
diff --git a/libmailutils/base/iterator.c b/libmailutils/base/iterator.c
index a39ce9c..b4f4967 100644
--- a/libmailutils/base/iterator.c
+++ b/libmailutils/base/iterator.c
@@ -304,3 +304,9 @@ mu_iterator_ctl (mu_iterator_t iterator, enum mu_itrctl_req req, void *arg)
     return ENOSYS;
   return iterator->itrctl (iterator->owner, req, arg);
 }
+
+int
+mu_iterator_count (mu_iterator_t iterator, size_t *size)
+{
+  return mu_iterator_ctl (iterator, mu_itrctl_count, size); 
+}
diff --git a/libmailutils/base/opool.c b/libmailutils/base/opool.c
index a516d98..d8a4d15 100644
--- a/libmailutils/base/opool.c
+++ b/libmailutils/base/opool.c
@@ -513,6 +513,31 @@ opitr_data_dup (void **ptr, void *owner)
   return 0;
 }
 
+static int
+opitr_itrctl (void *owner, enum mu_itrctl_req req, void *arg)
+{
+  struct opool_iterator *itr = owner;
+  switch (req)
+    {
+    case mu_itrctl_count:
+      if (!arg)
+	return EINVAL;
+      else
+	{
+	  size_t n = 0;
+	  union mu_opool_bucket *p;
+	  for (p = itr->opool->bkt_head; p; p = p->hdr.next)
+	    n++;
+	  *(size_t*)arg = n;
+	}
+      break;
+
+    default:
+      return ENOSYS;
+    }
+  return 0;
+}
+	  
 int
 mu_opool_get_iterator (mu_opool_t opool, mu_iterator_t *piterator)
 {
@@ -543,7 +568,8 @@ mu_opool_get_iterator (mu_opool_t opool, mu_iterator_t *piterator)
   mu_iterator_set_delitem (iterator, opitr_delitem);
   mu_iterator_set_destroy (iterator, opitr_destroy);
   mu_iterator_set_dup (iterator, opitr_data_dup);
-
+  mu_iterator_set_itrctl (iterator, opitr_itrctl);
+  
   opool->itr_count++;
 
   *piterator = iterator;
diff --git a/libmailutils/diag/debug.c b/libmailutils/diag/debug.c
index b69913c..57dfce0 100644
--- a/libmailutils/diag/debug.c
+++ b/libmailutils/diag/debug.c
@@ -632,6 +632,12 @@ list_itrctl (void *owner, enum mu_itrctl_req req, void *arg)
 	itr->flags |= ITR_BACKWARDS;
       break;
 
+    case mu_itrctl_count:
+      if (!arg)
+	return EINVAL;
+      *(size_t*)arg = catcnt;
+      break;
+      
     default:
       return ENOSYS;
     }
diff --git a/libmailutils/list/iterator.c b/libmailutils/list/iterator.c
index d22638a..ec37577 100644
--- a/libmailutils/list/iterator.c
+++ b/libmailutils/list/iterator.c
@@ -205,6 +205,11 @@ list_itrctl (void *owner, enum mu_itrctl_req req, void *arg)
 	itr->backwards = !!*(int*)arg;
       break;
       
+    case mu_itrctl_count:
+      if (!arg)
+	return EINVAL;
+      return mu_list_count (itr->list, arg);
+      
     default:
       return ENOSYS;
     }
diff --git a/libmailutils/mailbox/hdritr.c b/libmailutils/mailbox/hdritr.c
index 9669561..1d614d4 100644
--- a/libmailutils/mailbox/hdritr.c
+++ b/libmailutils/mailbox/hdritr.c
@@ -172,6 +172,11 @@ hdr_itrctl (void *owner, enum mu_itrctl_req req, void *arg)
       else
 	itr->backwards = !!*(int*)arg;
       break;
+
+    case mu_itrctl_count:
+      if (!arg)
+	return EINVAL;
+      return mu_header_get_field_count (itr->header, arg);
       
     default:
       return ENOSYS;
diff --git a/libmailutils/mailbox/mbxitr.c b/libmailutils/mailbox/mbxitr.c
index 9461d6b..02e4b96 100644
--- a/libmailutils/mailbox/mbxitr.c
+++ b/libmailutils/mailbox/mbxitr.c
@@ -175,6 +175,11 @@ mbx_itrctl (void *owner, enum mu_itrctl_req req, void *arg)
       else	
 	itr->backwards = !!*(int*)arg;
       break;
+
+    case mu_itrctl_count:
+      if (!arg)
+	return EINVAL;
+      return mu_mailbox_messages_count (itr->mbx, arg);
       
     default:
       return ENOSYS;
diff --git a/movemail/movemail.c b/movemail/movemail.c
index 8b544e5..39f9702 100644
--- a/movemail/movemail.c
+++ b/movemail/movemail.c
@@ -29,6 +29,10 @@
 #include <mailutils/tls.h>
 #include "mailutils/cli.h"
 #include <muaux.h>
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+#include <sys/ioctl.h>
 
 static int reverse_order;
 static int preserve_mail; 
@@ -39,6 +43,7 @@ static int ignore_errors;
 static char *program_id_option;
 static size_t max_messages_option;
 static int notify;
+static int progress_meter_option;
 
   /* These bits tell what to do when an error occurs: */
 #define ONERROR_SKIP     0x01  /* Skip to the next message */
@@ -303,6 +308,10 @@ static struct mu_option movemail_options[] = {
     N_("enable biff notification"),
     mu_c_bool, &notify },
 
+  { "progress-meter", 'm', NULL,   MU_OPTION_DEFAULT,
+    N_("enable progress meter"),
+    mu_c_bool, &progress_meter_option },
+
   MU_OPTION_END
 }, *options[] = { movemail_options, NULL };
 
@@ -840,6 +849,76 @@ set_program_id (const char *source_name, const char *dest_name)
   mu_stdstream_strerr_setup (MU_STRERR_STDERR);
 }
 
+static int
+screen_width (void)
+{
+  struct winsize ws;
+  ws.ws_col = 0;
+  if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
+    {
+      char *p = getenv ("COLUMNS");
+      if (p)
+	ws.ws_col = atol (p);
+    }
+  if (ws.ws_col == 0)
+    return 80;
+  return ws.ws_col;
+}
+
+static void
+progress_format (size_t pos, size_t count)
+{
+  int n;
+  
+  fputc ('\r', stdout);
+  n = printf ("message %zu/%zu", pos, count);
+  n = screen_width () - n;
+  while (n--)
+    fputc (' ', stdout);
+  fflush (stdout);
+}
+
+void
+progress_start (mu_iterator_t itr)
+{
+  size_t count;
+  
+  if (!progress_meter_option)
+    return;
+
+  if (mu_iterator_ctl (itr, mu_itrctl_count, &count))
+    {
+      progress_meter_option = 0;
+      return;
+    }
+  progress_format (0, count);
+}
+
+void
+progress_mark (mu_iterator_t itr)
+{
+  size_t count, pos;
+  
+  if (!progress_meter_option)
+    return;
+
+  if (mu_iterator_ctl (itr, mu_itrctl_count, &count)
+      || mu_iterator_ctl (itr, mu_itrctl_tell, &pos))
+    {
+      progress_meter_option = 0;
+      return;
+    }
+  if (reverse_order)
+    pos = count - pos + 1;
+  progress_format (pos, count);
+}
+
+void
+progress_stop (void)
+{
+  if (progress_meter_option)
+    fputc ('\n', stdout);
+}
 
 int
 main (int argc, char **argv)
@@ -871,6 +950,9 @@ main (int argc, char **argv)
 
   if (ignore_errors)
     onerror_flags |= ONERROR_SKIP|ONERROR_COUNT;
+
+  if (!isatty (1))
+    progress_meter_option = 0;
   
   if (emacs_mode)
     {      
@@ -965,6 +1047,7 @@ main (int argc, char **argv)
 	  exit (1);
 	}
       
+      progress_start (itr);
       for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
 	   mu_iterator_next (itr))
 	{
@@ -980,6 +1063,7 @@ main (int argc, char **argv)
 	      get_err_count++;
 	      continue;
 	    }
+	  progress_mark (itr);
 	  if (movemail (dest, msg, uidl->msgno))
 	    break;
 	}
@@ -1000,7 +1084,8 @@ main (int argc, char **argv)
 		    mu_strerror (rc));
 	  return 1;
 	}
-      
+
+      progress_start (itr);
       for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
 	   mu_iterator_next (itr))
 	{
@@ -1026,8 +1111,10 @@ main (int argc, char **argv)
 	  
 	  if (movemail (dest, msg, msgno))
 	    break;
+	  progress_mark (itr);
 	}
     }
+  progress_stop ();
   mu_iterator_destroy (&itr);
   
   if (verbose_option)
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.