From 5562efbd211a28b210a42e28e35eeba620d5a6e7 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Thu, 5 Feb 2004 05:14:04 +0000 Subject: [PATCH] ** See bug #53553. 2004-02-05 Not Zed ** See bug #53553. * camel-provider.c (camel_provider_init): changed to return a hashtable of url protocols to CamelProviderModule structs, rather than simple strings. * camel-session.c (get_provider): if we load a provider module, mark it as loaded. (ensure_loaded): Check the module loaded flag before trying to load it. * providers/local/libcamellocal.urls: Remove spoold from the list, since it doesn't exist anymore. Actually fixes #53553, the rest is to robustify the code. 2004-02-05 Not Zed * camel-session.c (CS_CLASS): dont typecheck cast. * camel-store.c (camel_vjunk_folder_new): removed, use vtrash_new(junk). (setup_special): changed to get_special, with a type now, and dont add vtrash folders to the sources. (get_trash, get_junk): down to 1 liners, call get_special * camel-vtrash-folder.c (CF_CLASS): dont use cast typecheck macros here, makes debugging easier and removes redundant checks. (camel_vtrash_folder_init): dont set flags here. (camel_vtrash_folder_new): takes a new argument, type, for junk folders too, removed name arg (taken from type). (vtrash_transfer_messages_to): parameterise flag processing. --- camel/ChangeLog | 34 ++++++++++++++++++++ camel/camel-provider.c | 18 ++++++++--- camel/camel-provider.h | 8 +++++ camel/camel-service.c | 2 +- camel/camel-session.c | 31 +++++++++--------- camel/camel-store.c | 40 +++++++---------------- camel/camel-vtrash-folder.c | 48 +++++++++++++++++----------- camel/camel-vtrash-folder.h | 17 +++++++--- camel/providers/local/camel-local-provider.c | 7 +++- camel/providers/local/libcamellocal.urls | 1 - 10 files changed, 131 insertions(+), 75 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index c048f2f..1e5cda0 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,37 @@ +2004-02-05 Not Zed + + ** See bug #53553. + + * camel-provider.c (camel_provider_init): changed to return a + hashtable of url protocols to CamelProviderModule structs, rather + than simple strings. + + * camel-session.c (get_provider): if we load a provider module, + mark it as loaded. + (ensure_loaded): Check the module loaded flag before trying to + load it. + + * providers/local/libcamellocal.urls: Remove spoold from the list, + since it doesn't exist anymore. Actually fixes #53553, the rest + is to robustify the code. + +2004-02-05 Not Zed + + * camel-session.c (CS_CLASS): dont typecheck cast. + + * camel-store.c (camel_vjunk_folder_new): removed, use + vtrash_new(junk). + (setup_special): changed to get_special, with a type now, and + dont add vtrash folders to the sources. + (get_trash, get_junk): down to 1 liners, call get_special + + * camel-vtrash-folder.c (CF_CLASS): dont use cast typecheck macros + here, makes debugging easier and removes redundant checks. + (camel_vtrash_folder_init): dont set flags here. + (camel_vtrash_folder_new): takes a new argument, type, for junk + folders too, removed name arg (taken from type). + (vtrash_transfer_messages_to): parameterise flag processing. + 2004-02-04 Jeffrey Stedfast * providers/imap/camel-imap-store.c: Get rid of some unnecessary diff --git a/camel/camel-provider.c b/camel/camel-provider.c index 321b307..ccbb286 100644 --- a/camel/camel-provider.c +++ b/camel/camel-provider.c @@ -65,7 +65,8 @@ camel_provider_init (void) DIR *dir; struct dirent *d; char *p, *name, buf[80]; - + CamelProviderModule *m; + providers = g_hash_table_new (camel_strcase_hash, camel_strcase_equal); dir = opendir (CAMEL_PROVIDERDIR); @@ -93,17 +94,24 @@ camel_provider_init (void) p = strrchr (name, '.'); strcpy (p, ".so"); + + m = g_malloc0(sizeof(*m)); + m->path = name; + while ((fgets (buf, sizeof (buf), fp))) { buf[sizeof (buf) - 1] = '\0'; p = strchr (buf, '\n'); if (p) *p = '\0'; - if (*buf) - g_hash_table_insert (providers, g_strdup (buf), g_strdup (name)); + if (*buf) { + char *protocol = g_strdup(buf); + + m->types = g_slist_prepend(m->types, protocol); + g_hash_table_insert(providers, protocol, m); + } } - - g_free (name); + fclose (fp); } diff --git a/camel/camel-provider.h b/camel/camel-provider.h index 98c5a3e..fb64143 100644 --- a/camel/camel-provider.h +++ b/camel/camel-provider.h @@ -184,6 +184,14 @@ typedef struct { char *translation_domain; } CamelProvider; +typedef struct _CamelProviderModule CamelProviderModule; + +struct _CamelProviderModule { + char *path; + GSList *types; + int loaded:1; +}; + GHashTable *camel_provider_init (void); void camel_provider_load (CamelSession *session, const char *path, CamelException *ex); diff --git a/camel/camel-service.c b/camel/camel-service.c index b5f5b4b..bb43b60 100644 --- a/camel/camel-service.c +++ b/camel/camel-service.c @@ -102,7 +102,7 @@ static void camel_service_finalize (CamelObject *object) { CamelService *service = CAMEL_SERVICE (object); - + if (service->status == CAMEL_SERVICE_CONNECTED) { CamelException ex; diff --git a/camel/camel-session.c b/camel/camel-session.c index 8b22689..2672c0a 100644 --- a/camel/camel-session.c +++ b/camel/camel-session.c @@ -47,7 +47,7 @@ #define d(x) -#define CS_CLASS(so) CAMEL_SESSION_CLASS (CAMEL_OBJECT_GET_CLASS (so)) +#define CS_CLASS(so) ((CamelSessionClass *)((CamelObject *)so)->klass) static void register_provider (CamelSession *session, CamelProvider *provider); static GList *list_providers (CamelSession *session, gboolean load); @@ -254,16 +254,16 @@ static void ensure_loaded (gpointer key, gpointer value, gpointer user_data) { CamelSession *session = user_data; - char *name = key; - char *path = value; + CamelProviderModule *m = value; + CamelException ex; - if (!g_hash_table_lookup (session->providers, name)) { - CamelException ex; + if (m->loaded) + return; - camel_exception_init (&ex); - camel_provider_load (session, path, &ex); - camel_exception_clear (&ex); - } + m->loaded = 1; + camel_exception_init(&ex); + camel_provider_load(session, m->path, &ex); + camel_exception_clear(&ex); } static gint @@ -333,11 +333,12 @@ get_provider (CamelSession *session, const char *url_string, CamelException *ex) provider = g_hash_table_lookup (session->providers, protocol); if (!provider) { /* See if there's one we can load. */ - char *path; + CamelProviderModule *m; - path = g_hash_table_lookup (session->modules, protocol); - if (path) { - camel_provider_load (session, path, ex); + m = g_hash_table_lookup (session->modules, protocol); + if (m && !m->loaded) { + m->loaded = 1; + camel_provider_load (session, m->path, ex); if (camel_exception_is_set (ex)) { g_free (protocol); return NULL; @@ -407,7 +408,7 @@ get_service (CamelSession *session, const char *url_string, camel_url_free (url); return NULL; } - + /* If the provider doesn't use paths but the URL contains one, * ignore it. */ @@ -429,7 +430,7 @@ get_service (CamelSession *session, const char *url_string, camel_object_bag_add(provider->service_cache[type], url, service); } } -done: + camel_url_free (url); return service; diff --git a/camel/camel-store.c b/camel/camel-store.c index 556d8da..d4ebdc8 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -517,53 +517,35 @@ camel_store_get_inbox (CamelStore *store, CamelException *ex) return folder; } -/* FIXME: derive vjunk folder object from vee_folder */ -#include "camel-vee-store.h" static CamelFolder * -camel_vjunk_folder_new (CamelStore *parent_store, const char *name) +get_special(CamelStore *store, enum _camel_vtrash_folder_t type) { - CamelFolder *vjunk; - - vjunk = (CamelFolder *)camel_object_new (camel_vee_folder_get_type ()); - vjunk->folder_flags |= CAMEL_FOLDER_IS_JUNK; - camel_vee_folder_construct (CAMEL_VEE_FOLDER (vjunk), parent_store, name, - CAMEL_STORE_FOLDER_PRIVATE | CAMEL_STORE_FOLDER_CREATE | CAMEL_STORE_VEE_FOLDER_AUTO); - camel_vee_folder_set_expression((CamelVeeFolder *)vjunk, "(match-all (system-flag \"Junk\"))"); - - return vjunk; -} - -static void -setup_special(CamelStore *store, CamelFolder *folder) -{ - GPtrArray *folders = camel_object_bag_list(store->folders); + CamelFolder *folder; + GPtrArray *folders; int i; + folder = camel_vtrash_folder_new(store, type); + folders = camel_object_bag_list(store->folders); for (i=0;ilen;i++) { - camel_vee_folder_add_folder((CamelVeeFolder *)folder, (CamelFolder *)folders->pdata[i]); + if (!CAMEL_IS_VTRASH_FOLDER(folders->pdata[i])) + camel_vee_folder_add_folder((CamelVeeFolder *)folder, (CamelFolder *)folders->pdata[i]); camel_object_unref(folders->pdata[i]); } g_ptr_array_free(folders, TRUE); + + return folder; } static CamelFolder * get_trash(CamelStore *store, CamelException *ex) { - CamelFolder *folder = camel_vtrash_folder_new(store, CAMEL_VTRASH_NAME); - - setup_special(store, folder); - - return folder; + return get_special(store, CAMEL_VTRASH_FOLDER_TRASH); } static CamelFolder * get_junk(CamelStore *store, CamelException *ex) { - CamelFolder *folder = camel_vjunk_folder_new(store, CAMEL_VJUNK_NAME); - - setup_special(store, folder); - - return folder; + return get_special(store, CAMEL_VTRASH_FOLDER_JUNK); } /** diff --git a/camel/camel-vtrash-folder.c b/camel/camel-vtrash-folder.c index aa21ce3..cd5df81 100644 --- a/camel/camel-vtrash-folder.c +++ b/camel/camel-vtrash-folder.c @@ -31,7 +31,17 @@ #include /* Returns the class for a CamelFolder */ -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) +#define CF_CLASS(so) ((CamelFolderClass *)((CamelObject *)(so))->klass) + +static struct { + const char *name; + const char *expr; + guint32 bit; + guint32 flags; +} vdata[] = { + { CAMEL_VTRASH_NAME, "(match-all (system-flag \"Deleted\"))", CAMEL_MESSAGE_DELETED, CAMEL_FOLDER_IS_TRASH }, + { CAMEL_VJUNK_NAME, "(match-all (system-flag \"Junk\"))", CAMEL_MESSAGE_JUNK, CAMEL_FOLDER_IS_JUNK }, +}; static CamelVeeFolderClass *camel_vtrash_folder_parent; @@ -56,9 +66,7 @@ camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass) static void camel_vtrash_folder_init (CamelVTrashFolder *vtrash) { - CamelFolder *folder = CAMEL_FOLDER (vtrash); - - folder->folder_flags |= CAMEL_FOLDER_IS_TRASH; + /*CamelFolder *folder = CAMEL_FOLDER (vtrash);*/ } CamelType @@ -83,7 +91,7 @@ camel_vtrash_folder_get_type (void) /** * camel_vtrash_folder_new: * @parent_store: the parent CamelVeeStore - * @name: the vfolder name + * @type: type of vfolder, CAMEL_VTRASH_FOLDER_TRASH or CAMEL_VTRASH_FOLDER_JUNK currently. * @ex: a CamelException * * Create a new CamelVeeFolder object. @@ -91,16 +99,21 @@ camel_vtrash_folder_get_type (void) * Return value: A new CamelVeeFolder widget. **/ CamelFolder * -camel_vtrash_folder_new (CamelStore *parent_store, const char *name) +camel_vtrash_folder_new (CamelStore *parent_store, enum _camel_vtrash_folder_t type) { - CamelFolder *vtrash; + CamelVTrashFolder *vtrash; - vtrash = (CamelFolder *)camel_object_new (camel_vtrash_folder_get_type ()); - camel_vee_folder_construct (CAMEL_VEE_FOLDER (vtrash), parent_store, name, - CAMEL_STORE_FOLDER_PRIVATE | CAMEL_STORE_FOLDER_CREATE | CAMEL_STORE_VEE_FOLDER_AUTO); - camel_vee_folder_set_expression((CamelVeeFolder *)vtrash, "(match-all (system-flag \"Deleted\"))"); + g_assert(type < CAMEL_VTRASH_FOLDER_LAST); + + vtrash = (CamelVTrashFolder *)camel_object_new(camel_vtrash_folder_get_type()); + camel_vee_folder_construct(CAMEL_VEE_FOLDER (vtrash), parent_store, vdata[type].name, + CAMEL_STORE_FOLDER_PRIVATE|CAMEL_STORE_FOLDER_CREATE|CAMEL_STORE_VEE_FOLDER_AUTO); - return vtrash; + ((CamelFolder *)vtrash)->folder_flags |= vdata[type].flags; + camel_vee_folder_set_expression((CamelVeeFolder *)vtrash, vdata[type].expr); + vtrash->bit = vdata[type].bit; + + return (CamelFolder *)vtrash; } static void @@ -143,6 +156,7 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids, GHashTable *batch = NULL; const char *tuid; struct _transfer_data *md; + guint32 sbit = ((CamelVTrashFolder *)source)->bit; /* This is a special case of transfer_messages_to: Either the * source or the destination is a vtrash folder (but not both @@ -157,14 +171,12 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids, if (!delete_originals) return; - /* Move to trash is the same as deleting the message */ + /* Move to trash is the same as setting the message flag */ for (i = 0; i < uids->len; i++) - camel_folder_delete_message (source, uids->pdata[i]); + camel_folder_set_message_flags(source, uids->pdata[i], sbit, ~0); return; } - g_return_if_fail (CAMEL_IS_VTRASH_FOLDER (source)); - /* Moving/Copying from the trash to the original folder = undelete. * Moving/Copying from the trash to a different folder = move/copy. * @@ -179,8 +191,8 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids, } if (dest == mi->folder) { - /* Just undelete the original message */ - camel_folder_set_message_flags (source, uids->pdata[i], CAMEL_MESSAGE_DELETED, 0); + /* Just unset the flag on the original message */ + camel_folder_set_message_flags (source, uids->pdata[i], sbit, 0); } else { if (batch == NULL) batch = g_hash_table_new(NULL, NULL); diff --git a/camel/camel-vtrash-folder.h b/camel/camel-vtrash-folder.h index 089c969..a640569 100644 --- a/camel/camel-vtrash-folder.h +++ b/camel/camel-vtrash-folder.h @@ -32,9 +32,6 @@ extern "C" { #include #include -#define CAMEL_VTRASH_NAME "Trash" -#define CAMEL_VJUNK_NAME "Junk" - #define CAMEL_VTRASH_FOLDER(obj) CAMEL_CHECK_CAST (obj, camel_vtrash_folder_get_type (), CamelVTrashFolder) #define CAMEL_VTRASH_FOLDER_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vtrash_folder_get_type (), CamelVTrashFolderClass) #define CAMEL_IS_VTRASH_FOLDER(obj) CAMEL_CHECK_TYPE (obj, camel_vtrash_folder_get_type ()) @@ -42,9 +39,19 @@ extern "C" { typedef struct _CamelVTrashFolder CamelVTrashFolder; typedef struct _CamelVTrashFolderClass CamelVTrashFolderClass; +#define CAMEL_VTRASH_NAME "Trash" +#define CAMEL_VJUNK_NAME "Junk" + +enum _camel_vtrash_folder_t { + CAMEL_VTRASH_FOLDER_TRASH, + CAMEL_VTRASH_FOLDER_JUNK, + CAMEL_VTRASH_FOLDER_LAST +}; + struct _CamelVTrashFolder { CamelVeeFolder parent; - + + guint32 bit; }; struct _CamelVTrashFolderClass { @@ -54,7 +61,7 @@ struct _CamelVTrashFolderClass { CamelType camel_vtrash_folder_get_type (void); -CamelFolder *camel_vtrash_folder_new (CamelStore *parent_store, const char *name); +CamelFolder *camel_vtrash_folder_new (CamelStore *parent_store, enum _camel_vtrash_folder_t type); #ifdef __cplusplus } diff --git a/camel/providers/local/camel-local-provider.c b/camel/providers/local/camel-local-provider.c index a52dfbd..fc33f34 100644 --- a/camel/providers/local/camel-local-provider.c +++ b/camel/providers/local/camel-local-provider.c @@ -192,7 +192,12 @@ local_url_equal(const void *v, const void *v2) void camel_provider_module_init(CamelSession * session) { char *path; - + static int init = 0; + + if (init) + abort(); + init = 1; + mh_conf_entries[0].value = ""; /* default path */ mh_provider.object_types[CAMEL_PROVIDER_STORE] = camel_mh_store_get_type (); mh_provider.url_hash = local_url_hash; diff --git a/camel/providers/local/libcamellocal.urls b/camel/providers/local/libcamellocal.urls index e2279ed..207c19a 100644 --- a/camel/providers/local/libcamellocal.urls +++ b/camel/providers/local/libcamellocal.urls @@ -2,4 +2,3 @@ mh mbox maildir spool -spoold -- 2.7.4