[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, ¬ify },
+ { "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)