commit 964e57a3db2d1cc9bdf177215c1a60d8a33d19f8
Author: Oswald Buddenhagen <[email protected]>
Date:   Sat Nov 27 18:10:07 2010 +0100

    fix error paths wrt sync drivers the right way
    
    instead of having essentially a second error path for the sync case,
    be more careful in the primary path.
    this reverts most of commit 023d3ee5775e0a805032d47d297c816d40577d77.

 src/drv_imap.c    |   51 +++++-----
 src/drv_maildir.c |  145 +++++++++++++++++----------
 src/isync.h       |   28 +++---
 src/sync.c        |  240 +++++++++++++++++++++++++--------------------
 4 files changed, 264 insertions(+), 200 deletions(-)

diff --git a/src/drv_imap.c b/src/drv_imap.c
index e403edc..9c4982d 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -1543,9 +1543,9 @@ imap_prepare_opts( store_t *gctx, int opts )
        gctx->opts = opts;
 }
 
-static int
+static void
 imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs,
-             int (*cb)( int sts, void *aux ), void *aux )
+             void (*cb)( int sts, void *aux ), void *aux )
 {
        imap_store_t *ctx = (imap_store_t *)gctx;
        struct imap_cmd *cmd = new_imap_cmd();
@@ -1598,18 +1598,18 @@ imap_select( store_t *gctx, int minuid, int maxuid, int 
*excs, int nexcs,
 
   bail:
        free( excs );
-       return cb( ret, aux );
+       cb( ret, aux );
 }
 
-static int
+static void
 imap_fetch_msg( store_t *ctx, message_t *msg, msg_data_t *data,
-                int (*cb)( int sts, void *aux ), void *aux )
+                void (*cb)( int sts, void *aux ), void *aux )
 {
        struct imap_cmd *cmd = new_imap_cmd();
        cmd->param.uid = msg->uid;
        cmd->param.aux = data;
-       return cb( imap_exec_m( (imap_store_t *)ctx, cmd, "UID FETCH %d 
(%sBODY.PEEK[])",
-                               msg->uid, (msg->status & M_FLAGS) ? "" : "FLAGS 
" ), aux );
+       cb( imap_exec_m( (imap_store_t *)ctx, cmd, "UID FETCH %d 
(%sBODY.PEEK[])",
+                        msg->uid, (msg->status & M_FLAGS) ? "" : "FLAGS " ), 
aux );
 }
 
 static int
@@ -1642,9 +1642,9 @@ imap_flags_helper( imap_store_t *ctx, int uid, char what, 
int flags)
        return DRV_OK;
 }
 
-static int
+static void
 imap_set_flags( store_t *gctx, message_t *msg, int uid, int add, int del,
-                int (*cb)( int sts, void *aux ), void *aux )
+                void (*cb)( int sts, void *aux ), void *aux )
 {
        imap_store_t *ctx = (imap_store_t *)gctx;
        int ret;
@@ -1659,31 +1659,31 @@ imap_set_flags( store_t *gctx, message_t *msg, int uid, 
int add, int del,
        if ((!add || (ret = imap_flags_helper( ctx, uid, '+', add )) == DRV_OK) 
&&
            (!del || (ret = imap_flags_helper( ctx, uid, '-', del )) == DRV_OK))
                ret = DRV_OK;
-       return cb( ret, aux );
+       cb( ret, aux );
 }
 
-static int
+static void
 imap_close( store_t *ctx,
-            int (*cb)( int sts, void *aux ), void *aux )
+            void (*cb)( int sts, void *aux ), void *aux )
 {
-       return cb( imap_exec_b( (imap_store_t *)ctx, 0, "CLOSE" ), aux );
+       cb( imap_exec_b( (imap_store_t *)ctx, 0, "CLOSE" ), aux );
 }
 
-static int
+static void
 imap_trash_msg( store_t *gctx, message_t *msg,
-                int (*cb)( int sts, void *aux ), void *aux )
+                void (*cb)( int sts, void *aux ), void *aux )
 {
        imap_store_t *ctx = (imap_store_t *)gctx;
        struct imap_cmd *cmd = new_imap_cmd();
        cmd->param.create = 1;
        cmd->param.to_trash = 1;
-       return cb( imap_exec_m( ctx, cmd, "UID COPY %d \"%s%s\"",
-                               msg->uid, ctx->prefix, gctx->conf->trash ), aux 
);
+       cb( imap_exec_m( ctx, cmd, "UID COPY %d \"%s%s\"",
+                        msg->uid, ctx->prefix, gctx->conf->trash ), aux );
 }
 
-static int
+static void
 imap_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
-                int (*cb)( int sts, int uid, void *aux ), void *aux )
+                void (*cb)( int sts, int uid, void *aux ), void *aux )
 {
        imap_store_t *ctx = (imap_store_t *)gctx;
        struct imap_cmd *cmd = new_imap_cmd();
@@ -1714,14 +1714,13 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int 
to_trash,
        }
        ret = imap_exec_m( ctx, cmd, "APPEND \"%s%s\" %s", prefix, box, flagstr 
);
        if (ret != DRV_OK)
-               return cb( ret, -1, aux );
-
-       return cb( DRV_OK, uid, aux );
+               uid = -1;
+       cb( ret, uid, aux );
 }
 
-static int
+static void
 imap_find_msg( store_t *gctx, const char *tuid,
-               int (*cb)( int sts, int uid, void *aux ), void *aux )
+               void (*cb)( int sts, int uid, void *aux ), void *aux )
 {
        imap_store_t *ctx = (imap_store_t *)gctx;
        struct imap_cmd *cmd = new_imap_cmd();
@@ -1731,9 +1730,9 @@ imap_find_msg( store_t *gctx, const char *tuid,
        cmd->param.aux = &uid;
        uid = -1; /* in case we get no SEARCH response at all */
        if ((ret = imap_exec_m( ctx, cmd, "UID SEARCH HEADER X-TUID %." 
stringify(TUIDL) "s", tuid )) != DRV_OK)
-               return cb( ret, -1, aux );
+               cb( ret, -1, aux );
        else
-               return cb( uid <= 0 ? DRV_MSG_BAD : DRV_OK, uid, aux );
+               cb( uid <= 0 ? DRV_MSG_BAD : DRV_OK, uid, aux );
 }
 
 static void
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index 5213922..1533890 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -764,9 +764,9 @@ maildir_prepare_opts( store_t *gctx, int opts )
        gctx->opts = opts;
 }
 
