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
This commit is contained in:
Oswald Buddenhagen 2022-05-18 23:03:50 +02:00
parent 0f7c231cc2
commit a1a3313ed4
4 changed files with 52 additions and 5 deletions

2
NEWS
View File

@ -8,6 +8,8 @@ is now the file's containing directory.
The unfiltered list of mailboxes in each Store can be printed now. The unfiltered list of mailboxes in each Store can be printed now.
A proper summary is now printed prior to exiting.
[1.4.0] [1.4.0]
The 'isync' compatibility wrapper was removed. The 'isync' compatibility wrapper was removed.

View File

@ -9,6 +9,7 @@
#define nz(a, b) ((a) ? (a) : (b)) #define nz(a, b) ((a) ? (a) : (b))
static int ops_any[2], trash_any[2];
static int chans_total, chans_done; static int chans_total, chans_done;
static int boxes_total, boxes_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] ); 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 static int
matches( const char *t, const char *p ) 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_REMOVE, OP_REMOVE, 0 );
merge_actions( chan, ops, XOP_HAVE_EXPUNGE, OP_EXPUNGE, 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;
*chanapp = &ce->next; *chanapp = &ce->next;
chans_total++; chans_total++;
@ -296,8 +327,10 @@ sync_chans( core_vars_t *cvars, char **argv )
stats(); stats();
do_sync_chans( mvars ); do_sync_chans( mvars );
main_loop(); main_loop();
if (!cvars->list) if (!cvars->list) {
flushn(); flushn();
summary();
}
} }
enum { enum {

View File

@ -102,7 +102,7 @@ Without category specification, all categories except net-all are enabled.
.TP .TP
\fB-q\fR, \fB--quiet\fR \fB-q\fR, \fB--quiet\fR
Suppress progress counters (this is implicit if stdout is no TTY, 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. If specified twice, suppress warning messages as well.
. .
.SH CONFIGURATION .SH CONFIGURATION
@ -754,6 +754,9 @@ The message counts represent added messages, messages with updated flags,
and trashed messages, respectively. and trashed messages, respectively.
No attempt is made to calculate the totals in advance, so they grow over No attempt is made to calculate the totals in advance, so they grow over
time as more information is gathered. 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 .SH RECOMMENDATIONS
Make sure your IMAP server does not auto-expunge deleted messages - it is Make sure your IMAP server does not auto-expunge deleted messages - it is

View File

@ -22,7 +22,7 @@ int Pid;
char Hostname[256]; char Hostname[256];
const char *Home; const char *Home;
static int need_nl; static int need_nl, need_del;
void void
flushn( void ) flushn( void )
@ -31,6 +31,16 @@ flushn( void )
putchar( '\n' ); putchar( '\n' );
fflush( stdout ); fflush( stdout );
need_nl = 0; 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_list va;
va_start( va, msg ); va_start( va, msg );
vprintf( msg, va ); need_del = vprintf( msg, va ) - 1;
va_end( va ); va_end( va );
fflush( stdout ); fflush( stdout );
need_nl = 1;
} }
static void ATTR_PRINTFLIKE(1, 0) static void ATTR_PRINTFLIKE(1, 0)