diff --git a/src/sync.c b/src/sync.c index 9799716..023b5f0 100644 --- a/src/sync.c +++ b/src/sync.c @@ -107,14 +107,37 @@ typedef struct sync_rec { } sync_rec_t; static int -findmsgs( sync_rec_t *srecs, store_t *ctx[], int t, FILE *jfp ) +select_box( sync_rec_t *srecs, store_t *ctx[], int maxuid[], int uidval[], int t, int minwuid, int *mexcs, int nmexcs, FILE *jfp ) { sync_rec_t *srec, *nsrec = 0; message_t *msg; const char *diag; - int uid; + int uid, maxwuid; char fbuf[16]; /* enlarge when support for keywords is added */ + if (ctx[t]->opts & OPEN_NEW) { + if (minwuid > maxuid[t] + 1) + minwuid = maxuid[t] + 1; + maxwuid = INT_MAX; + } else if (ctx[t]->opts & OPEN_OLD) { + maxwuid = 0; + for (srec = srecs; srec; srec = srec->next) + if (!(srec->status & S_DEAD) && srec->uid[t] > maxwuid) + maxwuid = srec->uid[t]; + } else + maxwuid = 0; + info( "Selecting %s %s... ", str_ms[t], ctx[t]->name ); + debug( maxwuid == INT_MAX ? "selecting %s [%d,inf]\n" : "selecting %s [%d,%d]\n", str_ms[t], minwuid, maxwuid ); + switch (ctx[t]->conf->driver->select( ctx[t], minwuid, maxwuid, mexcs, nmexcs )) { + case DRV_STORE_BAD: return SYNC_BAD(t); + case DRV_BOX_BAD: return SYNC_FAIL; + } + if (uidval[t] && uidval[t] != ctx[t]->uidvalidity) { + fprintf( stderr, "Error: UIDVALIDITY of %s changed (got %d, expected %d)\n", str_ms[t], ctx[t]->uidvalidity, uidval[t] ); + return SYNC_FAIL; + } + info( "%d messages, %d recent\n", ctx[M]->count, ctx[M]->recent ); + if (jfp) { /* * Alternatively, the TUIDs could be fetched into the messages and @@ -355,7 +378,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) FILE *dfp, *jfp, *nfp; int opts[2]; int nom, nos, del[2], ex[2], nex; - int muidval, suidval, smaxxuid, maxuid[2], minwuid, maxwuid; + int uidval[2], smaxxuid, maxuid[2], minwuid; int t1, t2, t3, t, uid, nmsgs; int lfd, ret, line, sline, todel, *mexcs, nmexcs, rmexcs; unsigned char nflags, sflags, aflags, dflags; @@ -409,7 +432,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) nfasprintf( &jname, "%s.journal", dname ); nfasprintf( &nname, "%s.new", dname ); nfasprintf( &lname, "%s.lock", dname ); - muidval = suidval = smaxxuid = maxuid[M] = maxuid[S] = 0; + uidval[M] = uidval[S] = smaxxuid = maxuid[M] = maxuid[S] = 0; memset( &lck, 0, sizeof(lck) ); #if SEEK_SET != 0 lck.l_whence = SEEK_SET; @@ -436,7 +459,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) ret = SYNC_FAIL; goto bail; } - if (sscanf( buf, "%d:%d %d:%d:%d", &muidval, &maxuid[M], &suidval, &smaxxuid, &maxuid[S]) != 5) { + if (sscanf( buf, "%d:%d %d:%d:%d", &uidval[M], &maxuid[M], &uidval[S], &smaxxuid, &maxuid[S]) != 5) { fprintf( stderr, "Error: invalid sync state header in %s\n", dname ); fclose( dfp ); ret = SYNC_FAIL; @@ -528,8 +551,8 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) else if (buf[0] == ')') maxuid[S] = t1; else if (buf[0] == '|') { - muidval = t1; - suidval = t2; + uidval[M] = t1; + uidval[S] = t2; } else if (buf[0] == '+') { srec = nfmalloc( sizeof(*srec) ); srec->uid[M] = t1; @@ -689,28 +712,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) driver[M]->prepare_opts( ctx[M], opts[M] ); driver[S]->prepare_opts( ctx[S], opts[S] ); - if (ctx[S]->opts & OPEN_NEW) - maxwuid = INT_MAX; - else if (ctx[S]->opts & OPEN_OLD) { - maxwuid = 0; - for (srec = recs; srec; srec = srec->next) - if (!(srec->status & S_DEAD) && srec->uid[S] > maxwuid) - maxwuid = srec->uid[S]; - } else - maxwuid = 0; - info( "Selecting slave %s... ", ctx[S]->name ); - debug( maxwuid == INT_MAX ? "selecting slave [1,inf]\n" : "selecting slave [1,%d]\n", maxwuid ); - switch (driver[S]->select( ctx[S], (ctx[S]->opts & OPEN_OLD) ? 1 : maxuid[S] + 1, maxwuid, 0, 0 )) { - case DRV_STORE_BAD: ret = SYNC_BAD(S); goto bail; - case DRV_BOX_BAD: ret = SYNC_FAIL; goto bail; - } - if (suidval && suidval != ctx[S]->uidvalidity) { - fprintf( stderr, "Error: UIDVALIDITY of slave changed\n" ); - ret = SYNC_FAIL; - goto finish; - } - info( "%d messages, %d recent\n", ctx[S]->count, ctx[S]->recent ); - if ((ret = findmsgs( recs, ctx, S, line ? jfp : 0 )) != SYNC_OK) + if ((ret = select_box( recs, ctx, maxuid, uidval, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0, line ? jfp : 0 )) != SYNC_OK) goto finish; mexcs = 0; @@ -770,36 +772,13 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) debug( "\n" ); } else if (ctx[M]->opts & OPEN_OLD) minwuid = 1; - if (ctx[M]->opts & OPEN_NEW) { - if (minwuid > maxuid[M] + 1) - minwuid = maxuid[M] + 1; - maxwuid = INT_MAX; - } else if (ctx[M]->opts & OPEN_OLD) { - maxwuid = 0; - for (srec = recs; srec; srec = srec->next) - if (!(srec->status & S_DEAD) && srec->uid[M] > maxwuid) - maxwuid = srec->uid[M]; - } else - maxwuid = 0; - info( "Selecting master %s... ", ctx[M]->name ); - debug( maxwuid == INT_MAX ? "selecting master [%d,inf]\n" : "selecting master [%d,%d]\n", minwuid, maxwuid ); - switch (driver[M]->select( ctx[M], minwuid, maxwuid, mexcs, nmexcs )) { - case DRV_STORE_BAD: ret = SYNC_BAD(M); goto finish; - case DRV_BOX_BAD: ret = SYNC_FAIL; goto finish; - } - if (muidval && muidval != ctx[M]->uidvalidity) { - fprintf( stderr, "Error: UIDVALIDITY of master changed\n" ); - ret = SYNC_FAIL; - goto finish; - } - info( "%d messages, %d recent\n", ctx[M]->count, ctx[M]->recent ); - if ((ret = findmsgs( recs, ctx, M, line ? jfp : 0 )) != SYNC_OK) + if ((ret = select_box( recs, ctx, maxuid, uidval, M, minwuid, mexcs, nmexcs, line ? jfp : 0 )) != SYNC_OK) goto finish; - if (!muidval || !suidval) { - muidval = ctx[M]->uidvalidity; - suidval = ctx[S]->uidvalidity; - Fprintf( jfp, "| %d %d\n", muidval, suidval ); + if (!uidval[M] || !uidval[S]) { + uidval[M] = ctx[M]->uidvalidity; + uidval[S] = ctx[S]->uidvalidity; + Fprintf( jfp, "| %d %d\n", uidval[M], uidval[S] ); } info( "Synchronizing...\n" ); @@ -1160,7 +1139,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) } } - Fprintf( nfp, "%d:%d %d:%d:%d\n", muidval, maxuid[M], suidval, smaxxuid, maxuid[S] ); + Fprintf( nfp, "%d:%d %d:%d:%d\n", uidval[M], maxuid[M], uidval[S], smaxxuid, maxuid[S] ); for (srec = recs; srec; srec = srec->next) { if (srec->status & S_DEAD) continue;