From c886f71054a1f28a992cc1f81833c09aa44f1a31 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 24 Mar 2017 14:18:41 +0100 Subject: [PATCH] make driver_t::prepare_load_box() return the final options ... and make 'opts' private to the drivers. --- src/driver.h | 5 ++--- src/drv_imap.c | 22 +++++++++++++--------- src/drv_maildir.c | 16 ++++++++++------ src/sync.c | 22 +++++++++++----------- 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/driver.h b/src/driver.h index 24f137d..ea8b4f3 100644 --- a/src/driver.h +++ b/src/driver.h @@ -93,7 +93,6 @@ typedef struct store { message_t *msgs; /* own */ int uidvalidity; int uidnext; /* from SELECT responses */ - uint opts; /* maybe preset? */ /* note that the following do _not_ reflect stats from msgs, but mailbox totals */ int count; /* # of messages */ int recent; /* # of recent messages - don't trust this beyond the initial read */ @@ -196,8 +195,8 @@ struct driver { /* Invoked before load_box(), this informs the driver which operations (OP_*) * will be performed on the mailbox. The driver may extend the set by implicitly - * needed or available operations. */ - void (*prepare_load_box)( store_t *ctx, int opts ); + * needed or available operations. Returns this possibly extended set. */ + int (*prepare_load_box)( store_t *ctx, int opts ); /* Load the message attributes needed to perform the requested operations. * Consider only messages with UIDs between minuid and maxuid (inclusive) diff --git a/src/drv_imap.c b/src/drv_imap.c index 8eb3d31..2adb9fa 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -100,6 +100,7 @@ struct imap_store { const char *prefix; const char *name; int ref_count; + uint opts; enum { SST_BAD, SST_HALF, SST_GOOD } state; /* trash folder's existence is not confirmed yet */ enum { TrashUnknown, TrashChecking, TrashKnown } trashnc; @@ -2436,10 +2437,13 @@ imap_finish_delete_box( store_t *gctx ATTR_UNUSED ) /******************* imap_load_box *******************/ -static void +static int imap_prepare_load_box( store_t *gctx, int opts ) { - gctx->opts = opts; + imap_store_t *ctx = (imap_store_t *)gctx; + + ctx->opts = opts; + return opts; } enum { WantSize = 1, WantTuids = 2, WantMsgids = 4 }; @@ -2495,7 +2499,7 @@ imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int seenuid, i if (i != j) bl += sprintf( buf + bl, ":%d", excs.data[i] ); } - imap_submit_load( ctx, buf, shifted_bit( ctx->gen.opts, OPEN_OLD_IDS, WantMsgids ), sts ); + imap_submit_load( ctx, buf, shifted_bit( ctx->opts, OPEN_OLD_IDS, WantMsgids ), sts ); } if (maxuid == INT_MAX) maxuid = ctx->gen.uidnext - 1; @@ -2505,12 +2509,12 @@ imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int seenuid, i ranges[0].last = maxuid; ranges[0].flags = 0; int nranges = 1; - if (ctx->gen.opts & (OPEN_OLD_SIZE | OPEN_NEW_SIZE)) - imap_set_range( ranges, &nranges, shifted_bit( ctx->gen.opts, OPEN_OLD_SIZE, WantSize), - shifted_bit( ctx->gen.opts, OPEN_NEW_SIZE, WantSize), seenuid ); - if (ctx->gen.opts & OPEN_FIND) + if (ctx->opts & (OPEN_OLD_SIZE | OPEN_NEW_SIZE)) + imap_set_range( ranges, &nranges, shifted_bit( ctx->opts, OPEN_OLD_SIZE, WantSize), + shifted_bit( ctx->opts, OPEN_NEW_SIZE, WantSize), seenuid ); + if (ctx->opts & OPEN_FIND) imap_set_range( ranges, &nranges, 0, WantTuids, newuid - 1 ); - if (ctx->gen.opts & OPEN_OLD_IDS) + if (ctx->opts & OPEN_OLD_IDS) imap_set_range( ranges, &nranges, WantMsgids, 0, seenuid ); for (int r = 0; r < nranges; r++) { sprintf( buf, "%d:%d", ranges[r].first, ranges[r].last ); @@ -2527,7 +2531,7 @@ imap_submit_load( imap_store_t *ctx, const char *buf, int flags, imap_cmd_refcou { imap_exec( ctx, imap_refcounted_new_cmd( sts ), imap_refcounted_done_box, "UID FETCH %s (UID%s%s%s%s%s%s%s)", buf, - (ctx->gen.opts & OPEN_FLAGS) ? " FLAGS" : "", + (ctx->opts & OPEN_FLAGS) ? " FLAGS" : "", (flags & WantSize) ? " RFC822.SIZE" : "", (flags & (WantTuids | WantMsgids)) ? " BODY.PEEK[HEADER.FIELDS (" : "", (flags & WantTuids) ? "X-TUID" : "", diff --git a/src/drv_maildir.c b/src/drv_maildir.c index d888d2a..9ad2fac 100644 --- a/src/drv_maildir.c +++ b/src/drv_maildir.c @@ -69,6 +69,7 @@ typedef struct { typedef struct { store_t gen; + uint opts; int uvfd, uvok, nuid, is_inbox, fresh[3]; int minuid, maxuid, newuid, seenuid; int_array_t excs; @@ -1116,9 +1117,9 @@ maildir_scan( maildir_store_t *ctx, msg_t_array_alloc_t *msglist ) free( entry->base ); entry->base = nfstrndup( buf + bl + 4, fnl ); } - int want_size = (uid > ctx->seenuid) ? (ctx->gen.opts & OPEN_NEW_SIZE) : (ctx->gen.opts & OPEN_OLD_SIZE); - int want_tuid = ((ctx->gen.opts & OPEN_FIND) && uid >= ctx->newuid); - int want_msgid = ((ctx->gen.opts & OPEN_OLD_IDS) && uid <= ctx->seenuid); + int want_size = (uid > ctx->seenuid) ? (ctx->opts & OPEN_NEW_SIZE) : (ctx->opts & OPEN_OLD_SIZE); + int want_tuid = ((ctx->opts & OPEN_FIND) && uid >= ctx->newuid); + int want_msgid = ((ctx->opts & OPEN_OLD_IDS) && uid <= ctx->seenuid); if (!want_size && !want_tuid && !want_msgid) continue; if (!fnl) @@ -1201,7 +1202,7 @@ maildir_init_msg( maildir_store_t *ctx, maildir_message_t *msg, msg_t *entry ) memcpy( msg->gen.tuid, entry->tuid, TUIDL ); if (entry->recent) msg->gen.status |= M_RECENT; - if (ctx->gen.opts & OPEN_FLAGS) { + if (ctx->opts & OPEN_FLAGS) { msg->gen.status |= M_FLAGS; msg->gen.flags = maildir_parse_flags( ((maildir_store_conf_t *)ctx->gen.conf)->info_prefix, msg->base ); } else @@ -1383,14 +1384,17 @@ maildir_finish_delete_box( store_t *gctx ) return DRV_OK; } -static void +static int maildir_prepare_load_box( store_t *gctx, int opts ) { + maildir_store_t *ctx = (maildir_store_t *)gctx; + if (opts & OPEN_SETFLAGS) opts |= OPEN_OLD; if (opts & OPEN_EXPUNGE) opts |= OPEN_OLD|OPEN_NEW|OPEN_FLAGS; - gctx->opts = opts; + ctx->opts = opts; + return opts; } static void diff --git a/src/sync.c b/src/sync.c index a8d1e33..fcef2ce 100644 --- a/src/sync.c +++ b/src/sync.c @@ -153,7 +153,7 @@ typedef struct { const char *orig_name[2]; message_t *new_msgs[2]; int_array_alloc_t trashed_msgs[2]; - int state[2], ref_count, nsrecs, ret, lfd, existing, replayed; + int state[2], opts[2], ref_count, nsrecs, ret, lfd, existing, replayed; 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 */ @@ -1258,11 +1258,11 @@ box_opened2( sync_vars_t *svars, int t ) assert( !"sync record with stray TUID" ); } } - svars->drv[M]->prepare_load_box( ctx[M], opts[M] ); - svars->drv[S]->prepare_load_box( ctx[S], opts[S] ); + svars->opts[M] = svars->drv[M]->prepare_load_box( ctx[M], opts[M] ); + svars->opts[S] = svars->drv[S]->prepare_load_box( ctx[S], opts[S] ); ARRAY_INIT( &mexcs ); - if (svars->ctx[M]->opts & OPEN_OLD) { + if (svars->opts[M] & OPEN_OLD) { if (chan->max_messages) { /* When messages have been expired on the slave, the master fetch is split into * two ranges: The bulk fetch which corresponds with the most recent messages, and an @@ -1275,7 +1275,7 @@ box_opened2( sync_vars_t *svars, int t ) if (srec->status & S_DEAD) continue; if (srec->uid[M] > 0 && srec->uid[S] > 0 && minwuid > srec->uid[M] && - (!(svars->ctx[M]->opts & OPEN_NEW) || svars->maxuid[M] >= srec->uid[M])) { + (!(svars->opts[M] & OPEN_NEW) || svars->maxuid[M] >= srec->uid[M])) { /* The pair is alive, but outside the bulk range. */ *int_array_append( &mexcs ) = srec->uid[M]; } @@ -1294,7 +1294,7 @@ box_opened2( sync_vars_t *svars, int t ) sync_ref( svars ); load_box( svars, M, minwuid, mexcs.array ); if (!check_cancel( svars )) - load_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, (int_array_t){ 0, 0 } ); + load_box( svars, S, (svars->opts[S] & OPEN_OLD) ? 1 : INT_MAX, (int_array_t){ 0, 0 } ); sync_deref( svars ); } @@ -1315,15 +1315,15 @@ load_box( sync_vars_t *svars, int t, int minwuid, int_array_t mexcs ) { int maxwuid, seenuid; - if (svars->ctx[t]->opts & OPEN_NEW) { + if (svars->opts[t] & OPEN_NEW) { if (minwuid > svars->maxuid[t] + 1) minwuid = svars->maxuid[t] + 1; maxwuid = INT_MAX; - if (svars->ctx[t]->opts & (OPEN_OLD_IDS|OPEN_OLD_SIZE)) + if (svars->opts[t] & (OPEN_OLD_IDS|OPEN_OLD_SIZE)) seenuid = get_seenuid( svars, t ); else seenuid = 0; - } else if (svars->ctx[t]->opts & OPEN_OLD) { + } else if (svars->opts[t] & OPEN_OLD) { maxwuid = seenuid = get_seenuid( svars, t ); } else maxwuid = seenuid = 0; @@ -1482,8 +1482,8 @@ box_loaded( int sts, void *aux ) continue; debug( "pair (%d,%d)\n", srec->uid[M], srec->uid[S] ); // no[] means that a message is known to be not there. - no[M] = !srec->msg[M] && (svars->ctx[M]->opts & OPEN_OLD); - no[S] = !srec->msg[S] && (svars->ctx[S]->opts & OPEN_OLD); + no[M] = !srec->msg[M] && (svars->opts[M] & OPEN_OLD); + no[S] = !srec->msg[S] && (svars->opts[S] & OPEN_OLD); if (no[M] && no[S]) { // It does not matter whether one side was already known to be missing // (never stored [skipped or failed] or expunged [possibly expired]) -