]> granicus.if.org Git - mutt/commitdiff
Another IMAP patch from Brendan.
authorThomas Roessler <roessler@does-not-exist.org>
Thu, 20 Jul 2000 17:50:02 +0000 (17:50 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Thu, 20 Jul 2000 17:50:02 +0000 (17:50 +0000)
imap/browse.c
imap/command.c
imap/imap.c
imap/imap.h
imap/imap_private.h
imap/util.c
mutt_socket.c
mutt_socket.h
mx.c
pop.c

index 0f0dfebc4f7b3e5415454bd770d2d37f9e205fd8..c63487ee1a2522773bd4fa0fe70e546f188933f0 100644 (file)
@@ -65,21 +65,9 @@ int imap_browse (char* path, struct browser_state* state)
 
   strfcpy (list_cmd, option (OPTIMAPLSUB) ? "LSUB" : "LIST", sizeof (list_cmd));
 
-  conn = mutt_socket_find (&(mx.account), 0);
-  idata = (IMAP_DATA*) conn->data;
-
-  if (!idata || (idata->state == IMAP_DISCONNECTED))
-  {
-    if (!idata)
-    {
-      /* The current connection is a new connection */
-      idata = safe_calloc (1, sizeof (IMAP_DATA));
-      conn->data = idata;
-      idata->conn = conn;
-    }
-    if (imap_open_connection (idata))
-      return -1;
-  }
+  if (!(idata = imap_conn_find (&(mx.account), 0)))
+    return -1;
+  conn = idata->conn;
 
   if (mx.mbox[0] == '\0')
   {
index 0a534fe62d2725f71b9c1101f9f7d874e54ce10a..c71d984144a20ee67ca22c6c5015f38c17eb863f 100644 (file)
@@ -63,7 +63,7 @@ void imap_cmd_start (IMAP_DATA* idata, const char* cmd)
  *   detected, do expunge) */
 void imap_cmd_finish (IMAP_DATA* idata)
 {
-  if (!(idata->state == IMAP_SELECTED) || idata->selected_ctx->closing)
+  if (!(idata->state == IMAP_SELECTED) || idata->ctx->closing)
   {
     idata->status = 0;
     mutt_clear_error ();
@@ -79,19 +79,18 @@ void imap_cmd_finish (IMAP_DATA* idata)
 
     if (!(idata->reopen & IMAP_REOPEN_PENDING) &&
        ((idata->status == IMAP_NEW_MAIL) || (idata->reopen & IMAP_NEWMAIL_PENDING))  
-       && count > idata->selected_ctx->msgcount)
+       && count > idata->ctx->msgcount)
     {
       /* read new mail messages */
       dprint (1, (debugfile, "imap_cmd_finish: fetching new mail\n"));
 
-      count = imap_read_headers (idata->selected_ctx, 
-        idata->selected_ctx->msgcount, count - 1) + 1;
+      count = imap_read_headers (idata->ctx, idata->ctx->msgcount, count-1)+1;
       idata->check_status = IMAP_NEW_MAIL;
       idata->reopen &= ~IMAP_NEWMAIL_PENDING;
     }
     else
     {
-      imap_reopen_mailbox (idata->selected_ctx, NULL);
+      imap_reopen_mailbox (idata->ctx, NULL);
       idata->check_status = IMAP_REOPENED;
       idata->reopen &= ~(IMAP_REOPEN_PENDING|IMAP_NEWMAIL_PENDING);
     }
@@ -197,20 +196,19 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
       /* new mail arrived */
       count = atoi (pn);
 
-      if ( (idata->status != IMAP_EXPUNGE) && 
-       count < idata->selected_ctx->msgcount)
+      if ( (idata->status != IMAP_EXPUNGE) && count < idata->ctx->msgcount)
       {
        /* something is wrong because the server reported fewer messages
         * than we previously saw
         */
        mutt_error _("Fatal error.  Message count is out of sync!");
        idata->status = IMAP_FATAL;
-       mx_fastclose_mailbox (idata->selected_ctx);
+       mx_fastclose_mailbox (idata->ctx);
        return -1;
       }
       /* at least the InterChange server sends EXISTS messages freely,
        * even when there is no new mail */
-      else if (count == idata->selected_ctx->msgcount)
+      else if (count == idata->ctx->msgcount)
        dprint (3, (debugfile,
           "imap_handle_untagged: superfluous EXISTS message.\n"));
       else
@@ -219,7 +217,7 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
         {
           dprint (2, (debugfile,
             "imap_handle_untagged: New mail in %s - %d messages total.\n",
-            idata->selected_mailbox, count));
+            idata->mailbox, count));
          idata->status = IMAP_NEW_MAIL;
         }
        idata->newMailCount = count;
