bug-mailutils
[Top][All Lists]
Advanced

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

Re: [bug-mailutils] movemail: needs more verbosity


From: Sergey Poznyakoff
Subject: Re: [bug-mailutils] movemail: needs more verbosity
Date: Thu, 16 Mar 2017 11:44:08 +0200

Jean Louis <address@hidden> 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

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)

reply via email to

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