keep the result of driver->list() and a flag whether it is valid in the store.

This commit is contained in:
Oswald Buddenhagen 2006-03-20 19:27:38 +00:00
parent 861dd7468e
commit 47e592b603
4 changed files with 23 additions and 32 deletions

View File

@ -113,7 +113,6 @@ typedef struct imap_store {
unsigned /*currentnc:1,*/ trashnc:1; unsigned /*currentnc:1,*/ trashnc:1;
int uidnext; /* from SELECT responses */ int uidnext; /* from SELECT responses */
list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */ list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */
string_list_t *boxes; /* LIST results */
message_t **msgapp; /* FETCH results */ message_t **msgapp; /* FETCH results */
unsigned caps, rcaps; /* CAPABILITY results */ unsigned caps, rcaps; /* CAPABILITY results */
/* command queue */ /* command queue */
@ -898,7 +897,7 @@ parse_list_rsp( imap_store_t *ctx, char *cmd )
arg += l; arg += l;
if (!memcmp( arg + strlen( arg ) - 5, ".lock", 5 )) /* workaround broken servers */ if (!memcmp( arg + strlen( arg ) - 5, ".lock", 5 )) /* workaround broken servers */
return; return;
add_string_list( &ctx->boxes, arg ); add_string_list( &ctx->gen.boxes, arg );
} }
static int static int
@ -1042,6 +1041,7 @@ imap_close_store( store_t *gctx )
imap_store_t *ctx = (imap_store_t *)gctx; imap_store_t *ctx = (imap_store_t *)gctx;
free_generic_messages( gctx->msgs ); free_generic_messages( gctx->msgs );
free_string_list( ctx->gen.boxes );
if (ctx->buf.sock.fd != -1) { if (ctx->buf.sock.fd != -1) {
imap_exec( ctx, 0, "LOGOUT" ); imap_exec( ctx, 0, "LOGOUT" );
close( ctx->buf.sock.fd ); close( ctx->buf.sock.fd );
@ -1180,6 +1180,9 @@ imap_open_store( store_conf_t *conf, store_t *oldctx )
if (ctx) { if (ctx) {
if (((imap_store_conf_t *)(ctx->gen.conf))->server == cfg->server) { 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; ctx->gen.conf = conf;
goto final; goto final;
} }
@ -1586,16 +1589,14 @@ imap_find_msg( store_t *gctx, const char *tuid, int *uid )
} }
static int static int
imap_list( store_t *gctx, string_list_t **retb ) imap_list( store_t *gctx )
{ {
imap_store_t *ctx = (imap_store_t *)gctx; imap_store_t *ctx = (imap_store_t *)gctx;
int ret; int ret;
ctx->boxes = 0; if ((ret = imap_exec_b( ctx, 0, "LIST \"\" \"%s%%\"", ctx->prefix )) == DRV_OK)
if ((ret = imap_exec_b( ctx, 0, "LIST \"\" \"%s%%\"", ctx->prefix )) != DRV_OK) gctx->listed = 1;
return ret; return ret;
*retb = ctx->boxes;
return DRV_OK;
} }
static int static int

View File

@ -147,11 +147,12 @@ static void
maildir_close_store( store_t *gctx ) maildir_close_store( store_t *gctx )
{ {
maildir_cleanup( gctx ); maildir_cleanup( gctx );
free_string_list( gctx->boxes );
free( gctx ); free( gctx );
} }
static int static int
maildir_list( store_t *gctx, string_list_t **retb ) maildir_list( store_t *gctx )
{ {
DIR *dir; DIR *dir;
struct dirent *de; 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) ); error( "%s: %s\n", gctx->conf->path, strerror(errno) );
return DRV_STORE_BAD; return DRV_STORE_BAD;
} }
*retb = 0;
while ((de = readdir( dir ))) { while ((de = readdir( dir ))) {
struct stat st; struct stat st;
char buf[PATH_MAX]; 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 ); nfsnprintf( buf, sizeof(buf), "%s%s/cur", gctx->conf->path, de->d_name );
if (stat( buf, &st ) || !S_ISDIR(st.st_mode)) if (stat( buf, &st ) || !S_ISDIR(st.st_mode))
continue; continue;
add_string_list( retb, de->d_name ); add_string_list( &gctx->boxes, de->d_name );
} }
closedir (dir); closedir (dir);
gctx->listed = 1;
return DRV_OK; return DRV_OK;
} }

View File

