[evolution-data-server] Rework how CamelServices are added to CamelSession.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Rework how CamelServices are added to CamelSession.
- Date: Thu, 21 Apr 2011 16:37:53 +0000 (UTC)
commit e0ac4d79705c8b51783c71b362499f38c15ee496
Author: Matthew Barnes <mbarnes redhat com>
Date: Tue Apr 19 15:32:47 2011 -0400
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.
camel/camel-disco-store.c | 35 +-
camel/camel-offline-store.c | 38 +-
camel/camel-provider.c | 6 -
camel/camel-provider.h | 2 -
camel/camel-sasl-popb4smtp.c | 54 ++-
camel/camel-service.c | 593 ++++++++++++++------
camel/camel-service.h | 14 +-
camel/camel-session.c | 409 +++++++++-----
camel/camel-session.h | 37 +-
camel/camel-store.c | 150 +++---
camel/camel-vee-store.c | 32 +-
camel/providers/groupwise/camel-groupwise-folder.c | 11 +-
camel/providers/groupwise/camel-groupwise-store.c | 283 ++++++----
camel/providers/groupwise/camel-groupwise-store.h | 1 -
.../groupwise/camel-groupwise-transport.c | 71 ++-
.../groupwise/camel-groupwise-transport.h | 10 +-
camel/providers/imap/camel-imap-folder.c | 10 +-
camel/providers/imap/camel-imap-store.c | 304 ++++++-----
camel/providers/imap/camel-imap-store.h | 2 +-
camel/providers/imapx/camel-imapx-store.c | 140 ++++--
camel/providers/imapx/camel-imapx-store.h | 2 +-
camel/providers/imapx/test-imapx.c | 8 +-
camel/providers/local/camel-local-store.c | 99 ++--
camel/providers/local/camel-mh-store.c | 32 +-
camel/providers/local/camel-spool-store.c | 134 +++--
camel/providers/nntp/camel-nntp-folder.c | 17 +-
camel/providers/nntp/camel-nntp-store.c | 71 ++-
camel/providers/nntp/camel-nntp-store.h | 2 +-
camel/providers/pop3/camel-pop3-store.c | 21 +-
docs/reference/camel/camel-sections.txt | 13 +-
.../reference/camel/tmpl/camel-cipher-context.sgml | 10 +
docs/reference/camel/tmpl/camel-provider.sgml | 2 -
docs/reference/camel/tmpl/camel-service.sgml | 32 +-
docs/reference/camel/tmpl/camel-session.sgml | 40 +-
docs/reference/camel/tmpl/camel-unused.sgml | 80 +++
35 files changed, 1683 insertions(+), 1082 deletions(-)
---
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 <stdlib.h>
#include <string.h>
+#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
#include <libedataserver/e-data-server-util.h>
@@ -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 <config.h>
#endif
+#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -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 <camel/camel.h>
+#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
</para>
+<!-- ##### ARG CamelService:provider ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG CamelService:session ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG CamelService:uid ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG CamelService:url ##### -->
+<para>
+
+</para>
+
<!-- ##### MACRO CAMEL_SERVICE_ERROR ##### -->
<para>
@@ -64,16 +84,12 @@ CamelService
@authproto:
@need_password:
-<!-- ##### FUNCTION camel_service_construct ##### -->
+<!-- ##### FUNCTION camel_service_get_user_data_dir ##### -->
<para>
</para>
@service:
- session:
- provider:
- url:
- error:
@Returns:
@@ -87,7 +103,7 @@ CamelService
@Returns:
-<!-- ##### FUNCTION camel_service_get_path ##### -->
+<!-- ##### FUNCTION camel_service_get_provider ##### -->
<para>
</para>
@@ -96,7 +112,7 @@ CamelService
@Returns:
-<!-- ##### FUNCTION camel_service_get_provider ##### -->
+<!-- ##### FUNCTION camel_service_get_session ##### -->
<para>
</para>
@@ -105,7 +121,7 @@ CamelService
@Returns:
-<!-- ##### FUNCTION camel_service_get_session ##### -->
+<!-- ##### FUNCTION camel_service_get_uid ##### -->
<para>
</para>
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
</para>
+<!-- ##### ARG CamelSession:user-data-dir ##### -->
+<para>
+
+</para>
+
<!-- ##### USER_FUNCTION CamelTimeoutCallback ##### -->
<para>
@@ -80,13 +85,13 @@ CamelSession
@session:
@data:
-<!-- ##### FUNCTION camel_session_construct ##### -->
+<!-- ##### FUNCTION camel_session_get_user_data_dir ##### -->
<para>
</para>
@session:
- storage_path:
+ Returns:
<!-- ##### FUNCTION camel_session_set_socks_proxy ##### -->
@@ -109,58 +114,45 @@ CamelSession
@port_ret:
-<!-- ##### FUNCTION camel_session_get_service ##### -->
+<!-- ##### FUNCTION camel_session_add_service ##### -->
<para>
</para>
@session:
- url_string:
+ uid:
+ uri_string:
@type:
@error:
@Returns:
-<!-- ##### FUNCTION camel_session_get_service_connected ##### -->
+<!-- ##### FUNCTION camel_session_get_service ##### -->
<para>
</para>
@session:
- url_string:
- type:
- error:
+ uid:
@Returns:
-<!-- ##### MACRO camel_session_get_store ##### -->
+<!-- ##### FUNCTION camel_session_get_service_by_url ##### -->
<para>
</para>
@session:
- url_string:
- error:
-
-
-<!-- ##### MACRO camel_session_get_transport ##### -->
-<para>
-
-</para>
-
- session:
- url_string:
- error:
+ url:
+ Returns:
-<!-- ##### FUNCTION camel_session_get_storage_path ##### -->
+<!-- ##### FUNCTION camel_session_list_services ##### -->
<para>
</para>
@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:
+<!-- ##### ARG CamelSession:data-dir ##### -->
+<para>
+
+</para>
+
+
<!-- ##### STRUCT CamelSimpleDataWrapper ##### -->
<para>
@@ -8500,6 +8506,18 @@ streams
@error:
@Returns:
+<!-- ##### FUNCTION camel_service_construct ##### -->
+<para>
+
+</para>
+
+ service:
+ session:
+ provider:
+ url:
+ error:
+ Returns:
+
<!-- ##### FUNCTION camel_service_disconnect ##### -->
<para>
@@ -8510,6 +8528,14 @@ streams
@error:
@Returns:
+<!-- ##### FUNCTION camel_service_get_path ##### -->
+<para>
+
+</para>
+
+ service:
+ Returns:
+
<!-- ##### FUNCTION camel_service_query_auth_types ##### -->
<para>
@@ -8528,6 +8554,22 @@ streams
@session:
@Returns:
+<!-- ##### FUNCTION camel_session_construct ##### -->
+<para>
+
+</para>
+
+ session:
+ storage_path:
+
+<!-- ##### FUNCTION camel_session_get_data_dir ##### -->
+<para>
+
+</para>
+
+ session:
+ Returns:
+
<!-- ##### FUNCTION camel_session_get_network_state ##### -->
<para>
@@ -8536,6 +8578,44 @@ streams
@session:
@Returns:
+<!-- ##### FUNCTION camel_session_get_service_connected ##### -->
+<para>
+
+</para>
+
+ session:
+ uid:
+ error:
+ Returns:
+
+<!-- ##### FUNCTION camel_session_get_storage_path ##### -->
+<para>
+
+</para>
+
+ session:
+ service:
+ error:
+ Returns:
+
+<!-- ##### MACRO camel_session_get_store ##### -->
+<para>
+
+</para>
+
+ session:
+ uid:
+ error:
+
+<!-- ##### MACRO camel_session_get_transport ##### -->
+<para>
+
+</para>
+
+ session:
+ uid:
+ error:
+
<!-- ##### FUNCTION camel_session_is_online ##### -->
<para>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]