summaryrefslogtreecommitdiffstats
path: root/imap
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2000-07-18 14:38:13 +0000
committerThomas Roessler <roessler@does-not-exist.org>2000-07-18 14:38:13 +0000
commit2cfb7e3e9c4a43259f135adff59c590c3ca5e0d6 (patch)
tree925b4d162317ec0d6023ab35e5b40c526fc62c79 /imap
parent2276418fdb25e61a395967fd30cef274967baaa9 (diff)
More IMAP clean-up from Brendan Cully.
Diffstat (limited to 'imap')
-rw-r--r--imap/auth.c33
-rw-r--r--imap/auth_gss.c7
-rw-r--r--imap/browse.c98
-rw-r--r--imap/command.c130
-rw-r--r--imap/imap.c61
-rw-r--r--imap/imap_private.h9
-rw-r--r--imap/message.c58
-rw-r--r--imap/socket.c7
8 files changed, 190 insertions, 213 deletions
diff --git a/imap/auth.c b/imap/auth.c
index 0f6254d2..77f25c0d 100644
--- a/imap/auth.c
+++ b/imap/auth.c
@@ -98,13 +98,11 @@ static int imap_auth_cram_md5 (IMAP_DATA* idata, const char* user,
char ibuf[LONG_STRING], obuf[LONG_STRING];
unsigned char hmac_response[MD5_DIGEST_LEN];
int len;
- char seq[SEQLEN+1];
dprint (2, (debugfile, "Attempting CRAM-MD5 login...\n"));
mutt_message _("Authenticating (CRAM-MD5)...");
- imap_make_sequence (seq, sizeof (seq));
- snprintf (obuf, LONG_STRING, "%s AUTHENTICATE CRAM-MD5\r\n", seq);
- mutt_socket_write (idata->conn, obuf);
+
+ imap_cmd_start (idata, "AUTHENTICATE CRAM-MD5");
/* From RFC 2195:
* The data encoded in the first ready response contains a presumptively
@@ -112,7 +110,7 @@ static int imap_auth_cram_md5 (IMAP_DATA* idata, const char* user,
* primary host name of the server. The syntax of the unencoded form must
* correspond to that of an RFC 822 'msg-id' [RFC822] as described in [POP3].
*/
- if (mutt_socket_readln (ibuf, LONG_STRING, idata->conn) < 0)
+ if (mutt_socket_readln (ibuf, sizeof (ibuf), idata->conn) < 0)
{
dprint (1, (debugfile, "Error receiving server response.\n"));
@@ -184,41 +182,39 @@ static int imap_auth_cram_md5 (IMAP_DATA* idata, const char* user,
static int imap_auth_anon (IMAP_DATA* idata)
{
- char ibuf[LONG_STRING], obuf[LONG_STRING];
- char seq[SEQLEN+1];
+ char buf[LONG_STRING];
dprint (2, (debugfile, "Attempting anonymous login...\n"));
mutt_message _("Authenticating (anonymous)...");
- imap_make_sequence (seq, sizeof (seq));
- snprintf (obuf, LONG_STRING, "%s AUTHENTICATE ANONYMOUS\r\n", seq);
- mutt_socket_write (idata->conn, obuf);
- if (mutt_socket_readln (ibuf, LONG_STRING, idata->conn) < 0)
+ imap_cmd_start (idata, "AUTHENTICATE ANONYMOUS");
+
+ if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0)
{
dprint (1, (debugfile, "Error receiving server response.\n"));
return -1;
}
- if (ibuf[0] != '+')
+ if (buf[0] != '+')
{
- dprint (1, (debugfile, "Invalid response from server: %s\n", ibuf));
+ dprint (1, (debugfile, "Invalid response from server.\n"));
return -1;
}
- strfcpy (ibuf, "ZHVtbXkK\r\n", sizeof (ibuf)); /* base64 ("dummy") */
+ strfcpy (buf, "ZHVtbXkK\r\n", sizeof (buf)); /* base64 ("dummy") */
- mutt_socket_write (idata->conn, ibuf);
+ mutt_socket_write (idata->conn, buf);
- if (mutt_socket_readln (ibuf, LONG_STRING, idata->conn) < 0)
+ if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0)
{
dprint (1, (debugfile, "Error receiving server response.\n"));
return -1;
}
- if (imap_code (ibuf))
+ if (imap_code (buf))
{
dprint (2, (debugfile, "Anonymous login complete.\n"));
@@ -226,11 +222,10 @@ static int imap_auth_anon (IMAP_DATA* idata)
}
dprint (2, (debugfile, "Anonymous login failed.\n"));
+
return -1;
}
-
-
/* imap_authenticate: loop until success or user abort. At each loop, all
* supported authentication methods are tried, from strongest to weakest.
* Currently available:
diff --git a/imap/auth_gss.c b/imap/auth_gss.c
index d334a0ad..effe47dd 100644
--- a/imap/auth_gss.c
+++ b/imap/auth_gss.c
@@ -54,8 +54,6 @@ int imap_auth_gss (IMAP_DATA* idata, const char* user)
char buf1[GSS_BUFSIZE], buf2[GSS_BUFSIZE], server_conf_flags;
unsigned long buf_size;
- char seq[16];
-
dprint (2, (debugfile, "Attempting GSS login...\n"));
/* get an IMAP service ticket for the server */
@@ -81,9 +79,8 @@ int imap_auth_gss (IMAP_DATA* idata, const char* user)
#endif
/* now begin login */
mutt_message _("Authenticating (GSSAPI)...");
- imap_make_sequence (seq, sizeof (seq));
- snprintf (buf1, sizeof (buf1), "%s AUTHENTICATE GSSAPI\r\n", seq);
- mutt_socket_write (idata->conn, buf1);
+
+ imap_cmd_start (idata, "AUTHENTICATE GSSAPI");
/* expect a null continuation response ("+") */
if (mutt_socket_readln (buf1, sizeof (buf1), idata->conn) < 0)
diff --git a/imap/browse.c b/imap/browse.c
index a8676b37..f039fb9d 100644
--- a/imap/browse.c
+++ b/imap/browse.c
@@ -26,15 +26,15 @@
#include "imap_private.h"
/* -- forward declarations -- */
-static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
- struct browser_state *state, short isparent);
+static int browse_add_list_result (CONNECTION* conn, const char* cmd,
+ struct browser_state* state, short isparent);
static void imap_add_folder (char delim, char *folder, int noselect,
int noinferiors, struct browser_state *state, short isparent);
static int compare_names(struct folder_file *a, struct folder_file *b);
-static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,
+static int browse_get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,
IMAP_NAMESPACE_INFO *nsi, int nsilen, int *nns);
-static int verify_namespace (CONNECTION *conn, IMAP_NAMESPACE_INFO *nsi,
- int nns);
+static int browse_verify_namespace (IMAP_DATA* idata,
+ IMAP_NAMESPACE_INFO* nsi, int nns);
int imap_init_browse (char *path, struct browser_state *state)
{
@@ -44,7 +44,6 @@ int imap_init_browse (char *path, struct browser_state *state)
char nsbuf[LONG_STRING];
char mbox[LONG_STRING];
char list_cmd[5];
- char seq[16];
IMAP_NAMESPACE_INFO nsi[16];
int home_namespace = 0;
int n;
@@ -91,10 +90,10 @@ int imap_init_browse (char *path, struct browser_state *state)
if (mutt_bit_isset(idata->capabilities,NAMESPACE))
{
mutt_message _("Getting namespaces...");
- if (get_namespace (idata, nsbuf, sizeof (nsbuf),
+ if (browse_get_namespace (idata, nsbuf, sizeof (nsbuf),
nsi, sizeof (nsi), &nns) != 0)
return -1;
- if (verify_namespace (conn, nsi, nns) != 0)
+ if (browse_verify_namespace (idata, nsi, nns) != 0)
return -1;
}
/* What if you have a shared namespace of ""? You'll never be
@@ -135,10 +134,8 @@ int imap_init_browse (char *path, struct browser_state *state)
* aren't already going to */
if (mbox[n-1] != idata->delim)
{
- imap_make_sequence (seq, sizeof (seq));
- snprintf (buf, sizeof (buf), "%s %s \"\" \"%s\"\r\n", seq, list_cmd,
- mbox);
- mutt_socket_write (conn, buf);
+ snprintf (buf, sizeof (buf), "%s \"\" \"%s\"", list_cmd, mbox);
+ imap_cmd_start (idata, buf);
do
{
if (imap_parse_list_response(conn, buf, sizeof(buf), &cur_folder,
@@ -157,7 +154,7 @@ int imap_init_browse (char *path, struct browser_state *state)
}
}
}
- while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+ while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
}
/* if we're descending a folder, mark it as current in browser_state */
@@ -184,22 +181,13 @@ int imap_init_browse (char *path, struct browser_state *state)
* had the parent not exist? */
ctmp = mbox[n];
mbox[n] = '\0';
-#if 0
- /* List it to see if it can be selected */
- dprint (2, (debugfile, "imap_init_browse: listing possible parent %s\n", mbox));
- imap_make_sequence (seq, sizeof (seq));
- snprintf (buf, sizeof (buf), "%s %s \"\" \"%s\"\r\n", seq,
- list_cmd, mbox);
- /* add this entry as a superior, if we aren't tab-completing */
- if (showparents && add_list_result (conn, seq, buf, state, 1))
- return -1;
-#else
+
if (showparents)
{
dprint (2, (debugfile, "imap_init_browse: adding parent %s\n", mbox));
imap_add_folder (idata->delim, mbox, 1, 0, state, 1);
}
-#endif
+
/* if our target isn't a folder, we are in our superior */
if (!state->folder)
{
@@ -241,18 +229,14 @@ int imap_init_browse (char *path, struct browser_state *state)
* namespace is not "", so we have to list it explicitly. We ask the
* server to see if it has descendants. */
dprint (4, (debugfile, "imap_init_browse: adding INBOX\n"));
- imap_make_sequence (seq, sizeof (seq));
- snprintf (buf, sizeof (buf), "%s LIST \"\" \"INBOX\"\r\n", seq);
- if (add_list_result (conn, seq, buf, state, 0))
+ if (browse_add_list_result (conn, "LIST \"\" \"INBOX\"", state, 0))
return -1;
}
nsup = state->entrylen;
- imap_make_sequence (seq, sizeof (seq));
- snprintf (buf, sizeof (buf), "%s %s \"\" \"%s%%\"\r\n", seq,
- list_cmd, mbox);
- if (add_list_result (conn, seq, buf, state, 0))
+ snprintf (buf, sizeof (buf), "%s \"\" \"%s%%\"", list_cmd, mbox);
+ if (browse_add_list_result (conn, buf, state, 0))
return -1;
qsort(&(state->entry[nsup]),state->entrylen-nsup,sizeof(state->entry[0]),
@@ -272,10 +256,10 @@ int imap_init_browse (char *path, struct browser_state *state)
return 0;
}
-static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
- struct browser_state *state, short isparent)
+static int browse_add_list_result (CONNECTION* conn, const char* cmd,
+ struct browser_state* state, short isparent)
{
- IMAP_DATA *idata = CONN_DATA;
+ IMAP_DATA* idata = CONN_DATA;
char buf[LONG_STRING];
char *name;
int noselect;
@@ -285,11 +269,11 @@ static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
if (imap_parse_path (state->folder, &mx))
{
dprint (2, (debugfile,
- "add_list_result: current folder %s makes no sense\n", state->folder));
+ "browse_add_list_result: current folder %s makes no sense\n", state->folder));
return -1;
}
- mutt_socket_write (conn, cmd);
+ imap_cmd_start (idata, cmd);
do
{
@@ -308,8 +292,9 @@ static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
isparent);
}
}
- while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
- return (0);
+ while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
+
+ return 0;
}
/* imap_add_folder: add a folder name to the browser list, formatting it as
@@ -376,11 +361,10 @@ static int compare_names(struct folder_file *a, struct folder_file *b)
return mutt_strcmp(a->name, b->name);
}
-static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,
- IMAP_NAMESPACE_INFO *nsi, int nsilen, int *nns)
+static int browse_get_namespace (IMAP_DATA* idata, char* nsbuf, int nsblen,
+ IMAP_NAMESPACE_INFO* nsi, int nsilen, int* nns)
{
char buf[LONG_STRING];
- char seq[16];
char *s;
int n;
char ns[LONG_STRING];
@@ -391,10 +375,8 @@ static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,
*nns = 0;
nsbuf[nsblen-1] = '\0';
- imap_make_sequence (seq, sizeof (seq));
- snprintf (buf, sizeof (buf), "%s NAMESPACE\r\n", seq);
-
- mutt_socket_write (idata->conn, buf);
+ imap_cmd_start (idata, "NAMESPACE");
+
do
{
if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0)
@@ -452,7 +434,7 @@ static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,
/* skip "" namespaces, they are already listed at the root */
if ((ns[0] != '\0') && (nsbused < nsblen) && (*nns < nsilen))
{
- dprint (4, (debugfile, "get_namespace: adding %s\n", ns));
+ dprint (3, (debugfile, "browse_get_namespace: adding %s\n", ns));
nsi->type = type;
/* Cyrus doesn't append the delimiter to the namespace,
* but UW-IMAP does. We'll strip it here and add it back
@@ -479,47 +461,47 @@ static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,
}
}
}
- while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+ while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
+
return 0;
}
/* Check which namespaces have contents */
-static int verify_namespace (CONNECTION *conn, IMAP_NAMESPACE_INFO *nsi,
- int nns)
+static int browse_verify_namespace (IMAP_DATA* idata,
+ IMAP_NAMESPACE_INFO *nsi, int nns)
{
char buf[LONG_STRING];
- char seq[16];
int i = 0;
char *name;
char delim;
for (i = 0; i < nns; i++, nsi++)
{
- imap_make_sequence (seq, sizeof (seq));
/* Cyrus gives back nothing if the % isn't added. This may return lots
* of data in some cases, I guess, but I currently feel that's better
* than invisible namespaces */
if (nsi->delim)
- snprintf (buf, sizeof (buf), "%s %s \"\" \"%s%c%%\"\r\n", seq,
+ snprintf (buf, sizeof (buf), "%s \"\" \"%s%c%%\"",
option (OPTIMAPLSUB) ? "LSUB" : "LIST", nsi->prefix,
nsi->delim);
else
- snprintf (buf, sizeof (buf), "%s %s \"\" \"%s%%\"\r\n", seq,
+ snprintf (buf, sizeof (buf), "%s \"\" \"%s%%\"",
option (OPTIMAPLSUB) ? "LSUB" : "LIST", nsi->prefix);
-
- mutt_socket_write (conn, buf);
+
+ imap_cmd_start (idata, buf);
nsi->listable = 0;
nsi->home_namespace = 0;
do
{
- if (imap_parse_list_response(conn, buf, sizeof(buf), &name,
+ if (imap_parse_list_response(idata->conn, buf, sizeof(buf), &name,
&(nsi->noselect), &(nsi->noinferiors), &delim) != 0)
return -1;
nsi->listable |= (name != NULL);
}
- while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+ while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
}
- return (0);
+
+ return 0;
}
diff --git a/imap/command.c b/imap/command.c
index 722b3973..0a534fe6 100644
--- a/imap/command.c
+++ b/imap/command.c
@@ -29,7 +29,9 @@
#include <stdlib.h>
/* forward declarations */
+static void cmd_make_sequence (char* buf, size_t buflen);
static void cmd_parse_capabilities (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",
@@ -37,10 +39,29 @@ static char *Capabilities[] = {"IMAP4", "IMAP4rev1", "STATUS", "ACL",
"LOGIN-REFERRALS", "MAILBOX-REFERRALS", "QUOTA", "SCAN", "SORT",
"THREAD=ORDEREDSUBJECT", "UIDPLUS", "AUTH=ANONYMOUS", 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)
+{
+ char* out;
+ int outlen;
+
+ cmd_make_sequence (idata->seq, sizeof (idata->seq));
+ /* seq, space, cmd, \r\n\0 */
+ outlen = strlen (idata->seq) + strlen (cmd) + 4;
+ out = (char*) safe_malloc (outlen);
+ snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd);
+
+ mutt_socket_write (idata->conn, out);
+
+ safe_free ((void**) &out);
+}
+
/* 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 (const char* seq, IMAP_DATA* idata)
+void imap_cmd_finish (IMAP_DATA* idata)
{
if (!(idata->state == IMAP_SELECTED) || idata->selected_ctx->closing)
{
@@ -63,9 +84,6 @@ void imap_cmd_finish (const char* seq, IMAP_DATA* idata)
/* read new mail messages */
dprint (1, (debugfile, "imap_cmd_finish: fetching new mail\n"));
- while (count > idata->selected_ctx->hdrmax)
- mx_alloc_memory (idata->selected_ctx);
-
count = imap_read_headers (idata->selected_ctx,
idata->selected_ctx->msgcount, count - 1) + 1;
idata->check_status = IMAP_NEW_MAIL;
@@ -113,14 +131,13 @@ int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd,
{
char* out;
int outlen;
- char seq[SEQLEN+1];
/* create sequence for command */
- imap_make_sequence (seq, sizeof (seq));
+ cmd_make_sequence (idata->seq, sizeof (idata->seq));
/* seq, space, cmd, \r\n\0 */
- outlen = strlen (seq) + strlen (cmd) + 4;
+ outlen = strlen (idata->seq) + strlen (cmd) + 4;
out = (char*) safe_malloc (outlen);
- snprintf (out, outlen, "%s %s\r\n", seq, cmd);
+ snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd);
mutt_socket_write_d (idata->conn, out,
flags & IMAP_CMD_PASS ? IMAP_LOG_PASS : IMAP_LOG_CMD);
@@ -135,9 +152,9 @@ int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd,
if (buf[0] == '*' && imap_handle_untagged (idata, buf) != 0)
return -1;
}
- while (mutt_strncmp (buf, seq, SEQLEN) != 0);
+ while (mutt_strncmp (buf, idata->seq, SEQLEN) != 0);
- imap_cmd_finish (seq, idata);
+ imap_cmd_finish (idata);
if (!imap_code (buf))
{
@@ -212,47 +229,9 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
idata->status = IMAP_EXPUNGE;
}
else if (mutt_strncasecmp ("CAPABILITY", s, 10) == 0)
- /* parse capabilities */
cmd_parse_capabilities (idata, s);
else if (mutt_strncasecmp ("MYRIGHTS", s, 8) == 0)
- {
- s = imap_next_word (s);
- s = imap_next_word (s);
- while (*s && !isspace(*s))
- {
- switch (*s)
- {
- case 'l':
- mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP);
- break;
- case 'r':
- mutt_bit_set (idata->rights, IMAP_ACL_READ);
- break;
- case 's':
- mutt_bit_set (idata->rights, IMAP_ACL_SEEN);
- break;
- case 'w':
- mutt_bit_set (idata->rights, IMAP_ACL_WRITE);
- break;
- case 'i':
- mutt_bit_set (idata->rights, IMAP_ACL_INSERT);
- break;
- case 'p':
- mutt_bit_set (idata->rights, IMAP_ACL_POST);
- break;
- case 'c':
- mutt_bit_set (idata->rights, IMAP_ACL_CREATE);
- break;
- case 'd':
- mutt_bit_set (idata->rights, IMAP_ACL_DELETE);
- break;
- case 'a':
- mutt_bit_set (idata->rights, IMAP_ACL_ADMIN);
- break;
- }
- s++;
- }
- }
+ cmd_parse_myrights (idata, s);
else if (mutt_strncasecmp ("BYE", s, 3) == 0)
{
/* server shut down our connection */
@@ -274,16 +253,14 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
sleep (1);
}
else
- {
dprint (1, (debugfile, "imap_handle_untagged(): unhandled request: %s\n",
- s));
- }
+ s));
return 0;
}
-/* imap_make_sequence: make a tag suitable for starting an IMAP command */
-void imap_make_sequence (char *buf, size_t buflen)
+/* cmd_make_sequence: make a tag suitable for starting an IMAP command */
+static void cmd_make_sequence (char* buf, size_t buflen)
{
static int sequence = 0;
@@ -310,3 +287,48 @@ static void cmd_parse_capabilities (IMAP_DATA *idata, char *s)
s = imap_next_word (s);
}
}
+
+/* cmd_parse_myrights: set rights bits according to MYRIGHTS response */
+static void cmd_parse_myrights (IMAP_DATA* idata, char* s)
+{
+ s = imap_next_word (s);
+ s = imap_next_word (s);
+
+ /* zero out current rights set */
+ memset (idata->rights, 0, sizeof (idata->rights));
+
+ while (*s && !isspace(*s))
+ {
+ switch (*s)
+ {
+ case 'l':
+ mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP);
+ break;
+ case 'r':
+ mutt_bit_set (idata->rights, IMAP_ACL_READ);
+ break;
+ case 's':
+ mutt_bit_set (idata->rights, IMAP_ACL_SEEN);
+ break;
+ case 'w':
+ mutt_bit_set (idata->rights, IMAP_ACL_WRITE);
+ break;
+ case 'i':
+ mutt_bit_set (idata->rights, IMAP_ACL_INSERT);
+ break;
+ case 'p':
+ mutt_bit_set (idata->rights, IMAP_ACL_POST);
+ break;
+ case 'c':
+ mutt_bit_set (idata->rights, IMAP_ACL_CREATE);
+ break;
+ case 'd':
+ mutt_bit_set (idata->rights, IMAP_ACL_DELETE);
+ break;
+ case 'a':
+ mutt_bit_set (idata->rights, IMAP_ACL_ADMIN);
+ break;
+ }
+ s++;
+ }
+}
diff --git a/imap/imap.c b/imap/imap.c
index dd73f031..e446d03b 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -172,7 +172,6 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint)
int old_msgcount;
char buf[LONG_STRING];
char bufout[LONG_STRING];
- char seq[8];
char *pc = NULL;
int count = 0;
int msg_mod = 0;
@@ -227,9 +226,9 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint)
mutt_message (_("Reopening mailbox... %s"), CTX_DATA->selected_mailbox);
imap_munge_mbox_name (buf, sizeof (buf), CTX_DATA->selected_mailbox);
- imap_make_sequence (seq, sizeof (seq));
- snprintf (bufout, sizeof (bufout), "%s STATUS %s (MESSAGES)\r\n", seq, buf);
- mutt_socket_write (CTX_DATA->conn, bufout);
+ snprintf (bufout, sizeof (bufout), "STATUS %s (MESSAGES)", buf);
+
+ imap_cmd_start (CTX_DATA, bufout);
do
{
@@ -260,7 +259,7 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint)
return -1;
}
}
- while (mutt_strncmp (seq, buf, mutt_strlen (seq)) != 0);
+ while (mutt_strncmp (CTX_DATA->seq, buf, mutt_strlen (CTX_DATA->seq)) != 0);
if (!imap_code (buf))
{
@@ -360,17 +359,13 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint)
static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn)
{
char buf[LONG_STRING];
- char seq[8];
char *s;
/* assume that the delim is /. If this fails, we're in bigger trouble
* than getting the delim wrong */
idata->delim = '/';
- imap_make_sequence (seq, sizeof (seq));
- snprintf (buf, sizeof (buf), "%s LIST \"\" \"\"\r\n", seq);
-
- mutt_socket_write (conn, buf);
+ imap_cmd_start (idata, "LIST \"\" \"\"");
do
{
@@ -399,7 +394,7 @@ static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn)
}
}
}
- while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+ while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
return 0;
}
@@ -551,7 +546,6 @@ int imap_open_mailbox (CONTEXT *ctx)
IMAP_DATA *idata;
char buf[LONG_STRING];
char bufout[LONG_STRING];
- char seq[SEQLEN+1];
int count = 0;
int n;
IMAP_MBOX mx;
@@ -600,10 +594,10 @@ int imap_open_mailbox (CONTEXT *ctx)
mutt_message (_("Selecting %s..."), idata->selected_mailbox);
imap_munge_mbox_name (buf, sizeof(buf), idata->selected_mailbox);
- imap_make_sequence (seq, sizeof (seq));
- snprintf (bufout, sizeof (bufout), "%s %s %s\r\n", seq,
+ snprintf (bufout, sizeof (bufout), "%s %s",
ctx->readonly ? "EXAMINE" : "SELECT", buf);
- mutt_socket_write (conn, bufout);
+
+ imap_cmd_start (idata, bufout);
idata->state = IMAP_SELECTED;
@@ -658,7 +652,7 @@ int imap_open_mailbox (CONTEXT *ctx)
return (-1);
}
}
- while (mutt_strncmp (seq, buf, mutt_strlen (seq)) != 0);
+ while (mutt_strncmp (idata->seq, buf, mutt_strlen (idata->seq)) != 0);
/* check for READ-ONLY notification */
if (!strncmp (imap_get_qualifier (buf), "[READ-ONLY]", 11))
{
@@ -836,20 +830,18 @@ int imap_open_mailbox_append (CONTEXT *ctx)
return 0;
}
-void imap_logout (CONNECTION *conn)
+void imap_logout (IMAP_DATA* idata)
{
char buf[LONG_STRING];
- char seq[8];
- imap_make_sequence (seq, sizeof (seq));
- snprintf (buf, sizeof (buf), "%s LOGOUT\r\n", seq);
- mutt_socket_write (conn, buf);
+ imap_cmd_start (idata, "LOGOUT");
+
do
{
- if (mutt_socket_readln (buf, sizeof (buf), conn) < 0)
+ if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0)
break;
}
- while (mutt_strncmp (seq, buf, SEQLEN) != 0);
+ while (mutt_strncmp (idata->seq, buf, SEQLEN) != 0);
}
int imap_close_connection (CONTEXT *ctx)
@@ -859,7 +851,7 @@ int imap_close_connection (CONTEXT *ctx)
if (CTX_DATA->status != IMAP_BYE)
{
mutt_message _("Closing connection to IMAP server...");
- imap_logout (CTX_DATA->conn);
+ imap_logout (CTX_DATA);
mutt_clear_error ();
}
mutt_socket_close (CTX_DATA->conn);
@@ -1209,7 +1201,6 @@ int imap_mailbox_check (char *path, int new)
char buf[LONG_STRING];
char mbox[LONG_STRING];
char mbox_unquoted[LONG_STRING];
- char seq[8];
char *s;
int msgcount = 0;
IMAP_MBOX mx;
@@ -1242,7 +1233,6 @@ int imap_mailbox_check (char *path, int new)
if (strlen (buf) < strlen (mx.mbox))
strcpy (mx.mbox, buf);
- imap_make_sequence (seq, sizeof (seq));
imap_munge_mbox_name (mbox, sizeof(mbox), buf);
strfcpy (mbox_unquoted, buf, sizeof (mbox_unquoted));
@@ -1254,12 +1244,12 @@ int imap_mailbox_check (char *path, int new)
|| (mutt_strcasecmp (mbox_unquoted, "INBOX") == 0
&& mutt_strcasecmp (mbox_unquoted, idata->selected_mailbox) == 0))
{
- snprintf (buf, sizeof (buf), "%s NOOP\r\n", seq);
+ strfcpy (buf, "NOOP", sizeof (buf));
}
else if (mutt_bit_isset(idata->capabilities,IMAP4REV1) ||
mutt_bit_isset(idata->capabilities,STATUS))
{
- snprintf (buf, sizeof (buf), "%s STATUS %s (%s)\r\n", seq, mbox,
+ snprintf (buf, sizeof (buf), "STATUS %s (%s)", mbox,
new ? "RECENT" : "MESSAGES");
}
else
@@ -1269,7 +1259,7 @@ int imap_mailbox_check (char *path, int new)
return -1;
}
- mutt_socket_write (conn, buf);
+ imap_cmd_start (idata, buf);
do
{
@@ -1304,9 +1294,9 @@ int imap_mailbox_check (char *path, int new)
}
}
}
- while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+ while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
- imap_cmd_finish (seq, idata);
+ imap_cmd_finish (idata);
return msgcount;
}
@@ -1436,7 +1426,6 @@ int imap_complete(char* dest, size_t dlen, char* path) {
IMAP_DATA* idata;
char list[LONG_STRING];
char buf[LONG_STRING];
- char seq[16];
char* list_word = NULL;
int noselect, noinferiors;
char delim;
@@ -1472,10 +1461,10 @@ int imap_complete(char* dest, size_t dlen, char* path) {
list[0] = '\0';
/* fire off command */
- imap_make_sequence (seq, sizeof(seq));
- snprintf (buf, sizeof(buf), "%s %s \"\" \"%s%%\"\r\n", seq,
+ snprintf (buf, sizeof(buf), "%s \"\" \"%s%%\"",
option (OPTIMAPLSUB) ? "LSUB" : "LIST", list);
- mutt_socket_write (conn, buf);
+
+ imap_cmd_start (idata, buf);
/* and see what the results are */
strfcpy (completion, mx.mbox, sizeof(completion));
@@ -1517,7 +1506,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
completions++;
}
}
- while (mutt_strncmp(seq, buf, strlen(seq)));
+ while (mutt_strncmp(idata->seq, buf, SEQLEN));
if (completions)
{
diff --git a/imap/imap_private.h b/imap/imap_private.h
index 0923966e..ea55e25b 100644
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -147,11 +147,12 @@ typedef struct
short status;
short state;
short check_status;
- char delim;
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;
unsigned char rights[(RIGHTSMAX + 7)/8];
@@ -177,18 +178,18 @@ int imap_parse_list_response(CONNECTION* conn, char* buf, int buflen,
char** name, int* noselect, int* noinferiors, char* delim);
int imap_read_literal (FILE* fp, CONNECTION* conn, long bytes);
int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint);
-void imap_logout (CONNECTION* conn);
+void imap_logout (IMAP_DATA* conn);
/* auth.c */
int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn);
/* command.c */
-void imap_cmd_finish (const char* seq, IMAP_DATA* idata);
+void imap_cmd_start (IMAP_DATA* idata, const char* cmd);
+void imap_cmd_finish (IMAP_DATA* idata);
int imap_code (const char* s);
int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd,
int flags);
int imap_handle_untagged (IMAP_DATA* idata, char* s);
-void imap_make_sequence (char *buf, size_t buflen);
/* message.c */
void imap_add_keywords (char* s, HEADER* keywords, LIST* mailbox_flags);
diff --git a/imap/message.c b/imap/message.c
index 6c1b2fca..72574b4d 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -50,7 +50,6 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
char hdrreq[STRING];
FILE *fp;
char tempfile[_POSIX_PATH_MAX];
- char seq[SEQLEN+1];
int msgno;
IMAP_HEADER* h;
int rc;
@@ -93,7 +92,6 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
if (msgno + 1 > fetchlast)
{
- imap_make_sequence (seq, sizeof (seq));
/*
* Make one request for everything. This makes fetching headers an
* order of magnitude faster if you have a large mailbox.
@@ -101,11 +99,12 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
* If we get more messages while doing this, we make another
* request for all the new messages.
*/
- snprintf (buf, sizeof (buf),
- "%s FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)\r\n",
- seq, msgno + 1, msgend + 1, hdrreq);
+ snprintf (buf, sizeof (buf),
+ "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgno + 1,
+ msgend + 1, hdrreq);
+
+ imap_cmd_start (CTX_DATA, buf);
- mutt_socket_write (CTX_DATA->conn, buf);
fetchlast = msgend + 1;
}
@@ -165,7 +164,8 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
safe_free ((void**) &h);
}
}
- while ((msgno + 1) >= fetchlast && mutt_strncmp (seq, buf, SEQLEN) != 0);
+ while ((msgno + 1) >= fetchlast && mutt_strncmp (CTX_DATA->seq, buf,
+ SEQLEN) != 0);
/* in case we get new mail while fetching the headers */
if (CTX_DATA->status == IMAP_NEW_MAIL)
@@ -184,11 +184,11 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
{
- char seq[SEQLEN+1];
char buf[LONG_STRING];
char path[_POSIX_PATH_MAX];
char *pc;
long bytes;
+ int uid;
IMAP_CACHE *cache;
/* see if we already have the message in our cache */
@@ -221,19 +221,14 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
cache->path = safe_strdup (path);
if (!(msg->fp = safe_fopen (path, "w+")))
{
- safe_free ((void **) &cache->path);
- return (-1);
+ safe_free ((void**) &cache->path);
+ return -1;
}
- imap_make_sequence (seq, sizeof (seq));
-#if 0
- snprintf (buf, sizeof (buf), "%s FETCH %d RFC822\r\n", seq,
- ctx->hdrs[msgno]->index + 1);
-#else
- snprintf (buf, sizeof (buf), "%s UID FETCH %d RFC822\r\n", seq,
- HEADER_DATA(ctx->hdrs[msgno])->uid);
-#endif
- mutt_socket_write (CTX_DATA->conn, buf);
+ snprintf (buf, sizeof (buf), "UID FETCH %d RFC822",
+ HEADER_DATA(ctx->hdrs[msgno])->uid);
+
+ imap_cmd_start (CTX_DATA, buf);
do
{
if (mutt_socket_readln (buf, sizeof (buf), CTX_DATA->conn) < 0)
@@ -251,8 +246,14 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
pc = imap_next_word (pc);
if (pc[0] == '(')
pc++;
- dprint (2, (debugfile, "Found FETCH word %s\n", pc));
- if (strncasecmp ("RFC822", pc, 6) == 0)
+ if (strncasecmp ("UID", pc, 3) == 0)
+ {
+ pc = imap_next_word (pc);
+ uid = atoi (pc);
+ if (uid != HEADER_DATA(ctx->hdrs[msgno])->uid)
+ mutt_error (_("The message index is incorrect. Try reopening the mailbox."));
+ }
+ else if (strncasecmp ("RFC822", pc, 6) == 0)
{
pc = imap_next_word (pc);
if (imap_get_literal_count(pc, &bytes) < 0)
@@ -321,12 +322,11 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
goto bail;
}
}
- while (mutt_strncmp (buf, seq, SEQLEN) != 0);
+ while (mutt_strncmp (buf, CTX_DATA->seq, SEQLEN) != 0);
if (!imap_code (buf))
goto bail;
-
/* Update the header information. Previously, we only downloaded a
* portion of the headers, those required for the main display.
*/
@@ -371,7 +371,6 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
char buf[LONG_STRING];
char mbox[LONG_STRING];
char mailbox[LONG_STRING];
- char seq[16];
size_t len;
int c, last;
IMAP_MBOX mx;
@@ -396,13 +395,10 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
}
rewind (fp);
- mutt_message _("Sending APPEND command ...");
-
imap_munge_mbox_name (mbox, sizeof (mbox), mailbox);
- imap_make_sequence (seq, sizeof (seq));
- snprintf (buf, sizeof (buf), "%s APPEND %s {%d}\r\n", seq, mbox, len);
+ snprintf (buf, sizeof (buf), "APPEND %s {%d}", mbox, len);
- mutt_socket_write (CTX_DATA->conn, buf);
+ imap_cmd_start (CTX_DATA, buf);
do
{
@@ -418,7 +414,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
return (-1);
}
}
- while ((mutt_strncmp (buf, seq, SEQLEN) != 0) && (buf[0] != '+'));
+ while ((mutt_strncmp (buf, CTX_DATA->seq, SEQLEN) != 0) && (buf[0] != '+'));
if (buf[0] != '+')
{
@@ -462,7 +458,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
if (buf[0] == '*' && imap_handle_untagged (CTX_DATA, buf) != 0)
return (-1);
}
- while (mutt_strncmp (buf, seq, SEQLEN) != 0);
+ while (mutt_strncmp (buf, CTX_DATA->seq, SEQLEN) != 0);
if (!imap_code (buf))
{
diff --git a/imap/socket.c b/imap/socket.c
index 2d8c93da..b70fc698 100644
--- a/imap/socket.c
+++ b/imap/socket.c
@@ -167,7 +167,7 @@ void imap_logout_all (void)
mutt_message (_("Closing connection to %s..."),
conn->mx.host);
- imap_logout (conn);
+ imap_logout (CONN_DATA);
mutt_clear_error ();
@@ -176,11 +176,6 @@ void imap_logout_all (void)
Connections = conn->next;
- if (conn->data) {
- dprint (2,