-static int
+static void
 maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs,
-                int (*cb)( int sts, void *aux ), void *aux )
+                void (*cb)( int sts, void *aux ), void *aux )
 {
        maildir_store_t *ctx = (maildir_store_t *)gctx;
        message_t **msgapp;
@@ -782,14 +782,17 @@ maildir_select( store_t *gctx, int minuid, int maxuid, 
int *excs, int nexcs,
        ctx->excs = nfrealloc( excs, nexcs * sizeof(int) );
        ctx->nexcs = nexcs;
 
-       if (maildir_validate( gctx->path, "", ctx->gen.opts & OPEN_CREATE ) != 
DRV_OK)
-               return cb( DRV_BOX_BAD, aux );
+       if (maildir_validate( gctx->path, "", ctx->gen.opts & OPEN_CREATE ) != 
DRV_OK) {
+               cb( DRV_BOX_BAD, aux );
+               return;
+       }
 
        nfsnprintf( uvpath, sizeof(uvpath), "%s/.uidvalidity", gctx->path );
 #ifndef USE_DB
        if ((ctx->uvfd = open( uvpath, O_RDWR|O_CREAT, 0600 )) < 0) {
                perror( uvpath );
-               return cb( DRV_BOX_BAD, aux );
+               cb( DRV_BOX_BAD, aux );
+               return;
        }
 #else
        if ((ctx->uvfd = open( uvpath, O_RDWR, 0600 )) < 0) {
@@ -804,7 +807,8 @@ maildir_select( store_t *gctx, int minuid, int maxuid, int 
*excs, int nexcs,
                                        goto fnok;
                        }
                        perror( uvpath );
-                       return cb( DRV_BOX_BAD, aux );
+                       cb( DRV_BOX_BAD, aux );
+                       return;
                }
          dbok:
 #if SEEK_SET != 0
@@ -816,7 +820,8 @@ maildir_select( store_t *gctx, int minuid, int maxuid, int 
*excs, int nexcs,
                  bork:
                        close( ctx->uvfd );
                        ctx->uvfd = -1;
-                       return cb( DRV_BOX_BAD, aux );
+                       cb( DRV_BOX_BAD, aux );
+                       return;
                }
                if (db_create( &ctx->db, 0, 0 )) {
                        fputs( "Maildir error: db_create() failed\n", stderr );
@@ -846,14 +851,16 @@ maildir_select( store_t *gctx, int minuid, int maxuid, 
int *excs, int nexcs,
   fnok:
 #endif /* USE_DB */
 
-       if (maildir_scan( ctx, &msglist ) != DRV_OK)
-               return cb( DRV_BOX_BAD, aux );
+       if (maildir_scan( ctx, &msglist ) != DRV_OK) {
+               cb( DRV_BOX_BAD, aux );
+               return;
+       }
        msgapp = &ctx->gen.msgs;
        for (i = 0; i < msglist.nents; i++)
                maildir_app_msg( ctx, &msgapp, msglist.ents + i );
        maildir_free_scan( &msglist );
 
-       return cb( DRV_OK, aux );
+       cb( DRV_OK, aux );
 }
 
 static int
@@ -921,9 +928,9 @@ maildir_again( maildir_store_t *ctx, maildir_message_t 
*msg, const char *fn )
        return (msg->gen.status & M_DEAD) ? DRV_MSG_BAD : DRV_OK;
 }
 
-static int
+static void
 maildir_fetch_msg( store_t *gctx, message_t *gmsg, msg_data_t *data,
-                   int (*cb)( int sts, void *aux ), void *aux )
+                   void (*cb)( int sts, void *aux ), void *aux )
 {
        maildir_store_t *ctx = (maildir_store_t *)gctx;
        maildir_message_t *msg = (maildir_message_t *)gmsg;
@@ -935,8 +942,10 @@ maildir_fetch_msg( store_t *gctx, message_t *gmsg, 
msg_data_t *data,
                nfsnprintf( buf, sizeof(buf), "%s/%s/%s", gctx->path, 
subdirs[gmsg->status & M_RECENT], msg->base );
                if ((fd = open( buf, O_RDONLY )) >= 0)
                        break;
-               if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK)
-                       return cb( ret, aux );
+               if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK) {
+                       cb( ret, aux );
+                       return;
+               }
        }
        fstat( fd, &st );
        data->len = st.st_size;
@@ -944,12 +953,13 @@ maildir_fetch_msg( store_t *gctx, message_t *gmsg, 
msg_data_t *data,
        if (read( fd, data->data, data->len ) != data->len) {
                perror( buf );
                close( fd );
-               return cb( DRV_MSG_BAD, aux );
+               cb( DRV_MSG_BAD, aux );
+               return;
        }
        close( fd );
        if (!(gmsg->status & M_FLAGS))
                data->flags = maildir_parse_flags( msg->base );
-       return cb( DRV_OK, aux );
+       cb( DRV_OK, aux );
 }
 
 static int
@@ -967,9 +977,9 @@ maildir_make_flags( int flags, char *buf )
        return d;
 }
 
-static int
+static void
 maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