@@ -240,7 +238,7 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
     mutt_error ("%s", s);
     idata->status = IMAP_BYE;
     if (idata->state == IMAP_SELECTED)
-      mx_fastclose_mailbox (idata->selected_ctx);
+      mx_fastclose_mailbox (idata->ctx);
     mutt_socket_close (idata->conn);
     idata->state = IMAP_DISCONNECTED;
 
index 73e88faef55a5802be1c85bc754b15422067c975..300f24d0349dc1bc00f837b3383130ed98000c13 100644 (file)
@@ -251,8 +251,8 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint)
   ctx->id_hash = hash_create (1031);
   ctx->subj_hash = hash_create (1031);
 
-  mutt_message (_("Reopening mailbox... %s"), CTX_DATA->selected_mailbox);
-  imap_munge_mbox_name (buf, sizeof (buf), CTX_DATA->selected_mailbox);
+  mutt_message (_("Reopening mailbox... %s"), CTX_DATA->mailbox);
+  imap_munge_mbox_name (buf, sizeof (buf), CTX_DATA->mailbox);
   snprintf (bufout, sizeof (bufout), "STATUS %s (MESSAGES)", buf);
 
   imap_cmd_start (CTX_DATA, bufout);
@@ -429,7 +429,7 @@ static int imap_check_acl (IMAP_DATA *idata)
   char buf[LONG_STRING];
   char mbox[LONG_STRING];
 
-  imap_munge_mbox_name (mbox, sizeof(mbox), idata->selected_mailbox);
+  imap_munge_mbox_name (mbox, sizeof(mbox), idata->mailbox);
   snprintf (buf, sizeof (buf), "MYRIGHTS %s", mbox);
   if (imap_exec (buf, sizeof (buf), idata, buf, 0) != 0)
   {
@@ -458,6 +458,57 @@ static int imap_check_capabilities (IMAP_DATA *idata)
   return 0;
 }
 
+/* imap_conn_find: Find an open IMAP connection matching account, or open
+ *   a new one if none can be found. */
+IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags)
+{
+  CONNECTION* conn;
+  IMAP_DATA* idata;
+  ACCOUNT* creds;
+
+  conn = mutt_conn_find (NULL, account);
+  /* if opening a new UNSELECTED connection, preserve existing creds */
+  creds = &(conn->account);
+
+  /* make sure this connection is not in SELECTED state, if neccessary */
+  if (flags & M_IMAP_CONN_NOSELECT)
+    while (conn->data && ((IMAP_DATA*) conn->data)->state == IMAP_SELECTED)
+    {
+      conn = mutt_conn_find (conn, account);
+      memcpy (&(conn->account), creds, sizeof (ACCOUNT));
+    }
+  
+  
+  idata = (IMAP_DATA*) conn->data;
+
+  /* don't open a new connection if one isn't wanted */
+  if (flags & M_IMAP_CONN_NONEW)
+    if (!idata || idata->state == IMAP_DISCONNECTED)
+    {
+      mutt_socket_free (conn);
+
+      return NULL;
+    }
+  
+  if (!idata)
+  {
+    /* The current connection is a new connection */
+    idata = safe_calloc (1, sizeof (IMAP_DATA));
+    conn->data = idata;
+    idata->conn = conn;
+  }
+  if (idata->state == IMAP_DISCONNECTED)
+    if (imap_open_connection (idata) != 0)
+    {
+      FREE (&idata);
+      mutt_socket_free (conn);
+
+      return NULL;
+    }
+  
+  return idata;
+}
+
 int imap_open_connection (IMAP_DATA* idata)
 {
   char buf[LONG_STRING];
@@ -581,44 +632,31 @@ int imap_open_mailbox (CONTEXT* ctx)
     return -1;
   }
 
