]> granicus.if.org Git - mutt/commitdiff
More IMAP fixes from Brendan Cully.
authorThomas Roessler <roessler@does-not-exist.org>
Thu, 6 Jul 2000 06:36:45 +0000 (06:36 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Thu, 6 Jul 2000 06:36:45 +0000 (06:36 +0000)
imap/browse.c
imap/command.c
imap/imap.c
imap/imap_private.h
imap/imap_socket.h
imap/message.c
imap/socket.c
imap/util.c

index 4ac57f14cf7c6f331898c8e76fe63f2cc18dabe9..5e6c85b6429bdbc062a23a32c86945e1efd5acce 100644 (file)
@@ -66,7 +66,7 @@ int imap_init_browse (char *path, struct browser_state *state)
 
   strfcpy (list_cmd, option (OPTIMAPLSUB) ? "LSUB" : "LIST", sizeof (list_cmd));
 
-  conn = mutt_socket_select_connection (&mx, 0);
+  conn = mutt_socket_find (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state == IMAP_DISCONNECTED))
index cfa7debae720d40d8b7919359a53abd71acdef68..28c6bee9c8f879c98006043cd7b333d5cd31031b 100644 (file)
@@ -257,9 +257,10 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
     idata->status = IMAP_BYE;
     if (idata->state == IMAP_SELECTED)
       mx_fastclose_mailbox (idata->selected_ctx);
-    mutt_socket_close_connection (idata->conn);
+    mutt_socket_close (idata->conn);
     idata->state = IMAP_DISCONNECTED;
-    return (-1);
+
+    return -1;
   }
   else if (option (OPTIMAPSERVERNOISE) && (mutt_strncasecmp ("NO", s, 2) == 0))
   {
index c796c2d5758a25b089b3d7101da35d0ae3074540..67a8ebbce4bdd86f6b3acb46909af1626eb402f6 100644 (file)
@@ -421,15 +421,16 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
 {
   char buf[LONG_STRING];
 
-  if (mutt_socket_open_connection (conn) < 0)
+  if (mutt_socket_open (conn) < 0)
     return -1;
 
   idata->state = IMAP_CONNECTED;
 
   if (mutt_socket_read_line_d (buf, sizeof (buf), conn) < 0)
   {
-    mutt_socket_close_connection (conn);
+    mutt_socket_close (conn);
     idata->state = IMAP_DISCONNECTED;
+
     return -1;
   }
 
@@ -438,7 +439,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
     if (imap_check_capabilities(idata) != 0 
        || imap_authenticate (idata, conn) != 0)
     {
-      mutt_socket_close_connection (conn);
+      mutt_socket_close (conn);
       idata->state = IMAP_DISCONNECTED;
       return -1;
     }
@@ -447,7 +448,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
   {
     if (imap_check_capabilities(idata) != 0)
     {
-      mutt_socket_close_connection (conn);
+      mutt_socket_close (conn);
       idata->state = IMAP_DISCONNECTED;
       return -1;
     }
@@ -455,7 +456,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
   else
   {
     imap_error ("imap_open_connection()", buf);
-    mutt_socket_close_connection (conn);
+    mutt_socket_close (conn);
     idata->state = IMAP_DISCONNECTED;
     return -1;
   }
@@ -540,7 +541,7 @@ int imap_open_mailbox (CONTEXT *ctx)
     return -1;
   }
 
-  conn = mutt_socket_select_connection (&mx, 0);
+  conn = mutt_socket_find (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state != IMAP_AUTHENTICATED))
@@ -551,7 +552,7 @@ int imap_open_mailbox (CONTEXT *ctx)
       /* We need to create a new connection, the current one isn't useful */
       idata = safe_calloc (1, sizeof (IMAP_DATA));
 
-      conn = mutt_socket_select_connection (&mx, 1);
+      conn = mutt_socket_find (&mx, 1);
       conn->data = idata;
       idata->conn = conn;
     }
@@ -721,7 +722,7 @@ int imap_select_mailbox (CONTEXT* ctx, const char* path)
     return -1;
 
   /* and that it's on the same server as the current folder */