-                   int (*cb)( int sts, int uid, void *aux ), void *aux )
+                   void (*cb)( int sts, int uid, void *aux ), void *aux )
 {
        maildir_store_t *ctx = (maildir_store_t *)gctx;
        const char *prefix, *box;
@@ -982,14 +992,17 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int 
to_trash,
                if (ctx->db) {
                        if ((ret = maildir_set_uid( ctx, base, &uid )) != 
DRV_OK) {
                                free( data->data );
-                               return cb( ret, 0, aux );
+                               cb( ret, 0, aux );
+                               return;
                        }
                } else
 #endif /* USE_DB */
                {
                        if ((ret = maildir_uidval_lock( ctx )) != DRV_OK ||
-                           (ret = maildir_obtain_uid( ctx, &uid )) != DRV_OK)
-                               return cb( ret, 0, aux );
+                           (ret = maildir_obtain_uid( ctx, &uid )) != DRV_OK) {
+                               cb( ret, 0, aux );
+                               return;
+                       }
                        maildir_uidval_unlock( ctx );
                        nfsnprintf( base + bl, sizeof(base) - bl, ",U=%d", uid 
);
                }
@@ -1006,16 +1019,19 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int 
to_trash,
                if (errno != ENOENT) {
                        perror( buf );
                        free( data->data );
-                       return cb( DRV_BOX_BAD, 0, aux );
+                       cb( DRV_BOX_BAD, 0, aux );
+                       return;
                }
                if ((ret = maildir_validate( gctx->conf->path, 
gctx->conf->trash, gctx->opts & OPEN_CREATE )) != DRV_OK) {
                        free( data->data );
-                       return cb( ret, 0, aux );
+                       cb( ret, 0, aux );
+                       return;
                }
                if ((fd = open( buf, O_WRONLY|O_CREAT|O_EXCL, 0600 )) < 0) {
                        perror( buf );
                        free( data->data );
-                       return cb( DRV_BOX_BAD, 0, aux );
+                       cb( DRV_BOX_BAD, 0, aux );
+                       return;
                }
        }
        ret = write( fd, data->data, data->len );
@@ -1026,34 +1042,38 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int 
to_trash,
                else
                        error( "Maildir error: %s: partial write\n", buf );
                close( fd );
-               return cb( DRV_BOX_BAD, 0, aux );
+               cb( DRV_BOX_BAD, 0, aux );
+               return;
        }
        close( fd );
        /* Moving seen messages to cur/ is strictly speaking incorrect, but 
makes mutt happy. */
        nfsnprintf( nbuf, sizeof(nbuf), "%s%s/%s/%s%s", prefix, box, 
subdirs[!(data->flags & F_SEEN)], base, fbuf );
        if (rename( buf, nbuf )) {
                perror( nbuf );
-               return cb( DRV_BOX_BAD, 0, aux );
+               cb( DRV_BOX_BAD, 0, aux );
+               return;
        }
-       return cb( DRV_OK, uid, aux );
+       cb( DRV_OK, uid, aux );
 }
 
-static int
+static void
 maildir_find_msg( store_t *gctx, const char *tuid,
-                  int (*cb)( int sts, int uid, void *aux ), void *aux )
+                  void (*cb)( int sts, int uid, void *aux ), void *aux )
 {
        message_t *msg;
 
        /* using a hash table might turn out to be more appropriate ... */
        for (msg = gctx->msgs; msg; msg = msg->next)
-               if (!(msg->status & M_DEAD) && !memcmp( ((maildir_message_t 
*)msg)->tuid, tuid, TUIDL ))
-                       return cb( DRV_OK, msg->uid, aux );
-       return cb( DRV_MSG_BAD, -1, aux );
+               if (!(msg->status & M_DEAD) && !memcmp( ((maildir_message_t 
*)msg)->tuid, tuid, TUIDL )) {
+                       cb( DRV_OK, msg->uid, aux );
+                       return;
+               }
+       cb( DRV_MSG_BAD, -1, aux );
 }
 
-static int
+static void
 maildir_set_flags( store_t *gctx, message_t *gmsg, int uid, int add, int del,
-                   int (*cb)( int sts, void *aux ), void *aux )
+                   void (*cb)( int sts, void *aux ), void *aux )
 {
        maildir_store_t *ctx = (maildir_store_t *)gctx;
        maildir_message_t *msg = (maildir_message_t *)gmsg;
@@ -1095,8 +1115,10 @@ maildir_set_flags( store_t *gctx, message_t *gmsg, int 
uid, int add, int del,
                }
                if (!rename( buf, nbuf ))
                        break;
-               if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK)
-                       return cb( ret, aux );
+               if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK) {
+                       cb( ret, aux );
+                       return;
+               }
        }
        free( msg->base );
        msg->base = nfmalloc( tl + 1 );
@@ -1105,7 +1127,7 @@ maildir_set_flags( store_t *gctx, message_t *gmsg, int 
uid, int add, int del,
        msg->gen.flags &= ~del;
        gmsg->status &= ~M_RECENT;
 
-       return cb( DRV_OK, aux );
+       cb( DRV_OK, aux );
 }
 
 #ifdef USE_DB
@@ -1125,9 +1147,9 @@ maildir_purge_msg( maildir_store_t *ctx, const char *name 
)
 }
 #endif /* USE_DB */
 
-static int
+static void
 maildir_trash_msg( store_t *gctx, message_t *gmsg,
-                   int (*cb)( int sts, void *aux ), void *aux )
+                   void (*cb)( int sts, void *aux ), void *aux )
 {
        maildir_store_t *ctx = (maildir_store_t *)gctx;
        maildir_message_t *msg = (maildir_message_t *)gmsg;
@@ -1144,31 +1166,38 @@ maildir_trash_msg( store_t *gctx, message_t *gmsg,
                if (!rename( buf, nbuf ))
                        break;
                if (!stat( buf, &st )) {
-                       if ((ret = maildir_validate( gctx->conf->path, 
gctx->conf->trash, 1 )) != DRV_OK)
-                               return cb( ret, aux );
+                       if ((ret = maildir_validate( gctx->conf->path, 
gctx->conf->trash, 1 )) != DRV_OK) {
+                               cb( ret, aux );
+                               return;
+                       }
                        if (!rename( buf, nbuf ))
                                break;
                        if (errno != ENOENT) {
                                perror( nbuf );
-                               return cb( DRV_BOX_BAD, aux );
+                               cb( DRV_BOX_BAD, aux );
+                               return;
                        }
                }
-               if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK)
-                       return cb( ret, aux );
+               if ((ret = maildir_again( ctx, msg, buf )) != DRV_OK) {
+                       cb( ret, aux );
+                       return;
+               }
        }
        gmsg->status |= M_DEAD;
        gctx->count--;
 
 #ifdef USE_DB
