From 7ed66fac42704097175f778660e391e86cc6d55d Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Fri, 27 Sep 2002 20:20:08 +0000 Subject: New function to decode the INTERNALDATE response from an IMAP server so we 2002-09-27 Jeffrey Stedfast * 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 * 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. svn path=/trunk/; revision=18252 --- camel/ChangeLog | 16 +++++ camel/broken-date-parser.c | 2 +- camel/camel-tcp-stream-ssl.c | 20 ++++--- camel/providers/imap/camel-imap-folder.c | 100 ++++++++++++++++++++++++++++++- camel/providers/imap/camel-imap-store.c | 36 +++++++---- 5 files changed, 152 insertions(+), 22 deletions(-) (limited to 'camel') diff --git a/camel/ChangeLog b/camel/ChangeLog index 6771d2328e..95abd36ba9 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,19 @@ +2002-09-27 Jeffrey Stedfast + + * 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 + + * 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 * providers/imap/camel-imap-folder.c (imap_update_summary): Use diff --git a/camel/broken-date-parser.c b/camel/broken-date-parser.c index cba19208b4..238665cb93 100644 --- a/camel/broken-date-parser.c +++ b/camel/broken-date-parser.c @@ -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; diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c index ed539451ad..09e5c94a02 100644 --- a/camel/camel-tcp-stream-ssl.c +++ b/camel/camel-tcp-stream-ssl.c @@ -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; diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 1365c720eb..23800bdefc 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -38,6 +38,7 @@ #include #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; diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index fbc1e20555..f854d78a11 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -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 */ -- cgit v1.2.3