#ifdef USE_IMAP
WHERE short ImapKeepalive;
WHERE short ImapPipelineDepth;
+WHERE short ImapPollTimeout;
#endif
/* flags for received signals */
/* forward declarations */
static int cmd_start (IMAP_DATA* idata, const char* cmdstr, int flags);
static int cmd_queue_full (IMAP_DATA* idata);
-static int cmd_queue (IMAP_DATA* idata, const char* cmdstr);
+static int cmd_queue (IMAP_DATA* idata, const char* cmdstr, int flags);
static IMAP_COMMAND* cmd_new (IMAP_DATA* idata);
static int cmd_status (const char *s);
static void cmd_handle_fatal (IMAP_DATA* idata);
* for checking for a mailbox on append and login
* IMAP_CMD_PASS: command contains a password. Suppress logging.
* IMAP_CMD_QUEUE: only queue command, do not execute.
+ * IMAP_CMD_POLL: poll the socket for a response before running imap_cmd_step.
* Return 0 on success, -1 on Failure, -2 on OK Failure
*/
int imap_exec (IMAP_DATA* idata, const char* cmdstr, int flags)
if (flags & IMAP_CMD_QUEUE)
return 0;
+ if ((flags & IMAP_CMD_POLL) &&
+ (ImapPollTimeout > 0) &&
+ (mutt_socket_poll (idata->conn, ImapPollTimeout)) == 0)
+ {
+ mutt_error (_("Connection to %s timed out"), idata->conn->account.host);
+ mutt_sleep (2);
+ cmd_handle_fatal (idata);
+ return -1;
+ }
+
do
rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
}
/* queues command. If the queue is full, attempts to drain it. */
-static int cmd_queue (IMAP_DATA* idata, const char* cmdstr)
+static int cmd_queue (IMAP_DATA* idata, const char* cmdstr, int flags)
{
IMAP_COMMAND* cmd;
int rc;
{
dprint (3, (debugfile, "Draining IMAP command pipeline\n"));
- rc = imap_exec (idata, NULL, IMAP_CMD_FAIL_OK);
+ rc = imap_exec (idata, NULL, IMAP_CMD_FAIL_OK | (flags & IMAP_CMD_POLL));
if (rc < 0 && rc != -2)
return rc;
return -1;
}
- if (cmdstr && ((rc = cmd_queue (idata, cmdstr)) < 0))
+ if (cmdstr && ((rc = cmd_queue (idata, cmdstr, flags)) < 0))
return rc;
if (flags & IMAP_CMD_QUEUE)
* receive a bye response (so it doesn't freak out and close the conn) */
(*idata)->status = IMAP_BYE;
imap_cmd_start (*idata, "LOGOUT");
- while (imap_cmd_step (*idata) == IMAP_CMD_CONTINUE)
- ;
+ if (ImapPollTimeout <= 0 ||
+ mutt_socket_poll ((*idata)->conn, ImapPollTimeout) != 0)
+ {
+ while (imap_cmd_step (*idata) == IMAP_CMD_CONTINUE)
+ ;
+ }
mutt_socket_close ((*idata)->conn);
imap_free_idata (idata);
if ((force ||
(idata->state != IMAP_IDLE && time(NULL) >= idata->lastread + Timeout))
- && imap_exec (idata, "NOOP", 0) != 0)
+ && imap_exec (idata, "NOOP", IMAP_CMD_POLL) != 0)
return -1;
/* We call this even when we haven't run NOOP in case we have pending
snprintf (command, sizeof (command),
"STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged);
- if (imap_exec (idata, command, IMAP_CMD_QUEUE) < 0)
+ if (imap_exec (idata, command, IMAP_CMD_QUEUE | IMAP_CMD_POLL) < 0)
{
dprint (1, (debugfile, "Error queueing command\n"));
return 0;
}
}
- if (lastdata && (imap_exec (lastdata, NULL, IMAP_CMD_FAIL_OK) == -1))
+ if (lastdata && (imap_exec (lastdata, NULL, IMAP_CMD_FAIL_OK | IMAP_CMD_POLL) == -1))
{
dprint (1, (debugfile, "Error polling mailboxes\n"));
return 0;
#define IMAP_CMD_FAIL_OK (1<<0)
#define IMAP_CMD_PASS (1<<1)
#define IMAP_CMD_QUEUE (1<<2)
+#define IMAP_CMD_POLL (1<<3)
/* length of "DD-MMM-YYYY HH:MM:SS +ZZzz" (null-terminated) */
#define IMAP_DATELEN 27
** .pp
** \fBNote:\fP Changes to this variable have no effect on open connections.
*/
+ { "imap_poll_timeout", DT_NUM, R_NONE, UL &ImapPollTimeout, 15 },
+ /*
+ ** .pp
+ ** This variable specifies the maximum amount of time in seconds
+ ** that mutt will wait for a response when polling IMAP connections
+ ** for new mail, before timing out and closing the connection. Set
+ ** to 0 to disable timing out.
+ */
{ "imap_servernoise", DT_BOOL, R_NONE, OPTIMAPSERVERNOISE, 1 },
/*
** .pp