Make this take a path to a directory that Camel can use for its own
authorDan Winship <danw@src.gnome.org>
Thu, 7 Sep 2000 19:59:53 +0000 (19:59 +0000)
committerDan Winship <danw@src.gnome.org>
Thu, 7 Sep 2000 19:59:53 +0000 (19:59 +0000)
* camel-session.c (camel_session_new): Make this take a path to a
directory that Camel can use for its own nefarious purposes.
(camel_session_get_storage_path): New function to return a path
that a service can use for its own nefarious sub-purposes.

* camel-service.c (camel_service_get_path): New method (and
useful default implementation) to get a (relative) pathname
corresponding to the service.

camel/ChangeLog
camel/camel-service.c
camel/camel-service.h
camel/camel-session.c
camel/camel-session.h

index 41bb904..e4b0ea1 100644 (file)
@@ -1,3 +1,14 @@
+2000-09-07  Dan Winship  <danw@helixcode.com>
+
+       * camel-session.c (camel_session_new): Make this take a path to a
+       directory that Camel can use for its own nefarious purposes.
+       (camel_session_get_storage_path): New function to return a path
+       that a service can use for its own nefarious sub-purposes.
+
+       * camel-service.c (camel_service_get_path): New method (and
+       useful default implementation) to get a (relative) pathname
+       corresponding to the service.
+
 2000-09-06  Dan Winship  <danw@helixcode.com>
 
        * providers/pop3/camel-pop3-store.c (connect_to_server): Make KPOP
index 63af88f..a2d5e8a 100644 (file)
@@ -42,6 +42,7 @@ static gboolean service_disconnect(CamelService *service, CamelException *ex);
 static GList *  query_auth_types_func (CamelService *service, CamelException *ex);
 static void     free_auth_types (CamelService *service, GList *authtypes);
 static char *   get_name (CamelService *service, gboolean brief);
+static char *   get_path (CamelService *service);
 static gboolean check_url (CamelService *service, CamelException *ex);
 
 
@@ -58,6 +59,7 @@ camel_service_class_init (CamelServiceClass *camel_service_class)
        camel_service_class->query_auth_types_generic = query_auth_types_func;
        camel_service_class->free_auth_types = free_auth_types;
        camel_service_class->get_name = get_name;
+       camel_service_class->get_path = get_path;
 }
 
 static void
@@ -342,6 +344,67 @@ camel_service_get_name (CamelService *service, gboolean brief)
 }
 
 
+static char *
+get_path (CamelService *service)
+{
+       GString *gpath;
+       char *path;
+       CamelURL *url = service->url;
+       int flags = service->url_flags;
+
+       /* A sort of ad-hoc default implementation that works for our
+        * current set of services.
+        */
+
+       gpath = g_string_new (service->provider->protocol);
+       if (flags & CAMEL_SERVICE_URL_ALLOW_USER) {
+               if (flags & CAMEL_SERVICE_URL_ALLOW_HOST) {
+                       g_string_sprintfa (gpath, "/%s@%s",
+                                          url->user ? url->user : "",
+                                          url->host ? url->host : "");
+               } else {
+                       g_string_sprintfa (gpath, "/%s%s",
+                                          url->user ? url->user : "",
+                                          flags & CAMEL_SERVICE_URL_NEED_USER ? "" : "@");
+               }
+       } else if (flags & CAMEL_SERVICE_URL_ALLOW_HOST) {
+               g_string_sprintfa (gpath, "/%s%s",
+                                  flags & CAMEL_SERVICE_URL_NEED_HOST ? "" : "@",
+                                  url->host ? url->host : "");
+       }
+       if (flags & CAMEL_SERVICE_URL_NEED_PATH) {
+               g_string_sprintfa (gpath, "%s%s",
+                                  *url->path == '/' ? "" : "/",
+                                  url->path);
+       }
+
+       path = gpath->str;
+       g_string_free (gpath, FALSE);
+       return path;
+}              
+
+/**
+ * camel_service_get_path:
+ * @service: the service
+ *
+ * This gets a valid UNIX relative path describing the 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.
+ *
+ * Return value: the path, which the caller must free.
+ **/
+char *
+camel_service_get_path (CamelService *service)
+{
+       g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL);
+       g_return_val_if_fail (service->url, NULL);
+
+       return CSERV_CLASS (service)->get_path (service);
+}
+
+
 /**
  * camel_service_get_session:
  * @service: a service
index f229c5e..aa52e31 100644 (file)
@@ -75,6 +75,7 @@ typedef struct {
 
        char *    (*get_name)          (CamelService *service,
                                        gboolean brief);
+       char *    (*get_path)          (CamelService *service);
 
 } CamelServiceClass;
 
@@ -121,6 +122,7 @@ gboolean            camel_service_disconnect         (CamelService *service,
 char *              camel_service_get_url            (CamelService *service);
 char *              camel_service_get_name           (CamelService *service,
                                                      gboolean brief);
+char *              camel_service_get_path           (CamelService *service);
 CamelSession *      camel_service_get_session        (CamelService *service);
 CamelProvider *     camel_service_get_provider       (CamelService *service);
 GList *             camel_service_query_auth_types   (CamelService *service,
index 9992a48..81781fe 100644 (file)
  */
 
 #include <config.h>