-  conn = mutt_socket_select_connection (&mx, 0);
+  conn = mutt_socket_find (&mx, 0);
   if (!CTX_DATA || !CONN_DATA || (CTX_DATA->conn != CONN_DATA->conn))
   {
     dprint(2, (debugfile,
@@ -755,7 +756,7 @@ int imap_open_mailbox_append (CONTEXT *ctx)
 
   ctx->magic = M_IMAP;
 
-  conn = mutt_socket_select_connection (&mx, 0);
+  conn = mutt_socket_find (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -838,7 +839,7 @@ int imap_close_connection (CONTEXT *ctx)
     while (mutt_strncmp (seq, buf, SEQLEN) != 0);
     mutt_clear_error ();
   }
-  mutt_socket_close_connection (CTX_DATA->conn);
+  mutt_socket_close (CTX_DATA->conn);
   CTX_DATA->state = IMAP_DISCONNECTED;
   CTX_DATA->conn->data = NULL;
   return 0;
@@ -1197,7 +1198,7 @@ int imap_mailbox_check (char *path, int new)
   if (imap_parse_path (path, &mx))
     return -1;
 
-  conn = mutt_socket_select_connection (&mx, 0);
+  conn = mutt_socket_find (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -1377,7 +1378,7 @@ int imap_subscribe (char *path, int subscribe)
   if (imap_parse_path (path, &mx))
     return (-1);
 
-  conn = mutt_socket_select_connection (&mx, 0);
+  conn = mutt_socket_find (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -1433,7 +1434,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
     return -1;
   }
 
-  conn = mutt_socket_select_connection (&mx, 0);
+  conn = mutt_socket_find (&mx, 0);
   idata = CONN_DATA;
 
   /* don't open a new socket just for completion */
index 2572efe16fdc2cdaefdea19d87bcf087372dbd7c..ae5847daa308bea4e7978a07d274781b26ceafdf 100644 (file)
@@ -187,6 +187,7 @@ void imap_free_header_data (void** data);
 int imap_read_headers (CONTEXT* ctx, int msgbegin, int msgend);
 
 /* util.c */
+int imap_account_match (const IMAP_MBOX* m1, const IMAP_MBOX* m2);
 int imap_continue (const char* msg, const char* resp);
 void imap_error (const char* where, const char* msg);
 char* imap_fix_path (IMAP_DATA* idata, char* mailbox, char* path, 
index 8a1649289b2995122602eab2dedd7135f5367a70..d868fd6e48aa9a76e42f27e10bacfffc1720cf83 100644 (file)
@@ -36,16 +36,19 @@ typedef struct _connection
   int (*write) (struct _connection *conn, const char *buf);
   int (*open) (struct _connection *conn);
   int (*close) (struct _connection *conn);
-} CONNECTION;
 
+  /* status bits */
+  int up : 1;
+} CONNECTION;
 
+int mutt_socket_open (CONNECTION* conn);
+int mutt_socket_close (CONNECTION* conn);
 int mutt_socket_readchar (CONNECTION *conn, char *c);
 int mutt_socket_read_line (char *buf, size_t buflen, CONNECTION *conn);
 int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn);
 int mutt_socket_write (CONNECTION *conn, const char *buf);
-CONNECTION *mutt_socket_select_connection (const IMAP_MBOX *mx, int newconn);
-int mutt_socket_open_connection (CONNECTION *conn);
-int mutt_socket_close_connection (CONNECTION *conn);
+
+CONNECTION* mutt_socket_find (const IMAP_MBOX* mx, int newconn);
 
 int raw_socket_read (CONNECTION *conn);
 int raw_socket_write (CONNECTION *conn, const char *buf);
index 8bf9c91ecf3f551c5e49f671dab97409e7a86951..197edba25d64d41b035b47dde09495d4d1902c14 100644 (file)
@@ -56,7 +56,6 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
   IMAP_HEADER *h, *h0;
   const char *want_headers = "DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO REPLY-TO LINES X-LABEL";
   int using_body_peek = 0;
-  int c;
   
   fetchlast = 0;
 
@@ -164,6 +163,13 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
               return -1;
             }
             imap_read_bytes (fp, CTX_DATA->conn, bytes);
+           /* make sure headers are followed by ONE blank line (separator
+            * for mutt_read_rfc822_header) */
+           do
+             fseek (fp, -2, SEEK_CUR);
+           while (fgetc (fp) == '\n');
+           fputs ("\n\n", fp);
+           
            /* we may have other fields of the FETCH _after_ the literal
             * (eg Domino puts FLAGS here). Nothing wrong with that, either.
             * This all has to go - we should accept literals and nonliterals
@@ -257,15 +263,6 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
     h = h->next;
     /* hdata is freed later */
     safe_free ((void **) &h0);
-
-    /* 
-     * skip over additional \n characters - Courier IMAP seems to
-     * put them here.
-     */
-    
-    while ((c = fgetc (fp)) == '\n')
-      ;
-    ungetc (c, fp);
   }
   
   fclose(fp);
