aboutsummaryrefslogtreecommitdiffstats
path: root/libemail-engine
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2013-05-25 02:09:54 +0800
committerMatthew Barnes <mbarnes@redhat.com>2013-05-25 10:03:51 +0800
commitdea7daf4c33ce4bdd020c19a3440538371b415a7 (patch)
treef1ba2eb8387f1da1f4cdfea7f0e76b488ed984f7 /libemail-engine
parent9b742e1f4a223e7025697faf1e1d2ffaab021226 (diff)
downloadgsoc2013-evolution-dea7daf4c33ce4bdd020c19a3440538371b415a7.tar.gz
gsoc2013-evolution-dea7daf4c33ce4bdd020c19a3440538371b415a7.tar.zst
gsoc2013-evolution-dea7daf4c33ce4bdd020c19a3440538371b415a7.zip
EMailSession: Add helper functions for sending messages.
New functions: e_mail_session_get_fcc_for_message_sync() e_mail_session_get_fcc_for_message() e_mail_session_get_fcc_for_message_finish() e_mail_session_ref_transport() e_mail_session_ref_default_transport() e_mail_session_ref_transport_for_message()
Diffstat (limited to 'libemail-engine')
-rw-r--r--libemail-engine/e-mail-session-utils.c677
-rw-r--r--libemail-engine/e-mail-session-utils.h23
2 files changed, 687 insertions, 13 deletions
diff --git a/libemail-engine/e-mail-session-utils.c b/libemail-engine/e-mail-session-utils.c
index da54b7640d..45033b01da 100644
--- a/libemail-engine/e-mail-session-utils.c
+++ b/libemail-engine/e-mail-session-utils.c
@@ -38,7 +38,7 @@
typedef struct _AsyncContext AsyncContext;
struct _AsyncContext {
- CamelFolder *sent_folder;
+ CamelFolder *folder;
CamelMimeMessage *message;
CamelMessageInfo *info;
@@ -67,8 +67,8 @@ struct _AsyncContext {
static void
async_context_free (AsyncContext *context)
{
- if (context->sent_folder != NULL)
- g_object_unref (context->sent_folder);
+ if (context->folder != NULL)
+ g_object_unref (context->folder);
if (context->message != NULL)
g_object_unref (context->message);
@@ -670,11 +670,11 @@ mail_session_send_to_thread (GSimpleAsyncResult *simple,
/* Try to extract a CamelFolder from the Sent folder URI. */
if (context->sent_folder_uri != NULL) {
- context->sent_folder = e_mail_session_uri_to_folder_sync (
+ context->folder = e_mail_session_uri_to_folder_sync (
session, context->sent_folder_uri, 0,
cancellable, &error);
if (error != NULL) {
- g_warn_if_fail (context->sent_folder == NULL);
+ g_warn_if_fail (context->folder == NULL);
if (error_messages->len > 0)
g_string_append (error_messages, "\n\n");
g_string_append_printf (
@@ -687,12 +687,12 @@ mail_session_send_to_thread (GSimpleAsyncResult *simple,
}
/* Fall back to the local Sent folder. */
- if (context->sent_folder == NULL)
- context->sent_folder = g_object_ref (local_sent_folder);
+ if (context->folder == NULL)
+ context->folder = g_object_ref (local_sent_folder);
/* Append the message. */
camel_folder_append_message_sync (
- context->sent_folder, context->message,
+ context->folder, context->message,
context->info, NULL, cancellable, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
@@ -703,11 +703,10 @@ mail_session_send_to_thread (GSimpleAsyncResult *simple,
/* If appending to a remote Sent folder failed,
* try appending to the local Sent folder. */
- if (context->sent_folder != local_sent_folder) {
+ if (context->folder != local_sent_folder) {
const gchar *description;
- description = camel_folder_get_description (
- context->sent_folder);
+ description = camel_folder_get_description (context->folder);
if (error_messages->len > 0)
g_string_append (error_messages, "\n\n");
@@ -776,9 +775,9 @@ exit:
}
/* Synchronize the Sent folder. */
- if (context->sent_folder != NULL)
+ if (context->folder != NULL)
camel_folder_synchronize_sync (
- context->sent_folder, FALSE, cancellable, NULL);
+ context->folder, FALSE, cancellable, NULL);
g_string_free (error_messages, TRUE);
}
@@ -1014,3 +1013,655 @@ e_mail_session_send_to_finish (EMailSession *session,
return !g_simple_async_result_propagate_error (simple, error);
}
+/* Helper for e_mail_session_get_fcc_for_message_sync() */
+static CamelFolder *
+mail_session_try_uri_to_folder (EMailSession *session,
+ const gchar *folder_uri,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolder *folder;
+ GError *local_error = NULL;
+
+ folder = e_mail_session_uri_to_folder_sync (
+ session, folder_uri, 0, cancellable, &local_error);
+
+ /* Sanity check. */
+ g_return_val_if_fail (
+ ((folder != NULL) && (local_error == NULL)) ||
+ ((folder == NULL) && (local_error != NULL)), NULL);
+
+ /* Disregard specific errors. */
+
+ /* Invalid URI. */
+ if (g_error_matches (
+ local_error, CAMEL_FOLDER_ERROR,
+ CAMEL_FOLDER_ERROR_INVALID))
+ g_clear_error (&local_error);
+
+ /* Folder not found. */
+ if (g_error_matches (
+ local_error, CAMEL_STORE_ERROR,
+ CAMEL_STORE_ERROR_NO_FOLDER))
+ g_clear_error (&local_error);
+
+ if (local_error != NULL)
+ g_propagate_error (error, local_error);
+
+ return folder;
+}
+
+/* Helper for e_mail_session_get_fcc_for_message_sync() */
+static CamelFolder *
+mail_session_ref_origin_folder (EMailSession *session,
+ CamelMimeMessage *message,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMedium *medium;
+ const gchar *header_name;
+ const gchar *header_value;
+
+ medium = CAMEL_MEDIUM (message);
+
+ /* Check that a "X-Evolution-Source-Flags" header is present
+ * and its value does not contain the substring "FORWARDED". */
+
+ header_name = "X-Evolution-Source-Flags";
+ header_value = camel_medium_get_header (medium, header_name);
+
+ if (header_value == NULL)
+ return NULL;
+
+ if (strstr (header_value, "FORWARDED") != NULL)
+ return NULL;
+
+ /* Check that a "X-Evolution-Source-Message" header is present. */
+
+ header_name = "X-Evolution-Source-Message";
+ header_value = camel_medium_get_header (medium, header_name);
+
+ if (header_value == NULL)
+ return NULL;
+
+ /* Check that a "X-Evolution-Source-Folder" header is present.
+ * Its value specifies the origin folder as a folder URI. */
+
+ header_name = "X-Evolution-Source-Folder";
+ header_value = camel_medium_get_header (medium, header_name);
+
+ if (header_value == NULL)
+ return NULL;
+
+ /* This may return NULL without setting a GError. */
+ return mail_session_try_uri_to_folder (
+ session, header_value, cancellable, error);
+}
+
+/* Helper for e_mail_session_get_fcc_for_message_sync() */
+static CamelFolder *
+mail_session_ref_fcc_from_identity (EMailSession *session,
+ ESource *source,
+ CamelMimeMessage *message,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ESourceRegistry *registry;
+ ESourceMailSubmission *extension;
+ CamelFolder *folder = NULL;
+ const gchar *extension_name;
+ gchar *folder_uri;
+
+ registry = e_mail_session_get_registry (session);
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+
+ if (source == NULL)
+ return NULL;
+
+ if (!e_source_registry_check_enabled (registry, source))
+ return NULL;
+
+ if (!e_source_has_extension (source, extension_name))
+ return NULL;
+
+ extension = e_source_get_extension (source, extension_name);
+
+ if (e_source_mail_submission_get_replies_to_origin_folder (extension)) {
+ GError *local_error = NULL;
+
+ /* This may return NULL without setting a GError. */
+ folder = mail_session_ref_origin_folder (
+ session, message, cancellable, &local_error);
+
+ if (local_error != NULL) {
+ g_warn_if_fail (folder == NULL);
+ g_propagate_error (error, local_error);
+ return NULL;
+ }
+ }
+
+ folder_uri = e_source_mail_submission_dup_sent_folder (extension);
+
+ if (folder_uri != NULL && folder == NULL) {
+ /* This may return NULL without setting a GError. */
+ folder = mail_session_try_uri_to_folder (
+ session, folder_uri, cancellable, error);
+ }
+
+ g_free (folder_uri);
+
+ return folder;
+}
+
+/* Helper for e_mail_session_get_fcc_for_message_sync() */
+static CamelFolder *
+mail_session_ref_fcc_from_x_identity (EMailSession *session,
+ CamelMimeMessage *message,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ESource *source;
+ ESourceRegistry *registry;
+ CamelFolder *folder;
+ CamelMedium *medium;
+ const gchar *header_name;
+ const gchar *header_value;
+ gchar *uid;
+
+ medium = CAMEL_MEDIUM (message);
+ header_name = "X-Evolution-Identity";
+ header_value = camel_medium_get_header (medium, header_name);
+
+ if (header_value == NULL)
+ return NULL;
+
+ uid = g_strstrip (g_strdup (header_value));
+
+ registry = e_mail_session_get_registry (session);
+ source = e_source_registry_ref_source (registry, uid);
+
+ /* This may return NULL without setting a GError. */
+ folder = mail_session_ref_fcc_from_identity (
+ session, source, message, cancellable, error);
+
+ g_clear_object (&source);
+
+ g_free (uid);
+
+ return folder;
+}
+
+/* Helper for e_mail_session_get_fcc_for_message_sync() */
+static CamelFolder *
+mail_session_ref_fcc_from_x_fcc (EMailSession *session,
+ CamelMimeMessage *message,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMedium *medium;
+ const gchar *header_name;
+ const gchar *header_value;
+
+ medium = CAMEL_MEDIUM (message);
+ header_name = "X-Evolution-Fcc";
+ header_value = camel_medium_get_header (medium, header_name);
+
+ if (header_value == NULL)
+ return NULL;
+
+ /* This may return NULL without setting a GError. */
+ return mail_session_try_uri_to_folder (
+ session, header_value, cancellable, error);
+}
+
+/* Helper for e_mail_session_get_fcc_for_message_sync() */
+static CamelFolder *
+mail_session_ref_fcc_from_default_identity (EMailSession *session,
+ CamelMimeMessage *message,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ESource *source;
+ ESourceRegistry *registry;
+ CamelFolder *folder;
+
+ registry = e_mail_session_get_registry (session);
+ source = e_source_registry_ref_default_mail_identity (registry);
+
+ /* This may return NULL without setting a GError. */
+ folder = mail_session_ref_fcc_from_identity (
+ session, source, message, cancellable, error);
+
+ g_clear_object (&source);
+
+ return folder;
+}
+
+/**
+ * e_mail_session_get_fcc_for_message_sync:
+ * @session: an #EMailSession
+ * @message: a #CamelMimeMessage
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Obtains the preferred "carbon-copy" folder (a.k.a Fcc) for @message
+ * by first checking @message for an "X-Evolution-Identity" header, and
+ * then an "X-Evolution-Fcc" header. Failing that, the function checks
+ * the default mail identity (if available), and failing even that, the
+ * function falls back to the Sent folder from the built-in mail store.
+ *
+ * Where applicable, the function attempts to honor the
+ * #ESourceMailSubmission:replies-to-origin-folder preference.
+ *
+ * The returned #CamelFolder is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * If a non-recoverable error occurs, the function sets @error and returns
+ * %NULL.
+ *
+ * Returns: a #CamelFolder, or %NULL
+ **/
+CamelFolder *
+e_mail_session_get_fcc_for_message_sync (EMailSession *session,
+ CamelMimeMessage *message,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolder *folder = NULL;
+
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+ g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
+
+ /* Check for "X-Evolution-Identity" header. */
+ if (folder == NULL) {
+ GError *local_error = NULL;
+
+ /* This may return NULL without setting a GError. */
+ folder = mail_session_ref_fcc_from_x_identity (
+ session, message, cancellable, &local_error);
+
+ if (local_error != NULL) {
+ g_warn_if_fail (folder == NULL);
+ g_propagate_error (error, local_error);
+ return NULL;
+ }
+ }
+
+ /* Check for "X-Evolution-Fcc" header. */
+ if (folder == NULL) {
+ GError *local_error = NULL;
+
+ /* This may return NULL without setting a GError. */
+ folder = mail_session_ref_fcc_from_x_fcc (
+ session, message, cancellable, &local_error);
+
+ if (local_error != NULL) {
+ g_warn_if_fail (folder == NULL);
+ g_propagate_error (error, local_error);
+ return NULL;
+ }
+ }
+
+ /* Check the default mail identity. */
+ if (folder == NULL) {
+ GError *local_error = NULL;
+
+ /* This may return NULL without setting a GError. */
+ folder = mail_session_ref_fcc_from_default_identity (
+ session, message, cancellable, &local_error);
+
+ if (local_error != NULL) {
+ g_warn_if_fail (folder == NULL);
+ g_propagate_error (error, local_error);
+ return NULL;
+ }
+ }
+
+ /* Last resort - local Sent folder. */
+ if (folder == NULL) {
+ folder = e_mail_session_get_local_folder (
+ session, E_MAIL_LOCAL_FOLDER_SENT);
+ g_object_ref (folder);
+ }
+
+ return folder;
+}
+
+/* Helper for e_mail_session_get_fcc_for_message() */
+static void
+mail_session_get_fcc_for_message_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *local_error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->folder =
+ e_mail_session_get_fcc_for_message_sync (
+ E_MAIL_SESSION (source_object),
+ async_context->message,
+ cancellable, &local_error);
+
+ if (local_error != NULL)
+ g_simple_async_result_take_error (simple, local_error);
+}
+
+/**
+ * e_mail_session_get_fcc_for_message:
+ * @session: an #EMailSession
+ * @message: a #CamelMimeMessage
+ * @io_priority: the I/O priority of the request
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: data to pass to the callback function
+ *
+ * Asynchronously obtains the preferred "carbon-copy" folder (a.k.a Fcc) for
+ * @message by first checking @message for an "X-Evolution-Identity" header,
+ * and then an "X-Evolution-Fcc" header. Failing that, the function checks
+ * the default mail identity (if available), and failing even that, the
+ * function falls back to the Sent folder from the built-in mail store.
+ *
+ * Where applicable, the function attempts to honor the
+ * #ESourceMailSubmission:replies-to-origin-folder preference.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call e_mail_session_get_fcc_for_message_finish() to get the result of the
+ * operation.
+ **/
+void
+e_mail_session_get_fcc_for_message (EMailSession *session,
+ CamelMimeMessage *message,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_if_fail (E_IS_MAIL_SESSION (session));
+ g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->message = g_object_ref (message);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (session), callback, user_data,
+ e_mail_session_get_fcc_for_message);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, mail_session_get_fcc_for_message_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+/**
+ * e_mail_session_get_fcc_for_message_finish:
+ * @session: an #EMailSession
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with e_mail_session_get_fcc_for_message().
+ *
+ * The returned #CamelFolder is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * If a non-recoverable error occurred, the function sets @error and
+ * returns %NULL.
+ *
+ * Returns: a #CamelFolder, or %NULL
+ **/
+CamelFolder *
+e_mail_session_get_fcc_for_message_finish (EMailSession *session,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (session),
+ e_mail_session_get_fcc_for_message), NULL);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+
+ g_return_val_if_fail (async_context->folder != NULL, NULL);
+
+ return g_object_ref (async_context->folder);
+}
+
+/**
+ * e_mail_session_ref_transport:
+ * @session: an #EMailSession
+ * @transport_uid: the UID of a mail transport
+ *
+ * Returns the transport #CamelService instance for @transport_uid,
+ * verifying first that the @transport_uid is indeed a mail transport and
+ * that the corresponding #ESource is enabled. If these checks fail, the
+ * function returns %NULL.
+ *
+ * The returned #CamelService is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: a #CamelService, or %NULL
+ **/
+CamelService *
+e_mail_session_ref_transport (EMailSession *session,
+ const gchar *transport_uid)
+{
+ ESourceRegistry *registry;
+ ESource *source = NULL;
+ CamelService *transport = NULL;
+ const gchar *extension_name;
+
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+ g_return_val_if_fail (transport_uid != NULL, NULL);
+
+ registry = e_mail_session_get_registry (session);
+ extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+
+ source = e_source_registry_ref_source (registry, transport_uid);
+
+ if (source == NULL)
+ goto exit;
+
+ if (!e_source_registry_check_enabled (registry, source))
+ goto exit;
+
+ if (!e_source_has_extension (source, extension_name))
+ goto exit;
+
+ transport = camel_session_ref_service (
+ CAMEL_SESSION (session), transport_uid);
+
+ /* Sanity check. */
+ if (transport != NULL)
+ g_warn_if_fail (CAMEL_IS_TRANSPORT (transport));
+
+exit:
+ g_clear_object (&source);
+
+ return transport;
+}
+
+/* Helper for e_mail_session_ref_default_transport()
+ * and mail_session_ref_transport_from_x_identity(). */
+static CamelService *
+mail_session_ref_transport_for_identity (EMailSession *session,
+ ESource *source)
+{
+ ESourceRegistry *registry;
+ ESourceMailSubmission *extension;
+ CamelService *transport = NULL;
+ const gchar *extension_name;
+ gchar *uid;
+
+ registry = e_mail_session_get_registry (session);
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+
+ if (source == NULL)
+ return NULL;
+
+ if (!e_source_registry_check_enabled (registry, source))
+ return NULL;
+
+ if (!e_source_has_extension (source, extension_name))
+ return NULL;
+
+ extension = e_source_get_extension (source, extension_name);
+ uid = e_source_mail_submission_dup_transport_uid (extension);
+
+ if (uid != NULL) {
+ transport = e_mail_session_ref_transport (session, uid);
+ g_free (uid);
+ }
+
+ return transport;
+}
+
+/**
+ * e_mail_session_ref_default_transport:
+ * @session: an #EMailSession
+ *
+ * Returns the default transport #CamelService instance according to
+ * #ESourceRegistry's #ESourceRegistry:default-mail-identity setting,
+ * verifying first that the #ESourceMailSubmission:transport-uid named by
+ * the #ESourceRegistry:default-mail-identity is indeed a mail transport,
+ * and that the corresponding #ESource is enabled. If these checks fail,
+ * the function returns %NULL.
+ *
+ * The returned #CamelService is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: a #CamelService, or %NULL
+ **/
+CamelService *
+e_mail_session_ref_default_transport (EMailSession *session)
+{
+ ESource *source;
+ ESourceRegistry *registry;
+ CamelService *transport;
+
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+ registry = e_mail_session_get_registry (session);
+ source = e_source_registry_ref_default_mail_identity (registry);
+ transport = mail_session_ref_transport_for_identity (session, source);
+ g_clear_object (&source);
+
+ return transport;
+}
+
+/* Helper for e_mail_session_ref_transport_for_message() */
+static CamelService *
+mail_session_ref_transport_from_x_identity (EMailSession *session,
+ CamelMimeMessage *message)
+{
+ ESource *source;
+ ESourceRegistry *registry;
+ CamelMedium *medium;
+ CamelService *transport;
+ const gchar *header_name;
+ const gchar *header_value;
+ gchar *uid;
+
+ medium = CAMEL_MEDIUM (message);
+ header_name = "X-Evolution-Identity";
+ header_value = camel_medium_get_header (medium, header_name);
+
+ if (header_value == NULL)
+ return NULL;
+
+ uid = g_strstrip (g_strdup (header_value));
+
+ registry = e_mail_session_get_registry (session);
+ source = e_source_registry_ref_source (registry, uid);
+ transport = mail_session_ref_transport_for_identity (session, source);
+ g_clear_object (&source);
+
+ g_free (uid);
+
+ return transport;
+}
+
+/* Helper for e_mail_session_ref_transport_for_message() */
+static CamelService *
+mail_session_ref_transport_from_x_transport (EMailSession *session,
+ CamelMimeMessage *message)
+{
+ CamelMedium *medium;
+ CamelService *transport;
+ const gchar *header_name;
+ const gchar *header_value;
+ gchar *uid;
+
+ medium = CAMEL_MEDIUM (message);
+ header_name = "X-Evolution-Transport";
+ header_value = camel_medium_get_header (medium, header_name);
+
+ if (header_value == NULL)
+ return NULL;
+
+ uid = g_strstrip (g_strdup (header_value));
+
+ transport = e_mail_session_ref_transport (session, uid);
+
+ g_free (uid);
+
+ return transport;
+}
+
+/**
+ * e_mail_session_ref_transport_for_message:
+ * @session: an #EMailSession
+ * @message: a #CamelMimeMessage
+ *
+ * Returns the preferred transport #CamelService instance for @message by
+ * first checking @message for an "X-Evolution-Identity" header, and then
+ * an "X-Evolution-Transport" header. Failing that, the function returns
+ * the default transport #CamelService instance (if available).
+ *
+ * The returned #CamelService is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: a #CamelService, or %NULL
+ **/
+CamelService *
+e_mail_session_ref_transport_for_message (EMailSession *session,
+ CamelMimeMessage *message)
+{
+ CamelService *transport = NULL;
+
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+ g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
+
+ /* Check for "X-Evolution-Identity" header. */
+ if (transport == NULL)
+ transport = mail_session_ref_transport_from_x_identity (
+ session, message);
+
+ /* Check for "X-Evolution-Transport" header. */
+ if (transport == NULL)
+ transport = mail_session_ref_transport_from_x_transport (
+ session, message);
+
+ /* Fall back to the default mail transport. */
+ if (transport == NULL)
+ transport = e_mail_session_ref_default_transport (session);
+
+ return transport;
+}
+
diff --git a/libemail-engine/e-mail-session-utils.h b/libemail-engine/e-mail-session-utils.h
index 0c7cff3f97..6349834d8d 100644
--- a/libemail-engine/e-mail-session-utils.h
+++ b/libemail-engine/e-mail-session-utils.h
@@ -97,6 +97,29 @@ void e_mail_session_send_to (EMailSession *session,
gboolean e_mail_session_send_to_finish (EMailSession *session,
GAsyncResult *result,
GError **error);
+CamelFolder * e_mail_session_get_fcc_for_message_sync
+ (EMailSession *session,
+ CamelMimeMessage *message,
+ GCancellable *cancellable,
+ GError **error);
+void e_mail_session_get_fcc_for_message
+ (EMailSession *session,
+ CamelMimeMessage *message,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+CamelFolder * e_mail_session_get_fcc_for_message_finish
+ (EMailSession *session,
+ GAsyncResult *result,
+ GError **error);
+CamelService * e_mail_session_ref_transport (EMailSession *session,
+ const gchar *transport_uid);
+CamelService * e_mail_session_ref_default_transport
+ (EMailSession *session);
+CamelService * e_mail_session_ref_transport_for_message
+ (EMailSession *session,
+ CamelMimeMessage *message);
G_END_DECLS