Some attributes are duplicated a synced between strucuture.
This change moves all STATUS informations in ImapMboxData
and remove ImapStatus structure.
mboxcache is also removed because ImapMboxData stay in memory during the
whole Mailbox life, no more need to cache that.
static void cmd_parse_status(struct ImapAccountData *adata, char *s)
{
char *value = NULL;
- struct ImapStatus *status = NULL;
unsigned int olduv, oldun;
unsigned int litlen;
short new = 0;
imap_unmunge_mbox_name(adata->unicode, mailbox);
}
- struct ImapMboxData *mdata = imap_mdata_new(adata, mailbox);
- status = imap_mboxcache_get(adata, mdata, true);
- imap_mdata_free((void *) &mdata);
+ struct Url url;
+ mutt_account_tourl(&adata->conn_account, &url);
+ url.path = mailbox;
+ char path[PATH_MAX];
+ url_tostring(&url, path, sizeof(path), 0);
- olduv = status->uidvalidity;
- oldun = status->uidnext;
+ struct Mailbox *m = mx_mbox_find2(path);
+ if (!m || !m->mdata)
+ {
+ mutt_debug(3, "Received status for an unexpected mailbox: %s\n", mailbox);
+ return;
+ }
+ struct ImapMboxData *mdata = m->mdata;
+ olduv = mdata->uid_validity;
+ oldun = mdata->uid_next;
if (*s++ != '(')
{
if (mutt_str_startswith(s, "MESSAGES", CASE_MATCH))
{
- status->messages = count;
+ mdata->messages = count;
new_msg_count = 1;
}
else if (mutt_str_startswith(s, "RECENT", CASE_MATCH))
- status->recent = count;
+ mdata->recent = count;
else if (mutt_str_startswith(s, "UIDNEXT", CASE_MATCH))
- status->uidnext = count;
+ mdata->uid_next = count;
else if (mutt_str_startswith(s, "UIDVALIDITY", CASE_MATCH))
- status->uidvalidity = count;
+ mdata->uid_validity = count;
else if (mutt_str_startswith(s, "UNSEEN", CASE_MATCH))
- status->unseen = count;
+ mdata->unseen = count;
s = value;
if (*s && *s != ')')
s = imap_next_word(s);
}
mutt_debug(3, "%s (UIDVALIDITY: %u, UIDNEXT: %u) %d messages, %d recent, %d unseen\n",
- status->name, status->uidvalidity, status->uidnext,
- status->messages, status->recent, status->unseen);
+ mdata->name, mdata->uid_validity, mdata->uid_next, mdata->messages,
+ mdata->recent, mdata->unseen);
+#if 0
+ // NOTE(sileht): I don't get this part, I haven't found where cmddata is reused
+ // after that.
/* caller is prepared to handle the result herself */
if (adata->cmddata && adata->cmdtype == IMAP_CT_STATUS)
{
memcpy(adata->cmddata, status, sizeof(struct ImapStatus));
return;
}
+#endif
mutt_debug(3, "Running default STATUS handler\n");
- /* should perhaps move this code back to imap_mailbox_check */
- struct MailboxNode *np = NULL;
- STAILQ_FOREACH(np, &AllMailboxes, entries)
- {
- if (np->m->magic != MUTT_IMAP)
- continue;
+ mutt_debug(3, "Found %s in mailbox list (OV: %u ON: %u U: %d)\n", mailbox,
+ olduv, oldun, mdata->unseen);
- struct ImapAccountData *m_adata = imap_adata_get(np->m);
- if (imap_account_match(&adata->conn_account, &m_adata->conn_account))
+ if (MailCheckRecent)
+ {
+ if (olduv && olduv == mdata->uid_validity)
{
- struct ImapMboxData *mdata2 = imap_mdata_get(np->m);
- if (mdata2 && imap_mxcmp(mailbox, mdata2->name) == 0)
- {
- mutt_debug(3, "Found %s in mailbox list (OV: %u ON: %u U: %d)\n",
- mailbox, olduv, oldun, status->unseen);
-
- if (MailCheckRecent)
- {
- if (olduv && olduv == status->uidvalidity)
- {
- if (oldun < status->uidnext)
- new = (status->unseen > 0);
- }
- else if (!olduv && !oldun)
- {
- /* first check per session, use recent. might need a flag for this. */
- new = (status->recent > 0);
- }
- else
- new = (status->unseen > 0);
- }
- else
- new = (status->unseen > 0);
+ if (oldun < mdata->uid_next)
+ new = (mdata->unseen > 0);
+ }
+ else if (!olduv && !oldun)
+ {
+ /* first check per session, use recent. might need a flag for this. */
+ new = (mdata->recent > 0);
+ }
+ else
+ new = (mdata->unseen > 0);
+ }
+ else
+ new = (mdata->unseen > 0);
#ifdef USE_SIDEBAR
- if ((np->m->has_new != new) || (np->m->msg_count != status->messages) ||
- (np->m->msg_unread != status->unseen))
- {
- mutt_menu_set_current_redraw(REDRAW_SIDEBAR);
- }
+ if ((m->has_new != new) || (m->msg_count != mdata->messages) ||
+ (m->msg_unread != mdata->unseen))
+ {
+ mutt_menu_set_current_redraw(REDRAW_SIDEBAR);
+ }
#endif
- np->m->has_new = new;
- if (new_msg_count)
- np->m->msg_count = status->messages;
- np->m->msg_unread = status->unseen;
+ m->has_new = new;
+ if (new_msg_count)
+ m->msg_count = mdata->messages;
+ m->msg_unread = mdata->unseen;
- if (np->m->has_new)
- {
- /* force back to keep detecting new mail until the mailbox is
- opened */
- status->uidnext = oldun;
- }
- return;
- }
- }
+ if (m->has_new)
+ {
+ /* force back to keep detecting new mail until the mailbox is
+ opened */
+ mdata->uid_next = oldun;
}
+ return;
}
/**
*/
static int imap_access2(struct ImapAccountData *adata, struct ImapMboxData *mdata)
{
- struct ImapMboxData *selected_mdata = NULL;
char buf[LONG_STRING * 2];
int rc;
- if (adata->mailbox)
- selected_mdata = adata->mailbox->mdata;
-
/* we may already be in the folder we're checking */
- if (selected_mdata && mutt_str_strcmp(selected_mdata->name, mdata->name) == 0)
+ if (adata->mailbox && adata->mailbox->mdata == mdata)
return 0;
- if (imap_mboxcache_get(adata, mdata, false))
- {
- mutt_debug(3, "found %s in cache\n", mdata->name);
+ // We already have the information from cache.
+ if (mdata->uid_validity > 0)
return 0;
- }
if (mutt_bit_isset(adata->capabilities, IMAP4REV1))
snprintf(buf, sizeof(buf), "STATUS %s (UIDVALIDITY)", mdata->munge_name);
*/
int imap_access(const char *path)
{
+ struct Mailbox *m = mx_mbox_find2(path);
+ if (m)
+ return imap_access2(m->account->adata, m->mdata);
+
+ // FIXME(sileht): Is that case possible ?
struct ImapAccountData *adata = NULL;
struct ImapMboxData *mdata = NULL;
int rc;
{
struct ImapAccountData *adata = NULL;
struct ImapMboxData *mdata = NULL;
- struct ImapMboxData *selected_mdata = NULL;
char command[LONG_STRING * 2];
if (imap_prepare_mailbox(m))
mdata = m->mdata;
adata = m->account->adata;
- if (adata->mailbox)
- selected_mdata = adata->mailbox->mdata;
-
/* Don't issue STATUS on the selected mailbox, it will be NOOPed or
* IDLEd elsewhere.
* adata->mailbox may be NULL for connections other than the current
* mailbox's.. #3216. */
- if (selected_mdata && mdata == selected_mdata)
+ if (adata->mailbox && adata->mailbox == m)
{
m->has_new = false;
return -1;
int imap_status(const char *path, bool queue)
{
static int queued = 0;
-
- struct ImapAccountData *adata = NULL;
- struct ImapMboxData *mdata = NULL;
- struct ImapMboxData *selected_mdata = NULL;
char buf[LONG_STRING * 2];
- struct ImapStatus *status = NULL;
- if (imap_adata_find(path, &adata, &mdata) < 0)
+ struct Mailbox *m = mx_mbox_find2(path);
+ if (!m)
return -1;
- if (adata->mailbox)
- selected_mdata = adata->mailbox->mdata;
+ if (imap_prepare_mailbox(m) < 0)
+ return -1;
+ struct ImapAccountData *adata = m->account->adata;
+ struct ImapMboxData *mdata = m->mdata;
// We are in the folder we're polling - just return the mailbox count.
- if (selected_mdata && selected_mdata == mdata)
- {
- imap_mdata_free((void **) &mdata);
- return adata->mailbox->msg_count;
- }
+ if (adata->mailbox == m)
+ return m->msg_count;
else if (mutt_bit_isset(adata->capabilities, IMAP4REV1) ||
mutt_bit_isset(adata->capabilities, STATUS))
{
/* Server does not support STATUS, and this is not the current mailbox.
* There is no lightweight way to check recent arrivals */
- imap_mdata_free((void **) &mdata);
return -1;
}
{
imap_exec(adata, buf, IMAP_CMD_QUEUE);
queued = 1;
- imap_mdata_free((void **) &mdata);
return 0;
}
else if (!queued)
imap_exec(adata, buf, 0);
- queued = 0;
- status = imap_mboxcache_get(adata, mdata, false);
- imap_mdata_free((void **) &mdata);
- if (status)
- return status->messages;
-
- return 0;
-}
-
-/**
- * imap_mboxcache_get - Open an hcache for a mailbox
- * @param adata Imap Account data
- * @param mdata Imap Mailbox data to cache
- * @param create Should it be created if it doesn't exist?
- * @retval ptr Stats of cached mailbox
- * @retval ptr Stats of new cache entry
- * @retval NULL Not in cache and create is false
- *
- * return cached mailbox stats or NULL if create is 0
- */
-struct ImapStatus *imap_mboxcache_get(struct ImapAccountData *adata,
- struct ImapMboxData *mdata, bool create)
-{
- struct ImapStatus *status = NULL;
- struct ListNode *np = NULL;
- STAILQ_FOREACH(np, &adata->mboxcache, entries)
- {
- status = (struct ImapStatus *) np->data;
-
- if (imap_mxcmp(mdata->name, status->name) == 0)
- return status;
- }
- status = NULL;
-
- /* lame */
- if (create)
- {
- struct ImapStatus *scache = mutt_mem_calloc(1, sizeof(struct ImapStatus));
- scache->name = mdata->name;
- mutt_list_insert_tail(&adata->mboxcache, (char *) scache);
- status = imap_mboxcache_get(adata, mdata, false);
- status->name = mutt_str_strdup(mdata->name);
- }
-
-#ifdef USE_HCACHE
- header_cache_t *hc = imap_hcache_open(adata, mdata);
- if (hc)
- {
- void *uidvalidity = mutt_hcache_fetch_raw(hc, "/UIDVALIDITY", 12);
- void *uidnext = mutt_hcache_fetch_raw(hc, "/UIDNEXT", 8);
- unsigned long long *modseq = mutt_hcache_fetch_raw(hc, "/MODSEQ", 7);
- if (uidvalidity)
- {
- if (!status)
- {
- mutt_hcache_free(hc, &uidvalidity);
- mutt_hcache_free(hc, &uidnext);
- mutt_hcache_free(hc, (void **) &modseq);
- mutt_hcache_close(hc);
- return imap_mboxcache_get(adata, mdata, true);
- }
- status->uidvalidity = *(unsigned int *) uidvalidity;
- status->uidnext = uidnext ? *(unsigned int *) uidnext : 0;
- status->modseq = modseq ? *modseq : 0;
- mutt_debug(3, "hcache uidvalidity %u, uidnext %u, modseq %llu\n",
- status->uidvalidity, status->uidnext, status->modseq);
- }
- mutt_hcache_free(hc, &uidvalidity);
- mutt_hcache_free(hc, &uidnext);
- mutt_hcache_free(hc, (void **) &modseq);
- mutt_hcache_close(hc);
- }
-#endif
-
- return status;
-}
-
-/**
- * imap_mboxcache_free - Free the cached ImapStatus
- * @param adata Imap Account data
- */
-void imap_mboxcache_free(struct ImapAccountData *adata)
-{
- struct ImapStatus *status = NULL;
-
- struct ListNode *np = NULL;
- STAILQ_FOREACH(np, &adata->mboxcache, entries)
- {
- status = (struct ImapStatus *) np->data;
- FREE(&status->name);
- }
-
- mutt_list_free(&adata->mboxcache);
+ return mdata->messages;
}
/**
if (!m->account)
return -1;
- struct ImapStatus *status = NULL;
char buf[PATH_MAX];
int count = 0;
int rc;
/* clear mailbox status */
adata->status = 0;
memset(adata->mailbox->rights, 0, sizeof(adata->mailbox->rights));
+ mdata->new_mail_count = 0;
mutt_message(_("Selecting %s..."), mdata->name);
imap_cmd_start(adata, buf);
- status = imap_mboxcache_get(adata, mdata, true);
-
do
{
char *pc = NULL;
pc = imap_next_word(pc);
if (mutt_str_atoui(pc, &mdata->uid_validity) < 0)
goto fail;
- status->uidvalidity = mdata->uid_validity;
}
else if (mutt_str_startswith(pc, "OK [UIDNEXT", CASE_IGNORE))
{
mutt_debug(3, "Getting mailbox UIDNEXT\n");
pc += 3;
pc = imap_next_word(pc);
- if (mutt_str_atoui(pc, &mdata->uidnext) < 0)
+ if (mutt_str_atoui(pc, &mdata->uid_next) < 0)
goto fail;
- status->uidnext = mdata->uidnext;
}
else if (mutt_str_startswith(pc, "OK [HIGHESTMODSEQ", CASE_IGNORE))
{
pc = imap_next_word(pc);
if (mutt_str_atoull(pc, &mdata->modseq) < 0)
goto fail;
- status->modseq = mdata->modseq;
}
else if (mutt_str_startswith(pc, "OK [NOMODSEQ", CASE_IGNORE))
{
mutt_debug(3, "Mailbox has NOMODSEQ set\n");
- status->modseq = mdata->modseq = 0;
+ mdata->modseq = 0;
}
else
{
adata->mailbox = NULL;
adata->ctx = NULL;
- // TODO(sileht): As this is associated to a Mailbox we could keep it
- // to not requery everything each time a mailbox is reopen. This need to be
- // tested and we need to free this somewhere.
- // For now free it each time we close the mailbox to keep the previous mutt
- // behavior.
- imap_mdata_free(&m->mdata);
+ imap_mdata_cache_reset(m->mdata);
}
return 0;
char *path;
};
-/**
- * struct ImapStatus - Status of an IMAP mailbox
- */
-struct ImapStatus
-{
- char *name;
-
- unsigned int messages;
- unsigned int recent;
- unsigned int uidnext;
- unsigned int uidvalidity;
- unsigned int unseen;
- unsigned long long modseq; /* Used by CONDSTORE. 1 <= modseq < 2^63 */
-};
-
/**
* struct ImapList - Items in an IMAP browser
*/
int lastcmd;
struct Buffer *cmdbuf;
- /* cache ImapStatus of visited mailboxes */
- struct ListHead mboxcache;
-
char delim;
struct Context *ctx;
struct Mailbox *mailbox; /* Current selected mailbox */
unsigned char reopen; /**< Flags, e.g. #IMAP_REOPEN_ALLOW */
unsigned short check_status; /**< Flags, e.g. #IMAP_NEWMAIL_PENDING */
unsigned int new_mail_count; /**< Set when EXISTS notifies of new mail */
- struct ImapCache cache[IMAP_CACHE_LEN];
- struct Hash *uid_hash;
+
+ // IMAP STATUS information
unsigned int uid_validity;
- unsigned int uidnext;
+ unsigned int uid_next;
unsigned long long modseq;
+ unsigned int messages;
+ unsigned int recent;
+ unsigned int unseen;
+
+ // Cached data used only when the mailbox is opened
+ struct ImapCache cache[IMAP_CACHE_LEN];
+ struct Hash *uid_hash;
struct Email **msn_index; /**< look up headers by (MSN-1) */
size_t msn_index_size; /**< allocation size */
unsigned int max_msn; /**< the largest MSN fetched so far */
int imap_check(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool force);
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox);
int imap_rename_mailbox(struct ImapAccountData *adata, char *oldname, const char *newname);
-struct ImapStatus *imap_mboxcache_get(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool create);
-void imap_mboxcache_free(struct ImapAccountData *adata);
int imap_exec_msgset(struct ImapAccountData *adata, const char *pre, const char *post,
int flag, bool changed, bool invert);
int imap_open_connection(struct ImapAccountData *adata);
void imap_adata_free(void **ptr);
struct ImapMboxData *imap_mdata_new(struct ImapAccountData *adata, const char* name);
void imap_mdata_free(void **ptr);
+void imap_mdata_cache_reset(struct ImapMboxData *mdata);
char *imap_fix_path(struct ImapAccountData *adata, const char *mailbox, char *path, size_t plen);
void imap_cachepath(struct ImapAccountData *adata, const char *mailbox, char *dest, size_t dlen);
int imap_get_literal_count(const char *buf, unsigned int *bytes);
* read_headers_normal_eval_cache - Retrieve data from the header cache
* @param adata Imap Account data
* @param msn_end Last Message Sequence number
- * @param uidnext UID of next email
+ * @param uid_next UID of next email
* @param store_flag_updates if true, save flags to the header cache
* @param eval_condstore if true, use CONDSTORE to fetch flags
* @retval 0 Success
* read_headers_condstore_qresync_updates().
*/
static int read_headers_normal_eval_cache(struct ImapAccountData *adata,
- unsigned int msn_end, unsigned int uidnext,
+ unsigned int msn_end, unsigned int uid_next,
bool store_flag_updates, bool eval_condstore)
{
struct Progress progress;
/* If we are using CONDSTORE's "FETCH CHANGEDSINCE", then we keep
* the flags in the header cache, and update them further below.
* Otherwise, we fetch the current state of the flags here. */
- snprintf(buf, sizeof(buf), "UID FETCH 1:%u (UID%s)", uidnext - 1,
+ snprintf(buf, sizeof(buf), "UID FETCH 1:%u (UID%s)", uid_next - 1,
eval_condstore ? "" : " FLAGS");
imap_cmd_start(adata, buf);
* read_headers_condstore_qresync_updates - Retrieve updates from the server
* @param adata Imap Account data
* @param msn_end Last Message Sequence number
- * @param uidnext UID of next email
+ * @param uid_next UID of next email
* @param hc_modseq Timestamp of last Header Cache update
* @param eval_qresync If true, use QRESYNC
* @retval 0 Success
* CONDSTORE and QRESYNC use FETCH extensions to grab updates.
*/
static int read_headers_condstore_qresync_updates(struct ImapAccountData *adata,
- unsigned int msn_end, unsigned int uidnext,
+ unsigned int msn_end, unsigned int uid_next,
unsigned long long hc_modseq, bool eval_qresync)
{
struct Progress progress;
MUTT_PROGRESS_MSG, ReadInc, msn_end);
snprintf(buf, sizeof(buf), "UID FETCH 1:%u (FLAGS) (CHANGEDSINCE %llu%s)",
- uidnext - 1, hc_modseq, eval_qresync ? " VANISHED" : "");
+ uid_next - 1, hc_modseq, eval_qresync ? " VANISHED" : "");
imap_cmd_start(adata, buf);
int imap_read_headers(struct ImapAccountData *adata, unsigned int msn_begin,
unsigned int msn_end, bool initial_download)
{
- struct ImapStatus *status = NULL;
int oldmsgcount;
unsigned int maxuid = 0;
int retval = -1;
#ifdef USE_HCACHE
void *uid_validity = NULL;
- void *puidnext = NULL;
- unsigned int uidnext = 0;
+ void *puid_next = NULL;
+ unsigned int uid_next = 0;
bool has_condstore = false;
bool has_qresync = false;
bool eval_condstore = false;
if (mdata->hcache && initial_download)
{
uid_validity = mutt_hcache_fetch_raw(mdata->hcache, "/UIDVALIDITY", 12);
- puidnext = mutt_hcache_fetch_raw(mdata->hcache, "/UIDNEXT", 8);
- if (puidnext)
+ puid_next = mutt_hcache_fetch_raw(mdata->hcache, "/UIDNEXT", 8);
+ if (puid_next)
{
- uidnext = *(unsigned int *) puidnext;
- mutt_hcache_free(mdata->hcache, &puidnext);
+ uid_next = *(unsigned int *) puid_next;
+ mutt_hcache_free(mdata->hcache, &puid_next);
}
if (mdata->modseq)
has_qresync = true;
}
- if (uid_validity && uidnext && (*(unsigned int *) uid_validity == mdata->uid_validity))
+ if (uid_validity && uid_next && (*(unsigned int *) uid_validity == mdata->uid_validity))
{
evalhc = true;
pmodseq = mutt_hcache_fetch_raw(mdata->hcache, "/MODSEQ", 7);
}
else
{
- if (read_headers_normal_eval_cache(adata, msn_end, uidnext, has_condstore || has_qresync,
+ if (read_headers_normal_eval_cache(adata, msn_end, uid_next, has_condstore || has_qresync,
eval_condstore) < 0)
goto bail;
}
if ((eval_condstore || eval_qresync) && (hc_modseq != mdata->modseq))
{
- if (read_headers_condstore_qresync_updates(adata, msn_end, uidnext,
+ if (read_headers_condstore_qresync_updates(adata, msn_end, uid_next,
hc_modseq, eval_qresync) < 0)
{
goto bail;
if (read_headers_fetch_new(adata, msn_begin, msn_end, evalhc, &maxuid, initial_download) < 0)
goto bail;
- if (maxuid && (status = imap_mboxcache_get(adata, mdata, 0)) &&
- (status->uidnext < maxuid + 1))
- {
- status->uidnext = maxuid + 1;
- }
+ if (maxuid && mdata->uid_next < maxuid + 1)
+ mdata->uid_next = maxuid + 1;
#ifdef USE_HCACHE
mutt_hcache_store_raw(mdata->hcache, "/UIDVALIDITY", 12, &mdata->uid_validity,
sizeof(mdata->uid_validity));
- if (maxuid && mdata->uidnext < maxuid + 1)
+ if (maxuid && mdata->uid_next < maxuid + 1)
{
- mutt_debug(2, "Overriding UIDNEXT: %u -> %u\n", mdata->uidnext, maxuid + 1);
- mdata->uidnext = maxuid + 1;
+ mutt_debug(2, "Overriding UIDNEXT: %u -> %u\n", mdata->uid_next, maxuid + 1);
+ mdata->uid_next = maxuid + 1;
}
- if (mdata->uidnext > 1)
+ if (mdata->uid_next > 1)
{
- mutt_hcache_store_raw(mdata->hcache, "/UIDNEXT", 8, &mdata->uidnext,
- sizeof(mdata->uidnext));
+ mutt_hcache_store_raw(mdata->hcache, "/UIDNEXT", 8, &mdata->uid_next,
+ sizeof(mdata->uid_next));
}
/* We currently only sync CONDSTORE and QRESYNC on the initial download.
FREE(&adata->capstr);
mutt_list_free(&adata->flags);
- imap_mboxcache_free(adata);
mutt_buffer_free(&adata->cmdbuf);
FREE(&adata->buf);
FREE(&adata->cmds);
adata->cmds = mutt_mem_calloc(adata->cmdslots, sizeof(*adata->cmds));
STAILQ_INIT(&adata->flags);
- STAILQ_INIT(&adata->mboxcache);
return adata;
}
mdata->reopen &= IMAP_REOPEN_ALLOW;
+#ifdef USE_HCACHE
+ header_cache_t *hc = imap_hcache_open(adata, mdata);
+ if (hc)
+ {
+ void *uidvalidity = mutt_hcache_fetch_raw(hc, "/UIDVALIDITY", 12);
+ void *uidnext = mutt_hcache_fetch_raw(hc, "/UIDNEXT", 8);
+ unsigned long long *modseq = mutt_hcache_fetch_raw(hc, "/MODSEQ", 7);
+ if (uidvalidity)
+ {
+ mdata->uid_validity = *(unsigned int *) uidvalidity;
+ mdata->uid_next = uidnext ? *(unsigned int *) uidnext : 0;
+ mdata->modseq = modseq ? *modseq : 0;
+ mutt_debug(3, "hcache uidvalidity %u, uidnext %u, modseq %llu\n",
+ mdata->uid_validity, mdata->uid_next, mdata->modseq);
+ }
+ mutt_hcache_free(hc, &uidvalidity);
+ mutt_hcache_free(hc, &uidnext);
+ mutt_hcache_free(hc, (void **) &modseq);
+ mutt_hcache_close(hc);
+ }
+#endif
+
return mdata;
}
/**
- * imap_mdata_free - Release and clear storage in an ImapMboxData structure
- * @param ptr Imap Mailbox data
+ * imap_mdata_cache_reset - Release and clear cache data of ImapMboxData structure
+ * @param mdata Imap Mailbox data
*/
-void imap_mdata_free(void **ptr)
+void imap_mdata_cache_reset(struct ImapMboxData *mdata)
{
- if (!ptr || !*ptr)
- return;
-
- struct ImapMboxData *mdata = *ptr;
+ mutt_hash_destroy(&mdata->uid_hash);
+ FREE(&mdata->msn_index);
+ mdata->msn_index_size = 0;
+ mdata->max_msn = 0;
for (int i = 0; i < IMAP_CACHE_LEN; i++)
{
}
mutt_bcache_close(&mdata->bcache);
- mutt_hash_destroy(&mdata->uid_hash);
+}
+
+/**
+ * imap_mdata_free - Release and clear storage in an ImapMboxData structure
+ * @param ptr Imap Mailbox data
+ */
+void imap_mdata_free(void **ptr)
+{
+ if (!ptr || !*ptr)
+ return;
+
+ struct ImapMboxData *mdata = *ptr;
+
+ imap_mdata_cache_reset(mdata);
FREE(&mdata->name);
FREE(&mdata->real_name);
FREE(&mdata->munge_name);
- FREE(&mdata->msn_index);
FREE(ptr);
}