Commit e0ac4d79 authored by Matthew Barnes's avatar Matthew Barnes

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.
parent d051278f
......@@ -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;
......
......@@ -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);
}
/**
......
......@@ -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)
......
......@@ -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;
......
......@@ -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;
}
......
This diff is collapsed.
......@@ -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);
......
This diff is collapsed.
......@@ -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,
......
......@@ -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)
......@@ -258,76 +270,6 @@ store_constructed (GObject *object)
store->folders = NULL;
}
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,
......@@ -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;
......@@ -1358,11 +1347,18 @@ camel_store_class_init (CamelStoreClass *class)
G_TYPE_POINTER);
}
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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);