summaryrefslogtreecommitdiffstats
path: root/imap
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2000-08-21 11:30:28 +0000
committerThomas Roessler <roessler@does-not-exist.org>2000-08-21 11:30:28 +0000
commit2526f63a480644c2b70494cbbbc3c9ce19f682f7 (patch)
treedd2f8f113fdd234aee6f47b3e1bc16c14952fcd5 /imap
parentd249f685cd736d45c46a8f26ffe4a0268768d6f8 (diff)
patch-bac.command-2
Diffstat (limited to 'imap')
-rw-r--r--imap/auth_anon.c4
-rw-r--r--imap/auth_cram.c4
-rw-r--r--imap/auth_gss.c10
-rw-r--r--imap/auth_login.c6
-rw-r--r--imap/auth_sasl.c4
-rw-r--r--imap/browse.c2
-rw-r--r--imap/command.c182
-rw-r--r--imap/imap.c242
-rw-r--r--imap/imap_private.h29
-rw-r--r--imap/message.c30
10 files changed, 172 insertions, 341 deletions
diff --git a/imap/auth_anon.c b/imap/auth_anon.c
index a7fd87ff..d9e48289 100644
--- a/imap/auth_anon.c
+++ b/imap/auth_anon.c
@@ -41,7 +41,7 @@ imap_auth_res_t imap_auth_anon (IMAP_DATA* idata)
imap_cmd_start (idata, "AUTHENTICATE ANONYMOUS");
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_RESPOND)
@@ -53,7 +53,7 @@ imap_auth_res_t imap_auth_anon (IMAP_DATA* idata)
mutt_socket_write (idata->conn, "ZHVtbXkK\r\n"); /* base64 ("dummy") */
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_DONE)
diff --git a/imap/auth_cram.c b/imap/auth_cram.c
index 00e0f0d9..f41ef4c5 100644
--- a/imap/auth_cram.c
+++ b/imap/auth_cram.c
@@ -58,7 +58,7 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP_DATA* idata)
* correspond to that of an RFC 822 'msg-id' [RFC822] as described in [POP3].
*/
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_RESPOND)
@@ -103,7 +103,7 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP_DATA* idata)
mutt_socket_write (idata->conn, ibuf);
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_DONE)
diff --git a/imap/auth_gss.c b/imap/auth_gss.c
index bf59c019..b1f03a37 100644
--- a/imap/auth_gss.c
+++ b/imap/auth_gss.c
@@ -90,7 +90,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
/* expect a null continuation response ("+") */
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_RESPOND)
@@ -127,7 +127,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
/* end authentication attempt */
mutt_socket_write (idata->conn, "*\r\n");
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
goto bail;
}
@@ -142,7 +142,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
if (maj_stat == GSS_S_CONTINUE_NEEDED)
{
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_RESPOND)
@@ -163,7 +163,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
/* get security flags and buffer size */
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_RESPOND)
@@ -230,7 +230,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
/* Joy of victory or agony of defeat? */
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_DONE)
{
diff --git a/imap/auth_login.c b/imap/auth_login.c
index 731f14f3..fff5baa6 100644
--- a/imap/auth_login.c
+++ b/imap/auth_login.c
@@ -29,6 +29,12 @@ imap_auth_res_t imap_auth_login (IMAP_DATA* idata)
char buf[STRING];
int rc;
+ if (mutt_bit_isset (idata->capabilities, LOGINDISABLED))
+ {
+ mutt_message _("LOGIN disabled on this server.");
+ return IMAP_AUTH_UNAVAIL;
+ }
+
if (mutt_account_getuser (&idata->conn->account))
return IMAP_AUTH_FAILURE;
if (mutt_account_getpass (&idata->conn->account))
diff --git a/imap/auth_sasl.c b/imap/auth_sasl.c
index 5e01331b..b628d8fc 100644
--- a/imap/auth_sasl.c
+++ b/imap/auth_sasl.c
@@ -98,7 +98,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata)
while (rc == SASL_CONTINUE)
{
do
- irc = imap_cmd_resp (idata);
+ irc = imap_cmd_step (idata);
while (irc == IMAP_CMD_CONTINUE);
if (irc == IMAP_CMD_FAIL)
@@ -147,7 +147,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata)
}
while (irc != IMAP_CMD_DONE)
- if ((irc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+ if ((irc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
if (rc != SASL_OK)
diff --git a/imap/browse.c b/imap/browse.c
index 1571a705..cd3b0470 100644
--- a/imap/browse.c
+++ b/imap/browse.c
@@ -347,7 +347,7 @@ static int browse_get_namespace (IMAP_DATA* idata, char* nsbuf, int nsblen,
do
{
- if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+ if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
s = imap_next_word (idata->buf);
diff --git a/imap/command.c b/imap/command.c
index 609f04e6..a406c942 100644
--- a/imap/command.c
+++ b/imap/command.c
@@ -32,24 +32,43 @@
#define IMAP_CMD_BUFSIZE 512
/* forward declarations */
+static void cmd_finish (IMAP_DATA* idata);
+static void cmd_handle_fatal (IMAP_DATA* idata);
+static int cmd_handle_untagged (IMAP_DATA* idata);
static void cmd_make_sequence (char* buf, size_t buflen);
static void cmd_parse_capabilities (IMAP_DATA* idata, char* s);
static void cmd_parse_expunge (IMAP_DATA* idata, char* s);
static void cmd_parse_myrights (IMAP_DATA* idata, char* s);
-static char *Capabilities[] = {"IMAP4", "IMAP4rev1", "STATUS", "ACL",
- "NAMESPACE", "AUTH=CRAM-MD5", "AUTH=KERBEROS_V4", "AUTH=GSSAPI",
- "AUTH=LOGIN", "AUTH-LOGIN", "AUTH=PLAIN", "AUTH=SKEY", "IDLE",
- "LOGIN-REFERRALS", "MAILBOX-REFERRALS", "QUOTA", "SCAN", "SORT",
- "THREAD=ORDEREDSUBJECT", "UIDPLUS", "AUTH=ANONYMOUS", NULL};
+static char *Capabilities[] = {
+ "IMAP4",
+ "IMAP4rev1",
+ "STATUS",
+ "ACL",
+ "NAMESPACE",
+ "AUTH=CRAM-MD5",
+ "AUTH=GSSAPI",
+ "AUTH=ANONYMOUS",
+ "STARTTLS",
+ "LOGINDISABLED",
+
+ NULL
+};
/* imap_cmd_start: Given an IMAP command, send it to the server.
* Currently a minor convenience, but helps to route all IMAP commands
* through a single interface. */
-void imap_cmd_start (IMAP_DATA* idata, const char* cmd)
+int imap_cmd_start (IMAP_DATA* idata, const char* cmd)
{
char* out;
int outlen;
+ int rc = 0;
+
+ if (idata->status == IMAP_FATAL)
+ {
+ cmd_handle_fatal (idata);
+ return IMAP_CMD_FAIL;
+ }
cmd_make_sequence (idata->seq, sizeof (idata->seq));
/* seq, space, cmd, \r\n\0 */
@@ -57,20 +76,28 @@ void imap_cmd_start (IMAP_DATA* idata, const char* cmd)
out = (char*) safe_malloc (outlen);
snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd);
- mutt_socket_write (idata->conn, out);
+ rc = mutt_socket_write (idata->conn, out);
- safe_free ((void**) &out);
+ FREE (&out);
+
+ return (rc < 0) ? IMAP_CMD_FAIL : 0;
}
-/* imap_cmd_resp: Reads server responses from an IMAP command, detects
+/* imap_cmd_step: Reads server responses from an IMAP command, detects
* tagged completion response, handles untagged messages, can read
* arbitrarily large strings (using malloc, so don't make it _too_
* large!). */
-int imap_cmd_resp (IMAP_DATA* idata)
+int imap_cmd_step (IMAP_DATA* idata)
{
unsigned int len = 0;
int c;
+ if (idata->status == IMAP_FATAL)
+ {
+ cmd_handle_fatal (idata);
+ return IMAP_CMD_FAIL;
+ }
+
/* read into buffer, expanding buffer as necessary until we have a full
* line */
do
@@ -79,15 +106,14 @@ int imap_cmd_resp (IMAP_DATA* idata)
{
safe_realloc ((void**) &idata->buf, idata->blen + IMAP_CMD_BUFSIZE);
idata->blen = idata->blen + IMAP_CMD_BUFSIZE;
- dprint (3, (debugfile, "imap_cmd_resp: grew buffer to %u bytes\n", idata->blen));
+ dprint (3, (debugfile, "imap_cmd_step: grew buffer to %u bytes\n", idata->blen));
}
if ((c = mutt_socket_readln (idata->buf + len, idata->blen - len,
idata->conn)) < 0)
{
- dprint (1, (debugfile, "imap_cmd_resp: Error while reading server response, closing connection.\n"));
+ dprint (1, (debugfile, "imap_cmd_step: Error while reading server response, closing connection.\n"));
mutt_socket_close (idata->conn);
- idata->state = IMAP_DISCONNECTED;
idata->status = IMAP_FATAL;
return IMAP_CMD_FAIL;
}
@@ -104,12 +130,12 @@ int imap_cmd_resp (IMAP_DATA* idata)
{
safe_realloc ((void**) &idata->buf, IMAP_CMD_BUFSIZE);
idata->blen = IMAP_CMD_BUFSIZE;
- dprint (3, (debugfile, "imap_cmd_resp: shrank buffer to %u bytes\n", idata->blen));
+ dprint (3, (debugfile, "imap_cmd_step: shrank buffer to %u bytes\n", idata->blen));
}
/* handle untagged messages. The caller still gets its shot afterwards. */
if (!strncmp (idata->buf, "* ", 2) &&
- imap_handle_untagged (idata, idata->buf))
+ cmd_handle_untagged (idata))
return IMAP_CMD_FAIL;
/* server demands a continuation response from us */
@@ -119,59 +145,13 @@ int imap_cmd_resp (IMAP_DATA* idata)
/* tagged completion code */
if (!mutt_strncmp (idata->buf, idata->seq, SEQLEN))
{
- imap_cmd_finish (idata);
+ cmd_finish (idata);
return IMAP_CMD_DONE;
}
return IMAP_CMD_CONTINUE;
}
-/* imap_cmd_finish: When the caller has finished reading command responses,
- * it must call this routine to perform cleanup (eg fetch new mail if
- * detected, do expunge) */
-void imap_cmd_finish (IMAP_DATA* idata)
-{
- if (!(idata->state == IMAP_SELECTED) || idata->ctx->closing)
- {
- idata->status = 0;
- mutt_clear_error ();
- return;
- }
-
- if ((idata->status == IMAP_NEW_MAIL ||
- (idata->reopen & (IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING)))
- && (idata->reopen & IMAP_REOPEN_ALLOW))
- {
- int count = idata->newMailCount;
-
- if (!(idata->reopen & IMAP_EXPUNGE_PENDING) &&
- ((idata->status == IMAP_NEW_MAIL) || (idata->reopen & IMAP_NEWMAIL_PENDING))
- && count > idata->ctx->msgcount)
- {
- /* read new mail messages */
- dprint (1, (debugfile, "imap_cmd_finish: fetching new mail\n"));
-
- 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_expunge_mailbox (idata);
- idata->check_status = IMAP_REOPENED;
- idata->reopen &= ~(IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING);
- }
-
- }
- else if (!(idata->reopen & IMAP_REOPEN_ALLOW))
- {
- if (idata->status == IMAP_NEW_MAIL)
- idata->reopen |= IMAP_NEWMAIL_PENDING;
- }
-
- idata->status = 0;
-}
-
/* imap_code: returns 1 if the command result was OK, or 0 if NO or BAD */
int imap_code (const char *s)
{
@@ -194,6 +174,12 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags)
int outlen;
int rc;
+ if (idata->status == IMAP_FATAL)
+ {
+ cmd_handle_fatal (idata);
+ return -1;
+ }
+
/* create sequence for command */
cmd_make_sequence (idata->seq, sizeof (idata->seq));
/* seq, space, cmd, \r\n\0 */
@@ -201,13 +187,15 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags)
out = (char*) safe_malloc (outlen);
snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd);
- mutt_socket_write_d (idata->conn, out,
+ rc = mutt_socket_write_d (idata->conn, out,
flags & IMAP_CMD_PASS ? IMAP_LOG_PASS : IMAP_LOG_CMD);
-
safe_free ((void**) &out);
+ if (rc < 0)
+ return -1;
+
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_DONE)
@@ -232,13 +220,62 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags)
return 0;
}
-/* imap_handle_untagged: fallback parser for otherwise unhandled messages. */
-int imap_handle_untagged (IMAP_DATA* idata, char* s)
+/* cmd_finish: When the caller has finished reading command responses,
+ * it must call this routine to perform cleanup (eg fetch new mail if
+ * detected, do expunge). Called automatically by imap_cmd_step */
+static void cmd_finish (IMAP_DATA* idata)
{
- char *pn;
+ if (!(idata->state == IMAP_SELECTED) || idata->ctx->closing)
+ {
+ mutt_clear_error ();
+ return;
+ }
+
+ if ((idata->reopen & IMAP_REOPEN_ALLOW) &&
+ (idata->reopen & (IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING)))
+ {
+ int count = idata->newMailCount;
+
+ if (!(idata->reopen & IMAP_EXPUNGE_PENDING) &&
+ (idata->reopen & IMAP_NEWMAIL_PENDING)
+ && count > idata->ctx->msgcount)
+ {
+ /* read new mail messages */
+ dprint (2, (debugfile, "cmd_finish: Fetching new mail\n"));
+ count = imap_read_headers (idata, idata->ctx->msgcount, count-1)+1;
+ /* check_status: curs_main uses imap_check_mailbox to detect
+ * whether the index needs updating */
+ idata->check_status = IMAP_NEWMAIL_PENDING;
+ idata->reopen &= ~IMAP_NEWMAIL_PENDING;
+ }
+ else
+ {
+ dprint (2, (debugfile, "cmd_finish: Expunging mailbox\n"));
+ imap_expunge_mailbox (idata);
+ idata->reopen &= ~(IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING);
+ }
+ }
+
+ idata->status = 0;
+}
+
+/* cmd_handle_fatal: when IMAP_DATA is in fatal state, do what we can */
+static void cmd_handle_fatal (IMAP_DATA* idata)
+{
+ if ((idata->state == IMAP_SELECTED) &&
+ (idata->reopen & IMAP_REOPEN_ALLOW) &&
+ !idata->ctx->closing)
+ mx_fastclose_mailbox (idata->ctx);
+}
+
+/* cmd_handle_untagged: fallback parser for otherwise unhandled messages. */
+static int cmd_handle_untagged (IMAP_DATA* idata)
+{
+ char* s;
+ char* pn;
int count;
- s = imap_next_word (s);
+ s = imap_next_word (idata->buf);
if ((idata->state == IMAP_SELECTED) && isdigit (*s))
{
@@ -263,22 +300,21 @@ int imap_handle_untagged (IMAP_DATA* idata, char* s)
*/
mutt_error _("Fatal error. Message count is out of sync!");
idata->status = IMAP_FATAL;
- 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->ctx->msgcount)
dprint (3, (debugfile,
- "imap_handle_untagged: superfluous EXISTS message.\n"));
+ "cmd_handle_untagged: superfluous EXISTS message.\n"));
else
{
if (!(idata->reopen & IMAP_EXPUNGE_PENDING))
{
dprint (2, (debugfile,
- "imap_handle_untagged: New mail in %s - %d messages total.\n",
+ "cmd_handle_untagged: New mail in %s - %d messages total.\n",
idata->mailbox, count));
- idata->status = IMAP_NEW_MAIL;
+ idata->reopen |= IMAP_NEWMAIL_PENDING;
}
idata->newMailCount = count;
}
diff --git a/imap/imap.c b/imap/imap.c
index 86ec6511..c122df69 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -231,210 +231,6 @@ void imap_expunge_mailbox (IMAP_DATA* idata)
mutt_sort_headers (idata->ctx, 1);
}
-#if 0
-/* imap_reopen_mailbox: Reopen an imap mailbox. This is used when the
- * server sends an EXPUNGE message, indicating that some messages may have
- * been deleted. This is a heavy handed approach, as it reparses all of the
- * headers, but it should guarantee correctness. Later, we might implement
- * something to actually only remove the messages that are marked
- * EXPUNGE.
- */
-int imap_reopen_mailbox (IMAP_DATA* idata)
-{
- HEADER **old_hdrs;
- CONTEXT* ctx;
- int old_msgcount;
- char buf[LONG_STRING];
- char bufout[LONG_STRING];
- char *pc = NULL;
- int count = 0;
- int msg_mod = 0;
- int n;
- int i, j;
- int index_hint_set;
-
- ctx = idata->ctx;
-
- ctx->quiet = 1;
-
- if (Sort != SORT_ORDER)
- {
- short old_sort;
-
- old_sort = Sort;
- Sort = SORT_ORDER;
- mutt_sort_headers (ctx, 1);
- Sort = old_sort;
- }
-
- old_hdrs = NULL;
- old_msgcount = 0;
-
- /* simulate a close */
- hash_destroy (&ctx->id_hash, NULL);
- hash_destroy (&ctx->subj_hash, NULL);
- safe_free ((void **) &ctx->v2r);
- if (ctx->readonly)
- {
- for (i = 0; i < ctx->msgcount; i++)
- mutt_free_header (&(ctx->hdrs[i])); /* nothing to do! */
- safe_free ((void **) &ctx->hdrs);
- }
- else
- {
- /* save the old headers */
- old_msgcount = ctx->msgcount;
- old_hdrs = ctx->hdrs;
- ctx->hdrs = NULL;
- }
-
- ctx->hdrmax = 0; /* force allocation of new headers */
- ctx->msgcount = 0;
- ctx->vcount = 0;
- ctx->tagged = 0;
- ctx->deleted = 0;
- ctx->new = 0;
- ctx->unread = 0;
- ctx->flagged = 0;
- ctx->changed = 0;
- ctx->id_hash = hash_create (1031);
- ctx->subj_hash = hash_create (1031);
-
- 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);
-
- do
- {
- if (mutt_socket_readln (buf, sizeof (buf), CTX_DATA->conn) < 0)
- break;
-
- if (buf[0] == '*')
- {
- pc = buf + 2;
-
- if (!mutt_strncasecmp ("STATUS", pc, 6) &&
- (pc = (char *) mutt_stristr (pc, "MESSAGES")))
- {
- char* pn;
-
- /* skip "MESSAGES" */
- pc += 8;
- SKIPWS (pc);
- pn = pc;
-
- while (*pc && isdigit (*pc))
- pc++;
- *pc++ = 0;
- n = atoi (pn);
- count = n;
- }
- else if (imap_handle_untagged (CTX_DATA, buf) != 0)
- return -1;
- }
- }
- while (mutt_strncmp (CTX_DATA->seq, buf, mutt_strlen (CTX_DATA->seq)) != 0);
-
- if (!imap_code (buf))
- {
- char *s;
- s = imap_next_word (buf); /* skip seq */
- s = imap_next_word (s); /* Skip response */
- mutt_error ("%s", s);
- sleep (1);
- return -1;
- }
-
- ctx->hdrmax = count;
- ctx->hdrs = safe_malloc (count * sizeof (HEADER *));
- ctx->v2r = safe_malloc (count * sizeof (int));
- ctx->msgcount = 0;
- count = imap_read_headers (ctx, 0, count - 1) + 1;
-
- index_hint_set = 1;
-
- if (!ctx->readonly)
- {
- for (i = 0; i < ctx->msgcount; i++)
- {
- int found = 0;
-
- /* some messages have been deleted, and new messages have been
- * appended at the end; the heuristic is that old messages have then
- * "advanced" towards the beginning of the folder, so we begin the
- * search at index "i"
- */
- for (j = i; j < old_msgcount; j++)
- {
- if (old_hdrs[j] == NULL)
- continue;
- if (mbox_strict_cmp_headers (ctx->hdrs[i], old_hdrs[j]))
- {
- found = 1;
- break;
- }
- }
- if (!found)
- {
- for (j = 0; j < i && j < old_msgcount; j++)
- {
- if (old_hdrs[j] == NULL)
- continue;
- if (mbox_strict_cmp_headers (ctx->hdrs[i], old_hdrs[j]))
- {
- found = 1;
- break;
- }
- }
- }
- if (found)
- {
- /* this is best done here */
-/*
- if (!index_hint_set && *index_hint == j)
- *index_hint = i;
-*/
-
- if (old_hdrs[j]->changed)
- {
- /* Only update the flags if the old header was changed;
- * otherwise, the header may have been modified
- * externally, and we don't want to lose _those_ changes
- */
-
- mutt_set_flag (ctx, ctx->hdrs[i], M_FLAG, old_hdrs[j]->flagged);
- mutt_set_flag (ctx, ctx->hdrs[i], M_REPLIED, old_hdrs[j]->replied);
- mutt_set_flag (ctx, ctx->hdrs[i], M_OLD, old_hdrs[j]->old);
- mutt_set_flag (ctx, ctx->hdrs[i], M_READ, old_hdrs[j]->read);
- }
- mutt_set_flag (ctx, ctx->hdrs[i], M_DELETE, old_hdrs[j]->deleted);
- mutt_set_flag (ctx, ctx->hdrs[i], M_TAG, old_hdrs[j]->tagged);
-
- /* we don't need this header any more */
- mutt_free_header (&(old_hdrs[j]));
- }
- }
-
- /* free the remaining old headers */
- for (j = 0; j < old_msgcount; j++)
- {
- if (old_hdrs[j])
- {
- mutt_free_header (&(old_hdrs[j]));
- msg_mod = 1;
- }
- }
- safe_free ((void **) &old_hdrs);
- }
-
- ctx->quiet = 0;
-
- return 0;
-}
-#endif
-
static int imap_get_delim (IMAP_DATA *idata)
{
char *s;
@@ -448,7 +244,7 @@ static int imap_get_delim (IMAP_DATA *idata)
do
{
- if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+ if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
s = imap_next_word (idata->buf);
@@ -572,7 +368,7 @@ int imap_open_connection (IMAP_DATA* idata)
idata->state = IMAP_CONNECTED;
- if (imap_cmd_resp (idata) != IMAP_CMD_CONTINUE)
+ if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
goto bail;
if (mutt_strncmp ("* OK", idata->buf, 4) == 0)
@@ -685,6 +481,9 @@ int imap_open_mailbox (CONTEXT* ctx)
/* once again the context is new */
ctx->data = idata;
+ if (idata->status == IMAP_FATAL)
+ return -1;
+
/* Clean up path and replace the one in the ctx */
imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
FREE(&(idata->mailbox));
@@ -713,7 +512,7 @@ int imap_open_mailbox (CONTEXT* ctx)
{
char *pc;
- if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+ if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
pc = idata->buf + 2;
@@ -722,7 +521,7 @@ int imap_open_mailbox (CONTEXT* ctx)
{
/* imap_handle_untagged will have picked up the EXISTS message and
* set the NEW_MAIL flag. We clear it here. */
- idata->status = 0;
+ idata->reopen &= ~IMAP_NEWMAIL_PENDING;
count = idata->newMailCount;
idata->newMailCount = 0;
}
@@ -821,7 +620,7 @@ int imap_open_mailbox (CONTEXT* ctx)
ctx->hdrs = safe_malloc (count * sizeof (HEADER *));
ctx->v2r = safe_malloc (count * sizeof (int));
ctx->msgcount = 0;
- count = imap_read_headers (ctx, 0, count - 1) + 1;
+ count = imap_read_headers (idata, 0, count - 1) + 1;
dprint (1, (debugfile, "imap_open_mailbox(): msgcount is %d\n", ctx->msgcount));
return 0;
@@ -894,7 +693,7 @@ void imap_logout (IMAP_DATA* idata)
* 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_resp (idata) == IMAP_CMD_CONTINUE)
+ while (imap_cmd_step (idata) == IMAP_CMD_CONTINUE)
;
}
@@ -1167,7 +966,9 @@ void imap_close_mailbox (CONTEXT* ctx)
idata->reopen &= IMAP_REOPEN_ALLOW;
- if ((idata->state == IMAP_SELECTED) && (ctx == idata->ctx))
+ if ((idata->status != IMAP_FATAL) &&
+ (idata->state == IMAP_SELECTED) &&
+ (ctx == idata->ctx))
{
if (!(idata->noclose) && imap_exec (idata, "CLOSE", 0))
imap_error ("CLOSE failed", idata->buf);
@@ -1193,7 +994,7 @@ void imap_close_mailbox (CONTEXT* ctx)
/* use the NOOP command to poll for new mail
*
* return values:
- * M_REOPENED mailbox has been reopened
+ * M_REOPENED mailbox has been externally modified
* M_NEW_MAIL new mail has arrived!
* 0 no change
* -1 error
@@ -1224,17 +1025,20 @@ int imap_check_mailbox (CONTEXT *ctx, int *index_hint)
{
if (ImapCheckTimeout) checktime += t;
- idata->check_status = 0;
if (imap_exec (idata, "NOOP", 0) != 0)
{
imap_error ("imap_check_mailbox", idata->buf);
return -1;
}
- if (idata->check_status == IMAP_NEW_MAIL)
+ if (idata->check_status & IMAP_NEWMAIL_PENDING)
+ {
+ idata->check_status &= ~IMAP_NEWMAIL_PENDING;
return M_NEW_MAIL;
- if (idata->check_status == IMAP_REOPENED)
- return M_REOPENED;
+ }
+
+ /* TODO: we should be able to detect external changes and return
+ * M_REOPENED here. */
}
return 0;
@@ -1305,7 +1109,7 @@ int imap_mailbox_check (char* path, int new)
do
{
- if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+ if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
s = imap_next_word (idata->buf);
@@ -1352,7 +1156,7 @@ int imap_parse_list_response(IMAP_DATA* idata, char **name, int *noselect,
*name = NULL;
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
if (rc == IMAP_CMD_DONE)
return 0;
if (rc != IMAP_CMD_CONTINUE)
@@ -1400,7 +1204,7 @@ int imap_parse_list_response(IMAP_DATA* idata, char **name, int *noselect,
{
if (imap_get_literal_count(idata->buf, &bytes) < 0)
return -1;
- if (imap_cmd_resp (idata) != IMAP_CMD_CONTINUE)
+ if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
return -1;
*name = idata->buf;
}
diff --git a/imap/imap_private.h b/imap/imap_private.h
index 412e9521..b574ee81 100644
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -54,7 +54,6 @@
enum
{
IMAP_FATAL = 1,
- IMAP_NEW_MAIL,
IMAP_BYE,
IMAP_REOPENED
};
@@ -92,7 +91,7 @@ enum
RIGHTSMAX
};
-/* Capabilities */
+/* Capabilities we are interested in */
enum
{
IMAP4 = 0,
@@ -101,21 +100,10 @@ enum
ACL, /* RFC 2086: IMAP4 ACL extension */
NAMESPACE, /* RFC 2342: IMAP4 Namespace */
ACRAM_MD5, /* RFC 2195: CRAM-MD5 authentication */
- AKERBEROS_V4, /* AUTH=KERBEROS_V4 */
AGSSAPI, /* RFC 1731: GSSAPI authentication */
- /* From here down, we don't care */
- ALOGIN, /* AUTH=LOGIN */
- AUTH_LOGIN, /* AUTH-LOGIN */
- APLAIN, /* AUTH=PLAIN */
- ASKEY, /* AUTH=SKEY */
- IDLE, /* RFC 2177: IMAP4 IDLE command */
- LOGIN_REFERRALS, /* LOGIN-REFERRALS */
- MAILBOX_REFERRALS, /* MAILBOX-REFERRALS */
- SCAN,
- SORT,
- TORDEREDSUBJECT, /* THREAD=ORDEREDSUBJECT */
- UIDPLUS, /* RFC 2859: IMAP4 UIDPLUS extension */
AUTH_ANON, /* AUTH=ANONYMOUS */
+ STARTTLS, /* RFC 2595: STARTTLS */
+ LOGINDISABLED, /* LOGINDISABLED */
CAPMAX
};
@@ -149,7 +137,6 @@ typedef struct
CONNECTION *conn;
unsigned char state;
unsigned char status;
- unsigned char check_status;
unsigned char capabilities[(CAPMAX + 7)/8];
char seq[SEQLEN+1];
/* command input buffer */
@@ -169,6 +156,7 @@ typedef struct
char delim;
CONTEXT *ctx;
char *mailbox;
+ unsigned short check_status;
unsigned char reopen;
unsigned char rights[(RIGHTSMAX + 7)/8];
unsigned int newMailCount;
@@ -193,24 +181,21 @@ int imap_parse_list_response(IMAP_DATA* idata, char** name, int* noselect,
int* noinferiors, char* delim);
int imap_read_literal (FILE* fp, IMAP_DATA* idata, long bytes);
void imap_expunge_mailbox (IMAP_DATA* idata);
-int imap_reopen_mailbox (IMAP_DATA* idata);
void imap_logout (IMAP_DATA* idata);
/* auth.c */
int imap_authenticate (IMAP_DATA* idata);
/* command.c */
-void imap_cmd_start (IMAP_DATA* idata, const char* cmd);
-int imap_cmd_resp (IMAP_DATA* idata);
-void imap_cmd_finish (IMAP_DATA* idata);
+int imap_cmd_start (IMAP_DATA* idata, const char* cmd);
+int imap_cmd_step (IMAP_DATA* idata);
int imap_code (const char* s);
int imap_exec (IMAP_DATA* idata, const char* cmd, int flags);
-int imap_handle_untagged (IMAP_DATA* idata, char* s);
/* message.c */
void imap_add_keywords (char* s, HEADER* keywords, LIST* mailbox_flags);
void imap_free_header_data (void** data);
-int imap_read_headers (CONTEXT* ctx, int msgbegin, int msgend);
+int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend);
/* util.c */
int imap_continue (const char* msg, const char* resp);
diff --git a/imap/message.c b/imap/message.c
index 74c4da85..ad25e918 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -43,9 +43,9 @@ static char* msg_parse_flags (IMAP_HEADER* h, char* s);
* msgno of the last message read. It will return a value other than
* msgend if mail comes in while downloading headers (in theory).
*/
-int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
+int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend)
{
- IMAP_DATA* idata;
+ CONTEXT* ctx;
char buf[LONG_STRING];
char hdrreq[STRING];
FILE *fp;
@@ -56,8 +56,8 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
int fetchlast = 0;
const char *want_headers = "DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO REPLY-TO LINES X-LABEL";
- idata = (IMAP_DATA*) ctx->data;
-
+ ctx = idata->ctx;
+
/* define search string */
if (mutt_bit_isset (idata->capabilities,IMAP4REV1))
{
@@ -84,8 +84,8 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
unlink (tempfile);
/* make sure context has room to hold the mailbox */
- while ((msgend) >= ctx->hdrmax)
- mx_alloc_memory (ctx);
+ while ((msgend) >= idata->ctx->hdrmax)
+ mx_alloc_memory (idata->ctx);
for (msgno = msgbegin; msgno <= msgend ; msgno++)
{
@@ -123,11 +123,11 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
{
mfhrc = 0;
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
if (rc != IMAP_CMD_CONTINUE)
break;
- if ((mfhrc = msg_fetch_header (ctx, &h, idata->buf, fp)) == -1)
+ if ((mfhrc = msg_fetch_header (idata->ctx, &h, idata->buf, fp)) == -1)
continue;
else if (mfhrc < 0)
break;
@@ -175,12 +175,12 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
/* h.data shouldn't be freed here, it is kept in ctx->headers */
/* in case we get new mail while fetching the headers */
- if (idata->status == IMAP_NEW_MAIL)
+ if (idata->reopen & IMAP_NEWMAIL_PENDING)
{
msgend = idata->newMailCount - 1;
while ((msgend) >= ctx->hdrmax)
mx_alloc_memory (ctx);
- idata->status = 0;
+ idata->status &= ~IMAP_NEWMAIL_PENDING;
}
}
@@ -247,7 +247,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
imap_cmd_start (idata, buf);
do
{
- if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+ if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
pc = idata->buf;
@@ -279,7 +279,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
if (imap_read_literal (msg->fp, idata, bytes) < 0)
goto bail;
/* pick up trailing line */
- if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+ if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
goto bail;
pc = idata->buf;
@@ -423,7 +423,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
imap_cmd_start (idata, buf);
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_RESPOND)
@@ -461,7 +461,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
fclose (fp);
do
- rc = imap_cmd_resp (idata);
+ rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
if (!imap_code (idata->buf))
@@ -663,7 +663,7 @@ static int msg_fetch_header (CONTEXT* ctx, IMAP_HEADER* h, char* buf, FILE* fp)
* (eg Domino puts FLAGS here). Nothing wrong with that, either.
* This all has to go - we should accept literals and nonliterals
* interchangeably at any time. */
- if (imap_cmd_resp (idata) != IMAP_CMD_CONTINUE)
+ if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
return -2;
if (msg_parse_fetch (h, idata->buf) == -1)