New function to decode the INTERNALDATE response from an IMAP server so we
authorJeffrey Stedfast <fejj@ximian.com>
Fri, 27 Sep 2002 20:20:08 +0000 (20:20 +0000)
committerJeffrey Stedfast <fejj@src.gnome.org>
Fri, 27 Sep 2002 20:20:08 +0000 (20:20 +0000)
2002-09-27  Jeffrey Stedfast  <fejj@ximian.com>

* providers/imap/camel-imap-folder.c (decode_internaldate): New
function to decode the INTERNALDATE response from an IMAP server
so we don't have to use my broken-date-parser routines.

2002-09-27  Jeffrey Stedfast  <fejj@ximian.com>

* providers/imap/camel-imap-store.c (connect_to_server):
NULL-check the streams before unreffing them in the case of a
failure during ssl negotiations.

* camel-tcp-stream-ssl.c (camel_tcp_stream_ssl_enable_ssl): Check
SSL_ResetHandshake() for errors. Also force a handshake after
we've reset the handshake state on the socket.

camel/ChangeLog
camel/broken-date-parser.c
camel/camel-tcp-stream-ssl.c
camel/providers/imap/camel-imap-folder.c
camel/providers/imap/camel-imap-store.c

index 6771d23..95abd36 100644 (file)
@@ -1,3 +1,19 @@
+2002-09-27  Jeffrey Stedfast  <fejj@ximian.com>
+
+       * providers/imap/camel-imap-folder.c (decode_internaldate): New
+       function to decode the INTERNALDATE response from an IMAP server
+       so we don't have to use my broken-date-parser routines.
+
+2002-09-27  Jeffrey Stedfast  <fejj@ximian.com>
+
+       * providers/imap/camel-imap-store.c (connect_to_server):
+       NULL-check the streams before unreffing them in the case of a
+       failure during ssl negotiations.
+
+       * camel-tcp-stream-ssl.c (camel_tcp_stream_ssl_enable_ssl): Check
+       SSL_ResetHandshake() for errors. Also force a handshake after
+       we've reset the handshake state on the socket.
+
 2002-09-27  Not Zed  <NotZed@Ximian.com>
 
        * providers/imap/camel-imap-folder.c (imap_update_summary): Use
index cba1920..238665c 100644 (file)
@@ -406,7 +406,7 @@ decode_broken_date (struct _date_token *tokens, int *tzone)
        
        time = e_mktime_utc (&tm);
        
-       /* t is now GMT of the time we want, but not offset by the timezone ... */
+       /* time is now GMT of the time we want, but not offset by the timezone ... */
        
        /* this should convert the time to the GMT equiv time */
        time -= ((offset / 100) * 60 * 60) + (offset % 100) * 60;
