2007-09-22 [colin] 3.0.1cvs23
authorColin Leroy <colin@colino.net>
Sat, 22 Sep 2007 12:03:56 +0000 (12:03 +0000)
committerColin Leroy <colin@colino.net>
Sat, 22 Sep 2007 12:03:56 +0000 (12:03 +0000)
* src/imap.c
* src/procmsg.h
* src/common/utils.c
* src/common/utils.h
* src/etpan/imap-thread.c
Optimise fetching IMAP cached emails *a lot*
(remember whether mail is fully cached and \r's
 are already stripped)

ChangeLog
PATCHSETS
configure.ac
src/common/utils.c
src/common/utils.h
src/etpan/imap-thread.c
src/imap.c
src/procmsg.h

index b4f4a014a06e7030645e28756a2411fb06ff1c42..9f9fd873920184a19957cdbb5d9e91d0cf328a10 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-09-22 [colin]     3.0.1cvs23
+
+       * src/imap.c
+       * src/procmsg.h
+       * src/common/utils.c
+       * src/common/utils.h
+       * src/etpan/imap-thread.c
+               Optimise fetching IMAP cached emails *a lot*
+               (remember whether mail is fully cached and \r's
+                are already stripped)
+
 2007-09-22 [colin]     3.0.1cvs22
 
        * src/folder.c
 2007-09-22 [colin]     3.0.1cvs22
 
        * src/folder.c
index ea6495ad69a6d7fbff82f45577aad43568823f14..034a7143a84ffda6ba8d853352c05ec5897f6b23 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.12.2.42 -r 1.12.2.43 src/gtk/prefswindow.c;  ) > 3.0.1cvs20.patchset
 ( cvs diff -u -r 1.395.2.326 -r 1.395.2.327 src/summaryview.c;  ) > 3.0.1cvs21.patchset
 ( cvs diff -u -r 1.213.2.161 -r 1.213.2.162 src/folder.c;  cvs diff -u -r 1.87.2.47 -r 1.87.2.48 src/folder.h;  cvs diff -u -r 1.52.2.49 -r 1.52.2.50 src/prefs_folder_item.c;  ) > 3.0.1cvs22.patchset
 ( cvs diff -u -r 1.12.2.42 -r 1.12.2.43 src/gtk/prefswindow.c;  ) > 3.0.1cvs20.patchset
 ( cvs diff -u -r 1.395.2.326 -r 1.395.2.327 src/summaryview.c;  ) > 3.0.1cvs21.patchset
 ( cvs diff -u -r 1.213.2.161 -r 1.213.2.162 src/folder.c;  cvs diff -u -r 1.87.2.47 -r 1.87.2.48 src/folder.h;  cvs diff -u -r 1.52.2.49 -r 1.52.2.50 src/prefs_folder_item.c;  ) > 3.0.1cvs22.patchset
+( cvs diff -u -r 1.179.2.187 -r 1.179.2.188 src/imap.c;  cvs diff -u -r 1.60.2.47 -r 1.60.2.48 src/procmsg.h;  cvs diff -u -r 1.36.2.113 -r 1.36.2.114 src/common/utils.c;  cvs diff -u -r 1.20.2.50 -r 1.20.2.51 src/common/utils.h;  cvs diff -u -r 1.1.4.84 -r 1.1.4.85 src/etpan/imap-thread.c;  ) > 3.0.1cvs23.patchset
index 78336968753923adfca16db2cd3baa46d4fc7692..4af4dfd134be75f25bbfbc3523639137ec90f730 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=0
 MICRO_VERSION=1
 INTERFACE_AGE=0
 BINARY_AGE=0
 MICRO_VERSION=1
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=22
+EXTRA_VERSION=23
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 0557dfc669dc505cbadb58bff5efdcd072694d50..0b2adc7275a716e3a0dbcab6d6f8fe86a5d31730 100644 (file)
@@ -483,7 +483,7 @@ gchar *strcrchomp(gchar *str)
        return str;
 }
 
        return str;
 }
 
