allow prefixes to Patterns
this makes it possible to "rename" a "namespace" while syncing.
This commit is contained in:
parent
6c6ad9710c
commit
cf0f32f800
57
src/main.c
57
src/main.c
|
@ -144,13 +144,16 @@ matches( const char *t, const char *p )
|
|||
}
|
||||
|
||||
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;
|
||||
const char *ps;
|
||||
int not, fnot;
|
||||
int not, fnot, pfxl;
|
||||
|
||||
pfxl = prefix ? strlen( prefix ) : 0;
|
||||
for (; boxes; boxes = boxes->next) {
|
||||
if (memcmp( boxes->string, prefix, pfxl ))
|
||||
continue;
|
||||
fnot = 1;
|
||||
for (cpat = patterns; cpat; cpat = cpat->next) {
|
||||
ps = cpat->string;
|
||||
|
@ -159,13 +162,13 @@ filter_boxes( string_list_t *boxes, string_list_t *patterns )
|
|||
not = 1;
|
||||
} else
|
||||
not = 0;
|
||||
if (matches( boxes->string, ps )) {
|
||||
if (matches( boxes->string + pfxl, ps )) {
|
||||
fnot = not;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fnot)
|
||||
add_string_list( &nboxes, boxes->string );
|
||||
add_string_list( &nboxes, boxes->string + pfxl );
|
||||
}
|
||||
return nboxes;
|
||||
}
|
||||
|
@ -195,7 +198,7 @@ typedef struct {
|
|||
driver_t *drv[2];
|
||||
store_t *ctx[2];
|
||||
string_list_t *boxes[2], *cboxes, *chanptr;
|
||||
const char *names[2];
|
||||
char *names[2];
|
||||
char **argv;
|
||||
int oind, ret, multiple, all, list, ops[2], state[2];
|
||||
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 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_2_dyn( int sts, void *aux );
|
||||
static void done_sync( int sts, void *aux );
|
||||
|
||||
#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) {
|
||||
mvars->boxlist = 1;
|
||||
mvars->boxes[M] = filter_boxes( mvars->ctx[M]->boxes, mvars->chan->patterns );
|
||||
mvars->boxes[S] = filter_boxes( mvars->ctx[S]->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->boxes[S], mvars->chan->patterns );
|
||||
for (mboxp = &mvars->boxes[M]; (mbox = *mboxp); ) {
|
||||
for (sboxp = &mvars->boxes[S]; (sbox = *sboxp); sboxp = &sbox->next)
|
||||
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) {
|
||||
const char *pat = cpat->string;
|
||||
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,
|
||||
* except implicity when the INBOX lives under Path. */
|
||||
if (!memcmp( pat, "INBOX", 5 )) {
|
||||
char c = pat[5];
|
||||
if (!memcmp( buf, "INBOX", 5 )) {
|
||||
char c = buf[5];
|
||||
if (!c) {
|
||||
/* User really wants the INBOX. */
|
||||
flags |= LIST_INBOX;
|
||||
|
@ -782,12 +788,25 @@ store_listed( int sts, void *aux )
|
|||
static int
|
||||
sync_listed_boxes( main_vars_t *mvars, string_list_t *mbox )
|
||||
{
|
||||
if (!mvars->list) {
|
||||
mvars->names[M] = mvars->names[S] = mbox->string;
|
||||
sync_boxes( mvars->ctx, (const char **)mvars->names, mvars->chan, done_sync_dyn, mvars );
|
||||
return 1;
|
||||
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) {
|
||||
mvars->names[M] = mvars->names[S] = mbox->string;
|
||||
sync_boxes( mvars->ctx, (const char **)mvars->names, mvars->chan, done_sync_dyn, mvars );
|
||||
return 1;
|
||||
}
|
||||
puts( mbox->string );
|
||||
}
|
||||
puts( mbox->string );
|
||||
free( mbox );
|
||||
return 0;
|
||||
}
|
||||
|
@ -801,6 +820,16 @@ done_sync_dyn( int sts, void *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
|
||||
done_sync( int sts, void *aux )
|
||||
{
|
||||
|
|
|
@ -367,7 +367,9 @@ Define the Channel \fIname\fR, opening a section for its parameters.
|
|||
.TP
|
||||
{\fBMaster\fR|\fBSlave\fR} \fB:\fIstore\fB:\fR[\fImailbox\fR]
|
||||
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.
|
||||
..
|
||||
.TP
|
||||
|
|
|
@ -94,3 +94,9 @@ Slave :mirror:
|
|||
Patterns %
|
||||
|
||||
Group partial o2o:inbox,sent-mail,foobar
|
||||
|
||||
# INBOX => server, INBOX.foo => server.foo, etc.
|
||||
Channel inbox
|
||||
Master :server:INBOX
|
||||
Slave :mirror:server
|
||||
Patterns *
|
||||
|
|
Loading…
Reference in New Issue
Block a user