aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Williams <peterw@ximian.com>2002-08-01 23:52:38 +0800
committerPeter Williams <peterw@src.gnome.org>2002-08-01 23:52:38 +0800
commitc89f5e6986b6f4ea6d5ee5104e0b052e6916d081 (patch)
tree3a5577dc01e102ebe5b71313f5c8a37453917580
parent1a8f31eb034c28a588b9bb3f2b838ea03b2b4c7c (diff)
downloadgsoc2013-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
-rw-r--r--camel/ChangeLog23
-rw-r--r--camel/providers/imap/camel-imap-store.c263
-rw-r--r--mail/ChangeLog14
-rw-r--r--mail/mail-folder-cache.c11
-rw-r--r--mail/subscribe-dialog.c1
5 files changed, 216 insertions, 96 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 22355a69b7..ed4b1c1477 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,26 @@
+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.
+
2002-07-31 Jeffrey Stedfast <fejj@ximian.com>
* providers/imap/camel-imap-folder.c (parse_fetch_response):
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
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 0fbcac4fb1..ca365eefb5 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,17 @@
+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.
+
2002-08-01 Jeffrey Stedfast <fejj@ximian.com>
* mail-format.c (setup_mime_tables): Don't setup a handler for
diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c
index 5d7f1c879e..ab49fd0c25 100644
--- a/mail/mail-folder-cache.c
+++ b/mail/mail-folder-cache.c
@@ -76,6 +76,7 @@ struct _folder_update {
unsigned int remove:1; /* removing from vfolders */
unsigned int delete:1; /* deleting as well? */
unsigned int add:1; /* add to vfolder */
+ unsigned int unsub:1; /* unsubcribing? */
char *path;
char *name;
@@ -159,6 +160,8 @@ real_flush_updates(void *o, void *event_data, void *data)
mail_vfolder_delete_uri(up->store, up->uri);
mail_filter_delete_uri(up->store, up->uri);
mail_config_uri_deleted(CAMEL_STORE_CLASS(CAMEL_OBJECT_GET_CLASS(up->store))->compare_folder_name, up->uri);
+ if (up->unsub)
+ evolution_storage_removed_folder (storage, up->path);
} else
mail_vfolder_add_uri(up->store, up->uri, TRUE);
} else {
@@ -222,7 +225,7 @@ flush_updates(void)
}
static void
-unset_folder_info(struct _folder_info *mfi, int delete)
+unset_folder_info(struct _folder_info *mfi, int delete, int unsub)
{
struct _folder_update *up;
@@ -242,7 +245,9 @@ unset_folder_info(struct _folder_info *mfi, int delete)
up->remove = TRUE;
up->delete = delete;
+ up->unsub = unsub;
up->store = mfi->store_info->store;
+ up->path = g_strdup (mfi->path);
camel_object_ref((CamelObject *)up->store);
up->uri = g_strdup(mfi->uri);
@@ -496,7 +501,7 @@ store_folder_unsubscribed(CamelObject *o, void *event_data, void *data)
if (mfi) {
g_hash_table_remove(si->folders, mfi->full_name);
g_hash_table_remove(si->folders_uri, mfi->uri);
- unset_folder_info(mfi, TRUE);
+ unset_folder_info(mfi, TRUE, TRUE);
free_folder_info(mfi);
}
}
@@ -639,7 +644,7 @@ struct _update_data {
static void
unset_folder_info_hash(char *path, struct _folder_info *mfi, void *data)
{
- unset_folder_info(mfi, FALSE);
+ unset_folder_info(mfi, FALSE, FALSE);
}
static void
diff --git a/mail/subscribe-dialog.c b/mail/subscribe-dialog.c
index 878d95eebc..e9c42855c0 100644
--- a/mail/subscribe-dialog.c
+++ b/mail/subscribe-dialog.c
@@ -843,7 +843,6 @@ fe_done_subscribing (const char *full_name, const char *name, gboolean subscribe
closure->data->flags &= ~FTREE_NODE_SUBSCRIBED;
/* FIXME: recursively remove folder as well? Possible? */
- evolution_storage_removed_folder (closure->ftree->e_storage, path);
}
g_free (path);