commit 83ebe9022d88d9493d7ee5739f4503af1e28448b
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Fri Mar 24 14:06:19 2017 +0100

    introduce get_box_path() driver callback
    
    ... and make 'path' private to the maildir driver.

 src/driver.h      |  7 +++---
 src/drv_imap.c    |  7 ++++++
 src/drv_maildir.c | 57 +++++++++++++++++++++++++++++------------------
 src/sync.c        |  5 +++--
 4 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/src/driver.h b/src/driver.h
index 43eb147..24f137d 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -90,7 +90,6 @@ typedef struct store {
        char listed; /* was _list already run? */
 
        /* currently open mailbox */
-       char *path; /* own */
        message_t *msgs; /* own */
        int uidvalidity;
        int uidnext; /* from SELECT responses */
@@ -167,10 +166,12 @@ struct driver {
        void (*list_store)( store_t *ctx, int flags,
                            void (*cb)( int sts, void *aux ), void *aux );
 
-       /* Invoked before open_box(), this informs the driver which box is to 
be opened.
-        * As a side effect, this should resolve ctx->path if applicable. */
+       /* Invoked before open_box(), this informs the driver which box is to 
be opened. */
        int (*select_box)( store_t *ctx, const char *name );
 
+       /* Get the selected box' on-disk path, if applicable, null otherwise. */
+       const char *(*get_box_path)( store_t *ctx );
+
        /* Create the selected mailbox. */
        void (*create_box)( store_t *ctx,
                            void (*cb)( int sts, void *aux ), void *aux );
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 5afddaf..8eb3d31 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -2306,6 +2306,12 @@ imap_select_box( store_t *gctx, const char *name )
        return DRV_OK;
 }
 
+static const char *
+imap_get_box_path( store_t *gctx ATTR_UNUSED )
+{
+       return 0;
+}
+
 static void imap_open_box_p2( imap_store_t *, imap_cmd_t *, int );
 static void imap_open_box_p3( imap_store_t *, imap_cmd_t *, int );
 
@@ -3212,6 +3218,7 @@ struct driver imap_driver = {
        imap_cancel_store,
        imap_list_store,
        imap_select_box,
+       imap_get_box_path,
        imap_create_box,
        imap_open_box,
        imap_confirm_box_empty,
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index a5bdf3f..d888d2a 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -72,6 +72,7 @@ typedef struct {
        int uvfd, uvok, nuid, is_inbox, fresh[3];
        int minuid, maxuid, newuid, seenuid;
        int_array_t excs;
+       char *path; /* own */
        char *trash;
 #ifdef USE_DB
        DB *db;
@@ -265,7 +266,7 @@ maildir_cleanup( store_t *gctx )
                ctx->db->close( ctx->db, 0 );
        free( ctx->usedb );
 #endif /* USE_DB */
-       free( gctx->path );
+       free( ctx->path );
        free( ctx->excs.data );
        if (ctx->uvfd >= 0)
                close( ctx->uvfd );
@@ -920,7 +921,7 @@ maildir_scan( maildir_store_t *ctx, msg_t_array_alloc_t 
*msglist )
                        }
                }
 #endif /* USE_DB */
-               bl = nfsnprintf( buf, sizeof(buf) - 4, "%s/", ctx->gen.path );
+               bl = nfsnprintf( buf, sizeof(buf) - 4, "%s/", ctx->path );
          restat:
                now = time( 0 );
                for (i = 0; i < 2; i++) {
@@ -1236,18 +1237,24 @@ maildir_select_box( store_t *gctx, const char *name )
        ctx->fresh[0] = ctx->fresh[1] = 0;
        if (starts_with( name, -1, "INBOX", 5 ) && (!name[5] || name[5] == 
'/')) {
                if (!name[5]) {
-                       gctx->path = nfstrdup( conf->inbox );
+                       ctx->path = nfstrdup( conf->inbox );
                        ctx->is_inbox = 1;
                } else {
-                       gctx->path = maildir_join_path( conf, 1, name + 5 );
+                       ctx->path = maildir_join_path( conf, 1, name + 5 );
                        ctx->is_inbox = 0;
                }
        } else {
-               if (!(gctx->path = maildir_join_path( conf, 0, name )))
+               if (!(ctx->path = maildir_join_path( conf, 0, name )))
                    return DRV_CANCELED;
                ctx->is_inbox = 0;
        }
-       return gctx->path ? DRV_OK : DRV_BOX_BAD;
+       return ctx->path ? DRV_OK : DRV_BOX_BAD;
+}
+
+static const char *
+maildir_get_box_path( store_t *gctx )
+{
+       return ((maildir_store_t *)gctx)->path;
 }
 
 static void
@@ -1258,10 +1265,10 @@ maildir_open_box( store_t *gctx,
        int ret;
        char uvpath[_POSIX_PATH_MAX];
 
-       if ((ret = maildir_validate( gctx->path, ctx->is_inbox, ctx )) != 
DRV_OK)
+       if ((ret = maildir_validate( ctx->path, ctx->is_inbox, ctx )) != DRV_OK)
                goto bail;
 
-       nfsnprintf( uvpath, sizeof(uvpath), "%s/.uidvalidity", gctx->path );
+       nfsnprintf( uvpath, sizeof(uvpath), "%s/.uidvalidity", ctx->path );
 #ifndef USE_DB
        if ((ctx->uvfd = open( uvpath, O_RDWR|O_CREAT, 0600 )) < 0) {
                sys_error( "Maildir error: cannot write %s", uvpath );
@@ -1271,13 +1278,13 @@ maildir_open_box( store_t *gctx,
 #else
        ctx->usedb = 0;
        if ((ctx->uvfd = open( uvpath, O_RDWR, 0600 )) < 0) {
-               nfsnprintf( uvpath, sizeof(uvpath), "%s/.isyncuidmap.db", 
gctx->path );
+               nfsnprintf( uvpath, sizeof(uvpath), "%s/.isyncuidmap.db", 
ctx->path );
                if ((ctx->uvfd = open( uvpath, O_RDWR, 0600 )) < 0) {
                        if (((maildir_store_conf_t *)gctx->conf)->alt_map) {
                                if ((ctx->uvfd = open( uvpath, O_RDWR|O_CREAT, 
0600 )) >= 0)
                                        goto dbok;
                        } else {
-                               nfsnprintf( uvpath, sizeof(uvpath), 
"%s/.uidvalidity", gctx->path );
+                               nfsnprintf( uvpath, sizeof(uvpath), 
"%s/.uidvalidity", ctx->path );
                                if ((ctx->uvfd = open( uvpath, O_RDWR|O_CREAT, 
0600 )) >= 0)
                                        goto fnok;
                        }
@@ -1301,7 +1308,9 @@ 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 );
+       maildir_store_t *ctx = (maildir_store_t *)gctx;
+
+       cb( maildir_validate( ctx->path, 1, ctx ), aux );
 }
 
 static int
@@ -1322,18 +1331,19 @@ static void
 maildir_delete_box( store_t *gctx,
                     void (*cb)( int sts, void *aux ), void *aux )
 {
+       maildir_store_t *ctx = (maildir_store_t *)gctx;
        int i, bl, ret = DRV_OK;
        struct stat st;
        char buf[_POSIX_PATH_MAX];
 
-       bl = nfsnprintf( buf, sizeof(buf) - 4, "%s/", gctx->path );
+       bl = nfsnprintf( buf, sizeof(buf) - 4, "%s/", ctx->path );
        if (stat( buf, &st )) {
                if (errno != ENOENT) {
-                       sys_error( "Maildir error: cannot access mailbox '%s'", 
gctx->path );
+                       sys_error( "Maildir error: cannot access mailbox '%s'", 
ctx->path );
                        ret = DRV_BOX_BAD;
                }
        } else if (!S_ISDIR(st.st_mode)) {
-               error( "Maildir error: '%s' is no valid mailbox\n", gctx->path 
);
+               error( "Maildir error: '%s' is no valid mailbox\n", ctx->path );
                ret = DRV_BOX_BAD;
        } else if ((ret = maildir_clear_tmp( buf, sizeof(buf), bl )) == DRV_OK) 
{
                nfsnprintf( buf + bl, sizeof(buf) - bl, ".uidvalidity" );
@@ -1362,10 +1372,12 @@ maildir_delete_box( store_t *gctx,
 static int
 maildir_finish_delete_box( store_t *gctx )
 {
+       maildir_store_t *ctx = (maildir_store_t *)gctx;
+
        /* Subfolders are not deleted; the deleted folder is only "stripped of 
its mailboxness".
         * Consequently, the rmdir may legitimately fail. This behavior follows 
the IMAP spec. */
-       if (rmdir( gctx->path ) && errno != ENOENT && errno != ENOTEMPTY) {
-               sys_error( "Maildir warning: cannot remove '%s'", gctx->path );
+       if (rmdir( ctx->path ) && errno != ENOENT && errno != ENOTEMPTY) {
+               sys_error( "Maildir warning: cannot remove '%s'", ctx->path );
                return DRV_BOX_BAD;
        }
        return DRV_OK;
@@ -1487,7 +1499,7 @@ maildir_fetch_msg( store_t *gctx, message_t *gmsg, 
msg_data_t *data,
        char buf[_POSIX_PATH_MAX];
 
        for (;;) {
-               nfsnprintf( buf, sizeof(buf), "%s/%s/%s", gctx->path, 
subdirs[gmsg->status & M_RECENT], msg->base );
+               nfsnprintf( buf, sizeof(buf), "%s/%s/%s", ctx->path, 
subdirs[gmsg->status & M_RECENT], msg->base );
                if ((fd = open( buf, O_RDONLY )) >= 0)
                        break;
                if ((ret = maildir_again( ctx, msg, "Cannot open %s", buf, 0 )) 
!= DRV_OK) {
@@ -1555,7 +1567,7 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int 
to_trash,
                        }
                        nfsnprintf( base + bl, sizeof(base) - bl, ",U=%d", uid 
);
                }
-               box = gctx->path;
+               box = ctx->path;
        } else {
                uid = 0;
                box = ctx->trash;
@@ -1640,8 +1652,8 @@ maildir_set_msg_flags( store_t *gctx, message_t *gmsg, 
int uid ATTR_UNUSED, int
        int j, ret, ol, fl, bbl, bl, tl;
        char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX];
 
-       bbl = nfsnprintf( buf, sizeof(buf), "%s/", gctx->path );
-       memcpy( nbuf, gctx->path, bbl - 1 );
+       bbl = nfsnprintf( buf, sizeof(buf), "%s/", ctx->path );
+       memcpy( nbuf, ctx->path, bbl - 1 );
        memcpy( nbuf + bbl - 1, "/cur/", 5 );
        for (;;) {
                bl = bbl + nfsnprintf( buf + bbl, sizeof(buf) - bbl, "%s/", 
subdirs[gmsg->status & M_RECENT] );
@@ -1715,7 +1727,7 @@ maildir_trash_msg( store_t *gctx, message_t *gmsg,
        char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX];
 
        for (;;) {
-               nfsnprintf( buf, sizeof(buf), "%s/%s/%s", gctx->path, 
subdirs[gmsg->status & M_RECENT], msg->base );
+               nfsnprintf( buf, sizeof(buf), "%s/%s/%s", ctx->path, 
subdirs[gmsg->status & M_RECENT], msg->base );
                s = strstr( msg->base, ((maildir_store_conf_t 
*)gctx->conf)->info_prefix );
                nfsnprintf( nbuf, sizeof(nbuf), "%s/%s/%ld.%d_%d.%s%s", 
ctx->trash,
                            subdirs[gmsg->status & M_RECENT], (long)time( 0 ), 
Pid, ++MaildirCount, Hostname, s ? s : "" );
@@ -1764,7 +1776,7 @@ maildir_close_box( store_t *gctx,
 
        for (;;) {
                retry = 0;
-               basel = nfsnprintf( buf, sizeof(buf), "%s/", gctx->path );
+               basel = nfsnprintf( buf, sizeof(buf), "%s/", ctx->path );
                for (msg = gctx->msgs; msg; msg = msg->next)
                        if (!(msg->status & M_DEAD) && (msg->flags & 
F_DELETED)) {
                                nfsnprintf( buf + basel, sizeof(buf) - basel, 
"%s/%s", subdirs[msg->status & M_RECENT], ((maildir_message_t *)msg)->base );
@@ -1895,6 +1907,7 @@ struct driver maildir_driver = {
        maildir_free_store, /* _cancel_, but it's the same */
        maildir_list_store,
        maildir_select_box,
+       maildir_get_box_path,
        maildir_create_box,
        maildir_open_box,
        maildir_confirm_box_empty,
diff --git a/src/sync.c b/src/sync.c
index 340758c..a8d1e33 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -577,11 +577,12 @@ prepare_state( sync_vars_t *svars )
 
        chan = svars->chan;
        if (!strcmp( chan->sync_state ? chan->sync_state : 
global_conf.sync_state, "*" )) {
-               if (!svars->ctx[S]->path) {
+               const char *path = svars->drv[S]->get_box_path( svars->ctx[S] );
+               if (!path) {
                        error( "Error: store '%s' does not support in-box sync 
state\n", chan->stores[S]->name );
                        return 0;
                }
-               nfasprintf( &svars->dname, "%s/." EXE "state", 
svars->ctx[S]->path );
+               nfasprintf( &svars->dname, "%s/." EXE "state", path );
        } else {
                csname = clean_strdup( svars->box_name[S] );
                if (chan->sync_state)

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to