-  conn = mutt_socket_find (&(mx.account), 0);
-  idata = (IMAP_DATA*) conn->data;
-
-  if (!idata || (idata->state != IMAP_AUTHENTICATED))
-  {
-    if (!idata || (idata->state == IMAP_SELECTED) ||
-        (idata->state == IMAP_CONNECTED))
-    {
-      /* We need to create a new connection, the current one isn't useful */
-      idata = safe_calloc (1, sizeof (IMAP_DATA));
+  /* we require a connection which isn't currently in IMAP_SELECTED state */
+  if (!(idata = imap_conn_find (&(mx.account), M_IMAP_CONN_NOSELECT)))
+    return -1;
+  conn = idata->conn;
 
-      conn = mutt_socket_find (&(mx.account), 1);
-      conn->data = idata;
-      idata->conn = conn;
-    }
-    if (imap_open_connection (idata))
-      return -1;
-  }
+  /* once again the context is new */
   ctx->data = (void *) idata;
 
   /* Clean up path and replace the one in the ctx */
   imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
-  FREE(&(idata->selected_mailbox));
-  idata->selected_mailbox = safe_strdup (buf);
-  imap_qualify_path (buf, sizeof (buf), &mx, idata->selected_mailbox,
-    NULL);
+  FREE(&(idata->mailbox));
+  idata->mailbox = safe_strdup (buf);
+  imap_qualify_path (buf, sizeof (buf), &mx, idata->mailbox, NULL);
 
   FREE (&(ctx->path));
   ctx->path = safe_strdup (buf);
 
-  idata->selected_ctx = ctx;
+  idata->ctx = ctx;
 
   /* clear status, ACL */
   idata->status = 0;
   memset (idata->rights, 0, (RIGHTSMAX+7)/8);
 
-  mutt_message (_("Selecting %s..."), idata->selected_mailbox);
-  imap_munge_mbox_name (buf, sizeof(buf), idata->selected_mailbox);
+  mutt_message (_("Selecting %s..."), idata->mailbox);
+  imap_munge_mbox_name (buf, sizeof(buf), idata->mailbox);
   snprintf (bufout, sizeof (bufout), "%s %s",
     ctx->readonly ? "EXAMINE" : "SELECT", buf);
 
@@ -759,23 +797,14 @@ int imap_open_mailbox_append (CONTEXT *ctx)
   if (imap_parse_path (ctx->path, &mx))
     return -1;
 
-  ctx->magic = M_IMAP;
+  /* in APPEND mode, we appear to hijack an existing IMAP connection -
+   * ctx is brand new and mostly empty */
 
-  conn = mutt_socket_find (&(mx.account), 0);
-  idata = (IMAP_DATA*) conn->data;
+  if (!(idata = imap_conn_find (&(mx.account), 0)))
+    return -1;
+  conn = idata->conn;
 
-  if (!idata || (idata->state == IMAP_DISCONNECTED))
-  {
-    if (!idata)
-    {
-      /* The current connection is a new connection */
-      idata = safe_calloc (1, sizeof (IMAP_DATA));
-      conn->data = idata;
-      idata->conn = conn;
-    }
-    if (imap_open_connection (idata))
-      return -1;
-  }
+  ctx->magic = M_IMAP;
   ctx->data = (void *) idata;
 
   /* check mailbox existance */
@@ -785,15 +814,11 @@ int imap_open_mailbox_append (CONTEXT *ctx)
   imap_munge_mbox_name (mbox, sizeof (mbox), mailbox);
                                
   if (mutt_bit_isset(idata->capabilities,IMAP4REV1))
-  {
     snprintf (buf, sizeof (buf), "STATUS %s (UIDVALIDITY)", mbox);
-  }
   else if (mutt_bit_isset(idata->capabilities,STATUS))
-  { 
     /* We have no idea what the other guy wants. UW imapd 8.3 wants this
      * (but it does not work if another mailbox is selected) */
     snprintf (buf, sizeof (buf), "STATUS %s (UID-VALIDITY)", mbox);
-  }
   else
   {
     /* STATUS not supported */
@@ -954,8 +979,9 @@ int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag,
  *   expunge: 0 or 1 - do expunge? 
  */
 
-int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint)
+int imap_sync_mailbox (CONTEXT* ctx, int expunge, intindex_hint)
 {
+  IMAP_DATA* idata;
   char buf[HUGE_STRING];
   char flags[LONG_STRING];
   char tmp[LONG_STRING];
@@ -964,21 +990,30 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint)
   int err_continue = M_NO;     /* continue on error? */
   int rc;
 