-       if (ctx->db)
-               return cb( maildir_purge_msg( ctx, msg->base ), aux );
+       if (ctx->db) {
+               cb( maildir_purge_msg( ctx, msg->base ), aux );
+               return;
+       }
 #endif /* USE_DB */
-       return cb( DRV_OK, aux );
+       cb( DRV_OK, aux );
 }
 
-static int
+static void
 maildir_close( store_t *gctx,
-               int (*cb)( int sts, void *aux ), void *aux )
+               void (*cb)( int sts, void *aux ), void *aux )
 {
 #ifdef USE_DB
        maildir_store_t *ctx = (maildir_store_t *)gctx;
@@ -1192,15 +1221,21 @@ maildir_close( store_t *gctx,
                                        msg->status |= M_DEAD;
                                        gctx->count--;
 #ifdef USE_DB
-                                       if (ctx->db && (ret = 
maildir_purge_msg( ctx, ((maildir_message_t *)msg)->base )) != DRV_OK)
-                                               return cb( ret, aux );
+                                       if (ctx->db && (ret = 
maildir_purge_msg( ctx, ((maildir_message_t *)msg)->base )) != DRV_OK) {
+                                               cb( ret, aux );
+                                               return;
+                                       }
 #endif /* USE_DB */
                                }
                        }
-               if (!retry)
-                       return cb( DRV_OK, aux );
-               if ((ret = maildir_rescan( (maildir_store_t *)gctx )) != DRV_OK)
-                       return cb( ret, aux );
+               if (!retry) {
+                       cb( DRV_OK, aux );
+                       return;
+               }
+               if ((ret = maildir_rescan( (maildir_store_t *)gctx )) != 
DRV_OK) {
+                       cb( ret, aux );
+                       return;
+               }
        }
 }
 
diff --git a/src/isync.h b/src/isync.h
index 7f05796..c8f2f00 100644
--- a/src/isync.h
+++ b/src/isync.h
@@ -195,20 +195,20 @@ struct driver {
                      void (*cb)( int sts, void *aux ), void *aux );
        void (*prepare_paths)( store_t *ctx );
        void (*prepare_opts)( store_t *ctx, int opts );
-       int (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int 
nexcs,
-                      int (*cb)( int sts, void *aux ), void *aux );
-       int (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data,
-                         int (*cb)( int sts, void *aux ), void *aux );
-       int (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash,
-                         int (*cb)( int sts, int uid, void *aux ), void *aux );
-       int (*find_msg)( store_t *ctx, const char *tuid,
-                        int (*cb)( int sts, int uid, void *aux ), void *aux );
-       int (*set_flags)( store_t *ctx, message_t *msg, int uid, int add, int 
del, /* msg can be null, therefore uid as a fallback */
-                         int (*cb)( int sts, void *aux ), void *aux );
-       int (*trash_msg)( store_t *ctx, message_t *msg, /* This may expunge the 
original message immediately, but it needn't to */
-                         int (*cb)( int sts, void *aux ), void *aux );
-       int (*close)( store_t *ctx, /* IMAP-style: expunge inclusive */
-                     int (*cb)( int sts, void *aux ), void *aux );
+       void (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int 
nexcs,
+                       void (*cb)( int sts, void *aux ), void *aux );
+       void (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data,
+                          void (*cb)( int sts, void *aux ), void *aux );
+       void (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash,
+                          void (*cb)( int sts, int uid, void *aux ), void *aux 
);
+       void (*find_msg)( store_t *ctx, const char *tuid,
+                         void (*cb)( int sts, int uid, void *aux ), void *aux 
);
+       void (*set_flags)( store_t *ctx, message_t *msg, int uid, int add, int 
del, /* msg can be null, therefore uid as a fallback */
+                          void (*cb)( int sts, void *aux ), void *aux );
+       void (*trash_msg)( store_t *ctx, message_t *msg, /* This may expunge 
the original message immediately, but it needn't to */
+                          void (*cb)( int sts, void *aux ), void *aux );
+       void (*close)( store_t *ctx, /* IMAP-style: expunge inclusive */
+                      void (*cb)( int sts, void *aux ), void *aux );
        void (*cancel)( store_t *ctx, /* only not yet sent commands */
                        void (*cb)( int sts, void *aux ), void *aux );
        void (*commit)( store_t *ctx );
diff --git a/src/sync.c b/src/sync.c
index c1324e1..65dfe7e 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -152,7 +152,7 @@ typedef struct {
        int flags_total[2], flags_done[2];
        int trash_total[2], trash_done[2];
        int maxuid[2], uidval[2], smaxxuid, lfd;
-       unsigned find:1;
+       unsigned find:1, cancel:1;
 } sync_vars_t;
 
 #define AUX &svars->t[t]
