commit 8aa22a62e790c4ced512e0f74c407725162a3b0d
parent 1de3ecd8830e98754721fd3f0267f9890aed2d2a
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date: Sat, 28 Mar 2015 17:26:08 +0100
make progress counters global
which means they are now cumulative, and include channels and boxes.
Diffstat:
5 files changed, 108 insertions(+), 53 deletions(-)
diff --git a/src/common.h b/src/common.h
@@ -78,6 +78,12 @@ extern const char *Home;
extern int BufferLimit;
+extern int new_total[2], new_done[2];
+extern int flags_total[2], flags_done[2];
+extern int trash_total[2], trash_done[2];
+
+void stats( void );
+
/* util.c */
void ATTR_PRINTFLIKE(1, 2) debug( const char *, ... );
diff --git a/src/drv_imap.c b/src/drv_imap.c
@@ -1728,6 +1728,7 @@ ensure_password( imap_server_conf_t *srvc )
int ret;
char buffer[80];
+ flushn();
if (!(fp = popen( srvc->pass_cmd, "r" ))) {
pipeerr:
sys_error( "Skipping account %s, password command failed", srvc->name );
@@ -1754,6 +1755,7 @@ ensure_password( imap_server_conf_t *srvc )
} else if (!srvc->pass) {
char *pass, prompt[80];
+ flushn();
sprintf( prompt, "Password (%s): ", srvc->name );
pass = getpass( prompt );
if (!pass) {
diff --git a/src/main.c b/src/main.c
@@ -45,6 +45,12 @@ const char *Home; /* for config */
int BufferLimit = 10 * 1024 * 1024;
+int chans_total, chans_done;
+int boxes_total, boxes_done;
+int new_total[2], new_done[2];
+int flags_total[2], flags_done[2];
+int trash_total[2], trash_done[2];
+
static void
version( void )
{
@@ -123,6 +129,32 @@ crashHandler( int n )
}
#endif
+void
+stats( void )
+{
+ char buf[3][64];
+ char *cs;
+ int t, l, ll, cls;
+ static int cols = -1;
+
+ if (DFlags & QUIET)
+ return;
+
+ if (cols < 0 && (!(cs = getenv( "COLUMNS" )) || !(cols = atoi( cs ))))
+ cols = 80;
+ ll = sprintf( buf[2], "C: %d/%d B: %d/%d", chans_done, chans_total, boxes_done, boxes_total );
+ cls = (cols - ll - 10) / 2;
+ for (t = 0; t < 2; t++) {
+ l = sprintf( buf[t], "+%d/%d *%d/%d #%d/%d",
+ new_done[t], new_total[t],
+ flags_done[t], flags_total[t],
+ trash_done[t], trash_total[t] );
+ if (l > cls)
+ buf[t][cls - 1] = '~';
+ }
+ infon( "\v\r%s M: %.*s S: %.*s", buf[2], cls, buf[0], cls, buf[1] );
+}
+
static int
matches( const char *t, const char *p )
{
@@ -254,6 +286,7 @@ add_channel( chan_ent_t ***chanapp, channel_conf_t *chan, int ops[] )
**chanapp = ce;
*chanapp = &ce->next;
+ chans_total++;
return ce;
}
@@ -297,8 +330,12 @@ add_named_channel( chan_ent_t ***chanapp, char *channame, int ops[] )
mbox->next = 0;
*mboxapp = mbox;
mboxapp = &mbox->next;
+ boxes_total++;
boxp = nboxp;
} while (boxp);
+ } else {
+ if (!chan->patterns)
+ boxes_total++;
}
ce = add_channel( chanapp, chan, ops );
@@ -315,7 +352,7 @@ typedef struct {
chan_ent_t *chanptr;
box_ent_t *boxptr;
char *names[2];
- int ret, multiple, all, list, state[2];
+ int ret, all, list, state[2];
char done, skip, cben;
} main_vars_t;
@@ -605,8 +642,11 @@ main( int argc, char **argv )
}
if (mvars->all) {
- for (chan = channels; chan; chan = chan->next)
+ for (chan = channels; chan; chan = chan->next) {
add_channel( &chanapp, chan, ops );
+ if (!chan->patterns)
+ boxes_total++;
+ }
} else {
for (; argv[oind]; oind++) {
for (group = groups; group; group = group->next) {
@@ -627,11 +667,14 @@ main( int argc, char **argv )
return 1;
}
mvars->chanptr = chans;
- mvars->multiple = !!chans->next;
+ if (!mvars->list)
+ stats();
mvars->cben = 1;
sync_chans( mvars, E_START );
main_loop();
+ if (!mvars->list)
+ flushn();
return mvars->ret;
}
@@ -723,13 +766,16 @@ sync_chans( main_vars_t *mvars, int ent )
mbox->next = 0;
*mboxapp = mbox;
mboxapp = &mbox->next;
+ boxes_total++;
}
free( boxes[M] );
free( boxes[S] );
+ if (!mvars->list)
+ stats();
}
mvars->boxptr = mvars->chanptr->boxes;
- if (mvars->list && mvars->multiple)
+ if (mvars->list && chans_total > 1)
printf( "%s:\n", mvars->chan->name );
syncml:
mvars->done = mvars->cben = 0;
@@ -775,7 +821,10 @@ sync_chans( main_vars_t *mvars, int ent )
mvars->chanptr->boxlist = 0;
}
next2:
- ;
+ if (!mvars->list) {
+ chans_done++;
+ stats();
+ }
} while ((mvars->chanptr = mvars->chanptr->next));
for (t = 0; t < N_DRIVERS; t++)
drivers[t]->cleanup();
@@ -921,6 +970,8 @@ done_sync( int sts, void *aux )
main_vars_t *mvars = (main_vars_t *)aux;
mvars->done = 1;
+ boxes_done++;
+ stats();
if (sts) {
mvars->ret = 1;
if (sts & (SYNC_BAD(M) | SYNC_BAD(S))) {
diff --git a/src/mbsync.1 b/src/mbsync.1
@@ -591,6 +591,21 @@ absolute limit, as even a single message can consume more memory than
this.
(Default: \fI10M\fR)
..
+.SH CONSOLE OUTPUT
+If \fBmbsync\fR's output is connected to a console, it will print progress
+counters by default. The output will look like this:
+.P
+.in +4
+C: 1/2 B: 3/4 M: +13/13 *23/42 #0/0 S: +0/7 *0/0 #0/0
+.in -4
+.P
+This represents the cumulative progress over channels, boxes, and messages
+affected on master and slave, respectively.
+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.
+..
.SH RECOMMENDATIONS
Make sure your IMAP server does not auto-expunge deleted messages - it is
slow, and semantically somewhat questionable. Specifically, Gmail needs to
diff --git a/src/sync.c b/src/sync.c
@@ -156,9 +156,7 @@ typedef struct {
const char *orig_name[2];
message_t *new_msgs[2];
int state[2], ref_count, nsrecs, ret, lfd, existing, replayed;
- int new_total[2], new_done[2];
- int flags_total[2], flags_done[2];
- int trash_total[2], trash_done[2];
+ int new_pending[2], flags_pending[2], trash_pending[2];
int maxuid[2]; /* highest UID that was already propagated */
int newmaxuid[2]; /* highest UID that is currently being propagated */
int uidval[2]; /* UID validity value */
@@ -446,30 +444,6 @@ msg_stored( int sts, int uid, void *aux )
}
-static void
-stats( sync_vars_t *svars )
-{
- char buf[2][64];
- char *cs;
- int t, l;
- static int cols = -1;
-
- if (cols < 0 && (!(cs = getenv( "COLUMNS" )) || !(cols = atoi( cs ) / 2)))
- cols = 36;
- if (!(DFlags & QUIET)) {
- for (t = 0; t < 2; t++) {
- l = sprintf( buf[t], "+%d/%d *%d/%d #%d/%d",
- svars->new_done[t], svars->new_total[t],
- svars->flags_done[t], svars->flags_total[t],
- svars->trash_done[t], svars->trash_total[t] );
- if (l > cols)
- buf[t][cols - 1] = '~';
- }
- infon( "\v\rM: %.*s S: %.*s", cols, buf[0], cols, buf[1] );
- }
-}
-
-
static void sync_bail( sync_vars_t *svars );
static void sync_bail2( sync_vars_t *svars );
static void sync_bail3( sync_vars_t *svars );
@@ -1697,8 +1671,9 @@ box_loaded( int sts, void *aux )
dflags &= srec->msg[t]->flags;
}
if (aflags | dflags) {
- svars->flags_total[t]++;
- stats( svars );
+ flags_total[t]++;
+ stats();
+ svars->flags_pending[t]++;
fv = nfmalloc( sizeof(*fv) );
fv->aux = AUX;
fv->srec = srec;
@@ -1756,8 +1731,9 @@ msg_copied( int sts, int uid, copy_vars_t *vars )
return;
}
free( vars );
- svars->new_done[t]++;
- stats( svars );
+ new_done[t]++;
+ stats();
+ svars->new_pending[t]--;
msgs_copied( svars, t );
}
@@ -1812,8 +1788,9 @@ msgs_copied( sync_vars_t *svars, int t )
svars->new_msgs[t] = tmsg;
goto out;
}
- svars->new_total[t]++;
- stats( svars );
+ new_total[t]++;
+ stats();
+ svars->new_pending[t]++;
svars->state[t] |= ST_SENDING_NEW;
cv = nfmalloc( sizeof(*cv) );
cv->cb = msg_copied;
@@ -1829,7 +1806,7 @@ msgs_copied( sync_vars_t *svars, int t )
svars->state[t] |= ST_SENT_NEW;
}
- if (svars->new_done[t] < svars->new_total[t])
+ if (svars->new_pending[t])
goto out;
Fprintf( svars->jfp, "%c %d\n", ")("[t], svars->maxuid[1-t] );
@@ -1885,8 +1862,9 @@ flags_set( int sts, void *aux )
break;
}
free( vars );
- svars->flags_done[t]++;
- stats( svars );
+ flags_done[t]++;
+ stats();
+ svars->flags_pending[t]--;
msgs_flags_set( svars, t );
}
@@ -1930,7 +1908,7 @@ msgs_flags_set( sync_vars_t *svars, int t )
message_t *tmsg;
copy_vars_t *cv;
- if (!(svars->state[t] & ST_SENT_FLAGS) || svars->flags_done[t] < svars->flags_total[t])
+ if (!(svars->state[t] & ST_SENT_FLAGS) || svars->flags_pending[t])
return;
sync_ref( svars );
@@ -1943,8 +1921,9 @@ msgs_flags_set( sync_vars_t *svars, int t )
if (svars->ctx[t]->conf->trash) {
if (!svars->ctx[t]->conf->trash_only_new || !tmsg->srec || tmsg->srec->uid[1-t] < 0) {
debug( "%s: trashing message %d\n", str_ms[t], tmsg->uid );
- svars->trash_total[t]++;
- stats( svars );
+ trash_total[t]++;
+ stats();
+ svars->trash_pending[t]++;
svars->drv[t]->trash_msg( svars->ctx[t], tmsg, msg_trashed, AUX );
if (check_cancel( svars ))
goto out;
@@ -1954,8 +1933,9 @@ msgs_flags_set( sync_vars_t *svars, int t )
if (!tmsg->srec || tmsg->srec->uid[1-t] < 0) {
if (tmsg->size <= svars->ctx[1-t]->conf->max_size) {
debug( "%s: remote trashing message %d\n", str_ms[t], tmsg->uid );
- svars->trash_total[t]++;
- stats( svars );
+ trash_total[t]++;
+ stats();
+ svars->trash_pending[t]++;
cv = nfmalloc( sizeof(*cv) );
cv->cb = msg_rtrashed;
cv->aux = INV_AUX;
@@ -1988,8 +1968,9 @@ msg_trashed( int sts, void *aux )
if (check_ret( sts, aux ))
return;
INIT_SVARS(aux);
- svars->trash_done[t]++;
- stats( svars );
+ trash_done[t]++;
+ stats();
+ svars->trash_pending[t]--;
sync_close( svars, t );
}
@@ -2008,8 +1989,9 @@ msg_rtrashed( int sts, int uid ATTR_UNUSED, copy_vars_t *vars )
}
free( vars );
t ^= 1;
- svars->trash_done[t]++;
- stats( svars );
+ trash_done[t]++;
+ stats();
+ svars->trash_pending[t]--;
sync_close( svars, t );
}
@@ -2019,8 +2001,8 @@ static void box_closed_p2( sync_vars_t *svars, int t );
static void
sync_close( sync_vars_t *svars, int t )
{
- if ((~svars->state[t] & (ST_FOUND_NEW|ST_SENT_TRASH)) || svars->trash_done[t] < svars->trash_total[t] ||
- !(svars->state[1-t] & ST_SENT_NEW) || svars->new_done[1-t] < svars->new_total[1-t])
+ if ((~svars->state[t] & (ST_FOUND_NEW|ST_SENT_TRASH)) || svars->trash_pending[t] ||
+ !(svars->state[1-t] & ST_SENT_NEW) || svars->new_pending[1-t])
return;
if (svars->state[t] & ST_CLOSING)
@@ -2120,7 +2102,6 @@ sync_bail2( sync_vars_t *svars )
free( svars->nname );
free( svars->jname );
free( svars->dname );
- flushn();
sync_bail3( svars );
}