-void file_strip_crs(const gchar *file)
+gint file_strip_crs(const gchar *file)
 {
        FILE *fp = NULL, *outfp = NULL;
        gchar buf[4096];
 {
        FILE *fp = NULL, *outfp = NULL;
        gchar buf[4096];
@@ -503,14 +503,27 @@ void file_strip_crs(const gchar *file)
 
        while (fgets(buf, sizeof (buf), fp) != NULL) {
                strcrchomp(buf);
 
        while (fgets(buf, sizeof (buf), fp) != NULL) {
                strcrchomp(buf);
-               fputs(buf, outfp);
+               if (fputs(buf, outfp) == EOF) {
+                       fclose(fp);
+                       fclose(outfp);
+                       goto unlinkout;
+               }
        }
 
        fclose(fp);
        }
 
        fclose(fp);
-       fclose(outfp);
-       rename_force(out, file);
+       if (fclose(outfp) == EOF) {
+               goto unlinkout;
+       }
+       
+       if (rename_force(out, file) < 0)
+               goto unlinkout;
+       
+       return 0;
+unlinkout:
+       g_unlink(out);
 freeout:
        g_free(out);
 freeout:
        g_free(out);
+       return -1;
 }
 
 /* Similar to `strstr' but this function ignores the case of both strings.  */
 }
 
 /* Similar to `strstr' but this function ignores the case of both strings.  */
index c352ec6b10ad593ecc0d61c1fc2387fecb2f874d..f335211a2edb3b06a8246ce70f019fd19505b336 100644 (file)
@@ -262,7 +262,7 @@ gchar *strretchomp  (gchar          *str);
 gchar *strtailchomp    (gchar          *str,
                         gchar           tail_char);
 gchar *strcrchomp      (gchar          *str);
 gchar *strtailchomp    (gchar          *str,
                         gchar           tail_char);
 gchar *strcrchomp      (gchar          *str);
-void file_strip_crs    (const gchar    *file);
+gint file_strip_crs    (const gchar    *file);
 gchar *strcasestr      (const gchar    *haystack,
                         const gchar    *needle);
 gpointer my_memmem     (gconstpointer   haystack,
 gchar *strcasestr      (const gchar    *haystack,
                         const gchar    *needle);
 gpointer my_memmem     (gconstpointer   haystack,
index e8c8af5fb2d9a371ea030de4191a4eb20e8a0714..400499fcb4cfffdb86a18495ba65b927e15fafbc 100644 (file)
@@ -2270,7 +2270,7 @@ static void fetch_content_run(struct etpan_thread_op * op)
                }
                
                r = fwrite(content, 1, content_size, f);
                }
                
                r = fwrite(content, 1, content_size, f);
-               if (r == 0) {
+               if (r < content_size) {
                        goto fclose;
                }
                
                        goto fclose;
                }
                
