Doh. Don't remove things from the hash table while foreach'ing it. (And
authorDan Winship <danw@src.gnome.org>
Tue, 3 Jul 2001 15:24:55 +0000 (15:24 +0000)
committerDan Winship <danw@src.gnome.org>
Tue, 3 Jul 2001 15:24:55 +0000 (15:24 +0000)
* providers/imap/camel-imap-message-cache.c
(camel_imap_message_cache_clear): Doh. Don't remove things from
the hash table while foreach'ing it. (And can't use foreach_remove
either because we have to remove them in a weird order). Fixes
#3618.

* providers/imap/camel-imap-folder.c (imap_get_message): If the
server returns OK from the FETCH BODY, but there's no parseable
BODY response, it's probably because there's an UN-parseable BODY
response, implying the message is badly formatted, MIMEwise. In
that case, fall back to fetching the message as a single part.

camel/ChangeLog
camel/providers/imap/camel-imap-folder.c
camel/providers/imap/camel-imap-message-cache.c

index 7b5a045..5f9a0fd 100644 (file)
@@ -1,3 +1,17 @@
+2001-07-03  Dan Winship  <danw@ximian.com>
+
+       * providers/imap/camel-imap-message-cache.c
+       (camel_imap_message_cache_clear): Doh. Don't remove things from
+       the hash table while foreach'ing it. (And can't use foreach_remove
+       either because we have to remove them in a weird order). Fixes
+       #3618.
+
+       * providers/imap/camel-imap-folder.c (imap_get_message): If the
+       server returns OK from the FETCH BODY, but there's no parseable
+       BODY response, it's probably because there's an UN-parseable BODY
+       response, implying the message is badly formatted, MIMEwise. In
+       that case, fall back to fetching the message as a single part.
+
 2001-07-02  Sam Creasey <sammy@oh.verio.com>
 
         * providers/nntp/camel-nntp-folder.c: Implemented
index c04c6cb..4797d49 100644 (file)
@@ -1423,6 +1423,26 @@ get_message (CamelImapFolder *imap_folder, const char *uid,
 #define IMAP_SMALL_BODY_SIZE 5120
 
 static CamelMimeMessage *
+get_message_simple (CamelImapFolder *imap_folder, const char *uid,
+                   CamelStream *stream, CamelException *ex)
+{
+       CamelMimeMessage *msg;
+
+       if (!stream) {
+               stream = camel_imap_folder_fetch_data (imap_folder, uid, "",
+                                                      FALSE, ex);
+               if (!stream)
+                       return NULL;
+       }
+
+       msg = camel_mime_message_new ();
+       camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg),
+                                                 stream);
+       camel_object_unref (CAMEL_OBJECT (stream));
+       return msg;
+}
+
+static CamelMimeMessage *
 imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
 {
        CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@@ -1431,25 +1451,20 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
        CamelMimeMessage *msg;
        CamelStream *stream = NULL;
 
+       /* If the server doesn't support IMAP4rev1, or we already have
+        * the whole thing cached, fetch it in one piece.
+        */
+       if (store->server_level < IMAP_LEVEL_IMAP4REV1 ||
+           (stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, NULL)))
+               return get_message_simple (imap_folder, uid, stream, ex);
+
        mi = camel_folder_summary_uid (folder->summary, uid);
        g_return_val_if_fail (mi != NULL, NULL);
 
-       /* If the message is small, or the server doesn't support
-        * IMAP4rev1, or we already have the whole thing cached,
-        * fetch it in one piece.
-        */
-       if (mi->size < IMAP_SMALL_BODY_SIZE ||
-           store->server_level < IMAP_LEVEL_IMAP4REV1 ||
-           (stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, NULL))) {
+       /* If the message is small, fetch it in one piece. */
+       if (mi->size < IMAP_SMALL_BODY_SIZE) {
                camel_folder_summary_info_free (folder->summary, mi);
-               if (!stream)
-                       stream = camel_imap_folder_fetch_data (imap_folder, uid, "", FALSE, ex);
-               if (!stream)
-                       return NULL;
-               msg = camel_mime_message_new ();
-               camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream);
-               camel_object_unref (CAMEL_OBJECT (stream));
-               return msg;
+               return get_message_simple (imap_folder, uid, NULL, ex);
        }
 
        /* For larger messages, fetch the structure and build a message
@@ -1492,10 +1507,14 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
                camel_imap_response_free (store, response);
 
                if (!mi->content->type) {
-                       camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
-                                             _("Could not find message body in FETCH response."));
+                       /* FETCH returned OK, but we didn't parse a BODY
+                        * response. Courier will return invalid BODY
+                        * responses for invalidly MIMEd messages, so
+                        * fall back to fetching the entire thing and
+                        * let the mailer's "bad MIME" code handle it.
+                        */
                        camel_folder_summary_info_free (folder->summary, mi);
-                       return NULL;
+                       return get_message_simple (imap_folder, uid, NULL, ex);
                }
        }
 
index 2f811ee..d4f5694 100644 (file)
@@ -421,12 +421,11 @@ camel_imap_message_cache_remove (CamelImapMessageCache *cache, const char *uid)
        g_ptr_array_free (subparts, TRUE);
 }
 
-static gboolean
-clear_part (gpointer key, gpointer value, gpointer data)
+static void
+add_uids (gpointer key, gpointer value, gpointer data)
 {
        if (!strchr (key, '.'))
-               camel_imap_message_cache_remove (data, key);
-       return TRUE;
+               g_ptr_array_add (data, key);
 }
 
 /**
@@ -438,7 +437,15 @@ clear_part (gpointer key, gpointer value, gpointer data)
 void
 camel_imap_message_cache_clear (CamelImapMessageCache *cache)
 {
-       g_hash_table_foreach_remove (cache->parts, clear_part, cache);
+       GPtrArray *uids;
+       int i;
+
+       uids = g_ptr_array_new ();
+       g_hash_table_foreach (cache->parts, add_uids, uids);
+
+       for (i = 0; i < uids->len; i++)
+               camel_imap_message_cache_remove (cache, uids->pdata[i]);
+       g_ptr_array_free (uids, TRUE);
 }