aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-provider.c
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2004-02-19 15:27:49 +0800
committerMichael Zucci <zucchi@src.gnome.org>2004-02-19 15:27:49 +0800
commit05e0ef6fea2f2feec010109142c8305c69e64c57 (patch)
treef01a116128a1e73d5971bf1ba1bfc711e292aaf4 /camel/camel-provider.c
parent8b86c88624f926a7122ab4dd39ebd26d0e839ab2 (diff)
downloadgsoc2013-evolution-05e0ef6fea2f2feec010109142c8305c69e64c57.tar.gz
gsoc2013-evolution-05e0ef6fea2f2feec010109142c8305c69e64c57.tar.zst
gsoc2013-evolution-05e0ef6fea2f2feec010109142c8305c69e64c57.zip
Fixes for api changes.
2004-02-19 Not Zed <NotZed@Ximian.com> * providers/*/camel-*-provider.c (camel_provider_module_init): Fixes for api changes. * camel-provider.c (camel_provider_load): no longer take session argument. the providers are global resources. (camel_provider_init): dont return anything anymore. (error?) call from camel_init now. Use a recursive lock too. * camel-session.c (camel_session_register_provider) (camel_session_list_providers, camel_session_get_provider): Moved to camel-provider, camel_provider_register/list/get. (vee_provider): moved to camel-provider.c svn path=/trunk/; revision=24794
Diffstat (limited to 'camel/camel-provider.c')
-rw-r--r--camel/camel-provider.c232
1 files changed, 215 insertions, 17 deletions
diff --git a/camel/camel-provider.c b/camel/camel-provider.c
index 1b8ef2cab5..be15aed046 100644
--- a/camel/camel-provider.c
+++ b/camel/camel-provider.c
@@ -1,7 +1,5 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-provider.c: provider framework */
-
-/*
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ * camel-provider.c: provider framework
*
* Authors:
* Bertrand Guiheneuf <bertrand@helixcode.com>
@@ -25,7 +23,6 @@
* USA
*/
-
/* FIXME: Shouldn't we add a version number to providers ? */
#ifdef HAVE_CONFIG_H
@@ -43,7 +40,33 @@
#include "camel-provider.h"
#include "camel-exception.h"
#include "camel-string-utils.h"
+#include "camel-vee-store.h"
+
+#include "e-util/e-msgport.h"
+/* table of CamelProviderModule's */
+static GHashTable *module_table;
+/* table of CamelProvider's */
+static GHashTable *provider_table;
+static EMutex *provider_lock;
+
+#define LOCK() e_mutex_lock(provider_lock);
+#define UNLOCK() e_mutex_unlock(provider_lock);
+
+/* The vfolder provider is always available */
+static CamelProvider vee_provider = {
+ "vfolder",
+ N_("Virtual folder email provider"),
+
+ N_("For reading mail as a query of another set of folders"),
+
+ "vfolder",
+
+ CAMEL_PROVIDER_IS_STORAGE,
+ CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
+
+ /* ... */
+};
/**
* camel_provider_init:
@@ -55,25 +78,35 @@
* A .urls file has the same initial prefix as the shared library it
* correspond to, and consists of a series of lines containing the URL
* protocols that that library handles.
- *
- * Return value: a hash table mapping URLs to module names
**/
-GHashTable *
+void
camel_provider_init (void)
{
- GHashTable *providers;
DIR *dir;
struct dirent *d;
char *p, *name, buf[80];
CamelProviderModule *m;
+ static int init = 0;
+
+ if (init)
+ return;
+
+ init = 1;
+
+ provider_lock = e_mutex_new(E_MUTEX_REC);
+ module_table = g_hash_table_new(camel_strcase_hash, camel_strcase_equal);
+ provider_table = g_hash_table_new(camel_strcase_hash, camel_strcase_equal);
+
+ vee_provider.object_types[CAMEL_PROVIDER_STORE] = camel_vee_store_get_type ();
+ vee_provider.url_hash = camel_url_hash;
+ vee_provider.url_equal = camel_url_equal;
+ camel_provider_register(&vee_provider);
- providers = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
-
dir = opendir (CAMEL_PROVIDERDIR);
if (!dir) {
g_error ("Could not open camel provider directory (%s): %s",
CAMEL_PROVIDERDIR, g_strerror (errno));
- return NULL;
+ return;
}
while ((d = readdir (dir))) {
@@ -108,7 +141,7 @@ camel_provider_init (void)
char *protocol = g_strdup(buf);
m->types = g_slist_prepend(m->types, protocol);
- g_hash_table_insert(providers, protocol, m);
+ g_hash_table_insert(module_table, protocol, m);
}
}
@@ -116,7 +149,6 @@ camel_provider_init (void)
}
closedir (dir);
- return providers;
}
/**
@@ -130,10 +162,10 @@ camel_provider_init (void)
* itself with @session.
**/
void
-camel_provider_load (CamelSession *session, const char *path, CamelException *ex)
+camel_provider_load(const char *path, CamelException *ex)
{
GModule *module;
- CamelProvider *(*camel_provider_module_init) ();
+ CamelProvider *(*camel_provider_module_init) (void);
if (!g_module_supported ()) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
@@ -160,7 +192,173 @@ camel_provider_load (CamelSession *session, const char *path, CamelException *ex
return;
}
- camel_provider_module_init (session);
+ camel_provider_module_init ();
+}
+
+/**
+ * camel_provider_register:
+ * @provider: provider object
+ *
+ * Registers a provider.
+ **/
+void
+camel_provider_register(CamelProvider *provider)
+{
+ int i;
+ CamelProviderConfEntry *conf;
+ GList *l;
+
+ g_return_if_fail (provider != NULL);
+
+ LOCK();
+
+ if (g_hash_table_lookup(provider_table, provider->protocol) != NULL) {
+ g_warning("Trying to re-register camel provider for protocol '%s'", provider->protocol);
+ UNLOCK();
+ 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)
+
+ provider->name = P_(provider->name);
+ provider->description = P_(provider->description);
+ conf = provider->extra_conf;
+ if (conf) {
+ for (i=0;conf[i].type != CAMEL_PROVIDER_CONF_END;i++) {
+ if (conf[i].text)
+ conf[i].text = P_(conf[i].text);
+ }
+ }
+
+ l = provider->authtypes;
+ while (l) {
+ CamelServiceAuthType *auth = l->data;
+
+ auth->name = P_(auth->name);
+ auth->description = P_(auth->description);
+ l = l->next;
+ }
+
+ g_hash_table_insert(provider_table, provider->protocol, provider);
+
+ UNLOCK();
+}
+
+static gint
+provider_compare (gconstpointer a, gconstpointer b)
+{
+ const CamelProvider *cpa = (const CamelProvider *)a;
+ const CamelProvider *cpb = (const CamelProvider *)b;
+
+ return strcmp (cpa->name, cpb->name);
+}
+
+static void
+add_to_list (gpointer key, gpointer value, gpointer user_data)
+{
+ GList **list = user_data;
+
+ *list = g_list_prepend(*list, value);
+}
+
+/**
+ * camel_session_list_providers:
+ * @session: the session
+ * @load: whether or not to load in providers that are not already loaded
+ *
+ * This returns a list of available providers in this session. If @load
+ * is %TRUE, it will first load in all available providers that haven't
+ * yet been loaded.
+ *
+ * Return value: a GList of providers, which the caller must free.
+ **/
+GList *
+camel_provider_list(gboolean load)
+{
+ GList *list;
+
+ LOCK();
+
+ if (load) {
+ GList *w;
+
+ g_hash_table_foreach(module_table, add_to_list, &list);
+ for (w = list;w;w = w->next) {
+ CamelProviderModule *m = w->data;
+
+ if (!m->loaded) {
+ camel_provider_load(m->path, NULL);
+ m->loaded = 1;
+ }
+ }
+ g_list_free(list);
+ list = NULL;
+ }
+
+ g_hash_table_foreach(provider_table, add_to_list, &list);
+
+ UNLOCK();
+
+ list = g_list_sort(list, provider_compare);
+
+ return list;
+}
+
+/**
+ * camel_provider_get:
+ * @url_string: the URL for the service whose provider you want
+ * @ex: a CamelException
+ *
+ * This returns the CamelProvider that would be used to handle
+ * @url_string, loading it in from disk if necessary.
+ *
+ * Return value: the provider, or %NULL, in which case @ex will be set.
+ **/
+CamelProvider *
+camel_provider_get(const char *url_string, CamelException *ex)
+{
+ CamelProvider *provider = NULL;
+ char *protocol;
+ size_t len;
+
+ g_return_val_if_fail(url_string != NULL, NULL);
+
+ len = strcspn(url_string, ":");
+ protocol = g_alloca(len+1);
+ memcpy(protocol, url_string, len);
+ protocol[len] = 0;
+
+ LOCK();
+
+ provider = g_hash_table_lookup(provider_table, protocol);
+ if (!provider) {
+ CamelProviderModule *m;
+
+ m = g_hash_table_lookup(module_table, protocol);
+ if (m && !m->loaded) {
+ m->loaded = 1;
+ camel_provider_load(m->path, ex);
+ if (camel_exception_is_set (ex))
+ goto fail;
+ }
+ provider = g_hash_table_lookup(provider_table, protocol);
+ }
+
+ if (provider == NULL)
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
+ _("No provider available for protocol `%s'"),
+ protocol);
+fail:
+ UNLOCK();
+
+ return provider;
}