From: Matthew Barnes Date: Tue, 19 Apr 2011 19:32:47 +0000 (-0400) Subject: Rework how CamelServices are added to CamelSession. X-Git-Tag: upstream/3.7.4~2112 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e0ac4d79705c8b51783c71b362499f38c15ee496;p=platform%2Fupstream%2Fevolution-data-server.git Rework how CamelServices are added to CamelSession. * Give CamelServices a simple unique ID string. That will be its identity from now on, not its URL. * Split adding a CamelService and retrieving a CamelService into two separate operations. Adding a CamelService requires both a UID and CamelURL (for now), retrieving a CamelService just requires the UID. * CamelService now implements the GInitable interface, replacing its construct() method. --- diff --git a/camel/camel-disco-store.c b/camel/camel-disco-store.c index d6e6306..fb3c1db 100644 --- a/camel/camel-disco-store.c +++ b/camel/camel-disco-store.c @@ -38,25 +38,25 @@ G_DEFINE_TYPE (CamelDiscoStore, camel_disco_store, CAMEL_TYPE_STORE) -static gboolean -disco_store_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) +static void +disco_store_constructed (GObject *object) { - CamelServiceClass *service_class; - CamelDiscoStore *disco = CAMEL_DISCO_STORE (service); + CamelDiscoStore *disco; + CamelService *service; + CamelSession *session; - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_disco_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; + disco = CAMEL_DISCO_STORE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (camel_disco_store_parent_class)->constructed (object); - disco->status = camel_session_get_online (session) ? - CAMEL_DISCO_STORE_ONLINE : CAMEL_DISCO_STORE_OFFLINE; + service = CAMEL_SERVICE (object); + session = camel_service_get_session (service); - return TRUE; + if (camel_session_get_online (session)) + disco->status = CAMEL_DISCO_STORE_ONLINE; + else + disco->status = CAMEL_DISCO_STORE_OFFLINE; } static void @@ -311,11 +311,14 @@ disco_store_set_status (CamelDiscoStore *disco_store, static void camel_disco_store_class_init (CamelDiscoStoreClass *class) { + GObjectClass *object_class; CamelServiceClass *service_class; CamelStoreClass *store_class; + object_class = G_OBJECT_CLASS (class); + object_class->constructed = disco_store_constructed; + service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = disco_store_construct; service_class->cancel_connect = disco_store_cancel_connect; service_class->connect_sync = disco_store_connect_sync; service_class->disconnect_sync = disco_store_disconnect_sync; diff --git a/camel/camel-offline-store.c b/camel/camel-offline-store.c index eb4e608..e5f5b12 100644 --- a/camel/camel-offline-store.c +++ b/camel/camel-offline-store.c @@ -31,49 +31,47 @@ #include "camel-offline-store.h" #include "camel-session.h" +#define CAMEL_OFFLINE_STORE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), CAMEL_TYPE_OFFLINE_STORE, CamelOfflineStorePrivate)) + struct _CamelOfflineStorePrivate { gboolean online; }; G_DEFINE_TYPE (CamelOfflineStore, camel_offline_store, CAMEL_TYPE_STORE) -static gboolean -offline_store_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) +static void +offline_store_constructed (GObject *object) { - CamelOfflineStore *store = CAMEL_OFFLINE_STORE (service); - CamelServiceClass *service_class; + CamelOfflineStorePrivate *priv; + CamelSession *session; - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_offline_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; + priv = CAMEL_OFFLINE_STORE_GET_PRIVATE (object); - store->priv->online = camel_session_get_online (session); + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (camel_offline_store_parent_class)-> + constructed (object); - return TRUE; + session = camel_service_get_session (CAMEL_SERVICE (object)); + priv->online = camel_session_get_online (session); } static void camel_offline_store_class_init (CamelOfflineStoreClass *class) { - CamelServiceClass *service_class; + GObjectClass *object_class; g_type_class_add_private (class, sizeof (CamelOfflineStorePrivate)); - service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = offline_store_construct; + object_class = G_OBJECT_CLASS (class); + object_class->constructed = offline_store_constructed; } static void camel_offline_store_init (CamelOfflineStore *store) { - store->priv = G_TYPE_INSTANCE_GET_PRIVATE ( - store, CAMEL_TYPE_OFFLINE_STORE, CamelOfflineStorePrivate); - store->priv->online = TRUE; + store->priv = CAMEL_OFFLINE_STORE_GET_PRIVATE (store); } /** diff --git a/camel/camel-provider.c b/camel/camel-provider.c index edea3ae..67f45bf 100644 --- a/camel/camel-provider.c +++ b/camel/camel-provider.c @@ -243,12 +243,6 @@ camel_provider_register (CamelProvider *provider) return; } - for (i = 0; i < CAMEL_NUM_PROVIDER_TYPES; i++) { - if (provider->object_types[i]) - provider->service_cache[i] = camel_object_bag_new (provider->url_hash, provider->url_equal, - (CamelCopyFunc)camel_url_copy, (GFreeFunc)camel_url_free); - } - /* Translate all strings here */ #define P_(string) dgettext (provider->translation_domain, string) diff --git a/camel/camel-provider.h b/camel/camel-provider.h index e98dd8c..8645685 100644 --- a/camel/camel-provider.h +++ b/camel/camel-provider.h @@ -223,8 +223,6 @@ typedef struct { /* GList of CamelServiceAuthTypes the provider supports */ GList *authtypes; - CamelObjectBag *service_cache[CAMEL_NUM_PROVIDER_TYPES]; - GHashFunc url_hash; GCompareFunc url_equal; diff --git a/camel/camel-sasl-popb4smtp.c b/camel/camel-sasl-popb4smtp.c index 24caa99..0f2de6e 100644 --- a/camel/camel-sasl-popb4smtp.c +++ b/camel/camel-sasl-popb4smtp.c @@ -65,33 +65,57 @@ sasl_popb4smtp_challenge_sync (CamelSasl *sasl, GCancellable *cancellable, GError **error) { - gchar *popuri; CamelService *service; CamelSession *session; - CamelStore *store; time_t now, *timep; + const gchar *type_name; + const gchar *uid; + gchar *pop_uid; service = camel_sasl_get_service (sasl); session = camel_service_get_session (service); + uid = camel_service_get_uid (service); + camel_sasl_set_authenticated (sasl, FALSE); - popuri = camel_session_get_password ( - session, service, NULL, _("POP Source URI"), - "popb4smtp_uri", 0, error); + pop_uid = camel_session_get_password ( + session, service, NULL, _("POP Source UID"), + "popb4smtp_uid", 0, error); + + if (pop_uid != NULL) + service = camel_session_get_service (session, pop_uid); + else + service = NULL; + + if (service == NULL) { + g_set_error ( + error, CAMEL_SERVICE_ERROR, + CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE, + _("POP Before SMTP authentication " + "using an unknown transport")); + g_free (pop_uid); + return NULL; + } + + type_name = G_OBJECT_TYPE_NAME (service); - if (popuri == NULL) { + if (!CAMEL_IS_STORE (service)) { g_set_error ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE, - _("POP Before SMTP authentication using an unknown transport")); + _("POP Before SMTP authentication attempted " + "with a %s service"), type_name); + g_free (pop_uid); return NULL; } - if (g_ascii_strncasecmp(popuri, "pop:", 4) != 0) { + if (strstr (type_name, "POP") == NULL) { g_set_error ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE, - _("POP Before SMTP authentication using a non-POP source")); + _("POP Before SMTP authentication attempted " + "with a %s service"), type_name); + g_free (pop_uid); return NULL; } @@ -101,24 +125,22 @@ sasl_popb4smtp_challenge_sync (CamelSasl *sasl, /* need to lock around the whole thing until finished with timep */ POPB4SMTP_LOCK (lock); - timep = g_hash_table_lookup (poplast, popuri); + timep = g_hash_table_lookup (poplast, pop_uid); if (timep) { if ((*timep + POPB4SMTP_TIMEOUT) > now) { camel_sasl_set_authenticated (sasl, TRUE); POPB4SMTP_UNLOCK (lock); - g_free (popuri); + g_free (pop_uid); return NULL; } } else { timep = g_malloc0 (sizeof (*timep)); - g_hash_table_insert (poplast, g_strdup (popuri), timep); + g_hash_table_insert (poplast, g_strdup (pop_uid), timep); } /* connect to pop session */ - store = camel_session_get_store (session, popuri, error); - if (store) { + if (camel_service_connect_sync (service, error)) { camel_sasl_set_authenticated (sasl, TRUE); - g_object_unref (store); *timep = now; } else { camel_sasl_set_authenticated (sasl, FALSE); @@ -127,7 +149,7 @@ sasl_popb4smtp_challenge_sync (CamelSasl *sasl, POPB4SMTP_UNLOCK (lock); - g_free (popuri); + g_free (pop_uid); return NULL; } diff --git a/camel/camel-service.c b/camel/camel-service.c index e844cb8..181c910 100644 --- a/camel/camel-service.c +++ b/camel/camel-service.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -44,11 +45,18 @@ #define d(x) #define w(x) +#define CAMEL_SERVICE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), CAMEL_TYPE_SERVICE, CamelServicePrivate)) + struct _CamelServicePrivate { - CamelSession *session; CamelProvider *provider; + CamelSession *session; CamelURL *url; + gchar *user_data_dir; + gchar *uid; + GCancellable *connect_op; CamelServiceConnectionStatus status; @@ -56,166 +64,284 @@ struct _CamelServicePrivate { GStaticMutex connect_op_lock; /* for locking the connection_op */ }; -G_DEFINE_ABSTRACT_TYPE (CamelService, camel_service, CAMEL_TYPE_OBJECT) +enum { + PROP_0, + PROP_PROVIDER, + PROP_SESSION, + PROP_UID, + PROP_URL +}; -static void -service_finalize (GObject *object) +/* Forward Declarations */ +static void camel_service_initable_init (GInitableIface *interface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE ( + CamelService, camel_service, CAMEL_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, camel_service_initable_init)) + +static gchar * +service_find_old_data_dir (CamelService *service) { - CamelService *service = CAMEL_SERVICE (object); + CamelProvider *provider; + CamelSession *session; + CamelURL *url; + GString *path; + gboolean allows_host; + gboolean allows_user; + gboolean needs_host; + gboolean needs_path; + gboolean needs_user; + const gchar *base_dir; + gchar *old_data_dir; + + provider = camel_service_get_provider (service); + session = camel_service_get_session (service); + url = camel_service_get_camel_url (service); - if (service->priv->status == CAMEL_SERVICE_CONNECTED) - CAMEL_SERVICE_GET_CLASS (service)->disconnect_sync ( - service, TRUE, NULL, NULL); + allows_host = CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_HOST); + allows_user = CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_USER); + + needs_host = CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_HOST); + needs_path = CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_PATH); + needs_user = CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_USER); + + /* This function reproduces the way service data directories used + * to be determined before we moved to just using the UID. If the + * old data directory exists, try renaming it to the new form. + * + * A virtual class method was used to determine the directory path, + * but no known CamelProviders ever overrode the default algorithm + * below. So this should work for everyone. */ + + path = g_string_new (provider->protocol); + + if (allows_user) { + g_string_append_c (path, '/'); + if (url->user != NULL) + g_string_append (path, url->user); + if (allows_host) { + g_string_append_c (path, '@'); + if (url->host != NULL) + g_string_append (path, url->host); + if (url->port) { + g_string_append_c (path, ':'); + g_string_append_printf (path, "%d", url->port); + } + } else if (!needs_user) { + g_string_append_c (path, '@'); + } - if (service->priv->url) - camel_url_free (service->priv->url); + } else if (allows_host) { + g_string_append_c (path, '/'); + if (!needs_host) + g_string_append_c (path, '@'); + if (url->host != NULL) + g_string_append (path, url->host); + if (url->port) { + g_string_append_c (path, ':'); + g_string_append_printf (path, "%d", url->port); + } + } - if (service->priv->session) - g_object_unref (service->priv->session); + if (needs_path) { + if (*url->path != '/') + g_string_append_c (path, '/'); + g_string_append (path, url->path); + } - g_static_rec_mutex_free (&service->priv->connect_lock); - g_static_mutex_free (&service->priv->connect_op_lock); + base_dir = camel_session_get_user_data_dir (session); + old_data_dir = g_build_filename (base_dir, path->str, NULL); - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (camel_service_parent_class)->finalize (object); -} + g_string_free (path, TRUE); -static gboolean -service_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) -{ - gchar *err, *url_string; - - if (CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_USER) && - (url->user == NULL || url->user[0] == '\0')) { - err = _("URL '%s' needs a username component"); - goto fail; - } else if (CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_HOST) && - (url->host == NULL || url->host[0] == '\0')) { - err = _("URL '%s' needs a host component"); - goto fail; - } else if (CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_PATH) && - (url->path == NULL || url->path[0] == '\0')) { - err = _("URL '%s' needs a path component"); - goto fail; + if (!g_file_test (old_data_dir, G_FILE_TEST_IS_DIR)) { + g_free (old_data_dir); + old_data_dir = NULL; } + return old_data_dir; +} + +static void +service_set_provider (CamelService *service, + CamelProvider *provider) +{ + g_return_if_fail (provider != NULL); + g_return_if_fail (service->priv->provider == NULL); + service->priv->provider = provider; - service->priv->url = camel_url_copy (url); +} + +static void +service_set_session (CamelService *service, + CamelSession *session) +{ + g_return_if_fail (CAMEL_IS_SESSION (session)); + g_return_if_fail (service->priv->session == NULL); + service->priv->session = g_object_ref (session); +} - service->priv->status = CAMEL_SERVICE_DISCONNECTED; +static void +service_set_uid (CamelService *service, + const gchar *uid) +{ + g_return_if_fail (uid != NULL); + g_return_if_fail (service->priv->uid == NULL); - return TRUE; + service->priv->uid = g_strdup (uid); +} -fail: - url_string = camel_url_to_string (url, CAMEL_URL_HIDE_PASSWORD); - g_set_error ( - error, CAMEL_SERVICE_ERROR, - CAMEL_SERVICE_ERROR_URL_INVALID, - err, url_string); - g_free (url_string); +static void +service_set_url (CamelService *service, + CamelURL *url) +{ + g_return_if_fail (url != NULL); + g_return_if_fail (service->priv->url == NULL); - return FALSE; + service->priv->url = camel_url_copy (url); } -static gchar * -service_get_name (CamelService *service, - gboolean brief) +static void +service_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - g_warning ( - "%s does not implement CamelServiceClass::get_name()", - G_OBJECT_TYPE_NAME (service)); + switch (property_id) { + case PROP_PROVIDER: + service_set_provider ( + CAMEL_SERVICE (object), + g_value_get_pointer (value)); + return; + + case PROP_SESSION: + service_set_session ( + CAMEL_SERVICE (object), + g_value_get_object (value)); + return; + + case PROP_UID: + service_set_uid ( + CAMEL_SERVICE (object), + g_value_get_string (value)); + return; + + case PROP_URL: + service_set_url ( + CAMEL_SERVICE (object), + g_value_get_boxed (value)); + return; + } - return g_strdup (G_OBJECT_TYPE_NAME (service)); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } -static gchar * -service_get_path (CamelService *service) -{ - CamelProvider *prov = service->priv->provider; - CamelURL *url = service->priv->url; - GString *use_path1 = NULL, *use_path2 = NULL; - gchar *ret_path = NULL; - - /* A sort of ad-hoc default implementation that works for our - * current set of services. - */ - - if (CAMEL_PROVIDER_ALLOWS (prov, CAMEL_URL_PART_USER)) { - use_path1 = g_string_new (""); - - if (CAMEL_PROVIDER_ALLOWS (prov, CAMEL_URL_PART_HOST)) { - g_string_append_printf (use_path1, "%s@%s", - url->user ? url->user : "", - url->host ? url->host : ""); - - if (url->port) - g_string_append_printf (use_path1, ":%d", url->port); - } else { - g_string_append_printf (use_path1, "%s%s", url->user ? url->user : "", - CAMEL_PROVIDER_NEEDS (prov, CAMEL_URL_PART_USER) ? "" : "@"); - } +static void +service_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_PROVIDER: + g_value_set_pointer ( + value, camel_service_get_provider ( + CAMEL_SERVICE (object))); + return; + + case PROP_SESSION: + g_value_set_object ( + value, camel_service_get_session ( + CAMEL_SERVICE (object))); + return; + + case PROP_UID: + g_value_set_string ( + value, camel_service_get_uid ( + CAMEL_SERVICE (object))); + return; + + case PROP_URL: + g_value_set_boxed ( + value, camel_service_get_url ( + CAMEL_SERVICE (object))); + return; + } - e_filename_make_safe (use_path1->str); - } else if (CAMEL_PROVIDER_ALLOWS (prov, CAMEL_URL_PART_HOST)) { - use_path1 = g_string_new (""); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} - g_string_append_printf (use_path1, "%s%s", - CAMEL_PROVIDER_NEEDS (prov, CAMEL_URL_PART_HOST) ? "" : "@", - url->host ? url->host : ""); +static void +service_dispose (GObject *object) +{ + CamelServicePrivate *priv; - if (url->port) - g_string_append_printf (use_path1, ":%d", url->port); + priv = CAMEL_SERVICE_GET_PRIVATE (object); - e_filename_make_safe (use_path1->str); + if (priv->session != NULL) { + g_object_unref (priv->session); + priv->session = NULL; } - if (CAMEL_PROVIDER_NEEDS (prov, CAMEL_URL_PART_PATH) && url->path && *url->path) { - use_path2 = g_string_new (*url->path == '/' ? url->path + 1 : url->path); + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (camel_service_parent_class)->dispose (object); +} - /* fix directory separators, if needed */ - if (G_DIR_SEPARATOR != '/') { - gchar **elems = g_strsplit (use_path2->str, "/", -1); +static void +service_finalize (GObject *object) +{ + CamelServicePrivate *priv; - if (elems) { - gint ii; + priv = CAMEL_SERVICE_GET_PRIVATE (object); - g_string_truncate (use_path2, 0); + if (priv->status == CAMEL_SERVICE_CONNECTED) + CAMEL_SERVICE_GET_CLASS (object)->disconnect_sync ( + CAMEL_SERVICE (object), TRUE, NULL, NULL); - for (ii = 0; elems[ii]; ii++) { - gchar *elem = elems[ii]; + if (priv->url != NULL) + camel_url_free (priv->url); - if (*elem) { - e_filename_make_safe (elem); + g_free (priv->user_data_dir); + g_free (priv->uid); - if (use_path2->len) - g_string_append_c (use_path2, G_DIR_SEPARATOR); - g_string_append (use_path2, elem); - } - } + g_static_rec_mutex_free (&priv->connect_lock); + g_static_mutex_free (&priv->connect_op_lock); - g_strfreev (elems); - } - } - } + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (camel_service_parent_class)->finalize (object); +} - if (!use_path1 && use_path2) { - use_path1 = use_path2; - use_path2 = NULL; - } +static void +service_constructed (GObject *object) +{ + CamelService *service; + CamelSession *session; + const gchar *base_data_dir; + const gchar *uid; - ret_path = g_build_filename (service->priv->provider->protocol, use_path1 ? use_path1->str : NULL, use_path2 ? use_path2->str : NULL, NULL); + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (camel_service_parent_class)->constructed (object); - if (use_path1) - g_string_free (use_path1, TRUE); - if (use_path2) - g_string_free (use_path2, TRUE); + service = CAMEL_SERVICE (object); + session = camel_service_get_session (service); - return ret_path; + uid = camel_service_get_uid (service); + base_data_dir = camel_session_get_user_data_dir (session); + + service->priv->user_data_dir = + g_build_filename (base_data_dir, uid, NULL); +} + +static gchar * +service_get_name (CamelService *service, + gboolean brief) +{ + g_warning ( + "%s does not implement CamelServiceClass::get_name()", + G_OBJECT_TYPE_NAME (service)); + + return g_strdup (G_OBJECT_TYPE_NAME (service)); } static void @@ -253,6 +379,76 @@ service_query_auth_types_sync (CamelService *service, return NULL; } +static gboolean +service_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + CamelProvider *provider; + CamelService *service; + CamelURL *url; + gboolean success = FALSE; + const gchar *new_data_dir; + gchar *old_data_dir; + gchar *url_string; + + service = CAMEL_SERVICE (initable); + url = camel_service_get_camel_url (service); + provider = camel_service_get_provider (service); + + url_string = camel_url_to_string (url, CAMEL_URL_HIDE_PASSWORD); + + if (CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_USER)) { + if (url->user == NULL || *url->user == '\0') { + g_set_error ( + error, CAMEL_SERVICE_ERROR, + CAMEL_SERVICE_ERROR_URL_INVALID, + _("URL '%s' needs a user component"), + url_string); + goto exit; + } + } + + if (CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_HOST)) { + if (url->host == NULL || *url->host == '\0') { + g_set_error ( + error, CAMEL_SERVICE_ERROR, + CAMEL_SERVICE_ERROR_URL_INVALID, + _("URL '%s' needs a host component"), + url_string); + goto exit; + } + } + + if (CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_PATH)) { + if (url->path == NULL || *url->path == '\0') { + g_set_error ( + error, CAMEL_SERVICE_ERROR, + CAMEL_SERVICE_ERROR_URL_INVALID, + _("URL '%s' needs a path component"), + url_string); + goto exit; + } + } + + new_data_dir = camel_service_get_user_data_dir (service); + old_data_dir = service_find_old_data_dir (service); + + /* If the old data directory name exists, try renaming + * it to the new data directory. Failure is non-fatal. */ + if (old_data_dir != NULL) { + g_rename (old_data_dir, new_data_dir); + g_free (old_data_dir); + } + + success = TRUE; + +exit: + g_free (url_string); + + return success; +} + static void camel_service_class_init (CamelServiceClass *class) { @@ -261,22 +457,78 @@ camel_service_class_init (CamelServiceClass *class) g_type_class_add_private (class, sizeof (CamelServicePrivate)); object_class = G_OBJECT_CLASS (class); + object_class->set_property = service_set_property; + object_class->get_property = service_get_property; + object_class->dispose = service_dispose; object_class->finalize = service_finalize; + object_class->constructed = service_constructed; - class->construct = service_construct; class->get_name = service_get_name; - class->get_path = service_get_path; class->cancel_connect = service_cancel_connect; class->connect_sync = service_connect_sync; class->disconnect_sync = service_disconnect_sync; class->query_auth_types_sync = service_query_auth_types_sync; + + g_object_class_install_property ( + object_class, + PROP_PROVIDER, + g_param_spec_pointer ( + "provider", + "Provider", + "The CamelProvider for the service", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_SESSION, + g_param_spec_object ( + "session", + "Session", + "A CamelSession instance", + CAMEL_TYPE_SESSION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_UID, + g_param_spec_string ( + "uid", + "UID", + "The unique identity of the service", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_URL, + g_param_spec_boxed ( + "url", + "URL", + "The CamelURL for the service", + CAMEL_TYPE_URL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +camel_service_initable_init (GInitableIface *interface) +{ + interface->init = service_initable_init; } static void camel_service_init (CamelService *service) { - service->priv = G_TYPE_INSTANCE_GET_PRIVATE ( - service, CAMEL_TYPE_SERVICE, CamelServicePrivate); + service->priv = CAMEL_SERVICE_GET_PRIVATE (service); + + service->priv->status = CAMEL_SERVICE_DISCONNECTED; g_static_rec_mutex_init (&service->priv->connect_lock); g_static_mutex_init (&service->priv->connect_op_lock); @@ -296,40 +548,6 @@ camel_service_error_quark (void) } /** - * camel_service_construct: - * @service: a #CamelService - * @session: the #CamelSession for @service - * @provider: the #CamelProvider associated with @service - * @url: the default URL for the service (may be %NULL) - * @error: return location for a #GError, or %NULL - * - * Constructs a #CamelService initialized with the given parameters. - * - * Returns: %TRUE on success, %FALSE on failure - **/ -gboolean -camel_service_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) -{ - CamelServiceClass *class; - gboolean success; - - g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE); - g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); - - class = CAMEL_SERVICE_GET_CLASS (service); - g_return_val_if_fail (class->construct != NULL, FALSE); - - success = class->construct (service, session, provider, url, error); - CAMEL_CHECK_GERROR (service, construct, success, error); - - return success; -} - -/** * camel_service_cancel_connect: * @service: a #CamelService * @@ -354,6 +572,27 @@ camel_service_cancel_connect (CamelService *service) } /** + * camel_service_get_user_data_dir: + * @service: a #CamelService + * + * Returns the base directory under which to store user-specific data + * for @service. The directory is formed by appending the directory + * returned by camel_session_get_user_data_dir() with the service's + * #CamelService:uid value. + * + * Returns: the base directory for @service + * + * Since: 3.2 + **/ +const gchar * +camel_service_get_user_data_dir (CamelService *service) +{ + g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL); + + return service->priv->user_data_dir; +} + +/** * camel_service_get_name: * @service: a #CamelService * @brief: whether or not to use a briefer form @@ -381,29 +620,19 @@ camel_service_get_name (CamelService *service, } /** - * camel_service_get_path: + * camel_service_get_provider: * @service: a #CamelService * - * This gets a valid UNIX relative path describing @service, which - * is guaranteed to be different from the path returned for any - * different service. This path MUST start with the name of the - * provider, followed by a "/", but after that, it is up to the - * provider. + * Gets the #CamelProvider associated with the service. * - * Returns: the path, which the caller must free + * Returns: the #CamelProvider **/ -gchar * -camel_service_get_path (CamelService *service) +CamelProvider * +camel_service_get_provider (CamelService *service) { - CamelServiceClass *class; - g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL); - g_return_val_if_fail (service->priv->url, NULL); - class = CAMEL_SERVICE_GET_CLASS (service); - g_return_val_if_fail (class->get_path != NULL, NULL); - - return class->get_path (service); + return service->priv->provider; } /** @@ -412,7 +641,7 @@ camel_service_get_path (CamelService *service) * * Gets the #CamelSession associated with the service. * - * Returns: the session + * Returns: the #CamelSession **/ CamelSession * camel_service_get_session (CamelService *service) @@ -423,19 +652,21 @@ camel_service_get_session (CamelService *service) } /** - * camel_service_get_provider: + * camel_service_get_uid: * @service: a #CamelService * - * Gets the #CamelProvider associated with the service. + * Gets the unique identifier string associated with the service. * - * Returns: the provider + * Returns: the UID string + * + * Since: 3.2 **/ -CamelProvider * -camel_service_get_provider (CamelService *service) +const gchar * +camel_service_get_uid (CamelService *service) { g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL); - return service->priv->provider; + return service->priv->uid; } /** diff --git a/camel/camel-service.h b/camel/camel-service.h index fd37ce0..f70472c 100644 --- a/camel/camel-service.h +++ b/camel/camel-service.h @@ -107,14 +107,8 @@ struct _CamelService { struct _CamelServiceClass { CamelObjectClass parent_class; - gboolean (*construct) (CamelService *service, - struct _CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error); gchar * (*get_name) (CamelService *service, gboolean brief); - gchar * (*get_path) (CamelService *service); void (*cancel_connect) (CamelService *service); gboolean (*connect_sync) (CamelService *service, @@ -141,17 +135,13 @@ typedef struct { GType camel_service_get_type (void); GQuark camel_service_error_quark (void) G_GNUC_CONST; -gboolean camel_service_construct (CamelService *service, - struct _CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error); +const gchar * camel_service_get_user_data_dir (CamelService *service); gchar * camel_service_get_name (CamelService *service, gboolean brief); -gchar * camel_service_get_path (CamelService *service); CamelProvider * camel_service_get_provider (CamelService *service); struct _CamelSession * camel_service_get_session (CamelService *service); +const gchar * camel_service_get_uid (CamelService *service); CamelURL * camel_service_get_camel_url (CamelService *service); gchar * camel_service_get_url (CamelService *service); void camel_service_cancel_connect (CamelService *service); diff --git a/camel/camel-session.c b/camel/camel-session.c index 20b2a0d..85701b0 100644 --- a/camel/camel-session.c +++ b/camel/camel-session.c @@ -47,17 +47,23 @@ #include "camel-folder.h" #include "camel-mime-message.h" +#define CAMEL_SESSION_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), CAMEL_TYPE_SESSION, CamelSessionPrivate)) + #define d(x) struct _CamelSessionPrivate { GMutex *lock; /* for locking everything basically */ GMutex *thread_lock; /* locking threads */ + gchar *user_data_dir; + gint thread_id; GHashTable *thread_active; GThreadPool *thread_pool; - GHashTable *thread_msg_op; + GHashTable *services; GHashTable *junk_headers; gchar *socks_proxy_host; @@ -73,7 +79,7 @@ enum { PROP_CHECK_JUNK, PROP_NETWORK_AVAILABLE, PROP_ONLINE, - PROP_STORAGE_PATH + PROP_USER_DATA_DIR, }; G_DEFINE_TYPE (CamelSession, camel_session, CAMEL_TYPE_OBJECT) @@ -93,6 +99,16 @@ cs_thread_status (CamelOperation *operation, } static void +session_set_user_data_dir (CamelSession *session, + const gchar *user_data_dir) +{ + g_return_if_fail (user_data_dir != NULL); + g_return_if_fail (session->priv->user_data_dir == NULL); + + session->priv->user_data_dir = g_strdup (user_data_dir); +} + +static void session_set_property (GObject *object, guint property_id, const GValue *value, @@ -116,6 +132,12 @@ session_set_property (GObject *object, CAMEL_SESSION (object), g_value_get_boolean (value)); return; + + case PROP_USER_DATA_DIR: + session_set_user_data_dir ( + CAMEL_SESSION (object), + g_value_get_string (value)); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -145,33 +167,54 @@ session_get_property (GObject *object, value, camel_session_get_online ( CAMEL_SESSION (object))); return; + + case PROP_USER_DATA_DIR: + g_value_set_string ( + value, camel_session_get_user_data_dir ( + CAMEL_SESSION (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void +session_dispose (GObject *object) +{ + CamelSessionPrivate *priv; + + priv = CAMEL_SESSION_GET_PRIVATE (object); + + g_hash_table_remove_all (priv->services); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (camel_session_parent_class)->dispose (object); +} + +static void session_finalize (GObject *object) { - CamelSession *session = CAMEL_SESSION (object); - GThreadPool *thread_pool = session->priv->thread_pool; + CamelSessionPrivate *priv; + + priv = CAMEL_SESSION_GET_PRIVATE (object); - g_hash_table_destroy (session->priv->thread_active); + g_free (priv->user_data_dir); - if (thread_pool != NULL) { + g_hash_table_destroy (priv->services); + g_hash_table_destroy (priv->thread_active); + + if (priv->thread_pool != NULL) { /* there should be no unprocessed tasks */ - g_assert (g_thread_pool_unprocessed (thread_pool) == 0); - g_thread_pool_free (thread_pool, FALSE, FALSE); + g_assert (g_thread_pool_unprocessed (priv->thread_pool) == 0); + g_thread_pool_free (priv->thread_pool, FALSE, FALSE); } - g_free (session->storage_path); - - g_mutex_free (session->priv->lock); - g_mutex_free (session->priv->thread_lock); + g_mutex_free (priv->lock); + g_mutex_free (priv->thread_lock); - if (session->priv->junk_headers) { - g_hash_table_remove_all (session->priv->junk_headers); - g_hash_table_destroy (session->priv->junk_headers); + if (priv->junk_headers) { + g_hash_table_remove_all (priv->junk_headers); + g_hash_table_destroy (priv->junk_headers); } /* Chain up to parent's finalize() method. */ @@ -179,87 +222,74 @@ session_finalize (GObject *object) } static CamelService * -session_get_service (CamelSession *session, +session_add_service (CamelSession *session, + const gchar *uid, const gchar *url_string, CamelProviderType type, GError **error) { CamelURL *url; - CamelProvider *provider; CamelService *service; + CamelProvider *provider; + GType service_type = G_TYPE_INVALID; + + service = g_hash_table_lookup (session->priv->services, uid); + if (CAMEL_IS_SERVICE (service)) + return service; + + g_debug ("%s: Entering", G_STRFUNC); url = camel_url_new (url_string, error); - if (!url) + if (url == NULL) return NULL; - /* We need to look up the provider so we can then lookup - the service in the provider's cache */ + /* Try to find a suitable CamelService subclass. */ provider = camel_provider_get (url->protocol, error); - if (provider && !provider->object_types[type]) { + if (provider != NULL) + service_type = provider->object_types[type]; + + if (service_type == G_TYPE_INVALID) { g_set_error ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_URL_INVALID, _("No provider available for protocol '%s'"), url->protocol); - provider = NULL; + camel_url_free (url); + return NULL; } - if (!provider) { + if (!g_type_is_a (service_type, CAMEL_TYPE_SERVICE)) { + g_set_error ( + error, CAMEL_SERVICE_ERROR, + CAMEL_SERVICE_ERROR_INVALID, + _("Invalid GType registered for protocol '%s'"), + url->protocol); camel_url_free (url); return NULL; } - /* If the provider doesn't use paths but the URL contains one, - * ignore it. - */ - if (url->path && !CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_PATH)) + /* If the provider does not use paths but the URL contains one, + * ignore it. */ + if (!CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_PATH)) camel_url_set_path (url, NULL); - /* Now look up the service in the provider's cache */ - service = camel_object_bag_reserve (provider->service_cache[type], url); - if (service == NULL) { - service = g_object_new (provider->object_types[type], NULL); - if (!camel_service_construct (service, session, provider, url, error)) { - g_object_unref (service); - service = NULL; - camel_object_bag_abort (provider->service_cache[type], url); - } else { - camel_object_bag_add (provider->service_cache[type], url, service); - } - } + service = g_initable_new ( + service_type, NULL, error, + "provider", provider, "session", + session, "uid", uid, "url", url, NULL); - camel_url_free (url); - - return service; -} - -static gchar * -session_get_storage_path (CamelSession *session, - CamelService *service, - GError **error) -{ - gchar *service_path; - gchar *storage_path; + /* The hash table takes ownership of the new CamelService. */ + if (service != NULL) + g_hash_table_insert ( + session->priv->services, + g_strdup (uid), service); - service_path = camel_service_get_path (service); - storage_path = g_build_filename ( - session->storage_path, service_path, NULL); - g_free (service_path); + if (service != NULL) + g_debug ("%s: Adding %s (%s)", G_STRFUNC, uid, url_string); - if (g_access (storage_path, F_OK) == 0) - return storage_path; - - if (g_mkdir_with_parents (storage_path, S_IRWXU) == -1) { - g_set_error ( - error, G_IO_ERROR, - g_io_error_from_errno (errno), - _("Could not create directory %s:\n%s"), - storage_path, g_strerror (errno)); - g_free (storage_path); - storage_path = NULL; - } + camel_url_free (url); - return storage_path; + return service; } static gpointer @@ -378,10 +408,10 @@ camel_session_class_init (CamelSessionClass *class) object_class = G_OBJECT_CLASS (class); object_class->set_property = session_set_property; object_class->get_property = session_get_property; + object_class->dispose = session_dispose; object_class->finalize = session_finalize; - class->get_service = session_get_service; - class->get_storage_path = session_get_storage_path; + class->add_service = session_add_service; class->thread_msg_new = session_thread_msg_new; class->thread_msg_free = session_thread_msg_free; class->thread_queue = session_thread_queue; @@ -397,7 +427,8 @@ camel_session_class_init (CamelSessionClass *class) "Check incoming messages for junk", FALSE, G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property ( object_class, @@ -408,7 +439,8 @@ camel_session_class_init (CamelSessionClass *class) "Whether the network is available", TRUE, G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property ( object_class, @@ -419,58 +451,92 @@ camel_session_class_init (CamelSessionClass *class) "Whether the shell is online", TRUE, G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_USER_DATA_DIR, + g_param_spec_string ( + "user-data-dir", + "User Data Directory", + "User-specific base directory for mail data", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); } static void camel_session_init (CamelSession *session) { - session->priv = G_TYPE_INSTANCE_GET_PRIVATE ( - session, CAMEL_TYPE_SESSION, CamelSessionPrivate); + GHashTable *services; + + services = g_hash_table_new_full ( + (GHashFunc) g_str_hash, + (GEqualFunc) g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + session->priv = CAMEL_SESSION_GET_PRIVATE (session); + session->priv->lock = g_mutex_new (); session->priv->thread_lock = g_mutex_new (); session->priv->thread_id = 1; session->priv->thread_active = g_hash_table_new (NULL, NULL); session->priv->thread_pool = NULL; + session->priv->services = services; session->priv->junk_headers = NULL; } /** - * camel_session_construct: - * @session: a #CamelSession object to construct - * @storage_path: path to a directory the session can use for - * persistent storage. (This directory must already exist.) + * camel_session_get_user_data_dir: + * @session: a #CamelSession + * + * Returns the base directory under which to store user-specific mail data. * - * Constructs @session. + * Returns: the base directory for mail data + * + * Since: 3.2 **/ -void -camel_session_construct (CamelSession *session, const gchar *storage_path) +const gchar * +camel_session_get_user_data_dir (CamelSession *session) { - session->storage_path = g_strdup (storage_path); + g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); + + return session->priv->user_data_dir; } /** - * camel_session_get_service: - * @session: a #CamelSession object - * @url_string: a #CamelURL describing the service to get + * camel_session_add_service: + * @session: a #CamelSession + * @uid: a unique identifier string + * @uri_string: a URI string describing the service * @type: the provider type (#CAMEL_PROVIDER_STORE or - * #CAMEL_PROVIDER_TRANSPORT) to get, since some URLs may be able - * to specify either type. + * #CAMEL_PROVIDER_TRANSPORT) to get, since some URLs may be able to + * specify either type * @error: return location for a #GError, or %NULL * - * This resolves a #CamelURL into a #CamelService, including loading the - * provider library for that service if it has not already been loaded. + * Instantiates a new #CamelService for @session. The @uid identifies the + * service for future lookup. The @uri_string describes which provider to + * use, authentication details, provider-specific options, etc. The @type + * explicitly designates the service as a #CamelStore or #CamelTransport. + * + * If the given @uid has already been added, the existing #CamelService + * with that @uid is returned regardless of whether it agrees with the + * given @uri_string and @type. + * + * If the @uri_string is invalid or no #CamelProvider is available to + * handle the @uri_string, the function sets @error and returns %NULL. * - * Services are cached, and asking for "the same" @url_string multiple - * times will return the same CamelService (with its reference count - * incremented by one each time). What constitutes "the same" URL - * depends in part on the provider. + * Returns: a #CamelService instance, or %NULL * - * Returns: the requested #CamelService, or %NULL + * Since: 3.2 **/ CamelService * -camel_session_get_service (CamelSession *session, - const gchar *url_string, +camel_session_add_service (CamelSession *session, + const gchar *uid, + const gchar *uri_string, CamelProviderType type, GError **error) { @@ -478,15 +544,16 @@ camel_session_get_service (CamelSession *session, CamelService *service; g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); - g_return_val_if_fail (url_string != NULL, NULL); + g_return_val_if_fail (uid != NULL, NULL); + g_return_val_if_fail (uri_string != NULL, NULL); class = CAMEL_SESSION_GET_CLASS (session); - g_return_val_if_fail (class->get_service != NULL, NULL); + g_return_val_if_fail (class->add_service != NULL, NULL); camel_session_lock (session, CAMEL_SESSION_SESSION_LOCK); - service = class->get_service (session, url_string, type, error); - CAMEL_CHECK_GERROR (session, get_service, service != NULL, error); + service = class->add_service (session, uid, uri_string, type, error); + CAMEL_CHECK_GERROR (session, add_service, service != NULL, error); camel_session_unlock (session, CAMEL_SESSION_SESSION_LOCK); @@ -494,81 +561,111 @@ camel_session_get_service (CamelSession *session, } /** - * camel_session_get_service_connected: - * @session: a #CamelSession object - * @url_string: a #CamelURL describing the service to get - * @type: the provider type - * @error: return location for a #GError, or %NULL + * camel_session_get_service: + * @session: a #CamelSession + * @uid: a unique identifier string * - * This works like camel_session_get_service(), but also ensures that - * the returned service will have been successfully connected (via - * camel_service_connect().) + * Looks up a #CamelService by its unique identifier string. The service + * must have been previously added using camel_session_add_service(). * - * Returns: the requested #CamelService, or %NULL + * Returns: a #CamelService instance, or %NULL **/ CamelService * -camel_session_get_service_connected (CamelSession *session, - const gchar *url_string, - CamelProviderType type, - GError **error) +camel_session_get_service (CamelSession *session, + const gchar *uid) { CamelService *service; - CamelServiceConnectionStatus status; - service = camel_session_get_service (session, url_string, type, error); - if (service == NULL) - return NULL; + g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); + g_return_val_if_fail (uid != NULL, NULL); + + camel_session_lock (session, CAMEL_SESSION_SESSION_LOCK); + + service = g_hash_table_lookup (session->priv->services, uid); + + camel_session_unlock (session, CAMEL_SESSION_SESSION_LOCK); + + return service; +} + +/** + * camel_session_get_service_by_url: + * @session: a #CamelSession + * @url: a #CamelURL + * + * Looks up a #CamelService by trying to match its #CamelURL against + * the given @url. The service must have been previously added using + * camel_session_add_service(). + * + * Note this function is significantly slower than camel_session_get_service(). + * + * Returns: a #CamelService instance, or %NULL + * + * Since: 3.2 + **/ +CamelService * +camel_session_get_service_by_url (CamelSession *session, + CamelURL *url) +{ + CamelService *match = NULL; + GList *list, *iter; + + g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); + g_return_val_if_fail (url != NULL, NULL); + + list = camel_session_list_services (session); + + for (iter = list; iter != NULL; iter = g_list_next (iter)) { + CamelProvider *provider; + CamelService *service; + CamelURL *service_url; - /* FIXME This blocks. Need to take a GCancellable. */ - status = camel_service_get_connection_status (service); - if (status != CAMEL_SERVICE_CONNECTED) { - if (!camel_service_connect_sync (service, error)) { - g_object_unref (service); - return NULL; + service = CAMEL_SERVICE (iter->data); + provider = camel_service_get_provider (service); + service_url = camel_service_get_camel_url (service); + + if (provider->url_equal == NULL) + continue; + + if (provider->url_equal (url, service_url)) { + match = service; + break; } } - return service; + g_list_free (list); + + return match; } /** - * camel_session_get_storage_path: - * @session: a #CamelSession object - * @service: a #CamelService - * @error: return location for a #GError, or %NULL + * camel_session_list_services: + * @session: a #CamelSession * - * This returns the path to a directory which the service can use for - * its own purposes. Data stored there will remain between Evolution - * sessions. No code outside of that service should ever touch the - * files in this directory. If the directory does not exist, it will - * be created. + * Returns a list of all #CamelService objects previously added using + * camel_session_add_service(). Free the returned list using g_list_free(). * - * Returns: the path (which the caller must free), or %NULL if an error - * occurs. + * Returns: an unsorted list of #CamelService objects **/ -gchar * -camel_session_get_storage_path (CamelSession *session, - CamelService *service, - GError **error) +GList * +camel_session_list_services (CamelSession *session) { - CamelSessionClass *class; - gchar *storage_path; + GList *list; g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); - g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL); - class = CAMEL_SESSION_GET_CLASS (session); - g_return_val_if_fail (class->get_storage_path != NULL, NULL); + camel_session_lock (session, CAMEL_SESSION_SESSION_LOCK); - storage_path = class->get_storage_path (session, service, error); - CAMEL_CHECK_GERROR (session, get_storage_path, storage_path != NULL, error); + list = g_hash_table_get_values (session->priv->services); - return storage_path; + camel_session_unlock (session, CAMEL_SESSION_SESSION_LOCK); + + return list; } /** * camel_session_get_password: - * @session: a #CamelSession object + * @session: a #CamelSession * @service: the #CamelService this query is being made by * @domain: domain of password request. May be null to use the default. * @prompt: prompt to provide to user @@ -626,7 +723,7 @@ camel_session_get_password (CamelSession *session, /** * camel_session_forget_password: - * @session: a #CamelSession object + * @session: a #CamelSession * @service: the #CamelService rejecting the password * @item: an identifier, unique within this service, for the information * @error: return location for a #GError, or %NULL @@ -666,7 +763,7 @@ camel_session_forget_password (CamelSession *session, /** * camel_session_alert_user: - * @session: a #CamelSession object + * @session: a #CamelSession * @type: the type of alert (info, warning, or error) * @prompt: the message for the user * @cancel: whether or not to provide a "Cancel" option in addition to @@ -795,7 +892,7 @@ camel_session_set_online (CamelSession *session, /** * camel_session_get_filter_driver: - * @session: a #CamelSession object + * @session: a #CamelSession * @type: the type of filter (eg, "incoming") * @error: return location for a #GError, or %NULL * @@ -823,7 +920,7 @@ camel_session_get_filter_driver (CamelSession *session, /** * camel_session_thread_msg_new: - * @session: a #CamelSession object + * @session: a #CamelSession * @ops: thread operations * @size: number of bytes * @@ -854,7 +951,7 @@ camel_session_thread_msg_new (CamelSession *session, /** * camel_session_thread_msg_free: - * @session: a #CamelSession object + * @session: a #CamelSession * @msg: a #CamelSessionThreadMsg * * Free a @msg. Note that the message must have been allocated using @@ -877,7 +974,7 @@ camel_session_thread_msg_free (CamelSession *session, /** * camel_session_thread_queue: - * @session: a #CamelSession object + * @session: a #CamelSession * @msg: a #CamelSessionThreadMsg * @flags: queue type flags, currently 0. * @@ -905,7 +1002,7 @@ camel_session_thread_queue (CamelSession *session, /** * camel_session_thread_wait: - * @session: a #CamelSession object + * @session: a #CamelSession * @id: id of the operation to wait on * * Wait on an operation to complete (by id). diff --git a/camel/camel-session.h b/camel/camel-session.h index 59893fa..0d40c35 100644 --- a/camel/camel-session.h +++ b/camel/camel-session.h @@ -89,7 +89,6 @@ struct _CamelSession { CamelObject parent; CamelSessionPrivate *priv; - gchar *storage_path; CamelJunkPlugin *junk_plugin; }; @@ -99,13 +98,11 @@ typedef struct _CamelSessionThreadMsg CamelSessionThreadMsg; struct _CamelSessionClass { CamelObjectClass parent_class; - CamelService * (*get_service) (CamelSession *session, + CamelService * (*add_service) (CamelSession *session, + const gchar *uid, const gchar *url_string, CamelProviderType type, GError **error); - gchar * (*get_storage_path) (CamelSession *session, - CamelService *service, - GError **error); gchar * (*get_password) (CamelSession *session, CamelService *service, const gchar *domain, @@ -153,36 +150,24 @@ struct _CamelSessionClass { }; GType camel_session_get_type (void); -void camel_session_construct (CamelSession *session, - const gchar *storage_path); - +const gchar * camel_session_get_user_data_dir (CamelSession *session); void camel_session_set_socks_proxy (CamelSession *session, const gchar *socks_host, gint socks_port); void camel_session_get_socks_proxy (CamelSession *session, gchar **host_ret, gint *port_ret); - -CamelService * camel_session_get_service (CamelSession *session, - const gchar *url_string, +CamelService * camel_session_add_service (CamelSession *session, + const gchar *uid, + const gchar *uri_string, CamelProviderType type, GError **error); -CamelService * camel_session_get_service_connected +CamelService * camel_session_get_service (CamelSession *session, + const gchar *uid); +CamelService * camel_session_get_service_by_url (CamelSession *session, - const gchar *url_string, - CamelProviderType type, - GError **error); - -#define camel_session_get_store(session, url_string, error) \ - ((CamelStore *) camel_session_get_service_connected \ - (session, url_string, CAMEL_PROVIDER_STORE, error)) -#define camel_session_get_transport(session, url_string, error) \ - ((CamelTransport *) camel_session_get_service_connected \ - (session, url_string, CAMEL_PROVIDER_TRANSPORT, error)) - -gchar * camel_session_get_storage_path (CamelSession *session, - CamelService *service, - GError **error); + CamelURL *url); +GList * camel_session_list_services (CamelSession *session); gchar * camel_session_get_password (CamelSession *session, CamelService *service, const gchar *domain, diff --git a/camel/camel-store.c b/camel/camel-store.c index 1f0b5ee..92132ef 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -27,6 +27,7 @@ #include #endif +#include #include #include #include @@ -44,6 +45,10 @@ #define d(x) #define w(x) +#define CAMEL_STORE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), CAMEL_TYPE_STORE, CamelStorePrivate)) + typedef struct _AsyncContext AsyncContext; typedef struct _SignalData SignalData; @@ -81,8 +86,15 @@ enum { }; static guint signals[LAST_SIGNAL]; +static GInitableIface *parent_initable_interface; + +/* Forward Declarations */ +static void camel_store_initable_init (GInitableIface *interface); -G_DEFINE_ABSTRACT_TYPE (CamelStore, camel_store, CAMEL_TYPE_SERVICE) +G_DEFINE_ABSTRACT_TYPE_WITH_CODE ( + CamelStore, camel_store, CAMEL_TYPE_SERVICE, + G_IMPLEMENT_INTERFACE ( + G_TYPE_INITABLE, camel_store_initable_init)) static void async_context_free (AsyncContext *async_context) @@ -259,76 +271,6 @@ store_constructed (GObject *object) } static gboolean -store_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) -{ - CamelServiceClass *service_class; - CamelStore *store = CAMEL_STORE (service); - gchar *store_db_path, *store_path = NULL; - - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; - - store_db_path = g_build_filename (url->path, CAMEL_DB_FILE, NULL); - - if (!url->path || strlen (store_db_path) < 2) { - store_path = camel_session_get_storage_path (session, service, error); - - g_free (store_db_path); - store_db_path = g_build_filename (store_path, CAMEL_DB_FILE, NULL); - } - - if (!g_file_test (url->path ? url->path : store_path, G_FILE_TEST_EXISTS)) { - /* Cache might be blown. Recreate. */ - g_mkdir_with_parents (url->path ? url->path : store_path, S_IRWXU); - } - - g_free (store_path); - - /* This is for reading from the store */ - store->cdb_r = camel_db_open (store_db_path, NULL); - if (camel_debug("sqlite")) - printf("store_db_path %s\n", store_db_path); - if (store->cdb_r == NULL) { - gchar *store_path; - - if (camel_debug("sqlite")) - g_print ("Failure for store_db_path : [%s]\n", store_db_path); - g_free (store_db_path); - - store_path = camel_session_get_storage_path (session, service, NULL); - store_db_path = g_build_filename (store_path, CAMEL_DB_FILE, NULL); - g_free (store_path); - - store->cdb_r = camel_db_open (store_db_path, NULL); - if (store->cdb_r == NULL) { - g_print("Retry with %s failed\n", store_db_path); - g_free (store_db_path); - return FALSE; - } - } - g_free (store_db_path); - - if (camel_db_create_folders_table (store->cdb_r, error)) { - g_warning ("something went wrong terribly during db creation \n"); - return FALSE; - } - - /* This is for writing to the store */ - store->cdb_w = camel_db_clone (store->cdb_r, error); - - if (camel_url_get_param(url, "filter")) - store->flags |= CAMEL_STORE_FILTER_INBOX; - - return TRUE; -} - -static gboolean store_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **error) @@ -1246,11 +1188,61 @@ store_noop_finish (CamelStore *store, return !g_simple_async_result_propagate_error (simple, error); } +static gboolean +store_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + CamelStore *store; + CamelService *service; + CamelSession *session; + CamelURL *url; + const gchar *user_data_dir; + gchar *filename; + + store = CAMEL_STORE (initable); + + /* Chain up to parent interface's init() method. */ + if (!parent_initable_interface->init (initable, cancellable, error)) + return FALSE; + + service = CAMEL_SERVICE (initable); + url = camel_service_get_camel_url (service); + session = camel_service_get_session (service); + user_data_dir = camel_service_get_user_data_dir (service); + + if (g_mkdir_with_parents (user_data_dir, S_IRWXU) == -1) { + g_set_error_literal ( + error, G_FILE_ERROR, + g_file_error_from_errno (errno), + g_strerror (errno)); + return FALSE; + } + + /* This is for reading from the store */ + filename = g_build_filename (user_data_dir, CAMEL_DB_FILE, NULL); + store->cdb_r = camel_db_open (filename, error); + g_free (filename); + + if (store->cdb_r == NULL) + return FALSE; + + if (camel_db_create_folders_table (store->cdb_r, error)) + return FALSE; + + /* This is for writing to the store */ + store->cdb_w = camel_db_clone (store->cdb_r, error); + + if (camel_url_get_param (url, "filter")) + store->flags |= CAMEL_STORE_FILTER_INBOX; + + return TRUE; +} + static void camel_store_class_init (CamelStoreClass *class) { GObjectClass *object_class; - CamelServiceClass *service_class; g_type_class_add_private (class, sizeof (CamelStorePrivate)); @@ -1258,9 +1250,6 @@ camel_store_class_init (CamelStoreClass *class) object_class->finalize = store_finalize; object_class->constructed = store_constructed; - service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = store_construct; - class->hash_folder_name = g_str_hash; class->compare_folder_name = g_str_equal; class->can_refresh_folder = store_can_refresh_folder; @@ -1359,10 +1348,17 @@ camel_store_class_init (CamelStoreClass *class) } static void +camel_store_initable_init (GInitableIface *interface) +{ + parent_initable_interface = g_type_interface_peek_parent (interface); + + interface->init = store_initable_init; +} + +static void camel_store_init (CamelStore *store) { - store->priv = G_TYPE_INSTANCE_GET_PRIVATE ( - store, CAMEL_TYPE_STORE, CamelStorePrivate); + store->priv = CAMEL_STORE_GET_PRIVATE (store); /* set vtrash and vjunk on by default */ store->flags = CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK; diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c index 4ebed62..bca8ae0 100644 --- a/camel/camel-vee-store.c +++ b/camel/camel-vee-store.c @@ -115,37 +115,29 @@ vee_store_finalize (GObject *object) G_OBJECT_CLASS (camel_vee_store_parent_class)->finalize (object); } -static gboolean -vee_store_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) +static void +vee_store_constructed (GObject *object) { - CamelServiceClass *service_class; - CamelStore *store; CamelVeeStore *vee_store; - store = CAMEL_STORE (service); - vee_store = CAMEL_VEE_STORE (service); + vee_store = CAMEL_VEE_STORE (object); - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_vee_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (camel_vee_store_parent_class)->constructed (object); - /* Set up unmatched folder */ #ifndef VEE_UNMATCHED_ENABLE + /* Set up unmatched folder */ vee_store->unmatched_uids = g_hash_table_new (g_str_hash, g_str_equal); vee_store->folder_unmatched = g_object_new ( CAMEL_TYPE_VEE_FOLDER, "full-name", CAMEL_UNMATCHED_NAME, - "name", _("Unmatched"), "parent-store", store, NULL); - camel_vee_folder_construct (vee_store->folder_unmatched, CAMEL_STORE_FOLDER_PRIVATE); - camel_db_create_vfolder (store->cdb_r, _("Unmatched"), NULL); + "name", _("Unmatched"), "parent-store", vee_store, NULL); + camel_vee_folder_construct ( + vee_store->folder_unmatched, CAMEL_STORE_FOLDER_PRIVATE); + camel_db_create_vfolder ( + CAMEL_STORE (vee_store)->cdb_r, _("Unmatched"), NULL); #endif - return TRUE; } static gchar * @@ -470,9 +462,9 @@ camel_vee_store_class_init (CamelVeeStoreClass *class) object_class = G_OBJECT_CLASS (class); object_class->finalize = vee_store_finalize; + object_class->constructed = vee_store_constructed; service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = vee_store_construct; service_class->get_name = vee_store_get_name; store_class = CAMEL_STORE_CLASS (class); diff --git a/camel/providers/groupwise/camel-groupwise-folder.c b/camel/providers/groupwise/camel-groupwise-folder.c index 2982f4e..b9bfd16 100644 --- a/camel/providers/groupwise/camel-groupwise-folder.c +++ b/camel/providers/groupwise/camel-groupwise-folder.c @@ -355,19 +355,20 @@ static void groupwise_folder_rename (CamelFolder *folder, const gchar *new) { CamelGroupwiseFolder *gw_folder; - CamelGroupwiseStore *gw_store; CamelStore *parent_store; - gchar *folder_dir, *summary_path, *state_file, *storage_path; + CamelService *service; + const gchar *user_data_dir; + gchar *folder_dir, *summary_path, *state_file; gchar *folders; parent_store = camel_folder_get_parent_store (folder); gw_folder = CAMEL_GROUPWISE_FOLDER (folder); - gw_store = CAMEL_GROUPWISE_STORE (parent_store); - storage_path = storage_path_lookup (gw_store->priv); + service = CAMEL_SERVICE (parent_store); + user_data_dir = camel_service_get_user_data_dir (service); - folders = g_strconcat (storage_path, "/folders", NULL); + folders = g_strconcat (user_data_dir, "/folders", NULL); folder_dir = e_path_to_physical (folders, new); g_free (folders); diff --git a/camel/providers/groupwise/camel-groupwise-store.c b/camel/providers/groupwise/camel-groupwise-store.c index 7f2e06f..cd3f607 100644 --- a/camel/providers/groupwise/camel-groupwise-store.c +++ b/camel/providers/groupwise/camel-groupwise-store.c @@ -41,6 +41,7 @@ #include "camel-groupwise-store-summary.h" #include "camel-groupwise-store.h" #include "camel-groupwise-summary.h" +#include "camel-groupwise-transport.h" #include "camel-groupwise-utils.h" #ifdef G_OS_WIN32 @@ -62,7 +63,6 @@ struct _CamelGroupwiseStorePrivate { gchar *use_ssl; gchar *base_url; - gchar *storage_path; GHashTable *id_hash; /*get names from ids*/ GHashTable *name_hash;/*get ids from names*/ @@ -71,88 +71,18 @@ struct _CamelGroupwiseStorePrivate { }; extern CamelServiceAuthType camel_groupwise_password_authtype; /*for the query_auth_types function*/ + +static GInitableIface *parent_initable_interface; + static CamelFolderInfo *convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, const gchar *url, GCancellable *cancellable, GError **error); static gboolean groupwise_folders_sync (CamelGroupwiseStore *store, GCancellable *cancellable, GError **error); static gint match_path (const gchar *path, const gchar *name); +static void camel_groupwise_store_initable_init (GInitableIface *interface); -G_DEFINE_TYPE (CamelGroupwiseStore, camel_groupwise_store, CAMEL_TYPE_OFFLINE_STORE) - -static gboolean -groupwise_store_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) -{ - CamelServiceClass *service_class; - CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (service); - CamelStore *store = CAMEL_STORE (service); - const gchar *property_value; - CamelGroupwiseStorePrivate *priv = groupwise_store->priv; - gchar *path = NULL; - - d(printf ("\nin groupwise store constrcut\n")); - - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_groupwise_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; - - if (!(url->host || url->user)) { - g_set_error ( - error, CAMEL_SERVICE_ERROR, - CAMEL_SERVICE_ERROR_INVALID, - _("Host or user not available in url")); - } - - /*storage path*/ - priv->storage_path = camel_session_get_storage_path (session, service, error); - if (!priv->storage_path) - return FALSE; - - /*store summary*/ - path = g_alloca (strlen (priv->storage_path) + 32); - sprintf (path, "%s/.summary", priv->storage_path); - groupwise_store->summary = camel_groupwise_store_summary_new (); - camel_store_summary_set_filename ((CamelStoreSummary *)groupwise_store->summary, path); - camel_store_summary_touch ((CamelStoreSummary *)groupwise_store->summary); - camel_store_summary_load ((CamelStoreSummary *) groupwise_store->summary); - - /*host and user*/ - priv->server_name = g_strdup (url->host); - priv->user = g_strdup (url->user); - - /*base url*/ - priv->base_url = camel_url_to_string ( - url, CAMEL_URL_HIDE_PASSWORD | - CAMEL_URL_HIDE_PARAMS | CAMEL_URL_HIDE_AUTH); - - /*soap port*/ - property_value = camel_url_get_param (url, "soap_port"); - if (property_value == NULL) - priv->port = g_strdup ("7191"); - else if (strlen (property_value) == 0) - priv->port = g_strdup ("7191"); - else - priv->port = g_strdup (property_value); - - /*filter*/ - if (camel_url_get_param (url, "filter")) - store->flags |= CAMEL_STORE_FILTER_INBOX; - - /*Hash Table*/ - priv->id_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->parent_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - /*ssl*/ - priv->use_ssl = g_strdup (camel_url_get_param (url, "use_ssl")); - - store->flags &= ~CAMEL_STORE_VJUNK; - store->flags &= ~CAMEL_STORE_VTRASH; - - return TRUE; -} +G_DEFINE_TYPE_WITH_CODE ( + CamelGroupwiseStore, camel_groupwise_store, CAMEL_TYPE_OFFLINE_STORE, + G_IMPLEMENT_INTERFACE ( + G_TYPE_INITABLE, camel_groupwise_store_initable_init)) static guint groupwise_hash_folder_name (gconstpointer key) @@ -302,6 +232,7 @@ groupwise_connect_sync (CamelService *service, CamelProvider *provider; CamelSession *session; CamelURL *url; + const gchar *user_data_dir; d("in groupwise store connect\n"); @@ -309,16 +240,11 @@ groupwise_connect_sync (CamelService *service, session = camel_service_get_session (service); provider = camel_service_get_provider (service); status = camel_service_get_connection_status (service); + user_data_dir = camel_service_get_user_data_dir (service); if (status == CAMEL_SERVICE_DISCONNECTED) return FALSE; - if (!priv) { - store->priv = g_new0 (CamelGroupwiseStorePrivate, 1); - priv = store->priv; - camel_service_construct (service, session, provider, url, error); - } - camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); if (priv->cnc) { @@ -343,7 +269,8 @@ groupwise_connect_sync (CamelService *service, } - ns = camel_groupwise_store_summary_namespace_new (store->summary, priv->storage_path, '/'); + ns = camel_groupwise_store_summary_namespace_new ( + store->summary, user_data_dir, '/'); camel_groupwise_store_summary_namespace_set (store->summary, ns); if (camel_store_summary_count ((CamelStoreSummary *)store->summary) == 0) { @@ -395,9 +322,6 @@ groupwise_disconnect_cleanup (CamelService *service, gboolean clean, GError **er priv->base_url = NULL; } - if (priv->storage_path) - g_free (priv->storage_path); - if (groupwise_store->root_container) g_free (groupwise_store->root_container); @@ -518,12 +442,16 @@ groupwise_build_folder_info (CamelGroupwiseStore *gw_store, const gchar *parent_ static void groupwise_forget_folder (CamelGroupwiseStore *gw_store, const gchar *folder_name, GError **error) { - CamelGroupwiseStorePrivate *priv = gw_store->priv; + CamelService *service; + const gchar *user_data_dir; gchar *state_file; gchar *folder_dir, *storage_path; CamelFolderInfo *fi; - storage_path = g_strdup_printf ("%s/folders", priv->storage_path); + service = CAMEL_SERVICE (gw_store); + user_data_dir = camel_service_get_user_data_dir (service); + + storage_path = g_strdup_printf ("%s/folders", user_data_dir); folder_dir = e_path_to_physical (storage_path,folder_name); if (g_access (folder_dir, F_OK) != 0) { @@ -553,14 +481,18 @@ groupwise_get_folder_from_disk (CamelStore *store, GCancellable *cancellable, GError **error) { - CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store); - CamelGroupwiseStorePrivate *priv = gw_store->priv; CamelFolder *folder; + CamelService *service; + const gchar *user_data_dir; gchar *folder_dir, *storage_path; - storage_path = g_strdup_printf("%s/folders", priv->storage_path); + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + + storage_path = g_strdup_printf ("%s/folders", user_data_dir); folder_dir = e_path_to_physical (storage_path, folder_name); g_free (storage_path); + if (!folder_dir || g_access (folder_dir, F_OK) != 0) { g_free (folder_dir); g_set_error ( @@ -586,17 +518,22 @@ groupwise_store_get_folder_sync (CamelStore *store, CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store); CamelGroupwiseStorePrivate *priv = gw_store->priv; CamelFolder *folder; + CamelService *service; CamelGroupwiseSummary *summary; gchar *container_id, *folder_dir, *storage_path; EGwConnectionStatus status; GList *list = NULL; gboolean done = FALSE, all_ok = TRUE; + const gchar *user_data_dir; const gchar *position = E_GW_CURSOR_POSITION_END; gint count = 0, cursor, summary_count = 0; CamelStoreInfo *si = NULL; guint total = 0; GError *local_error = NULL; + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + folder = groupwise_get_folder_from_disk ( store, folder_name, flags, cancellable, &local_error); if (folder) { @@ -611,30 +548,30 @@ groupwise_store_get_folder_sync (CamelStore *store, } else g_clear_error (&local_error); - camel_service_lock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); groupwise_store_set_current_folder (gw_store, NULL); if (!camel_groupwise_store_connected (gw_store, cancellable, error)) { - camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } if (!E_IS_GW_CONNECTION ( priv->cnc)) { - if (!groupwise_connect_sync (CAMEL_SERVICE (store), cancellable, error)) { - camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + if (!groupwise_connect_sync (service, cancellable, error)) { + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } } container_id = g_strdup (g_hash_table_lookup (priv->name_hash, folder_name)); - storage_path = g_strdup_printf("%s/folders", priv->storage_path); + storage_path = g_strdup_printf ("%s/folders", user_data_dir); folder_dir = e_path_to_physical (storage_path, folder_name); g_free (storage_path); folder = camel_gw_folder_new (store, folder_name, folder_dir, cancellable, NULL); if (!folder) { - camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); g_set_error ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID, @@ -668,7 +605,7 @@ groupwise_store_get_folder_sync (CamelStore *store, &cursor); if (status != E_GW_CONNECTION_STATUS_OK) { - camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); g_free (container_id); return NULL; } @@ -731,7 +668,7 @@ groupwise_store_get_folder_sync (CamelStore *store, groupwise_store_set_current_folder (gw_store, folder); g_free (container_id); - camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return folder; } @@ -1326,10 +1263,15 @@ groupwise_store_rename_folder_sync (CamelStore *store, { CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store); CamelGroupwiseStorePrivate *priv = groupwise_store->priv; + CamelService *service; + const gchar *user_data_dir; gchar *oldpath, *newpath, *storepath; const gchar *container_id; gchar *temp_new = NULL; + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + if (groupwise_is_system_folder (old_name)) { g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, @@ -1338,10 +1280,10 @@ groupwise_store_rename_folder_sync (CamelStore *store, return FALSE; } - camel_service_lock (CAMEL_SERVICE (groupwise_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); if (!camel_groupwise_store_connected (groupwise_store, cancellable, error)) { - camel_service_unlock (CAMEL_SERVICE (groupwise_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return FALSE; } @@ -1360,7 +1302,7 @@ groupwise_store_rename_folder_sync (CamelStore *store, error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Cannot rename GroupWise folder '%s' to '%s'"), old_name, new_name); - camel_service_unlock (CAMEL_SERVICE (groupwise_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return FALSE; } @@ -1370,7 +1312,7 @@ groupwise_store_rename_folder_sync (CamelStore *store, g_hash_table_remove (priv->name_hash, old_name); /*FIXME:Update all the id in the parent_hash*/ - storepath = g_strdup_printf ("%s/folders", priv->storage_path); + storepath = g_strdup_printf ("%s/folders", user_data_dir); oldpath = e_path_to_physical (storepath, old_name); newpath = e_path_to_physical (storepath, new_name); g_free (storepath); @@ -1383,7 +1325,7 @@ groupwise_store_rename_folder_sync (CamelStore *store, g_free (oldpath); g_free (newpath); - camel_service_unlock (CAMEL_SERVICE (groupwise_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return TRUE; } @@ -1426,12 +1368,6 @@ cnc_lookup (CamelGroupwiseStorePrivate *priv) return priv->cnc; } -gchar * -storage_path_lookup (CamelGroupwiseStorePrivate *priv) -{ - return priv->storage_path; -} - const gchar * groupwise_base_url_lookup (CamelGroupwiseStorePrivate *priv) { @@ -1449,7 +1385,15 @@ groupwise_store_get_trash_folder_sync (CamelStore *store, store, "Trash", 0, cancellable, error); if (folder) { CamelObject *object = CAMEL_OBJECT (folder); - gchar *state = g_build_filename((CAMEL_GROUPWISE_STORE(store))->priv->storage_path, "folders", "Trash", "cmeta", NULL); + CamelService *service; + const gchar *user_data_dir; + gchar *state; + + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + + state = g_build_filename ( + user_data_dir, "folders", "Trash", "cmeta", NULL); camel_object_set_state_filename (object, state); g_free (state); @@ -1559,7 +1503,6 @@ groupwise_store_finalize (GObject *object) g_free (groupwise_store->priv->port); g_free (groupwise_store->priv->use_ssl); g_free (groupwise_store->priv->base_url); - g_free (groupwise_store->priv->storage_path); g_free (groupwise_store->root_container); if (groupwise_store->priv->id_hash != NULL) @@ -1575,6 +1518,107 @@ groupwise_store_finalize (GObject *object) G_OBJECT_CLASS (camel_groupwise_store_parent_class)->finalize (object); } +static gboolean +groupwise_store_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + CamelGroupwiseStore *groupwise_store; + CamelService *transport; + CamelService *service; + CamelSession *session; + CamelURL *url; + const gchar *property_value; + const gchar *user_data_dir; + const gchar *store_uid; + gchar *transport_uid; + gchar *uri_string; + gchar *path = NULL; + + groupwise_store = CAMEL_GROUPWISE_STORE (initable); + + /* Chain up to parent interface's init() method. */ + if (!parent_initable_interface->init (initable, cancellable, error)) + return FALSE; + + service = CAMEL_SERVICE (initable); + url = camel_service_get_camel_url (service); + session = camel_service_get_session (service); + user_data_dir = camel_service_get_user_data_dir (service); + + if (!(url->host || url->user)) { + g_set_error ( + error, CAMEL_SERVICE_ERROR, + CAMEL_SERVICE_ERROR_INVALID, + _("Host or user not available in url")); + } + + /*store summary*/ + path = g_alloca (strlen (user_data_dir) + 32); + sprintf (path, "%s/.summary", user_data_dir); + groupwise_store->summary = camel_groupwise_store_summary_new (); + camel_store_summary_set_filename ((CamelStoreSummary *)groupwise_store->summary, path); + camel_store_summary_touch ((CamelStoreSummary *)groupwise_store->summary); + camel_store_summary_load ((CamelStoreSummary *) groupwise_store->summary); + + /*host and user*/ + groupwise_store->priv->server_name = g_strdup (url->host); + groupwise_store->priv->user = g_strdup (url->user); + + /*base url*/ + groupwise_store->priv->base_url = camel_url_to_string ( + url, CAMEL_URL_HIDE_PASSWORD | + CAMEL_URL_HIDE_PARAMS | CAMEL_URL_HIDE_AUTH); + + /*soap port*/ + property_value = camel_url_get_param (url, "soap_port"); + if (property_value == NULL) + groupwise_store->priv->port = g_strdup ("7191"); + else if (strlen (property_value) == 0) + groupwise_store->priv->port = g_strdup ("7191"); + else + groupwise_store->priv->port = g_strdup (property_value); + + /*filter*/ + if (camel_url_get_param (url, "filter")) + CAMEL_STORE (groupwise_store)->flags |= CAMEL_STORE_FILTER_INBOX; + + /*Hash Table*/ + groupwise_store->priv->id_hash = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + groupwise_store->priv->name_hash = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + groupwise_store->priv->parent_hash = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + /*ssl*/ + groupwise_store->priv->use_ssl = + g_strdup (camel_url_get_param (url, "use_ssl")); + + CAMEL_STORE (groupwise_store)->flags &= ~CAMEL_STORE_VJUNK; + CAMEL_STORE (groupwise_store)->flags &= ~CAMEL_STORE_VTRASH; + + /* Add a corresponding CamelGroupwiseTransport. */ + + store_uid = camel_service_get_uid (service); + transport_uid = g_strconcat (store_uid, "-transport", NULL); + uri_string = camel_url_to_string (url, CAMEL_URL_HIDE_ALL); + + transport = camel_session_add_service ( + session, transport_uid, uri_string, + CAMEL_PROVIDER_TRANSPORT, error); + + g_free (transport_uid); + g_free (uri_string); + + if (transport != NULL) + camel_groupwise_transport_set_store ( + CAMEL_GROUPWISE_TRANSPORT (transport), + groupwise_store); + + return (transport != NULL); +} + static void camel_groupwise_store_class_init (CamelGroupwiseStoreClass *class) { @@ -1589,7 +1633,6 @@ camel_groupwise_store_class_init (CamelGroupwiseStoreClass *class) object_class->finalize = groupwise_store_finalize; service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = groupwise_store_construct; service_class->get_name = groupwise_get_name; service_class->connect_sync = groupwise_connect_sync; service_class->disconnect_sync = groupwise_disconnect_sync; @@ -1609,6 +1652,14 @@ camel_groupwise_store_class_init (CamelGroupwiseStoreClass *class) } static void +camel_groupwise_store_initable_init (GInitableIface *interface) +{ + parent_initable_interface = g_type_interface_peek_parent (interface); + + interface->init = groupwise_store_initable_init; +} + +static void camel_groupwise_store_init (CamelGroupwiseStore *groupwise_store) { groupwise_store->priv = G_TYPE_INSTANCE_GET_PRIVATE ( diff --git a/camel/providers/groupwise/camel-groupwise-store.h b/camel/providers/groupwise/camel-groupwise-store.h index 7e901c3..6a72357 100644 --- a/camel/providers/groupwise/camel-groupwise-store.h +++ b/camel/providers/groupwise/camel-groupwise-store.h @@ -86,7 +86,6 @@ const gchar * camel_groupwise_store_folder_lookup (CamelGroupwiseStore *store, const gchar *container_id); EGwConnection * cnc_lookup (CamelGroupwiseStorePrivate *priv); -gchar * storage_path_lookup (CamelGroupwiseStorePrivate *priv); const gchar * groupwise_base_url_lookup (CamelGroupwiseStorePrivate *priv); CamelFolderInfo * create_junk_folder (CamelStore *store); diff --git a/camel/providers/groupwise/camel-groupwise-transport.c b/camel/providers/groupwise/camel-groupwise-transport.c index 6f2876d..54b3af9 100644 --- a/camel/providers/groupwise/camel-groupwise-transport.c +++ b/camel/providers/groupwise/camel-groupwise-transport.c @@ -36,8 +36,33 @@ #define REPLY_VIEW "default message attachments threading" +#define CAMEL_GROUPWISE_TRANSPORT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), CAMEL_TYPE_GROUPWISE_TRANSPORT, CamelGroupwiseTransportPrivate)) + G_DEFINE_TYPE (CamelGroupwiseTransport, camel_groupwise_transport, CAMEL_TYPE_TRANSPORT) +struct _CamelGroupwiseTransportPrivate { + CamelGroupwiseStore *store; +}; + +static void +groupwise_transport_dispose (GObject *object) +{ + CamelGroupwiseTransportPrivate *priv; + + priv = CAMEL_GROUPWISE_TRANSPORT_GET_PRIVATE (object); + + if (priv->store != NULL) { + g_object_unref (priv->store); + priv->store = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (camel_groupwise_transport_parent_class)-> + dispose (object); +} + static gchar * groupwise_transport_get_name (CamelService *service, gboolean brief) @@ -72,17 +97,14 @@ groupwise_send_to_sync (CamelTransport *transport, GCancellable *cancellable, GError **error) { + CamelGroupwiseTransportPrivate *priv; CamelService *service; CamelSession *session; - CamelStore *store = NULL; CamelURL *service_url; - CamelGroupwiseStore *groupwise_store = NULL; - CamelGroupwiseStorePrivate *priv = NULL; EGwItem *item ,*temp_item=NULL; EGwConnection *cnc = NULL; EGwConnectionStatus status = 0; GSList *sent_item_list = NULL; - gchar *url = NULL; gchar *reply_request = NULL; EGwItemLinkInfo *info = NULL; @@ -94,31 +116,16 @@ groupwise_send_to_sync (CamelTransport *transport, return FALSE; } + priv = CAMEL_GROUPWISE_TRANSPORT_GET_PRIVATE (transport); + service = CAMEL_SERVICE (transport); session = camel_service_get_session (service); service_url = camel_service_get_camel_url (service); - url = camel_url_to_string ( - service_url, CAMEL_URL_HIDE_PASSWORD | - CAMEL_URL_HIDE_PARAMS | CAMEL_URL_HIDE_AUTH); - camel_operation_push_message (cancellable, _("Sending Message") ); /*camel groupwise store and cnc*/ - store = camel_session_get_store (session, url, NULL); - g_free (url); - if (!store) { - g_warning ("ERROR: Could not get a pointer to the store"); - g_set_error ( - error, CAMEL_STORE_ERROR, - CAMEL_STORE_ERROR_INVALID, - _("Cannot get folder: Invalid operation on this store")); - return FALSE; - } - groupwise_store = CAMEL_GROUPWISE_STORE (store); - priv = groupwise_store->priv; - - cnc = cnc_lookup (priv); + cnc = cnc_lookup (priv->store->priv); if (!cnc) { g_warning ("||| Eh!!! Failure |||\n"); camel_operation_pop_message (cancellable); @@ -185,9 +192,16 @@ groupwise_send_to_sync (CamelTransport *transport, static void camel_groupwise_transport_class_init (CamelGroupwiseTransportClass *class) { + GObjectClass *object_class; CamelServiceClass *service_class; CamelTransportClass *transport_class; + g_type_class_add_private ( + class, sizeof (CamelGroupwiseTransportPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->dispose = groupwise_transport_dispose; + service_class = CAMEL_SERVICE_CLASS (class); service_class->get_name = groupwise_transport_get_name; service_class->connect_sync = groupwise_transport_connect_sync; @@ -197,6 +211,17 @@ camel_groupwise_transport_class_init (CamelGroupwiseTransportClass *class) } static void -camel_groupwise_transport_init (CamelGroupwiseTransport *groupwise_transport) +camel_groupwise_transport_init (CamelGroupwiseTransport *transport) { + transport->priv = CAMEL_GROUPWISE_TRANSPORT_GET_PRIVATE (transport); +} + +void +camel_groupwise_transport_set_store (CamelGroupwiseTransport *transport, + CamelGroupwiseStore *store) +{ + g_return_if_fail (CAMEL_IS_GROUPWISE_TRANSPORT (transport)); + g_return_if_fail (CAMEL_IS_GROUPWISE_STORE (store)); + + transport->priv->store = g_object_ref (store); } diff --git a/camel/providers/groupwise/camel-groupwise-transport.h b/camel/providers/groupwise/camel-groupwise-transport.h index 9abf71a..ee9d21c 100644 --- a/camel/providers/groupwise/camel-groupwise-transport.h +++ b/camel/providers/groupwise/camel-groupwise-transport.h @@ -24,7 +24,7 @@ #ifndef CAMEL_GROUPWISE_TRANSPORT_H #define CAMEL_GROUPWISE_TRANSPORT_H -#include +#include "camel-groupwise-store.h" /* Standard GObject macros */ #define CAMEL_TYPE_GROUPWISE_TRANSPORT \ @@ -49,17 +49,21 @@ G_BEGIN_DECLS typedef struct _CamelGroupwiseTransport CamelGroupwiseTransport; typedef struct _CamelGroupwiseTransportClass CamelGroupwiseTransportClass; +typedef struct _CamelGroupwiseTransportPrivate CamelGroupwiseTransportPrivate; struct _CamelGroupwiseTransport { CamelTransport parent; - gboolean connected; + CamelGroupwiseTransportPrivate *priv; }; struct _CamelGroupwiseTransportClass { CamelTransportClass parent_class; }; -GType camel_groupwise_transport_get_type (void); +GType camel_groupwise_transport_get_type (void); +void camel_groupwise_transport_set_store + (CamelGroupwiseTransport *transport, + CamelGroupwiseStore *store); G_END_DECLS diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index c4bd8c5..77519cd 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -629,18 +629,22 @@ imap_get_filename (CamelFolder *folder, static void imap_rename (CamelFolder *folder, const gchar *new) { + CamelService *service; CamelStore *parent_store; CamelImapFolder *imap_folder = (CamelImapFolder *)folder; - CamelImapStore *imap_store; + const gchar *user_data_dir; gchar *folder_dir, *summary_path, *state_file; gchar *folders; parent_store = camel_folder_get_parent_store (folder); - imap_store = CAMEL_IMAP_STORE (parent_store); - folders = g_strconcat (imap_store->storage_path, "/folders", NULL); + service = CAMEL_SERVICE (parent_store); + user_data_dir = camel_service_get_user_data_dir (service); + + folders = g_strconcat (user_data_dir, "/folders", NULL); folder_dir = imap_path_to_physical (folders, new); g_free (folders); + summary_path = g_strdup_printf("%s/summary", folder_dir); CAMEL_IMAP_FOLDER_REC_LOCK (folder, cache_lock); diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index 74c1fc8..dc8cd8e 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -136,7 +136,15 @@ static struct { extern CamelServiceAuthType camel_imap_password_authtype; -G_DEFINE_TYPE (CamelImapStore, camel_imap_store, CAMEL_TYPE_OFFLINE_STORE) +static GInitableIface *parent_initable_interface; + +/* Forward Declarations */ +static void camel_imap_store_initable_init (GInitableIface *interface); + +G_DEFINE_TYPE_WITH_CODE ( + CamelImapStore, camel_imap_store, CAMEL_TYPE_OFFLINE_STORE, + G_IMPLEMENT_INTERFACE ( + G_TYPE_INITABLE, camel_imap_store_initable_init)) static void parse_capability (CamelImapStore *store, gchar *capa) @@ -910,7 +918,6 @@ imap_store_finalize (GObject *object) camel_service_disconnect_sync (CAMEL_SERVICE (imap_store), TRUE, NULL); g_free (imap_store->base_url); - g_free (imap_store->storage_path); g_free (imap_store->users_namespace); g_free (imap_store->custom_headers); g_free (imap_store->real_trash_path); @@ -920,110 +927,6 @@ imap_store_finalize (GObject *object) G_OBJECT_CLASS (camel_imap_store_parent_class)->finalize (object); } -static gboolean -imap_store_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) -{ - CamelServiceClass *service_class; - CamelImapStore *imap_store = CAMEL_IMAP_STORE (service); - CamelStore *store = CAMEL_STORE (service); - gchar *tmp; - CamelURL *summary_url; - - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_imap_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; - - imap_store->storage_path = camel_session_get_storage_path (session, service, error); - if (!imap_store->storage_path) - return FALSE; - - /* FIXME */ - imap_store->base_url = camel_url_to_string ( - url, CAMEL_URL_HIDE_PASSWORD | - CAMEL_URL_HIDE_PARAMS | CAMEL_URL_HIDE_AUTH); - - imap_store->parameters = 0; - if (camel_url_get_param (url, "use_lsub")) - imap_store->parameters |= IMAP_PARAM_SUBSCRIPTIONS; - if (camel_url_get_param (url, "override_namespace") && camel_url_get_param (url, "namespace")) { - imap_store->parameters |= IMAP_PARAM_OVERRIDE_NAMESPACE; - g_free (imap_store->users_namespace); - imap_store->users_namespace = g_strdup (camel_url_get_param (url, "namespace")); - } - if (camel_url_get_param (url, "check_all")) - imap_store->parameters |= IMAP_PARAM_CHECK_ALL; - if (camel_url_get_param (url, "check_lsub")) - imap_store->parameters |= IMAP_PARAM_CHECK_LSUB; - if (camel_url_get_param (url, "filter")) { - imap_store->parameters |= IMAP_PARAM_FILTER_INBOX; - store->flags |= CAMEL_STORE_FILTER_INBOX; - } - if (camel_url_get_param (url, "filter_junk")) - imap_store->parameters |= IMAP_PARAM_FILTER_JUNK; - if (camel_url_get_param (url, "filter_junk_inbox")) - imap_store->parameters |= IMAP_PARAM_FILTER_JUNK_INBOX; - - imap_store->headers = IMAP_FETCH_MAILING_LIST_HEADERS; - if (camel_url_get_param (url, "all_headers")) - imap_store->headers = IMAP_FETCH_ALL_HEADERS; - else if (camel_url_get_param (url, "basic_headers")) - imap_store->headers = IMAP_FETCH_MINIMAL_HEADERS; - - if (camel_url_get_param (url, "imap_custom_headers")) { - imap_store->custom_headers = g_strdup(camel_url_get_param (url, "imap_custom_headers")); - } - - imap_store->real_trash_path = g_strdup (camel_url_get_param (url, "real_trash_path")); - imap_store->real_junk_path = g_strdup (camel_url_get_param (url, "real_junk_path")); - - if (imap_store->real_trash_path && !*imap_store->real_trash_path) { - g_free (imap_store->real_trash_path); - imap_store->real_trash_path = NULL; - } - - if (imap_store->real_trash_path && *imap_store->real_trash_path) - store->flags &= ~CAMEL_STORE_VTRASH; - - if (imap_store->real_junk_path && !*imap_store->real_junk_path) { - g_free (imap_store->real_junk_path); - imap_store->real_junk_path = NULL; - } - - if (imap_store->real_junk_path && *imap_store->real_junk_path) { - store->flags &= ~CAMEL_STORE_VJUNK; - store->flags |= CAMEL_STORE_REAL_JUNK_FOLDER; - } - - /* setup/load the store summary */ - tmp = alloca (strlen (imap_store->storage_path)+32); - sprintf(tmp, "%s/.ev-store-summary", imap_store->storage_path); - imap_store->summary = camel_imap_store_summary_new (); - camel_store_summary_set_filename ((CamelStoreSummary *)imap_store->summary, tmp); - summary_url = camel_url_new (imap_store->base_url, NULL); - camel_store_summary_set_uri_base ((CamelStoreSummary *)imap_store->summary, summary_url); - camel_url_free (summary_url); - if (camel_store_summary_load ((CamelStoreSummary *)imap_store->summary) == 0) { - CamelImapStoreSummary *is = imap_store->summary; - - if (is->namespace) { - /* if namespace has changed, clear folder list */ - if (imap_store->users_namespace && strcmp (imap_store->users_namespace, is->namespace->full_name) != 0) { - camel_store_summary_clear ((CamelStoreSummary *)is); - } - } - - imap_store->capabilities = is->capabilities; - imap_set_server_level (imap_store); - } - - return TRUE; -} - static gchar * imap_store_get_name (CamelService *service, gboolean brief) @@ -1313,6 +1216,110 @@ imap_store_query_auth_types_sync (CamelService *service, return g_list_prepend (sasl_types, &camel_imap_password_authtype); } +static gboolean +imap_store_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + CamelImapStore *imap_store; + CamelService *service; + CamelURL *summary_url; + CamelURL *url; + const gchar *user_data_dir; + gchar *tmp; + + imap_store = CAMEL_IMAP_STORE (initable); + + /* Chain up to parent interface's init() method. */ + if (!parent_initable_interface->init (initable, cancellable, error)) + return FALSE; + + service = CAMEL_SERVICE (initable); + url = camel_service_get_camel_url (service); + user_data_dir = camel_service_get_user_data_dir (service); + + /* FIXME */ + imap_store->base_url = camel_url_to_string ( + url, CAMEL_URL_HIDE_PASSWORD | + CAMEL_URL_HIDE_PARAMS | CAMEL_URL_HIDE_AUTH); + + imap_store->parameters = 0; + if (camel_url_get_param (url, "use_lsub")) + imap_store->parameters |= IMAP_PARAM_SUBSCRIPTIONS; + if (camel_url_get_param (url, "override_namespace") && camel_url_get_param (url, "namespace")) { + imap_store->parameters |= IMAP_PARAM_OVERRIDE_NAMESPACE; + g_free (imap_store->users_namespace); + imap_store->users_namespace = g_strdup (camel_url_get_param (url, "namespace")); + } + if (camel_url_get_param (url, "check_all")) + imap_store->parameters |= IMAP_PARAM_CHECK_ALL; + if (camel_url_get_param (url, "check_lsub")) + imap_store->parameters |= IMAP_PARAM_CHECK_LSUB; + if (camel_url_get_param (url, "filter")) { + imap_store->parameters |= IMAP_PARAM_FILTER_INBOX; + CAMEL_STORE (imap_store)->flags |= CAMEL_STORE_FILTER_INBOX; + } + if (camel_url_get_param (url, "filter_junk")) + imap_store->parameters |= IMAP_PARAM_FILTER_JUNK; + if (camel_url_get_param (url, "filter_junk_inbox")) + imap_store->parameters |= IMAP_PARAM_FILTER_JUNK_INBOX; + + imap_store->headers = IMAP_FETCH_MAILING_LIST_HEADERS; + if (camel_url_get_param (url, "all_headers")) + imap_store->headers = IMAP_FETCH_ALL_HEADERS; + else if (camel_url_get_param (url, "basic_headers")) + imap_store->headers = IMAP_FETCH_MINIMAL_HEADERS; + + if (camel_url_get_param (url, "imap_custom_headers")) { + imap_store->custom_headers = g_strdup(camel_url_get_param (url, "imap_custom_headers")); + } + + imap_store->real_trash_path = g_strdup (camel_url_get_param (url, "real_trash_path")); + imap_store->real_junk_path = g_strdup (camel_url_get_param (url, "real_junk_path")); + + if (imap_store->real_trash_path && !*imap_store->real_trash_path) { + g_free (imap_store->real_trash_path); + imap_store->real_trash_path = NULL; + } + + if (imap_store->real_trash_path && *imap_store->real_trash_path) + CAMEL_STORE (imap_store)->flags &= ~CAMEL_STORE_VTRASH; + + if (imap_store->real_junk_path && !*imap_store->real_junk_path) { + g_free (imap_store->real_junk_path); + imap_store->real_junk_path = NULL; + } + + if (imap_store->real_junk_path && *imap_store->real_junk_path) { + CAMEL_STORE (imap_store)->flags &= ~CAMEL_STORE_VJUNK; + CAMEL_STORE (imap_store)->flags |= CAMEL_STORE_REAL_JUNK_FOLDER; + } + + /* setup/load the store summary */ + tmp = alloca (strlen (user_data_dir) + 32); + sprintf(tmp, "%s/.ev-store-summary", user_data_dir); + imap_store->summary = camel_imap_store_summary_new (); + camel_store_summary_set_filename ((CamelStoreSummary *)imap_store->summary, tmp); + summary_url = camel_url_new (imap_store->base_url, NULL); + camel_store_summary_set_uri_base ((CamelStoreSummary *)imap_store->summary, summary_url); + camel_url_free (summary_url); + if (camel_store_summary_load ((CamelStoreSummary *)imap_store->summary) == 0) { + CamelImapStoreSummary *is = imap_store->summary; + + if (is->namespace) { + /* if namespace has changed, clear folder list */ + if (imap_store->users_namespace && strcmp (imap_store->users_namespace, is->namespace->full_name) != 0) { + camel_store_summary_clear ((CamelStoreSummary *)is); + } + } + + imap_store->capabilities = is->capabilities; + imap_set_server_level (imap_store); + } + + return TRUE; +} + static void camel_imap_store_class_init (CamelImapStoreClass *class) { @@ -1325,7 +1332,6 @@ camel_imap_store_class_init (CamelImapStoreClass *class) object_class->finalize = imap_store_finalize; service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = imap_store_construct; service_class->get_name = imap_store_get_name; service_class->connect_sync = imap_store_connect_sync; service_class->disconnect_sync = imap_store_disconnect_sync; @@ -1350,6 +1356,14 @@ camel_imap_store_class_init (CamelImapStoreClass *class) } static void +camel_imap_store_initable_init (GInitableIface *interface) +{ + parent_initable_interface = g_type_interface_peek_parent (interface); + + interface->init = imap_store_initable_init; +} + +static void camel_imap_store_init (CamelImapStore *imap_store) { imap_store->istream = NULL; @@ -1455,6 +1469,8 @@ imap_folder_effectively_unsubscribed (CamelImapStore *imap_store, static void imap_forget_folder (CamelImapStore *imap_store, const gchar *folder_name, GError **error) { + CamelService *service; + const gchar *user_data_dir; gchar *state_file; gchar *journal_file; gchar *folder_dir, *storage_path; @@ -1467,7 +1483,10 @@ imap_forget_folder (CamelImapStore *imap_store, const gchar *folder_name, GError else name = folder_name; - storage_path = g_strdup_printf ("%s/folders", imap_store->storage_path); + service = CAMEL_SERVICE (imap_store); + user_data_dir = camel_service_get_user_data_dir (service); + + storage_path = g_strdup_printf ("%s/folders", user_data_dir); folder_dir = imap_path_to_physical (storage_path, folder_name); g_free (storage_path); if (g_access (folder_dir, F_OK) != 0) { @@ -1607,7 +1626,15 @@ imap_store_get_trash_folder_sync (CamelStore *store, if (folder) { CamelObject *object = CAMEL_OBJECT (folder); - gchar *state = g_build_filename(((CamelImapStore *)store)->storage_path, "system", "Trash.cmeta", NULL); + CamelService *service; + const gchar *user_data_dir; + gchar *state; + + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + + state = g_build_filename ( + user_data_dir, "system", "Trash.cmeta", NULL); camel_object_set_state_filename (object, state); g_free (state); @@ -1645,7 +1672,15 @@ imap_store_get_junk_folder_sync (CamelStore *store, if (folder) { CamelObject *object = CAMEL_OBJECT (folder); - gchar *state = g_build_filename(((CamelImapStore *)store)->storage_path, "system", "Junk.cmeta", NULL); + CamelService *service; + const gchar *user_data_dir; + gchar *state; + + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + + state = g_build_filename ( + user_data_dir, "system", "Junk.cmeta", NULL); camel_object_set_state_filename (object, state); g_free (state); @@ -1792,9 +1827,14 @@ imap_store_get_folder_sync (CamelStore *store, CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); CamelImapResponse *response; CamelFolder *new_folder; + CamelService *service; + const gchar *user_data_dir; gchar *folder_dir, *storage_path; GError *local_error = NULL; + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + /* Try to get it locally first, if it is, then the client will force a select when necessary */ new_folder = get_folder_offline (store, folder_name, flags, &local_error); @@ -1811,10 +1851,10 @@ imap_store_get_folder_sync (CamelStore *store, return NULL; } - camel_service_lock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); if (!camel_imap_store_connected (imap_store, error)) { - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } @@ -1832,7 +1872,7 @@ imap_store_get_folder_sync (CamelStore *store, const gchar *c; if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); g_propagate_error (error, local_error); return NULL; } @@ -1840,7 +1880,7 @@ imap_store_get_folder_sync (CamelStore *store, g_clear_error (&local_error); if (!(flags & CAMEL_STORE_FOLDER_CREATE)) { - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); g_set_error ( error, CAMEL_STORE_ERROR, CAMEL_STORE_ERROR_NO_FOLDER, @@ -1854,7 +1894,7 @@ imap_store_get_folder_sync (CamelStore *store, c++; if (*c != '\0') { - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); g_set_error ( error, CAMEL_FOLDER_ERROR, CAMEL_FOLDER_ERROR_INVALID_PATH, @@ -1877,7 +1917,7 @@ imap_store_get_folder_sync (CamelStore *store, gint i; if (!(response = camel_imap_command (imap_store, NULL, cancellable, error, "LIST \"\" %G", parent_real))) { - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); g_free (parent_name); g_free (parent_real); return NULL; @@ -1923,7 +1963,7 @@ imap_store_get_folder_sync (CamelStore *store, error, CAMEL_FOLDER_ERROR, CAMEL_FOLDER_ERROR_INVALID_STATE, _("The parent folder is not allowed to contain subfolders")); - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); g_free (parent_name); g_free (parent_real); return NULL; @@ -1932,7 +1972,7 @@ imap_store_get_folder_sync (CamelStore *store, /* delete the old parent and recreate it */ if (!imap_store_delete_folder_sync ( store, parent_name, cancellable, error)) { - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); g_free (parent_name); g_free (parent_real); return NULL; @@ -1945,7 +1985,7 @@ imap_store_get_folder_sync (CamelStore *store, g_free (name); if (!response) { - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); g_free (parent_name); g_free (parent_real); return NULL; @@ -1969,7 +2009,7 @@ imap_store_get_folder_sync (CamelStore *store, } g_free (folder_real); if (!response) { - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } } else if (flags & CAMEL_STORE_FOLDER_EXCL) { @@ -1980,12 +2020,12 @@ imap_store_get_folder_sync (CamelStore *store, camel_imap_response_free_without_processing (imap_store, response); - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } - storage_path = g_strdup_printf("%s/folders", imap_store->storage_path); + storage_path = g_strdup_printf("%s/folders", user_data_dir); folder_dir = imap_path_to_physical (storage_path, folder_name); g_free (storage_path); new_folder = camel_imap_folder_new (store, folder_name, folder_dir, error); @@ -2003,7 +2043,7 @@ imap_store_get_folder_sync (CamelStore *store, } camel_imap_response_free_without_processing (imap_store, response); - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return new_folder; } @@ -2015,6 +2055,11 @@ get_folder_offline (CamelStore *store, const gchar *folder_name, CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); CamelFolder *new_folder = NULL; CamelStoreInfo *si; + CamelService *service; + const gchar *user_data_dir; + + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); si = camel_store_summary_path ((CamelStoreSummary *)imap_store->summary, folder_name); if (si) { @@ -2030,7 +2075,7 @@ get_folder_offline (CamelStore *store, const gchar *folder_name, if (!g_ascii_strcasecmp (folder_name, "INBOX")) folder_name = "INBOX"; - storage_path = g_strdup_printf("%s/folders", imap_store->storage_path); + storage_path = g_strdup_printf("%s/folders", user_data_dir); folder_dir = imap_path_to_physical (storage_path, folder_name); g_free (storage_path); new_folder = camel_imap_folder_new (store, folder_name, folder_dir, error); @@ -2172,10 +2217,15 @@ imap_store_rename_folder_sync (CamelStore *store, { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); CamelImapResponse *response; + CamelService *service; + const gchar *user_data_dir; gchar *oldpath, *newpath, *storage_path; gboolean success = TRUE; - camel_service_lock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + + camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); if (!camel_imap_store_connected (imap_store, error)) { success = FALSE; @@ -2220,7 +2270,7 @@ imap_store_rename_folder_sync (CamelStore *store, manage_subscriptions ( store, new_name_in, TRUE, cancellable); - storage_path = g_strdup_printf("%s/folders", imap_store->storage_path); + storage_path = g_strdup_printf("%s/folders", user_data_dir); oldpath = imap_path_to_physical (storage_path, old_name); newpath = imap_path_to_physical (storage_path, new_name_in); @@ -2256,7 +2306,7 @@ imap_store_rename_folder_sync (CamelStore *store, g_free (newpath); fail: imap_store->renaming = FALSE; - camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return success; } diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h index eacacae..59024a0 100644 --- a/camel/providers/imap/camel-imap-store.h +++ b/camel/providers/imap/camel-imap-store.h @@ -153,7 +153,7 @@ struct _CamelImapStore { /* Information about the server */ CamelImapServerLevel server_level; guint32 capabilities, parameters; - gchar *users_namespace, dir_sep, *base_url, *storage_path; + gchar *users_namespace, dir_sep, *base_url; GHashTable *authtypes; time_t refresh_stamp; diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c index 5ccb1b4..bb644ad 100644 --- a/camel/providers/imapx/camel-imapx-store.c +++ b/camel/providers/imapx/camel-imapx-store.c @@ -50,7 +50,15 @@ #define FINFO_REFRESH_INTERVAL 60 -G_DEFINE_TYPE (CamelIMAPXStore, camel_imapx_store, CAMEL_TYPE_OFFLINE_STORE) +static GInitableIface *parent_initable_interface; + +/* Forward Declarations */ +static void camel_imapx_store_initable_init (GInitableIface *interface); + +G_DEFINE_TYPE_WITH_CODE ( + CamelIMAPXStore, camel_imapx_store, CAMEL_TYPE_OFFLINE_STORE, + G_IMPLEMENT_INTERFACE ( + G_TYPE_INITABLE, camel_imapx_store_initable_init)) static guint imapx_name_hash (gconstpointer key) @@ -142,44 +150,6 @@ imapx_store_finalize (GObject *object) G_OBJECT_CLASS (camel_imapx_store_parent_class)->finalize (object); } -static gboolean -imapx_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) -{ - gchar *summary; - CamelIMAPXStore *store = (CamelIMAPXStore *)service; - CamelServiceClass *service_class; - - service_class = CAMEL_SERVICE_CLASS (camel_imapx_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; - - store->base_url = camel_url_to_string ( - url, CAMEL_URL_HIDE_PASSWORD | - CAMEL_URL_HIDE_PARAMS | CAMEL_URL_HIDE_AUTH); - imapx_parse_receiving_options (store, url); - - store->summary = camel_imapx_store_summary_new (); - store->storage_path = camel_session_get_storage_path (session, service, error); - - if (store->storage_path == NULL) - return FALSE; - - summary = g_build_filename(store->storage_path, ".ev-store-summary", NULL); - camel_store_summary_set_filename ((CamelStoreSummary *)store->summary, summary); - /* FIXME: need to remove params, passwords, etc */ - camel_store_summary_set_uri_base ( - (CamelStoreSummary *)store->summary, url); - camel_store_summary_load ((CamelStoreSummary *)store->summary); - - g_free (summary); - - return TRUE; -} - static gchar * imapx_get_name (CamelService *service, gboolean brief) { @@ -324,6 +294,11 @@ get_folder_offline (CamelStore *store, const gchar *folder_name, CamelIMAPXStore *imapx_store = CAMEL_IMAPX_STORE (store); CamelFolder *new_folder = NULL; CamelStoreInfo *si; + CamelService *service; + const gchar *user_data_dir; + + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); si = camel_store_summary_path ((CamelStoreSummary *)imapx_store->summary, folder_name); if (si) { @@ -339,7 +314,7 @@ get_folder_offline (CamelStore *store, const gchar *folder_name, if (!g_ascii_strcasecmp (folder_name, "INBOX")) folder_name = "INBOX"; - storage_path = g_strdup_printf("%s/folders", imapx_store->storage_path); + storage_path = g_strdup_printf("%s/folders", user_data_dir); folder_dir = imapx_path_to_physical (storage_path, folder_name); g_free (storage_path); /* FIXME */ @@ -587,8 +562,13 @@ imapx_delete_folder_from_cache (CamelIMAPXStore *istore, const gchar *folder_nam gchar *state_file; gchar *folder_dir, *storage_path; CamelFolderInfo *fi; + CamelService *service; + const gchar *user_data_dir; - storage_path = g_strdup_printf ("%s/folders", istore->storage_path); + service = CAMEL_SERVICE (istore); + user_data_dir = camel_service_get_user_data_dir (service); + + storage_path = g_strdup_printf ("%s/folders", user_data_dir); folder_dir = imapx_path_to_physical (storage_path, folder_name); g_free (storage_path); if (g_access (folder_dir, F_OK) != 0) { @@ -1262,7 +1242,15 @@ imapx_store_get_junk_folder_sync (CamelStore *store, if (folder) { CamelObject *object = CAMEL_OBJECT (folder); - gchar *state = g_build_filename(((CamelIMAPXStore *)store)->storage_path, "system", "Junk.cmeta", NULL); + CamelService *service; + const gchar *user_data_dir; + gchar *state; + + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + + state = g_build_filename ( + user_data_dir, "system", "Junk.cmeta", NULL); camel_object_set_state_filename (object, state); g_free (state); @@ -1286,7 +1274,15 @@ imapx_store_get_trash_folder_sync (CamelStore *store, if (folder) { CamelObject *object = CAMEL_OBJECT (folder); - gchar *state = g_build_filename(((CamelIMAPXStore *)store)->storage_path, "system", "Trash.cmeta", NULL); + CamelService *service; + const gchar *user_data_dir; + gchar *state; + + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + + state = g_build_filename ( + user_data_dir, "system", "Trash.cmeta", NULL); camel_object_set_state_filename (object, state); g_free (state); @@ -1433,9 +1429,14 @@ imapx_store_rename_folder_sync (CamelStore *store, { CamelIMAPXStore *istore = (CamelIMAPXStore *) store; CamelIMAPXServer *server; + CamelService *service; + const gchar *user_data_dir; gchar *oldpath, *newpath, *storage_path; gboolean success = FALSE; + service = CAMEL_SERVICE (store); + user_data_dir = camel_service_get_user_data_dir (service); + if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) { g_set_error ( error, CAMEL_SERVICE_ERROR, @@ -1468,7 +1469,7 @@ imapx_store_rename_folder_sync (CamelStore *store, success = imapx_subscribe_folder ( store, new, FALSE, cancellable, error); - storage_path = g_strdup_printf("%s/folders", istore->storage_path); + storage_path = g_strdup_printf("%s/folders", user_data_dir); oldpath = imapx_path_to_physical (storage_path, old); newpath = imapx_path_to_physical (storage_path, new); g_free (storage_path); @@ -1532,6 +1533,48 @@ imapx_store_noop_sync (CamelStore *store, return success; } +static gboolean +imapx_store_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + CamelIMAPXStore *store; + CamelService *service; + CamelSession *session; + CamelURL *url; + const gchar *user_data_dir; + gchar *summary; + + store = CAMEL_IMAPX_STORE (initable); + + /* Chain up to parent interface's init() method. */ + if (!parent_initable_interface->init (initable, cancellable, error)) + return FALSE; + + service = CAMEL_SERVICE (initable); + url = camel_service_get_camel_url (service); + session = camel_service_get_session (service); + user_data_dir = camel_service_get_user_data_dir (service); + + store->base_url = camel_url_to_string ( + url, CAMEL_URL_HIDE_PASSWORD | + CAMEL_URL_HIDE_PARAMS | CAMEL_URL_HIDE_AUTH); + imapx_parse_receiving_options (store, url); + + store->summary = camel_imapx_store_summary_new (); + + summary = g_build_filename (user_data_dir, ".ev-store-summary", NULL); + camel_store_summary_set_filename ((CamelStoreSummary *)store->summary, summary); + /* FIXME: need to remove params, passwords, etc */ + camel_store_summary_set_uri_base ( + (CamelStoreSummary *)store->summary, url); + camel_store_summary_load ((CamelStoreSummary *)store->summary); + + g_free (summary); + + return TRUE; +} + static void camel_imapx_store_class_init (CamelIMAPXStoreClass *class) { @@ -1543,7 +1586,6 @@ camel_imapx_store_class_init (CamelIMAPXStoreClass *class) object_class->finalize = imapx_store_finalize; service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = imapx_construct; service_class->get_name = imapx_get_name; service_class->connect_sync = imapx_connect_sync; service_class->disconnect_sync = imapx_disconnect_sync; @@ -1568,6 +1610,14 @@ camel_imapx_store_class_init (CamelIMAPXStoreClass *class) } static void +camel_imapx_store_initable_init (GInitableIface *interface) +{ + parent_initable_interface = g_type_interface_peek_parent (interface); + + interface->init = imapx_store_initable_init; +} + +static void camel_imapx_store_init (CamelIMAPXStore *istore) { CamelStore *store = CAMEL_STORE (istore); diff --git a/camel/providers/imapx/camel-imapx-store.h b/camel/providers/imapx/camel-imapx-store.h index be5ce65..b4dcbe6 100644 --- a/camel/providers/imapx/camel-imapx-store.h +++ b/camel/providers/imapx/camel-imapx-store.h @@ -70,7 +70,7 @@ struct _CamelIMAPXStore { CamelIMAPXConnManager *con_man; CamelIMAPXStoreSummary *summary; /* in-memory list of folders */ - gchar *namespace, dir_sep, *base_url, *storage_path; + gchar *namespace, dir_sep, *base_url; guint32 rec_options; diff --git a/camel/providers/imapx/test-imapx.c b/camel/providers/imapx/test-imapx.c index 7f3d270..20c2b66 100644 --- a/camel/providers/imapx/test-imapx.c +++ b/camel/providers/imapx/test-imapx.c @@ -41,10 +41,12 @@ main (gint argc, gchar *argv[]) camel_init ("/tmp/test-camel-imapx", TRUE); camel_provider_init (); - session = g_object_new (CAMEL_TYPE_SESSION, NULL); - camel_session_construct (session, "/tmp/test-camel-imapx"); + session = g_object_new ( + CAMEL_TYPE_SESSION, + "user-data-dir", "/tmp/test-camel-imapx", NULL); - service = camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, NULL); + service = camel_session_add_service ( + session, "text-imapx", uri, CAMEL_PROVIDER_STORE, NULL); camel_service_connect_sync (service, NULL); camel_store_get_folder_info_sync ( diff --git a/camel/providers/local/camel-local-store.c b/camel/providers/local/camel-local-store.c index 7d81a29..5b88d9c 100644 --- a/camel/providers/local/camel-local-store.c +++ b/camel/providers/local/camel-local-store.c @@ -39,7 +39,6 @@ #define d(x) -static gboolean construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, GError **error); static CamelFolder *local_store_get_folder_sync (CamelStore *store, const gchar *folder_name, CamelStoreGetFolderFlags flags, GCancellable *cancellable, GError **error); static gchar *get_name (CamelService *service, gboolean brief); static CamelFolder *local_store_get_inbox_folder_sync (CamelStore *store, GCancellable *cancellable, GError **error); @@ -57,6 +56,54 @@ static gchar *local_get_meta_path (CamelLocalStore *lf, const gchar *full_name, G_DEFINE_TYPE (CamelLocalStore, camel_local_store, CAMEL_TYPE_STORE) static void +local_store_constructed (GObject *object) +{ + CamelLocalStore *local_store; + CamelService *service; + CamelURL *url; + gchar *local_store_path; + gchar *local_store_uri; + gint len; + + local_store = CAMEL_LOCAL_STORE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (camel_local_store_parent_class)->constructed (object); + + service = CAMEL_SERVICE (object); + url = camel_service_get_camel_url (service); + + len = strlen (url->path); + if (!G_IS_DIR_SEPARATOR (url->path[len - 1])) + local_store->toplevel_dir = g_strdup_printf ("%s/", url->path); + else + local_store->toplevel_dir = g_strdup (url->path); + + local_store->is_main_store = FALSE; + + local_store_path = g_build_filename ( + e_get_user_data_dir (), "mail", "local", NULL); + local_store_uri = g_filename_to_uri (local_store_path, NULL, NULL); + if (local_store_uri) { + CamelProvider *provider; + CamelURL *local_store_url = camel_url_new (local_store_uri, NULL); + + provider = camel_service_get_provider (service); + camel_url_set_protocol (local_store_url, url->protocol); + camel_url_set_host (local_store_url, url->host); + + local_store->is_main_store = + provider && provider->url_equal ? + provider->url_equal (url, local_store_url) : + camel_url_equal (url, local_store_url); + camel_url_free (local_store_url); + } + + g_free (local_store_uri); + g_free (local_store_path); +} + +static void local_store_finalize (GObject *object) { CamelLocalStore *local_store = CAMEL_LOCAL_STORE (object); @@ -76,9 +123,9 @@ camel_local_store_class_init (CamelLocalStoreClass *class) object_class = G_OBJECT_CLASS (class); object_class->finalize = local_store_finalize; + object_class->constructed = local_store_constructed; service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = construct; service_class->get_name = get_name; store_class = CAMEL_STORE_CLASS (class); @@ -102,54 +149,6 @@ camel_local_store_init (CamelLocalStore *local_store) { } -static gboolean -construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) -{ - CamelLocalStore *local_store = CAMEL_LOCAL_STORE (service); - CamelServiceClass *service_class; - gint len; - gchar *local_store_path, *local_store_uri; - - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_local_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; - - len = strlen (url->path); - if (!G_IS_DIR_SEPARATOR (url->path[len - 1])) - local_store->toplevel_dir = g_strdup_printf ("%s/", url->path); - else - local_store->toplevel_dir = g_strdup (url->path); - - local_store->is_main_store = FALSE; - - local_store_path = g_build_filename (e_get_user_data_dir (), "mail", "local", NULL); - local_store_uri = g_filename_to_uri (local_store_path, NULL, NULL); - if (local_store_uri) { - CamelProvider *provider; - CamelURL *local_store_url = camel_url_new (local_store_uri, NULL); - - provider = camel_service_get_provider (service); - camel_url_set_protocol (local_store_url, url->protocol); - camel_url_set_host (local_store_url, url->host); - - local_store->is_main_store = - provider && provider->url_equal ? - provider->url_equal (url, local_store_url) : - camel_url_equal (url, local_store_url); - camel_url_free (local_store_url); - } - - g_free (local_store_uri); - g_free (local_store_path); - - return TRUE; -} - const gchar * camel_local_store_get_toplevel_dir (CamelLocalStore *store) { diff --git a/camel/providers/local/camel-mh-store.c b/camel/providers/local/camel-mh-store.c index de41092..6c33f7f 100644 --- a/camel/providers/local/camel-mh-store.c +++ b/camel/providers/local/camel-mh-store.c @@ -416,25 +416,23 @@ inode_free (gpointer k, gpointer v, gpointer d) g_free (k); } -static gboolean -mh_folder_store_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) +static void +mh_store_constructed (GObject *object) { - CamelServiceClass *service_class; - CamelMhStore *mh_store = (CamelMhStore *)service; + CamelMhStore *mh_store; + CamelService *service; + CamelURL *url; - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_mh_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; + mh_store = CAMEL_MH_STORE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (camel_mh_store_parent_class)->constructed (object); + + service = CAMEL_SERVICE (object); + url = camel_service_get_camel_url (service); if (camel_url_get_param(url, "dotfolders")) mh_store->flags |= CAMEL_MH_DOTFOLDERS; - - return TRUE; } static CamelFolder * @@ -625,11 +623,11 @@ mh_store_rename_folder_sync (CamelStore *store, static void camel_mh_store_class_init (CamelMhStoreClass *class) { - CamelServiceClass *service_class; + GObjectClass *object_class; CamelStoreClass *store_class; - service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = mh_folder_store_construct; + object_class = G_OBJECT_CLASS (class); + object_class->constructed = mh_store_constructed; store_class = CAMEL_STORE_CLASS (class); store_class->get_folder_sync = mh_store_get_folder_sync; diff --git a/camel/providers/local/camel-spool-store.c b/camel/providers/local/camel-spool-store.c index 539d1c2..0675eb4 100644 --- a/camel/providers/local/camel-spool-store.c +++ b/camel/providers/local/camel-spool-store.c @@ -40,7 +40,15 @@ #define d(x) -G_DEFINE_TYPE (CamelSpoolStore, camel_spool_store, CAMEL_TYPE_MBOX_STORE) +static GInitableIface *parent_initable_interface; + +/* Forward Declarations */ +static void camel_spool_store_initable_init (GInitableIface *interface); + +G_DEFINE_TYPE_WITH_CODE ( + CamelSpoolStore, camel_spool_store, CAMEL_TYPE_MBOX_STORE, + G_IMPLEMENT_INTERFACE ( + G_TYPE_INITABLE, camel_spool_store_initable_init)) /* partially copied from mbox */ static void @@ -297,59 +305,6 @@ get_folder_info_mbox (CamelStore *store, return fi; } -static gboolean -spool_store_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) -{ - CamelServiceClass *service_class; - struct stat st; - - d(printf("constructing store of type %s '%s:%s'\n", - G_OBJECT_CLASS_NAME (((CamelObject *)service)->s.type), url->protocol, url->path)); - - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_spool_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; - - if (url->path[0] != '/') { - g_set_error ( - error, CAMEL_STORE_ERROR, - CAMEL_STORE_ERROR_NO_FOLDER, - _("Store root %s is not an absolute path"), - url->path); - return FALSE; - } - - if (g_stat (url->path, &st) == -1) { - g_set_error ( - error, G_IO_ERROR, - g_io_error_from_errno (errno), - _("Spool '%s' cannot be opened: %s"), - url->path, g_strerror (errno)); - return FALSE; - } - - if (S_ISREG (st.st_mode)) - ((CamelSpoolStore *)service)->type = CAMEL_SPOOL_STORE_MBOX; - else if (S_ISDIR (st.st_mode)) - /* we could check here for slight variations */ - ((CamelSpoolStore *)service)->type = CAMEL_SPOOL_STORE_ELM; - else { - g_set_error ( - error, CAMEL_STORE_ERROR, - CAMEL_STORE_ERROR_NO_FOLDER, - _("Spool '%s' is not a regular file or directory"), - url->path); - return FALSE; - } - - return TRUE; -} - static gchar * spool_store_get_name (CamelService *service, gboolean brief) @@ -526,25 +481,71 @@ spool_store_get_meta_path (CamelLocalStore *ls, { CamelService *service; CamelSession *session; - gchar *root; + const gchar *user_data_dir; gchar *path, *key; service = CAMEL_SERVICE (ls); session = camel_service_get_session (service); - root = camel_session_get_storage_path (session, service, NULL); - - if (root == NULL) - return NULL; + user_data_dir = camel_service_get_user_data_dir (service); - g_mkdir_with_parents (root, 0700); key = camel_file_util_safe_filename (full_name); - path = g_strdup_printf ("%s/%s%s", root, key, ext); + path = g_strdup_printf ("%s/%s%s", user_data_dir, key, ext); g_free (key); - g_free (root); return path; } +static gboolean +spool_store_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + CamelService *service; + CamelURL *url; + struct stat st; + + /* Chain up to parent interface's init() method. */ + if (!parent_initable_interface->init (initable, cancellable, error)) + return FALSE; + + service = CAMEL_SERVICE (initable); + url = camel_service_get_camel_url (service); + + if (url->path[0] != '/') { + g_set_error ( + error, CAMEL_STORE_ERROR, + CAMEL_STORE_ERROR_NO_FOLDER, + _("Store root %s is not an absolute path"), + url->path); + return FALSE; + } + + if (g_stat (url->path, &st) == -1) { + g_set_error ( + error, G_IO_ERROR, + g_io_error_from_errno (errno), + _("Spool '%s' cannot be opened: %s"), + url->path, g_strerror (errno)); + return FALSE; + } + + if (S_ISREG (st.st_mode)) + ((CamelSpoolStore *)service)->type = CAMEL_SPOOL_STORE_MBOX; + else if (S_ISDIR (st.st_mode)) + /* we could check here for slight variations */ + ((CamelSpoolStore *)service)->type = CAMEL_SPOOL_STORE_ELM; + else { + g_set_error ( + error, CAMEL_STORE_ERROR, + CAMEL_STORE_ERROR_NO_FOLDER, + _("Spool '%s' is not a regular file or directory"), + url->path); + return FALSE; + } + + return TRUE; +} + static void camel_spool_store_class_init (CamelSpoolStoreClass *class) { @@ -553,7 +554,6 @@ camel_spool_store_class_init (CamelSpoolStoreClass *class) CamelLocalStoreClass *local_store_class; service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = spool_store_construct; service_class->get_name = spool_store_get_name; store_class = CAMEL_STORE_CLASS (class); @@ -570,6 +570,14 @@ camel_spool_store_class_init (CamelSpoolStoreClass *class) } static void +camel_spool_store_initable_init (GInitableIface *interface) +{ + parent_initable_interface = g_type_interface_peek_parent (interface); + + interface->init = spool_store_initable_init; +} + +static void camel_spool_store_init (CamelSpoolStore *spool_store) { } diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c index f5651d0..18823fa 100644 --- a/camel/providers/nntp/camel-nntp-folder.c +++ b/camel/providers/nntp/camel-nntp-folder.c @@ -658,17 +658,12 @@ camel_nntp_folder_new (CamelStore *parent, CamelService *service; CamelSession *session; CamelStoreInfo *si; + const gchar *user_data_dir; gboolean subscribed = TRUE; service = CAMEL_SERVICE (parent); session = camel_service_get_session (service); - - root = camel_session_get_storage_path (session, service, error); - if (root == NULL) - return NULL; - - /* If this doesn't work, stuff wont save, but let it continue anyway */ - g_mkdir_with_parents (root, 0700); + user_data_dir = camel_service_get_user_data_dir (service); folder = g_object_new ( CAMEL_TYPE_NNTP_FOLDER, @@ -677,10 +672,12 @@ camel_nntp_folder_new (CamelStore *parent, "parent-store", parent, NULL); nntp_folder = (CamelNNTPFolder *)folder; - folder->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY|CAMEL_FOLDER_HAS_SEARCH_CAPABILITY; + folder->folder_flags |= + CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY | + CAMEL_FOLDER_HAS_SEARCH_CAPABILITY; - nntp_folder->storage_path = g_build_filename (root, folder_name, NULL); - g_free (root); + nntp_folder->storage_path = + g_build_filename (user_data_dir, folder_name, NULL); root = g_strdup_printf ("%s.cmeta", nntp_folder->storage_path); camel_object_set_state_filename (CAMEL_OBJECT (nntp_folder), root); diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c index ab83a77..b3741ed 100644 --- a/camel/providers/nntp/camel-nntp-store.c +++ b/camel/providers/nntp/camel-nntp-store.c @@ -54,7 +54,15 @@ #define DUMP_EXTENSIONS -G_DEFINE_TYPE (CamelNNTPStore, camel_nntp_store, CAMEL_TYPE_DISCO_STORE) +static GInitableIface *parent_initable_interface; + +/* Forward Declarations */ +static void camel_nntp_store_initable_init (GInitableIface *interface); + +G_DEFINE_TYPE_WITH_CODE ( + CamelNNTPStore, camel_nntp_store, CAMEL_TYPE_DISCO_STORE, + G_IMPLEMENT_INTERFACE ( + G_TYPE_INITABLE, camel_nntp_store_initable_init)) static gint camel_nntp_try_authenticate (CamelNNTPStore *store, @@ -182,7 +190,6 @@ nntp_store_finalize (GObject *object) struct _xover_header *xover, *xn; g_free (nntp_store->base_url); - g_free (nntp_store->storage_path); xover = nntp_store->xover; while (xover) { @@ -327,6 +334,7 @@ connect_to_server (CamelService *service, gchar *socks_host; gint socks_port; CamelStream *tcp_stream; + const gchar *user_data_dir; gboolean retval = FALSE; guchar *buf; guint len; @@ -334,8 +342,9 @@ connect_to_server (CamelService *service, url = camel_service_get_camel_url (service); session = camel_service_get_session (service); + user_data_dir = camel_service_get_user_data_dir (service); - camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); if (ssl_mode != MODE_CLEAR) { #ifdef CAMEL_HAVE_SSL @@ -416,7 +425,7 @@ connect_to_server (CamelService *service, goto fail; if (!disco_store->diary) { - path = g_build_filename (store->storage_path, ".ev-journal", NULL); + path = g_build_filename (user_data_dir, ".ev-journal", NULL); disco_store->diary = camel_disco_diary_new (disco_store, path, error); g_free (path); } @@ -427,7 +436,7 @@ connect_to_server (CamelService *service, store->current_folder = NULL; fail: - camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return retval; } @@ -514,14 +523,14 @@ nntp_connect_offline (CamelService *service, { CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (service); CamelDiscoStore *disco_store = (CamelDiscoStore *) nntp_store; + const gchar *user_data_dir; gchar *path; - if (nntp_store->storage_path == NULL) - return FALSE; + user_data_dir = camel_service_get_user_data_dir (service); /* setup store-wide cache */ if (nntp_store->cache == NULL) { - nntp_store->cache = camel_data_cache_new (nntp_store->storage_path, error); + nntp_store->cache = camel_data_cache_new (user_data_dir, error); if (nntp_store->cache == NULL) return FALSE; @@ -533,7 +542,7 @@ nntp_connect_offline (CamelService *service, if (disco_store->diary) return TRUE; - path = g_build_filename (nntp_store->storage_path, ".ev-journal", NULL); + path = g_build_filename (user_data_dir, ".ev-journal", NULL); disco_store->diary = camel_disco_diary_new (disco_store, path, error); g_free (path); @@ -1361,35 +1370,36 @@ nntp_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **erro return TRUE; } -/* construction function in which we set some basic store properties */ static gboolean -nntp_construct (CamelService *service, - CamelSession *session, - CamelProvider *provider, - CamelURL *url, - GError **error) +nntp_store_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) { - CamelServiceClass *service_class; - CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (service); + CamelNNTPStore *nntp_store; + CamelService *service; + CamelSession *session; CamelURL *summary_url; + CamelURL *url; + const gchar *user_data_dir; gchar *tmp; - /* construct the parent first */ - service_class = CAMEL_SERVICE_CLASS (camel_nntp_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; + nntp_store = CAMEL_NNTP_STORE (initable); - /* find out the storage path, base url */ - nntp_store->storage_path = camel_session_get_storage_path (session, service, error); - if (!nntp_store->storage_path) + /* Chain up to parent interface's init() method. */ + if (!parent_initable_interface->init (initable, cancellable, error)) return FALSE; + service = CAMEL_SERVICE (initable); + url = camel_service_get_camel_url (service); + session = camel_service_get_session (service); + user_data_dir = camel_service_get_user_data_dir (service); + /* FIXME */ nntp_store->base_url = camel_url_to_string ( url, CAMEL_URL_HIDE_PASSWORD | CAMEL_URL_HIDE_PARAMS | CAMEL_URL_HIDE_AUTH); - tmp = g_build_filename (nntp_store->storage_path, ".ev-store-summary", NULL); + tmp = g_build_filename (user_data_dir, ".ev-store-summary", NULL); nntp_store->summary = camel_nntp_store_summary_new (); camel_store_summary_set_filename ((CamelStoreSummary *) nntp_store->summary, tmp); summary_url = camel_url_new (nntp_store->base_url, NULL); @@ -1410,7 +1420,7 @@ nntp_construct (CamelService *service, nntp_store->folder_hierarchy_relative = FALSE; /* setup store-wide cache */ - nntp_store->cache = camel_data_cache_new (nntp_store->storage_path, error); + nntp_store->cache = camel_data_cache_new (user_data_dir, error); if (nntp_store->cache == NULL) return FALSE; @@ -1436,7 +1446,6 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *class) object_class->finalize = nntp_store_finalize; service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = nntp_construct; service_class->get_name = nntp_store_get_name; service_class->query_auth_types_sync = nntp_store_query_auth_types_sync; @@ -1465,6 +1474,14 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *class) } static void +camel_nntp_store_initable_init (GInitableIface *interface) +{ + parent_initable_interface = g_type_interface_peek_parent (interface); + + interface->init = nntp_store_initable_init; +} + +static void camel_nntp_store_init (CamelNNTPStore *nntp_store) { CamelStore *store = CAMEL_STORE (nntp_store); diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h index cc6a36b..7d58ad7 100644 --- a/camel/providers/nntp/camel-nntp-store.h +++ b/camel/providers/nntp/camel-nntp-store.h @@ -102,7 +102,7 @@ struct _CamelNNTPStore { struct _CamelDataCache *cache; - gchar *current_folder, *storage_path, *base_url; + gchar *current_folder, *base_url; struct _xover_header *xover; guint32 capabilities; /* bit-or of nntp_capabilities */ diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c index 51e1f96..27cdfd9 100644 --- a/camel/providers/pop3/camel-pop3-store.c +++ b/camel/providers/pop3/camel-pop3-store.c @@ -589,26 +589,21 @@ pop3_store_connect_sync (CamelService *service, { CamelPOP3Store *store = (CamelPOP3Store *)service; gboolean reprompt = FALSE; - CamelSession *session; CamelURL *url; + const gchar *user_data_dir; gchar *errbuf = NULL; GError *local_error = NULL; url = camel_service_get_camel_url (service); - session = camel_service_get_session (service); + user_data_dir = camel_service_get_user_data_dir (service); if (store->cache == NULL) { - gchar *root; - - root = camel_session_get_storage_path (session, service, error); - if (root) { - store->cache = camel_data_cache_new (root, error); - g_free (root); - if (store->cache) { - /* Ensure cache will never expire, otherwise it causes redownload of messages */ - camel_data_cache_set_expire_age (store->cache, -1); - camel_data_cache_set_expire_access (store->cache, -1); - } + store->cache = camel_data_cache_new (user_data_dir, error); + if (store->cache) { + /* Ensure cache will never expire, otherwise + * it causes redownload of messages. */ + camel_data_cache_set_expire_age (store->cache, -1); + camel_data_cache_set_expire_access (store->cache, -1); } } diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt index d94d791..64912a2 100644 --- a/docs/reference/camel/camel-sections.txt +++ b/docs/reference/camel/camel-sections.txt @@ -1876,11 +1876,11 @@ CAMEL_SERVICE_ERROR CamelServiceError CamelServiceConnectionStatus CamelServiceAuthType -camel_service_construct +camel_service_get_user_data_dir camel_service_get_name -camel_service_get_path camel_service_get_provider camel_service_get_session +camel_service_get_uid camel_service_get_camel_url camel_service_get_url camel_service_cancel_connect @@ -1913,14 +1913,13 @@ CamelTimeoutCallback CamelSessionAlertType CamelSessionThreadOps CamelSessionThreadMsg -camel_session_construct +camel_session_get_user_data_dir camel_session_set_socks_proxy camel_session_get_socks_proxy +camel_session_add_service camel_session_get_service -camel_session_get_service_connected -camel_session_get_store -camel_session_get_transport -camel_session_get_storage_path +camel_session_get_service_by_url +camel_session_list_services camel_session_get_password camel_session_forget_password camel_session_alert_user diff --git a/docs/reference/camel/tmpl/camel-cipher-context.sgml b/docs/reference/camel/tmpl/camel-cipher-context.sgml index 8d450dc..dfff463 100644 --- a/docs/reference/camel/tmpl/camel-cipher-context.sgml +++ b/docs/reference/camel/tmpl/camel-cipher-context.sgml @@ -732,6 +732,16 @@ CamelCipherContext @gpointer cert_data: @gpointer cert_data: @gpointer cert_data: +@gpointer cert_data: +@gpointer cert_data: +@gpointer cert_data: +@gpointer cert_data: +@gpointer cert_data: +@gpointer cert_data: +@gpointer cert_data: +@gpointer cert_data: +@gpointer cert_data: +@gpointer cert_data: @gpointer cert_data: diff --git a/docs/reference/camel/tmpl/camel-provider.sgml b/docs/reference/camel/tmpl/camel-provider.sgml index 92cd567..fd7e795 100644 --- a/docs/reference/camel/tmpl/camel-provider.sgml +++ b/docs/reference/camel/tmpl/camel-provider.sgml @@ -36,7 +36,6 @@ camel-provider @auto_detect: @object_types: @authtypes: -@service_cache: @url_hash: @url_equal: @translation_domain: @@ -268,7 +267,6 @@ camel-provider @auto_detect: @object_types: @authtypes: -@service_cache: @url_hash: @url_equal: @translation_domain: diff --git a/docs/reference/camel/tmpl/camel-service.sgml b/docs/reference/camel/tmpl/camel-service.sgml index 2716896..6720693 100644 --- a/docs/reference/camel/tmpl/camel-service.sgml +++ b/docs/reference/camel/tmpl/camel-service.sgml @@ -26,6 +26,26 @@ CamelService + + + + + + + + + + + + + + + + + + + + @@ -64,16 +84,12 @@ CamelService @authproto: @need_password: - + @service: -@session: -@provider: -@url: -@error: @Returns: @@ -87,7 +103,7 @@ CamelService @Returns: - + @@ -96,7 +112,7 @@ CamelService @Returns: - + @@ -105,7 +121,7 @@ CamelService @Returns: - + diff --git a/docs/reference/camel/tmpl/camel-session.sgml b/docs/reference/camel/tmpl/camel-session.sgml index 7070939..f2c94f1 100644 --- a/docs/reference/camel/tmpl/camel-session.sgml +++ b/docs/reference/camel/tmpl/camel-session.sgml @@ -41,6 +41,11 @@ CamelSession + + + + + @@ -80,13 +85,13 @@ CamelSession @session: @data: - + @session: -@storage_path: +@Returns: @@ -109,58 +114,45 @@ CamelSession @port_ret: - + @session: -@url_string: +@uid: +@uri_string: @type: @error: @Returns: - + @session: -@url_string: -@type: -@error: +@uid: @Returns: - + @session: -@url_string: -@error: - - - - - - - -@session: -@url_string: -@error: +@url: +@Returns: - + @session: -@service: -@error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-unused.sgml b/docs/reference/camel/tmpl/camel-unused.sgml index 9953772..c4200f6 100644 --- a/docs/reference/camel/tmpl/camel-unused.sgml +++ b/docs/reference/camel/tmpl/camel-unused.sgml @@ -4387,6 +4387,12 @@ streams @parent: + + + + + + @@ -8500,6 +8506,18 @@ streams @error: @Returns: + + + + + +@service: +@session: +@provider: +@url: +@error: +@Returns: + @@ -8510,6 +8528,14 @@ streams @error: @Returns: + + + + + +@service: +@Returns: + @@ -8528,6 +8554,22 @@ streams @session: @Returns: + + + + + +@session: +@storage_path: + + + + + + +@session: +@Returns: + @@ -8536,6 +8578,44 @@ streams @session: @Returns: + + + + + +@session: +@uid: +@error: +@Returns: + + + + + + +@session: +@service: +@error: +@Returns: + + + + + + +@session: +@uid: +@error: + + + + + + +@session: +@uid: +@error: +