diff options
author | Thomas Roessler <roessler@does-not-exist.org> | 2000-07-18 14:38:13 +0000 |
---|---|---|
committer | Thomas Roessler <roessler@does-not-exist.org> | 2000-07-18 14:38:13 +0000 |
commit | 2cfb7e3e9c4a43259f135adff59c590c3ca5e0d6 (patch) | |
tree | 925b4d162317ec0d6023ab35e5b40c526fc62c79 /imap | |
parent | 2276418fdb25e61a395967fd30cef274967baaa9 (diff) |
More IMAP clean-up from Brendan Cully.
Diffstat (limited to 'imap')
-rw-r--r-- | imap/auth.c | 33 | ||||
-rw-r--r-- | imap/auth_gss.c | 7 | ||||
-rw-r--r-- | imap/browse.c | 98 | ||||
-rw-r--r-- | imap/command.c | 130 | ||||
-rw-r--r-- | imap/imap.c | 61 | ||||
-rw-r--r-- | imap/imap_private.h | 9 | ||||
-rw-r--r-- | imap/message.c | 58 | ||||
-rw-r--r-- | imap/socket.c | 7 |
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, |