@@ -179,33 +179,34 @@ typedef struct {
 #define ST_SENT_FLAGS      (1<<3)
 #define ST_SENT_TRASH      (1<<4)
 #define ST_CLOSED          (1<<5)
-#define ST_CANCELED        (1<<6)
+#define ST_SENT_CANCEL     (1<<6)
+#define ST_CANCELED        (1<<7)
 
 #define ST_DID_EXPUNGE     (1<<16)
 
 
 typedef struct copy_vars {
-       int (*cb)( int sts, int uid, struct copy_vars *vars );
+       void (*cb)( int sts, int uid, struct copy_vars *vars );
        void *aux;
        sync_rec_t *srec; /* also ->tuid */
        message_t *msg;
        msg_data_t data;
 } copy_vars_t;
 
-static int msg_fetched( int sts, void *aux );
+static void msg_fetched( int sts, void *aux );
 
-static int
+static void
 copy_msg( copy_vars_t *vars )
 {
        SVARS(vars->aux)
 
        vars->data.flags = vars->msg->flags;
-       return svars->drv[1-t]->fetch_msg( svars->ctx[1-t], vars->msg, 
&vars->data, msg_fetched, vars );
+       svars->drv[1-t]->fetch_msg( svars->ctx[1-t], vars->msg, &vars->data, 
msg_fetched, vars );
 }
 
-static int msg_stored( int sts, int uid, void *aux );
+static void msg_stored( int sts, int uid, void *aux );
 
-static int
+static void
 msg_fetched( int sts, void *aux )
 {
        copy_vars_t *vars = (copy_vars_t *)aux;
@@ -251,7 +252,8 @@ msg_fetched( int sts, void *aux )
                                warn( "Warning: message %d from %s has 
incomplete header.\n",
                                      vars->msg->uid, str_ms[1-t] );
                                free( fmap );
-                               return vars->cb( SYNC_NOGOOD, 0, vars );
+                               vars->cb( SYNC_NOGOOD, 0, vars );
+                               break;
                          oke:
                                extra += 8 + TUIDL + 1 + (tcr && crs);
                        }
@@ -318,19 +320,24 @@ msg_fetched( int sts, void *aux )
                        free( fmap );
                }
 
-               return svars->drv[t]->store_msg( svars->ctx[t], &vars->data, 
!vars->srec, msg_stored, vars );
+               svars->drv[t]->store_msg( svars->ctx[t], &vars->data, 
!vars->srec, msg_stored, vars );
+               break;
        case DRV_CANCELED:
-               return vars->cb( SYNC_CANCELED, 0, vars );
+               vars->cb( SYNC_CANCELED, 0, vars );
+               break;
        case DRV_MSG_BAD:
-               return vars->cb( SYNC_NOGOOD, 0, vars );
+               vars->cb( SYNC_NOGOOD, 0, vars );
+               break;
        case DRV_STORE_BAD:
-               return vars->cb( SYNC_BAD(1-t), 0, vars );
+               vars->cb( SYNC_BAD(1-t), 0, vars );
+               break;
        default:
-               return vars->cb( SYNC_FAIL, 0, vars );
+               vars->cb( SYNC_FAIL, 0, vars );
+               break;
        }
 }
 
-static int
+static void
 msg_stored( int sts, int uid, void *aux )
 {
        copy_vars_t *vars = (copy_vars_t *)aux;
@@ -339,17 +346,22 @@ msg_stored( int sts, int uid, void *aux )
        (void)svars;
        switch (sts) {
        case DRV_OK:
-               return vars->cb( SYNC_OK, uid, vars );
+               vars->cb( SYNC_OK, uid, vars );
+               break;
        case DRV_CANCELED:
-               return vars->cb( SYNC_CANCELED, 0, vars );
+               vars->cb( SYNC_CANCELED, 0, vars );
+               break;
        case DRV_MSG_BAD:
                warn( "Warning: %s refuses to store message %d from %s.\n",
                      str_ms[t], vars->msg->uid, str_ms[1-t] );
-               return vars->cb( SYNC_NOGOOD, 0, vars );
+               vars->cb( SYNC_NOGOOD, 0, vars );
+               break;
        case DRV_STORE_BAD:
-               return vars->cb( SYNC_BAD(t), 0, vars );
+               vars->cb( SYNC_BAD(t), 0, vars );
+               break;
        default:
-               return vars->cb( SYNC_FAIL, 0, vars );
+               vars->cb( SYNC_FAIL, 0, vars );
+               break;
        }
 }
 
@@ -390,12 +402,15 @@ cancel_sync( sync_vars_t *svars )
 {
        int t;
 
-       /* the 1st round is guaranteed not to trash svars */
+       svars->cancel = 1;
        for (t = 0; t < 2; t++)
-               if (svars->ret & SYNC_BAD(t))
+               if (svars->ret & SYNC_BAD(t)) {
                        cancel_done( DRV_STORE_BAD, AUX );
-               else
+               } else if (!(svars->state[t] & ST_SENT_CANCEL)) {
+                       /* ignore subsequent failures from in-flight commands */
+                       svars->state[t] |= ST_SENT_CANCEL;
                        svars->drv[t]->cancel( svars->ctx[t], cancel_done, AUX 
);
+               }
 }
 
 static void
@@ -403,9 +418,11 @@ cancel_done( int sts, void *aux )
 {
        SVARS(aux)
 
-       if (sts != DRV_OK) {
+       if (sts != DRV_OK && svars->ctx[t]) {
                svars->ret |= SYNC_BAD(t);
+               /* this should never recurse into cancel_sync() */
                svars->drv[t]->cancel_store( svars->ctx[t] );
+               svars->ctx[t] = 0;
        }
        svars->state[t] |= ST_CANCELED;
        if (svars->state[1-t] & ST_CANCELED) {
@@ -460,7 +477,7 @@ clean_strdup( const char *s )
 
 #define JOURNAL_VERSION "2"
 
-static int select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int 
nmexcs );
+static void select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, 
int nmexcs );
 
 void
 sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan,
@@ -830,14 +847,15 @@ sync_boxes( store_t *ctx[], const char *names[], 
channel_conf_t *chan,
        svars->drv[S]->prepare_opts( ctx[S], opts[S] );
 
        svars->find = line != 0;
-       if (!svars->smaxxuid && select_box( svars, M, (ctx[M]->opts & OPEN_OLD) 
? 1 : INT_MAX, 0, 0 ))
-               return;
-       select_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 );
+       if (!svars->smaxxuid)
+               select_box( svars, M, (ctx[M]->opts & OPEN_OLD) ? 1 : INT_MAX, 
0, 0 );
+       if (!svars->cancel)
+               select_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 
0, 0 );
 }
 
