commit 46389fba6480163d673d0a8920387a11db971e36
Author: Oswald Buddenhagen <o...@kde.org>
Date:   Sat Aug 18 13:58:14 2012 +0200

    introduce ability to flatten the hierarchy of Stores

 src/config.c |   13 ++++++++++++-
 src/isync.h  |    4 +++-
 src/main.c   |    9 +++++++++
 src/mbsync.1 |   12 ++++++++++++
 src/sync.c   |   22 +++++++++++++++++++---
 5 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/src/config.c b/src/config.c
index ed0466f..658d7f8 100644
--- a/src/config.c
+++ b/src/config.c
@@ -430,7 +430,18 @@ parse_generic_store( store_conf_t *store, conffile_t *cfg, 
int *err )
                store->max_size = parse_size( cfg );
        else if (!strcasecmp( "MapInbox", cfg->cmd ))
                store->map_inbox = nfstrdup( cfg->val );
-       else {
+       else if (!strcasecmp( "Flatten", cfg->cmd )) {
+               int sl = strlen( cfg->val );
+               if (sl != 1) {
+                       error( "%s:%d: malformed flattened hierarchy 
delimiter\n", cfg->file, cfg->line );
+                       *err = 1;
+               } else if (cfg->val[0] == '/') {
+                       error( "%s:%d: flattened hierarchy delimiter cannot be 
the canonical delimiter '/'\n", cfg->file, cfg->line );
+                       *err = 1;
+               } else {
+                       store->flat_delim = cfg->val[0];
+               }
+       } else {
                error( "%s:%d: unknown keyword '%s'\n", cfg->file, cfg->line, 
cfg->cmd );
                *err = 1;
        }
diff --git a/src/isync.h b/src/isync.h
index 28b3b8e..efb365a 100644
--- a/src/isync.h
+++ b/src/isync.h
@@ -142,6 +142,7 @@ typedef struct store_conf {
        const char *trash;
        unsigned max_size; /* off_t is overkill */
        unsigned trash_remote_new:1, trash_only_new:1;
+       char flat_delim;
 } store_conf_t;
 
 typedef struct string_list {
@@ -216,7 +217,8 @@ typedef struct store {
        void *bad_callback_aux;
 
        /* currently open mailbox */
-       const char *name; /* foreign! maybe preset? */
+       const char *orig_name; /* foreign! maybe preset? */
+       char *name; /* foreign! maybe preset? */
        char *path; /* own */
        message_t *msgs; /* own */
        int uidvalidity;
diff --git a/src/main.c b/src/main.c
index d3d0302..1535a30 100644
--- a/src/main.c
+++ b/src/main.c
@@ -718,12 +718,21 @@ static void
 store_listed( int sts, void *aux )
 {
        MVARS(aux)
+       string_list_t *box;
 
        switch (sts) {
        case DRV_CANCELED:
                return;
        case DRV_OK:
                mvars->ctx[t]->listed = 1;
+               if (mvars->ctx[t]->conf->flat_delim) {
+                       for (box = mvars->ctx[t]->boxes; box; box = box->next) {
+                               if (map_name( box->string, 
mvars->ctx[t]->conf->flat_delim, '/' ) < 0) {
+                                       error( "Error: flattened mailbox name 
'%s' contains canonical hierarchy delimiter\n", box->string );
+                                       mvars->ret = mvars->skip = 1;
+                               }
+                       }
+               }
                if (mvars->ctx[t]->conf->map_inbox)
                        add_string_list( &mvars->ctx[t]->boxes, 
mvars->ctx[t]->conf->map_inbox );
                break;
diff --git a/src/mbsync.1 b/src/mbsync.1
index 5d41e1a..7f653b6 100644
--- a/src/mbsync.1
+++ b/src/mbsync.1
@@ -150,6 +150,15 @@ Channels section.
 This virtual mailbox does not support subfolders.
 ..
 .TP
+\fBFlatten\fR \fIdelim\fR
+Flatten the hierarchy within this Store by substituting the canonical
+hierarchy delimiter \fB/\fR with \fIdelim\fR.
+This can be useful when the MUA used to access the Store provides
+suboptimal handling of hierarchical mailboxes, as is the case with
+\fBMutt\fR.
+A common choice for the delimiter is \fB.\fR.
+..
+.TP
 \fBTrash\fR \fImailbox\fR
 Specifies a mailbox (relative to \fBPath\fR) to copy deleted messages to
 prior to expunging. See \fBINHERENT PROBLEMS\fR below.
@@ -318,6 +327,9 @@ This option is meaningless if a \fBPath\fR was specified.
 \fBPathDelimiter\fR \fIdelim\fR
 Specify the server's hierarchy delimiter character.
 (Default: taken from the server's first "personal" NAMESPACE)
+.br
+Do \fBNOT\fR abuse this to re-interpret the hierarchy.
+Use \fBFlatten\fR instead.
 ..
 .SS Channels
 .TP
diff --git a/src/sync.c b/src/sync.c
index e7f0518..45fc2cc 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -467,6 +467,7 @@ stats( sync_vars_t *svars )
 static void sync_bail( sync_vars_t *svars );
 static void sync_bail1( sync_vars_t *svars );
 static void sync_bail2( sync_vars_t *svars );
+static void sync_bail3( sync_vars_t *svars );
 static void cancel_done( void *aux );
 
 static void
@@ -605,9 +606,16 @@ sync_boxes( store_t *ctx[], const char *names[], 
channel_conf_t *chan,
        svars->srecadd = &svars->srecs;
 
        for (t = 0; t < 2; t++) {
-               ctx[t]->name =
+               ctx[t]->orig_name =
                        (!names[t] || (ctx[t]->conf->map_inbox && !strcmp( 
ctx[t]->conf->map_inbox, names[t] ))) ?
                                "INBOX" : names[t];
+               ctx[t]->name = nfstrdup( ctx[t]->orig_name );
+               if (ctx[t]->conf->flat_delim && map_name( ctx[t]->name, '/', 
ctx[t]->conf->flat_delim ) < 0) {
+                       error( "Error: canonical mailbox name '%s' contains 
flattened hierarchy delimiter\n", ctx[t]->name );
+                       svars->ret = SYNC_FAIL;
+                       sync_bail3( svars );
+                       return;
+               }
                ctx[t]->uidvalidity = -1;
                set_bad_callback( ctx[t], store_bad, AUX );
                svars->drv[t] = ctx[t]->conf->driver;
@@ -615,7 +623,7 @@ sync_boxes( store_t *ctx[], const char *names[], 
channel_conf_t *chan,
        /* Both boxes must be fully set up at this point, so that error exit 
paths
         * don't run into uninitialized variables. */
        for (t = 0; t < 2; t++) {
-               info( "Selecting %s %s...\n", str_ms[t], ctx[t]->name );
+               info( "Selecting %s %s...\n", str_ms[t], ctx[t]->orig_name );
                DRIVER_CALL(select( ctx[t], (chan->ops[t] & OP_CREATE) != 0, 
box_selected, AUX ));
        }
 }
@@ -696,7 +704,7 @@ box_selected( int sts, void *aux )
        }
        if (fcntl( svars->lfd, F_SETLK, &lck )) {
                error( "Error: channel :%s:%s-:%s:%s is locked\n",
-                        chan->stores[M]->name, ctx[M]->name, 
chan->stores[S]->name, ctx[S]->name );
+                        chan->stores[M]->name, ctx[M]->orig_name, 
chan->stores[S]->name, ctx[S]->orig_name );
                svars->ret = SYNC_FAIL;
                sync_bail1( svars );
                return;
@@ -1721,6 +1729,14 @@ sync_bail2( sync_vars_t *svars )
        free( svars->jname );
        free( svars->dname );
        flushn();
+       sync_bail3( svars );
+}
+
+static void
+sync_bail3( sync_vars_t *svars )
+{
+       free( svars->ctx[M]->name );
+       free( svars->ctx[S]->name );
        sync_deref( svars );
 }
 

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to