[evolution-mapi] Adapt to Camel API changes.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Adapt to Camel API changes.
- Date: Tue, 28 Sep 2010 16:28:18 +0000 (UTC)
commit 4c69558f4af8975a78ae12e45b7b41bd0fc6b2a6
Author: Matthew Barnes <mbarnes redhat com>
Date: Sat Sep 18 22:07:44 2010 -0400
Adapt to Camel API changes.
src/camel/camel-mapi-folder.c | 1049 ++++++------
src/camel/camel-mapi-folder.h | 4 +-
src/camel/camel-mapi-notifications.c | 5 +-
src/camel/camel-mapi-store.c | 2168 ++++++++++++------------
src/camel/camel-mapi-transport.c | 12 +-
src/camel/camel-mapi-utils.c | 30 +-
src/camel/camel-mapi-utils.h | 2 +-
src/libexchangemapi/exchange-mapi-connection.c | 3 +-
src/libexchangemapi/exchange-mapi-mail-utils.c | 6 +-
9 files changed, 1678 insertions(+), 1601 deletions(-)
---
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index 402959a..10803b4 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -69,7 +69,13 @@ typedef struct {
/*For collecting summary info from server*/
static void mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **changeinfo,
- GError **error, gboolean uid_flag);
+ GCancellable *cancellable, GError **error, gboolean uid_flag);
+
+static gboolean mapi_folder_synchronize_sync
+ (CamelFolder *folder,
+ gboolean expunge,
+ GCancellable *cancellable,
+ GError **error);
G_DEFINE_TYPE (CamelMapiFolder, camel_mapi_folder, CAMEL_TYPE_OFFLINE_FOLDER)
@@ -140,15 +146,6 @@ update_store_summary (CamelFolder *folder, GError **error)
}
static gboolean
-mapi_refresh_info (CamelFolder *folder, GError **error)
-{
- if (!mapi_refresh_folder (folder, error))
- return FALSE;
-
- return update_store_summary (folder, error);
-}
-
-static gboolean
fetch_items_summary_cb (FetchItemsCallbackData *item_data, gpointer data)
{
fetch_items_data *fi_data = (fetch_items_data *)data;
@@ -231,7 +228,7 @@ fetch_items_summary_cb (FetchItemsCallbackData *item_data, gpointer data)
/*Write summary to db in batches of SUMMARY_FETCH_BATCH_COUNT items.*/
if ((item_data->index % SUMMARY_FETCH_BATCH_COUNT == 0) ||
item_data->index == item_data->total-1) {
- mapi_update_cache (fi_data->folder, *slist, &fi_data->changes, NULL, false);
+ mapi_update_cache (fi_data->folder, *slist, &fi_data->changes, NULL, NULL, false);
g_slist_foreach (*slist, (GFunc)mail_item_free, NULL);
g_slist_free (*slist);
*slist = NULL;
@@ -322,7 +319,7 @@ mapi_set_message_references (CamelMapiMessageInfo *mapi_mi, const gchar *referen
static void
mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **changeinfo,
- GError **error, gboolean uid_flag)
+ GCancellable *cancellable, GError **error, gboolean uid_flag)
{
CamelMapiMessageInfo *mi = NULL;
CamelMessageInfo *pmi = NULL;
@@ -352,8 +349,9 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
return;
}
- camel_operation_start (
- NULL, _("Updating local summary cache for new messages in %s"),
+ camel_operation_push_message (
+ cancellable,
+ _("Updating local summary cache for new messages in %s"),
camel_folder_get_name (folder));
for (; item_list != NULL; item_list = g_slist_next (item_list) ) {
@@ -371,7 +369,7 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
item = temp_item;
}
- camel_operation_progress (NULL, (100*i)/total_items);
+ camel_operation_progress (cancellable, (100*i)/total_items);
/************************ First populate summary *************************/
mi = NULL;
@@ -515,7 +513,7 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
g_free (msg_uid);
i++;
}
- camel_operation_end (NULL);
+ camel_operation_pop_message (cancellable);
g_string_free (str, TRUE);
}
@@ -582,13 +580,13 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
mapi_folder = CAMEL_MAPI_FOLDER (m->folder);
mapi_store = CAMEL_MAPI_STORE (parent_store);
- if (((CamelOfflineStore *) mapi_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL ||
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)) ||
((CamelService *)mapi_store)->status == CAMEL_SERVICE_DISCONNECTED) {
return;
}
- camel_operation_start (
+ camel_operation_push_message (
NULL, _("Retrieving message IDs from server for %s"),
camel_folder_get_name (m->folder));
@@ -605,7 +603,7 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
deleted_items_sync_cb, server_messages,
options | MAPI_OPTIONS_DONT_OPEN_MESSAGE, NULL);
- camel_operation_end (NULL);
+ camel_operation_pop_message (NULL);
camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -618,7 +616,7 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
changes = camel_folder_change_info_new ();
count = camel_folder_summary_count (m->folder->summary);
- camel_operation_start (
+ camel_operation_push_message (
NULL, _("Removing deleted messages from cache in %s"),
camel_folder_get_name (m->folder));
@@ -672,7 +670,7 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
}
}
- camel_operation_end (NULL);
+ camel_operation_pop_message (NULL);
if (camel_folder_change_info_changed (changes)) {
if (flags_changed)
@@ -704,7 +702,8 @@ mapi_sync_deleted_free (CamelSession *session, CamelSessionThreadMsg *msg)
mapi_summary->sync_time_stamp = NULL;
camel_service_unlock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- if (!mapi_refresh_folder (m->folder, &local_error)) {
+ /* FIXME Need to pass a GCancellable here. */
+ if (!mapi_refresh_folder (m->folder, NULL, &local_error)) {
g_warning ("%s: %s", G_STRFUNC, local_error->message);
g_error_free (local_error);
}
@@ -720,200 +719,6 @@ static CamelSessionThreadOps deleted_items_sync_ops = {
};
static gboolean
-mapi_sync (CamelFolder *folder, gboolean expunge, GError **error)
-{
- CamelMapiStore *mapi_store;
- CamelMapiFolder *mapi_folder;
- CamelMessageInfo *info = NULL;
- CamelMapiMessageInfo *mapi_info = NULL;
- CamelStore *parent_store;
-
- GSList *read_items = NULL, *unread_items = NULL, *to_free = NULL, *junk_items = NULL, *deleted_items = NULL, *l;
- flags_diff_t diff, unset_flags;
- const gchar *folder_id;
- const gchar *full_name;
- mapi_id_t fid, deleted_items_fid;
- gint count, i;
- guint32 options =0;
- gboolean is_junk_folder;
- gboolean success;
-
- full_name = camel_folder_get_full_name (folder);
- parent_store = camel_folder_get_parent_store (folder);
-
- mapi_folder = CAMEL_MAPI_FOLDER (folder);
- mapi_store = CAMEL_MAPI_STORE (parent_store);
-
- if (((CamelOfflineStore *) mapi_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL ||
- ((CamelService *)mapi_store)->status == CAMEL_SERVICE_DISCONNECTED) {
- return update_store_summary (folder, error);
- }
-
- if (((CamelMapiFolder *)folder)->type & CAMEL_MAPI_FOLDER_PUBLIC)
- options |= MAPI_OPTIONS_USE_PFSTORE;
-
- folder_id = camel_mapi_store_folder_id_lookup (mapi_store, full_name);
- exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
-
- camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- if (!camel_mapi_store_connected (mapi_store, NULL)) {
- camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- return TRUE;
- }
- camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
- is_junk_folder = (mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_JUNK;
-
- camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-
- count = camel_folder_summary_count (folder->summary);
- for (i=0; i < count; i++) {
- info = camel_folder_summary_index (folder->summary, i);
- mapi_info = (CamelMapiMessageInfo *) info;
-
- if (mapi_info && (mapi_info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- const gchar *uid;
- mapi_id_t *mid = g_new0 (mapi_id_t, 1); /* FIXME : */
- mapi_id_t temp_fid;
- guint32 flags;
- gboolean used = FALSE;
-
- uid = camel_message_info_uid (info);
- flags= camel_message_info_flags (info);
-
- /* Why are we getting so much noise here :-/ */
- if (!exchange_mapi_util_mapi_ids_from_uid (uid, &temp_fid, mid)) {
- camel_message_info_free (info);
- g_free (mid);
- continue;
- }
-
- mapi_utils_do_flags_diff (&diff, mapi_info->server_flags, mapi_info->info.flags);
- mapi_utils_do_flags_diff (&unset_flags, flags, mapi_info->server_flags);
-
- diff.changed &= folder->permanent_flags;
- if (!diff.changed) {
- camel_message_info_free (info);
- g_free (mid);
- continue;
- }
- if (diff.bits & CAMEL_MESSAGE_DELETED) {
- deleted_items = g_slist_prepend (deleted_items, mid);
- used = TRUE;
- } else if (!is_junk_folder && (diff.bits & CAMEL_MESSAGE_JUNK) != 0) {
- junk_items = g_slist_prepend (junk_items, mid);
- used = TRUE;
- }
-
- if (diff.bits & CAMEL_MESSAGE_SEEN) {
- read_items = g_slist_prepend (read_items, mid);
- used = TRUE;
- } else if (unset_flags.bits & CAMEL_MESSAGE_SEEN) {
- unread_items = g_slist_prepend (unread_items, mid);
- used = TRUE;
- }
-
- if (used)
- to_free = g_slist_prepend (to_free, mid);
- else
- g_free (mid);
-
- mapi_info->server_flags = mapi_info->info.flags;
- }
-
- if (info)
- camel_message_info_free (info);
- }
-
- camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
- /*
- Sync up the READ changes before deleting the message.
- Note that if a message is marked as unread and then deleted,
- Evo doesnt not take care of it, as I find that scenario to be impractical.
- */
-
- if (read_items) {
- camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- exchange_mapi_connection_set_flags (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, read_items, 0, NULL);
- camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- }
-
- if (unread_items) {
- camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- exchange_mapi_connection_set_flags (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, unread_items, CLEAR_READ_FLAG, NULL);
- camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- }
-
- /* Remove messages from server*/
- if (deleted_items) {
- camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
- exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, deleted_items, NULL);
- } else {
- GError *err = NULL;
-
- exchange_mapi_util_mapi_id_from_string (camel_mapi_store_system_folder_fid (mapi_store, olFolderDeletedItems), &deleted_items_fid);
- exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), fid, options, deleted_items_fid, 0, deleted_items, &err);
-
- if (err) {
- g_warning ("%s: Failed to move deleted items: %s", G_STRFUNC, err->message);
- g_error_free (err);
- }
- }
-
- camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- }
-
- if (junk_items) {
- mapi_id_t junk_fid = 0;
- GError *err = NULL;
-
- camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- exchange_mapi_util_mapi_id_from_string (camel_mapi_store_system_folder_fid (mapi_store, olFolderJunk), &junk_fid);
- exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), fid, options, junk_fid, 0, junk_items, &err);
- camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
- /* in junk_items are only emails which are not deleted */
- deleted_items = g_slist_concat (deleted_items, g_slist_copy (junk_items));
-
- if (err) {
- g_warning ("%s: Failed to move junk items: %s", G_STRFUNC, err->message);
- g_error_free (err);
- }
- }
-
- /*Remove messages from local cache*/
- for (l = deleted_items; l; l = l->next) {
- gchar * deleted_msg_uid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X%016" G_GINT64_MODIFIER "X", fid, *(mapi_id_t *)l->data);
-
- camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_summary_remove_uid (folder->summary, deleted_msg_uid);
- camel_data_cache_remove(mapi_folder->cache, "cache", deleted_msg_uid, NULL);
- camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- }
-
- g_slist_free (read_items);
- g_slist_free (unread_items);
- g_slist_free (deleted_items);
- g_slist_free (junk_items);
-
- g_slist_foreach (to_free, (GFunc) g_free, NULL);
- g_slist_free (to_free);
-
- if (expunge) {
- /* TODO */
- }
-
- camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- success = update_store_summary (folder, error);
- camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
- return success;
-}
-
-static gboolean
mapi_camel_get_summary_list (ExchangeMapiConnection *conn, mapi_id_t fid, TALLOC_CTX *mem_ctx, struct SPropTagArray *props, gpointer data)
{
static const uint32_t summary_prop_list[] = {
@@ -942,14 +747,14 @@ mapi_camel_get_summary_list (ExchangeMapiConnection *conn, mapi_id_t fid, TALLOC
gboolean
camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const mapi_id_t fid, struct mapi_SRestriction *res,
- struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GError **mapi_error)
+ struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GCancellable *cancellable, GError **mapi_error)
{
gboolean status;
CamelMapiStore *mapi_store = (CamelMapiStore *) store;
/*TODO : Check for online state*/
- camel_operation_start (NULL, _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder));
+ camel_operation_push_message (cancellable, _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder));
camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -960,13 +765,13 @@ camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const m
camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- camel_operation_end (NULL);
+ camel_operation_pop_message (cancellable);
return status;
}
gboolean
-mapi_refresh_folder(CamelFolder *folder, GError **error)
+mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **error)
{
CamelMapiStore *mapi_store;
@@ -998,12 +803,12 @@ mapi_refresh_folder(CamelFolder *folder, GError **error)
is_proxy = parent_store->flags & CAMEL_STORE_PROXY;
session = CAMEL_SERVICE (parent_store)->session;
- if (((CamelOfflineStore *) mapi_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)))
goto end1;
/* Sync-up the (un)read changes before getting updates,
so that the getFolderList will reflect the most recent changes too */
- mapi_sync (folder, FALSE, NULL);
+ mapi_folder_synchronize_sync (folder, FALSE, cancellable, NULL);
//creating a copy
folder_id = camel_mapi_store_folder_id_lookup (mapi_store, full_name);
@@ -1083,7 +888,7 @@ mapi_refresh_folder(CamelFolder *folder, GError **error)
options |= MAPI_OPTIONS_USE_PFSTORE;
status = camel_mapi_folder_fetch_summary ((CamelStore *)mapi_store, folder, temp_folder_id, res, sort,
- fetch_data, options, &mapi_error);
+ fetch_data, options, cancellable, &mapi_error);
if (!status) {
if (mapi_error) {
@@ -1138,8 +943,334 @@ end1:
return success;
}
+static void
+mapi_folder_search_free (CamelFolder *folder, GPtrArray *uids)
+{
+ CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER(folder);
+
+ g_return_if_fail (mapi_folder->search);
+
+ CAMEL_MAPI_FOLDER_LOCK(mapi_folder, search_lock);
+
+ camel_folder_search_free_result (mapi_folder->search, uids);
+
+ CAMEL_MAPI_FOLDER_UNLOCK(mapi_folder, search_lock);
+
+}
+
+#if 0
+static CamelMessageInfo*
+mapi_get_message_info(CamelFolder *folder, const gchar *uid)
+{
+ CamelMessageInfo *msg_info = NULL;
+ CamelMessageInfoBase *mi = (CamelMessageInfoBase *)msg;
+ gint status = 0;
+ oc_message_headers_t headers;
+
+ if (folder->summary) {
+ msg_info = camel_folder_summary_uid(folder->summary, uid);
+ }
+ if (msg_info != NULL) {
+ mi = (CamelMessageInfoBase *)msg_info;
+ return (msg_info);
+ }
+ /* Go online and fetch message summary. */
+
+ msg_info = camel_message_info_new(folder->summary);
+ mi = (CamelMessageInfoBase *)msg_info;
+
+ if (headers.subject) mi->subject = (gchar *)camel_pstring_strdup(headers.subject);
+ if (headers.from) mi->from = (gchar *)camel_pstring_strdup(headers.from);
+ if (headers.to) mi->to = (gchar *)camel_pstring_strdup(headers.to);
+ if (headers.cc) mi->cc = (gchar *)camel_pstring_strdup(headers.cc);
+ mi->flags = headers.flags;
+
+ mi->user_flags = NULL;
+ mi->user_tags = NULL;
+ mi->date_received = 0;
+ mi->date_sent = headers.send;
+ mi->content = NULL;
+ mi->summary = folder->summary;
+ if (uid) mi->uid = g_strdup(uid);
+ oc_message_headers_release(&headers);
+ return (msg);
+}
+#endif
+
+static void
+mapi_folder_rename (CamelFolder *folder, const gchar *new)
+{
+ ((CamelFolderClass *)camel_mapi_folder_parent_class)->rename(folder, new);
+}
+
+static gint
+mapi_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
+{
+ g_return_val_if_fail (uid1 != NULL, 0);
+ g_return_val_if_fail (uid2 != NULL, 0);
+
+ return strcmp (uid1, uid2);
+}
+
+static gboolean
+mapi_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set)
+{
+ CamelMessageInfo *info;
+ gint res;
+
+ g_return_val_if_fail (folder->summary != NULL, FALSE);
+
+ info = camel_folder_summary_uid (folder->summary, uid);
+ if (info == NULL)
+ return FALSE;
+
+ res = camel_message_info_set_flags (info, flags, set);
+
+ camel_message_info_free (info);
+ return res;
+}
+
+static void
+mapi_folder_dispose (GObject *object)
+{
+ CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER (object);
+
+ if (mapi_folder->cache != NULL) {
+ g_object_unref (mapi_folder->cache);
+ mapi_folder->cache = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (camel_mapi_folder_parent_class)->dispose (object);
+}
+
+static void
+mapi_folder_constructed (GObject *object)
+{
+ CamelFolder *folder;
+ CamelStore *parent_store;
+ CamelURL *url;
+ const gchar *full_name;
+ gchar *description;
+
+ folder = CAMEL_FOLDER (object);
+ full_name = camel_folder_get_full_name (folder);
+ parent_store = camel_folder_get_parent_store (folder);
+ url = CAMEL_SERVICE (parent_store)->url;
+
+ description = g_strdup_printf (
+ "%s %s:%s", url->user, url->host, full_name);
+ camel_folder_set_description (folder, description);
+ g_free (description);
+}
+
+static gboolean
+mapi_folder_append_message_sync (CamelFolder *folder,
+ CamelMimeMessage *message,
+ CamelMessageInfo *info,
+ gchar **appended_uid,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMapiStore *mapi_store;
+ CamelOfflineStore *offline;
+ CamelAddress *from = NULL;
+ CamelStoreInfo *si;
+ CamelStore *parent_store;
+ MailItem *item = NULL;
+ mapi_id_t fid = 0, mid = 0;
+ const gchar *folder_id;
+ const gchar *full_name;
+ guint32 folder_flags = 0;
+ GError *mapi_error = NULL;
+
+ full_name = camel_folder_get_full_name (folder);
+ parent_store = camel_folder_get_parent_store (folder);
+
+ mapi_store = CAMEL_MAPI_STORE (parent_store);
+ offline = CAMEL_OFFLINE_STORE (parent_store);
+
+ /*Reject outbox / sent & trash*/
+ si = camel_store_summary_path ((CamelStoreSummary *)mapi_store->summary, full_name);
+ if (si) {
+ folder_flags = si->flags;
+ camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
+ }
+
+ if (((folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) ||
+ ((folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_OUTBOX)) {
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Cannot append message to folder '%s'"),
+ full_name);
+ return FALSE;
+ }
+
+ if (!camel_offline_store_get_online (offline)) {
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Offline."));
+ return FALSE;
+ }
+
+ folder_id = camel_mapi_store_folder_id_lookup (mapi_store, full_name);
+
+ exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
+
+ /* Convert MIME to Item */
+ from = (CamelAddress *) camel_mime_message_get_from (message);
+
+ item = camel_mapi_utils_mime_to_item (message, from, cancellable, error);
+ if (item == NULL)
+ return FALSE;
+
+ mid = exchange_mapi_connection_create_item (camel_mapi_store_get_exchange_connection (mapi_store), -1, fid,
+ camel_mapi_utils_create_item_build_props, item,
+ item->recipients, item->attachments,
+ item->generic_streams, 0, &mapi_error);
+
+ if (!mid) {
+ if (mapi_error) {
+ g_set_error_literal (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, mapi_error->message);
+ g_error_free (mapi_error);
+ } else {
+ g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Offline."));
+ }
+
+ return FALSE;
+ }
+
+ if (appended_uid)
+ *appended_uid = exchange_mapi_util_mapi_ids_to_uid(fid, mid);
+
+ return TRUE;
+}
+
+static gboolean
+mapi_folder_expunge_sync (CamelFolder *folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMapiStore *mapi_store;
+ CamelMapiFolder *mapi_folder;
+ CamelMapiMessageInfo *minfo;
+ CamelMessageInfo *info;
+ CamelFolderChangeInfo *changes;
+ CamelStore *parent_store;
+
+ mapi_id_t fid;
+
+ gint i, count;
+ gboolean delete = FALSE, status = FALSE;
+ gchar *folder_id;
+ GSList *deleted_items, *deleted_head;
+ GSList *deleted_items_uid, *deleted_items_uid_head;
+ const gchar *full_name;
+
+ deleted_items = deleted_head = NULL;
+ deleted_items_uid = deleted_items_uid_head = NULL;
+
+ full_name = camel_folder_get_full_name (folder);
+ parent_store = camel_folder_get_parent_store (folder);
+
+ mapi_folder = CAMEL_MAPI_FOLDER (folder);
+ mapi_store = CAMEL_MAPI_STORE (parent_store);
+
+ folder_id = g_strdup (camel_mapi_store_folder_id_lookup (mapi_store, full_name));
+ exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
+
+ if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
+ GError *mapi_error = NULL;
+
+ camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ status = exchange_mapi_connection_empty_folder (camel_mapi_store_get_exchange_connection (mapi_store), fid, 0, &mapi_error);
+ camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ if (status) {
+ camel_folder_freeze (folder);
+ mapi_summary_clear (folder->summary, TRUE);
+ camel_folder_thaw (folder);
+ } else if (mapi_error) {
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Failed to empty Trash: %s"), mapi_error->message);
+ g_error_free (mapi_error);
+ } else {
+ g_set_error_literal (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Failed to empty Trash"));
+ }
+
+ return status;
+ }
+
+ changes = camel_folder_change_info_new ();
+ count = camel_folder_summary_count (folder->summary);
+
+ /*Collect UIDs of deleted messages.*/
+ for (i = 0; i < count; i++) {
+ info = camel_folder_summary_index (folder->summary, i);
+ minfo = (CamelMapiMessageInfo *) info;
+ if (minfo && (minfo->info.flags & CAMEL_MESSAGE_DELETED)) {
+ const gchar *uid = camel_message_info_uid (info);
+ mapi_id_t *mid = g_new0 (mapi_id_t, 1);
+
+ if (!exchange_mapi_util_mapi_ids_from_uid (uid, &fid, mid))
+ continue;
+
+ if (deleted_items)
+ deleted_items = g_slist_prepend (deleted_items, mid);
+ else {
+ g_slist_free (deleted_head);
+ deleted_head = NULL;
+ deleted_head = deleted_items = g_slist_prepend (deleted_items, mid);
+ }
+ deleted_items_uid = g_slist_prepend (deleted_items_uid, (gpointer) uid);
+ }
+ camel_message_info_free (info);
+ }
+
+ deleted_items_uid_head = deleted_items_uid;
+
+ if (deleted_items) {
+ camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ status = exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, 0, deleted_items, NULL);
+
+ camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ if (status) {
+ while (deleted_items_uid) {
+ const gchar *uid = (gchar *)deleted_items_uid->data;
+ camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ camel_folder_change_info_remove_uid (changes, uid);
+ camel_folder_summary_remove_uid (folder->summary, uid);
+ camel_data_cache_remove(mapi_folder->cache, "cache", uid, NULL);
+ camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ deleted_items_uid = g_slist_next (deleted_items_uid);
+ }
+ }
+ delete = TRUE;
+
+ g_slist_foreach (deleted_head, (GFunc)g_free, NULL);
+ g_slist_free (deleted_head);
+ g_slist_free (deleted_items_uid_head);
+ }
+
+ if (delete)
+ camel_folder_changed (folder, changes);
+
+ g_free (folder_id);
+ camel_folder_change_info_free (changes);
+
+ return TRUE;
+}
+
static CamelMimeMessage *
-mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
+mapi_folder_get_message_sync (CamelFolder *folder,
+ const gchar *uid,
+ GCancellable *cancellable,
+ GError **error )
{
CamelMimeMessage *msg = NULL;
CamelMapiFolder *mapi_folder;
@@ -1178,9 +1309,9 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
msg = camel_mime_message_new ();
camel_stream_reset (stream, NULL);
- camel_stream_write_to_stream (cache_stream, stream, NULL);
+ camel_stream_write_to_stream (cache_stream, stream, cancellable, NULL);
camel_stream_reset (stream, NULL);
- if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, stream, &local_error) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, cancellable, &local_error)) {
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
g_object_unref (msg);
g_object_unref (cache_stream);
@@ -1203,7 +1334,7 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
return msg;
}
- if (((CamelOfflineStore *) mapi_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store))) {
g_set_error (
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_UNAVAILABLE,
@@ -1271,8 +1402,8 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
/* add to cache */
camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
if ((cache_stream = camel_data_cache_add (mapi_folder->cache, "cache", uid, NULL))) {
- if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) msg, cache_stream, NULL) == -1
- || camel_stream_flush (cache_stream, NULL) == -1) {
+ if (camel_data_wrapper_write_to_stream_sync ((CamelDataWrapper *) msg, cache_stream, cancellable, NULL) == -1
+ || camel_stream_flush (cache_stream, cancellable, NULL) == -1) {
camel_data_cache_remove (mapi_folder->cache, "cache", uid, NULL);
} else {
CamelMimeMessage *msg2;
@@ -1283,7 +1414,7 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
they appear properly in the UI. */
msg2 = camel_mime_message_new ();
camel_stream_reset (cache_stream, NULL);
- if (camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg2), cache_stream, NULL) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync (CAMEL_DATA_WRAPPER (msg2), cache_stream, cancellable, NULL)) {
g_object_unref (msg2);
} else {
g_object_unref (msg);
@@ -1300,81 +1431,38 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, GError **error )
return msg;
}
-static void
-mapi_folder_search_free (CamelFolder *folder, GPtrArray *uids)
-{
- CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER(folder);
-
- g_return_if_fail (mapi_folder->search);
-
- CAMEL_MAPI_FOLDER_LOCK(mapi_folder, search_lock);
-
- camel_folder_search_free_result (mapi_folder->search, uids);
-
- CAMEL_MAPI_FOLDER_UNLOCK(mapi_folder, search_lock);
-
-}
-
-#if 0
-static CamelMessageInfo*
-mapi_get_message_info(CamelFolder *folder, const gchar *uid)
+static gboolean
+mapi_folder_refresh_info_sync (CamelFolder *folder,
+ GCancellable *cancellable,
+ GError **error)
{
- CamelMessageInfo *msg_info = NULL;
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *)msg;
- gint status = 0;
- oc_message_headers_t headers;
-
- if (folder->summary) {
- msg_info = camel_folder_summary_uid(folder->summary, uid);
- }
- if (msg_info != NULL) {
- mi = (CamelMessageInfoBase *)msg_info;
- return (msg_info);
- }
- /* Go online and fetch message summary. */
-
- msg_info = camel_message_info_new(folder->summary);
- mi = (CamelMessageInfoBase *)msg_info;
-
- if (headers.subject) mi->subject = (gchar *)camel_pstring_strdup(headers.subject);
- if (headers.from) mi->from = (gchar *)camel_pstring_strdup(headers.from);
- if (headers.to) mi->to = (gchar *)camel_pstring_strdup(headers.to);
- if (headers.cc) mi->cc = (gchar *)camel_pstring_strdup(headers.cc);
- mi->flags = headers.flags;
+ if (!mapi_refresh_folder (folder, cancellable, error))
+ return FALSE;
- mi->user_flags = NULL;
- mi->user_tags = NULL;
- mi->date_received = 0;
- mi->date_sent = headers.send;
- mi->content = NULL;
- mi->summary = folder->summary;
- if (uid) mi->uid = g_strdup(uid);
- oc_message_headers_release(&headers);
- return (msg);
+ return update_store_summary (folder, error);
}
-#endif
static gboolean
-mapi_expunge (CamelFolder *folder, GError **error)
+mapi_folder_synchronize_sync (CamelFolder *folder,
+ gboolean expunge,
+ GCancellable *cancellable,
+ GError **error)
{
CamelMapiStore *mapi_store;
CamelMapiFolder *mapi_folder;
- CamelMapiMessageInfo *minfo;
- CamelMessageInfo *info;
- CamelFolderChangeInfo *changes;
+ CamelMessageInfo *info = NULL;
+ CamelMapiMessageInfo *mapi_info = NULL;
CamelStore *parent_store;
- mapi_id_t fid;
-
- gint i, count;
- gboolean delete = FALSE, status = FALSE;
- gchar *folder_id;
- GSList *deleted_items, *deleted_head;
- GSList *deleted_items_uid, *deleted_items_uid_head;
+ GSList *read_items = NULL, *unread_items = NULL, *to_free = NULL, *junk_items = NULL, *deleted_items = NULL, *l;
+ flags_diff_t diff, unset_flags;
+ const gchar *folder_id;
const gchar *full_name;
-
- deleted_items = deleted_head = NULL;
- deleted_items_uid = deleted_items_uid_head = NULL;
+ mapi_id_t fid, deleted_items_fid;
+ gint count, i;
+ guint32 options =0;
+ gboolean is_junk_folder;
+ gboolean success;
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
@@ -1382,100 +1470,183 @@ mapi_expunge (CamelFolder *folder, GError **error)
mapi_folder = CAMEL_MAPI_FOLDER (folder);
mapi_store = CAMEL_MAPI_STORE (parent_store);
- folder_id = g_strdup (camel_mapi_store_folder_id_lookup (mapi_store, full_name));
- exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)) ||
+ ((CamelService *)mapi_store)->status == CAMEL_SERVICE_DISCONNECTED) {
+ return update_store_summary (folder, error);
+ }
- if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
- GError *mapi_error = NULL;
+ if (((CamelMapiFolder *)folder)->type & CAMEL_MAPI_FOLDER_PUBLIC)
+ options |= MAPI_OPTIONS_USE_PFSTORE;
- camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- status = exchange_mapi_connection_empty_folder (camel_mapi_store_get_exchange_connection (mapi_store), fid, 0, &mapi_error);
+ folder_id = camel_mapi_store_folder_id_lookup (mapi_store, full_name);
+ exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
+
+ camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ if (!camel_mapi_store_connected (mapi_store, NULL)) {
camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ return TRUE;
+ }
+ camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- if (status) {
- camel_folder_freeze (folder);
- mapi_summary_clear (folder->summary, TRUE);
- camel_folder_thaw (folder);
- } else if (mapi_error) {
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("Failed to empty Trash: %s"), mapi_error->message);
- g_error_free (mapi_error);
- } else {
- g_set_error_literal (
- error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("Failed to empty Trash"));
- }
+ is_junk_folder = (mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_JUNK;
- return status;
- }
+ camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
- changes = camel_folder_change_info_new ();
count = camel_folder_summary_count (folder->summary);
-
- /*Collect UIDs of deleted messages.*/
- for (i = 0; i < count; i++) {
+ for (i=0; i < count; i++) {
info = camel_folder_summary_index (folder->summary, i);
- minfo = (CamelMapiMessageInfo *) info;
- if (minfo && (minfo->info.flags & CAMEL_MESSAGE_DELETED)) {
- const gchar *uid = camel_message_info_uid (info);
- mapi_id_t *mid = g_new0 (mapi_id_t, 1);
+ mapi_info = (CamelMapiMessageInfo *) info;
- if (!exchange_mapi_util_mapi_ids_from_uid (uid, &fid, mid))
+ if (mapi_info && (mapi_info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+ const gchar *uid;
+ mapi_id_t *mid = g_new0 (mapi_id_t, 1); /* FIXME : */
+ mapi_id_t temp_fid;
+ guint32 flags;
+ gboolean used = FALSE;
+
+ uid = camel_message_info_uid (info);
+ flags= camel_message_info_flags (info);
+
+ /* Why are we getting so much noise here :-/ */
+ if (!exchange_mapi_util_mapi_ids_from_uid (uid, &temp_fid, mid)) {
+ camel_message_info_free (info);
+ g_free (mid);
continue;
+ }
- if (deleted_items)
+ mapi_utils_do_flags_diff (&diff, mapi_info->server_flags, mapi_info->info.flags);
+ mapi_utils_do_flags_diff (&unset_flags, flags, mapi_info->server_flags);
+
+ diff.changed &= folder->permanent_flags;
+ if (!diff.changed) {
+ camel_message_info_free (info);
+ g_free (mid);
+ continue;
+ }
+ if (diff.bits & CAMEL_MESSAGE_DELETED) {
deleted_items = g_slist_prepend (deleted_items, mid);
- else {
- g_slist_free (deleted_head);
- deleted_head = NULL;
- deleted_head = deleted_items = g_slist_prepend (deleted_items, mid);
+ used = TRUE;
+ } else if (!is_junk_folder && (diff.bits & CAMEL_MESSAGE_JUNK) != 0) {
+ junk_items = g_slist_prepend (junk_items, mid);
+ used = TRUE;
}
- deleted_items_uid = g_slist_prepend (deleted_items_uid, (gpointer) uid);
+
+ if (diff.bits & CAMEL_MESSAGE_SEEN) {
+ read_items = g_slist_prepend (read_items, mid);
+ used = TRUE;
+ } else if (unset_flags.bits & CAMEL_MESSAGE_SEEN) {
+ unread_items = g_slist_prepend (unread_items, mid);
+ used = TRUE;
+ }
+
+ if (used)
+ to_free = g_slist_prepend (to_free, mid);
+ else
+ g_free (mid);
+
+ mapi_info->server_flags = mapi_info->info.flags;
}
- camel_message_info_free (info);
+
+ if (info)
+ camel_message_info_free (info);
}
- deleted_items_uid_head = deleted_items_uid;
+ camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ /*
+ Sync up the READ changes before deleting the message.
+ Note that if a message is marked as unread and then deleted,
+ Evo doesnt not take care of it, as I find that scenario to be impractical.
+ */
+ if (read_items) {
+ camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ exchange_mapi_connection_set_flags (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, read_items, 0, NULL);
+ camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ }
+
+ if (unread_items) {
+ camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ exchange_mapi_connection_set_flags (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, unread_items, CLEAR_READ_FLAG, NULL);
+ camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ }
+
+ /* Remove messages from server*/
if (deleted_items) {
camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
+ exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, options, deleted_items, NULL);
+ } else {
+ GError *err = NULL;
- status = exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, 0, deleted_items, NULL);
+ exchange_mapi_util_mapi_id_from_string (camel_mapi_store_system_folder_fid (mapi_store, olFolderDeletedItems), &deleted_items_fid);
+ exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), fid, options, deleted_items_fid, 0, deleted_items, &err);
+
+ if (err) {
+ g_warning ("%s: Failed to move deleted items: %s", G_STRFUNC, err->message);
+ g_error_free (err);
+ }
+ }
camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ }
- if (status) {
- while (deleted_items_uid) {
- const gchar *uid = (gchar *)deleted_items_uid->data;
- camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_change_info_remove_uid (changes, uid);
- camel_folder_summary_remove_uid (folder->summary, uid);
- camel_data_cache_remove(mapi_folder->cache, "cache", uid, NULL);
- camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- deleted_items_uid = g_slist_next (deleted_items_uid);
- }
+ if (junk_items) {
+ mapi_id_t junk_fid = 0;
+ GError *err = NULL;
+
+ camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ exchange_mapi_util_mapi_id_from_string (camel_mapi_store_system_folder_fid (mapi_store, olFolderJunk), &junk_fid);
+ exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), fid, options, junk_fid, 0, junk_items, &err);
+ camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ /* in junk_items are only emails which are not deleted */
+ deleted_items = g_slist_concat (deleted_items, g_slist_copy (junk_items));
+
+ if (err) {
+ g_warning ("%s: Failed to move junk items: %s", G_STRFUNC, err->message);
+ g_error_free (err);
}
- delete = TRUE;
+ }
- g_slist_foreach (deleted_head, (GFunc)g_free, NULL);
- g_slist_free (deleted_head);
- g_slist_free (deleted_items_uid_head);
+ /*Remove messages from local cache*/
+ for (l = deleted_items; l; l = l->next) {
+ gchar * deleted_msg_uid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X%016" G_GINT64_MODIFIER "X", fid, *(mapi_id_t *)l->data);
+
+ camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ camel_folder_summary_remove_uid (folder->summary, deleted_msg_uid);
+ camel_data_cache_remove(mapi_folder->cache, "cache", deleted_msg_uid, NULL);
+ camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
}
- if (delete)
- camel_folder_changed (folder, changes);
+ g_slist_free (read_items);
+ g_slist_free (unread_items);
+ g_slist_free (deleted_items);
+ g_slist_free (junk_items);
- g_free (folder_id);
- camel_folder_change_info_free (changes);
+ g_slist_foreach (to_free, (GFunc) g_free, NULL);
+ g_slist_free (to_free);
- return TRUE;
+ if (expunge) {
+ /* TODO */
+ }
+
+ camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ success = update_store_summary (folder, error);
+ camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ return success;
}
static gboolean
-mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
- CamelFolder *destination, GPtrArray **transferred_uids,
- gboolean delete_originals, GError **error)
+mapi_folder_transfer_messages_to_sync (CamelFolder *source,
+ GPtrArray *uids,
+ CamelFolder *destination,
+ gboolean delete_originals,
+ GPtrArray **transferred_uids,
+ GCancellable *cancellable,
+ GError **error)
{
mapi_id_t src_fid, dest_fid;
guint32 src_fid_options, dest_fid_options;
@@ -1500,9 +1671,9 @@ mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
/* because cannot use MAPI to copy/move messages with public folders,
thus fallback to per-message copy/move */
folder_class = CAMEL_FOLDER_CLASS (camel_mapi_folder_parent_class);
- return folder_class->transfer_messages_to (
- source, uids, destination, transferred_uids,
- delete_originals, error);
+ return folder_class->transfer_messages_to_sync (
+ source, uids, destination, delete_originals,
+ transferred_uids, cancellable, error);
}
source_full_name = camel_folder_get_full_name (source);
@@ -1515,7 +1686,7 @@ mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
offline = CAMEL_OFFLINE_STORE (destination_parent_store);
/* check for offline operation */
- if (offline->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+ if (!camel_offline_store_get_online (offline))
return FALSE;
folder_id = camel_mapi_store_folder_id_lookup (mapi_store, source_full_name);
@@ -1575,152 +1746,6 @@ mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
}
static void
-mapi_folder_rename (CamelFolder *folder, const gchar *new)
-{
- ((CamelFolderClass *)camel_mapi_folder_parent_class)->rename(folder, new);
-}
-
-static gint
-mapi_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
-{
- g_return_val_if_fail (uid1 != NULL, 0);
- g_return_val_if_fail (uid2 != NULL, 0);
-
- return strcmp (uid1, uid2);
-}
-
-static gboolean
-mapi_append_message (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, gchar **appended_uid,
- GError **error)
-{
- CamelMapiStore *mapi_store;
- CamelOfflineStore *offline;
- CamelAddress *from = NULL;
- CamelStoreInfo *si;
- CamelStore *parent_store;
- MailItem *item = NULL;
- mapi_id_t fid = 0, mid = 0;
- const gchar *folder_id;
- const gchar *full_name;
- guint32 folder_flags = 0;
- GError *mapi_error = NULL;
-
- full_name = camel_folder_get_full_name (folder);
- parent_store = camel_folder_get_parent_store (folder);
-
- mapi_store = CAMEL_MAPI_STORE (parent_store);
- offline = CAMEL_OFFLINE_STORE (parent_store);
-
- /*Reject outbox / sent & trash*/
- si = camel_store_summary_path ((CamelStoreSummary *)mapi_store->summary, full_name);
- if (si) {
- folder_flags = si->flags;
- camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
- }
-
- if (((folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) ||
- ((folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_OUTBOX)) {
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("Cannot append message to folder '%s'"),
- full_name);
- return FALSE;
- }
-
- if (offline->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("Offline."));
- return FALSE;
- }
-
- folder_id = camel_mapi_store_folder_id_lookup (mapi_store, full_name);
-
- exchange_mapi_util_mapi_id_from_string (folder_id, &fid);
-
- /* Convert MIME to Item */
- from = (CamelAddress *) camel_mime_message_get_from (message);
-
- item = camel_mapi_utils_mime_to_item (message, from, error);
- if (item == NULL)
- return FALSE;
-
- mid = exchange_mapi_connection_create_item (camel_mapi_store_get_exchange_connection (mapi_store), -1, fid,
- camel_mapi_utils_create_item_build_props, item,
- item->recipients, item->attachments,
- item->generic_streams, 0, &mapi_error);
-
- if (!mid) {
- if (mapi_error) {
- g_set_error_literal (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, mapi_error->message);
- g_error_free (mapi_error);
- } else {
- g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Offline."));
- }
-
- return FALSE;
- }
-
- if (appended_uid)
- *appended_uid = exchange_mapi_util_mapi_ids_to_uid(fid, mid);
-
- return TRUE;
-}
-
-static gboolean
-mapi_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set)
-{
- CamelMessageInfo *info;
- gint res;
-
- g_return_val_if_fail (folder->summary != NULL, FALSE);
-
- info = camel_folder_summary_uid (folder->summary, uid);
- if (info == NULL)
- return FALSE;
-
- res = camel_message_info_set_flags (info, flags, set);
-
- camel_message_info_free (info);
- return res;
-}
-
-static void
-mapi_folder_dispose (GObject *object)
-{
- CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER (object);
-
- if (mapi_folder->cache != NULL) {
- g_object_unref (mapi_folder->cache);
- mapi_folder->cache = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (camel_mapi_folder_parent_class)->dispose (object);
-}
-
-static void
-mapi_folder_constructed (GObject *object)
-{
- CamelFolder *folder;
- CamelStore *parent_store;
- CamelURL *url;
- const gchar *full_name;
- gchar *description;
-
- folder = CAMEL_FOLDER (object);
- full_name = camel_folder_get_full_name (folder);
- parent_store = camel_folder_get_parent_store (folder);
- url = CAMEL_SERVICE (parent_store)->url;
-
- description = g_strdup_printf (
- "%s %s:%s", url->user, url->host, full_name);
- camel_folder_set_description (folder, description);
- g_free (description);
-}
-
-static void
camel_mapi_folder_class_init (CamelMapiFolderClass *class)
{
GObjectClass *object_class;
@@ -1733,18 +1758,18 @@ camel_mapi_folder_class_init (CamelMapiFolderClass *class)
object_class->constructed = mapi_folder_constructed;
folder_class = CAMEL_FOLDER_CLASS (class);
- folder_class->get_message = mapi_folder_get_message;
folder_class->rename = mapi_folder_rename;
folder_class->search_by_expression = mapi_folder_search_by_expression;
folder_class->cmp_uids = mapi_cmp_uids;
folder_class->search_by_uids = mapi_folder_search_by_uids;
folder_class->search_free = mapi_folder_search_free;
- folder_class->append_message = mapi_append_message;
- folder_class->refresh_info = mapi_refresh_info;
- folder_class->sync = mapi_sync;
folder_class->set_message_flags = mapi_set_message_flags;
- folder_class->expunge = mapi_expunge;
- folder_class->transfer_messages_to = mapi_transfer_messages_to;
+ folder_class->append_message_sync = mapi_folder_append_message_sync;
+ folder_class->expunge_sync = mapi_folder_expunge_sync;
+ folder_class->get_message_sync = mapi_folder_get_message_sync;
+ folder_class->refresh_info_sync = mapi_folder_refresh_info_sync;
+ folder_class->synchronize_sync = mapi_folder_synchronize_sync;
+ folder_class->transfer_messages_to_sync = mapi_folder_transfer_messages_to_sync;
}
static void
diff --git a/src/camel/camel-mapi-folder.h b/src/camel/camel-mapi-folder.h
index ab8f604..3216906 100644
--- a/src/camel/camel-mapi-folder.h
+++ b/src/camel/camel-mapi-folder.h
@@ -91,9 +91,9 @@ CamelFolder *
camel_mapi_folder_new(CamelStore *store, const gchar *folder_name, const gchar *folder_dir, guint32 flags, GError **error);
void mapi_update_summary ( CamelFolder *folder, GList *item_list,GError **error);
-gboolean mapi_refresh_folder(CamelFolder *folder, GError **error);
+gboolean mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **error);
gboolean camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const mapi_id_t fid, struct mapi_SRestriction *res,
- struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GError **mapi_error);
+ struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GCancellable *cancellable, GError **mapi_error);
G_END_DECLS
diff --git a/src/camel/camel-mapi-notifications.c b/src/camel/camel-mapi-notifications.c
index 21fc3dc..f12d6e4 100644
--- a/src/camel/camel-mapi-notifications.c
+++ b/src/camel/camel-mapi-notifications.c
@@ -95,7 +95,8 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
info_count--;
}
- folder = camel_store_get_folder ((CamelStore *)store, folder_name, 0, NULL);
+ folder = camel_store_get_folder_sync (
+ (CamelStore *)store, folder_name, 0, NULL, NULL);
/* Abort on failure*/
if (!folder)
@@ -117,7 +118,7 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
fetch_data->folder = folder;
camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- camel_mapi_folder_fetch_summary ((CamelStore *)store, folder, new_mail_notif->FID, res, NULL, fetch_data, options, NULL);
+ camel_mapi_folder_fetch_summary ((CamelStore *)store, folder, new_mail_notif->FID, res, NULL, fetch_data, options, NULL, NULL);
camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
camel_folder_summary_touch (folder->summary);
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index 587d621..cc59cdb 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -82,26 +82,14 @@ static gboolean mapi_construct(CamelService *, CamelSession *,
CamelProvider *, CamelURL *,
GError **);
static gchar *mapi_get_name(CamelService *, gboolean );
-static gboolean mapi_connect(CamelService *, GError **);
-static gboolean mapi_disconnect(CamelService *, gboolean , GError **);
-static GList *mapi_query_auth_types(CamelService *, GError **);
+static gboolean mapi_connect_sync(CamelService *, GCancellable *cancellable, GError **);
+static gboolean mapi_disconnect_sync(CamelService *, gboolean , GCancellable *cancellable, GError **);
+static GList *mapi_query_auth_types_sync(CamelService *, GCancellable *cancellable, GError **);
/* store methods */
-static CamelFolder *mapi_get_folder(CamelStore *, const gchar *, guint32, GError **);
-static CamelFolderInfo *mapi_create_folder(CamelStore *, const gchar *, const gchar *, GError **);
-static gboolean mapi_delete_folder(CamelStore *, const gchar *, GError **);
-static gboolean mapi_rename_folder(CamelStore *, const gchar *, const gchar *, GError **);
-static CamelFolderInfo *mapi_get_folder_info(CamelStore *, const gchar *, guint32, GError **);
-static gboolean mapi_subscribe_folder(CamelStore *, const gchar *, GError **);
-static gboolean mapi_folder_is_subscribed (CamelStore *store, const gchar *folder_name);
-static gboolean mapi_unsubscribe_folder(CamelStore *, const gchar *, GError **);
-static gboolean mapi_noop(CamelStore *, GError **);
static CamelFolderInfo * mapi_build_folder_info(CamelMapiStore *mapi_store, const gchar *parent_name, const gchar *folder_name);
static gboolean mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const gchar *fid);
static void mapi_update_hash_table_type (CamelMapiStore *store, const gchar *full_name, guint *folder_type);
-static CamelFolder *mapi_get_trash (CamelStore *store, GError **error);
-static CamelFolder *mapi_get_junk (CamelStore *store, GError **error);
-static gboolean mapi_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **error);
static void mapi_update_folder_hash_tables (CamelMapiStore *store, const gchar *name, const gchar *fid, const gchar *parent_id);
guint mapi_folders_hash_table_type_lookup (CamelMapiStore *store, const gchar *name);
@@ -110,6 +98,12 @@ guint mapi_folders_hash_table_type_lookup (CamelMapiStore *store, const gchar *n
static const gchar * mapi_folders_hash_table_fid_lookup (CamelMapiStore *store, const gchar *name, gboolean use_cache);
#endif
+static CamelFolderInfo *
+ mapi_store_create_folder_sync (CamelStore *store,
+ const gchar *parent_name,
+ const gchar *folder_name,
+ GCancellable *cancellable,
+ GError **error);
#if 0
static void
dump_summary (CamelMapiStore *mstore)
@@ -145,368 +139,712 @@ dump_summary (CamelMapiStore *mstore)
}
#endif
-static guint
-mapi_hash_folder_name(gconstpointer key)
+static gboolean
+check_for_connection (CamelService *service, GError **error)
{
- return g_str_hash(key);
+ CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+
+ return store && store->priv->conn && exchange_mapi_connection_connected (store->priv->conn);
}
-static gint
-mapi_compare_folder_name(gconstpointer a, gconstpointer b)
+static CamelFolder *
+mapi_get_folder_with_type (CamelStore *store, guint folder_type, GCancellable *cancellable, GError **error)
{
- gconstpointer aname = a;
- gconstpointer bname = b;
+ CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+ CamelFolderInfo *all_fi, *fi;
+ CamelFolder *folder = NULL;
- return g_str_equal(aname, bname);
-}
+ g_return_val_if_fail (mapi_store != NULL, NULL);
+ g_return_val_if_fail (mapi_store->priv != NULL, NULL);
-static void
-mapi_store_dispose (GObject *object)
-{
- CamelMapiStorePrivate *priv;
+ all_fi = camel_store_get_folder_info_sync (
+ store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE,
+ cancellable, error);
+ if (all_fi == NULL)
+ return NULL;
- priv = CAMEL_MAPI_STORE_GET_PRIVATE (object);
+ fi = all_fi;
+ while (fi) {
+ CamelFolderInfo *next;
- if (priv->conn != NULL) {
- g_object_unref (priv->conn);
- priv->conn = NULL;
+ if ((fi->flags & CAMEL_FOLDER_TYPE_MASK) == folder_type) {
+ folder = camel_store_get_folder_sync (
+ store, fi->full_name, 0, cancellable, error);
+ break;
+ }
+
+ /* move to the next, depth-first search */
+ next = fi->child;
+ if (!next)
+ next = fi->next;
+ if (!next) {
+ next = fi->parent;
+ while (next) {
+ CamelFolderInfo *sibl = next->next;
+ if (sibl) {
+ next = sibl;
+ break;
+ } else {
+ next = next->parent;
+ }
+ }
+ }
+
+ fi = next;
}
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (camel_mapi_store_parent_class)->dispose (object);
+ camel_store_free_folder_info (store, all_fi);
+
+ return folder;
}
-static void
-mapi_store_finalize (GObject *object)
+static CamelFolderInfo *
+mapi_convert_to_folder_info (CamelMapiStore *store, ExchangeMAPIFolder *folder, const gchar *url, GError **error)
{
- CamelMapiStorePrivate *priv;
+ const gchar *name = NULL;
+ gchar *parent, *id = NULL;
+ mapi_id_t mapi_id_folder;
- priv = CAMEL_MAPI_STORE_GET_PRIVATE (object);
+ const gchar *par_name = NULL;
+ CamelFolderInfo *fi;
- g_free (priv->profile);
- g_free (priv->storage_path);
- g_free (priv->base_url);
+ name = exchange_mapi_folder_get_name (folder);
- if (priv->id_hash != NULL)
- g_hash_table_destroy (priv->id_hash);
+ id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid (folder));
- if (priv->name_hash != NULL)
- g_hash_table_destroy (priv->name_hash);
+ fi = camel_folder_info_new ();
- if (priv->parent_hash != NULL)
- g_hash_table_destroy (priv->parent_hash);
+ if (folder->is_default) {
+ switch (folder->default_type) {
+ case olFolderTopInformationStore:
+ fi->flags |= CAMEL_FOLDER_NOSELECT;
+ break;
+ case olFolderInbox:
+ fi->flags |= CAMEL_FOLDER_TYPE_INBOX;
+ break;
+ case olFolderSentMail:
+ fi->flags |= CAMEL_FOLDER_TYPE_SENT;
+ break;
+ case olFolderDeletedItems:
+ fi->flags |= CAMEL_FOLDER_TYPE_TRASH;
+ break;
+ case olFolderOutbox:
+ fi->flags |= CAMEL_FOLDER_TYPE_OUTBOX;
+ break;
+ case olFolderJunk:
+ fi->flags |= CAMEL_FOLDER_TYPE_JUNK;
+ break;
+ }
- if (priv->default_folders != NULL)
- g_hash_table_destroy (priv->default_folders);
- if (priv->container_hash != NULL)
- g_hash_table_destroy (priv->container_hash);
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (camel_mapi_store_parent_class)->finalize (object);
-}
+ fi->flags |= CAMEL_FOLDER_SYSTEM;
+ }
-static void
-camel_mapi_store_class_init (CamelMapiStoreClass *class)
-{
- GObjectClass *object_class;
- CamelServiceClass *service_class;
- CamelStoreClass *store_class;
+ if (folder->category == MAPI_PERSONAL_FOLDER) {
+ fi->flags |= CAMEL_MAPI_FOLDER_PERSONAL;
+ fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED; /*Set this default for mailbox.*/
+ } else if (folder->category == MAPI_FAVOURITE_FOLDER)
+ fi->flags |= CAMEL_MAPI_FOLDER_PUBLIC;
- g_type_class_add_private (class, sizeof (CamelMapiStorePrivate));
+ if (folder->child_count <=0)
+ fi->flags |= CAMEL_FOLDER_NOCHILDREN;
+ /*
+ parent_hash contains the "parent id <-> folder id" combination. So we form
+ the path for the full name in camelfolder info by looking up the hash table until
+ NULL is found
+ */
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = mapi_store_dispose;
- object_class->finalize = mapi_store_finalize;
+ mapi_id_folder = exchange_mapi_folder_get_parent_id (folder);
+ parent = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", mapi_id_folder);
- service_class = CAMEL_SERVICE_CLASS (class);
- service_class->construct = mapi_construct;
- service_class->get_name = mapi_get_name;
- service_class->connect = mapi_connect;
- service_class->disconnect = mapi_disconnect;
- service_class->query_auth_types = mapi_query_auth_types;
+ fi->name = g_strdup (name);
- store_class = CAMEL_STORE_CLASS (class);
- store_class->hash_folder_name = mapi_hash_folder_name;
- store_class->compare_folder_name = mapi_compare_folder_name;
- store_class->get_folder = mapi_get_folder;
- store_class->create_folder = mapi_create_folder;
- store_class->delete_folder = mapi_delete_folder;
- store_class->rename_folder = mapi_rename_folder;
- store_class->get_folder_info = mapi_get_folder_info;
- store_class->free_folder_info = camel_store_free_folder_info_full;
- store_class->subscribe_folder = mapi_subscribe_folder;
- store_class->folder_is_subscribed = mapi_folder_is_subscribed;
- store_class->unsubscribe_folder = mapi_unsubscribe_folder;
- store_class->noop = mapi_noop;
- store_class->get_trash = mapi_get_trash;
- store_class->get_junk = mapi_get_junk;
- store_class->can_refresh_folder = mapi_can_refresh_folder;
+ par_name = mapi_folders_hash_table_name_lookup (store, parent, TRUE);
+ if (par_name != NULL) {
+ gchar *str = g_strconcat (par_name, "/", name, NULL);
+
+ fi->full_name = str; /* takes ownership of the string */
+ fi->uri = g_strconcat (url, str, NULL);
+ } else {
+ fi->full_name = g_strdup (name);
+ fi->uri = g_strconcat (url, "", name, NULL);
+ }
+
+ /*name_hash returns the container id given the name */
+ mapi_update_folder_hash_tables (store, fi->full_name, id, parent);
+
+ g_free (parent);
+ g_free (id);
+
+ fi->total = folder->total;
+ fi->unread = folder->unread_count;
+
+ return fi;
}
-/*
-** store is already initilyse to NULL or 0 value
-** class already have a parent_class
-** nothing must be doing here
-*/
static void
-camel_mapi_store_init (CamelMapiStore *mapi_store)
+remove_path_from_store_summary (const gchar *path, gpointer value, CamelMapiStore *mstore)
{
- mapi_store->priv = CAMEL_MAPI_STORE_GET_PRIVATE (mapi_store);
+ const gchar *folder_id;
+ CamelStoreInfo *si;
+
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (mstore != NULL);
+
+ folder_id = g_hash_table_lookup (mstore->priv->name_hash, path);
+ if (folder_id) {
+ /* name_hash as the second, because folder_id is from there */
+ g_hash_table_remove (mstore->priv->id_hash, folder_id);
+ g_hash_table_remove (mstore->priv->name_hash, path);
+ }
+
+ si = camel_store_summary_path ((CamelStoreSummary *)mstore->summary, path);
+ if (si) {
+ CamelFolderInfo *fi;
+
+ fi = camel_folder_info_new ();
+ fi->unread = -1;
+ fi->total = -1;
+ fi->uri = g_strdup (camel_store_info_uri (mstore->summary, si));
+ fi->name = g_strdup (camel_store_info_name (mstore->summary, si));
+ fi->full_name = g_strdup (camel_mapi_store_info_full_name (mstore->summary, si));
+ if (!fi->name && fi->full_name) {
+ fi->name = strrchr (fi->full_name, '/');
+ if (fi->name)
+ fi->name = g_strdup (fi->name + 1);
+ }
+
+ camel_store_folder_unsubscribed (CAMEL_STORE (mstore), fi);
+ camel_store_folder_deleted (CAMEL_STORE (mstore), fi);
+ camel_folder_info_free (fi);
+
+ camel_store_summary_info_free ((CamelStoreSummary *)mstore->summary, si);
+ }
+
+ camel_store_summary_remove_path ((CamelStoreSummary *)mstore->summary, path);
}
-/* service methods */
-static gboolean mapi_construct(CamelService *service, CamelSession *session,
- CamelProvider *provider, CamelURL *url,
- GError **error)
+static gboolean
+mapi_folders_sync (CamelMapiStore *store, guint32 flags, GError **error)
{
- CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (service);
- CamelStore *store = CAMEL_STORE (service);
- CamelMapiStorePrivate *priv = mapi_store->priv;
- gchar *path = NULL;
+ CamelMapiStorePrivate *priv = store->priv;
+ gboolean status;
+ GSList *folder_list = NULL, *temp_list = NULL, *list = NULL;
+ gchar *url, *temp_url;
+ gboolean subscription_list = FALSE;
+ CamelFolderInfo *info = NULL;
+ CamelMapiStoreInfo *mapi_si = NULL;
+ guint32 count, i;
+ CamelStoreInfo *si = NULL;
+ GHashTable *old_cache_folders;
+ GError *err = NULL;
- if (!CAMEL_SERVICE_CLASS (camel_mapi_store_parent_class)->construct (service, session, provider, url, error))
+ if (!camel_mapi_store_connected (store, NULL)) {
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_UNAVAILABLE,
+ _("Folder list not available in offline mode."));
return FALSE;
+ }
- /*storage path*/
- priv->storage_path = camel_session_get_storage_path (session, service, error);
- if (!priv->storage_path)
- return FALSE;
+ status = exchange_mapi_connection_get_folders_list (priv->conn, &folder_list, &err);
- /*store summary*/
- path = g_alloca (strlen (priv->storage_path) + 32);
- sprintf (path, "%s/.summary", priv->storage_path);
+ if (!status) {
+ g_warning ("Could not get folder list (%s)\n", err ? err->message : "Unknown error");
+ if (err)
+ g_error_free (err);
+ return TRUE;
+ }
- mapi_store->summary = camel_mapi_store_summary_new ();
- camel_store_summary_set_filename ((CamelStoreSummary *)mapi_store->summary, path);
+ /* remember all folders in cache before update */
+ old_cache_folders = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ count = camel_store_summary_count ((CamelStoreSummary *)store->summary);
+ for (i = 0; i < count; i++) {
+ si = camel_store_summary_index ((CamelStoreSummary *)store->summary, i);
+ if (si == NULL)
+ continue;
- camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
- camel_store_summary_load ((CamelStoreSummary *) mapi_store->summary);
+ /* those whose left in old_cache_folders are removed at the end,
+ which is not good for public folders, thus preserve them from
+ an automatic removal */
+ if ((si->flags & CAMEL_MAPI_FOLDER_PUBLIC) == 0 || (si->flags & CAMEL_FOLDER_SUBSCRIBED) == 0)
+ g_hash_table_insert (old_cache_folders, g_strdup (camel_store_info_path (store->summary, si)), GINT_TO_POINTER (1));
- /*user and profile*/
- priv->profile = g_strdup (camel_url_get_param(url, "profile"));
+ camel_store_summary_info_free ((CamelStoreSummary *)store->summary, si);
+ }
- /*base url*/
- priv->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
- CAMEL_URL_HIDE_PARAMS |
- CAMEL_URL_HIDE_AUTH) );
+ subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
+ if (subscription_list) {
+ GError *err = NULL;
- /*filter*/
- if (camel_url_get_param (url, "filter"))
- store->flags |= CAMEL_STORE_FILTER_INBOX;
+ /*Consult the name <-> fid hash table for a FID.*/
+ status = exchange_mapi_connection_get_pf_folders_list (priv->conn, &folder_list, &err);
+ if (!status)
+ g_warning ("Could not get Public folder list (%s)\n", err ? err->message : "Unknown error");
- /*Hash Table*/
- priv->id_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* folder ID to folder Full name */
- priv->name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* folder Full name to folder ID */
- /*priv->parent_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); / * folder ID to its parent folder ID */
- priv->default_folders = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free); /* default folder type to folder ID */
- priv->container_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- store->flags &= ~CAMEL_STORE_VJUNK;
- store->flags &= ~CAMEL_STORE_VTRASH;
+ if (err)
+ g_error_free (err);
+ }
- store->flags |= CAMEL_STORE_SUBSCRIPTIONS | CAMEL_STORE_REAL_JUNK_FOLDER;
+ temp_list = folder_list;
+ list = folder_list;
+
+ url = camel_url_to_string (CAMEL_SERVICE(store)->url,
+ (CAMEL_URL_HIDE_PASSWORD|
+ CAMEL_URL_HIDE_PARAMS|
+ CAMEL_URL_HIDE_AUTH));
+ if ( url[strlen(url) - 1] != '/') {
+ temp_url = g_strconcat (url, "/", NULL);
+ g_free ((gchar *)url);
+ url = temp_url;
+ }
+
+ /*populate the hash table for finding the mapping from container id <-> folder name*/
+ for (;temp_list != NULL; temp_list = g_slist_next (temp_list) ) {
+ const gchar *full_name = NULL;
+ gchar *fid = NULL, *parent_id = NULL, *tmp = NULL;
+ guint *folder_type = g_new0 (guint, 1);
+
+ fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(temp_list->data)));
+ parent_id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_parent_id ((ExchangeMAPIFolder *)(temp_list->data)));
+ full_name = g_hash_table_lookup (priv->id_hash, fid);
+ if (!full_name) {
+ const gchar *par_full_name;
+
+ par_full_name = g_hash_table_lookup (priv->id_hash, parent_id);
+ if (par_full_name) {
+ tmp = g_strconcat (par_full_name, "/", exchange_mapi_folder_get_name (temp_list->data), NULL);
+ full_name = tmp;
+ } else {
+ full_name = exchange_mapi_folder_get_name (temp_list->data);
+ }
+ }
+
+ /* remove from here; what lefts is not on the server any more */
+ g_hash_table_remove (old_cache_folders, full_name);
+ *folder_type = ((ExchangeMAPIFolder *)(temp_list->data))->container_class;
+ mapi_update_folder_hash_tables (store, full_name, fid, parent_id);
+ mapi_update_hash_table_type (store, full_name, folder_type);
+ if (((ExchangeMAPIFolder *)(temp_list->data))->is_default) {
+ guint *type = g_new0 (guint, 1);
+ *type = ((ExchangeMAPIFolder *)(temp_list->data))->default_type;
+ g_hash_table_insert (priv->default_folders, type,
+ g_strdup(fid));
+ }
+ g_free (fid);
+ g_free (parent_id);
+ g_free (tmp);
+ }
+
+ for (;folder_list != NULL; folder_list = g_slist_next (folder_list)) {
+ ExchangeMAPIFolder *folder = (ExchangeMAPIFolder *) folder_list->data;
+
+ if (folder->default_type == olPublicFoldersAllPublicFolders)
+ continue;
+
+ if ( folder->container_class == MAPI_FOLDER_TYPE_MAIL) {
+ info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, NULL);
+ info->flags |= CAMEL_MAPI_FOLDER_MAIL;
+ mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
+
+ if (!mapi_si) {
+ gchar *fid, *pfid = NULL;
+
+ fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+ exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
+ pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+ exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
+
+ mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
+ g_free (fid);
+ g_free (pfid);
+ if (mapi_si == NULL)
+ continue;
+
+ camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+
+ if (!subscription_list) {
+ camel_store_folder_created (CAMEL_STORE (store), info);
+ camel_store_folder_subscribed (CAMEL_STORE (store), info);
+ }
+ }
+
+ mapi_si->info.flags |= info->flags;
+ mapi_si->info.total = info->total;
+ mapi_si->info.unread = info->unread;
+
+ camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+ camel_folder_info_free (info);
+ } else if (folder->category == MAPI_FAVOURITE_FOLDER) {
+ gchar *fid, *pfid = NULL;
+ info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, NULL);
+ mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
+ fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+ exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
+ pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
+ exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
+ mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
+ g_free (fid);
+ g_free (pfid);
+
+ if (mapi_si == NULL)
+ continue;
+
+ camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+ mapi_si->info.flags |= info->flags;
+ camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
+ camel_folder_info_free (info);
+ }
+ }
+
+ /* Weed out deleted folders */
+ g_hash_table_foreach (old_cache_folders, (GHFunc) remove_path_from_store_summary, store);
+ g_hash_table_destroy (old_cache_folders);
+
+ camel_store_summary_touch ((CamelStoreSummary *)store->summary);
+ camel_store_summary_save ((CamelStoreSummary *)store->summary);
+
+ g_free (url);
+
+ g_slist_foreach (list, (GFunc) exchange_mapi_folder_free, NULL);
+ g_slist_free (list);
+
+ priv->folders_synced = TRUE;
+
+ // g_hash_table_foreach (present, get_folders_free, NULL);
+ // g_hash_table_destroy (present);
+
+ /* FIXME : This place is not right! */
+ /* Start Push Notification listener */
+ /* event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted | */
+ /* fnevObjectModified | fnevObjectMoved | fnevObjectCopied; */
+
+ /* camel_mapi_notfication_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE); */
return TRUE;
}
-static char
-*mapi_get_name(CamelService *service, gboolean brief)
+static gchar *
+mapi_concat ( const gchar *prefix, const gchar *suffix)
{
- if (brief) {
- /* Translators: The %s is replaced with a server's host name */
- return g_strdup_printf(_("Exchange MAPI server %s"), service->url->host);
- } else {
- /*To translators : Example string : Exchange MAPI service for
- _username_ on _server host name__*/
- return g_strdup_printf(_("Exchange MAPI service for %s on %s"),
- service->url->user, service->url->host);
- }
+ gsize len;
+
+ len = strlen (prefix);
+ if (len == 0 || prefix[len - 1] == '/')
+ return g_strdup_printf ("%s%s", prefix, suffix);
+ else
+ return g_strdup_printf ("%s%c%s", prefix, '/', suffix);
}
-static gboolean
-check_for_connection (CamelService *service, GError **error)
+//do we realy need this. move to utils then !
+static gint
+match_path(const gchar *path, const gchar *name)
{
- CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+ gchar p, n;
- return store && store->priv->conn && exchange_mapi_connection_connected (store->priv->conn);
+ p = *path++;
+ n = *name++;
+ while (n && p) {
+ if (n == p) {
+ p = *path++;
+ n = *name++;
+ } else if (p == '%') {
+ if (n != '/') {
+ n = *name++;
+ } else {
+ p = *path++;
+ }
+ } else if (p == '*') {
+ return TRUE;
+ } else
+ return FALSE;
+ }
+
+ return n == 0 && (p == '%' || p == 0);
}
-static gboolean
-mapi_auth_loop (CamelService *service, GError **error)
+static CamelFolderInfo *
+mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
+ guint32 flags, GError **error)
{
- CamelMapiStore *store = CAMEL_MAPI_STORE (service);
- CamelSession *session = camel_service_get_session (service);
+ CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+ CamelFolderInfo *fi;
+ GPtrArray *folders;
+ gchar *path, *name;
+ gint i;
+ gboolean subscribed, favourites = FALSE, subscription_list = FALSE;
- gchar *errbuf = NULL;
- gboolean authenticated = FALSE;
- guint32 prompt_flags = CAMEL_SESSION_PASSWORD_SECRET;
+ subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
+ subscribed = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED);
- service->url->passwd = NULL;
+ folders = g_ptr_array_new ();
- while (!authenticated) {
- GError *mapi_error = NULL;
+ if (top == NULL)
+ top = "";
- if (errbuf) {
- /* We need to un-cache the password before prompting again */
- prompt_flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
- g_free (service->url->passwd);
- service->url->passwd = NULL;
+ /* get starting point */
+ if (top[0] == 0) {
+ name = g_strdup("");
+ } else {
+ name = camel_mapi_store_summary_full_from_path(mapi_store->summary, top);
+ if (name == NULL)
+ name = camel_mapi_store_summary_path_to_full(mapi_store->summary, top, '/');
+ }
+
+ path = mapi_concat (name, "*");
+
+ for (i=0;i<camel_store_summary_count((CamelStoreSummary *)mapi_store->summary);i++) {
+ CamelStoreInfo *si = camel_store_summary_index((CamelStoreSummary *)mapi_store->summary, i);
+
+ if (si == NULL)
+ continue;
+
+ /* Allow only All Public Folders heirarchy */
+ if (subscription_list && (!(si->flags & CAMEL_MAPI_FOLDER_PUBLIC))) {
+ camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
+ continue;
}
- if (!service->url->passwd ) {
- gchar *prompt;
+ /*Allow Mailbox and Favourites (Subscribed public folders)*/
+ if (subscribed && (!(si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))) {
+ camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
+ continue;
+ }
- /*To translators : First %s : is the error text or the reason
- for prompting the user if it is available.
- Second %s is : Username.
- Third %s is : Server host name.*/
- prompt = g_strdup_printf (_("%s Please enter the MAPI password for %s %s"),
- errbuf ? errbuf : "",
- service->url->user,
- service->url->host);
- service->url->passwd =
- camel_session_get_password (session, service, E_PASSWORD_COMPONENT,
- prompt, "password", prompt_flags, NULL);
- g_free (prompt);
- g_free (errbuf);
- errbuf = NULL;
+ if (!subscription_list && !(si->flags & CAMEL_MAPI_FOLDER_MAIL) && si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED &&
+ si->flags & CAMEL_MAPI_FOLDER_PUBLIC)
+ continue;
+ if (!strcmp(name, camel_mapi_store_info_full_name (mapi_store->summary, si))
+ || match_path (path, camel_mapi_store_info_full_name (mapi_store->summary, si))) {
- if (!service->url->passwd) {
- g_set_error (
- error, G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("You did not enter a password."));
- return FALSE;
+ const gchar *store_info_path = camel_store_info_path((CamelStoreSummary *)mapi_store->summary, si);
+ gchar *parent_name = NULL;
+ const gchar *folder_name = NULL;
+
+ /* TODO : UTF8 / i18n*/
+ if (g_str_has_prefix (store_info_path, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) && subscribed) {
+ parent_name = DISPLAY_NAME_FAVOURITES;
+
+ folder_name = strrchr(store_info_path,'/');
+ if (folder_name != NULL)
+ store_info_path = ++folder_name;
+
+ favourites = TRUE;
}
- }
- store->priv->conn = exchange_mapi_connection_new (store->priv->profile, service->url->passwd, &mapi_error);
- if (!store->priv->conn || !exchange_mapi_connection_connected (store->priv->conn)) {
- if (mapi_error) {
- errbuf = g_strdup_printf (_("Unable to authenticate to Exchange MAPI server: %s"), mapi_error->message);
- g_error_free (mapi_error);
- } else {
- errbuf = g_strdup (_("Unable to authenticate to Exchange MAPI server"));
+ fi = mapi_build_folder_info(mapi_store, parent_name, store_info_path);
+ if (favourites) {
+ CamelURL *url;
+ url = camel_url_new(mapi_store->priv->base_url,NULL);
+ url->path = g_strdup_printf("/%s", camel_store_info_path((CamelStoreSummary *)mapi_store->summary, si));
+ g_free (fi->uri);
+ fi->uri = camel_url_to_string(url,CAMEL_URL_HIDE_ALL);
+ camel_url_free (url);
}
- } else
- authenticated = TRUE;
+ fi->unread = si->unread;
+ fi->total = si->total;
+ fi->flags = si->flags;
+
+ g_ptr_array_add (folders, fi);
+ }
+ camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
}
- return TRUE;
+
+ if (!(subscription_list) && top[0] == '\0') {
+ fi = mapi_build_folder_info(mapi_store, NULL, DISPLAY_NAME_FAVOURITES);
+ fi->flags |= CAMEL_FOLDER_NOSELECT;
+ fi->flags |= CAMEL_FOLDER_SYSTEM;
+
+ g_ptr_array_add (folders, fi);
+ }
+
+ g_free(name);
+ g_free (path);
+ fi = camel_folder_info_build (folders, top, '/', TRUE);
+ g_ptr_array_free (folders, TRUE);
+ return fi;
}
static gboolean
-mapi_connect(CamelService *service, GError **error)
+mapi_forget_folder (CamelMapiStore *mapi_store, const gchar *folder_name, GError **error)
{
- CamelMapiStore *store = CAMEL_MAPI_STORE (service);
- CamelMapiStorePrivate *priv = store->priv;
- guint16 event_mask = 0;
+ CamelMapiStorePrivate *priv = mapi_store->priv;
+ gchar *state_file;
+ gchar *folder_dir, *storage_path;
+ CamelFolderInfo *fi;
+ const gchar *name;
- if (service->status == CAMEL_SERVICE_DISCONNECTED) {
- return FALSE;
- }
+ name = folder_name;
- if (!priv) {
- store->priv = g_new0 (CamelMapiStorePrivate, 1);
- priv = store->priv;
- if (!camel_service_construct (service, service->session, service->provider, service->url, error))
- return FALSE;
- }
+ storage_path = g_strdup_printf ("%s/folders", priv->storage_path);
- camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
- if (check_for_connection (service, NULL)) {
- camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
- return TRUE;
- }
+ /* Fixme Path - e_*-to_path */
+ folder_dir = g_strconcat (storage_path, "/", folder_name, NULL);
+ g_free (storage_path);
- if (!mapi_auth_loop (service, error)) {
- camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
- camel_service_disconnect (service, TRUE, NULL);
- return FALSE;
+ if (g_access(folder_dir, F_OK) != 0) {
+ g_free(folder_dir);
+ return TRUE;
}
- service->status = CAMEL_SERVICE_CONNECTED;
- ((CamelOfflineStore *) store)->state = CAMEL_OFFLINE_STORE_NETWORK_AVAIL;
-
- /* Start event monitor */
- event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted |
- fnevObjectModified | fnevObjectMoved | fnevObjectCopied;
+ state_file = g_strdup_printf ("%s/cmeta", folder_dir);
+ g_unlink (state_file);
+ g_free (state_file);
- /* use MAPI_LISTEN_NOTIFY=1 to enable notifications */
- if (!store->priv->notification_data && g_getenv ("MAPI_LISTEN_NOTIFY") != NULL)
- store->priv->notification_data = camel_mapi_notification_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE);
+ g_rmdir (folder_dir);
+ g_free (folder_dir);
- camel_store_summary_save ((CamelStoreSummary *) store->summary);
+ camel_store_summary_remove_path ((CamelStoreSummary *)mapi_store->summary, folder_name);
+ camel_store_summary_save ((CamelStoreSummary *)mapi_store->summary);
- camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+ fi = mapi_build_folder_info (mapi_store, NULL, folder_name);
+ camel_store_folder_deleted (CAMEL_STORE (mapi_store), fi);
+ camel_folder_info_free (fi);
return TRUE;
}
-void
-camel_mapi_store_unset_notification_data (CamelMapiStore *mstore)
+static void
+mapi_rename_folder_infos (CamelMapiStore *mapi_store, const gchar *old_name, const gchar *new_name)
{
- g_return_if_fail (mstore != NULL);
- g_return_if_fail (CAMEL_IS_MAPI_STORE (mstore));
+ gint sz, i, olen;
+ CamelStoreInfo *si = NULL;
- mstore->priv->notification_data = NULL;
+ g_return_if_fail (mapi_store != NULL);
+ g_return_if_fail (old_name != NULL);
+ g_return_if_fail (new_name != NULL);
+
+ olen = strlen (old_name);
+ sz = camel_store_summary_count ((CamelStoreSummary*) mapi_store->summary);
+ for (i = 0; i < sz; i++) {
+ const gchar *full_name;
+
+ si = camel_store_summary_index ((CamelStoreSummary *) mapi_store->summary, i);
+ if (!si)
+ continue;
+
+ full_name = camel_mapi_store_info_full_name (mapi_store->summary, si);
+ if (full_name && g_str_has_prefix (full_name, old_name) && !g_str_equal (full_name, old_name) &&
+ full_name [olen] == '/' && full_name [olen + 1] != '\0') {
+ /* it's a subfolder of old_name */
+ const gchar *fid = camel_mapi_store_info_folder_id (mapi_store->summary, si);
+
+ if (fid) {
+ gchar *new_full_name;
+
+ /* do not remove it from name_hash yet, because this function
+ will be called for it again */
+ /* g_hash_table_remove (mapi_store->priv->name_hash, full_name); */
+ g_hash_table_remove (mapi_store->priv->id_hash, fid);
+
+ /* parent is still the same, only the path changed */
+ new_full_name = g_strconcat (new_name, full_name + olen + (g_str_has_suffix (new_name, "/") ? 1 : 0), NULL);
+
+ mapi_update_folder_hash_tables (mapi_store, new_full_name, fid, NULL);
+
+ camel_store_info_set_string ((CamelStoreSummary *)mapi_store->summary, si, CAMEL_STORE_INFO_PATH, new_full_name);
+ camel_store_info_set_string ((CamelStoreSummary *)mapi_store->summary, si, CAMEL_MAPI_STORE_INFO_FULL_NAME, new_full_name);
+ camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
+
+ g_free (new_full_name);
+ }
+ }
+ camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
+ }
}
-static gboolean
-mapi_disconnect(CamelService *service, gboolean clean, GError **error)
+static void
+mapi_store_dispose (GObject *object)
{
- CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+ CamelMapiStorePrivate *priv;
- /* Disconnect from event monitor */
- if (store->priv->notification_data) {
- camel_mapi_notification_listener_stop (store, store->priv->notification_data);
- store->priv->notification_data = NULL;
- }
+ priv = CAMEL_MAPI_STORE_GET_PRIVATE (object);
- if (store->priv->conn) {
- /* Close the mapi subsystem */
- g_object_unref (store->priv->conn);
- store->priv->conn = NULL;
+ if (priv->conn != NULL) {
+ g_object_unref (priv->conn);
+ priv->conn = NULL;
}
- store->priv->folders_synced = FALSE;
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (camel_mapi_store_parent_class)->dispose (object);
+}
- ((CamelOfflineStore *) store)->state = CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL;
- service->status = CAMEL_SERVICE_DISCONNECTED;
+static void
+mapi_store_finalize (GObject *object)
+{
+ CamelMapiStorePrivate *priv;
- return TRUE;
+ priv = CAMEL_MAPI_STORE_GET_PRIVATE (object);
+
+ g_free (priv->profile);
+ g_free (priv->storage_path);
+ g_free (priv->base_url);
+
+ if (priv->id_hash != NULL)
+ g_hash_table_destroy (priv->id_hash);
+
+ if (priv->name_hash != NULL)
+ g_hash_table_destroy (priv->name_hash);
+
+ if (priv->parent_hash != NULL)
+ g_hash_table_destroy (priv->parent_hash);
+
+ if (priv->default_folders != NULL)
+ g_hash_table_destroy (priv->default_folders);
+ if (priv->container_hash != NULL)
+ g_hash_table_destroy (priv->container_hash);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (camel_mapi_store_parent_class)->finalize (object);
}
-static GList *mapi_query_auth_types(CamelService *service, GError **error)
+static guint
+mapi_store_hash_folder_name (gconstpointer key)
{
- return NULL;
+ return g_str_hash(key);
}
-static gboolean
-hash_check_fid_presence (gpointer key, gpointer value, gpointer folder_id)
+static gint
+mapi_store_compare_folder_name (gconstpointer a,
+ gconstpointer b)
{
- return (g_ascii_strcasecmp (value, folder_id) == 0);
+ gconstpointer aname = a;
+ gconstpointer bname = b;
+
+ return g_str_equal(aname, bname);
}
static gboolean
-mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const gchar *fid)
+mapi_store_can_refresh_folder (CamelStore *store,
+ CamelFolderInfo *info,
+ GError **error)
{
- CamelMapiStorePrivate *priv = mapi_store->priv;
-
- if (!(fid && *fid))
- return FALSE;
-
- return (g_hash_table_find (priv->default_folders, hash_check_fid_presence, (gpointer) fid) != NULL);
+ return CAMEL_STORE_CLASS(camel_mapi_store_parent_class)->can_refresh_folder (store, info, error) ||
+ (camel_url_get_param (((CamelService *)store)->url, "check_all") != NULL);
}
-static const gchar *
-mapi_system_folder_fid (CamelMapiStore *mapi_store, gint folder_type)
+static gboolean
+mapi_store_folder_is_subscribed (CamelStore *store,
+ const gchar *folder_name)
{
- CamelMapiStorePrivate *priv = mapi_store->priv;
+ CamelMapiStore *mapi_store = (CamelMapiStore *) store;
+ CamelStoreInfo *si;
+ gint truth = FALSE;
- return g_hash_table_lookup (priv->default_folders, &folder_type);
+ if ((si = camel_store_summary_path ((CamelStoreSummary *) mapi_store->summary, folder_name))) {
+ truth = (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) != 0;
+ camel_store_summary_info_free ((CamelStoreSummary *) mapi_store->summary, si);
+ }
+
+ return truth;
}
static CamelFolder *
-mapi_get_folder(CamelStore *store, const gchar *folder_name, guint32 flags, GError **error)
+mapi_store_get_folder_sync (CamelStore *store,
+ const gchar *folder_name,
+ guint32 flags,
+ GCancellable *cancellable,
+ GError **error)
{
CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
CamelMapiStorePrivate *priv = mapi_store->priv;
@@ -529,7 +867,8 @@ mapi_get_folder(CamelStore *store, const gchar *folder_name, guint32 flags, GErr
parent = tmp;
}
- folder_info = mapi_create_folder (store, parent, name, error);
+ folder_info = mapi_store_create_folder_sync (
+ store, parent, name, cancellable, error);
g_free (tmp);
if (!folder_info)
@@ -549,7 +888,71 @@ mapi_get_folder(CamelStore *store, const gchar *folder_name, guint32 flags, GErr
}
static CamelFolderInfo*
-mapi_create_folder(CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error)
+mapi_store_get_folder_info_sync (CamelStore *store,
+ const gchar *top,
+ guint32 flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+
+ /*
+ * Thanks to Michael, for his cached folders implementation in IMAP
+ * is used as is here.
+ */
+
+ camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ if (camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
+ if (((CamelService *)store)->status == CAMEL_SERVICE_DISCONNECTED) {
+ ((CamelService *)store)->status = CAMEL_SERVICE_CONNECTING;
+ mapi_connect_sync ((CamelService *)store, cancellable, NULL);
+ }
+ }
+
+ /* update folders from the server only when asking for the top most or the 'top' is not known;
+ otherwise believe the local cache, because folders sync is pretty slow operation to be done
+ one every single question on the folder info */
+ if (((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) != 0 ||
+ (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) ||
+ (!mapi_store->priv->folders_synced) ||
+ (top && *top && !camel_mapi_store_folder_id_lookup (mapi_store, top))) &&
+ (check_for_connection ((CamelService *)store, NULL) || ((CamelService *)store)->status == CAMEL_SERVICE_CONNECTING)) {
+ if (!mapi_folders_sync (mapi_store, flags, error)) {
+ camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ return NULL;
+ }
+ camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
+ camel_store_summary_save ((CamelStoreSummary *)mapi_store->summary);
+ }
+
+ camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ return mapi_get_folder_info_offline (store, top, flags, error);
+}
+
+static CamelFolder *
+mapi_store_get_junk_folder_sync (CamelStore *store,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return mapi_get_folder_with_type (store, CAMEL_FOLDER_TYPE_JUNK, cancellable, error);
+}
+
+static CamelFolder *
+mapi_store_get_trash_folder_sync (CamelStore *store,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return mapi_get_folder_with_type (store, CAMEL_FOLDER_TYPE_TRASH, cancellable, error);
+}
+
+static CamelFolderInfo *
+mapi_store_create_folder_sync (CamelStore *store,
+ const gchar *parent_name,
+ const gchar *folder_name,
+ GCancellable *cancellable,
+ GError **error)
{
CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
CamelMapiStorePrivate *priv = mapi_store->priv;
@@ -558,7 +961,7 @@ mapi_create_folder(CamelStore *store, const gchar *parent_name, const gchar *fol
mapi_id_t parent_fid, new_folder_id;
GError *mapi_error = NULL;
- if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Cannot create MAPI folders in offline mode."));
@@ -578,7 +981,7 @@ mapi_create_folder(CamelStore *store, const gchar *parent_name, const gchar *fol
else
parent_id = g_strdup ("");
- if (!mapi_connect (CAMEL_SERVICE(store), NULL)) {
+ if (!mapi_connect_sync (CAMEL_SERVICE(store), cancellable, NULL)) {
g_set_error (
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
@@ -622,46 +1025,10 @@ mapi_create_folder(CamelStore *store, const gchar *parent_name, const gchar *fol
}
static gboolean
-mapi_forget_folder (CamelMapiStore *mapi_store, const gchar *folder_name, GError **error)
-{
- CamelMapiStorePrivate *priv = mapi_store->priv;
- gchar *state_file;
- gchar *folder_dir, *storage_path;
- CamelFolderInfo *fi;
- const gchar *name;
-
- name = folder_name;
-
- storage_path = g_strdup_printf ("%s/folders", priv->storage_path);
-
- /* Fixme Path - e_*-to_path */
- folder_dir = g_strconcat (storage_path, "/", folder_name, NULL);
- g_free (storage_path);
-
- if (g_access(folder_dir, F_OK) != 0) {
- g_free(folder_dir);
- return TRUE;
- }
-
- state_file = g_strdup_printf ("%s/cmeta", folder_dir);
- g_unlink (state_file);
- g_free (state_file);
-
- g_rmdir (folder_dir);
- g_free (folder_dir);
-
- camel_store_summary_remove_path ((CamelStoreSummary *)mapi_store->summary, folder_name);
- camel_store_summary_save ((CamelStoreSummary *)mapi_store->summary);
-
- fi = mapi_build_folder_info (mapi_store, NULL, folder_name);
- camel_store_folder_deleted (CAMEL_STORE (mapi_store), fi);
- camel_folder_info_free (fi);
-
- return TRUE;
-}
-
-static gboolean
-mapi_delete_folder(CamelStore *store, const gchar *folder_name, GError **error)
+mapi_store_delete_folder_sync (CamelStore *store,
+ const gchar *folder_name,
+ GCancellable *cancellable,
+ GError **error)
{
CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
CamelMapiStorePrivate *priv = mapi_store->priv;
@@ -722,57 +1089,12 @@ mapi_delete_folder(CamelStore *store, const gchar *folder_name, GError **error)
return success;
}
-static void
-mapi_rename_folder_infos (CamelMapiStore *mapi_store, const gchar *old_name, const gchar *new_name)
-{
- gint sz, i, olen;
- CamelStoreInfo *si = NULL;
-
- g_return_if_fail (mapi_store != NULL);
- g_return_if_fail (old_name != NULL);
- g_return_if_fail (new_name != NULL);
-
- olen = strlen (old_name);
- sz = camel_store_summary_count ((CamelStoreSummary*) mapi_store->summary);
- for (i = 0; i < sz; i++) {
- const gchar *full_name;
-
- si = camel_store_summary_index ((CamelStoreSummary *) mapi_store->summary, i);
- if (!si)
- continue;
-
- full_name = camel_mapi_store_info_full_name (mapi_store->summary, si);
- if (full_name && g_str_has_prefix (full_name, old_name) && !g_str_equal (full_name, old_name) &&
- full_name [olen] == '/' && full_name [olen + 1] != '\0') {
- /* it's a subfolder of old_name */
- const gchar *fid = camel_mapi_store_info_folder_id (mapi_store->summary, si);
-
- if (fid) {
- gchar *new_full_name;
-
- /* do not remove it from name_hash yet, because this function
- will be called for it again */
- /* g_hash_table_remove (mapi_store->priv->name_hash, full_name); */
- g_hash_table_remove (mapi_store->priv->id_hash, fid);
-
- /* parent is still the same, only the path changed */
- new_full_name = g_strconcat (new_name, full_name + olen + (g_str_has_suffix (new_name, "/") ? 1 : 0), NULL);
-
- mapi_update_folder_hash_tables (mapi_store, new_full_name, fid, NULL);
-
- camel_store_info_set_string ((CamelStoreSummary *)mapi_store->summary, si, CAMEL_STORE_INFO_PATH, new_full_name);
- camel_store_info_set_string ((CamelStoreSummary *)mapi_store->summary, si, CAMEL_MAPI_STORE_INFO_FULL_NAME, new_full_name);
- camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
-
- g_free (new_full_name);
- }
- }
- camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
- }
-}
-
static gboolean
-mapi_rename_folder(CamelStore *store, const gchar *old_name, const gchar *new_name, GError **error)
+mapi_store_rename_folder_sync (CamelStore *store,
+ const gchar *old_name,
+ const gchar *new_name,
+ GCancellable *cancellable,
+ GError **error)
{
CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
CamelMapiStorePrivate *priv = mapi_store->priv;
@@ -985,6 +1307,429 @@ mapi_rename_folder(CamelStore *store, const gchar *old_name, const gchar *new_na
return TRUE;
}
+static gboolean
+mapi_store_subscribe_folder_sync (CamelStore *store,
+ const gchar *folder_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+ CamelFolderInfo *fi;
+ CamelStoreInfo *si = NULL;
+ const gchar *parent_name = NULL, *use_folder_name = folder_name, *fid = NULL;
+ gboolean favourites = FALSE;
+ /* TODO : exchange_mapi_add_to_favorites (); */
+
+ fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
+
+ if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
+ const gchar *f_name = NULL;
+
+ parent_name = DISPLAY_NAME_FAVOURITES;
+
+ f_name = strrchr (folder_name,'/');
+ if (!f_name) {
+ /* Don't process All Public Folder. */
+ return TRUE;
+ }
+
+ use_folder_name = ++f_name;
+ favourites = TRUE;
+ }
+ si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
+
+ if (si != NULL) {
+ if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
+ si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+ si->flags |= CAMEL_FOLDER_SUBSCRIBED;
+ camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
+ }
+ }
+
+ if (si->flags & CAMEL_MAPI_FOLDER_MAIL) {
+ fi = mapi_build_folder_info (mapi_store, parent_name, use_folder_name);
+ if (favourites) {
+ CamelURL *url;
+ url = camel_url_new (mapi_store->priv->base_url, NULL);
+ url->path = g_strdup_printf ("/%s", camel_store_info_path (mapi_store->summary, si));
+ g_free (fi->uri);
+ fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
+ camel_url_free (url);
+ }
+
+ fi->unread = si->unread;
+ fi->total = si->total;
+ fi->flags = si->flags;
+ fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
+ fi->flags |= CAMEL_FOLDER_NOCHILDREN;
+ fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+ camel_store_folder_subscribed (store, fi);
+ camel_folder_info_free (fi);
+ } else {
+ guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, folder_name);
+ exchange_mapi_add_esource (CAMEL_SERVICE(mapi_store)->url, use_folder_name, fid, folder_type);
+ }
+ camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
+ return TRUE;
+}
+
+static gboolean
+mapi_store_unsubscribe_folder_sync (CamelStore *store,
+ const gchar *folder_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolderInfo *fi;
+ CamelStoreInfo *si;
+ gchar *parent_name = NULL;
+ const gchar *fid = NULL, *use_folder_name = folder_name;
+ gchar *f_name = NULL;
+
+ CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+ CamelURL *url = CAMEL_SERVICE (mapi_store)->url;
+ fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
+ si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
+ if (si) {
+ if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
+ si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+ camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
+ camel_store_summary_save((CamelStoreSummary *)mapi_store->summary);
+ }
+ }
+
+ if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
+ parent_name = DISPLAY_NAME_FAVOURITES;
+
+ f_name = strrchr(folder_name,'/');
+ if (f_name != NULL)
+ folder_name = ++f_name;
+ else //Don't process All Public Folder.
+ return TRUE;
+ }
+ if (si->flags & CAMEL_MAPI_FOLDER_MAIL) {
+ fi = mapi_build_folder_info (mapi_store, parent_name, folder_name);
+ camel_store_folder_unsubscribed (store, fi);
+ camel_folder_info_free (fi);
+ } else {
+ guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, use_folder_name);
+ exchange_mapi_remove_esource(url, folder_name, fid, folder_type);
+ }
+ camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
+
+ return TRUE;
+}
+
+static gboolean
+mapi_store_noop_sync (CamelStore *store,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+camel_mapi_store_class_init (CamelMapiStoreClass *class)
+{
+ GObjectClass *object_class;
+ CamelServiceClass *service_class;
+ CamelStoreClass *store_class;
+
+ g_type_class_add_private (class, sizeof (CamelMapiStorePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = mapi_store_dispose;
+ object_class->finalize = mapi_store_finalize;
+
+ service_class = CAMEL_SERVICE_CLASS (class);
+ service_class->construct = mapi_construct;
+ service_class->get_name = mapi_get_name;
+ service_class->connect_sync = mapi_connect_sync;
+ service_class->disconnect_sync = mapi_disconnect_sync;
+ service_class->query_auth_types_sync = mapi_query_auth_types_sync;
+
+ store_class = CAMEL_STORE_CLASS (class);
+ store_class->hash_folder_name = mapi_store_hash_folder_name;
+ store_class->compare_folder_name = mapi_store_compare_folder_name;
+ store_class->can_refresh_folder = mapi_store_can_refresh_folder;
+ store_class->folder_is_subscribed = mapi_store_folder_is_subscribed;
+ store_class->free_folder_info = camel_store_free_folder_info_full;
+ store_class->get_folder_sync = mapi_store_get_folder_sync;
+ store_class->get_folder_info_sync = mapi_store_get_folder_info_sync;
+ store_class->get_junk_folder_sync = mapi_store_get_junk_folder_sync;
+ store_class->get_trash_folder_sync = mapi_store_get_trash_folder_sync;
+ store_class->create_folder_sync = mapi_store_create_folder_sync;
+ store_class->delete_folder_sync = mapi_store_delete_folder_sync;
+ store_class->rename_folder_sync = mapi_store_rename_folder_sync;
+ store_class->subscribe_folder_sync = mapi_store_subscribe_folder_sync;
+ store_class->unsubscribe_folder_sync = mapi_store_unsubscribe_folder_sync;
+ store_class->noop_sync = mapi_store_noop_sync;
+}
+
+/*
+** store is already initilyse to NULL or 0 value
+** class already have a parent_class
+** nothing must be doing here
+*/
+static void
+camel_mapi_store_init (CamelMapiStore *mapi_store)
+{
+ mapi_store->priv = CAMEL_MAPI_STORE_GET_PRIVATE (mapi_store);
+}
+
+/* service methods */
+static gboolean mapi_construct(CamelService *service, CamelSession *session,
+ CamelProvider *provider, CamelURL *url,
+ GError **error)
+{
+ CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (service);
+ CamelStore *store = CAMEL_STORE (service);
+ CamelMapiStorePrivate *priv = mapi_store->priv;
+ gchar *path = NULL;
+
+ if (!CAMEL_SERVICE_CLASS (camel_mapi_store_parent_class)->construct (service, session, provider, url, error))
+ return FALSE;
+
+ /*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);
+
+ mapi_store->summary = camel_mapi_store_summary_new ();
+ camel_store_summary_set_filename ((CamelStoreSummary *)mapi_store->summary, path);
+
+ camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
+ camel_store_summary_load ((CamelStoreSummary *) mapi_store->summary);
+
+ /*user and profile*/
+ priv->profile = g_strdup (camel_url_get_param(url, "profile"));
+
+ /*base url*/
+ priv->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
+ CAMEL_URL_HIDE_PARAMS |
+ CAMEL_URL_HIDE_AUTH) );
+
+ /*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); /* folder ID to folder Full name */
+ priv->name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* folder Full name to folder ID */
+ /*priv->parent_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); / * folder ID to its parent folder ID */
+ priv->default_folders = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free); /* default folder type to folder ID */
+ priv->container_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ store->flags &= ~CAMEL_STORE_VJUNK;
+ store->flags &= ~CAMEL_STORE_VTRASH;
+
+ store->flags |= CAMEL_STORE_SUBSCRIPTIONS | CAMEL_STORE_REAL_JUNK_FOLDER;
+
+ return TRUE;
+}
+
+static char
+*mapi_get_name(CamelService *service, gboolean brief)
+{
+ if (brief) {
+ /* Translators: The %s is replaced with a server's host name */
+ return g_strdup_printf(_("Exchange MAPI server %s"), service->url->host);
+ } else {
+ /*To translators : Example string : Exchange MAPI service for
+ _username_ on _server host name__*/
+ return g_strdup_printf(_("Exchange MAPI service for %s on %s"),
+ service->url->user, service->url->host);
+ }
+}
+
+static gboolean
+mapi_auth_loop (CamelService *service, GError **error)
+{
+ CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+ CamelSession *session = camel_service_get_session (service);
+
+ gchar *errbuf = NULL;
+ gboolean authenticated = FALSE;
+ guint32 prompt_flags = CAMEL_SESSION_PASSWORD_SECRET;
+
+ service->url->passwd = NULL;
+
+ while (!authenticated) {
+ GError *mapi_error = NULL;
+
+ if (errbuf) {
+ /* We need to un-cache the password before prompting again */
+ prompt_flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
+ g_free (service->url->passwd);
+ service->url->passwd = NULL;
+ }
+
+ if (!service->url->passwd ) {
+ gchar *prompt;
+
+ /*To translators : First %s : is the error text or the reason
+ for prompting the user if it is available.
+ Second %s is : Username.
+ Third %s is : Server host name.*/
+ prompt = g_strdup_printf (_("%s Please enter the MAPI password for %s %s"),
+ errbuf ? errbuf : "",
+ service->url->user,
+ service->url->host);
+ service->url->passwd =
+ camel_session_get_password (session, service, E_PASSWORD_COMPONENT,
+ prompt, "password", prompt_flags, NULL);
+ g_free (prompt);
+ g_free (errbuf);
+ errbuf = NULL;
+
+ if (!service->url->passwd) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ _("You did not enter a password."));
+ return FALSE;
+ }
+ }
+
+ store->priv->conn = exchange_mapi_connection_new (store->priv->profile, service->url->passwd, &mapi_error);
+ if (!store->priv->conn || !exchange_mapi_connection_connected (store->priv->conn)) {
+ if (mapi_error) {
+ errbuf = g_strdup_printf (_("Unable to authenticate to Exchange MAPI server: %s"), mapi_error->message);
+ g_error_free (mapi_error);
+ } else {
+ errbuf = g_strdup (_("Unable to authenticate to Exchange MAPI server"));
+ }
+ } else
+ authenticated = TRUE;
+
+ }
+ return TRUE;
+}
+
+static gboolean
+mapi_connect_sync (CamelService *service,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+ CamelMapiStorePrivate *priv = store->priv;
+ guint16 event_mask = 0;
+
+ if (service->status == CAMEL_SERVICE_DISCONNECTED) {
+ return FALSE;
+ }
+
+ if (!priv) {
+ store->priv = g_new0 (CamelMapiStorePrivate, 1);
+ priv = store->priv;
+ if (!camel_service_construct (service, service->session, service->provider, service->url, error))
+ return FALSE;
+ }
+
+ camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+ if (check_for_connection (service, NULL)) {
+ camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+ return TRUE;
+ }
+
+ if (!mapi_auth_loop (service, error)) {
+ camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+ camel_service_disconnect_sync (service, TRUE, NULL);
+ return FALSE;
+ }
+
+ service->status = CAMEL_SERVICE_CONNECTED;
+ camel_offline_store_set_online_sync (
+ CAMEL_OFFLINE_STORE (store), TRUE, cancellable, NULL);
+
+ /* Start event monitor */
+ event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted |
+ fnevObjectModified | fnevObjectMoved | fnevObjectCopied;
+
+ /* use MAPI_LISTEN_NOTIFY=1 to enable notifications */
+ if (!store->priv->notification_data && g_getenv ("MAPI_LISTEN_NOTIFY") != NULL)
+ store->priv->notification_data = camel_mapi_notification_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE);
+
+ camel_store_summary_save ((CamelStoreSummary *) store->summary);
+
+ camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ return TRUE;
+}
+
+void
+camel_mapi_store_unset_notification_data (CamelMapiStore *mstore)
+{
+ g_return_if_fail (mstore != NULL);
+ g_return_if_fail (CAMEL_IS_MAPI_STORE (mstore));
+
+ mstore->priv->notification_data = NULL;
+}
+
+static gboolean
+mapi_disconnect_sync (CamelService *service,
+ gboolean clean,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+
+ /* Disconnect from event monitor */
+ if (store->priv->notification_data) {
+ camel_mapi_notification_listener_stop (store, store->priv->notification_data);
+ store->priv->notification_data = NULL;
+ }
+
+ if (store->priv->conn) {
+ /* Close the mapi subsystem */
+ g_object_unref (store->priv->conn);
+ store->priv->conn = NULL;
+ }
+
+ store->priv->folders_synced = FALSE;
+
+ camel_offline_store_set_online_sync (
+ CAMEL_OFFLINE_STORE (store), FALSE, cancellable, NULL);
+ service->status = CAMEL_SERVICE_DISCONNECTED;
+
+ return TRUE;
+}
+
+static GList *
+mapi_query_auth_types_sync (CamelService *service,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return NULL;
+}
+
+static gboolean
+hash_check_fid_presence (gpointer key, gpointer value, gpointer folder_id)
+{
+ return (g_ascii_strcasecmp (value, folder_id) == 0);
+}
+
+static gboolean
+mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const gchar *fid)
+{
+ CamelMapiStorePrivate *priv = mapi_store->priv;
+
+ if (!(fid && *fid))
+ return FALSE;
+
+ return (g_hash_table_find (priv->default_folders, hash_check_fid_presence, (gpointer) fid) != NULL);
+}
+
+static const gchar *
+mapi_system_folder_fid (CamelMapiStore *mapi_store, gint folder_type)
+{
+ CamelMapiStorePrivate *priv = mapi_store->priv;
+
+ return g_hash_table_lookup (priv->default_folders, &folder_type);
+}
+
static guint32 hexnib(guint32 c)
{
if (c >= '0' && c <= '9')
@@ -1066,45 +1811,6 @@ camel_mapi_store_summary_path_to_full(CamelMapiStoreSummary *s, const gchar *pat
return f;
}
-//do we realy need this. move to utils then !
-static gint
-match_path(const gchar *path, const gchar *name)
-{
- gchar p, n;
-
- p = *path++;
- n = *name++;
- while (n && p) {
- if (n == p) {
- p = *path++;
- n = *name++;
- } else if (p == '%') {
- if (n != '/') {
- n = *name++;
- } else {
- p = *path++;
- }
- } else if (p == '*') {
- return TRUE;
- } else
- return FALSE;
- }
-
- return n == 0 && (p == '%' || p == 0);
-}
-
-static gchar *
-mapi_concat ( const gchar *prefix, const gchar *suffix)
-{
- gsize len;
-
- len = strlen (prefix);
- if (len == 0 || prefix[len - 1] == '/')
- return g_strdup_printf ("%s%s", prefix, suffix);
- else
- return g_strdup_printf ("%s%c%s", prefix, '/', suffix);
-}
-
static CamelFolderInfo *
mapi_build_folder_info(CamelMapiStore *mapi_store, const gchar *parent_name, const gchar *folder_name)
{
@@ -1145,197 +1851,11 @@ mapi_build_folder_info(CamelMapiStore *mapi_store, const gchar *parent_name, con
return fi;
}
-static CamelFolderInfo *
-mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
- guint32 flags, GError **error)
-{
- CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
- CamelFolderInfo *fi;
- GPtrArray *folders;
- gchar *path, *name;
- gint i;
- gboolean subscribed, favourites = FALSE, subscription_list = FALSE;
-
- subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
- subscribed = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED);
-
- folders = g_ptr_array_new ();
-
- if (top == NULL)
- top = "";
-
- /* get starting point */
- if (top[0] == 0) {
- name = g_strdup("");
- } else {
- name = camel_mapi_store_summary_full_from_path(mapi_store->summary, top);
- if (name == NULL)
- name = camel_mapi_store_summary_path_to_full(mapi_store->summary, top, '/');
- }
-
- path = mapi_concat (name, "*");
-
- for (i=0;i<camel_store_summary_count((CamelStoreSummary *)mapi_store->summary);i++) {
- CamelStoreInfo *si = camel_store_summary_index((CamelStoreSummary *)mapi_store->summary, i);
-
- if (si == NULL)
- continue;
-
- /* Allow only All Public Folders heirarchy */
- if (subscription_list && (!(si->flags & CAMEL_MAPI_FOLDER_PUBLIC))) {
- camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
- continue;
- }
-
- /*Allow Mailbox and Favourites (Subscribed public folders)*/
- if (subscribed && (!(si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))) {
- camel_store_summary_info_free ((CamelStoreSummary *)mapi_store->summary, si);
- continue;
- }
-
- if (!subscription_list && !(si->flags & CAMEL_MAPI_FOLDER_MAIL) && si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED &&
- si->flags & CAMEL_MAPI_FOLDER_PUBLIC)
- continue;
- if (!strcmp(name, camel_mapi_store_info_full_name (mapi_store->summary, si))
- || match_path (path, camel_mapi_store_info_full_name (mapi_store->summary, si))) {
-
- const gchar *store_info_path = camel_store_info_path((CamelStoreSummary *)mapi_store->summary, si);
- gchar *parent_name = NULL;
- const gchar *folder_name = NULL;
-
- /* TODO : UTF8 / i18n*/
- if (g_str_has_prefix (store_info_path, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) && subscribed) {
- parent_name = DISPLAY_NAME_FAVOURITES;
-
- folder_name = strrchr(store_info_path,'/');
- if (folder_name != NULL)
- store_info_path = ++folder_name;
-
- favourites = TRUE;
- }
-
- fi = mapi_build_folder_info(mapi_store, parent_name, store_info_path);
- if (favourites) {
- CamelURL *url;
- url = camel_url_new(mapi_store->priv->base_url,NULL);
- url->path = g_strdup_printf("/%s", camel_store_info_path((CamelStoreSummary *)mapi_store->summary, si));
- g_free (fi->uri);
- fi->uri = camel_url_to_string(url,CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
- }
-
- fi->unread = si->unread;
- fi->total = si->total;
- fi->flags = si->flags;
-
- g_ptr_array_add (folders, fi);
- }
- camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
- }
-
- if (!(subscription_list) && top[0] == '\0') {
- fi = mapi_build_folder_info(mapi_store, NULL, DISPLAY_NAME_FAVOURITES);
- fi->flags |= CAMEL_FOLDER_NOSELECT;
- fi->flags |= CAMEL_FOLDER_SYSTEM;
-
- g_ptr_array_add (folders, fi);
- }
-
- g_free(name);
- g_free (path);
- fi = camel_folder_info_build (folders, top, '/', TRUE);
- g_ptr_array_free (folders, TRUE);
- return fi;
-}
-
-static CamelFolderInfo *
-mapi_convert_to_folder_info (CamelMapiStore *store, ExchangeMAPIFolder *folder, const gchar *url, GError **error)
-{
- const gchar *name = NULL;
- gchar *parent, *id = NULL;
- mapi_id_t mapi_id_folder;
-
- const gchar *par_name = NULL;
- CamelFolderInfo *fi;
-
- name = exchange_mapi_folder_get_name (folder);
-
- id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid (folder));
-
- fi = camel_folder_info_new ();
-
- if (folder->is_default) {
- switch (folder->default_type) {
- case olFolderTopInformationStore:
- fi->flags |= CAMEL_FOLDER_NOSELECT;
- break;
- case olFolderInbox:
- fi->flags |= CAMEL_FOLDER_TYPE_INBOX;
- break;
- case olFolderSentMail:
- fi->flags |= CAMEL_FOLDER_TYPE_SENT;
- break;
- case olFolderDeletedItems:
- fi->flags |= CAMEL_FOLDER_TYPE_TRASH;
- break;
- case olFolderOutbox:
- fi->flags |= CAMEL_FOLDER_TYPE_OUTBOX;
- break;
- case olFolderJunk:
- fi->flags |= CAMEL_FOLDER_TYPE_JUNK;
- break;
- }
-
- fi->flags |= CAMEL_FOLDER_SYSTEM;
- }
-
- if (folder->category == MAPI_PERSONAL_FOLDER) {
- fi->flags |= CAMEL_MAPI_FOLDER_PERSONAL;
- fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED; /*Set this default for mailbox.*/
- } else if (folder->category == MAPI_FAVOURITE_FOLDER)
- fi->flags |= CAMEL_MAPI_FOLDER_PUBLIC;
-
- if (folder->child_count <=0)
- fi->flags |= CAMEL_FOLDER_NOCHILDREN;
- /*
- parent_hash contains the "parent id <-> folder id" combination. So we form
- the path for the full name in camelfolder info by looking up the hash table until
- NULL is found
- */
-
- mapi_id_folder = exchange_mapi_folder_get_parent_id (folder);
- parent = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", mapi_id_folder);
-
- fi->name = g_strdup (name);
-
- par_name = mapi_folders_hash_table_name_lookup (store, parent, TRUE);
- if (par_name != NULL) {
- gchar *str = g_strconcat (par_name, "/", name, NULL);
-
- fi->full_name = str; /* takes ownership of the string */
- fi->uri = g_strconcat (url, str, NULL);
- } else {
- fi->full_name = g_strdup (name);
- fi->uri = g_strconcat (url, "", name, NULL);
- }
-
- /*name_hash returns the container id given the name */
- mapi_update_folder_hash_tables (store, fi->full_name, id, parent);
-
- g_free (parent);
- g_free (id);
-
- fi->total = folder->total;
- fi->unread = folder->unread_count;
-
- return fi;
-}
-
gboolean
camel_mapi_store_connected (CamelMapiStore *store, GError **error)
{
- return (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL
- && camel_service_connect ((CamelService *)store, error));
+ return camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))
+ && camel_service_connect_sync ((CamelService *)store, error);
}
static void
@@ -1430,288 +1950,6 @@ mapi_folders_hash_table_fid_lookup (CamelMapiStore *store, const gchar *name,
}
#endif
-static void
-remove_path_from_store_summary (const gchar *path, gpointer value, CamelMapiStore *mstore)
-{
- const gchar *folder_id;
- CamelStoreInfo *si;
-
- g_return_if_fail (path != NULL);
- g_return_if_fail (mstore != NULL);
-
- folder_id = g_hash_table_lookup (mstore->priv->name_hash, path);
- if (folder_id) {
- /* name_hash as the second, because folder_id is from there */
- g_hash_table_remove (mstore->priv->id_hash, folder_id);
- g_hash_table_remove (mstore->priv->name_hash, path);
- }
-
- si = camel_store_summary_path ((CamelStoreSummary *)mstore->summary, path);
- if (si) {
- CamelFolderInfo *fi;
-
- fi = camel_folder_info_new ();
- fi->unread = -1;
- fi->total = -1;
- fi->uri = g_strdup (camel_store_info_uri (mstore->summary, si));
- fi->name = g_strdup (camel_store_info_name (mstore->summary, si));
- fi->full_name = g_strdup (camel_mapi_store_info_full_name (mstore->summary, si));
- if (!fi->name && fi->full_name) {
- fi->name = strrchr (fi->full_name, '/');
- if (fi->name)
- fi->name = g_strdup (fi->name + 1);
- }
-
- camel_store_folder_unsubscribed (CAMEL_STORE (mstore), fi);
- camel_store_folder_deleted (CAMEL_STORE (mstore), fi);
- camel_folder_info_free (fi);
-
- camel_store_summary_info_free ((CamelStoreSummary *)mstore->summary, si);
- }
-
- camel_store_summary_remove_path ((CamelStoreSummary *)mstore->summary, path);
-}
-
-static gboolean
-mapi_folders_sync (CamelMapiStore *store, guint32 flags, GError **error)
-{
- CamelMapiStorePrivate *priv = store->priv;
- gboolean status;
- GSList *folder_list = NULL, *temp_list = NULL, *list = NULL;
- gchar *url, *temp_url;
- gboolean subscription_list = FALSE;
- CamelFolderInfo *info = NULL;
- CamelMapiStoreInfo *mapi_si = NULL;
- guint32 count, i;
- CamelStoreInfo *si = NULL;
- GHashTable *old_cache_folders;
- GError *err = NULL;
-
- if (!camel_mapi_store_connected (store, NULL)) {
- g_set_error (
- error, CAMEL_SERVICE_ERROR,
- CAMEL_SERVICE_ERROR_UNAVAILABLE,
- _("Folder list not available in offline mode."));
- return FALSE;
- }
-
- status = exchange_mapi_connection_get_folders_list (priv->conn, &folder_list, &err);
-
- if (!status) {
- g_warning ("Could not get folder list (%s)\n", err ? err->message : "Unknown error");
- if (err)
- g_error_free (err);
- return TRUE;
- }
-
- /* remember all folders in cache before update */
- old_cache_folders = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- count = camel_store_summary_count ((CamelStoreSummary *)store->summary);
- for (i = 0; i < count; i++) {
- si = camel_store_summary_index ((CamelStoreSummary *)store->summary, i);
- if (si == NULL)
- continue;
-
- /* those whose left in old_cache_folders are removed at the end,
- which is not good for public folders, thus preserve them from
- an automatic removal */
- if ((si->flags & CAMEL_MAPI_FOLDER_PUBLIC) == 0 || (si->flags & CAMEL_FOLDER_SUBSCRIBED) == 0)
- g_hash_table_insert (old_cache_folders, g_strdup (camel_store_info_path (store->summary, si)), GINT_TO_POINTER (1));
-
- camel_store_summary_info_free ((CamelStoreSummary *)store->summary, si);
- }
-
- subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
- if (subscription_list) {
- GError *err = NULL;
-
- /*Consult the name <-> fid hash table for a FID.*/
- status = exchange_mapi_connection_get_pf_folders_list (priv->conn, &folder_list, &err);
- if (!status)
- g_warning ("Could not get Public folder list (%s)\n", err ? err->message : "Unknown error");
-
- if (err)
- g_error_free (err);
- }
-
- temp_list = folder_list;
- list = folder_list;
-
- url = camel_url_to_string (CAMEL_SERVICE(store)->url,
- (CAMEL_URL_HIDE_PASSWORD|
- CAMEL_URL_HIDE_PARAMS|
- CAMEL_URL_HIDE_AUTH));
- if ( url[strlen(url) - 1] != '/') {
- temp_url = g_strconcat (url, "/", NULL);
- g_free ((gchar *)url);
- url = temp_url;
- }
-
- /*populate the hash table for finding the mapping from container id <-> folder name*/
- for (;temp_list != NULL; temp_list = g_slist_next (temp_list) ) {
- const gchar *full_name = NULL;
- gchar *fid = NULL, *parent_id = NULL, *tmp = NULL;
- guint *folder_type = g_new0 (guint, 1);
-
- fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(temp_list->data)));
- parent_id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_parent_id ((ExchangeMAPIFolder *)(temp_list->data)));
- full_name = g_hash_table_lookup (priv->id_hash, fid);
- if (!full_name) {
- const gchar *par_full_name;
-
- par_full_name = g_hash_table_lookup (priv->id_hash, parent_id);
- if (par_full_name) {
- tmp = g_strconcat (par_full_name, "/", exchange_mapi_folder_get_name (temp_list->data), NULL);
- full_name = tmp;
- } else {
- full_name = exchange_mapi_folder_get_name (temp_list->data);
- }
- }
-
- /* remove from here; what lefts is not on the server any more */
- g_hash_table_remove (old_cache_folders, full_name);
- *folder_type = ((ExchangeMAPIFolder *)(temp_list->data))->container_class;
- mapi_update_folder_hash_tables (store, full_name, fid, parent_id);
- mapi_update_hash_table_type (store, full_name, folder_type);
- if (((ExchangeMAPIFolder *)(temp_list->data))->is_default) {
- guint *type = g_new0 (guint, 1);
- *type = ((ExchangeMAPIFolder *)(temp_list->data))->default_type;
- g_hash_table_insert (priv->default_folders, type,
- g_strdup(fid));
- }
- g_free (fid);
- g_free (parent_id);
- g_free (tmp);
- }
-
- for (;folder_list != NULL; folder_list = g_slist_next (folder_list)) {
- ExchangeMAPIFolder *folder = (ExchangeMAPIFolder *) folder_list->data;
-
- if (folder->default_type == olPublicFoldersAllPublicFolders)
- continue;
-
- if ( folder->container_class == MAPI_FOLDER_TYPE_MAIL) {
- info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, NULL);
- info->flags |= CAMEL_MAPI_FOLDER_MAIL;
- mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
-
- if (!mapi_si) {
- gchar *fid, *pfid = NULL;
-
- fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
- exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
- pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
- exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
-
- mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
- g_free (fid);
- g_free (pfid);
- if (mapi_si == NULL)
- continue;
-
- camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
-
- if (!subscription_list) {
- camel_store_folder_created (CAMEL_STORE (store), info);
- camel_store_folder_subscribed (CAMEL_STORE (store), info);
- }
- }
-
- mapi_si->info.flags |= info->flags;
- mapi_si->info.total = info->total;
- mapi_si->info.unread = info->unread;
-
- camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
- camel_folder_info_free (info);
- } else if (folder->category == MAPI_FAVOURITE_FOLDER) {
- gchar *fid, *pfid = NULL;
- info = mapi_convert_to_folder_info (store, folder, (const gchar *)url, NULL);
- mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name);
- fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
- exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
- pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X",
- exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
- mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
- g_free (fid);
- g_free (pfid);
-
- if (mapi_si == NULL)
- continue;
-
- camel_store_summary_info_ref ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
- mapi_si->info.flags |= info->flags;
- camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)mapi_si);
- camel_folder_info_free (info);
- }
- }
-
- /* Weed out deleted folders */
- g_hash_table_foreach (old_cache_folders, (GHFunc) remove_path_from_store_summary, store);
- g_hash_table_destroy (old_cache_folders);
-
- camel_store_summary_touch ((CamelStoreSummary *)store->summary);
- camel_store_summary_save ((CamelStoreSummary *)store->summary);
-
- g_free (url);
-
- g_slist_foreach (list, (GFunc) exchange_mapi_folder_free, NULL);
- g_slist_free (list);
-
- priv->folders_synced = TRUE;
-
- // g_hash_table_foreach (present, get_folders_free, NULL);
- // g_hash_table_destroy (present);
-
- /* FIXME : This place is not right! */
- /* Start Push Notification listener */
- /* event_mask = fnevNewMail | fnevObjectCreated | fnevObjectDeleted | */
- /* fnevObjectModified | fnevObjectMoved | fnevObjectCopied; */
-
- /* camel_mapi_notfication_listener_start (store, event_mask, MAPI_EVENTS_USE_STORE); */
-
- return TRUE;
-}
-
-static CamelFolderInfo*
-mapi_get_folder_info(CamelStore *store, const gchar *top, guint32 flags, GError **error)
-{
- CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
-
- /*
- * Thanks to Michael, for his cached folders implementation in IMAP
- * is used as is here.
- */
-
- camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
- if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL) {
- if (((CamelService *)store)->status == CAMEL_SERVICE_DISCONNECTED) {
- ((CamelService *)store)->status = CAMEL_SERVICE_CONNECTING;
- mapi_connect ((CamelService *)store, NULL);
- }
- }
-
- /* update folders from the server only when asking for the top most or the 'top' is not known;
- otherwise believe the local cache, because folders sync is pretty slow operation to be done
- one every single question on the folder info */
- if (((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) != 0 ||
- (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) ||
- (!mapi_store->priv->folders_synced) ||
- (top && *top && !camel_mapi_store_folder_id_lookup (mapi_store, top))) &&
- (check_for_connection ((CamelService *)store, NULL) || ((CamelService *)store)->status == CAMEL_SERVICE_CONNECTING)) {
- if (!mapi_folders_sync (mapi_store, flags, error)) {
- camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- return NULL;
- }
- camel_store_summary_touch ((CamelStoreSummary *)mapi_store->summary);
- camel_store_summary_save ((CamelStoreSummary *)mapi_store->summary);
- }
-
- camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-
- return mapi_get_folder_info_offline (store, top, flags, error);
-}
-
const gchar *
camel_mapi_store_folder_id_lookup_offline (CamelMapiStore *mapi_store, const gchar *folder_name)
{
@@ -1762,133 +2000,6 @@ camel_mapi_store_get_profile_name (CamelMapiStore *mapi_store)
return priv->profile;
}
-static gboolean
-mapi_subscribe_folder(CamelStore *store, const gchar *folder_name, GError **error)
-{
- CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
- CamelFolderInfo *fi;
- CamelStoreInfo *si = NULL;
- const gchar *parent_name = NULL, *use_folder_name = folder_name, *fid = NULL;
- gboolean favourites = FALSE;
- /* TODO : exchange_mapi_add_to_favorites (); */
-
- fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
-
- if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
- const gchar *f_name = NULL;
-
- parent_name = DISPLAY_NAME_FAVOURITES;
-
- f_name = strrchr (folder_name,'/');
- if (!f_name) {
- /* Don't process All Public Folder. */
- return TRUE;
- }
-
- use_folder_name = ++f_name;
- favourites = TRUE;
- }
- si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
-
- if (si != NULL) {
- if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
- si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
- si->flags |= CAMEL_FOLDER_SUBSCRIBED;
- camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
- }
- }
-
- if (si->flags & CAMEL_MAPI_FOLDER_MAIL) {
- fi = mapi_build_folder_info (mapi_store, parent_name, use_folder_name);
- if (favourites) {
- CamelURL *url;
- url = camel_url_new (mapi_store->priv->base_url, NULL);
- url->path = g_strdup_printf ("/%s", camel_store_info_path (mapi_store->summary, si));
- g_free (fi->uri);
- fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
- }
-
- fi->unread = si->unread;
- fi->total = si->total;
- fi->flags = si->flags;
- fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
- fi->flags |= CAMEL_FOLDER_NOCHILDREN;
- fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
- camel_store_folder_subscribed (store, fi);
- camel_folder_info_free (fi);
- } else {
- guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, folder_name);
- exchange_mapi_add_esource (CAMEL_SERVICE(mapi_store)->url, use_folder_name, fid, folder_type);
- }
- camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
- return TRUE;
-}
-
-static gboolean
-mapi_folder_is_subscribed (CamelStore *store, const gchar *folder_name)
-{
- CamelMapiStore *mapi_store = (CamelMapiStore *) store;
- CamelStoreInfo *si;
- gint truth = FALSE;
-
- if ((si = camel_store_summary_path ((CamelStoreSummary *) mapi_store->summary, folder_name))) {
- truth = (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) != 0;
- camel_store_summary_info_free ((CamelStoreSummary *) mapi_store->summary, si);
- }
-
- return truth;
-}
-
-static gboolean
-mapi_unsubscribe_folder(CamelStore *store, const gchar *folder_name, GError **error)
-{
- CamelFolderInfo *fi;
- CamelStoreInfo *si;
- gchar *parent_name = NULL;
- const gchar *fid = NULL, *use_folder_name = folder_name;
- gchar *f_name = NULL;
-
- CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
- CamelURL *url = CAMEL_SERVICE (mapi_store)->url;
- fid = camel_mapi_store_folder_id_lookup(mapi_store, folder_name);
- si = camel_store_summary_path((CamelStoreSummary *)mapi_store->summary, folder_name);
- if (si) {
- if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
- si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
- camel_store_summary_touch((CamelStoreSummary *)mapi_store->summary);
- camel_store_summary_save((CamelStoreSummary *)mapi_store->summary);
- }
- }
-
- if (g_str_has_prefix (folder_name, DISPLAY_NAME_ALL_PUBLIC_FOLDERS) ) {
- parent_name = DISPLAY_NAME_FAVOURITES;
-
- f_name = strrchr(folder_name,'/');
- if (f_name != NULL)
- folder_name = ++f_name;
- else //Don't process All Public Folder.
- return TRUE;
- }
- if (si->flags & CAMEL_MAPI_FOLDER_MAIL) {
- fi = mapi_build_folder_info (mapi_store, parent_name, folder_name);
- camel_store_folder_unsubscribed (store, fi);
- camel_folder_info_free (fi);
- } else {
- guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, use_folder_name);
- exchange_mapi_remove_esource(url, folder_name, fid, folder_type);
- }
- camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
-
- return TRUE;
-}
-
-static gboolean
-mapi_noop(CamelStore *store, GError **error)
-{
- return TRUE;
-}
-
ExchangeMapiConnection *
camel_mapi_store_get_exchange_connection (CamelMapiStore *mapi_store)
{
@@ -1899,70 +2010,3 @@ camel_mapi_store_get_exchange_connection (CamelMapiStore *mapi_store)
return mapi_store->priv->conn;
}
-static CamelFolder *
-mapi_get_folder_with_type (CamelStore *store, guint folder_type, GError **error)
-{
- CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
- CamelFolderInfo *all_fi, *fi;
- CamelFolder *folder = NULL;
-
- g_return_val_if_fail (mapi_store != NULL, NULL);
- g_return_val_if_fail (mapi_store->priv != NULL, NULL);
-
- all_fi = camel_store_get_folder_info (
- store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE, error);
- if (all_fi == NULL)
- return NULL;
-
- fi = all_fi;
- while (fi) {
- CamelFolderInfo *next;
-
- if ((fi->flags & CAMEL_FOLDER_TYPE_MASK) == folder_type) {
- folder = camel_store_get_folder (store, fi->full_name, 0, error);
- break;
- }
-
- /* move to the next, depth-first search */
- next = fi->child;
- if (!next)
- next = fi->next;
- if (!next) {
- next = fi->parent;
- while (next) {
- CamelFolderInfo *sibl = next->next;
- if (sibl) {
- next = sibl;
- break;
- } else {
- next = next->parent;
- }
- }
- }
-
- fi = next;
- }
-
- camel_store_free_folder_info (store, all_fi);
-
- return folder;
-}
-
-static CamelFolder *
-mapi_get_trash (CamelStore *store, GError **error)
-{
- return mapi_get_folder_with_type (store, CAMEL_FOLDER_TYPE_TRASH, error);
-}
-
-static CamelFolder *
-mapi_get_junk (CamelStore *store, GError **error)
-{
- return mapi_get_folder_with_type (store, CAMEL_FOLDER_TYPE_JUNK, error);
-}
-
-static gboolean
-mapi_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **error)
-{
- return CAMEL_STORE_CLASS(camel_mapi_store_parent_class)->can_refresh_folder (store, info, error) ||
- (camel_url_get_param (((CamelService *)store)->url, "check_all") != NULL);
-}
diff --git a/src/camel/camel-mapi-transport.c b/src/camel/camel-mapi-transport.c
index 1467a1e..c322a1c 100644
--- a/src/camel/camel-mapi-transport.c
+++ b/src/camel/camel-mapi-transport.c
@@ -71,8 +71,12 @@ mapi_message_item_send (ExchangeMapiConnection *conn, MailItem *item, GError **p
}
static gboolean
-mapi_send_to (CamelTransport *transport, CamelMimeMessage *message,
- CamelAddress *from, CamelAddress *recipients, GError **error)
+mapi_send_to_sync (CamelTransport *transport,
+ CamelMimeMessage *message,
+ CamelAddress *from,
+ CamelAddress *recipients,
+ GCancellable *cancellable,
+ GError **error)
{
ExchangeMapiConnection *conn;
MailItem *item = NULL;
@@ -101,7 +105,7 @@ mapi_send_to (CamelTransport *transport, CamelMimeMessage *message,
}
/* Convert MIME to MailItem, attacment lists and recipient list.*/
- item = camel_mapi_utils_mime_to_item (message, from, NULL);
+ item = camel_mapi_utils_mime_to_item (message, from, cancellable, NULL);
/* send */
st = mapi_message_item_send (conn, item, error);
@@ -148,7 +152,7 @@ camel_mapi_transport_class_init (CamelMapiTransportClass *class)
service_class->get_name = mapi_transport_get_name;
transport_class = CAMEL_TRANSPORT_CLASS (class);
- transport_class->send_to = mapi_send_to;
+ transport_class->send_to_sync = mapi_send_to_sync;
}
static void
diff --git a/src/camel/camel-mapi-utils.c b/src/camel/camel-mapi-utils.c
index 863f01e..889d157 100644
--- a/src/camel/camel-mapi-utils.c
+++ b/src/camel/camel-mapi-utils.c
@@ -118,7 +118,7 @@ mail_item_set_subject(MailItem *item, const gchar *subject)
#define MAX_READ_SIZE 0x1000
static void
-mail_item_set_body_stream (MailItem *item, CamelStream *body, MailItemPartType part_type)
+mail_item_set_body_stream (MailItem *item, CamelStream *body, MailItemPartType part_type, GCancellable *cancellable)
{
guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
guint32 read_size = 0, i;
@@ -129,7 +129,7 @@ mail_item_set_body_stream (MailItem *item, CamelStream *body, MailItemPartType p
stream->value = g_byte_array_new ();
- while (read_size = camel_stream_read (body, (gchar *)buf, STREAM_SIZE, NULL), read_size > 0) {
+ while (read_size = camel_stream_read (body, (gchar *)buf, STREAM_SIZE, cancellable, NULL), read_size > 0) {
stream->value = g_byte_array_append (stream->value, buf, read_size);
is_null_terminated = buf [read_size - 1] == 0;
@@ -186,7 +186,7 @@ mail_item_set_body_stream (MailItem *item, CamelStream *body, MailItemPartType p
}
static gboolean
-mail_item_add_attach (MailItem *item, CamelMimePart *part, CamelStream *content_stream)
+mail_item_add_attach (MailItem *item, CamelMimePart *part, CamelStream *content_stream, GCancellable *cancellable)
{
guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
const gchar *content_id = NULL;
@@ -248,7 +248,7 @@ mail_item_add_attach (MailItem *item, CamelMimePart *part, CamelStream *content_
stream->value = g_byte_array_new ();
camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET, NULL);
- while (read_size = camel_stream_read(content_stream, (gchar *)buf, STREAM_SIZE, NULL), read_size > 0) {
+ while (read_size = camel_stream_read(content_stream, (gchar *)buf, STREAM_SIZE, cancellable, NULL), read_size > 0) {
stream->value = g_byte_array_append (stream->value, buf, read_size);
}
@@ -259,7 +259,7 @@ mail_item_add_attach (MailItem *item, CamelMimePart *part, CamelStream *content_
}
static gboolean
-mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
+mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first, GCancellable *cancellable)
{
CamelDataWrapper *dw;
CamelStream *content_stream;
@@ -280,7 +280,7 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
dw = camel_medium_get_content (CAMEL_MEDIUM (part));
if (CAMEL_IS_MULTIPART(dw)) {
/* recursive */
- if (!mapi_do_multipart (CAMEL_MULTIPART (dw), item, is_first))
+ if (!mapi_do_multipart (CAMEL_MULTIPART (dw), item, is_first, cancellable))
return FALSE;
continue;
}
@@ -288,7 +288,8 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
filename = camel_mime_part_get_filename(part);
content_stream = camel_stream_mem_new();
- content_size = camel_data_wrapper_decode_to_stream (dw, (CamelStream *) content_stream, NULL);
+ content_size = camel_data_wrapper_decode_to_stream_sync (
+ dw, (CamelStream *) content_stream, cancellable, NULL);
camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET, NULL);
@@ -298,12 +299,12 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
type = camel_mime_part_get_content_type(part);
if (i_part == 0 && (*is_first) && camel_content_type_is (type, "text", "plain")) {
- mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
+ mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT, cancellable);
*is_first = FALSE;
} else if (camel_content_type_is (type, "text", "html")) {
- mail_item_set_body_stream (item, content_stream, PART_TYPE_TEXT_HTML);
+ mail_item_set_body_stream (item, content_stream, PART_TYPE_TEXT_HTML, cancellable);
} else {
- mail_item_add_attach (item, part, content_stream);
+ mail_item_add_attach (item, part, content_stream, cancellable);
}
}
@@ -311,7 +312,7 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first)
}
MailItem *
-camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GError **error)
+camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GCancellable *cancellable, GError **error)
{
CamelDataWrapper *dw = NULL;
CamelContentType *type;
@@ -371,7 +372,7 @@ camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GE
if (CAMEL_IS_MULTIPART(multipart)) {
gboolean is_first = TRUE;
- if (!mapi_do_multipart (CAMEL_MULTIPART(multipart), item, &is_first))
+ if (!mapi_do_multipart (CAMEL_MULTIPART(multipart), item, &is_first, cancellable))
printf("camel message multi part error\n");
} else {
dw = camel_medium_get_content (CAMEL_MEDIUM (message));
@@ -380,9 +381,10 @@ camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GE
content_type = camel_content_type_simple (type);
content_stream = (CamelStream *)camel_stream_mem_new();
- content_size = camel_data_wrapper_decode_to_stream(dw, (CamelStream *)content_stream, NULL);
+ content_size = camel_data_wrapper_decode_to_stream_sync (
+ dw, (CamelStream *)content_stream, cancellable, NULL);
- mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
+ mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT, cancellable);
}
}
diff --git a/src/camel/camel-mapi-utils.h b/src/camel/camel-mapi-utils.h
index 6205b72..4aa59cf 100644
--- a/src/camel/camel-mapi-utils.h
+++ b/src/camel/camel-mapi-utils.h
@@ -31,7 +31,7 @@ G_BEGIN_DECLS
#include <camel/camel.h>
MailItem *
-camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GError **error);
+camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, GCancellable *cancellable, GError **error);
gboolean
camel_mapi_utils_create_item_build_props (ExchangeMapiConnection *conn, mapi_id_t fid, TALLOC_CTX *mem_ctx, struct SPropValue **values, uint32_t *n_values, gpointer data);
diff --git a/src/libexchangemapi/exchange-mapi-connection.c b/src/libexchangemapi/exchange-mapi-connection.c
index d39e6c1..45c9976 100644
--- a/src/libexchangemapi/exchange-mapi-connection.c
+++ b/src/libexchangemapi/exchange-mapi-connection.c
@@ -908,7 +908,8 @@ obj_message_to_camel_mime (ExchangeMapiConnection *conn, mapi_id_t fid, mapi_obj
mem = camel_stream_mem_new ();
camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (mem), res);
- camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (msg), mem, NULL);
+ camel_data_wrapper_write_to_stream_sync (
+ CAMEL_DATA_WRAPPER (msg), mem, NULL, NULL);
g_object_unref (mem);
g_object_unref (msg);
diff --git a/src/libexchangemapi/exchange-mapi-mail-utils.c b/src/libexchangemapi/exchange-mapi-mail-utils.c
index 29a0e09..e608753 100644
--- a/src/libexchangemapi/exchange-mapi-mail-utils.c
+++ b/src/libexchangemapi/exchange-mapi-mail-utils.c
@@ -384,7 +384,7 @@ mapi_mime_set_msg_headers (ExchangeMapiConnection *conn, CamelMimeMessage *msg,
camel_mime_parser_scan_from (parser, FALSE);
g_object_unref (stream);
- if (camel_mime_part_construct_from_parser (part, parser, NULL) != -1) {
+ if (camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) {
struct _camel_header_raw *h;
for (h = part->headers; h; h = h->next) {
@@ -783,7 +783,7 @@ mapi_mime_classify_attachments (ExchangeMapiConnection *conn, mapi_id_t fid, con
CamelStream *mem;
mem = camel_stream_mem_new ();
- camel_stream_write (mem, (const gchar *) stream->value->data, stream->value->len, NULL);
+ camel_stream_write (mem, (const gchar *) stream->value->data, stream->value->len, NULL, NULL);
camel_stream_reset (mem, NULL);
parser = camel_mime_parser_new ();
@@ -797,7 +797,7 @@ mapi_mime_classify_attachments (ExchangeMapiConnection *conn, mapi_id_t fid, con
part = camel_mime_part_new ();
camel_data_wrapper_set_mime_type_field (CAMEL_DATA_WRAPPER (part), camel_mime_parser_content_type (parser));
- camel_mime_part_construct_content_from_parser (part, parser, NULL);
+ camel_mime_part_construct_content_from_parser (part, parser, NULL, NULL);
} else {
is_smime = FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]