More modular way to open messages.
[apps/madmutt.git] / imap / imap.c
index b390b45..ea2eb80 100644 (file)
 
 #include "mutt.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 <lib-sys/mutt_ssl.h>
-#endif
 #include "buffy.h"
 
 /* imap forward declarations */
@@ -237,14 +234,14 @@ static int imap_get_delim (IMAP_DATA * idata)
    * than getting the delim wrong */
   idata->delim = '/';
 
-  imap_cmd_start (idata, "string_list_t \"\" \"\"");
+  imap_cmd_start (idata, "LIST \"\" \"\"");
 
   do {
     if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
       break;
 
-    s = imap_next_word (idata->cmd.buf);
-    if (ascii_strncasecmp ("string_list_t", s, 4) == 0) {
+    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);
       if (s && s[0] == '\"' && s[1] && s[2] == '\"')
@@ -278,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;
   }
 
@@ -301,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;
@@ -331,33 +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;
     } else {
-      mutt_account_unsetpass (&idata->conn->account);
+      mutt_socket_close(idata->conn);
+      idata->state = IMAP_DISCONNECTED;
+      idata->conn->account.has_pass = 0;
     }
 
     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;
@@ -378,28 +372,22 @@ 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 (mod_ssl.starttls) {
         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
           {
             mutt_error (_("Could not negotiate TLS connection"));
             mutt_sleep (1);
@@ -414,14 +402,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;
@@ -544,7 +531,7 @@ static 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 */
@@ -586,7 +573,7 @@ static 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);
@@ -598,7 +585,7 @@ static 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)) {
     ctx->readonly = 1;
   }
@@ -662,7 +649,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;
 
@@ -684,7 +671,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. */
@@ -695,26 +682,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)
-{
-  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,
@@ -867,7 +837,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;
   }
@@ -967,7 +937,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;
     }
@@ -1131,7 +1101,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 
@@ -1305,8 +1275,8 @@ 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);
-  if ((ascii_strncasecmp ("string_list_t", s, 4) == 0) ||
+  s = imap_next_word (idata->cmd.buf.data);
+  if ((ascii_strncasecmp ("LIST", s, 4) == 0) ||
       (ascii_strncasecmp ("LSUB", s, 4) == 0)) {
     *noselect = 0;
     *noinferiors = 0;
@@ -1346,11 +1316,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;
@@ -1365,8 +1335,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) {
@@ -1382,13 +1350,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);
-    mutt_parse_rc_line (mbox, &token, &err);
-    p_delete(&token.data);
+    buffy_do_mailboxes(path, subscribe);
   }
 
   if (subscribe)
@@ -1434,7 +1396,7 @@ static int imap_complete_hosts (char *dest, ssize_t len) {
 
   matchlen = m_strlen(dest);
   if (!Incoming.len)
-    return (-1);
+    return -1;
   for (i = 0; i < Incoming.len; i++) {
     mailbox = Incoming.arr[i];
     if (!m_strncmp(dest, mailbox->path, matchlen)) {
@@ -1508,7 +1470,7 @@ int imap_complete (char *dest, size_t dlen, char *path) {
 
   /* fire off command */
   snprintf (buf, sizeof (buf), "%s \"\" \"%s%%\"",
-            option (OPTIMAPLSUB) ? "LSUB" : "string_list_t", list);
+            option (OPTIMAPLSUB) ? "LSUB" : "LIST", list);
 
   imap_cmd_start (idata, buf);
 
@@ -1542,7 +1504,7 @@ int imap_complete (char *dest, size_t dlen, char *path) {
       completions++;
     }
   }
-  while (m_strncmp(idata->cmd.seq, idata->cmd.buf, SEQLEN));
+  while (m_strncmp(idata->cmd.seq, idata->cmd.buf.data, SEQLEN));
 
   if (completions) {
     /* reformat output */
@@ -1562,7 +1524,7 @@ int imap_reconnect (CONTEXT * ctx)
   IMAP_DATA *imap_data;
 
   if (!ctx)
-    return (-1);
+    return -1;
 
   imap_data = (IMAP_DATA *) ctx->data;
 
@@ -1583,9 +1545,9 @@ int imap_reconnect (CONTEXT * ctx)
 int imap_is_magic (const char* path, struct stat* st __attribute__ ((unused))) {
   url_scheme_t s;
   if (!path || !*path)
-    return (-1);
+    return -1;
   s = url_check_scheme (NONULL (path));
-  return ((s == U_IMAP || s == U_IMAPS) ? M_IMAP : -1);
+  return (s == U_IMAP || s == U_IMAPS) ? M_IMAP : -1;
 }
 
 static int acl_check_imap (CONTEXT* ctx, int bit) {
@@ -1599,7 +1561,7 @@ static int imap_open_new_message (MESSAGE * msg,
 {
     char tmp[_POSIX_PATH_MAX];
 
-    msg->fp = m_tempfile(tmp, sizeof(tmp), NONULL(Tempdir), NULL);
+    msg->fp = m_tempfile(tmp, sizeof(tmp), NONULL(mod_core.tmpdir), NULL);
     if (!msg->fp) {
         mutt_perror(tmp);
         return -1;
@@ -1614,7 +1576,7 @@ static int imap_open_new_message (MESSAGE * msg,
 static int _imap_check_mailbox (CONTEXT* ctx,
                                 int* index_hint,
                                 int lock __attribute__ ((unused))) {
-  return (imap_check_mailbox (ctx, index_hint, 0));
+  return imap_check_mailbox (ctx, index_hint, 0);
 }
 
 static int imap_commit_message (MESSAGE* msg, CONTEXT* ctx) {
@@ -1622,7 +1584,7 @@ static int imap_commit_message (MESSAGE* msg, CONTEXT* ctx) {
 
   if ((r = m_fclose(&msg->fp)) == 0)
     r = imap_append_message (ctx, msg);
-  return (r);
+  return r;
 }
 
 mx_t const imap_mx = {
@@ -1633,6 +1595,7 @@ mx_t const imap_mx = {
     imap_access,
     imap_open_mailbox,
     imap_open_new_message,
+    imap_fetch_message,
     acl_check_imap,
     _imap_check_mailbox,
     imap_close_mailbox,