From f47c29082322dba38c40097df0ca3a1b20766b0a Mon Sep 17 00:00:00 2001 From: Thomas Roessler Date: Thu, 20 Jul 2000 17:50:02 +0000 Subject: [PATCH] Another IMAP patch from Brendan. --- imap/browse.c | 18 +-- imap/command.c | 20 ++-- imap/imap.c | 265 +++++++++++++++++++++++--------------------- imap/imap.h | 2 +- imap/imap_private.h | 23 ++-- imap/util.c | 7 +- mutt_socket.c | 21 ++-- mutt_socket.h | 2 +- mx.c | 2 +- pop.c | 2 +- 10 files changed, 181 insertions(+), 181 deletions(-) diff --git a/imap/browse.c b/imap/browse.c index 0f0dfebc..c63487ee 100644 --- a/imap/browse.c +++ b/imap/browse.c @@ -65,21 +65,9 @@ int imap_browse (char* path, struct browser_state* state) strfcpy (list_cmd, option (OPTIMAPLSUB) ? "LSUB" : "LIST", sizeof (list_cmd)); - conn = mutt_socket_find (&(mx.account), 0); - idata = (IMAP_DATA*) conn->data; - - if (!idata || (idata->state == IMAP_DISCONNECTED)) - { - if (!idata) - { - /* The current connection is a new connection */ - idata = safe_calloc (1, sizeof (IMAP_DATA)); - conn->data = idata; - idata->conn = conn; - } - if (imap_open_connection (idata)) - return -1; - } + if (!(idata = imap_conn_find (&(mx.account), 0))) + return -1; + conn = idata->conn; if (mx.mbox[0] == '\0') { diff --git a/imap/command.c b/imap/command.c index 0a534fe6..c71d9841 100644 --- a/imap/command.c +++ b/imap/command.c @@ -63,7 +63,7 @@ void imap_cmd_start (IMAP_DATA* idata, const char* cmd) * detected, do expunge) */ void imap_cmd_finish (IMAP_DATA* idata) { - if (!(idata->state == IMAP_SELECTED) || idata->selected_ctx->closing) + if (!(idata->state == IMAP_SELECTED) || idata->ctx->closing) { idata->status = 0; mutt_clear_error (); @@ -79,19 +79,18 @@ void imap_cmd_finish (IMAP_DATA* idata) if (!(idata->reopen & IMAP_REOPEN_PENDING) && ((idata->status == IMAP_NEW_MAIL) || (idata->reopen & IMAP_NEWMAIL_PENDING)) - && count > idata->selected_ctx->msgcount) + && count > idata->ctx->msgcount) { /* read new mail messages */ dprint (1, (debugfile, "imap_cmd_finish: fetching new mail\n")); - count = imap_read_headers (idata->selected_ctx, - idata->selected_ctx->msgcount, count - 1) + 1; + count = imap_read_headers (idata->ctx, idata->ctx->msgcount, count-1)+1; idata->check_status = IMAP_NEW_MAIL; idata->reopen &= ~IMAP_NEWMAIL_PENDING; } else { - imap_reopen_mailbox (idata->selected_ctx, NULL); + imap_reopen_mailbox (idata->ctx, NULL); idata->check_status = IMAP_REOPENED; idata->reopen &= ~(IMAP_REOPEN_PENDING|IMAP_NEWMAIL_PENDING); } @@ -197,20 +196,19 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s) /* new mail arrived */ count = atoi (pn); - if ( (idata->status != IMAP_EXPUNGE) && - count < idata->selected_ctx->msgcount) + if ( (idata->status != IMAP_EXPUNGE) && count < idata->ctx->msgcount) { /* something is wrong because the server reported fewer messages * than we previously saw */ mutt_error _("Fatal error. Message count is out of sync!"); idata->status = IMAP_FATAL; - mx_fastclose_mailbox (idata->selected_ctx); + mx_fastclose_mailbox (idata->ctx); return -1; } /* at least the InterChange server sends EXISTS messages freely, * even when there is no new mail */ - else if (count == idata->selected_ctx->msgcount) + else if (count == idata->ctx->msgcount) dprint (3, (debugfile, "imap_handle_untagged: superfluous EXISTS message.\n")); else @@ -219,7 +217,7 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s) { dprint (2, (debugfile, "imap_handle_untagged: New mail in %s - %d messages total.\n", - idata->selected_mailbox, count)); + idata->mailbox, count)); idata->status = IMAP_NEW_MAIL; } idata->newMailCount = count; @@ -240,7 +238,7 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s) mutt_error ("%s", s); idata->status = IMAP_BYE; if (idata->state == IMAP_SELECTED) - mx_fastclose_mailbox (idata->selected_ctx); + mx_fastclose_mailbox (idata->ctx); mutt_socket_close (idata->conn); idata->state = IMAP_DISCONNECTED; diff --git a/imap/imap.c b/imap/imap.c index 73e88fae..300f24d0 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -251,8 +251,8 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint) ctx->id_hash = hash_create (1031); ctx->subj_hash = hash_create (1031); - mutt_message (_("Reopening mailbox... %s"), CTX_DATA->selected_mailbox); - imap_munge_mbox_name (buf, sizeof (buf), CTX_DATA->selected_mailbox); + mutt_message (_("Reopening mailbox... %s"), CTX_DATA->mailbox); + imap_munge_mbox_name (buf, sizeof (buf), CTX_DATA->mailbox); snprintf (bufout, sizeof (bufout), "STATUS %s (MESSAGES)", buf); imap_cmd_start (CTX_DATA, bufout); @@ -429,7 +429,7 @@ static int imap_check_acl (IMAP_DATA *idata) char buf[LONG_STRING]; char mbox[LONG_STRING]; - imap_munge_mbox_name (mbox, sizeof(mbox), idata->selected_mailbox); + imap_munge_mbox_name (mbox, sizeof(mbox), idata->mailbox); snprintf (buf, sizeof (buf), "MYRIGHTS %s", mbox); if (imap_exec (buf, sizeof (buf), idata, buf, 0) != 0) { @@ -458,6 +458,57 @@ static int imap_check_capabilities (IMAP_DATA *idata) return 0; } +/* imap_conn_find: Find an open IMAP connection matching account, or open + * a new one if none can be found. */ +IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags) +{ + CONNECTION* conn; + IMAP_DATA* idata; + ACCOUNT* creds; + + conn = mutt_conn_find (NULL, account); + /* if opening a new UNSELECTED connection, preserve existing creds */ + creds = &(conn->account); + + /* make sure this connection is not in SELECTED state, if neccessary */ + if (flags & M_IMAP_CONN_NOSELECT) + while (conn->data && ((IMAP_DATA*) conn->data)->state == IMAP_SELECTED) + { + conn = mutt_conn_find (conn, account); + memcpy (&(conn->account), creds, sizeof (ACCOUNT)); + } + + + idata = (IMAP_DATA*) conn->data; + + /* don't open a new connection if one isn't wanted */ + if (flags & M_IMAP_CONN_NONEW) + if (!idata || idata->state == IMAP_DISCONNECTED) + { + mutt_socket_free (conn); + + return NULL; + } + + if (!idata) + { + /* The current connection is a new connection */ + idata = safe_calloc (1, sizeof (IMAP_DATA)); + conn->data = idata; + idata->conn = conn; + } + if (idata->state == IMAP_DISCONNECTED) + if (imap_open_connection (idata) != 0) + { + FREE (&idata); + mutt_socket_free (conn); + + return NULL; + } + + return idata; +} + int imap_open_connection (IMAP_DATA* idata) { char buf[LONG_STRING]; @@ -581,44 +632,31 @@ int imap_open_mailbox (CONTEXT* ctx) return -1; } - conn = mutt_socket_find (&(mx.account), 0); - idata = (IMAP_DATA*) conn->data; - - if (!idata || (idata->state != IMAP_AUTHENTICATED)) - { - if (!idata || (idata->state == IMAP_SELECTED) || - (idata->state == IMAP_CONNECTED)) - { - /* We need to create a new connection, the current one isn't useful */ - idata = safe_calloc (1, sizeof (IMAP_DATA)); + /* we require a connection which isn't currently in IMAP_SELECTED state */ + if (!(idata = imap_conn_find (&(mx.account), M_IMAP_CONN_NOSELECT))) + return -1; + conn = idata->conn; - conn = mutt_socket_find (&(mx.account), 1); - conn->data = idata; - idata->conn = conn; - } - if (imap_open_connection (idata)) - return -1; - } + /* once again the context is new */ ctx->data = (void *) idata; /* Clean up path and replace the one in the ctx */ imap_fix_path (idata, mx.mbox, buf, sizeof (buf)); - FREE(&(idata->selected_mailbox)); - idata->selected_mailbox = safe_strdup (buf); - imap_qualify_path (buf, sizeof (buf), &mx, idata->selected_mailbox, - NULL); + FREE(&(idata->mailbox)); + idata->mailbox = safe_strdup (buf); + imap_qualify_path (buf, sizeof (buf), &mx, idata->mailbox, NULL); FREE (&(ctx->path)); ctx->path = safe_strdup (buf); - idata->selected_ctx = ctx; + idata->ctx = ctx; /* clear status, ACL */ idata->status = 0; memset (idata->rights, 0, (RIGHTSMAX+7)/8); - mutt_message (_("Selecting %s..."), idata->selected_mailbox); - imap_munge_mbox_name (buf, sizeof(buf), idata->selected_mailbox); + mutt_message (_("Selecting %s..."), idata->mailbox); + imap_munge_mbox_name (buf, sizeof(buf), idata->mailbox); snprintf (bufout, sizeof (bufout), "%s %s", ctx->readonly ? "EXAMINE" : "SELECT", buf); @@ -759,23 +797,14 @@ int imap_open_mailbox_append (CONTEXT *ctx) if (imap_parse_path (ctx->path, &mx)) return -1; - ctx->magic = M_IMAP; + /* in APPEND mode, we appear to hijack an existing IMAP connection - + * ctx is brand new and mostly empty */ - conn = mutt_socket_find (&(mx.account), 0); - idata = (IMAP_DATA*) conn->data; + if (!(idata = imap_conn_find (&(mx.account), 0))) + return -1; + conn = idata->conn; - if (!idata || (idata->state == IMAP_DISCONNECTED)) - { - if (!idata) - { - /* The current connection is a new connection */ - idata = safe_calloc (1, sizeof (IMAP_DATA)); - conn->data = idata; - idata->conn = conn; - } - if (imap_open_connection (idata)) - return -1; - } + ctx->magic = M_IMAP; ctx->data = (void *) idata; /* check mailbox existance */ @@ -785,15 +814,11 @@ int imap_open_mailbox_append (CONTEXT *ctx) imap_munge_mbox_name (mbox, sizeof (mbox), mailbox); if (mutt_bit_isset(idata->capabilities,IMAP4REV1)) - { snprintf (buf, sizeof (buf), "STATUS %s (UIDVALIDITY)", mbox); - } else if (mutt_bit_isset(idata->capabilities,STATUS)) - { /* We have no idea what the other guy wants. UW imapd 8.3 wants this * (but it does not work if another mailbox is selected) */ snprintf (buf, sizeof (buf), "STATUS %s (UID-VALIDITY)", mbox); - } else { /* STATUS not supported */ @@ -954,8 +979,9 @@ int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag, * expunge: 0 or 1 - do expunge? */ -int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint) +int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint) { + IMAP_DATA* idata; char buf[HUGE_STRING]; char flags[LONG_STRING]; char tmp[LONG_STRING]; @@ -964,21 +990,30 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint) int err_continue = M_NO; /* continue on error? */ int rc; - if (CTX_DATA->state != IMAP_SELECTED) + idata = (IMAP_DATA*) ctx->data; + + if (idata->state != IMAP_SELECTED) { dprint (2, (debugfile, "imap_sync_mailbox: no mailbox selected\n")); return -1; } - imap_allow_reopen (ctx); /* This function is only called when the calling code - * expects the context to be changed. - */ + /* CLOSE purges deleted messages. If we don't want to purge them, we must + * tell imap_close_mailbox not to issue the CLOSE command */ + if (expunge) + idata->noclose = 0; + else + idata->noclose = 1; + + /* This function is only called when the calling code expects the context + * to be changed. */ + imap_allow_reopen (ctx); if ((rc = imap_check_mailbox (ctx, index_hint)) != 0) return rc; /* if we are expunging anyway, we can do deleted messages very quickly... */ - if (expunge && mutt_bit_isset (CTX_DATA->rights, IMAP_ACL_DELETE)) + if (expunge && mutt_bit_isset (idata->rights, IMAP_ACL_DELETE)) { deleted = imap_make_msg_set (buf, sizeof (buf), ctx, M_DELETE, 1); @@ -987,7 +1022,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint) { mutt_message (_("Marking %d messages deleted..."), deleted); snprintf (tmp, sizeof (tmp), "STORE %s +FLAGS.SILENT (\\Deleted)", buf); - if (imap_exec (buf, sizeof (buf), CTX_DATA, tmp, 0) != 0) + if (imap_exec (buf, sizeof (buf), idata, tmp, 0) != 0) /* continue, let regular store try before giving up */ dprint(2, (debugfile, "imap_sync_mailbox: fast delete failed\n")); else @@ -1017,8 +1052,8 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint) flags); /* now make sure we don't lose custom tags */ - if (mutt_bit_isset (CTX_DATA->rights, IMAP_ACL_WRITE)) - imap_add_keywords (flags, ctx->hdrs[n], CTX_DATA->flags); + if (mutt_bit_isset (idata->rights, IMAP_ACL_WRITE)) + imap_add_keywords (flags, ctx->hdrs[n], idata->flags); mutt_remove_trailing_ws (flags); @@ -1042,7 +1077,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint) /* after all this it's still possible to have no flags, if you * have no ACL rights */ - if (*flags && (imap_exec (buf, sizeof (buf), CTX_DATA, buf, 0) != 0) && + if (*flags && (imap_exec (buf, sizeof (buf), idata, buf, 0) != 0) && (err_continue != M_YES)) { err_continue = imap_continue ("imap_sync_mailbox: STORE failed", buf); @@ -1055,30 +1090,19 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint) } ctx->changed = 0; - if (expunge == 1) + /* We must send an EXPUNGE command if we're not closing. */ + if (expunge && !(ctx->closing) && + mutt_bit_isset(idata->rights, IMAP_ACL_DELETE)) { - /* expunge is implicit if closing */ - if (ctx->closing) + mutt_message _("Expunging messages from server..."); + /* FIXME: these status changes seem dubious */ + idata->status = IMAP_EXPUNGE; + if (imap_exec (buf, sizeof (buf), CTX_DATA, "EXPUNGE", 0) != 0) { - mutt_message _("Closing mailbox..."); - if (imap_exec (buf, sizeof (buf), CTX_DATA, "CLOSE", 0) != 0) - { - imap_error ("imap_sync_mailbox: CLOSE failed", buf); - return -1; - } - /* state is set in imap_fastclose_mailbox */ - } - else if (mutt_bit_isset(CTX_DATA->rights, IMAP_ACL_DELETE)) - { - mutt_message _("Expunging messages from server..."); - CTX_DATA->status = IMAP_EXPUNGE; - if (imap_exec (buf, sizeof (buf), CTX_DATA, "EXPUNGE", 0) != 0) - { - imap_error ("imap_sync_mailbox: EXPUNGE failed", buf); - return -1; - } - CTX_DATA->status = 0; + imap_error ("imap_sync_mailbox: EXPUNGE failed", buf); + return -1; } + idata->status = 0; } for (n = 0; n < IMAP_CACHE_LEN; n++) @@ -1093,20 +1117,31 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint) return 0; } -void imap_fastclose_mailbox (CONTEXT *ctx) +/* imap_close_mailbox: issue close command if neccessary, reset IMAP_DATA */ +void imap_close_mailbox (CONTEXT* ctx) { + IMAP_DATA* idata; + char buf[LONG_STRING]; int i; + idata = (IMAP_DATA*) ctx->data; /* Check to see if the mailbox is actually open */ - if (!ctx->data) + if (!idata) return; - CTX_DATA->reopen &= IMAP_REOPEN_ALLOW; + idata->reopen &= IMAP_REOPEN_ALLOW; - if ((CTX_DATA->state == IMAP_SELECTED) && (ctx == CTX_DATA->selected_ctx)) + if ((idata->state == IMAP_SELECTED) && (ctx == idata->ctx)) { - CTX_DATA->state = IMAP_AUTHENTICATED; - FREE (&(CTX_DATA->selected_mailbox)); + if (!(idata->noclose)) + { + mutt_message _("Closing mailbox..."); + if (imap_exec (buf, sizeof (buf), idata, "CLOSE", 0) != 0) + imap_error ("CLOSE failed", buf); + } + + idata->state = IMAP_AUTHENTICATED; + FREE (&(idata->mailbox)); } /* free IMAP part of headers */ @@ -1115,10 +1150,10 @@ void imap_fastclose_mailbox (CONTEXT *ctx) for (i = 0; i < IMAP_CACHE_LEN; i++) { - if (CTX_DATA->cache[i].path) + if (idata->cache[i].path) { - unlink (CTX_DATA->cache[i].path); - safe_free ((void **) &CTX_DATA->cache[i].path); + unlink (idata->cache[i].path); + safe_free ((void **) &idata->cache[i].path); } } } @@ -1184,30 +1219,19 @@ int imap_mailbox_check (char* path, int new) char mbox_unquoted[LONG_STRING]; char *s; int msgcount = 0; + int connflags = 0; IMAP_MBOX mx; if (imap_parse_path (path, &mx)) return -1; - conn = mutt_socket_find (&(mx.account), 0); - idata = (IMAP_DATA*) conn->data; + /* If imap_passive is set, don't open a connection to check for new mail */ + if (option (OPTIMAPPASSIVE)) + connflags &= M_IMAP_CONN_NONEW; - if (!idata || (idata->state == IMAP_DISCONNECTED)) - { - /* If passive is selected, then we don't open connections to check - * for new mail */ - if (option (OPTIMAPPASSIVE)) - return -1; - if (!idata) - { - /* The current connection is a new connection */ - idata = safe_calloc (1, sizeof (IMAP_DATA)); - conn->data = idata; - idata->conn = conn; - } - if (imap_open_connection (idata)) - return -1; - } + if (!(idata = imap_conn_find (&(mx.account), connflags))) + return -1; + conn = idata->conn; imap_fix_path (idata, mx.mbox, buf, sizeof (buf)); /* Update the path, if it fits */ @@ -1221,9 +1245,9 @@ int imap_mailbox_check (char* path, int new) * command on a mailbox that you have selected */ - if (mutt_strcmp (mbox_unquoted, idata->selected_mailbox) == 0 + if (mutt_strcmp (mbox_unquoted, idata->mailbox) == 0 || (mutt_strcasecmp (mbox_unquoted, "INBOX") == 0 - && mutt_strcasecmp (mbox_unquoted, idata->selected_mailbox) == 0)) + && mutt_strcasecmp (mbox_unquoted, idata->mailbox) == 0)) { strfcpy (buf, "NOOP", sizeof (buf)); } @@ -1373,21 +1397,10 @@ int imap_subscribe (char *path, int subscribe) if (imap_parse_path (path, &mx)) return -1; - conn = mutt_socket_find (&(mx.account), 0); - idata = (IMAP_DATA*) conn->data; - - if (!idata || (idata->state == IMAP_DISCONNECTED)) - { - if (!idata) - { - /* The current connection is a new connection */ - idata = safe_calloc (1, sizeof (IMAP_DATA)); - conn->data = idata; - idata->conn = conn; - } - if (imap_open_connection (idata)) - return -1; - } + if (!(idata = imap_conn_find (&(mx.account), 0))) + return -1; + + conn = idata->conn; imap_fix_path (idata, mx.mbox, buf, sizeof (buf)); if (subscribe) @@ -1428,16 +1441,10 @@ int imap_complete(char* dest, size_t dlen, char* path) { return -1; } - conn = mutt_socket_find (&(mx.account), 0); - idata = (IMAP_DATA*) conn->data; - /* don't open a new socket just for completion */ - if (!idata) - { - dprint (2, (debugfile, - "imap_complete: refusing to open new connection for %s", path)); + if (!(idata = imap_conn_find (&(mx.account), M_IMAP_CONN_NONEW))) return -1; - } + conn = idata->conn; /* reformat path for IMAP list, and append wildcard */ /* don't use INBOX in place of "" */ diff --git a/imap/imap.h b/imap/imap.h index a1223faa..99eaacaa 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -38,7 +38,7 @@ int imap_delete_mailbox (CONTEXT* idata, char* mailbox); int imap_open_mailbox (CONTEXT *ctx); int imap_open_mailbox_append (CONTEXT *ctx); int imap_sync_mailbox (CONTEXT *ctx, int expunge, int *index_hint); -void imap_fastclose_mailbox (CONTEXT *ctx); +void imap_close_mailbox (CONTEXT *ctx); int imap_buffy_check (char *path); int imap_mailbox_check (char *path, int new); int imap_subscribe (char *path, int subscribe); diff --git a/imap/imap_private.h b/imap/imap_private.h index f2639ab8..35545ce3 100644 --- a/imap/imap_private.h +++ b/imap/imap_private.h @@ -51,8 +51,7 @@ enum IMAP_NEW_MAIL, IMAP_EXPUNGE, IMAP_BYE, - IMAP_REOPENED, - IMAP_LOGOUT + IMAP_REOPENED }; enum @@ -116,6 +115,10 @@ enum CAPMAX }; +/* imap_conn_find flags */ +#define M_IMAP_CONN_NONEW (1<<0) +#define M_IMAP_CONN_NOSELECT (1<<1) + /* -- data structures -- */ typedef struct { @@ -138,21 +141,22 @@ typedef struct typedef struct { /* This data is specific to a CONNECTION to an IMAP server */ - short status; - short state; - short check_status; + CONNECTION *conn; + unsigned char state; + unsigned char status; + unsigned char check_status; unsigned char capabilities[(CAPMAX + 7)/8]; char seq[SEQLEN+1]; - CONNECTION *conn; /* The following data is all specific to the currently SELECTED mbox */ char delim; - CONTEXT *selected_ctx; - char *selected_mailbox; + CONTEXT *ctx; + char *mailbox; + unsigned char reopen; unsigned char rights[(RIGHTSMAX + 7)/8]; unsigned int newMailCount; IMAP_CACHE cache[IMAP_CACHE_LEN]; - short reopen; + int noclose : 1; /* all folder flags - system flags AND keywords */ LIST *flags; @@ -166,6 +170,7 @@ typedef struct int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag, int changed); int imap_open_connection (IMAP_DATA* idata); +IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags); time_t imap_parse_date (char* s); int imap_parse_list_response(IMAP_DATA* idata, char* buf, int buflen, char** name, int* noselect, int* noinferiors, char* delim); diff --git a/imap/util.c b/imap/util.c index cb16c43f..aa64c4a3 100644 --- a/imap/util.c +++ b/imap/util.c @@ -353,8 +353,7 @@ void imap_keepalive (void) { CONTEXT *ctx = Context; - if (ctx == NULL || ctx->magic != M_IMAP || - CTX_DATA->selected_ctx != ctx) + if (ctx == NULL || ctx->magic != M_IMAP || CTX_DATA->ctx != ctx) return; imap_check_mailbox (ctx, NULL); @@ -408,12 +407,12 @@ int imap_wait_keepalive (pid_t pid) void imap_allow_reopen (CONTEXT *ctx) { - if (ctx && ctx->magic == M_IMAP && CTX_DATA->selected_ctx == ctx) + if (ctx && ctx->magic == M_IMAP && CTX_DATA->ctx == ctx) CTX_DATA->reopen |= IMAP_REOPEN_ALLOW; } void imap_disallow_reopen (CONTEXT *ctx) { - if (ctx && ctx->magic == M_IMAP && CTX_DATA->selected_ctx == ctx) + if (ctx && ctx->magic == M_IMAP && CTX_DATA->ctx == ctx) CTX_DATA->reopen &= ~IMAP_REOPEN_ALLOW; } diff --git a/mutt_socket.c b/mutt_socket.c index 48f3a0d2..0d2d1270 100644 --- a/mutt_socket.c +++ b/mutt_socket.c @@ -145,19 +145,22 @@ void mutt_socket_free (CONNECTION* conn) } } -CONNECTION* mutt_socket_find (const ACCOUNT* account, int newconn) +/* mutt_conn_find: find a connection off the list of connections whose + * account matches account. If newconn is true, don't reuse one, but add + * it to the list. If start is not null, only search for connections after + * the given connection (allows higher level socket code to make more + * fine-grained searches than account info - eg in IMAP we may wish + * to find a connection which is not in IMAP_SELECTED state) */ +CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account) { CONNECTION* conn; - if (! newconn) + conn = start ? start->next : Connections; + while (conn) { - conn = Connections; - while (conn) - { - if (mutt_account_match (account, &(conn->account))) - return conn; - conn = conn->next; - } + if (mutt_account_match (account, &(conn->account))) + return conn; + conn = conn->next; } conn = socket_new_conn (); diff --git a/mutt_socket.h b/mutt_socket.h index 04ffe055..6b8590da 100644 --- a/mutt_socket.h +++ b/mutt_socket.h @@ -61,7 +61,7 @@ int mutt_socket_write_d (CONNECTION *conn, const char *buf, int dbg); /* stupid hack for imap_logout_all */ CONNECTION* mutt_socket_head (void); void mutt_socket_free (CONNECTION* conn); -CONNECTION* mutt_socket_find (const ACCOUNT* mx, int newconn); +CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account); int raw_socket_read (CONNECTION *conn); int raw_socket_write (CONNECTION *conn, const char *buf); diff --git a/mx.c b/mx.c index 2fbc393d..61cd80c1 100644 --- a/mx.c +++ b/mx.c @@ -684,7 +684,7 @@ void mx_fastclose_mailbox (CONTEXT *ctx) #ifdef USE_IMAP if (ctx->magic == M_IMAP) - imap_fastclose_mailbox (ctx); + imap_close_mailbox (ctx); #endif /* USE_IMAP */ if (ctx->subj_hash) hash_destroy (&ctx->subj_hash, NULL); diff --git a/pop.c b/pop.c index 16ba9928..6e640202 100644 --- a/pop.c +++ b/pop.c @@ -137,7 +137,7 @@ void mutt_fetchPopMail (void) account.port = PopPort; account.type = M_ACCT_TYPE_POP; account.flags = 0; - conn = mutt_socket_find (&account, 0); + conn = mutt_conn_find (NULL, &account); if (mutt_socket_open (conn) < 0) return; -- 2.40.0