From 1fb4f1bfee3badccac9419a6115aefa34ab8f6b1 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 7 Sep 2000 19:59:53 +0000 Subject: Make this take a path to a directory that Camel can use for its own * 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. svn path=/trunk/; revision=5239 --- camel/ChangeLog | 11 +++++ camel/camel-service.c | 63 ++++++++++++++++++++++++++ camel/camel-service.h | 2 + camel/camel-session.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++---- camel/camel-session.h | 15 ++++--- 5 files changed, 196 insertions(+), 15 deletions(-) (limited to 'camel') diff --git a/camel/ChangeLog b/camel/ChangeLog index 41bb90427e..e4b0ea11ee 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,14 @@ +2000-09-07 Dan Winship + + * 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 * providers/pop3/camel-pop3-store.c (connect_to_server): Make KPOP diff --git a/camel/camel-service.c b/camel/camel-service.c index 63af88f4cb..a2d5e8af3a 100644 --- a/camel/camel-service.c +++ b/camel/camel-service.c @@ -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 diff --git a/camel/camel-service.h b/camel/camel-service.h index f229c5e559..aa52e31755 100644 --- a/camel/camel-service.h +++ b/camel/camel-service.h @@ -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, diff --git a/camel/camel-session.c b/camel/camel-session.c index 9992a48aaf..81781fe85a 100644 --- a/camel/camel-session.c +++ b/camel/camel-session.c @@ -27,7 +27,11 @@ */ #include +#include #include +#include +#include +#include #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; @@ -273,6 +326,57 @@ camel_session_get_service_connected (CamelSession *session, const char *url_stri return svc; } +/** + * 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 @@ -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); } diff --git a/camel/camel-session.h b/camel/camel-session.h index 7cb2306e4c..fed21be6f1 100644 --- a/camel/camel-session.h +++ b/camel/camel-session.h @@ -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, -- cgit v1.2.3