From: Marcin Niestroj <macius19...@gmail.com> It turns out that some IMAP servers do not return messages in ascending UID order to a UID FETCH request. Below is a log fragment that shows `mbsync -D -a` on poczta.o2.pl mail server:
M: * 502 FETCH (UID 1221 FLAGS (\Seen)) M: * 164 FETCH (UID 164 FLAGS (\Seen)) M: * 1035 FETCH (UID 4377 FLAGS (\Seen)) M: * 715 FETCH (UID 2275 FLAGS (\Seen)) M: * 668 FETCH (UID 2005 FLAGS (\Seen)) M: * 15 FETCH (UID 15 FLAGS (\Seen)) M: * 393 FETCH (UID 427 FLAGS (\Seen)) M: * 801 FETCH (UID 2854 FLAGS (\Seen)) M: * 764 FETCH (UID 2620 FLAGS (\Seen)) M: * 583 FETCH (UID 1593 FLAGS (\Seen)) M: * 572 FETCH (UID 1564 FLAGS (\Seen)) M: * 457 FETCH (UID 934 FLAGS (\Seen)) M: * 67 FETCH (UID 67 FLAGS (\Seen \Answered)) ... uid= 1221, flags= S, size= 0, tuid=? uid= 164, flags= S, size= 0, tuid=? uid= 4377, flags= S, size= 0, tuid=? uid= 2275, flags= S, size= 0, tuid=? uid= 2005, flags= S, size= 0, tuid=? uid= 15, flags= S, size= 0, tuid=? uid= 427, flags= S, size= 0, tuid=? uid= 2854, flags= S, size= 0, tuid=? uid= 2620, flags= S, size= 0, tuid=? uid= 1593, flags= S, size= 0, tuid=? uid= 1564, flags= S, size= 0, tuid=? uid= 934, flags= S, size= 0, tuid=? uid= 67, flags= RS, size= 0, tuid=? ... master: 1335 messages, 0 recent matching messages on master against sync records Synchronizing... synchronizing old entries synchronizing new entries new message 1221 on master -> pair(1221,0) created -> updated flags to 16 new message 4377 on master -> pair(4377,0) created -> updated flags to 16 new message 4500 on master -> pair(4500,0) created -> updated flags to 16 new message 5960 on master -> pair(5960,0) created -> updated flags to 16 new message 6030 on master -> pair(6030,0) created -> updated flags to 16 new message 6048 on master -> pair(6048,0) created synchronizing flags As a result only 6 messages are downloaded out of 1335 in INBOX. This patch adds a new step after all messages from IMAP server are fetched. It sorts fetched messages in ascending UID order, so any code executed in later stages can rely on that. It solves issue described above with poczta.o2.pl server, so all 1335 (in that case) messages are downloaded. --- src/drv_imap.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/drv_imap.c b/src/drv_imap.c index 03eaf30..d964ddf 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -2593,6 +2593,64 @@ imap_load_box( store_t *gctx, uint minuid, uint maxuid, uint newuid, uint seenui } } +static int +imap_sort_msgs_comp( const void *a_, const void *b_ ) +{ + const message_t *a = *(const message_t * const *) a_; + const message_t *b = *(const message_t * const *) b_; + + if (a->uid < b->uid) + return -1; + else if (a->uid == b->uid) + return 0; + else + return 1; +} + +static size_t +imap_msgs_count( imap_store_t *ctx ) +{ + message_t *msg = ctx->msgs; + size_t count = 0; + + while (msg) { + count++; + msg = msg->next; + } + + return count; +} + +static void +imap_sort_msgs( imap_store_t *ctx ) +{ + size_t count = imap_msgs_count( ctx ); + message_t *m = ctx->msgs; + message_t **t; + size_t i; + + if (count <= 1) + return; + + t = nfmalloc( sizeof(*t) * count ); + + for (i = 0; i < count; i++) { + t[i] = m; + m = m->next; + } + + qsort( t, count, sizeof(*t), imap_sort_msgs_comp ); + + for (i = 0; i < count - 1; i++) + t[i]->next = t[i + 1]; + t[count - 1]->next = NULL; + + ctx->msgs = t[0]; + ctx->msgapp = &t[count - 1]->next; + + free(t); +} + static void imap_submit_load_p2( imap_store_t *, imap_cmd_t *, int ); static void @@ -2614,6 +2672,8 @@ imap_submit_load_p2( imap_store_t *ctx, imap_cmd_t *cmd, int response ) { imap_load_box_state_t *sts = (imap_load_box_state_t *)((imap_cmd_refcounted_t *)cmd)->state; + imap_sort_msgs( ctx ); + transform_refcounted_box_response( &sts->gen, response ); imap_submit_load_p3( ctx, sts ); } -- 2.19.1 _______________________________________________ isync-devel mailing list isync-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/isync-devel