+#include <errno.h>
 #include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
 #include "camel-session.h"
 #include "camel-store.h"
 #include "camel-transport.h"
@@ -89,14 +93,29 @@ camel_session_get_type (void)
        return camel_session_type;
 }
 
-
+/**
+ * camel_session_new:
+ * @storage_path: Path to a directory Camel can use for persistent storage.
+ * (This directory must already exist.)
+ * @authenticator: A callback for discussing authentication information
+ * @registrar: A callback for registering timeout callbacks
+ * @remove: A callback for removing timeout callbacks
+ *
+ * This creates a new CamelSession object, which represents global state
+ * for the Camel library, and contains callbacks that can be used to
+ * interact with the main application.
+ *
+ * Return value: the new CamelSession
+ **/
 CamelSession *
-camel_session_new (CamelAuthCallback authenticator,
+camel_session_new (const char *storage_path,
+                  CamelAuthCallback authenticator,
                   CamelTimeoutRegisterCallback registrar,
                   CamelTimeoutRemoveCallback remover)
 {
        CamelSession *session = CAMEL_SESSION (camel_object_new (CAMEL_SESSION_TYPE));
 
+       session->storage_path = g_strdup (storage_path);
        session->authenticator = authenticator;
        session->registrar = registrar;
        session->remover = remover;
@@ -196,12 +215,31 @@ service_cache_remove (CamelService *service, gpointer event_data, gpointer user_
        g_hash_table_remove (provider->service_cache, service->url);
 }
 
+/**
+ * camel_session_get_service:
+ * @session: the CamelSession
+ * @url_string: a Camel URL describing the service to get
+ * @type: the provider type (%CAMEL_PROVIDER_STORE or
+ * %CAMEL_PROVIDER_TRANSPORT) to get, since some URLs may be able
+ * to specify either type.
+ * @ex: a CamelException
+ *
+ * This resolves a CamelURL into a CamelService, including loading the
+ * provider library for that service if it has not already been loaded.
+ *
+ * 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.
+ *
+ * Return value: the requested CamelService, or %NULL
+ **/
 CamelService *
 camel_session_get_service (CamelSession *session, const char *url_string,
                           CamelProviderType type, CamelException *ex)
 {
        CamelURL *url;
-       const CamelProvider *provider;
+       CamelProvider *provider;
        CamelService *service;
 
        url = camel_url_new (url_string, ex);
@@ -253,9 +291,24 @@ camel_session_get_service (CamelSession *session, const char *url_string,
        return service;
 }
 
+/**
+ * camel_session_get_service_connected:
+ * @session: the CamelSession
+ * @url_string: a Camel URL describing the service to get
+ * @type: the provider type
+ * @ex: a CamelException
+ *
+ * This works like camel_session_get_service(), but also ensures that
+ * the returned service will have been successfully connected (via
+ * camel_service_connect().)
+ *
+ * Return value: the requested CamelService, or %NULL
+ **/
 CamelService *
-camel_session_get_service_connected (CamelSession *session, const char *url_string,
-                                    CamelProviderType type, CamelException *ex)
+camel_session_get_service_connected (CamelSession *session,
+                                    const char *url_string,
+                                    CamelProviderType type,
+                                    CamelException *ex)
 {
        CamelService *svc;
 
@@ -274,6 +327,57 @@ camel_session_get_service_connected (CamelSession *session, const char *url_stri
 }
 
 /**
+ * camel_session_get_storage_path:
+ * @session: session object
+ * @service: a CamelService
+ * @ex: a CamelException
+ *
+ * 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.
+ *
+ * Return value: the path (which the caller must free), or %NULL if
+ * an error occurs.
+ **/
+char *
+camel_session_get_storage_path (CamelSession *session, CamelService *service,
+                               CamelException *ex)
+{
+       char *path, *p;
+
+       path = g_strdup_printf ("%s/%s", session->storage_path,
+                               camel_service_get_path (service));
+
+       if (access (path, F_OK) == 0)
+               return path;
+
+       p = path + strlen (session->storage_path);
+       do {
+               p = strchr (p + 1, '/');
+               if (p)
+                       *p = '\0';
+               if (access (path, F_OK) == -1) {
+                       if (mkdir (path, S_IRWXU) == -1) {
+                               camel_exception_setv (ex,
+                                                     CAMEL_EXCEPTION_SYSTEM,
+                                                     "Could not create "
+                                                     "directory %s:\n%s",
+                                                     path,
+                                                     g_strerror (errno));
+                               g_free (path);
+                               return NULL;
+                       }
+               }
+               if (p)
+                       *p = '/';
+       } while (p);
+
+       return path;
+}
+
+/**
  * camel_session_query_authenticator: query the session authenticator
  * @session: session object
  * @mode: %CAMEL_AUTHENTICATOR_ASK or %CAMEL_AUTHENTICATOR_TELL
@@ -333,7 +437,6 @@ camel_session_query_authenticator (CamelSession *session,
  * camel_session_remove_timeout on success, and 0 on failure to 
  * register the timeout.
  **/
-
 guint
 camel_session_register_timeout (CamelSession *session,
                                guint32 interval,
@@ -357,9 +460,8 @@ camel_session_register_timeout (CamelSession *session,
  *
  * Returns TRUE on success and FALSE on failure.
  **/
-
-gboolean camel_session_remove_timeout (CamelSession *session,
-                                      guint handle)
+gboolean
+camel_session_remove_timeout (CamelSession *session, guint handle)
 {
        return session->remover (handle);
 }
index 7cb2306..fed21be 100644 (file)
@@ -61,6 +61,7 @@ struct _CamelSession
 {
        CamelObject parent_object;
 
+       char *storage_path;
        CamelAuthCallback authenticator;
        CamelTimeoutRegisterCallback registrar;
        CamelTimeoutRemoveCallback remover;
@@ -80,12 +81,11 @@ typedef struct {
 CamelType camel_session_get_type (void);
 
 
-CamelSession *  camel_session_new                     (CamelAuthCallback
-                                                      authenticator,
-                                                      CamelTimeoutRegisterCallback
-                                                      registrar,
-                                                      CamelTimeoutRemoveCallback
-                                                      remover);
+CamelSession *  camel_session_new (const char *storage_path,
+                                  CamelAuthCallback authenticator,
+                                  CamelTimeoutRegisterCallback registrar,
+                                  CamelTimeoutRemoveCallback remover);
+
 void            camel_session_register_provider       (CamelSession *session,
                                                       CamelProvider *provider);
 GList *         camel_session_list_providers          (CamelSession *session,
@@ -105,6 +105,9 @@ CamelService *  camel_session_get_service_connected   (CamelSession *session,
 #define camel_session_get_transport(session, url_string, ex) \
        ((CamelTransport *) camel_session_get_service_connected (session, url_string, CAMEL_PROVIDER_TRANSPORT, ex))
 
+char *          camel_session_get_storage_path (CamelSession *session,
+                                               CamelService *service,
+                                               CamelException *ex);
 
 char *          camel_session_query_authenticator (CamelSession *session,
                                                   CamelAuthCallbackMode mode,