-  if (CTX_DATA->state != IMAP_SELECTED)
+  idata = (IMAP_DATA*) ctx->data;
+
+  if (idata->state != IMAP_SELECTED)
   {
     dprint (2, (debugfile, "imap_sync_mailbox: no mailbox selected\n"));
     return -1;
   }
 
-  imap_allow_reopen (ctx);     /* This function is only called when the calling code
-                                * expects the context to be changed.
-                                */
+  /* CLOSE purges deleted messages. If we don't want to purge them, we must
+   * tell imap_close_mailbox not to issue the CLOSE command */
+  if (expunge)
+    idata->noclose = 0;
+  else
+    idata->noclose = 1;
+
+  /* This function is only called when the calling code        expects the context
+   * to be changed. */
+  imap_allow_reopen (ctx);     
 
   if ((rc = imap_check_mailbox (ctx, index_hint)) != 0)
     return rc;
 
   /* if we are expunging anyway, we can do deleted messages very quickly... */
-  if (expunge && mutt_bit_isset (CTX_DATA->rights, IMAP_ACL_DELETE))
+  if (expunge && mutt_bit_isset (idata->rights, IMAP_ACL_DELETE))
   {
     deleted = imap_make_msg_set (buf, sizeof (buf), ctx, M_DELETE, 1);
 
@@ -987,7 +1022,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint)
     {
       mutt_message (_("Marking %d messages deleted..."), deleted);
       snprintf (tmp, sizeof (tmp), "STORE %s +FLAGS.SILENT (\\Deleted)", buf);
-      if (imap_exec (buf, sizeof (buf), CTX_DATA, tmp, 0) != 0)
+      if (imap_exec (buf, sizeof (buf), idata, tmp, 0) != 0)
         /* continue, let regular store try before giving up */
         dprint(2, (debugfile, "imap_sync_mailbox: fast delete failed\n"));
       else
@@ -1017,8 +1052,8 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint)
         flags);
 
       /* now make sure we don't lose custom tags */
-      if (mutt_bit_isset (CTX_DATA->rights, IMAP_ACL_WRITE))
-        imap_add_keywords (flags, ctx->hdrs[n], CTX_DATA->flags);
+      if (mutt_bit_isset (idata->rights, IMAP_ACL_WRITE))
+        imap_add_keywords (flags, ctx->hdrs[n], idata->flags);
       
       mutt_remove_trailing_ws (flags);
       
@@ -1042,7 +1077,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint)
 
       /* after all this it's still possible to have no flags, if you
        * have no ACL rights */
-      if (*flags && (imap_exec (buf, sizeof (buf), CTX_DATA, buf, 0) != 0) &&
+      if (*flags && (imap_exec (buf, sizeof (buf), idata, buf, 0) != 0) &&
         (err_continue != M_YES))
       {
         err_continue = imap_continue ("imap_sync_mailbox: STORE failed", buf);
@@ -1055,30 +1090,19 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint)
   }
   ctx->changed = 0;
 
-  if (expunge == 1)
+  /* We must send an EXPUNGE command if we're not closing. */
+  if (expunge && !(ctx->closing) &&
+      mutt_bit_isset(idata->rights, IMAP_ACL_DELETE))
   {
-    /* expunge is implicit if closing */
-    if (ctx->closing)
+    mutt_message _("Expunging messages from server...");
+    /* FIXME: these status changes seem dubious */
+    idata->status = IMAP_EXPUNGE;
+    if (imap_exec (buf, sizeof (buf), CTX_DATA, "EXPUNGE", 0) != 0)
     {
-      mutt_message _("Closing mailbox...");
-      if (imap_exec (buf, sizeof (buf), CTX_DATA, "CLOSE", 0) != 0)
-      {
-        imap_error ("imap_sync_mailbox: CLOSE failed", buf);
-        return -1;
-      }
-      /* state is set in imap_fastclose_mailbox */
-    }
-    else if (mutt_bit_isset(CTX_DATA->rights, IMAP_ACL_DELETE))
-    {
-      mutt_message _("Expunging messages from server...");
-      CTX_DATA->status = IMAP_EXPUNGE;
-      if (imap_exec (buf, sizeof (buf), CTX_DATA, "EXPUNGE", 0) != 0)
-      {
-        imap_error ("imap_sync_mailbox: EXPUNGE failed", buf);
-        return -1;
-      }
-      CTX_DATA->status = 0;
+      imap_error ("imap_sync_mailbox: EXPUNGE failed", buf);
+      return -1;
     }
+    idata->status = 0;
   }
 
   for (n = 0; n < IMAP_CACHE_LEN; n++)
