aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2001-01-12 06:04:29 +0800
committerDan Winship <danw@src.gnome.org>2001-01-12 06:04:29 +0800
commit47d864c709acf663365af2dd539cbc88bfb87a86 (patch)
treec3b96161432a10599ce398e1417595168096706e /camel/providers/imap
parent093c24b9a767d2fa5bc29becc70bf935c9d01e7a (diff)
downloadgsoc2013-evolution-47d864c709acf663365af2dd539cbc88bfb87a86.tar.gz
gsoc2013-evolution-47d864c709acf663365af2dd539cbc88bfb87a86.tar.zst
gsoc2013-evolution-47d864c709acf663365af2dd539cbc88bfb87a86.zip
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
Diffstat (limited to 'camel/providers/imap')
-rw-r--r--camel/providers/imap/camel-imap-command.c1
-rw-r--r--camel/providers/imap/camel-imap-folder.c82
-rw-r--r--camel/providers/imap/camel-imap-folder.h4
3 files changed, 83 insertions, 4 deletions
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);