(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
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)
{
}
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,
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,
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
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,
}
/**
- * 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);
}
/**
- * 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;
}
const gchar *
-camel_cipher_hash_to_id (CamelCipherContext *context,
- CamelCipherHash hash)
+camel_cipher_context_hash_to_id (CamelCipherContext *context,
+ CamelCipherHash hash)
{
CamelCipherContextClass *class;
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,
CamelMimePart *ipart,
GCancellable *cancellable,
GError **error);
- gint (*encrypt_sync) (CamelCipherContext *context,
+ gboolean (*encrypt_sync) (CamelCipherContext *context,
const gchar *userid,
GPtrArray *recipients,
CamelMimePart *ipart,
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:
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 */
(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
}
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;
}
return ret;
}
-static gint
+static gboolean
data_wrapper_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
CamelStream *stream,
GCancellable *cancellable,
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
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
/**
* 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.
/**
* 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
**/
/**
* 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
**/
/**
* 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
/**
* 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
}
/**
+ * 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,
}
/**
+ * 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,
}
/**
+ * 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);
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);
}
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);
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,
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);
(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
*
* Since: 2.24
**/
-typedef gint (*CamelDBCollate)(gpointer ,int,gconstpointer ,int,gconstpointer );
+typedef gint (*CamelDBCollate)(gpointer, gint, gconstpointer, gint, gconstpointer );
/**
* CamelDB:
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 (
}
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++) {
}
lose:
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
/* Close folders */
g_hash_table_foreach (
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"));
NULL, &mm->error);
}
- camel_operation_end (mm->cancellable);
+ camel_operation_pop_message (mm->cancellable);
}
static void
static gboolean
disco_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
disco_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
gint i;
gboolean success = TRUE;
- camel_operation_start (
+ camel_operation_push_message (
cancellable, _("Preparing folder '%s' for offline"),
camel_folder_get_full_name (folder));
uids = camel_folder_get_uids (folder);
if (!uids) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
else
camel_folder_free_uids (folder, uids);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return success;
}
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)
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)
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,
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;
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) {
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);
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);
*
* Reference an info.
**/
-void
+gpointer
camel_message_info_ref (gpointer o)
{
CamelMessageInfo *mi = o;
mi->refcount++;
GLOBAL_INFO_UNLOCK (info);
}
+
+ return o;
}
/**
/* 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);
#define d(x)
#define w(x)
+typedef struct _AsyncContext AsyncContext;
+
struct _CamelFolderPrivate {
GStaticRecMutex lock;
GStaticMutex change_lock;
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 */
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)
{
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'",
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'",
g_object_unref (msg);
}
}
- camel_operation_end (tmsg->cancellable);
+ camel_operation_pop_message (tmsg->cancellable);
}
if (m->junk || m->notjunk)
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'",
g_free (source_url);
- camel_operation_end (tmsg->cancellable);
+ camel_operation_pop_message (tmsg->cancellable);
}
}
folder_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
}
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) {
camel_folder_thaw (source);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
if (local_error != NULL)
g_propagate_error (error, local_error);
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,
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
*
}
/**
- * camel_folder_synchronize_sync:
+ * camel_folder_get_name:
* @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 the short name of the folder. The fully qualified name
+ * can be obtained with camel_folder_get_full_name().
*
- * Returns: %TRUE on success, %FALSE on failure
+ * Returns: the short name of the folder
**/
-gboolean
-camel_folder_synchronize_sync (CamelFolder *folder,
- gboolean expunge,
- GCancellable *cancellable,
- GError **error)
+const gchar *
+camel_folder_get_name (CamelFolder *folder)
{
- 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);
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
- return success;
+ return folder->priv->name;
}
/**
- * camel_folder_refresh_info_sync:
+ * camel_folder_set_name:
* @folder: a #CamelFolder
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
+ * @name: a name for the folder
*
- * Updates a folder's summary to be in sync with its backing store.
+ * Sets the short name of the folder.
*
- * Returns: %TRUE on success, %FALSE on failure
+ * Since: 2.32
**/
-gboolean
-camel_folder_refresh_info_sync (CamelFolder *folder,
- GCancellable *cancellable,
- GError **error)
+void
+camel_folder_set_name (CamelFolder *folder,
+ const gchar *name)
{
- CamelFolderClass *class;
- gboolean success;
-
- g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
- class = CAMEL_FOLDER_GET_CLASS (folder);
- g_return_val_if_fail (class->refresh_info_sync != NULL, FALSE);
+ g_free (folder->priv->name);
+ folder->priv->name = g_strdup (name);
- 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
- *
- * Returns the short name of the folder. The fully qualified name
- * can be obtained with camel_folder_get_full_name().
- *
- * Returns: the short name of the folder
- **/
-const gchar *
-camel_folder_get_name (CamelFolder *folder)
-{
- g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
-
- return folder->priv->name;
-}
-
-/**
- * camel_folder_set_name:
- * @folder: a #CamelFolder
- * @name: a name for the folder
- *
- * Sets the short name of the folder.
- *
- * Since: 2.32
- **/
-void
-camel_folder_set_name (CamelFolder *folder,
- const gchar *name)
-{
- g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
- g_free (folder->priv->name);
- folder->priv->name = g_strdup (name);
-
- g_object_notify (G_OBJECT (folder), "name");
-}
+ g_object_notify (G_OBJECT (folder), "name");
+}
/**
* camel_folder_get_full_name:
}
/**
- * 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
*
}
/**
- * 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
*
/* 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
*
}
/**
- * 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
*
}
/**
- * camel_folder_change_info_new:
- *
- * Create a new folder change info structure.
+ * camel_folder_lock:
+ * @folder: a #CamelFolder
+ * @lock: lock type to lock
*
- * Change info structures are not MT-SAFE and must be
- * locked for exclusive access externally.
+ * Locks #folder's #lock. Unlock it with camel_folder_unlock().
*
- * Returns: a new #CamelFolderChangeInfo
+ * Since: 2.32
**/
-CamelFolderChangeInfo *
-camel_folder_change_info_new (void)
+void
+camel_folder_lock (CamelFolder *folder,
+ CamelFolderLock lock)
{
- CamelFolderChangeInfo *info;
+ 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.
+ *
+ * Change info structures are not MT-SAFE and must be
+ * locked for exclusive access externally.
+ *
+ * Returns: a new #CamelFolderChangeInfo
+ **/
+CamelFolderChangeInfo *
+camel_folder_change_info_new (void)
+{
+ CamelFolderChangeInfo *info;
info = g_slice_new (CamelFolderChangeInfo);
info->uid_added = g_ptr_array_new ();
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 ();
- }
-}
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,
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);
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,
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 */
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 */
(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 */
return CAMEL_CIPHER_HASH_DEFAULT;
}
-static gint
+static gboolean
gpg_sign_sync (CamelCipherContext *context,
const gchar *userid,
CamelCipherHash hash,
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 */
goto fail;
}
- res = 0;
+ success = TRUE;
dw = camel_data_wrapper_new ();
camel_stream_reset (ostream, NULL);
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);
if (gpg)
gpg_ctx_free (gpg);
- return res;
+ return success;
}
static CamelCipherValidity *
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 {
return NULL;
}
-static gint
+static gboolean
gpg_encrypt_sync (CamelCipherContext *context,
const gchar *userid,
GPtrArray *recipients,
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);
goto fail;
}
- res = 0;
+ success = TRUE;
dw = camel_data_wrapper_new ();
camel_data_wrapper_construct_from_stream_sync (
g_object_unref (istream);
g_object_unref (ostream);
- return res;
+ return success;
}
static CamelCipherValidity *
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 (
}
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 ();
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);
/* 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);
/* 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);
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;
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);
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,
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);
goto fail;
}
- res = 0;
+ success = TRUE;
fail:
gpg_ctx_free (gpg);
- return res;
+ return success;
}
static void
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,
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);
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);
error, G_IO_ERROR,
g_io_error_from_errno (errno),
"%s", g_strerror (errno));
- ret = -1;
+ success = FALSE;
}
- return ret;
+ return success;
}
static void
/* 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;
* 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;
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
GByteArray *buffer;
CamelStream *mem;
gsize len;
- gint retval;
+ gboolean success;
d(printf ("simple_data_wrapper_construct_from_parser()\n"));
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;
}
/**
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"));
/**
* camel_mime_message_build_preview:
*
+ * <note>
+ * <para>
+ * This function blocks like crazy.
+ * </para>
+ * </note>
+ *
* Since: 2.28
**/
gboolean
/* !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;
(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;
CamelTransferEncoding encoding;
};
+struct _AsyncContext {
+ /* arguments */
+ CamelMimeParser *parser;
+};
+
enum {
PROP_0,
PROP_CONTENT_ID,
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,
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)
{
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)
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);
}
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
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,
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;
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.
*
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);
}
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);
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
return -1;
}
-static gint
+static gboolean
multipart_signed_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
CamelStream *stream,
GCancellable *cancellable,
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
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 */
cs_freeinfo (msg);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return res;
}
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));
cs_freeinfo (msg);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return result;
}
(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;
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"));
"(match-all)", NULL, &mm->error);
}
- camel_operation_end (mm->cancellable);
+ camel_operation_pop_message (mm->cancellable);
}
static void
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));
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;
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,
/**
* 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)
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);
+}
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
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;
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)
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;
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);
}
#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;
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;
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 ();
}
/**
* 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
**/
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)
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 ();
-}
* 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
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), CAMEL_TYPE_SASL, CamelSaslPrivate))
+typedef struct _AsyncContext AsyncContext;
+
struct _CamelSaslPrivate {
CamelService *service;
gboolean authenticated;
gchar *mechanism;
};
+struct _AsyncContext {
+ /* arguments */
+ GByteArray *token;
+ gchar *base64_token;
+
+ /* results */
+ GByteArray *response;
+ gchar *base64_response;
+};
+
enum {
PROP_0,
PROP_AUTHENTICATED,
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)
{
}
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;
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,
/**
* 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.
/**
* 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.
**/
}
/**
+ * 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,
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;
} 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;
}
/**
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);
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 *
return CAMEL_CIPHER_HASH_DEFAULT;
}
-static gint
+static gboolean
smime_context_sign_sync (CamelCipherContext *context,
const gchar *userid,
CamelCipherHash hash,
GError **error)
{
CamelCipherContextClass *class;
- gint res = -1;
NSSCMSMessage *cmsg;
CamelStream *ostream, *istream;
GByteArray *buffer;
NSSCMSEncoderContext *enc;
CamelDataWrapper *dw;
CamelContentType *ct;
+ gboolean success = FALSE;
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
goto fail;
}
- res = 0;
+ success = TRUE;
dw = camel_data_wrapper_new ();
camel_stream_reset (ostream, NULL);
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);
g_object_unref (ostream);
g_object_unref (istream);
- return res;
+ return success;
}
static CamelCipherValidity *
return valid;
}
-static gint
+static gboolean
smime_context_encrypt_sync (CamelCipherContext *context,
const gchar *userid,
GPtrArray *recipients,
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 */
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)
PORT_FreeArena (poolp, PR_FALSE);
- return -1;
+ return FALSE;
}
static CamelCipherValidity *
/* 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,
/* 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);
(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,
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.
}
static void
-camel_store_class_init (CamelStoreClass *class)
+store_get_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
{
- GObjectClass *object_class;
- CamelServiceClass *service_class;
+ AsyncContext *async_context;
+ GError *error = NULL;
- g_type_class_add_private (class, sizeof (CamelStorePrivate));
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = store_finalize;
- object_class->constructed = store_constructed;
+ async_context->folder = camel_store_get_folder_sync (
+ CAMEL_STORE (object), async_context->folder_name_1,
+ async_context->flags, cancellable, &error);
- service_class = CAMEL_SERVICE_CLASS (class);
- service_class->construct = store_construct;
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
- 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;
+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;
- signals[FOLDER_CREATED] = g_signal_new (
- "folder-created",
- G_OBJECT_CLASS_TYPE (class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CamelStoreClass, folder_created),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (folder_name);
+ async_context->flags = flags;
- signals[FOLDER_DELETED] = g_signal_new (
- "folder-deleted",
- G_OBJECT_CLASS_TYPE (class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CamelStoreClass, folder_deleted),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback, user_data, store_get_folder);
- signals[FOLDER_OPENED] = g_signal_new (
- "folder-opened",
- G_OBJECT_CLASS_TYPE (class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CamelStoreClass, folder_opened),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- CAMEL_TYPE_FOLDER);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- signals[FOLDER_RENAMED] = g_signal_new (
- "folder-renamed",
- G_OBJECT_CLASS_TYPE (class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CamelStoreClass, folder_renamed),
- NULL, NULL,
- camel_marshal_VOID__STRING_POINTER,
- G_TYPE_NONE, 2,
- G_TYPE_STRING,
- G_TYPE_POINTER);
+ g_simple_async_result_run_in_thread (
+ simple, store_get_folder_thread, io_priority, cancellable);
- signals[FOLDER_SUBSCRIBED] = g_signal_new (
- "folder-subscribed",
- G_OBJECT_CLASS_TYPE (class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CamelStoreClass, folder_subscribed),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
+ g_object_unref (simple);
+}
- signals[FOLDER_UNSUBSCRIBED] = g_signal_new (
- "folder-unsubscribed",
- G_OBJECT_CLASS_TYPE (class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CamelStoreClass, folder_unsubscribed),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
+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
-camel_store_init (CamelStore *store)
+store_get_folder_info_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
{
- store->priv = CAMEL_STORE_GET_PRIVATE (store);
+ AsyncContext *async_context;
+ GError *error = NULL;
- /* set vtrash and vjunk on by default */
- store->flags = CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK;
- store->mode = CAMEL_STORE_READ | CAMEL_STORE_WRITE;
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- g_static_rec_mutex_init (&store->priv->folder_lock);
+ 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);
+ }
}
-GQuark
-camel_store_error_quark (void)
+static void
+store_get_folder_info (CamelStore *store,
+ const gchar *top,
+ guint32 flags,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- static GQuark quark = 0;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- if (G_UNLIKELY (quark == 0)) {
- const gchar *string = "camel-store-error-quark";
- quark = g_quark_from_static_string (string);
- }
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (top);
+ async_context->flags = flags;
- return quark;
+ 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);
}
-/**
- * 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)
+static CamelFolderInfo *
+store_get_folder_info_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- CamelStoreClass *class;
- CamelFolder *folder = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ CamelFolderInfo *folder_info;
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
- g_return_val_if_fail (folder_name != NULL, NULL);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_get_folder_info), NULL);
- class = CAMEL_STORE_GET_CLASS (store);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- /* 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 (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
- 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;
- }
- }
+ folder_info = async_context->folder_info;
+ async_context->folder_info = NULL;
- if (!folder) {
+ return folder_info;
+}
- 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;
- }
+static void
+store_get_inbox_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = 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;
- }
- }
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- 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);
+ async_context->folder = camel_store_get_inbox_folder_sync (
+ CAMEL_STORE (object), cancellable, &error);
- if (folder) {
- CamelVeeFolder *vfolder;
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
- 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);
- }
+static void
+store_get_inbox_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- 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);
- }
- }
- }
+ async_context = g_slice_new0 (AsyncContext);
- if (store->folders) {
- if (folder)
- camel_object_bag_add (store->folders, folder_name, folder);
- else
- camel_object_bag_abort (store->folders, folder_name);
- }
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_get_inbox_folder);
- if (folder)
- g_signal_emit (store, signals[FOLDER_OPENED], 0, folder);
- }
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- return folder;
+ g_simple_async_result_run_in_thread (
+ simple, store_get_inbox_folder_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
}
-/**
- * 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)
+static CamelFolder *
+store_get_inbox_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- CamelStoreClass *class;
- CamelFolderInfo *fi;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
- g_return_val_if_fail (folder_name != NULL, NULL);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_get_inbox_folder), NULL);
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->create_folder_sync != NULL, NULL);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- 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);
+ if (g_simple_async_result_propagate_error (simple, error))
return NULL;
- }
- camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+ return g_object_ref (async_context->folder);
+}
- fi = class->create_folder_sync (
- store, parent_name, folder_name, cancellable, error);
- CAMEL_CHECK_GERROR (store, create_folder_sync, fi != NULL, error);
+static void
+store_get_junk_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
- camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- return fi;
+ 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);
+ }
}
-/* deletes folder/removes it from the folder cache, if it's there */
static void
-cs_delete_cached_folder (CamelStore *store,
- const gchar *folder_name)
+store_get_junk_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- CamelFolder *folder;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- if (store->folders
- && (folder = camel_object_bag_get (store->folders, folder_name))) {
- CamelVeeFolder *vfolder;
+ async_context = g_slice_new0 (AsyncContext);
- if ((store->flags & CAMEL_STORE_VTRASH)
- && (vfolder = camel_object_bag_get(store->folders, CAMEL_VTRASH_NAME))) {
- camel_vee_folder_remove_folder (vfolder, folder);
- g_object_unref (vfolder);
- }
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_get_junk_folder);
- if ((store->flags & CAMEL_STORE_VJUNK)
- && (vfolder = camel_object_bag_get(store->folders, CAMEL_VJUNK_NAME))) {
- camel_vee_folder_remove_folder(vfolder, folder);
- g_object_unref (vfolder);
- }
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- camel_folder_delete (folder);
+ g_simple_async_result_run_in_thread (
+ simple, store_get_junk_folder_thread,
+ io_priority, cancellable);
- camel_object_bag_remove (store->folders, folder);
- g_object_unref (folder);
- }
+ g_object_unref (simple);
}
-/**
- * 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)
+static CamelFolder *
+store_get_junk_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- CamelStoreClass *class;
- gboolean success;
- GError *local_error = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
- g_return_val_if_fail (folder_name != NULL, FALSE);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_get_folder), NULL);
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->delete_folder_sync != NULL, FALSE);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- /* 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;
+ 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);
}
+}
- camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+static void
+store_get_trash_folder (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- success = class->delete_folder_sync (
- store, folder_name, cancellable, &local_error);
- CAMEL_CHECK_GERROR (store, delete_folder_sync, success, &local_error);
+ async_context = g_slice_new0 (AsyncContext);
- /* 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);
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_get_trash_folder);
- if (local_error == NULL)
- cs_delete_cached_folder(store, folder_name);
- else
- g_propagate_error (error, local_error);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ g_simple_async_result_run_in_thread (
+ simple, store_get_trash_folder_thread,
+ io_priority, cancellable);
- return success;
+ g_object_unref (simple);
}
-/**
- * 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)
+static CamelFolder *
+store_get_trash_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- CamelStoreClass *class;
- CamelFolder *folder;
- gint i, oldlen, namelen;
- GPtrArray *folders = NULL;
- gchar *old_name;
- gboolean success;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- 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);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_get_trash_folder), NULL);
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->rename_folder_sync != NULL, FALSE);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- if (strcmp (old_namein, new_name) == 0)
- return TRUE;
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
- 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;
+ 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);
}
+}
- /* 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);
+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;
- camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (parent_name);
+ async_context->folder_name_2 = g_strdup (folder_name);
- /* 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;
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback, user_data, store_create_folder);
- folder = folders->pdata[i];
- full_name = camel_folder_get_full_name (folder);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- 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);
- }
- }
- }
+ g_simple_async_result_run_in_thread (
+ simple, store_create_folder_thread, io_priority, cancellable);
- /* 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);
+ g_object_unref (simple);
+}
- /* If it worked, update all open folders/unlock them */
- if (folders) {
- if (success) {
- guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE;
- CamelFolderInfo *folder_info;
+static CamelFolderInfo *
+store_create_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ CamelFolderInfo *folder_info;
- for (i=0;i<folders->len;i++) {
- const gchar *full_name;
- gchar *new;
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_create_folder_finish), NULL);
- folder = folders->pdata[i];
- full_name = camel_folder_get_full_name (folder);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- 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);
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
- camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
- g_object_unref (folder);
- }
+ folder_info = async_context->folder_info;
+ async_context->folder_info = NULL;
- /* Emit renamed signal */
- if (store->flags & CAMEL_STORE_SUBSCRIPTIONS)
- flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
+ return folder_info;
+}
- folder_info = class->get_folder_info_sync (
- store, new_name, flags, cancellable, error);
- CAMEL_CHECK_GERROR (store, get_folder_info, folder_info != NULL, error);
+static void
+store_delete_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
- 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);
- }
- }
+ 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);
}
+}
- camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+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;
- g_ptr_array_free (folders, TRUE);
- g_free (old_name);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (folder_name);
- return success;
+ 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);
}
-/**
- * camel_store_folder_created:
- * @store: a #CamelStore
- * @info: information about the created folder
- *
- * Emits the #CamelStore::folder-created signal.
- *
- * This function is only intended for Camel providers.
- *
- * Since: 2.32
- **/
-void
-camel_store_folder_created (CamelStore *store,
- CamelFolderInfo *info)
+static gboolean
+store_delete_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- g_return_if_fail (CAMEL_STORE (store));
- g_return_if_fail (info != NULL);
+ GSimpleAsyncResult *simple;
- g_signal_emit (store, signals[FOLDER_CREATED], 0, info);
+ 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);
}
-/**
- * camel_store_folder_deleted:
- * @store: a #CamelStore
- * @info: information about the deleted folder
- *
- * Emits the #CamelStore::folder-deleted signal.
- *
- * This function is only intended for Camel providers.
- *
- * Since: 2.32
- **/
-void
-camel_store_folder_deleted (CamelStore *store,
- CamelFolderInfo *info)
+static void
+store_rename_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
{
- g_return_if_fail (CAMEL_STORE (store));
- g_return_if_fail (info != NULL);
+ AsyncContext *async_context;
+ GError *error = NULL;
- g_signal_emit (store, signals[FOLDER_DELETED], 0, info);
+ 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);
+ }
}
-/**
- * camel_store_folder_renamed:
- * @store: a #CamelStore
- * @old_name: the old name of the folder
- * @info: information about the renamed folder
- *
- * Emits the #CamelStore::folder-renamed signal.
- *
- * This function is only intended for Camel providers.
- *
- * Since: 2.32
- **/
-void
-camel_store_folder_renamed (CamelStore *store,
- const gchar *old_name,
- CamelFolderInfo *info)
+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)
{
- g_return_if_fail (CAMEL_STORE (store));
- g_return_if_fail (old_name != NULL);
- g_return_if_fail (info != NULL);
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- g_signal_emit (store, signals[FOLDER_RENAMED], 0, old_name, info);
+ 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);
}
-/**
- * camel_store_folder_subscribed:
- * @store: a #CamelStore
- * @info: information about the subscribed folder
- *
- * Emits the #CamelStore::folder-subscribed signal.
- *
- * This function is only intended for Camel providers.
- *
- * Since: 2.32
- **/
-void
-camel_store_folder_subscribed (CamelStore *store,
- CamelFolderInfo *info)
+static gboolean
+store_rename_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- g_return_if_fail (CAMEL_STORE (store));
- g_return_if_fail (info != NULL);
+ GSimpleAsyncResult *simple;
- g_signal_emit (store, signals[FOLDER_SUBSCRIBED], 0, info);
+ 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);
}
-/**
- * camel_store_folder_unsubscribed:
- * @store: a #CamelStore
- * @info: information about the unsubscribed folder
- *
- * Emits the #CamelStore::folder-unsubscribed signal.
- *
- * This function is only intended for Camel providers.
- *
- * Since: 2.32
- **/
-void
-camel_store_folder_unsubscribed (CamelStore *store,
- CamelFolderInfo *info)
+static void
+store_subscribe_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
{
- g_return_if_fail (CAMEL_STORE (store));
- g_return_if_fail (info != NULL);
+ AsyncContext *async_context;
+ GError *error = NULL;
- g_signal_emit (store, signals[FOLDER_UNSUBSCRIBED], 0, info);
+ 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);
+ }
}
-/**
- * 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)
+static void
+store_subscribe_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- CamelStoreClass *class;
- CamelFolder *folder;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- 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);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (folder_name);
- camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_subscribe_folder);
- folder = class->get_inbox_folder_sync (store, cancellable, error);
- CAMEL_CHECK_GERROR (
- store, get_inbox_folder_sync, folder != NULL, error);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ g_simple_async_result_run_in_thread (
+ simple, store_subscribe_folder_thread,
+ io_priority, cancellable);
- return folder;
+ g_object_unref (simple);
}
-/**
- * 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)
+static gboolean
+store_subscribe_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ GSimpleAsyncResult *simple;
- if ((store->flags & CAMEL_STORE_VJUNK) == 0) {
- CamelStoreClass *class;
- CamelFolder *folder;
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_subscribe_folder), FALSE);
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->get_junk_folder_sync != NULL, NULL);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
- folder = class->get_junk_folder_sync (store, cancellable, error);
- CAMEL_CHECK_GERROR (
- store, get_junk_folder_sync, folder != NULL, error);
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
- return folder;
- }
+static void
+store_unsubscribe_folder_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
- return camel_store_get_folder_sync (
- store, CAMEL_VJUNK_NAME, 0, cancellable, error);
+ 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);
+ }
}
-/**
- * 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)
+static void
+store_unsubscribe_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- if ((store->flags & CAMEL_STORE_VTRASH) == 0) {
- CamelStoreClass *class;
- CamelFolder *folder;
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->folder_name_1 = g_strdup (folder_name);
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->get_trash_folder_sync != NULL, NULL);
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback,
+ user_data, store_unsubscribe_folder);
- folder = class->get_trash_folder_sync (
- store, cancellable, error);
- CAMEL_CHECK_GERROR (
- store, get_trash_folder_sync, folder != NULL, error);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- return folder;
- }
+ g_simple_async_result_run_in_thread (
+ simple, store_unsubscribe_folder_thread,
+ io_priority, cancellable);
- return camel_store_get_folder_sync (
- store, CAMEL_VTRASH_NAME, 0, cancellable, error);
+ g_object_unref (simple);
}
-/**
- * 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)
+static gboolean
+store_unsubscribe_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- CamelStoreClass *class;
- gboolean success;
-
- g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ GSimpleAsyncResult *simple;
- class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->synchronize_sync != NULL, FALSE);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (store), store_unsubscribe_folder), FALSE);
- success = class->synchronize_sync (store, expunge, cancellable, error);
- CAMEL_CHECK_GERROR (store, synchronize_sync, success, error);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
- return success;
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
static void
-add_special_info (CamelStore *store,
- CamelFolderInfo *info,
- const gchar *name,
- const gchar *translated,
- gboolean unread_count,
- guint32 flags)
+store_synchronize_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
{
- CamelFolderInfo *fi, *vinfo, *parent;
- gchar *uri, *path;
- CamelURL *url;
+ AsyncContext *async_context;
+ GError *error = NULL;
- g_return_if_fail (info != NULL);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- parent = NULL;
- for (fi = info; fi; fi = fi->next) {
- if (!strcmp (fi->full_name, name))
- break;
- parent = fi;
- }
+ camel_store_synchronize_sync (
+ CAMEL_STORE (object), async_context->expunge,
+ cancellable, &error);
- /* create our vTrash/vJunk URL */
- url = camel_url_new (info->uri, NULL);
- if (((CamelService *) store)->provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) {
- camel_url_set_fragment (url, name);
- } else {
- path = g_strdup_printf ("/%s", name);
- camel_url_set_path (url, path);
- g_free (path);
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
}
+}
- uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
+static void
+store_synchronize (CamelStore *store,
+ gboolean expunge,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- if (fi) {
- /* We're going to replace the physical Trash/Junk folder with our vTrash/vJunk folder */
- vinfo = fi;
- g_free (vinfo->full_name);
- g_free (vinfo->name);
- g_free (vinfo->uri);
- } else {
- /* There wasn't a Trash/Junk folder so create a new folder entry */
- vinfo = camel_folder_info_new ();
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->expunge = expunge;
- g_assert (parent != NULL);
+ simple = g_simple_async_result_new (
+ G_OBJECT (store), callback, user_data, store_synchronize);
- vinfo->flags |= CAMEL_FOLDER_NOINFERIORS | CAMEL_FOLDER_SUBSCRIBED;
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- /* link it into the right spot */
- vinfo->next = parent->next;
- parent->next = vinfo;
- }
+ g_simple_async_result_run_in_thread (
+ simple, store_synchronize_thread, io_priority, cancellable);
- /* Fill in the new fields */
- vinfo->flags |= flags;
- vinfo->full_name = g_strdup (name);
- vinfo->name = g_strdup (translated);
- vinfo->uri = uri;
- if (!unread_count)
- vinfo->unread = -1;
+ 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
-dump_fi (CamelFolderInfo *fi, gint depth)
+store_noop_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
{
- gchar *s;
+ GError *error = NULL;
- s = g_alloca (depth+1);
- memset (s, ' ', depth);
- s[depth] = 0;
+ camel_store_noop_sync (CAMEL_STORE (object), cancellable, &error);
- while (fi) {
- printf("%suri: %s\n", s, fi->uri);
- printf("%sfull_name: %s\n", s, fi->full_name);
- printf("%sflags: %08x\n", s, fi->flags);
- dump_fi (fi->child, depth+2);
- fi = fi->next;
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
}
}
-/**
- * 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
+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;
+ CamelServiceClass *service_class;
+
+ g_type_class_add_private (class, sizeof (CamelStorePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = store_finalize;
+ object_class->constructed = store_constructed;
+
+ service_class = CAMEL_SERVICE_CLASS (class);
+ service_class->construct = store_construct;
+
+ class->hash_folder_name = g_str_hash;
+ class->compare_folder_name = g_str_equal;
+ class->can_refresh_folder = store_can_refresh_folder;
+
+ 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),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CamelStoreClass, folder_created),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[FOLDER_DELETED] = g_signal_new (
+ "folder-deleted",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CamelStoreClass, folder_deleted),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[FOLDER_OPENED] = g_signal_new (
+ "folder-opened",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CamelStoreClass, folder_opened),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ CAMEL_TYPE_FOLDER);
+
+ signals[FOLDER_RENAMED] = g_signal_new (
+ "folder-renamed",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CamelStoreClass, folder_renamed),
+ NULL, NULL,
+ camel_marshal_VOID__STRING_POINTER,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_POINTER);
+
+ signals[FOLDER_SUBSCRIBED] = g_signal_new (
+ "folder-subscribed",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CamelStoreClass, folder_subscribed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[FOLDER_UNSUBSCRIBED] = g_signal_new (
+ "folder-unsubscribed",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CamelStoreClass, folder_unsubscribed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+}
+
+static void
+camel_store_init (CamelStore *store)
+{
+ store->priv = CAMEL_STORE_GET_PRIVATE (store);
+
+ /* set vtrash and vjunk on by default */
+ store->flags = CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK;
+ store->mode = CAMEL_STORE_READ | CAMEL_STORE_WRITE;
+
+ g_static_rec_mutex_init (&store->priv->folder_lock);
+}
+
+GQuark
+camel_store_error_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY (quark == 0)) {
+ const gchar *string = "camel-store-error-quark";
+ quark = g_quark_from_static_string (string);
+ }
+
+ return quark;
+}
+
+/* deletes folder/removes it from the folder cache, if it's there */
+static void
+cs_delete_cached_folder (CamelStore *store,
+ const gchar *folder_name)
+{
+ CamelFolder *folder;
+
+ if (store->folders
+ && (folder = camel_object_bag_get (store->folders, folder_name))) {
+ CamelVeeFolder *vfolder;
+
+ if ((store->flags & CAMEL_STORE_VTRASH)
+ && (vfolder = camel_object_bag_get(store->folders, CAMEL_VTRASH_NAME))) {
+ camel_vee_folder_remove_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_remove_folder(vfolder, folder);
+ g_object_unref (vfolder);
+ }
+
+ camel_folder_delete (folder);
+
+ camel_object_bag_remove (store->folders, folder);
+ g_object_unref (folder);
+ }
+}
+
+/**
+ * camel_store_folder_created:
+ * @store: a #CamelStore
+ * @info: information about the created folder
+ *
+ * Emits the #CamelStore::folder-created signal.
+ *
+ * This function is only intended for Camel providers.
+ *
+ * Since: 2.32
+ **/
+void
+camel_store_folder_created (CamelStore *store,
+ CamelFolderInfo *info)
+{
+ g_return_if_fail (CAMEL_STORE (store));
+ g_return_if_fail (info != NULL);
+
+ g_signal_emit (store, signals[FOLDER_CREATED], 0, info);
+}
+
+/**
+ * camel_store_folder_deleted:
+ * @store: a #CamelStore
+ * @info: information about the deleted folder
+ *
+ * Emits the #CamelStore::folder-deleted signal.
+ *
+ * This function is only intended for Camel providers.
+ *
+ * Since: 2.32
+ **/
+void
+camel_store_folder_deleted (CamelStore *store,
+ CamelFolderInfo *info)
+{
+ g_return_if_fail (CAMEL_STORE (store));
+ g_return_if_fail (info != NULL);
+
+ g_signal_emit (store, signals[FOLDER_DELETED], 0, info);
+}
+
+/**
+ * camel_store_folder_renamed:
+ * @store: a #CamelStore
+ * @old_name: the old name of the folder
+ * @info: information about the renamed folder
+ *
+ * Emits the #CamelStore::folder-renamed signal.
+ *
+ * This function is only intended for Camel providers.
+ *
+ * Since: 2.32
+ **/
+void
+camel_store_folder_renamed (CamelStore *store,
+ const gchar *old_name,
+ CamelFolderInfo *info)
+{
+ g_return_if_fail (CAMEL_STORE (store));
+ g_return_if_fail (old_name != NULL);
+ g_return_if_fail (info != NULL);
+
+ g_signal_emit (store, signals[FOLDER_RENAMED], 0, old_name, info);
+}
+
+/**
+ * camel_store_folder_subscribed:
+ * @store: a #CamelStore
+ * @info: information about the subscribed folder
+ *
+ * Emits the #CamelStore::folder-subscribed signal.
+ *
+ * This function is only intended for Camel providers.
+ *
+ * Since: 2.32
+ **/
+void
+camel_store_folder_subscribed (CamelStore *store,
+ CamelFolderInfo *info)
+{
+ g_return_if_fail (CAMEL_STORE (store));
+ g_return_if_fail (info != NULL);
+
+ g_signal_emit (store, signals[FOLDER_SUBSCRIBED], 0, info);
+}
+
+/**
+ * camel_store_folder_unsubscribed:
+ * @store: a #CamelStore
+ * @info: information about the unsubscribed folder
+ *
+ * Emits the #CamelStore::folder-unsubscribed signal.
+ *
+ * This function is only intended for Camel providers.
+ *
+ * Since: 2.32
+ **/
+void
+camel_store_folder_unsubscribed (CamelStore *store,
+ CamelFolderInfo *info)
+{
+ g_return_if_fail (CAMEL_STORE (store));
+ g_return_if_fail (info != NULL);
+
+ g_signal_emit (store, signals[FOLDER_UNSUBSCRIBED], 0, info);
+}
+
+static void
+add_special_info (CamelStore *store,
+ CamelFolderInfo *info,
+ const gchar *name,
+ const gchar *translated,
+ gboolean unread_count,
+ guint32 flags)
+{
+ CamelFolderInfo *fi, *vinfo, *parent;
+ gchar *uri, *path;
+ CamelURL *url;
+
+ g_return_if_fail (info != NULL);
+
+ parent = NULL;
+ for (fi = info; fi; fi = fi->next) {
+ if (!strcmp (fi->full_name, name))
+ break;
+ parent = fi;
+ }
+
+ /* create our vTrash/vJunk URL */
+ url = camel_url_new (info->uri, NULL);
+ if (((CamelService *) store)->provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) {
+ camel_url_set_fragment (url, name);
+ } else {
+ path = g_strdup_printf ("/%s", name);
+ camel_url_set_path (url, path);
+ g_free (path);
+ }
+
+ uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
+ camel_url_free (url);
+
+ if (fi) {
+ /* We're going to replace the physical Trash/Junk folder with our vTrash/vJunk folder */
+ vinfo = fi;
+ g_free (vinfo->full_name);
+ g_free (vinfo->name);
+ g_free (vinfo->uri);
+ } else {
+ /* There wasn't a Trash/Junk folder so create a new folder entry */
+ vinfo = camel_folder_info_new ();
+
+ g_assert (parent != NULL);
+
+ vinfo->flags |= CAMEL_FOLDER_NOINFERIORS | CAMEL_FOLDER_SUBSCRIBED;
+
+ /* link it into the right spot */
+ vinfo->next = parent->next;
+ parent->next = vinfo;
+ }
+
+ /* Fill in the new fields */
+ vinfo->flags |= flags;
+ vinfo->full_name = g_strdup (name);
+ vinfo->name = g_strdup (translated);
+ vinfo->uri = uri;
+ if (!unread_count)
+ vinfo->unread = -1;
+}
+
+static void
+dump_fi (CamelFolderInfo *fi, gint depth)
+{
+ gchar *s;
+
+ s = g_alloca (depth+1);
+ memset (s, ' ', depth);
+ s[depth] = 0;
+
+ while (fi) {
+ printf("%suri: %s\n", s, fi->uri);
+ printf("%sfull_name: %s\n", s, fi->full_name);
+ printf("%sflags: %08x\n", s, fi->flags);
+ dump_fi (fi->child, depth+2);
+ fi = fi->next;
+ }
+}
+
+/**
+ * camel_store_free_folder_info:
+ * @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,
+ * nothing is done, the routine simply returns.
+ **/
+void
+camel_store_free_folder_info (CamelStore *store,
+ CamelFolderInfo *fi)
+{
+ CamelStoreClass *class;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ if (fi == NULL)
+ return;
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_if_fail (class->free_folder_info != NULL);
+
+ class->free_folder_info (store, fi);
+}
+
+/**
+ * camel_store_free_folder_info_full:
+ * @store: a #CamelStore
+ * @fi: a #CamelFolderInfo as gotten via #camel_store_get_folder_info
+ *
+ * An implementation for #CamelStore::free_folder_info. Frees all
+ * of the data.
+ **/
+void
+camel_store_free_folder_info_full (CamelStore *store,
+ CamelFolderInfo *fi)
+{
+ camel_folder_info_free (fi);
+}
+
+/**
+ * camel_store_free_folder_info_nop:
+ * @store: a #CamelStore
+ * @fi: a #CamelFolderInfo as gotten via #camel_store_get_folder_info
+ *
+ * An implementation for #CamelStore::free_folder_info. Does nothing.
+ **/
+void
+camel_store_free_folder_info_nop (CamelStore *store,
+ CamelFolderInfo *fi)
+{
+ ;
+}
+
+/**
+ * camel_folder_info_free:
+ * @fi: a #CamelFolderInfo
+ *
+ * Frees @fi.
+ **/
+void
+camel_folder_info_free (CamelFolderInfo *fi)
+{
+ if (fi != NULL) {
+ camel_folder_info_free (fi->next);
+ camel_folder_info_free (fi->child);
+ g_free (fi->name);
+ g_free (fi->full_name);
+ g_free (fi->uri);
+ g_slice_free (CamelFolderInfo, fi);
+ }
+}
+
+/**
+ * camel_folder_info_new:
+ *
+ * Returns: a new empty CamelFolderInfo instance
+ *
+ * Since: 2.22
+ **/
+CamelFolderInfo *
+camel_folder_info_new (void)
+{
+ return g_slice_new0 (CamelFolderInfo);
+}
+
+static gint
+folder_info_cmp (gconstpointer ap,
+ gconstpointer bp)
+{
+ const CamelFolderInfo *a = ((CamelFolderInfo **)ap)[0];
+ const CamelFolderInfo *b = ((CamelFolderInfo **)bp)[0];
+
+ return strcmp (a->full_name, b->full_name);
+}
+
+/**
+ * camel_folder_info_build:
+ * @folders: an array of #CamelFolderInfo
+ * @namespace: an ignorable prefix on the folder names
+ * @separator: the hieararchy separator character
+ * @short_names: %TRUE if the (short) name of a folder is the part after
+ * the last @separator in the full name. %FALSE if it is the full name.
+ *
+ * This takes an array of folders and attaches them together according
+ * to the hierarchy described by their full_names and @separator. If
+ * @namespace is non-%NULL, then it will be ignored as a full_name
+ * prefix, for purposes of comparison. If necessary,
+ * #camel_folder_info_build will create additional #CamelFolderInfo with
+ * %NULL urls to fill in gaps in the tree. The value of @short_names
+ * is used in constructing the names of these intermediate folders.
+ *
+ * NOTE: This is deprected, do not use this.
+ * FIXME: remove this/move it to imap, which is the only user of it now.
+ *
+ * Returns: the top level of the tree of linked folder info.
+ **/
+CamelFolderInfo *
+camel_folder_info_build (GPtrArray *folders,
+ const gchar *namespace,
+ gchar separator,
+ gboolean short_names)
+{
+ CamelFolderInfo *fi, *pfi, *top = NULL, *tail = NULL;
+ GHashTable *hash;
+ gchar *p, *pname;
+ gint i, nlen;
+
+ if (!namespace)
+ namespace = "";
+ nlen = strlen (namespace);
+
+ qsort (folders->pdata, folders->len, sizeof (folders->pdata[0]), folder_info_cmp);
+
+ /* Hash the folders. */
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ for (i = 0; i < folders->len; i++) {
+ fi = folders->pdata[i];
+ g_hash_table_insert (hash, g_strdup (fi->full_name), fi);
+ }
+
+ /* Now find parents. */
+ for (i = 0; i < folders->len; i++) {
+ fi = folders->pdata[i];
+ if (!strncmp (namespace, fi->full_name, nlen)
+ && (p = strrchr (fi->full_name+nlen, separator))) {
+ pname = g_strndup (fi->full_name, p - fi->full_name);
+ pfi = g_hash_table_lookup (hash, pname);
+ if (pfi) {
+ g_free (pname);
+ } else {
+ /* we are missing a folder in the heirarchy so
+ create a fake folder node */
+ const gchar *path;
+ CamelURL *url;
+ gchar *sep;
+
+ pfi = camel_folder_info_new ();
+ if (short_names) {
+ pfi->name = strrchr (pname, separator);
+ if (pfi->name)
+ pfi->name = g_strdup (pfi->name + 1);
+ else
+ pfi->name = g_strdup (pname);
+ } else
+ pfi->name = g_strdup (pname);
+
+ url = camel_url_new (fi->uri, NULL);
+ if (url->fragment)
+ path = url->fragment;
+ else
+ path = url->path + 1;
+
+ sep = strrchr (path, separator);
+ if (sep)
+ *sep = '\0';
+ else {
+ d(g_warning ("huh, no \"%c\" in \"%s\"?", separator, fi->uri));
+ }
+
+ pfi->full_name = g_strdup (path);
+
+ /* since this is a "fake" folder node, it is not selectable */
+ camel_url_set_param (url, "noselect", "yes");
+ pfi->uri = camel_url_to_string (url, 0);
+ camel_url_free (url);
+
+ g_hash_table_insert (hash, pname, pfi);
+ g_ptr_array_add (folders, pfi);
+ }
+ tail = (CamelFolderInfo *)&pfi->child;
+ while (tail->next)
+ tail = tail->next;
+ tail->next = fi;
+ fi->parent = pfi;
+ } else if (!top)
+ top = fi;
+ }
+ g_hash_table_destroy (hash);
+
+ /* Link together the top-level folders */
+ tail = top;
+ for (i = 0; i < folders->len; i++) {
+ fi = folders->pdata[i];
+
+ if (fi->child)
+ fi->flags &= ~CAMEL_FOLDER_NOCHILDREN;
+
+ if (fi->parent || fi == top)
+ continue;
+ if (tail == NULL) {
+ tail = fi;
+ top = fi;
+ } else {
+ tail->next = fi;
+ tail = fi;
+ }
+ }
+
+ return top;
+}
+
+static CamelFolderInfo *
+folder_info_clone_rec (CamelFolderInfo *fi,
+ CamelFolderInfo *parent)
+{
+ CamelFolderInfo *info;
+
+ info = camel_folder_info_new ();
+ info->parent = parent;
+ info->uri = g_strdup (fi->uri);
+ info->name = g_strdup (fi->name);
+ info->full_name = g_strdup (fi->full_name);
+ info->unread = fi->unread;
+ info->flags = fi->flags;
+
+ if (fi->next)
+ info->next = folder_info_clone_rec (fi->next, parent);
+ else
+ info->next = NULL;
+
+ if (fi->child)
+ info->child = folder_info_clone_rec (fi->child, info);
+ else
+ info->child = NULL;
+
+ return info;
+}
+
+/**
+ * camel_folder_info_clone:
+ * @fi: a #CamelFolderInfo
+ *
+ * Clones @fi recursively.
+ *
+ * Returns: the cloned #CamelFolderInfo tree.
+ **/
+CamelFolderInfo *
+camel_folder_info_clone (CamelFolderInfo *fi)
+{
+ if (fi == NULL)
+ return NULL;
+
+ return folder_info_clone_rec (fi, NULL);
+}
+
+/**
+ * camel_store_supports_subscriptions:
+ * @store: a #CamelStore
+ *
+ * Get whether or not @store supports subscriptions to folders.
+ *
+ * Returns: %TRUE if folder subscriptions are supported or %FALSE otherwise
+ **/
+gboolean
+camel_store_supports_subscriptions (CamelStore *store)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+
+ return (store->flags & CAMEL_STORE_SUBSCRIPTIONS);
+}
+
+/**
+ * camel_store_folder_is_subscribed:
+ * @store: a #CamelStore
+ * @folder_name: full path of the folder
+ *
+ * Find out if a folder has been subscribed to.
+ *
+ * Returns: %TRUE if the folder has been subscribed to or %FALSE otherwise
+ **/
+gboolean
+camel_store_folder_is_subscribed (CamelStore *store,
+ const gchar *folder_name)
+{
+ CamelStoreClass *class;
+ gboolean is_subscribed;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (folder_name != NULL, FALSE);
+ g_return_val_if_fail (store->flags & CAMEL_STORE_SUBSCRIPTIONS, FALSE);
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->folder_is_subscribed != NULL, FALSE);
+
+ camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ is_subscribed = class->folder_is_subscribed (store, folder_name);
+
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+
+ return is_subscribed;
+}
+
+/**
+ * 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 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.
+ * 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.
*
- * Returns: a #CamelFolderInfo tree, which must be freed with
- * #camel_store_free_folder_info, or %NULL.
+ * Since: 2.34
**/
-CamelFolderInfo *
-camel_store_get_folder_info_sync (CamelStore *store,
- const gchar *top,
- guint32 flags,
- GCancellable *cancellable,
- GError **error)
+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;
- CamelFolderInfo *info;
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_sync != NULL, NULL);
+ g_return_val_if_fail (class->get_trash_folder_finish != 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);
+ return class->get_trash_folder_finish (store, result, 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);
+/**
+ * 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;
}
- 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 ();
+ 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;
}
- return info;
+ 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_free_folder_info:
- * @store: a #CamelStore object
- * @fi: a #CamelFolderInfo as gotten via #camel_store_get_folder_info
+ * 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
*
- * Frees the data returned by #camel_store_get_folder_info. If @fi is %NULL,
- * nothing is done, the routine simply returns.
+ * 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_free_folder_info (CamelStore *store,
- CamelFolderInfo *fi)
+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));
-
- if (fi == NULL)
- return;
+ g_return_if_fail (folder_name != NULL);
class = CAMEL_STORE_GET_CLASS (store);
- g_return_if_fail (class->free_folder_info != NULL);
+ g_return_if_fail (class->create_folder != NULL);
- class->free_folder_info (store, fi);
+ class->create_folder (
+ store, parent_name, folder_name, io_priority,
+ cancellable, callback, user_data);
}
/**
- * camel_store_free_folder_info_full:
- * @store: a #CamelStore object
- * @fi: a #CamelFolderInfo as gotten via #camel_store_get_folder_info
+ * camel_store_create_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
*
- * An implementation for #CamelStore::free_folder_info. Frees all
- * of the data.
+ * 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
**/
-void
-camel_store_free_folder_info_full (CamelStore *store,
- CamelFolderInfo *fi)
+CamelFolderInfo *
+camel_store_create_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- camel_folder_info_free (fi);
+ 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_free_folder_info_nop:
- * @store: a #CamelStore object
- * @fi: a #CamelFolderInfo as gotten via #camel_store_get_folder_info
+ * 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
*
- * An implementation for #CamelStore::free_folder_info. Does nothing.
+ * Deletes the folder described by @folder_name. The folder must be empty.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 2.34
**/
-void
-camel_store_free_folder_info_nop (CamelStore *store,
- CamelFolderInfo *fi)
+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_folder_info_free:
- * @fi: a #CamelFolderInfo
+ * 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
*
- * Frees @fi.
+ * 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_folder_info_free (CamelFolderInfo *fi)
+camel_store_delete_folder (CamelStore *store,
+ const gchar *folder_name,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- if (fi != NULL) {
- camel_folder_info_free (fi->next);
- camel_folder_info_free (fi->child);
- g_free (fi->name);
- g_free (fi->full_name);
- g_free (fi->uri);
- g_slice_free (CamelFolderInfo, fi);
- }
+ 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_folder_info_new:
+ * camel_store_delete_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
*
- * Returns: a new empty CamelFolderInfo instance
+ * Finishes the operation started with camel_store_delete_folder().
*
- * Since: 2.22
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
-CamelFolderInfo *
-camel_folder_info_new (void)
+gboolean
+camel_store_delete_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
- return g_slice_new0 (CamelFolderInfo);
-}
+ CamelStoreClass *class;
-static gint
-folder_info_cmp (gconstpointer ap,
- gconstpointer bp)
-{
- const CamelFolderInfo *a = ((CamelFolderInfo **)ap)[0];
- const CamelFolderInfo *b = ((CamelFolderInfo **)bp)[0];
+ 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 strcmp (a->full_name, b->full_name);
+ return class->delete_folder_finish (store, result, error);
}
/**
- * camel_folder_info_build:
- * @folders: an array of #CamelFolderInfo
- * @namespace: an ignorable prefix on the folder names
- * @separator: the hieararchy separator character
- * @short_names: %TRUE if the (short) name of a folder is the part after
- * the last @separator in the full name. %FALSE if it is the full name.
+ * 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
*
- * This takes an array of folders and attaches them together according
- * to the hierarchy described by their full_names and @separator. If
- * @namespace is non-%NULL, then it will be ignored as a full_name
- * prefix, for purposes of comparison. If necessary,
- * #camel_folder_info_build will create additional #CamelFolderInfo with
- * %NULL urls to fill in gaps in the tree. The value of @short_names
- * is used in constructing the names of these intermediate folders.
+ * Renames the folder described by @old_name to @new_name.
*
- * NOTE: This is deprected, do not use this.
- * FIXME: remove this/move it to imap, which is the only user of it now.
+ * Returns: %TRUE on success, %FALSE on error
*
- * Returns: the top level of the tree of linked folder info.
+ * Since: 2.34
**/
-CamelFolderInfo *
-camel_folder_info_build (GPtrArray *folders,
- const gchar *namespace,
- gchar separator,
- gboolean short_names)
+gboolean
+camel_store_rename_folder_sync (CamelStore *store,
+ const gchar *old_namein,
+ const gchar *new_name,
+ GCancellable *cancellable,
+ GError **error)
{
- CamelFolderInfo *fi, *pfi, *top = NULL, *tail = NULL;
- GHashTable *hash;
- gchar *p, *pname;
- gint i, nlen;
+ CamelStoreClass *class;
+ CamelFolder *folder;
+ gint i, oldlen, namelen;
+ GPtrArray *folders = NULL;
+ gchar *old_name;
+ gboolean success;
- if (!namespace)
- namespace = "";
- nlen = strlen (namespace);
+ 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);
- qsort (folders->pdata, folders->len, sizeof (folders->pdata[0]), folder_info_cmp);
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->rename_folder_sync != NULL, FALSE);
- /* Hash the folders. */
- hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- for (i = 0; i < folders->len; i++) {
- fi = folders->pdata[i];
- g_hash_table_insert (hash, g_strdup (fi->full_name), fi);
- }
+ if (strcmp (old_namein, new_name) == 0)
+ return TRUE;
- /* Now find parents. */
- for (i = 0; i < folders->len; i++) {
- fi = folders->pdata[i];
- if (!strncmp (namespace, fi->full_name, nlen)
- && (p = strrchr (fi->full_name+nlen, separator))) {
- pname = g_strndup (fi->full_name, p - fi->full_name);
- pfi = g_hash_table_lookup (hash, pname);
- if (pfi) {
- g_free (pname);
- } else {
- /* we are missing a folder in the heirarchy so
- create a fake folder node */
- const gchar *path;
- CamelURL *url;
- gchar *sep;
+ 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;
+ }
- pfi = camel_folder_info_new ();
- if (short_names) {
- pfi->name = strrchr (pname, separator);
- if (pfi->name)
- pfi->name = g_strdup (pfi->name + 1);
- else
- pfi->name = g_strdup (pname);
- } else
- pfi->name = g_strdup (pname);
+ /* 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);
- url = camel_url_new (fi->uri, NULL);
- if (url->fragment)
- path = url->fragment;
- else
- path = url->path + 1;
+ camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
- sep = strrchr (path, separator);
- if (sep)
- *sep = '\0';
- else {
- d(g_warning ("huh, no \"%c\" in \"%s\"?", separator, fi->uri));
- }
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
+ return FALSE;
+ }
- pfi->full_name = g_strdup (path);
+ /* 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;
- /* since this is a "fake" folder node, it is not selectable */
- camel_url_set_param (url, "noselect", "yes");
- pfi->uri = camel_url_to_string (url, 0);
- camel_url_free (url);
+ folder = folders->pdata[i];
+ full_name = camel_folder_get_full_name (folder);
- g_hash_table_insert (hash, pname, pfi);
- g_ptr_array_add (folders, pfi);
+ 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);
}
- tail = (CamelFolderInfo *)&pfi->child;
- while (tail->next)
- tail = tail->next;
- tail->next = fi;
- fi->parent = pfi;
- } else if (!top)
- top = fi;
+ }
}
- g_hash_table_destroy (hash);
- /* Link together the top-level folders */
- tail = top;
- for (i = 0; i < folders->len; i++) {
- fi = folders->pdata[i];
+ /* 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 (fi->child)
- fi->flags &= ~CAMEL_FOLDER_NOCHILDREN;
+ /* If it worked, update all open folders/unlock them */
+ if (folders) {
+ if (success) {
+ guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE;
+ CamelFolderInfo *folder_info;
- if (fi->parent || fi == top)
- continue;
- if (tail == NULL) {
- tail = fi;
- top = fi;
- } else {
- tail->next = fi;
- tail = fi;
- }
- }
+ for (i=0;i<folders->len;i++) {
+ const gchar *full_name;
+ gchar *new;
- return top;
-}
+ folder = folders->pdata[i];
+ full_name = camel_folder_get_full_name (folder);
-static CamelFolderInfo *
-folder_info_clone_rec (CamelFolderInfo *fi,
- CamelFolderInfo *parent)
-{
- CamelFolderInfo *info;
+ 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);
- info = camel_folder_info_new ();
- info->parent = parent;
- info->uri = g_strdup (fi->uri);
- info->name = g_strdup (fi->name);
- info->full_name = g_strdup (fi->full_name);
- info->unread = fi->unread;
- info->flags = fi->flags;
+ camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+ g_object_unref (folder);
+ }
- if (fi->next)
- info->next = folder_info_clone_rec (fi->next, parent);
- else
- info->next = NULL;
+ /* Emit renamed signal */
+ if (store->flags & CAMEL_STORE_SUBSCRIPTIONS)
+ flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
- if (fi->child)
- info->child = folder_info_clone_rec (fi->child, info);
- else
- info->child = NULL;
+ folder_info = class->get_folder_info_sync (
+ store, new_name, flags, cancellable, error);
+ CAMEL_CHECK_GERROR (store, get_folder_info, folder_info != NULL, error);
- return info;
-}
+ 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_folder_info_clone:
- * @fi: a #CamelFolderInfo
- *
- * Clones @fi recursively.
- *
- * Returns: the cloned #CamelFolderInfo tree.
- **/
-CamelFolderInfo *
-camel_folder_info_clone (CamelFolderInfo *fi)
-{
- if (fi == NULL)
- return NULL;
+ camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
- return folder_info_clone_rec (fi, NULL);
+ g_ptr_array_free (folders, TRUE);
+ g_free (old_name);
+
+ return success;
}
/**
- * camel_store_supports_subscriptions:
- * @store: a #CamelStore object
+ * 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
*
- * Get whether or not @store supports subscriptions to folders.
+ * Asynchronously renames the folder described by @old_name to @new_name.
*
- * Returns: %TRUE if folder subscriptions are supported or %FALSE otherwise
+ * 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
**/
-gboolean
-camel_store_supports_subscriptions (CamelStore *store)
+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)
{
- g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ CamelStoreClass *class;
- return (store->flags & CAMEL_STORE_SUBSCRIPTIONS);
+ 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_folder_is_subscribed:
- * @store: a #CamelStore object
- * @folder_name: full path of the folder
+ * camel_store_rename_folder_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
*
- * Find out if a folder has been subscribed to.
+ * Finishes the operation started with camel_store_rename_folder().
*
- * Returns: %TRUE if the folder has been subscribed to or %FALSE otherwise
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.34
**/
gboolean
-camel_store_folder_is_subscribed (CamelStore *store,
- const gchar *folder_name)
+camel_store_rename_folder_finish (CamelStore *store,
+ GAsyncResult *result,
+ GError **error)
{
CamelStoreClass *class;
- gboolean is_subscribed;
g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
- g_return_val_if_fail (folder_name != NULL, FALSE);
- g_return_val_if_fail (store->flags & CAMEL_STORE_SUBSCRIPTIONS, FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
class = CAMEL_STORE_GET_CLASS (store);
- g_return_val_if_fail (class->folder_is_subscribed != NULL, FALSE);
-
- camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
-
- is_subscribed = class->folder_is_subscribed (store, folder_name);
+ g_return_val_if_fail (class->rename_folder_finish != NULL, FALSE);
- camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
-
- return is_subscribed;
+ 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,
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);
}
/**
+ * 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,
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);
}
/**
- * 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);
+ g_return_val_if_fail (class->unsubscribe_folder_finish != NULL, FALSE);
- success = class->noop_sync (store, cancellable, error);
- CAMEL_CHECK_GERROR (store, noop_sync, success, error);
-
- 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);
}
GHashFunc hash_folder_name;
GCompareFunc compare_folder_name;
- /* Methods */
+ /* Non-Blocking Methods */
gboolean (*can_refresh_folder) (CamelStore *store,
CamelFolderInfo *info,
GError **error);
void (*free_folder_info) (CamelStore *store,
CamelFolderInfo *fi);
+ /* Synchronous I/O Methods */
CamelFolder * (*get_folder_sync) (CamelStore *store,
const gchar *folder_name,
guint32 flags,
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);
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,
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
(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;
}
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;
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
}
/**
+ * 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
* @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,
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);
}
/**
- * 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);
}
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 */
static gboolean
vee_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
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)
{
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);
static gboolean
vtrash_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
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)
{
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);
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");
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 (
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);
}
goto end1;
}
- camel_operation_start (
+ camel_operation_push_message (
msg->cancellable,
_("Checking for deleted messages %s"),
camel_folder_get_name (m->folder));
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);
is_junk = TRUE;
}
- camel_operation_start (
+ camel_operation_push_message (
cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (folder));
g_object_unref (item);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_free (container_id);
g_string_free (str_to, TRUE);
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;
static gboolean
groupwise_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
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);
groupwise_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *destination,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
}
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;
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 */
return NULL;
}
- camel_operation_start (
+ camel_operation_push_message (
cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (folder));
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)
return FALSE;
}
- camel_operation_start (
+ camel_operation_push_message (
cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (folder));
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;
}
e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
}
if (done) {
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);
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,
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)
g_object_unref (temp_item);
g_object_unref (item);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return TRUE;
}
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);
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
}
/* 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;
}
"UID FETCH 1:%s (FLAGS)", uid);
g_free (uid);
if (!ok) {
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return FALSE;
}
}
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++) {
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;
}
static gboolean
imap_append_offline (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GError **error)
{
static CamelImapResponse *
do_append (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **uid,
GCancellable *cancellable,
GError **error)
static gboolean
imap_append_online (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
gboolean
camel_imap_append_resyncing (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
imap_transfer_offline (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
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)
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 (
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)
{
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! */
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;
}
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);
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);
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;
}
GError **error)
{
CamelMimeMessage *msg;
- gint ret;
+ gboolean success;
if (!stream) {
stream = camel_imap_folder_fetch_data (imap_folder, uid, "",
}
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;
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;
}
return FALSE;
}
- camel_operation_start (
+ camel_operation_push_message (
cancellable,
_("Fetching summary information for new messages in %s"),
camel_folder_get_name (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)
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));
"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;
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);
}
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) */
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
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) {
static gboolean
imapx_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
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;
}
imapx_transfer_messages_to_sync (CamelFolder *source,
GPtrArray *uids,
CamelFolder *dest,
- GPtrArray **transferred_uids,
gboolean delete_originals,
+ GPtrArray **transferred_uids,
GCancellable *cancellable,
GError **error)
{
/* 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));
{
CamelIMAPXCommand *ic;
- camel_operation_start (
+ camel_operation_push_message (
job->cancellable,
_("Scanning for changed messages in %s"),
camel_folder_get_name (job->folder));
} 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));
static gboolean
maildir_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
}
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);
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)
{
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);
camel_folder_thaw (source);
camel_folder_thaw (dest);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
} else
fallback = TRUE;
/* 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;
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 */
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;
}
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);
g_free (src);
g_free (dest);
}
- camel_operation_end (cancellable);
+
+ camel_operation_pop_message (cancellable);
closedir (dir);
}
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);
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);
static gboolean
mbox_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
}
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);
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) {
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;
}
}
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return ok;
}
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) {
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;
}
}
tmpname = NULL;
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return 0;
error:
if (tmpname)
g_unlink (tmpname);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
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) {
_("Could not open file: %s: %s"),
cls->folder_path, g_strerror (errno));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
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;
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;
static gboolean
mh_folder_append_message_sync (CamelFolder *folder,
CamelMimeMessage *message,
- const CamelMessageInfo *info,
+ CamelMessageInfo *info,
gchar **appended_uid,
GCancellable *cancellable,
GError **error)
}
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);
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) {
_("Could not open file: %s: %s"),
((CamelLocalSummary *)cls)->folder_path,
g_strerror (errno));
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
if (tmpname[0] != '\0')
unlink (tmpname);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return 0;
error:
if (tmpname[0] != '\0')
unlink (tmpname);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return -1;
}
}
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;
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);
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,
camel_header_raw_clear (&headers);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_folder_summary_free_hashtable (summary_table);
mp = camel_mime_parser_new ();
- camel_operation_start (
+ camel_operation_push_message (
cancellable, _("%s: Scanning new messages"),
((CamelService *)store)->url->host);
}
g_object_unref (mp);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_folder_summary_free_hashtable (summary_table);
/* 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
}
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;
done:
g_object_unref (stream);
fail:
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return message;
}
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);
/* dont need this anymore */
g_hash_table_destroy (pop3_folder->uids_id);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return success;
}
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];
cancellable, (i+1) * 100 / pop3_folder->uids->len);
}
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
camel_pop3_store_expunge (pop3_store, error);
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;
cancellable, (i+1) * 100 / pop3_folder->uids->len);
}
- camel_operation_end (cancellable);
-
camel_pop3_store_expunge (pop3_store, error);
return 0;
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);
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;
}
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;
}
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;
}
transport->authtypes = NULL;
}
- camel_operation_start_transient (cancellable, _("SMTP Greeting"));
+ camel_operation_push_message (cancellable, _("SMTP Greeting"));
addr = transport->localaddr;
addrlen = transport->localaddrlen;
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);
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;
}
} while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */
g_free (respbuf);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
return TRUE;
}
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."));
}
g_object_unref (sasl);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_free (respbuf);
lose:
g_object_unref (sasl);
- camel_operation_end (cancellable);
+ camel_operation_pop_message (cancellable);
g_free (respbuf);
<title>Index of deprecated symbols</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-2.34" role="2.34">
+ <title>Index of new symbols in 2.34</title>
+ <xi:include href="xml/api-index-2.34.xml"><xi:fallback /></xi:include>
+ </index>
<index id="api-index-2.32" role="2.32">
<title>Index of new symbols in 2.32</title>
<xi:include href="xml/api-index-2.32.xml"><xi:fallback /></xi:include>
camel_cipher_validity_mode_t
camel_cipher_context_new
camel_cipher_context_get_session
-camel_cipher_id_to_hash
-camel_cipher_hash_to_id
-camel_cipher_sign_sync
-camel_cipher_verify_sync
-camel_cipher_encrypt_sync
-camel_cipher_decrypt_sync
-camel_cipher_import_keys_sync
-camel_cipher_export_keys_sync
+camel_cipher_context_id_to_hash
+camel_cipher_context_hash_to_id
+camel_cipher_context_sign_sync
+camel_cipher_context_sign
+camel_cipher_context_sign_finish
+camel_cipher_context_verify_sync
+camel_cipher_context_verify
+camel_cipher_context_verify_finish
+camel_cipher_context_encrypt_sync
+camel_cipher_context_encrypt
+camel_cipher_context_encrypt_finish
+camel_cipher_context_decrypt_sync
+camel_cipher_context_decrypt
+camel_cipher_context_decrypt_finish
+camel_cipher_context_import_keys_sync
+camel_cipher_context_import_keys
+camel_cipher_context_import_keys_finish
+camel_cipher_context_export_keys_sync
+camel_cipher_context_export_keys
+camel_cipher_context_export_keys_finish
camel_cipher_validity_new
camel_cipher_validity_init
camel_cipher_validity_get_valid
camel_data_wrapper_set_mime_type_field
camel_data_wrapper_is_offline
camel_data_wrapper_write_to_stream_sync
+camel_data_wrapper_write_to_stream
+camel_data_wrapper_write_to_stream_finish
camel_data_wrapper_decode_to_stream_sync
+camel_data_wrapper_decode_to_stream
+camel_data_wrapper_decode_to_stream_finish
camel_data_wrapper_construct_from_stream_sync
+camel_data_wrapper_construct_from_stream
+camel_data_wrapper_construct_from_stream_finish
CamelDataWrapperLock
camel_data_wrapper_lock
camel_data_wrapper_unlock
camel_folder_free_deep
camel_folder_get_filename
camel_folder_append_message_sync
+camel_folder_append_message
+camel_folder_append_message_finish
camel_folder_expunge_sync
+camel_folder_expunge
+camel_folder_expunge_finish
camel_folder_get_message_sync
+camel_folder_get_message
+camel_folder_get_message_finish
camel_folder_refresh_info_sync
+camel_folder_refresh_info
+camel_folder_refresh_info_finish
camel_folder_synchronize_sync
+camel_folder_synchronize
+camel_folder_synchronize_finish
camel_folder_synchronize_message_sync
+camel_folder_synchronize_message
+camel_folder_synchronize_message_finish
camel_folder_transfer_messages_to_sync
+camel_folder_transfer_messages_to
+camel_folder_transfer_messages_to_finish
camel_folder_change_info_new
camel_folder_change_info_clear
camel_folder_change_info_free
camel_mime_message_build_mbox_from
camel_mime_message_has_attachment
camel_mime_message_dump
+camel_mime_message_build_preview
<SUBSECTION Standard>
CAMEL_MIME_MESSAGE
CAMEL_IS_MIME_MESSAGE
camel_mime_part_set_content_type
camel_mime_part_get_content_type
camel_mime_part_construct_from_parser_sync
+camel_mime_part_construct_from_parser
+camel_mime_part_construct_from_parser_finish
camel_mime_part_set_content
-camel_mime_part_get_content_size
camel_mime_part_construct_content_from_parser
-camel_mime_message_build_preview
<SUBSECTION Standard>
CAMEL_MIME_PART
CAMEL_IS_MIME_PART
camel_offline_folder_get_offline_sync
camel_offline_folder_set_offline_sync
camel_offline_folder_downsync_sync
+camel_offline_folder_downsync
+camel_offline_folder_downsync_finish
<SUBSECTION Standard>
CAMEL_OFFLINE_FOLDER
CAMEL_IS_OFFLINE_FOLDER
camel_operation_cancel_check
camel_operation_cancel_fd
camel_operation_cancel_prfd
-camel_operation_start
-camel_operation_start_transient
+camel_operation_push_message
+camel_operation_pop_message
camel_operation_progress
-camel_operation_end
<SUBSECTION Standard>
CAMEL_OPERATION
CAMEL_IS_OPERATION
camel_sasl_get_service
camel_sasl_get_service_name
camel_sasl_challenge_sync
+camel_sasl_challenge
+camel_sasl_challenge_finish
camel_sasl_challenge_base64_sync
+camel_sasl_challenge_base64
+camel_sasl_challenge_base64_finish
camel_sasl_authtype_list
camel_sasl_authtype
<SUBSECTION Standard>
camel_store_lock
camel_store_unlock
camel_store_get_folder_sync
+camel_store_get_folder
+camel_store_get_folder_finish
camel_store_get_folder_info_sync
+camel_store_get_folder_info
+camel_store_get_folder_info_finish
camel_store_get_inbox_folder_sync
+camel_store_get_inbox_folder
+camel_store_get_inbox_folder_finish
camel_store_get_junk_folder_sync
+camel_store_get_junk_folder
+camel_store_get_junk_folder_finish
camel_store_get_trash_folder_sync
+camel_store_get_trash_folder
+camel_store_get_trash_folder_finish
camel_store_create_folder_sync
+camel_store_create_folder
+camel_store_create_folder_finish
camel_store_delete_folder_sync
+camel_store_delete_folder
+camel_store_delete_folder_finish
camel_store_rename_folder_sync
+camel_store_rename_folder
+camel_store_rename_folder_finish
camel_store_subscribe_folder_sync
+camel_store_subscribe_folder
+camel_store_subscribe_folder_finish
camel_store_unsubscribe_folder_sync
+camel_store_unsubscribe_folder
+camel_store_unsubscribe_folder_finish
camel_store_synchronize_sync
+camel_store_synchronize
+camel_store_synchronize_finish
camel_store_noop_sync
+camel_store_noop
+camel_store_noop_finish
<SUBSECTION Standard>
CAMEL_STORE
CAMEL_IS_STORE
<FILE>camel-transport</FILE>
<TITLE>CamelTransport</TITLE>
CamelTransport
-camel_transport_send_to_sync
CamelTransportLock
camel_transport_lock
camel_transport_unlock
+camel_transport_send_to_sync
+camel_transport_send_to
+camel_transport_send_to_finish
<SUBSECTION Standard>
CAMEL_TRANSPORT
CAMEL_IS_TRANSPORT
@Returns:
-<!-- ##### FUNCTION camel_cipher_id_to_hash ##### -->
+<!-- ##### FUNCTION camel_cipher_context_id_to_hash ##### -->
<para>
</para>
@Returns:
-<!-- ##### FUNCTION camel_cipher_hash_to_id ##### -->
+<!-- ##### FUNCTION camel_cipher_context_hash_to_id ##### -->
<para>
</para>
@Returns:
-<!-- ##### FUNCTION camel_cipher_sign_sync ##### -->
+<!-- ##### FUNCTION camel_cipher_context_sign_sync ##### -->
<para>
</para>
@Returns:
-<!-- ##### FUNCTION camel_cipher_verify_sync ##### -->
+<!-- ##### FUNCTION camel_cipher_context_sign ##### -->
<para>
</para>
@context:
+@userid:
+@hash:
@ipart:
+@opart:
+@io_priority:
@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_cipher_context_sign_finish ##### -->
+<para>
+
+</para>
+
+@context:
+@result:
+@error:
+@Returns:
+
+
+<!-- ##### FUNCTION camel_cipher_context_verify_sync ##### -->
+<para>
+
+</para>
+
+@context:
+@ipart:
+@cancellable:
+@error:
+@Returns:
+
+
+<!-- ##### FUNCTION camel_cipher_context_verify ##### -->
+<para>
+
+</para>
+
+@context:
+@ipart:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_cipher_context_verify_finish ##### -->
+<para>
+
+</para>
+
+@context:
+@result:
@error:
@Returns:
-<!-- ##### FUNCTION camel_cipher_encrypt_sync ##### -->
+<!-- ##### FUNCTION camel_cipher_context_encrypt_sync ##### -->
<para>
</para>
@Returns:
-<!-- ##### FUNCTION camel_cipher_decrypt_sync ##### -->
+<!-- ##### FUNCTION camel_cipher_context_encrypt ##### -->
+<para>
+
+</para>
+
+@context:
+@userid:
+@recipients:
+@ipart:
+@opart:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_cipher_context_encrypt_finish ##### -->
+<para>
+
+</para>
+
+@context:
+@result:
+@error:
+@Returns:
+
+
+<!-- ##### FUNCTION camel_cipher_context_decrypt_sync ##### -->
<para>
</para>
@Returns:
-<!-- ##### FUNCTION camel_cipher_import_keys_sync ##### -->
+<!-- ##### FUNCTION camel_cipher_context_decrypt ##### -->
+<para>
+
+</para>
+
+@context:
+@ipart:
+@opart:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_cipher_context_decrypt_finish ##### -->
+<para>
+
+</para>
+
+@context:
+@result:
+@error:
+@Returns:
+
+
+<!-- ##### FUNCTION camel_cipher_context_import_keys_sync ##### -->
+<para>
+
+</para>
+
+@context:
+@istream:
+@cancellable:
+@error:
+@Returns:
+
+
+<!-- ##### FUNCTION camel_cipher_context_import_keys ##### -->
<para>
</para>
@context:
@istream:
+@io_priority:
@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_cipher_context_import_keys_finish ##### -->
+<para>
+
+</para>
+
+@context:
+@result:
@error:
@Returns:
-<!-- ##### FUNCTION camel_cipher_export_keys_sync ##### -->
+<!-- ##### FUNCTION camel_cipher_context_export_keys_sync ##### -->
<para>
</para>
@Returns:
+<!-- ##### FUNCTION camel_cipher_context_export_keys ##### -->
+<para>
+
+</para>
+
+@context:
+@keys:
+@ostream:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_cipher_context_export_keys_finish ##### -->
+<para>
+
+</para>
+
+@context:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_cipher_validity_new ##### -->
<para>
@gpointer cert_data:
@gpointer cert_data:
@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
+@gpointer cert_data:
@gpointer cert_data:
@Returns:
+<!-- ##### FUNCTION camel_data_wrapper_write_to_stream ##### -->
+<para>
+
+</para>
+
+@data_wrapper:
+@stream:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_data_wrapper_write_to_stream_finish ##### -->
+<para>
+
+</para>
+
+@data_wrapper:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_data_wrapper_decode_to_stream_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_data_wrapper_decode_to_stream ##### -->
+<para>
+
+</para>
+
+@data_wrapper:
+@stream:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_data_wrapper_decode_to_stream_finish ##### -->
+<para>
+
+</para>
+
+@data_wrapper:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_data_wrapper_construct_from_stream_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_data_wrapper_construct_from_stream ##### -->
+<para>
+
+</para>
+
+@data_wrapper:
+@stream:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_data_wrapper_construct_from_stream_finish ##### -->
+<para>
+
+</para>
+
+@data_wrapper:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### ENUM CamelDataWrapperLock ##### -->
<para>
</para>
@Param1:
-@Varargs:
+@Param2:
@Param3:
-@Varargs:
+@Param4:
@Param5:
@Returns:
</para>
@info:
+@Returns:
<!-- ##### FUNCTION camel_message_info_new_from_header ##### -->
@Returns:
+<!-- ##### FUNCTION camel_folder_append_message ##### -->
+<para>
+
+</para>
+
+@folder:
+@message:
+@info:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_folder_append_message_finish ##### -->
+<para>
+
+</para>
+
+@folder:
+@result:
+@appended_uid:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_folder_expunge_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_folder_expunge ##### -->
+<para>
+
+</para>
+
+@folder:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_folder_expunge_finish ##### -->
+<para>
+
+</para>
+
+@folder:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_folder_get_message_sync ##### -->
<para>
</para>
@folder:
-@uid:
+@message_uid:
@cancellable:
@error:
@Returns:
+<!-- ##### FUNCTION camel_folder_get_message ##### -->
+<para>
+
+</para>
+
+@folder:
+@message_uid:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_folder_get_message_finish ##### -->
+<para>
+
+</para>
+
+@folder:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_folder_refresh_info_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_folder_refresh_info ##### -->
+<para>
+
+</para>
+
+@folder:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_folder_refresh_info_finish ##### -->
+<para>
+
+</para>
+
+@folder:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_folder_synchronize_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_folder_synchronize ##### -->
+<para>
+
+</para>
+
+@folder:
+@expunge:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_folder_synchronize_finish ##### -->
+<para>
+
+</para>
+
+@folder:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_folder_synchronize_message_sync ##### -->
<para>
</para>
@folder:
-@uid:
+@message_uid:
@cancellable:
@error:
@Returns:
+<!-- ##### FUNCTION camel_folder_synchronize_message ##### -->
+<para>
+
+</para>
+
+@folder:
+@message_uid:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_folder_synchronize_message_finish ##### -->
+<para>
+
+</para>
+
+@folder:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_folder_transfer_messages_to_sync ##### -->
<para>
</para>
@source:
-@uids:
-@dest:
+@message_uids:
+@destination:
+@delete_originals:
@transferred_uids:
+@cancellable:
+@error:
+@Returns:
+
+
+<!-- ##### FUNCTION camel_folder_transfer_messages_to ##### -->
+<para>
+
+</para>
+
+@source:
+@message_uids:
+@destination:
@delete_originals:
+@io_priority:
@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_folder_transfer_messages_to_finish ##### -->
+<para>
+
+</para>
+
+@source:
+@result:
+@transferred_uids:
@error:
@Returns:
</para>
-@msg:
+@message:
@body:
+<!-- ##### FUNCTION camel_mime_message_build_preview ##### -->
+<para>
+
+</para>
+
+@mime_part:
+@info:
+@Returns:
+
+
@Returns:
-<!-- ##### FUNCTION camel_mime_part_set_content ##### -->
+<!-- ##### FUNCTION camel_mime_part_construct_from_parser ##### -->
<para>
</para>
@mime_part:
-@data:
-@length:
-@type:
+@parser:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
-<!-- ##### FUNCTION camel_mime_part_get_content_size ##### -->
+<!-- ##### FUNCTION camel_mime_part_construct_from_parser_finish ##### -->
<para>
</para>
@mime_part:
+@result:
+@error:
@Returns:
-<!-- ##### FUNCTION camel_mime_part_construct_content_from_parser ##### -->
+<!-- ##### FUNCTION camel_mime_part_set_content ##### -->
<para>
</para>
@mime_part:
-@mp:
-@cancellable:
-@error:
-@Returns:
+@data:
+@length:
+@type:
-<!-- ##### FUNCTION camel_mime_message_build_preview ##### -->
+<!-- ##### FUNCTION camel_mime_part_construct_content_from_parser ##### -->
<para>
</para>
@mime_part:
-@info:
+@mp:
+@cancellable:
+@error:
@Returns:
</para>
-@offline:
+@folder:
@Returns:
</para>
-@offline:
+@folder:
@offline_sync:
</para>
-@offline:
+@folder:
@expression:
@cancellable:
@error:
@Returns:
+<!-- ##### FUNCTION camel_offline_folder_downsync ##### -->
+<para>
+
+</para>
+
+@folder:
+@expression:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_offline_folder_downsync_finish ##### -->
+<para>
+
+</para>
+
+@folder:
+@result:
+@error:
+@Returns:
+
+
@Returns:
-<!-- ##### FUNCTION camel_operation_start ##### -->
+<!-- ##### FUNCTION camel_operation_push_message ##### -->
<para>
</para>
@cancellable:
-@what:
+@format:
@Varargs:
-<!-- ##### FUNCTION camel_operation_start_transient ##### -->
+<!-- ##### FUNCTION camel_operation_pop_message ##### -->
<para>
</para>
@cancellable:
-@what:
-@Varargs:
<!-- ##### FUNCTION camel_operation_progress ##### -->
</para>
@cancellable:
-@pc:
-
-
-<!-- ##### FUNCTION camel_operation_end ##### -->
-<para>
-
-</para>
-
-@cancellable:
+@percent:
@Returns:
+<!-- ##### FUNCTION camel_sasl_challenge ##### -->
+<para>
+
+</para>
+
+@sasl:
+@token:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_sasl_challenge_finish ##### -->
+<para>
+
+</para>
+
+@sasl:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_sasl_challenge_base64_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_sasl_challenge_base64 ##### -->
+<para>
+
+</para>
+
+@sasl:
+@token:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_sasl_challenge_base64_finish ##### -->
+<para>
+
+</para>
+
+@sasl:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_sasl_authtype_list ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_get_folder ##### -->
+<para>
+
+</para>
+
+@store:
+@folder_name:
+@flags:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_get_folder_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_get_folder_info_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_get_folder_info ##### -->
+<para>
+
+</para>
+
+@store:
+@top:
+@flags:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_get_folder_info_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_get_inbox_folder_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_get_inbox_folder ##### -->
+<para>
+
+</para>
+
+@store:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_get_inbox_folder_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_get_junk_folder_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_get_junk_folder ##### -->
+<para>
+
+</para>
+
+@store:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_get_junk_folder_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_get_trash_folder_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_get_trash_folder ##### -->
+<para>
+
+</para>
+
+@store:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_get_trash_folder_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_create_folder_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_create_folder ##### -->
+<para>
+
+</para>
+
+@store:
+@parent_name:
+@folder_name:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_create_folder_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_delete_folder_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_delete_folder ##### -->
+<para>
+
+</para>
+
+@store:
+@folder_name:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_delete_folder_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_rename_folder_sync ##### -->
<para>
</para>
@store:
-@old_namein:
+@old_name:
+@new_name:
+@cancellable:
+@error:
+@Returns:
+
+
+<!-- ##### FUNCTION camel_store_rename_folder ##### -->
+<para>
+
+</para>
+
+@store:
+@old_name:
@new_name:
+@io_priority:
@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_rename_folder_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
@error:
@Returns:
@Returns:
+<!-- ##### FUNCTION camel_store_subscribe_folder ##### -->
+<para>
+
+</para>
+
+@store:
+@folder_name:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_subscribe_folder_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_unsubscribe_folder_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_unsubscribe_folder ##### -->
+<para>
+
+</para>
+
+@store:
+@folder_name:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_unsubscribe_folder_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_synchronize_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_synchronize ##### -->
+<para>
+
+</para>
+
+@store:
+@expunge:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_synchronize_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
<!-- ##### FUNCTION camel_store_noop_sync ##### -->
<para>
@Returns:
+<!-- ##### FUNCTION camel_store_noop ##### -->
+<para>
+
+</para>
+
+@store:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
+
+
+<!-- ##### FUNCTION camel_store_noop_finish ##### -->
+<para>
+
+</para>
+
+@store:
+@result:
+@error:
+@Returns:
+
+
</para>
+<!-- ##### ENUM CamelTransportLock ##### -->
+<para>
+
+</para>
+
+@CAMEL_TRANSPORT_SEND_LOCK:
+
+<!-- ##### FUNCTION camel_transport_lock ##### -->
+<para>
+
+</para>
+
+@transport:
+@lock:
+
+
+<!-- ##### FUNCTION camel_transport_unlock ##### -->
+<para>
+
+</para>
+
+@transport:
+@lock:
+
+
<!-- ##### FUNCTION camel_transport_send_to_sync ##### -->
<para>
@Returns:
-<!-- ##### ENUM CamelTransportLock ##### -->
-<para>
-
-</para>
-
-@CAMEL_TRANSPORT_SEND_LOCK:
-
-<!-- ##### FUNCTION camel_transport_lock ##### -->
+<!-- ##### FUNCTION camel_transport_send_to ##### -->
<para>
</para>
@transport:
-@lock:
+@message:
+@from:
+@recipients:
+@io_priority:
+@cancellable:
+@callback:
+@user_data:
-<!-- ##### FUNCTION camel_transport_unlock ##### -->
+<!-- ##### FUNCTION camel_transport_send_to_finish ##### -->
<para>
</para>
@transport:
-@lock:
+@result:
+@error:
+@Returns:
@error:
@Returns:
+<!-- ##### FUNCTION camel_cipher_decrypt_sync ##### -->
+<para>
+
+</para>
+
+@context:
+@ipart:
+@opart:
+@cancellable:
+@error:
+@Returns:
+
<!-- ##### FUNCTION camel_cipher_encrypt ##### -->
<para>
@error:
@Returns:
+<!-- ##### FUNCTION camel_cipher_encrypt_sync ##### -->
+<para>
+
+</para>
+
+@context:
+@userid:
+@recipients:
+@ipart:
+@opart:
+@cancellable:
+@error:
+@Returns:
+
<!-- ##### FUNCTION camel_cipher_export_keys ##### -->
<para>
@error:
@Returns:
-<!-- ##### FUNCTION camel_cipher_import_keys ##### -->
+<!-- ##### FUNCTION camel_cipher_export_keys_sync ##### -->
<para>
</para>
@context:
-@istream:
+@keys:
+@ostream:
@cancellable:
@error:
@Returns:
-<!-- ##### FUNCTION camel_cipher_sign ##### -->
+<!-- ##### FUNCTION camel_cipher_hash_to_id ##### -->
<para>
</para>
@context:
-@userid:
@hash:
-@ipart:
-@opart:
-@cancellable:
-@error:
@Returns:
-<!-- ##### FUNCTION camel_cipher_verify ##### -->
+<!-- ##### FUNCTION camel_cipher_id_to_hash ##### -->
<para>
</para>
@context:
-@ipart:
+@id:
+@Returns:
+
+<!-- ##### FUNCTION camel_cipher_import_keys ##### -->
+<para>
+
+</para>
+
+@context:
+@istream:
@cancellable:
@error:
@Returns:
-<!-- ##### FUNCTION camel_data_cache_clear ##### -->
+<!-- ##### FUNCTION camel_cipher_import_keys_sync ##### -->
<para>
</para>
-@cache:
-@path:
-@ex:
+@context:
+@istream:
+@cancellable:
+@error:
@Returns:
-<!-- ##### FUNCTION camel_data_cache_rename ##### -->
+<!-- ##### FUNCTION camel_cipher_sign ##### -->
<para>
</para>
-@cache:
-@old:
-@new:
-@ex:
+@context:
+@userid:
+@hash:
+@ipart:
+@opart:
+@cancellable:
+@error:
@Returns:
-<!-- ##### FUNCTION camel_data_wrapper_construct_from_stream ##### -->
+<!-- ##### FUNCTION camel_cipher_sign_sync ##### -->
<para>
</para>
-@data_wrapper:
-@stream:
+@context:
+@userid:
+@hash:
+@ipart:
+@opart:
@cancellable:
@error:
@Returns:
-<!-- ##### FUNCTION camel_data_wrapper_decode_to_stream ##### -->
+<!-- ##### FUNCTION camel_cipher_verify ##### -->
<para>
</para>
-@data_wrapper:
-@stream:
+@context:
+@ipart:
@cancellable:
@error:
@Returns:
-<!-- ##### FUNCTION camel_data_wrapper_write_to_stream ##### -->
+<!-- ##### FUNCTION camel_cipher_verify_sync ##### -->
<para>
</para>
-@data_wrapper:
-@stream:
+@context:
+@ipart:
@cancellable:
@error:
@Returns:
+<!-- ##### FUNCTION camel_data_cache_clear ##### -->
+<para>
+
+</para>
+
+@cache:
+@path:
+@ex:
+@Returns:
+
+<!-- ##### FUNCTION camel_data_cache_rename ##### -->
+<para>
+
+</para>
+
+@cache:
+@old:
+@new:
+@ex:
+@Returns:
+
<!-- ##### FUNCTION camel_digest_folder_new ##### -->
<para>
@n:
@Returns:
-<!-- ##### FUNCTION camel_folder_append_message ##### -->
-<para>
-
-</para>
-
-@folder:
-@message:
-@info:
-@appended_uid:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### FUNCTION camel_folder_construct ##### -->
<para>
@full_name:
@name:
-<!-- ##### FUNCTION camel_folder_expunge ##### -->
-<para>
-
-</para>
-
-@folder:
-@cancellable:
-@error:
-@Returns:
-
-<!-- ##### FUNCTION camel_folder_get_message ##### -->
-<para>
-
-</para>
-
-@folder:
-@uid:
-@cancellable:
-@error:
-@Returns:
-
-<!-- ##### FUNCTION camel_folder_refresh_info ##### -->
-<para>
-
-</para>
-
-@folder:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### FUNCTION camel_folder_summary_array_free ##### -->
<para>
@error:
@Returns:
-<!-- ##### FUNCTION camel_folder_transfer_messages_to ##### -->
-<para>
-
-</para>
-
-@source:
-@uids:
-@dest:
-@transferred_uids:
-@delete_originals:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### FUNCTION camel_groupwise_journal_append ##### -->
<para>
@stream:
@Returns:
-<!-- ##### FUNCTION camel_mime_part_construct_from_parser ##### -->
-<para>
-
-</para>
-
-@mime_part:
-@parser:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### FUNCTION camel_mime_part_get_content_MD5 ##### -->
<para>
@Param1:
-<!-- ##### FUNCTION camel_offline_folder_downsync ##### -->
-<para>
-
-</para>
-
-@offline:
-@expression:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### FUNCTION camel_offline_store_get_network_state ##### -->
<para>
@cc:
+<!-- ##### FUNCTION camel_operation_end ##### -->
+<para>
+
+</para>
+
+@cancellable:
+
<!-- ##### FUNCTION camel_operation_mute ##### -->
<para>
@void:
@Returns:
+<!-- ##### FUNCTION camel_operation_start ##### -->
+<para>
+
+</para>
+
+@cancellable:
+@what:
+@Varargs:
+
+<!-- ##### FUNCTION camel_operation_start_transient ##### -->
+<para>
+
+</para>
+
+@cancellable:
+@what:
+@Varargs:
+
<!-- ##### ENUM camel_operation_status_t ##### -->
<para>
@sasl:
@Returns:
-<!-- ##### FUNCTION camel_sasl_challenge ##### -->
-<para>
-
-</para>
-
-@sasl:
-@token:
-@cancellable:
-@error:
-@Returns:
-
-<!-- ##### FUNCTION camel_sasl_challenge_base64 ##### -->
-<para>
-
-</para>
-
-@sasl:
-@token:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### FUNCTION camel_search_build_match_regex ##### -->
<para>
@xevline:
@Returns:
-<!-- ##### FUNCTION camel_store_create_folder ##### -->
-<para>
-
-</para>
-
-@store:
-@parent_name:
-@folder_name:
-@cancellable:
-@error:
-@Returns:
-
-<!-- ##### FUNCTION camel_store_delete_folder ##### -->
-<para>
-
-</para>
-
-@store:
-@folder_name:
-@cancellable:
-@error:
-@Returns:
-
-<!-- ##### FUNCTION camel_store_get_folder ##### -->
-<para>
-
-</para>
-
-@store:
-@folder_name:
-@flags:
-@cancellable:
-@error:
-@Returns:
-
-<!-- ##### FUNCTION camel_store_get_folder_info ##### -->
-<para>
-
-</para>
-
-@store:
-@top:
-@flags:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### FUNCTION camel_store_get_inbox ##### -->
<para>
@error:
@Returns:
-<!-- ##### FUNCTION camel_store_noop ##### -->
-<para>
-
-</para>
-
-@store:
-@cancellable:
-@error:
-@Returns:
-
-<!-- ##### FUNCTION camel_store_rename_folder ##### -->
-<para>
-
-</para>
-
-@store:
-@old_namein:
-@new_name:
-@cancellable:
-@error:
-@Returns:
-
-<!-- ##### FUNCTION camel_store_subscribe_folder ##### -->
-<para>
-
-</para>
-
-@store:
-@folder_name:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### FUNCTION camel_store_sync ##### -->
<para>
@error:
@Returns:
-<!-- ##### FUNCTION camel_store_unsubscribe_folder ##### -->
-<para>
-
-</para>
-
-@store:
-@folder_name:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### FUNCTION camel_stream_filter_new_with_stream ##### -->
<para>
@Returns:
-<!-- ##### FUNCTION camel_transport_send_to ##### -->
-<para>
-
-</para>
-
-@transport:
-@message:
-@from:
-@recipients:
-@cancellable:
-@error:
-@Returns:
-
<!-- ##### MACRO camel_type_get_global_classfuncs ##### -->
<para>