aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog40
-rw-r--r--camel/camel-remote-store.c13
-rw-r--r--camel/camel-service.c83
-rw-r--r--camel/camel-service.h10
-rw-r--r--camel/camel-session.c9
-rw-r--r--camel/camel-store.c320
-rw-r--r--camel/camel-store.h25
-rw-r--r--camel/providers/imap/camel-imap-store.c47
-rw-r--r--camel/providers/local/camel-local-store.c72
-rw-r--r--camel/providers/local/camel-maildir-store.c10
-rw-r--r--camel/providers/local/camel-mbox-store.c11
-rw-r--r--camel/providers/local/camel-mh-store.c10
-rw-r--r--camel/providers/nntp/camel-nntp-store.c7
-rw-r--r--camel/providers/pop3/camel-pop3-store.c26
-rw-r--r--camel/providers/vee/camel-vee-store.c9
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);
-}
-