index c87dca24325aa4e631340b188c60245b0372b53d..6a7cbf969d8f06c5c7a32522d85997379f2a05df 100644 (file)
@@ -1063,22 +1063,40 @@ static gchar *imap_fetch_msg_full(Folder *folder, FolderItem *item, gint uid,
                 * or not. As the IMAP server reports size with \r chars,
                 * we have to update the local file (UNIX \n only) size */
                MsgInfo *cached = msgcache_get_msg(item->cache,uid);
                 * or not. As the IMAP server reports size with \r chars,
                 * we have to update the local file (UNIX \n only) size */
                MsgInfo *cached = msgcache_get_msg(item->cache,uid);
-               guint have_size = get_file_size_with_crs(filename);
+               guint have_size = -1;
 
                if (cached)
 
                if (cached)
-                       debug_print("message %d has been already %scached (%d/%d).\n", uid,
-                               have_size >= cached->size ? "fully ":"",
-                               have_size, (int)cached->size);
+                       debug_print("message %d has been already %scached.\n", uid,
+                               MSG_IS_FULLY_CACHED(cached->flags) ? "fully ":"");
                
                
-               if (cached && (cached->size <= have_size || !body)) {
+               if (!cached || !MSG_IS_FULLY_CACHED(cached->flags)) {
+                       have_size = get_file_size_with_crs(filename);
+                       if (cached && (cached->size <= have_size || !body)) {
+                               procmsg_msginfo_free(cached);
+                               ok = file_strip_crs(filename);
+                               if (ok == 0 && cached && cached->size <= have_size) {
+                                       /* we have it all and stripped */
+                                       debug_print("...fully cached in fact; setting flag.\n");
+                                       procmsg_msginfo_set_flags(cached, MSG_FULLY_CACHED, 0);
+                               }
+                               return filename;
+                       } else if (!cached && time(NULL) - get_file_mtime(filename) < 60) {
+                               debug_print("message not cached and file recent, considering file complete\n");
+                               ok = file_strip_crs(filename);
+                               if (ok == 0)
+                                       return filename;
+                       } else {
+                               procmsg_msginfo_free(cached);
+                       }
+               }
+               if (cached && MSG_IS_FULLY_CACHED(cached->flags)) {
                        procmsg_msginfo_free(cached);
                        procmsg_msginfo_free(cached);
-                       file_strip_crs(filename);
-                       return filename;
-               } else if (!cached && time(NULL) - get_file_mtime(filename) < 60) {
-                       debug_print("message not cached and file recent, considering file complete\n");
-                       file_strip_crs(filename);
                        return filename;
                        return filename;
-               } else {
+               }
+       } else {
+               MsgInfo *cached = msgcache_get_msg(item->cache,uid);
+               if (cached) {
+                       procmsg_msginfo_unset_flags(cached, MSG_FULLY_CACHED, 0);
                        procmsg_msginfo_free(cached);
                }
        }
                        procmsg_msginfo_free(cached);
                }
        }
@@ -1112,7 +1130,21 @@ static gchar *imap_fetch_msg_full(Folder *folder, FolderItem *item, gint uid,
        }
 
        unlock_session(session);
        }
 
        unlock_session(session);
-       file_strip_crs(filename);
+       ok = file_strip_crs(filename);
+
+       if (ok == 0 && headers && body) {
+               MsgInfo *cached = msgcache_get_msg(item->cache,uid);
+               if (cached) {
+                       procmsg_msginfo_set_flags(cached, MSG_FULLY_CACHED, 0);
+                       procmsg_msginfo_free(cached);
+               }
+       } else if (ok == -1) {
+               MsgInfo *cached = msgcache_get_msg(item->cache,uid);
+               if (cached) {
+                       procmsg_msginfo_unset_flags(cached, MSG_FULLY_CACHED, 0);
+                       procmsg_msginfo_free(cached);
+               }
+       }
        return filename;
 }
 
        return filename;
 }
 
