diff --git a/src/drv_imap.c b/src/drv_imap.c index 2844559..86642b2 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -113,7 +113,6 @@ typedef struct imap_store { unsigned /*currentnc:1,*/ trashnc:1; int uidnext; /* from SELECT responses */ list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */ - string_list_t *boxes; /* LIST results */ message_t **msgapp; /* FETCH results */ unsigned caps, rcaps; /* CAPABILITY results */ /* command queue */ @@ -898,7 +897,7 @@ parse_list_rsp( imap_store_t *ctx, char *cmd ) arg += l; if (!memcmp( arg + strlen( arg ) - 5, ".lock", 5 )) /* workaround broken servers */ return; - add_string_list( &ctx->boxes, arg ); + add_string_list( &ctx->gen.boxes, arg ); } static int @@ -1042,6 +1041,7 @@ imap_close_store( store_t *gctx ) imap_store_t *ctx = (imap_store_t *)gctx; free_generic_messages( gctx->msgs ); + free_string_list( ctx->gen.boxes ); if (ctx->buf.sock.fd != -1) { imap_exec( ctx, 0, "LOGOUT" ); close( ctx->buf.sock.fd ); @@ -1180,6 +1180,9 @@ imap_open_store( store_conf_t *conf, store_t *oldctx ) if (ctx) { if (((imap_store_conf_t *)(ctx->gen.conf))->server == cfg->server) { + free_string_list( ctx->gen.boxes ); + ctx->gen.boxes = 0; + ctx->gen.listed = 0; ctx->gen.conf = conf; goto final; } @@ -1586,16 +1589,14 @@ imap_find_msg( store_t *gctx, const char *tuid, int *uid ) } static int -imap_list( store_t *gctx, string_list_t **retb ) +imap_list( store_t *gctx ) { imap_store_t *ctx = (imap_store_t *)gctx; int ret; - ctx->boxes = 0; - if ((ret = imap_exec_b( ctx, 0, "LIST \"\" \"%s%%\"", ctx->prefix )) != DRV_OK) - return ret; - *retb = ctx->boxes; - return DRV_OK; + if ((ret = imap_exec_b( ctx, 0, "LIST \"\" \"%s%%\"", ctx->prefix )) == DRV_OK) + gctx->listed = 1; + return ret; } static int diff --git a/src/drv_maildir.c b/src/drv_maildir.c index cd38940..d3b0b3e 100644 --- a/src/drv_maildir.c +++ b/src/drv_maildir.c @@ -147,11 +147,12 @@ static void maildir_close_store( store_t *gctx ) { maildir_cleanup( gctx ); + free_string_list( gctx->boxes ); free( gctx ); } static int -maildir_list( store_t *gctx, string_list_t **retb ) +maildir_list( store_t *gctx ) { DIR *dir; struct dirent *de; @@ -160,7 +161,6 @@ maildir_list( store_t *gctx, string_list_t **retb ) error( "%s: %s\n", gctx->conf->path, strerror(errno) ); return DRV_STORE_BAD; } - *retb = 0; while ((de = readdir( dir ))) { struct stat st; char buf[PATH_MAX]; @@ -170,9 +170,10 @@ maildir_list( store_t *gctx, string_list_t **retb ) nfsnprintf( buf, sizeof(buf), "%s%s/cur", gctx->conf->path, de->d_name ); if (stat( buf, &st ) || !S_ISDIR(st.st_mode)) continue; - add_string_list( retb, de->d_name ); + add_string_list( &gctx->boxes, de->d_name ); } closedir (dir); + gctx->listed = 1; return DRV_OK; } diff --git a/src/isync.h b/src/isync.h index 7c90da1..7a06fe2 100644 --- a/src/isync.h +++ b/src/isync.h @@ -144,6 +144,8 @@ typedef struct message { typedef struct store { store_conf_t *conf; /* foreign */ + string_list_t *boxes; /* _list results - own */ + unsigned listed:1; /* was _list already run? */ /* currently open mailbox */ const char *name; /* foreign! maybe preset? */ @@ -176,7 +178,7 @@ struct driver { int (*parse_store)( conffile_t *cfg, store_conf_t **storep, int *err ); store_t *(*open_store)( store_conf_t *conf, store_t *oldctx ); void (*close_store)( store_t *ctx ); - int (*list)( store_t *ctx, string_list_t **boxes ); + int (*list)( store_t *ctx ); void (*prepare_paths)( store_t *ctx ); void (*prepare_opts)( store_t *ctx, int opts ); int (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs ); diff --git a/src/main.c b/src/main.c index d0df5d9..8cf09cd 100644 --- a/src/main.c +++ b/src/main.c @@ -194,10 +194,10 @@ main( int argc, char **argv ) group_conf_t *group; driver_t *driver[2]; store_t *ctx[2]; - string_list_t *uboxes[2], *boxes[2], *mbox, *sbox, **mboxp, **sboxp, *cboxes, *chanptr; + string_list_t *boxes[2], *mbox, *sbox, **mboxp, **sboxp, *cboxes, *chanptr; char *config = 0, *channame, *boxlist, *opt, *ochar; const char *names[2]; - int all = 0, list = 0, cops = 0, ops[2] = { 0, 0 }, guboxes[2]; + int all = 0, list = 0, cops = 0, ops[2] = { 0, 0 }; int oind, ret, op, multiple, pseudo = 0, t; gethostname( Hostname, sizeof(Hostname) ); @@ -444,8 +444,6 @@ main( int argc, char **argv ) ctx[M] = ctx[S] = 0; conf[M] = conf[S] = 0; /* make-gcc-happy */ driver[M] = driver[S] = 0; /* make-gcc-happy */ - guboxes[M] = guboxes[S] = 0; - uboxes[M] = uboxes[S] = 0; if (all) multiple = channels->next != 0; else if (argv[oind + 1]) @@ -493,9 +491,6 @@ main( int argc, char **argv ) if (ctx[t]) { if (conf[t] == chan->stores[t]) continue; - free_string_list( uboxes[t] ); - uboxes[t] = 0; - guboxes[t] = 0; if (conf[t]->driver != chan->stores[t]->driver) { driver[t]->close_store( ctx[t] ); ctx[t] = 0; @@ -525,23 +520,17 @@ main( int argc, char **argv ) } } else if (chan->patterns) { for (t = 0; t < 2; t++) { - if (!guboxes[t]) { - if (driver[t]->list( ctx[t], &uboxes[t] ) != DRV_OK) { + if (!ctx[t]->listed) { + if (driver[t]->list( ctx[t] ) != DRV_OK) { screwt: driver[t]->close_store( ctx[t] ); - free_string_list( uboxes[t] ); - uboxes[t] = 0; - guboxes[t] = 0; ctx[t] = 0; ret = 1; goto next; - } else { - guboxes[t] = 1; - if (ctx[t]->conf->map_inbox) - add_string_list( &uboxes[t], ctx[t]->conf->map_inbox ); - } + } else if (ctx[t]->conf->map_inbox) + add_string_list( &ctx[t]->boxes, ctx[t]->conf->map_inbox ); } - boxes[t] = filter_boxes( uboxes[t], chan->patterns ); + boxes[t] = filter_boxes( ctx[t]->boxes, chan->patterns ); } for (mboxp = &boxes[M]; (mbox = *mboxp); ) { for (sboxp = &boxes[S]; (sbox = *sboxp); sboxp = &sbox->next) @@ -606,10 +595,8 @@ main( int argc, char **argv ) break; } } - free_string_list( uboxes[S] ); if (ctx[S]) driver[S]->close_store( ctx[S] ); - free_string_list( uboxes[M] ); if (ctx[M]) driver[M]->close_store( ctx[M] );