fix error paths wrt sync drivers

This commit is contained in:
Oswald Buddenhagen 2006-12-09 10:39:30 +00:00
parent 9056504483
commit 023d3ee577
4 changed files with 198 additions and 246 deletions

View File

@ -1426,7 +1426,6 @@ imap_open_store( store_conf_t *conf,
bail: bail:
imap_cancel_store( &ctx->gen ); imap_cancel_store( &ctx->gen );
cb( 0, aux ); cb( 0, aux );
return;
} }
static void static void
@ -1442,9 +1441,9 @@ imap_prepare_opts( store_t *gctx, int opts )
gctx->opts = opts; gctx->opts = opts;
} }
static void static int
imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
imap_store_t *ctx = (imap_store_t *)gctx; imap_store_t *ctx = (imap_store_t *)gctx;
const char *prefix; const char *prefix;
@ -1499,19 +1498,19 @@ imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs,
bail: bail:
if (excs) if (excs)
free( excs ); free( excs );
cb( ret, aux ); return cb( ret, aux );
} }
static void static int
imap_fetch_msg( store_t *ctx, message_t *msg, msg_data_t *data, imap_fetch_msg( store_t *ctx, message_t *msg, msg_data_t *data,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
struct imap_cmd_cb cbd; struct imap_cmd_cb cbd;
memset( &cbd, 0, sizeof(cbd) ); memset( &cbd, 0, sizeof(cbd) );
cbd.uid = msg->uid; cbd.uid = msg->uid;
cbd.ctx = data; cbd.ctx = data;
cb( imap_exec_m( (imap_store_t *)ctx, &cbd, "UID FETCH %d (%sBODY.PEEK[])", return cb( imap_exec_m( (imap_store_t *)ctx, &cbd, "UID FETCH %d (%sBODY.PEEK[])",
msg->uid, (msg->status & M_FLAGS) ? "" : "FLAGS " ), aux ); msg->uid, (msg->status & M_FLAGS) ? "" : "FLAGS " ), aux );
} }
@ -1542,9 +1541,9 @@ imap_flags_helper( imap_store_t *ctx, int uid, char what, int flags)
return issue_imap_cmd_w( ctx, 0, "UID STORE %d %cFLAGS.SILENT %s", uid, what, buf ) ? DRV_OK : DRV_STORE_BAD; return issue_imap_cmd_w( ctx, 0, "UID STORE %d %cFLAGS.SILENT %s", uid, what, buf ) ? DRV_OK : DRV_STORE_BAD;
} }
static void static int
imap_set_flags( store_t *gctx, message_t *msg, int uid, int add, int del, imap_set_flags( store_t *gctx, message_t *msg, int uid, int add, int del,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
imap_store_t *ctx = (imap_store_t *)gctx; imap_store_t *ctx = (imap_store_t *)gctx;
int ret; int ret;
@ -1559,32 +1558,32 @@ imap_set_flags( store_t *gctx, message_t *msg, int uid, int add, int del,
if ((!add || (ret = imap_flags_helper( ctx, uid, '+', add )) == DRV_OK) && if ((!add || (ret = imap_flags_helper( ctx, uid, '+', add )) == DRV_OK) &&
(!del || (ret = imap_flags_helper( ctx, uid, '-', del )) == DRV_OK)) (!del || (ret = imap_flags_helper( ctx, uid, '-', del )) == DRV_OK))
ret = DRV_OK; ret = DRV_OK;
cb( ret, aux ); return cb( ret, aux );
} }
static void static int
imap_close( store_t *ctx, imap_close( store_t *ctx,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
cb( imap_exec_b( (imap_store_t *)ctx, 0, "CLOSE" ), aux ); return cb( imap_exec_b( (imap_store_t *)ctx, 0, "CLOSE" ), aux );
} }
static void static int
imap_trash_msg( store_t *gctx, message_t *msg, imap_trash_msg( store_t *gctx, message_t *msg,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
imap_store_t *ctx = (imap_store_t *)gctx; imap_store_t *ctx = (imap_store_t *)gctx;
struct imap_cmd_cb cbd; struct imap_cmd_cb cbd;
memset( &cbd, 0, sizeof(cbd) ); memset( &cbd, 0, sizeof(cbd) );
cbd.create = 1; cbd.create = 1;
cb( imap_exec_m( ctx, &cbd, "UID COPY %d \"%s%s\"", return cb( imap_exec_m( ctx, &cbd, "UID COPY %d \"%s%s\"",
msg->uid, ctx->prefix, gctx->conf->trash ), aux ); msg->uid, ctx->prefix, gctx->conf->trash ), aux );
} }
static void static int
imap_store_msg( store_t *gctx, msg_data_t *data, int to_trash, imap_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
void (*cb)( int sts, int uid, void *aux ), void *aux ) int (*cb)( int sts, int uid, void *aux ), void *aux )
{ {
imap_store_t *ctx = (imap_store_t *)gctx; imap_store_t *ctx = (imap_store_t *)gctx;
struct imap_cmd_cb cbd; struct imap_cmd_cb cbd;
@ -1620,22 +1619,20 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
} }
ret = imap_exec_m( ctx, &cbd, "APPEND \"%s%s\" %s", prefix, box, flagstr ); ret = imap_exec_m( ctx, &cbd, "APPEND \"%s%s\" %s", prefix, box, flagstr );
ctx->caps = ctx->rcaps; ctx->caps = ctx->rcaps;
if (ret != DRV_OK) { if (ret != DRV_OK)
cb( ret, -1, aux ); return cb( ret, -1, aux );
return;
}
if (to_trash) if (to_trash)
ctx->trashnc = 0; ctx->trashnc = 0;
else { else {
/*ctx->currentnc = 0;*/ /*ctx->currentnc = 0;*/
} }
cb( DRV_OK, uid, aux ); return cb( DRV_OK, uid, aux );
} }
static void static int
imap_find_msg( store_t *gctx, const char *tuid, imap_find_msg( store_t *gctx, const char *tuid,
void (*cb)( int sts, int uid, void *aux ), void *aux ) int (*cb)( int sts, int uid, void *aux ), void *aux )
{ {
imap_store_t *ctx = (imap_store_t *)gctx; imap_store_t *ctx = (imap_store_t *)gctx;
struct imap_cmd_cb cbd; struct imap_cmd_cb cbd;
@ -1646,9 +1643,9 @@ imap_find_msg( store_t *gctx, const char *tuid,
cbd.ctx = &uid; cbd.ctx = &uid;
uid = -1; /* in case we get no SEARCH response at all */ uid = -1; /* in case we get no SEARCH response at all */
if ((ret = imap_exec_m( ctx, &cbd, "UID SEARCH HEADER X-TUID %." stringify(TUIDL) "s", tuid )) != DRV_OK) if ((ret = imap_exec_m( ctx, &cbd, "UID SEARCH HEADER X-TUID %." stringify(TUIDL) "s", tuid )) != DRV_OK)
cb( ret, -1, aux ); return cb( ret, -1, aux );
else else
cb( uid <= 0 ? DRV_MSG_BAD : DRV_OK, uid, aux ); return cb( uid <= 0 ? DRV_MSG_BAD : DRV_OK, uid, aux );
} }
static void static void

View File

@ -767,9 +767,9 @@ maildir_prepare_opts( store_t *gctx, int opts )
gctx->opts = opts; gctx->opts = opts;
} }
static void static int
maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
maildir_store_t *ctx = (maildir_store_t *)gctx; maildir_store_t *ctx = (maildir_store_t *)gctx;
message_t **msgapp; message_t **msgapp;
@ -785,17 +785,14 @@ maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs,
ctx->excs = nfrealloc( excs, nexcs * sizeof(int) ); ctx->excs = nfrealloc( excs, nexcs * sizeof(int) );
ctx->nexcs = nexcs; ctx->nexcs = nexcs;
if (maildir_validate( gctx->path, "", ctx->gen.opts & OPEN_CREATE ) != DRV_OK) { if (maildir_validate( gctx->path, "", ctx->gen.opts & OPEN_CREATE ) != DRV_OK)
cb( DRV_BOX_BAD, aux ); return cb( DRV_BOX_BAD, aux );
return;
}
nfsnprintf( uvpath, sizeof(uvpath), "%s/.uidvalidity", gctx->path ); nfsnprintf( uvpath, sizeof(uvpath), "%s/.uidvalidity", gctx->path );
#ifndef USE_DB #ifndef USE_DB
if ((ctx->uvfd = open( uvpath, O_RDWR|O_CREAT, 0600 )) < 0) { if ((ctx->uvfd = open( uvpath, O_RDWR|O_CREAT, 0600 )) < 0) {
perror( uvpath ); perror( uvpath );
cb( DRV_BOX_BAD, aux ); return cb( DRV_BOX_BAD, aux );
return;
} }
#else #else
if ((ctx->uvfd = open( uvpath, O_RDWR, 0600 )) < 0) { if ((ctx->uvfd = open( uvpath, O_RDWR, 0600 )) < 0) {
@ -810,8 +807,7 @@ maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs,
goto fnok; goto fnok;
} }
perror( uvpath ); perror( uvpath );
cb( DRV_BOX_BAD, aux ); return cb( DRV_BOX_BAD, aux );
return;
} }
dbok: dbok:
#if SEEK_SET != 0 #if SEEK_SET != 0
@ -823,8 +819,7 @@ maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs,
bork: bork:
close( ctx->uvfd ); close( ctx->uvfd );
ctx->uvfd = -1; ctx->uvfd = -1;
cb( DRV_BOX_BAD, aux ); return cb( DRV_BOX_BAD, aux );
return;
} }
if (db_create( &ctx->db, 0, 0 )) { if (db_create( &ctx->db, 0, 0 )) {
fputs( "Maildir error: db_create() failed\n", stderr ); fputs( "Maildir error: db_create() failed\n", stderr );
@ -854,16 +849,14 @@ maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs,
fnok: fnok:
#endif /* USE_DB */ #endif /* USE_DB */
if (maildir_scan( ctx, &msglist ) != DRV_OK) { if (maildir_scan( ctx, &msglist ) != DRV_OK)
cb( DRV_BOX_BAD, aux ); return cb( DRV_BOX_BAD, aux );
return;
}
msgapp = &ctx->gen.msgs; msgapp = &ctx->gen.msgs;
for (i = 0; i < msglist.nents; i++) for (i = 0; i < msglist.nents; i++)
maildir_app_msg( ctx, &msgapp, msglist.ents + i ); maildir_app_msg( ctx, &msgapp, msglist.ents + i );
maildir_free_scan( &msglist ); maildir_free_scan( &msglist );
cb( DRV_OK, aux ); return cb( DRV_OK, aux );
} }
static int static int
@ -931,9 +924,9 @@ maildir_again( maildir_store_t *ctx, maildir_message_t *msg, const char *fn )
return (msg->gen.status & M_DEAD) ? DRV_MSG_BAD : DRV_OK; return (msg->gen.status & M_DEAD) ? DRV_MSG_BAD : DRV_OK;
} }
static void static int
maildir_fetch_msg( store_t *gctx, message_t *gmsg, msg_data_t *data, maildir_fetch_msg( store_t *gctx, message_t *gmsg, msg_data_t *data,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
maildir_store_t *ctx = (maildir_store_t *)gctx; maildir_store_t *ctx = (maildir_store_t *)gctx;
maildir_message_t *msg = (maildir_message_t *)gmsg; maildir_message_t *msg = (maildir_message_t *)gmsg;
@ -945,10 +938,8 @@ maildir_fetch_msg( store_t *gctx, message_t *gmsg, msg_data_t *data,
nfsnprintf( buf, sizeof(buf), "%s/%s/%s", gctx->path, subdirs[gmsg->status & M_RECENT], msg->base ); nfsnprintf( buf, sizeof(buf), "%s/%s/%s", gctx->path, subdirs[gmsg->status & M_RECENT], msg->base );
if ((fd = open( buf, O_RDONLY )) >= 0) if ((fd = open( buf, O_RDONLY )) >= 0)
break; break;
if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK) { if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK)
cb( ret, aux ); return cb( ret, aux );
return;
}
} }
fstat( fd, &st ); fstat( fd, &st );
data->len = st.st_size; data->len = st.st_size;
@ -956,13 +947,12 @@ maildir_fetch_msg( store_t *gctx, message_t *gmsg, msg_data_t *data,
if (read( fd, data->data, data->len ) != data->len) { if (read( fd, data->data, data->len ) != data->len) {
perror( buf ); perror( buf );
close( fd ); close( fd );
cb( DRV_MSG_BAD, aux ); return cb( DRV_MSG_BAD, aux );
return;
} }
close( fd ); close( fd );
if (!(gmsg->status & M_FLAGS)) if (!(gmsg->status & M_FLAGS))
data->flags = maildir_parse_flags( msg->base ); data->flags = maildir_parse_flags( msg->base );
cb( DRV_OK, aux ); return cb( DRV_OK, aux );
} }
static int static int
@ -980,9 +970,9 @@ maildir_make_flags( int flags, char *buf )
return d; return d;
} }
static void static int
maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash, maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
void (*cb)( int sts, int uid, void *aux ), void *aux ) int (*cb)( int sts, int uid, void *aux ), void *aux )
{ {
maildir_store_t *ctx = (maildir_store_t *)gctx; maildir_store_t *ctx = (maildir_store_t *)gctx;
const char *prefix, *box; const char *prefix, *box;
@ -995,17 +985,14 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
if (ctx->db) { if (ctx->db) {
if ((ret = maildir_set_uid( ctx, base, &uid )) != DRV_OK) { if ((ret = maildir_set_uid( ctx, base, &uid )) != DRV_OK) {
free( data->data ); free( data->data );
cb( ret, 0, aux ); return cb( ret, 0, aux );
return;
} }
} else } else
#endif /* USE_DB */ #endif /* USE_DB */
{ {
if ((ret = maildir_uidval_lock( ctx )) != DRV_OK || if ((ret = maildir_uidval_lock( ctx )) != DRV_OK ||
(ret = maildir_obtain_uid( ctx, &uid )) != DRV_OK) { (ret = maildir_obtain_uid( ctx, &uid )) != DRV_OK)
cb( ret, 0, aux ); return cb( ret, 0, aux );
return;
}
maildir_uidval_unlock( ctx ); maildir_uidval_unlock( ctx );
nfsnprintf( base + bl, sizeof(base) - bl, ",U=%d", uid ); nfsnprintf( base + bl, sizeof(base) - bl, ",U=%d", uid );
} }
@ -1022,19 +1009,16 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
if (errno != ENOENT) { if (errno != ENOENT) {
perror( buf ); perror( buf );
free( data->data ); free( data->data );
cb( DRV_BOX_BAD, 0, aux ); return cb( DRV_BOX_BAD, 0, aux );
return;
} }
if ((ret = maildir_validate( gctx->conf->path, gctx->conf->trash, gctx->opts & OPEN_CREATE )) != DRV_OK) { if ((ret = maildir_validate( gctx->conf->path, gctx->conf->trash, gctx->opts & OPEN_CREATE )) != DRV_OK) {
free( data->data ); free( data->data );
cb( ret, 0, aux ); return cb( ret, 0, aux );
return;
} }
if ((fd = open( buf, O_WRONLY|O_CREAT|O_EXCL, 0600 )) < 0) { if ((fd = open( buf, O_WRONLY|O_CREAT|O_EXCL, 0600 )) < 0) {
perror( buf ); perror( buf );
free( data->data ); free( data->data );
cb( DRV_BOX_BAD, 0, aux ); return cb( DRV_BOX_BAD, 0, aux );
return;
} }
} }
ret = write( fd, data->data, data->len ); ret = write( fd, data->data, data->len );
@ -1045,38 +1029,34 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
else else
error( "Maildir error: %s: partial write\n", buf ); error( "Maildir error: %s: partial write\n", buf );
close( fd ); close( fd );
cb( DRV_BOX_BAD, 0, aux ); return cb( DRV_BOX_BAD, 0, aux );
return;
} }
close( fd ); close( fd );
/* Moving seen messages to cur/ is strictly speaking incorrect, but makes mutt happy. */ /* Moving seen messages to cur/ is strictly speaking incorrect, but makes mutt happy. */
nfsnprintf( nbuf, sizeof(nbuf), "%s%s/%s/%s%s", prefix, box, subdirs[!(data->flags & F_SEEN)], base, fbuf ); nfsnprintf( nbuf, sizeof(nbuf), "%s%s/%s/%s%s", prefix, box, subdirs[!(data->flags & F_SEEN)], base, fbuf );
if (rename( buf, nbuf )) { if (rename( buf, nbuf )) {
perror( nbuf ); perror( nbuf );
cb( DRV_BOX_BAD, 0, aux ); return cb( DRV_BOX_BAD, 0, aux );
return;
} }
cb( DRV_OK, uid, aux ); return cb( DRV_OK, uid, aux );
} }
static void static int
maildir_find_msg( store_t *gctx, const char *tuid, maildir_find_msg( store_t *gctx, const char *tuid,
void (*cb)( int sts, int uid, void *aux ), void *aux ) int (*cb)( int sts, int uid, void *aux ), void *aux )
{ {
message_t *msg; message_t *msg;
/* using a hash table might turn out to be more appropriate ... */ /* using a hash table might turn out to be more appropriate ... */
for (msg = gctx->msgs; msg; msg = msg->next) for (msg = gctx->msgs; msg; msg = msg->next)
if (!(msg->status & M_DEAD) && !memcmp( ((maildir_message_t *)msg)->tuid, tuid, TUIDL )) { if (!(msg->status & M_DEAD) && !memcmp( ((maildir_message_t *)msg)->tuid, tuid, TUIDL ))
cb( DRV_OK, msg->uid, aux ); return cb( DRV_OK, msg->uid, aux );
return; return cb( DRV_MSG_BAD, -1, aux );
}
cb( DRV_MSG_BAD, -1, aux );
} }
static void static int
maildir_set_flags( store_t *gctx, message_t *gmsg, int uid, int add, int del, maildir_set_flags( store_t *gctx, message_t *gmsg, int uid, int add, int del,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
maildir_store_t *ctx = (maildir_store_t *)gctx; maildir_store_t *ctx = (maildir_store_t *)gctx;
maildir_message_t *msg = (maildir_message_t *)gmsg; maildir_message_t *msg = (maildir_message_t *)gmsg;
@ -1118,10 +1098,8 @@ maildir_set_flags( store_t *gctx, message_t *gmsg, int uid, int add, int del,
} }
if (!rename( buf, nbuf )) if (!rename( buf, nbuf ))
break; break;
if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK) { if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK)
cb( ret, aux ); return cb( ret, aux );
return;
}
} }
free( msg->base ); free( msg->base );
msg->base = nfmalloc( tl + 1 ); msg->base = nfmalloc( tl + 1 );
@ -1130,7 +1108,7 @@ maildir_set_flags( store_t *gctx, message_t *gmsg, int uid, int add, int del,
msg->gen.flags &= ~del; msg->gen.flags &= ~del;
gmsg->status &= ~M_RECENT; gmsg->status &= ~M_RECENT;
cb( DRV_OK, aux ); return cb( DRV_OK, aux );
} }
#ifdef USE_DB #ifdef USE_DB
@ -1150,9 +1128,9 @@ maildir_purge_msg( maildir_store_t *ctx, const char *name )
} }
#endif /* USE_DB */ #endif /* USE_DB */
static void static int
maildir_trash_msg( store_t *gctx, message_t *gmsg, maildir_trash_msg( store_t *gctx, message_t *gmsg,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
maildir_store_t *ctx = (maildir_store_t *)gctx; maildir_store_t *ctx = (maildir_store_t *)gctx;
maildir_message_t *msg = (maildir_message_t *)gmsg; maildir_message_t *msg = (maildir_message_t *)gmsg;
@ -1169,38 +1147,31 @@ maildir_trash_msg( store_t *gctx, message_t *gmsg,
if (!rename( buf, nbuf )) if (!rename( buf, nbuf ))
break; break;
if (!stat( buf, &st )) { if (!stat( buf, &st )) {
if ((ret = maildir_validate( gctx->conf->path, gctx->conf->trash, 1 )) != DRV_OK) { if ((ret = maildir_validate( gctx->conf->path, gctx->conf->trash, 1 )) != DRV_OK)
cb( ret, aux ); return cb( ret, aux );
return;
}
if (!rename( buf, nbuf )) if (!rename( buf, nbuf ))
break; break;
if (errno != ENOENT) { if (errno != ENOENT) {
perror( nbuf ); perror( nbuf );
cb( DRV_BOX_BAD, aux ); return cb( DRV_BOX_BAD, aux );
return;
} }
} }
if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK) { if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK)
cb( ret, aux ); return cb( ret, aux );
return;
}
} }
gmsg->status |= M_DEAD; gmsg->status |= M_DEAD;
gctx->count--; gctx->count--;
#ifdef USE_DB #ifdef USE_DB
if (ctx->db) { if (ctx->db)
cb( maildir_purge_msg( ctx, msg->base ), aux ); return cb( maildir_purge_msg( ctx, msg->base ), aux );
return;
}
#endif /* USE_DB */ #endif /* USE_DB */
cb( DRV_OK, aux ); return cb( DRV_OK, aux );
} }
static void static int
maildir_close( store_t *gctx, maildir_close( store_t *gctx,
void (*cb)( int sts, void *aux ), void *aux ) int (*cb)( int sts, void *aux ), void *aux )
{ {
#ifdef USE_DB #ifdef USE_DB
maildir_store_t *ctx = (maildir_store_t *)gctx; maildir_store_t *ctx = (maildir_store_t *)gctx;
@ -1224,21 +1195,15 @@ maildir_close( store_t *gctx,
msg->status |= M_DEAD; msg->status |= M_DEAD;
gctx->count--; gctx->count--;
#ifdef USE_DB #ifdef USE_DB
if (ctx->db && (ret = maildir_purge_msg( ctx, ((maildir_message_t *)msg)->base )) != DRV_OK) { if (ctx->db && (ret = maildir_purge_msg( ctx, ((maildir_message_t *)msg)->base )) != DRV_OK)
cb( ret, aux ); return cb( ret, aux );
return;
}
#endif /* USE_DB */ #endif /* USE_DB */
} }
} }
if (!retry) { if (!retry)
cb( DRV_OK, aux ); return cb( DRV_OK, aux );
return; if ((ret = maildir_rescan( (maildir_store_t *)gctx )) != DRV_OK)
} return cb( ret, aux );
if ((ret = maildir_rescan( (maildir_store_t *)gctx )) != DRV_OK) {
cb( ret, aux );
return;
}
} }
} }

