diff options
author | Peter Williams <peterw@ximian.com> | 2002-08-01 23:52:38 +0800 |
---|---|---|
committer | Peter Williams <peterw@src.gnome.org> | 2002-08-01 23:52:38 +0800 |
commit | c89f5e6986b6f4ea6d5ee5104e0b052e6916d081 (patch) | |
tree | 3a5577dc01e102ebe5b71313f5c8a37453917580 /camel/providers | |
parent | 1a8f31eb034c28a588b9bb3f2b838ea03b2b4c7c (diff) | |
download | gsoc2013-evolution-c89f5e6986b6f4ea6d5ee5104e0b052e6916d081.tar.gz gsoc2013-evolution-c89f5e6986b6f4ea6d5ee5104e0b052e6916d081.tar.zst gsoc2013-evolution-c89f5e6986b6f4ea6d5ee5104e0b052e6916d081.zip |
camel:
2002-07-29 Peter Williams <peterw@ximian.com>
Fix bug #28238
* providers/imap/camel-imap-store.c (imap_forget_folder): New
function, breaking out the code in delete_folder() to handle when
a folder is removed.
(imap_folder_effectively_unsubscribed): New function, breaking out
the code in unsubscribe_folder() to handle when a folder is
unsubscribed.
(imap_check_folder_still_extant): New function, check whether a
folder exists by LIST'ing it.
(imap_store_refresh_folders): Add code here to check if the folder
still exists if we're unable to refresh its info. If so, pretend
that it was unsubscribed (to get the mailer to remove it from
the tree) and delete its cache. If somehow this goofs up, the
worst that can happen is that we must redownload the headers.
(get_folder_status): If we can't get the status, behave as above.
(delete_folder): Call imap_forget_folder() where the bulk of this
code has gone.
(unsubscribe_folder): Call imap_folder_effectively_unsubscribed()
where the bulk of this code has gone.
mail:
2002-07-31 Peter Williams <peterw@ximian.com>
* mail-folder-cache.c: Add another bitfield "unsub"
(real_flush_updates): If unsubscribing, manually remove the folder
from the shell.
(unset_folder_info): Add another parameter which is used to set
the unsub member.
(store_folder_unsubscribed): Pass true for @unsub.
(unset_folder_info_hash): Pass false for @unsub.
* subscribe-dialog.c (fe_done_subscribing): Don't notify the shell
here. The folder cache does it now, and it was broken to make the
CORBA call in another thread anyway.
svn path=/trunk/; revision=17669
Diffstat (limited to 'camel/providers')
-rw-r--r-- | camel/providers/imap/camel-imap-store.c | 263 |
1 files changed, 171 insertions, 92 deletions
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index 7781316f27..daee1cde70 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -112,6 +112,16 @@ static void unsubscribe_folder (CamelStore *store, const char *folder_name, static void get_folders_online (CamelImapStore *imap_store, const char *pattern, GPtrArray *folders, gboolean lsub, CamelException *ex); + +static void imap_folder_effectively_unsubscribed(CamelImapStore *imap_store, + const char *folder_name, CamelException *ex); + +static gboolean imap_check_folder_still_extant (CamelImapStore *imap_store, const char *full_name, + CamelException *ex); + +static void imap_forget_folder(CamelImapStore *imap_store, const char *folder_name, + CamelException *ex); + static void camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class) { @@ -754,6 +764,136 @@ query_auth_types (CamelService *service, CamelException *ex) } static void +imap_folder_effectively_unsubscribed(CamelImapStore *imap_store, + const char *folder_name, CamelException *ex) +{ + gpointer key, value; + CamelFolderInfo *fi; + const char *name; + + if (g_hash_table_lookup_extended (imap_store->subscribed_folders, + folder_name, &key, &value)) { + g_hash_table_remove (imap_store->subscribed_folders, key); + g_free (key); + } + + if (imap_store->renaming) { + /* we don't need to emit a "folder_unsubscribed" signal + if we are in the process of renaming folders, so we + are done here... */ + return; + } + + name = strrchr (folder_name, imap_store->dir_sep); + if (name) + name++; + else + name = folder_name; + + fi = g_new0 (CamelFolderInfo, 1); + fi->full_name = g_strdup (folder_name); + fi->name = g_strdup (name); + fi->url = g_strdup_printf ("%s/%s", imap_store->base_url, folder_name); + fi->unread_message_count = -1; + camel_folder_info_build_path (fi, imap_store->dir_sep); + + camel_object_trigger_event (CAMEL_OBJECT (imap_store), "folder_unsubscribed", fi); + camel_folder_info_free (fi); +} + +static void +imap_forget_folder(CamelImapStore *imap_store, const char *folder_name, CamelException *ex) +{ + CamelFolderSummary *summary; + CamelImapMessageCache *cache; + char *summary_file; + char *journal_file; + char *folder_dir, *storage_path; + CamelFolderInfo *fi; + const char *name; + + storage_path = g_strdup_printf("%s/folders", imap_store->storage_path); + folder_dir = e_path_to_physical (storage_path, folder_name); + g_free(storage_path); + if (access (folder_dir, F_OK) != 0) { + g_free (folder_dir); + goto event; + } + + summary_file = g_strdup_printf ("%s/summary", folder_dir); + summary = camel_imap_summary_new (summary_file); + if (!summary) { + g_free (summary_file); + g_free (folder_dir); + goto event; + } + + cache = camel_imap_message_cache_new (folder_dir, summary, ex); + if (cache) + camel_imap_message_cache_clear (cache); + + camel_object_unref (CAMEL_OBJECT (cache)); + camel_object_unref (CAMEL_OBJECT (summary)); + + unlink (summary_file); + g_free (summary_file); + + journal_file = g_strdup_printf ("%s/summary", folder_dir); + unlink (journal_file); + g_free (journal_file); + + rmdir (folder_dir); + g_free (folder_dir); + + name = strrchr (folder_name, imap_store->dir_sep); + if (name) + name++; + else + name = folder_name; + + event: + + fi = g_new0 (CamelFolderInfo, 1); + fi->full_name = g_strdup (folder_name); + fi->name = g_strdup (name); + fi->url = g_strdup_printf ("%s/%s", imap_store->base_url, folder_name); + fi->unread_message_count = -1; + camel_folder_info_build_path (fi, imap_store->dir_sep); + camel_object_trigger_event (CAMEL_OBJECT (imap_store), "folder_deleted", fi); + camel_folder_info_free (fi); +} + +static gboolean +imap_check_folder_still_extant (CamelImapStore *imap_store, const char *full_name, + CamelException *ex) +{ + CamelImapResponse *response; + + response = camel_imap_command (imap_store, NULL, ex, "LIST \"\" %S", + full_name); + + if (response) { + gboolean stillthere = FALSE; + + if (response->untagged->len) + stillthere = TRUE; + + camel_imap_response_free_without_processing (imap_store, response); + + if (stillthere) + return TRUE; + } + + /* either LIST command was rejected or it gave no results, + * we can be sure that the folder is gone. */ + + camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID, + _("The folder %s no longer exists"), + full_name); + return FALSE; +} + +static void copy_folder(char *key, CamelFolder *folder, GPtrArray *out) { g_ptr_array_add(out, folder); @@ -781,11 +921,26 @@ imap_store_refresh_folders (CamelImapStore *store, CamelException *ex) for (i = 0; i <folders->len; i++) { CamelFolder *folder = folders->pdata[i]; - + CAMEL_IMAP_FOLDER (folder)->need_rescan = TRUE; if (!camel_exception_is_set(ex)) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->refresh_info(folder, ex); - camel_object_unref((CamelObject *)folder); + + if (camel_exception_is_set (ex) && + imap_check_folder_still_extant (store, folder->full_name, ex) == FALSE) { + gchar *namedup; + + /* the folder was deleted (may happen when we come back online + * after being offline */ + + namedup = g_strdup (folder->full_name); + camel_object_unref((CamelObject *)folder); + imap_folder_effectively_unsubscribed (store, namedup, ex); + imap_forget_folder (store, namedup, ex); + camel_exception_clear (ex); + g_free (namedup); + } else + camel_object_unref((CamelObject *)folder); } g_ptr_array_free (folders, TRUE); @@ -981,7 +1136,7 @@ imap_connect_online (CamelService *service, CamelException *ex) FILE *storeinfo; int i, flags; size_t len; - + CAMEL_IMAP_STORE_LOCK (store, command_lock); if (!connect_to_server_wrapper (service, ex) || !imap_auth_loop (service, ex)) { @@ -1285,8 +1440,17 @@ get_folder_status (CamelImapStore *imap_store, const char *folder_name, const ch folder_name, type); - if (!response) + if (!response) { + CamelException ex; + + camel_exception_init (&ex); + if (imap_check_folder_still_extant (imap_store, folder_name, &ex) == FALSE) { + imap_folder_effectively_unsubscribed (imap_store, folder_name, &ex); + imap_forget_folder (imap_store, folder_name, &ex); + } + camel_exception_clear (&ex); return -1; + } status = camel_imap_response_extract (imap_store, response, "STATUS", NULL); @@ -1434,63 +1598,8 @@ delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) folder_name); if (response) { - CamelFolderSummary *summary; - CamelImapMessageCache *cache; - char *summary_file; - char *journal_file; - char *folder_dir, *storage_path; - CamelFolderInfo *fi; - const char *name; - camel_imap_response_free (imap_store, response); - - storage_path = g_strdup_printf("%s/folders", imap_store->storage_path); - folder_dir = e_path_to_physical (storage_path, folder_name); - g_free(storage_path); - if (access (folder_dir, F_OK) != 0) { - g_free (folder_dir); - return; - } - - summary_file = g_strdup_printf ("%s/summary", folder_dir); - summary = camel_imap_summary_new (summary_file); - if (!summary) { - g_free (summary_file); - g_free (folder_dir); - return; - } - - cache = camel_imap_message_cache_new (folder_dir, summary, ex); - if (cache) - camel_imap_message_cache_clear (cache); - - camel_object_unref (CAMEL_OBJECT (cache)); - camel_object_unref (CAMEL_OBJECT (summary)); - - unlink (summary_file); - g_free (summary_file); - - journal_file = g_strdup_printf ("%s/summary", folder_dir); - unlink (journal_file); - g_free (journal_file); - - rmdir (folder_dir); - g_free (folder_dir); - - name = strrchr (folder_name, imap_store->dir_sep); - if (name) - name++; - else - name = folder_name; - - fi = g_new0 (CamelFolderInfo, 1); - fi->full_name = g_strdup (folder_name); - fi->name = g_strdup (name); - fi->url = g_strdup_printf ("%s/%s", imap_store->base_url, folder_name); - fi->unread_message_count = -1; - camel_folder_info_build_path (fi, imap_store->dir_sep); - camel_object_trigger_event (CAMEL_OBJECT (store), "folder_deleted", fi); - camel_folder_info_free (fi); + imap_forget_folder (imap_store, folder_name, ex); } } @@ -2179,9 +2288,6 @@ unsubscribe_folder (CamelStore *store, const char *folder_name, { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); CamelImapResponse *response; - gpointer key, value; - CamelFolderInfo *fi; - const char *name; if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex)) return; @@ -2193,35 +2299,8 @@ unsubscribe_folder (CamelStore *store, const char *folder_name, if (!response) return; camel_imap_response_free (imap_store, response); - - if (g_hash_table_lookup_extended (imap_store->subscribed_folders, - folder_name, &key, &value)) { - g_hash_table_remove (imap_store->subscribed_folders, key); - g_free (key); - } - - if (imap_store->renaming) { - /* we don't need to emit a "folder_unsubscribed" signal - if we are in the process of renaming folders, so we - are done here... */ - return; - } - - name = strrchr (folder_name, imap_store->dir_sep); - if (name) - name++; - else - name = folder_name; - - fi = g_new0 (CamelFolderInfo, 1); - fi->full_name = g_strdup (folder_name); - fi->name = g_strdup (name); - fi->url = g_strdup_printf ("%s/%s", imap_store->base_url, folder_name); - fi->unread_message_count = -1; - camel_folder_info_build_path (fi, imap_store->dir_sep); - - camel_object_trigger_event (CAMEL_OBJECT (store), "folder_unsubscribed", fi); - camel_folder_info_free (fi); + + imap_folder_effectively_unsubscribed (imap_store, folder_name, ex); } #if 0 |