commit 7b7304b6254db1dea3e567753df47b94dd11e573
Author: Oswald Buddenhagen <[email protected]>
Date:   Mon Dec 29 01:42:17 2014 +0100

    split create_box() off from open_box()
    
    this allows us to do something else than creating missing boxes
    depending on circumstances. hypothetically, that is.

 src/driver.h      |    9 +++++-
 src/drv_imap.c    |   39 +++++++++++++++++++++------
 src/drv_maildir.c |   12 +++++++-
 src/sync.c        |   64 +++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 106 insertions(+), 18 deletions(-)

diff --git a/src/driver.h b/src/driver.h
index b56677c..217d624 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -165,8 +165,13 @@ struct driver {
         * As a side effect, this should resolve ctx->path if applicable. */
        int (*select_box)( store_t *ctx, const char *name );
 
-       /* Open the selected mailbox. Optionally create missing boxes. */
-       void (*open_box)( store_t *ctx, int create,
+       /* Create the selected mailbox. */
+       void (*create_box)( store_t *ctx,
+                           void (*cb)( int sts, void *aux ), void *aux );
+
+       /* Open the selected mailbox.
+        * Note that this should not directly complain about failure to open. */
+       void (*open_box)( store_t *ctx,
                          void (*cb)( int sts, void *aux ), void *aux );
 
        /* Invoked before load_box(), this informs the driver which operations 
(OP_*)
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 7600471..2db2670 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -143,8 +143,8 @@ struct imap_cmd {
                int uid; /* to identify fetch responses */
                char high_prio; /* if command is queued, put it at the front of 
the queue. */
                char to_trash; /* we are storing to trash, not current. */
-               char create; /* create the mailbox if we get an error ... */
-               char trycreate; /* ... but only if this is true or the server 
says so. */
+               char create; /* create the mailbox if we get an error which 
suggests so. */
+               char failok; /* Don't complain about NO response. */
        } param;
 };
 
@@ -1333,10 +1333,7 @@ imap_socket_read( void *aux )
                                resp = RESP_OK;
                        } else {
                                if (!strcmp( "NO", arg )) {
-                                       if (cmdp->param.create &&
-                                           (cmdp->param.trycreate ||
-                                            (cmd && starts_with( cmd, -1, 
"[TRYCREATE]", 11 ))))
-                                       { /* SELECT, APPEND or UID COPY */
+                                       if (cmdp->param.create && cmd && 
starts_with( cmd, -1, "[TRYCREATE]", 11 )) { /* APPEND or UID COPY */
                                                struct imap_cmd_trycreate *cmd2 
=
                                                        (struct 
imap_cmd_trycreate *)new_imap_cmd( sizeof(*cmd2) );
                                                cmd2->orig_cmd = cmdp;
@@ -1348,12 +1345,15 @@ imap_socket_read( void *aux )
                                                continue;
                                        }
                                        resp = RESP_NO;
+                                       if (cmdp->param.failok)
+                                               goto doresp;
                                } else /*if (!strcmp( "BAD", arg ))*/
                                        resp = RESP_CANCEL;
                                error( "IMAP command '%s' returned an error: %s 
%s\n",
                                       !starts_with( cmdp->cmd, -1, "LOGIN", 5 
) ? cmdp->cmd : "LOGIN <user> <pass>",
                                       arg, cmd ? cmd : "" );
                        }
+                 doresp:
                        if ((resp2 = parse_response_code( ctx, cmdp, cmd )) > 
resp)
                                resp = resp2;
                        imap_ref( ctx );
@@ -2124,7 +2124,7 @@ imap_select_box( store_t *gctx, const char *name )
 }
 
 static void
-imap_open_box( store_t *gctx, int create,
+imap_open_box( store_t *gctx,
                void (*cb)( int sts, void *aux ), void *aux )
 {
        imap_store_t *ctx = (imap_store_t *)gctx;
@@ -2139,13 +2139,33 @@ imap_open_box( store_t *gctx, int create,
        ctx->gen.uidnext = 0;
 
        INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux)
-       cmd->gen.param.create = create;
-       cmd->gen.param.trycreate = 1;
+       cmd->gen.param.failok = 1;
        imap_exec( ctx, &cmd->gen, imap_done_simple_box,
                   "SELECT \"%\\s\"", buf );
        free( buf );
 }
 
+/******************* imap_create_box *******************/
+
+static void
+imap_create_box( store_t *gctx,
+                 void (*cb)( int sts, void *aux ), void *aux )
+{
+       imap_store_t *ctx = (imap_store_t *)gctx;
+       struct imap_cmd_simple *cmd;
+       char *buf;
+
+       if (prepare_box( &buf, ctx ) < 0) {
+               cb( DRV_BOX_BAD, aux );
+               return;
+       }
+
+       INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux)
+       imap_exec( ctx, &cmd->gen, imap_done_simple_box,
+                  "CREATE \"%\\s\"", buf );
+       free( buf );
+}
+
 /******************* imap_load_box *******************/
 
 static void