View File

@ -191,20 +191,20 @@ struct driver {
void (*cb)( int sts, void *aux ), void *aux ); void (*cb)( int sts, void *aux ), void *aux );
void (*prepare_paths)( store_t *ctx ); void (*prepare_paths)( store_t *ctx );
void (*prepare_opts)( store_t *ctx, int opts ); void (*prepare_opts)( store_t *ctx, int opts );
void (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs, int (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs,
void (*cb)( int sts, void *aux ), void *aux ); int (*cb)( int sts, void *aux ), void *aux );
void (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data, int (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data,
void (*cb)( int sts, void *aux ), void *aux ); int (*cb)( int sts, void *aux ), void *aux );
void (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash, int (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash,
void (*cb)( int sts, int uid, void *aux ), void *aux ); int (*cb)( int sts, int uid, void *aux ), void *aux );
void (*find_msg)( store_t *ctx, const char *tuid, int (*find_msg)( store_t *ctx, const char *tuid,
void (*cb)( int sts, int uid, void *aux ), void *aux ); int (*cb)( int sts, int uid, void *aux ), void *aux );
void (*set_flags)( store_t *ctx, message_t *msg, int uid, int add, int del, /* msg can be null, therefore uid as a fallback */ int (*set_flags)( store_t *ctx, message_t *msg, int uid, int add, int del, /* msg can be null, therefore uid as a fallback */
void (*cb)( int sts, void *aux ), void *aux ); int (*cb)( int sts, void *aux ), void *aux );
void (*trash_msg)( store_t *ctx, message_t *msg, /* This may expunge the original message immediately, but it needn't to */ int (*trash_msg)( store_t *ctx, message_t *msg, /* This may expunge the original message immediately, but it needn't to */
void (*cb)( int sts, void *aux ), void *aux ); int (*cb)( int sts, void *aux ), void *aux );
void (*close)( store_t *ctx, /* IMAP-style: expunge inclusive */ int (*close)( store_t *ctx, /* IMAP-style: expunge inclusive */
void (*cb)( int sts, void *aux ), void *aux ); int (*cb)( int sts, void *aux ), void *aux );
void (*cancel)( store_t *ctx, /* only not yet sent commands */ void (*cancel)( store_t *ctx, /* only not yet sent commands */
void (*cb)( int sts, void *aux ), void *aux ); void (*cb)( int sts, void *aux ), void *aux );
void (*commit)( store_t *ctx ); void (*commit)( store_t *ctx );