-static int box_selected( int sts, void *aux );
+static void box_selected( int sts, void *aux );
 
-static int
+static void
 select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs )
 {
        sync_rec_t *srec;
@@ -856,7 +874,7 @@ select_box( sync_vars_t *svars, int t, int minwuid, int 
*mexcs, int nmexcs )
                maxwuid = 0;
        info( "Selecting %s %s...\n", str_ms[t], svars->ctx[t]->name );
        debug( maxwuid == INT_MAX ? "selecting %s [%d,inf]\n" : "selecting %s 
[%d,%d]\n", str_ms[t], minwuid, maxwuid );
-       return svars->drv[t]->select( svars->ctx[t], minwuid, maxwuid, mexcs, 
nmexcs, box_selected, AUX );
+       svars->drv[t]->select( svars->ctx[t], minwuid, maxwuid, mexcs, nmexcs, 
box_selected, AUX );
 }
 
 typedef struct {
@@ -864,10 +882,10 @@ typedef struct {
        sync_rec_t *srec;
 } find_vars_t;
 
-static int msg_found_sel( int sts, int uid, void *aux );
-static int msgs_found_sel( sync_vars_t *svars, int t );
+static void msg_found_sel( int sts, int uid, void *aux );
+static void msgs_found_sel( sync_vars_t *svars, int t );
 
-static int
+static void
 box_selected( int sts, void *aux )
 {
        SVARS(aux)
@@ -875,13 +893,13 @@ box_selected( int sts, void *aux )
        sync_rec_t *srec;
 
        if (check_ret( sts, svars, t ))
-               return 1;
+               return;
        if (svars->uidval[t] >= 0 && svars->uidval[t] != 
svars->ctx[t]->uidvalidity) {
                error( "Error: UIDVALIDITY of %s changed (got %d, expected 
%d)\n",
                         str_ms[t], svars->ctx[t]->uidvalidity, 
svars->uidval[t] );
                svars->ret |= SYNC_FAIL;
                cancel_sync( svars );
-               return 1;
+               return;
        }
        info( "%s: %d messages, %d recent\n", str_ms[t], svars->ctx[t]->count, 
svars->ctx[t]->recent );
 
@@ -904,23 +922,24 @@ box_selected( int sts, void *aux )
                                fv = nfmalloc( sizeof(*fv) );
                                fv->aux = AUX;
                                fv->srec = srec;
-                               if (svars->drv[t]->find_msg( svars->ctx[t], 
srec->tuid, msg_found_sel, fv ))
-                                       return 1;
+                               svars->drv[t]->find_msg( svars->ctx[t], 
srec->tuid, msg_found_sel, fv );
+                               if (svars->cancel)
+                                       return;
                        }
                }
        }
        svars->state[t] |= ST_SENT_FIND_OLD;
-       return msgs_found_sel( svars, t );
+       msgs_found_sel( svars, t );
 }
 