@ -144,6 +144,8 @@ typedef struct message {
typedef struct store { typedef struct store {
store_conf_t *conf; /* foreign */ store_conf_t *conf; /* foreign */
string_list_t *boxes; /* _list results - own */
unsigned listed:1; /* was _list already run? */
/* currently open mailbox */ /* currently open mailbox */
const char *name; /* foreign! maybe preset? */ const char *name; /* foreign! maybe preset? */
@ -176,7 +178,7 @@ struct driver {
int (*parse_store)( conffile_t *cfg, store_conf_t **storep, int *err ); int (*parse_store)( conffile_t *cfg, store_conf_t **storep, int *err );
store_t *(*open_store)( store_conf_t *conf, store_t *oldctx ); store_t *(*open_store)( store_conf_t *conf, store_t *oldctx );
void (*close_store)( store_t *ctx ); 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_paths)( store_t *ctx );
void (*prepare_opts)( store_t *ctx, int opts ); void (*prepare_opts)( store_t *ctx, int opts );
int (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs ); int (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs );

View File

@ -194,10 +194,10 @@ main( int argc, char **argv )
group_conf_t *group; group_conf_t *group;
driver_t *driver[2]; driver_t *driver[2];
store_t *ctx[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; char *config = 0, *channame, *boxlist, *opt, *ochar;
const char *names[2]; 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; int oind, ret, op, multiple, pseudo = 0, t;
gethostname( Hostname, sizeof(Hostname) ); gethostname( Hostname, sizeof(Hostname) );
@ -444,8 +444,6 @@ main( int argc, char **argv )
ctx[M] = ctx[S] = 0; ctx[M] = ctx[S] = 0;
conf[M] = conf[S] = 0; /* make-gcc-happy */ conf[M] = conf[S] = 0; /* make-gcc-happy */
driver[M] = driver[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) if (all)
multiple = channels->next != 0; multiple = channels->next != 0;
else if (argv[oind + 1]) else if (argv[oind + 1])
@ -493,9 +491,6 @@ main( int argc, char **argv )
if (ctx[t]) { if (ctx[t]) {
if (conf[t] == chan->stores[t]) if (conf[t] == chan->stores[t])
continue; continue;
free_string_list( uboxes[t] );
uboxes[t] = 0;
guboxes[t] = 0;
if (conf[t]->driver != chan->stores[t]->driver) { if (conf[t]->driver != chan->stores[t]->driver) {
driver[t]->close_store( ctx[t] ); driver[t]->close_store( ctx[t] );
ctx[t] = 0; ctx[t] = 0;
@ -525,23 +520,17 @@ main( int argc, char **argv )
} }
} else if (chan->patterns) { } else if (chan->patterns) {
for (t = 0; t < 2; t++) { for (t = 0; t < 2; t++) {
if (!guboxes[t]) { if (!ctx[t]->listed) {
if (driver[t]->list( ctx[t], &uboxes[t] ) != DRV_OK) { if (driver[t]->list( ctx[t] ) != DRV_OK) {
screwt: screwt:
driver[t]->close_store( ctx[t] ); driver[t]->close_store( ctx[t] );
free_string_list( uboxes[t] );
uboxes[t] = 0;
guboxes[t] = 0;
ctx[t] = 0; ctx[t] = 0;
ret = 1; ret = 1;
goto next; goto next;
} else { } else if (ctx[t]->conf->map_inbox)
guboxes[t] = 1; add_string_list( &ctx[t]->boxes, ctx[t]->conf->map_inbox );
if (ctx[t]->conf->map_inbox)
add_string_list( &uboxes[t], ctx[t]->conf->map_inbox );
} }
} boxes[t] = filter_boxes( ctx[t]->boxes, chan->patterns );
boxes[t] = filter_boxes( uboxes[t], chan->patterns );
} }
for (mboxp = &boxes[M]; (mbox = *mboxp); ) { for (mboxp = &boxes[M]; (mbox = *mboxp); ) {
for (sboxp = &boxes[S]; (sbox = *sboxp); sboxp = &sbox->next) for (sboxp = &boxes[S]; (sbox = *sboxp); sboxp = &sbox->next)
@ -606,10 +595,8 @@ main( int argc, char **argv )
break; break;
} }
} }
free_string_list( uboxes[S] );
if (ctx[S]) if (ctx[S])
driver[S]->close_store( ctx[S] ); driver[S]->close_store( ctx[S] );
free_string_list( uboxes[M] );
if (ctx[M]) if (ctx[M])
driver[M]->close_store( ctx[M] ); driver[M]->close_store( ctx[M] );