Jean Louis <bugs@gnu.support> 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)
_______________________________________________ Bug-mailutils mailing list Bug-mailutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-mailutils