isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit a1a3313ed436e3892d8a5549dfc1a07ca9fc93c0
parent 0f7c231cc2f5753ed57005f50d7805b82df257f8
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Wed, 18 May 2022 23:03:50 +0200

print human-readable summary at exit

this is meant primarily for use with a redirected output, where no
progress counters are shown. but it would be weird not to have it with
tty output as well, so it replaces the counters after completion.

REFMAIL: 87bl2cgt6u.fsf@curie.anarc.at

Diffstat:
MNEWS | 2++
Msrc/main_sync.c | 35++++++++++++++++++++++++++++++++++-
Msrc/mbsync.1 | 5++++-
Msrc/util.c | 15++++++++++++---
4 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS @@ -8,6 +8,8 @@ is now the file's containing directory. The unfiltered list of mailboxes in each Store can be printed now. +A proper summary is now printed prior to exiting. + [1.4.0] The 'isync' compatibility wrapper was removed. diff --git a/src/main_sync.c b/src/main_sync.c @@ -9,6 +9,7 @@ #define nz(a, b) ((a) ? (a) : (b)) +static int ops_any[2], trash_any[2]; static int chans_total, chans_done; static int boxes_total, boxes_done; @@ -37,6 +38,27 @@ stats( void ) progress( "\r%s F: %.*s N: %.*s", buf[2], cls, buf[0], cls, buf[1] ); } +static void +summary( void ) +{ + if (Verbosity < TERSE) + return; + + if (!boxes_done) + return; // Shut up if we errored out early. + + printf( "Processed %d box(es) in %d channel(s)", boxes_done, chans_done ); + for (int t = 2; --t >= 0; ) { + if (ops_any[t]) + printf( ",\n%sed %d new message(s) and %d flag update(s)", + str_hl[t], new_done[t], flags_done[t] ); + if (trash_any[t]) + printf( ",\nmoved %d %s message(s) to trash", + trash_done[t], str_fn[t] ); + } + puts( "." ); +} + static int matches( const char *t, const char *p ) { @@ -165,6 +187,15 @@ add_channel( chan_ent_t ***chanapp, channel_conf_t *chan, int ops[] ) merge_actions( chan, ops, XOP_HAVE_REMOVE, OP_REMOVE, 0 ); merge_actions( chan, ops, XOP_HAVE_EXPUNGE, OP_EXPUNGE, 0 ); + for (int t = 0; t < 2; t++) { + if (chan->ops[t] & OP_MASK_TYPE) + ops_any[t] = 1; + if ((chan->ops[t] & OP_EXPUNGE) && + (chan->stores[t]->trash || + (chan->stores[t^1]->trash && chan->stores[t^1]->trash_remote_new))) + trash_any[t] = 1; + } + **chanapp = ce; *chanapp = &ce->next; chans_total++; @@ -296,8 +327,10 @@ sync_chans( core_vars_t *cvars, char **argv ) stats(); do_sync_chans( mvars ); main_loop(); - if (!cvars->list) + if (!cvars->list) { flushn(); + summary(); + } } enum { diff --git a/src/mbsync.1 b/src/mbsync.1 @@ -102,7 +102,7 @@ Without category specification, all categories except net-all are enabled. .TP \fB-q\fR, \fB--quiet\fR Suppress progress counters (this is implicit if stdout is no TTY, -or any debugging categories are enabled) and notices. +or any debugging categories are enabled), notices, and the summary. If specified twice, suppress warning messages as well. . .SH CONFIGURATION @@ -754,6 +754,9 @@ The message counts represent added messages, messages with updated flags, and trashed messages, respectively. No attempt is made to calculate the totals in advance, so they grow over time as more information is gathered. +.P +Irrespective of output redirection, \fBmbsync\fR will print a summary +of the above in plain language upon completion, except in quiet mode. . .SH RECOMMENDATIONS Make sure your IMAP server does not auto-expunge deleted messages - it is diff --git a/src/util.c b/src/util.c @@ -22,7 +22,7 @@ int Pid; char Hostname[256]; const char *Home; -static int need_nl; +static int need_nl, need_del; void flushn( void ) @@ -31,6 +31,16 @@ flushn( void ) putchar( '\n' ); fflush( stdout ); need_nl = 0; + } else if (need_del) { + static const char delstr[] = + " " + " "; + if (need_del > (int)sizeof(delstr) - 1) + need_del = (int)sizeof(delstr) - 1; + // We could use ^[[K instead, but we assume a dumb terminal. + printf( "\r%.*s\r", need_del, delstr ); + fflush( stdout ); + need_del = 0; } } @@ -75,10 +85,9 @@ progress( const char *msg, ... ) va_list va; va_start( va, msg ); - vprintf( msg, va ); + need_del = vprintf( msg, va ) - 1; va_end( va ); fflush( stdout ); - need_nl = 1; } static void ATTR_PRINTFLIKE(1, 0)