@@ -1125,6 +1157,10 @@ static gboolean imap_is_msg_fully_cached(Folder *folder, FolderItem *item, gint
        if (!cached)
                return FALSE;
 
        if (!cached)
                return FALSE;
 
+       if (MSG_IS_FULLY_CACHED(cached->flags)) {
+               procmsg_msginfo_free(cached);
+               return TRUE;
+       }
        path = folder_item_get_path(item);
        if (!is_dir_exist(path))
                return FALSE;
        path = folder_item_get_path(item);
        if (!is_dir_exist(path))
                return FALSE;
@@ -1135,6 +1171,7 @@ static gboolean imap_is_msg_fully_cached(Folder *folder, FolderItem *item, gint
                if (cached && cached->total_size == cached->size) {
                        /* fast path */
                        g_free(filename);
                if (cached && cached->total_size == cached->size) {
                        /* fast path */
                        g_free(filename);
+                       procmsg_msginfo_set_flags(cached, MSG_FULLY_CACHED, 0);
                        return TRUE;
                }
                size = get_file_size_with_crs(filename);
                        return TRUE;
                }
                size = get_file_size_with_crs(filename);
@@ -1142,6 +1179,7 @@ static gboolean imap_is_msg_fully_cached(Folder *folder, FolderItem *item, gint
        }
        if (cached && size >= cached->size) {
                cached->total_size = cached->size;
        }
        if (cached && size >= cached->size) {
                cached->total_size = cached->size;
+               procmsg_msginfo_set_flags(cached, MSG_FULLY_CACHED, 0);
                procmsg_msginfo_free(cached);
                return TRUE;
        }
                procmsg_msginfo_free(cached);
                return TRUE;
        }
@@ -1496,9 +1534,9 @@ static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest,
        IMAP_FOLDER_ITEM(dest)->uid_next = 0;
        g_slist_free(IMAP_FOLDER_ITEM(dest)->uid_list);
        IMAP_FOLDER_ITEM(dest)->uid_list = NULL;
        IMAP_FOLDER_ITEM(dest)->uid_next = 0;
        g_slist_free(IMAP_FOLDER_ITEM(dest)->uid_list);
        IMAP_FOLDER_ITEM(dest)->uid_list = NULL;
-       imap_scan_required(folder, dest);
 
        unlock_session(session);
 
        unlock_session(session);
+       imap_scan_required(folder, dest);
        if (ok == IMAP_SUCCESS)
                return last_num;
        else
        if (ok == IMAP_SUCCESS)
                return last_num;
        else
index c7fee40ed91e0377ca3da38c50f5997642fbecb8..8ee667429af9fb0fe880566e8112212d1a221e08 100644 (file)
@@ -87,6 +87,7 @@ typedef GSList MsgNumberList;
 #define MSG_SPAM               (1U << 13)   /* new one */ 
 #define MSG_POSTFILTERED       (1U << 14)
 #define MSG_WATCH_THREAD       (1U << 15)   /* watch threads */
 #define MSG_SPAM               (1U << 13)   /* new one */ 
 #define MSG_POSTFILTERED       (1U << 14)
 #define MSG_WATCH_THREAD       (1U << 15)   /* watch threads */
+#define MSG_FULLY_CACHED       (1U << 16)   /* IMAP: fully cached */
                                                
 /* RESERVED */
 #define        MSG_RESERVED_CLAWS      (1U << 30)   /* for claws-mail */
                                                
 /* RESERVED */
 #define        MSG_RESERVED_CLAWS      (1U << 30)   /* for claws-mail */
@@ -161,6 +162,7 @@ typedef guint32 MsgTmpFlags;
 #define MSG_IS_RETRCPT_SENT(msg)       (((msg).perm_flags & MSG_RETRCPT_SENT) != 0)
 #define MSG_IS_SPAM(msg)               (((msg).perm_flags & MSG_SPAM) != 0)
 #define MSG_IS_WATCH_THREAD(msg)       (((msg).perm_flags & MSG_WATCH_THREAD) != 0)
 #define MSG_IS_RETRCPT_SENT(msg)       (((msg).perm_flags & MSG_RETRCPT_SENT) != 0)
 #define MSG_IS_SPAM(msg)               (((msg).perm_flags & MSG_SPAM) != 0)
 #define MSG_IS_WATCH_THREAD(msg)       (((msg).perm_flags & MSG_WATCH_THREAD) != 0)
+#define MSG_IS_FULLY_CACHED(msg)       (((msg).perm_flags & MSG_FULLY_CACHED) != 0)
 
 #define MSGINFO_UPDATE_HOOKLIST "msginfo_update"
 #define MAIL_FILTERING_HOOKLIST "mail_filtering_hooklist"
 
 #define MSGINFO_UPDATE_HOOKLIST "msginfo_update"
 #define MAIL_FILTERING_HOOKLIST "mail_filtering_hooklist"