@@ -597,8 +594,8 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
     return -1;
   }
 
-  /* check that the save-to folder is on the same server */
-  if (mutt_socket_select_connection (&mx, 0) != CTX_DATA->conn)
+  /* check that the save-to folder is in the same account */
+  if (!imap_account_match (&(CTX_DATA->conn->mx), &mx))
   {
     dprint (3, (debugfile, "imap_copy_message: %s not same server as %s\n",
       dest, ctx->path));
index d621f923387398cb082ab7223e1e433f0fbf2324..adf7b3e580268590dda48f39ee03c5288d7418d3 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * Copyright (C) 1998 Michael R. Elkins <me@cs.hmc.edu>
+ * Copyright (C) 1999-2000 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 1999-2000 Tommi Komulainen <Tommi.Komulainen@iki.fi>
  * 
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License as published by
 #include <string.h>
 
 /* support for multiple socket connections */
-
 static CONNECTION *Connections = NULL;
 
+/* forward declarations */
+static int socket_connect (CONNECTION* conn, struct sockaddr_in sin,
+  int verbose);
+static CONNECTION* socket_new_conn ();
 
 /* Wrappers */
-int mutt_socket_open_connection (CONNECTION *conn) 
+int mutt_socket_open (CONNECTION* conn) 
 {
-  return conn->open (conn);
+  int rc;
+  
+  rc = conn->open (conn);
+  if (!rc)
+    conn->up = 1;
+
+  return rc;
 }
 
-int mutt_socket_close_connection (CONNECTION *conn)
+int mutt_socket_close (CONNECTION* conn)
 {
+  conn->up = 0;
+
   return conn->close (conn);
 }
 
@@ -55,8 +68,6 @@ int mutt_socket_write (CONNECTION *conn, const char *buf)
   return conn->write (conn, buf);
 }
 
-
-
 /* simple read buffering to speed things up. */
 int mutt_socket_readchar (CONNECTION *conn, char *c)
 {
@@ -99,28 +110,9 @@ int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn)
   return r;
 }
 
-/* imap_account_match: compare account info (host/port/user) */
-static int imap_account_match (const IMAP_MBOX *m1, const IMAP_MBOX *m2)
+CONNECTION* mutt_socket_find (const IMAP_MBOX* mx, int newconn)
 {
-  const char *user = ImapUser ? ImapUser : NONULL (Username);
-
-  if (mutt_strcasecmp (m1->host, m2->host))
-    return 0;
-  if (m1->port != m2->port)
-    return 0;
-  
-  if (m1->flags & m2->flags & M_IMAP_USER)
-    return (!strcmp (m1->user, m2->user));
-  if (m1->flags & M_IMAP_USER)
-    return (!strcmp (m1->user, user));
-  if (m2->flags & M_IMAP_USER)
-    return (!strcmp (m2->user, user));
-  return 1;
-}
-
-CONNECTION *mutt_socket_select_connection (const IMAP_MBOX *mx, int newconn)
-{
-  CONNECTION *conn;
+  CONNECTION* conn;
 
   if (! newconn)
   {
@@ -132,11 +124,11 @@ CONNECTION *mutt_socket_select_connection (const IMAP_MBOX *mx, int newconn)
       conn = conn->next;
     }
   }
-  conn = (CONNECTION *) safe_calloc (1, sizeof (CONNECTION));
-  conn->fd = -1;
+
+  conn = socket_new_conn ();
   memcpy (&conn->mx, mx, sizeof (conn->mx));
   conn->mx.mbox = 0;
-  conn->preconnect = safe_strdup (ImapPreconnect); 
+
   conn->next = Connections;
   Connections = conn;
 
