commit a4c513800b37d394b6c28866557fe886bb9ed4e6 Author: Oswald Buddenhagen <o...@kde.org> Date: Sat Jul 23 16:06:32 2011 +0200
split out drv->load() from drv->select() src/drv_imap.c | 29 +++++++------ src/drv_maildir.c | 72 ++++++++++++++++++--------------- src/isync.h | 8 ++-- src/sync.c | 97 ++++++++++++++++++++++++++++---------------- 4 files changed, 121 insertions(+), 85 deletions(-) diff --git a/src/drv_imap.c b/src/drv_imap.c index 87f3f5d..0c35d58 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -1542,28 +1542,21 @@ imap_open_store( store_conf_t *conf, } static void -imap_prepare_paths( store_t *gctx ) -{ - free_generic_messages( gctx->msgs ); - gctx->msgs = 0; -} - -static void imap_prepare_opts( store_t *gctx, int opts ) { gctx->opts = opts; } static void -imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, +imap_select( store_t *gctx, int create, void (*cb)( int sts, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; struct imap_cmd *cmd = new_imap_cmd(); const char *prefix; - int ret, i, j, bl; - char buf[1000]; + free_generic_messages( gctx->msgs ); + gctx->msgs = 0; if (!strcmp( gctx->name, "INBOX" )) { prefix = ""; @@ -1573,10 +1566,18 @@ imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, ctx->uidnext = -1; - cmd->param.create = (gctx->opts & OPEN_CREATE) != 0; + cmd->param.create = create; cmd->param.trycreate = 1; - if ((ret = imap_exec_b( ctx, cmd, "SELECT \"%s%s\"", prefix, gctx->name )) != DRV_OK) - goto bail; + cb( imap_exec_b( ctx, cmd, "SELECT \"%s%s\"", prefix, gctx->name ), aux ); +} + +static void +imap_load( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, + void (*cb)( int sts, void *aux ), void *aux ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + int ret, i, j, bl; + char buf[1000]; if (gctx->count) { ctx->msgapp = &gctx->msgs; @@ -1907,9 +1908,9 @@ struct driver imap_driver = { imap_own_store, imap_cancel_store, imap_list, - imap_prepare_paths, imap_prepare_opts, imap_select, + imap_load, imap_fetch_msg, imap_store_msg, imap_find_msg, diff --git a/src/drv_maildir.c b/src/drv_maildir.c index bda598e..8b60553 100644 --- a/src/drv_maildir.c +++ b/src/drv_maildir.c @@ -745,9 +745,12 @@ maildir_app_msg( maildir_store_t *ctx, message_t ***msgapp, msg_t *entry ) } static void -maildir_prepare_paths( store_t *gctx ) +maildir_select( store_t *gctx, int create, + void (*cb)( int sts, void *aux ), void *aux ) { maildir_store_t *ctx = (maildir_store_t *)gctx; + int ret; + char uvpath[_POSIX_PATH_MAX]; maildir_cleanup( gctx ); gctx->msgs = 0; @@ -759,37 +762,8 @@ maildir_prepare_paths( store_t *gctx ) gctx->path = nfstrdup( ((maildir_store_conf_t *)gctx->conf)->inbox ); else nfasprintf( &gctx->path, "%s%s", gctx->conf->path, gctx->name ); -} - -static void -maildir_prepare_opts( store_t *gctx, int opts ) -{ - if (opts & OPEN_SETFLAGS) - opts |= OPEN_OLD; - if (opts & OPEN_EXPUNGE) - opts |= OPEN_OLD|OPEN_NEW|OPEN_FLAGS; - gctx->opts = opts; -} - -static void -maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, - void (*cb)( int sts, void *aux ), void *aux ) -{ - maildir_store_t *ctx = (maildir_store_t *)gctx; - message_t **msgapp; - msglist_t msglist; - int i; -#ifdef USE_DB - int ret; -#endif /* USE_DB */ - char uvpath[_POSIX_PATH_MAX]; - - ctx->minuid = minuid; - ctx->maxuid = maxuid; - ctx->excs = nfrealloc( excs, nexcs * sizeof(int) ); - ctx->nexcs = nexcs; - if ((ret = maildir_validate( gctx->path, "", ctx->gen.opts & OPEN_CREATE, ctx )) != DRV_OK) { + if ((ret = maildir_validate( gctx->path, "", create, ctx )) != DRV_OK) { cb( ret, aux ); return; } @@ -854,9 +828,43 @@ maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, ctx->nuid = ((int *)value.data)[1]; ctx->uvok = 1; } + cb( DRV_OK, aux ); + return; } fnok: #endif /* USE_DB */ + if ((ret = maildir_uidval_lock( ctx )) != DRV_OK) { + cb( ret, aux ); + return; + } + maildir_uidval_unlock( ctx ); + + cb( DRV_OK, aux ); +} + +static void +maildir_prepare_opts( store_t *gctx, int opts ) +{ + if (opts & OPEN_SETFLAGS) + opts |= OPEN_OLD; + if (opts & OPEN_EXPUNGE) + opts |= OPEN_OLD|OPEN_NEW|OPEN_FLAGS; + gctx->opts = opts; +} + +static void +maildir_load( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, + void (*cb)( int sts, void *aux ), void *aux ) +{ + maildir_store_t *ctx = (maildir_store_t *)gctx; + message_t **msgapp; + msglist_t msglist; + int i; + + ctx->minuid = minuid; + ctx->maxuid = maxuid; + ctx->excs = nfrealloc( excs, nexcs * sizeof(int) ); + ctx->nexcs = nexcs; if (maildir_scan( ctx, &msglist ) != DRV_OK) { cb( DRV_BOX_BAD, aux ); @@ -1302,9 +1310,9 @@ struct driver maildir_driver = { maildir_own_store, maildir_disown_store, /* _cancel_, but it's the same */ maildir_list, - maildir_prepare_paths, maildir_prepare_opts, maildir_select, + maildir_load, maildir_fetch_msg, maildir_store_msg, maildir_find_msg, diff --git a/src/isync.h b/src/isync.h index b34f08c..f18427a 100644 --- a/src/isync.h +++ b/src/isync.h @@ -142,7 +142,6 @@ typedef struct message { #define OPEN_NEW (1<<1) #define OPEN_FLAGS (1<<2) #define OPEN_SIZE (1<<3) -#define OPEN_CREATE (1<<4) #define OPEN_EXPUNGE (1<<5) #define OPEN_SETFLAGS (1<<6) #define OPEN_APPEND (1<<7) @@ -208,10 +207,11 @@ struct driver { void (*cancel_store)( store_t *ctx ); void (*list)( store_t *ctx, void (*cb)( int sts, void *aux ), void *aux ); - void (*prepare_paths)( store_t *ctx ); void (*prepare_opts)( store_t *ctx, int opts ); - void (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs, - void (*cb)( int sts, void *aux ), void *aux ); + void (*select)( store_t *ctx, int create, + void (*cb)( int sts, void *aux ), void *aux ); + void (*load)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs, + void (*cb)( int sts, void *aux ), void *aux ); void (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data, void (*cb)( int sts, void *aux ), void *aux ); void (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash, diff --git a/src/sync.c b/src/sync.c index f56c551..eb4faad 100644 --- a/src/sync.c +++ b/src/sync.c @@ -207,6 +207,7 @@ static int check_cancel( sync_vars_t *svars ); #define ST_CLOSED (1<<5) #define ST_SENT_CANCEL (1<<6) #define ST_CANCELED (1<<7) +#define ST_SELECTED (1<<8) #define ST_DID_EXPUNGE (1<<16) @@ -452,9 +453,13 @@ cancel_done( void *aux ) svars->state[t] |= ST_CANCELED; if (svars->state[1-t] & ST_CANCELED) { - Fclose( svars->nfp ); - Fclose( svars->jfp ); - sync_bail( svars ); + if (svars->lfd) { + Fclose( svars->nfp ); + Fclose( svars->jfp ); + sync_bail( svars ); + } else { + sync_bail2( svars ); + } } } @@ -537,21 +542,14 @@ clean_strdup( const char *s ) #define JOURNAL_VERSION "2" -static int select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ); +static void box_selected( int sts, void *aux ); void sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, void (*cb)( int sts, void *aux ), void *aux ) { sync_vars_t *svars; - sync_rec_t *srec, *nsrec; - char *s, *cmname, *csname; - FILE *jfp; - int opts[2], line, t1, t2, t3, t; - struct stat st; - struct flock lck; - char fbuf[16]; /* enlarge when support for keywords is added */ - char buf[64]; + int t; svars = nfcalloc( sizeof(*svars) ); svars->t[1] = 1; @@ -571,15 +569,44 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, ctx[t]->uidvalidity = -1; set_bad_callback( ctx[t], store_bad, AUX ); svars->drv[t] = ctx[t]->conf->driver; - svars->drv[t]->prepare_paths( ctx[t] ); + info( "Selecting %s %s...\n", str_ms[t], ctx[t]->name ); + DRIVER_CALL(select( ctx[t], (chan->ops[t] & OP_CREATE) != 0, box_selected, AUX )); } +} + +static int load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ); +static void +box_selected( int sts, void *aux ) +{ + DECL_SVARS; + sync_rec_t *srec, *nsrec; + char *s, *cmname, *csname; + store_t *ctx[2]; + channel_conf_t *chan; + FILE *jfp; + int opts[2], line, t1, t2, t3; + struct stat st; + struct flock lck; + char fbuf[16]; /* enlarge when support for keywords is added */ + char buf[64]; + + if (check_ret( sts, aux )) + return; + INIT_SVARS(aux); + ctx[0] = svars->ctx[0]; + ctx[1] = svars->ctx[1]; + svars->state[t] |= ST_SELECTED; + if (!(svars->state[1-t] & ST_SELECTED)) + return; + + chan = svars->chan; if (!strcmp( chan->sync_state ? chan->sync_state : global_sync_state, "*" )) { if (!ctx[S]->path) { error( "Error: store '%s' does not support in-box sync state\n", chan->stores[S]->name ); sbail: - free( svars ); - cb( SYNC_BAD(S), aux ); + svars->ret = SYNC_BAD(S); + sync_bail2( svars ); return; } nfasprintf( &svars->dname, "%s/." EXE "state", ctx[S]->path ); @@ -597,13 +624,11 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, } if (!(s = strrchr( svars->dname, '/' ))) { error( "Error: invalid SyncState '%s'\n", svars->dname ); - free( svars->dname ); goto sbail; } *s = 0; if (mkdir( svars->dname, 0700 ) && errno != EEXIST) { error( "Error: cannot create SyncState directory '%s': %s\n", svars->dname, strerror(errno) ); - free( svars->dname ); goto sbail; } *s = '/'; @@ -810,6 +835,17 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, goto bail; } } + + t1 = 0; + for (t = 0; t < 2; t++) + if (svars->uidval[t] >= 0 && svars->uidval[t] != ctx[t]->uidvalidity) { + error( "Error: UIDVALIDITY of %s changed (got %d, expected %d)\n", + str_ms[t], ctx[t]->uidvalidity, svars->uidval[t] ); + t1++; + } + if (t1) + goto bail; + if (!(svars->nfp = fopen( svars->nname, "w" ))) { error( "Error: cannot write new sync state %s\n", svars->nname ); goto bail; @@ -851,8 +887,6 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, } else if (chan->stores[1-t]->trash && chan->stores[1-t]->trash_remote_new) opts[t] |= OPEN_NEW|OPEN_FLAGS; } - if (chan->ops[t] & OP_CREATE) - opts[t] |= OPEN_CREATE; } if ((chan->ops[S] & (OP_NEW|OP_RENEW)) && chan->max_messages) opts[S] |= OPEN_OLD|OPEN_NEW|OPEN_FLAGS; @@ -873,15 +907,15 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, svars->drv[S]->prepare_opts( ctx[S], opts[S] ); svars->find = line != 0; - if (!svars->smaxxuid && select_box( svars, M, (ctx[M]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 )) + if (!svars->smaxxuid && load_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 ); + load_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 ); } -static void box_selected( int sts, void *aux ); +static void box_loaded( int sts, void *aux ); static int -select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ) +load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ) { sync_rec_t *srec; int maxwuid; @@ -897,9 +931,9 @@ select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ) maxwuid = srec->uid[t]; } else maxwuid = 0; - 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 ); - DRIVER_CALL_RET(select( svars->ctx[t], minwuid, maxwuid, mexcs, nmexcs, box_selected, AUX )); + info( "Loading %s...\n", str_ms[t] ); + debug( maxwuid == INT_MAX ? "loading %s [%d,inf]\n" : "loading %s [%d,%d]\n", str_ms[t], minwuid, maxwuid ); + DRIVER_CALL_RET(load( svars->ctx[t], minwuid, maxwuid, mexcs, nmexcs, box_loaded, AUX )); } typedef struct { @@ -911,19 +945,12 @@ static void msg_found_sel( int sts, int uid, void *aux ); static void msgs_found_sel( sync_vars_t *svars, int t ); static void -box_selected( int sts, void *aux ) +box_loaded( int sts, void *aux ) { find_vars_t *fv; sync_rec_t *srec; SVARS_CHECK_RET; - if (svars->uidval[t] >= 0 && svars->uidval[t] != svars->ctx[t]->uidvalidity) { - error( "Error: UIDVALIDITY of %s changed (got %d, expected %d)\n", - str_ms[t], svars->ctx[t]->uidvalidity, svars->uidval[t] ); - svars->ret |= SYNC_FAIL; - cancel_sync( svars ); - return; - } info( "%s: %d messages, %d recent\n", str_ms[t], svars->ctx[t]->count, svars->ctx[t]->recent ); if (svars->find) { @@ -1100,7 +1127,7 @@ msgs_found_sel( sync_vars_t *svars, int t ) for (t = 0; t < nmexcs; t++) debugn( " %d", mexcs[t] ); debug( "\n" ); - select_box( svars, M, minwuid, mexcs, nmexcs ); + load_box( svars, M, minwuid, mexcs, nmexcs ); return; } ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ isync-devel mailing list isync-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/isync-devel