@@ -1093,20 +1117,31 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int *index_hint)
   return 0;
 }
 
-void imap_fastclose_mailbox (CONTEXT *ctx)
+/* imap_close_mailbox: issue close command if neccessary, reset IMAP_DATA */
+void imap_close_mailbox (CONTEXT* ctx)
 {
+  IMAP_DATA* idata;
+  char buf[LONG_STRING];
   int i;
 
+  idata = (IMAP_DATA*) ctx->data;
   /* Check to see if the mailbox is actually open */
-  if (!ctx->data)
+  if (!idata)
     return;
 
-  CTX_DATA->reopen &= IMAP_REOPEN_ALLOW;
+  idata->reopen &= IMAP_REOPEN_ALLOW;
 
-  if ((CTX_DATA->state == IMAP_SELECTED) && (ctx == CTX_DATA->selected_ctx))
+  if ((idata->state == IMAP_SELECTED) && (ctx == idata->ctx))
   {
-    CTX_DATA->state = IMAP_AUTHENTICATED;
-    FREE (&(CTX_DATA->selected_mailbox));
+    if (!(idata->noclose))
+    {
+      mutt_message _("Closing mailbox...");
+      if (imap_exec (buf, sizeof (buf), idata, "CLOSE", 0) != 0)
+        imap_error ("CLOSE failed", buf);
+    }
+    
+    idata->state = IMAP_AUTHENTICATED;
+    FREE (&(idata->mailbox));
   }
 
   /* free IMAP part of headers */
@@ -1115,10 +1150,10 @@ void imap_fastclose_mailbox (CONTEXT *ctx)
 
   for (i = 0; i < IMAP_CACHE_LEN; i++)
   {
-    if (CTX_DATA->cache[i].path)
+    if (idata->cache[i].path)
     {
-      unlink (CTX_DATA->cache[i].path);
-      safe_free ((void **) &CTX_DATA->cache[i].path);
+      unlink (idata->cache[i].path);
+      safe_free ((void **) &idata->cache[i].path);
     }
   }
 }
@@ -1184,30 +1219,19 @@ int imap_mailbox_check (char* path, int new)
   char mbox_unquoted[LONG_STRING];
   char *s;
   int msgcount = 0;
+  int connflags = 0;
   IMAP_MBOX mx;
   
   if (imap_parse_path (path, &mx))
     return -1;
 
-  conn = mutt_socket_find (&(mx.account), 0);
-  idata = (IMAP_DATA*) conn->data;
+  /* If imap_passive is set, don't open a connection to check for new mail */
+  if (option (OPTIMAPPASSIVE))
+    connflags &= M_IMAP_CONN_NONEW;
 
-  if (!idata || (idata->state == IMAP_DISCONNECTED))
-  {
-    /* If passive is selected, then we don't open connections to check
-     * for new mail */
-    if (option (OPTIMAPPASSIVE))
-      return -1;
-    if (!idata)
-    {
-      /* The current connection is a new connection */
-      idata = safe_calloc (1, sizeof (IMAP_DATA));
-      conn->data = idata;
-      idata->conn = conn;
-    }
-    if (imap_open_connection (idata))
-      return -1;
-  }
+  if (!(idata = imap_conn_find (&(mx.account), connflags)))
+    return -1;
+  conn = idata->conn;
 
   imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
   /* Update the path, if it fits */
@@ -1221,9 +1245,9 @@ int imap_mailbox_check (char* path, int new)
    * command on a mailbox that you have selected 
    */
 
-  if (mutt_strcmp (mbox_unquoted, idata->selected_mailbox) == 0
+  if (mutt_strcmp (mbox_unquoted, idata->mailbox) == 0
       || (mutt_strcasecmp (mbox_unquoted, "INBOX") == 0
-         && mutt_strcasecmp (mbox_unquoted, idata->selected_mailbox) == 0))
+         && mutt_strcasecmp (mbox_unquoted, idata->mailbox) == 0))
   {
     strfcpy (buf, "NOOP", sizeof (buf));
   }