View File

@ -152,7 +152,7 @@ typedef struct {
int flags_total[2], flags_done[2]; int flags_total[2], flags_done[2];
int trash_total[2], trash_done[2]; int trash_total[2], trash_done[2];
int maxuid[2], uidval[2], smaxxuid, lfd; int maxuid[2], uidval[2], smaxxuid, lfd;
unsigned find:1, cancel:1; unsigned find:1;
} sync_vars_t; } sync_vars_t;
#define AUX &svars->t[t] #define AUX &svars->t[t]
@ -185,27 +185,27 @@ typedef struct {
typedef struct copy_vars { typedef struct copy_vars {
void (*cb)( int sts, int uid, struct copy_vars *vars ); int (*cb)( int sts, int uid, struct copy_vars *vars );
void *aux; void *aux;
sync_rec_t *srec; /* also ->tuid */ sync_rec_t *srec; /* also ->tuid */
message_t *msg; message_t *msg;
msg_data_t data; msg_data_t data;
} copy_vars_t; } copy_vars_t;
static void msg_fetched( int sts, void *aux ); static int msg_fetched( int sts, void *aux );
static void static int
copy_msg( copy_vars_t *vars ) copy_msg( copy_vars_t *vars )
{ {
SVARS(vars->aux) SVARS(vars->aux)
vars->data.flags = vars->msg->flags; vars->data.flags = vars->msg->flags;
svars->drv[1-t]->fetch_msg( svars->ctx[1-t], vars->msg, &vars->data, msg_fetched, vars ); return svars->drv[1-t]->fetch_msg( svars->ctx[1-t], vars->msg, &vars->data, msg_fetched, vars );
} }
static void msg_stored( int sts, int uid, void *aux ); static int msg_stored( int sts, int uid, void *aux );
static void static int
msg_fetched( int sts, void *aux ) msg_fetched( int sts, void *aux )
{ {
copy_vars_t *vars = (copy_vars_t *)aux; copy_vars_t *vars = (copy_vars_t *)aux;
@ -254,8 +254,7 @@ msg_fetched( int sts, void *aux )
} }
/* invalid message */ /* invalid message */
free( fmap ); free( fmap );
vars->cb( SYNC_NOGOOD, 0, vars ); return vars->cb( SYNC_NOGOOD, 0, vars );
break;
} }
oke: oke:
if (cra || crd) if (cra || crd)
@ -310,24 +309,19 @@ msg_fetched( int sts, void *aux )
free( fmap ); free( fmap );
} }
svars->drv[t]->store_msg( svars->ctx[t], &vars->data, !vars->srec, msg_stored, vars ); return svars->drv[t]->store_msg( svars->ctx[t], &vars->data, !vars->srec, msg_stored, vars );
break;
case DRV_CANCELED: case DRV_CANCELED:
vars->cb( SYNC_CANCELED, 0, vars ); return vars->cb( SYNC_CANCELED, 0, vars );
break;
case DRV_MSG_BAD: case DRV_MSG_BAD:
vars->cb( SYNC_NOGOOD, 0, vars ); return vars->cb( SYNC_NOGOOD, 0, vars );
break;
case DRV_STORE_BAD: case DRV_STORE_BAD:
vars->cb( SYNC_BAD(1-t), 0, vars ); return vars->cb( SYNC_BAD(1-t), 0, vars );
break;
default: default:
vars->cb( SYNC_FAIL, 0, vars ); return vars->cb( SYNC_FAIL, 0, vars );
break;
} }
} }
static void static int
msg_stored( int sts, int uid, void *aux ) msg_stored( int sts, int uid, void *aux )
{ {
copy_vars_t *vars = (copy_vars_t *)aux; copy_vars_t *vars = (copy_vars_t *)aux;
@ -336,17 +330,13 @@ msg_stored( int sts, int uid, void *aux )
(void)svars; (void)svars;
switch (sts) { switch (sts) {
case DRV_OK: case DRV_OK:
vars->cb( SYNC_OK, uid, vars ); return vars->cb( SYNC_OK, uid, vars );
break;
case DRV_CANCELED: case DRV_CANCELED:
vars->cb( SYNC_CANCELED, 0, vars ); return vars->cb( SYNC_CANCELED, 0, vars );
break;
case DRV_STORE_BAD: case DRV_STORE_BAD:
vars->cb( SYNC_BAD(t), 0, vars ); return vars->cb( SYNC_BAD(t), 0, vars );
break;
default: default:
vars->cb( SYNC_FAIL, 0, vars ); return vars->cb( SYNC_FAIL, 0, vars );
break;
} }
} }
@ -387,7 +377,7 @@ cancel_sync( sync_vars_t *svars )
{ {
int t; int t;
svars->cancel = 1; /* the 1st round is guaranteed not to trash svars */
for (t = 0; t < 2; t++) for (t = 0; t < 2; t++)
if (svars->ret & SYNC_BAD(t)) if (svars->ret & SYNC_BAD(t))
cancel_done( DRV_STORE_BAD, AUX ); cancel_done( DRV_STORE_BAD, AUX );
@ -457,7 +447,7 @@ clean_strdup( const char *s )
#define JOURNAL_VERSION "2" #define JOURNAL_VERSION "2"
static void select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ); static int select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs );
void void
sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan,
@ -494,6 +484,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan,
if (!strcmp( chan->sync_state ? chan->sync_state : global_sync_state, "*" )) { if (!strcmp( chan->sync_state ? chan->sync_state : global_sync_state, "*" )) {
if (!ctx[S]->path) { if (!ctx[S]->path) {
error( "Error: store '%s' does not support in-box sync state\n", chan->stores[S]->name ); error( "Error: store '%s' does not support in-box sync state\n", chan->stores[S]->name );
free( svars );
cb( SYNC_BAD(S), aux ); cb( SYNC_BAD(S), aux );
return; return;
} }
@ -513,6 +504,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan,
if (!(s = strrchr( svars->dname, '/' ))) { if (!(s = strrchr( svars->dname, '/' ))) {
error( "Error: invalid SyncState '%s'\n", svars->dname ); error( "Error: invalid SyncState '%s'\n", svars->dname );
free( svars->dname ); free( svars->dname );
free( svars );
cb( SYNC_BAD(S), aux ); cb( SYNC_BAD(S), aux );
return; return;
} }
@ -520,6 +512,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan,
if (mkdir( svars->dname, 0700 ) && errno != EEXIST) { if (mkdir( svars->dname, 0700 ) && errno != EEXIST) {
error( "Error: cannot create SyncState directory '%s': %s\n", svars->dname, strerror(errno) ); error( "Error: cannot create SyncState directory '%s': %s\n", svars->dname, strerror(errno) );
free( svars->dname ); free( svars->dname );
free( svars );
cb( SYNC_BAD(S), aux ); cb( SYNC_BAD(S), aux );
return; return;
} }
@ -823,14 +816,14 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan,
svars->drv[S]->prepare_opts( ctx[S], opts[S] ); svars->drv[S]->prepare_opts( ctx[S], opts[S] );
svars->find = line != 0; svars->find = line != 0;
if (!svars->smaxxuid) if (!svars->smaxxuid && select_box( svars, M, (ctx[M]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 ))
select_box( svars, M, (ctx[M]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 ); return;
select_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 ); select_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 );
} }
static void box_selected( int sts, void *aux ); static int box_selected( int sts, void *aux );
static void static int
select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ) select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs )
{ {
sync_rec_t *srec; sync_rec_t *srec;
@ -849,7 +842,7 @@ select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs )
maxwuid = 0; maxwuid = 0;
info( "Selecting %s %s...\n", str_ms[t], svars->ctx[t]->name ); info( "Selecting %s %s...\n", str_ms[t], svars->ctx[t]->name );
debug( maxwuid == INT_MAX ? "selecting %s [%d,inf]\n" : "selecting %s [%d,%d]\n", str_ms[t], minwuid, maxwuid ); debug( maxwuid == INT_MAX ? "selecting %s [%d,inf]\n" : "selecting %s [%d,%d]\n", str_ms[t], minwuid, maxwuid );
svars->drv[t]->select( svars->ctx[t], minwuid, maxwuid, mexcs, nmexcs, box_selected, AUX ); return svars->drv[t]->select( svars->ctx[t], minwuid, maxwuid, mexcs, nmexcs, box_selected, AUX );
} }
typedef struct { typedef struct {
@ -857,10 +850,10 @@ typedef struct {
sync_rec_t *srec; sync_rec_t *srec;
} find_vars_t; } find_vars_t;
static void msg_found_sel( int sts, int uid, void *aux ); static int msg_found_sel( int sts, int uid, void *aux );
static void msgs_found_sel( sync_vars_t *svars, int t ); static int msgs_found_sel( sync_vars_t *svars, int t );
static void static int
box_selected( int sts, void *aux ) box_selected( int sts, void *aux )
{ {
SVARS(aux) SVARS(aux)
@ -868,13 +861,13 @@ box_selected( int sts, void *aux )
sync_rec_t *srec; sync_rec_t *srec;
if (check_ret( sts, svars, t )) if (check_ret( sts, svars, t ))
return; return 1;
if (svars->uidval[t] && svars->uidval[t] != svars->ctx[t]->uidvalidity) { if (svars->uidval[t] && svars->uidval[t] != svars->ctx[t]->uidvalidity) {
error( "Error: UIDVALIDITY of %s changed (got %d, expected %d)\n", error( "Error: UIDVALIDITY of %s changed (got %d, expected %d)\n",
str_ms[t], svars->ctx[t]->uidvalidity, svars->uidval[t] ); str_ms[t], svars->ctx[t]->uidvalidity, svars->uidval[t] );
svars->ret |= SYNC_FAIL; svars->ret |= SYNC_FAIL;
cancel_sync( svars ); cancel_sync( svars );
return; return 1;
} }
info( "%s: %d messages, %d recent\n", str_ms[t], svars->ctx[t]->count, svars->ctx[t]->recent ); info( "%s: %d messages, %d recent\n", str_ms[t], svars->ctx[t]->count, svars->ctx[t]->recent );
@ -897,24 +890,23 @@ box_selected( int sts, void *aux )
fv = nfmalloc( sizeof(*fv) ); fv = nfmalloc( sizeof(*fv) );
fv->aux = AUX; fv->aux = AUX;
fv->srec = srec; fv->srec = srec;
svars->drv[t]->find_msg( svars->ctx[t], srec->tuid, msg_found_sel, fv ); if (svars->drv[t]->find_msg( svars->ctx[t], srec->tuid, msg_found_sel, fv ))
if (svars->cancel) return 1;
return;
} }
} }
} }
svars->state[t] |= ST_SENT_FIND_OLD; svars->state[t] |= ST_SENT_FIND_OLD;
msgs_found_sel( svars, t ); return msgs_found_sel( svars, t );
} }
static void static int
msg_found_sel( int sts, int uid, void *aux ) msg_found_sel( int sts, int uid, void *aux )
{ {
find_vars_t *vars = (find_vars_t *)aux; find_vars_t *vars = (find_vars_t *)aux;
SVARS(vars->aux) SVARS(vars->aux)
if (check_ret_aux( sts, svars, t, vars )) if (check_ret_aux( sts, svars, t, vars ))
return; return 1;
switch (sts) { switch (sts) {
case DRV_OK: case DRV_OK:
debug( " -> new UID %d\n", uid ); debug( " -> new UID %d\n", uid );
@ -932,7 +924,7 @@ msg_found_sel( int sts, int uid, void *aux )
free( vars ); free( vars );
svars->find_old_done[t]++; svars->find_old_done[t]++;
stats( svars ); stats( svars );
msgs_found_sel( svars, t ); return msgs_found_sel( svars, t );
} }
typedef struct { typedef struct {
@ -941,15 +933,15 @@ typedef struct {
int aflags, dflags; int aflags, dflags;
} flag_vars_t; } flag_vars_t;
static void flags_set_del( int sts, void *aux ); static int flags_set_del( int sts, void *aux );
static void flags_set_sync( int sts, void *aux ); static int flags_set_sync( int sts, void *aux );
static void flags_set_sync_p2( sync_vars_t *svars, sync_rec_t *srec, int t ); static void flags_set_sync_p2( sync_vars_t *svars, sync_rec_t *srec, int t );
static void msgs_flags_set( sync_vars_t *svars, int t ); static int msgs_flags_set( sync_vars_t *svars, int t );
static void msg_copied( int sts, int uid, copy_vars_t *vars ); static int msg_copied( int sts, int uid, copy_vars_t *vars );
static void msg_copied_p2( sync_vars_t *svars, sync_rec_t *srec, int t, message_t *tmsg, int uid ); static void msg_copied_p2( sync_vars_t *svars, sync_rec_t *srec, int t, message_t *tmsg, int uid );
static void msgs_copied( sync_vars_t *svars, int t ); static int msgs_copied( sync_vars_t *svars, int t );
static void static int
msgs_found_sel( sync_vars_t *svars, int t ) msgs_found_sel( sync_vars_t *svars, int t )
{ {
sync_rec_t *srec, *nsrec = 0; sync_rec_t *srec, *nsrec = 0;
@ -962,7 +954,7 @@ msgs_found_sel( sync_vars_t *svars, int t )
char fbuf[16]; /* enlarge when support for keywords is added */ char fbuf[16]; /* enlarge when support for keywords is added */
if (!(svars->state[t] & ST_SENT_FIND_OLD) || svars->find_old_done[t] < svars->find_new_total[t]) if (!(svars->state[t] & ST_SENT_FIND_OLD) || svars->find_old_done[t] < svars->find_new_total[t])
return; return 0;
/* /*
* Mapping tmsg -> srec (this variant) is dog slow for new messages. * Mapping tmsg -> srec (this variant) is dog slow for new messages.
@ -1058,12 +1050,11 @@ msgs_found_sel( sync_vars_t *svars, int t )
for (t = 0; t < nmexcs; t++) for (t = 0; t < nmexcs; t++)
debugn( " %d", mexcs[t] ); debugn( " %d", mexcs[t] );
debug( "\n" ); debug( "\n" );
select_box( svars, M, minwuid, mexcs, nmexcs ); return select_box( svars, M, minwuid, mexcs, nmexcs );
return;
} }
if (!(svars->state[1-t] & ST_SENT_FIND_OLD) || svars->find_old_done[1-t] < svars->find_new_total[1-t]) if (!(svars->state[1-t] & ST_SENT_FIND_OLD) || svars->find_old_done[1-t] < svars->find_new_total[1-t])
return; return 0;
if (!svars->uidval[M] || !svars->uidval[S]) { if (!svars->uidval[M] || !svars->uidval[S]) {
svars->uidval[M] = svars->ctx[M]->uidvalidity; svars->uidval[M] = svars->ctx[M]->uidvalidity;
@ -1118,9 +1109,8 @@ msgs_found_sel( sync_vars_t *svars, int t )
cv->msg = tmsg; cv->msg = tmsg;
Fprintf( svars->jfp, "# %d %d %." stringify(TUIDL) "s\n", srec->uid[M], srec->uid[S], srec->tuid ); Fprintf( svars->jfp, "# %d %d %." stringify(TUIDL) "s\n", srec->uid[M], srec->uid[S], srec->tuid );
debug( " -> %sing message, TUID %." stringify(TUIDL) "s\n", str_hl[t], srec->tuid ); debug( " -> %sing message, TUID %." stringify(TUIDL) "s\n", str_hl[t], srec->tuid );
copy_msg( cv ); if (copy_msg( cv ))
if (svars->cancel) return 1;
return;
} else { } else {
if (tmsg->srec) { if (tmsg->srec) {
debug( " -> not %sing - still too big\n", str_hl[t] ); debug( " -> not %sing - still too big\n", str_hl[t] );
@ -1132,7 +1122,8 @@ msgs_found_sel( sync_vars_t *svars, int t )
} }
} }
svars->state[t] |= ST_SENT_NEW; svars->state[t] |= ST_SENT_NEW;
msgs_copied( svars, t ); if (msgs_copied( svars, t ))
return 1;
} }
debug( "synchronizing old entries\n" ); debug( "synchronizing old entries\n" );
@ -1170,9 +1161,8 @@ msgs_found_sel( sync_vars_t *svars, int t )
fv = nfmalloc( sizeof(*fv) ); fv = nfmalloc( sizeof(*fv) );
fv->aux = AUX; fv->aux = AUX;
fv->srec = srec; fv->srec = srec;
svars->drv[t]->set_flags( svars->ctx[t], srec->msg[t], srec->uid[t], F_DELETED, 0, flags_set_del, fv ); if (svars->drv[t]->set_flags( svars->ctx[t], srec->msg[t], srec->uid[t], F_DELETED, 0, flags_set_del, fv ))
if (svars->cancel) return 1;
return;
} else } else
debug( " not %sing delete\n", str_hl[t] ); debug( " not %sing delete\n", str_hl[t] );
} else if (!srec->msg[1-t]) } else if (!srec->msg[1-t])
@ -1282,9 +1272,8 @@ msgs_found_sel( sync_vars_t *svars, int t )
fv->srec = srec; fv->srec = srec;
fv->aflags = aflags; fv->aflags = aflags;
fv->dflags = dflags; fv->dflags = dflags;
svars->drv[t]->set_flags( svars->ctx[t], srec->msg[t], srec->uid[t], aflags, dflags, flags_set_sync, fv ); if (svars->drv[t]->set_flags( svars->ctx[t], srec->msg[t], srec->uid[t], aflags, dflags, flags_set_sync, fv ))
if (svars->cancel) return 1;
return;
} else } else
flags_set_sync_p2( svars, srec, t ); flags_set_sync_p2( svars, srec, t );
} }
@ -1292,11 +1281,13 @@ msgs_found_sel( sync_vars_t *svars, int t )
for (t = 0; t < 2; t++) { for (t = 0; t < 2; t++) {
svars->drv[t]->commit( svars->ctx[t] ); svars->drv[t]->commit( svars->ctx[t] );
svars->state[t] |= ST_SENT_FLAGS; svars->state[t] |= ST_SENT_FLAGS;
msgs_flags_set( svars, t ); if (msgs_flags_set( svars, t ))
return 1;
} }
return 0;
} }
static void static int
msg_copied( int sts, int uid, copy_vars_t *vars ) msg_copied( int sts, int uid, copy_vars_t *vars )
{ {
SVARS(vars->aux) SVARS(vars->aux)
@ -1314,12 +1305,12 @@ msg_copied( int sts, int uid, copy_vars_t *vars )
cancel_sync( svars ); cancel_sync( svars );
case SYNC_CANCELED: case SYNC_CANCELED:
free( vars ); free( vars );
return; return 1;
} }
free( vars ); free( vars );
svars->new_done[t]++; svars->new_done[t]++;
stats( svars ); stats( svars );
msgs_copied( svars, t ); return msgs_copied( svars, t );
} }
static void static void
@ -1340,17 +1331,17 @@ msg_copied_p2( sync_vars_t *svars, sync_rec_t *srec, int t, message_t *tmsg, int
} }
} }
static void msg_found_new( int sts, int uid, void *aux ); static int msg_found_new( int sts, int uid, void *aux );
static void sync_close( sync_vars_t *svars, int t ); static int sync_close( sync_vars_t *svars, int t );
static void static int
msgs_copied( sync_vars_t *svars, int t ) msgs_copied( sync_vars_t *svars, int t )
{ {
sync_rec_t *srec; sync_rec_t *srec;
find_vars_t *fv; find_vars_t *fv;
if (!(svars->state[t] & ST_SENT_NEW) || svars->new_done[t] < svars->new_total[t]) if (!(svars->state[t] & ST_SENT_NEW) || svars->new_done[t] < svars->new_total[t])
return; return 0;
debug( "finding just copied messages on %s\n", str_ms[t] ); debug( "finding just copied messages on %s\n", str_ms[t] );
for (srec = svars->srecs; srec; srec = srec->next) { for (srec = svars->srecs; srec; srec = srec->next) {
@ -1363,23 +1354,22 @@ msgs_copied( sync_vars_t *svars, int t )
fv = nfmalloc( sizeof(*fv) ); fv = nfmalloc( sizeof(*fv) );
fv->aux = AUX; fv->aux = AUX;
fv->srec = srec; fv->srec = srec;
svars->drv[t]->find_msg( svars->ctx[t], srec->tuid, msg_found_new, fv ); if (svars->drv[t]->find_msg( svars->ctx[t], srec->tuid, msg_found_new, fv ))
if (svars->cancel) return 1;
return;
} }
} }
svars->state[t] |= ST_SENT_FIND_NEW; svars->state[t] |= ST_SENT_FIND_NEW;
sync_close( svars, t ); return sync_close( svars, t );
} }
static void static int
msg_found_new( int sts, int uid, void *aux ) msg_found_new( int sts, int uid, void *aux )
{ {
find_vars_t *vars = (find_vars_t *)aux; find_vars_t *vars = (find_vars_t *)aux;
SVARS(vars->aux) SVARS(vars->aux)
if (check_ret_aux( sts, svars, t, vars )) if (check_ret_aux( sts, svars, t, vars ))
return; return 1;
switch (sts) { switch (sts) {
case DRV_OK: case DRV_OK:
debug( " -> new UID %d\n", uid ); debug( " -> new UID %d\n", uid );
@ -1395,17 +1385,17 @@ msg_found_new( int sts, int uid, void *aux )
free( vars ); free( vars );
svars->find_new_done[t]++; svars->find_new_done[t]++;
stats( svars ); stats( svars );
sync_close( svars, t ); return sync_close( svars, t );
} }
static void static int
flags_set_del( int sts, void *aux ) flags_set_del( int sts, void *aux )
{ {
flag_vars_t *vars = (flag_vars_t *)aux; flag_vars_t *vars = (flag_vars_t *)aux;
SVARS(vars->aux) SVARS(vars->aux)
if (check_ret_aux( sts, svars, t, vars )) if (check_ret_aux( sts, svars, t, vars ))
return; return 1;
switch (sts) { switch (sts) {
case DRV_OK: case DRV_OK:
vars->srec->status |= S_DEL(t); vars->srec->status |= S_DEL(t);
@ -1416,17 +1406,17 @@ flags_set_del( int sts, void *aux )
free( vars ); free( vars );
svars->flags_done[t]++; svars->flags_done[t]++;
stats( svars ); stats( svars );
msgs_flags_set( svars, t ); return msgs_flags_set( svars, t );
} }
static void static int
flags_set_sync( int sts, void *aux ) flags_set_sync( int sts, void *aux )
{ {
flag_vars_t *vars = (flag_vars_t *)aux; flag_vars_t *vars = (flag_vars_t *)aux;
SVARS(vars->aux) SVARS(vars->aux)
if (check_ret_aux( sts, svars, t, vars )) if (check_ret_aux( sts, svars, t, vars ))
return; return 1;
switch (sts) { switch (sts) {
case DRV_OK: case DRV_OK:
if (vars->aflags & F_DELETED) if (vars->aflags & F_DELETED)
@ -1439,7 +1429,7 @@ flags_set_sync( int sts, void *aux )
free( vars ); free( vars );
svars->flags_done[t]++; svars->flags_done[t]++;
stats( svars ); stats( svars );
msgs_flags_set( svars, t ); return msgs_flags_set( svars, t );
} }
static void static void
@ -1469,17 +1459,17 @@ flags_set_sync_p2( sync_vars_t *svars, sync_rec_t *srec, int t )
} }
} }
static void msg_trashed( int sts, void *aux ); static int msg_trashed( int sts, void *aux );
static void msg_rtrashed( int sts, int uid, copy_vars_t *vars ); static int msg_rtrashed( int sts, int uid, copy_vars_t *vars );
static void static int
msgs_flags_set( sync_vars_t *svars, int t ) msgs_flags_set( sync_vars_t *svars, int t )
{ {
message_t *tmsg; message_t *tmsg;
copy_vars_t *cv; 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_done[t] < svars->flags_total[t])
return; return 0;
if ((svars->chan->ops[t] & OP_EXPUNGE) && if ((svars->chan->ops[t] & OP_EXPUNGE) &&
(svars->ctx[t]->conf->trash || (svars->ctx[1-t]->conf->trash && svars->ctx[1-t]->conf->trash_remote_new))) { (svars->ctx[t]->conf->trash || (svars->ctx[1-t]->conf->trash && svars->ctx[1-t]->conf->trash_remote_new))) {
@ -1491,9 +1481,8 @@ msgs_flags_set( sync_vars_t *svars, int t )
debug( "%s: trashing message %d\n", str_ms[t], tmsg->uid ); debug( "%s: trashing message %d\n", str_ms[t], tmsg->uid );
svars->trash_total[t]++; svars->trash_total[t]++;
stats( svars ); stats( svars );
svars->drv[t]->trash_msg( svars->ctx[t], tmsg, msg_trashed, AUX ); if (svars->drv[t]->trash_msg( svars->ctx[t], tmsg, msg_trashed, AUX ))
if (svars->cancel) return 1;
return;
} else } else
debug( "%s: not trashing message %d - not new\n", str_ms[t], tmsg->uid ); debug( "%s: not trashing message %d - not new\n", str_ms[t], tmsg->uid );
} else { } else {
@ -1507,9 +1496,8 @@ msgs_flags_set( sync_vars_t *svars, int t )
cv->aux = AUX; cv->aux = AUX;
cv->srec = 0; cv->srec = 0;
cv->msg = tmsg; cv->msg = tmsg;
copy_msg( cv ); if (copy_msg( cv ))
if (svars->cancel) return 1;
return;
} else } else
debug( "%s: not remote trashing message %d - too big\n", str_ms[t], tmsg->uid ); debug( "%s: not remote trashing message %d - too big\n", str_ms[t], tmsg->uid );
} else } else
@ -1518,10 +1506,10 @@ msgs_flags_set( sync_vars_t *svars, int t )
} }
} }
svars->state[t] |= ST_SENT_TRASH; svars->state[t] |= ST_SENT_TRASH;
sync_close( svars, t ); return sync_close( svars, t );
} }
static void static int
msg_trashed( int sts, void *aux ) msg_trashed( int sts, void *aux )
{ {
SVARS(aux) SVARS(aux)
@ -1529,13 +1517,13 @@ msg_trashed( int sts, void *aux )
if (sts == DRV_MSG_BAD) if (sts == DRV_MSG_BAD)
sts = DRV_BOX_BAD; sts = DRV_BOX_BAD;
if (check_ret( sts, svars, t )) if (check_ret( sts, svars, t ))
return; return 1;
svars->trash_done[t]++; svars->trash_done[t]++;
stats( svars ); stats( svars );
sync_close( svars, t ); return sync_close( svars, t );
} }
static void static int
msg_rtrashed( int sts, int uid, copy_vars_t *vars ) msg_rtrashed( int sts, int uid, copy_vars_t *vars )
{ {
SVARS(vars->aux) SVARS(vars->aux)
@ -1549,41 +1537,43 @@ msg_rtrashed( int sts, int uid, copy_vars_t *vars )
cancel_sync( svars ); cancel_sync( svars );
case SYNC_CANCELED: case SYNC_CANCELED:
free( vars ); free( vars );
return; return 1;
} }
free( vars ); free( vars );
svars->trash_done[t]++; svars->trash_done[t]++;
stats( svars ); stats( svars );
sync_close( svars, t ); return sync_close( svars, t );
} }
static void box_closed( int sts, void *aux ); static int box_closed( int sts, void *aux );
static void box_closed_p2( sync_vars_t *svars, int t ); static void box_closed_p2( sync_vars_t *svars, int t );
static void static int
sync_close( sync_vars_t *svars, int t ) sync_close( sync_vars_t *svars, int t )
{ {
if ((~svars->state[t] & (ST_SENT_FIND_NEW|ST_SENT_TRASH)) || if ((~svars->state[t] & (ST_SENT_FIND_NEW|ST_SENT_TRASH)) ||
svars->find_new_done[t] < svars->find_new_total[t] || svars->find_new_done[t] < svars->find_new_total[t] ||
svars->trash_done[t] < svars->trash_total[t]) svars->trash_done[t] < svars->trash_total[t])
return; return 0;
if ((svars->chan->ops[t] & OP_EXPUNGE) /*&& !(svars->state[t] & ST_TRASH_BAD)*/) { if ((svars->chan->ops[t] & OP_EXPUNGE) /*&& !(svars->state[t] & ST_TRASH_BAD)*/) {
debug( "expunging %s\n", str_ms[t] ); debug( "expunging %s\n", str_ms[t] );
svars->drv[t]->close( svars->ctx[t], box_closed, AUX ); return svars->drv[t]->close( svars->ctx[t], box_closed, AUX );
} else }
box_closed_p2( svars, t ); box_closed_p2( svars, t );
return 0;
} }
static void static int
box_closed( int sts, void *aux ) box_closed( int sts, void *aux )
{ {
SVARS(aux) SVARS(aux)
if (check_ret( sts, svars, t )) if (check_ret( sts, svars, t ))
return; return 1;
svars->state[t] |= ST_DID_EXPUNGE; svars->state[t] |= ST_DID_EXPUNGE;
box_closed_p2( svars, t ); box_closed_p2( svars, t );
return 0;
} }
static void static void