diff options
-rw-r--r-- | camel/ChangeLog | 40 | ||||
-rw-r--r-- | camel/camel-remote-store.c | 13 | ||||
-rw-r--r-- | camel/camel-service.c | 83 | ||||
-rw-r--r-- | camel/camel-service.h | 10 | ||||
-rw-r--r-- | camel/camel-session.c | 9 | ||||
-rw-r--r-- | camel/camel-store.c | 320 | ||||
-rw-r--r-- | camel/camel-store.h | 25 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.c | 47 | ||||
-rw-r--r-- | camel/providers/local/camel-local-store.c | 72 | ||||
-rw-r--r-- | camel/providers/local/camel-maildir-store.c | 10 | ||||
-rw-r--r-- | camel/providers/local/camel-mbox-store.c | 11 | ||||
-rw-r--r-- | camel/providers/local/camel-mh-store.c | 10 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-store.c | 7 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-store.c | 26 | ||||
-rw-r--r-- | camel/providers/vee/camel-vee-store.c | 9 |
15 files changed, 243 insertions, 449 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 06e0ac796d..379219c7b9 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,43 @@ +2001-02-08 Dan Winship <danw@ximian.com> + + * camel-store.c: Rewrite a bunch. Replace the existing folder + cache stuff with much simpler code that still handles all the + existing cases. Now the folder hash table is always created by the + base class, using hash and compare functions provided by the class + implementation. (If they are set to NULL, CamelStore won't cache + folders.) lookup_folder, cache_folder, and uncache_folder are no + longer class methods, and get_name is gone completely. + + (camel_store_get_inbox): Renamed from + camel_store_get_default_folder, since that wasn't being used, and + this is what we actually need. + (camel_store_get_root_folder): Removed, since it's not needed for + anything given get_folder_info. + + * camel-remote-store.c: + * providers/nntp/camel-nntp-store.c: + * providers/pop3/camel-pop3-store.c: + * providers/vee/camel-vee-store.c: Minor updates for CamelStore + changes + + * providers/imap/camel-imap-store.c (camel_imap_store_class_init): + Update for CamelStore changes. + (hash_folder_name, compare_folder_name): treat INBOX + case-insensitively, otherwise use g_str_hash and g_str_equal. + + * camel-service.c (camel_service_construct): Remove + camel_service_new and create camel_service_construct (as a class + method) in its place. + + * camel-session.c (camel_session_get_service): Use + camel_object_new and camel_service_construct to replace + camel_service_new. + + * providers/local/camel-local-store.c: Update for CamelStore + changes + (construct): Append a '/' to the URL path if it doesn't end with + one + 2001-01-31 Jeffrey Stedfast <fejj@helixcode.com> * camel-tcp-stream-ssl.c: Oops, include the camel-tcp-stream-ssl diff --git a/camel/camel-remote-store.c b/camel/camel-remote-store.c index d1352300b7..52f1908f05 100644 --- a/camel/camel-remote-store.c +++ b/camel/camel-remote-store.c @@ -65,9 +65,6 @@ static gboolean remote_disconnect (CamelService *service, gboolean clean, C static GList *remote_query_auth_types(CamelService *service, gboolean connect, CamelException *ex); static void remote_free_auth_types (CamelService *service, GList *authtypes); static char *remote_get_name (CamelService *service, gboolean brief); -static char *remote_get_folder_name (CamelStore *store, - const char *folder_name, - CamelException *ex); static gint remote_send_string (CamelRemoteStore *store, CamelException *ex, char *fmt, va_list ap); static gint remote_send_stream (CamelRemoteStore *store, CamelStream *stream, @@ -81,8 +78,6 @@ camel_remote_store_class_init (CamelRemoteStoreClass *camel_remote_store_class) /* virtual method overload */ CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_remote_store_class); - CamelStoreClass *camel_store_class = - CAMEL_STORE_CLASS (camel_remote_store_class); store_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ())); @@ -93,8 +88,6 @@ camel_remote_store_class_init (CamelRemoteStoreClass *camel_remote_store_class) camel_service_class->free_auth_types = remote_free_auth_types; camel_service_class->get_name = remote_get_name; - camel_store_class->get_folder_name = remote_get_folder_name; - camel_remote_store_class->send_string = remote_send_string; camel_remote_store_class->send_stream = remote_send_stream; camel_remote_store_class->recv_line = remote_recv_line; @@ -386,12 +379,6 @@ remote_disconnect (CamelService *service, gboolean clean, CamelException *ex) return TRUE; } -static gchar * -remote_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) -{ - return g_strdup (folder_name); -} - static gint remote_send_string (CamelRemoteStore *store, CamelException *ex, char *fmt, va_list ap) { diff --git a/camel/camel-service.c b/camel/camel-service.c index 0eae1cd98a..bdaa807572 100644 --- a/camel/camel-service.c +++ b/camel/camel-service.c @@ -38,6 +38,9 @@ static CamelObjectClass *parent_class = NULL; /* Returns the class for a CamelService */ #define CSERV_CLASS(so) CAMEL_SERVICE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) +static void construct (CamelService *service, CamelSession *session, + CamelProvider *provider, CamelURL *url, + CamelException *ex); static gboolean service_connect(CamelService *service, CamelException *ex); static gboolean service_disconnect(CamelService *service, gboolean clean, CamelException *ex); @@ -46,7 +49,6 @@ static GList * query_auth_types (CamelService *service, gboolean connect, Camel static void free_auth_types (CamelService *service, GList *authtypes); static char * get_name (CamelService *service, gboolean brief); static char * get_path (CamelService *service); -static gboolean check_url (CamelService *service, CamelException *ex); static void @@ -55,9 +57,9 @@ camel_service_class_init (CamelServiceClass *camel_service_class) parent_class = camel_type_get_global_classfuncs (CAMEL_OBJECT_TYPE); /* virtual method definition */ + camel_service_class->construct = construct; camel_service_class->connect = service_connect; camel_service_class->disconnect = service_disconnect; - /*camel_service_class->is_connected = is_connected;*/ camel_service_class->query_auth_types = query_auth_types; camel_service_class->free_auth_types = free_auth_types; camel_service_class->get_name = get_name; @@ -125,82 +127,69 @@ camel_service_get_type (void) return camel_service_type; } -static gboolean -check_url (CamelService *service, CamelException *ex) + +static void +construct (CamelService *service, CamelSession *session, + CamelProvider *provider, CamelURL *url, CamelException *ex) { char *url_string; - if (((service->provider->url_flags & CAMEL_URL_NEED_USER) + if (((provider->url_flags & CAMEL_URL_NEED_USER) == CAMEL_URL_NEED_USER) && - (service->url->user == NULL || service->url->user[0] == '\0')) { - url_string = camel_url_to_string (service->url, FALSE); + (url->user == NULL || url->user[0] == '\0')) { + url_string = camel_url_to_string (url, FALSE); camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID, _("URL '%s' needs a username component"), url_string); g_free (url_string); - return FALSE; - } else if (((service->provider->url_flags & CAMEL_URL_NEED_HOST) + return; + } else if (((provider->url_flags & CAMEL_URL_NEED_HOST) == CAMEL_URL_NEED_HOST) && - (service->url->host == NULL || service->url->host[0] == '\0')) { - url_string = camel_url_to_string (service->url, FALSE); + (url->host == NULL || url->host[0] == '\0')) { + url_string = camel_url_to_string (url, FALSE); camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID, _("URL '%s' needs a host component"), url_string); g_free (url_string); - return FALSE; - } else if (((service->provider->url_flags & CAMEL_URL_NEED_PATH) + return; + } else if (((provider->url_flags & CAMEL_URL_NEED_PATH) == CAMEL_URL_NEED_PATH) && - (service->url->path == NULL || service->url->path[0] == '\0')) { - url_string = camel_url_to_string (service->url, FALSE); + (url->path == NULL || url->path[0] == '\0')) { + url_string = camel_url_to_string (url, FALSE); camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID, _("URL '%s' needs a path component"), url_string); g_free (url_string); - return FALSE; + return; } - return TRUE; + service->provider = provider; + service->url = url; + service->session = session; + camel_object_ref (CAMEL_OBJECT (session)); + + service->connected = FALSE; } /** - * camel_service_new: create a new CamelService or subtype - * @type: the CamelType of the class to create + * camel_service_construct: + * @service: the CamelService * @session: the session for the service * @provider: the service's provider * @url: the default URL for the service (may be NULL) * @ex: a CamelException * - * Creates a new CamelService (or one of its subtypes), initialized - * with the given parameters. - * - * Return value: the CamelService, or NULL. + * Constructs a CamelService initialized with the given parameters. **/ -CamelService * -camel_service_new (CamelType type, CamelSession *session, - CamelProvider *provider, CamelURL *url, - CamelException *ex) +void +camel_service_construct (CamelService *service, CamelSession *session, + CamelProvider *provider, CamelURL *url, + CamelException *ex) { - CamelService *service; - - g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); - - service = CAMEL_SERVICE (camel_object_new (type)); - - /*service->connect_level = 0;*/ - - service->provider = provider; - service->url = url; - if (!check_url (service, ex)) { - camel_object_unref (CAMEL_OBJECT (service)); - return NULL; - } - - service->session = session; - camel_object_ref (CAMEL_OBJECT (session)); - - service->connected = FALSE; + g_return_if_fail (CAMEL_IS_SERVICE (service)); + g_return_if_fail (CAMEL_IS_SESSION (session)); - return service; + CSERV_CLASS (service)->construct (service, session, provider, url, ex); } diff --git a/camel/camel-service.h b/camel/camel-service.h index 728db6c4ce..aeb71c933d 100644 --- a/camel/camel-service.h +++ b/camel/camel-service.h @@ -59,14 +59,18 @@ struct _CamelService { typedef struct { CamelObjectClass parent_class; + void (*construct) (CamelService *service, + CamelSession *session, + CamelProvider *provider, + CamelURL *url, + CamelException *ex); + gboolean (*connect) (CamelService *service, CamelException *ex); gboolean (*disconnect) (CamelService *service, gboolean clean, CamelException *ex); - /*gboolean (*is_connected) (CamelService *service);*/ - GList * (*query_auth_types) (CamelService *service, gboolean connect, CamelException *ex); @@ -88,7 +92,7 @@ typedef struct { /* public methods */ -CamelService * camel_service_new (CamelType type, +void camel_service_construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, diff --git a/camel/camel-session.c b/camel/camel-session.c index a8ca5983ec..5ef31158b7 100644 --- a/camel/camel-session.c +++ b/camel/camel-session.c @@ -39,6 +39,7 @@ #include "string-utils.h" #include "camel-url.h" #include "hash-table-utils.h" +#include <gal/util/e-util.h> #include "camel-private.h" @@ -311,8 +312,12 @@ camel_session_get_service (CamelSession *session, const char *url_string, return service; } - service = camel_service_new (provider->object_types[type], session, provider, url, ex); - if (service) { + service = (CamelService *)camel_object_new (provider->object_types[type]); + camel_service_construct (service, session, provider, url, ex); + if (camel_exception_is_set (ex)) { + camel_object_unref (CAMEL_OBJECT (service)); + service = NULL; + } else { g_hash_table_insert (provider->service_cache, url, service); camel_object_hook_event (CAMEL_OBJECT (service), "finalize", (CamelObjectEventHookFunc) service_cache_remove, session); } diff --git a/camel/camel-store.c b/camel/camel-store.c index 5b48299231..e7bd25a4be 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -2,7 +2,6 @@ /* camel-store.c : Abstract class for an email store */ /* - * * Authors: * Bertrand Guiheneuf <bertrand@helixcode.com> * Dan Winship <danw@helixcode.com> @@ -24,6 +23,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ + #include <config.h> #include <string.h> @@ -40,16 +40,13 @@ static CamelServiceClass *parent_class = NULL; static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); +static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); + static void delete_folder (CamelStore *store, const char *folder_name, CamelException *ex); static void rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); -static char *get_default_folder_name (CamelStore *store, CamelException *ex); - static void store_sync (CamelStore *store, CamelException *ex); static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, gboolean fast, gboolean recursive, @@ -57,11 +54,6 @@ static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, CamelException *ex); static void free_folder_info (CamelStore *store, CamelFolderInfo *tree); -static CamelFolder *lookup_folder (CamelStore *store, const char *folder_name); -static void cache_folder (CamelStore *store, const char *folder_name, - CamelFolder *folder); -static void uncache_folder (CamelStore *store, CamelFolder *folder); - static gboolean folder_subscribed (CamelStore *store, const char *folder_name); static void subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex); static void unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex); @@ -72,30 +64,31 @@ camel_store_class_init (CamelStoreClass *camel_store_class) parent_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ())); /* virtual method definition */ + camel_store_class->hash_folder_name = g_str_hash; + 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->delete_folder = delete_folder; camel_store_class->rename_folder = rename_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_root_folder_name = get_root_folder_name; - camel_store_class->get_default_folder_name = get_default_folder_name; camel_store_class->sync = store_sync; camel_store_class->get_folder_info = get_folder_info; camel_store_class->free_folder_info = free_folder_info; - camel_store_class->lookup_folder = lookup_folder; - camel_store_class->cache_folder = cache_folder; - camel_store_class->uncache_folder = uncache_folder; camel_store_class->folder_subscribed = folder_subscribed; camel_store_class->subscribe_folder = subscribe_folder; camel_store_class->unsubscribe_folder = unsubscribe_folder; } static void -camel_store_init (void *o, void *k) +camel_store_init (void *o) { CamelStore *store = o; + CamelStoreClass *store_class = (CamelStoreClass *)CAMEL_OBJECT_GET_CLASS (o); - if (store->folders == NULL) - store->folders = g_hash_table_new (g_str_hash, g_str_equal); + if (store_class->hash_folder_name) { + store->folders = g_hash_table_new (store_class->hash_folder_name, + store_class->compare_folder_name); + } else + store->folders = NULL; store->flags = 0; store->priv = g_malloc0(sizeof(*store->priv)); @@ -146,106 +139,6 @@ camel_store_get_type (void) } -static CamelFolder * -get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) -{ - g_warning("CamelStore::get_folder not implemented for `%s'", - camel_type_to_name(CAMEL_OBJECT_GET_TYPE(store))); - return NULL; -} - -static void -delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) -{ - g_warning ("CamelStore::delete_folder not implemented for `%s'", - camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); -} - -static void -rename_folder (CamelStore *store, const char *old_name, - const char *new_name, CamelException *ex) -{ - g_warning ("CamelStore::rename_folder not implemented for `%s'", - camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); -} - - -/* CamelStore::get_folder_name should: - * a) make sure that the provided name is valid - * b) return it in canonical form, in allocated memory. - * - * This is used to make sure that duplicate names for the same folder - * don't result in duplicate cache entries. - */ -static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - g_warning ("CamelStore::get_folder_name not implemented for `%s'", - camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); - return NULL; -} - -static char * -get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup ("/"); -} - -static char * -get_default_folder_name (CamelStore *store, CamelException *ex) -{ - return CS_CLASS (store)->get_root_folder_name (store, ex); -} - -static CamelFolder * -lookup_folder (CamelStore *store, const char *folder_name) -{ - CamelFolder *folder = NULL; - - CAMEL_STORE_LOCK(store, cache_lock); - - if (store->folders) { - folder = g_hash_table_lookup (store->folders, folder_name); - if (folder) - camel_object_ref(CAMEL_OBJECT(folder)); - } - - CAMEL_STORE_UNLOCK(store, cache_lock); - - return folder; -} - -static void folder_finalize (CamelObject *folder, gpointer event_data, gpointer user_data) -{ - CS_CLASS (user_data)->uncache_folder (CAMEL_STORE(user_data), CAMEL_FOLDER(folder)); -} - -static void -cache_folder (CamelStore *store, const char *folder_name, CamelFolder *folder) -{ - CAMEL_STORE_LOCK(store, cache_lock); - - if (store->folders) { - if (g_hash_table_lookup (store->folders, folder_name)) { - g_warning ("Caching folder %s that already exists.", folder_name); - } - g_hash_table_insert (store->folders, g_strdup (folder_name), folder); - - camel_object_hook_event (CAMEL_OBJECT (folder), "finalize", folder_finalize, store); - } - - CAMEL_STORE_UNLOCK(store, cache_lock); - - /* - * gt_k so as not to get caught by my little gt_k cleanliness detector. - * - * gt_k_signal_connect_object (CAMEL_OBJECT (folder), "destroy", - * GT_K_SIGNAL_FUNC (CS_CLASS (store)->uncache_folder), - * CAMEL_OBJECT (store)); - */ -} - static gboolean folder_matches (gpointer key, gpointer value, gpointer user_data) { @@ -257,39 +150,25 @@ folder_matches (gpointer key, gpointer value, gpointer user_data) } static void -uncache_folder (CamelStore *store, CamelFolder *folder) +folder_finalize (CamelObject *folder, gpointer event_data, gpointer user_data) { - CAMEL_STORE_LOCK(store, cache_lock); - - g_hash_table_foreach_remove (store->folders, folder_matches, folder); + CamelStore *store = CAMEL_STORE (user_data); - CAMEL_STORE_UNLOCK(store, cache_lock); + if (store->folders) { + CAMEL_STORE_LOCK(store, cache_lock); + g_hash_table_foreach_remove (store->folders, folder_matches, folder); + CAMEL_STORE_UNLOCK(store, cache_lock); + } } - static CamelFolder * -get_folder_internal(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) +get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { - CamelFolder *folder = NULL; - - /* NB: we already have folder_lock */ - - /* Try cache first. */ - folder = CS_CLASS(store)->lookup_folder(store, folder_name); - - if (!folder) { - folder = CS_CLASS(store)->get_folder(store, folder_name, flags, ex); - if (!folder) - return NULL; - - CS_CLASS(store)->cache_folder(store, folder_name, folder); - } - - return folder; + g_warning ("CamelStore::get_folder not implemented for `%s'", + camel_type_to_name(CAMEL_OBJECT_GET_TYPE(store))); + return NULL; } - - /** * camel_store_get_folder: Return the folder corresponding to a path. * @store: a CamelStore @@ -297,32 +176,48 @@ get_folder_internal(CamelStore *store, const char *folder_name, guint32 flags, C * @flags: folder flags (create, save body index, etc) * @ex: a CamelException * - * Returns the folder corresponding to the path @folder_name. If the - * path begins with the separator character, it is relative to the - * root folder. Otherwise, it is relative to the default folder. - * - * Return value: the folder + * Return value: the folder corresponding to the path @folder_name. **/ CamelFolder * -camel_store_get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) +camel_store_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { - char *name; CamelFolder *folder = NULL; CAMEL_STORE_LOCK(store, folder_lock); - name = CS_CLASS(store)->get_folder_name(store, folder_name, ex); - if (name) { - folder = get_folder_internal(store, name, flags, ex); - g_free (name); + if (store->folders) { + /* Try cache first. */ + CAMEL_STORE_LOCK(store, cache_lock); + folder = g_hash_table_lookup (store->folders, folder_name); + if (folder) + camel_object_ref (CAMEL_OBJECT (folder)); + CAMEL_STORE_UNLOCK(store, cache_lock); } - CAMEL_STORE_UNLOCK(store, folder_lock); + if (!folder) { + folder = CS_CLASS (store)->get_folder (store, folder_name, flags, ex); + if (folder && store->folders) { + CAMEL_STORE_LOCK(store, cache_lock); + g_hash_table_insert (store->folders, g_strdup (folder_name), folder); + + camel_object_hook_event (CAMEL_OBJECT (folder), "finalize", folder_finalize, store); + CAMEL_STORE_UNLOCK(store, cache_lock); + } + } + + CAMEL_STORE_UNLOCK(store, folder_lock); return folder; } +static void +delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) +{ + g_warning ("CamelStore::delete_folder not implemented for `%s'", + camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); +} + /** * camel_store_delete_folder: Delete the folder corresponding to a path. * @store: a CamelStore @@ -332,104 +227,65 @@ camel_store_get_folder(CamelStore *store, const char *folder_name, guint32 flags * Deletes the named folder. The folder must be empty. **/ void -camel_store_delete_folder (CamelStore *store, const char *folder_name, - CamelException *ex) +camel_store_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) { - char *name; - CAMEL_STORE_LOCK(store, folder_lock); + CS_CLASS (store)->delete_folder (store, folder_name, ex); + CAMEL_STORE_UNLOCK(store, folder_lock); - name = CS_CLASS (store)->get_folder_name (store, folder_name, ex); - if (name) { - CS_CLASS (store)->delete_folder (store, name, ex); - g_free (name); - } +} - CAMEL_STORE_UNLOCK(store, folder_lock); + +static void +rename_folder (CamelStore *store, const char *old_name, + const char *new_name, CamelException *ex) +{ + g_warning ("CamelStore::rename_folder not implemented for `%s'", + camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); } /** * camel_store_rename_folder: - * @store: - * @old_name: - * @new_name: - * @ex: + * @store: a CamelStore + * @old_name: the current name of the folder + * @new_name: the new name of the folder + * @ex: a CamelException * * Rename a named folder to a new name. **/ -void camel_store_rename_folder (CamelStore *store, - const char *old_name, - const char *new_name, - CamelException *ex) +void +camel_store_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex) { - char *old, *new; - CAMEL_STORE_LOCK(store, folder_lock); - - old = CS_CLASS (store)->get_folder_name(store, old_name, ex); - if (old) { - new = CS_CLASS (store)->get_folder_name(store, new_name, ex); - if (new) { - CS_CLASS (store)->rename_folder(store, old, new, ex); - g_free(new); - } - g_free(old); - } - + CS_CLASS (store)->rename_folder (store, old_name, new_name, ex); CAMEL_STORE_UNLOCK(store, folder_lock); } -/** - * camel_store_get_root_folder: return the top-level folder - * - * Returns the folder which is at the top of the folder hierarchy. - * This folder may or may not be the same as the default folder. - * - * Return value: the top-level folder. - **/ -CamelFolder * -camel_store_get_root_folder (CamelStore *store, CamelException *ex) +static CamelFolder * +get_inbox (CamelStore *store, CamelException *ex) { - char *name; - CamelFolder *folder = NULL; - - CAMEL_STORE_LOCK(store, folder_lock); - - name = CS_CLASS (store)->get_root_folder_name (store, ex); - if (name) { - folder = get_folder_internal (store, name, CAMEL_STORE_FOLDER_CREATE, ex); - g_free (name); - } - - CAMEL_STORE_UNLOCK(store, folder_lock); - - return folder; + /* Default: assume the inbox's name is "inbox" + * and open with default flags. + */ + return CS_CLASS (store)->get_folder (store, "inbox", 0, ex); } /** - * camel_store_get_default_folder: return the store default folder - * - * The default folder is the folder which is presented to the user in - * the default configuration. This defaults to the root folder if - * the store doesn't override it. + * camel_store_get_inbox: + * @store: a CamelStore + * @ex: a CamelException * - * Return value: the default folder. + * Return value: the folder in the store into which new mail is + * delivered, or %NULL if no such folder exists. **/ CamelFolder * -camel_store_get_default_folder (CamelStore *store, CamelException *ex) +camel_store_get_inbox (CamelStore *store, CamelException *ex) { - char *name; - CamelFolder *folder = NULL; + CamelFolder *folder; CAMEL_STORE_LOCK(store, folder_lock); - - name = CS_CLASS (store)->get_default_folder_name (store, ex); - if (name) { - folder = get_folder_internal (store, name, CAMEL_STORE_FOLDER_CREATE, ex); - g_free (name); - } - + folder = CS_CLASS (store)->get_inbox (store, ex); CAMEL_STORE_UNLOCK(store, folder_lock); return folder; @@ -446,9 +302,11 @@ sync_folder (gpointer key, gpointer folder, gpointer ex) static void store_sync (CamelStore *store, CamelException *ex) { - CAMEL_STORE_LOCK(store, cache_lock); - g_hash_table_foreach (store->folders, sync_folder, ex); - CAMEL_STORE_UNLOCK(store, cache_lock); + if (store->folders) { + CAMEL_STORE_LOCK(store, cache_lock); + g_hash_table_foreach (store->folders, sync_folder, ex); + CAMEL_STORE_UNLOCK(store, cache_lock); + } } /** diff --git a/camel/camel-store.h b/camel/camel-store.h index 1141f09dcf..da81a435f0 100644 --- a/camel/camel-store.h +++ b/camel/camel-store.h @@ -73,10 +73,15 @@ struct _CamelStore typedef struct { CamelServiceClass parent_class; + GHashFunc hash_folder_name; + GCompareFunc compare_folder_name; + CamelFolder * (*get_folder) (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); + CamelFolder * (*get_inbox) (CamelStore *store, + CamelException *ex); void (*delete_folder) (CamelStore *store, const char *folder_name, @@ -89,22 +94,6 @@ typedef struct { void (*sync) (CamelStore *store, CamelException *ex); - char * (*get_folder_name) (CamelStore *store, - const char *folder_name, - CamelException *ex); - char * (*get_root_folder_name) (CamelStore *store, - CamelException *ex); - char * (*get_default_folder_name) (CamelStore *store, - CamelException *ex); - - CamelFolder * (*lookup_folder) (CamelStore *store, - const char *folder_name); - void (*cache_folder) (CamelStore *store, - const char *folder_name, - CamelFolder *folder); - void (*uncache_folder) (CamelStore *store, - CamelFolder *folder); - /* this should take flags instead, so its more futureproof */ CamelFolderInfo *(*get_folder_info) (CamelStore *store, const char *top, @@ -134,9 +123,7 @@ CamelFolder * camel_store_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -CamelFolder * camel_store_get_root_folder (CamelStore *store, - CamelException *ex); -CamelFolder * camel_store_get_default_folder (CamelStore *store, +CamelFolder * camel_store_get_inbox (CamelStore *store, CamelException *ex); void camel_store_delete_folder (CamelStore *store, diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index cd46d56226..f19d8feb31 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -60,10 +60,9 @@ static CamelRemoteStoreClass *remote_store_class = NULL; static gboolean imap_connect (CamelService *service, CamelException *ex); static gboolean imap_disconnect (CamelService *service, gboolean clean, CamelException *ex); static GList *query_auth_types (CamelService *service, gboolean connect, CamelException *ex); +static guint hash_folder_name (gconstpointer key); +static gint compare_folder_name (gconstpointer a, gconstpointer b); static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, gboolean fast, gboolean recursive, gboolean subscribed_only, @@ -94,9 +93,9 @@ camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class) camel_service_class->connect = imap_connect; camel_service_class->disconnect = imap_disconnect; + camel_store_class->hash_folder_name = hash_folder_name; + camel_store_class->compare_folder_name = compare_folder_name; camel_store_class->get_folder = get_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_root_folder_name = get_root_folder_name; camel_store_class->get_folder_info = get_folder_info; camel_store_class->free_folder_info = camel_store_free_folder_info_full; @@ -603,6 +602,27 @@ imap_create (CamelImapStore *store, const char *folder_name, return !camel_exception_is_set (ex); } +static guint +hash_folder_name (gconstpointer key) +{ + if (g_strcasecmp (key, "INBOX") == 0) + return g_str_hash ("INBOX"); + else + return g_str_hash (key); +} + +static gint +compare_folder_name (gconstpointer a, gconstpointer b) +{ + gconstpointer aname = a, bname = b; + + if (g_strcasecmp (a, "INBOX") == 0) + aname = "INBOX"; + if (g_strcasecmp (b, "INBOX") == 0) + bname = "INBOX"; + return g_str_equal (aname, bname); +} + static CamelFolder * get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) @@ -661,23 +681,6 @@ get_folder (CamelStore *store, const char *folder_name, guint32 flags, return new_folder; } -static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - /* INBOX is case-insensitive */ - if (g_strcasecmp (folder_name, "INBOX") == 0) - return g_strdup ("INBOX"); - else - return g_strdup (folder_name); -} - -static char * -get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup (""); -} - static CamelFolderInfo * parse_list_response_as_folder_info (CamelImapStore *imap_store, const char *response) diff --git a/camel/providers/local/camel-local-store.c b/camel/providers/local/camel-local-store.c index 9af9df2744..b6ea31a98f 100644 --- a/camel/providers/local/camel-local-store.c +++ b/camel/providers/local/camel-local-store.c @@ -39,12 +39,11 @@ #define CLOCALS_CLASS(so) CAMEL_LOCAL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) #define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) +static void construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex); static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex); static char *get_name(CamelService *service, gboolean brief); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); -static char *get_default_folder_name (CamelStore *store, CamelException *ex); +static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex); -static char *get_folder_name(CamelStore *store, const char *folder_name, CamelException *ex); static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, gboolean fast, gboolean recursive, gboolean subscribed_only, @@ -52,18 +51,21 @@ static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex); static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex); +static CamelStoreClass *parent_class = NULL; + static void camel_local_store_class_init (CamelLocalStoreClass *camel_local_store_class) { CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_local_store_class); CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_local_store_class); + parent_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ())); + /* virtual method overload */ + camel_service_class->construct = construct; camel_service_class->get_name = get_name; camel_store_class->get_folder = get_folder; - camel_store_class->get_root_folder_name = get_root_folder_name; - camel_store_class->get_default_folder_name = get_default_folder_name; - camel_store_class->get_folder_name = get_folder_name; + camel_store_class->get_inbox = get_inbox; camel_store_class->get_folder_info = get_folder_info; camel_store_class->free_folder_info = camel_store_free_folder_info_full; @@ -71,18 +73,6 @@ camel_local_store_class_init (CamelLocalStoreClass *camel_local_store_class) camel_store_class->rename_folder = rename_folder; } -static void -camel_local_store_init (gpointer object, gpointer klass) -{ - CamelStore *store = CAMEL_STORE (object); - - /* local names are filenames, so they are case-sensitive. */ - if (store->folders) - g_hash_table_destroy(store->folders); - - store->folders = g_hash_table_new (g_str_hash, g_str_equal); -} - CamelType camel_local_store_get_type (void) { @@ -94,13 +84,29 @@ camel_local_store_get_type (void) sizeof (CamelLocalStoreClass), (CamelObjectClassInitFunc) camel_local_store_class_init, NULL, - (CamelObjectInitFunc) camel_local_store_init, + NULL, NULL); } return camel_local_store_type; } +static void +construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex) +{ + int len; + + CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex); + if (camel_exception_is_set (ex)) + return; + + len = strlen (service->url->path); + if (service->url->path[len - 1] != '/') { + service->url->path = g_realloc (service->url->path, len + 2); + strcpy (service->url->path + len, "/"); + } +} + const char * camel_local_store_get_toplevel_dir (CamelLocalStore *store) { @@ -161,37 +167,15 @@ get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelExce return NULL; } -static char * -get_root_folder_name(CamelStore *store, CamelException *ex) -{ - camel_exception_set(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Local stores do not have a root folder")); - return NULL; -} - -static char * -get_default_folder_name(CamelStore *store, CamelException *ex) +static CamelFolder * +get_inbox(CamelStore *store, CamelException *ex) { camel_exception_set(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Local stores do not have a default folder")); + _("Local stores do not have an inbox")); return NULL; } static char * -get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) -{ - /* For now, we don't allow hieararchy. FIXME. */ - if (strchr (folder_name + 1, '/')) { - camel_exception_set (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Local folders may not be nested.")); - return NULL; - } - - return *folder_name == '/' ? g_strdup (folder_name) : - g_strdup_printf ("/%s", folder_name); -} - -static char * get_name (CamelService *service, gboolean brief) { if (brief) diff --git a/camel/providers/local/camel-maildir-store.c b/camel/providers/local/camel-maildir-store.c index f5bd353b6f..d419095ea0 100644 --- a/camel/providers/local/camel-maildir-store.c +++ b/camel/providers/local/camel-maildir-store.c @@ -56,14 +56,6 @@ static void camel_maildir_store_class_init(CamelObjectClass * camel_maildir_stor camel_store_class->delete_folder = delete_folder; } -static void camel_maildir_store_init(CamelObject * object) -{ - CamelStore *store = CAMEL_STORE(object); - - /* maildir names are filenames, so they are case-sensitive. */ - store->folders = g_hash_table_new(g_str_hash, g_str_equal); -} - CamelType camel_maildir_store_get_type(void) { static CamelType camel_maildir_store_type = CAMEL_INVALID_TYPE; @@ -74,7 +66,7 @@ CamelType camel_maildir_store_get_type(void) sizeof(CamelMaildirStoreClass), (CamelObjectClassInitFunc) camel_maildir_store_class_init, NULL, - (CamelObjectInitFunc) camel_maildir_store_init, + NULL, NULL); } diff --git a/camel/providers/local/camel-mbox-store.c b/camel/providers/local/camel-mbox-store.c index 8ae0891b31..c6ddc7ce0a 100644 --- a/camel/providers/local/camel-mbox-store.c +++ b/camel/providers/local/camel-mbox-store.c @@ -54,15 +54,6 @@ camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_store_class) camel_store_class->delete_folder = delete_folder; } -static void -camel_mbox_store_init (gpointer object, gpointer klass) -{ - CamelStore *store = CAMEL_STORE (object); - - /* mbox names are filenames, so they are case-sensitive. */ - store->folders = g_hash_table_new (g_str_hash, g_str_equal); -} - CamelType camel_mbox_store_get_type (void) { @@ -74,7 +65,7 @@ camel_mbox_store_get_type (void) sizeof (CamelMboxStoreClass), (CamelObjectClassInitFunc) camel_mbox_store_class_init, NULL, - (CamelObjectInitFunc) camel_mbox_store_init, + NULL, NULL); } diff --git a/camel/providers/local/camel-mh-store.c b/camel/providers/local/camel-mh-store.c index 3d637e4cad..a488a71c12 100644 --- a/camel/providers/local/camel-mh-store.c +++ b/camel/providers/local/camel-mh-store.c @@ -54,14 +54,6 @@ static void camel_mh_store_class_init(CamelObjectClass * camel_mh_store_class) camel_store_class->delete_folder = delete_folder; } -static void camel_mh_store_init(CamelObject * object) -{ - CamelStore *store = CAMEL_STORE(object); - - /* mh names are filenames, so they are case-sensitive. */ - store->folders = g_hash_table_new(g_str_hash, g_str_equal); -} - CamelType camel_mh_store_get_type(void) { static CamelType camel_mh_store_type = CAMEL_INVALID_TYPE; @@ -72,7 +64,7 @@ CamelType camel_mh_store_get_type(void) sizeof(CamelMhStoreClass), (CamelObjectClassInitFunc) camel_mh_store_class_init, NULL, - (CamelObjectInitFunc) camel_mh_store_init, + NULL, NULL); } diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c index 8edf05e099..c1e8fb81e8 100644 --- a/camel/providers/nntp/camel-nntp-store.c +++ b/camel/providers/nntp/camel-nntp-store.c @@ -543,12 +543,6 @@ nntp_store_get_folder_info (CamelStore *store, const char *top, } } -static char * -nntp_store_get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup (""); -} - static gboolean nntp_store_folder_subscribed (CamelStore *store, const char *folder_name) { @@ -601,7 +595,6 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class) camel_service_class->get_name = nntp_store_get_name; camel_store_class->get_folder = nntp_store_get_folder; - camel_store_class->get_root_folder_name = nntp_store_get_root_folder_name; camel_store_class->get_folder_info = nntp_store_get_folder_info; camel_store_class->free_folder_info = camel_store_free_folder_info_full; diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c index f0338a8584..fac9cae931 100644 --- a/camel/providers/pop3/camel-pop3-store.c +++ b/camel/providers/pop3/camel-pop3-store.c @@ -76,9 +76,6 @@ static GList *query_auth_types (CamelService *service, gboolean connect, CamelEx static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); static int pop3_get_response (CamelPop3Store *store, char **ret, CamelException *ex); @@ -90,9 +87,6 @@ camel_pop3_store_class_init (CamelPop3StoreClass *camel_pop3_store_class) CAMEL_SERVICE_CLASS (camel_pop3_store_class); CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_pop3_store_class); - /*CamelRemoteStoreClass *camel_remote_store_class = - * CAMEL_STORE_CLASS (camel_pop3_store_class); - */ parent_class = CAMEL_REMOTE_STORE_CLASS(camel_type_get_global_classfuncs (camel_remote_store_get_type ())); @@ -103,8 +97,6 @@ camel_pop3_store_class_init (CamelPop3StoreClass *camel_pop3_store_class) camel_service_class->disconnect = pop3_disconnect; camel_store_class->get_folder = get_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_root_folder_name = get_root_folder_name; } @@ -533,26 +525,12 @@ static CamelFolder * get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { - return camel_pop3_folder_new (store, ex); -} - -static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - if (!g_strcasecmp (folder_name, "inbox")) - return g_strdup ("inbox"); - else { + if (g_strcasecmp (folder_name, "inbox") != 0) { camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID, _("No such folder `%s'."), folder_name); return NULL; } -} - -static char * -get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup ("inbox"); + return camel_pop3_folder_new (store, ex); } diff --git a/camel/providers/vee/camel-vee-store.c b/camel/providers/vee/camel-vee-store.c index 7acc127542..b39707e1a0 100644 --- a/camel/providers/vee/camel-vee-store.c +++ b/camel/providers/vee/camel-vee-store.c @@ -23,7 +23,6 @@ #include "camel-vee-folder.h" static CamelFolder *vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -static char *vee_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); struct _CamelVeeStorePrivate { }; @@ -63,7 +62,6 @@ camel_vee_store_class_init (CamelVeeStoreClass *klass) /* virtual method overload */ store_class->get_folder = vee_get_folder; - store_class->get_folder_name = vee_get_folder_name; } static void @@ -93,10 +91,3 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel { return camel_vee_folder_new (store, folder_name, ex); } - -static char * -vee_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) -{ - return g_strdup(folder_name); -} - |