index ed53945..09e5c94 100644 (file)
@@ -268,20 +268,22 @@ camel_tcp_stream_ssl_enable_ssl (CamelTcpStreamSSL *ssl)
        g_return_val_if_fail (CAMEL_IS_TCP_STREAM_SSL (ssl), -1);
        
        if (ssl->priv->sockfd && !ssl->priv->ssl_mode) {
-               fd = enable_ssl (ssl, NULL);
-               if (fd == NULL) {
-                       int errnosave;
-                       
+               if (!(fd = enable_ssl (ssl, NULL))) {
                        set_errno (PR_GetError ());
-                       errnosave = errno;
-                       errno = errnosave;
-                       
                        return -1;
                }
                
-               SSL_ResetHandshake (fd, FALSE);
-               
                ssl->priv->sockfd = fd;
+               
+               if (SSL_ResetHandshake (fd, FALSE) == SECFailure) {
+                       set_errno (PR_GetError ());
+                       return -1;
+               }
+               
+               if (SSL_ForceHandshake (fd) == -1) {
+                       set_errno (PR_GetError ());
+                       return -1;
+               }
        }
        
        ssl->priv->ssl_mode = TRUE;
index 1365c72..23800bd 100644 (file)
@@ -38,6 +38,7 @@
 #include <ctype.h>
 
 #include "e-util/e-path.h"
+#include "e-util/e-time-utils.h"
 
 #include "camel-imap-folder.h"
 #include "camel-imap-command.h"
@@ -2002,6 +2003,100 @@ imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid,
 #define IMAP_PRETEND_SIZEOF_SIZE         20
 #define IMAP_PRETEND_SIZEOF_HEADERS    2000
 
+static char *tm_months[] = {
+       "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static gboolean
+decode_time (const unsigned char **in, int *hour, int *min, int *sec)
+{
+       register const unsigned char *inptr;
+       int *val, colons = 0;
+       
+       *hour = *min = *sec = 0;
+       
+       val = hour;
+       for (inptr = *in; *inptr && !isspace ((int) *inptr); inptr++) {
+               if (*inptr == ':') {
+                       colons++;
+                       switch (colons) {
+                       case 1:
+                               val = min;
+                               break;
+                       case 2:
+                               val = sec;
+                               break;
+                       default:
+                               return FALSE;
+                       }
+               } else if (!isdigit ((int) *inptr))
+                       return FALSE;
+               else
+                       *val = (*val * 10) + (*inptr - '0');
+       }
+       
+       *in = inptr;
+       
+       return TRUE;
+}
+
+static time_t
+decode_internaldate (const unsigned char *in)
+{
+       const unsigned char *inptr = in;
+       int hour, min, sec, n;
+       unsigned char *buf;
+       struct tm tm;
+       time_t date;
+       
+       memset ((void *) &tm, 0, sizeof (struct tm));
+       
+       tm.tm_mday = strtoul (inptr, (char **) &buf, 10);
+       if (buf == inptr || *buf != '-')
+               return (time_t) -1;
+       
+       inptr = buf + 1;
+       if (inptr[3] != '-')
+               return (time_t) -1;
+       
+       for (n = 0; n < 12; n++) {
+               if (!g_strncasecmp (inptr, tm_months[n], 3))
+                       break;
+       }
+       
+       if (n >= 12)
+               return (time_t) -1;
+       
+       tm.tm_mon = n;
+       
+       inptr += 4;
+       
+       n = strtoul (inptr, (char **) &buf, 10);
+       if (buf == inptr || *buf != ' ')
+               return (time_t) -1;
+       
+       tm.tm_year = n - 1900;
+       
+       if (!decode_time (&inptr, &hour, &min, &sec))
+               return (time_t) -1;
+       
+       tm.tm_hour = hour;
+       tm.tm_min = min;
+       tm.tm_sec = sec;
+       
+       n = strtoul (inptr, NULL, 10);
+       
+       date = e_mktime_utc (&tm);
+       
+       /* date is now GMT of the time we want, but not offset by the timezone ... */
+       
+       /* this should convert the time to the GMT equiv time */
+       date -= ((n / 100) * 60 * 60) + (n % 100) * 60;
+       
+       return date;
+}
+
 static void
 add_message_from_data (CamelFolder *folder, GPtrArray *messages,
                       int first, GData *data)
@@ -2032,8 +2127,9 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
        camel_object_unref (CAMEL_OBJECT (msg));
        
        if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
-               mi->date_received = parse_broken_date (idate, NULL);
-       else
+               mi->date_received = decode_internaldate (idate);
+       
+       if (mi->date_received == -1)
                mi->date_received = mi->date_sent;
        
        messages->pdata[seq - first] = mi;
index fbc1e20..f854d78 100644 (file)
@@ -528,7 +528,7 @@ imap_get_capability (CamelService *service, CamelException *ex)
        g_free (result);
        
        imap_set_server_level (store);
-
+       
        if (store->summary->capabilities != store->capabilities) {
                store->summary->capabilities = store->capabilities;
                camel_store_summary_touch((CamelStoreSummary *)store->summary);
@@ -682,27 +682,43 @@ connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelE
        /* rfc2595, section 4 states that after a successful STLS
            command, the client MUST discard prior CAPA responses */
        if (!imap_get_capability (service, ex)) {
-               camel_object_unref (CAMEL_OBJECT (store->istream));
-               camel_object_unref (CAMEL_OBJECT (store->ostream));
-               store->istream = NULL;
-               store->ostream = NULL;
+               if (store->istream) {
+                       camel_object_unref (CAMEL_OBJECT (store->istream));
+                       store->istream = NULL;
+               }
+               
+               if (store->ostream) {
+                       camel_object_unref (CAMEL_OBJECT (store->ostream));
+                       store->ostream = NULL;
+               }
+               
+               store->connected = FALSE;
+               
                return FALSE;
        }
        
        return TRUE;
        
  exception:
-       if (clean_quit) {
+       
+       if (clean_quit && store->connected) {
                /* try to disconnect cleanly */
                response = camel_imap_command (store, NULL, ex, "LOGOUT");
                if (response)
                        camel_imap_response_free_without_processing (store, response);
        }
        
-       camel_object_unref (CAMEL_OBJECT (store->istream));
-       camel_object_unref (CAMEL_OBJECT (store->ostream));
-       store->istream = NULL;
-       store->ostream = NULL;
+       if (store->istream) {
+               camel_object_unref (CAMEL_OBJECT (store->istream));
+               store->istream = NULL;
+       }
+       
+       if (store->ostream) {
+               camel_object_unref (CAMEL_OBJECT (store->ostream));
+               store->ostream = NULL;
+       }
+       
+       store->connected = FALSE;
        
        return FALSE;
 #endif /* HAVE_SSL */