commit 2fa75cf159d18c5705a877690b62f9e5de160c81
Author: Oswald Buddenhagen <[email protected]>
Date:   Sun Jan 11 14:29:19 2015 +0100

    fix UID assignment with some non-UIDPLUS servers
    
    the seznam.cz IMAP server seems very eager to send UIDNEXT responses
    despite not supporting UIDPLUS. this doesn't appear to be a particularly
    sensible combination, but it's valid nonetheless.
    
    however, that means that we need to save the UIDNEXT value before we
    start storing messages, lest imap_find_new_msgs() will simply overlook
    them. we do that outside the driver, in an already present field - this
    actually makes the main path more consistent with the journal recovery
    path.
    
    analysis by Tomas Tintera <[email protected]>.
    
    REFMAIL: [email protected]

 src/driver.h      |    2 +-
 src/drv_imap.c    |   21 ++++++++++++++-------
 src/drv_maildir.c |    2 +-
 src/sync.c        |    5 +++--
 4 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/src/driver.h b/src/driver.h
index 31ee1bf..4557aa6 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -192,7 +192,7 @@ struct driver {
        /* Index the messages which have newly appeared in the mailbox, 
including their
         * temporary UID headers. This is needed if store_msg() does not 
guarantee returning
         * a UID; otherwise the driver needs to implement only the OPEN_FIND 
flag. */
-       void (*find_new_msgs)( store_t *ctx,
+       void (*find_new_msgs)( store_t *ctx, int newuid,
                               void (*cb)( int sts, void *aux ), void *aux );
 
        /* Add/remove the named flags to/from the given message. The message 
may be either
diff --git a/src/drv_imap.c b/src/drv_imap.c
index e6d93ee..f58736d 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -153,6 +153,11 @@ struct imap_cmd_out_uid {
        int out_uid;
 };
 
+struct imap_cmd_find_new {
+       struct imap_cmd_simple gen;
+       int uid;
+};
+
 struct imap_cmd_refcounted_state {
        void (*callback)( int sts, void *aux );
        void *callback_aux;
@@ -2158,28 +2163,30 @@ imap_store_msg_p2( imap_store_t *ctx ATTR_UNUSED, 
struct imap_cmd *cmd, int resp
 static void imap_find_new_msgs_p2( imap_store_t *, struct imap_cmd *, int );
 
 static void
-imap_find_new_msgs( store_t *gctx,
+imap_find_new_msgs( store_t *gctx, int newuid,
                     void (*cb)( int sts, void *aux ), void *aux )
 {
        imap_store_t *ctx = (imap_store_t *)gctx;
-       struct imap_cmd_simple *cmd;
+       struct imap_cmd_find_new *cmd;
 
-       INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux)
-       imap_exec( (imap_store_t *)ctx, &cmd->gen, imap_find_new_msgs_p2, 
"CHECK" );
+       INIT_IMAP_CMD_X(imap_cmd_find_new, cmd, cb, aux)
+       cmd->uid = newuid;
+       imap_exec( (imap_store_t *)ctx, &cmd->gen.gen, imap_find_new_msgs_p2, 
"CHECK" );
 }
 
 static void
 imap_find_new_msgs_p2( imap_store_t *ctx, struct imap_cmd *gcmd, int response )
 {
-       struct imap_cmd_simple *cmdp = (struct imap_cmd_simple *)gcmd, *cmd;
+       struct imap_cmd_find_new *cmdp = (struct imap_cmd_find_new *)gcmd;
+       struct imap_cmd_simple *cmd;
 
        if (response != RESP_OK) {
                imap_done_simple_box( ctx, gcmd, response );
                return;
        }
-       INIT_IMAP_CMD(imap_cmd_simple, cmd, cmdp->callback, cmdp->callback_aux)
+       INIT_IMAP_CMD(imap_cmd_simple, cmd, cmdp->gen.callback, 
cmdp->gen.callback_aux)
        imap_exec( (imap_store_t *)ctx, &cmd->gen, imap_done_simple_box,
-                  "UID FETCH %d:1000000000 (UID BODY.PEEK[HEADER.FIELDS 
(X-TUID)])", ctx->gen.uidnext );
+                  "UID FETCH %d:1000000000 (UID BODY.PEEK[HEADER.FIELDS 
(X-TUID)])", cmdp->uid );
 }
 
 /******************* imap_list *******************/
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index f936938..f151b5b 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -1292,7 +1292,7 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int 
to_trash,
 }
 
 static void
-maildir_find_new_msgs( store_t *gctx ATTR_UNUSED,
+maildir_find_new_msgs( store_t *gctx ATTR_UNUSED, int newuid ATTR_UNUSED,
                        void (*cb)( int sts, void *aux ) ATTR_UNUSED, void *aux 
ATTR_UNUSED )
 {
        assert( !"maildir_find_new_msgs is not supposed to be called" );
diff --git a/src/sync.c b/src/sync.c
index 99f3895..443da1b 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -1506,7 +1506,8 @@ box_loaded( int sts, void *aux )
        if (UseFSync)
                fdatasync( fileno( svars->jfp ) );
        for (t = 0; t < 2; t++) {
-               Fprintf( svars->jfp, "%c %d\n", "{}"[t], svars->ctx[t]->uidnext 
);
+               svars->newuid[t] = svars->ctx[t]->uidnext;
+               Fprintf( svars->jfp, "%c %d\n", "{}"[t], svars->newuid[t] );
                for (tmsg = svars->ctx[1-t]->msgs; tmsg; tmsg = tmsg->next) {
                        if ((srec = tmsg->srec) && srec->tuid[0]) {
                                svars->new_total[t]++;
@@ -1604,7 +1605,7 @@ msgs_copied( sync_vars_t *svars, int t )
 
        if (svars->state[t] & ST_FIND_NEW) {
                debug( "finding just copied messages on %s\n", str_ms[t] );
-               svars->drv[t]->find_new_msgs( svars->ctx[t], msgs_found_new, 
AUX );
+               svars->drv[t]->find_new_msgs( svars->ctx[t], svars->newuid[t], 
msgs_found_new, AUX );
        } else {
                msgs_new_done( svars, t );
        }

------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to