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
* 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"));
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"));
}
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:
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 */
#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)
#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)
{
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;
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
* 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,
}
}
}
- 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 */
* 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)
{
* 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]),
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;
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
{
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
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];
*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)
/* 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
}
}
}
- 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;
}
#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",
"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)
{
/* 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;
{
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);
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))
{
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 */
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;
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++;
+ }
+}
int old_msgcount;
char buf[LONG_STRING];
char bufout[LONG_STRING];
- char seq[8];
char *pc = NULL;
int count = 0;
int msg_mod = 0;
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
{
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))
{
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
{
}
}
}
- while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+ while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
return 0;
}
IMAP_DATA *idata;
char buf[LONG_STRING];
char bufout[LONG_STRING];
- char seq[SEQLEN+1];
int count = 0;
int n;
IMAP_MBOX mx;
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;
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))
{
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)
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);
char buf[LONG_STRING];
char mbox[LONG_STRING];
char mbox_unquoted[LONG_STRING];
- char seq[8];
char *s;
int msgcount = 0;
IMAP_MBOX mx;
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));
|| (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
return -1;
}
- mutt_socket_write (conn, buf);
+ imap_cmd_start (idata, buf);
do
{
}
}
}
- 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;
}
IMAP_DATA* idata;
char list[LONG_STRING];
char buf[LONG_STRING];
- char seq[16];
char* list_word = NULL;
int noselect, noinferiors;
char delim;
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));
completions++;
}
}
- while (mutt_strncmp(seq, buf, strlen(seq)));
+ while (mutt_strncmp(idata->seq, buf, SEQLEN));
if (completions)
{
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];
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);
char hdrreq[STRING];
FILE *fp;
char tempfile[_POSIX_PATH_MAX];
- char seq[SEQLEN+1];
int msgno;
IMAP_HEADER* h;
int rc;
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.
* 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;
}
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)
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 */
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)
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)
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.
*/
char buf[LONG_STRING];
char mbox[LONG_STRING];
char mailbox[LONG_STRING];
- char seq[16];
size_t len;
int c, last;
IMAP_MBOX mx;
}
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
{
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] != '+')
{
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))
{
mutt_message (_("Closing connection to %s..."),
conn->mx.host);
- imap_logout (conn);
+ imap_logout (CONN_DATA);
mutt_clear_error ();
Connections = conn->next;
- if (conn->data) {
- dprint (2, (debugfile,
- "imap_logout_all: Connection still has valid CONTEXT?!\n"));
- }
-
free (conn);
conn = Connections;