X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=imap%2Fimap.c;h=83bb6da48070788ffae24b7bdd1af54332e986d6;hp=48f1dc4cc1c5ee46bdd97b4572599be8496d92f8;hb=98f62b5fcbd680fd5214ee85e1635b84322cbdd1;hpb=05a3bbbe420e4afc76e0eea24ce32f859405dc4a diff --git a/imap/imap.c b/imap/imap.c index 48f1dc4..83bb6da 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -11,40 +11,20 @@ /* Support for IMAP4rev1, with the occasional nod to IMAP 4. */ -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include +#include +#include #include "mutt.h" -#include "mx.h" #include "globals.h" +#include "pattern.h" #include "sort.h" -#include "browser.h" #include "message.h" #include "imap_private.h" -#if defined(USE_SSL) || defined(USE_GNUTLS) -# include -#endif #include "buffy.h" -#include - -#include -#include -#include -#include -#include -#include - /* imap forward declarations */ static int imap_get_delim (IMAP_DATA * idata); -static char *imap_get_flags (LIST ** hflags, char *s); +static char *imap_get_flags (string_list_t ** hflags, char *s); static int imap_check_acl (IMAP_DATA * idata); static int imap_check_capabilities (IMAP_DATA * idata); static void imap_set_flag (IMAP_DATA * idata, int aclbit, int flag, @@ -53,7 +33,7 @@ static void imap_set_flag (IMAP_DATA * idata, int aclbit, int flag, /* imap_access: Check permissions on an IMAP mailbox. * TODO: ACL checks. Right now we assume if it exists we can * mess with it. */ -int imap_access (const char *path, int flags) +static int imap_access (const char *path, int flags __attribute__ ((unused))) { IMAP_DATA *idata; IMAP_MBOX mx; @@ -74,7 +54,7 @@ int imap_access (const char *path, int flags) imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox)); /* we may already be in the folder we're checking */ - if (!ascii_strcmp(idata->mailbox, mx.mbox)) { + if (!m_strcmp(idata->mailbox, mx.mbox)) { p_delete(&mx.mbox); return 0; } @@ -87,12 +67,10 @@ int imap_access (const char *path, int flags) else if (mutt_bit_isset (idata->capabilities, STATUS)) snprintf (buf, sizeof (buf), "STATUS %s (UID-VALIDITY)", mbox); else { - debug_print (2, ("STATUS not supported?\n")); return -1; } if (imap_exec (idata, buf, IMAP_CMD_FAIL_OK) < 0) { - debug_print (1, ("Can't check STATUS of %s\n", mbox)); return -1; } @@ -190,17 +168,13 @@ int imap_read_literal (FILE * fp, IMAP_DATA * idata, long bytes, progress_t* bar int r = 0; - debug_print (2, ("reading %ld bytes\n", bytes)); - for (pos = 0; pos < bytes; pos++) { if (mutt_socket_readchar (idata->conn, &c) != 1) { - debug_print (1, ("error during read, %ld bytes read\n", pos)); idata->status = IMAP_FATAL; return -1; } -#if 1 if (r == 1 && c != '\n') fputc ('\r', fp); @@ -210,14 +184,10 @@ int imap_read_literal (FILE * fp, IMAP_DATA * idata, long bytes, progress_t* bar } else r = 0; -#endif + fputc (c, fp); if (bar && !(pos % 1024)) mutt_progress_bar (bar, pos); -#ifdef DEBUG - if (DebugFile && DebugLevel >= IMAP_LOG_LTRL) - fputc (c, DebugFile); -#endif } return 0; @@ -235,8 +205,6 @@ void imap_expunge_mailbox (IMAP_DATA * idata) h = idata->ctx->hdrs[i]; if (h->index == -1) { - debug_print (2, ("Expunging message UID %d.\n", HEADER_DATA (h)->uid)); - h->active = 0; /* free cached body from disk, if neccessary */ @@ -272,7 +240,7 @@ static int imap_get_delim (IMAP_DATA * idata) if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE) break; - s = imap_next_word (idata->cmd.buf); + s = imap_next_word (idata->cmd.buf.data); if (ascii_strncasecmp ("LIST", s, 4) == 0) { s = imap_next_word (s); s = imap_next_word (s); @@ -285,13 +253,6 @@ static int imap_get_delim (IMAP_DATA * idata) } while (rc == IMAP_CMD_CONTINUE); - if (rc != IMAP_CMD_OK) { - debug_print (1, ("failed.\n")); - return -1; - } - - debug_print (2, ("Delimiter: %c\n", idata->delim)); - return -1; } @@ -314,7 +275,7 @@ static int imap_check_acl (IMAP_DATA * idata) static int imap_check_capabilities (IMAP_DATA * idata) { if (imap_exec (idata, "CAPABILITY", 0) != 0) { - imap_error ("imap_check_capabilities", idata->cmd.buf); + imap_error ("imap_check_capabilities", idata->cmd.buf.data); return -1; } @@ -337,7 +298,6 @@ IMAP_DATA *imap_conn_find (const ACCOUNT * account, int flags) CONNECTION *conn; IMAP_DATA *idata; ACCOUNT *creds; - int new = 0; if (!(conn = mutt_conn_find (NULL, account))) return NULL; @@ -367,35 +327,31 @@ IMAP_DATA *imap_conn_find (const ACCOUNT * account, int flags) if (!idata) { /* The current connection is a new connection */ - if (!(idata = imap_new_idata ())) { - mutt_socket_free (conn); - return NULL; - } - - conn->data = idata; + idata = imap_new_idata(); + conn->data = idata; idata->conn = conn; - new = 1; } if (idata->state == IMAP_DISCONNECTED) imap_open_connection (idata); if (idata->state == IMAP_CONNECTED) { - if (!imap_authenticate (idata)) { + if (!imap_authenticate(idata)) { idata->state = IMAP_AUTHENTICATED; - if (idata->conn->ssf) - debug_print (2, ("Communication encrypted at %d bits\n", idata->conn->ssf)); + } else { + mutt_socket_close(idata->conn); + idata->state = IMAP_DISCONNECTED; + idata->conn->account.has_pass = 0; } - else - mutt_account_unsetpass (&idata->conn->account); p_delete(&idata->capstr); } - if (new && idata->state == IMAP_AUTHENTICATED) { + if (idata->isnew && idata->state == IMAP_AUTHENTICATED) { imap_get_delim (idata); if (option (OPTIMAPCHECKSUBSCRIBED)) { mutt_message _("Checking mailbox subscriptions"); imap_exec (idata, "LSUB \"\" \"*\"", 0); } + idata->isnew = 0; } return idata; @@ -416,34 +372,26 @@ int imap_open_connection (IMAP_DATA * idata) return -1; } - if (ascii_strncasecmp ("* OK", idata->cmd.buf, 4) == 0) { + if (ascii_strncasecmp ("* OK", idata->cmd.buf.data, 4) == 0) { /* TODO: Parse new tagged CAPABILITY data (* OK [CAPABILITY...]) */ if (imap_check_capabilities (idata)) goto bail; -#if defined(USE_SSL) || defined(USE_GNUTLS) /* Attempt STARTTLS if available and desired. */ - if (!idata->conn->ssf && (option(OPTSSLFORCETLS) || + if (!idata->conn->ssf && (mod_ssl.force_tls || mutt_bit_isset (idata->capabilities, STARTTLS))) { int rc; - if (option (OPTSSLFORCETLS)) + if (mod_ssl.force_tls) rc = M_YES; - else if ((rc = query_quadoption (OPT_SSLSTARTTLS, - _("Secure connection with TLS?"))) == -1) - goto err_close_conn; - if (rc == M_YES) { + else { if ((rc = imap_exec (idata, "STARTTLS", IMAP_CMD_FAIL_OK)) == -1) goto bail; if (rc != -2) { -#if defined (USE_SSL) || defined (USE_GNUTLS) - if (mutt_ssl_starttls (idata->conn)) -#endif - { + if (mutt_ssl_starttls (idata->conn)) { mutt_error (_("Could not negotiate TLS connection")); mutt_sleep (1); goto err_close_conn; - } - else { + } else { /* RFC 2595 demands we recheck CAPABILITY after TLS completes. */ if (imap_exec (idata, "CAPABILITY", 0)) goto bail; @@ -452,14 +400,13 @@ int imap_open_connection (IMAP_DATA * idata) } } - if (option(OPTSSLFORCETLS) && ! idata->conn->ssf) { + if (mod_ssl.force_tls && ! idata->conn->ssf) { mutt_error _("Encrypted connection unavailable"); mutt_sleep (1); goto err_close_conn; } -#endif } - else if (ascii_strncasecmp ("* PREAUTH", idata->cmd.buf, 9) == 0) { + else if (ascii_strncasecmp ("* PREAUTH", idata->cmd.buf.data, 9) == 0) { idata->state = IMAP_AUTHENTICATED; if (imap_check_capabilities (idata) != 0) goto bail; @@ -482,25 +429,23 @@ bail: /* imap_get_flags: Make a simple list out of a FLAGS response. * return stream following FLAGS response */ -static char *imap_get_flags (LIST ** hflags, char *s) +static char *imap_get_flags (string_list_t ** hflags, char *s) { - LIST *flags; + string_list_t *flags; char *flag_word; char ctmp; /* sanity-check string */ if (ascii_strncasecmp ("FLAGS", s, 5) != 0) { - debug_print (1, ("not a FLAGS response: %s\n", s)); return NULL; } s = vskipspaces(s + 5); if (*s != '(') { - debug_print (1, ("bogus FLAGS response: %s\n", s)); return NULL; } /* create list, update caller's flags handle */ - flags = mutt_new_list (); + flags = string_item_new(); *hflags = flags; while (*s && *s != ')') { @@ -517,8 +462,7 @@ static char *imap_get_flags (LIST ** hflags, char *s) /* note bad flags response */ if (*s != ')') { - debug_print (1, ("Unterminated FLAGS response: %s\n", s)); - mutt_free_list (hflags); + string_list_wipe(hflags); return NULL; } @@ -528,7 +472,7 @@ static char *imap_get_flags (LIST ** hflags, char *s) return s; } -int imap_open_mailbox (CONTEXT * ctx) +static int imap_open_mailbox (CONTEXT * ctx) { CONNECTION *conn; IMAP_DATA *idata; @@ -585,23 +529,21 @@ int imap_open_mailbox (CONTEXT * ctx) if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE) break; - pc = idata->cmd.buf + 2; + pc = idata->cmd.buf.data + 2; /* Obtain list of available flags here, may be overridden by a * PERMANENTFLAGS tag in the OK response */ if (ascii_strncasecmp ("FLAGS", pc, 5) == 0) { /* don't override PERMANENTFLAGS */ if (!idata->flags) { - debug_print (2, ("Getting mailbox FLAGS\n")); if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL) goto fail; } } /* PERMANENTFLAGS are massaged to look like FLAGS, then override FLAGS */ else if (ascii_strncasecmp ("OK [PERMANENTFLAGS", pc, 18) == 0) { - debug_print (2, ("Getting mailbox PERMANENTFLAGS\n")); /* safe to call on NULL */ - mutt_free_list (&(idata->flags)); + string_list_wipe(&(idata->flags)); /* skip "OK [PERMANENT" so syntax is the same as FLAGS */ pc += 13; if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL) @@ -610,7 +552,6 @@ int imap_open_mailbox (CONTEXT * ctx) #ifdef USE_HCACHE /* save UIDVALIDITY for the header cache */ else if (ascii_strncasecmp ("OK [UIDVALIDITY", pc, 14) == 0) { - debug_print (2, ("Getting mailbox UIDVALIDITY\n")); pc += 3; pc = imap_next_word (pc); @@ -630,7 +571,7 @@ int imap_open_mailbox (CONTEXT * ctx) if (rc == IMAP_CMD_NO) { char *s; - s = imap_next_word (idata->cmd.buf); /* skip seq */ + s = imap_next_word (idata->cmd.buf.data); /* skip seq */ s = imap_next_word (s); /* Skip response */ mutt_error ("%s", s); mutt_sleep (2); @@ -642,31 +583,11 @@ int imap_open_mailbox (CONTEXT * ctx) /* check for READ-ONLY notification */ if (!ascii_strncasecmp - (imap_get_qualifier (idata->cmd.buf), "[READ-ONLY]", 11) + (imap_get_qualifier (idata->cmd.buf.data), "[READ-ONLY]", 11) && !mutt_bit_isset (idata->capabilities, ACL)) { - debug_print (2, ("Mailbox is read-only.\n")); ctx->readonly = 1; } -#ifdef DEBUG - /* dump the mailbox flags we've found */ - if (DebugLevel > 2) { - if (!idata->flags) - debug_print (3, ("No folder flags found\n")); - else { - LIST *t = idata->flags; - - debug_print (3, ("Mailbox flags:\n")); - - t = t->next; - while (t) { - debug_print (3, ("[%s]\n", t->data)); - t = t->next; - } - } - } -#endif - if (mutt_bit_isset (idata->capabilities, ACL)) { if (imap_check_acl (idata)) goto fail; @@ -699,7 +620,6 @@ int imap_open_mailbox (CONTEXT * ctx) goto fail; } - debug_print (2, ("msgcount is %d\n", ctx->msgcount)); p_delete(&mx.mbox); return 0; @@ -727,7 +647,7 @@ int imap_open_mailbox_append (CONTEXT * ctx) if (!(idata = imap_conn_find (&(mx.account), 0))) { p_delete(&mx.mbox); - return (-1); + return -1; } conn = idata->conn; @@ -749,7 +669,7 @@ int imap_open_mailbox_append (CONTEXT * ctx) if (imap_create_mailbox (idata, mailbox) < 0) return -1; - return (0); + return 0; } /* imap_logout: Gracefully log out of server. */ @@ -760,27 +680,9 @@ void imap_logout (IMAP_DATA * idata) idata->status = IMAP_BYE; imap_cmd_start (idata, "LOGOUT"); while (imap_cmd_step (idata) == IMAP_CMD_CONTINUE); - p_delete(&idata->cmd.buf); - p_delete(&idata); + imap_free_idata(&idata); } -/* -int imap_close_connection (CONTEXT *ctx) -{ - debug_print (1, (debugfile, "imap_close_connection(): closing connection\n")); - if (CTX_DATA->status != IMAP_BYE) - { - mutt_message _("Closing connection to IMAP server..."); - imap_logout (CTX_DATA); - mutt_clear_error (); - } - mutt_socket_close (CTX_DATA->conn); - CTX_DATA->state = IMAP_DISCONNECTED; - CTX_DATA->conn->data = NULL; - return 0; -} -*/ - /* imap_set_flag: append str to flags if we currently have permission * according to aclbit */ static void imap_set_flag(IMAP_DATA *idata, int aclbit, int flag, @@ -805,7 +707,7 @@ int imap_make_msg_set (IMAP_DATA * idata, BUFFER * buf, int flag, int changed) HEADER **hdrs; /* sorted local copy */ int count = 0; /* number of messages in message set */ int match = 0; /* whether current message matches flag condition */ - unsigned int setstart = 0; /* start of current message range */ + int setstart = 0; /* start of current message range */ int n; short oldsort; /* we clobber reverse, must restore it */ @@ -933,7 +835,7 @@ int imap_sync_message (IMAP_DATA *idata, HEADER *hdr, BUFFER *cmd, err_continue && (*err_continue != M_YES)) { *err_continue = imap_continue ("imap_sync_message: STORE failed", - idata->cmd.buf); + idata->cmd.buf.data); if (*err_continue != M_YES) return -1; } @@ -963,7 +865,6 @@ int imap_sync_mailbox (CONTEXT * ctx, int expunge, int *index_hint) idata = (IMAP_DATA *) ctx->data; if (idata->state != IMAP_SELECTED) { - debug_print (2, ("no mailbox selected\n")); return -1; } @@ -1011,14 +912,11 @@ int imap_sync_mailbox (CONTEXT * ctx, int expunge, int *index_hint) * This works better if we're expunging, of course. */ if ((ctx->hdrs[n]->env && (ctx->hdrs[n]->env->refs_changed || ctx->hdrs[n]->env->irt_changed)) || ctx->hdrs[n]->attach_del) { - debug_print (3, ("Attachments to be deleted, falling back to _mutt_save_message\n")); if (!appendctx) appendctx = mx_open_mailbox (ctx->path, M_APPEND | M_QUIET, NULL); - if (!appendctx) { - debug_print (1, ("Error opening mailbox in append mode\n")); - } - else + if (appendctx) { _mutt_save_message (ctx->hdrs[n], appendctx, 1, 0, 0); + } } if (imap_sync_message (idata, ctx->hdrs[n], &cmd, &err_continue) < 0) { @@ -1037,7 +935,7 @@ int imap_sync_mailbox (CONTEXT * ctx, int expunge, int *index_hint) /* Set expunge bit so we don't get spurious reopened messages */ idata->reopen |= IMAP_EXPUNGE_EXPECTED; if (imap_exec (idata, "EXPUNGE", 0) != 0) { - imap_error (_("imap_sync_mailbox: EXPUNGE failed"), idata->cmd.buf); + imap_error (_("imap_sync_mailbox: EXPUNGE failed"), idata->cmd.buf.data); rc = imap_reconnect (ctx); goto out; } @@ -1061,7 +959,7 @@ out: } /* imap_close_mailbox: clean up IMAP data in CONTEXT */ -void imap_close_mailbox (CONTEXT * ctx) +static void imap_close_mailbox (CONTEXT * ctx) { IMAP_DATA *idata; int i; @@ -1082,7 +980,7 @@ void imap_close_mailbox (CONTEXT * ctx) idata->reopen &= IMAP_REOPEN_ALLOW; p_delete(&(idata->mailbox)); - mutt_free_list (&idata->flags); + string_list_wipe(&idata->flags); idata->ctx = NULL; } @@ -1106,7 +1004,7 @@ void imap_close_mailbox (CONTEXT * ctx) * 0 no change * -1 error */ -int imap_check_mailbox (CONTEXT * ctx, int *index_hint, int force) +int imap_check_mailbox (CONTEXT * ctx, int *index_hint __attribute__ ((unused)), int force) { /* overload keyboard timeout to avoid many mailbox checks in a row. * Most users don't like having to wait exactly when they press a key. */ @@ -1201,7 +1099,7 @@ int imap_mailbox_check (char *path, int new) if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE) break; - s = imap_next_word (idata->cmd.buf); + s = imap_next_word (idata->cmd.buf.data); if (ascii_strncasecmp ("STATUS", s, 6) == 0) { s = imap_next_word (s); /* The mailbox name may or may not be quoted here. We could try to @@ -1214,12 +1112,9 @@ int imap_mailbox_check (char *path, int new) if (isdigit ((unsigned char) *s)) { if (*s != '0') { msgcount = atoi (s); - debug_print (2, ("%d new messages in %s\n", msgcount, path)); } } } - else - debug_print (1, ("STATUS response doesn't match requested mailbox.\n")); } } while (rc == IMAP_CMD_CONTINUE); @@ -1361,7 +1256,7 @@ int imap_search (CONTEXT* ctx, const pattern_t* pat) { /* all this listing/browsing is a mess. I don't like that name is a pointer * into idata->buf (used to be a pointer into the passed in buffer, just * as bad), nor do I like the fact that the fetch is done here. This - * code can't possibly handle non-LIST untagged responses properly. + * code can't possibly handle non-string_list_t untagged responses properly. * FIXME. ?! */ int imap_parse_list_response (IMAP_DATA * idata, char **name, int *noselect, int *noinferiors, char *delim) @@ -1378,7 +1273,7 @@ int imap_parse_list_response (IMAP_DATA * idata, char **name, int *noselect, if (rc != IMAP_CMD_CONTINUE) return -1; - s = imap_next_word (idata->cmd.buf); + s = imap_next_word (idata->cmd.buf.data); if ((ascii_strncasecmp ("LIST", s, 4) == 0) || (ascii_strncasecmp ("LSUB", s, 4) == 0)) { *noselect = 0; @@ -1419,11 +1314,11 @@ int imap_parse_list_response (IMAP_DATA * idata, char **name, int *noselect, } s = imap_next_word (s); /* name */ if (s && *s == '{') { /* Literal */ - if (imap_get_literal_count (idata->cmd.buf, &bytes) < 0) + if (imap_get_literal_count (idata->cmd.buf.data, &bytes) < 0) return -1; if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE) return -1; - *name = idata->cmd.buf; + *name = idata->cmd.buf.data; } else *name = s; @@ -1438,8 +1333,6 @@ int imap_subscribe (char *path, int subscribe) IMAP_DATA *idata; char buf[LONG_STRING]; char mbox[LONG_STRING]; - char errstr[STRING]; - BUFFER err, token; IMAP_MBOX mx; if (mx_get_magic (path) != M_IMAP || imap_parse_path (path, &mx) < 0) { @@ -1455,14 +1348,7 @@ int imap_subscribe (char *path, int subscribe) imap_fix_path (idata, mx.mbox, buf, sizeof (buf)); if (option (OPTIMAPCHECKSUBSCRIBED)) { - p_clear(&token, 1); - err.data = errstr; - err.dsize = sizeof (errstr); - snprintf (mbox, sizeof (mbox), "%smailboxes \"%s\"", - subscribe ? "" : "un", path); - if (mutt_parse_rc_line (mbox, &token, &err)) - debug_print (1, ("Error adding subscribed mailbox: %s\n", errstr)); - p_delete(&token.data); + buffy_do_mailboxes(path, subscribe); } if (subscribe) @@ -1487,7 +1373,7 @@ fail: /* trim dest to the length of the longest prefix it shares with src, * returning the length of the trimmed string */ static int longest_common_prefix (char *dest, const char* src, - int start, size_t dlen) { + int start, ssize_t dlen) { int pos = start; while (pos < dlen && dest[pos] && dest[pos] == src[pos]) @@ -1499,7 +1385,7 @@ static int longest_common_prefix (char *dest, const char* src, /* look for IMAP URLs to complete from defined mailboxes. Could be extended * to complete over open connections and account/folder hooks too. */ -static int imap_complete_hosts (char *dest, size_t len) { +static int imap_complete_hosts (char *dest, ssize_t len) { BUFFY* mailbox; CONNECTION* conn; int rc = -1; @@ -1507,10 +1393,10 @@ static int imap_complete_hosts (char *dest, size_t len) { int i = 0; matchlen = m_strlen(dest); - if (list_empty (Incoming)) - return (-1); - for (i = 0; i < Incoming->length; i++) { - mailbox = (BUFFY*) Incoming->data[i]; + if (!Incoming.len) + return -1; + for (i = 0; i < Incoming.len; i++) { + mailbox = Incoming.arr[i]; if (!m_strncmp(dest, mailbox->path, matchlen)) { if (rc) { m_strcpy(dest, len, mailbox->path); @@ -1616,7 +1502,7 @@ int imap_complete (char *dest, size_t dlen, char *path) { completions++; } } - while (ascii_strncmp (idata->cmd.seq, idata->cmd.buf, SEQLEN)); + while (m_strncmp(idata->cmd.seq, idata->cmd.buf.data, SEQLEN)); if (completions) { /* reformat output */ @@ -1636,7 +1522,7 @@ int imap_reconnect (CONTEXT * ctx) IMAP_DATA *imap_data; if (!ctx) - return (-1); + return -1; imap_data = (IMAP_DATA *) ctx->data; @@ -1653,3 +1539,64 @@ int imap_reconnect (CONTEXT * ctx) mx_open_mailbox (ctx->path, 0, ctx); return 0; } + +static int imap_is_magic (const char* path, struct stat* st __attribute__ ((unused))) { + url_scheme_t s; + if (!path || !*path) + return -1; + s = url_check_scheme (NONULL (path)); + return (s == U_IMAP || s == U_IMAPS) ? M_IMAP : -1; +} + +static int acl_check_imap (CONTEXT* ctx, int bit) { + return (!mutt_bit_isset (((IMAP_DATA*) ctx->data)->capabilities, ACL) || + mutt_bit_isset (((IMAP_DATA*) ctx->data)->rights, bit)); +} + +static int imap_open_new_message (MESSAGE * msg, + CONTEXT * dest __attribute__ ((unused)), + HEADER * hdr __attribute__ ((unused))) +{ + char tmp[_POSIX_PATH_MAX]; + + msg->fp = m_tempfile(tmp, sizeof(tmp), NONULL(mod_core.tmpdir), NULL); + if (!msg->fp) { + mutt_perror(tmp); + return -1; + } + + msg->path = m_strdup(tmp); + return 0; +} + +/* this ugly kludge is required since the last int to + * imap_check_mailbox() doesn't mean 'lock' but 'force'... */ +static int _imap_check_mailbox (CONTEXT* ctx, + int* index_hint, + int lock __attribute__ ((unused))) { + return imap_check_mailbox (ctx, index_hint, 0); +} + +static int imap_commit_message (MESSAGE* msg, CONTEXT* ctx) { + int r = 0; + + if ((r = m_fclose(&msg->fp)) == 0) + r = imap_append_message (ctx, msg); + return r; +} + +mx_t const imap_mx = { + M_IMAP, + 0, + imap_is_magic, + NULL, + imap_access, + imap_open_mailbox, + imap_open_new_message, + imap_fetch_message, + acl_check_imap, + _imap_check_mailbox, + imap_close_mailbox, + imap_sync_mailbox, + imap_commit_message, +};