@@ -1373,21 +1397,10 @@ int imap_subscribe (char *path, int subscribe)
   if (imap_parse_path (path, &mx))
     return -1;
 
-  conn = mutt_socket_find (&(mx.account), 0);
-  idata = (IMAP_DATA*) conn->data;
-
-  if (!idata || (idata->state == IMAP_DISCONNECTED))
-  {
-    if (!idata)
-    {
-      /* The current connection is a new connection */
-      idata = safe_calloc (1, sizeof (IMAP_DATA));
-      conn->data = idata;
-      idata->conn = conn;
-    }
-    if (imap_open_connection (idata))
-      return -1;
-  }
+  if (!(idata = imap_conn_find (&(mx.account), 0)))
+    return -1;
+  
+  conn = idata->conn;
 
   imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
   if (subscribe)
@@ -1428,16 +1441,10 @@ int imap_complete(char* dest, size_t dlen, char* path) {
     return -1;
   }
 
-  conn = mutt_socket_find (&(mx.account), 0);
-  idata = (IMAP_DATA*) conn->data;
-
   /* don't open a new socket just for completion */
-  if (!idata)
-  {
-    dprint (2, (debugfile,
-      "imap_complete: refusing to open new connection for %s", path));
+  if (!(idata = imap_conn_find (&(mx.account), M_IMAP_CONN_NONEW)))
     return -1;
-  }
+  conn = idata->conn;
 
   /* reformat path for IMAP list, and append wildcard */
   /* don't use INBOX in place of "" */
index a1223faa98728eec5d987064ade5b71d9b25148c..99eaacaa0a82000d77af7fe2571111bc446aa05e 100644 (file)
@@ -38,7 +38,7 @@ int imap_delete_mailbox (CONTEXT* idata, char* mailbox);
 int imap_open_mailbox (CONTEXT *ctx);
 int imap_open_mailbox_append (CONTEXT *ctx);
 int imap_sync_mailbox (CONTEXT *ctx, int expunge, int *index_hint);
-void imap_fastclose_mailbox (CONTEXT *ctx);
+void imap_close_mailbox (CONTEXT *ctx);
 int imap_buffy_check (char *path);
 int imap_mailbox_check (char *path, int new);
 int imap_subscribe (char *path, int subscribe);
index f2639ab8ed97028a54ced2f830a617fcb5e5e25f..35545ce328fad1b1b2762102261f2a25b5acf6c1 100644 (file)
@@ -51,8 +51,7 @@ enum
   IMAP_NEW_MAIL,
   IMAP_EXPUNGE,
   IMAP_BYE,
-  IMAP_REOPENED,
-  IMAP_LOGOUT
+  IMAP_REOPENED
 };
 
 enum
@@ -116,6 +115,10 @@ enum
   CAPMAX
 };
 
+/* imap_conn_find flags */
+#define M_IMAP_CONN_NONEW    (1<<0)
+#define M_IMAP_CONN_NOSELECT (1<<1)
+
 /* -- data structures -- */
 typedef struct
 {
@@ -138,21 +141,22 @@ typedef struct
 typedef struct
 {
   /* This data is specific to a CONNECTION to an IMAP server */
-  short status;
-  short state;
-  short check_status;
+  CONNECTION *conn;
+  unsigned char state;
+  unsigned char status;
+  unsigned char check_status;
   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;
+  CONTEXT *ctx;
+  char *mailbox;
+  unsigned char reopen;
   unsigned char rights[(RIGHTSMAX + 7)/8];
   unsigned int newMailCount;
   IMAP_CACHE cache[IMAP_CACHE_LEN];
-  short reopen;
+  int noclose : 1;
   
   /* all folder flags - system flags AND keywords */
   LIST *flags;
@@ -166,6 +170,7 @@ typedef struct
 int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag,
   int changed);
 int imap_open_connection (IMAP_DATA* idata);
+IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags);
 time_t imap_parse_date (char* s);
 int imap_parse_list_response(IMAP_DATA* idata, char* buf, int buflen,
   char** name, int* noselect, int* noinferiors, char* delim);
