[evolution-mapi] Different approach for CamelMapiFolder's summary fetching
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Different approach for CamelMapiFolder's summary fetching
- Date: Tue, 8 Nov 2011 10:11:28 +0000 (UTC)
commit 98a632f7c9cb532ec05119160a8945b9de4b65fb
Author: Milan Crha <mcrha redhat com>
Date: Tue Nov 8 11:09:58 2011 +0100
Different approach for CamelMapiFolder's summary fetching
src/camel/camel-mapi-folder-summary.c | 59 +--
src/camel/camel-mapi-folder-summary.h | 9 +-
src/camel/camel-mapi-folder.c | 961 +++++++++++++++----------------
src/camel/camel-mapi-folder.h | 5 +-
src/camel/camel-mapi-notifications.c | 43 +--
src/camel/camel-mapi-store-summary.c | 20 +-
src/camel/camel-mapi-store-summary.h | 10 +-
src/camel/camel-mapi-store.c | 33 +-
src/libexchangemapi/e-mapi-connection.c | 175 ++++++
src/libexchangemapi/e-mapi-connection.h | 8 +
10 files changed, 700 insertions(+), 623 deletions(-)
---
diff --git a/src/camel/camel-mapi-folder-summary.c b/src/camel/camel-mapi-folder-summary.c
index 9082c3d..ae49547 100644
--- a/src/camel/camel-mapi-folder-summary.c
+++ b/src/camel/camel-mapi-folder-summary.c
@@ -54,10 +54,6 @@ G_DEFINE_TYPE (CamelMapiFolderSummary, camel_mapi_folder_summary, CAMEL_TYPE_FOL
static void
mapi_summary_finalize (GObject *object)
{
- CamelMapiFolderSummary *mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY (object);
-
- g_free (mapi_summary->sync_time_stamp);
-
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_mapi_folder_summary_parent_class)->finalize (object);
}
@@ -74,6 +70,7 @@ mapi_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
to = (CamelMapiMessageInfo *)folder_summary_class->message_info_clone(s, mi);
to->server_flags = from->server_flags;
+ to->last_modified = from->last_modified;
/* FIXME: parent clone should do this */
to->info.content = camel_folder_summary_content_info_new(s);
@@ -105,6 +102,7 @@ camel_mapi_folder_summary_class_init (CamelMapiFolderSummaryClass *class)
static void
camel_mapi_folder_summary_init (CamelMapiFolderSummary *mapi_summary)
{
+ mapi_summary->latest_last_modify = 0;
}
/**
@@ -124,7 +122,7 @@ camel_mapi_folder_summary_new (CamelFolder *folder, const gchar *filename)
summary = g_object_new (CAMEL_TYPE_MAPI_FOLDER_SUMMARY, "folder", folder, NULL);
- camel_folder_summary_set_build_content (summary, TRUE);
+ camel_folder_summary_set_build_content (summary, FALSE);
camel_folder_summary_set_filename (summary, filename);
if (!camel_folder_summary_load_from_db (summary, &local_error)) {
@@ -139,44 +137,6 @@ camel_mapi_folder_summary_new (CamelFolder *folder, const gchar *filename)
return summary;
}
-void
-camel_mapi_folder_summary_update_store_info_counts (CamelMapiFolderSummary *mapi_summary)
-{
- CamelFolderSummary *summary;
-
- g_return_if_fail (mapi_summary != NULL);
-
- summary = CAMEL_FOLDER_SUMMARY (mapi_summary);
- g_return_if_fail (summary != NULL);
-
- if (camel_folder_summary_get_folder (summary)) {
- CamelMapiStore *mapi_store;
-
- mapi_store = CAMEL_MAPI_STORE (camel_folder_get_parent_store (camel_folder_summary_get_folder (summary)));
- if (mapi_store && mapi_store->summary) {
- CamelStoreInfo *si;
- CamelStoreSummary *store_summary = CAMEL_STORE_SUMMARY (mapi_store->summary);
- CamelFolder*folder;
-
- g_return_if_fail (store_summary != NULL);
-
- folder = camel_folder_summary_get_folder (summary);
- si = camel_store_summary_path (store_summary, camel_folder_get_full_name (folder));
- if (si) {
- if (si->unread != camel_folder_summary_get_unread_count (summary) ||
- si->total != camel_folder_summary_get_saved_count (summary)) {
- si->unread = camel_folder_summary_get_unread_count (summary);
- si->total = camel_folder_summary_get_saved_count (summary);
-
- camel_store_summary_touch (store_summary);
- }
-
- camel_store_summary_info_free (store_summary, si);
- }
- }
- }
-}
-
static gboolean
mapi_summary_header_from_db (CamelFolderSummary *summary, CamelFIRecord *fir)
{
@@ -195,18 +155,12 @@ mapi_summary_header_from_db (CamelFolderSummary *summary, CamelFIRecord *fir)
if (part)
mapi_summary->version = bdata_extract_digit (&part);
- if (part && *part && part++) {
- g_free (mapi_summary->sync_time_stamp);
- mapi_summary->sync_time_stamp = g_strdup (part);
- }
-
return TRUE;
}
static CamelFIRecord *
mapi_summary_header_to_db (CamelFolderSummary *summary, GError **error)
{
- CamelMapiFolderSummary *mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY(summary);
CamelFolderSummaryClass *folder_summary_class;
struct _CamelFIRecord *fir;
@@ -218,9 +172,7 @@ mapi_summary_header_to_db (CamelFolderSummary *summary, GError **error)
if (!fir)
return NULL;
- fir->bdata = g_strdup_printf ("%d %s", CAMEL_MAPI_FOLDER_SUMMARY_VERSION, mapi_summary->sync_time_stamp);
-
- camel_mapi_folder_summary_update_store_info_counts (mapi_summary);
+ fir->bdata = g_strdup_printf ("%d", CAMEL_MAPI_FOLDER_SUMMARY_VERSION);
return fir;
}
@@ -242,6 +194,7 @@ mapi_message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
m_info = (CamelMapiMessageInfo *) info;
m_info->server_flags = bdata_extract_digit (&part);
+ m_info->last_modified = bdata_extract_digit (&part);
}
}
@@ -260,7 +213,7 @@ mapi_message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info)
mir = folder_summary_class->message_info_to_db (s, info);
if (mir)
- mir->bdata = g_strdup_printf ("%u", m_info->server_flags);
+ mir->bdata = g_strdup_printf ("%u %u", m_info->server_flags, (guint32) m_info->last_modified);
return mir;
}
diff --git a/src/camel/camel-mapi-folder-summary.h b/src/camel/camel-mapi-folder-summary.h
index 713619d..e6e023f 100644
--- a/src/camel/camel-mapi-folder-summary.h
+++ b/src/camel/camel-mapi-folder-summary.h
@@ -52,16 +52,11 @@ typedef struct _CamelMapiFolderSummaryClass CamelMapiFolderSummaryClass;
typedef struct _CamelMapiMessageInfo CamelMapiMessageInfo;
typedef struct _CamelMapiMessageContentInfo CamelMapiMessageContentInfo;
-/* extra summary flags*/
-enum {
- CAMEL_GW_MESSAGE_JUNK = 1<<17,
- CAMEL_GW_MESSAGE_NOJUNK = 1<<18,
-};
-
struct _CamelMapiMessageInfo {
CamelMessageInfoBase info;
guint32 server_flags;
+ time_t last_modified; /* PidTagLastModificationTime of this message */
};
struct _CamelMapiMessageContentInfo {
@@ -71,7 +66,7 @@ struct _CamelMapiMessageContentInfo {
struct _CamelMapiFolderSummary {
CamelFolderSummary parent;
- gchar *sync_time_stamp;
+ time_t latest_last_modify;
guint32 version;
guint32 validity;
};
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index bb2c1f2..4c3221b 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -51,9 +51,7 @@ extern gint camel_application_is_exiting;
struct _CamelMapiFolderPrivate {
-//#ifdef ENABLE_THREADS
GStaticMutex search_lock; /* for locking the search object */
-//#endif
};
@@ -107,136 +105,6 @@ mapi_folder_search_by_uids (CamelFolder *folder, const gchar *expression, GPtrAr
return matches;
}
-static gboolean
-update_store_summary (CamelFolder *folder, GError **error)
-{
- CamelStore *parent_store;
- CamelStoreSummary *store_summary;
- CamelStoreInfo *si;
- const gchar *full_name;
- gboolean retval;
-
- full_name = camel_folder_get_full_name (folder);
- parent_store = camel_folder_get_parent_store (folder);
- store_summary = ((CamelMapiStore *) parent_store)->summary;
-
- si = camel_store_summary_path (store_summary, full_name);
-
- if (si) {
- guint32 unread, total;
-
- unread = camel_folder_summary_get_unread_count (folder->summary);
- total = camel_folder_summary_count (folder->summary);
-
- if (si->total != total || si->unread != unread) {
- si->total = total;
- si->unread = unread;
- camel_store_summary_touch (store_summary);
- }
- camel_store_summary_info_free (store_summary, si);
- }
-
- retval = camel_folder_summary_save_to_db (folder->summary, error);
- camel_store_summary_save (store_summary);
-
- return retval;
-}
-
-static gboolean
-fetch_items_summary_cb (FetchItemsCallbackData *item_data,
- gpointer data,
- GCancellable *cancellable,
- GError **perror)
-{
- fetch_items_data *fi_data = (fetch_items_data *)data;
-
- GSList **slist = &(fi_data->items_list);
-
- long *flags = NULL;
- struct FILETIME *delivery_date = NULL;
- struct FILETIME *last_modification_time = NULL;
- struct timeval item_modification_time = { 0 };
- struct timeval fi_data_mod_time = { 0 };
- guint32 j = 0;
-
- MailItem *item = g_new0(MailItem , 1);
-
- if (camel_debug_start("mapi:folder")) {
- e_mapi_debug_dump_properties (item_data->conn, item_data->fid, item_data->properties, 3);
- camel_debug_end();
- }
-
- item->fid = item_data->fid;
- item->mid = item_data->mid;
-
- /*Hold a reference to Recipient List*/
- item->recipients = item_data->recipients;
-
- for (j = 0; j < item_data->properties->cValues; j++) {
- gconstpointer prop_data = get_mapi_SPropValue_data(&item_data->properties->lpProps[j]);
-
- if (fetch_read_item_common_data (item, item_data->properties->lpProps[j].ulPropTag, prop_data))
- continue;
-
- switch (item_data->properties->lpProps[j].ulPropTag) {
- case PR_MESSAGE_DELIVERY_TIME:
- delivery_date = (struct FILETIME *) prop_data;
- break;
- case PR_LAST_MODIFICATION_TIME:
- last_modification_time = (struct FILETIME *) prop_data;
- break;
- case PR_MESSAGE_FLAGS:
- flags = (long *) prop_data;
- break;
- default:
- break;
- }
- }
-
- /* item->header.from = camel_internet_address_format_address (from_name, from_email); */
-
- if (delivery_date) {
- item->header.recieved_time = e_mapi_util_filetime_to_time_t (delivery_date);
- }
-
- if (last_modification_time) {
- item_modification_time.tv_sec = e_mapi_util_filetime_to_time_t (last_modification_time);
- item_modification_time.tv_usec = 0;
- }
-
- fi_data_mod_time.tv_sec = fi_data->last_modification_time.tv_sec;
- fi_data_mod_time.tv_usec = fi_data->last_modification_time.tv_usec;
-
- if (timeval_compare (&item_modification_time, &fi_data_mod_time) == 1) {
- fi_data->last_modification_time.tv_sec = item_modification_time.tv_sec;
- fi_data->last_modification_time.tv_usec = item_modification_time.tv_usec;
- }
-
- if ((*flags & MSGFLAG_READ) != 0)
- item->header.flags |= CAMEL_MESSAGE_SEEN;
- if ((*flags & MSGFLAG_HASATTACH) != 0)
- item->header.flags |= CAMEL_MESSAGE_ATTACHMENTS;
-
- *slist = g_slist_prepend (*slist, item);
-
- /*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, NULL);
- g_slist_foreach (*slist, (GFunc)mail_item_free, NULL);
- g_slist_free (*slist);
- *slist = NULL;
- }
-
- if (item_data->total > 0)
- camel_operation_progress (NULL, (item_data->index * 100)/item_data->total);
-
- if (camel_application_is_exiting)
- return FALSE;
-
- return TRUE;
-}
-
static void
mapi_set_message_id (CamelMapiMessageInfo *mapi_mi, const gchar *message_id)
{
@@ -362,7 +230,7 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
/************************ First populate summary *************************/
mi = NULL;
pmi = NULL;
- msg_uid = e_mapi_util_mapi_ids_to_uid (item->fid, item->mid);
+ msg_uid = e_mapi_util_mapi_id_to_string (item->mid);
pmi = camel_folder_summary_get (folder->summary, msg_uid);
if (pmi) {
@@ -387,7 +255,7 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
guint32 count_to = 0, count_cc =0;
gchar *to = NULL, *cc = NULL;
- mi->info.uid = e_mapi_util_mapi_ids_to_uid(item->fid, item->mid);
+ mi->info.uid = e_mapi_util_mapi_id_to_string (item->mid);
mi->info.subject = camel_pstring_strdup(item->header.subject);
mi->info.date_sent = mi->info.date_received = item->header.recieved_time;
mi->info.size = (guint32) item->header.size;
@@ -509,329 +377,515 @@ mapi_utils_do_flags_diff (flags_diff_t *diff, guint32 old, guint32 _new)
diff->bits = _new & diff->changed;
}
-typedef struct _SyncDeletedData SyncDeletedData;
+static gboolean
+build_last_modify_restriction (EMapiConnection *conn,
+ mapi_id_t fid,
+ TALLOC_CTX *mem_ctx,
+ struct mapi_SRestriction **restrictions,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ const time_t *latest_last_modify = user_data;
+ struct mapi_SRestriction *restriction = NULL;
-struct _SyncDeletedData {
- CamelFolder *folder;
- mapi_id_t folder_id;
- gboolean need_refresh;
+ g_return_val_if_fail (restrictions != NULL, FALSE);
+
+ if (latest_last_modify && *latest_last_modify > 0) {
+ struct SPropValue sprop;
+ struct timeval t;
+
+ restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
+ g_return_val_if_fail (restriction != NULL, FALSE);
+
+ restriction->rt = RES_PROPERTY;
+ restriction->res.resProperty.relop = RELOP_GT;
+ restriction->res.resProperty.ulPropTag = PR_LAST_MODIFICATION_TIME;
+
+ t.tv_sec = *latest_last_modify;
+ t.tv_usec = 0;
+
+ set_SPropValue_proptag_date_timeval (&sprop, PR_LAST_MODIFICATION_TIME, &t);
+ cast_mapi_SPropValue (mem_ctx, &(restriction->res.resProperty.lpProp), &sprop);
+ }
+
+ *restrictions = restriction;
+
+ return TRUE;
+}
+
+struct GatherChangedObjectsData
+{
+ CamelFolderSummary *summary;
+ mapi_id_t fid;
+ GSList *to_update;
+ GHashTable *removed_uids;
+ time_t latest_last_modify;
};
static gboolean
-deleted_items_sync_cb (FetchItemsCallbackData *item_data,
- gpointer data,
- GCancellable *cancellable,
- GError **perror)
+gather_changed_objects_to_slist (EMapiConnection *conn,
+ mapi_id_t fid,
+ TALLOC_CTX *mem_ctx,
+ const ListObjectsData *object_data,
+ guint32 obj_index,
+ guint32 obj_total,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
{
- guint32 msg_flags = CAMEL_MESSAGE_FOLDER_FLAGGED; /* to not have 0 in the hash table */
- GHashTable *uids = data;
- gchar *msg_uid = e_mapi_util_mapi_ids_to_uid (item_data->fid,
- item_data->mid);
+ struct GatherChangedObjectsData *gco = user_data;
+ ListObjectsData *copy;
+ gchar *uid_str;
+ gboolean update = FALSE;
- if ((item_data->msg_flags & MSGFLAG_READ) != 0)
- msg_flags |= CAMEL_MESSAGE_SEEN;
- if ((item_data->msg_flags & MSGFLAG_HASATTACH) != 0)
- msg_flags |= CAMEL_MESSAGE_ATTACHMENTS;
+ g_return_val_if_fail (gco != NULL, FALSE);
+ g_return_val_if_fail (object_data != NULL, FALSE);
- g_hash_table_insert (uids, msg_uid, GINT_TO_POINTER (msg_flags));
+ uid_str = e_mapi_util_mapi_id_to_string (object_data->mid);
+ if (!uid_str)
+ return FALSE;
- /* Progress update */
- if (item_data->total > 0)
- camel_operation_progress (NULL, (item_data->index * 100)/item_data->total);
+ if (camel_folder_summary_check_uid (gco->summary, uid_str)) {
+ CamelMessageInfo *info;
- /* Check if we have to stop */
- if (camel_application_is_exiting)
- return FALSE;
+ if (gco->removed_uids)
+ g_hash_table_remove (gco->removed_uids, uid_str);
+
+ info = camel_folder_summary_get (gco->summary, uid_str);
+ if (info) {
+ CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
+
+ if (minfo->last_modified != object_data->last_modified) {
+ update = TRUE;
+ } else {
+ guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS, flags = 0;
+
+ if ((object_data->msg_flags & MSGFLAG_READ) != 0)
+ flags |= CAMEL_MESSAGE_SEEN;
+ if ((object_data->msg_flags & MSGFLAG_HASATTACH) != 0)
+ flags |= CAMEL_MESSAGE_ATTACHMENTS;
+
+ if ((minfo->info.flags & mask) != (flags & mask)) {
+ camel_message_info_set_flags (info, mask, flags);
+ minfo->server_flags = camel_message_info_flags (info);
+ minfo->info.dirty = TRUE;
+ }
+ }
+
+ camel_message_info_free (info);
+ }
+ } else {
+ update = TRUE;
+ }
+
+ if (update) {
+ copy = g_new0 (ListObjectsData, 1);
+ *copy = *object_data;
+
+ gco->to_update = g_slist_prepend (gco->to_update, copy);
+ }
+
+ if (gco->latest_last_modify < object_data->last_modified)
+ gco->latest_last_modify = object_data->last_modified;
+
+ if (obj_total > 0)
+ camel_operation_progress (cancellable, obj_index * 100 / obj_total);
+
+ g_free (uid_str);
return TRUE;
}
+struct GatherObjectSummaryData
+{
+ CamelFolder *folder;
+ CamelFolderChangeInfo *changes;
+};
+
static void
-mapi_sync_deleted (CamelSession *session,
- GCancellable *cancellable,
- SyncDeletedData *data,
- GError **error)
+remove_removed_uids_cb (gpointer uid_str, gpointer value, gpointer user_data)
{
- CamelMapiStore *mapi_store;
- CamelMapiFolder *mapi_folder;
- CamelFolderChangeInfo *changes = NULL;
- CamelMessageInfo *info = NULL;
- CamelStore *parent_store;
- CamelServiceConnectionStatus status;
- CamelService *service;
- GPtrArray *known_uids = NULL;
- guint32 index, options = 0;
- GHashTable *server_messages = NULL;
- const gchar *uid = NULL;
- gboolean flags_changed = FALSE;
+ struct GatherObjectSummaryData *gos = user_data;
- parent_store = camel_folder_get_parent_store (data->folder);
+ g_return_if_fail (gos != NULL);
+ g_return_if_fail (gos->folder != NULL);
+ g_return_if_fail (gos->changes != NULL);
- mapi_folder = CAMEL_MAPI_FOLDER (data->folder);
- mapi_store = CAMEL_MAPI_STORE (parent_store);
+ camel_folder_change_info_remove_uid (gos->changes, uid_str);
+ camel_folder_summary_remove_uid (gos->folder->summary, uid_str);
+ camel_data_cache_remove (CAMEL_MAPI_FOLDER (gos->folder)->cache, "cache", uid_str, NULL);
+}
- service = CAMEL_SERVICE (mapi_store);
- status = camel_service_get_connection_status (service);
+static gboolean
+gather_object_summary_cb (EMapiConnection *conn,
+ TALLOC_CTX *mem_ctx,
+ /* const */ EMapiObject *object,
+ guint32 obj_index,
+ guint32 obj_total,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ struct GatherObjectSummaryData *gos = user_data;
+ gchar *uid_str;
+ const mapi_id_t *pmid;
+ const uint32_t *pmsg_flags;
+ const struct FILETIME *last_modified;
+ const gchar *transport_headers;
+ uint32_t msg_flags;
+ CamelMessageInfo *info;
+ gboolean is_new = FALSE;
- if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)) ||
- status == CAMEL_SERVICE_DISCONNECTED) {
+ g_return_val_if_fail (gos != NULL, FALSE);
+ g_return_val_if_fail (gos->folder != NULL, FALSE);
+ g_return_val_if_fail (object != NULL, FALSE);
+
+ pmid = e_mapi_util_find_array_propval (&object->properties, PR_MID);
+ pmsg_flags = e_mapi_util_find_array_propval (&object->properties, PR_MESSAGE_FLAGS);
+ last_modified = e_mapi_util_find_array_propval (&object->properties, PR_LAST_MODIFICATION_TIME);
+ transport_headers = e_mapi_util_find_array_propval (&object->properties, PR_TRANSPORT_MESSAGE_HEADERS_UNICODE);
- goto exit;
+ if (!pmid) {
+ g_debug ("%s: Received message [%d/%d] without PR_MID", G_STRFUNC, obj_index, obj_total);
+ e_mapi_debug_dump_object (object, TRUE, 3);
+ return TRUE;
}
- camel_operation_push_message (
- cancellable,
- _("Retrieving message IDs from server for %s"),
- camel_folder_get_display_name (data->folder));
+ if (!last_modified) {
+ g_debug ("%s: Received message [%d/%d] without PR_LAST_MODIFICATION_TIME", G_STRFUNC, obj_index, obj_total);
+ e_mapi_debug_dump_object (object, TRUE, 3);
+ }
- camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+ uid_str = e_mapi_util_mapi_id_to_string (*pmid);
+ if (!uid_str)
+ return FALSE;
- if (mapi_folder->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC)
- options |= MAPI_OPTIONS_USE_PFSTORE;
+ msg_flags = pmsg_flags ? *pmsg_flags : 0;
- server_messages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ info = camel_folder_summary_get (gos->folder->summary, uid_str);
+ if (!info) {
+ is_new = TRUE;
- /*Get the UID list from server.*/
- e_mapi_connection_fetch_items (camel_mapi_store_get_connection (mapi_store), data->folder_id, NULL, NULL, NULL,
- NULL, NULL,
- deleted_items_sync_cb, server_messages,
- options | MAPI_OPTIONS_DONT_OPEN_MESSAGE, cancellable, NULL);
+ if (transport_headers && *transport_headers) {
+ CamelMimePart *part = camel_mime_part_new ();
+ CamelStream *stream;
+ CamelMimeParser *parser;
- camel_operation_pop_message (cancellable);
+ stream = camel_stream_mem_new_with_buffer (transport_headers, strlen (transport_headers));
+ parser = camel_mime_parser_new ();
+ camel_mime_parser_init_with_stream (parser, stream, NULL);
+ camel_mime_parser_scan_from (parser, FALSE);
+ g_object_unref (stream);
- camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+ if (camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) {
+ info = camel_folder_summary_info_new_from_header (gos->folder->summary, part->headers);
+ if (info) {
+ CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
- /* Check if we have to stop */
- if (g_cancellable_is_cancelled (cancellable) || camel_application_is_exiting) {
- g_hash_table_destroy (server_messages);
- goto exit;
- }
+ minfo->info.uid = camel_pstring_strdup (uid_str);
+ }
+ }
- changes = camel_folder_change_info_new ();
+ g_object_unref (parser);
+ g_object_unref (part);
+ }
- camel_operation_push_message (
- cancellable,
- _("Removing deleted messages from cache in %s"),
- camel_folder_get_display_name (data->folder));
+ if (!info) {
+ CamelMapiMessageInfo *minfo;
+ const gchar *subject, *message_id, *references, *in_reply_to, *display_to, *display_cc;
+ const gchar *from_addr_type, *from_name, *from_email;
+ const struct FILETIME *delivery_time;
+ const uint32_t *msg_size;
+ EMapiRecipient *recipient;
+ gchar *to = NULL, *cc = NULL, *formatted_addr;
+
+ subject = e_mapi_util_find_array_propval (&object->properties, PR_SUBJECT_UNICODE);
+ delivery_time = e_mapi_util_find_array_propval (&object->properties, PR_MESSAGE_DELIVERY_TIME);
+ msg_size = e_mapi_util_find_array_propval (&object->properties, PR_MESSAGE_SIZE);
+ message_id = e_mapi_util_find_array_propval (&object->properties, PR_INTERNET_MESSAGE_ID);
+ references = e_mapi_util_find_array_propval (&object->properties, PR_INTERNET_REFERENCES);
+ in_reply_to = e_mapi_util_find_array_propval (&object->properties, PR_IN_REPLY_TO_ID);
+ display_to = e_mapi_util_find_array_propval (&object->properties, PR_DISPLAY_TO_UNICODE);
+ display_cc = e_mapi_util_find_array_propval (&object->properties, PR_DISPLAY_CC_UNICODE);
+ from_addr_type = e_mapi_util_find_array_propval (&object->properties, PR_SENT_REPRESENTING_ADDRTYPE);
+ from_name = e_mapi_util_find_array_propval (&object->properties, PR_SENT_REPRESENTING_NAME_UNICODE);
+ from_email = e_mapi_util_find_array_propval (&object->properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE);
+
+ info = camel_message_info_new (gos->folder->summary);
+ minfo = (CamelMapiMessageInfo *) info;
+
+ minfo->info.uid = camel_pstring_strdup (uid_str);
+ minfo->info.subject = camel_pstring_strdup (subject);
+ minfo->info.date_sent = minfo->info.date_received = e_mapi_util_filetime_to_time_t (delivery_time);
+ minfo->info.size = msg_size ? *msg_size : 0;
+
+ /* Threading related properties */
+ mapi_set_message_id (minfo, message_id);
+ if (references || in_reply_to)
+ mapi_set_message_references (minfo, references, in_reply_to);
+
+ /* Recipients */
+ for (recipient = object->recipients; recipient; recipient = recipient->next) {
+ const uint32_t *recip_type = e_mapi_util_find_array_propval (&recipient->properties, PR_RECIPIENT_TYPE);
+ const gchar *name, *email;
+ gchar **dest = NULL;
+
+ if (!recip_type)
+ continue;
+
+ switch (*recip_type) {
+ case MAPI_TO:
+ dest = &to;
+ break;
+ case MAPI_CC:
+ dest = &cc;
+ break;
+ default:
+ break;
+ }
- /* Iterate over cache and check if the UID is in server */
- known_uids = camel_folder_summary_get_array (data->folder->summary);
- for (index = 0; known_uids && index < known_uids->len; index++) {
- guint32 msg_flags;
+ if (!dest)
+ continue;
+
+ /* PidTagNickname for Recipients table */
+ name = e_mapi_util_find_array_propval (&recipient->properties, PROP_TAG (PT_UNICODE, 0x6001));
+ name = name ? name : e_mapi_util_find_array_propval (&recipient->properties, PidTagNickname);
+ name = name ? name : e_mapi_util_find_array_propval (&recipient->properties, PR_DISPLAY_NAME_UNICODE);
+ name = name ? name : e_mapi_util_find_array_propval (&recipient->properties, PR_RECIPIENT_DISPLAY_NAME_UNICODE);
+ name = name ? name : e_mapi_util_find_array_propval (&recipient->properties, PR_7BIT_DISPLAY_NAME_UNICODE);
+
+ email = e_mapi_util_find_array_propval (&recipient->properties, PidTagPrimarySmtpAddress);
+ email = email ? email : e_mapi_util_find_array_propval (&recipient->properties, PidTagSmtpAddress);
+
+ formatted_addr = camel_internet_address_format_address (name, email ? email : "");
+ if (*dest) {
+ gchar *tmp = *dest;
+ *dest = g_strconcat (*dest, ", ", formatted_addr, NULL);
+ g_free (formatted_addr);
+ g_free (tmp);
+ } else {
+ *dest = formatted_addr;
+ }
+ }
- /* Iterate in a reverse order, thus removal will not hurt */
- info = camel_folder_summary_get (data->folder->summary, g_ptr_array_index (known_uids, index));
- if (!info) continue; /*This is bad. *Should* not happen*/
+ minfo->info.to = to ? camel_pstring_strdup (to) : camel_pstring_strdup (display_to);
+ minfo->info.cc = cc ? camel_pstring_strdup (cc) : camel_pstring_strdup (display_cc);
- uid = camel_message_info_uid (info);
- if (!uid) {
- camel_message_info_free (info);
- continue;
- }
+ if (from_addr_type && g_ascii_strcasecmp (from_addr_type, "EX") == 0) {
+ gchar *email = NULL, *name = NULL;
- msg_flags = GPOINTER_TO_INT (g_hash_table_lookup (server_messages, uid));
+ email = e_mapi_connection_ex_to_smtp (conn, from_email, &name, cancellable, perror);
+ if (email && *email) {
+ gchar *from = camel_internet_address_format_address (name, email);
- /* If it is not in server list, clean our cache */
- if (!msg_flags) {
- camel_folder_summary_lock (data->folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- camel_folder_summary_remove_uid (data->folder->summary, uid);
- camel_data_cache_remove (mapi_folder->cache, "cache", uid, NULL);
- camel_folder_change_info_remove_uid (changes, uid);
- camel_folder_summary_unlock (data->folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- } else {
- CamelMapiMessageInfo *mapi_info = (CamelMapiMessageInfo *) info;
-
- msg_flags = msg_flags & (~CAMEL_MESSAGE_FOLDER_FLAGGED);
- if (mapi_info->server_flags != msg_flags) {
- mapi_info->server_flags = msg_flags;
- camel_message_info_set_flags (info, msg_flags, CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS);
- camel_folder_change_info_change_uid (changes, uid);
- flags_changed = TRUE;
- }
- }
+ minfo->info.from = camel_pstring_strdup (from);
- camel_message_info_free (info);
+ g_free (from);
+ } else if (from_name && *from_name) {
+ minfo->info.from = camel_pstring_strdup (from_name);
+ }
- /* Progress update */
- camel_operation_progress (cancellable, (index * 100) / known_uids->len);
+ g_free (name);
+ g_free (email);
+ } else if (from_email) {
+ gchar *from = camel_internet_address_format_address (from_name, from_email);
- /* Check if we have to stop */
- if (g_cancellable_is_cancelled (cancellable) || camel_application_is_exiting) {
- g_hash_table_destroy (server_messages);
- if (camel_folder_change_info_changed (changes))
- camel_folder_changed (data->folder, changes);
- camel_folder_change_info_free (changes);
- goto exit;
- }
- }
+ minfo->info.from = camel_pstring_strdup (from);
- camel_operation_pop_message (cancellable);
+ g_free (from);
+ }
- if (camel_folder_change_info_changed (changes)) {
- if (flags_changed)
- camel_mapi_folder_summary_update_store_info_counts (CAMEL_MAPI_FOLDER_SUMMARY (CAMEL_FOLDER (mapi_folder)->summary));
- camel_folder_changed (data->folder, changes);
+ g_free (to);
+ g_free (cc);
+ }
}
- camel_folder_change_info_free (changes);
- data->need_refresh = camel_folder_summary_count (data->folder->summary) != g_hash_table_size (server_messages);
+ if (info) {
+ CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
+ guint32 flags = 0, mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS;
- g_hash_table_destroy (server_messages);
+ if (last_modified) {
+ minfo->last_modified = e_mapi_util_filetime_to_time_t (last_modified);
+ } else {
+ minfo->last_modified = 0;
+ }
- exit:
- camel_folder_summary_free_array (known_uids);
+ if ((msg_flags & MSGFLAG_READ) != 0)
+ flags |= CAMEL_MESSAGE_SEEN;
+ if ((msg_flags & MSGFLAG_HASATTACH) != 0)
+ flags |= CAMEL_MESSAGE_ATTACHMENTS;
- if (data->need_refresh) {
- CamelMapiFolderSummary *mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY (data->folder->summary);
- if (mapi_summary) {
- camel_service_lock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- g_free (mapi_summary->sync_time_stamp);
- mapi_summary->sync_time_stamp = NULL;
- camel_service_unlock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ if ((camel_message_info_flags (info) & mask) != flags) {
+ if (is_new)
+ minfo->info.flags = flags;
+ else
+ camel_message_info_set_flags (info, mask, flags);
+ minfo->server_flags = camel_message_info_flags (info);
+ minfo->info.dirty = TRUE;
+ }
+
+ if (is_new) {
+ camel_folder_summary_add (gos->folder->summary, info);
+ camel_folder_change_info_add_uid (gos->changes, camel_message_info_uid (info));
+ camel_folder_change_info_recent_uid (gos->changes, camel_message_info_uid (info));
- mapi_refresh_folder (data->folder, cancellable, error);
+ camel_message_info_ref (info);
+ } else {
+ camel_folder_change_info_change_uid (gos->changes, camel_message_info_uid (info));
}
+
+ camel_message_info_free (info);
}
-}
-static void
-mapi_sync_deleted_data_free (SyncDeletedData *data)
-{
- g_object_unref (data->folder);
- g_slice_free (SyncDeletedData, data);
-}
+ if (obj_total > 0)
+ camel_operation_progress (cancellable, obj_index * 100 / obj_total);
-static gboolean
-mapi_camel_get_summary_list (EMapiConnection *conn,
- mapi_id_t fid,
- TALLOC_CTX *mem_ctx,
- struct SPropTagArray *props,
- gpointer data,
- GCancellable *cancellable,
- GError **perror)
-{
- static const uint32_t summary_prop_list[] = {
- PR_INTERNET_CPID,
- PR_SUBJECT_UNICODE,
- PR_MESSAGE_SIZE,
- PR_MESSAGE_DELIVERY_TIME,
- PR_MESSAGE_FLAGS,
- PR_SENT_REPRESENTING_NAME_UNICODE,
- PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE,
- PR_SENT_REPRESENTING_ADDRTYPE_UNICODE,
- PR_LAST_MODIFICATION_TIME,
- PR_INTERNET_MESSAGE_ID,
- PR_INTERNET_REFERENCES,
- PR_IN_REPLY_TO_ID,
- PR_DISPLAY_TO_UNICODE,
- PR_DISPLAY_CC_UNICODE,
- PR_DISPLAY_BCC_UNICODE,
- PR_TRANSPORT_MESSAGE_HEADERS_UNICODE
- };
-
- g_return_val_if_fail (props != NULL, FALSE);
-
- return e_mapi_utils_add_props_to_props_array (mem_ctx, props, summary_prop_list, G_N_ELEMENTS (summary_prop_list));
+ g_free (uid_str);
+
+ return TRUE;
}
gboolean
-camel_mapi_folder_fetch_summary (CamelStore *store, CamelFolder *folder, const mapi_id_t fid, BuildRestrictionsCB build_rs_cb, gpointer build_rs_cb_data,
- struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GCancellable *cancellable, GError **mapi_error)
+camel_mapi_folder_fetch_summary (CamelFolder *folder, GCancellable *cancellable, GError **mapi_error)
{
gboolean status;
- CamelMapiStore *mapi_store = (CamelMapiStore *) store;
+ gboolean full_download;
+ CamelSettings *settings;
+ CamelStore *store = camel_folder_get_parent_store (folder);
+ CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
+ CamelMapiFolder *mapi_folder = CAMEL_MAPI_FOLDER (folder);
+ CamelMapiFolderSummary *mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY (folder->summary);
+ EMapiConnection *conn = camel_mapi_store_get_connection (mapi_store);
+ struct GatherChangedObjectsData gco;
+ mapi_object_t obj_folder;
+
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store)))
+ return FALSE;
- /*TODO : Check for online state*/
+ camel_folder_freeze (folder);
- camel_operation_push_message (cancellable, _("Fetching summary information for new messages in %s"), camel_folder_get_display_name (folder));
+ settings = camel_service_get_settings (CAMEL_SERVICE (store));
+ full_download =
+ camel_offline_settings_get_stay_synchronized (CAMEL_OFFLINE_SETTINGS (settings)) ||
+ camel_offline_folder_get_offline_sync (CAMEL_OFFLINE_FOLDER (folder));
+
+ if (full_download)
+ camel_operation_push_message (cancellable, _("Downloading messages in folder '%s'"), camel_folder_get_display_name (folder));
+ else
+ camel_operation_push_message (cancellable, _("Refreshing folder '%s'"), camel_folder_get_display_name (folder));
camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- status = e_mapi_connection_fetch_items (camel_mapi_store_get_connection (mapi_store), fid, build_rs_cb, build_rs_cb_data, sort,
- mapi_camel_get_summary_list, NULL,
- fetch_items_summary_cb, fetch_data,
- options, cancellable, mapi_error);
+ if ((CAMEL_MAPI_FOLDER (folder)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0)
+ status = e_mapi_connection_open_public_folder (conn, mapi_folder->folder_id, &obj_folder, cancellable, mapi_error);
+ else
+ status = e_mapi_connection_open_personal_folder (conn, mapi_folder->folder_id, &obj_folder, cancellable, mapi_error);
- camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+ gco.latest_last_modify = 0;
+ gco.fid = mapi_object_get_id (&obj_folder);
+ gco.summary = folder->summary;
+ gco.to_update = NULL;
+ gco.removed_uids = NULL;
- camel_operation_pop_message (cancellable);
+ if (mapi_summary->latest_last_modify <= 0) {
+ GPtrArray *known_uids;
- return status;
-}
+ camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-static gboolean
-cmf_build_last_modify_restriction (EMapiConnection *conn,
- mapi_id_t fid,
- TALLOC_CTX *mem_ctx,
- struct mapi_SRestriction **restrictions,
- gpointer user_data,
- GCancellable *cancellable,
- GError **perror)
-{
- const gchar *sync_time_stamp = user_data;
- GTimeVal last_modification_time;
+ gco.removed_uids = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL);
+ known_uids = camel_folder_summary_get_array (folder->summary);
+ if (known_uids) {
+ gint ii;
- g_return_val_if_fail (restrictions != NULL, FALSE);
+ for (ii = 0; ii < known_uids->len; ii++) {
+ g_hash_table_insert (gco.removed_uids, (gpointer) camel_pstring_strdup (g_ptr_array_index (known_uids, ii)), GINT_TO_POINTER (1));
+ }
- if (sync_time_stamp && *sync_time_stamp &&
- g_time_val_from_iso8601 (sync_time_stamp,
- &last_modification_time)) {
- struct mapi_SRestriction *restriction;
- struct SPropValue sprop;
- struct timeval t;
+ camel_folder_summary_free_array (known_uids);
+ }
+ }
- restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
- g_return_val_if_fail (restriction != NULL, FALSE);
+ if (status) {
+ status = e_mapi_connection_list_objects (conn, &obj_folder,
+ full_download ? NULL : build_last_modify_restriction, &mapi_summary->latest_last_modify,
+ gather_changed_objects_to_slist, &gco, cancellable, mapi_error);
+ }
- restriction->rt = RES_PROPERTY;
- restriction->res.resProperty.relop = RELOP_GE;
- restriction->res.resProperty.ulPropTag = PR_LAST_MODIFICATION_TIME;
+ if (status && gco.to_update) {
+ GSList *uids = NULL, *iter;
+ struct GatherObjectSummaryData gos;
- t.tv_sec = last_modification_time.tv_sec;
- t.tv_usec = last_modification_time.tv_usec;
+ for (iter = gco.to_update; iter; iter = iter->next) {
+ ListObjectsData *data = iter->data;
- set_SPropValue_proptag_date_timeval (&sprop, PR_LAST_MODIFICATION_TIME, &t);
- cast_mapi_SPropValue (mem_ctx, &(restriction->res.resProperty.lpProp), &sprop);
+ if (data)
+ uids = g_slist_prepend (uids, &data->mid);
+ }
+
+ gos.folder = folder;
+ gos.changes = camel_folder_change_info_new ();
+
+ if (gco.removed_uids)
+ g_hash_table_foreach (gco.removed_uids, remove_removed_uids_cb, &gos);
+
+ status = e_mapi_connection_transfer_summary (conn, &obj_folder, uids, gather_object_summary_cb, &gos, cancellable, mapi_error);
+
+ g_slist_free (uids);
+
+ if (camel_folder_change_info_changed (gos.changes))
+ camel_folder_changed (folder, gos.changes);
+ camel_folder_change_info_free (gos.changes);
+ } else if (status && gco.removed_uids) {
+ struct GatherObjectSummaryData gos;
+
+ gos.folder = folder;
+ gos.changes = camel_folder_change_info_new ();
- *restrictions = restriction;
+ g_hash_table_foreach (gco.removed_uids, remove_removed_uids_cb, &gos);
+ if (camel_folder_change_info_changed (gos.changes))
+ camel_folder_changed (folder, gos.changes);
+ camel_folder_change_info_free (gos.changes);
}
- return TRUE;
+ e_mapi_connection_close_folder (conn, &obj_folder, cancellable, mapi_error);
+
+ g_slist_free_full (gco.to_update, g_free);
+ if (gco.removed_uids)
+ g_hash_table_destroy (gco.removed_uids);
+
+ camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ camel_operation_pop_message (cancellable);
+
+ if (status && gco.latest_last_modify > 0) {
+ mapi_summary->latest_last_modify = gco.latest_last_modify;
+ }
+
+ camel_folder_thaw (folder);
+
+ return status;
}
gboolean
-mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **error)
+mapi_refresh_folder (CamelFolder *folder, GCancellable *cancellable, GError **error)
{
CamelMapiStore *mapi_store;
CamelMapiFolder *mapi_folder;
- CamelMapiFolderSummary *mapi_summary;
CamelService *service;
- CamelSession *session;
CamelStore *parent_store;
-
- gboolean is_proxy;
gboolean is_locked = FALSE;
gboolean status;
gboolean success = TRUE;
+ GError *mapi_error = NULL;
- struct SSortOrderSet *sort = NULL;
- fetch_items_data *fetch_data = g_new0 (fetch_items_data, 1);
- const gchar *folder_id = NULL;
- const gchar *full_name;
-
- 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);
- mapi_summary = CAMEL_MAPI_FOLDER_SUMMARY (folder->summary);
-
- is_proxy = parent_store->flags & CAMEL_STORE_PROXY;
-
service = CAMEL_SERVICE (parent_store);
- session = camel_service_get_session (service);
if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)))
goto end1;
@@ -840,14 +894,12 @@ mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **err
so that the getFolderList will reflect the most recent changes too */
mapi_folder_synchronize_sync (folder, FALSE, cancellable, NULL);
- //creating a copy
- folder_id = camel_mapi_store_folder_id_lookup (mapi_store, full_name);
- if (!folder_id) {
+ if (!mapi_folder->folder_id) {
d(printf ("\nERROR - Folder id not present. Cannot refresh info for %s\n", full_name));
goto end1;
}
- if (camel_folder_is_frozen (folder) ) {
+ if (camel_folder_is_frozen (folder)) {
mapi_folder->need_refresh = TRUE;
}
@@ -857,98 +909,42 @@ mapi_refresh_folder(CamelFolder *folder, GCancellable *cancellable, GError **err
if (!camel_mapi_store_connected (mapi_store, NULL))
goto end1;
- /*Get the New Items*/
- if (!is_proxy) {
- SyncDeletedData *sync_data;
- mapi_id_t temp_folder_id;
- guint32 options = 0;
- GError *mapi_error = NULL;
-
- if (mapi_summary->sync_time_stamp && *mapi_summary->sync_time_stamp)
- g_time_val_from_iso8601 (mapi_summary->sync_time_stamp,
- &fetch_data->last_modification_time);
-
- /*Initialize other fetch_data fields*/
- fetch_data->changes = camel_folder_change_info_new ();
- fetch_data->folder = folder;
-
- /*Set sort order*/
- sort = g_new0 (struct SSortOrderSet, 1);
- sort->cSorts = 1;
- sort->aSort = g_new0 (struct SSortOrder, sort->cSorts);
- sort->aSort[0].ulPropTag = PR_LAST_MODIFICATION_TIME;
- sort->aSort[0].ulOrder = TABLE_SORT_ASCEND;
+ if (!camel_mapi_store_connected (mapi_store, NULL)) {
+ /*BUG : Fix exception string.*/
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_UNAVAILABLE,
+ _("This message is not available in offline mode."));
+ success = FALSE;
+ goto end1;
+ }
- e_mapi_util_mapi_id_from_string (folder_id, &temp_folder_id);
+ status = camel_mapi_folder_fetch_summary (folder, cancellable, &mapi_error);
- if (!camel_mapi_store_connected (mapi_store, NULL)) {
- /*BUG : Fix exception string.*/
+ if (!status) {
+ if (mapi_error) {
g_set_error (
- error, CAMEL_SERVICE_ERROR,
- CAMEL_SERVICE_ERROR_UNAVAILABLE,
- _("This message is not available in offline mode."));
- success = FALSE;
- goto end1;
- }
-
- options |= MAPI_OPTIONS_FETCH_RECIPIENTS;
-
- if (((CamelMapiFolder *)folder)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC)
- options |= MAPI_OPTIONS_USE_PFSTORE;
-
- status = camel_mapi_folder_fetch_summary ((CamelStore *)mapi_store, folder, temp_folder_id,
- cmf_build_last_modify_restriction, mapi_summary->sync_time_stamp, sort,
- fetch_data, options, cancellable, &mapi_error);
-
- if (!status) {
- if (mapi_error) {
- g_set_error (
- error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID,
- _("Fetching items failed: %s"), mapi_error->message);
- g_error_free (mapi_error);
- } else {
- g_set_error_literal (
- error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID,
- _("Fetching items failed"));
- }
- success = FALSE;
- goto end1;
+ error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID,
+ _("Fetching items failed: %s"), mapi_error->message);
+ g_error_free (mapi_error);
+ } else {
+ g_set_error_literal (
+ error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID,
+ _("Fetching items failed"));
}
+ success = FALSE;
+ goto end1;
+ }
- /*Preserve last_modification_time from this fetch for later use with restrictions.*/
- g_free (mapi_summary->sync_time_stamp);
- mapi_summary->sync_time_stamp = g_time_val_to_iso8601 (&fetch_data->last_modification_time);
-
- camel_folder_summary_touch (folder->summary);
- update_store_summary (folder, NULL);
+ camel_folder_summary_touch (folder->summary);
- camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
- is_locked = FALSE;
-
- /* Downsync deleted items */
- sync_data = g_slice_new0 (SyncDeletedData);
- sync_data->folder = g_object_ref (folder);
- sync_data->folder_id = temp_folder_id;
- sync_data->need_refresh = FALSE;
-
- camel_session_submit_job (
- session,
- (CamelSessionCallback) mapi_sync_deleted,
- sync_data,
- (GDestroyNotify) mapi_sync_deleted_data_free);
-
- camel_folder_changed (folder, fetch_data->changes);
- camel_folder_change_info_free (fetch_data->changes);
- }
+ camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+ is_locked = FALSE;
-end1:
+ end1:
if (is_locked)
camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
- g_slist_foreach (fetch_data->items_list, (GFunc) mail_item_free, NULL);
- g_slist_free (fetch_data->items_list);
- g_free (fetch_data);
-
return success;
}
@@ -1197,7 +1193,7 @@ mapi_folder_append_message_sync (CamelFolder *folder,
}
if (appended_uid)
- *appended_uid = e_mapi_util_mapi_ids_to_uid(fid, mid);
+ *appended_uid = e_mapi_util_mapi_id_to_string (mid);
return TRUE;
}
@@ -1213,27 +1209,20 @@ mapi_folder_expunge_sync (CamelFolder *folder,
CamelMessageInfo *info;
CamelFolderChangeInfo *changes;
CamelStore *parent_store;
- mapi_id_t fid;
GPtrArray *known_uids;
gint i;
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));
- e_mapi_util_mapi_id_from_string (folder_id, &fid);
-
if ((mapi_folder->camel_folder_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
GError *mapi_error = NULL;
GPtrArray *folders;
@@ -1259,7 +1248,7 @@ mapi_folder_expunge_sync (CamelFolder *folder,
g_ptr_array_free (folders, TRUE);
camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- status = e_mapi_connection_empty_folder (camel_mapi_store_get_connection (mapi_store), fid, 0, cancellable, &mapi_error);
+ status = e_mapi_connection_empty_folder (camel_mapi_store_get_connection (mapi_store), mapi_folder->folder_id, 0, cancellable, &mapi_error);
camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
if (status) {
@@ -1291,7 +1280,7 @@ mapi_folder_expunge_sync (CamelFolder *folder,
const gchar *uid = camel_message_info_uid (info);
mapi_id_t *mid = g_new0 (mapi_id_t, 1);
- if (!e_mapi_util_mapi_ids_from_uid (uid, &fid, mid))
+ if (!e_mapi_util_mapi_id_from_string (uid, mid))
continue;
if (deleted_items)
@@ -1313,7 +1302,7 @@ mapi_folder_expunge_sync (CamelFolder *folder,
if (deleted_items) {
camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- status = e_mapi_connection_remove_items (camel_mapi_store_get_connection (mapi_store), 0, fid, 0, deleted_items, cancellable, NULL);
+ status = e_mapi_connection_remove_items (camel_mapi_store_get_connection (mapi_store), 0, mapi_folder->folder_id, 0, deleted_items, cancellable, NULL);
camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -1338,7 +1327,6 @@ mapi_folder_expunge_sync (CamelFolder *folder,
if (delete)
camel_folder_changed (folder, changes);
- g_free (folder_id);
camel_folder_change_info_free (changes);
return TRUE;
@@ -1394,7 +1382,6 @@ mapi_folder_get_message_sync (CamelFolder *folder,
CamelMapiMessageInfo *mi = NULL;
CamelStream *cache_stream;
CamelStore *parent_store;
- mapi_id_t id_folder;
mapi_id_t id_message;
MailItem *item = NULL;
guint32 options = 0;
@@ -1447,14 +1434,14 @@ mapi_folder_get_message_sync (CamelFolder *folder,
options = MAPI_OPTIONS_FETCH_ALL | MAPI_OPTIONS_FETCH_BODY_STREAM |
MAPI_OPTIONS_GETBESTBODY | MAPI_OPTIONS_FETCH_RECIPIENTS;
- e_mapi_util_mapi_ids_from_uid (uid, &id_folder, &id_message);
+ e_mapi_util_mapi_id_from_string (uid, &id_message);
if (((CamelMapiFolder *)folder)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) {
options |= MAPI_OPTIONS_USE_PFSTORE;
}
camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- e_mapi_connection_fetch_item (camel_mapi_store_get_connection (mapi_store), id_folder, id_message,
+ e_mapi_connection_fetch_item (camel_mapi_store_get_connection (mapi_store), mapi_folder->folder_id, id_message,
mapi_mail_get_item_prop_list, NULL,
fetch_props_to_mail_item_cb, &item,
options, cancellable, &mapi_error);
@@ -1527,10 +1514,7 @@ mapi_folder_refresh_info_sync (CamelFolder *folder,
GCancellable *cancellable,
GError **error)
{
- if (!mapi_refresh_folder (folder, cancellable, error))
- return FALSE;
-
- return update_store_summary (folder, error);
+ return mapi_refresh_folder (folder, cancellable, error);
}
static gboolean
@@ -1556,7 +1540,6 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
gint 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);
@@ -1568,8 +1551,8 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
status = camel_service_get_connection_status (service);
if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (mapi_store)) ||
- status == CAMEL_SERVICE_DISCONNECTED) {
- return update_store_summary (folder, error);
+ status == CAMEL_SERVICE_DISCONNECTED) {
+ return TRUE;
}
if (((CamelMapiFolder *)folder)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC)
@@ -1598,7 +1581,6 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
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;
@@ -1606,7 +1588,7 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
flags= camel_message_info_flags (info);
/* Why are we getting so much noise here :-/ */
- if (!e_mapi_util_mapi_ids_from_uid (uid, &temp_fid, mid)) {
+ if (!e_mapi_util_mapi_id_from_string (uid, mid)) {
camel_message_info_free (info);
g_free (mid);
continue;
@@ -1739,11 +1721,7 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
/* TODO */
}
- camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
- success = update_store_summary (folder, error);
- camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
-
- return success;
+ return TRUE;
}
static gboolean
@@ -1755,7 +1733,6 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
GCancellable *cancellable,
GError **error)
{
- mapi_id_t src_fid, dest_fid;
guint32 src_fid_options, dest_fid_options;
CamelOfflineStore *offline;
@@ -1763,9 +1740,7 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
CamelFolderChangeInfo *changes = NULL;
CamelStore *source_parent_store;
CamelStore *destination_parent_store;
- const gchar *folder_id = NULL;
- const gchar *source_full_name;
- const gchar *destination_full_name;
+ CamelMapiFolder *src_mapi_folder, *des_mapi_folder;
gint i = 0;
GSList *src_msg_ids = NULL;
gboolean success = TRUE;
@@ -1789,10 +1764,7 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
transferred_uids, cancellable, error);
}
- source_full_name = camel_folder_get_full_name (source);
source_parent_store = camel_folder_get_parent_store (source);
-
- destination_full_name = camel_folder_get_full_name (destination);
destination_parent_store = camel_folder_get_parent_store (destination);
mapi_store = CAMEL_MAPI_STORE (source_parent_store);
@@ -1802,17 +1774,15 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
if (!camel_offline_store_get_online (offline))
return FALSE;
- folder_id = camel_mapi_store_folder_id_lookup (mapi_store, source_full_name);
- e_mapi_util_mapi_id_from_string (folder_id, &src_fid);
- src_fid_options = (CAMEL_MAPI_FOLDER (source)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? MAPI_OPTIONS_USE_PFSTORE : 0;
+ src_mapi_folder = CAMEL_MAPI_FOLDER (source);
+ src_fid_options = (src_mapi_folder->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? MAPI_OPTIONS_USE_PFSTORE : 0;
- folder_id = camel_mapi_store_folder_id_lookup (mapi_store, destination_full_name);
- e_mapi_util_mapi_id_from_string (folder_id, &dest_fid);
- dest_fid_options = (CAMEL_MAPI_FOLDER (destination)->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? MAPI_OPTIONS_USE_PFSTORE : 0;
+ des_mapi_folder = CAMEL_MAPI_FOLDER (destination);
+ dest_fid_options = (des_mapi_folder->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? MAPI_OPTIONS_USE_PFSTORE : 0;
for (i=0; i < uids->len; i++) {
mapi_id_t *mid = g_new0 (mapi_id_t, 1); /* FIXME : */
- if (!e_mapi_util_mapi_ids_from_uid (g_ptr_array_index (uids, i), &src_fid, mid))
+ if (!e_mapi_util_mapi_id_from_string (g_ptr_array_index (uids, i), mid))
continue;
src_msg_ids = g_slist_prepend (src_msg_ids, mid);
@@ -1821,7 +1791,7 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
if (delete_originals) {
GError *err = NULL;
- if (!e_mapi_connection_move_items (camel_mapi_store_get_connection (mapi_store), src_fid, src_fid_options, dest_fid, dest_fid_options, src_msg_ids, cancellable, &err)) {
+ if (!e_mapi_connection_move_items (camel_mapi_store_get_connection (mapi_store), src_mapi_folder->folder_id, src_fid_options, des_mapi_folder->folder_id, dest_fid_options, src_msg_ids, cancellable, &err)) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
"%s", err ? err->message : _("Unknown error"));
@@ -1842,7 +1812,7 @@ mapi_folder_transfer_messages_to_sync (CamelFolder *source,
} else {
GError *err = NULL;
- if (!e_mapi_connection_copy_items (camel_mapi_store_get_connection (mapi_store), src_fid, src_fid_options, dest_fid, dest_fid_options, src_msg_ids, cancellable, &err)) {
+ if (!e_mapi_connection_copy_items (camel_mapi_store_get_connection (mapi_store), src_mapi_folder->folder_id, src_fid_options, des_mapi_folder->folder_id, dest_fid_options, src_msg_ids, cancellable, &err)) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
"%s", err ? err->message : _("Unknown error"));
@@ -2004,6 +1974,7 @@ camel_mapi_folder_new (CamelStore *store, const gchar *folder_name, const gchar
mapi_folder->mapi_folder_flags = msi->mapi_folder_flags;
mapi_folder->camel_folder_flags = msi->camel_folder_flags;
+ mapi_folder->folder_id = msi->folder_id;
if ((si->flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH)
folder->folder_flags |= CAMEL_FOLDER_IS_TRASH;
diff --git a/src/camel/camel-mapi-folder.h b/src/camel/camel-mapi-folder.h
index 39baae6..b0fb595 100644
--- a/src/camel/camel-mapi-folder.h
+++ b/src/camel/camel-mapi-folder.h
@@ -61,6 +61,8 @@ struct _CamelMapiFolder {
CamelOfflineFolder parent;
CamelMapiFolderPrivate *priv;
+ mapi_id_t folder_id;
+
CamelFolderSearch *search;
CamelOfflineJournal *journal;
@@ -94,8 +96,7 @@ camel_mapi_folder_new(CamelStore *store, const gchar *folder_name, const gchar *
void mapi_update_summary ( CamelFolder *folder, GList *item_list,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, BuildRestrictionsCB build_rs_cb, gpointer build_rs_cb_data,
- struct SSortOrderSet *sort, fetch_items_data *fetch_data, guint32 options, GCancellable *cancellable, GError **mapi_error);
+gboolean camel_mapi_folder_fetch_summary (CamelFolder *folder, 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 25c9d24..21e9bcd 100644
--- a/src/camel/camel-mapi-notifications.c
+++ b/src/camel/camel-mapi-notifications.c
@@ -57,40 +57,9 @@ struct mapi_push_notification_data {
GThread *thread;
};
-static gboolean
-cmn_build_mid_restriction (EMapiConnection *conn,
- mapi_id_t fid,
- TALLOC_CTX *mem_ctx,
- struct mapi_SRestriction **restrictions,
- gpointer user_data,
- GCancellable *cancellable,
- GError **perror)
-{
- mapi_id_t *pmid = user_data;
- struct mapi_SRestriction *restriction;
-
- g_return_val_if_fail (pmid != NULL, FALSE);
- g_return_val_if_fail (restrictions != NULL, FALSE);
-
- restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
- g_return_val_if_fail (restriction != NULL, FALSE);
-
- restriction->rt = RES_PROPERTY;
- restriction->res.resProperty.relop = RES_PROPERTY;
- restriction->res.resProperty.ulPropTag = PR_MID;
- restriction->res.resProperty.lpProp.ulPropTag = PR_MID;
- restriction->res.resProperty.lpProp.value.dbl = *pmid;
-
- *restrictions = restriction;
-
- return TRUE;
-}
-
static void
process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *new_mail_notif)
{
- guint32 options = 0;
- fetch_items_data *fetch_data;
CamelFolder *folder = NULL;
CamelStore *parent_store;
gint info_count = -1;
@@ -111,7 +80,7 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
while (info_count >= 0) {
si = camel_store_summary_index (store->summary, info_count);
msi = (CamelMapiStoreInfo *) si;
- if (si && msi->folder_mid == new_mail_notif->FID) {
+ if (si && msi->folder_id == new_mail_notif->FID) {
folder_name = camel_store_info_path (store->summary, si);
info_count = 0;
}
@@ -128,12 +97,8 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
parent_store = camel_folder_get_parent_store (folder);
- fetch_data = g_new0 (fetch_items_data, 1);
- fetch_data->changes = camel_folder_change_info_new ();
- 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, cmn_build_mid_restriction, &new_mail_notif->MID, NULL, fetch_data, options, NULL, NULL);
+ camel_mapi_folder_fetch_summary (folder, NULL, NULL);
camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
camel_folder_summary_touch (folder->summary);
@@ -141,10 +106,6 @@ process_mapi_new_mail_notif (CamelMapiStore *store, struct NewMailNotification *
camel_folder_summary_save_to_db (folder->summary, NULL);
camel_store_summary_touch (((CamelMapiStore *)parent_store)->summary);
camel_store_summary_save (((CamelMapiStore *)parent_store)->summary);
-
- camel_folder_changed (folder, fetch_data->changes);
-
- camel_folder_change_info_free (fetch_data->changes);
}
static gint
diff --git a/src/camel/camel-mapi-store-summary.c b/src/camel/camel-mapi-store-summary.c
index 35cf80d..162c3c5 100644
--- a/src/camel/camel-mapi-store-summary.c
+++ b/src/camel/camel-mapi-store-summary.c
@@ -138,8 +138,8 @@ store_info_load (CamelStoreSummary *s, FILE *in)
|| camel_file_util_decode_uint32 (in, &msi->camel_folder_flags) == -1
|| camel_file_util_decode_uint32 (in, &msi->mapi_folder_flags) == -1
|| camel_file_util_decode_string (in, &msi->foreign_user_name) == -1
- || !e_mapi_util_mapi_id_from_string (folder_id_str, &msi->folder_mid)
- || !e_mapi_util_mapi_id_from_string (parent_id_str, &msi->parent_mid)) {
+ || !e_mapi_util_mapi_id_from_string (folder_id_str, &msi->folder_id)
+ || !e_mapi_util_mapi_id_from_string (parent_id_str, &msi->parent_id)) {
camel_store_summary_info_free (s, si);
si = NULL;
} else {
@@ -166,8 +166,8 @@ store_info_save (CamelStoreSummary *s, FILE *out, CamelStoreInfo *si)
store_summary_class = CAMEL_STORE_SUMMARY_CLASS (camel_mapi_store_summary_parent_class);
- folder_id_str = e_mapi_util_mapi_id_to_string (msi->folder_mid);
- parent_id_str = e_mapi_util_mapi_id_to_string (msi->parent_mid);
+ folder_id_str = e_mapi_util_mapi_id_to_string (msi->folder_id);
+ parent_id_str = e_mapi_util_mapi_id_to_string (msi->parent_id);
if (store_summary_class->store_info_save (s, out, si) == -1
|| camel_file_util_encode_string (out, folder_id_str) == -1
@@ -229,8 +229,8 @@ camel_mapi_store_summary_new (void)
CamelStoreInfo *
camel_mapi_store_summary_add_from_full (CamelStoreSummary *s,
const gchar *path,
- mapi_id_t folder_mid,
- mapi_id_t parent_mid,
+ mapi_id_t folder_id,
+ mapi_id_t parent_id,
guint32 camel_folder_flags,
guint32 mapi_folder_flags,
const gchar *foreign_user_name)
@@ -247,8 +247,8 @@ camel_mapi_store_summary_add_from_full (CamelStoreSummary *s,
if (si) {
CamelMapiStoreInfo *msi = (CamelMapiStoreInfo *) si;
- msi->folder_mid = folder_mid;
- msi->parent_mid = parent_mid;
+ msi->folder_id = folder_id;
+ msi->parent_id = parent_id;
msi->camel_folder_flags = camel_folder_flags;
msi->mapi_folder_flags = mapi_folder_flags;
msi->foreign_user_name = g_strdup ((foreign_user_name && *foreign_user_name) ? foreign_user_name : "");
@@ -259,7 +259,7 @@ camel_mapi_store_summary_add_from_full (CamelStoreSummary *s,
/* free the returned pointer with camel_store_summary_info_free(), if not NULL */
CamelStoreInfo *
-camel_mapi_store_summary_get_folder_id (CamelStoreSummary *s, mapi_id_t folder_mid)
+camel_mapi_store_summary_get_folder_id (CamelStoreSummary *s, mapi_id_t folder_id)
{
gint ii, count;
@@ -271,7 +271,7 @@ camel_mapi_store_summary_get_folder_id (CamelStoreSummary *s, mapi_id_t folder_m
if (si == NULL)
continue;
- if (msi->folder_mid == folder_mid)
+ if (msi->folder_id == folder_id)
return si;
camel_store_summary_info_free (s, si);
diff --git a/src/camel/camel-mapi-store-summary.h b/src/camel/camel-mapi-store-summary.h
index 2124232..9715d79 100644
--- a/src/camel/camel-mapi-store-summary.h
+++ b/src/camel/camel-mapi-store-summary.h
@@ -67,8 +67,8 @@ enum {
struct _CamelMapiStoreInfo {
CamelStoreInfo info;
- mapi_id_t folder_mid;
- mapi_id_t parent_mid;
+ mapi_id_t folder_id;
+ mapi_id_t parent_id;
guint32 camel_folder_flags; /* CamelFolderInfo::flags */
guint32 mapi_folder_flags; /* bit-or of CamelMapiStoreFolderFlags */
gchar *foreign_user_name; /* only if CAMEL_MAPI_STORE_FOLDER_FLAG_FOREIGN is set */
@@ -87,13 +87,13 @@ GType camel_mapi_store_summary_get_type (void);
CamelStoreSummary * camel_mapi_store_summary_new (void);
CamelStoreInfo * camel_mapi_store_summary_add_from_full (CamelStoreSummary *s,
const gchar *path,
- mapi_id_t folder_mid,
- mapi_id_t parent_mid,
+ mapi_id_t folder_id,
+ mapi_id_t parent_id,
guint32 camel_folder_flags, /* CamelFolderInfo::flags */
guint32 mapi_folder_flags, /* bit-or of CamelMapiStoreFolderFlags */
const gchar *foreign_user_name); /* only if CAMEL_MAPI_STORE_FOLDER_FLAG_FOREIGN is set */
CamelStoreInfo * camel_mapi_store_summary_get_folder_id (CamelStoreSummary *s,
- mapi_id_t folder_mid);
+ mapi_id_t folder_id);
G_END_DECLS
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index b719667..8057860 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -769,7 +769,7 @@ mapi_rename_folder_infos (CamelMapiStore *mapi_store, const gchar *old_name, con
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 */
- mapi_id_t fid = ((CamelMapiStoreInfo *)si)->folder_mid;
+ mapi_id_t fid = ((CamelMapiStoreInfo *)si)->folder_id;
if (fid) {
gchar *new_full_name;
@@ -943,12 +943,14 @@ mapi_update_folder_info_cb (CamelSession *session,
name = camel_service_get_name (service, TRUE);
camel_operation_push_message (cancellable, _("Scanning folders in '%s'"), name);
- g_free (name);
status = camel_service_get_connection_status (service);
if (camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
- if (status == CAMEL_SERVICE_DISCONNECTED)
+ if (status == CAMEL_SERVICE_DISCONNECTED) {
+ camel_operation_push_message (cancellable, _("Connecting to '%s'"), name);
camel_service_connect_sync (service, NULL);
+ camel_operation_pop_message (cancellable);
+ }
/* 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
@@ -962,6 +964,7 @@ mapi_update_folder_info_cb (CamelSession *session,
}
}
+ g_free (name);
camel_operation_pop_message (cancellable);
camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -982,6 +985,10 @@ mapi_store_get_folder_info_sync (CamelStore *store,
camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
if (camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
+ CamelServiceConnectionStatus status;
+
+ status = camel_service_get_connection_status (service);
+
/* 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 */
@@ -989,10 +996,6 @@ mapi_store_get_folder_info_sync (CamelStore *store,
(!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) ||
(top && *top && !camel_mapi_store_folder_id_lookup (mapi_store, top)) ||
camel_store_summary_count (mapi_store->summary) <= 1) {
- CamelServiceConnectionStatus status;
-
- status = camel_service_get_connection_status (service);
-
if (status == CAMEL_SERVICE_DISCONNECTED)
camel_service_connect_sync (service, NULL);
@@ -1003,6 +1006,8 @@ mapi_store_get_folder_info_sync (CamelStore *store,
}
}
} else if (!mapi_store->priv->folders_synced) {
+ mapi_store->priv->folders_synced = TRUE;
+
camel_session_submit_job (
camel_service_get_session (CAMEL_SERVICE (store)),
mapi_update_folder_info_cb,
@@ -1379,7 +1384,7 @@ mapi_store_rename_folder_sync (CamelStore *store,
camel_store_info_set_string (mapi_store->summary, si, CAMEL_STORE_INFO_PATH, new_name);
if (new_parent_fid_str && e_mapi_util_mapi_id_from_string (new_parent_fid_str, &new_parent_fid))
- ((CamelMapiStoreInfo *) si)->parent_mid = new_parent_fid;
+ ((CamelMapiStoreInfo *) si)->parent_id = new_parent_fid;
camel_store_summary_info_free (mapi_store->summary, si);
camel_store_summary_touch (mapi_store->summary);
}
@@ -1704,6 +1709,7 @@ mapi_connect_sync (CamelService *service,
CamelMapiStore *store = CAMEL_MAPI_STORE (service);
CamelServiceConnectionStatus status;
CamelSession *session;
+ gchar *name;
guint16 event_mask = 0;
session = camel_service_get_session (service);
@@ -1719,12 +1725,19 @@ mapi_connect_sync (CamelService *service,
return TRUE;
}
+ name = camel_service_get_name (service, TRUE);
+ camel_operation_push_message (cancellable, _("Connecting to '%s'"), name);
+ g_free (name);
+
if (!camel_session_authenticate_sync (session, service, NULL, cancellable, error)) {
+ camel_operation_pop_message (cancellable);
camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
camel_service_disconnect_sync (service, TRUE, NULL);
return FALSE;
}
+ camel_operation_pop_message (cancellable);
+
camel_offline_store_set_online_sync (
CAMEL_OFFLINE_STORE (store), TRUE, cancellable, NULL);
@@ -1950,8 +1963,8 @@ mapi_folders_update_hash_tables_from_cache (CamelMapiStore *store)
if (msi == NULL)
continue;
- fid = e_mapi_util_mapi_id_to_string (msi->folder_mid);
- pid = e_mapi_util_mapi_id_to_string (msi->parent_mid);
+ fid = e_mapi_util_mapi_id_to_string (msi->folder_id);
+ pid = e_mapi_util_mapi_id_to_string (msi->parent_id);
mapi_update_folder_hash_tables (store, camel_store_info_path (summary, msi), fid, pid);
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index f078650..5aefef7 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -2213,6 +2213,7 @@ e_mapi_connection_transfer_objects (EMapiConnection *conn,
CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+ e_return_val_mapi_error_if_fail (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
LOCK ();
mem_ctx = talloc_new (priv->session);
@@ -2247,6 +2248,180 @@ e_mapi_connection_transfer_objects (EMapiConnection *conn,
return ms == MAPI_E_SUCCESS;
}
+struct GetSummaryData {
+ guint32 obj_index;
+ guint32 obj_total;
+ struct SPropValue *lpProps;
+ uint32_t prop_count;
+ TransferObjectCB cb;
+ gpointer cb_user_data;
+};
+
+static gboolean
+internal_get_summary_cb (EMapiConnection *conn,
+ TALLOC_CTX *mem_ctx,
+ /* const */ EMapiObject *object,
+ guint32 obj_index,
+ guint32 obj_total,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ struct GetSummaryData *gsd = user_data;
+
+ g_return_val_if_fail (gsd != NULL, FALSE);
+ g_return_val_if_fail (gsd->cb != NULL, FALSE);
+ g_return_val_if_fail (object != NULL, FALSE);
+
+ /* also include properties received from GetProps,
+ as those like PR_MID are not included by default */
+ if (gsd->lpProps && gsd->prop_count > 0) {
+ uint32_t ii;
+
+ for (ii = 0; ii < gsd->prop_count; ii++) {
+ /* skip errors and already included properties */
+ if ((gsd->lpProps[ii].ulPropTag & 0xFFFF) == PT_ERROR
+ || e_mapi_util_find_array_propval (&object->properties, gsd->lpProps[ii].ulPropTag))
+ continue;
+
+ object->properties.cValues++;
+ object->properties.lpProps = talloc_realloc (mem_ctx,
+ object->properties.lpProps,
+ struct mapi_SPropValue,
+ object->properties.cValues + 1);
+ cast_mapi_SPropValue (mem_ctx, &object->properties.lpProps[object->properties.cValues - 1], &gsd->lpProps[ii]);
+ object->properties.lpProps[object->properties.cValues].ulPropTag = 0;
+ }
+ }
+
+ return gsd->cb (conn, mem_ctx, object, gsd->obj_index, gsd->obj_total, gsd->cb_user_data, cancellable, perror);
+}
+
+/* transfers items summary, which is either PR_TRANSPORT_MESSAGE_HEADERS_UNICODE or
+ the object without attachment */
+gboolean
+e_mapi_connection_transfer_summary (EMapiConnection *conn,
+ mapi_object_t *obj_folder,
+ const GSList *mids,
+ TransferObjectCB cb,
+ gpointer cb_user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ enum MAPISTATUS ms;
+ TALLOC_CTX *mem_ctx;
+ const GSList *iter;
+ guint32 index, total;
+
+ CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+ e_return_val_mapi_error_if_fail (priv->session != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+ e_return_val_mapi_error_if_fail (cb != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+ e_return_val_mapi_error_if_fail (obj_folder != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+
+ LOCK ();
+ mem_ctx = talloc_new (priv->session);
+
+ ms = MAPI_E_SUCCESS;
+ total = g_slist_length ((GSList *) mids);
+ for (iter = mids, index = 0; iter && ms == MAPI_E_SUCCESS; iter = iter->next, index++) {
+ mapi_id_t *pmid = iter->data;
+
+ if (pmid) {
+ mapi_object_t obj_message;
+ struct SPropTagArray *tags;
+ struct SPropValue *lpProps = NULL;
+ uint32_t prop_count = 0, ii;
+
+ mapi_object_init (&obj_message);
+
+ ms = OpenMessage (obj_folder, mapi_object_get_id (obj_folder), *pmid, &obj_message, 0);
+ if (ms != MAPI_E_SUCCESS && ms != MAPI_E_NOT_FOUND) {
+ make_mapi_error (perror, "OpenMessage", ms);
+ goto cleanup;
+ }
+
+ tags = set_SPropTagArray (mem_ctx, 6,
+ PR_FID,
+ PR_MID,
+ PR_MESSAGE_FLAGS,
+ PR_LAST_MODIFICATION_TIME,
+ PR_MESSAGE_CLASS,
+ PR_TRANSPORT_MESSAGE_HEADERS_UNICODE);
+
+ ms = GetProps (&obj_message, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, tags, &lpProps, &prop_count);
+ if (ms == MAPI_E_SUCCESS) {
+ ms = MAPI_E_NOT_FOUND;
+ if (lpProps && prop_count > 0) {
+ const gchar *headers = e_mapi_util_find_SPropVal_array_propval (lpProps, PR_TRANSPORT_MESSAGE_HEADERS_UNICODE);
+
+ if (headers && *headers) {
+ EMapiObject *object;
+
+ ms = MAPI_E_SUCCESS;
+
+ object = e_mapi_object_new (mem_ctx);
+ for (ii = 0; ii < prop_count; ii++) {
+ object->properties.cValues++;
+ object->properties.lpProps = talloc_realloc (mem_ctx,
+ object->properties.lpProps,
+ struct mapi_SPropValue,
+ object->properties.cValues + 1);
+ cast_mapi_SPropValue (mem_ctx, &object->properties.lpProps[object->properties.cValues - 1], &lpProps[ii]);
+ object->properties.lpProps[object->properties.cValues].ulPropTag = 0;
+ }
+
+ if (!cb (conn, mem_ctx, object, index, total, cb_user_data, cancellable, perror)) {
+ ms = MAPI_E_USER_CANCEL;
+ e_mapi_object_free (object);
+ mapi_object_release (&obj_message);
+ goto cleanup;
+ }
+
+ e_mapi_object_free (object);
+ }
+ }
+ }
+
+ if (ms == MAPI_E_NOT_FOUND) {
+ struct GetSummaryData gsd;
+
+ gsd.obj_index = index;
+ gsd.obj_total = total;
+ gsd.lpProps = lpProps;
+ gsd.prop_count = prop_count;
+ gsd.cb = cb;
+ gsd.cb_user_data = cb_user_data;
+
+ ms = e_mapi_fast_transfer_object (conn, mem_ctx, &obj_message, E_MAPI_FAST_TRANSFER_FLAG_RECIPIENTS, internal_get_summary_cb, &gsd, cancellable, perror);
+ if (ms != MAPI_E_SUCCESS) {
+ make_mapi_error (perror, "transfer_object", ms);
+ mapi_object_release (&obj_message);
+ goto cleanup;
+ }
+ }
+
+ mapi_object_release (&obj_message);
+ talloc_free (tags);
+ }
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
+ ms = MAPI_E_USER_CANCEL;
+ goto cleanup;
+ }
+ }
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
+ ms = MAPI_E_USER_CANCEL;
+ goto cleanup;
+ }
+
+ cleanup:
+ talloc_free (mem_ctx);
+ UNLOCK ();
+
+ return ms == MAPI_E_SUCCESS;
+}
+
gboolean
e_mapi_connection_fetch_items (EMapiConnection *conn,
mapi_id_t fid,
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index b0f919a..15afe6a 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -328,6 +328,14 @@ gboolean e_mapi_connection_transfer_objects (EMapiConnection *conn,
GCancellable *cancellable,
GError **perror);
+gboolean e_mapi_connection_transfer_summary (EMapiConnection *conn,
+ mapi_object_t *obj_folder,
+ const GSList *mids,
+ TransferObjectCB cb,
+ gpointer cb_user_data,
+ GCancellable *cancellable,
+ GError **perror);
+
gboolean e_mapi_connection_fetch_object_props (EMapiConnection *conn,
mapi_object_t *obj_folder,
mapi_id_t fid,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]