allow prefixes to Patterns

this makes it possible to "rename" a "namespace" while syncing.
This commit is contained in:
Oswald Buddenhagen 2013-12-08 09:49:39 +01:00
parent 6c6ad9710c
commit cf0f32f800
3 changed files with 52 additions and 15 deletions

View File

@ -144,13 +144,16 @@ matches( const char *t, const char *p )
} }
static string_list_t * static string_list_t *
filter_boxes( string_list_t *boxes, string_list_t *patterns ) filter_boxes( string_list_t *boxes, const char *prefix, string_list_t *patterns )
{ {
string_list_t *nboxes = 0, *cpat; string_list_t *nboxes = 0, *cpat;
const char *ps; const char *ps;
int not, fnot; int not, fnot, pfxl;
pfxl = prefix ? strlen( prefix ) : 0;
for (; boxes; boxes = boxes->next) { for (; boxes; boxes = boxes->next) {
if (memcmp( boxes->string, prefix, pfxl ))
continue;
fnot = 1; fnot = 1;
for (cpat = patterns; cpat; cpat = cpat->next) { for (cpat = patterns; cpat; cpat = cpat->next) {
ps = cpat->string; ps = cpat->string;
@ -159,13 +162,13 @@ filter_boxes( string_list_t *boxes, string_list_t *patterns )
not = 1; not = 1;
} else } else
not = 0; not = 0;
if (matches( boxes->string, ps )) { if (matches( boxes->string + pfxl, ps )) {
fnot = not; fnot = not;
break; break;
} }
} }
if (!fnot) if (!fnot)
add_string_list( &nboxes, boxes->string ); add_string_list( &nboxes, boxes->string + pfxl );
} }
return nboxes; return nboxes;
} }
@ -195,7 +198,7 @@ typedef struct {
driver_t *drv[2]; driver_t *drv[2];
store_t *ctx[2]; store_t *ctx[2];
string_list_t *boxes[2], *cboxes, *chanptr; string_list_t *boxes[2], *cboxes, *chanptr;
const char *names[2]; char *names[2];
char **argv; char **argv;
int oind, ret, multiple, all, list, ops[2], state[2]; int oind, ret, multiple, all, list, ops[2], state[2];
char done, skip, cben, boxlist; char done, skip, cben, boxlist;
@ -504,6 +507,7 @@ static void store_opened( store_t *ctx, void *aux );
static void store_listed( int sts, void *aux ); static void store_listed( int sts, void *aux );
static int sync_listed_boxes( main_vars_t *mvars, string_list_t *mbox ); static int sync_listed_boxes( main_vars_t *mvars, string_list_t *mbox );
static void done_sync_dyn( int sts, void *aux ); static void done_sync_dyn( int sts, void *aux );
static void done_sync_2_dyn( int sts, void *aux );
static void done_sync( int sts, void *aux ); static void done_sync( int sts, void *aux );
#define nz(a,b) ((a)?(a):(b)) #define nz(a,b) ((a)?(a):(b))
@ -601,8 +605,8 @@ sync_chans( main_vars_t *mvars, int ent )
if (!mvars->boxlist && mvars->chan->patterns) { if (!mvars->boxlist && mvars->chan->patterns) {
mvars->boxlist = 1; mvars->boxlist = 1;
mvars->boxes[M] = filter_boxes( mvars->ctx[M]->boxes, mvars->chan->patterns ); mvars->boxes[M] = filter_boxes( mvars->ctx[M]->boxes, mvars->chan->boxes[M], mvars->chan->patterns );
mvars->boxes[S] = filter_boxes( mvars->ctx[S]->boxes, mvars->chan->patterns ); mvars->boxes[S] = filter_boxes( mvars->ctx[S]->boxes, mvars->chan->boxes[S], mvars->chan->patterns );
for (mboxp = &mvars->boxes[M]; (mbox = *mboxp); ) { for (mboxp = &mvars->boxes[M]; (mbox = *mboxp); ) {
for (sboxp = &mvars->boxes[S]; (sbox = *sboxp); sboxp = &sbox->next) for (sboxp = &mvars->boxes[S]; (sbox = *sboxp); sboxp = &sbox->next)
if (!strcmp( sbox->string, mbox->string )) { if (!strcmp( sbox->string, mbox->string )) {
@ -710,10 +714,12 @@ store_opened( store_t *ctx, void *aux )
for (flags = 0, cpat = mvars->chan->patterns; cpat; cpat = cpat->next) { for (flags = 0, cpat = mvars->chan->patterns; cpat; cpat = cpat->next) {
const char *pat = cpat->string; const char *pat = cpat->string;
if (*pat != '!') { if (*pat != '!') {
char buf[8];
snprintf( buf, sizeof(buf), "%s%s", mvars->chan->boxes[t], pat );
/* Partial matches like "INB*" or even "*" are not considered, /* Partial matches like "INB*" or even "*" are not considered,
* except implicity when the INBOX lives under Path. */ * except implicity when the INBOX lives under Path. */
if (!memcmp( pat, "INBOX", 5 )) { if (!memcmp( buf, "INBOX", 5 )) {
char c = pat[5]; char c = buf[5];
if (!c) { if (!c) {
/* User really wants the INBOX. */ /* User really wants the INBOX. */
flags |= LIST_INBOX; flags |= LIST_INBOX;
@ -782,12 +788,25 @@ store_listed( int sts, void *aux )
static int static int
sync_listed_boxes( main_vars_t *mvars, string_list_t *mbox ) sync_listed_boxes( main_vars_t *mvars, string_list_t *mbox )
{ {
if (mvars->chan->boxes[M] || mvars->chan->boxes[S]) {
const char *mpfx = nz( mvars->chan->boxes[M], "" );
const char *spfx = nz( mvars->chan->boxes[S], "" );
if (!mvars->list) {
nfasprintf( &mvars->names[M], "%s%s", mpfx, mbox->string );
nfasprintf( &mvars->names[S], "%s%s", spfx, mbox->string );
free( mbox );
sync_boxes( mvars->ctx, (const char **)mvars->names, mvars->chan, done_sync_2_dyn, mvars );
return 1;
}
printf( "%s%s <=> %s%s\n", mpfx, mbox->string, spfx, mbox->string );
} else {
if (!mvars->list) { if (!mvars->list) {
mvars->names[M] = mvars->names[S] = mbox->string; mvars->names[M] = mvars->names[S] = mbox->string;
sync_boxes( mvars->ctx, (const char **)mvars->names, mvars->chan, done_sync_dyn, mvars ); sync_boxes( mvars->ctx, (const char **)mvars->names, mvars->chan, done_sync_dyn, mvars );
return 1; return 1;
} }
puts( mbox->string ); puts( mbox->string );
}
free( mbox ); free( mbox );
return 0; return 0;
} }
@ -801,6 +820,16 @@ done_sync_dyn( int sts, void *aux )
done_sync( sts, aux ); done_sync( sts, aux );
} }
static void
done_sync_2_dyn( int sts, void *aux )
{
main_vars_t *mvars = (main_vars_t *)aux;
free( mvars->names[M] );
free( mvars->names[S] );
done_sync( sts, aux );
}
static void static void
done_sync( int sts, void *aux ) done_sync( int sts, void *aux )
{ {

View File

@ -367,7 +367,9 @@ Define the Channel \fIname\fR, opening a section for its parameters.
.TP .TP
{\fBMaster\fR|\fBSlave\fR} \fB:\fIstore\fB:\fR[\fImailbox\fR] {\fBMaster\fR|\fBSlave\fR} \fB:\fIstore\fB:\fR[\fImailbox\fR]
Specify the Master resp. Slave Store to be connected by this Channel. Specify the Master resp. Slave Store to be connected by this Channel.
If \fBPatterns\fR are specified, \fImailbox\fR is ignored. If \fBPatterns\fR are specified, \fImailbox\fR is interpreted as a
prefix which is not matched against the patterns, and which is not
affected by mailbox list overrides.
Otherwise, if \fImailbox\fR is omitted, \fBINBOX\fR is assumed. Otherwise, if \fImailbox\fR is omitted, \fBINBOX\fR is assumed.
.. ..
.TP .TP

View File

@ -94,3 +94,9 @@ Slave :mirror:
Patterns % Patterns %
Group partial o2o:inbox,sent-mail,foobar Group partial o2o:inbox,sent-mail,foobar
# INBOX => server, INBOX.foo => server.foo, etc.
Channel inbox
Master :server:INBOX
Slave :mirror:server
Patterns *