index cb16c43f16307548e7a116a10b69ee235c728c83..aa64c4a38f8424d3f97cf6266b74dec2df21cb98 100644 (file)
@@ -353,8 +353,7 @@ void imap_keepalive (void)
 {
   CONTEXT *ctx = Context;
   
-  if (ctx == NULL || ctx->magic != M_IMAP ||
-      CTX_DATA->selected_ctx != ctx)
+  if (ctx == NULL || ctx->magic != M_IMAP || CTX_DATA->ctx != ctx)
     return;
 
   imap_check_mailbox (ctx, NULL);
@@ -408,12 +407,12 @@ int imap_wait_keepalive (pid_t pid)
 
 void imap_allow_reopen (CONTEXT *ctx)
 {
-  if (ctx && ctx->magic == M_IMAP && CTX_DATA->selected_ctx == ctx)
+  if (ctx && ctx->magic == M_IMAP && CTX_DATA->ctx == ctx)
     CTX_DATA->reopen |= IMAP_REOPEN_ALLOW;
 }
 
 void imap_disallow_reopen (CONTEXT *ctx)
 {
-  if (ctx && ctx->magic == M_IMAP && CTX_DATA->selected_ctx == ctx)
+  if (ctx && ctx->magic == M_IMAP && CTX_DATA->ctx == ctx)
     CTX_DATA->reopen &= ~IMAP_REOPEN_ALLOW;
 }
index 48f3a0d267a87f0a5fa7acedba913cc799c70f78..0d2d127039630e34570ebe64bcd72863faddb499 100644 (file)
@@ -145,19 +145,22 @@ void mutt_socket_free (CONNECTION* conn)
   }
 }
 
-CONNECTION* mutt_socket_find (const ACCOUNT* account, int newconn)
+/* mutt_conn_find: find a connection off the list of connections whose
+ *   account matches account. If newconn is true, don't reuse one, but add
+ *   it to the list. If start is not null, only search for connections after
+ *   the given connection (allows higher level socket code to make more
+ *   fine-grained searches than account info - eg in IMAP we may wish
+ *   to find a connection which is not in IMAP_SELECTED state) */
+CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account)
 {
   CONNECTION* conn;
 
-  if (! newconn)
+  conn = start ? start->next : Connections;
+  while (conn)
   {
-    conn = Connections;
-    while (conn)
-    {
-      if (mutt_account_match (account, &(conn->account)))
-       return conn;
-      conn = conn->next;
-    }
+    if (mutt_account_match (account, &(conn->account)))
+      return conn;
+    conn = conn->next;
   }
 
   conn = socket_new_conn ();
index 04ffe055e674aa41ee9e90e7e8a0f4accfe2080d..6b8590dacd9985e5dcf21ebd57d006a84ab3522b 100644 (file)
@@ -61,7 +61,7 @@ int mutt_socket_write_d (CONNECTION *conn, const char *buf, int dbg);
 /* stupid hack for imap_logout_all */
 CONNECTION* mutt_socket_head (void);
 void mutt_socket_free (CONNECTION* conn);
-CONNECTION* mutt_socket_find (const ACCOUNT* mx, int newconn);
+CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account);
 
 int raw_socket_read (CONNECTION *conn);
 int raw_socket_write (CONNECTION *conn, const char *buf);
diff --git a/mx.c b/mx.c
index 2fbc393d9cd7b3050884b928d9826786f5b81696..61cd80c18e760c99d0590b42f9cb232e1eb42b09 100644 (file)
--- a/mx.c
+++ b/mx.c
@@ -684,7 +684,7 @@ void mx_fastclose_mailbox (CONTEXT *ctx)
   
 #ifdef USE_IMAP
   if (ctx->magic == M_IMAP)
-    imap_fastclose_mailbox (ctx);
+    imap_close_mailbox (ctx);
 #endif /* USE_IMAP */
   if (ctx->subj_hash)
     hash_destroy (&ctx->subj_hash, NULL);
diff --git a/pop.c b/pop.c
index 16ba99289127f8a5f0162f076581c7a42ad1bfdd..6e640202de9020498d87a86cf9211363c1088cd0 100644 (file)
--- a/pop.c
+++ b/pop.c
@@ -137,7 +137,7 @@ void mutt_fetchPopMail (void)
   account.port = PopPort;
   account.type = M_ACCT_TYPE_POP;
   account.flags = 0;
-  conn = mutt_socket_find (&account, 0);
+  conn = mutt_conn_find (NULL, &account);
   if (mutt_socket_open (conn) < 0)
     return;