From 47897d2403f2ef5e9c7e53eac129144526ed7654 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Sat, 4 Oct 2014 18:26:10 +0200 Subject: [PATCH] fix memory management of current mailbox name it was a stupid idea to store the pointer to a variable we need to dispose in a structure which has its own lifetime. --- src/driver.h | 5 ++--- src/drv_imap.c | 6 ++++-- src/drv_maildir.c | 8 ++++---- src/sync.c | 17 ++++++++--------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/driver.h b/src/driver.h index 9fd1428..31ee1bf 100644 --- a/src/driver.h +++ b/src/driver.h @@ -87,7 +87,6 @@ typedef struct store { /* currently open mailbox */ const char *orig_name; /* foreign! maybe preset? */ - char *name; /* foreign! maybe preset? */ char *path; /* own */ message_t *msgs; /* own */ int uidvalidity; @@ -168,9 +167,9 @@ struct driver { * needed or available operations. */ void (*prepare_opts)( store_t *ctx, int opts ); - /* Open the mailbox ctx->name. Optionally create missing boxes. + /* Open the mailbox name. Optionally create missing boxes. * As a side effect, this should resolve ctx->path if applicable. */ - void (*select)( store_t *ctx, int create, + void (*select)( store_t *ctx, const char *name, int create, void (*cb)( int sts, void *aux ), void *aux ); /* Load the message attributes needed to perform the requested operations. diff --git a/src/drv_imap.c b/src/drv_imap.c index 32b6708..e6d93ee 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -88,6 +88,7 @@ typedef struct imap_store { store_t gen; const char *label; /* foreign */ const char *prefix; + const char *name; int ref_count; /* trash folder's existence is not confirmed yet */ enum { TrashUnknown, TrashChecking, TrashKnown } trashnc; @@ -1136,7 +1137,7 @@ prepare_name( char **buf, const imap_store_t *ctx, const char *prefix, const cha static int prepare_box( char **buf, const imap_store_t *ctx ) { - const char *name = ctx->gen.name; + const char *name = ctx->name; return prepare_name( buf, ctx, (starts_with( name, -1, "INBOX", 5 ) && (!name[5] || name[5] == '/')) ? "" : ctx->prefix, name ); @@ -1828,7 +1829,7 @@ imap_prepare_opts( store_t *gctx, int opts ) /******************* imap_select *******************/ static void -imap_select( store_t *gctx, int create, +imap_select( store_t *gctx, const char *name, int create, void (*cb)( int sts, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; @@ -1839,6 +1840,7 @@ imap_select( store_t *gctx, int create, gctx->msgs = 0; ctx->msgapp = &gctx->msgs; + ctx->name = name; if (prepare_box( &buf, ctx ) < 0) { cb( DRV_BOX_BAD, aux ); return; diff --git a/src/drv_maildir.c b/src/drv_maildir.c index 2b30c90..f936938 100644 --- a/src/drv_maildir.c +++ b/src/drv_maildir.c @@ -924,7 +924,7 @@ maildir_app_msg( maildir_store_t *ctx, message_t ***msgapp, msg_t *entry ) } static void -maildir_select( store_t *gctx, int create, +maildir_select( store_t *gctx, const char *name, int create, void (*cb)( int sts, void *aux ), void *aux ) { maildir_store_t *ctx = (maildir_store_t *)gctx; @@ -941,15 +941,15 @@ maildir_select( store_t *gctx, int create, #ifdef USE_DB ctx->db = 0; #endif /* USE_DB */ - if (starts_with( gctx->name, -1, "INBOX", 5 ) && (!gctx->name[5] || gctx->name[5] == '/')) { - gctx->path = maildir_join_path( ((maildir_store_conf_t *)gctx->conf)->inbox, gctx->name + 5 ); + if (starts_with( name, -1, "INBOX", 5 ) && (!name[5] || name[5] == '/')) { + gctx->path = maildir_join_path( ((maildir_store_conf_t *)gctx->conf)->inbox, name + 5 ); } else { if (maildir_validate_path( gctx->conf ) < 0) { maildir_invoke_bad_callback( gctx ); cb( DRV_CANCELED, aux ); return; } - gctx->path = maildir_join_path( gctx->conf->path, gctx->name ); + gctx->path = maildir_join_path( gctx->conf->path, name ); } if ((ret = maildir_validate( gctx->path, create, ctx )) != DRV_OK) { diff --git a/src/sync.c b/src/sync.c index 35eaf38..fd1ba4f 100644 --- a/src/sync.c +++ b/src/sync.c @@ -147,7 +147,7 @@ typedef struct sync_rec { typedef struct { int t[2]; void (*cb)( int sts, void *aux ), *aux; - char *dname, *jname, *nname, *lname; + char *dname, *jname, *nname, *lname, *box_name[2]; FILE *jfp, *nfp; sync_rec_t *srecs, **srecadd; channel_conf_t *chan; @@ -598,14 +598,13 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, svars->uidval[0] = svars->uidval[1] = -1; svars->srecadd = &svars->srecs; - ctx[0]->name = ctx[1]->name = 0; for (t = 0; t < 2; t++) { ctx[t]->orig_name = (!names[t] || (ctx[t]->conf->map_inbox && !strcmp( ctx[t]->conf->map_inbox, names[t] ))) ? "INBOX" : names[t]; if (!ctx[t]->conf->flat_delim) { - ctx[t]->name = nfstrdup( ctx[t]->orig_name ); - } else if (map_name( ctx[t]->orig_name, &ctx[t]->name, 0, "/", ctx[t]->conf->flat_delim ) < 0) { + svars->box_name[t] = nfstrdup( ctx[t]->orig_name ); + } else if (map_name( ctx[t]->orig_name, &svars->box_name[t], 0, "/", ctx[t]->conf->flat_delim ) < 0) { error( "Error: canonical mailbox name '%s' contains flattened hierarchy delimiter\n", ctx[t]->orig_name ); svars->ret = SYNC_FAIL; sync_bail3( svars ); @@ -620,7 +619,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, sync_ref( svars ); for (t = 0; t < 2; t++) { info( "Selecting %s %s...\n", str_ms[t], ctx[t]->orig_name ); - svars->drv[t]->select( ctx[t], (chan->ops[t] & OP_CREATE) != 0, box_selected, AUX ); + svars->drv[t]->select( ctx[t], svars->box_name[t], (chan->ops[t] & OP_CREATE) != 0, box_selected, AUX ); if (check_cancel( svars )) break; } @@ -665,11 +664,11 @@ box_selected( int sts, void *aux ) } nfasprintf( &svars->dname, "%s/." EXE "state", ctx[S]->path ); } else { - csname = clean_strdup( ctx[S]->name ); + csname = clean_strdup( svars->box_name[S] ); if (chan->sync_state) nfasprintf( &svars->dname, "%s%s", chan->sync_state, csname ); else { - cmname = clean_strdup( ctx[M]->name ); + cmname = clean_strdup( svars->box_name[M] ); nfasprintf( &svars->dname, "%s:%s:%s_:%s:%s", global_conf.sync_state, chan->stores[M]->name, cmname, chan->stores[S]->name, csname ); free( cmname ); @@ -1919,8 +1918,8 @@ sync_bail2( sync_vars_t *svars ) static void sync_bail3( sync_vars_t *svars ) { - free( svars->ctx[M]->name ); - free( svars->ctx[S]->name ); + free( svars->box_name[M] ); + free( svars->box_name[S] ); sync_deref( svars ); }