summaryrefslogtreecommitdiff
path: root/camel
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-09-23 14:04:32 -0400
committerMatthew Barnes <mbarnes@redhat.com>2010-09-28 11:36:48 -0400
commitcea02d071c2e5334d5f38b802d32e47bf06766cc (patch)
tree0f79b76ab79959978d20c0b46a8acd70cf699d6c /camel
parent68a4fe903696822894def062d300155f2646cc14 (diff)
downloadevolution-data-server-cea02d071c2e5334d5f38b802d32e47bf06766cc.tar.gz
Camel: Add an asynchronous API.
Add pairs of asynchronous "dispatch" and "finish" methods for most blocking "sync" methods in Camel's public API. All asynchronous methods have default implementations that just call its synchronous counterpart from a thread in GIO's thread pool (which is roughly equivalent to what Evolution is doing from its own thread pool). The possibility for Camel providers to implement an asynchronous architecture by overriding the asynchronous methods exists, but first requires some cleanup in the synchronous dispatching functions, many of which are not "pure" in the sense that they do extra stuff before and after calling the class method they wrap. That extra logic needs to somehow run as part of the class method itself, either via chaining up from subclasses or some other means. In simpler terms, the following invariant must hold before providers can override asynchronous methods and expect correct behavior from Camel: Calling camel_foo_frobnicate_sync(foo) is equivalent to calling CAMEL_FOO_GET_CLASS (foo)->frobnicate_sync (foo), just with fewer runtime checks.
Diffstat (limited to 'camel')
-rw-r--r--camel/camel-cipher-context.c1281
-rw-r--r--camel/camel-cipher-context.h172
-rw-r--r--camel/camel-data-wrapper.c573
-rw-r--r--camel/camel-data-wrapper.h81
-rw-r--r--camel/camel-db.h2
-rw-r--r--camel/camel-disco-diary.c9
-rw-r--r--camel/camel-disco-folder.c14
-rw-r--r--camel/camel-filter-driver.c18
-rw-r--r--camel/camel-folder-search.c3
-rw-r--r--camel/camel-folder-summary.c5
-rw-r--r--camel/camel-folder-summary.h2
-rw-r--r--camel/camel-folder.c1732
-rw-r--r--camel/camel-folder.h176
-rw-r--r--camel/camel-gpg-context.c59
-rw-r--r--camel/camel-mime-message.c25
-rw-r--r--camel/camel-mime-message.h102
-rw-r--r--camel/camel-mime-part-utils.c18
-rw-r--r--camel/camel-mime-part.c736
-rw-r--r--camel/camel-mime-part.h33
-rw-r--r--camel/camel-multipart-signed.c6
-rw-r--r--camel/camel-net-utils.c8
-rw-r--r--camel/camel-offline-folder.c193
-rw-r--r--camel/camel-offline-folder.h29
-rw-r--r--camel/camel-operation.c249
-rw-r--r--camel/camel-operation.h11
-rw-r--r--camel/camel-sasl.c321
-rw-r--r--camel/camel-sasl.h32
-rw-r--r--camel/camel-smime-context.c26
-rw-r--r--camel/camel-store.c3012
-rw-r--r--camel/camel-store.h246
-rw-r--r--camel/camel-transport.c238
-rw-r--r--camel/camel-transport.h32
-rw-r--r--camel/camel-vee-folder.c4
-rw-r--r--camel/camel-vtrash-folder.c6
-rw-r--r--camel/providers/groupwise/camel-groupwise-folder.c26
-rw-r--r--camel/providers/groupwise/camel-groupwise-journal.c4
-rw-r--r--camel/providers/groupwise/camel-groupwise-store.c10
-rw-r--r--camel/providers/groupwise/camel-groupwise-transport.c8
-rw-r--r--camel/providers/imap/camel-imap-folder.c119
-rw-r--r--camel/providers/imap/camel-imap-folder.h4
-rw-r--r--camel/providers/imap/camel-imap-journal.c2
-rw-r--r--camel/providers/imapx/camel-imapx-folder.c8
-rw-r--r--camel/providers/imapx/camel-imapx-server.c6
-rw-r--r--camel/providers/local/camel-maildir-folder.c17
-rw-r--r--camel/providers/local/camel-maildir-summary.c17
-rw-r--r--camel/providers/local/camel-mbox-folder.c6
-rw-r--r--camel/providers/local/camel-mbox-summary.c22
-rw-r--r--camel/providers/local/camel-mh-folder.c6
-rw-r--r--camel/providers/local/camel-spool-summary.c8
-rw-r--r--camel/providers/nntp/camel-nntp-folder.c2
-rw-r--r--camel/providers/nntp/camel-nntp-summary.c10
-rw-r--r--camel/providers/pop3/camel-pop3-folder.c30
-rw-r--r--camel/providers/smtp/camel-smtp-transport.c32
53 files changed, 7627 insertions, 2164 deletions
diff --git a/camel/camel-cipher-context.c b/camel/camel-cipher-context.c
index 3ffa355f9..782e99722 100644
--- a/camel/camel-cipher-context.c
+++ b/camel/camel-cipher-context.c
@@ -50,11 +50,26 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), CAMEL_TYPE_CIPHER_CONTEXT, CamelCipherContextPrivate))
+typedef struct _AsyncContext AsyncContext;
+
struct _CamelCipherContextPrivate {
CamelSession *session;
GMutex *lock;
};
+struct _AsyncContext {
+ /* arguments */
+ CamelCipherHash hash;
+ CamelMimePart *ipart;
+ CamelMimePart *opart;
+ CamelStream *stream;
+ GPtrArray *strings;
+ gchar *userid;
+
+ /* results */
+ CamelCipherValidity *validity;
+};
+
enum {
PROP_0,
PROP_SESSION
@@ -63,6 +78,32 @@ enum {
G_DEFINE_TYPE (CamelCipherContext, camel_cipher_context, CAMEL_TYPE_OBJECT)
static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->ipart != NULL)
+ g_object_unref (async_context->ipart);
+
+ if (async_context->opart != NULL)
+ g_object_unref (async_context->opart);
+
+ if (async_context->stream != NULL)
+ g_object_unref (async_context->stream);
+
+ if (async_context->strings != NULL) {
+ g_ptr_array_foreach (
+ async_context->strings, (GFunc) g_free, NULL);
+ g_ptr_array_free (async_context->strings, TRUE);
+ }
+
+ if (async_context->validity != NULL)
+ camel_cipher_validity_free (async_context->validity);
+
+ g_free (async_context->userid);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
cipher_context_set_session (CamelCipherContext *context,
CamelSession *session)
{
@@ -136,40 +177,40 @@ cipher_context_finalize (GObject *object)
}
static const gchar *
-cipher_hash_to_id (CamelCipherContext *context,
- CamelCipherHash hash)
+cipher_context_hash_to_id (CamelCipherContext *context,
+ CamelCipherHash hash)
{
return NULL;
}
static CamelCipherHash
-cipher_id_to_hash (CamelCipherContext *context,
- const gchar *id)
+cipher_context_id_to_hash (CamelCipherContext *context,
+ const gchar *id)
{
return CAMEL_CIPHER_HASH_DEFAULT;
}
-static gint
-cipher_sign_sync (CamelCipherContext *ctx,
- const gchar *userid,
- CamelCipherHash hash,
- CamelMimePart *ipart,
- CamelMimePart *opart,
- GCancellable *cancellable,
- GError **error)
+static gboolean
+cipher_context_sign_sync (CamelCipherContext *ctx,
+ const gchar *userid,
+ CamelCipherHash hash,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ GCancellable *cancellable,
+ GError **error)
{
g_set_error (
error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Signing is not supported by this cipher"));
- return -1;
+ return FALSE;
}
static CamelCipherValidity *
-cipher_verify_sync (CamelCipherContext *context,
- CamelMimePart *sigpart,
- GCancellable *cancellable,
- GError **error)
+cipher_context_verify_sync (CamelCipherContext *context,
+ CamelMimePart *sigpart,
+ GCancellable *cancellable,
+ GError **error)
{
g_set_error (
error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
@@ -178,28 +219,28 @@ cipher_verify_sync (CamelCipherContext *context,
return NULL;
}
-static gint
-cipher_encrypt_sync (CamelCipherContext *context,
- const gchar *userid,
- GPtrArray *recipients,
- CamelMimePart *ipart,
- CamelMimePart *opart,
- GCancellable *cancellable,
- GError **error)
+static gboolean
+cipher_context_encrypt_sync (CamelCipherContext *context,
+ const gchar *userid,
+ GPtrArray *recipients,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ GCancellable *cancellable,
+ GError **error)
{
g_set_error (
error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Encryption is not supported by this cipher"));
- return -1;
+ return FALSE;
}
static CamelCipherValidity *
-cipher_decrypt_sync (CamelCipherContext *context,
- CamelMimePart *ipart,
- CamelMimePart *opart,
- GCancellable *cancellable,
- GError **error)
+cipher_context_decrypt_sync (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ GCancellable *cancellable,
+ GError **error)
{
g_set_error (
error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
@@ -208,31 +249,469 @@ cipher_decrypt_sync (CamelCipherContext *context,
return NULL;
}
-static gint
-cipher_import_keys_sync (CamelCipherContext *context,
- CamelStream *istream,
- GCancellable *cancellable,
- GError **error)
+static gboolean
+cipher_context_import_keys_sync (CamelCipherContext *context,
+ CamelStream *istream,
+ GCancellable *cancellable,
+ GError **error)
{
g_set_error (
error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("You may not import keys with this cipher"));
- return -1;
+ return FALSE;
}
static gint
-cipher_export_keys_sync (CamelCipherContext *context,
- GPtrArray *keys,
- CamelStream *ostream,
- GCancellable *cancellable,
- GError **error)
+cipher_context_export_keys_sync (CamelCipherContext *context,
+ GPtrArray *keys,
+ CamelStream *ostream,
+ GCancellable *cancellable,
+ GError **error)
{
g_set_error (
error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("You may not export keys with this cipher"));
- return -1;
+ return FALSE;
+}
+
+static void
+cipher_context_sign_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_cipher_context_sign_sync (
+ CAMEL_CIPHER_CONTEXT (object),
+ async_context->userid, async_context->hash,
+ async_context->ipart, async_context->opart,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+cipher_context_sign (CamelCipherContext *context,
+ const gchar *userid,
+ CamelCipherHash hash,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->userid = g_strdup (userid);
+ async_context->hash = hash;
+ async_context->ipart = g_object_ref (ipart);
+ async_context->opart = g_object_ref (opart);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (context), callback, user_data, cipher_context_sign);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, cipher_context_sign_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+cipher_context_sign_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (context), cipher_context_sign), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+cipher_context_verify_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->validity = camel_cipher_context_verify_sync (
+ CAMEL_CIPHER_CONTEXT (object), async_context->ipart,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+cipher_context_verify (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->ipart = g_object_ref (ipart);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (context), callback,
+ user_data, cipher_context_verify);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, cipher_context_verify_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static CamelCipherValidity *
+cipher_context_verify_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ CamelCipherValidity *validity;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (context), cipher_context_verify), 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;
+
+ validity = async_context->validity;
+ async_context->validity = NULL;
+
+ return validity;
+}
+
+static void
+cipher_context_encrypt_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_cipher_context_encrypt_sync (
+ CAMEL_CIPHER_CONTEXT (object),
+ async_context->userid, async_context->strings,
+ async_context->ipart, async_context->opart,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+cipher_context_encrypt (CamelCipherContext *context,
+ const gchar *userid,
+ GPtrArray *recipients,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ guint ii;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->userid = g_strdup (userid);
+ async_context->strings = g_ptr_array_new ();
+ async_context->ipart = g_object_ref (ipart);
+ async_context->opart = g_object_ref (opart);
+
+ for (ii = 0; ii < recipients->len; ii++)
+ g_ptr_array_add (
+ async_context->strings,
+ g_strdup (recipients->pdata[ii]));
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (context), callback,
+ user_data, cipher_context_encrypt);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, cipher_context_encrypt_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+cipher_context_encrypt_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (context), cipher_context_encrypt), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+cipher_context_decrypt_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->validity = camel_cipher_context_decrypt_sync (
+ CAMEL_CIPHER_CONTEXT (object), async_context->ipart,
+ async_context->opart, cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+cipher_context_decrypt (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->ipart = g_object_ref (ipart);
+ async_context->opart = g_object_ref (opart);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (context), callback,
+ user_data, cipher_context_decrypt);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, cipher_context_decrypt_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static CamelCipherValidity *
+cipher_context_decrypt_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ CamelCipherValidity *validity;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (context), cipher_context_decrypt), 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;
+
+ validity = async_context->validity;
+ async_context->validity = NULL;
+
+ return validity;
+}
+
+static void
+cipher_context_import_keys_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_cipher_context_import_keys_sync (
+ CAMEL_CIPHER_CONTEXT (object), async_context->stream,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+cipher_context_import_keys (CamelCipherContext *context,
+ CamelStream *istream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->stream = g_object_ref (istream);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (context), callback,
+ user_data, cipher_context_import_keys);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, cipher_context_import_keys_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+cipher_context_import_keys_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (context),
+ cipher_context_import_keys), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+cipher_context_export_keys_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_cipher_context_export_keys_sync (
+ CAMEL_CIPHER_CONTEXT (object), async_context->strings,
+ async_context->stream, cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+cipher_context_export_keys (CamelCipherContext *context,
+ GPtrArray *keys,
+ CamelStream *ostream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ guint ii;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->strings = g_ptr_array_new ();
+ async_context->stream = g_object_ref (ostream);
+
+ for (ii = 0; ii < keys->len; ii++)
+ g_ptr_array_add (
+ async_context->strings,
+ g_strdup (keys->pdata[ii]));
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (context), callback,
+ user_data, cipher_context_export_keys);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, cipher_context_export_keys_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+cipher_context_export_keys_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (context),
+ cipher_context_export_keys), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
static void
@@ -248,14 +727,28 @@ camel_cipher_context_class_init (CamelCipherContextClass *class)
object_class->dispose = cipher_context_dispose;
object_class->finalize = cipher_context_finalize;
- class->hash_to_id = cipher_hash_to_id;
- class->id_to_hash = cipher_id_to_hash;
- class->sign_sync = cipher_sign_sync;
- class->verify_sync = cipher_verify_sync;
- class->encrypt_sync = cipher_encrypt_sync;
- class->decrypt_sync = cipher_decrypt_sync;
- class->import_keys_sync = cipher_import_keys_sync;
- class->export_keys_sync = cipher_export_keys_sync;
+ class->hash_to_id = cipher_context_hash_to_id;
+ class->id_to_hash = cipher_context_id_to_hash;
+
+ class->sign_sync = cipher_context_sign_sync;
+ class->verify_sync = cipher_context_verify_sync;
+ class->encrypt_sync = cipher_context_encrypt_sync;
+ class->decrypt_sync = cipher_context_decrypt_sync;
+ class->import_keys_sync = cipher_context_import_keys_sync;
+ class->export_keys_sync = cipher_context_export_keys_sync;
+
+ class->sign = cipher_context_sign;
+ class->sign_finish = cipher_context_sign_finish;
+ class->verify = cipher_context_verify;
+ class->verify_finish = cipher_context_verify_finish;
+ class->encrypt = cipher_context_encrypt;
+ class->encrypt_finish = cipher_context_encrypt_finish;
+ class->decrypt = cipher_context_decrypt;
+ class->decrypt_finish = cipher_context_decrypt_finish;
+ class->import_keys = cipher_context_import_keys;
+ class->import_keys_finish = cipher_context_import_keys_finish;
+ class->export_keys = cipher_context_export_keys;
+ class->export_keys_finish = cipher_context_export_keys_finish;
g_object_class_install_property (
object_class,
@@ -277,81 +770,169 @@ camel_cipher_context_init (CamelCipherContext *context)
}
/**
- * camel_cipher_sign_sync:
- * @context: Cipher Context
- * @userid: private key to use to sign the stream
+ * camel_cipher_context_sign_sync:
+ * @context: a #CamelCipherContext
+ * @userid: a private key to use to sign the stream
* @hash: preferred Message-Integrity-Check hash algorithm
- * @ipart: Input part.
- * @opart: output part.
+ * @ipart: input #CamelMimePart
+ * @opart: output #CamelMimePart
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
- * Converts the (unsigned) part @ipart into a new self-contained mime
+ * Converts the (unsigned) part @ipart into a new self-contained MIME
* part @opart. This may be a multipart/signed part, or a simple part
* for enveloped types.
*
- * Returns: 0 for success or -1 for failure.
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
-gint
-camel_cipher_sign_sync (CamelCipherContext *context,
- const gchar *userid,
- CamelCipherHash hash,
- CamelMimePart *ipart,
- CamelMimePart *opart,
- GCancellable *cancellable,
- GError **error)
+gboolean
+camel_cipher_context_sign_sync (CamelCipherContext *context,
+ const gchar *userid,
+ CamelCipherHash hash,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ GCancellable *cancellable,
+ GError **error)
{
CamelCipherContextClass *class;
- gint retval;
+ gboolean success;
- g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1);
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), FALSE);
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
- g_return_val_if_fail (class->sign_sync != NULL, -1);
+ g_return_val_if_fail (class->sign_sync != NULL, FALSE);
CIPHER_LOCK (context);
- retval = class->sign_sync (
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ CIPHER_UNLOCK (context);
+ return FALSE;
+ }
+
+ camel_operation_push_message (cancellable, _("Signing message"));
+
+ success = class->sign_sync (
context, userid, hash, ipart, opart, cancellable, error);
- CAMEL_CHECK_GERROR (context, sign_sync, retval == 0, error);
+ CAMEL_CHECK_GERROR (context, sign_sync, success, error);
+
+ camel_operation_pop_message (cancellable);
CIPHER_UNLOCK (context);
- return retval;
+ return success;
+}
+
+/**
+ * camel_cipher_context_sign:
+ * @context: a #CamelCipherContext
+ * @userid: a private key to use to sign the stream
+ * @hash: preferred Message-Integrity-Check hash algorithm
+ * @ipart: input #CamelMimePart
+ * @opart: output #CamelMimePart
+ * @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 converts the (unsigned) part @ipart into a new
+ * self-contained MIME part @opart. This may be a multipart/signed part,
+ * or a simple part for enveloped types.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_cipher_context_sign_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_cipher_context_sign (CamelCipherContext *context,
+ const gchar *userid,
+ CamelCipherHash hash,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelCipherContextClass *class;
+
+ g_return_if_fail (CAMEL_IS_CIPHER_CONTEXT (context));
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_if_fail (class->sign != NULL);
+
+ class->sign (
+ context, userid, hash, ipart, opart, io_priority,
+ cancellable, callback, user_data);
}
/**
- * camel_cipher_verify_sync:
- * @context: Cipher Context
- * @ipart: part to verify
+ * camel_cipher_context_sign_finish:
+ * @context: a #CamelCipherContext
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_cipher_context_sign().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_cipher_context_sign_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelCipherContextClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_val_if_fail (class->sign_finish != NULL, FALSE);
+
+ return class->sign_finish (context, result, error);
+}
+
+/**
+ * camel_cipher_context_verify_sync:
+ * @context: a #CamelCipherContext
+ * @ipart: the #CamelMimePart to verify
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
- * Verifies the signature. If @istream is a clearsigned stream,
- * you should pass %NULL as the sigstream parameter. Otherwise
- * @sigstream is assumed to be the signature stream and is used to
- * verify the integirity of the @istream.
+ * Verifies the signature.
*
- * Returns: a CamelCipherValidity structure containing information
- * about the integrity of the input stream or %NULL on failure to
- * execute at all.
+ * Returns: a #CamelCipherValidity structure containing information
+ * about the integrity of the input stream, or %NULL on failure to
+ * execute at all
**/
CamelCipherValidity *
-camel_cipher_verify_sync (CamelCipherContext *context,
- CamelMimePart *ipart,
- GCancellable *cancellable,
- GError **error)
+camel_cipher_context_verify_sync (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ GCancellable *cancellable,
+ GError **error)
{
CamelCipherContextClass *class;
CamelCipherValidity *valid;
g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL);
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (ipart), NULL);
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
g_return_val_if_fail (class->verify_sync != NULL, NULL);
CIPHER_LOCK (context);
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ CIPHER_UNLOCK (context);
+ return NULL;
+ }
+
valid = class->verify_sync (context, ipart, cancellable, error);
CAMEL_CHECK_GERROR (context, verify_sync, valid != NULL, error);
@@ -361,162 +942,542 @@ camel_cipher_verify_sync (CamelCipherContext *context,
}
/**
- * camel_cipher_encrypt_sync:
- * @context: Cipher Context
- * @userid: key id (or email address) to use when signing, or NULL to not sign.
- * @recipients: an array of recipient key ids and/or email addresses
- * @ipart: cleartext input stream
- * @opart: ciphertext output stream
+ * camel_cipher_context_verify:
+ * @context: a #CamelCipherContext
+ * @ipart: the #CamelMimePart to verify
+ * @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 verifies the signature.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_cipher_context_verify_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_cipher_context_verify (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelCipherContextClass *class;
+
+ g_return_if_fail (CAMEL_IS_CIPHER_CONTEXT (context));
+ g_return_if_fail (CAMEL_IS_MIME_PART (ipart));
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_if_fail (class->verify != NULL);
+
+ class->verify (
+ context, ipart, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_cipher_context_verify_finish:
+ * @context: a #CamelCipherContext
+ * @result: a #GAsyncResult
* @error: return location for a #GError, or %NULL
*
- * Encrypts (and optionally signs) the cleartext input stream and
- * writes the resulting ciphertext to the output stream.
+ * Finishes the operation started with camel_cipher_context_verify().
*
- * Returns: 0 for success or -1 for failure.
+ * Returns: a #CamelCipherValidity structure containing information
+ * about the integrity of the input stream, or %NULL on failure to
+ * execute at all
+ *
+ * Since: 2.34
**/
-gint
-camel_cipher_encrypt_sync (CamelCipherContext *context,
- const gchar *userid,
- GPtrArray *recipients,
- CamelMimePart *ipart,
- CamelMimePart *opart,
- GCancellable *cancellable,
- GError **error)
+CamelCipherValidity *
+camel_cipher_context_verify_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelCipherContextClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (context), NULL);
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_val_if_fail (class->verify_finish != NULL, NULL);
+
+ return class->verify_finish (context, result, error);
+}
+
+/**
+ * camel_cipher_context_encrypt_sync:
+ * @context: a #CamelCipherContext
+ * @userid: key ID (or email address) to use when signing, or %NULL to not sign
+ * @recipients: an array of recipient key IDs and/or email addresses
+ * @ipart: clear-text #CamelMimePart
+ * @opart: cipher-text #CamelMimePart
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Encrypts (and optionally signs) the clear-text @ipart and writes the
+ * resulting cipher-text to @opart.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_cipher_context_encrypt_sync (CamelCipherContext *context,
+ const gchar *userid,
+ GPtrArray *recipients,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ GCancellable *cancellable,
+ GError **error)
{
CamelCipherContextClass *class;
- gint retval;
+ gboolean success;
- g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1);
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), FALSE);
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (ipart), FALSE);
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (opart), FALSE);
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
- g_return_val_if_fail (class->encrypt_sync != NULL, -1);
+ g_return_val_if_fail (class->encrypt_sync != NULL, FALSE);
CIPHER_LOCK (context);
- retval = class->encrypt_sync (
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ CIPHER_UNLOCK (context);
+ return FALSE;
+ }
+
+ camel_operation_push_message (cancellable, _("Encrypting message"));
+
+ success = class->encrypt_sync (
context, userid, recipients,
ipart, opart, cancellable, error);
- CAMEL_CHECK_GERROR (context, encrypt_sync, retval == 0, error);
+ CAMEL_CHECK_GERROR (context, encrypt_sync, success, error);
+
+ camel_operation_pop_message (cancellable);
CIPHER_UNLOCK (context);
- return retval;
+ return success;
}
/**
- * camel_cipher_decrypt_sync:
- * @context:
- * @ipart:
- * @opart:
+ * camel_cipher_context_encrypt:
+ * @context: a #CamelCipherContext
+ * @userid: key id (or email address) to use when signing, or %NULL to not sign
+ * @recipients: an array of recipient key IDs and/or email addresses
+ * @ipart: clear-text #CamelMimePart
+ * @opart: cipher-text #CamelMimePart
+ * @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 encrypts (and optionally signs) the clear-text @ipart and
+ * writes the resulting cipher-text to @opart.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_cipher_context_encrypt_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_cipher_context_encrypt (CamelCipherContext *context,
+ const gchar *userid,
+ GPtrArray *recipients,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelCipherContextClass *class;
+
+ g_return_if_fail (CAMEL_IS_CIPHER_CONTEXT (context));
+ g_return_if_fail (CAMEL_IS_MIME_PART (ipart));
+ g_return_if_fail (CAMEL_IS_MIME_PART (opart));
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_if_fail (class->encrypt != NULL);
+
+ class->encrypt (
+ context, userid, recipients, ipart, opart,
+ io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * camel_cipher_context_encrypt_finish:
+ * @context: a #CamelCipherContext
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_cipher_context_encrypt().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_cipher_context_encrypt_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelCipherContextClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_val_if_fail (class->encrypt_finish != NULL, FALSE);
+
+ return class->encrypt_finish (context, result, error);
+}
+
+/**
+ * camel_cipher_context_decrypt_sync:
+ * @context: a #CamelCipherContext
+ * @ipart: cipher-text #CamelMimePart
+ * @opart: clear-text #CamelMimePart
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
* Decrypts @ipart into @opart.
*
- * Returns: A validity/encryption status.
+ * Returns: a validity/encryption status, or %NULL on error
+ *
+ * Since: 2.34
**/
CamelCipherValidity *
-camel_cipher_decrypt_sync (CamelCipherContext *context,
- CamelMimePart *ipart,
- CamelMimePart *opart,
- GCancellable *cancellable,
- GError **error)
+camel_cipher_context_decrypt_sync (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ GCancellable *cancellable,
+ GError **error)
{
CamelCipherContextClass *class;
CamelCipherValidity *valid;
g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL);
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (ipart), NULL);
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (opart), NULL);
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
g_return_val_if_fail (class->decrypt_sync != NULL, NULL);
CIPHER_LOCK (context);
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ CIPHER_UNLOCK (context);
+ return NULL;
+ }
+
+ camel_operation_push_message (cancellable, _("Decrypting message"));
+
valid = class->decrypt_sync (
context, ipart, opart, cancellable, error);
CAMEL_CHECK_GERROR (context, decrypt_sync, valid != NULL, error);
+ camel_operation_pop_message (cancellable);
+
CIPHER_UNLOCK (context);
return valid;
}
/**
- * camel_cipher_import_keys_sync:
- * @context: Cipher Context
- * @istream: input stream (containing keys)
+ * camel_cipher_context_decrypt:
+ * @context: a #CamelCipherContext
+ * @ipart: cipher-text #CamelMimePart
+ * @opart: clear-text #CamelMimePart
+ * @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 decrypts @ipart into @opart.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_cipher_context_decrypt_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_cipher_context_decrypt (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelCipherContextClass *class;
+
+ g_return_if_fail (CAMEL_IS_CIPHER_CONTEXT (context));
+ g_return_if_fail (CAMEL_IS_MIME_PART (ipart));
+ g_return_if_fail (CAMEL_IS_MIME_PART (opart));
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_if_fail (class->decrypt != NULL);
+
+ class->decrypt (
+ context, ipart, opart, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_cipher_context_decrypt_finish:
+ * @context: a #CamelCipherContext
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_cipher_context_decrypt().
+ *
+ * Returns: a validity/encryption status, or %NULL on error
+ *
+ * Since: 2.34
+ **/
+CamelCipherValidity *
+camel_cipher_context_decrypt_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelCipherContextClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_val_if_fail (class->decrypt_finish != NULL, NULL);
+
+ return class->decrypt_finish (context, result, error);
+}
+
+/**
+ * camel_cipher_context_import_keys_sync:
+ * @context: a #CamelCipherContext
+ * @istream: an input stream containing keys
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
* Imports a stream of keys/certificates contained within @istream
- * into the key/certificate database controlled by @ctx.
+ * into the key/certificate database controlled by @context.
*
- * Returns: 0 on success or -1 on fail.
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
-gint
-camel_cipher_import_keys_sync (CamelCipherContext *context,
- CamelStream *istream,
- GCancellable *cancellable,
- GError **error)
+gboolean
+camel_cipher_context_import_keys_sync (CamelCipherContext *context,
+ CamelStream *istream,
+ GCancellable *cancellable,
+ GError **error)
{
CamelCipherContextClass *class;
- gint retval;
+ gboolean success;
- g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1);
- g_return_val_if_fail (CAMEL_IS_STREAM (istream), -1);
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), FALSE);
+ g_return_val_if_fail (CAMEL_IS_STREAM (istream), FALSE);
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
- g_return_val_if_fail (class->import_keys_sync != NULL, -1);
+ g_return_val_if_fail (class->import_keys_sync != NULL, FALSE);
- retval = class->import_keys_sync (
+ success = class->import_keys_sync (
context, istream, cancellable, error);
- CAMEL_CHECK_GERROR (context, import_keys_sync, retval == 0, error);
+ CAMEL_CHECK_GERROR (context, import_keys_sync, success, error);
+
+ return success;
+}
+
+/**
+ * camel_cipher_context_import_keys:
+ * @context: a #CamelCipherContext
+ * @istream: an input stream containing keys
+ * @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 imports a stream of keys/certificates contained within
+ * @istream into the key/certificate database controlled by @context.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_cipher_context_import_keys_finish() to get the result
+ * of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_cipher_context_import_keys (CamelCipherContext *context,
+ CamelStream *istream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelCipherContextClass *class;
+
+ g_return_if_fail (CAMEL_IS_CIPHER_CONTEXT (context));
+ g_return_if_fail (CAMEL_IS_STREAM (istream));
- return retval;
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_if_fail (class->import_keys != NULL);
+
+ class->import_keys (
+ context, istream, io_priority,
+ cancellable, callback, user_data);
}
/**
- * camel_cipher_export_keys_sync:
- * @context: Cipher Context
- * @keys: an array of key ids
- * @ostream: output stream
+ * camel_cipher_context_import_keys_finish:
+ * @context: a #CamelCipherContext
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_cipher_context_import_keys().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_cipher_context_import_keys_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelCipherContextClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_val_if_fail (class->import_keys_finish != NULL, FALSE);
+
+ return class->import_keys_finish (context, result, error);
+}
+
+/**
+ * camel_cipher_context_export_keys_sync:
+ * @context: a #CamelCipherContext
+ * @keys: an array of key IDs
+ * @ostream: an output stream
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
* Exports the keys/certificates in @keys to the stream @ostream from
- * the key/certificate database controlled by @ctx.
+ * the key/certificate database controlled by @context.
*
- * Returns: 0 on success or -1 on fail.
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
-gint
-camel_cipher_export_keys_sync (CamelCipherContext *context,
- GPtrArray *keys,
- CamelStream *ostream,
- GCancellable *cancellable,
- GError **error)
+gboolean
+camel_cipher_context_export_keys_sync (CamelCipherContext *context,
+ GPtrArray *keys,
+ CamelStream *ostream,
+ GCancellable *cancellable,
+ GError **error)
{
CamelCipherContextClass *class;
- gint retval;
+ gboolean success;
- g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1);
- g_return_val_if_fail (CAMEL_IS_STREAM (ostream), -1);
- g_return_val_if_fail (keys != NULL, -1);
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), FALSE);
+ g_return_val_if_fail (keys != NULL, FALSE);
+ g_return_val_if_fail (CAMEL_IS_STREAM (ostream), FALSE);
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
- g_return_val_if_fail (class->export_keys_sync != NULL, -1);
+ g_return_val_if_fail (class->export_keys_sync != NULL, FALSE);
- retval = class->export_keys_sync (
+ success = class->export_keys_sync (
context, keys, ostream, cancellable, error);
- CAMEL_CHECK_GERROR (context, export_keys_sync, retval == 0, error);
+ CAMEL_CHECK_GERROR (context, export_keys_sync, success, error);
+
+ return success;
+}
+
+/**
+ * camel_cipher_context_export_keys:
+ * @context: a #CamelCipherContext
+ * @keys: an array of key IDs
+ * @ostream: an output stream
+ * @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 exports the keys/certificates in @keys to the stream
+ * @ostream from the key/certificate database controlled by @context.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_cipher_context_export_keys_finish() to get the result of the
+ * operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_cipher_context_export_keys (CamelCipherContext *context,
+ GPtrArray *keys,
+ CamelStream *ostream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelCipherContextClass *class;
+
+ g_return_if_fail (CAMEL_IS_CIPHER_CONTEXT (context));
+ g_return_if_fail (keys != NULL);
+ g_return_if_fail (CAMEL_IS_STREAM (ostream));
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_if_fail (class->export_keys != NULL);
+
+ class->export_keys (
+ context, keys, ostream, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_cipher_context_export_keys_finish:
+ * @context: a #CamelCipherContext
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_cipher_context_export_keys().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_cipher_context_export_keys_finish (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelCipherContextClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
+ g_return_val_if_fail (class->export_keys_finish != NULL, FALSE);
- return retval;
+ return class->export_keys_finish (context, result, error);
}
/* a couple of util functions */
CamelCipherHash
-camel_cipher_id_to_hash (CamelCipherContext *context,
- const gchar *id)
+camel_cipher_context_id_to_hash (CamelCipherContext *context,
+ const gchar *id)
{
CamelCipherContextClass *class;
@@ -532,8 +1493,8 @@ camel_cipher_id_to_hash (CamelCipherContext *context,
}
const gchar *
-camel_cipher_hash_to_id (CamelCipherContext *context,
- CamelCipherHash hash)
+camel_cipher_context_hash_to_id (CamelCipherContext *context,
+ CamelCipherHash hash)
{
CamelCipherContextClass *class;
diff --git a/camel/camel-cipher-context.h b/camel/camel-cipher-context.h
index e3d231ae6..71da9d6f9 100644
--- a/camel/camel-cipher-context.h
+++ b/camel/camel-cipher-context.h
@@ -134,12 +134,14 @@ struct _CamelCipherContextClass {
const gchar *encrypt_protocol;
const gchar *key_protocol;
+ /* Non-Blocking Methods */
CamelCipherHash (*id_to_hash) (CamelCipherContext *context,
const gchar *id);
const gchar * (*hash_to_id) (CamelCipherContext *context,
CamelCipherHash hash);
- gint (*sign_sync) (CamelCipherContext *context,
+ /* Synchronous I/O Methods */
+ gboolean (*sign_sync) (CamelCipherContext *context,
const gchar *userid,
CamelCipherHash hash,
CamelMimePart *ipart,
@@ -151,7 +153,7 @@ struct _CamelCipherContextClass {
CamelMimePart *ipart,
GCancellable *cancellable,
GError **error);
- gint (*encrypt_sync) (CamelCipherContext *context,
+ gboolean (*encrypt_sync) (CamelCipherContext *context,
const gchar *userid,
GPtrArray *recipients,
CamelMimePart *ipart,
@@ -164,26 +166,93 @@ struct _CamelCipherContextClass {
CamelMimePart *opart,
GCancellable *cancellable,
GError **error);
- gint (*import_keys_sync) (CamelCipherContext *context,
+ gboolean (*import_keys_sync) (CamelCipherContext *context,
CamelStream *istream,
GCancellable *cancellable,
GError **error);
- gint (*export_keys_sync) (CamelCipherContext *context,
+ gboolean (*export_keys_sync) (CamelCipherContext *context,
GPtrArray *keys,
CamelStream *ostream,
GCancellable *cancellable,
GError **error);
+
+ /* Asynchronous I/O Methods (all have defaults) */
+ void (*sign) (CamelCipherContext *context,
+ const gchar *userid,
+ CamelCipherHash hash,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*sign_finish) (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
+ void (*verify) (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ CamelCipherValidity *
+ (*verify_finish) (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
+ void (*encrypt) (CamelCipherContext *context,
+ const gchar *user_id,
+ GPtrArray *recipients,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*encrypt_finish) (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
+ void (*decrypt) (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ CamelCipherValidity *
+ (*decrypt_finish) (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
+ void (*import_keys) (CamelCipherContext *context,
+ CamelStream *istream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*import_keys_finish) (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
+ void (*export_keys) (CamelCipherContext *context,
+ GPtrArray *keys,
+ CamelStream *ostream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*export_keys_finish) (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
};
GType camel_cipher_context_get_type (void);
CamelCipherContext *
camel_cipher_context_new (CamelSession *session);
-CamelSession * camel_cipher_context_get_session (CamelCipherContext *context);
+CamelSession * camel_cipher_context_get_session
+ (CamelCipherContext *context);
/* cipher context util routines */
-CamelCipherHash camel_cipher_id_to_hash (CamelCipherContext *context,
+CamelCipherHash camel_cipher_context_id_to_hash (CamelCipherContext *context,
const gchar *id);
-const gchar * camel_cipher_hash_to_id (CamelCipherContext *context,
+const gchar * camel_cipher_context_hash_to_id (CamelCipherContext *context,
CamelCipherHash hash);
/* FIXME:
@@ -192,41 +261,118 @@ const gchar * camel_cipher_hash_to_id (CamelCipherContext *context,
to the cipher, etc etc. */
/* cipher routines */
-gint camel_cipher_sign_sync (CamelCipherContext *context,
+gboolean camel_cipher_context_sign_sync (CamelCipherContext *context,
const gchar *userid,
CamelCipherHash hash,
CamelMimePart *ipart,
CamelMimePart *opart,
GCancellable *cancellable,
GError **error);
+void camel_cipher_context_sign (CamelCipherContext *context,
+ const gchar *userid,
+ CamelCipherHash hash,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_cipher_context_sign_finish
+ (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
+CamelCipherValidity *
+ camel_cipher_context_verify_sync
+ (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ GCancellable *cancellable,
+ GError **error);
+void camel_cipher_context_verify (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
CamelCipherValidity *
- camel_cipher_verify_sync (CamelCipherContext *context,
+ camel_cipher_context_verify_finish
+ (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
+gboolean camel_cipher_context_encrypt_sync
+ (CamelCipherContext *context,
+ const gchar *userid,
+ GPtrArray *recipients,
CamelMimePart *ipart,
+ CamelMimePart *opart,
GCancellable *cancellable,
GError **error);
-gint camel_cipher_encrypt_sync (CamelCipherContext *context,
+void camel_cipher_context_encrypt (CamelCipherContext *context,
const gchar *userid,
GPtrArray *recipients,
CamelMimePart *ipart,
CamelMimePart *opart,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_cipher_context_encrypt_finish
+ (CamelCipherContext *context,
+ GAsyncResult *result,
GError **error);
CamelCipherValidity *
- camel_cipher_decrypt_sync (CamelCipherContext *context,
+ camel_cipher_context_decrypt_sync
+ (CamelCipherContext *context,
CamelMimePart *ipart,
CamelMimePart *opart,
GCancellable *cancellable,
GError **error);
+void camel_cipher_context_decrypt (CamelCipherContext *context,
+ CamelMimePart *ipart,
+ CamelMimePart *opart,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+CamelCipherValidity *
+ camel_cipher_context_decrypt_finish
+ (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
/* key/certificate routines */
-gint camel_cipher_import_keys_sync (CamelCipherContext *context,
+gboolean camel_cipher_context_import_keys_sync
+ (CamelCipherContext *context,
CamelStream *istream,
GCancellable *cancellable,
GError **error);
-gint camel_cipher_export_keys_sync (CamelCipherContext *context,
+void camel_cipher_context_import_keys
+ (CamelCipherContext *context,
+ CamelStream *istream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_cipher_context_import_keys_finish
+ (CamelCipherContext *context,
+ GAsyncResult *result,
+ GError **error);
+gboolean camel_cipher_context_export_keys_sync
+ (CamelCipherContext *context,
+ GPtrArray *keys,
+ CamelStream *ostream,
+ GCancellable *cancellable,
+ GError **error);
+void camel_cipher_context_export_keys
+ (CamelCipherContext *context,
GPtrArray *keys,
CamelStream *ostream,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_cipher_context_export_keys_finish
+ (CamelCipherContext *context,
+ GAsyncResult *result,
GError **error);
/* CamelCipherValidity utility functions */
diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c
index 4969f7825..a9f9a0b69 100644
--- a/camel/camel-data-wrapper.c
+++ b/camel/camel-data-wrapper.c
@@ -40,10 +40,29 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), CAMEL_TYPE_DATA_WRAPPER, CamelDataWrapperPrivate))
+typedef struct _AsyncContext AsyncContext;
+
struct _CamelDataWrapperPrivate {
GStaticMutex stream_lock;
};
+struct _AsyncContext {
+ /* arguments */
+ CamelStream *stream;
+
+ /* results */
+ gssize bytes_written;
+};
+
+static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->stream != NULL)
+ g_object_unref (async_context->stream);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
G_DEFINE_TYPE (CamelDataWrapper, camel_data_wrapper, CAMEL_TYPE_OBJECT)
static void
@@ -130,8 +149,17 @@ data_wrapper_write_to_stream_sync (CamelDataWrapper *data_wrapper,
}
camel_data_wrapper_lock (data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_data_wrapper_unlock (
+ data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);
+ return -1;
+ }
+
if (camel_stream_reset (data_wrapper->stream, error) == -1) {
- camel_data_wrapper_unlock (data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);
+ camel_data_wrapper_unlock (
+ data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);
return -1;
}
@@ -191,7 +219,7 @@ data_wrapper_decode_to_stream_sync (CamelDataWrapper *data_wrapper,
return ret;
}
-static gint
+static gboolean
data_wrapper_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
CamelStream *stream,
GCancellable *cancellable,
@@ -202,7 +230,217 @@ data_wrapper_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
data_wrapper->stream = g_object_ref (stream);
- return 0;
+ return TRUE;
+}
+
+static void
+data_wrapper_write_to_stream_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->bytes_written =
+ camel_data_wrapper_write_to_stream_sync (
+ CAMEL_DATA_WRAPPER (object),
+ async_context->stream,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->stream = g_object_ref (stream);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (data_wrapper), callback,
+ user_data, data_wrapper_write_to_stream);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, data_wrapper_write_to_stream_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gssize
+data_wrapper_write_to_stream_finish (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (data_wrapper),
+ data_wrapper_write_to_stream), -1);
+
+ 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 -1;
+
+ return async_context->bytes_written;
+}
+
+static void
+data_wrapper_decode_to_stream_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->bytes_written =
+ camel_data_wrapper_decode_to_stream_sync (
+ CAMEL_DATA_WRAPPER (object),
+ async_context->stream,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->stream = g_object_ref (stream);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (data_wrapper), callback,
+ user_data, data_wrapper_decode_to_stream);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, data_wrapper_decode_to_stream_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gssize
+data_wrapper_decode_to_stream_finish (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (data_wrapper),
+ data_wrapper_decode_to_stream), -1);
+
+ 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 -1;
+
+ return async_context->bytes_written;
+}
+
+static void
+data_wrapper_construct_from_stream_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_data_wrapper_construct_from_stream_sync (
+ CAMEL_DATA_WRAPPER (object), async_context->stream,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->stream = g_object_ref (stream);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (data_wrapper), callback, user_data,
+ data_wrapper_construct_from_stream);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, data_wrapper_construct_from_stream_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+data_wrapper_construct_from_stream_finish (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (data_wrapper),
+ data_wrapper_construct_from_stream), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
static void
@@ -221,9 +459,17 @@ camel_data_wrapper_class_init (CamelDataWrapperClass *class)
class->get_mime_type_field = data_wrapper_get_mime_type_field;
class->set_mime_type_field = data_wrapper_set_mime_type_field;
class->is_offline = data_wrapper_is_offline;
+
class->write_to_stream_sync = data_wrapper_write_to_stream_sync;
class->decode_to_stream_sync = data_wrapper_decode_to_stream_sync;
class->construct_from_stream_sync = data_wrapper_construct_from_stream_sync;
+
+ class->write_to_stream = data_wrapper_write_to_stream;
+ class->write_to_stream_finish = data_wrapper_write_to_stream_finish;
+ class->decode_to_stream = data_wrapper_decode_to_stream;
+ class->decode_to_stream_finish = data_wrapper_decode_to_stream_finish;
+ class->construct_from_stream = data_wrapper_construct_from_stream;
+ class->construct_from_stream_finish = data_wrapper_construct_from_stream_finish;
}
static void
@@ -254,7 +500,7 @@ camel_data_wrapper_new (void)
/**
* camel_data_wrapper_set_mime_type:
- * @data_wrapper: a #CamelDataWrapper object
+ * @data_wrapper: a #CamelDataWrapper
* @mime_type: a MIME type
*
* This sets the data wrapper's MIME type.
@@ -282,7 +528,7 @@ camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
/**
* camel_data_wrapper_get_mime_type:
- * @data_wrapper: a #CamelDataWrapper object
+ * @data_wrapper: a #CamelDataWrapper
*
* Returns: the MIME type which must be freed by the caller
**/
@@ -301,7 +547,7 @@ camel_data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper)
/**
* camel_data_wrapper_get_mime_type_field:
- * @data_wrapper: a #CamelDataWrapper object
+ * @data_wrapper: a #CamelDataWrapper
*
* Returns: the parsed form of the data wrapper's MIME type
**/
@@ -320,7 +566,7 @@ camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper)
/**
* camel_data_wrapper_set_mime_type_field:
- * @data_wrapper: a #CamelDataWrapper object
+ * @data_wrapper: a #CamelDataWrapper
* @mime_type: a #CamelContentType
*
* This sets the data wrapper's MIME type. It suffers from the same
@@ -343,7 +589,7 @@ camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
/**
* camel_data_wrapper_is_offline:
- * @data_wrapper: a #CamelDataWrapper object
+ * @data_wrapper: a #CamelDataWrapper
*
* Returns: whether @data_wrapper is "offline" (data stored
* remotely) or not. Some optional code paths may choose to not
@@ -363,18 +609,77 @@ camel_data_wrapper_is_offline (CamelDataWrapper *data_wrapper)
}
/**
+ * camel_data_wrapper_lock:
+ * @data_wrapper: a #CamelDataWrapper
+ * @lock: lock type to lock
+ *
+ * Locks #data_wrapper's #lock. Unlock it with camel_data_wrapper_unlock().
+ *
+ * Since: 2.32
+ **/
+void
+camel_data_wrapper_lock (CamelDataWrapper *data_wrapper,
+ CamelDataWrapperLock lock)
+{
+ g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+
+ switch (lock) {
+ case CAMEL_DATA_WRAPPER_STREAM_LOCK:
+ g_static_mutex_lock (&data_wrapper->priv->stream_lock);
+ break;
+ default:
+ g_return_if_reached ();
+ }
+}
+
+/**
+ * camel_data_wrapper_unlock:
+ * @data_wrapper: a #CamelDataWrapper
+ * @lock: lock type to unlock
+ *
+ * Unlocks #data_wrapper's #lock, previously locked with
+ * camel_data_wrapper_lock().
+ *
+ * Since: 2.32
+ **/
+void
+camel_data_wrapper_unlock (CamelDataWrapper *data_wrapper,
+ CamelDataWrapperLock lock)
+{
+ g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+
+ switch (lock) {
+ case CAMEL_DATA_WRAPPER_STREAM_LOCK:
+ g_static_mutex_unlock (&data_wrapper->priv->stream_lock);
+ break;
+ default:
+ g_return_if_reached ();
+ }
+}
+
+/**
* camel_data_wrapper_write_to_stream_sync:
- * @data_wrapper: a #CamelDataWrapper object
+ * @data_wrapper: a #CamelDataWrapper
* @stream: a #CamelStream for output
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
* Writes the content of @data_wrapper to @stream in a machine-independent
- * format appropriate for the data. It should be possible to construct an
+ * format appropriate for the data. It should be possible to construct an
* equivalent data wrapper object later by passing this stream to
- * #camel_data_wrapper_construct_from_stream.
+ * camel_data_wrapper_construct_from_stream_sync().
+ *
+ * <note>
+ * <para>
+ * This function may block even if the given output stream does not.
+ * For example, the content may have to be fetched across a network
+ * before it can be written to @stream.
+ * </para>
+ * </note>
*
- * Returns: the number of bytes written, or %-1 on fail
+ * Returns: the number of bytes written, or %-1 on error
+ *
+ * Since: 2.34
**/
gssize
camel_data_wrapper_write_to_stream_sync (CamelDataWrapper *data_wrapper,
@@ -400,15 +705,94 @@ camel_data_wrapper_write_to_stream_sync (CamelDataWrapper *data_wrapper,
}
/**
+ * camel_data_wrapper_write_to_stream:
+ * @data_wrapper: a #CamelDataWrapper
+ * @stream: a #CamelStream for writed data to be written to
+ * @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 writes the content of @data_wrapper to @stream in a
+ * machine-independent format appropriate for the data. It should be
+ * possible to construct an equivalent data wrapper object later by
+ * passing this stream to camel_data_wrapper_construct_from_stream().
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_data_wrapper_write_to_stream_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelDataWrapperClass *class;
+
+ g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+ g_return_if_fail (CAMEL_IS_STREAM (stream));
+
+ class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
+ g_return_if_fail (class->write_to_stream != NULL);
+
+ class->write_to_stream (
+ data_wrapper, stream, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_data_wrapper_write_to_stream_finish:
+ * @data_wrapper: a #CamelDataWrapper
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_data_wrapper_write_to_stream().
+ *
+ * Returns: the number of bytes written, or %-1 or error
+ *
+ * Since: 2.34
+ **/
+gssize
+camel_data_wrapper_write_to_stream_finish (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelDataWrapperClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), -1);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
+
+ class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
+ g_return_val_if_fail (class->write_to_stream_finish != NULL, -1);
+
+ return class->write_to_stream_finish (data_wrapper, result, error);
+}
+
+/**
* camel_data_wrapper_decode_to_stream_sync:
- * @data_wrapper: a #CamelDataWrapper object
+ * @data_wrapper: a #CamelDataWrapper
* @stream: a #CamelStream for decoded data to be written to
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
* Writes the decoded data content to @stream.
*
- * Returns: the number of bytes written, or %-1 on fail
+ * <note>
+ * <para>
+ * This function may block even if the given output stream does not.
+ * For example, the content may have to be fetched across a network
+ * before it can be written to @stream.
+ * </para>
+ * </note>
+ *
+ * Returns: the number of bytes written, or %-1 on error
+ *
+ * Since: 2.34
**/
gssize
camel_data_wrapper_decode_to_stream_sync (CamelDataWrapper *data_wrapper,
@@ -434,24 +818,92 @@ camel_data_wrapper_decode_to_stream_sync (CamelDataWrapper *data_wrapper,
}
/**
+ * camel_data_wrapper_decode_to_stream:
+ * @data_wrapper: a #CamelDataWrapper
+ * @stream: a #CamelStream for decoded data to be written to
+ * @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 writes the decoded data content to @stream.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_data_wrapper_decode_to_stream_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelDataWrapperClass *class;
+
+ g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+ g_return_if_fail (CAMEL_IS_STREAM (stream));
+
+ class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
+ g_return_if_fail (class->decode_to_stream != NULL);
+
+ class->decode_to_stream (
+ data_wrapper, stream, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_data_wrapper_decode_to_stream_finish:
+ * @data_wrapper: a #CamelDataWrapper
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_data_wrapper_decode_to_stream().
+ *
+ * Returns: the number of bytes written, or %-1 on error
+ *
+ * Since: 2.34
+ **/
+gssize
+camel_data_wrapper_decode_to_stream_finish (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelDataWrapperClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), -1);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
+
+ class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
+ g_return_val_if_fail (class->decode_to_stream_finish != NULL, -1);
+
+ return class->decode_to_stream_finish (data_wrapper, result, error);
+}
+
+/**
* camel_data_wrapper_construct_from_stream_sync:
- * @data_wrapper: a #CamelDataWrapper object
+ * @data_wrapper: a #CamelDataWrapper
* @stream: an input #CamelStream
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
- * Constructs the content of @data_wrapper from the supplied @stream.
+ * Constructs the content of @data_wrapper from the given @stream.
+ *
+ * Returns: %TRUE on success, %FALSE on error
*
- * Returns: %0 on success or %-1 on fail
+ * Since: 2.34
**/
-gint
+gboolean
camel_data_wrapper_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
CamelStream *stream,
GCancellable *cancellable,
GError **error)
{
CamelDataWrapperClass *class;
- gint retval;
+ gboolean success;
g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), -1);
g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
@@ -459,59 +911,78 @@ camel_data_wrapper_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
g_return_val_if_fail (class->construct_from_stream_sync != NULL, -1);
- retval = class->construct_from_stream_sync (
+ success = class->construct_from_stream_sync (
data_wrapper, stream, cancellable, error);
CAMEL_CHECK_GERROR (
- data_wrapper, construct_from_stream_sync, retval == 0, error);
+ data_wrapper, construct_from_stream_sync, success, error);
- return retval;
+ return success;
}
/**
- * camel_data_wrapper_lock:
+ * camel_data_wrapper_construct_from_stream:
* @data_wrapper: a #CamelDataWrapper
- * @lock: lock type to lock
+ * @stream: an input #CamelStream
+ * @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
*
- * Locks #data_wrapper's #lock. Unlock it with camel_data_wrapper_unlock().
+ * Asynchronously constructs the content of @data_wrapper from the given
+ * @stream.
*
- * Since: 2.32
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_data_wrapper_construct_from_stream_finish() to get the result
+ * of the operation.
+ *
+ * Since: 2.34
**/
void
-camel_data_wrapper_lock (CamelDataWrapper *data_wrapper,
- CamelDataWrapperLock lock)
+camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
+ CamelDataWrapperClass *class;
+
g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+ g_return_if_fail (CAMEL_IS_STREAM (stream));
- switch (lock) {
- case CAMEL_DATA_WRAPPER_STREAM_LOCK:
- g_static_mutex_lock (&data_wrapper->priv->stream_lock);
- break;
- default:
- g_return_if_reached ();
- }
+ class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
+ g_return_if_fail (class->construct_from_stream != NULL);
+
+ class->construct_from_stream (
+ data_wrapper, stream, io_priority,
+ cancellable, callback, user_data);
}
/**
- * camel_data_wrapper_unlock:
+ * camel_data_wrapper_construct_from_stream_finish:
* @data_wrapper: a #CamelDataWrapper
- * @lock: lock type to unlock
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
*
- * Unlocks #data_wrapper's #lock, previously locked with
- * camel_data_wrapper_lock().
+ * Finishes the operation started with
+ * camel_data_wrapper_construct_from_stream().
*
- * Since: 2.32
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
-void
-camel_data_wrapper_unlock (CamelDataWrapper *data_wrapper,
- CamelDataWrapperLock lock)
+gboolean
+camel_data_wrapper_construct_from_stream_finish (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error)
{
- g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+ CamelDataWrapperClass *class;
- switch (lock) {
- case CAMEL_DATA_WRAPPER_STREAM_LOCK:
- g_static_mutex_unlock (&data_wrapper->priv->stream_lock);
- break;
- default:
- g_return_if_reached ();
- }
+ g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
+ g_return_val_if_fail (class->construct_from_stream_finish != NULL, FALSE);
+
+ return class->construct_from_stream_finish (data_wrapper, result, error);
}
diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h
index adde13586..d363456a1 100644
--- a/camel/camel-data-wrapper.h
+++ b/camel/camel-data-wrapper.h
@@ -83,6 +83,7 @@ struct _CamelDataWrapper {
struct _CamelDataWrapperClass {
CamelObjectClass parent_class;
+ /* Non-Blocking Methods */
void (*set_mime_type) (CamelDataWrapper *data_wrapper,
const gchar *mime_type);
gchar * (*get_mime_type) (CamelDataWrapper *data_wrapper);
@@ -92,6 +93,7 @@ struct _CamelDataWrapperClass {
CamelContentType *mime_type_field);
gboolean (*is_offline) (CamelDataWrapper *data_wrapper);
+ /* Synchronous I/O Methods */
gssize (*write_to_stream_sync) (CamelDataWrapper *data_wrapper,
CamelStream *stream,
GCancellable *cancellable,
@@ -100,11 +102,44 @@ struct _CamelDataWrapperClass {
CamelStream *stream,
GCancellable *cancellable,
GError **error);
- gint (*construct_from_stream_sync)
+ gboolean (*construct_from_stream_sync)
(CamelDataWrapper *data_wrapper,
CamelStream *stream,
GCancellable *cancellable,
GError **error);
+
+ /* Asyncrhonous I/O Methods (all have defaults) */
+ void (*write_to_stream) (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gssize (*write_to_stream_finish)
+ (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error);
+ void (*decode_to_stream) (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gssize (*decode_to_stream_finish)
+ (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error);
+ void (*construct_from_stream)
+ (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*construct_from_stream_finish)
+ (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error);
};
GType camel_data_wrapper_get_type (void);
@@ -120,25 +155,59 @@ void camel_data_wrapper_set_mime_type_field
(CamelDataWrapper *data_wrapper,
CamelContentType *mime_type);
gboolean camel_data_wrapper_is_offline (CamelDataWrapper *data_wrapper);
+void camel_data_wrapper_lock (CamelDataWrapper *data_wrapper,
+ CamelDataWrapperLock lock);
+void camel_data_wrapper_unlock (CamelDataWrapper *data_wrapper,
+ CamelDataWrapperLock lock);
+
gssize camel_data_wrapper_write_to_stream_sync
(CamelDataWrapper *data_wrapper,
CamelStream *stream,
GCancellable *cancellable,
GError **error);
+void camel_data_wrapper_write_to_stream
+ (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gssize camel_data_wrapper_write_to_stream_finish
+ (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error);
gssize camel_data_wrapper_decode_to_stream_sync
(CamelDataWrapper *data_wrapper,
CamelStream *stream,
GCancellable *cancellable,
GError **error);
-gint camel_data_wrapper_construct_from_stream_sync
+void camel_data_wrapper_decode_to_stream
(CamelDataWrapper *data_wrapper,
CamelStream *stream,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gssize camel_data_wrapper_decode_to_stream_finish
+ (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error);
+gboolean camel_data_wrapper_construct_from_stream_sync
+ (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GCancellable *cancellable,
+ GError **error);
+void camel_data_wrapper_construct_from_stream
+ (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_data_wrapper_construct_from_stream_finish
+ (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
GError **error);
-void camel_data_wrapper_lock (CamelDataWrapper *data_wrapper,
- CamelDataWrapperLock lock);
-void camel_data_wrapper_unlock (CamelDataWrapper *data_wrapper,
- CamelDataWrapperLock lock);
G_END_DECLS
diff --git a/camel/camel-db.h b/camel/camel-db.h
index a2d7148c3..bf047ff6b 100644
--- a/camel/camel-db.h
+++ b/camel/camel-db.h
@@ -47,7 +47,7 @@ typedef struct _CamelDBPrivate CamelDBPrivate;
*
* Since: 2.24
**/
-typedef gint (*CamelDBCollate)(gpointer ,int,gconstpointer ,int,gconstpointer );
+typedef gint (*CamelDBCollate)(gpointer, gint, gconstpointer, gint, gconstpointer );
/**
* CamelDB:
diff --git a/camel/camel-disco-diary.c b/camel/camel-disco-diary.c
index 530d386e4..9c48a6a26 100644
--- a/camel/camel-disco-diary.c
+++ b/camel/camel-disco-diary.c
@@ -300,7 +300,8 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
g_return_if_fail (size != 0);
rewind (diary->file);
- camel_operation_start (cancellable, _("Resynchronizing with server"));
+ camel_operation_push_message (
+ cancellable, _("Resynchronizing with server"));
while (local_error == NULL) {
camel_operation_progress (
@@ -390,8 +391,8 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
}
camel_folder_transfer_messages_to_sync (
- source, uids, destination, &ret_uids,
- delete_originals, cancellable, &local_error);
+ source, uids, destination, delete_originals,
+ &ret_uids, cancellable, &local_error);
if (ret_uids) {
for (i = 0; i < uids->len; i++) {
@@ -410,7 +411,7 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
}
lose:
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
/* Close folders */
g_hash_table_foreach (
diff --git a/camel/camel-disco-folder.c b/camel/camel-disco-folder.c
index 6fd9009d6..65e103187 100644
--- a/camel/camel-disco-folder.c
+++ b/camel/camel-disco-folder.c
@@ -62,7 +62,7 @@ cdf_sync_offline (CamelSession *session, CamelSessionThreadMsg *mm)
struct _cdf_sync_msg *m = (struct _cdf_sync_msg *)mm;
gint i;
- camel_operation_start (
+ camel_operation_push_message (
mm->cancellable,
_("Downloading new messages for offline mode"));
@@ -81,7 +81,7 @@ cdf_sync_offline (CamelSession *session, CamelSessionThreadMsg *mm)
NULL, &mm->error);
}
- camel_operation_end (mm->cancellable);
+ camel_operation_pop_message (mm->cancellable);
}
static void
@@ -203,7 +203,7 @@ disco_expunge_uids (CamelFolder *folder,
static gboolean
disco_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -336,8 +336,8 @@ static gboolean
disco_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
@@ -385,7 +385,7 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
gint i;
gboolean success = TRUE;
- camel_operation_start (
+ camel_operation_push_message (
cancellable, _("Preparing folder '%s' for offline"),
camel_folder_get_full_name (folder));
@@ -395,7 +395,7 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
uids = camel_folder_get_uids (folder);
if (!uids) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
@@ -411,7 +411,7 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
else
camel_folder_free_uids (folder, uids);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return success;
}
diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c
index 9a4a77cca..2c876cd9a 100644
--- a/camel/camel-filter-driver.c
+++ b/camel/camel-filter-driver.c
@@ -506,8 +506,8 @@ do_copy (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilterDri
g_ptr_array_add (uids, (gchar *) p->uid);
/* FIXME Pass a GCancellable */
camel_folder_transfer_messages_to_sync (
- p->source, uids, outbox, NULL,
- FALSE, NULL, &p->error);
+ p->source, uids, outbox, FALSE,
+ NULL, NULL, &p->error);
g_ptr_array_free (uids, TRUE);
} else {
if (p->message == NULL)
@@ -567,8 +567,8 @@ do_move (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilterDri
g_ptr_array_add (uids, (gchar *) p->uid);
/* FIXME Pass a GCancellable */
camel_folder_transfer_messages_to_sync (
- p->source, uids, outbox, NULL,
- last, NULL, &p->error);
+ p->source, uids, outbox, last,
+ NULL, NULL, &p->error);
g_ptr_array_free (uids, TRUE);
} else {
if (p->message == NULL)
@@ -877,8 +877,8 @@ pipe_to_system (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFi
g_object_unref (mem);
message = camel_mime_message_new ();
- if (camel_mime_part_construct_from_parser_sync (
- (CamelMimePart *) message, parser, NULL, NULL) == -1) {
+ if (!camel_mime_part_construct_from_parser_sync (
+ (CamelMimePart *) message, parser, NULL, NULL)) {
gint err = camel_mime_parser_errno (parser);
g_set_error (
&p->error, G_IO_ERROR,
@@ -1309,8 +1309,8 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
message = camel_mime_message_new ();
mime_part = CAMEL_MIME_PART (message);
- if (camel_mime_part_construct_from_parser_sync (
- mime_part, mp, cancellable, error) == -1) {
+ if (!camel_mime_part_construct_from_parser_sync (
+ mime_part, mp, cancellable, error)) {
report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Failed on message %d"), i);
g_object_unref (message);
goto fail;
@@ -1672,7 +1672,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
g_ptr_array_add (uids, (gchar *) p->uid);
camel_folder_transfer_messages_to_sync (
p->source, uids, p->defaultfolder,
- NULL, FALSE, cancellable, &p->error);
+ FALSE, NULL, cancellable, &p->error);
g_ptr_array_free (uids, TRUE);
} else {
if (p->message == NULL) {
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index 399980e59..05c1351fb 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -1432,7 +1432,8 @@ match_words_1message (CamelDataWrapper *object, struct _camel_search_words *word
byte_array = g_byte_array_new ();
stream = camel_stream_mem_new_with_byte_array (byte_array);
- /* FIXME: The match should be part of a stream op */
+ /* FIXME The match should be part of a stream op */
+ /* FIXME Pass a GCancellable and GError here. */
camel_data_wrapper_decode_to_stream_sync (
containee, stream, NULL, NULL);
camel_stream_write (stream, "", 1, NULL, NULL);
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 489d1c00d..1382fd5b0 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -4043,6 +4043,7 @@ summary_build_content_info_message (CamelFolderSummary *s, CamelMessageInfo *msg
CAMEL_STREAM_FILTER (p->filter_stream),
p->filter_index);
+ /* FIXME Pass a GCancellable and GError here. */
camel_data_wrapper_decode_to_stream_sync (
containee, p->filter_stream, NULL, NULL);
camel_stream_flush (p->filter_stream, NULL, NULL);
@@ -4452,7 +4453,7 @@ camel_message_info_new (CamelFolderSummary *s)
*
* Reference an info.
**/
-void
+gpointer
camel_message_info_ref (gpointer o)
{
CamelMessageInfo *mi = o;
@@ -4468,6 +4469,8 @@ camel_message_info_ref (gpointer o)
mi->refcount++;
GLOBAL_INFO_UNLOCK (info);
}
+
+ return o;
}
/**
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index 5dcd835ec..c4e565fa7 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -435,7 +435,7 @@ void camel_tag_list_free (CamelTag **list);
/* Summary may be null */
/* Use anonymous pointers to avoid tons of cast crap */
gpointer camel_message_info_new (CamelFolderSummary *summary);
-void camel_message_info_ref (gpointer info);
+gpointer camel_message_info_ref (gpointer info);
CamelMessageInfo *camel_message_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *header);
void camel_message_info_free (gpointer info);
gpointer camel_message_info_clone (gconstpointer info);
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index 2863942a7..66cda685d 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -49,6 +49,8 @@
#define d(x)
#define w(x)
+typedef struct _AsyncContext AsyncContext;
+
struct _CamelFolderPrivate {
GStaticRecMutex lock;
GStaticMutex change_lock;
@@ -64,6 +66,20 @@ struct _CamelFolderPrivate {
gchar *description;
};
+struct _AsyncContext {
+ /* arguments */
+ CamelMimeMessage *message; /* also a result */
+ CamelMessageInfo *info;
+ CamelFolder *destination;
+ GPtrArray *message_uids;
+ gchar *message_uid; /* also a result */
+ gboolean delete_originals;
+ gboolean expunge;
+
+ /* results */
+ GPtrArray *transferred_uids;
+};
+
struct _CamelFolderChangeInfoPrivate {
GHashTable *uid_stored; /* what we have stored, which array they're in */
GHashTable *uid_source; /* used to create unique lists */
@@ -102,6 +118,37 @@ static guint signals[LAST_SIGNAL];
G_DEFINE_ABSTRACT_TYPE (CamelFolder, camel_folder, CAMEL_TYPE_OBJECT)
static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->message != NULL)
+ g_object_unref (async_context->message);
+
+ /* XXX This is actually an unref. Good god, no wonder we
+ * have so many crashes involving CamelMessageInfos! */
+ if (async_context->info != NULL)
+ camel_message_info_free (async_context->info);
+
+ if (async_context->destination != NULL)
+ g_object_unref (async_context->destination);
+
+ if (async_context->message_uids != NULL) {
+ g_ptr_array_foreach (
+ async_context->message_uids, (GFunc) g_free, NULL);
+ g_ptr_array_free (async_context->message_uids, TRUE);
+ }
+
+ if (async_context->transferred_uids != NULL) {
+ g_ptr_array_foreach (
+ async_context->transferred_uids, (GFunc) g_free, NULL);
+ g_ptr_array_free (async_context->transferred_uids, TRUE);
+ }
+
+ g_free (async_context->message_uid);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
filter_filter (CamelSession *session,
CamelSessionThreadMsg *tmsg)
{
@@ -121,7 +168,7 @@ filter_filter (CamelSession *session,
if (m->junk) {
/* Translators: The %s is replaced with a folder name where the operation is running. */
- camel_operation_start (
+ camel_operation_push_message (
tmsg->cancellable, ngettext (
"Learning new spam message in '%s'",
"Learning new spam messages in '%s'",
@@ -140,12 +187,12 @@ filter_filter (CamelSession *session,
g_object_unref (msg);
}
}
- camel_operation_end (tmsg->cancellable);
+ camel_operation_pop_message (tmsg->cancellable);
}
if (m->notjunk) {
/* Translators: The %s is replaced with a folder name where the operation is running. */
- camel_operation_start (
+ camel_operation_push_message (
tmsg->cancellable, ngettext (
"Learning new ham message in '%s'",
"Learning new ham messages in '%s'",
@@ -163,7 +210,7 @@ filter_filter (CamelSession *session,
g_object_unref (msg);
}
}
- camel_operation_end (tmsg->cancellable);
+ camel_operation_pop_message (tmsg->cancellable);
}
if (m->junk || m->notjunk)
@@ -171,7 +218,7 @@ filter_filter (CamelSession *session,
if (m->driver && m->recents) {
/* Translators: The %s is replaced with a folder name where the operation is running. */
- camel_operation_start (
+ camel_operation_push_message (
tmsg->cancellable, ngettext (
"Filtering new message in '%s'",
"Filtering new messages in '%s'",
@@ -218,7 +265,7 @@ filter_filter (CamelSession *session,
g_free (source_url);
- camel_operation_end (tmsg->cancellable);
+ camel_operation_pop_message (tmsg->cancellable);
}
}
@@ -755,8 +802,8 @@ static gboolean
folder_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
@@ -770,10 +817,10 @@ folder_transfer_messages_to_sync (CamelFolder *source,
}
if (delete_originals)
- camel_operation_start (
+ camel_operation_push_message (
cancellable, _("Moving messages"));
else
- camel_operation_start (
+ camel_operation_push_message (
cancellable, _("Copying messages"));
if (uids->len > 1) {
@@ -798,7 +845,7 @@ folder_transfer_messages_to_sync (CamelFolder *source,
camel_folder_thaw (source);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
if (local_error != NULL)
g_propagate_error (error, local_error);
@@ -806,6 +853,465 @@ folder_transfer_messages_to_sync (CamelFolder *source,
return TRUE;
}
+static void
+folder_append_message_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_folder_append_message_sync (
+ CAMEL_FOLDER (object), async_context->message,
+ async_context->info, &async_context->message_uid,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+folder_append_message (CamelFolder *folder,
+ CamelMimeMessage *message,
+ CamelMessageInfo *info,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->message = g_object_ref (message);
+ async_context->info = camel_message_info_ref (info);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (folder), callback,
+ user_data, folder_append_message);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, folder_append_message_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+folder_append_message_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ gchar **appended_uid,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (folder), folder_append_message), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (appended_uid != NULL) {
+ *appended_uid = async_context->message_uid;
+ async_context->message_uid = NULL;
+ }
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+folder_expunge_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ GError *error = NULL;
+
+ camel_folder_expunge_sync (
+ CAMEL_FOLDER (object), cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+folder_expunge (CamelFolder *folder,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (folder), callback, user_data, folder_expunge);
+
+ g_simple_async_result_run_in_thread (
+ simple, folder_expunge_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+folder_expunge_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (folder), folder_expunge), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+folder_get_message_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->message = camel_folder_get_message_sync (
+ CAMEL_FOLDER (object), async_context->message_uid,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+folder_get_message (CamelFolder *folder,
+ const gchar *message_uid,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->message_uid = g_strdup (message_uid);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (folder), callback, user_data, folder_get_message);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, folder_get_message_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static CamelMimeMessage *
+folder_get_message_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (folder), folder_get_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;
+
+ return g_object_ref (async_context->message);
+}
+
+static void
+folder_refresh_info_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ GError *error = NULL;
+
+ camel_folder_refresh_info_sync (
+ CAMEL_FOLDER (object), cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+folder_refresh_info (CamelFolder *folder,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (folder), callback, user_data, folder_refresh_info);
+
+ g_simple_async_result_run_in_thread (
+ simple, folder_refresh_info_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+folder_refresh_info_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (folder), folder_refresh_info), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+folder_synchronize_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_folder_synchronize_sync (
+ CAMEL_FOLDER (object), async_context->expunge,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+folder_synchronize (CamelFolder *folder,
+ gboolean expunge,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->expunge = expunge;
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (folder), callback, user_data, folder_synchronize);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, folder_synchronize_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+folder_synchronize_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (folder), folder_synchronize), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+folder_synchronize_message_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_folder_synchronize_message_sync (
+ CAMEL_FOLDER (object), async_context->message_uid,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+folder_synchronize_message (CamelFolder *folder,
+ const gchar *message_uid,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->message_uid = g_strdup (message_uid);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (folder), callback,
+ user_data, folder_synchronize_message);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, folder_synchronize_message_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+folder_synchronize_message_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (folder),
+ folder_synchronize_message), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+folder_transfer_messages_to_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_folder_transfer_messages_to_sync (
+ CAMEL_FOLDER (object), async_context->message_uids,
+ async_context->destination, async_context->delete_originals,
+ &async_context->transferred_uids, cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+folder_transfer_messages_to (CamelFolder *source,
+ GPtrArray *message_uids,
+ CamelFolder *destination,
+ gboolean delete_originals,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ guint ii;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->message_uids = g_ptr_array_new ();
+ async_context->destination = g_object_ref (destination);
+ async_context->delete_originals = delete_originals;
+
+ for (ii = 0; ii < message_uids->len; ii++)
+ g_ptr_array_add (
+ async_context->message_uids,
+ g_strdup (message_uids->pdata[ii]));
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (source), callback,
+ user_data, folder_transfer_messages_to);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, folder_transfer_messages_to_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+folder_transfer_messages_to_finish (CamelFolder *source,
+ GAsyncResult *result,
+ GPtrArray **transferred_uids,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (source),
+ folder_transfer_messages_to), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (transferred_uids != NULL) {
+ *transferred_uids = async_context->transferred_uids;
+ async_context->transferred_uids = NULL;
+ }
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
/* Signal callback that stops emission when folder is frozen. */
static void
folder_changed (CamelFolder *folder,
@@ -936,6 +1442,21 @@ camel_folder_class_init (CamelFolderClass *class)
class->transfer_messages_to_sync = folder_transfer_messages_to_sync;
class->changed = folder_changed;
+ class->append_message = folder_append_message;
+ class->append_message_finish = folder_append_message_finish;
+ class->expunge = folder_expunge;
+ class->expunge_finish = folder_expunge_finish;
+ class->get_message = folder_get_message;
+ class->get_message_finish = folder_get_message_finish;
+ class->refresh_info = folder_refresh_info;
+ class->refresh_info_finish = folder_refresh_info_finish;
+ class->synchronize = folder_synchronize;
+ class->synchronize_finish = folder_synchronize_finish;
+ class->synchronize_message = folder_synchronize_message;
+ class->synchronize_message_finish = folder_synchronize_message_finish;
+ class->transfer_messages_to = folder_transfer_messages_to;
+ class->transfer_messages_to_finish = folder_transfer_messages_to_finish;
+
/**
* CamelFolder:description
*
@@ -1112,78 +1633,6 @@ camel_folder_get_filename (CamelFolder *folder,
}
/**
- * camel_folder_synchronize_sync:
- * @folder: a #CamelFolder
- * @expunge: whether or not to expunge deleted messages
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Sync changes made to a folder to its backing store, possibly
- * expunging deleted messages as well.
- *
- * Returns: %TRUE on success, %FALSE on failure
- **/
-gboolean
-camel_folder_synchronize_sync (CamelFolder *folder,
- gboolean expunge,
- GCancellable *cancellable,
- GError **error)
-{
- CamelFolderClass *class;
- gboolean success = TRUE;
-
- g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
-
- class = CAMEL_FOLDER_GET_CLASS (folder);
- g_return_val_if_fail (class->synchronize_sync != NULL, FALSE);
-
- camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
-
- if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
- success = class->synchronize_sync (
- folder, expunge, cancellable, error);
- CAMEL_CHECK_GERROR (folder, synchronize_sync, success, error);
- }
-
- camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
-
- return success;
-}
-
-/**
- * camel_folder_refresh_info_sync:
- * @folder: a #CamelFolder
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Updates a folder's summary to be in sync with its backing store.
- *
- * Returns: %TRUE on success, %FALSE on failure
- **/
-gboolean
-camel_folder_refresh_info_sync (CamelFolder *folder,
- GCancellable *cancellable,
- GError **error)
-{
- CamelFolderClass *class;
- gboolean success;
-
- g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
-
- class = CAMEL_FOLDER_GET_CLASS (folder);
- g_return_val_if_fail (class->refresh_info_sync != NULL, FALSE);
-
- camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
-
- success = class->refresh_info_sync (folder, cancellable, error);
- CAMEL_CHECK_GERROR (folder, refresh_info_sync, success, error);
-
- camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
-
- return success;
-}
-
-/**
* camel_folder_get_name:
* @folder: a #CamelFolder
*
@@ -1316,41 +1765,6 @@ camel_folder_get_parent_store (CamelFolder *folder)
}
/**
- * camel_folder_expunge_sync:
- * @folder: a #CamelFolder
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Delete messages which have been marked as "DELETED"
- *
- * Returns: %TRUE on success, %FALSE on failure
- **/
-gboolean
-camel_folder_expunge_sync (CamelFolder *folder,
- GCancellable *cancellable,
- GError **error)
-{
- CamelFolderClass *class;
- gboolean success = TRUE;
-
- g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
-
- class = CAMEL_FOLDER_GET_CLASS (folder);
- g_return_val_if_fail (class->expunge_sync != NULL, FALSE);
-
- camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
-
- if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
- success = class->expunge_sync (folder, cancellable, error);
- CAMEL_CHECK_GERROR (folder, expunge_sync, success, error);
- }
-
- camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
-
- return success;
-}
-
-/**
* camel_folder_get_message_count:
* @folder: a #CamelFolder
*
@@ -1404,50 +1818,6 @@ camel_folder_get_deleted_message_count (CamelFolder *folder)
}
/**
- * camel_folder_append_message_sync:
- * @folder: a #CamelFolder
- * @message: a #CamelMimeMessage object
- * @info: a #CamelMessageInfo with additional flags/etc to set on
- * new message, or %NULL
- * @appended_uid: if non-%NULL, the UID of the appended message will
- * be returned here, if it is known.
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Append @message to @folder. Only the flag and tag data from @info
- * are used. If @info is %NULL, no flags or tags will be set.
- *
- * Returns: %TRUE on success, %FALSE on failure
- **/
-gboolean
-camel_folder_append_message_sync (CamelFolder *folder,
- CamelMimeMessage *message,
- const CamelMessageInfo *info,
- gchar **appended_uid,
- GCancellable *cancellable,
- GError **error)
-{
- CamelFolderClass *class;
- gboolean success;
-
- g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
- g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), FALSE);
-
- class = CAMEL_FOLDER_GET_CLASS (folder);
- g_return_val_if_fail (class->append_message_sync != NULL, FALSE);
-
- camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
-
- success = class->append_message_sync (
- folder, message, info, appended_uid, cancellable, error);
- CAMEL_CHECK_GERROR (folder, append_message_sync, success, error);
-
- camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
-
- return success;
-}
-
-/**
* camel_folder_get_permanent_flags:
* @folder: a #CamelFolder
*
@@ -1750,110 +2120,6 @@ camel_folder_has_summary_capability (CamelFolder *folder)
/* UIDs stuff */
/**
- * camel_folder_get_message_sync:
- * @folder: a #CamelFolder
- * @uid: the UID
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Get a message from its UID in the folder.
- *
- * Returns: a #CamelMimeMessage corresponding to @uid
- **/
-CamelMimeMessage *
-camel_folder_get_message_sync (CamelFolder *folder,
- const gchar *uid,
- GCancellable *cancellable,
- GError **error)
-{
- CamelFolderClass *class;
- CamelMimeMessage *ret;
-
- g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
- g_return_val_if_fail (uid != NULL, NULL);
-
- class = CAMEL_FOLDER_GET_CLASS (folder);
- g_return_val_if_fail (class->get_message_sync != NULL, NULL);
-
- camel_operation_start (
- cancellable, _("Retrieving message '%s'"), uid);
-
- camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
-
- ret = class->get_message_sync (folder, uid, cancellable, error);
- CAMEL_CHECK_GERROR (folder, get_message_sync, ret != NULL, error);
-
- camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
-
- camel_operation_end (cancellable);
-
- if (ret && camel_debug_start (":folder")) {
- printf ("CamelFolder:get_message ('%s', '%s') =\n",
- camel_folder_get_full_name (folder), uid);
- camel_mime_message_dump (ret, FALSE);
- camel_debug_end ();
- }
-
- return ret;
-}
-
-/**
- * camel_folder_synchronize_message_sync:
- * @folder: a #CamelFolder
- * @uid: the UID
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Ensure that a message identified by UID has been synced in the folder (so
- * that camel_folder_get_message on it later will work in offline mode).
- *
- * Returns: %TRUE on success, %FALSE on failure
- *
- * Since: 2.26
- **/
-gboolean
-camel_folder_synchronize_message_sync (CamelFolder *folder,
- const gchar *uid,
- GCancellable *cancellable,
- GError **error)
-{
- CamelFolderClass *class;
- gboolean success = FALSE;
-
- g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
- g_return_val_if_fail (uid != NULL, FALSE);
-
- class = CAMEL_FOLDER_GET_CLASS (folder);
- g_return_val_if_fail (class->get_message_sync != NULL, FALSE);
-
- camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
-
- /* Use the sync_message method if the class implements it. */
- if (class->synchronize_message_sync != NULL) {
- success = class->synchronize_message_sync (
- folder, uid, cancellable, error);
- CAMEL_CHECK_GERROR (
- folder, synchronize_message_sync, success, error);
- } else {
- CamelMimeMessage *message;
-
- message = class->get_message_sync (
- folder, uid, cancellable, error);
- CAMEL_CHECK_GERROR (
- folder, get_message_sync, message != NULL, error);
-
- if (message != NULL) {
- g_object_unref (message);
- success = TRUE;
- }
- }
-
- camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
-
- return success;
-}
-
-/**
* camel_folder_get_uids:
* @folder: a #CamelFolder
*
@@ -2171,62 +2437,6 @@ camel_folder_search_free (CamelFolder *folder,
}
/**
- * camel_folder_transfer_messages_to_sync:
- * @source: the source #CamelFolder object
- * @uids: message UIDs in @source
- * @dest: the destination #CamelFolder object
- * @transferred_uids: if non-%NULL, the UIDs of the resulting messages
- * in @dest will be stored here, if known.
- * @delete_originals: whether or not to delete the original messages
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * This copies or moves messages from one folder to another. If the
- * @source and @dest folders have the same parent_store, this may be
- * more efficient than using #camel_folder_append_message.
- *
- * Returns: %TRUE on success, %FALSE on failure
- **/
-gboolean
-camel_folder_transfer_messages_to_sync (CamelFolder *source,
- GPtrArray *uids,
- CamelFolder *dest,
- GPtrArray **transferred_uids,
- gboolean delete_originals,
- GCancellable *cancellable,
- GError **error)
-{
- CamelFolderClass *class;
- gboolean success;
-
- g_return_val_if_fail (CAMEL_IS_FOLDER (source), FALSE);
- g_return_val_if_fail (CAMEL_IS_FOLDER (dest), FALSE);
- g_return_val_if_fail (uids != NULL, FALSE);
-
- if (source == dest || uids->len == 0) {
- /* source and destination folders are the same, or no work to do, do nothing. */
- return TRUE;
- }
-
- if (source->priv->parent_store == dest->priv->parent_store) {
- /* If either folder is a vtrash, we need to use the
- * vtrash transfer method. */
- if (CAMEL_IS_VTRASH_FOLDER (dest))
- class = CAMEL_FOLDER_GET_CLASS (dest);
- else
- class = CAMEL_FOLDER_GET_CLASS (source);
- success = class->transfer_messages_to_sync (
- source, uids, dest, transferred_uids,
- delete_originals, cancellable, error);
- } else
- success = folder_transfer_messages_to_sync (
- source, uids, dest, transferred_uids,
- delete_originals, cancellable, error);
-
- return success;
-}
-
-/**
* camel_folder_delete:
* @folder: a #CamelFolder
*
@@ -2551,6 +2761,830 @@ camel_folder_free_deep (CamelFolder *folder,
}
/**
+ * camel_folder_lock:
+ * @folder: a #CamelFolder
+ * @lock: lock type to lock
+ *
+ * Locks #folder's #lock. Unlock it with camel_folder_unlock().
+ *
+ * Since: 2.32
+ **/
+void
+camel_folder_lock (CamelFolder *folder,
+ CamelFolderLock lock)
+{
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+ switch (lock) {
+ case CAMEL_FOLDER_CHANGE_LOCK:
+ g_static_mutex_lock (&folder->priv->change_lock);
+ break;
+ case CAMEL_FOLDER_REC_LOCK:
+ if (folder->priv->skip_folder_lock == FALSE)
+ g_static_rec_mutex_lock (&folder->priv->lock);
+ break;
+ default:
+ g_return_if_reached ();
+ }
+}
+
+/**
+ * camel_folder_unlock:
+ * @folder: a #CamelFolder
+ * @lock: lock type to unlock
+ *
+ * Unlocks #folder's #lock, previously locked with camel_folder_lock().
+ *
+ * Since: 2.32
+ **/
+void
+camel_folder_unlock (CamelFolder *folder,
+ CamelFolderLock lock)
+{
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+ switch (lock) {
+ case CAMEL_FOLDER_CHANGE_LOCK:
+ g_static_mutex_unlock (&folder->priv->change_lock);
+ break;
+ case CAMEL_FOLDER_REC_LOCK:
+ if (folder->priv->skip_folder_lock == FALSE)
+ g_static_rec_mutex_unlock (&folder->priv->lock);
+ break;
+ default:
+ g_return_if_reached ();
+ }
+}
+
+/**
+ * camel_folder_append_message_sync:
+ * @folder: a #CamelFolder
+ * @message: a #CamelMimeMessage
+ * @info: a #CamelMessageInfo with additional flags/etc to set on the
+ * new message, or %NULL
+ * @appended_uid: if non-%NULL, the UID of the appended message will
+ * be returned here, if it is known
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Appends @message to @folder. Only the flag and tag data from @info
+ * are used. If @info is %NULL, no flags or tags will be set.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_append_message_sync (CamelFolder *folder,
+ CamelMimeMessage *message,
+ CamelMessageInfo *info,
+ gchar **appended_uid,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolderClass *class;
+ gboolean success;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->append_message_sync != NULL, FALSE);
+
+ camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+ return FALSE;
+ }
+
+ success = class->append_message_sync (
+ folder, message, info, appended_uid, cancellable, error);
+ CAMEL_CHECK_GERROR (folder, append_message_sync, success, error);
+
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ return success;
+}
+
+/**
+ * camel_folder_append_message:
+ * @folder a #CamelFolder
+ * @message: a #CamelMimeMessage
+ * @info: a #CamelMessageInfo with additional flags/etc to set on the
+ * new message, or %NULL
+ * @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
+ *
+ * Appends @message to @folder asynchronously. Only the flag and tag data
+ * from @info are used. If @info is %NULL, no flags or tags will be set.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_folder_append_message_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_folder_append_message (CamelFolder *folder,
+ CamelMimeMessage *message,
+ CamelMessageInfo *info,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelFolderClass *class;
+
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+ g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_if_fail (class->append_message != NULL);
+
+ class->append_message (
+ folder, message, info, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_folder_append_message_finish:
+ * @folder: a #CamelFolder
+ * @result: a #GAsyncResult
+ * @appended_uid: if non-%NULL, the UID of the appended message will
+ * be returned here, if it is known
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_folder_append_message_finish().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_append_message_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ gchar **appended_uid,
+ GError **error)
+{
+ CamelFolderClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->append_message_finish != NULL, FALSE);
+
+ return class->append_message_finish (
+ folder, result, appended_uid, error);
+}
+
+/**
+ * camel_folder_expunge_sync:
+ * @folder: a #CamelFolder
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Deletes messages which have been marked as "DELETED".
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_expunge_sync (CamelFolder *folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolderClass *class;
+ gboolean success = TRUE;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->expunge_sync != NULL, FALSE);
+
+ camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+ return FALSE;
+ }
+
+ if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
+ success = class->expunge_sync (folder, cancellable, error);
+ CAMEL_CHECK_GERROR (folder, expunge_sync, success, error);
+ }
+
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ return success;
+}
+
+/**
+ * camel_folder_expunge:
+ * @folder: a #CamelFolder
+ * @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 deletes messages which have been marked as "DELETED".
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_folder_expunge_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_folder_expunge (CamelFolder *folder,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelFolderClass *class;
+
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_if_fail (class->expunge != NULL);
+
+ class->expunge (folder, io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * camel_folder_expunge_finish:
+ * @folder: a #CamelFolder
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_folder_expunge().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_expunge_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelFolderClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->expunge_finish != NULL, FALSE);
+
+ return class->expunge_finish (folder, result, error);
+}
+
+/**
+ * camel_folder_get_message_sync:
+ * @folder: a #CamelFolder
+ * @message_uid: the message UID
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the message corresponding to @message_uid from @folder.
+ *
+ * Returns: a #CamelMimeMessage corresponding to the requested UID
+ *
+ * Since: 2.34
+ **/
+CamelMimeMessage *
+camel_folder_get_message_sync (CamelFolder *folder,
+ const gchar *message_uid,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolderClass *class;
+ CamelMimeMessage *message;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+ g_return_val_if_fail (message_uid != NULL, NULL);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->get_message_sync != NULL, NULL);
+
+ camel_operation_push_message (
+ cancellable, _("Retrieving message '%s'"), message_uid);
+
+ camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+ return NULL;
+ }
+
+ message = class->get_message_sync (
+ folder, message_uid, cancellable, error);
+ CAMEL_CHECK_GERROR (folder, get_message_sync, message != NULL, error);
+
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ camel_operation_pop_message (cancellable);
+
+ if (message != NULL && camel_debug_start (":folder")) {
+ printf ("CamelFolder:get_message ('%s', '%s') =\n",
+ camel_folder_get_full_name (folder), message_uid);
+ camel_mime_message_dump (message, FALSE);
+ camel_debug_end ();
+ }
+
+ return message;
+}
+
+/**
+ * camel_folder_get_message:
+ * @folder: a #CamelFolder
+ * @message_uid: the message UID
+ * @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 gets the message corresponding to @message_uid from @folder.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_folder_get_message_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_folder_get_message (CamelFolder *folder,
+ const gchar *message_uid,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelFolderClass *class;
+
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+ g_return_if_fail (message_uid != NULL);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_if_fail (class->get_message != NULL);
+
+ class->get_message (
+ folder, message_uid, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_folder_get_message_finish:
+ * @folder: a #CamelFolder
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError or %NULL
+ *
+ * Finishes the operation started with camel_folder_get_message().
+ *
+ * Returns: a #CamelMimeMessage corresponding to the requested UID
+ *
+ * Since: 2.34
+ **/
+CamelMimeMessage *
+camel_folder_get_message_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelFolderClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->get_message_finish != NULL, NULL);
+
+ return class->get_message_finish (folder, result, error);
+}
+
+/**
+ * camel_folder_refresh_info_sync:
+ * @folder: a #CamelFolder
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Synchronizes a folder's summary with its backing store.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_refresh_info_sync (CamelFolder *folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolderClass *class;
+ gboolean success;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->refresh_info_sync != NULL, FALSE);
+
+ camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+ return FALSE;
+ }
+
+ success = class->refresh_info_sync (folder, cancellable, error);
+ CAMEL_CHECK_GERROR (folder, refresh_info_sync, success, error);
+
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ return success;
+}
+
+/**
+ * camel_folder_synchronize_sync:
+ * @folder: a #CamelFolder
+ * @expunge: whether to expunge after synchronizing
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Synchronizes any changes that have been made to @folder to its
+ * backing store, optionally expunging deleted messages as well.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_synchronize_sync (CamelFolder *folder,
+ gboolean expunge,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolderClass *class;
+ gboolean success = TRUE;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->synchronize_sync != NULL, FALSE);
+
+ camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+ return FALSE;
+ }
+
+ if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
+ success = class->synchronize_sync (
+ folder, expunge, cancellable, error);
+ CAMEL_CHECK_GERROR (folder, synchronize_sync, success, error);
+ }
+
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ return success;
+}
+
+/**
+ * camel_folder_synchronize:
+ * @folder: a #CamelFolder
+ * @expunge: whether to expunge after synchronizing
+ * @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
+ *
+ * Synchronizes any changes that have been made to @folder to its backing
+ * store asynchronously, optionally expunging deleted messages as well.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_folder_synchronize_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_folder_synchronize (CamelFolder *folder,
+ gboolean expunge,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelFolderClass *class;
+
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_if_fail (class->synchronize != NULL);
+
+ class->synchronize (
+ folder, expunge, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_folder_synchronize_finish:
+ * @folder: a #CamelFolder
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_folder_synchronize().
+ *
+ * Returns: %TRUE on sucess, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_synchronize_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelFolderClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->synchronize_finish != NULL, FALSE);
+
+ return class->synchronize_finish (folder, result, error);
+}
+
+/**
+ * camel_folder_synchronize_message_sync:
+ * @folder: a #CamelFolder
+ * @message_uid: a message UID
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Ensure that a message identified by @message_uid has been synchronized in
+ * @folder so that calling camel_folder_get_message() on it later will work
+ * in offline mode.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_synchronize_message_sync (CamelFolder *folder,
+ const gchar *message_uid,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolderClass *class;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ g_return_val_if_fail (message_uid != NULL, FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->get_message_sync != NULL, FALSE);
+
+ camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+ return FALSE;
+ }
+
+ /* Use the sync_message method if the class implements it. */
+ if (class->synchronize_message_sync != NULL) {
+ success = class->synchronize_message_sync (
+ folder, message_uid, cancellable, error);
+ CAMEL_CHECK_GERROR (
+ folder, synchronize_message_sync, success, error);
+ } else {
+ CamelMimeMessage *message;
+
+ message = class->get_message_sync (
+ folder, message_uid, cancellable, error);
+ CAMEL_CHECK_GERROR (
+ folder, get_message_sync, message != NULL, error);
+
+ if (message != NULL) {
+ g_object_unref (message);
+ success = TRUE;
+ }
+ }
+
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+
+ return success;
+}
+
+/**
+ * camel_folder_synchronize_message;
+ * @folder: a #CamelFolder
+ * @message_uid: a message UID
+ * @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 ensure that a message identified by @message_uid has been
+ * synchronized in @folder so that calling camel_folder_get_message() on it
+ * later will work in offline mode.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_folder_synchronize_message_finish() to get the result of the
+ * operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_folder_synchronize_message (CamelFolder *folder,
+ const gchar *message_uid,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelFolderClass *class;
+
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+ g_return_if_fail (message_uid != NULL);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_if_fail (class->synchronize_message != NULL);
+
+ class->synchronize_message (
+ folder, message_uid, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_folder_synchronize_message_finish:
+ * @folder: a #CamelFolder
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_folder_synchronize_message().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_synchronize_message_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelFolderClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->synchronize_message_finish != NULL, FALSE);
+
+ return class->synchronize_message_finish (folder, result, error);
+}
+
+/**
+ * camel_folder_transfer_messages_to_sync:
+ * @source: the source #CamelFolder
+ * @message_uids: message UIDs in @source
+ * @destination: the destination #CamelFolder
+ * @delete_originals: whether or not to delete the original messages
+ * @transferred_uids: if non-%NULL, the UIDs of the resulting messages
+ * in @destination will be stored here, if known.
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Copies or moves messages from one folder to another. If the
+ * @source and @destination folders have the same parent_store, this
+ * may be more efficient than using camel_folder_append_message_sync().
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_transfer_messages_to_sync (CamelFolder *source,
+ GPtrArray *message_uids,
+ CamelFolder *destination,
+ gboolean delete_originals,
+ GPtrArray **transferred_uids,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolderClass *class;
+ gboolean success;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (source), FALSE);
+ g_return_val_if_fail (CAMEL_IS_FOLDER (destination), FALSE);
+ g_return_val_if_fail (message_uids != NULL, FALSE);
+
+ if (source == destination || message_uids->len == 0)
+ return TRUE;
+
+ if (source->priv->parent_store == destination->priv->parent_store) {
+ /* If either folder is a vtrash, we need to use the
+ * vtrash transfer method. */
+ if (CAMEL_IS_VTRASH_FOLDER (destination))
+ class = CAMEL_FOLDER_GET_CLASS (destination);
+ else
+ class = CAMEL_FOLDER_GET_CLASS (source);
+ success = class->transfer_messages_to_sync (
+ source, message_uids, destination, delete_originals,
+ transferred_uids, cancellable, error);
+ } else
+ success = folder_transfer_messages_to_sync (
+ source, message_uids, destination, delete_originals,
+ transferred_uids, cancellable, error);
+
+ return success;
+}
+
+/**
+ * camel_folder_transfer_messages_to:
+ * @source: the source #CamelFolder
+ * @message_uids: message UIDs in @source
+ * @destination: the destination #CamelFolder
+ * @delete_originals: whether or not to delete the original messages
+ * @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 copies or moves messages from one folder to another.
+ * If the @source or @destination folders have the same parent store,
+ * this may be more efficient than using camel_folder_append_message().
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_folder_transfer_messages_to_finish() to get the result of the
+ * operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_folder_transfer_messages_to (CamelFolder *source,
+ GPtrArray *message_uids,
+ CamelFolder *destination,
+ gboolean delete_originals,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelFolderClass *class;
+
+ g_return_if_fail (CAMEL_IS_FOLDER (source));
+ g_return_if_fail (CAMEL_IS_FOLDER (destination));
+ g_return_if_fail (message_uids != NULL);
+
+ class = CAMEL_FOLDER_GET_CLASS (source);
+ g_return_if_fail (class->transfer_messages_to != NULL);
+
+ class->transfer_messages_to (
+ source, message_uids, destination, delete_originals,
+ io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * camel_folder_transfer_messages_to_finish:
+ * @source: a #CamelFolder
+ * @result: a #GAsyncResult
+ * @transferred_uids: if non-%NULL, the UIDs of the resulting messages
+ * in @destination will be stored here, if known.
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_folder_transfer_messages_to().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_folder_transfer_messages_to_finish (CamelFolder *source,
+ GAsyncResult *result,
+ GPtrArray **transferred_uids,
+ GError **error)
+{
+ CamelFolderClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (source), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_FOLDER_GET_CLASS (source);
+ g_return_val_if_fail (class->transfer_messages_to_finish != NULL, FALSE);
+
+ return class->transfer_messages_to_finish (
+ source, result, transferred_uids, error);
+}
+
+/**
* camel_folder_change_info_new:
*
* Create a new folder change info structure.
@@ -2991,59 +4025,3 @@ camel_folder_change_info_free (CamelFolderChangeInfo *info)
g_ptr_array_free (info->uid_recent, TRUE);
g_slice_free (CamelFolderChangeInfo, info);
}
-
-/**
- * camel_folder_lock:
- * @folder: a #CamelFolder
- * @lock: lock type to lock
- *
- * Locks #folder's #lock. Unlock it with camel_folder_unlock().
- *
- * Since: 2.32
- **/
-void
-camel_folder_lock (CamelFolder *folder,
- CamelFolderLock lock)
-{
- g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
- switch (lock) {
- case CAMEL_FOLDER_CHANGE_LOCK:
- g_static_mutex_lock (&folder->priv->change_lock);
- break;
- case CAMEL_FOLDER_REC_LOCK:
- if (folder->priv->skip_folder_lock == FALSE)
- g_static_rec_mutex_lock (&folder->priv->lock);
- break;
- default:
- g_return_if_reached ();
- }
-}
-
-/**
- * camel_folder_unlock:
- * @folder: a #CamelFolder
- * @lock: lock type to unlock
- *
- * Unlocks #folder's #lock, previously locked with camel_folder_lock().
- *
- * Since: 2.32
- **/
-void
-camel_folder_unlock (CamelFolder *folder,
- CamelFolderLock lock)
-{
- g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
- switch (lock) {
- case CAMEL_FOLDER_CHANGE_LOCK:
- g_static_mutex_unlock (&folder->priv->change_lock);
- break;
- case CAMEL_FOLDER_REC_LOCK:
- if (folder->priv->skip_folder_lock == FALSE)
- g_static_rec_mutex_unlock (&folder->priv->lock);
- break;
- default:
- g_return_if_reached ();
- }
-}
diff --git a/camel/camel-folder.h b/camel/camel-folder.h
index 652cba701..0fb551b21 100644
--- a/camel/camel-folder.h
+++ b/camel/camel-folder.h
@@ -143,7 +143,7 @@ struct _CamelFolder {
struct _CamelFolderClass {
CamelObjectClass parent_class;
- /* Methods */
+ /* Non-Blocking Methods */
gint (*get_message_count) (CamelFolder *folder);
guint32 (*get_permanent_flags) (CamelFolder *folder);
guint32 (*get_message_flags) (CamelFolder *folder,
@@ -212,9 +212,10 @@ struct _CamelFolderClass {
const gchar *uid,
GError **error);
+ /* Synchronous I/O Methods */
gboolean (*append_message_sync) (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error);
@@ -223,7 +224,7 @@ struct _CamelFolderClass {
GError **error);
CamelMimeMessage *
(*get_message_sync) (CamelFolder *folder,
- const gchar *uid,
+ const gchar *message_uid,
GCancellable *cancellable,
GError **error);
gboolean (*refresh_info_sync) (CamelFolder *folder,
@@ -235,16 +236,88 @@ struct _CamelFolderClass {
GError **error);
gboolean (*synchronize_message_sync)
(CamelFolder *folder,
- const gchar *uid,
+ const gchar *message_uid,
GCancellable *cancellable,
GError **error);
gboolean (*transfer_messages_to_sync)
(CamelFolder *source,
- GPtrArray *uids,
+ GPtrArray *message_uids,
CamelFolder *destination,
+ gboolean delete_originals,
GPtrArray **transferred_uids,
+ GCancellable *cancellable,
+ GError **error);
+
+ /* Asynchronous I/O Methods (all have defaults) */
+ void (*append_message) (CamelFolder *folder,
+ CamelMimeMessage *message,
+ CamelMessageInfo *info,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*append_message_finish)
+ (CamelFolder *folder,
+ GAsyncResult *result,
+ gchar **appended_uid,
+ GError **error);
+ void (*expunge) (CamelFolder *folder,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*expunge_finish) (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error);
+ void (*get_message) (CamelFolder *folder,
+ const gchar *message_uid,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ CamelMimeMessage *
+ (*get_message_finish) (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error);
+ void (*refresh_info) (CamelFolder *folder,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*refresh_info_finish) (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error);
+ void (*synchronize) (CamelFolder *folder,
+ gboolean expunge,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*synchronize_finish) (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error);
+ void (*synchronize_message) (CamelFolder *folder,
+ const gchar *message_uid,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*synchronize_message_finish)
+ (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error);
+ void (*transfer_messages_to) (CamelFolder *source,
+ GPtrArray *message_uids,
+ CamelFolder *destination,
gboolean delete_originals,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*transfer_messages_to_finish)
+ (CamelFolder *source,
+ GAsyncResult *result,
+ GPtrArray **transferred_uids,
GError **error);
/* Signals */
@@ -378,40 +451,118 @@ void camel_folder_free_deep (CamelFolder *folder,
gchar * camel_folder_get_filename (CamelFolder *folder,
const gchar *uid,
GError **error);
+void camel_folder_lock (CamelFolder *folder,
+ CamelFolderLock lock);
+void camel_folder_unlock (CamelFolder *folder,
+ CamelFolderLock lock);
+
gboolean camel_folder_append_message_sync
(CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error);
+void camel_folder_append_message (CamelFolder *folder,
+ CamelMimeMessage *message,
+ CamelMessageInfo *info,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_folder_append_message_finish
+ (CamelFolder *folder,
+ GAsyncResult *result,
+ gchar **appended_uid,
+ GError **error);
gboolean camel_folder_expunge_sync (CamelFolder *folder,
GCancellable *cancellable,
GError **error);
+void camel_folder_expunge (CamelFolder *folder,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_folder_expunge_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error);
CamelMimeMessage *
camel_folder_get_message_sync (CamelFolder *folder,
- const gchar *uid,
+ const gchar *message_uid,
+ GCancellable *cancellable,
+ GError **error);
+void camel_folder_get_message (CamelFolder *folder,
+ const gchar *message_uid,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+CamelMimeMessage *
+ camel_folder_get_message_finish (CamelFolder *folder,
+ GAsyncResult *result,
GError **error);
gboolean camel_folder_refresh_info_sync (CamelFolder *folder,
GCancellable *cancellable,
GError **error);
+void camel_folder_refresh_info (CamelFolder *folder,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_folder_refresh_info_finish
+ (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error);
gboolean camel_folder_synchronize_sync (CamelFolder *folder,
gboolean expunge,
GCancellable *cancellable,
GError **error);
+void camel_folder_synchronize (CamelFolder *folder,
+ gboolean expunge,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_folder_synchronize_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error);
gboolean camel_folder_synchronize_message_sync
(CamelFolder *folder,
- const gchar *uid,
+ const gchar *message_uid,
+ GCancellable *cancellable,
+ GError **error);
+void camel_folder_synchronize_message
+ (CamelFolder *folder,
+ const gchar *message_uid,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_folder_synchronize_message_finish
+ (CamelFolder *folder,
+ GAsyncResult *result,
GError **error);
gboolean camel_folder_transfer_messages_to_sync
(CamelFolder *source,
- GPtrArray *uids,
- CamelFolder *dest,
+ GPtrArray *message_uids,
+ CamelFolder *destination,
+ gboolean delete_originals,
GPtrArray **transferred_uids,
+ GCancellable *cancellable,
+ GError **error);
+void camel_folder_transfer_messages_to
+ (CamelFolder *source,
+ GPtrArray *message_uids,
+ CamelFolder *destination,
gboolean delete_originals,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_folder_transfer_messages_to_finish
+ (CamelFolder *source,
+ GAsyncResult *result,
+ GPtrArray **transferred_uids,
GError **error);
/* update functions for change info */
@@ -452,11 +603,6 @@ void camel_folder_change_info_recent_uid
(CamelFolderChangeInfo *info,
const gchar *uid);
-void camel_folder_lock (CamelFolder *folder,
- CamelFolderLock lock);
-void camel_folder_unlock (CamelFolder *folder,
- CamelFolderLock lock);
-
G_END_DECLS
#endif /* CAMEL_FOLDER_H */
diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c
index a63257f97..f027917c9 100644
--- a/camel/camel-gpg-context.c
+++ b/camel/camel-gpg-context.c
@@ -1506,7 +1506,7 @@ gpg_id_to_hash (CamelCipherContext *context,
return CAMEL_CIPHER_HASH_DEFAULT;
}
-static gint
+static gboolean
gpg_sign_sync (CamelCipherContext *context,
const gchar *userid,
CamelCipherHash hash,
@@ -1520,9 +1520,9 @@ gpg_sign_sync (CamelCipherContext *context,
CamelStream *ostream = camel_stream_mem_new (), *istream;
CamelDataWrapper *dw;
CamelContentType *ct;
- gint res = -1;
CamelMimePart *sigpart;
CamelMultipartSigned *mps;
+ gboolean success = FALSE;
/* Note: see rfc2015 or rfc3156, section 5 */
@@ -1588,7 +1588,7 @@ gpg_sign_sync (CamelCipherContext *context,
goto fail;
}
- res = 0;
+ success = TRUE;
dw = camel_data_wrapper_new ();
camel_stream_reset (ostream, NULL);
@@ -1608,7 +1608,7 @@ gpg_sign_sync (CamelCipherContext *context,
mps = camel_multipart_signed_new ();
ct = camel_content_type_new("multipart", "signed");
- camel_content_type_set_param(ct, "micalg", camel_cipher_hash_to_id (context, hash == CAMEL_CIPHER_HASH_DEFAULT ? gpg->hash : hash));
+ camel_content_type_set_param(ct, "micalg", camel_cipher_context_hash_to_id (context, hash == CAMEL_CIPHER_HASH_DEFAULT ? gpg->hash : hash));
camel_content_type_set_param(ct, "protocol", class->sign_protocol);
camel_data_wrapper_set_mime_type_field ((CamelDataWrapper *)mps, ct);
camel_content_type_unref (ct);
@@ -1626,7 +1626,7 @@ fail:
if (gpg)
gpg_ctx_free (gpg);
- return res;
+ return success;
}
static CamelCipherValidity *
@@ -1689,8 +1689,9 @@ gpg_verify_sync (CamelCipherContext *context,
CamelDataWrapper *content;
content = camel_medium_get_content ((CamelMedium *) ipart);
istream = camel_stream_mem_new ();
- camel_data_wrapper_decode_to_stream_sync (
- content, istream, NULL, NULL);
+ if (!camel_data_wrapper_decode_to_stream_sync (
+ content, istream, cancellable, error))
+ goto exception;
camel_stream_reset (istream, NULL);
sigpart = NULL;
} else {
@@ -1831,7 +1832,7 @@ gpg_verify_sync (CamelCipherContext *context,
return NULL;
}
-static gint
+static gboolean
gpg_encrypt_sync (CamelCipherContext *context,
const gchar *userid,
GPtrArray *recipients,
@@ -1843,12 +1844,13 @@ gpg_encrypt_sync (CamelCipherContext *context,
CamelCipherContextClass *class;
CamelGpgContext *ctx = (CamelGpgContext *) context;
struct _GpgCtx *gpg;
- gint i, res = -1;
CamelStream *istream, *ostream, *vstream;
CamelMimePart *encpart, *verpart;
CamelDataWrapper *dw;
CamelContentType *ct;
CamelMultipartEncrypted *mpe;
+ gboolean success = FALSE;
+ gint i;
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
@@ -1895,7 +1897,7 @@ gpg_encrypt_sync (CamelCipherContext *context,
goto fail;
}
- res = 0;
+ success = TRUE;
dw = camel_data_wrapper_new ();
camel_data_wrapper_construct_from_stream_sync (
@@ -1946,7 +1948,7 @@ fail1:
g_object_unref (istream);
g_object_unref (ostream);
- return res;
+ return success;
}
static CamelCipherValidity *
@@ -1956,14 +1958,14 @@ gpg_decrypt_sync (CamelCipherContext *context,
GCancellable *cancellable,
GError **error)
{
- struct _GpgCtx *gpg;
+ struct _GpgCtx *gpg = NULL;
CamelCipherValidity *valid = NULL;
CamelStream *ostream, *istream;
CamelDataWrapper *content;
CamelMimePart *encrypted;
CamelMultipart *mp;
CamelContentType *ct;
- gint rv;
+ gboolean success;
if (!ipart) {
g_set_error (
@@ -2005,8 +2007,9 @@ gpg_decrypt_sync (CamelCipherContext *context,
}
istream = camel_stream_mem_new ();
- camel_data_wrapper_decode_to_stream_sync (
- content, istream, NULL, NULL);
+ if (!camel_data_wrapper_decode_to_stream_sync (
+ content, istream, cancellable, error))
+ goto fail;
camel_stream_reset (istream, NULL);
ostream = camel_stream_mem_new ();
@@ -2044,7 +2047,7 @@ gpg_decrypt_sync (CamelCipherContext *context,
CamelStream *null = camel_stream_null_new ();
/* Multipart encrypted - parse a full mime part */
- rv = camel_data_wrapper_construct_from_stream_sync (
+ success = camel_data_wrapper_construct_from_stream_sync (
CAMEL_DATA_WRAPPER (opart),
ostream, NULL, error);
@@ -2054,8 +2057,8 @@ gpg_decrypt_sync (CamelCipherContext *context,
/* nothing had been decoded from the stream, it doesn't
contain any header, like Content-Type or such, thus
write it as a message body */
- rv = camel_data_wrapper_construct_from_stream_sync (
- dw, ostream, NULL, error);
+ success = camel_data_wrapper_construct_from_stream_sync (
+ dw, ostream, cancellable, error);
}
g_object_unref (null);
@@ -2063,7 +2066,7 @@ gpg_decrypt_sync (CamelCipherContext *context,
/* Inline signed - raw data (may not be a mime part) */
CamelDataWrapper *dw;
dw = camel_data_wrapper_new ();
- rv = camel_data_wrapper_construct_from_stream_sync (
+ success = camel_data_wrapper_construct_from_stream_sync (
dw, ostream, NULL, error);
camel_data_wrapper_set_mime_type(dw, "application/octet-stream");
camel_medium_set_content ((CamelMedium *)opart, dw);
@@ -2072,7 +2075,7 @@ gpg_decrypt_sync (CamelCipherContext *context,
camel_mime_part_set_content_type(opart, "application/octet-stream");
}
- if (rv != -1) {
+ if (success) {
valid = camel_cipher_validity_new ();
valid->encrypt.description = g_strdup(_("Encrypted content"));
valid->encrypt.status = CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED;
@@ -2103,14 +2106,14 @@ gpg_decrypt_sync (CamelCipherContext *context,
return valid;
}
-static gint
+static gboolean
gpg_import_keys_sync (CamelCipherContext *context,
CamelStream *istream,
GCancellable *cancellable,
GError **error)
{
struct _GpgCtx *gpg;
- gint res = -1;
+ gboolean success = FALSE;
gpg = gpg_ctx_new (context);
gpg_ctx_set_mode (gpg, GPG_CTX_MODE_IMPORT);
@@ -2137,14 +2140,14 @@ gpg_import_keys_sync (CamelCipherContext *context,
goto fail;
}
- res = 0;
+ success = TRUE;
fail:
gpg_ctx_free (gpg);
- return res;
+ return success;
}
-static gint
+static gboolean
gpg_export_keys_sync (CamelCipherContext *context,
GPtrArray *keys,
CamelStream *ostream,
@@ -2152,8 +2155,8 @@ gpg_export_keys_sync (CamelCipherContext *context,
GError **error)
{
struct _GpgCtx *gpg;
+ gboolean success = FALSE;
gint i;
- gint res = -1;
gpg = gpg_ctx_new (context);
gpg_ctx_set_mode (gpg, GPG_CTX_MODE_EXPORT);
@@ -2185,11 +2188,11 @@ gpg_export_keys_sync (CamelCipherContext *context,
goto fail;
}
- res = 0;
+ success = TRUE;
fail:
gpg_ctx_free (gpg);
- return res;
+ return success;
}
static void
diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c
index ba97e3aa9..217b85c0a 100644
--- a/camel/camel-mime-message.c
+++ b/camel/camel-mime-message.c
@@ -288,7 +288,7 @@ mime_message_remove_header (CamelMedium *medium,
CAMEL_MEDIUM_CLASS (camel_mime_message_parent_class)->remove_header (medium, name);
}
-static gint
+static gboolean
mime_message_construct_from_parser_sync (CamelMimePart *dw,
CamelMimeParser *mp,
GCancellable *cancellable,
@@ -298,16 +298,16 @@ mime_message_construct_from_parser_sync (CamelMimePart *dw,
gchar *buf;
gsize len;
gint state;
- gint ret;
gint err;
+ gboolean success;
/* let the mime-part construct the guts ... */
mime_part_class = CAMEL_MIME_PART_CLASS (camel_mime_message_parent_class);
- ret = mime_part_class->construct_from_parser_sync (
+ success = mime_part_class->construct_from_parser_sync (
dw, mp, cancellable, error);
- if (ret == -1)
- return -1;
+ if (!success)
+ return FALSE;
/* ... then clean up the follow-on state */
state = camel_mime_parser_step (mp, &buf, &len);
@@ -321,7 +321,7 @@ mime_message_construct_from_parser_sync (CamelMimePart *dw,
default:
g_error ("Bad parser state: Expecing MESSAGE_END or EOF or EOM, got: %u", camel_mime_parser_state (mp));
camel_mime_parser_unstep (mp);
- return -1;
+ return FALSE;
}
err = camel_mime_parser_errno (mp);
@@ -331,10 +331,10 @@ mime_message_construct_from_parser_sync (CamelMimePart *dw,
error, G_IO_ERROR,
g_io_error_from_errno (errno),
"%s", g_strerror (errno));
- ret = -1;
+ success = FALSE;
}
- return ret;
+ return success;
}
static void
@@ -845,7 +845,10 @@ camel_mime_message_has_8bit_parts (CamelMimeMessage *msg)
/* finds the best charset and transfer encoding for a given part */
static CamelTransferEncoding
-find_best_encoding (CamelMimePart *part, CamelBestencRequired required, CamelBestencEncoding enctype, gchar **charsetp)
+find_best_encoding (CamelMimePart *part,
+ CamelBestencRequired required,
+ CamelBestencEncoding enctype,
+ gchar **charsetp)
{
CamelMimeFilter *charenc = NULL;
CamelTransferEncoding encoding;
@@ -1034,7 +1037,9 @@ best_encoding (CamelMimeMessage *msg, CamelMimePart *part, gpointer datap)
* parts will be encoded as binary and 8bit textual parts will be encoded as 8bit.
**/
void
-camel_mime_message_set_best_encoding (CamelMimeMessage *msg, CamelBestencRequired required, CamelBestencEncoding enctype)
+camel_mime_message_set_best_encoding (CamelMimeMessage *msg,
+ CamelBestencRequired required,
+ CamelBestencEncoding enctype)
{
struct _enc_data data;
diff --git a/camel/camel-mime-message.h b/camel/camel-mime-message.h
index f4cac90d7..3f6ae1f1b 100644
--- a/camel/camel-mime-message.h
+++ b/camel/camel-mime-message.h
@@ -93,55 +93,63 @@ struct _CamelMimeMessageClass {
CamelMimePartClass parent_class;
};
-GType camel_mime_message_get_type (void);
-
-/* public methods */
-CamelMimeMessage *camel_mime_message_new (void);
-void camel_mime_message_set_date (CamelMimeMessage *message,
- time_t date,
- gint offset);
-time_t camel_mime_message_get_date (CamelMimeMessage *message,
- gint *offset);
-time_t camel_mime_message_get_date_received (CamelMimeMessage *message,
- gint *offset);
-void camel_mime_message_set_message_id (CamelMimeMessage *message,
- const gchar *message_id);
-const gchar *camel_mime_message_get_message_id (CamelMimeMessage *message);
-void camel_mime_message_set_reply_to (CamelMimeMessage *message,
- CamelInternetAddress *reply_to);
-CamelInternetAddress * camel_mime_message_get_reply_to (CamelMimeMessage *message);
-
-void camel_mime_message_set_subject (CamelMimeMessage *message,
- const gchar *subject);
-const gchar *camel_mime_message_get_subject (CamelMimeMessage *message);
-void camel_mime_message_set_from (CamelMimeMessage *message,
- CamelInternetAddress *from);
-CamelInternetAddress * camel_mime_message_get_from (CamelMimeMessage *message);
-
-CamelInternetAddress * camel_mime_message_get_recipients (CamelMimeMessage *message,
- const gchar *type);
-void camel_mime_message_set_recipients (CamelMimeMessage *message,
- const gchar *type,
- CamelInternetAddress *recipients);
-
-void camel_mime_message_set_source (CamelMimeMessage *message,
- const gchar *identity);
-const gchar *camel_mime_message_get_source (CamelMimeMessage *message);
+GType camel_mime_message_get_type (void);
+CamelMimeMessage *
+ camel_mime_message_new (void);
+void camel_mime_message_set_date (CamelMimeMessage *message,
+ time_t date,
+ gint offset);
+time_t camel_mime_message_get_date (CamelMimeMessage *message,
+ gint *offset);
+time_t camel_mime_message_get_date_received
+ (CamelMimeMessage *message,
+ gint *offset);
+void camel_mime_message_set_message_id
+ (CamelMimeMessage *message,
+ const gchar *message_id);
+const gchar * camel_mime_message_get_message_id
+ (CamelMimeMessage *message);
+void camel_mime_message_set_reply_to (CamelMimeMessage *message,
+ CamelInternetAddress *reply_to);
+CamelInternetAddress *
+ camel_mime_message_get_reply_to (CamelMimeMessage *message);
+void camel_mime_message_set_subject (CamelMimeMessage *message,
+ const gchar *subject);
+const gchar * camel_mime_message_get_subject (CamelMimeMessage *message);
+void camel_mime_message_set_from (CamelMimeMessage *message,
+ CamelInternetAddress *from);
+CamelInternetAddress *
+ camel_mime_message_get_from (CamelMimeMessage *message);
+CamelInternetAddress *
+ camel_mime_message_get_recipients
+ (CamelMimeMessage *message,
+ const gchar *type);
+void camel_mime_message_set_recipients
+ (CamelMimeMessage *message,
+ const gchar *type,
+ CamelInternetAddress *recipients);
+void camel_mime_message_set_source (CamelMimeMessage *message,
+ const gchar *identity);
+const gchar * camel_mime_message_get_source (CamelMimeMessage *message);
/* utility functions */
-gboolean camel_mime_message_has_8bit_parts (CamelMimeMessage *message);
-void camel_mime_message_set_best_encoding (CamelMimeMessage *message,
- CamelBestencRequired required,
- CamelBestencEncoding enctype);
-void camel_mime_message_encode_8bit_parts (CamelMimeMessage *message);
-
-CamelMimePart *camel_mime_message_get_part_by_content_id (CamelMimeMessage *message, const gchar *content_id);
-
-gchar *camel_mime_message_build_mbox_from (CamelMimeMessage *message);
-
-gboolean camel_mime_message_has_attachment (CamelMimeMessage *message);
-
-void camel_mime_message_dump (CamelMimeMessage *msg, gint body);
+gboolean camel_mime_message_has_8bit_parts
+ (CamelMimeMessage *message);
+void camel_mime_message_set_best_encoding
+ (CamelMimeMessage *message,
+ CamelBestencRequired required,
+ CamelBestencEncoding enctype);
+void camel_mime_message_encode_8bit_parts
+ (CamelMimeMessage *message);
+CamelMimePart * camel_mime_message_get_part_by_content_id
+ (CamelMimeMessage *message,
+ const gchar *content_id);
+gchar * camel_mime_message_build_mbox_from
+ (CamelMimeMessage *message);
+gboolean camel_mime_message_has_attachment
+ (CamelMimeMessage *message);
+void camel_mime_message_dump (CamelMimeMessage *message,
+ gint body);
G_END_DECLS
diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c
index e9c7268b9..b9aad19d6 100644
--- a/camel/camel-mime-part-utils.c
+++ b/camel/camel-mime-part-utils.c
@@ -64,7 +64,7 @@ simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw,
GByteArray *buffer;
CamelStream *mem;
gsize len;
- gint retval;
+ gboolean success;
d(printf ("simple_data_wrapper_construct_from_parser()\n"));
@@ -78,11 +78,11 @@ simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw,
d(printf("message part kept in memory!\n"));
mem = camel_stream_mem_new_with_byte_array (buffer);
- retval = camel_data_wrapper_construct_from_stream_sync (
+ success = camel_data_wrapper_construct_from_stream_sync (
dw, mem, cancellable, error);
g_object_unref (mem);
- return (retval == 0);
+ return success;
}
/**
@@ -123,8 +123,8 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw,
case CAMEL_MIME_PARSER_STATE_MESSAGE:
d(printf("Creating message part\n"));
content = (CamelDataWrapper *) camel_mime_message_new ();
- success = (camel_mime_part_construct_from_parser_sync (
- (CamelMimePart *)content, mp, cancellable, error) == 0);
+ success = camel_mime_part_construct_from_parser_sync (
+ (CamelMimePart *)content, mp, cancellable, error);
break;
case CAMEL_MIME_PARSER_STATE_MULTIPART:
d(printf("Creating multi-part\n"));
@@ -160,6 +160,12 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw,
/**
* camel_mime_message_build_preview:
*
+ * <note>
+ * <para>
+ * This function blocks like crazy.
+ * </para>
+ * </note>
+ *
* Since: 2.28
**/
gboolean
@@ -186,6 +192,8 @@ camel_mime_message_build_preview (CamelMimePart *msg,
/* !camel_content_type_is (dw->mime_type, "text", "html") && */
!camel_content_type_is (dw->mime_type, "text", "calendar")) {
CamelStream *mstream, *bstream;
+
+ /* FIXME Pass a GCancellable and GError here. */
mstream = camel_stream_mem_new ();
if (camel_data_wrapper_decode_to_stream_sync (dw, mstream, NULL, NULL) > 0) {
gchar *line = NULL;
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index e4d7025b7..8b5bc99ad 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -53,9 +53,9 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), CAMEL_TYPE_MIME_PART, CamelMimePartPrivate))
-struct _CamelMimePartPrivate {
+typedef struct _AsyncContext AsyncContext;
- /* TODO: these should be in a camelcontentinfo */
+struct _CamelMimePartPrivate {
gchar *description;
CamelContentDisposition *disposition;
gchar *content_id;
@@ -65,6 +65,11 @@ struct _CamelMimePartPrivate {
CamelTransferEncoding encoding;
};
+struct _AsyncContext {
+ /* arguments */
+ CamelMimeParser *parser;
+};
+
enum {
PROP_0,
PROP_CONTENT_ID,
@@ -92,6 +97,15 @@ static GHashTable *header_formatted_table;
G_DEFINE_TYPE (CamelMimePart, camel_mime_part, CAMEL_TYPE_MEDIUM)
+static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->parser != NULL)
+ g_object_unref (async_context->parser);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
static gssize
write_header (CamelStream *stream,
const gchar *name,
@@ -671,31 +685,32 @@ mime_part_write_to_stream_sync (CamelDataWrapper *dw,
return total;
}
-static gint
+static gboolean
mime_part_construct_from_stream_sync (CamelDataWrapper *dw,
- CamelStream *s,
+ CamelStream *stream,
GCancellable *cancellable,
GError **error)
{
- CamelMimeParser *mp;
- gint ret;
+ CamelMimeParser *parser;
+ gboolean success;
d(printf("mime_part::construct_from_stream()\n"));
- mp = camel_mime_parser_new ();
- if (camel_mime_parser_init_with_stream (mp, s, error) == -1) {
- ret = -1;
+ parser = camel_mime_parser_new ();
+ if (camel_mime_parser_init_with_stream (parser, stream, error) == -1) {
+ success = FALSE;
} else {
- ret = camel_mime_part_construct_from_parser_sync (
- CAMEL_MIME_PART (dw), mp, cancellable, error);
+ success = camel_mime_part_construct_from_parser_sync (
+ CAMEL_MIME_PART (dw), parser, cancellable, error);
}
- g_object_unref (mp);
- return ret;
+ g_object_unref (parser);
+
+ return success;
}
-static gint
+static gboolean
mime_part_construct_from_parser_sync (CamelMimePart *mime_part,
- CamelMimeParser *mp,
+ CamelMimeParser *parser,
GCancellable *cancellable,
GError **error)
{
@@ -705,10 +720,9 @@ mime_part_construct_from_parser_sync (CamelMimePart *mime_part,
gchar *buf;
gsize len;
gint err;
- gboolean success;
- gboolean retval = 0;
+ gboolean success = TRUE;
- switch (camel_mime_parser_step (mp, &buf, &len)) {
+ switch (camel_mime_parser_step (parser, &buf, &len)) {
case CAMEL_MIME_PARSER_STATE_MESSAGE:
/* set the default type of a message always */
if (dw->mime_type)
@@ -717,7 +731,7 @@ mime_part_construct_from_parser_sync (CamelMimePart *mime_part,
case CAMEL_MIME_PARSER_STATE_HEADER:
case CAMEL_MIME_PARSER_STATE_MULTIPART:
/* we have the headers, build them into 'us' */
- headers = camel_mime_parser_headers_raw (mp);
+ headers = camel_mime_parser_headers_raw (parser);
/* if content-type exists, process it first, set for fallback charset in headers */
content = camel_header_raw_find(&headers, "content-type", NULL);
@@ -734,24 +748,89 @@ mime_part_construct_from_parser_sync (CamelMimePart *mime_part,
}
success = camel_mime_part_construct_content_from_parser (
- mime_part, mp, cancellable, error);
- retval = success ? 0 : -1;
+ mime_part, parser, cancellable, error);
break;
default:
- g_warning("Invalid state encountered???: %u", camel_mime_parser_state(mp));
+ g_warning("Invalid state encountered???: %u", camel_mime_parser_state(parser));
}
- err = camel_mime_parser_errno (mp);
+ err = camel_mime_parser_errno (parser);
if (err != 0) {
errno = err;
g_set_error (
error, G_IO_ERROR,
g_io_error_from_errno (errno),
"%s", g_strerror (errno));
- retval = -1;
+ success = FALSE;
+ }
+
+ return success;
+}
+
+static void
+mime_part_construct_from_parser_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_mime_part_construct_from_parser_sync (
+ CAMEL_MIME_PART (object), async_context->parser,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
}
+}
+
+static void
+mime_part_construct_from_parser (CamelMimePart *mime_part,
+ CamelMimeParser *parser,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->parser = g_object_ref (parser);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (mime_part), callback, user_data,
+ mime_part_construct_from_parser);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, mime_part_construct_from_parser_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+mime_part_construct_from_parser_finish (CamelMimePart *mime_part,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
- return retval;
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (mime_part),
+ mime_part_construct_from_parser), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
static void
@@ -782,6 +861,8 @@ camel_mime_part_class_init (CamelMimePartClass *class)
data_wrapper_class->construct_from_stream_sync = mime_part_construct_from_stream_sync;
class->construct_from_parser_sync = mime_part_construct_from_parser_sync;
+ class->construct_from_parser = mime_part_construct_from_parser;
+ class->construct_from_parser_finish = mime_part_construct_from_parser_finish;
g_object_class_install_property (
object_class,
@@ -842,245 +923,264 @@ camel_mime_part_init (CamelMimePart *mime_part)
data_wrapper->mime_type = camel_content_type_new ("text", "plain");
}
-/* **** Content-Description */
+/**
+ * camel_mime_part_new:
+ *
+ * Create a new MIME part.
+ *
+ * Returns: a new #CamelMimePart
+ **/
+CamelMimePart *
+camel_mime_part_new (void)
+{
+ return g_object_new (CAMEL_TYPE_MIME_PART, NULL);
+}
/**
- * camel_mime_part_set_description:
- * @mime_part: a #CamelMimePart object
- * @description: description of the MIME part
+ * camel_mime_part_set_content:
+ * @mime_part: a #CamelMimePart
+ * @data: data to put into the part
+ * @length: length of @data
+ * @type: Content-Type of the data
*
- * Set a description on the MIME part.
+ * Utility function used to set the content of a mime part object to
+ * be the provided data. If @length is 0, this routine can be used as
+ * a way to remove old content (in which case @data and @type are
+ * ignored and may be %NULL).
**/
void
-camel_mime_part_set_description (CamelMimePart *mime_part,
- const gchar *description)
+camel_mime_part_set_content (CamelMimePart *mime_part,
+ const gchar *data,
+ gint length,
+ const gchar *type) /* why on earth is the type last? */
{
- CamelMedium *medium;
- gchar *text;
+ CamelMedium *medium = CAMEL_MEDIUM (mime_part);
- g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
- g_return_if_fail (description != NULL);
+ if (length) {
+ CamelDataWrapper *dw;
+ CamelStream *stream;
- medium = CAMEL_MEDIUM (mime_part);
+ dw = camel_data_wrapper_new ();
+ camel_data_wrapper_set_mime_type (dw, type);
+ stream = camel_stream_mem_new_with_buffer (data, length);
+ camel_data_wrapper_construct_from_stream_sync (
+ dw, stream, NULL, NULL);
+ g_object_unref (stream);
+ camel_medium_set_content (medium, dw);
+ g_object_unref (dw);
+ } else
+ camel_medium_set_content (medium, NULL);
+}
- text = camel_header_encode_string ((guchar *) description);
- camel_medium_set_header (medium, "Content-Description", text);
- g_free (text);
+/**
+ * camel_mime_part_get_content_disposition:
+ * @mime_part: a #CamelMimePart
+ *
+ * Get the disposition of the MIME part as a structure.
+ * Returned pointer is owned by #mime_part.
+ *
+ * Returns: the disposition structure
+ *
+ * Since: 2.30
+ **/
+const CamelContentDisposition *
+camel_mime_part_get_content_disposition (CamelMimePart *mime_part)
+{
+ g_return_val_if_fail (mime_part != NULL, NULL);
- g_object_notify (G_OBJECT (mime_part), "description");
+ return mime_part->priv->disposition;
}
/**
- * camel_mime_part_get_description:
- * @mime_part: a #CamelMimePart object
+ * camel_mime_part_get_content_id:
+ * @mime_part: a #CamelMimePart
*
- * Get the description of the MIME part.
+ * Get the content-id field of a MIME part.
*
- * Returns: the description
+ * Returns: the content-id field of the MIME part
**/
const gchar *
-camel_mime_part_get_description (CamelMimePart *mime_part)
+camel_mime_part_get_content_id (CamelMimePart *mime_part)
{
g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
- return mime_part->priv->description;
+ return mime_part->priv->content_id;
}
-/* **** Content-Disposition */
-
/**
- * camel_mime_part_set_disposition:
- * @mime_part: a #CamelMimePart object
- * @disposition: disposition of the MIME part
+ * camel_mime_part_set_content_id:
+ * @mime_part: a #CamelMimePart
+ * @contentid: content id
*
- * Set a disposition on the MIME part.
+ * Set the content-id field on a MIME part.
**/
void
-camel_mime_part_set_disposition (CamelMimePart *mime_part,
- const gchar *disposition)
+camel_mime_part_set_content_id (CamelMimePart *mime_part,
+ const gchar *contentid)
{
CamelMedium *medium;
- gchar *text;
+ gchar *cid, *id;
g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
medium = CAMEL_MEDIUM (mime_part);
- /* we poke in a new disposition (so we dont lose 'filename', etc) */
- if (mime_part->priv->disposition == NULL)
- mime_part_set_disposition (mime_part, disposition);
+ if (contentid)
+ id = g_strstrip (g_strdup (contentid));
+ else
+ id = camel_header_msgid_generate ();
- if (mime_part->priv->disposition != NULL) {
- g_free (mime_part->priv->disposition->disposition);
- mime_part->priv->disposition->disposition = g_strdup (disposition);
- }
+ cid = g_strdup_printf ("<%s>", id);
+ camel_medium_set_header (medium, "Content-ID", cid);
+ g_free (cid);
- text = camel_content_disposition_format (mime_part->priv->disposition);
- camel_medium_set_header (medium, "Content-Disposition", text);
- g_free (text);
+ g_free (id);
- g_object_notify (G_OBJECT (mime_part), "disposition");
+ g_object_notify (G_OBJECT (mime_part), "content-id");
}
/**
- * camel_mime_part_get_disposition:
- * @mime_part: a #CamelMimePart object
+ * camel_mime_part_get_content_location:
+ * @mime_part: a #CamelMimePart
*
- * Get the disposition of the MIME part.
+ * Get the content-location field of a MIME part.
*
- * Returns: the disposition
+ * Returns: the content-location field of a MIME part
**/
const gchar *
-camel_mime_part_get_disposition (CamelMimePart *mime_part)
+camel_mime_part_get_content_location (CamelMimePart *mime_part)
{
g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
- if (mime_part->priv->disposition)
- return mime_part->priv->disposition->disposition;
- else
- return NULL;
+ return mime_part->priv->content_location;
}
/**
- * camel_mime_part_get_content_disposition:
- * @mime_part: a #CamelMimePart object
+ * camel_mime_part_set_content_location:
+ * @mime_part: a #CamelMimePart
+ * @location: the content-location value of the MIME part
*
- * Get the disposition of the MIME part as a structure.
- * Returned pointer is owned by #mime_part.
+ * Set the content-location field of the MIME part.
+ **/
+void
+camel_mime_part_set_content_location (CamelMimePart *mime_part,
+ const gchar *location)
+{
+ CamelMedium *medium;
+
+ g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
+
+ medium = CAMEL_MEDIUM (mime_part);
+
+ /* FIXME: this should perform content-location folding */
+ camel_medium_set_header (medium, "Content-Location", location);
+
+ g_object_notify (G_OBJECT (mime_part), "content-location");
+}
+
+/**
+ * camel_mime_part_get_content_md5:
+ * @mime_part: a #CamelMimePart
*
- * Returns: the disposition structure
+ * Get the content-md5 field of the MIME part.
*
- * Since: 2.30
+ * Returns: the content-md5 field of the MIME part
**/
-const CamelContentDisposition *
-camel_mime_part_get_content_disposition (CamelMimePart *mime_part)
+const gchar *
+camel_mime_part_get_content_md5 (CamelMimePart *mime_part)
{
- g_return_val_if_fail (mime_part != NULL, NULL);
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
- return mime_part->priv->disposition;
+ return mime_part->priv->content_md5;
}
-/* **** Content-Disposition: filename="xxx" */
-
/**
- * camel_mime_part_set_filename:
- * @mime_part: a #CamelMimePart object
- * @filename: filename given to the MIME part
+ * camel_mime_part_set_content_md5:
+ * @mime_part: a #CamelMimePart
+ * @md5sum: the md5sum of the MIME part
*
- * Set the filename on a MIME part.
+ * Set the content-md5 field of the MIME part.
**/
void
-camel_mime_part_set_filename (CamelMimePart *mime_part, const gchar *filename)
+camel_mime_part_set_content_md5 (CamelMimePart *mime_part,
+ const gchar *content_md5)
{
- CamelDataWrapper *dw;
CamelMedium *medium;
- gchar *str;
-
- medium = CAMEL_MEDIUM (mime_part);
-
- if (mime_part->priv->disposition == NULL)
- mime_part->priv->disposition =
- camel_content_disposition_decode("attachment");
- camel_header_set_param (
- &mime_part->priv->disposition->params, "filename", filename);
- str = camel_content_disposition_format (mime_part->priv->disposition);
+ g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
- camel_medium_set_header (medium, "Content-Disposition", str);
- g_free (str);
+ medium = CAMEL_MEDIUM (mime_part);
- dw = (CamelDataWrapper *) mime_part;
- if (!dw->mime_type)
- dw->mime_type = camel_content_type_new ("application", "octet-stream");
- camel_content_type_set_param (dw->mime_type, "name", filename);
- str = camel_content_type_format (dw->mime_type);
- camel_medium_set_header (medium, "Content-Type", str);
- g_free (str);
+ camel_medium_set_header (medium, "Content-MD5", content_md5);
}
/**
- * camel_mime_part_get_filename:
- * @mime_part: a #CamelMimePart object
+ * camel_mime_part_get_content_languages:
+ * @mime_part: a #CamelMimePart
*
- * Get the filename of a MIME part.
+ * Get the Content-Languages set on the MIME part.
*
- * Returns: the filename of the MIME part
+ * Returns: a #GList of languages
**/
-const gchar *
-camel_mime_part_get_filename (CamelMimePart *mime_part)
+const GList *
+camel_mime_part_get_content_languages (CamelMimePart *mime_part)
{
- if (mime_part->priv->disposition) {
- const gchar *name = camel_header_param (
- mime_part->priv->disposition->params, "filename");
- if (name)
- return name;
- }
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
- return camel_content_type_param (((CamelDataWrapper *) mime_part)->mime_type, "name");
+ return mime_part->priv->content_languages;
}
-/* **** Content-ID: */
-
/**
- * camel_mime_part_set_content_id:
- * @mime_part: a #CamelMimePart object
- * @contentid: content id
+ * camel_mime_part_set_content_languages:
+ * @mime_part: a #CamelMimePart
+ * @content_languages: list of languages
*
- * Set the content-id field on a MIME part.
+ * Set the Content-Languages field of a MIME part.
**/
void
-camel_mime_part_set_content_id (CamelMimePart *mime_part,
- const gchar *contentid)
+camel_mime_part_set_content_languages (CamelMimePart *mime_part,
+ GList *content_languages)
{
- CamelMedium *medium;
- gchar *cid, *id;
-
g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
- medium = CAMEL_MEDIUM (mime_part);
-
- if (contentid)
- id = g_strstrip (g_strdup (contentid));
- else
- id = camel_header_msgid_generate ();
-
- cid = g_strdup_printf ("<%s>", id);
- camel_medium_set_header (medium, "Content-ID", cid);
- g_free (cid);
+ if (mime_part->priv->content_languages)
+ camel_string_list_free (mime_part->priv->content_languages);
- g_free (id);
+ mime_part->priv->content_languages = content_languages;
- g_object_notify (G_OBJECT (mime_part), "content-id");
+ /* FIXME: translate to a header and set it */
}
/**
- * camel_mime_part_get_content_id:
- * @mime_part: a #CamelMimePart object
+ * camel_mime_part_get_content_type:
+ * @mime_part: a #CamelMimePart
*
- * Get the content-id field of a MIME part.
+ * Get the Content-Type of a MIME part.
*
- * Returns: the content-id field of the MIME part
+ * Returns: the parsed #CamelContentType of the MIME part
**/
-const gchar *
-camel_mime_part_get_content_id (CamelMimePart *mime_part)
+CamelContentType *
+camel_mime_part_get_content_type (CamelMimePart *mime_part)
{
+ CamelDataWrapper *data_wrapper;
+
g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
- return mime_part->priv->content_id;
-}
+ data_wrapper = CAMEL_DATA_WRAPPER (mime_part);
-/* **** Content-MD5: */
+ return camel_data_wrapper_get_mime_type_field (data_wrapper);
+}
/**
- * camel_mime_part_set_content_md5:
- * @mime_part: a #CamelMimePart object
- * @md5sum: the md5sum of the MIME part
+ * camel_mime_part_set_content_type:
+ * @mime_part: a #CamelMimePart
+ * @content_type: content-type string
*
- * Set the content-md5 field of the MIME part.
+ * Set the content-type on a MIME part.
**/
void
-camel_mime_part_set_content_md5 (CamelMimePart *mime_part,
- const gchar *content_md5)
+camel_mime_part_set_content_type (CamelMimePart *mime_part,
+ const gchar *content_type)
{
CamelMedium *medium;
@@ -1088,93 +1188,107 @@ camel_mime_part_set_content_md5 (CamelMimePart *mime_part,
medium = CAMEL_MEDIUM (mime_part);
- camel_medium_set_header (medium, "Content-MD5", content_md5);
+ camel_medium_set_header (medium, "Content-Type", content_type);
}
/**
- * camel_mime_part_get_content_md5:
- * @mime_part: a #CamelMimePart object
+ * camel_mime_part_get_description:
+ * @mime_part: a #CamelMimePart
*
- * Get the content-md5 field of the MIME part.
+ * Get the description of the MIME part.
*
- * Returns: the content-md5 field of the MIME part
+ * Returns: the description
**/
const gchar *
-camel_mime_part_get_content_md5 (CamelMimePart *mime_part)
+camel_mime_part_get_description (CamelMimePart *mime_part)
{
g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
- return mime_part->priv->content_md5;
+ return mime_part->priv->description;
}
-/* **** Content-Location: */
-
/**
- * camel_mime_part_set_content_location:
- * @mime_part: a #CamelMimePart object
- * @location: the content-location value of the MIME part
+ * camel_mime_part_set_description:
+ * @mime_part: a #CamelMimePart
+ * @description: description of the MIME part
*
- * Set the content-location field of the MIME part.
+ * Set a description on the MIME part.
**/
void
-camel_mime_part_set_content_location (CamelMimePart *mime_part,
- const gchar *location)
+camel_mime_part_set_description (CamelMimePart *mime_part,
+ const gchar *description)
{
CamelMedium *medium;
+ gchar *text;
g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
+ g_return_if_fail (description != NULL);
medium = CAMEL_MEDIUM (mime_part);
- /* FIXME: this should perform content-location folding */
- camel_medium_set_header (medium, "Content-Location", location);
+ text = camel_header_encode_string ((guchar *) description);
+ camel_medium_set_header (medium, "Content-Description", text);
+ g_free (text);
- g_object_notify (G_OBJECT (mime_part), "content-location");
+ g_object_notify (G_OBJECT (mime_part), "description");
}
/**
- * camel_mime_part_get_content_location:
- * @mime_part: a #CamelMimePart object
+ * camel_mime_part_get_disposition:
+ * @mime_part: a #CamelMimePart
*
- * Get the content-location field of a MIME part.
+ * Get the disposition of the MIME part.
*
- * Returns: the content-location field of a MIME part
+ * Returns: the disposition
**/
const gchar *
-camel_mime_part_get_content_location (CamelMimePart *mime_part)
+camel_mime_part_get_disposition (CamelMimePart *mime_part)
{
g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
- return mime_part->priv->content_location;
+ if (mime_part->priv->disposition)
+ return mime_part->priv->disposition->disposition;
+ else
+ return NULL;
}
-/* **** Content-Transfer-Encoding: */
-
/**
- * camel_mime_part_set_encoding:
- * @mime_part: a #CamelMimePart object
- * @encoding: a #CamelTransferEncoding
+ * camel_mime_part_set_disposition:
+ * @mime_part: a #CamelMimePart
+ * @disposition: disposition of the MIME part
*
- * Set the Content-Transfer-Encoding to use on a MIME part.
+ * Set a disposition on the MIME part.
**/
void
-camel_mime_part_set_encoding (CamelMimePart *mime_part,
- CamelTransferEncoding encoding)
+camel_mime_part_set_disposition (CamelMimePart *mime_part,
+ const gchar *disposition)
{
CamelMedium *medium;
- const gchar *text;
+ gchar *text;
g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
medium = CAMEL_MEDIUM (mime_part);
- text = camel_transfer_encoding_to_string (encoding);
- camel_medium_set_header (medium, "Content-Transfer-Encoding", text);
+ /* we poke in a new disposition (so we dont lose 'filename', etc) */
+ if (mime_part->priv->disposition == NULL)
+ mime_part_set_disposition (mime_part, disposition);
+
+ if (mime_part->priv->disposition != NULL) {
+ g_free (mime_part->priv->disposition->disposition);
+ mime_part->priv->disposition->disposition = g_strdup (disposition);
+ }
+
+ text = camel_content_disposition_format (mime_part->priv->disposition);
+ camel_medium_set_header (medium, "Content-Disposition", text);
+ g_free (text);
+
+ g_object_notify (G_OBJECT (mime_part), "disposition");
}
/**
* camel_mime_part_get_encoding:
- * @mime_part: a #CamelMimePart object
+ * @mime_part: a #CamelMimePart
*
* Get the Content-Transfer-Encoding of a MIME part.
*
@@ -1190,193 +1304,185 @@ camel_mime_part_get_encoding (CamelMimePart *mime_part)
return mime_part->priv->encoding;
}
-/* FIXME: do something with this stuff ... */
-
/**
- * camel_mime_part_set_content_languages:
- * @mime_part: a #CamelMimePart object
- * @content_languages: list of languages
+ * camel_mime_part_set_encoding:
+ * @mime_part: a #CamelMimePart
+ * @encoding: a #CamelTransferEncoding
*
- * Set the Content-Languages field of a MIME part.
+ * Set the Content-Transfer-Encoding to use on a MIME part.
**/
void
-camel_mime_part_set_content_languages (CamelMimePart *mime_part,
- GList *content_languages)
+camel_mime_part_set_encoding (CamelMimePart *mime_part,
+ CamelTransferEncoding encoding)
{
- g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
+ CamelMedium *medium;
+ const gchar *text;
- if (mime_part->priv->content_languages)
- camel_string_list_free (mime_part->priv->content_languages);
+ g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
- mime_part->priv->content_languages = content_languages;
+ medium = CAMEL_MEDIUM (mime_part);
- /* FIXME: translate to a header and set it */
+ text = camel_transfer_encoding_to_string (encoding);
+ camel_medium_set_header (medium, "Content-Transfer-Encoding", text);
}
/**
- * camel_mime_part_get_content_languages:
- * @mime_part: a #CamelMimePart object
+ * camel_mime_part_get_filename:
+ * @mime_part: a #CamelMimePart
*
- * Get the Content-Languages set on the MIME part.
+ * Get the filename of a MIME part.
*
- * Returns: a #GList of languages
+ * Returns: the filename of the MIME part
**/
-const GList *
-camel_mime_part_get_content_languages (CamelMimePart *mime_part)
+const gchar *
+camel_mime_part_get_filename (CamelMimePart *mime_part)
{
- g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
+ if (mime_part->priv->disposition) {
+ const gchar *name = camel_header_param (
+ mime_part->priv->disposition->params, "filename");
+ if (name)
+ return name;
+ }
- return mime_part->priv->content_languages;
+ return camel_content_type_param (
+ ((CamelDataWrapper *) mime_part)->mime_type, "name");
}
-/* **** */
-
-/* **** Content-Type: */
-
/**
- * camel_mime_part_set_content_type:
- * @mime_part: a #CamelMimePart object
- * @content_type: content-type string
+ * camel_mime_part_set_filename:
+ * @mime_part: a #CamelMimePart
+ * @filename: filename given to the MIME part
*
- * Set the content-type on a MIME part.
+ * Set the filename on a MIME part.
**/
void
-camel_mime_part_set_content_type (CamelMimePart *mime_part,
- const gchar *content_type)
+camel_mime_part_set_filename (CamelMimePart *mime_part,
+ const gchar *filename)
{
+ CamelDataWrapper *dw;
CamelMedium *medium;
-
- g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
+ gchar *str;
medium = CAMEL_MEDIUM (mime_part);
- camel_medium_set_header (medium, "Content-Type", content_type);
-}
+ if (mime_part->priv->disposition == NULL)
+ mime_part->priv->disposition =
+ camel_content_disposition_decode("attachment");
-/**
- * camel_mime_part_get_content_type:
- * @mime_part: a #CamelMimePart object
- *
- * Get the Content-Type of a MIME part.
- *
- * Returns: the parsed #CamelContentType of the MIME part
- **/
-CamelContentType *
-camel_mime_part_get_content_type (CamelMimePart *mime_part)
-{
- g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
+ camel_header_set_param (
+ &mime_part->priv->disposition->params, "filename", filename);
+ str = camel_content_disposition_format (mime_part->priv->disposition);
+
+ camel_medium_set_header (medium, "Content-Disposition", str);
+ g_free (str);
- return camel_data_wrapper_get_mime_type_field ((CamelDataWrapper *) mime_part);
+ dw = (CamelDataWrapper *) mime_part;
+ if (!dw->mime_type)
+ dw->mime_type = camel_content_type_new ("application", "octet-stream");
+ camel_content_type_set_param (dw->mime_type, "name", filename);
+ str = camel_content_type_format (dw->mime_type);
+ camel_medium_set_header (medium, "Content-Type", str);
+ g_free (str);
}
/**
* camel_mime_part_construct_from_parser_sync:
- * @mime_part: a #CamelMimePart object
- * @parser: a #CamelMimeParser object
+ * @mime_part: a #CamelMimePart
+ * @parser: a #CamelMimeParser
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
* Constructs a MIME part from a parser.
*
- * Returns: %0 on success or %-1 on fail
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
-gint
+gboolean
camel_mime_part_construct_from_parser_sync (CamelMimePart *mime_part,
- CamelMimeParser *mp,
+ CamelMimeParser *parser,
GCancellable *cancellable,
GError **error)
{
CamelMimePartClass *class;
- gint retval;
+ gboolean success;
g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), -1);
- g_return_val_if_fail (CAMEL_IS_MIME_PARSER (mp), -1);
+ g_return_val_if_fail (CAMEL_IS_MIME_PARSER (parser), -1);
class = CAMEL_MIME_PART_GET_CLASS (mime_part);
g_return_val_if_fail (class->construct_from_parser_sync != NULL, -1);
- retval = class->construct_from_parser_sync (
- mime_part, mp, cancellable, error);
+ success = class->construct_from_parser_sync (
+ mime_part, parser, cancellable, error);
CAMEL_CHECK_GERROR (
- mime_part, construct_from_parser_sync, retval == 0, error);
+ mime_part, construct_from_parser_sync, success, error);
- return retval;
+ return success;
}
/**
- * camel_mime_part_new:
+ * camel_mime_part_construct_from_parser:
+ * @mime_part: a #CamelMimePart
+ * @parser: a #CamelMimeParser
+ * @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
*
- * Create a new MIME part.
+ * Asynchronously constructs a MIME part from a parser.
*
- * Returns: a new #CamelMimePart object
- **/
-CamelMimePart *
-camel_mime_part_new (void)
-{
- return g_object_new (CAMEL_TYPE_MIME_PART, NULL);
-}
-
-/**
- * camel_mime_part_set_content:
- * @mime_part: a #CamelMimePart object
- * @data: data to put into the part
- * @length: length of @data
- * @type: Content-Type of the data
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_mime_part_construct_from_parser_finish() to get the result of
+ * the operation.
*
- * Utility function used to set the content of a mime part object to
- * be the provided data. If @length is 0, this routine can be used as
- * a way to remove old content (in which case @data and @type are
- * ignored and may be %NULL).
+ * Since: 2.34
**/
void
-camel_mime_part_set_content (CamelMimePart *mime_part,
- const gchar *data, gint length,
- const gchar *type) /* why on earth is the type last? */
+camel_mime_part_construct_from_parser (CamelMimePart *mime_part,
+ CamelMimeParser *parser,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- CamelMedium *medium = CAMEL_MEDIUM (mime_part);
+ CamelMimePartClass *class;
- if (length) {
- CamelDataWrapper *dw;
- CamelStream *stream;
+ g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
+ g_return_if_fail (CAMEL_IS_MIME_PARSER (parser));
- dw = camel_data_wrapper_new ();
- camel_data_wrapper_set_mime_type (dw, type);
- stream = camel_stream_mem_new_with_buffer (data, length);
- camel_data_wrapper_construct_from_stream_sync (
- dw, stream, NULL, NULL);
- g_object_unref (stream);
- camel_medium_set_content (medium, dw);
- g_object_unref (dw);
- } else
- camel_medium_set_content (medium, NULL);
+ class = CAMEL_MIME_PART_GET_CLASS (mime_part);
+ g_return_if_fail (class->construct_from_parser != NULL);
+
+ class->construct_from_parser (
+ mime_part, parser, io_priority,
+ cancellable, callback, user_data);
}
/**
- * camel_mime_part_get_content_size:
- * @mime_part: a #CamelMimePart object
+ * camel_mime_part_construct_from_parser_finish:
+ * @mime_part: a #CamelMimePart
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
*
- * Get the decoded size of the MIME part's content.
+ * Finishes the operation started with camel_mime_part_construct_from_parser().
*
- * Returns: the size of the MIME part's content in bytes.
+ * Returns: %TRUE on success, %FALSE on error
*
- * Since: 2.22
+ * Since: 2.34
**/
-gsize
-camel_mime_part_get_content_size (CamelMimePart *mime_part)
+gboolean
+camel_mime_part_construct_from_parser_finish (CamelMimePart *mime_part,
+ GAsyncResult *result,
+ GError **error)
{
- CamelStream *null;
- CamelDataWrapper *dw;
- gsize size;
-
- g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), 0);
-
- dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
+ CamelMimePartClass *class;
- null = camel_stream_null_new ();
- camel_data_wrapper_decode_to_stream_sync (dw, null, NULL, NULL);
- size = CAMEL_STREAM_NULL (null)->written;
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
- g_object_unref (null);
+ class = CAMEL_MIME_PART_GET_CLASS (mime_part);
+ g_return_val_if_fail (class->construct_from_parser_finish != NULL, FALSE);
- return size;
+ return class->construct_from_parser_finish (mime_part, result, error);
}
diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h
index 748a31b8e..89b0dc110 100644
--- a/camel/camel-mime-part.h
+++ b/camel/camel-mime-part.h
@@ -69,10 +69,25 @@ struct _CamelMimePart {
struct _CamelMimePartClass {
CamelMediumClass parent_class;
- gint (*construct_from_parser_sync) (CamelMimePart *mime_part,
+ /* Synchronous I/O Methods */
+ gboolean (*construct_from_parser_sync)
+ (CamelMimePart *mime_part,
CamelMimeParser *parser,
GCancellable *cancellable,
GError **error);
+
+ /* Asynchronous I/O Methods (all have defaults) */
+ void (*construct_from_parser)
+ (CamelMimePart *mime_part,
+ CamelMimeParser *parser,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*construct_from_parser_finish)
+ (CamelMimePart *mime_part,
+ GAsyncResult *result,
+ GError **error);
};
GType camel_mime_part_get_type (void);
@@ -119,13 +134,23 @@ void camel_mime_part_set_content (CamelMimePart *mime_part,
const gchar *data,
gint length,
const gchar *type);
-gsize camel_mime_part_get_content_size
- (CamelMimePart *mime_part);
-gint camel_mime_part_construct_from_parser_sync
+
+gboolean camel_mime_part_construct_from_parser_sync
(CamelMimePart *mime_part,
CamelMimeParser *parser,
GCancellable *cancellable,
GError **error);
+void camel_mime_part_construct_from_parser
+ (CamelMimePart *mime_part,
+ CamelMimeParser *parser,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_mime_part_construct_from_parser_finish
+ (CamelMimePart *mime_part,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/camel/camel-multipart-signed.c b/camel/camel-multipart-signed.c
index 21968fb91..1affe87a9 100644
--- a/camel/camel-multipart-signed.c
+++ b/camel/camel-multipart-signed.c
@@ -359,7 +359,7 @@ file_error:
return -1;
}
-static gint
+static gboolean
multipart_signed_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
CamelStream *stream,
GCancellable *cancellable,
@@ -370,11 +370,11 @@ multipart_signed_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
if (camel_stream_write_to_stream (
stream, mem, cancellable, error) == -1)
- return -1;
+ return FALSE;
multipart_signed_set_stream (mps, mem);
- return 0;
+ return TRUE;
}
static void
diff --git a/camel/camel-net-utils.c b/camel/camel-net-utils.c
index 6769285cd..13d3b973e 100644
--- a/camel/camel-net-utils.c
+++ b/camel/camel-net-utils.c
@@ -691,7 +691,7 @@ camel_getaddrinfo (const gchar *name,
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return NULL;
- camel_operation_start_transient (
+ camel_operation_push_message (
cancellable, _("Resolving: %s"), name);
/* force ipv4 addresses only */
@@ -729,7 +729,7 @@ camel_getaddrinfo (const gchar *name,
cs_freeinfo (msg);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return res;
}
@@ -841,7 +841,7 @@ camel_getnameinfo (const struct sockaddr *sa,
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return -1;
- camel_operation_start_transient (
+ camel_operation_push_message (
cancellable, _("Resolving address"));
msg = g_malloc0 (sizeof (*msg));
@@ -879,7 +879,7 @@ camel_getnameinfo (const struct sockaddr *sa,
cs_freeinfo (msg);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return result;
}
diff --git a/camel/camel-offline-folder.c b/camel/camel-offline-folder.c
index 73338f696..7e755d264 100644
--- a/camel/camel-offline-folder.c
+++ b/camel/camel-offline-folder.c
@@ -37,10 +37,17 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), CAMEL_TYPE_OFFLINE_FOLDER, CamelOfflineFolderPrivate))
+typedef struct _AsyncContext AsyncContext;
+
struct _CamelOfflineFolderPrivate {
gboolean offline_sync;
};
+struct _AsyncContext {
+ /* arguments */
+ gchar *expression;
+};
+
struct _offline_downsync_msg {
CamelSessionThreadMsg msg;
@@ -58,12 +65,20 @@ enum {
G_DEFINE_TYPE (CamelOfflineFolder, camel_offline_folder, CAMEL_TYPE_FOLDER)
static void
+async_context_free (AsyncContext *async_context)
+{
+ g_free (async_context->expression);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
offline_downsync_sync (CamelSession *session, CamelSessionThreadMsg *mm)
{
struct _offline_downsync_msg *m = (struct _offline_downsync_msg *) mm;
gint i;
- camel_operation_start (
+ camel_operation_push_message (
mm->cancellable,
_("Downloading new messages for offline mode"));
@@ -84,7 +99,7 @@ offline_downsync_sync (CamelSession *session, CamelSessionThreadMsg *mm)
"(match-all)", NULL, &mm->error);
}
- camel_operation_end (mm->cancellable);
+ camel_operation_pop_message (mm->cancellable);
}
static void
@@ -174,7 +189,7 @@ offline_folder_downsync_sync (CamelOfflineFolder *offline,
GPtrArray *uids, *uncached_uids = NULL;
gint i;
- camel_operation_start (
+ camel_operation_push_message (
cancellable, _("Syncing messages in folder '%s' to disk"),
camel_folder_get_full_name (folder));
@@ -207,12 +222,77 @@ done:
if (uncached_uids)
camel_folder_free_uids (folder, uncached_uids);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return TRUE;
}
static void
+offline_folder_downsync_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_offline_folder_downsync_sync (
+ CAMEL_OFFLINE_FOLDER (object), async_context->expression,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+offline_folder_downsync (CamelOfflineFolder *folder,
+ const gchar *expression,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->expression = g_strdup (expression);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (folder), callback,
+ user_data, offline_folder_downsync);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, offline_folder_downsync_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+offline_folder_downsync_finish (CamelOfflineFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (folder), offline_folder_downsync), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
camel_offline_folder_class_init (CamelOfflineFolderClass *class)
{
GObjectClass *object_class;
@@ -224,6 +304,8 @@ camel_offline_folder_class_init (CamelOfflineFolderClass *class)
object_class->get_property = offline_folder_get_property;
class->downsync_sync = offline_folder_downsync_sync;
+ class->downsync = offline_folder_downsync;
+ class->downsync_finish = offline_folder_downsync_finish;
g_object_class_install_property (
object_class,
@@ -249,51 +331,53 @@ camel_offline_folder_init (CamelOfflineFolder *folder)
/**
* camel_offline_folder_get_offline_sync:
- * @offline_folder: a #CamelOfflineFolder
+ * @folder: a #CamelOfflineFolder
*
* Since: 2.32
**/
gboolean
-camel_offline_folder_get_offline_sync (CamelOfflineFolder *offline_folder)
+camel_offline_folder_get_offline_sync (CamelOfflineFolder *folder)
{
- g_return_val_if_fail (CAMEL_IS_OFFLINE_FOLDER (offline_folder), FALSE);
+ g_return_val_if_fail (CAMEL_IS_OFFLINE_FOLDER (folder), FALSE);
- return offline_folder->priv->offline_sync;
+ return folder->priv->offline_sync;
}
/**
* camel_offline_folder_set_offline_sync:
- * @offline_folder: a #CamelOfflineFolder
+ * @folder: a #CamelOfflineFolder
* @offline_sync: whether to synchronize for offline use
*
* Since: 2.32
**/
void
-camel_offline_folder_set_offline_sync (CamelOfflineFolder *offline_folder,
+camel_offline_folder_set_offline_sync (CamelOfflineFolder *folder,
gboolean offline_sync)
{
- g_return_if_fail (CAMEL_IS_OFFLINE_FOLDER (offline_folder));
+ g_return_if_fail (CAMEL_IS_OFFLINE_FOLDER (folder));
- offline_folder->priv->offline_sync = offline_sync;
+ folder->priv->offline_sync = offline_sync;
- g_object_notify (G_OBJECT (offline_folder), "offline-sync");
+ g_object_notify (G_OBJECT (folder), "offline-sync");
}
/**
* camel_offline_folder_downsync_sync:
- * @offline: a #CamelOfflineFolder object
+ * @folder: a #CamelOfflineFolder
* @expression: search expression describing which set of messages
* to downsync (%NULL for all)
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
- * Syncs messages in @offline described by the search @expression to
+ * Synchronizes messages in @folder described by the search @expression to
* the local machine for offline availability.
*
- * Returns: %TRUE on success, %FALSE on failure
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
gboolean
-camel_offline_folder_downsync_sync (CamelOfflineFolder *offline,
+camel_offline_folder_downsync_sync (CamelOfflineFolder *folder,
const gchar *expression,
GCancellable *cancellable,
GError **error)
@@ -301,14 +385,81 @@ camel_offline_folder_downsync_sync (CamelOfflineFolder *offline,
CamelOfflineFolderClass *class;
gboolean success;
- g_return_val_if_fail (CAMEL_IS_OFFLINE_FOLDER (offline), FALSE);
+ g_return_val_if_fail (CAMEL_IS_OFFLINE_FOLDER (folder), FALSE);
- class = CAMEL_OFFLINE_FOLDER_GET_CLASS (offline);
+ class = CAMEL_OFFLINE_FOLDER_GET_CLASS (folder);
g_return_val_if_fail (class->downsync_sync != NULL, FALSE);
success = class->downsync_sync (
- offline, expression, cancellable, error);
- CAMEL_CHECK_GERROR (offline, downsync_sync, success, error);
+ folder, expression, cancellable, error);
+ CAMEL_CHECK_GERROR (folder, downsync_sync, success, error);
return success;
}
+
+/**
+ * camel_offline_folder_downsync:
+ * @folder: a #CamelOfflineFolder
+ * @expression: search expression describing which set of messages
+ * to downsync (%NULL for all)
+ * @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
+ *
+ * Synchronizes messages in @folder described by the search @expression to
+ * the local machine asynchronously for offline availability.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_offline_folder_downsync_finish() to get the result of the
+ * operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_offline_folder_downsync (CamelOfflineFolder *folder,
+ const gchar *expression,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelOfflineFolderClass *class;
+
+ g_return_if_fail (CAMEL_IS_OFFLINE_FOLDER (folder));
+
+ class = CAMEL_OFFLINE_FOLDER_GET_CLASS (folder);
+ g_return_if_fail (class->downsync != NULL);
+
+ class->downsync (
+ folder, expression, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_offline_folder_downsync_finish:
+ * @folder: a #CamelOfflineFolder
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_offline_folder_downsync().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_offline_folder_downsync_finish (CamelOfflineFolder *folder,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelOfflineFolderClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_OFFLINE_FOLDER (folder), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_OFFLINE_FOLDER_GET_CLASS (folder);
+ g_return_val_if_fail (class->downsync_finish != NULL, FALSE);
+
+ return class->downsync_finish (folder, result, error);
+}
diff --git a/camel/camel-offline-folder.h b/camel/camel-offline-folder.h
index d3ca48caa..977e7696a 100644
--- a/camel/camel-offline-folder.h
+++ b/camel/camel-offline-folder.h
@@ -62,22 +62,45 @@ struct _CamelOfflineFolder {
struct _CamelOfflineFolderClass {
CamelFolderClass parent_class;
+ /* Synchronous I/O Methods */
gboolean (*downsync_sync) (CamelOfflineFolder *folder,
const gchar *expression,
GCancellable *cancellable,
GError **error);
+
+ /* Asynchronous I/O Methods (all have defaults) */
+ void (*downsync) (CamelOfflineFolder *folder,
+ const gchar *expression,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*downsync_finish) (CamelOfflineFolder *folder,
+ GAsyncResult *result,
+ GError **error);
};
GType camel_offline_folder_get_type (void);
gboolean camel_offline_folder_get_offline_sync
- (CamelOfflineFolder *offline);
+ (CamelOfflineFolder *folder);
void camel_offline_folder_set_offline_sync
- (CamelOfflineFolder *offline,
+ (CamelOfflineFolder *folder,
gboolean offline_sync);
+
gboolean camel_offline_folder_downsync_sync
- (CamelOfflineFolder *offline,
+ (CamelOfflineFolder *folder,
+ const gchar *expression,
+ GCancellable *cancellable,
+ GError **error);
+void camel_offline_folder_downsync (CamelOfflineFolder *folder,
const gchar *expression,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_offline_folder_downsync_finish
+ (CamelOfflineFolder *folder,
+ GAsyncResult *result,
GError **error);
G_END_DECLS
diff --git a/camel/camel-operation.c b/camel/camel-operation.c
index 82c698957..f00c92b91 100644
--- a/camel/camel-operation.c
+++ b/camel/camel-operation.c
@@ -38,20 +38,13 @@
typedef struct _StatusNode StatusNode;
struct _StatusNode {
- gboolean transient;
- gchar *msg;
- gint pc; /* last percentage reported */
- guint stamp; /* last time stamp reported */
+ CamelOperation *operation;
+ guint source_id; /* for timeout or idle */
+ gchar *message;
+ gint percent;
};
struct _CamelOperationPrivate {
- guint status_idle_id;
-
- /* For the next 'status' signal. */
- gchar *status_msg;
- gint status_pc;
-
- guint status_update;
GQueue status_stack;
@@ -66,9 +59,6 @@ enum {
LAST_SIGNAL
};
-/* Delay before a transient operation has any effect on the status */
-#define CAMEL_OPERATION_TRANSIENT_DELAY (5)
-
static GStaticRecMutex operation_lock = G_STATIC_REC_MUTEX_INIT;
#define LOCK() g_static_rec_mutex_lock (&operation_lock)
#define UNLOCK() g_static_rec_mutex_unlock (&operation_lock)
@@ -79,85 +69,56 @@ static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE (CamelOperation, camel_operation, G_TYPE_CANCELLABLE)
-static StatusNode *
-status_node_new (CamelOperation *operation)
-{
- StatusNode *node;
-
- node = g_slice_new0 (StatusNode);
- g_queue_push_head (&operation->priv->status_stack, node);
-
- return node;
-}
-
static void
status_node_free (StatusNode *node)
{
- g_free (node->msg);
- g_slice_free (StatusNode, node);
-}
+ g_free (node->message);
-static guint
-stamp (void)
-{
- GTimeVal tv;
+ if (node->source_id > 0)
+ g_source_remove (node->source_id);
- g_get_current_time (&tv);
- /* update 4 times/second */
- return (tv.tv_sec * 4) + tv.tv_usec / (1000000/4);
+ g_slice_free (StatusNode, node);
}
static gboolean
-operation_idle_cb (CamelOperation *operation)
+operation_emit_status_cb (StatusNode *node)
{
- gchar *msg;
- gint pc;
+ StatusNode *head_node;
+ gchar *message = NULL;
+ gint percent = 0;
/* Keep the operation alive until we emit the signal,
* otherwise it might be finalized between unlocking
* the mutex and emitting the signal. */
- g_object_ref (operation);
+ g_object_ref (node->operation);
LOCK ();
- msg = operation->priv->status_msg;
- operation->priv->status_msg = NULL;
+ node->source_id = 0;
- pc = operation->priv->status_pc;
+ head_node = g_queue_peek_head (&node->operation->priv->status_stack);
- operation->priv->status_idle_id = 0;
+ if (node == head_node) {
+ message = g_strdup (node->message);
+ percent = node->percent;
+ }
UNLOCK ();
- if (msg != NULL) {
- g_signal_emit (operation, signals[STATUS], 0, msg, pc);
- g_free (msg);
+ if (message != NULL) {
+ g_signal_emit (
+ node->operation,
+ signals[STATUS], 0,
+ message, percent);
+ g_free (message);
}
- g_object_unref (operation);
+ g_object_unref (node->operation);
return FALSE;
}
static void
-operation_queue_status_update (CamelOperation *operation,
- StatusNode *node)
-{
- LOCK ();
-
- if (operation->priv->status_idle_id == 0)
- operation->priv->status_idle_id = g_idle_add (
- (GSourceFunc) operation_idle_cb, operation);
-
- g_free (operation->priv->status_msg);
- operation->priv->status_msg = g_strdup (node->msg);
-
- operation->priv->status_pc = node->pc;
-
- UNLOCK ();
-}
-
-static void
operation_flush_msgport (CamelOperation *operation)
{
CamelOperationPrivate *priv = operation->priv;
@@ -183,16 +144,13 @@ operation_finalize (GObject *object)
g_queue_remove (&operation_list, object);
- if (priv->status_idle_id > 0)
- g_source_remove (priv->status_idle_id);
-
operation_flush_msgport (CAMEL_OPERATION (object));
camel_msgport_destroy (priv->cancel_port);
while ((node = g_queue_pop_head (&priv->status_stack)) != NULL) {
g_warning (
"CamelOperation status stack non-empty: %s",
- node->msg);
+ node->message);
status_node_free (node);
}
@@ -398,24 +356,24 @@ camel_operation_cancel_prfd (CamelOperation *operation)
#endif /* CAMEL_HAVE_NSS */
/**
- * camel_operation_start:
+ * camel_operation_push_message:
* @cancellable: a #GCancellable or %NULL
- * @what: action being performed (printf-style format string)
- * @Varargs: varargs
+ * @format: a standard printf() format string
+ * @Varargs: the parameters to insert into the format string
*
- * Report the start of an operation. All start operations should have
- * similar end operations.
+ * Call this function to describe an operation being performed.
+ * Call camel_operation_progress() to report progress on the operation.
+ * Call camel_operation_pop_message() when the operation is complete.
*
* This function only works if @cancellable is a #CamelOperation cast as a
* #GCancellable. If @cancellable is a plain #GCancellable or %NULL, the
* function does nothing and returns silently.
**/
void
-camel_operation_start (GCancellable *cancellable,
- const gchar *what, ...)
+camel_operation_push_message (GCancellable *cancellable,
+ const gchar *format, ...)
{
CamelOperation *operation;
- const guint signal_id = signals[STATUS];
StatusNode *node;
va_list ap;
@@ -427,48 +385,45 @@ camel_operation_start (GCancellable *cancellable,
g_return_if_fail (CAMEL_IS_OPERATION (cancellable));
- if (!g_signal_has_handler_pending (cancellable, signal_id, 0, TRUE))
- return;
-
LOCK ();
operation = CAMEL_OPERATION (cancellable);
- operation->priv->status_update = 0;
+ va_start (ap, format);
- va_start (ap, what);
+ node = g_slice_new0 (StatusNode);
+ node->message = g_strdup_vprintf (format, ap);
+ node->operation = operation; /* not referenced */
- node = status_node_new (operation);
- node->msg = g_strdup_vprintf (what, ap);
+ if (g_queue_is_empty (&operation->priv->status_stack))
+ node->source_id = g_idle_add (
+ (GSourceFunc) operation_emit_status_cb, node);
+ else
+ node->source_id = g_timeout_add_seconds (
+ 4, (GSourceFunc) operation_emit_status_cb, node);
- va_end (ap);
+ g_queue_push_head (&operation->priv->status_stack, node);
- operation_queue_status_update (operation, node);
+ va_end (ap);
UNLOCK ();
}
/**
- * camel_operation_start_transient:
- * @cancellable: a #GCancellable or %NULL
- * @what: printf-style format string describing the action being performed
- * @Varargs: varargs
+ * camel_operation_pop_message:
+ * @cancellable: a #GCancellable
*
- * Start a transient event. We only update this to the display if it
- * takes very long to process, and if we do, we then go back to the
- * previous state when finished.
+ * Pops the most recently pushed message.
*
* This function only works if @cancellable is a #CamelOperation cast as a
* #GCancellable. If @cancellable is a plain #GCancellable or %NULL, the
* function does nothing and returns silently.
**/
void
-camel_operation_start_transient (GCancellable *cancellable,
- const gchar *what, ...)
+camel_operation_pop_message (GCancellable *cancellable)
{
CamelOperation *operation;
StatusNode *node;
- va_list ap;
if (cancellable == NULL)
return;
@@ -481,17 +436,16 @@ camel_operation_start_transient (GCancellable *cancellable,
LOCK ();
operation = CAMEL_OPERATION (cancellable);
+ node = g_queue_pop_head (&operation->priv->status_stack);
- operation->priv->status_update = 0;
+ if (node != NULL)
+ status_node_free (node);
- va_start (ap, what);
+ node = g_queue_peek_head (&operation->priv->status_stack);
- node = status_node_new (operation);
- node->msg = g_strdup_vprintf (what, ap);
- node->stamp = stamp ();
- node->transient = TRUE;
-
- va_end (ap);
+ if (node != NULL && node->source_id == 0)
+ node->source_id = g_idle_add (
+ (GSourceFunc) operation_emit_status_cb, node);
UNLOCK ();
}
@@ -499,9 +453,9 @@ camel_operation_start_transient (GCancellable *cancellable,
/**
* camel_operation_progress:
* @cancellable: a #GCancellable or %NULL
- * @pc: percent complete, 0 to 100.
+ * @percent: percent complete, 0 to 100.
*
- * Report progress on the current operation. @pc reports the current
+ * Report progress on the current operation. @percent reports the current
* percentage of completion, which should be in the range of 0 to 100.
*
* This function only works if @cancellable is a #CamelOperation cast as a
@@ -510,12 +464,9 @@ camel_operation_start_transient (GCancellable *cancellable,
**/
void
camel_operation_progress (GCancellable *cancellable,
- gint pc)
+ gint percent)
{
CamelOperation *operation;
- const guint signal_id = signals[STATUS];
- CamelOperationPrivate *priv;
- guint now;
StatusNode *node;
if (cancellable == NULL)
@@ -526,83 +477,21 @@ camel_operation_progress (GCancellable *cancellable,
g_return_if_fail (CAMEL_IS_OPERATION (cancellable));
- if (!g_signal_has_handler_pending (cancellable, signal_id, 0, TRUE))
- return;
-
LOCK ();
operation = CAMEL_OPERATION (cancellable);
- priv = operation->priv;
+ node = g_queue_peek_head (&operation->priv->status_stack);
- if (g_queue_is_empty (&priv->status_stack)) {
- UNLOCK ();
- return;
- }
+ if (node != NULL) {
+ node->percent = percent;
- node = g_queue_peek_head (&priv->status_stack);
- node->pc = pc;
-
- /* Transient messages dont start updating till 4 seconds after
- they started, then they update every second */
- now = stamp ();
- if (priv->status_update == now) {
- operation = NULL;
- } else if (node->transient) {
- if (node->stamp + CAMEL_OPERATION_TRANSIENT_DELAY > now) {
- operation = NULL;
- } else {
- priv->status_update = now;
- }
- } else {
- node->stamp = priv->status_update = now;
+ /* Rate limit progress updates. */
+ if (node->source_id == 0)
+ node->source_id = g_timeout_add (
+ 250, (GSourceFunc)
+ operation_emit_status_cb, node);
}
- if (operation != NULL)
- operation_queue_status_update (operation, node);
-
UNLOCK ();
}
-/**
- * camel_operation_end:
- * @cancellable: a #GCancellable
- *
- * Report the end of an operation.
- *
- * This function only works if @cancellable is a #CamelOperation cast as a
- * #GCancellable. If @cancellable is a plain #GCancellable or %NULL, the
- * function does nothing and returns silently.
- **/
-void
-camel_operation_end (GCancellable *cancellable)
-{
- CamelOperation *operation;
- const guint signal_id = signals[STATUS];
- GQueue *status_stack;
- StatusNode *node;
-
- if (cancellable == NULL)
- return;
-
- if (G_OBJECT_TYPE (cancellable) == G_TYPE_CANCELLABLE)
- return;
-
- g_return_if_fail (CAMEL_IS_OPERATION (cancellable));
-
- if (!g_signal_has_handler_pending (cancellable, signal_id, 0, TRUE))
- return;
-
- LOCK ();
-
- operation = CAMEL_OPERATION (cancellable);
-
- status_stack = &operation->priv->status_stack;
-
- if ((node = g_queue_pop_head (status_stack)) != NULL) {
- node->pc = 100;
- operation_queue_status_update (operation, node);
- status_node_free (node);
- }
-
- UNLOCK ();
-}
diff --git a/camel/camel-operation.h b/camel/camel-operation.h
index 6b6b54995..7cdec8e72 100644
--- a/camel/camel-operation.h
+++ b/camel/camel-operation.h
@@ -84,15 +84,12 @@ struct PRFileDesc *
* a GCancellable pointer and just return silently if the pointer is
* NULL or the pointed to object actually is a plain GCancellable. */
-void camel_operation_start (GCancellable *cancellable,
- const gchar *what,
- ...) G_GNUC_PRINTF (2, 3);
-void camel_operation_start_transient (GCancellable *cancellable,
- const gchar *what,
+void camel_operation_push_message (GCancellable *cancellable,
+ const gchar *format,
...) G_GNUC_PRINTF (2, 3);
+void camel_operation_pop_message (GCancellable *cancellable);
void camel_operation_progress (GCancellable *cancellable,
- gint pc);
-void camel_operation_end (GCancellable *cancellable);
+ gint percent);
G_END_DECLS
diff --git a/camel/camel-sasl.c b/camel/camel-sasl.c
index 496660263..de82c55d4 100644
--- a/camel/camel-sasl.c
+++ b/camel/camel-sasl.c
@@ -44,6 +44,8 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), CAMEL_TYPE_SASL, CamelSaslPrivate))
+typedef struct _AsyncContext AsyncContext;
+
struct _CamelSaslPrivate {
CamelService *service;
gboolean authenticated;
@@ -51,6 +53,16 @@ struct _CamelSaslPrivate {
gchar *mechanism;
};
+struct _AsyncContext {
+ /* arguments */
+ GByteArray *token;
+ gchar *base64_token;
+
+ /* results */
+ GByteArray *response;
+ gchar *base64_response;
+};
+
enum {
PROP_0,
PROP_AUTHENTICATED,
@@ -62,6 +74,21 @@ enum {
G_DEFINE_ABSTRACT_TYPE (CamelSasl, camel_sasl, CAMEL_TYPE_OBJECT)
static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->token != NULL)
+ g_byte_array_free (async_context->token, TRUE);
+
+ if (async_context->response != NULL)
+ g_byte_array_free (async_context->response, TRUE);
+
+ g_free (async_context->base64_token);
+ g_free (async_context->base64_response);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
sasl_set_mechanism (CamelSasl *sasl,
const gchar *mechanism)
{
@@ -192,6 +219,79 @@ sasl_finalize (GObject *object)
}
static void
+sasl_challenge_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->response = camel_sasl_challenge_sync (
+ CAMEL_SASL (object), async_context->token,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+sasl_challenge (CamelSasl *sasl,
+ GByteArray *token,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->token = g_byte_array_new ();
+
+ g_byte_array_append (async_context->token, token->data, token->len);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (sasl), callback, user_data, sasl_challenge);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, sasl_challenge_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static GByteArray *
+sasl_challenge_finish (CamelSasl *sasl,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ GByteArray *response;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (sasl), sasl_challenge), 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;
+
+ response = async_context->response;
+ async_context->response = NULL;
+
+ return response;
+}
+
+static void
camel_sasl_class_init (CamelSaslClass *class)
{
GObjectClass *object_class;
@@ -204,6 +304,9 @@ camel_sasl_class_init (CamelSaslClass *class)
object_class->dispose = sasl_dispose;
object_class->finalize = sasl_finalize;
+ class->challenge = sasl_challenge;
+ class->challenge_finish = sasl_challenge_finish;
+
g_object_class_install_property (
object_class,
PROP_AUTHENTICATED,
@@ -303,7 +406,7 @@ camel_sasl_new (const gchar *service_name,
/**
* camel_sasl_get_authenticated:
- * @sasl: a #CamelSasl object
+ * @sasl: a #CamelSasl
*
* Returns: whether or not @sasl has successfully authenticated the
* user. This will be %TRUE after it returns the last needed response.
@@ -380,16 +483,18 @@ camel_sasl_get_service_name (CamelSasl *sasl)
/**
* camel_sasl_challenge_sync:
- * @sasl: a #CamelSasl object
+ * @sasl: a #CamelSasl
* @token: a token, or %NULL
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
* If @token is %NULL, generate the initial SASL message to send to
- * the server. (This will be %NULL if the client doesn't initiate the
- * exchange.) Otherwise, @token is a challenge from the server, and
+ * the server. (This will be %NULL if the client doesn't initiate the
+ * exchange.) Otherwise, @token is a challenge from the server, and
* the return value is the response.
*
+ * Free the returned #GByteArray with g_byte_array_free().
+ *
* Returns: the SASL response or %NULL. If an error occurred, @error will
* also be set.
**/
@@ -416,16 +521,86 @@ camel_sasl_challenge_sync (CamelSasl *sasl,
}
/**
+ * camel_sasl_challenge:
+ * @sasl: a #CamelSasl
+ * @token: a token, or %NULL
+ * @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
+ *
+ * If @token is %NULL, asynchronously generate the initial SASL message
+ * to send to the server. (This will be %NULL if the client doesn't
+ * initiate the exchange.) Otherwise, @token is a challenge from the
+ * server, and the asynchronous result is the response.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_sasl_challenge_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_sasl_challenge (CamelSasl *sasl,
+ GByteArray *token,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelSaslClass *class;
+
+ g_return_if_fail (CAMEL_IS_SASL (sasl));
+
+ class = CAMEL_SASL_GET_CLASS (sasl);
+ g_return_if_fail (class->challenge != NULL);
+
+ class->challenge (
+ sasl, token, io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * camel_sasl_challenge_finish:
+ * @sasl: a #CamelSasl
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_sasl_challenge(). Free the
+ * returned #GByteArray with g_byte_array_free().
+ *
+ * Returns: the SASL response or %NULL. If an error occurred, @error will
+ * also be set.
+ *
+ * Since: 2.34
+ **/
+GByteArray *
+camel_sasl_challenge_finish (CamelSasl *sasl,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelSaslClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_SASL (sasl), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ class = CAMEL_SASL_GET_CLASS (sasl);
+ g_return_val_if_fail (class->challenge_finish != NULL, NULL);
+
+ return class->challenge_finish (sasl, result, error);
+}
+
+/**
* camel_sasl_challenge_base64_sync:
- * @sasl: a #CamelSasl object
+ * @sasl: a #CamelSasl
* @token: a base64-encoded token
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
- * As with #camel_sasl_challenge, but the challenge @token and the
+ * As with camel_sasl_challenge_sync(), but the challenge @token and the
* response are both base64-encoded.
*
- * Returns: the base64 encoded challenge string
+ * Returns: the base64-encoded response
+ *
+ * Since: 2.34
**/
gchar *
camel_sasl_challenge_base64_sync (CamelSasl *sasl,
@@ -433,12 +608,13 @@ camel_sasl_challenge_base64_sync (CamelSasl *sasl,
GCancellable *cancellable,
GError **error)
{
- GByteArray *token_binary, *ret_binary;
- gchar *ret;
+ GByteArray *token_binary;
+ GByteArray *response_binary;
+ gchar *response;
g_return_val_if_fail (CAMEL_IS_SASL (sasl), NULL);
- if (token && *token) {
+ if (token != NULL && *token != '\0') {
guchar *data;
gsize length = 0;
@@ -449,20 +625,131 @@ camel_sasl_challenge_base64_sync (CamelSasl *sasl,
} else
token_binary = NULL;
- ret_binary = camel_sasl_challenge_sync (
+ response_binary = camel_sasl_challenge_sync (
sasl, token_binary, cancellable, error);
if (token_binary)
g_byte_array_free (token_binary, TRUE);
- if (!ret_binary)
+ if (response_binary == NULL)
return NULL;
- if (ret_binary->len > 0)
- ret = g_base64_encode (ret_binary->data, ret_binary->len);
+ if (response_binary->len > 0)
+ response = g_base64_encode (
+ response_binary->data, response_binary->len);
else
- ret = g_strdup ("");
- g_byte_array_free (ret_binary, TRUE);
+ response = g_strdup ("");
+
+ g_byte_array_free (response_binary, TRUE);
+
+ return response;
+}
+
+/* Helper for camel_sasl_challenge_base64() */
+static void
+sasl_challenge_base64_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->base64_response = camel_sasl_challenge_base64_sync (
+ CAMEL_SASL (object), async_context->base64_token,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+/**
+ * camel_sasl_challenge_base64:
+ * @sasl: a #CamelSasl
+ * @token: a base64-encoded token
+ * @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
+ *
+ * As with camel_sasl_challenge(), but the challenge @token and the
+ * response are both base64-encoded.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_store_challenge_base64_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_sasl_challenge_base64 (CamelSasl *sasl,
+ const gchar *token,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_if_fail (CAMEL_IS_SASL (sasl));
- return ret;
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->base64_token = g_strdup (token);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (sasl), callback, user_data,
+ camel_sasl_challenge_base64);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, sasl_challenge_base64_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+/**
+ * camel_sasl_challenge_base64_finish:
+ * @sasl: a #CamelSasl
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_sasl_challenge_base64().
+ *
+ * Returns: the base64-encoded response
+ *
+ * Since: 2.34
+ **/
+gchar *
+camel_sasl_challenge_base64_finish (CamelSasl *sasl,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ gchar *response;
+
+ g_return_val_if_fail (CAMEL_IS_SASL (sasl), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (sasl), camel_sasl_challenge_base64), 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;
+
+ response = async_context->base64_response;
+ async_context->base64_response = NULL;
+
+ return response;
}
/**
diff --git a/camel/camel-sasl.h b/camel/camel-sasl.h
index 57dc1c816..3bb3a8478 100644
--- a/camel/camel-sasl.h
+++ b/camel/camel-sasl.h
@@ -63,10 +63,22 @@ struct _CamelSasl {
struct _CamelSaslClass {
CamelObjectClass parent_class;
+ /* Synchronous I/O Methods */
GByteArray * (*challenge_sync) (CamelSasl *sasl,
GByteArray *token,
GCancellable *cancellable,
GError **error);
+
+ /* Asynchronous I/O Methods (all have defaults) */
+ void (*challenge) (CamelSasl *sasl,
+ GByteArray *token,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ GByteArray * (*challenge_finish) (CamelSasl *sasl,
+ GAsyncResult *result,
+ GError **error);
};
GType camel_sasl_get_type (void);
@@ -79,15 +91,35 @@ void camel_sasl_set_authenticated (CamelSasl *sasl,
const gchar * camel_sasl_get_mechanism (CamelSasl *sasl);
CamelService * camel_sasl_get_service (CamelSasl *sasl);
const gchar * camel_sasl_get_service_name (CamelSasl *sasl);
+
GByteArray * camel_sasl_challenge_sync (CamelSasl *sasl,
GByteArray *token,
GCancellable *cancellable,
GError **error);
+void camel_sasl_challenge (CamelSasl *sasl,
+ GByteArray *token,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GByteArray * camel_sasl_challenge_finish (CamelSasl *sasl,
+ GAsyncResult *result,
+ GError **error);
gchar * camel_sasl_challenge_base64_sync
(CamelSasl *sasl,
const gchar *token,
GCancellable *cancellable,
GError **error);
+void camel_sasl_challenge_base64 (CamelSasl *sasl,
+ const gchar *token,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gchar * camel_sasl_challenge_base64_finish
+ (CamelSasl *sasl,
+ GAsyncResult *result,
+ GError **error);
GList * camel_sasl_authtype_list (gboolean include_plain);
CamelServiceAuthType *
diff --git a/camel/camel-smime-context.c b/camel/camel-smime-context.c
index 58e81d2f8..309eef19c 100644
--- a/camel/camel-smime-context.c
+++ b/camel/camel-smime-context.c
@@ -759,7 +759,7 @@ get_hash_from_oid (SECOidTag oidTag)
return CAMEL_CIPHER_HASH_DEFAULT;
}
-static gint
+static gboolean
smime_context_sign_sync (CamelCipherContext *context,
const gchar *userid,
CamelCipherHash hash,
@@ -769,7 +769,6 @@ smime_context_sign_sync (CamelCipherContext *context,
GError **error)
{
CamelCipherContextClass *class;
- gint res = -1;
NSSCMSMessage *cmsg;
CamelStream *ostream, *istream;
GByteArray *buffer;
@@ -777,6 +776,7 @@ smime_context_sign_sync (CamelCipherContext *context,
NSSCMSEncoderContext *enc;
CamelDataWrapper *dw;
CamelContentType *ct;
+ gboolean success = FALSE;
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
@@ -846,7 +846,7 @@ smime_context_sign_sync (CamelCipherContext *context,
goto fail;
}
- res = 0;
+ success = TRUE;
dw = camel_data_wrapper_new ();
camel_stream_reset (ostream, NULL);
@@ -872,7 +872,7 @@ smime_context_sign_sync (CamelCipherContext *context,
mps = camel_multipart_signed_new ();
ct = camel_content_type_new ("multipart", "signed");
- camel_content_type_set_param (ct, "micalg", camel_cipher_hash_to_id (context, get_hash_from_oid (sechash)));
+ camel_content_type_set_param (ct, "micalg", camel_cipher_context_hash_to_id (context, get_hash_from_oid (sechash)));
camel_content_type_set_param (ct, "protocol", class->sign_protocol);
camel_data_wrapper_set_mime_type_field ((CamelDataWrapper *)mps, ct);
camel_content_type_unref (ct);
@@ -904,7 +904,7 @@ fail:
g_object_unref (ostream);
g_object_unref (istream);
- return res;
+ return success;
}
static CamelCipherValidity *
@@ -998,7 +998,7 @@ fail:
return valid;
}
-static gint
+static gboolean
smime_context_encrypt_sync (CamelCipherContext *context,
const gchar *userid,
GPtrArray *recipients,
@@ -1029,7 +1029,7 @@ smime_context_encrypt_sync (CamelCipherContext *context,
poolp = PORT_NewArena (1024);
if (poolp == NULL) {
set_nss_error (error, g_strerror (ENOMEM));
- return -1;
+ return FALSE;
}
/* Lookup all recipients certs, for later working */
@@ -1164,7 +1164,7 @@ smime_context_encrypt_sync (CamelCipherContext *context,
camel_mime_part_set_description (opart, "S/MIME Encrypted Message");
camel_mime_part_set_encoding (opart, CAMEL_TRANSFER_ENCODING_BASE64);
- return 0;
+ return TRUE;
fail:
if (ostream)
@@ -1181,7 +1181,7 @@ fail:
PORT_FreeArena (poolp, PR_FALSE);
- return -1;
+ return FALSE;
}
static CamelCipherValidity *
@@ -1207,9 +1207,12 @@ smime_context_decrypt_sync (CamelCipherContext *context,
/* FIXME: stream this to the decoder incrementally */
buffer = g_byte_array_new ();
istream = camel_stream_mem_new_with_byte_array (buffer);
- camel_data_wrapper_decode_to_stream_sync (
+ if (!camel_data_wrapper_decode_to_stream_sync (
camel_medium_get_content (CAMEL_MEDIUM (ipart)),
- istream, NULL, NULL);
+ istream, cancellable, error)) {
+ g_object_unref (istream);
+ goto fail;
+ }
camel_stream_reset (istream, NULL);
dec = NSS_CMSDecoder_Start (NULL,
@@ -1352,6 +1355,7 @@ camel_smime_context_describe_part (CamelSMIMEContext *context, CamelMimePart *pa
/* FIXME: stream this to the decoder incrementally */
buffer = g_byte_array_new ();
istream = camel_stream_mem_new_with_byte_array (buffer);
+ /* FIXME Pass a GCancellable and GError here. */
camel_data_wrapper_decode_to_stream_sync (
camel_medium_get_content ((CamelMedium *)part),
istream, NULL, NULL);
diff --git a/camel/camel-store.c b/camel/camel-store.c
index fa4997f1d..f109e5712 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -48,10 +48,24 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), CAMEL_TYPE_STORE, CamelStorePrivate))
+typedef struct _AsyncContext AsyncContext;
+
struct _CamelStorePrivate {
GStaticRecMutex folder_lock; /* for locking folder operations */
};
+struct _AsyncContext {
+ /* arguments */
+ gchar *folder_name_1;
+ gchar *folder_name_2;
+ gboolean expunge;
+ guint32 flags;
+
+ /* results */
+ CamelFolder *folder;
+ CamelFolderInfo *folder_info;
+};
+
enum {
FOLDER_CREATED,
FOLDER_DELETED,
@@ -66,6 +80,20 @@ static guint signals[LAST_SIGNAL];
G_DEFINE_ABSTRACT_TYPE (CamelStore, camel_store, CAMEL_TYPE_SERVICE)
+static void
+async_context_free (AsyncContext *async_context)
+{
+ g_free (async_context->folder_name_1);
+ g_free (async_context->folder_name_2);
+
+ if (async_context->folder != NULL)
+ g_object_unref (async_context->folder);
+
+ camel_folder_info_free (async_context->folder_info);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
/**
* ignore_no_such_table_exception:
* Clears the exception 'ex' when it's the 'no such table' exception.
@@ -302,6 +330,789 @@ store_noop_sync (CamelStore *store,
}
static void
+store_get_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->folder = camel_store_get_folder_sync (
+ CAMEL_STORE (object), async_context->folder_name_1,
+ async_context->flags, cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_get_folder (CamelStore *store,
+ const gchar *folder_name,
+ guint32 flags,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (folder_name);
+ async_context->flags = flags;
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback, user_data, store_get_folder);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_get_folder_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static CamelFolder *
+store_get_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_get_folder), 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;
+
+ return g_object_ref (async_context->folder);
+}
+
+static void
+store_get_folder_info_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->folder_info = camel_store_get_folder_info_sync (
+ CAMEL_STORE (object), async_context->folder_name_1,
+ async_context->flags, cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_get_folder_info (CamelStore *store,
+ const gchar *top,
+ guint32 flags,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (top);
+ async_context->flags = flags;
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_get_folder_info);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_get_folder_info_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static CamelFolderInfo *
+store_get_folder_info_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ CamelFolderInfo *folder_info;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_get_folder_info), 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;
+
+ folder_info = async_context->folder_info;
+ async_context->folder_info = NULL;
+
+ return folder_info;
+}
+
+static void
+store_get_inbox_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->folder = camel_store_get_inbox_folder_sync (
+ CAMEL_STORE (object), cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_get_inbox_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_get_inbox_folder);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_get_inbox_folder_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static CamelFolder *
+store_get_inbox_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_get_inbox_folder), 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;
+
+ return g_object_ref (async_context->folder);
+}
+
+static void
+store_get_junk_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->folder = camel_store_get_junk_folder_sync (
+ CAMEL_STORE (object), cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_get_junk_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_get_junk_folder);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_get_junk_folder_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static CamelFolder *
+store_get_junk_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_get_folder), 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;
+
+ return g_object_ref (async_context->folder);
+}
+
+static void
+store_get_trash_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->folder = camel_store_get_trash_folder_sync (
+ CAMEL_STORE (object), cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_get_trash_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_get_trash_folder);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_get_trash_folder_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static CamelFolder *
+store_get_trash_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_get_trash_folder), 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;
+
+ return g_object_ref (async_context->folder);
+}
+
+static void
+store_create_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->folder_info = camel_store_create_folder_sync (
+ CAMEL_STORE (object), async_context->folder_name_1,
+ async_context->folder_name_2, cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_create_folder (CamelStore *store,
+ const gchar *parent_name,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (parent_name);
+ async_context->folder_name_2 = g_strdup (folder_name);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback, user_data, store_create_folder);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_create_folder_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static CamelFolderInfo *
+store_create_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ CamelFolderInfo *folder_info;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_create_folder_finish), 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;
+
+ folder_info = async_context->folder_info;
+ async_context->folder_info = NULL;
+
+ return folder_info;
+}
+
+static void
+store_delete_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_store_delete_folder_sync (
+ CAMEL_STORE (object), async_context->folder_name_1,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_delete_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (folder_name);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback, user_data, store_delete_folder);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_delete_folder_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+store_delete_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_delete_folder), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+store_rename_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_store_rename_folder_sync (
+ CAMEL_STORE (object), async_context->folder_name_1,
+ async_context->folder_name_2, cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_rename_folder (CamelStore *store,
+ const gchar *old_name,
+ const gchar *new_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (old_name);
+ async_context->folder_name_2 = g_strdup (new_name);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback, user_data, store_rename_folder);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_rename_folder_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+store_rename_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_rename_folder), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+store_subscribe_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_store_subscribe_folder_sync (
+ CAMEL_STORE (object), async_context->folder_name_1,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_subscribe_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (folder_name);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_subscribe_folder);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_subscribe_folder_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+store_subscribe_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_subscribe_folder), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+store_unsubscribe_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_store_unsubscribe_folder_sync (
+ CAMEL_STORE (object), async_context->folder_name_1,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_unsubscribe_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (folder_name);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_unsubscribe_folder);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_unsubscribe_folder_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+store_unsubscribe_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_unsubscribe_folder), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+store_synchronize_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_store_synchronize_sync (
+ CAMEL_STORE (object), async_context->expunge,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_synchronize (CamelStore *store,
+ gboolean expunge,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->expunge = expunge;
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback, user_data, store_synchronize);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_synchronize_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+store_synchronize_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_synchronize), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+store_noop_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ GError *error = NULL;
+
+ camel_store_noop_sync (CAMEL_STORE (object), cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+store_noop (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback, user_data, store_noop);
+
+ g_simple_async_result_run_in_thread (
+ simple, store_noop_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+store_noop_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_noop), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
camel_store_class_init (CamelStoreClass *class)
{
GObjectClass *object_class;
@@ -319,12 +1130,38 @@ camel_store_class_init (CamelStoreClass *class)
class->hash_folder_name = g_str_hash;
class->compare_folder_name = g_str_equal;
class->can_refresh_folder = store_can_refresh_folder;
+
class->get_inbox_folder_sync = store_get_inbox_folder_sync;
class->get_junk_folder_sync = store_get_junk_folder_sync;
class->get_trash_folder_sync = store_get_trash_folder_sync;
class->synchronize_sync = store_synchronize_sync;
class->noop_sync = store_noop_sync;
+ class->get_folder = store_get_folder;
+ class->get_folder_finish = store_get_folder_finish;
+ class->get_folder_info = store_get_folder_info;
+ class->get_folder_info_finish = store_get_folder_info_finish;
+ class->get_inbox_folder = store_get_inbox_folder;
+ class->get_inbox_folder_finish = store_get_inbox_folder_finish;
+ class->get_junk_folder = store_get_junk_folder;
+ class->get_junk_folder_finish = store_get_junk_folder_finish;
+ class->get_trash_folder = store_get_trash_folder;
+ class->get_trash_folder_finish = store_get_trash_folder_finish;
+ class->create_folder = store_create_folder;
+ class->create_folder_finish = store_create_folder_finish;
+ class->delete_folder = store_delete_folder;
+ class->delete_folder_finish = store_delete_folder_finish;
+ class->rename_folder = store_rename_folder;
+ class->rename_folder_finish = store_rename_folder_finish;
+ class->subscribe_folder = store_subscribe_folder;
+ class->subscribe_folder_finish = store_subscribe_folder_finish;
+ class->unsubscribe_folder = store_unsubscribe_folder;
+ class->unsubscribe_folder_finish = store_unsubscribe_folder_finish;
+ class->synchronize = store_synchronize;
+ class->synchronize_finish = store_synchronize_finish;
+ class->noop = store_noop;
+ class->noop_finish = store_noop_finish;
+
signals[FOLDER_CREATED] = g_signal_new (
"folder-created",
G_OBJECT_CLASS_TYPE (class),
@@ -412,161 +1249,6 @@ camel_store_error_quark (void)
return quark;
}
-/**
- * camel_store_get_folder_sync:
- * @store: a #CamelStore object
- * @folder_name: name of the folder to get
- * @flags: folder flags (create, save body index, etc)
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Get a specific folder object from the store by name.
- *
- * Returns: the folder corresponding to the path @folder_name or %NULL.
- **/
-CamelFolder *
-camel_store_get_folder_sync (CamelStore *store,
- const gchar *folder_name,
- guint32 flags,
- GCancellable *cancellable,
- GError **error)
-{
- CamelStoreClass *class;
- CamelFolder *folder = NULL;
-
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
- g_return_val_if_fail (folder_name != NULL, NULL);
-
- class = CAMEL_STORE_GET_CLASS (store);
-
- /* O_EXCL doesn't make sense if we aren't requesting to also create the folder if it doesn't exist */
- if (!(flags & CAMEL_STORE_FOLDER_CREATE))
- flags &= ~CAMEL_STORE_FOLDER_EXCL;
-
- if (store->folders) {
- /* Try cache first. */
- folder = camel_object_bag_reserve (store->folders, folder_name);
- if (folder && (flags & CAMEL_STORE_FOLDER_EXCL)) {
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("Cannot create folder '%s': folder exists"),
- folder_name);
- camel_object_bag_abort (store->folders, folder_name);
- g_object_unref (folder);
- return NULL;
- }
- }
-
- if (!folder) {
-
- if (flags & CAMEL_STORE_IS_MIGRATING) {
- if ((store->flags & CAMEL_STORE_VTRASH) && strcmp (folder_name, CAMEL_VTRASH_NAME) == 0) {
- if (store->folders)
- camel_object_bag_abort (store->folders, folder_name);
- return NULL;
- }
-
- if ((store->flags & CAMEL_STORE_VJUNK) && strcmp (folder_name, CAMEL_VJUNK_NAME) == 0) {
- if (store->folders)
- camel_object_bag_abort (store->folders, folder_name);
- return NULL;
- }
- }
-
- if ((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0) {
- folder = class->get_trash_folder_sync (store, cancellable, error);
- CAMEL_CHECK_GERROR (store, get_trash_folder_sync, folder != NULL, error);
- } else if ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0) {
- folder = class->get_junk_folder_sync (store, cancellable, error);
- CAMEL_CHECK_GERROR (store, get_junk_folder_sync, folder != NULL, error);
- } else {
- folder = class->get_folder_sync (
- store, folder_name, flags, cancellable, error);
- CAMEL_CHECK_GERROR (store, get_folder_sync, folder != NULL, error);
-
- if (folder) {
- CamelVeeFolder *vfolder;
-
- if ((store->flags & CAMEL_STORE_VTRASH)
- && (vfolder = camel_object_bag_get (store->folders, CAMEL_VTRASH_NAME))) {
- camel_vee_folder_add_folder (vfolder, folder);
- g_object_unref (vfolder);
- }
-
- if ((store->flags & CAMEL_STORE_VJUNK)
- && (vfolder = camel_object_bag_get (store->folders, CAMEL_VJUNK_NAME))) {
- camel_vee_folder_add_folder (vfolder, folder);
- g_object_unref (vfolder);
- }
- }
- }
-
- if (store->folders) {
- if (folder)
- camel_object_bag_add (store->folders, folder_name, folder);
- else
- camel_object_bag_abort (store->folders, folder_name);
- }
-
- if (folder)
- g_signal_emit (store, signals[FOLDER_OPENED], 0, folder);
- }
-
- return folder;
-}
-
-/**
- * camel_store_create_folder_sync:
- * @store: a #CamelStore object
- * @parent_name: name of the new folder's parent, or %NULL
- * @folder_name: name of the folder to create
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Creates a new folder as a child of an existing folder.
- * @parent_name can be %NULL to create a new top-level folder.
- *
- * Returns: info about the created folder, which the caller must
- * free with #camel_store_free_folder_info, or %NULL.
- **/
-CamelFolderInfo *
-camel_store_create_folder_sync (CamelStore *store,
- const gchar *parent_name,
- const gchar *folder_name,
- GCancellable *cancellable,
- GError **error)
-{
- CamelStoreClass *class;
- CamelFolderInfo *fi;
-
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
- g_return_val_if_fail (folder_name != NULL, NULL);
-
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->create_folder_sync != NULL, NULL);
-
- if ((parent_name == NULL || parent_name[0] == 0)
- && (((store->flags & CAMEL_STORE_VTRASH) && strcmp (folder_name, CAMEL_VTRASH_NAME) == 0)
- || ((store->flags & CAMEL_STORE_VJUNK) && strcmp (folder_name, CAMEL_VJUNK_NAME) == 0))) {
- g_set_error (
- error, CAMEL_STORE_ERROR,
- CAMEL_STORE_ERROR_INVALID,
- _("Cannot create folder: %s: folder exists"),
- folder_name);
- return NULL;
- }
-
- camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
-
- fi = class->create_folder_sync (
- store, parent_name, folder_name, cancellable, error);
- CAMEL_CHECK_GERROR (store, create_folder_sync, fi != NULL, error);
-
- camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
-
- return fi;
-}
-
/* deletes folder/removes it from the folder cache, if it's there */
static void
cs_delete_cached_folder (CamelStore *store,
@@ -598,199 +1280,6 @@ cs_delete_cached_folder (CamelStore *store,
}
/**
- * camel_store_delete_folder_sync:
- * @store: a #CamelStore object
- * @folder_name: name of the folder to delete
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Deletes the named folder. The folder must be empty.
- *
- * Returns: %TRUE on success, %FALSE on failure
- **/
-gboolean
-camel_store_delete_folder_sync (CamelStore *store,
- const gchar *folder_name,
- GCancellable *cancellable,
- GError **error)
-{
- CamelStoreClass *class;
- gboolean success;
- GError *local_error = NULL;
-
- g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
- g_return_val_if_fail (folder_name != NULL, FALSE);
-
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->delete_folder_sync != NULL, FALSE);
-
- /* TODO: should probably be a parameter/bit on the storeinfo */
- if (((store->flags & CAMEL_STORE_VTRASH) && strcmp (folder_name, CAMEL_VTRASH_NAME) == 0)
- || ((store->flags & CAMEL_STORE_VJUNK) && strcmp (folder_name, CAMEL_VJUNK_NAME) == 0)) {
- g_set_error (
- error, CAMEL_STORE_ERROR,
- CAMEL_STORE_ERROR_NO_FOLDER,
- _("Cannot delete folder: %s: Invalid operation"),
- folder_name);
- return FALSE;
- }
-
- camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
-
- success = class->delete_folder_sync (
- store, folder_name, cancellable, &local_error);
- CAMEL_CHECK_GERROR (store, delete_folder_sync, success, &local_error);
-
- /* ignore 'no such table' errors */
- if (local_error != NULL &&
- g_ascii_strncasecmp (local_error->message, "no such table", 13) == 0)
- g_clear_error (&local_error);
-
- if (local_error == NULL)
- cs_delete_cached_folder(store, folder_name);
- else
- g_propagate_error (error, local_error);
-
- camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
-
- return success;
-}
-
-/**
- * camel_store_rename_folder_sync:
- * @store: a #CamelStore object
- * @old_namein: the current name of the folder
- * @new_name: the new name of the folder
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Rename a named folder to a new name.
- *
- * Returns: %TRUE on success, %FALSE on failure
- **/
-gboolean
-camel_store_rename_folder_sync (CamelStore *store,
- const gchar *old_namein,
- const gchar *new_name,
- GCancellable *cancellable,
- GError **error)
-{
- CamelStoreClass *class;
- CamelFolder *folder;
- gint i, oldlen, namelen;
- GPtrArray *folders = NULL;
- gchar *old_name;
- gboolean success;
-
- g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
- g_return_val_if_fail (old_namein != NULL, FALSE);
- g_return_val_if_fail (new_name != NULL, FALSE);
-
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->rename_folder_sync != NULL, FALSE);
-
- if (strcmp (old_namein, new_name) == 0)
- return TRUE;
-
- if (((store->flags & CAMEL_STORE_VTRASH) && strcmp (old_namein, CAMEL_VTRASH_NAME) == 0)
- || ((store->flags & CAMEL_STORE_VJUNK) && strcmp (old_namein, CAMEL_VJUNK_NAME) == 0)) {
- g_set_error (
- error, CAMEL_STORE_ERROR,
- CAMEL_STORE_ERROR_NO_FOLDER,
- _("Cannot rename folder: %s: Invalid operation"),
- old_namein);
- return FALSE;
- }
-
- /* need to save this, since old_namein might be folder->full_name, which could go away */
- old_name = g_strdup (old_namein);
- oldlen = strlen (old_name);
-
- camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
-
- /* If the folder is open (or any subfolders of the open folder)
- We need to rename them atomically with renaming the actual folder path */
- if (store->folders) {
- folders = camel_object_bag_list (store->folders);
- for (i=0;i<folders->len;i++) {
- const gchar *full_name;
-
- folder = folders->pdata[i];
- full_name = camel_folder_get_full_name (folder);
-
- namelen = strlen (full_name);
- if ((namelen == oldlen &&
- strcmp (full_name, old_name) == 0)
- || ((namelen > oldlen)
- && strncmp (full_name, old_name, oldlen) == 0
- && full_name[oldlen] == '/')) {
- camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
- } else {
- g_ptr_array_remove_index_fast (folders, i);
- i--;
- g_object_unref (folder);
- }
- }
- }
-
- /* Now try the real rename (will emit renamed signal) */
- success = class->rename_folder_sync (
- store, old_name, new_name, cancellable, error);
- CAMEL_CHECK_GERROR (store, rename_folder_sync, success, error);
-
- /* If it worked, update all open folders/unlock them */
- if (folders) {
- if (success) {
- guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE;
- CamelFolderInfo *folder_info;
-
- for (i=0;i<folders->len;i++) {
- const gchar *full_name;
- gchar *new;
-
- folder = folders->pdata[i];
- full_name = camel_folder_get_full_name (folder);
-
- new = g_strdup_printf("%s%s", new_name, full_name + strlen(old_name));
- camel_object_bag_rekey (store->folders, folder, new);
- camel_folder_rename (folder, new);
- g_free (new);
-
- camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
- g_object_unref (folder);
- }
-
- /* Emit renamed signal */
- if (store->flags & CAMEL_STORE_SUBSCRIPTIONS)
- flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
-
- folder_info = class->get_folder_info_sync (
- store, new_name, flags, cancellable, error);
- CAMEL_CHECK_GERROR (store, get_folder_info, folder_info != NULL, error);
-
- if (folder_info != NULL) {
- camel_store_folder_renamed (store, old_name, folder_info);
- class->free_folder_info (store, folder_info);
- }
- } else {
- /* Failed, just unlock our folders for re-use */
- for (i=0;i<folders->len;i++) {
- folder = folders->pdata[i];
- camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
- g_object_unref (folder);
- }
- }
- }
-
- camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
-
- g_ptr_array_free (folders, TRUE);
- g_free (old_name);
-
- return success;
-}
-
-/**
* camel_store_folder_created:
* @store: a #CamelStore
* @info: information about the created folder
@@ -898,140 +1387,6 @@ camel_store_folder_unsubscribed (CamelStore *store,
g_signal_emit (store, signals[FOLDER_UNSUBSCRIBED], 0, info);
}
-/**
- * camel_store_get_inbox_folder_sync:
- * @store: a #CamelStore object
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Returns: the folder in the store into which new mail is delivered,
- * or %NULL if no such folder exists.
- **/
-CamelFolder *
-camel_store_get_inbox_folder_sync (CamelStore *store,
- GCancellable *cancellable,
- GError **error)
-{
- CamelStoreClass *class;
- CamelFolder *folder;
-
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
-
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->get_inbox_folder_sync != NULL, NULL);
-
- camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
-
- folder = class->get_inbox_folder_sync (store, cancellable, error);
- CAMEL_CHECK_GERROR (
- store, get_inbox_folder_sync, folder != NULL, error);
-
- camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
-
- return folder;
-}
-
-/**
- * camel_store_get_junk_folder_sync:
- * @store: a #CamelStore object
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Returns: the folder in the store into which junk is delivered, or
- * %NULL if no such folder exists.
- **/
-CamelFolder *
-camel_store_get_junk_folder_sync (CamelStore *store,
- GCancellable *cancellable,
- GError **error)
-{
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
-
- if ((store->flags & CAMEL_STORE_VJUNK) == 0) {
- CamelStoreClass *class;
- CamelFolder *folder;
-
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->get_junk_folder_sync != NULL, NULL);
-
- folder = class->get_junk_folder_sync (store, cancellable, error);
- CAMEL_CHECK_GERROR (
- store, get_junk_folder_sync, folder != NULL, error);
-
- return folder;
- }
-
- return camel_store_get_folder_sync (
- store, CAMEL_VJUNK_NAME, 0, cancellable, error);
-}
-
-/**
- * camel_store_get_trash_folder_sync:
- * @store: a #CamelStore object
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Returns: the folder in the store into which trash is delivered, or
- * %NULL if no such folder exists.
- **/
-CamelFolder *
-camel_store_get_trash_folder_sync (CamelStore *store,
- GCancellable *cancellable,
- GError **error)
-{
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
-
- if ((store->flags & CAMEL_STORE_VTRASH) == 0) {
- CamelStoreClass *class;
- CamelFolder *folder;
-
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->get_trash_folder_sync != NULL, NULL);
-
- folder = class->get_trash_folder_sync (
- store, cancellable, error);
- CAMEL_CHECK_GERROR (
- store, get_trash_folder_sync, folder != NULL, error);
-
- return folder;
- }
-
- return camel_store_get_folder_sync (
- store, CAMEL_VTRASH_NAME, 0, cancellable, error);
-}
-
-/**
- * camel_store_synchronize_sync:
- * @store: a #CamelStore object
- * @expunge: %TRUE if an expunge should be done after sync or %FALSE otherwise
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Syncs any changes that have been made to the store object and its
- * folders with the real store.
- *
- * Returns: %TRUE on success, %FALSE on failure
- **/
-gboolean
-camel_store_synchronize_sync (CamelStore *store,
- gboolean expunge,
- GCancellable *cancellable,
- GError **error)
-{
- CamelStoreClass *class;
- gboolean success;
-
- g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
-
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->synchronize_sync != NULL, FALSE);
-
- success = class->synchronize_sync (store, expunge, cancellable, error);
- CAMEL_CHECK_GERROR (store, synchronize_sync, success, error);
-
- return success;
-}
-
static void
add_special_info (CamelStore *store,
CamelFolderInfo *info,
@@ -1113,79 +1468,8 @@ dump_fi (CamelFolderInfo *fi, gint depth)
}
/**
- * camel_store_get_folder_info_sync:
- * @store: a #CamelStore object
- * @top: the name of the folder to start from
- * @flags: various CAMEL_STORE_FOLDER_INFO_* flags to control behavior
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * This fetches information about the folder structure of @store,
- * starting with @top, and returns a tree of CamelFolderInfo
- * structures. If @flags includes %CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
- * only subscribed folders will be listed. If the store doesn't support
- * subscriptions, then it will list all folders. If @flags includes
- * %CAMEL_STORE_FOLDER_INFO_RECURSIVE, the returned tree will include
- * all levels of hierarchy below @top. If not, it will only include
- * the immediate subfolders of @top. If @flags includes
- * %CAMEL_STORE_FOLDER_INFO_FAST, the unread_message_count fields of
- * some or all of the structures may be set to %-1, if the store cannot
- * determine that information quickly. If @flags includes
- * %CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL, don't include special virtual
- * folders (such as vTrash or vJunk).
- *
- * The CAMEL_STORE_FOLDER_INFO_FAST flag should be considered
- * deprecated; most backends will behave the same whether it is
- * supplied or not. The only guaranteed way to get updated folder
- * counts is to both open the folder and invoke refresh_info() it.
- *
- * Returns: a #CamelFolderInfo tree, which must be freed with
- * #camel_store_free_folder_info, or %NULL.
- **/
-CamelFolderInfo *
-camel_store_get_folder_info_sync (CamelStore *store,
- const gchar *top,
- guint32 flags,
- GCancellable *cancellable,
- GError **error)
-{
- CamelStoreClass *class;
- CamelFolderInfo *info;
-
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
-
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->get_folder_info_sync != NULL, NULL);
-
- info = class->get_folder_info_sync (
- store, top, flags, cancellable, error);
- if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED))
- CAMEL_CHECK_GERROR (
- store, get_folder_info_sync, info != NULL, error);
-
- if (info && (top == NULL || *top == '\0') && (flags & CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL) == 0) {
- if (info->uri && (store->flags & CAMEL_STORE_VTRASH))
- /* the name of the Trash folder, used for deleted messages */
- add_special_info (store, info, CAMEL_VTRASH_NAME, _("Trash"), FALSE, CAMEL_FOLDER_VIRTUAL|CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_VTRASH|CAMEL_FOLDER_TYPE_TRASH);
- if (info->uri && (store->flags & CAMEL_STORE_VJUNK))
- /* the name of the Junk folder, used for spam messages */
- add_special_info (store, info, CAMEL_VJUNK_NAME, _("Junk"), TRUE, CAMEL_FOLDER_VIRTUAL|CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_VTRASH|CAMEL_FOLDER_TYPE_JUNK);
- }
-
- if (camel_debug_start("store:folder_info")) {
- gchar *url = camel_url_to_string (((CamelService *)store)->url, CAMEL_URL_HIDE_ALL);
- printf("Get folder info(%p:%s, '%s') =\n", (gpointer) store, url, top?top:"<null>");
- g_free (url);
- dump_fi (info, 2);
- camel_debug_end ();
- }
-
- return info;
-}
-
-/**
* camel_store_free_folder_info:
- * @store: a #CamelStore object
+ * @store: a #CamelStore
* @fi: a #CamelFolderInfo as gotten via #camel_store_get_folder_info
*
* Frees the data returned by #camel_store_get_folder_info. If @fi is %NULL,
@@ -1210,7 +1494,7 @@ camel_store_free_folder_info (CamelStore *store,
/**
* camel_store_free_folder_info_full:
- * @store: a #CamelStore object
+ * @store: a #CamelStore
* @fi: a #CamelFolderInfo as gotten via #camel_store_get_folder_info
*
* An implementation for #CamelStore::free_folder_info. Frees all
@@ -1225,7 +1509,7 @@ camel_store_free_folder_info_full (CamelStore *store,
/**
* camel_store_free_folder_info_nop:
- * @store: a #CamelStore object
+ * @store: a #CamelStore
* @fi: a #CamelFolderInfo as gotten via #camel_store_get_folder_info
*
* An implementation for #CamelStore::free_folder_info. Does nothing.
@@ -1451,7 +1735,7 @@ camel_folder_info_clone (CamelFolderInfo *fi)
/**
* camel_store_supports_subscriptions:
- * @store: a #CamelStore object
+ * @store: a #CamelStore
*
* Get whether or not @store supports subscriptions to folders.
*
@@ -1467,7 +1751,7 @@ camel_store_supports_subscriptions (CamelStore *store)
/**
* camel_store_folder_is_subscribed:
- * @store: a #CamelStore object
+ * @store: a #CamelStore
* @folder_name: full path of the folder
*
* Find out if a folder has been subscribed to.
@@ -1498,15 +1782,1259 @@ camel_store_folder_is_subscribed (CamelStore *store,
}
/**
+ * camel_store_folder_uri_equal:
+ * @store: a #CamelStore
+ * @uri0: a folder uri
+ * @uri1: another folder uri
+ *
+ * Compares two folder uris to check that they are equal.
+ *
+ * Returns: %TRUE if they are equal or %FALSE otherwise
+ **/
+gint
+camel_store_folder_uri_equal (CamelStore *store,
+ const gchar *uri0,
+ const gchar *uri1)
+{
+ CamelStoreClass *class;
+ CamelProvider *provider;
+ CamelURL *url0, *url1;
+ gint equal;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (uri0 && uri1, FALSE);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->compare_folder_name != NULL, FALSE);
+
+ provider = ((CamelService *) store)->provider;
+
+ if (!(url0 = camel_url_new (uri0, NULL)))
+ return FALSE;
+
+ if (!(url1 = camel_url_new (uri1, NULL))) {
+ camel_url_free (url0);
+ return FALSE;
+ }
+
+ if ((equal = provider->url_equal (url0, url1))) {
+ const gchar *name0, *name1;
+
+ if (provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) {
+ name0 = url0->fragment;
+ name1 = url1->fragment;
+ } else {
+ name0 = url0->path && url0->path[0] == '/' ? url0->path + 1 : url0->path;
+ name1 = url1->path && url1->path[0] == '/' ? url1->path + 1 : url1->path;
+ }
+
+ if (name0 == NULL)
+ g_warning("URI is badly formed, missing folder name: %s", uri0);
+
+ if (name1 == NULL)
+ g_warning("URI is badly formed, missing folder name: %s", uri1);
+
+ equal = name0 && name1 && class->compare_folder_name (name0, name1);
+ }
+
+ camel_url_free (url0);
+ camel_url_free (url1);
+
+ return equal;
+}
+
+/**
+ * camel_store_can_refresh_folder
+ * @store: a #CamelStore
+ * @info: a #CamelFolderInfo
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns if this folder (param info) should be checked for new mail or not.
+ * It should not look into sub infos (info->child) or next infos, it should
+ * return value only for the actual folder info.
+ * Default behavior is that all Inbox folders are intended to be refreshed.
+ *
+ * Returns: whether folder should be checked for new mails
+ *
+ * Since: 2.22
+ **/
+gboolean
+camel_store_can_refresh_folder (CamelStore *store,
+ CamelFolderInfo *info,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->can_refresh_folder != NULL, FALSE);
+
+ return class->can_refresh_folder (store, info, error);
+}
+
+/**
+ * camel_store_lock:
+ * @store: a #CamelStore
+ * @lock: lock type to lock
+ *
+ * Locks #store's #lock. Unlock it with camel_store_unlock().
+ *
+ * Since: 2.32
+ **/
+void
+camel_store_lock (CamelStore *store,
+ CamelStoreLock lock)
+{
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ switch (lock) {
+ case CAMEL_STORE_FOLDER_LOCK:
+ g_static_rec_mutex_lock (&store->priv->folder_lock);
+ break;
+ default:
+ g_return_if_reached ();
+ }
+}
+
+/**
+ * camel_store_unlock:
+ * @store: a #CamelStore
+ * @lock: lock type to unlock
+ *
+ * Unlocks #store's #lock, previously locked with camel_store_lock().
+ *
+ * Since: 2.32
+ **/
+void
+camel_store_unlock (CamelStore *store,
+ CamelStoreLock lock)
+{
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ switch (lock) {
+ case CAMEL_STORE_FOLDER_LOCK:
+ g_static_rec_mutex_unlock (&store->priv->folder_lock);
+ break;
+ default:
+ g_return_if_reached ();
+ }
+}
+
+/**
+ * camel_store_get_folder_sync:
+ * @store: a #CamelStore
+ * @folder_name: name of the folder to get
+ * @flags: folder flags (create, save body index, etc)
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets a specific folder object from @store by name.
+ *
+ * Returns: the requested #CamelFolder object, or %NULL on error
+ *
+ * Since: 2.34
+ **/
+CamelFolder *
+camel_store_get_folder_sync (CamelStore *store,
+ const gchar *folder_name,
+ guint32 flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStoreClass *class;
+ CamelFolder *folder = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ g_return_val_if_fail (folder_name != NULL, NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+
+ /* O_EXCL doesn't make sense if we aren't requesting to also create the folder if it doesn't exist */
+ if (!(flags & CAMEL_STORE_FOLDER_CREATE))
+ flags &= ~CAMEL_STORE_FOLDER_EXCL;
+
+ if (store->folders) {
+ /* Try cache first. */
+ folder = camel_object_bag_reserve (store->folders, folder_name);
+ if (folder && (flags & CAMEL_STORE_FOLDER_EXCL)) {
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Cannot create folder '%s': folder exists"),
+ folder_name);
+ camel_object_bag_abort (store->folders, folder_name);
+ g_object_unref (folder);
+ return NULL;
+ }
+ }
+
+ if (!folder) {
+
+ if (flags & CAMEL_STORE_IS_MIGRATING) {
+ if ((store->flags & CAMEL_STORE_VTRASH) && strcmp (folder_name, CAMEL_VTRASH_NAME) == 0) {
+ if (store->folders)
+ camel_object_bag_abort (store->folders, folder_name);
+ return NULL;
+ }
+
+ if ((store->flags & CAMEL_STORE_VJUNK) && strcmp (folder_name, CAMEL_VJUNK_NAME) == 0) {
+ if (store->folders)
+ camel_object_bag_abort (store->folders, folder_name);
+ return NULL;
+ }
+ }
+
+ if ((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0) {
+ folder = class->get_trash_folder_sync (store, cancellable, error);
+ CAMEL_CHECK_GERROR (store, get_trash_folder_sync, folder != NULL, error);
+ } else if ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0) {
+ folder = class->get_junk_folder_sync (store, cancellable, error);
+ CAMEL_CHECK_GERROR (store, get_junk_folder_sync, folder != NULL, error);
+ } else {
+ folder = class->get_folder_sync (
+ store, folder_name, flags, cancellable, error);
+ CAMEL_CHECK_GERROR (store, get_folder_sync, folder != NULL, error);
+
+ if (folder) {
+ CamelVeeFolder *vfolder;
+
+ if ((store->flags & CAMEL_STORE_VTRASH)
+ && (vfolder = camel_object_bag_get (store->folders, CAMEL_VTRASH_NAME))) {
+ camel_vee_folder_add_folder (vfolder, folder);
+ g_object_unref (vfolder);
+ }
+
+ if ((store->flags & CAMEL_STORE_VJUNK)
+ && (vfolder = camel_object_bag_get (store->folders, CAMEL_VJUNK_NAME))) {
+ camel_vee_folder_add_folder (vfolder, folder);
+ g_object_unref (vfolder);
+ }
+ }
+ }
+
+ if (store->folders) {
+ if (folder)
+ camel_object_bag_add (store->folders, folder_name, folder);
+ else
+ camel_object_bag_abort (store->folders, folder_name);
+ }
+
+ if (folder)
+ g_signal_emit (store, signals[FOLDER_OPENED], 0, folder);
+ }
+
+ return folder;
+}
+
+/**
+ * camel_store_get_folder:
+ * @store: a #CamelStore
+ * @folder_name: name of the folder to get
+ * @flags: folder flags (create, save body index, etc)
+ * @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 gets a specific folder object from @store by name.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_store_get_folder_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_get_folder (CamelStore *store,
+ const gchar *folder_name,
+ guint32 flags,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (folder_name != NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->get_folder != NULL);
+
+ class->get_folder (
+ store, folder_name, flags, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_get_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_get_folder().
+ *
+ * Returns: the requested #CamelFolder object, or %NULL on error
+ *
+ * Since: 2.34
+ **/
+CamelFolder *
+camel_store_get_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->get_folder_finish != NULL, NULL);
+
+ return class->get_folder_finish (store, result, error);
+}
+
+/**
+ * camel_store_get_folder_info_sync:
+ * @store: a #CamelStore
+ * @top: the name of the folder to start from
+ * @flags: various CAMEL_STORE_FOLDER_INFO_* flags to control behavior
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * This fetches information about the folder structure of @store,
+ * starting with @top, and returns a tree of #CamelFolderInfo
+ * structures. If @flags includes %CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
+ * only subscribed folders will be listed. If the store doesn't support
+ * subscriptions, then it will list all folders. If @flags includes
+ * %CAMEL_STORE_FOLDER_INFO_RECURSIVE, the returned tree will include
+ * all levels of hierarchy below @top. If not, it will only include
+ * the immediate subfolders of @top. If @flags includes
+ * %CAMEL_STORE_FOLDER_INFO_FAST, the unread_message_count fields of
+ * some or all of the structures may be set to %-1, if the store cannot
+ * determine that information quickly. If @flags includes
+ * %CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL, don't include special virtual
+ * folders (such as vTrash or vJunk).
+ *
+ * The returned #CamelFolderInfo tree should be freed with
+ * camel_store_free_folder_info().
+ *
+ * The CAMEL_STORE_FOLDER_INFO_FAST flag should be considered
+ * deprecated; most backends will behave the same whether it is
+ * supplied or not. The only guaranteed way to get updated folder
+ * counts is to both open the folder and invoke refresh_info() it.
+ *
+ * Returns: a #CamelFolderInfo tree, or %NULL on error
+ *
+ * Since: 2.34
+ **/
+CamelFolderInfo *
+camel_store_get_folder_info_sync (CamelStore *store,
+ const gchar *top,
+ guint32 flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStoreClass *class;
+ CamelFolderInfo *info;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->get_folder_info_sync != NULL, NULL);
+
+ info = class->get_folder_info_sync (
+ store, top, flags, cancellable, error);
+ if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED))
+ CAMEL_CHECK_GERROR (
+ store, get_folder_info_sync, info != NULL, error);
+
+ if (info && (top == NULL || *top == '\0') && (flags & CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL) == 0) {
+ if (info->uri && (store->flags & CAMEL_STORE_VTRASH))
+ /* the name of the Trash folder, used for deleted messages */
+ add_special_info (store, info, CAMEL_VTRASH_NAME, _("Trash"), FALSE, CAMEL_FOLDER_VIRTUAL|CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_VTRASH|CAMEL_FOLDER_TYPE_TRASH);
+ if (info->uri && (store->flags & CAMEL_STORE_VJUNK))
+ /* the name of the Junk folder, used for spam messages */
+ add_special_info (store, info, CAMEL_VJUNK_NAME, _("Junk"), TRUE, CAMEL_FOLDER_VIRTUAL|CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_VTRASH|CAMEL_FOLDER_TYPE_JUNK);
+ }
+
+ if (camel_debug_start("store:folder_info")) {
+ gchar *url = camel_url_to_string (((CamelService *)store)->url, CAMEL_URL_HIDE_ALL);
+ printf("Get folder info(%p:%s, '%s') =\n", (gpointer) store, url, top?top:"<null>");
+ g_free (url);
+ dump_fi (info, 2);
+ camel_debug_end ();
+ }
+
+ return info;
+}
+
+/**
+ * camel_store_get_folder_info:
+ * @store: a #CamelStore
+ * @top: the name of the folder to start from
+ * @flags: various CAMEL_STORE_FOLDER_INFO_* flags to control behavior
+ * @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 fetches information about the folder structure of @store,
+ * starting with @top. For details of the behavior, see
+ * camel_store_get_folder_info_sync().
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_store_get_folder_info_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_get_folder_info (CamelStore *store,
+ const gchar *top,
+ guint32 flags,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->get_folder_info != NULL);
+
+ class->get_folder_info (
+ store, top, flags, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_get_folder_info_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_get_folder_info().
+ * The returned #CamelFolderInfo tree should be freed with
+ * camel_store_free_folder_info().
+ *
+ * Returns: a #CamelFolderInfo tree, or %NULL on error
+ *
+ * Since: 2.34
+ **/
+CamelFolderInfo *
+camel_store_get_folder_info_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->get_folder_info_finish != NULL, NULL);
+
+ return class->get_folder_info_finish (store, result, error);
+}
+
+/**
+ * camel_store_get_inbox_folder_sync:
+ * @store: a #CamelStore
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the folder in @store into which new mail is delivered.
+ *
+ * Returns: the inbox folder for @store, or %NULL on error or if no such
+ * folder exists
+ *
+ * Since: 2.34
+ **/
+CamelFolder *
+camel_store_get_inbox_folder_sync (CamelStore *store,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStoreClass *class;
+ CamelFolder *folder;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->get_inbox_folder_sync != NULL, NULL);
+
+ camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ return NULL;
+ }
+
+ folder = class->get_inbox_folder_sync (store, cancellable, error);
+ CAMEL_CHECK_GERROR (
+ store, get_inbox_folder_sync, folder != NULL, error);
+
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ return folder;
+}
+
+/**
+ * camel_store_get_inbox_folder:
+ * @store: a #CamelStore
+ * @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 gets the folder in @store into which new mail is delivered.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_store_get_inbox_folder_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_get_inbox_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->get_inbox_folder != NULL);
+
+ class->get_inbox_folder (
+ store, io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_get_inbox_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_get_inbox_folder().
+ *
+ * Returns: the inbox folder for @store, or %NULL on error or if no such
+ * folder exists
+ *
+ * Since: 2.34
+ **/
+CamelFolder *
+camel_store_get_inbox_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->get_inbox_folder_finish != NULL, NULL);
+
+ return class->get_inbox_folder_finish (store, result, error);
+}
+
+/**
+ * camel_store_get_junk_folder_sync:
+ * @store: a #CamelStore
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the folder in @store into which junk is delivered.
+ *
+ * Returns: the junk folder for @store, or %NULL on error or if no such
+ * folder exists
+ *
+ * Since: 2.34
+ **/
+CamelFolder *
+camel_store_get_junk_folder_sync (CamelStore *store,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ if ((store->flags & CAMEL_STORE_VJUNK) == 0) {
+ CamelStoreClass *class;
+ CamelFolder *folder;
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->get_junk_folder_sync != NULL, NULL);
+
+ folder = class->get_junk_folder_sync (store, cancellable, error);
+ CAMEL_CHECK_GERROR (
+ store, get_junk_folder_sync, folder != NULL, error);
+
+ return folder;
+ }
+
+ return camel_store_get_folder_sync (
+ store, CAMEL_VJUNK_NAME, 0, cancellable, error);
+}
+
+/**
+ * camel_store_get_junk_folder:
+ * @store: a #CamelStore
+ * @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 gets the folder in @store into which junk is delivered.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_store_get_junk_folder_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_get_junk_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->get_junk_folder != NULL);
+
+ class->get_junk_folder (
+ store, io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_get_junk_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_get_junk_folder().
+ *
+ * Returns: the junk folder for @store, or %NULL on error or if no such
+ * folder exists
+ *
+ * Since: 2.34
+ **/
+CamelFolder *
+camel_store_get_junk_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->get_junk_folder_finish != NULL, NULL);
+
+ return class->get_junk_folder_finish (store, result, error);
+}
+
+/**
+ * camel_store_get_trash_folder_sync:
+ * @store: a #CamelStore
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the folder in @store into which trash is delivered.
+ *
+ * Returns: the trash folder for @store, or %NULL on error or if no such
+ * folder exists
+ *
+ * Since: 2.34
+ **/
+CamelFolder *
+camel_store_get_trash_folder_sync (CamelStore *store,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ if ((store->flags & CAMEL_STORE_VTRASH) == 0) {
+ CamelStoreClass *class;
+ CamelFolder *folder;
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->get_trash_folder_sync != NULL, NULL);
+
+ folder = class->get_trash_folder_sync (
+ store, cancellable, error);
+ CAMEL_CHECK_GERROR (
+ store, get_trash_folder_sync, folder != NULL, error);
+
+ return folder;
+ }
+
+ return camel_store_get_folder_sync (
+ store, CAMEL_VTRASH_NAME, 0, cancellable, error);
+}
+
+/**
+ * camel_store_get_trash_folder:
+ * @store: a #CamelStore
+ * @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 gets the folder in @store into which trash is delivered.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_store_get_trash_folder_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_get_trash_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->get_trash_folder != NULL);
+
+ class->get_trash_folder (
+ store, io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_get_trash_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_get_trash_folder().
+ *
+ * Returns: the trash folder for @store, or %NULL on error or if no such
+ * folder exists
+ *
+ * Since: 2.34
+ **/
+CamelFolder *
+camel_store_get_trash_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->get_trash_folder_finish != NULL, NULL);
+
+ return class->get_trash_folder_finish (store, result, error);
+}
+
+/**
+ * camel_store_create_folder_sync:
+ * @store: a #CamelStore
+ * @parent_name: name of the new folder's parent, or %NULL
+ * @folder_name: name of the folder to create
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Creates a new folder as a child of an existing folder.
+ * @parent_name can be %NULL to create a new top-level folder.
+ * The returned #CamelFolderInfo struct should be freed with
+ * camel_store_free_folder_info().
+ *
+ * Returns: info about the created folder, or %NULL on error
+ *
+ * Since: 2.34
+ **/
+CamelFolderInfo *
+camel_store_create_folder_sync (CamelStore *store,
+ const gchar *parent_name,
+ const gchar *folder_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStoreClass *class;
+ CamelFolderInfo *fi;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ g_return_val_if_fail (folder_name != NULL, NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->create_folder_sync != NULL, NULL);
+
+ if ((parent_name == NULL || parent_name[0] == 0)
+ && (((store->flags & CAMEL_STORE_VTRASH) && strcmp (folder_name, CAMEL_VTRASH_NAME) == 0)
+ || ((store->flags & CAMEL_STORE_VJUNK) && strcmp (folder_name, CAMEL_VJUNK_NAME) == 0))) {
+ g_set_error (
+ error, CAMEL_STORE_ERROR,
+ CAMEL_STORE_ERROR_INVALID,
+ _("Cannot create folder: %s: folder exists"),
+ folder_name);
+ return NULL;
+ }
+
+ camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ return NULL;
+ }
+
+ fi = class->create_folder_sync (
+ store, parent_name, folder_name, cancellable, error);
+ CAMEL_CHECK_GERROR (store, create_folder_sync, fi != NULL, error);
+
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ return fi;
+}
+
+/**
+ * camel_store_create_folder:
+ * @store: a #CamelStore
+ * @parent_name: name of the new folder's parent, or %NULL
+ * @folder_name: name of the folder to create
+ * @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 creates a new folder as a child of an existing folder.
+ * @parent_name can be %NULL to create a new top-level folder.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_store_create_folder_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_create_folder (CamelStore *store,
+ const gchar *parent_name,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (folder_name != NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->create_folder != NULL);
+
+ class->create_folder (
+ store, parent_name, folder_name, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_create_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_create_folder().
+ * The returned #CamelFolderInfo struct should be freed with
+ * camel_store_free_folder_info().
+ *
+ * Returns: info about the created folder, or %NULL on error
+ *
+ * Since: 2.34
+ **/
+CamelFolderInfo *
+camel_store_create_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->create_folder_finish != NULL, NULL);
+
+ return class->create_folder_finish (store, result, error);
+}
+
+/**
+ * camel_store_delete_folder_sync:
+ * @store: a #CamelStore
+ * @folder_name: name of the folder to delete
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Deletes the folder described by @folder_name. The folder must be empty.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_store_delete_folder_sync (CamelStore *store,
+ const gchar *folder_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStoreClass *class;
+ gboolean success;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (folder_name != NULL, FALSE);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->delete_folder_sync != NULL, FALSE);
+
+ /* TODO: should probably be a parameter/bit on the storeinfo */
+ if (((store->flags & CAMEL_STORE_VTRASH) && strcmp (folder_name, CAMEL_VTRASH_NAME) == 0)
+ || ((store->flags & CAMEL_STORE_VJUNK) && strcmp (folder_name, CAMEL_VJUNK_NAME) == 0)) {
+ g_set_error (
+ error, CAMEL_STORE_ERROR,
+ CAMEL_STORE_ERROR_NO_FOLDER,
+ _("Cannot delete folder: %s: Invalid operation"),
+ folder_name);
+ return FALSE;
+ }
+
+ camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ return FALSE;
+ }
+
+ success = class->delete_folder_sync (
+ store, folder_name, cancellable, &local_error);
+ CAMEL_CHECK_GERROR (store, delete_folder_sync, success, &local_error);
+
+ /* ignore 'no such table' errors */
+ if (local_error != NULL &&
+ g_ascii_strncasecmp (local_error->message, "no such table", 13) == 0)
+ g_clear_error (&local_error);
+
+ if (local_error == NULL)
+ cs_delete_cached_folder(store, folder_name);
+ else
+ g_propagate_error (error, local_error);
+
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ return success;
+}
+
+/**
+ * camel_store_delete_folder:
+ * @store: a #CamelStore
+ * @folder_name: name of the folder to delete
+ * @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 deletes the folder described by @folder_name. The
+ * folder must be empty.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_store_delete_folder_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_delete_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (folder_name != NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->delete_folder != NULL);
+
+ class->delete_folder (
+ store, folder_name, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_delete_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_delete_folder().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_store_delete_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->delete_folder_finish != NULL, FALSE);
+
+ return class->delete_folder_finish (store, result, error);
+}
+
+/**
+ * camel_store_rename_folder_sync:
+ * @store: a #CamelStore
+ * @old_name: the current name of the folder
+ * @new_name: the new name of the folder
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Renames the folder described by @old_name to @new_name.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_store_rename_folder_sync (CamelStore *store,
+ const gchar *old_namein,
+ const gchar *new_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStoreClass *class;
+ CamelFolder *folder;
+ gint i, oldlen, namelen;
+ GPtrArray *folders = NULL;
+ gchar *old_name;
+ gboolean success;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (old_namein != NULL, FALSE);
+ g_return_val_if_fail (new_name != NULL, FALSE);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->rename_folder_sync != NULL, FALSE);
+
+ if (strcmp (old_namein, new_name) == 0)
+ return TRUE;
+
+ if (((store->flags & CAMEL_STORE_VTRASH) && strcmp (old_namein, CAMEL_VTRASH_NAME) == 0)
+ || ((store->flags & CAMEL_STORE_VJUNK) && strcmp (old_namein, CAMEL_VJUNK_NAME) == 0)) {
+ g_set_error (
+ error, CAMEL_STORE_ERROR,
+ CAMEL_STORE_ERROR_NO_FOLDER,
+ _("Cannot rename folder: %s: Invalid operation"),
+ old_namein);
+ return FALSE;
+ }
+
+ /* need to save this, since old_namein might be folder->full_name, which could go away */
+ old_name = g_strdup (old_namein);
+ oldlen = strlen (old_name);
+
+ camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ return FALSE;
+ }
+
+ /* If the folder is open (or any subfolders of the open folder)
+ We need to rename them atomically with renaming the actual folder path */
+ if (store->folders) {
+ folders = camel_object_bag_list (store->folders);
+ for (i=0;i<folders->len;i++) {
+ const gchar *full_name;
+
+ folder = folders->pdata[i];
+ full_name = camel_folder_get_full_name (folder);
+
+ namelen = strlen (full_name);
+ if ((namelen == oldlen &&
+ strcmp (full_name, old_name) == 0)
+ || ((namelen > oldlen)
+ && strncmp (full_name, old_name, oldlen) == 0
+ && full_name[oldlen] == '/')) {
+ camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
+ } else {
+ g_ptr_array_remove_index_fast (folders, i);
+ i--;
+ g_object_unref (folder);
+ }
+ }
+ }
+
+ /* Now try the real rename (will emit renamed signal) */
+ success = class->rename_folder_sync (
+ store, old_name, new_name, cancellable, error);
+ CAMEL_CHECK_GERROR (store, rename_folder_sync, success, error);
+
+ /* If it worked, update all open folders/unlock them */
+ if (folders) {
+ if (success) {
+ guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE;
+ CamelFolderInfo *folder_info;
+
+ for (i=0;i<folders->len;i++) {
+ const gchar *full_name;
+ gchar *new;
+
+ folder = folders->pdata[i];
+ full_name = camel_folder_get_full_name (folder);
+
+ new = g_strdup_printf("%s%s", new_name, full_name + strlen(old_name));
+ camel_object_bag_rekey (store->folders, folder, new);
+ camel_folder_rename (folder, new);
+ g_free (new);
+
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+ g_object_unref (folder);
+ }
+
+ /* Emit renamed signal */
+ if (store->flags & CAMEL_STORE_SUBSCRIPTIONS)
+ flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
+
+ folder_info = class->get_folder_info_sync (
+ store, new_name, flags, cancellable, error);
+ CAMEL_CHECK_GERROR (store, get_folder_info, folder_info != NULL, error);
+
+ if (folder_info != NULL) {
+ camel_store_folder_renamed (store, old_name, folder_info);
+ class->free_folder_info (store, folder_info);
+ }
+ } else {
+ /* Failed, just unlock our folders for re-use */
+ for (i=0;i<folders->len;i++) {
+ folder = folders->pdata[i];
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+ g_object_unref (folder);
+ }
+ }
+ }
+
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ g_ptr_array_free (folders, TRUE);
+ g_free (old_name);
+
+ return success;
+}
+
+/**
+ * camel_store_rename_folder:
+ * @store: a #CamelStore
+ * @old_name: the current name of the folder
+ * @new_name: the new name of the folder
+ * @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 renames the folder described by @old_name to @new_name.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_store_rename_folder_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_rename_folder (CamelStore *store,
+ const gchar *old_name,
+ const gchar *new_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (old_name != NULL);
+ g_return_if_fail (new_name != NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->rename_folder != NULL);
+
+ class->rename_folder (
+ store, old_name, new_name, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_rename_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_rename_folder().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_store_rename_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->rename_folder_finish != NULL, FALSE);
+
+ return class->rename_folder_finish (store, result, error);
+}
+
+/**
* camel_store_subscribe_folder_sync:
- * @store: a #CamelStore object
+ * @store: a #CamelStore
* @folder_name: full path of the folder
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
- * Subscribe to the folder described by @folder_name.
+ * Subscribes to the folder described by @folder_name.
*
- * Returns: %TRUE on success, %FALSE on failure
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
gboolean
camel_store_subscribe_folder_sync (CamelStore *store,
@@ -1526,6 +3054,12 @@ camel_store_subscribe_folder_sync (CamelStore *store,
camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ return FALSE;
+ }
+
success = class->subscribe_folder_sync (
store, folder_name, cancellable, error);
CAMEL_CHECK_GERROR (store, subscribe_folder_sync, success, error);
@@ -1536,15 +3070,83 @@ camel_store_subscribe_folder_sync (CamelStore *store,
}
/**
+ * camel_store_subscribe_folder:
+ * @store: a #CamelStore
+ * @folder_name: full path of the folder
+ * @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 subscribes to the folder described by @folder_name.
+ *
+ * When the operation is finished, @callback will be called. You can
+ * then call camel_store_subscribe_folder_finish() to get the result of
+ * the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_subscribe_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (folder_name != NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->subscribe_folder != NULL);
+
+ class->subscribe_folder (
+ store, folder_name, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_subscribe_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_subscribe_folder().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_store_subscribe_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->subscribe_folder_finish != NULL, FALSE);
+
+ return class->subscribe_folder_finish (store, result, error);
+}
+
+/**
* camel_store_unsubscribe_folder_sync:
- * @store: a #CamelStore object
+ * @store: a #CamelStore
* @folder_name: full path of the folder
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
- * Unsubscribe from the folder described by @folder_name.
+ * Unsubscribes from the folder described by @folder_name.
*
- * Returns: %TRUE on success, %FALSE on failure
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
gboolean
camel_store_unsubscribe_folder_sync (CamelStore *store,
@@ -1564,6 +3166,12 @@ camel_store_unsubscribe_folder_sync (CamelStore *store,
camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ return FALSE;
+ }
+
success = class->unsubscribe_folder_sync (
store, folder_name, cancellable, error);
CAMEL_CHECK_GERROR (store, unsubscribe_folder_sync, success, error);
@@ -1577,171 +3185,257 @@ camel_store_unsubscribe_folder_sync (CamelStore *store,
}
/**
- * camel_store_noop_sync:
- * @store: a #CamelStore object
+ * camel_store_unsubscribe_folder:
+ * @store: a #CamelStore
+ * @folder_name: full path of the folder
+ * @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 unsubscribes from the folder described by @folder_name.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_store_unsubscribe_folder_finish() to get the result of the
+ * operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_unsubscribe_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (folder_name != NULL);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->unsubscribe_folder != NULL);
+
+ class->unsubscribe_folder (
+ store, folder_name, io_priority,
+ cancellable, callback, user_data);
+}
+
+/**
+ * camel_store_unsubscribe_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
* @error: return location for a #GError, or %NULL
*
- * Pings @store so that its connection doesn't timeout.
+ * Finishes the operation started with camel_store_unsubscribe_folder().
*
- * Returns: %TRUE on success, %FALSE on failure
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
gboolean
-camel_store_noop_sync (CamelStore *store,
- GCancellable *cancellable,
- GError **error)
+camel_store_unsubscribe_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
CamelStoreClass *class;
- gboolean success;
g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->noop_sync != NULL, FALSE);
-
- success = class->noop_sync (store, cancellable, error);
- CAMEL_CHECK_GERROR (store, noop_sync, success, error);
+ g_return_val_if_fail (class->unsubscribe_folder_finish != NULL, FALSE);
- return success;
+ return class->unsubscribe_folder_finish (store, result, error);
}
/**
- * camel_store_folder_uri_equal:
- * @store: a #CamelStore object
- * @uri0: a folder uri
- * @uri1: another folder uri
+ * camel_store_synchronize_sync:
+ * @store: a #CamelStore
+ * @expunge: whether to expunge after synchronizing
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
*
- * Compares two folder uris to check that they are equal.
+ * Synchronizes any changes that have been made to @store and its folders
+ * with the real store.
*
- * Returns: %TRUE if they are equal or %FALSE otherwise
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
-gint
-camel_store_folder_uri_equal (CamelStore *store,
- const gchar *uri0,
- const gchar *uri1)
+gboolean
+camel_store_synchronize_sync (CamelStore *store,
+ gboolean expunge,
+ GCancellable *cancellable,
+ GError **error)
{
CamelStoreClass *class;
- CamelProvider *provider;
- CamelURL *url0, *url1;
- gint equal;
+ gboolean success;
g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
- g_return_val_if_fail (uri0 && uri1, FALSE);
class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->compare_folder_name != NULL, FALSE);
+ g_return_val_if_fail (class->synchronize_sync != NULL, FALSE);
- provider = ((CamelService *) store)->provider;
+ success = class->synchronize_sync (store, expunge, cancellable, error);
+ CAMEL_CHECK_GERROR (store, synchronize_sync, success, error);
- if (!(url0 = camel_url_new (uri0, NULL)))
- return FALSE;
+ return success;
+}
- if (!(url1 = camel_url_new (uri1, NULL))) {
- camel_url_free (url0);
- return FALSE;
- }
+/**
+ * camel_store_synchronize:
+ * @store: a #CamelStore
+ * @expunge: whether to expunge after synchronizing
+ * @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
+ *
+ * Synchronizes any changes that have been made to @store and its folders
+ * with the real store asynchronously.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_store_synchronize_finish() to get the result of the operation.
+ *
+ * Since: 2.34
+ **/
+void
+camel_store_synchronize (CamelStore *store,
+ gboolean expunge,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CamelStoreClass *class;
- if ((equal = provider->url_equal (url0, url1))) {
- const gchar *name0, *name1;
+ g_return_if_fail (CAMEL_IS_STORE (store));
- if (provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) {
- name0 = url0->fragment;
- name1 = url1->fragment;
- } else {
- name0 = url0->path && url0->path[0] == '/' ? url0->path + 1 : url0->path;
- name1 = url1->path && url1->path[0] == '/' ? url1->path + 1 : url1->path;
- }
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->synchronize != NULL);
- if (name0 == NULL)
- g_warning("URI is badly formed, missing folder name: %s", uri0);
+ class->synchronize (
+ store, expunge, io_priority,
+ cancellable, callback, user_data);
+}
- if (name1 == NULL)
- g_warning("URI is badly formed, missing folder name: %s", uri1);
+/**
+ * camel_store_synchronize_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_synchronize().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
+ **/
+gboolean
+camel_store_synchronize_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ CamelStoreClass *class;
- equal = name0 && name1 && class->compare_folder_name (name0, name1);
- }
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
- camel_url_free (url0);
- camel_url_free (url1);
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->synchronize_finish != NULL, FALSE);
- return equal;
+ return class->synchronize_finish (store, result, error);
}
/**
- * camel_store_can_refresh_folder
+ * camel_store_noop_sync:
* @store: a #CamelStore
- * @info: a #CamelFolderInfo
+ * @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
- * Returns if this folder (param info) should be checked for new mail or not.
- * It should not look into sub infos (info->child) or next infos, it should
- * return value only for the actual folder info.
- * Default behavior is that all Inbox folders are intended to be refreshed.
+ * Pings @store so its connection doesn't time out.
*
- * Returns: whether folder should be checked for new mails
+ * Returns: %TRUE on success, %FALSE on error
*
- * Since: 2.22
+ * Since: 2.34
**/
gboolean
-camel_store_can_refresh_folder (CamelStore *store,
- CamelFolderInfo *info,
- GError **error)
+camel_store_noop_sync (CamelStore *store,
+ GCancellable *cancellable,
+ GError **error)
{
CamelStoreClass *class;
+ gboolean success;
g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
- g_return_val_if_fail (info != NULL, FALSE);
class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->can_refresh_folder != NULL, FALSE);
+ g_return_val_if_fail (class->noop_sync != NULL, FALSE);
- return class->can_refresh_folder (store, info, error);
+ success = class->noop_sync (store, cancellable, error);
+ CAMEL_CHECK_GERROR (store, noop_sync, success, error);
+
+ return success;
}
/**
- * camel_store_lock:
+ * camel_store_noop:
* @store: a #CamelStore
- * @lock: lock type to lock
+ * @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
*
- * Locks #store's #lock. Unlock it with camel_store_unlock().
+ * Pings @store asynchronously so its connection doesn't time out.
*
- * Since: 2.32
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_store_noop_finish() to get the result of the operation.
+ *
+ * Since: 2.34
**/
void
-camel_store_lock (CamelStore *store,
- CamelStoreLock lock)
+camel_store_noop (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
+ CamelStoreClass *class;
+
g_return_if_fail (CAMEL_IS_STORE (store));
- switch (lock) {
- case CAMEL_STORE_FOLDER_LOCK:
- g_static_rec_mutex_lock (&store->priv->folder_lock);
- break;
- default:
- g_return_if_reached ();
- }
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->noop != NULL);
+
+ class->noop (store, io_priority, cancellable, callback, user_data);
}
/**
- * camel_store_unlock:
+ * camel_store_noop_finish:
* @store: a #CamelStore
- * @lock: lock type to unlock
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
*
- * Unlocks #store's #lock, previously locked with camel_store_lock().
+ * Finishes the operation started with camel_store_noop().
*
- * Since: 2.32
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
-void
-camel_store_unlock (CamelStore *store,
- CamelStoreLock lock)
+gboolean
+camel_store_noop_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- g_return_if_fail (CAMEL_IS_STORE (store));
+ CamelStoreClass *class;
- switch (lock) {
- case CAMEL_STORE_FOLDER_LOCK:
- g_static_rec_mutex_unlock (&store->priv->folder_lock);
- break;
- default:
- g_return_if_reached ();
- }
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->noop_finish != NULL, FALSE);
+
+ return class->noop_finish (store, result, error);
}
diff --git a/camel/camel-store.h b/camel/camel-store.h
index 641c6e186..ce53de6a5 100644
--- a/camel/camel-store.h
+++ b/camel/camel-store.h
@@ -220,7 +220,7 @@ struct _CamelStoreClass {
GHashFunc hash_folder_name;
GCompareFunc compare_folder_name;
- /* Methods */
+ /* Non-Blocking Methods */
gboolean (*can_refresh_folder) (CamelStore *store,
CamelFolderInfo *info,
GError **error);
@@ -229,6 +229,7 @@ struct _CamelStoreClass {
void (*free_folder_info) (CamelStore *store,
CamelFolderInfo *fi);
+ /* Synchronous I/O Methods */
CamelFolder * (*get_folder_sync) (CamelStore *store,
const gchar *folder_name,
guint32 flags,
@@ -284,6 +285,124 @@ struct _CamelStoreClass {
GCancellable *cancellable,
GError **error);
+ /* Asyncrhonous I/O Methods (all have defaults) */
+ void (*get_folder) (CamelStore *store,
+ const gchar *folder_name,
+ guint32 flags,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ CamelFolder * (*get_folder_finish) (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*get_folder_info) (CamelStore *store,
+ const gchar *top,
+ guint32 flags,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ CamelFolderInfo *
+ (*get_folder_info_finish)
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*get_inbox_folder) (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ CamelFolder * (*get_inbox_folder_finish)
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*get_junk_folder) (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ CamelFolder * (*get_junk_folder_finish)
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*get_trash_folder) (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ CamelFolder * (*get_trash_folder_finish)
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*create_folder) (CamelStore *store,
+ const gchar *parent_name,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ CamelFolderInfo *
+ (*create_folder_finish) (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*delete_folder) (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*delete_folder_finish) (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*rename_folder) (CamelStore *store,
+ const gchar *old_name,
+ const gchar *new_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*rename_folder_finish) (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*subscribe_folder) (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*subscribe_folder_finish)
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*unsubscribe_folder) (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*unsubscribe_folder_finish)
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*synchronize) (CamelStore *store,
+ gboolean expunge,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*synchronize_finish) (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+ void (*noop) (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*noop_finish) (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+
/* Signals */
void (*folder_created) (CamelStore *store,
CamelFolderInfo *info);
@@ -352,6 +471,16 @@ CamelFolder * camel_store_get_folder_sync (CamelStore *store,
guint32 flags,
GCancellable *cancellable,
GError **error);
+void camel_store_get_folder (CamelStore *store,
+ const gchar *folder_name,
+ guint32 flags,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+CamelFolder * camel_store_get_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
CamelFolderInfo *
camel_store_get_folder_info_sync
(CamelStore *store,
@@ -359,50 +488,159 @@ CamelFolderInfo *
guint32 flags,
GCancellable *cancellable,
GError **error);
+void camel_store_get_folder_info (CamelStore *store,
+ const gchar *top,
+ guint32 flags,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+CamelFolderInfo *
+ camel_store_get_folder_info_finish
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
CamelFolder * camel_store_get_inbox_folder_sync
(CamelStore *store,
GCancellable *cancellable,
GError **error);
-CamelFolder * camel_store_get_trash_folder_sync
- (CamelStore *store,
+void camel_store_get_inbox_folder (CamelStore *store,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+CamelFolder * camel_store_get_inbox_folder_finish
+ (CamelStore *store,
+ GAsyncResult *result,
GError **error);
CamelFolder * camel_store_get_junk_folder_sync
(CamelStore *store,
GCancellable *cancellable,
GError **error);
+void camel_store_get_junk_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+CamelFolder * camel_store_get_junk_folder_finish
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
+CamelFolder * camel_store_get_trash_folder_sync
+ (CamelStore *store,
+ GCancellable *cancellable,
+ GError **error);
+void camel_store_get_trash_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+CamelFolder * camel_store_get_trash_folder_finish
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
CamelFolderInfo *
camel_store_create_folder_sync (CamelStore *store,
const gchar *parent_name,
const gchar *folder_name,
GCancellable *cancellable,
GError **error);
+void camel_store_create_folder (CamelStore *store,
+ const gchar *parent_name,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+CamelFolderInfo *
+ camel_store_create_folder_finish
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
gboolean camel_store_delete_folder_sync (CamelStore *store,
const gchar *folder_name,
GCancellable *cancellable,
GError **error);
+void camel_store_delete_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_store_delete_folder_finish
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
gboolean camel_store_rename_folder_sync (CamelStore *store,
- const gchar *old_namein,
+ const gchar *old_name,
const gchar *new_name,
GCancellable *cancellable,
GError **error);
+void camel_store_rename_folder (CamelStore *store,
+ const gchar *old_name,
+ const gchar *new_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_store_rename_folder_finish
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
gboolean camel_store_subscribe_folder_sync
(CamelStore *store,
const gchar *folder_name,
GCancellable *cancellable,
GError **error);
+void camel_store_subscribe_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_store_subscribe_folder_finish
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
gboolean camel_store_unsubscribe_folder_sync
(CamelStore *store,
const gchar *folder_name,
GCancellable *cancellable,
GError **error);
+void camel_store_unsubscribe_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_store_unsubscribe_folder_finish
+ (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
gboolean camel_store_synchronize_sync (CamelStore *store,
gboolean expunge,
GCancellable *cancellable,
GError **error);
+void camel_store_synchronize (CamelStore *store,
+ gboolean expunge,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_store_synchronize_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
gboolean camel_store_noop_sync (CamelStore *store,
GCancellable *cancellable,
GError **error);
+void camel_store_noop (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_store_noop_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/camel/camel-transport.c b/camel/camel-transport.c
index 24bdc7b7e..068c2ef4e 100644
--- a/camel/camel-transport.c
+++ b/camel/camel-transport.c
@@ -36,13 +36,37 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), CAMEL_TYPE_TRANSPORT, CamelTransportPrivate))
+typedef struct _AsyncContext AsyncContext;
+
struct _CamelTransportPrivate {
GMutex *send_lock; /* for locking send operations */
};
+struct _AsyncContext {
+ /* arguments */
+ CamelAddress *from;
+ CamelAddress *recipients;
+ CamelMimeMessage *message;
+};
+
G_DEFINE_ABSTRACT_TYPE (CamelTransport, camel_transport, CAMEL_TYPE_SERVICE)
static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->from != NULL)
+ g_object_unref (async_context->from);
+
+ if (async_context->recipients != NULL)
+ g_object_unref (async_context->recipients);
+
+ if (async_context->message != NULL)
+ g_object_unref (async_context->message);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
transport_finalize (GObject *object)
{
CamelTransportPrivate *priv;
@@ -56,6 +80,74 @@ transport_finalize (GObject *object)
}
static void
+transport_send_to_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ camel_transport_send_to_sync (
+ CAMEL_TRANSPORT (object), async_context->message,
+ async_context->from, async_context->recipients,
+ cancellable, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+static void
+transport_send_to (CamelTransport *transport,
+ CamelMimeMessage *message,
+ CamelAddress *from,
+ CamelAddress *recipients,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->from = g_object_ref (from);
+ async_context->recipients = g_object_ref (recipients);
+ async_context->message = g_object_ref (message);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (transport), callback, user_data, transport_send_to);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, transport_send_to_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+transport_send_to_finish (CamelTransport *transport,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (transport), transport_send_to), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
camel_transport_class_init (CamelTransportClass *class)
{
GObjectClass *object_class;
@@ -64,6 +156,9 @@ camel_transport_class_init (CamelTransportClass *class)
object_class = G_OBJECT_CLASS (class);
object_class->finalize = transport_finalize;
+
+ class->send_to = transport_send_to;
+ class->send_to_finish = transport_send_to_finish;
}
static void
@@ -75,8 +170,56 @@ camel_transport_init (CamelTransport *transport)
}
/**
+ * camel_transport_lock:
+ * @transport: a #CamelTransport
+ * @lock: lock type to lock
+ *
+ * Locks #transport's #lock. Unlock it with camel_transport_unlock().
+ *
+ * Since: 2.32
+ **/
+void
+camel_transport_lock (CamelTransport *transport,
+ CamelTransportLock lock)
+{
+ g_return_if_fail (CAMEL_IS_TRANSPORT (transport));
+
+ switch (lock) {
+ case CAMEL_TRANSPORT_SEND_LOCK:
+ g_mutex_lock (transport->priv->send_lock);
+ break;
+ default:
+ g_return_if_reached ();
+ }
+}
+
+/**
+ * camel_transport_unlock:
+ * @transport: a #CamelTransport
+ * @lock: lock type to unlock
+ *
+ * Unlocks #transport's #lock, previously locked with camel_transport_lock().
+ *
+ * Since: 2.32
+ **/
+void
+camel_transport_unlock (CamelTransport *transport,
+ CamelTransportLock lock)
+{
+ g_return_if_fail (CAMEL_IS_TRANSPORT (transport));
+
+ switch (lock) {
+ case CAMEL_TRANSPORT_SEND_LOCK:
+ g_mutex_unlock (transport->priv->send_lock);
+ break;
+ default:
+ g_return_if_reached ();
+ }
+}
+
+/**
* camel_transport_send_to_sync:
- * @transport: a #CamelTransport object
+ * @transport: a #CamelTransport
* @message: a #CamelMimeMessage to send
* @from: a #CamelAddress to send from
* @recipients: a #CamelAddress containing all recipients
@@ -84,10 +227,12 @@ camel_transport_init (CamelTransport *transport)
* @error: return location for a #GError, or %NULL
*
* Sends the message to the given recipients, regardless of the contents
- * of @message. If the message contains a "Bcc" header, the transport
+ * of @message. If the message contains a "Bcc" header, the transport
* is responsible for stripping it.
*
- * Return %TRUE on success or %FALSE on fail
+ * Returns: %TRUE on success or %FALSE on error
+ *
+ * Since: 2.34
**/
gboolean
camel_transport_send_to_sync (CamelTransport *transport,
@@ -110,6 +255,12 @@ camel_transport_send_to_sync (CamelTransport *transport,
camel_transport_lock (transport, CAMEL_TRANSPORT_SEND_LOCK);
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_transport_unlock (transport, CAMEL_TRANSPORT_SEND_LOCK);
+ return FALSE;
+ }
+
success = class->send_to_sync (
transport, message, from, recipients, cancellable, error);
CAMEL_CHECK_GERROR (transport, send_to_sync, success, error);
@@ -120,49 +271,74 @@ camel_transport_send_to_sync (CamelTransport *transport,
}
/**
- * camel_transport_lock:
+ * camel_transport_send_to:
* @transport: a #CamelTransport
- * @lock: lock type to lock
+ * @message: a #CamelMimeMessage to send
+ * @from: a #CamelAddress to send from
+ * @recipients: a #CamelAddress containing all recipients
+ * @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
*
- * Locks #transport's #lock. Unlock it with camel_transport_unlock().
+ * Sends the message asynchronously to the given recipients, regardless of
+ * the contents of @message. If the message contains a "Bcc" header, the
+ * transport is responsible for stripping it.
*
- * Since: 2.32
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_transport_send_to_finish() to get the result of the operation.
+ *
+ * Since: 2.34
**/
void
-camel_transport_lock (CamelTransport *transport,
- CamelTransportLock lock)
+camel_transport_send_to (CamelTransport *transport,
+ CamelMimeMessage *message,
+ CamelAddress *from,
+ CamelAddress *recipients,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
+ CamelTransportClass *class;
+
g_return_if_fail (CAMEL_IS_TRANSPORT (transport));
+ g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
+ g_return_if_fail (CAMEL_IS_ADDRESS (from));
+ g_return_if_fail (CAMEL_IS_ADDRESS (recipients));
- switch (lock) {
- case CAMEL_TRANSPORT_SEND_LOCK:
- g_mutex_lock (transport->priv->send_lock);
- break;
- default:
- g_return_if_reached ();
- }
+ class = CAMEL_TRANSPORT_GET_CLASS (transport);
+ g_return_if_fail (class->send_to != NULL);
+
+ class->send_to (
+ transport, message, from, recipients, io_priority,
+ cancellable, callback, user_data);
}
/**
- * camel_transport_unlock:
+ * camel_transport_send_to_finish:
* @transport: a #CamelTransport
- * @lock: lock type to unlock
+ * @result: a #GAsyncResult
+ * @error: return locaton for a #GError, or %NULL
*
- * Unlocks #transport's #lock, previously locked with camel_transport_lock().
+ * Finishes the operation started with camel_transport_send_to().
*
- * Since: 2.32
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
-void
-camel_transport_unlock (CamelTransport *transport,
- CamelTransportLock lock)
+gboolean
+camel_transport_send_to_finish (CamelTransport *transport,
+ GAsyncResult *result,
+ GError **error)
{
- g_return_if_fail (CAMEL_IS_TRANSPORT (transport));
+ CamelTransportClass *class;
- switch (lock) {
- case CAMEL_TRANSPORT_SEND_LOCK:
- g_mutex_unlock (transport->priv->send_lock);
- break;
- default:
- g_return_if_reached ();
- }
+ g_return_val_if_fail (CAMEL_IS_TRANSPORT (transport), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ class = CAMEL_TRANSPORT_GET_CLASS (transport);
+ g_return_val_if_fail (class->send_to_finish != NULL, FALSE);
+
+ return class->send_to_finish (transport, result, error);
}
diff --git a/camel/camel-transport.h b/camel/camel-transport.h
index 7a5396143..ce01ef296 100644
--- a/camel/camel-transport.h
+++ b/camel/camel-transport.h
@@ -76,26 +76,52 @@ struct _CamelTransport {
struct _CamelTransportClass {
CamelServiceClass parent_class;
+ /* Synchronous I/O Methods */
gboolean (*send_to_sync) (CamelTransport *transport,
CamelMimeMessage *message,
CamelAddress *from,
CamelAddress *recipients,
GCancellable *cancellable,
GError **error);
-};
-GType camel_transport_get_type (void);
-gboolean camel_transport_send_to_sync (CamelTransport *transport,
+ /* Asynchronous I/O Methods (all have defaults) */
+ void (*send_to) (CamelTransport *transport,
CamelMimeMessage *message,
CamelAddress *from,
CamelAddress *recipients,
+ gint io_priority,
GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*send_to_finish) (CamelTransport *transport,
+ GAsyncResult *result,
GError **error);
+};
+
+GType camel_transport_get_type (void);
void camel_transport_lock (CamelTransport *transport,
CamelTransportLock lock);
void camel_transport_unlock (CamelTransport *transport,
CamelTransportLock lock);
+gboolean camel_transport_send_to_sync (CamelTransport *transport,
+ CamelMimeMessage *message,
+ CamelAddress *from,
+ CamelAddress *recipients,
+ GCancellable *cancellable,
+ GError **error);
+void camel_transport_send_to (CamelTransport *transport,
+ CamelMimeMessage *message,
+ CamelAddress *from,
+ CamelAddress *recipients,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_transport_send_to_finish (CamelTransport *transport,
+ GAsyncResult *result,
+ GError **error);
+
G_END_DECLS
#endif /* CAMEL_TRANSPORT_H */
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index 858510871..17c985ccc 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -1210,7 +1210,7 @@ vee_folder_thaw (CamelFolder *folder)
static gboolean
vee_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -1372,8 +1372,8 @@ static gboolean
vee_folder_transfer_messages_to_sync (CamelFolder *folder,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
diff --git a/camel/camel-vtrash-folder.c b/camel/camel-vtrash-folder.c
index 63fd5dbc7..31fd3877a 100644
--- a/camel/camel-vtrash-folder.c
+++ b/camel/camel-vtrash-folder.c
@@ -70,7 +70,7 @@ transfer_messages (CamelFolder *folder,
camel_folder_transfer_messages_to_sync (
md->folder, md->uids, md->dest,
- NULL, md->delete, md->cancellable, error);
+ md->delete, NULL, md->cancellable, error);
if (md->cancellable != NULL)
g_object_unref (md->cancellable);
@@ -86,7 +86,7 @@ transfer_messages (CamelFolder *folder,
static gboolean
vtrash_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -102,8 +102,8 @@ static gboolean
vtrash_folder_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
diff --git a/camel/providers/groupwise/camel-groupwise-folder.c b/camel/providers/groupwise/camel-groupwise-folder.c
index 53da6ce67..622c57ba6 100644
--- a/camel/providers/groupwise/camel-groupwise-folder.c
+++ b/camel/providers/groupwise/camel-groupwise-folder.c
@@ -77,7 +77,7 @@ struct _CamelGroupwiseFolderPrivate {
extern gint camel_application_is_exiting;
/*prototypes*/
-static gboolean groupwise_transfer_messages_to_sync (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, GPtrArray **transferred_uids, gboolean delete_originals, GCancellable *cancellable, GError **error);
+static gboolean groupwise_transfer_messages_to_sync (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, gboolean delete_originals, GPtrArray **transferred_uids, GCancellable *cancellable, GError **error);
void convert_to_calendar (EGwItem *item, gchar **str, gint *len);
static void convert_to_task (EGwItem *item, gchar **str, gint *len);
static void convert_to_note (EGwItem *item, gchar **str, gint *len);
@@ -548,7 +548,7 @@ move_to_mailbox (CamelFolder *folder,
CAMEL_GW_MESSAGE_JUNK, 0);
if (dest)
groupwise_transfer_messages_to_sync (
- folder, uids, dest, NULL, TRUE, cancellable, error);
+ folder, uids, dest, TRUE, NULL, cancellable, error);
else
g_warning ("No Mailbox folder found");
@@ -577,7 +577,7 @@ move_to_junk (CamelFolder *folder,
if (dest)
groupwise_transfer_messages_to_sync (
- folder, uids, dest, NULL, TRUE, cancellable, error);
+ folder, uids, dest, TRUE, NULL, cancellable, error);
else {
fi = create_junk_folder (parent_store);
dest = camel_store_get_folder_sync (
@@ -586,7 +586,7 @@ move_to_junk (CamelFolder *folder,
g_warning ("Could not get JunkFolder:Message not moved");
else
groupwise_transfer_messages_to_sync (
- folder, uids, dest, NULL, TRUE, cancellable, error);
+ folder, uids, dest, TRUE, NULL, cancellable, error);
}
update_junk_list (parent_store, info, ADD_JUNK_ENTRY);
}
@@ -1030,7 +1030,7 @@ update_update (CamelSession *session,
goto end1;
}
- camel_operation_start (
+ camel_operation_push_message (
msg->cancellable,
_("Checking for deleted messages %s"),
camel_folder_get_name (m->folder));
@@ -1103,12 +1103,12 @@ update_update (CamelSession *session,
g_print ("\nNumber of items in the folder: %d \n", g_list_length(items_full_list));
gw_update_all_items (m->folder, items_full_list, NULL, NULL);
- camel_operation_end (msg->cancellable);
+ camel_operation_pop_message (msg->cancellable);
return;
end1:
camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- camel_operation_end (msg->cancellable);
+ camel_operation_pop_message (msg->cancellable);
if (items_full_list) {
g_list_foreach (items_full_list, (GFunc)g_free, NULL);
g_list_free (items_full_list);
@@ -1515,7 +1515,7 @@ gw_update_cache (CamelFolder *folder,
is_junk = TRUE;
}
- camel_operation_start (
+ camel_operation_push_message (
cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (folder));
@@ -1714,7 +1714,7 @@ gw_update_cache (CamelFolder *folder,
g_object_unref (item);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_free (container_id);
g_string_free (str_to, TRUE);
@@ -2060,7 +2060,7 @@ groupwise_folder_item_to_msg ( CamelFolder *folder,
msg = camel_mime_message_new ();
if (has_mime_822 && body) {
temp_stream = camel_stream_mem_new_with_buffer (body, body_len);
- if (camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, temp_stream, NULL, error) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, temp_stream, NULL, error)) {
g_object_unref (msg);
g_object_unref (temp_stream);
msg = NULL;
@@ -2398,7 +2398,7 @@ groupwise_folder_constructed (GObject *object)
static gboolean
groupwise_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -2653,7 +2653,7 @@ groupwise_folder_get_message_sync (CamelFolder *folder,
camel_stream_reset (stream, NULL);
camel_stream_write_to_stream (cache_stream, stream, cancellable, NULL);
camel_stream_reset (stream, NULL);
- if (camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, cancellable, error) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, cancellable, error)) {
if (errno == EINTR) {
g_object_unref (msg);
g_object_unref (cache_stream);
@@ -2810,8 +2810,8 @@ static gboolean
groupwise_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *destination,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
diff --git a/camel/providers/groupwise/camel-groupwise-journal.c b/camel/providers/groupwise/camel-groupwise-journal.c
index 0927106cc..81fa47cbc 100644
--- a/camel/providers/groupwise/camel-groupwise-journal.c
+++ b/camel/providers/groupwise/camel-groupwise-journal.c
@@ -175,7 +175,7 @@ groupwise_entry_play_append (CamelOfflineJournal *journal,
}
message = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) message, stream, cancellable, error) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) message, stream, cancellable, error)) {
g_object_unref (message);
g_object_unref (stream);
goto done;
@@ -229,7 +229,7 @@ groupwise_entry_play_transfer (CamelOfflineJournal *journal,
g_ptr_array_add (uids, entry->original_uid);
if (camel_folder_transfer_messages_to_sync (
- src, uids, folder, &xuids, FALSE, cancellable, error)) {
+ src, uids, folder, FALSE, &xuids, cancellable, error)) {
real = (CamelGroupwiseMessageInfo *) camel_folder_summary_uid (folder->summary, xuids->pdata[0]);
/* transfer all the system flags, user flags/tags, etc */
diff --git a/camel/providers/groupwise/camel-groupwise-store.c b/camel/providers/groupwise/camel-groupwise-store.c
index cdc8cd9da..0a8d5ff48 100644
--- a/camel/providers/groupwise/camel-groupwise-store.c
+++ b/camel/providers/groupwise/camel-groupwise-store.c
@@ -667,7 +667,7 @@ groupwise_store_get_folder_sync (CamelStore *store,
return NULL;
}
- camel_operation_start (
+ camel_operation_push_message (
cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (folder));
@@ -712,7 +712,7 @@ groupwise_store_get_folder_sync (CamelStore *store,
e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
}
if (done && all_ok) {
if (summary->time_string)
@@ -798,7 +798,7 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store,
return FALSE;
}
- camel_operation_start (
+ camel_operation_push_message (
cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (folder));
@@ -815,7 +815,7 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store,
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_INVALID,
_("Authentication failed"));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_free (container_id);
return FALSE;
}
@@ -849,7 +849,7 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store,
e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
}
if (done) {
diff --git a/camel/providers/groupwise/camel-groupwise-transport.c b/camel/providers/groupwise/camel-groupwise-transport.c
index 12caf78c4..3b5336ba4 100644
--- a/camel/providers/groupwise/camel-groupwise-transport.c
+++ b/camel/providers/groupwise/camel-groupwise-transport.c
@@ -94,7 +94,7 @@ groupwise_send_to_sync (CamelTransport *transport,
CAMEL_URL_HIDE_PARAMS |
CAMEL_URL_HIDE_AUTH) );
- camel_operation_start (cancellable, _("Sending Message") );
+ camel_operation_push_message (cancellable, _("Sending Message") );
/*camel groupwise store and cnc*/
store = camel_session_get_store (service->session, url, NULL);
@@ -113,7 +113,7 @@ groupwise_send_to_sync (CamelTransport *transport,
cnc = cnc_lookup (priv);
if (!cnc) {
g_warning ("||| Eh!!! Failure |||\n");
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_set_error (
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
@@ -140,7 +140,7 @@ groupwise_send_to_sync (CamelTransport *transport,
status = e_gw_connection_send_item (cnc, item, &sent_item_list);
if (status != E_GW_CONNECTION_STATUS_OK) {
g_warning (" Error Sending mail");
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
e_gw_item_set_link_info (item, NULL);
g_object_unref (item);
if (temp_item)
@@ -169,7 +169,7 @@ groupwise_send_to_sync (CamelTransport *transport,
g_object_unref (temp_item);
g_object_unref (item);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return TRUE;
}
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 0f073a37f..6517e803c 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -89,23 +89,27 @@ static CamelMimeMessage *imap_get_message_sync (CamelFolder *folder, const gchar
static gboolean imap_synchronize_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable,
GError **error);
static gboolean imap_append_online (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, gchar **appended_uid,
+ CamelMessageInfo *info, gchar **appended_uid,
GCancellable *cancellable,
GError **error);
static gboolean imap_append_offline (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, gchar **appended_uid,
+ CamelMessageInfo *info, gchar **appended_uid,
GError **error);
-static gboolean imap_transfer_online (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals,
- GCancellable *cancellable,
- GError **error);
-static gboolean imap_transfer_offline (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals,
- GCancellable *cancellable,
- GError **error);
+static gboolean imap_transfer_online (CamelFolder *source,
+ GPtrArray *uids,
+ CamelFolder *dest,
+ gboolean delete_originals,
+ GPtrArray **transferred_uids,
+ GCancellable *cancellable,
+ GError **error);
+static gboolean imap_transfer_offline (CamelFolder *source,
+ GPtrArray *uids,
+ CamelFolder *dest,
+ gboolean delete_originals,
+ GPtrArray **transferred_uids,
+ GCancellable *cancellable,
+ GError **error);
/* searching */
static GPtrArray *imap_search_by_expression (CamelFolder *folder, const gchar *expression, GError **error);
@@ -124,11 +128,14 @@ static CamelImapMessageInfo * imap_folder_summary_uid_or_error (
const gchar * uid,
GError **error);
-static gboolean
-imap_transfer_messages (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals, gboolean can_call_sync,
- GCancellable *cancellable, GError **error);
+static gboolean imap_transfer_messages (CamelFolder *source,
+ GPtrArray *uids,
+ CamelFolder *dest,
+ gboolean delete_originals,
+ GPtrArray **transferred_uids,
+ gboolean can_call_sync,
+ GCancellable *cancellable,
+ GError **error);
#ifdef G_OS_WIN32
/* The strtok() in Microsoft's C library is MT-safe (but still uses
@@ -979,13 +986,13 @@ imap_rescan (CamelFolder *folder,
}
/* Check UIDs and flags of all messages we already know of. */
- camel_operation_start (
+ camel_operation_push_message (
cancellable, _("Scanning for changed messages in %s"),
camel_folder_get_name (folder));
uid = camel_folder_summary_uid_from_index (folder->summary, summary_len - 1);
if (!uid) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return TRUE;
}
@@ -994,7 +1001,7 @@ imap_rescan (CamelFolder *folder,
"UID FETCH 1:%s (FLAGS)", uid);
g_free (uid);
if (!ok) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
@@ -1029,13 +1036,13 @@ imap_rescan (CamelFolder *folder,
}
if (summary_got == 0 && summary_len == 0) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
g_free (new);
return TRUE;
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) {
for (i = 0; i < summary_len && new[i].uid; i++) {
@@ -1486,8 +1493,8 @@ move_messages (CamelFolder *src_folder,
if (src_folder != des_folder) {
/* do 'copy' to not be bothered with CAMEL_MESSAGE_DELETED again */
if (!imap_transfer_messages (
- src_folder, uids, des_folder, NULL,
- FALSE, FALSE, cancellable, error))
+ src_folder, uids, des_folder, FALSE,
+ NULL, FALSE, cancellable, error))
return;
}
@@ -2175,7 +2182,7 @@ get_temp_uid (void)
static gboolean
imap_append_offline (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GError **error)
{
@@ -2231,7 +2238,7 @@ imap_folder_uid_in_ignore_recent (CamelImapFolder *imap_folder, const gchar *uid
static CamelImapResponse *
do_append (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **uid,
GCancellable *cancellable,
GError **error)
@@ -2341,7 +2348,7 @@ retry:
static gboolean
imap_append_online (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -2397,7 +2404,7 @@ imap_append_online (CamelFolder *folder,
gboolean
camel_imap_append_resyncing (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -2439,8 +2446,8 @@ static gboolean
imap_transfer_offline (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
@@ -2758,8 +2765,8 @@ static gboolean
imap_transfer_messages (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
gboolean can_call_sync,
GCancellable *cancellable,
GError **error)
@@ -2774,8 +2781,8 @@ imap_transfer_messages (CamelFolder *source,
if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store)))
return imap_transfer_offline (
- source, uids, dest, transferred_uids,
- delete_originals, cancellable, error);
+ source, uids, dest, delete_originals,
+ transferred_uids, cancellable, error);
/* Sync message flags if needed. */
if (can_call_sync && !imap_synchronize_sync (
@@ -2806,22 +2813,22 @@ static gboolean
imap_transfer_online (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
return imap_transfer_messages (
- source, uids, dest, transferred_uids,
- delete_originals, TRUE, cancellable, error);
+ source, uids, dest, delete_originals,
+ transferred_uids, TRUE, cancellable, error);
}
gboolean
camel_imap_transfer_resyncing (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
@@ -3097,7 +3104,7 @@ get_content (CamelImapFolder *imap_folder,
if (camel_content_type_is (ci->type, "multipart", "signed")) {
CamelMultipartSigned *body_mp;
gchar *spec;
- gint ret;
+ gboolean success;
/* Note: because we get the content parts uninterpreted anyway, we could potentially
just use the normalmultipart code, except that multipart/signed wont let you yet! */
@@ -3116,10 +3123,10 @@ get_content (CamelImapFolder *imap_folder,
stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, cancellable, error);
if (stream) {
- ret = camel_data_wrapper_construct_from_stream_sync (
+ success = camel_data_wrapper_construct_from_stream_sync (
CAMEL_DATA_WRAPPER (body_mp), stream, cancellable, error);
g_object_unref (CAMEL_OBJECT (stream));
- if (ret == -1) {
+ if (!success) {
g_object_unref ( body_mp);
return NULL;
}
@@ -3154,13 +3161,13 @@ get_content (CamelImapFolder *imap_folder,
sprintf (child_spec + speclen, "%d.MIME", num++);
stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, FALSE, cancellable, error);
if (stream) {
- gint ret;
+ gboolean success;
part = camel_mime_part_new ();
- ret = camel_data_wrapper_construct_from_stream_sync (
+ success = camel_data_wrapper_construct_from_stream_sync (
CAMEL_DATA_WRAPPER (part), stream, cancellable, error);
g_object_unref (CAMEL_OBJECT (stream));
- if (ret == -1) {
+ if (!success) {
g_object_unref (CAMEL_OBJECT (part));
g_object_unref (CAMEL_OBJECT (body_mp));
g_free (child_spec);
@@ -3244,7 +3251,7 @@ get_message (CamelImapFolder *imap_folder,
CamelMimeMessage *msg;
CamelStream *stream;
gchar *section_text, *part_spec;
- gint ret;
+ gboolean success;
folder = CAMEL_FOLDER (imap_folder);
parent_store = camel_folder_get_parent_store (folder);
@@ -3262,10 +3269,10 @@ get_message (CamelImapFolder *imap_folder,
return NULL;
msg = camel_mime_message_new ();
- ret = camel_data_wrapper_construct_from_stream_sync (
+ success = camel_data_wrapper_construct_from_stream_sync (
CAMEL_DATA_WRAPPER (msg), stream, cancellable, error);
g_object_unref (CAMEL_OBJECT (stream));
- if (ret == -1) {
+ if (!success) {
g_object_unref (CAMEL_OBJECT (msg));
return NULL;
}
@@ -3302,7 +3309,7 @@ get_message_simple (CamelImapFolder *imap_folder,
GError **error)
{
CamelMimeMessage *msg;
- gint ret;
+ gboolean success;
if (!stream) {
stream = camel_imap_folder_fetch_data (imap_folder, uid, "",
@@ -3312,10 +3319,10 @@ get_message_simple (CamelImapFolder *imap_folder,
}
msg = camel_mime_message_new ();
- ret = camel_data_wrapper_construct_from_stream_sync (
+ success = camel_data_wrapper_construct_from_stream_sync (
CAMEL_DATA_WRAPPER (msg), stream, cancellable, error);
g_object_unref (CAMEL_OBJECT (stream));
- if (ret == -1) {
+ if (!success) {
g_prefix_error (error, _("Unable to retrieve message: "));
g_object_unref (CAMEL_OBJECT (msg));
return NULL;
@@ -3730,8 +3737,8 @@ add_message_from_data (CamelFolder *folder,
g_ptr_array_set_size (messages, seq - first + 1);
msg = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream_sync (
- CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync (
+ CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL)) {
g_object_unref (CAMEL_OBJECT (msg));
return;
}
@@ -3907,7 +3914,7 @@ imap_update_summary (CamelFolder *folder,
return FALSE;
}
- camel_operation_start (
+ camel_operation_push_message (
cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (folder));
@@ -3954,7 +3961,7 @@ imap_update_summary (CamelFolder *folder,
g_ptr_array_add (fetch_data, data);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) {
if (type != CAMEL_IMAP_RESPONSE_ERROR && type != CAMEL_IMAP_RESPONSE_TAGGED)
@@ -3989,7 +3996,7 @@ imap_update_summary (CamelFolder *folder,
qsort (needheaders->pdata, needheaders->len,
sizeof (gpointer), uid_compar);
- camel_operation_start (
+ camel_operation_push_message (
cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (folder));
@@ -4000,7 +4007,7 @@ imap_update_summary (CamelFolder *folder,
"UID FETCH %s BODYSTRUCTURE BODY.PEEK[%s]",
uidset, header_spec->str)) {
g_ptr_array_free (needheaders, TRUE);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_free (uidset);
g_string_free (header_spec, TRUE);
goto lose;
@@ -4028,7 +4035,7 @@ imap_update_summary (CamelFolder *folder,
if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) {
g_ptr_array_free (needheaders, TRUE);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
if (type != CAMEL_IMAP_RESPONSE_ERROR && type != CAMEL_IMAP_RESPONSE_TAGGED)
camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -4038,7 +4045,7 @@ imap_update_summary (CamelFolder *folder,
}
g_string_free (header_spec, TRUE);
g_ptr_array_free (needheaders, TRUE);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
}
/* Now finish up summary entries (fix UIDs, set flags and size) */
diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h
index e24bd96c2..7ea971123 100644
--- a/camel/providers/imap/camel-imap-folder.h
+++ b/camel/providers/imap/camel-imap-folder.h
@@ -102,15 +102,15 @@ CamelStream * camel_imap_folder_fetch_data (CamelImapFolder *imap_folder,
GError **error);
gboolean camel_imap_append_resyncing (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error);
gboolean camel_imap_transfer_resyncing (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error);
gboolean camel_imap_expunge_uids_resyncing
diff --git a/camel/providers/imap/camel-imap-journal.c b/camel/providers/imap/camel-imap-journal.c
index cd6f74fe1..d94b5225f 100644
--- a/camel/providers/imap/camel-imap-journal.c
+++ b/camel/providers/imap/camel-imap-journal.c
@@ -370,7 +370,7 @@ imap_entry_play (CamelOfflineJournal *journal,
if (!camel_imap_transfer_resyncing (
journal->folder, imap_entry->uids, destination,
- &ret_uids, imap_entry->move, cancellable, error))
+ imap_entry->move, &ret_uids, cancellable, error))
return -1;
if (ret_uids) {
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index bf5595a76..02457cbec 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -278,7 +278,7 @@ imapx_search_by_expression (CamelFolder *folder, const gchar *expression, GError
static gboolean
imapx_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -399,8 +399,8 @@ imapx_get_message_sync (CamelFolder *folder,
msg = camel_mime_message_new ();
g_mutex_lock (ifolder->stream_lock);
- if (camel_data_wrapper_construct_from_stream_sync (
- (CamelDataWrapper *)msg, stream, cancellable, error) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync (
+ (CamelDataWrapper *)msg, stream, cancellable, error)) {
g_object_unref (msg);
msg = NULL;
}
@@ -521,8 +521,8 @@ static gboolean
imapx_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index f2bf917a6..2776d0223 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -3847,7 +3847,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
/* If we have any new messages, download their headers, but only a few (100?) at a time */
if (fetch_new) {
- camel_operation_start (
+ camel_operation_push_message (
job->cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (job->folder));
@@ -3889,7 +3889,7 @@ imapx_job_scan_changes_start (CamelIMAPXServer *is,
{
CamelIMAPXCommand *ic;
- camel_operation_start (
+ camel_operation_push_message (
job->cancellable,
_("Scanning for changed messages in %s"),
camel_folder_get_name (job->folder));
@@ -3974,7 +3974,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is,
} else
uid = g_strdup ("1");
- camel_operation_start (
+ camel_operation_push_message (
job->cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (folder));
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
index 57f322f83..764b1ee58 100644
--- a/camel/providers/local/camel-maildir-folder.c
+++ b/camel/providers/local/camel-maildir-folder.c
@@ -114,7 +114,7 @@ maildir_folder_get_filename (CamelFolder *folder,
static gboolean
maildir_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -253,9 +253,9 @@ maildir_folder_get_message_sync (CamelFolder *folder,
}
message = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream_sync (
+ if (!camel_data_wrapper_construct_from_stream_sync (
(CamelDataWrapper *)message,
- message_stream, cancellable, error) == -1) {
+ message_stream, cancellable, error)) {
g_prefix_error (
error, _("Cannot get message %s from folder %s: "),
uid, lf->folder_path);
@@ -281,8 +281,8 @@ static gboolean
maildir_folder_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
@@ -293,7 +293,8 @@ maildir_folder_transfer_messages_to_sync (CamelFolder *source,
CamelLocalFolder *lf = (CamelLocalFolder *) source;
CamelLocalFolder *df = (CamelLocalFolder *) dest;
- camel_operation_start (cancellable, _("Moving messages"));
+ camel_operation_push_message (
+ cancellable, _("Moving messages"));
camel_folder_freeze (dest);
camel_folder_freeze (source);
@@ -346,7 +347,7 @@ maildir_folder_transfer_messages_to_sync (CamelFolder *source,
camel_folder_thaw (source);
camel_folder_thaw (dest);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
} else
fallback = TRUE;
@@ -356,8 +357,8 @@ maildir_folder_transfer_messages_to_sync (CamelFolder *source,
/* Chain up to parent's transfer_messages_to() method. */
folder_class = CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class);
return folder_class->transfer_messages_to_sync (
- source, uids, dest, transferred_uids,
- delete_originals, cancellable, error);
+ source, uids, dest, delete_originals,
+ transferred_uids, cancellable, error);
}
return TRUE;
diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c
index dca9bb804..7ad3e242e 100644
--- a/camel/providers/local/camel-maildir-summary.c
+++ b/camel/providers/local/camel-maildir-summary.c
@@ -552,7 +552,8 @@ maildir_summary_check (CamelLocalSummary *cls,
d(printf("checking summary ...\n"));
- camel_operation_start (cancellable, _("Checking folder consistency"));
+ camel_operation_push_message (
+ cancellable, _("Checking folder consistency"));
/* scan the directory, check for mail files not in the index, or index entries that
no longer exist */
@@ -565,7 +566,7 @@ maildir_summary_check (CamelLocalSummary *cls,
cls->folder_path, g_strerror (errno));
g_free (cur);
g_free (new);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_mutex_unlock (((CamelMaildirSummary *) cls)->priv->summary_lock);
return -1;
}
@@ -642,9 +643,10 @@ maildir_summary_check (CamelLocalSummary *cls,
g_hash_table_foreach (left, (GHFunc)remove_summary, &rd);
g_hash_table_destroy (left);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
- camel_operation_start (cancellable, _("Checking for new messages"));
+ camel_operation_push_message (
+ cancellable, _("Checking for new messages"));
/* now, scan new for new messages, and copy them to cur, and so forth */
dir = opendir (new);
@@ -704,7 +706,8 @@ maildir_summary_check (CamelLocalSummary *cls,
g_free (src);
g_free (dest);
}
- camel_operation_end (cancellable);
+
+ camel_operation_pop_message (cancellable);
closedir (dir);
}
@@ -736,7 +739,7 @@ maildir_summary_sync (CamelLocalSummary *cls,
if (camel_local_summary_check (cls, changes, cancellable, error) == -1)
return -1;
- camel_operation_start (cancellable, _("Storing folder"));
+ camel_operation_push_message (cancellable, _("Storing folder"));
camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *)cls, error);
count = camel_folder_summary_count ((CamelFolderSummary *)cls);
@@ -792,7 +795,7 @@ maildir_summary_sync (CamelLocalSummary *cls,
camel_message_info_free (info);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
/* Chain up to parent's sync() method. */
local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (camel_maildir_summary_parent_class);
diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c
index 32abf3306..8174904b3 100644
--- a/camel/providers/local/camel-mbox-folder.c
+++ b/camel/providers/local/camel-mbox-folder.c
@@ -138,7 +138,7 @@ fail:
static gboolean
mbox_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -380,8 +380,8 @@ retry:
}
message = camel_mime_message_new ();
- if (camel_mime_part_construct_from_parser_sync (
- (CamelMimePart *)message, parser, cancellable, error) == -1) {
+ if (!camel_mime_part_construct_from_parser_sync (
+ (CamelMimePart *)message, parser, cancellable, error)) {
g_prefix_error (
error, _("Cannot get message %s from folder %s: "),
uid, lf->folder_path);
diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c
index 86d056271..5ce1476ff 100644
--- a/camel/providers/local/camel-mbox-summary.c
+++ b/camel/providers/local/camel-mbox-summary.c
@@ -469,7 +469,7 @@ summary_update (CamelLocalSummary *cls,
cls->index_force = FALSE;
- camel_operation_start (cancellable, _("Storing folder"));
+ camel_operation_push_message (cancellable, _("Storing folder"));
fd = g_open (cls->folder_path, O_LARGEFILE | O_RDONLY | O_BINARY, 0);
if (fd == -1) {
@@ -479,7 +479,7 @@ summary_update (CamelLocalSummary *cls,
g_io_error_from_errno (errno),
_("Could not open folder: %s: %s"),
cls->folder_path, g_strerror (errno));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
@@ -598,7 +598,7 @@ summary_update (CamelLocalSummary *cls,
}
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return ok;
}
@@ -691,7 +691,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs,
d(printf("performing full summary/sync\n"));
- camel_operation_start (cancellable, _("Storing folder"));
+ camel_operation_push_message (cancellable, _("Storing folder"));
fd = g_open (cls->folder_path, O_LARGEFILE | O_RDONLY | O_BINARY, 0);
if (fd == -1) {
@@ -700,7 +700,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs,
g_io_error_from_errno (errno),
_("Could not open file: %s: %s"),
cls->folder_path, g_strerror (errno));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
@@ -763,7 +763,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs,
}
tmpname = NULL;
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return 0;
error:
@@ -776,7 +776,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs,
if (tmpname)
g_unlink (tmpname);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
@@ -827,7 +827,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
d(printf("Performing quick summary sync\n"));
- camel_operation_start (cancellable, _("Storing folder"));
+ camel_operation_push_message (cancellable, _("Storing folder"));
fd = g_open (cls->folder_path, O_LARGEFILE|O_RDWR|O_BINARY, 0);
if (fd == -1) {
@@ -837,7 +837,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
_("Could not open file: %s: %s"),
cls->folder_path, g_strerror (errno));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
@@ -960,7 +960,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
g_ptr_array_free (summary, TRUE);
g_object_unref (mp);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
return 0;
@@ -974,7 +974,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
if (info)
camel_message_info_free ((CamelMessageInfo *)info);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
return -1;
diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c
index a005a1352..59147efd6 100644
--- a/camel/providers/local/camel-mh-folder.c
+++ b/camel/providers/local/camel-mh-folder.c
@@ -55,7 +55,7 @@ mh_folder_get_filename (CamelFolder *folder,
static gboolean
mh_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
@@ -171,9 +171,9 @@ mh_folder_get_message_sync (CamelFolder *folder,
}
message = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream_sync (
+ if (!camel_data_wrapper_construct_from_stream_sync (
(CamelDataWrapper *)message,
- message_stream, cancellable, error) == -1) {
+ message_stream, cancellable, error)) {
g_prefix_error (
error, _("Cannot get message %s from folder %s: "),
name, lf->folder_path);
diff --git a/camel/providers/local/camel-spool-summary.c b/camel/providers/local/camel-spool-summary.c
index 30fc1689e..3dbf398ee 100644
--- a/camel/providers/local/camel-spool-summary.c
+++ b/camel/providers/local/camel-spool-summary.c
@@ -128,7 +128,7 @@ spool_summary_sync_full (CamelMboxSummary *cls,
d(printf("performing full summary/sync\n"));
- camel_operation_start (cancellable, _("Storing folder"));
+ camel_operation_push_message (cancellable, _("Storing folder"));
fd = open (((CamelLocalSummary *)cls)->folder_path, O_RDWR|O_LARGEFILE);
if (fd == -1) {
@@ -138,7 +138,7 @@ spool_summary_sync_full (CamelMboxSummary *cls,
_("Could not open file: %s: %s"),
((CamelLocalSummary *)cls)->folder_path,
g_strerror (errno));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
@@ -286,7 +286,7 @@ spool_summary_sync_full (CamelMboxSummary *cls,
if (tmpname[0] != '\0')
unlink (tmpname);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return 0;
error:
@@ -299,7 +299,7 @@ spool_summary_sync_full (CamelMboxSummary *cls,
if (tmpname[0] != '\0')
unlink (tmpname);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
index 450b903d7..5c0e1b32d 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -414,7 +414,7 @@ nntp_folder_get_message_sync (CamelFolder *folder,
}
message = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) message, stream, cancellable, error) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) message, stream, cancellable, error)) {
g_prefix_error (error, _("Cannot get message %s: "), uid);
g_object_unref (message);
message = NULL;
diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c
index 1076171b3..68129a7fc 100644
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ b/camel/providers/nntp/camel-nntp-summary.c
@@ -241,7 +241,7 @@ add_range_xover (CamelNNTPSummary *cns,
s = (CamelFolderSummary *)cns;
summary_table = camel_folder_summary_get_hashtable (s);
- camel_operation_start (
+ camel_operation_push_message (
cancellable, _("%s: Scanning new messages"),
((CamelService *)store)->url->host);
@@ -250,7 +250,7 @@ add_range_xover (CamelNNTPSummary *cns,
ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "xover %r", low, high);
if (ret != 224) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
if (ret != -1)
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
@@ -321,7 +321,7 @@ add_range_xover (CamelNNTPSummary *cns,
camel_header_raw_clear (&headers);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_folder_summary_free_hashtable (summary_table);
@@ -352,7 +352,7 @@ add_range_head (CamelNNTPSummary *cns,
mp = camel_mime_parser_new ();
- camel_operation_start (
+ camel_operation_push_message (
cancellable, _("%s: Scanning new messages"),
((CamelService *)store)->url->host);
@@ -426,7 +426,7 @@ ioerror:
}
g_object_unref (mp);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_folder_summary_free_hashtable (summary_table);
diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c
index 390fd7752..fce90e923 100644
--- a/camel/providers/pop3/camel-pop3-folder.c
+++ b/camel/providers/pop3/camel-pop3-folder.c
@@ -338,7 +338,7 @@ pop3_folder_get_message_sync (CamelFolder *folder,
/* Sigh, most of the crap in this function is so that the cancel button
returns the proper exception code. Sigh. */
- camel_operation_start_transient (
+ camel_operation_push_message (
cancellable, _("Retrieving POP message %d"), fi->id);
/* If we have an oustanding retrieve message running, wait for that to complete
@@ -450,8 +450,8 @@ pop3_folder_get_message_sync (CamelFolder *folder,
}
message = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream_sync (
- CAMEL_DATA_WRAPPER (message), stream, cancellable, error) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync (
+ CAMEL_DATA_WRAPPER (message), stream, cancellable, error)) {
g_prefix_error (error, _("Cannot get message %s: "), uid);
g_object_unref (message);
message = NULL;
@@ -459,7 +459,7 @@ pop3_folder_get_message_sync (CamelFolder *folder,
done:
g_object_unref (stream);
fail:
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return message;
}
@@ -479,7 +479,8 @@ pop3_folder_refresh_info_sync (CamelFolder *folder,
parent_store = camel_folder_get_parent_store (folder);
pop3_store = CAMEL_POP3_STORE (parent_store);
- camel_operation_start (cancellable, _("Retrieving POP summary"));
+ camel_operation_push_message (
+ cancellable, _("Retrieving POP summary"));
pop3_folder->uids = g_ptr_array_new ();
pop3_folder->uids_uid = g_hash_table_new (g_str_hash, g_str_equal);
@@ -528,7 +529,7 @@ pop3_folder_refresh_info_sync (CamelFolder *folder,
/* dont need this anymore */
g_hash_table_destroy (pop3_folder->uids_id);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return success;
}
@@ -553,17 +554,22 @@ pop3_folder_synchronize_sync (CamelFolder *folder,
if (pop3_store->delete_after && !expunge) {
d(printf("%s(%d): pop3_store->delete_after = [%d], expunge=[%d]\n",
__FILE__, __LINE__, pop3_store->delete_after, expunge));
- camel_operation_start (cancellable, _("Expunging old messages"));
+ camel_operation_push_message (
+ cancellable, _("Expunging old messages"));
+
camel_pop3_delete_old (
folder, pop3_store->delete_after,
cancellable, error);
+
+ camel_operation_pop_message (cancellable);
}
if (!expunge) {
return TRUE;
}
- camel_operation_start (cancellable, _("Expunging deleted messages"));
+ camel_operation_push_message (
+ cancellable, _("Expunging deleted messages"));
for (i = 0; i < pop3_folder->uids->len; i++) {
fi = pop3_folder->uids->pdata[i];
@@ -602,7 +608,7 @@ pop3_folder_synchronize_sync (CamelFolder *folder,
cancellable, (i+1) * 100 / pop3_folder->uids->len);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_pop3_store_expunge (pop3_store, error);
@@ -681,8 +687,8 @@ pop3_get_message_time_from_cache (CamelFolder *folder, const gchar *uid, time_t
CamelMimeMessage *message;
message = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream_sync (
- (CamelDataWrapper *)message, stream, NULL, NULL) == -1) {
+ if (!camel_data_wrapper_construct_from_stream_sync (
+ (CamelDataWrapper *)message, stream, NULL, NULL)) {
g_warning (_("Cannot get message %s: %s"), uid, g_strerror (errno));
g_object_unref (message);
message = NULL;
@@ -782,8 +788,6 @@ camel_pop3_delete_old (CamelFolder *folder,
cancellable, (i+1) * 100 / pop3_folder->uids->len);
}
- camel_operation_end (cancellable);
-
camel_pop3_store_expunge (pop3_store, error);
return 0;
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index 9f1716000..2b17ec0db 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -614,7 +614,7 @@ smtp_send_to_sync (CamelTransport *transport,
return FALSE;
}
- camel_operation_start (cancellable, _("Sending message"));
+ camel_operation_push_message (cancellable, _("Sending message"));
/* find out if the message has 8bit mime parts */
has_8bit_parts = camel_mime_message_has_8bit_parts (message);
@@ -623,7 +623,7 @@ smtp_send_to_sync (CamelTransport *transport,
you'll be sending an 8bit mime message at "MAIL FROM:" time. */
if (!smtp_mail (
smtp_transport, addr, has_8bit_parts, cancellable, error)) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
@@ -632,7 +632,7 @@ smtp_send_to_sync (CamelTransport *transport,
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Cannot send message: no recipients defined."));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
@@ -645,28 +645,28 @@ smtp_send_to_sync (CamelTransport *transport,
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Cannot send message: "
"one or more invalid recipients"));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
enc = camel_internet_address_encode_address (NULL, NULL, addr);
if (!smtp_rcpt (smtp_transport, enc, cancellable, error)) {
g_free (enc);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
g_free (enc);
}
if (!smtp_data (smtp_transport, message, cancellable, error)) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
/* reset the service for our next transfer session */
smtp_rset (smtp_transport, cancellable, NULL);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return TRUE;
}
@@ -1011,7 +1011,7 @@ smtp_helo (CamelSmtpTransport *transport,
transport->authtypes = NULL;
}
- camel_operation_start_transient (cancellable, _("SMTP Greeting"));
+ camel_operation_push_message (cancellable, _("SMTP Greeting"));
addr = transport->localaddr;
addrlen = transport->localaddrlen;
@@ -1039,7 +1039,7 @@ smtp_helo (CamelSmtpTransport *transport,
transport->ostream, cmdbuf, cancellable, error) == -1) {
g_free (cmdbuf);
g_prefix_error (error, _("HELO command failed: "));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_service_disconnect_sync (
(CamelService *) transport, FALSE, NULL);
@@ -1057,14 +1057,14 @@ smtp_helo (CamelSmtpTransport *transport,
if (respbuf == NULL) {
g_prefix_error (error, _("HELO command failed: "));
transport->connected = FALSE;
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
if (strncmp (respbuf, "250", 3)) {
smtp_set_error (
transport, respbuf, cancellable, error);
g_prefix_error (error, _("HELO command failed: "));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_free (respbuf);
return FALSE;
}
@@ -1113,7 +1113,7 @@ smtp_helo (CamelSmtpTransport *transport,
} while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */
g_free (respbuf);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return TRUE;
}
@@ -1131,11 +1131,11 @@ smtp_auth (CamelSmtpTransport *transport,
service = CAMEL_SERVICE (transport);
- camel_operation_start_transient (cancellable, _("SMTP Authentication"));
+ camel_operation_push_message (cancellable, _("SMTP Authentication"));
sasl = camel_sasl_new ("smtp", mech, service);
if (!sasl) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Error creating SASL authentication object."));
@@ -1242,7 +1242,7 @@ smtp_auth (CamelSmtpTransport *transport,
}
g_object_unref (sasl);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_free (respbuf);
@@ -1258,7 +1258,7 @@ smtp_auth (CamelSmtpTransport *transport,
lose:
g_object_unref (sasl);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_free (respbuf);