rework Pattern application
instead of creating three lists of mailboxes (common, master, slave) and deriving the mailbox presence from the list being processed, create a single joined list which contains the presence information. additionally, the list is sorted alphabetically (with INBOX first), which is neater.
This commit is contained in:
parent
e00d0f1ac3
commit
05deb008db
153
src/main.c
153
src/main.c
|
@ -153,12 +153,33 @@ matches( const char *t, const char *p )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static string_list_t *
|
|
||||||
|
static int
|
||||||
|
is_inbox( const char *name )
|
||||||
|
{
|
||||||
|
return starts_with( name, -1, "INBOX", 5 ) && (!name[5] || name[5] == '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmp_box_names( const void *a, const void *b )
|
||||||
|
{
|
||||||
|
const char *as = *(const char **)a;
|
||||||
|
const char *bs = *(const char **)b;
|
||||||
|
int ai = is_inbox( as );
|
||||||
|
int bi = is_inbox( bs );
|
||||||
|
int di = bi - ai;
|
||||||
|
if (di)
|
||||||
|
return di;
|
||||||
|
return strcmp( as, bs );
|
||||||
|
}
|
||||||
|
|
||||||
|
static char **
|
||||||
filter_boxes( string_list_t *boxes, const char *prefix, 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 *cpat;
|
||||||
|
char **boxarr = 0;
|
||||||
const char *ps;
|
const char *ps;
|
||||||
int not, fnot, pfxl;
|
int not, fnot, pfxl, num = 0, rnum = 0;
|
||||||
|
|
||||||
pfxl = prefix ? strlen( prefix ) : 0;
|
pfxl = prefix ? strlen( prefix ) : 0;
|
||||||
for (; boxes; boxes = boxes->next) {
|
for (; boxes; boxes = boxes->next) {
|
||||||
|
@ -177,10 +198,15 @@ filter_boxes( string_list_t *boxes, const char *prefix, string_list_t *patterns
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!fnot)
|
if (!fnot) {
|
||||||
add_string_list( &nboxes, boxes->string + pfxl );
|
if (num + 1 >= rnum)
|
||||||
|
boxarr = nfrealloc( boxarr, (rnum = (rnum + 10) * 2) * sizeof(*boxarr) );
|
||||||
|
boxarr[num++] = nfstrdup( boxes->string + pfxl );
|
||||||
|
boxarr[num] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nboxes;
|
qsort( boxarr, num, sizeof(*boxarr), cmp_box_names );
|
||||||
|
return boxarr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -202,12 +228,19 @@ merge_actions( channel_conf_t *chan, int ops[], int have, int mask, int def )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct box_ent {
|
||||||
|
struct box_ent *next;
|
||||||
|
char *name;
|
||||||
|
int present[2];
|
||||||
|
} box_ent_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int t[2];
|
int t[2];
|
||||||
channel_conf_t *chan;
|
channel_conf_t *chan;
|
||||||
driver_t *drv[2];
|
driver_t *drv[2];
|
||||||
store_t *ctx[2];
|
store_t *ctx[2];
|
||||||
string_list_t *boxes[2], *cboxes, *chanptr;
|
box_ent_t *boxes;
|
||||||
|
string_list_t *chanptr;
|
||||||
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];
|
||||||
|
@ -524,7 +557,7 @@ main( int argc, char **argv )
|
||||||
|
|
||||||
static void store_opened( store_t *ctx, void *aux );
|
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, int present[] );
|
static int sync_listed_boxes( main_vars_t *mvars, box_ent_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_2_dyn( int sts, void *aux );
|
||||||
static void done_sync( int sts, void *aux );
|
static void done_sync( int sts, void *aux );
|
||||||
|
@ -536,10 +569,10 @@ sync_chans( main_vars_t *mvars, int ent )
|
||||||
{
|
{
|
||||||
group_conf_t *group;
|
group_conf_t *group;
|
||||||
channel_conf_t *chan;
|
channel_conf_t *chan;
|
||||||
string_list_t *mbox, *sbox, **mboxp, **sboxp;
|
box_ent_t *mbox, *nmbox, **mboxapp;
|
||||||
char *channame, *boxp, *nboxp;
|
char *channame, **boxes[2], *boxp, *nboxp;
|
||||||
const char *labels[2];
|
const char *labels[2];
|
||||||
int t;
|
int t, mb, sb, cmp;
|
||||||
|
|
||||||
if (!mvars->cben)
|
if (!mvars->cben)
|
||||||
return;
|
return;
|
||||||
|
@ -549,7 +582,7 @@ sync_chans( main_vars_t *mvars, int ent )
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
mvars->boxlist = 0;
|
mvars->boxlist = 0;
|
||||||
mvars->boxes[M] = mvars->boxes[S] = mvars->cboxes = 0;
|
mvars->boxes = 0;
|
||||||
if (!mvars->all) {
|
if (!mvars->all) {
|
||||||
if (mvars->chanptr)
|
if (mvars->chanptr)
|
||||||
channame = mvars->chanptr->string;
|
channame = mvars->chanptr->string;
|
||||||
|
@ -580,6 +613,7 @@ sync_chans( main_vars_t *mvars, int ent )
|
||||||
goto gotnone;
|
goto gotnone;
|
||||||
}
|
}
|
||||||
mvars->boxlist = 1;
|
mvars->boxlist = 1;
|
||||||
|
mboxapp = &mvars->boxes;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
nboxp = strpbrk( boxp, ",\n" );
|
nboxp = strpbrk( boxp, ",\n" );
|
||||||
if (nboxp) {
|
if (nboxp) {
|
||||||
|
@ -588,10 +622,15 @@ sync_chans( main_vars_t *mvars, int ent )
|
||||||
} else {
|
} else {
|
||||||
t = strlen( boxp );
|
t = strlen( boxp );
|
||||||
}
|
}
|
||||||
|
mbox = nfmalloc( sizeof(*mbox) );
|
||||||
if (t)
|
if (t)
|
||||||
add_string_list_n( &mvars->cboxes, boxp, t );
|
mbox->name = nfstrndup( boxp, t );
|
||||||
else
|
else
|
||||||
add_string_list_n( &mvars->cboxes, "INBOX", 5 );
|
mbox->name = nfstrndup( "INBOX", 5 );
|
||||||
|
mbox->present[M] = mbox->present[S] = BOX_POSSIBLE;
|
||||||
|
mbox->next = 0;
|
||||||
|
*mboxapp = mbox;
|
||||||
|
mboxapp = &mbox->next;
|
||||||
if (!nboxp)
|
if (!nboxp)
|
||||||
break;
|
break;
|
||||||
boxp = nboxp;
|
boxp = nboxp;
|
||||||
|
@ -638,21 +677,34 @@ 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->boxes[M], mvars->chan->patterns );
|
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 );
|
boxes[S] = filter_boxes( mvars->ctx[S]->boxes, mvars->chan->boxes[S], mvars->chan->patterns );
|
||||||
for (mboxp = &mvars->boxes[M]; (mbox = *mboxp); ) {
|
mboxapp = &mvars->boxes;
|
||||||
for (sboxp = &mvars->boxes[S]; (sbox = *sboxp); sboxp = &sbox->next)
|
for (mb = sb = 0; boxes[M][mb] || boxes[S][sb]; ) {
|
||||||
if (!strcmp( sbox->string, mbox->string )) {
|
mbox = nfmalloc( sizeof(*mbox) );
|
||||||
*sboxp = sbox->next;
|
if (!(cmp = !boxes[M][mb] - !boxes[S][sb]) && !(cmp = cmp_box_names( boxes[M] + mb, boxes[S] + sb ))) {
|
||||||
free( sbox );
|
mbox->name = boxes[M][mb];
|
||||||
*mboxp = mbox->next;
|
free( boxes[S][sb] );
|
||||||
mbox->next = mvars->cboxes;
|
mbox->present[M] = mbox->present[S] = BOX_PRESENT;
|
||||||
mvars->cboxes = mbox;
|
mb++;
|
||||||
goto gotdupe;
|
sb++;
|
||||||
}
|
} else if (cmp < 0) {
|
||||||
mboxp = &mbox->next;
|
mbox->name = boxes[M][mb];
|
||||||
gotdupe: ;
|
mbox->present[M] = BOX_PRESENT;
|
||||||
|
mbox->present[S] = BOX_ABSENT;
|
||||||
|
mb++;
|
||||||
|
} else {
|
||||||
|
mbox->name = boxes[S][sb];
|
||||||
|
mbox->present[M] = BOX_ABSENT;
|
||||||
|
mbox->present[S] = BOX_PRESENT;
|
||||||
|
sb++;
|
||||||
|
}
|
||||||
|
mbox->next = 0;
|
||||||
|
*mboxapp = mbox;
|
||||||
|
mboxapp = &mbox->next;
|
||||||
}
|
}
|
||||||
|
free( boxes[M] );
|
||||||
|
free( boxes[S] );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mvars->list && mvars->multiple)
|
if (mvars->list && mvars->multiple)
|
||||||
|
@ -660,21 +712,11 @@ sync_chans( main_vars_t *mvars, int ent )
|
||||||
syncml:
|
syncml:
|
||||||
mvars->done = mvars->cben = 0;
|
mvars->done = mvars->cben = 0;
|
||||||
if (mvars->boxlist) {
|
if (mvars->boxlist) {
|
||||||
while ((mbox = mvars->cboxes)) {
|
while ((mbox = mvars->boxes)) {
|
||||||
int present[] = { BOX_PRESENT, BOX_PRESENT };
|
mvars->boxes = mbox->next;
|
||||||
mvars->cboxes = mbox->next;
|
if (sync_listed_boxes( mvars, mbox ))
|
||||||
if (sync_listed_boxes( mvars, mbox, present ))
|
|
||||||
goto syncw;
|
goto syncw;
|
||||||
}
|
}
|
||||||
for (t = 0; t < 2; t++)
|
|
||||||
while ((mbox = mvars->boxes[t])) {
|
|
||||||
int present[2];
|
|
||||||
present[t] = BOX_PRESENT;
|
|
||||||
present[1-t] = BOX_ABSENT;
|
|
||||||
mvars->boxes[t] = mbox->next;
|
|
||||||
if (sync_listed_boxes( mvars, mbox, present ))
|
|
||||||
goto syncw;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!mvars->list) {
|
if (!mvars->list) {
|
||||||
int present[] = { BOX_POSSIBLE, BOX_POSSIBLE };
|
int present[] = { BOX_POSSIBLE, BOX_POSSIBLE };
|
||||||
|
@ -701,9 +743,11 @@ sync_chans( main_vars_t *mvars, int ent )
|
||||||
mvars->skip = mvars->cben = 1;
|
mvars->skip = mvars->cben = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
free_string_list( mvars->cboxes );
|
for (nmbox = mvars->boxes; (mbox = nmbox); ) {
|
||||||
free_string_list( mvars->boxes[M] );
|
nmbox = mbox->next;
|
||||||
free_string_list( mvars->boxes[S] );
|
free( mbox->name );
|
||||||
|
free( mbox );
|
||||||
|
}
|
||||||
next2:
|
next2:
|
||||||
if (mvars->all) {
|
if (mvars->all) {
|
||||||
if (!(mvars->chan = mvars->chan->next))
|
if (!(mvars->chan = mvars->chan->next))
|
||||||
|
@ -821,27 +865,30 @@ store_listed( int sts, void *aux )
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sync_listed_boxes( main_vars_t *mvars, string_list_t *mbox, int present[] )
|
sync_listed_boxes( main_vars_t *mvars, box_ent_t *mbox )
|
||||||
{
|
{
|
||||||
if (mvars->chan->boxes[M] || mvars->chan->boxes[S]) {
|
if (mvars->chan->boxes[M] || mvars->chan->boxes[S]) {
|
||||||
const char *mpfx = nz( mvars->chan->boxes[M], "" );
|
const char *mpfx = nz( mvars->chan->boxes[M], "" );
|
||||||
const char *spfx = nz( mvars->chan->boxes[S], "" );
|
const char *spfx = nz( mvars->chan->boxes[S], "" );
|
||||||
if (!mvars->list) {
|
if (!mvars->list) {
|
||||||
nfasprintf( &mvars->names[M], "%s%s", mpfx, mbox->string );
|
nfasprintf( &mvars->names[M], "%s%s", mpfx, mbox->name );
|
||||||
nfasprintf( &mvars->names[S], "%s%s", spfx, mbox->string );
|
nfasprintf( &mvars->names[S], "%s%s", spfx, mbox->name );
|
||||||
|
free( mbox->name );
|
||||||
|
sync_boxes( mvars->ctx, (const char **)mvars->names, mbox->present, mvars->chan, done_sync_2_dyn, mvars );
|
||||||
free( mbox );
|
free( mbox );
|
||||||
sync_boxes( mvars->ctx, (const char **)mvars->names, present, mvars->chan, done_sync_2_dyn, mvars );
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
printf( "%s%s <=> %s%s\n", mpfx, mbox->string, spfx, mbox->string );
|
printf( "%s%s <=> %s%s\n", mpfx, mbox->name, spfx, mbox->name );
|
||||||
} else {
|
} else {
|
||||||
if (!mvars->list) {
|
if (!mvars->list) {
|
||||||
mvars->names[M] = mvars->names[S] = mbox->string;
|
mvars->names[M] = mvars->names[S] = mbox->name;
|
||||||
sync_boxes( mvars->ctx, (const char **)mvars->names, present, mvars->chan, done_sync_dyn, mvars );
|
sync_boxes( mvars->ctx, (const char **)mvars->names, mbox->present, mvars->chan, done_sync_dyn, mvars );
|
||||||
|
free( mbox );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
puts( mbox->string );
|
puts( mbox->name );
|
||||||
}
|
}
|
||||||
|
free( mbox->name );
|
||||||
free( mbox );
|
free( mbox );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -851,7 +898,7 @@ done_sync_dyn( int sts, void *aux )
|
||||||
{
|
{
|
||||||
main_vars_t *mvars = (main_vars_t *)aux;
|
main_vars_t *mvars = (main_vars_t *)aux;
|
||||||
|
|
||||||
free( ((char *)mvars->names[S]) - offsetof(string_list_t, string) );
|
free( mvars->names[M] );
|
||||||
done_sync( sts, aux );
|
done_sync( sts, aux );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user