-static int
+static void
 msg_found_sel( int sts, int uid, void *aux )
 {
        find_vars_t *vars = (find_vars_t *)aux;
        SVARS(vars->aux)
 
        if (check_ret_aux( sts, svars, t, vars ))
-               return 1;
+               return;
        switch (sts) {
        case DRV_OK:
                debug( "  -> new UID %d\n", uid );
@@ -938,7 +957,7 @@ msg_found_sel( int sts, int uid, void *aux )
        free( vars );
        svars->find_old_done[t]++;
        stats( svars );
-       return msgs_found_sel( svars, t );
+       msgs_found_sel( svars, t );
 }
 
 typedef struct {
@@ -947,15 +966,15 @@ typedef struct {
        int aflags, dflags;
 } flag_vars_t;
 
-static int flags_set_del( int sts, void *aux );
-static int flags_set_sync( int sts, void *aux );
+static void flags_set_del( int sts, void *aux );
+static void flags_set_sync( int sts, void *aux );
 static void flags_set_sync_p2( sync_vars_t *svars, sync_rec_t *srec, int t );
-static int msgs_flags_set( sync_vars_t *svars, int t );
-static int msg_copied( int sts, int uid, copy_vars_t *vars );
+static void msgs_flags_set( sync_vars_t *svars, int t );
+static void msg_copied( int sts, int uid, copy_vars_t *vars );
 static void msg_copied_p2( sync_vars_t *svars, sync_rec_t *srec, int t, 
message_t *tmsg, int uid );
-static int msgs_copied( sync_vars_t *svars, int t );
+static void msgs_copied( sync_vars_t *svars, int t );
 
-static int
+static void
 msgs_found_sel( sync_vars_t *svars, int t )
 {
        sync_rec_t *srec, *nsrec = 0;
@@ -968,7 +987,7 @@ msgs_found_sel( sync_vars_t *svars, int t )
        char fbuf[16]; /* enlarge when support for keywords is added */
 
        if (!(svars->state[t] & ST_SENT_FIND_OLD) || svars->find_old_done[t] < 
svars->find_old_total[t])
-               return 0;
+               return;
 
        /*
         * Mapping tmsg -> srec (this variant) is dog slow for new messages.
@@ -1064,11 +1083,12 @@ msgs_found_sel( sync_vars_t *svars, int t )
                for (t = 0; t < nmexcs; t++)
                        debugn( " %d", mexcs[t] );
                debug( "\n" );
-               return select_box( svars, M, minwuid, mexcs, nmexcs );
+               select_box( svars, M, minwuid, mexcs, nmexcs );
+               return;
        }
 
        if (!(svars->state[1-t] & ST_SENT_FIND_OLD) || 
svars->find_old_done[1-t] < svars->find_old_total[1-t])
-               return 0;
+               return;
 
        if (svars->uidval[M] < 0 || svars->uidval[S] < 0) {
                svars->uidval[M] = svars->ctx[M]->uidvalidity;
@@ -1123,8 +1143,9 @@ msgs_found_sel( sync_vars_t *svars, int t )
                                                cv->msg = tmsg;
                                                Fprintf( svars->jfp, "# %d %d 
%." stringify(TUIDL) "s\n", srec->uid[M], srec->uid[S], srec->tuid );
                                                debug( "  -> %sing message, 
TUID %." stringify(TUIDL) "s\n", str_hl[t], srec->tuid );
-                                               if (copy_msg( cv ))
-                                                       return 1;
+                                               copy_msg( cv );
+                                               if (svars->cancel)
+                                                       return;
                                        } else {
                                                if (tmsg->srec) {
                                                        debug( "  -> not %sing 
- still too big\n", str_hl[t] );
@@ -1136,8 +1157,9 @@ msgs_found_sel( sync_vars_t *svars, int t )
                                }
                        }
                svars->state[t] |= ST_SENT_NEW;
-               if (msgs_copied( svars, t ))
-                       return 1;
+               msgs_copied( svars, t );
+               if (svars->cancel)
+                       return;
        }
 
        debug( "synchronizing old entries\n" );
@@ -1175,8 +1197,9 @@ msgs_found_sel( sync_vars_t *svars, int t )
                                                fv = nfmalloc( sizeof(*fv) );
                                                fv->aux = AUX;
                                                fv->srec = srec;
-                                               if (svars->drv[t]->set_flags( 
svars->ctx[t], srec->msg[t], srec->uid[t], F_DELETED, 0, flags_set_del, fv ))
-                                                       return 1;
+                                               svars->drv[t]->set_flags( 
svars->ctx[t], srec->msg[t], srec->uid[t], F_DELETED, 0, flags_set_del, fv );
+                                               if (svars->cancel)
+                                                       return;
                                        } else
                                                debug( "  not %sing delete\n", 
str_hl[t] );
                                } else if (!srec->msg[1-t])
@@ -1286,22 +1309,25 @@ msgs_found_sel( sync_vars_t *svars, int t )
                                fv->srec = srec;
                                fv->aflags = aflags;
                                fv->dflags = dflags;
-                               if (svars->drv[t]->set_flags( svars->ctx[t], 
srec->msg[t], srec->uid[t], aflags, dflags, flags_set_sync, fv ))
-                                       return 1;
+                               svars->drv[t]->set_flags( svars->ctx[t], 
srec->msg[t], srec->uid[t], aflags, dflags, flags_set_sync, fv );
+                               if (svars->cancel)
+                                       return;
                        } else
                                flags_set_sync_p2( svars, srec, t );
                }
        }
        for (t = 0; t < 2; t++) {
                svars->drv[t]->commit( svars->ctx[t] );
+               if (svars->cancel)
+                       return;
                svars->state[t] |= ST_SENT_FLAGS;
-               if (msgs_flags_set( svars, t ))
-                       return 1;
+               msgs_flags_set( svars, t );
+               if (svars->cancel)
+                       return;
        }
-       return 0;
 }
 
-static int
+static void
 msg_copied( int sts, int uid, copy_vars_t *vars )
 {
        SVARS(vars->aux)
@@ -1317,14 +1343,15 @@ msg_copied( int sts, int uid, copy_vars_t *vars )
                break;
        default:
                cancel_sync( svars );
+               /* fallthrough */
        case SYNC_CANCELED:
                free( vars );
-               return 1;
+               return;
        }
        free( vars );
        svars->new_done[t]++;
        stats( svars );
-       return msgs_copied( svars, t );
+       msgs_copied( svars, t );
 }
 
 static void
@@ -1345,17 +1372,17 @@ msg_copied_p2( sync_vars_t *svars, sync_rec_t *srec, 
int t, message_t *tmsg, int
        }
 }
 
-static int msg_found_new( int sts, int uid, void *aux );
-static int sync_close( sync_vars_t *svars, int t );
+static void msg_found_new( int sts, int uid, void *aux );
+static void sync_close( sync_vars_t *svars, int t );
 
-static int
+static void
 msgs_copied( sync_vars_t *svars, int t )
 {
        sync_rec_t *srec;
        find_vars_t *fv;
 
        if (!(svars->state[t] & ST_SENT_NEW) || svars->new_done[t] < 
svars->new_total[t])
-               return 0;
+               return;
 
        debug( "finding just copied messages on %s\n", str_ms[t] );
        for (srec = svars->srecs; srec; srec = srec->next) {
@@ -1368,22 +1395,23 @@ msgs_copied( sync_vars_t *svars, int t )
                        fv = nfmalloc( sizeof(*fv) );
                        fv->aux = AUX;
                        fv->srec = srec;
-                       if (svars->drv[t]->find_msg( svars->ctx[t], srec->tuid, 
msg_found_new, fv ))
-                               return 1;
+                       svars->drv[t]->find_msg( svars->ctx[t], srec->tuid, 
msg_found_new, fv );
+                       if (svars->cancel)
+                               return;
                }
        }
        svars->state[t] |= ST_SENT_FIND_NEW;
-       return sync_close( svars, t );
+       sync_close( svars, t );
 }
 
