From 956b17ed95a946949c51bfb6be9b4e358e764a45 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Wed, 4 Feb 2004 05:57:21 +0000 Subject: changed order around, first try to delete and only remove from the object 2004-02-04 Not Zed * camel-store.c (camel_store_delete_folder): changed order around, first try to delete and only remove from the object bag if the delete worked. If vjunk/vtrash enabled, don't allow those to be deleted. (cs_delete_cached_folder): helper to delete the folder if its in the cache, remove it from trash/junk, etc. (camel_store_unsubscribe_folder): changed similarly to delete_folder. * camel-vee-store.c (vee_delete_folder): dont do any trash/junk processing anymore. 2004-02-03 Not Zed * camel-store.c: use the folders object bag to manage the trash folder and junk folders. Remove the init_trash and init_junk stuff, just use get_trash and get_junk to mean the same thing. Get rid of the hacked up vjunk and vtrash "uri" stuff too. * camel-object.c (camel_object_bag_add): null out the pair->func, otherwise we get an uninitalised memory read during unhook event. svn path=/trunk/; revision=24603 --- camel/camel-store.c | 304 +++++++++++++++++++++++----------------------------- 1 file changed, 134 insertions(+), 170 deletions(-) (limited to 'camel/camel-store.c') diff --git a/camel/camel-store.c b/camel/camel-store.c index 44d20b3f7e..677c4a9586 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -50,10 +50,7 @@ static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); -static void init_trash (CamelStore *store); static CamelFolder *get_trash (CamelStore *store, CamelException *ex); - -static void init_junk (CamelStore *store); static CamelFolder *get_junk (CamelStore *store, CamelException *ex); static CamelFolderInfo *create_folder (CamelStore *store, @@ -96,9 +93,7 @@ camel_store_class_init (CamelStoreClass *camel_store_class) camel_store_class->compare_folder_name = g_str_equal; camel_store_class->get_folder = get_folder; camel_store_class->get_inbox = get_inbox; - camel_store_class->init_trash = init_trash; camel_store_class->get_trash = get_trash; - camel_store_class->init_junk = init_junk; camel_store_class->get_junk = get_junk; camel_store_class->create_folder = create_folder; camel_store_class->delete_folder = delete_folder; @@ -242,18 +237,33 @@ camel_store_get_folder (CamelStore *store, const char *folder_name, guint32 flag folder = camel_object_bag_reserve(store->folders, folder_name); if (!folder) { - folder = CS_CLASS (store)->get_folder (store, folder_name, flags, ex); - if (folder) { - /* Add the folder to the vTrash/vJunk folder if this store implements it */ - if (store->vtrash) - camel_vee_folder_add_folder (CAMEL_VEE_FOLDER (store->vtrash), folder); - if (store->vjunk) - camel_vee_folder_add_folder (CAMEL_VEE_FOLDER (store->vjunk), folder); - - if (store->folders) + if ((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0) + folder = CS_CLASS(store)->get_trash(store, ex); + else if ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0) + folder = CS_CLASS(store)->get_junk(store, ex); + else { + folder = CS_CLASS (store)->get_folder(store, folder_name, flags, ex); + if (folder) { + CamelVeeFolder *vfolder; + + if ((store->flags & CAMEL_STORE_VTRASH) + && (vfolder = camel_object_bag_get(store->folders, CAMEL_VTRASH_NAME))) { + camel_vee_folder_add_folder(vfolder, folder); + camel_object_unref(vfolder); + } + + if ((store->flags & CAMEL_STORE_VJUNK) + && (vfolder = camel_object_bag_get(store->folders, CAMEL_VJUNK_NAME))) { + camel_vee_folder_add_folder(vfolder, folder); + camel_object_unref(vfolder); + } + } + } + + if (store->folders) { + if (folder) camel_object_bag_add(store->folders, folder_name, folder); - } else { - if (store->folders) + else camel_object_bag_abort(store->folders, folder_name); } } @@ -302,6 +312,34 @@ camel_store_create_folder (CamelStore *store, const char *parent_name, return fi; } +/* deletes folder/removes it from the folder cache, if it's there */ +static void +cs_delete_cached_folder(CamelStore *store, const char *folder_name) +{ + CamelFolder *folder; + + if (store->folders + && (folder = camel_object_bag_get(store->folders, folder_name))) { + CamelVeeFolder *vfolder; + + if ((store->flags & CAMEL_STORE_VTRASH) + && (vfolder = camel_object_bag_get(store->folders, CAMEL_VTRASH_NAME))) { + camel_vee_folder_remove_folder(vfolder, folder); + camel_object_unref(vfolder); + } + + if ((store->flags & CAMEL_STORE_VJUNK) + && (vfolder = camel_object_bag_get(store->folders, CAMEL_VJUNK_NAME))) { + camel_vee_folder_remove_folder(vfolder, folder); + camel_object_unref(vfolder); + } + + camel_folder_delete(folder); + + camel_object_bag_remove(store->folders, folder); + camel_object_unref(folder); + } +} static void delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) @@ -321,32 +359,26 @@ delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) void camel_store_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) { - CamelFolder *folder = NULL; - - CAMEL_STORE_LOCK(store, folder_lock); + CamelException local; - /* NB: Note similarity of this code to unsubscribe_folder */ - - /* if we deleted a folder, force it out of the cache, and also out of the vtrash/vjunk if setup */ - if (store->folders) { - folder = camel_object_bag_get(store->folders, folder_name); - if (folder) { - if (store->vtrash) - camel_vee_folder_remove_folder((CamelVeeFolder *)store->vtrash, folder); - if (store->vjunk) - camel_vee_folder_remove_folder((CamelVeeFolder *)store->vjunk, folder); - camel_folder_delete (folder); - } + /* TODO: should probably be a parameter/bit on the storeinfo */ + if (((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0) + || ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0)) { + camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, + _("Cannot delete folder: %s: Invalid operation"), folder_name); + return; } - CS_CLASS (store)->delete_folder (store, folder_name, ex); - - if (folder) { - if (store->folders) - camel_object_bag_remove (store->folders, folder); - - camel_object_unref (folder); - } + camel_exception_init(&local); + + CAMEL_STORE_LOCK(store, folder_lock); + + CS_CLASS(store)->delete_folder(store, folder_name, &local); + + if (!camel_exception_is_set(&local)) + cs_delete_cached_folder(store, folder_name); + else + camel_exception_xfer(ex, &local); CAMEL_STORE_UNLOCK(store, folder_lock); } @@ -485,22 +517,6 @@ camel_store_get_inbox (CamelStore *store, CamelException *ex) return folder; } -static void -trash_finalize (CamelObject *trash, gpointer event_data, gpointer user_data) -{ - CamelStore *store = CAMEL_STORE (user_data); - - store->vtrash = NULL; -} - -static void -junk_finalize (CamelObject *junk, gpointer event_data, gpointer user_data) -{ - CamelStore *store = CAMEL_STORE (user_data); - - store->vjunk = NULL; -} - /* FIXME: derive vjunk folder object from vee_folder */ #include "camel-vee-store.h" static CamelFolder * @@ -518,85 +534,36 @@ camel_vjunk_folder_new (CamelStore *parent_store, const char *name) } static void -init_trash_or_junk (CamelStore *store, CamelFolder *folder, void (*finalize) (CamelObject *o, gpointer event_data, gpointer user_data)) +setup_special(CamelStore *store, CamelFolder *folder) { - if (folder) { - /* FIXME: this should probably use the object bag or another one ? ... */ - /* attach to the finalise event of the vtrash/vjunk */ - camel_object_hook_event (folder, "finalize", finalize, store); - - /* add all the pre-opened folders to the vtrash/vjunk */ - if (store->folders) { - GPtrArray *folders = camel_object_bag_list(store->folders); - int i; + GPtrArray *folders = camel_object_bag_list(store->folders); + int i; - for (i=0;ilen;i++) { - camel_vee_folder_add_folder (CAMEL_VEE_FOLDER (folder), (CamelFolder *)folders->pdata[i]); - camel_object_unref(folders->pdata[i]); - } - g_ptr_array_free(folders, TRUE); - } + for (i=0;ilen;i++) { + camel_vee_folder_add_folder((CamelVeeFolder *)folder, (CamelFolder *)folders->pdata[i]); + camel_object_unref(folders->pdata[i]); } + g_ptr_array_free(folders, TRUE); } -static void -init_trash (CamelStore *store) +static CamelFolder * +get_trash(CamelStore *store, CamelException *ex) { - if ((store->flags & CAMEL_STORE_VTRASH) == 0) - return; + CamelFolder *folder = camel_vtrash_folder_new(store, CAMEL_VTRASH_NAME); - store->vtrash = camel_vtrash_folder_new (store, CAMEL_VTRASH_NAME); - init_trash_or_junk (store, store->vtrash, trash_finalize); -} + setup_special(store, folder); -static void -init_junk (CamelStore *store) -{ - if ((store->flags & CAMEL_STORE_VJUNK) == 0) - return; - - store->vjunk = camel_vjunk_folder_new (store, CAMEL_VJUNK_NAME); - init_trash_or_junk (store, store->vjunk, junk_finalize); + return folder; } static CamelFolder * -get_trash (CamelStore *store, CamelException *ex) +get_junk(CamelStore *store, CamelException *ex) { - if (store->vtrash) { - camel_object_ref (store->vtrash); - return store->vtrash; - } else { - CS_CLASS (store)->init_trash (store); - if (store->vtrash) { - /* We don't ref here because we don't want the - store to own a ref on the trash folder */ - /*camel_object_ref (store->vtrash);*/ - return store->vtrash; - } else { - w(g_warning ("This store does not support vTrash.")); - return NULL; - } - } -} + CamelFolder *folder = camel_vjunk_folder_new(store, CAMEL_VJUNK_NAME); -static CamelFolder * -get_junk (CamelStore *store, CamelException *ex) -{ - if (store->vjunk) { - camel_object_ref (CAMEL_OBJECT (store->vjunk)); - return store->vjunk; - } else { - CS_CLASS (store)->init_junk (store); - if (store->vjunk) { - /* We don't ref here because we don't want the - store to own a ref on the junk folder */ - /*camel_object_ref (CAMEL_OBJECT (store->vjunk));*/ - return store->vjunk; - } else { - w(g_warning ("This store does not support vJunk.")); - return NULL; - } - } + setup_special(store, folder); + + return folder; } /** @@ -612,11 +579,22 @@ camel_store_get_trash (CamelStore *store, CamelException *ex) { CamelFolder *folder; - if ((store->flags & CAMEL_STORE_VTRASH) == 0) + if ((store->flags & CAMEL_STORE_VTRASH) == 0 + || store->folders == NULL) return NULL; CAMEL_STORE_LOCK(store, folder_lock); - folder = CS_CLASS (store)->get_trash (store, ex); + + folder = camel_object_bag_reserve(store->folders, CAMEL_VTRASH_NAME); + if (!folder) { + folder = CS_CLASS(store)->get_trash(store, ex); + + if (folder) + camel_object_bag_add(store->folders, CAMEL_VTRASH_NAME, folder); + else + camel_object_bag_abort(store->folders, CAMEL_VTRASH_NAME); + } + CAMEL_STORE_UNLOCK(store, folder_lock); return folder; @@ -635,11 +613,22 @@ camel_store_get_junk (CamelStore *store, CamelException *ex) { CamelFolder *folder; - if ((store->flags & CAMEL_STORE_VJUNK) == 0) + if ((store->flags & CAMEL_STORE_VJUNK) == 0 + || store->folders == NULL) return NULL; CAMEL_STORE_LOCK(store, folder_lock); - folder = CS_CLASS (store)->get_junk (store, ex); + + folder = camel_object_bag_reserve(store->folders, CAMEL_VJUNK_NAME); + if (!folder) { + folder = CS_CLASS(store)->get_junk(store, ex); + + if (folder) + camel_object_bag_add(store->folders, CAMEL_VJUNK_NAME, folder); + else + camel_object_bag_abort(store->folders, CAMEL_VJUNK_NAME); + } + CAMEL_STORE_UNLOCK(store, folder_lock); return folder; @@ -695,8 +684,7 @@ get_folder_info (CamelStore *store, const char *top, } static void -add_special_info (CamelStore *store, CamelFolderInfo *info, const char *name, const char *full_name, - const char *url_base, gboolean unread_count) +add_special_info (CamelStore *store, CamelFolderInfo *info, const char *name, const char *full_name, gboolean unread_count) { CamelFolderInfo *fi, *vinfo, *parent; char *uri, *path; @@ -747,11 +735,10 @@ add_special_info (CamelStore *store, CamelFolderInfo *info, const char *name, co /* Fill in the new fields */ vinfo->full_name = g_strdup (full_name); vinfo->name = g_strdup (vinfo->full_name); - vinfo->url = g_strdup_printf ("%s:%s", url_base, uri); + vinfo->url = uri; if (!unread_count) vinfo->unread_message_count = -1; vinfo->path = g_strdup_printf ("/%s", vinfo->name); - g_free (uri); } /** @@ -793,9 +780,9 @@ camel_store_get_folder_info (CamelStore *store, const char *top, if (info && (top == NULL || *top == '\0')) { if (info->url && (store->flags & CAMEL_STORE_VTRASH)) - add_special_info (store, info, CAMEL_VTRASH_NAME, _("Trash"), "vtrash", FALSE); + add_special_info (store, info, CAMEL_VTRASH_NAME, _("Trash"), FALSE); if (info->url && (store->flags & CAMEL_STORE_VJUNK)) - add_special_info (store, info, CAMEL_VJUNK_NAME, _("Junk"), "vjunk", TRUE); + add_special_info (store, info, CAMEL_VJUNK_NAME, _("Junk"), TRUE); } return info; @@ -851,7 +838,6 @@ camel_store_free_folder_info_nop (CamelStore *store, CamelFolderInfo *fi) ; } - /** * camel_folder_info_free: * @fi: the CamelFolderInfo @@ -872,7 +858,6 @@ camel_folder_info_free (CamelFolderInfo *fi) } } - /** * camel_folder_info_build_path: * @fi: folder info @@ -931,6 +916,9 @@ free_name(void *key, void *data, void *user) * %NULL urls to fill in gaps in the tree. The value of @short_names * is used in constructing the names of these intermediate folders. * + * NOTE: This is deprected, do not use this. + * FIXME: remove this/move it to imap, which is the only user of it now. + * * Return value: the top level of the tree of linked folder info. **/ CamelFolderInfo * @@ -1090,9 +1078,8 @@ camel_store_supports_subscriptions (CamelStore *store) return (store->flags & CAMEL_STORE_SUBSCRIPTIONS); } - static gboolean -folder_subscribed (CamelStore *store, const char *folder_name) +folder_subscribed(CamelStore *store, const char *folder_name) { w(g_warning ("CamelStore::folder_subscribed not implemented for `%s'", camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store)))); @@ -1107,8 +1094,7 @@ folder_subscribed (CamelStore *store, const char *folder_name) * Return value: TRUE if folder is subscribed, FALSE if not. **/ gboolean -camel_store_folder_subscribed (CamelStore *store, - const char *folder_name) +camel_store_folder_subscribed(CamelStore *store, const char *folder_name) { gboolean ret; @@ -1125,7 +1111,7 @@ camel_store_folder_subscribed (CamelStore *store, } static void -subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex) +subscribe_folder(CamelStore *store, const char *folder_name, CamelException *ex) { w(g_warning ("CamelStore::subscribe_folder not implemented for `%s'", camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store)))); @@ -1137,9 +1123,7 @@ subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex * @folder_name: the folder to subscribe to. **/ void -camel_store_subscribe_folder (CamelStore *store, - const char *folder_name, - CamelException *ex) +camel_store_subscribe_folder(CamelStore *store, const char *folder_name, CamelException *ex) { g_return_if_fail (CAMEL_IS_STORE (store)); g_return_if_fail (store->flags & CAMEL_STORE_SUBSCRIPTIONS); @@ -1152,57 +1136,39 @@ camel_store_subscribe_folder (CamelStore *store, } static void -unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex) +unsubscribe_folder(CamelStore *store, const char *folder_name, CamelException *ex) { w(g_warning ("CamelStore::unsubscribe_folder not implemented for `%s'", camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store)))); } - /** * camel_store_unsubscribe_folder: marks a folder as unsubscribed. * @store: a CamelStore * @folder_name: the folder to unsubscribe from. **/ void -camel_store_unsubscribe_folder (CamelStore *store, - const char *folder_name, - CamelException *ex) +camel_store_unsubscribe_folder(CamelStore *store, const char *folder_name, CamelException *ex) { - CamelFolder *folder = NULL; + CamelException local; g_return_if_fail (CAMEL_IS_STORE (store)); g_return_if_fail (store->flags & CAMEL_STORE_SUBSCRIPTIONS); - CAMEL_STORE_LOCK(store, folder_lock); + camel_exception_init(&local); - /* NB: Note similarity of this code to delete_folder */ - - /* if we deleted a folder, force it out of the cache, and also out of the vtrash/vjunk if setup */ - if (store->folders) { - folder = camel_object_bag_get(store->folders, folder_name); - if (folder) { - if (store->vtrash) - camel_vee_folder_remove_folder((CamelVeeFolder *)store->vtrash, folder); - if (store->vjunk) - camel_vee_folder_remove_folder((CamelVeeFolder *)store->vjunk, folder); - camel_folder_delete (folder); - } - } + CAMEL_STORE_LOCK(store, folder_lock); CS_CLASS (store)->unsubscribe_folder (store, folder_name, ex); - if (folder) { - if (store->folders) - camel_object_bag_remove(store->folders, folder); - - camel_object_unref(folder); - } + if (!camel_exception_is_set(&local)) + cs_delete_cached_folder(store, folder_name); + else + camel_exception_xfer(ex, &local); CAMEL_STORE_UNLOCK(store, folder_lock); } - static void noop (CamelStore *store, CamelException *ex) { @@ -1210,7 +1176,6 @@ noop (CamelStore *store, CamelException *ex) ; } - /** * camel_store_noop: * @store: CamelStore @@ -1224,7 +1189,6 @@ camel_store_noop (CamelStore *store, CamelException *ex) CS_CLASS (store)->noop (store, ex); } - /* Return true if these uri's refer to the same object */ gboolean camel_store_uri_cmp(CamelStore *store, const char *uria, const char *urib) -- cgit v1.2.3