make progress counters global
which means they are now cumulative, and include channels and boxes.
This commit is contained in:
parent
1de3ecd883
commit
8aa22a62e7
|
@ -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 *, ... );
|
||||
|
|
|
@ -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) {
|
||||
|
|
61
src/main.c
61
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))) {
|
||||
|
|
15
src/mbsync.1
15
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
|
||||
|
|
77
src/sync.c
77
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 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user