make progress counters global

which means they are now cumulative, and include channels and boxes.
This commit is contained in:
Oswald Buddenhagen 2015-03-28 17:26:08 +01:00
parent 1de3ecd883
commit 8aa22a62e7
5 changed files with 108 additions and 53 deletions

View File

@ -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 *, ... );

View File

@ -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) {

View File

@ -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))) {

View File

@ -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

View File

@ -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 );
}