From 47d864c709acf663365af2dd539cbc88bfb87a86 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 11 Jan 2001 22:04:29 +0000 Subject: New function to check for added/deleted messages when re-selecting a * providers/imap/camel-imap-folder.c (camel_imap_folder_selected): New function to check for added/deleted messages when re-selecting a folder. (imap_refresh_info, imap_rescan, imap_update_summary): Various locking tweaks that turn out to be irrelevant since command_lock is recursive, but whatever. * providers/imap/camel-imap-command.c (camel_imap_command): When selecting a new folder, call camel_imap_folder_selected on it. svn path=/trunk/; revision=7410 --- camel/providers/imap/camel-imap-command.c | 1 + camel/providers/imap/camel-imap-folder.c | 82 +++++++++++++++++++++++++++++-- camel/providers/imap/camel-imap-folder.h | 4 ++ 3 files changed, 83 insertions(+), 4 deletions(-) (limited to 'camel/providers') diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c index b242dd122c..af61ed0981 100644 --- a/camel/providers/imap/camel-imap-command.c +++ b/camel/providers/imap/camel-imap-command.c @@ -96,6 +96,7 @@ camel_imap_command (CamelImapStore *store, CamelFolder *folder, if (!fmt) return response; + camel_imap_folder_selected (folder, response, ex); camel_imap_response_free (response); } diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 302ddee88f..d3ba77478e 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -207,6 +207,78 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name, return folder; } +/* Called with the store's command_lock locked */ +void +camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response, + CamelException *ex) +{ + unsigned long exists, val, uid; + CamelMessageInfo *info; + int i, count; + char *resp; + + for (i = 0; i < response->untagged->len; i++) { + resp = response->untagged->pdata[i] + 2; + + exists = strtoul (resp, &resp, 10); + if (!g_strncasecmp (resp, " EXISTS", 7)) + break; + } + if (i == response->untagged->len) { + g_warning ("Server response did not include EXISTS info"); + return; + } + + count = camel_folder_summary_count (folder->summary); + + /* If we've lost messages, we have to rescan everything */ + if (exists < count) { + imap_rescan (folder, count, ex); + return; + } + + /* Similarly, if the UID of the highest message we know about + * has changed, then that indicates that messages have been + * both added and removed, so we have to rescan to find the + * removed ones. (We pass NULL for the folder since we know + * that this folder is selected, and we don't want + * camel_imap_command to worry about it.) + */ + response = camel_imap_command (CAMEL_IMAP_STORE (folder->parent_store), + NULL, ex, "FETCH %d UID", count); + if (!response) + return; + uid = 0; + for (i = 0; i < response->untagged->len; i++) { + resp = response->untagged->pdata[i]; + val = strtoul (resp + 2, &resp, 10); + if (val != count || g_strncasecmp (resp, " FETCH (", 8) != 0) + continue; + resp = e_strstrcase (resp, "UID "); + if (!resp) + continue; + uid = strtoul (resp + 4, NULL, 10); + break; + } + camel_imap_response_free (response); + + info = camel_folder_summary_index (folder->summary, count - 1); + val = strtoul (camel_message_info_uid (info), NULL, 10); + camel_folder_summary_info_free (folder->summary, info); + if (uid == 0 || uid != val) { + imap_rescan (folder, exists, ex); + return; + } + + /* OK. So now we know that no messages have been expunged. Whew. + * Now see if messages have been added. + */ + if (exists > count) + camel_imap_folder_changed (folder, exists, NULL, ex); + + /* And we're done. */ +} + static void imap_finalize (CamelObject *object) { @@ -224,9 +296,12 @@ imap_finalize (CamelObject *object) static void imap_refresh_info (CamelFolder *folder, CamelException *ex) { + CAMEL_IMAP_STORE_LOCK (folder->parent_store, command_lock); imap_rescan (folder, camel_folder_summary_count (folder->summary), ex); + CAMEL_IMAP_STORE_UNLOCK (folder->parent_store, command_lock); } +/* Called with the store's command_lock locked */ static void imap_rescan (CamelFolder *folder, int exists, CamelException *ex) { @@ -245,11 +320,9 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex) /* Get UIDs and flags of all messages. */ if (exists > 0) { - CAMEL_IMAP_STORE_LOCK(store, command_lock); response = camel_imap_command (store, folder, ex, "FETCH 1:%d (UID FLAGS)", exists); - CAMEL_IMAP_STORE_UNLOCK(store, command_lock); if (!response) return; @@ -570,6 +643,7 @@ imap_protocol_get_summary_specifier (CamelImapStore *store) headers_wanted, sect_end); } +/* Called with the store's command_lock locked */ static void imap_update_summary (CamelFolder *folder, int first, int last, CamelFolderChangeInfo *changes, CamelException *ex) @@ -583,7 +657,7 @@ imap_update_summary (CamelFolder *folder, int first, int last, int i; summary_specifier = imap_protocol_get_summary_specifier (store); - CAMEL_IMAP_STORE_LOCK(store, command_lock); + /* We already have the command lock */ if (first == last) { response = camel_imap_command (store, folder, ex, "FETCH %d (%s)", first, @@ -593,7 +667,6 @@ imap_update_summary (CamelFolder *folder, int first, int last, "FETCH %d:%d (%s)", first, last, summary_specifier); } - CAMEL_IMAP_STORE_UNLOCK(store, command_lock); g_free (summary_specifier); if (!response) @@ -708,6 +781,7 @@ imap_search_free (CamelFolder *folder, GPtrArray *uids) CAMEL_IMAP_FOLDER_UNLOCK(folder, search_lock); } +/* Called with the store's command_lock locked */ void camel_imap_folder_changed (CamelFolder *folder, int exists, GArray *expunged, CamelException *ex) diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h index 6863782c8a..a943189f5a 100644 --- a/camel/providers/imap/camel-imap-folder.h +++ b/camel/providers/imap/camel-imap-folder.h @@ -66,6 +66,10 @@ CamelFolder *camel_imap_folder_new (CamelStore *parent, const char *summary_file, CamelException *ex); +void camel_imap_folder_selected (CamelFolder *folder, + CamelImapResponse *response, + CamelException *ex); + void camel_imap_folder_changed (CamelFolder *folder, int exists, GArray *expunged, CamelException *ex); -- cgit v1.2.3