-static int
+static void
 msg_found_new( int sts, int uid, void *aux )
 {
        find_vars_t *vars = (find_vars_t *)aux;
        SVARS(vars->aux)
 
        if (check_ret_aux( sts, svars, t, vars ))
-               return 1;
+               return;
        switch (sts) {
        case DRV_OK:
                debug( "  -> new UID %d\n", uid );
@@ -1399,17 +1427,17 @@ msg_found_new( int sts, int uid, void *aux )
        free( vars );
        svars->find_new_done[t]++;
        stats( svars );
-       return sync_close( svars, t );
+       sync_close( svars, t );
 }
 
-static int
+static void
 flags_set_del( int sts, void *aux )
 {
        flag_vars_t *vars = (flag_vars_t *)aux;
        SVARS(vars->aux)
 
        if (check_ret_aux( sts, svars, t, vars ))
-               return 1;
+               return;
        switch (sts) {
        case DRV_OK:
                vars->srec->status |= S_DEL(t);
@@ -1420,17 +1448,17 @@ flags_set_del( int sts, void *aux )
        free( vars );
        svars->flags_done[t]++;
        stats( svars );
-       return msgs_flags_set( svars, t );
+       msgs_flags_set( svars, t );
 }
 
-static int
+static void
 flags_set_sync( int sts, void *aux )
 {
        flag_vars_t *vars = (flag_vars_t *)aux;
        SVARS(vars->aux)
 
        if (check_ret_aux( sts, svars, t, vars ))
-               return 1;
+               return;
        switch (sts) {
        case DRV_OK:
                if (vars->aflags & F_DELETED)
@@ -1443,7 +1471,7 @@ flags_set_sync( int sts, void *aux )
        free( vars );
        svars->flags_done[t]++;
        stats( svars );
-       return msgs_flags_set( svars, t );
+       msgs_flags_set( svars, t );
 }
 
 static void
@@ -1473,17 +1501,17 @@ flags_set_sync_p2( sync_vars_t *svars, sync_rec_t 
*srec, int t )
        }
 }
 
-static int msg_trashed( int sts, void *aux );
-static int msg_rtrashed( int sts, int uid, copy_vars_t *vars );
+static void msg_trashed( int sts, void *aux );
+static void msg_rtrashed( int sts, int uid, copy_vars_t *vars );
 
-static int
+static void
 msgs_flags_set( sync_vars_t *svars, int t )
 {
        message_t *tmsg;
        copy_vars_t *cv;
 
        if (!(svars->state[t] & ST_SENT_FLAGS) || svars->flags_done[t] < 
svars->flags_total[t])
-               return 0;
+               return;
 
        if ((svars->chan->ops[t] & OP_EXPUNGE) &&
            (svars->ctx[t]->conf->trash || (svars->ctx[1-t]->conf->trash && 
svars->ctx[1-t]->conf->trash_remote_new))) {
@@ -1495,8 +1523,9 @@ msgs_flags_set( sync_vars_t *svars, int t )
                                                debug( "%s: trashing message 
%d\n", str_ms[t], tmsg->uid );
                                                svars->trash_total[t]++;
                                                stats( svars );
-                                               if (svars->drv[t]->trash_msg( 
svars->ctx[t], tmsg, msg_trashed, AUX ))
-                                                       return 1;
+                                               svars->drv[t]->trash_msg( 
svars->ctx[t], tmsg, msg_trashed, AUX );
+                                               if (svars->cancel)
+                                                       return;
                                        } else
                                                debug( "%s: not trashing 
message %d - not new\n", str_ms[t], tmsg->uid );
                                } else {
@@ -1510,8 +1539,9 @@ msgs_flags_set( sync_vars_t *svars, int t )
                                                        cv->aux = AUX;
                                                        cv->srec = 0;
                                                        cv->msg = tmsg;
-                                                       if (copy_msg( cv ))
-                                                               return 1;
+                                                       copy_msg( cv );
+                                                       if (svars->cancel)
+                                                               return;
                                                } else
                                                        debug( "%s: not remote 
trashing message %d - too big\n", str_ms[t], tmsg->uid );
                                        } else
@@ -1520,10 +1550,10 @@ msgs_flags_set( sync_vars_t *svars, int t )
                        }
        }
        svars->state[t] |= ST_SENT_TRASH;
-       return sync_close( svars, t );
+       sync_close( svars, t );
 }
 
-static int
+static void
 msg_trashed( int sts, void *aux )
 {
        SVARS(aux)
@@ -1531,13 +1561,13 @@ msg_trashed( int sts, void *aux )
        if (sts == DRV_MSG_BAD)
                sts = DRV_BOX_BAD;
        if (check_ret( sts, svars, t ))
-               return 1;
+               return;
        svars->trash_done[t]++;
        stats( svars );
-       return sync_close( svars, t );
+       sync_close( svars, t );
 }
 
-static int
+static void
 msg_rtrashed( int sts, int uid, copy_vars_t *vars )
 {
        SVARS(vars->aux)
@@ -1549,45 +1579,45 @@ msg_rtrashed( int sts, int uid, copy_vars_t *vars )
                break;
        default:
                cancel_sync( svars );
+               /* fallthrough */
        case SYNC_CANCELED:
                free( vars );
-               return 1;
+               return;
        }
        free( vars );
        svars->trash_done[t]++;
        stats( svars );
-       return sync_close( svars, t );
+       sync_close( svars, t );
 }
 
-static int box_closed( int sts, void *aux );
+static void box_closed( int sts, void *aux );
 static void box_closed_p2( sync_vars_t *svars, int t );
 
-static int
+static void
 sync_close( sync_vars_t *svars, int t )
 {
        if ((~svars->state[t] & (ST_SENT_FIND_NEW|ST_SENT_TRASH)) ||
            svars->find_new_done[t] < svars->find_new_total[t] ||
            svars->trash_done[t] < svars->trash_total[t])
-               return 0;
+               return;
 
        if ((svars->chan->ops[t] & OP_EXPUNGE) /*&& !(svars->state[t] & 
ST_TRASH_BAD)*/) {
                debug( "expunging %s\n", str_ms[t] );
-               return svars->drv[t]->close( svars->ctx[t], box_closed, AUX );
+               svars->drv[t]->close( svars->ctx[t], box_closed, AUX );
+       } else {
+               box_closed_p2( svars, t );
        }
-       box_closed_p2( svars, t );
-       return 0;
 }
 
-static int
+static void
 box_closed( int sts, void *aux )
 {
        SVARS(aux)
 
        if (check_ret( sts, svars, t ))
-               return 1;
+               return;
        svars->state[t] |= ST_DID_EXPUNGE;
        box_closed_p2( svars, t );
-       return 0;
 }
 
 static void

------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to