isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit 04c7126ce9770fa5953c25953cd67e0169f34500
parent 767a318eea666a3af4881e3f351dcdabdf2df216
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Wed, 20 Apr 2022 11:15:30 +0200

add autotest for syncing non-UIDPLUS stores

Diffstat:
Msrc/common.h | 1+
Msrc/driver.h | 5++++-
Msrc/drv_maildir.c | 29++++++++++++++++++++---------
Msrc/main.c | 3+++
Msrc/run-tests.pl | 3+++
5 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/src/common.h b/src/common.h @@ -118,6 +118,7 @@ BIT_ENUM( FORCEJOURNAL, FORCEASYNC(2), FAKEEXPUNGE, + FAKEDUMBSTORE, ) #define DEBUG_ANY (DEBUG_MAILDIR | DEBUG_NET | DEBUG_SYNC | DEBUG_MAIN | DEBUG_DRV) diff --git a/src/driver.h b/src/driver.h @@ -240,7 +240,10 @@ struct driver { * Messages up to pairuid need to have the Message-Id populated when OPEN_PAIRED_IDS is set. * Messages up to newuid need to have the size populated when OPEN_OLD_SIZE is set; * likewise messages above newuid when OPEN_NEW_SIZE is set. - * The returned message list remains owned by the driver. */ + * The returned message list remains owned by the driver and remains valid + * until a new box is selected or the store is freed. New messages within + * the specified range may be added to the list as a result of invoking + * other driver functions. */ void (*load_box)( store_t *ctx, uint minuid, uint maxuid, uint finduid, uint pairuid, uint newuid, uint_array_t excs, void (*cb)( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux ), void *aux ); diff --git a/src/drv_maildir.c b/src/drv_maildir.c @@ -73,6 +73,7 @@ typedef union maildir_store { // but mailbox totals. also, don't trust them beyond the initial load. int total_msgs, recent_msgs; maildir_message_t *msgs; + maildir_message_t **app_msgs; // Only for testing find_new() wakeup_t lcktmr; void (*expunge_callback)( message_t *msg, void *aux ); @@ -1227,6 +1228,7 @@ maildir_select_box( store_t *gctx, const char *name ) maildir_cleanup( gctx ); ctx->msgs = NULL; + ctx->app_msgs = &ctx->msgs; ctx->excs.data = NULL; ctx->uvfd = -1; #ifdef USE_DB @@ -1426,6 +1428,7 @@ maildir_load_box( store_t *gctx, uint minuid, uint maxuid, uint finduid, uint pa ARRAY_SQUEEZE( &excs ); ctx->excs = excs; + assert( !ctx->msgs ); if (maildir_scan( ctx, &msglist ) != DRV_OK) { cb( DRV_BOX_BAD, NULL, 0, 0, aux ); return; @@ -1433,6 +1436,7 @@ maildir_load_box( store_t *gctx, uint minuid, uint maxuid, uint finduid, uint pa msgapp = &ctx->msgs; for (i = 0; i < msglist.array.size; i++) maildir_app_msg( ctx, &msgapp, msglist.array.data + i ); + ctx->app_msgs = msgapp; maildir_free_scan( &msglist ); cb( DRV_OK, &ctx->msgs->gen, ctx->total_msgs, ctx->recent_msgs, aux ); @@ -1451,12 +1455,8 @@ maildir_rescan( maildir_store_t *ctx ) debug( "Maildir processing rescan of %s:\n", ctx->path ); for (msgapp = &ctx->msgs, i = 0; (msg = *msgapp) || i < msglist.array.size; ) { if (!msg) { -#if 0 debug( " adding new message %u\n", msglist.array.data[i].uid ); maildir_app_msg( ctx, &msgapp, msglist.array.data + i ); -#else - debug( " ignoring new message %u\n", msglist.array.data[i].uid ); -#endif i++; } else if (i >= msglist.array.size) { debug( " purging deleted message %u\n", msg->uid ); @@ -1465,12 +1465,8 @@ maildir_rescan( maildir_store_t *ctx ) msgapp = &msg->next; } else if (msglist.array.data[i].uid < msg->uid) { /* this should not happen, actually */ -#if 0 debug( " adding new message %u\n", msglist.array.data[i].uid ); maildir_app_msg( ctx, &msgapp, msglist.array.data + i ); -#else - debug( " ignoring new message %u\n", msglist.array.data[i].uid ); -#endif i++; } else if (msglist.array.data[i].uid > msg->uid) { debug( " purging deleted message %u\n", msg->uid ); @@ -1655,10 +1651,25 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash, cb( DRV_BOX_BAD, 0, aux ); return; } + if (DFlags & FAKEDUMBSTORE) + uid = 0; cb( DRV_OK, uid, aux ); } static void +maildir_find_new_msgs( store_t *gctx, uint newuid, + void (*cb)( int sts, message_t *msgs, void *aux ), void *aux ) +{ + maildir_store_t *ctx = (maildir_store_t *)gctx; + + assert( DFlags & FAKEDUMBSTORE ); + ctx->opts |= OPEN_FIND; + ctx->finduid = newuid; + int ret = maildir_rescan( ctx ); + cb( ret, &(*ctx->app_msgs)->gen, aux ); +} + +static void maildir_set_msg_flags( store_t *gctx, message_t *gmsg, uint uid ATTR_UNUSED, int add, int del, void (*cb)( int sts, void *aux ), void *aux ) { @@ -1940,7 +1951,7 @@ struct driver maildir_driver = { maildir_load_box, maildir_fetch_msg, maildir_store_msg, - NULL, // find_new_msgs + maildir_find_new_msgs, maildir_set_msg_flags, maildir_trash_msg, maildir_close_box, diff --git a/src/main.c b/src/main.c @@ -461,6 +461,9 @@ main( int argc, char **argv ) case 's': JLimit = strtol( ochar, &ochar, 10 ); break; + case 'u': + DFlags |= FAKEDUMBSTORE; + break; case 'x': DFlags |= FAKEEXPUNGE; break; diff --git a/src/run-tests.pl b/src/run-tests.pl @@ -981,6 +981,9 @@ my @X01 = ( ); test("full", \@x01, \@X01, \@O01); +my @O01a = ("", "", "", "-Tu"); +test("full (non-UIDPLUS)", \@x01, \@X01, \@O01a); + my @O02 = ("", "", "Expunge Both\n"); my @X02 = ( M, 0, K,