From: Brendan Cully Date: Tue, 15 Jul 2003 11:41:32 +0000 (+0000) Subject: The attached patch should keep all opened IMAP connections alive, no X-Git-Tag: pre-type-punning-patch~45 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb059c9288af6e8154a6b982405c8477a22f8285;p=mutt The attached patch should keep all opened IMAP connections alive, no matter what mailbox you are currently in. With the patch that got committed yesterday, this should close bug 1523. (There was a typo in that patch. This one supersedes it.) --- diff --git a/curs_main.c b/curs_main.c index cf618895..4506c29c 100644 --- a/curs_main.c +++ b/curs_main.c @@ -509,6 +509,7 @@ int mutt_index_menu (void) } #ifdef USE_IMAP + imap_keepalive (); imap_disallow_reopen (Context); #endif @@ -976,7 +977,8 @@ CHECK_IMAP_ACL(IMAP_ACL_DELETE); #ifdef USE_IMAP case OP_MAIN_IMAP_FETCH: - ImapLastCheck = 0; + if (Context->magic == M_IMAP) + imap_check_mailbox (Context, &index_hint, 1); break; #endif diff --git a/globals.h b/globals.h index 445611ca..dca04c1d 100644 --- a/globals.h +++ b/globals.h @@ -124,10 +124,6 @@ WHERE LIST *UnIgnore INITVAL(0); WHERE LIST *MailLists INITVAL(0); WHERE LIST *SubscribedLists INITVAL(0); -#ifdef USE_IMAP -WHERE time_t ImapLastCheck INITVAL(0); -#endif - /* bit vector for boolean variables */ #ifdef MAIN_C unsigned char Options[(OPTMAX + 7)/8]; diff --git a/imap/command.c b/imap/command.c index 71b4b879..fb01bd20 100644 --- a/imap/command.c +++ b/imap/command.c @@ -133,7 +133,9 @@ int imap_cmd_step (IMAP_DATA* idata) cmd->blen = IMAP_CMD_BUFSIZE; dprint (3, (debugfile, "imap_cmd_step: shrank buffer to %u bytes\n", cmd->blen)); } - + + idata->lastread = time(NULL); + /* handle untagged messages. The caller still gets its shot afterwards. */ if (!ascii_strncmp (cmd->buf, "* ", 2) && cmd_handle_untagged (idata)) diff --git a/imap/imap.c b/imap/imap.c index 36fde9e1..a70d2232 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -1,7 +1,7 @@ /* * Copyright (C) 1996-8 Michael R. Elkins * Copyright (C) 1996-9 Brandon Long - * Copyright (C) 1999-2002 Brendan Cully + * Copyright (C) 1999-2003 Brendan Cully * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -525,9 +525,6 @@ int imap_open_mailbox (CONTEXT* ctx) /* once again the context is new */ ctx->data = idata; - if (idata->status == IMAP_FATAL) - goto fail; - /* Clean up path and replace the one in the ctx */ imap_fix_path (idata, mx.mbox, buf, sizeof (buf)); FREE(&(idata->mailbox)); @@ -918,7 +915,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint) * to be changed. */ imap_allow_reopen (ctx); - if ((rc = imap_check_mailbox (ctx, index_hint)) != 0) + if ((rc = imap_check_mailbox (ctx, index_hint, 0)) != 0) return rc; memset (&cmd, 0, sizeof (cmd)); @@ -1085,6 +1082,7 @@ void imap_close_mailbox (CONTEXT* ctx) idata->state = IMAP_AUTHENTICATED; FREE (&(idata->mailbox)); mutt_free_list (&idata->flags); + idata->ctx = NULL; } /* free IMAP part of headers */ @@ -1109,25 +1107,18 @@ void imap_close_mailbox (CONTEXT* ctx) * 0 no change * -1 error */ -int imap_check_mailbox (CONTEXT *ctx, int *index_hint) +int imap_check_mailbox (CONTEXT *ctx, int *index_hint, int force) { /* overload keyboard timeout to avoid many mailbox checks in a row. * Most users don't like having to wait exactly when they press a key. */ - IMAP_DATA* idata; - time_t now; int result = 0; idata = (IMAP_DATA*) ctx->data; - now = time(NULL); - if (now > ImapLastCheck + Timeout) - { - ImapLastCheck = now; - - if (imap_exec (idata, "NOOP", 0) != 0) - return -1; - } + if ((force || time(NULL) > idata->lastread + Timeout) + && imap_exec (idata, "NOOP", 0) != 0) + return -1; /* We call this even when we haven't run NOOP in case we have pending * changes to process, since we can reopen here. */ diff --git a/imap/imap.h b/imap/imap.h index 3a374255..4a3608d0 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1996-8 Michael R. Elkins - * Copyright (C) 2000-1 Brendan Cully + * Copyright (C) 2000-3 Brendan Cully * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ typedef struct /* imap.c */ int imap_access (const char*, int); -int imap_check_mailbox (CONTEXT *ctx, int *index_hint); +int imap_check_mailbox (CONTEXT *ctx, int *index_hint, int force); int imap_close_connection (CONTEXT *ctx); int imap_delete_mailbox (CONTEXT* idata, IMAP_MBOX mx); int imap_open_mailbox (CONTEXT *ctx); diff --git a/imap/imap_private.h b/imap/imap_private.h index 7efd9c55..0a554097 100644 --- a/imap/imap_private.h +++ b/imap/imap_private.h @@ -165,6 +165,7 @@ typedef struct char* capstr; unsigned char capabilities[(CAPMAX + 7)/8]; unsigned int seqno; + time_t lastread; /* last time we read a command for the server */ /* who knows, one day we may run multiple commands in parallel */ IMAP_COMMAND cmd; diff --git a/imap/util.c b/imap/util.c index 6fd13e73..ae72edb7 100644 --- a/imap/util.c +++ b/imap/util.c @@ -249,22 +249,7 @@ void imap_error (const char *where, const char *msg) /* imap_new_idata: Allocate and initialise a new IMAP_DATA structure. * Returns NULL on failure (no mem) */ IMAP_DATA* imap_new_idata (void) { - IMAP_DATA* idata; - - idata = safe_calloc (1, sizeof (IMAP_DATA)); - if (!idata) - return NULL; - - idata->conn = NULL; - idata->capstr = NULL; - idata->state = IMAP_DISCONNECTED; - idata->seqno = 0; - - idata->cmd.buf = NULL; - idata->cmd.blen = 0; - idata->cmd.state = IMAP_CMD_OK; - - return idata; + return safe_calloc (1, sizeof (IMAP_DATA)); } /* imap_free_idata: Release and clear storage in an IMAP_DATA structure. */ @@ -562,12 +547,35 @@ static RETSIGTYPE alrm_handler (int sig) void imap_keepalive (void) { - CONTEXT *ctx = Context; - - if (ctx == NULL || ctx->magic != M_IMAP || CTX_DATA->ctx != ctx) - return; + CONNECTION *conn; + CONTEXT *ctx = NULL; + IMAP_DATA *idata; + + conn = mutt_socket_head (); + while (conn) + { + if (conn->account.type == M_ACCT_TYPE_IMAP) + { + idata = (IMAP_DATA*) conn->data; - imap_check_mailbox (ctx, NULL); + if (idata->state >= IMAP_AUTHENTICATED + && time(NULL) >= idata->lastread + ImapKeepalive) + { + if (idata->ctx) + ctx = idata->ctx; + else + { + ctx = safe_calloc (1, sizeof (CONTEXT)); + ctx->data = idata; + } + imap_check_mailbox (ctx, NULL, 1); + if (!idata->ctx) + FREE (&ctx); + } + } + + conn = conn->next; + } } int imap_wait_keepalive (pid_t pid) diff --git a/mx.c b/mx.c index c00444f0..bc7b8ffc 100644 --- a/mx.c +++ b/mx.c @@ -1360,7 +1360,7 @@ int mx_check_mailbox (CONTEXT *ctx, int *index_hint, int lock) #ifdef USE_IMAP case M_IMAP: - return (imap_check_mailbox (ctx, index_hint)); + return (imap_check_mailbox (ctx, index_hint, 0)); #endif /* USE_IMAP */ #ifdef USE_POP