@@ -2788,6 +2808,7 @@ struct driver imap_driver = {
        imap_cancel_store,
        imap_list_store,
        imap_select_box,
+       imap_create_box,
        imap_open_box,
        imap_prepare_load_box,
        imap_load_box,
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index 9ee61a7..443d4cc 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -951,7 +951,7 @@ maildir_select_box( store_t *gctx, const char *name )
 }
 
 static void
-maildir_open_box( store_t *gctx, int create,
+maildir_open_box( store_t *gctx,
                   void (*cb)( int sts, void *aux ), void *aux )
 {
        maildir_store_t *ctx = (maildir_store_t *)gctx;
@@ -961,7 +961,7 @@ maildir_open_box( store_t *gctx, int create,
 #endif /* USE_DB */
        char uvpath[_POSIX_PATH_MAX];
 
-       if ((ret = maildir_validate( gctx->path, create, ctx )) != DRV_OK) {
+       if ((ret = maildir_validate( gctx->path, 0, ctx )) != DRV_OK) {
                cb( ret, aux );
                return;
        }
@@ -1047,6 +1047,13 @@ maildir_open_box( store_t *gctx, int create,
 }
 
 static void
+maildir_create_box( store_t *gctx,
+                    void (*cb)( int sts, void *aux ), void *aux )
+{
+       cb( maildir_validate( gctx->path, 1, (maildir_store_t *)gctx ), aux );
+}
+
+static void
 maildir_prepare_load_box( store_t *gctx, int opts )
 {
        if (opts & OPEN_SETFLAGS)
@@ -1538,6 +1545,7 @@ struct driver maildir_driver = {
        maildir_disown_store, /* _cancel_, but it's the same */
        maildir_list_store,
        maildir_select_box,
+       maildir_create_box,
        maildir_open_box,
        maildir_prepare_load_box,
        maildir_load_box,
diff --git a/src/sync.c b/src/sync.c
index 889af28..016a1f4 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -923,7 +923,10 @@ load_state( sync_vars_t *svars )
        return 1;
 }
 
+static void box_confirmed( int sts, void *aux );
+static void box_created( int sts, void *aux );
 static void box_opened( int sts, void *aux );
+static void box_opened2( sync_vars_t *svars, int t );
 static void load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int 
nmexcs );
 
 void
@@ -984,7 +987,7 @@ sync_boxes( store_t *ctx[], const char *names[], 
channel_conf_t *chan,
        sync_ref( svars );
        for (t = 0; ; t++) {
                info( "Opening %s box %s...\n", str_ms[t], svars->orig_name[t] 
);
-               svars->drv[t]->open_box( ctx[t], (chan->ops[t] & OP_CREATE) != 
0, box_opened, AUX );
+               svars->drv[t]->open_box( ctx[t], box_confirmed, AUX );
                if (t || check_cancel( svars ))
                        break;
        }
@@ -992,19 +995,70 @@ sync_boxes( store_t *ctx[], const char *names[], 
channel_conf_t *chan,
 }
 
 static void
+box_confirmed( int sts, void *aux )
+{
+       DECL_SVARS;
+
+       if (sts == DRV_CANCELED)
+               return;
+       INIT_SVARS(aux);
+       if (check_cancel( svars ))
+               return;
+
+       if (sts == DRV_BOX_BAD) {
+               if (!(svars->chan->ops[t] & OP_CREATE)) {
+                       box_opened( sts, aux );
+               } else {
+                       info( "Creating %s %s...\n", str_ms[t], 
svars->orig_name[t] );
+                       svars->drv[t]->create_box( svars->ctx[t], box_created, 
AUX );
+               }
+       } else {
+               box_opened2( svars, t );
+       }
+}
+
+static void
+box_created( int sts, void *aux )
+{
+       DECL_SVARS;
+
+       if (check_ret( sts, aux ))
+               return;
+       INIT_SVARS(aux);
+
+       svars->drv[t]->open_box( svars->ctx[t], box_opened, AUX );
+}
+
+static void
 box_opened( int sts, void *aux )
 {
        DECL_SVARS;
+
+       if (sts == DRV_CANCELED)
+               return;
+       INIT_SVARS(aux);
+       if (check_cancel( svars ))
+               return;
+
+       if (sts == DRV_BOX_BAD) {
+               error( "Error: channel %s: %s %s cannot be opened.\n",
+                      svars->chan->name, str_ms[t], svars->orig_name[t] );
+               svars->ret = SYNC_FAIL;
+               sync_bail( svars );
+       } else {
+               box_opened2( svars, t );
+       }
+}
+
+static void
+box_opened2( sync_vars_t *svars, int t )
+{
        store_t *ctx[2];
        channel_conf_t *chan;
        sync_rec_t *srec;
        int opts[2], fails;
        int *mexcs, nmexcs, rmexcs, minwuid;
 
-       if (check_ret( sts, aux ))
-               return;
-       INIT_SVARS(aux);
-
        svars->state[t] |= ST_SELECTED;
        if (!(svars->state[1-t] & ST_SELECTED))
                return;

------------------------------------------------------------------------------
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