@@ -161,16 +153,15 @@ CONNECTION *mutt_socket_select_connection (const IMAP_MBOX *mx, int newconn)
  *   make sure we've got all the context we need. */
 void imap_logout_all (void) 
 {
-  CONNECTION* conn, *tmp;
-  char buf[LONG_STRING];
+  CONNECTION* conn;
+  char buf[SHORT_STRING];
   char seq[SEQLEN+1];
   
   conn = Connections;
 
   while (conn)
   {
-    /* what's up here? the last connection doesn't seem to be used */
-    if (conn->fd >= 0)
+    if (conn->up)
     {
       snprintf (buf, sizeof (buf), _("Closing connection to %s..."),
         conn->mx.host);
@@ -188,31 +179,33 @@ void imap_logout_all (void)
       }
       while (mutt_strncmp (buf, seq, SEQLEN) != 0);
       mutt_clear_error ();
+
+      mutt_socket_close (conn);
     }
     
-    tmp = conn;
-    conn = conn->next;
+    Connections = conn->next;
 
-    mutt_socket_close_connection (tmp);
-
-    if (tmp->data) {
+    if (conn->data) {
       dprint (2, (debugfile,
         "imap_logout_all: Connection still has valid CONTEXT?!\n"));
     }
 
-    free (tmp);
+    free (conn);
+
+    conn = Connections;
   }
 }
 
-
-static int try_socket_and_connect (CONNECTION *conn, struct sockaddr_in sin,
-                           int verbose)
+/* socket_connect: attempt to bind a socket and connect to it */
+static int socket_connect (CONNECTION* conn, struct sockaddr_in sin,
+  int verbose)
 {
   if ((conn->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
   {
     if (verbose) 
       mutt_perror ("socket");
-    return (-1);
+
+    return -1;
   }
 
   if (connect (conn->fd, (struct sockaddr *) &sin, sizeof (sin)) < 0)
@@ -223,12 +216,25 @@ static int try_socket_and_connect (CONNECTION *conn, struct sockaddr_in sin,
       mutt_perror ("connect");
       sleep (1);
     }
-    return (-1);
+
+    return -1;
   }
 
   return 0;
 }
 
+/* socket_new_conn: allocate and initialise a new connection. */
+static CONNECTION* socket_new_conn ()
+{
+  CONNECTION* conn;
+
+  conn = (CONNECTION *) safe_calloc (1, sizeof (CONNECTION));
+  conn->preconnect = safe_strdup (ImapPreconnect);
+  conn->fd = -1;
+
+  return conn;
+}
+
 int raw_socket_close (CONNECTION *conn)
 {
   int ret = close (conn->fd);
@@ -272,7 +278,7 @@ int raw_socket_open (CONNECTION *conn)
   if (do_preconnect && first_try_without_preconnect)
   {
     verbose = FALSE;
-    if (try_socket_and_connect (conn, sin, verbose) == 0)
+    if (socket_connect (conn, sin, verbose) == 0)
       return 0;
   }
   
@@ -294,5 +300,6 @@ int raw_socket_open (CONNECTION *conn)
   }
   
   verbose = TRUE;
-  return try_socket_and_connect (conn, sin, verbose);
+
+  return socket_connect (conn, sin, verbose);
 }
index 6e959fc4c796b609b4275ea98e2bc1a554b711fb..e36d91d27e21454a5b24e56fbf3335fb87b9a391 100644 (file)
 
 #include <errno.h>
 
+/* imap_account_match: compare account info (host/port/user) */
+int imap_account_match (const IMAP_MBOX* m1, const IMAP_MBOX* m2)
+{
+  const char* user = ImapUser ? ImapUser : NONULL (Username);
+
+  if (mutt_strcasecmp (m1->host, m2->host))
+    return 0;
+  if (m1->port != m2->port)
+    return 0;
+  
+  if (m1->flags & m2->flags & M_IMAP_USER)
+    return (!strcmp (m1->user, m2->user));
+  if (m1->flags & M_IMAP_USER)
+    return (!strcmp (m1->user, user));
+  if (m2->flags & M_IMAP_USER)
+    return (!strcmp (m2->user, user));
+
+  return 1;
+}
+
 /* imap_continue: display a message and ask the user if she wants to
  *   go on. */
 int imap_continue (const char* msg, const char* resp)