From: Matthew Barnes Date: Sun, 9 May 2010 16:26:48 +0000 (-0500) Subject: Use GCancellable in all methods that may block. X-Git-Tag: upstream/3.7.4~2555 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=db4fd695a3770cbaa817e9e294852697a5dc707d;p=platform%2Fupstream%2Fevolution-data-server.git Use GCancellable in all methods that may block. --- diff --git a/camel/camel-block-file.c b/camel/camel-block-file.c index a910e58..0b93d2a 100644 --- a/camel/camel-block-file.c +++ b/camel/camel-block-file.c @@ -573,7 +573,7 @@ camel_block_file_get_block (CamelBlockFile *bs, bl = g_malloc0 (sizeof (*bl)); bl->id = id; if (lseek (bs->fd, id, SEEK_SET) == -1 || - camel_read (bs->fd, (gchar *) bl->data, CAMEL_BLOCK_SIZE, NULL) == -1) { + camel_read (bs->fd, (gchar *) bl->data, CAMEL_BLOCK_SIZE, NULL, NULL) == -1) { block_file_unuse (bs); CAMEL_BLOCK_FILE_UNLOCK (bs, cache_lock); g_free (bl); diff --git a/camel/camel-cipher-context.c b/camel/camel-cipher-context.c index fd93f58..60d3bca 100644 --- a/camel/camel-cipher-context.c +++ b/camel/camel-cipher-context.c @@ -62,21 +62,220 @@ enum { G_DEFINE_TYPE (CamelCipherContext, camel_cipher_context, CAMEL_TYPE_OBJECT) +static void +cipher_context_set_session (CamelCipherContext *context, + CamelSession *session) +{ + g_return_if_fail (CAMEL_IS_SESSION (session)); + g_return_if_fail (context->priv->session == NULL); + + context->priv->session = g_object_ref (session); +} + +static void +cipher_context_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SESSION: + cipher_context_set_session ( + CAMEL_CIPHER_CONTEXT (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +cipher_context_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SESSION: + g_value_set_object ( + value, camel_cipher_context_get_session ( + CAMEL_CIPHER_CONTEXT (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +cipher_context_dispose (GObject *object) +{ + CamelCipherContextPrivate *priv; + + priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (object); + + if (priv->session != NULL) { + g_object_unref (priv->session); + priv->session = NULL; + } + + /* Chain up to parent's dispose () method. */ + G_OBJECT_CLASS (camel_cipher_context_parent_class)->dispose (object); +} + +static void +cipher_context_finalize (GObject *object) +{ + CamelCipherContextPrivate *priv; + + priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (object); + + g_mutex_free (priv->lock); + + /* Chain up to parent's finalize () method. */ + G_OBJECT_CLASS (camel_cipher_context_parent_class)->finalize (object); +} + +static const gchar * +cipher_hash_to_id (CamelCipherContext *context, + CamelCipherHash hash) +{ + return NULL; +} + +static CamelCipherHash +cipher_id_to_hash (CamelCipherContext *context, + const gchar *id) +{ + return CAMEL_CIPHER_HASH_DEFAULT; +} + static gint cipher_sign (CamelCipherContext *ctx, const gchar *userid, CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, + error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Signing is not supported by this cipher")); return -1; } +static CamelCipherValidity * +cipher_verify (CamelCipherContext *context, + CamelMimePart *sigpart, + GCancellable *cancellable, + GError **error) +{ + g_set_error ( + error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Verifying is not supported by this cipher")); + + return NULL; +} + +static gint +cipher_encrypt (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; +} + +static CamelCipherValidity * +cipher_decrypt (CamelCipherContext *context, + CamelMimePart *ipart, + CamelMimePart *opart, + GCancellable *cancellable, + GError **error) +{ + g_set_error ( + error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Decryption is not supported by this cipher")); + + return NULL; +} + +static gint +cipher_import_keys (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; +} + +static gint +cipher_export_keys (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; +} + +static void +camel_cipher_context_class_init (CamelCipherContextClass *class) +{ + GObjectClass *object_class; + + g_type_class_add_private (class, sizeof (CamelCipherContextPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = cipher_context_set_property; + object_class->get_property = cipher_context_get_property; + 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 = cipher_sign; + class->verify = cipher_verify; + class->encrypt = cipher_encrypt; + class->decrypt = cipher_decrypt; + class->import_keys = cipher_import_keys; + class->export_keys = cipher_export_keys; + + g_object_class_install_property ( + object_class, + PROP_SESSION, + g_param_spec_object ( + "session", + "Session", + NULL, + CAMEL_TYPE_SESSION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +camel_cipher_context_init (CamelCipherContext *context) +{ + context->priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (context); + context->priv->lock = g_mutex_new (); +} + /** * camel_cipher_sign: * @context: Cipher Context @@ -84,6 +283,7 @@ cipher_sign (CamelCipherContext *ctx, * @hash: preferred Message-Integrity-Check hash algorithm * @ipart: Input part. * @opart: output part. + * @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 part @opart. @@ -97,6 +297,7 @@ camel_cipher_sign (CamelCipherContext *context, CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -107,36 +308,22 @@ camel_cipher_sign (CamelCipherContext *context, class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context); g_return_val_if_fail (class->sign != NULL, -1); - camel_operation_start (NULL, _("Signing message")); - CIPHER_LOCK (context); - retval = class->sign (context, userid, hash, ipart, opart, error); + retval = class->sign ( + context, userid, hash, ipart, opart, cancellable, error); CAMEL_CHECK_GERROR (context, sign, retval == 0, error); CIPHER_UNLOCK (context); - camel_operation_end (NULL); - return retval; } -static CamelCipherValidity * -cipher_verify (CamelCipherContext *context, - CamelMimePart *sigpart, - GError **error) -{ - g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, - _("Verifying is not supported by this cipher")); - - return NULL; -} - /** * camel_cipher_verify: * @context: Cipher Context * @ipart: part 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, @@ -151,6 +338,7 @@ cipher_verify (CamelCipherContext *context, CamelCipherValidity * camel_cipher_verify (CamelCipherContext *context, CamelMimePart *ipart, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -161,35 +349,16 @@ camel_cipher_verify (CamelCipherContext *context, class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context); g_return_val_if_fail (class->verify != NULL, NULL); - camel_operation_start (NULL, _("Verifying message")); - CIPHER_LOCK (context); - valid = class->verify (context, ipart, error); + valid = class->verify (context, ipart, cancellable, error); CAMEL_CHECK_GERROR (context, verify, valid != NULL, error); CIPHER_UNLOCK (context); - camel_operation_end (NULL); - return valid; } -static gint -cipher_encrypt (CamelCipherContext *context, - const gchar *userid, - GPtrArray *recipients, - CamelMimePart *ipart, - CamelMimePart *opart, - GError **error) -{ - g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, - _("Encryption is not supported by this cipher")); - - return -1; -} - /** * camel_cipher_encrypt: * @context: Cipher Context @@ -197,6 +366,7 @@ cipher_encrypt (CamelCipherContext *context, * @recipients: an array of recipient key ids and/or email addresses * @ipart: cleartext input stream * @opart: ciphertext output stream + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Encrypts (and optionally signs) the cleartext input stream and @@ -210,6 +380,7 @@ camel_cipher_encrypt (CamelCipherContext *context, GPtrArray *recipients, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -220,39 +391,24 @@ camel_cipher_encrypt (CamelCipherContext *context, class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context); g_return_val_if_fail (class->encrypt != NULL, -1); - camel_operation_start (NULL, _("Encrypting message")); - CIPHER_LOCK (context); retval = class->encrypt ( - context, userid, recipients, ipart, opart, error); + context, userid, recipients, + ipart, opart, cancellable, error); CAMEL_CHECK_GERROR (context, encrypt, retval == 0, error); CIPHER_UNLOCK (context); - camel_operation_end (NULL); - return retval; } -static CamelCipherValidity * -cipher_decrypt (CamelCipherContext *context, - CamelMimePart *ipart, - CamelMimePart *opart, - GError **error) -{ - g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, - _("Decryption is not supported by this cipher")); - - return NULL; -} - /** * camel_cipher_decrypt: * @context: * @ipart: * @opart: + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Decrypts @ipart into @opart. @@ -263,6 +419,7 @@ CamelCipherValidity * camel_cipher_decrypt (CamelCipherContext *context, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -273,36 +430,21 @@ camel_cipher_decrypt (CamelCipherContext *context, class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context); g_return_val_if_fail (class->decrypt != NULL, NULL); - camel_operation_start (NULL, _("Decrypting message")); - CIPHER_LOCK (context); - valid = class->decrypt (context, ipart, opart, error); + valid = class->decrypt (context, ipart, opart, cancellable, error); CAMEL_CHECK_GERROR (context, decrypt, valid != NULL, error); CIPHER_UNLOCK (context); - camel_operation_end (NULL); - return valid; } -static gint -cipher_import_keys (CamelCipherContext *context, - CamelStream *istream, - GError **error) -{ - g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, - _("You may not import keys with this cipher")); - - return -1; -} - /** * camel_cipher_import_keys: * @context: Cipher Context * @istream: 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 @@ -313,6 +455,7 @@ cipher_import_keys (CamelCipherContext *context, gint camel_cipher_import_keys (CamelCipherContext *context, CamelStream *istream, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -324,30 +467,18 @@ camel_cipher_import_keys (CamelCipherContext *context, class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context); g_return_val_if_fail (class->import_keys != NULL, -1); - retval = class->import_keys (context, istream, error); + retval = class->import_keys (context, istream, cancellable, error); CAMEL_CHECK_GERROR (context, import_keys, retval == 0, error); return retval; } -static gint -cipher_export_keys (CamelCipherContext *context, - GPtrArray *keys, - CamelStream *ostream, - GError **error) -{ - g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, - _("You may not export keys with this cipher")); - - return -1; -} - /** * camel_cipher_export_keys: * @context: Cipher Context * @keys: an array of key ids * @ostream: 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 @@ -359,6 +490,7 @@ gint camel_cipher_export_keys (CamelCipherContext *context, GPtrArray *keys, CamelStream *ostream, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -371,18 +503,13 @@ camel_cipher_export_keys (CamelCipherContext *context, class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context); g_return_val_if_fail (class->export_keys != NULL, -1); - retval = class->export_keys (context, keys, ostream, error); + retval = class->export_keys ( + context, keys, ostream, cancellable, error); CAMEL_CHECK_GERROR (context, export_keys, retval == 0, error); return retval; } -static CamelCipherHash -cipher_id_to_hash (CamelCipherContext *context, const gchar *id) -{ - return CAMEL_CIPHER_HASH_DEFAULT; -} - /* a couple of util functions */ CamelCipherHash camel_cipher_id_to_hash (CamelCipherContext *context, @@ -401,12 +528,6 @@ camel_cipher_id_to_hash (CamelCipherContext *context, return class->id_to_hash (context, id); } -static const gchar * -cipher_hash_to_id (CamelCipherContext *context, CamelCipherHash hash) -{ - return NULL; -} - const gchar * camel_cipher_hash_to_id (CamelCipherContext *context, CamelCipherHash hash) @@ -646,120 +767,6 @@ camel_cipher_validity_free (CamelCipherValidity *validity) /* ********************************************************************** */ -static void -cipher_context_set_session (CamelCipherContext *context, - CamelSession *session) -{ - g_return_if_fail (CAMEL_IS_SESSION (session)); - g_return_if_fail (context->priv->session == NULL); - - context->priv->session = g_object_ref (session); -} - -static void -cipher_context_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SESSION: - cipher_context_set_session ( - CAMEL_CIPHER_CONTEXT (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -cipher_context_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SESSION: - g_value_set_object ( - value, camel_cipher_context_get_session ( - CAMEL_CIPHER_CONTEXT (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -cipher_context_dispose (GObject *object) -{ - CamelCipherContextPrivate *priv; - - priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (object); - - if (priv->session != NULL) { - g_object_unref (priv->session); - priv->session = NULL; - } - - /* Chain up to parent's dispose () method. */ - G_OBJECT_CLASS (camel_cipher_context_parent_class)->dispose (object); -} - -static void -cipher_context_finalize (GObject *object) -{ - CamelCipherContextPrivate *priv; - - priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (object); - - g_mutex_free (priv->lock); - - /* Chain up to parent's finalize () method. */ - G_OBJECT_CLASS (camel_cipher_context_parent_class)->finalize (object); -} - -static void -camel_cipher_context_class_init (CamelCipherContextClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (CamelCipherContextPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = cipher_context_set_property; - object_class->get_property = cipher_context_get_property; - 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 = cipher_sign; - class->verify = cipher_verify; - class->encrypt = cipher_encrypt; - class->decrypt = cipher_decrypt; - class->import_keys = cipher_import_keys; - class->export_keys = cipher_export_keys; - - g_object_class_install_property ( - object_class, - PROP_SESSION, - g_param_spec_object ( - "session", - "Session", - NULL, - CAMEL_TYPE_SESSION, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); -} - -static void -camel_cipher_context_init (CamelCipherContext *context) -{ - context->priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (context); - context->priv->lock = g_mutex_new (); -} - /** * camel_cipher_context_new: * @session: a #CamelSession @@ -829,6 +836,7 @@ cc_prepare_sign (CamelMimePart *part) * @part: Part to write. * @flags: flags for the canonicalisation filter (CamelMimeFilterCanon) * @ostream: stream to write canonicalised output to. + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Writes a part to a stream in a canonicalised format, suitable for signing/encrypting. @@ -841,6 +849,7 @@ gint camel_cipher_canonical_to_stream (CamelMimePart *part, guint32 flags, CamelStream *ostream, + GCancellable *cancellable, GError **error) { CamelStream *filter; @@ -856,8 +865,8 @@ camel_cipher_canonical_to_stream (CamelMimePart *part, g_object_unref (canon); if (camel_data_wrapper_write_to_stream ( - (CamelDataWrapper *)part, filter, error) != -1 - && camel_stream_flush (filter, error) != -1) + CAMEL_DATA_WRAPPER (part), filter, cancellable, error) != -1 + && camel_stream_flush (filter, cancellable, error) != -1) res = 0; g_object_unref (filter); diff --git a/camel/camel-cipher-context.h b/camel/camel-cipher-context.h index 7b5a5d3..2e21efa 100644 --- a/camel/camel-cipher-context.h +++ b/camel/camel-cipher-context.h @@ -143,28 +143,34 @@ struct _CamelCipherContextClass { CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error); CamelCipherValidity * (*verify) (CamelCipherContext *context, CamelMimePart *ipart, + GCancellable *cancellable, GError **error); gint (*encrypt) (CamelCipherContext *context, const gchar *userid, GPtrArray *recipients, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error); CamelCipherValidity * (*decrypt) (CamelCipherContext *context, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error); gint (*import_keys) (CamelCipherContext *context, CamelStream *istream, + GCancellable *cancellable, GError **error); gint (*export_keys) (CamelCipherContext *context, GPtrArray *keys, CamelStream *ostream, + GCancellable *cancellable, GError **error); }; @@ -174,8 +180,10 @@ CamelCipherContext * CamelSession * camel_cipher_context_get_session (CamelCipherContext *context); /* cipher context util routines */ -CamelCipherHash camel_cipher_id_to_hash (CamelCipherContext *context, const gchar *id); -const gchar * camel_cipher_hash_to_id (CamelCipherContext *context, CamelCipherHash hash); +CamelCipherHash camel_cipher_id_to_hash (CamelCipherContext *context, + const gchar *id); +const gchar * camel_cipher_hash_to_id (CamelCipherContext *context, + CamelCipherHash hash); /* FIXME: There are some inconsistencies here, the api's should probably handle CamelMimePart's as input/outputs, @@ -183,44 +191,81 @@ const gchar * camel_cipher_hash_to_id (CamelCipherContext *context, CamelCi to the cipher, etc etc. */ /* cipher routines */ -gint camel_cipher_sign (CamelCipherContext *context, const gchar *userid, CamelCipherHash hash, - CamelMimePart *ipart, CamelMimePart *opart, GError **error); -CamelCipherValidity *camel_cipher_verify (CamelCipherContext *context, CamelMimePart *ipart, GError **error); -gint camel_cipher_encrypt (CamelCipherContext *context, const gchar *userid, - GPtrArray *recipients, CamelMimePart *ipart, CamelMimePart *opart, - GError **error); -CamelCipherValidity *camel_cipher_decrypt (CamelCipherContext *context, CamelMimePart *ipart, CamelMimePart *opart, - GError **error); +gint camel_cipher_sign (CamelCipherContext *context, + const gchar *userid, + CamelCipherHash hash, + CamelMimePart *ipart, + CamelMimePart *opart, + GCancellable *cancellable, + GError **error); +CamelCipherValidity * + camel_cipher_verify (CamelCipherContext *context, + CamelMimePart *ipart, + GCancellable *cancellable, + GError **error); +gint camel_cipher_encrypt (CamelCipherContext *context, + const gchar *userid, + GPtrArray *recipients, + CamelMimePart *ipart, + CamelMimePart *opart, + GCancellable *cancellable, + GError **error); +CamelCipherValidity * + camel_cipher_decrypt (CamelCipherContext *context, + CamelMimePart *ipart, + CamelMimePart *opart, + GCancellable *cancellable, + GError **error); /* key/certificate routines */ -gint camel_cipher_import_keys (CamelCipherContext *context, CamelStream *istream, - GError **error); -gint camel_cipher_export_keys (CamelCipherContext *context, GPtrArray *keys, - CamelStream *ostream, GError **error); +gint camel_cipher_import_keys (CamelCipherContext *context, + CamelStream *istream, + GCancellable *cancellable, + GError **error); +gint camel_cipher_export_keys (CamelCipherContext *context, + GPtrArray *keys, + CamelStream *ostream, + GCancellable *cancellable, + GError **error); /* CamelCipherValidity utility functions */ -CamelCipherValidity *camel_cipher_validity_new (void); -void camel_cipher_validity_init (CamelCipherValidity *validity); -gboolean camel_cipher_validity_get_valid (CamelCipherValidity *validity); -void camel_cipher_validity_set_valid (CamelCipherValidity *validity, gboolean valid); -gchar *camel_cipher_validity_get_description (CamelCipherValidity *validity); -void camel_cipher_validity_set_description (CamelCipherValidity *validity, const gchar *description); -void camel_cipher_validity_clear (CamelCipherValidity *validity); -CamelCipherValidity *camel_cipher_validity_clone (CamelCipherValidity *vin); -void camel_cipher_validity_add_certinfo (CamelCipherValidity *vin, camel_cipher_validity_mode_t mode, const gchar *name, const gchar *email); -void camel_cipher_validity_add_certinfo_ex ( - CamelCipherValidity *vin, - camel_cipher_validity_mode_t mode, - const gchar *name, - const gchar *email, - gpointer cert_data, - void (*cert_data_free) (gpointer cert_data), - gpointer (*cert_data_clone) (gpointer cert_data)); -void camel_cipher_validity_envelope (CamelCipherValidity *parent, CamelCipherValidity *valid); -void camel_cipher_validity_free (CamelCipherValidity *validity); +CamelCipherValidity * + camel_cipher_validity_new (void); +void camel_cipher_validity_init (CamelCipherValidity *validity); +gboolean camel_cipher_validity_get_valid (CamelCipherValidity *validity); +void camel_cipher_validity_set_valid (CamelCipherValidity *validity, + gboolean valid); +gchar * camel_cipher_validity_get_description + (CamelCipherValidity *validity); +void camel_cipher_validity_set_description + (CamelCipherValidity *validity, + const gchar *description); +void camel_cipher_validity_clear (CamelCipherValidity *validity); +CamelCipherValidity * + camel_cipher_validity_clone (CamelCipherValidity *vin); +void camel_cipher_validity_add_certinfo + (CamelCipherValidity *vin, + camel_cipher_validity_mode_t mode, + const gchar *name, + const gchar *email); +void camel_cipher_validity_add_certinfo_ex ( + CamelCipherValidity *vin, + camel_cipher_validity_mode_t mode, + const gchar *name, + const gchar *email, + gpointer cert_data, + void (*cert_data_free) (gpointer cert_data), + gpointer (*cert_data_clone) (gpointer cert_data)); +void camel_cipher_validity_envelope (CamelCipherValidity *parent, + CamelCipherValidity *valid); +void camel_cipher_validity_free (CamelCipherValidity *validity); /* utility functions */ -gint camel_cipher_canonical_to_stream (CamelMimePart *part, guint32 flags, CamelStream *ostream, GError **error); +gint camel_cipher_canonical_to_stream(CamelMimePart *part, + guint32 flags, + CamelStream *ostream, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c index 20bf199..d35eb49 100644 --- a/camel/camel-data-wrapper.c +++ b/camel/camel-data-wrapper.c @@ -79,6 +79,7 @@ data_wrapper_finalize (GObject *object) static gssize data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { gssize ret; @@ -97,7 +98,7 @@ data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, } ret = camel_stream_write_to_stream ( - data_wrapper->stream, stream, error); + data_wrapper->stream, stream, cancellable, error); camel_data_wrapper_unlock (data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK); @@ -107,6 +108,7 @@ data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, static gssize data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelMimeFilter *filter; @@ -142,9 +144,10 @@ data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper, g_object_unref (filter); } - ret = camel_data_wrapper_write_to_stream (data_wrapper, fstream, error); + ret = camel_data_wrapper_write_to_stream ( + data_wrapper, fstream, cancellable, error); - camel_stream_flush (fstream, NULL); + camel_stream_flush (fstream, NULL, NULL); g_object_unref (fstream); return ret; @@ -185,6 +188,7 @@ data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper, static gint data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { if (data_wrapper->stream) @@ -252,6 +256,7 @@ camel_data_wrapper_new (void) * camel_data_wrapper_write_to_stream: * @data_wrapper: a #CamelDataWrapper object * @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 @@ -264,6 +269,7 @@ camel_data_wrapper_new (void) gssize camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelDataWrapperClass *class; @@ -275,8 +281,10 @@ camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper); g_return_val_if_fail (class->write_to_stream != NULL, -1); - n_bytes = class->write_to_stream (data_wrapper, stream, error); - CAMEL_CHECK_GERROR (data_wrapper, write_to_stream, n_bytes >= 0, error); + n_bytes = class->write_to_stream ( + data_wrapper, stream, cancellable, error); + CAMEL_CHECK_GERROR ( + data_wrapper, write_to_stream, n_bytes >= 0, error); return n_bytes; } @@ -285,6 +293,7 @@ camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, * camel_data_wrapper_decode_to_stream: * @data_wrapper: a #CamelDataWrapper object * @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. @@ -294,6 +303,7 @@ camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, gssize camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelDataWrapperClass *class; @@ -305,8 +315,10 @@ camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper, class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper); g_return_val_if_fail (class->decode_to_stream != NULL, -1); - n_bytes = class->decode_to_stream (data_wrapper, stream, error); - CAMEL_CHECK_GERROR (data_wrapper, decode_to_stream, n_bytes >= 0, error); + n_bytes = class->decode_to_stream ( + data_wrapper, stream, cancellable, error); + CAMEL_CHECK_GERROR ( + data_wrapper, decode_to_stream, n_bytes >= 0, error); return n_bytes; } @@ -315,6 +327,7 @@ camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper, * camel_data_wrapper_construct_from_stream: * @data_wrapper: a #CamelDataWrapper object * @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. @@ -324,6 +337,7 @@ camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper, gint camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelDataWrapperClass *class; @@ -335,7 +349,8 @@ camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper); g_return_val_if_fail (class->construct_from_stream != NULL, -1); - retval = class->construct_from_stream (data_wrapper, stream, error); + retval = class->construct_from_stream ( + data_wrapper, stream, cancellable, error); CAMEL_CHECK_GERROR ( data_wrapper, construct_from_stream, retval == 0, error); diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h index cb41386..bbfbeea 100644 --- a/camel/camel-data-wrapper.h +++ b/camel/camel-data-wrapper.h @@ -92,12 +92,15 @@ struct _CamelDataWrapperClass { CamelContentType *mime_type_field); gssize (*write_to_stream) (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error); gssize (*decode_to_stream) (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error); gint (*construct_from_stream)(CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error); gboolean (*is_offline) (CamelDataWrapper *data_wrapper); }; @@ -108,10 +111,12 @@ CamelDataWrapper * gssize camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error); gssize camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error); void camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper, const gchar *mime_type); @@ -125,6 +130,7 @@ void camel_data_wrapper_set_mime_type_field gint camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error); gboolean camel_data_wrapper_is_offline (CamelDataWrapper *data_wrapper); void camel_data_wrapper_lock (CamelDataWrapper *data_wrapper, diff --git a/camel/camel-disco-diary.c b/camel/camel-disco-diary.c index af87299..cddd2d9 100644 --- a/camel/camel-disco-diary.c +++ b/camel/camel-disco-diary.c @@ -237,7 +237,8 @@ diary_decode_uids (CamelDiscoDiary *diary) } static CamelFolder * -diary_decode_folder (CamelDiscoDiary *diary) +diary_decode_folder (CamelDiscoDiary *diary, + GCancellable *cancellable) { CamelFolder *folder; gchar *name; @@ -250,7 +251,8 @@ diary_decode_folder (CamelDiscoDiary *diary) gchar *msg; folder = camel_store_get_folder ( - CAMEL_STORE (diary->store), name, 0, &error); + CAMEL_STORE (diary->store), + name, 0, cancellable, &error); if (folder) g_hash_table_insert (diary->folders, name, folder); else { @@ -273,20 +275,22 @@ diary_decode_folder (CamelDiscoDiary *diary) } static void -close_folder (gpointer name, gpointer folder, gpointer data) +close_folder (gchar *name, + CamelFolder *folder, + GCancellable *cancellable) { g_free (name); - camel_folder_sync (folder, FALSE, NULL); + camel_folder_sync (folder, FALSE, cancellable, NULL); g_object_unref (folder); } void camel_disco_diary_replay (CamelDiscoDiary *diary, + GCancellable *cancellable, GError **error) { guint32 action; goffset size; - gdouble pc; GError *local_error = NULL; d(printf("disco diary replay\n")); @@ -296,10 +300,11 @@ camel_disco_diary_replay (CamelDiscoDiary *diary, g_return_if_fail (size != 0); rewind (diary->file); - camel_operation_start (NULL, _("Resynchronizing with server")); + camel_operation_start (cancellable, _("Resynchronizing with server")); + while (local_error == NULL) { - pc = ftell (diary->file) / size; - camel_operation_progress (NULL, pc * 100); + camel_operation_progress ( + cancellable, (ftell (diary->file) / size) * 100); if (camel_file_util_decode_uint32 (diary->file, &action) == -1) break; @@ -312,14 +317,15 @@ camel_disco_diary_replay (CamelDiscoDiary *diary, CamelFolder *folder; GPtrArray *uids; - folder = diary_decode_folder (diary); + folder = diary_decode_folder (diary, cancellable); uids = diary_decode_uids (diary); if (!uids) goto lose; if (folder) camel_disco_folder_expunge_uids ( - folder, uids, &local_error); + folder, uids, cancellable, + &local_error); free_uids (uids); break; } @@ -331,7 +337,7 @@ camel_disco_diary_replay (CamelDiscoDiary *diary, CamelMimeMessage *message; CamelMessageInfo *info; - folder = diary_decode_folder (diary); + folder = diary_decode_folder (diary, cancellable); if (camel_file_util_decode_string (diary->file, &uid) == -1) goto lose; @@ -340,7 +346,8 @@ camel_disco_diary_replay (CamelDiscoDiary *diary, continue; } - message = camel_folder_get_message (folder, uid, NULL); + message = camel_folder_get_message ( + folder, uid, cancellable, NULL); if (!message) { /* The message was appended and then deleted. */ g_free (uid); @@ -349,7 +356,8 @@ camel_disco_diary_replay (CamelDiscoDiary *diary, info = camel_folder_get_message_info (folder, uid); camel_folder_append_message ( - folder, message, info, &ret_uid, &local_error); + folder, message, info, &ret_uid, + cancellable, &local_error); camel_folder_free_message_info (folder, info); if (ret_uid) { @@ -368,8 +376,8 @@ camel_disco_diary_replay (CamelDiscoDiary *diary, guint32 delete_originals; gint i; - source = diary_decode_folder (diary); - destination = diary_decode_folder (diary); + source = diary_decode_folder (diary, cancellable); + destination = diary_decode_folder (diary, cancellable); uids = diary_decode_uids (diary); if (!uids) goto lose; @@ -383,7 +391,7 @@ camel_disco_diary_replay (CamelDiscoDiary *diary, camel_folder_transfer_messages_to ( source, uids, destination, &ret_uids, - delete_originals, &local_error); + delete_originals, cancellable, &local_error); if (ret_uids) { for (i = 0; i < uids->len; i++) { @@ -402,10 +410,11 @@ camel_disco_diary_replay (CamelDiscoDiary *diary, } lose: - camel_operation_end (NULL); + camel_operation_end (cancellable); /* Close folders */ - g_hash_table_foreach (diary->folders, close_folder, diary); + g_hash_table_foreach ( + diary->folders, (GHFunc) close_folder, cancellable); g_hash_table_destroy (diary->folders); diary->folders = NULL; diff --git a/camel/camel-disco-diary.h b/camel/camel-disco-diary.h index 359600c..5c219cd 100644 --- a/camel/camel-disco-diary.h +++ b/camel/camel-disco-diary.h @@ -89,6 +89,7 @@ void camel_disco_diary_log (CamelDiscoDiary *diary, CamelDiscoDiaryAction action, ...); void camel_disco_diary_replay (CamelDiscoDiary *diary, + GCancellable *cancellable, GError **error); /* Temporary->Permanent UID map stuff */ diff --git a/camel/camel-disco-folder.c b/camel/camel-disco-folder.c index 12ed983..336d692 100644 --- a/camel/camel-disco-folder.c +++ b/camel/camel-disco-folder.c @@ -57,7 +57,9 @@ enum { G_DEFINE_TYPE (CamelDiscoFolder, camel_disco_folder, CAMEL_TYPE_FOLDER) /* Forward Declarations */ -static gboolean disco_expunge (CamelFolder *folder, GError **error); +static gboolean disco_expunge (CamelFolder *folder, + GCancellable *cancellable, + GError **error); static void cdf_sync_offline (CamelSession *session, CamelSessionThreadMsg *mm) @@ -65,24 +67,26 @@ cdf_sync_offline (CamelSession *session, CamelSessionThreadMsg *mm) struct _cdf_sync_msg *m = (struct _cdf_sync_msg *)mm; gint i; - camel_operation_start(NULL, _("Downloading new messages for offline mode")); + camel_operation_start ( + mm->cancellable, + _("Downloading new messages for offline mode")); if (m->changes) { for (i=0;ichanges->uid_added->len;i++) { gint pc = i * 100 / m->changes->uid_added->len; - camel_operation_progress (NULL, pc); + camel_operation_progress (mm->cancellable, pc); camel_disco_folder_cache_message ((CamelDiscoFolder *)m->folder, m->changes->uid_added->pdata[i], - &mm->error); + NULL, &mm->error); } } else { camel_disco_folder_prepare_for_offline ((CamelDiscoFolder *)m->folder, "(match-all)", - &mm->error); + NULL, &mm->error); } - camel_operation_end (NULL); + camel_operation_end (mm->cancellable); } static void @@ -161,6 +165,7 @@ disco_folder_get_property (GObject *object, static gboolean disco_refresh_info (CamelFolder *folder, + GCancellable *cancellable, GError **error) { CamelDiscoFolderClass *disco_folder_class; @@ -174,7 +179,8 @@ disco_refresh_info (CamelFolder *folder, disco_folder_class = CAMEL_DISCO_FOLDER_GET_CLASS (folder); - success = disco_folder_class->refresh_info_online (folder, error); + success = disco_folder_class->refresh_info_online ( + folder, cancellable, error); CAMEL_CHECK_GERROR (folder, refresh_info_online, success, error); return success; @@ -183,13 +189,14 @@ disco_refresh_info (CamelFolder *folder, static gboolean disco_sync (CamelFolder *folder, gboolean expunge, + GCancellable *cancellable, GError **error) { CamelDiscoFolderClass *disco_folder_class; CamelStore *parent_store; gboolean success; - if (expunge && !disco_expunge (folder, error)) + if (expunge && !disco_expunge (folder, cancellable, error)) return FALSE; camel_object_state_write (CAMEL_OBJECT (folder)); @@ -220,6 +227,7 @@ disco_sync (CamelFolder *folder, static gboolean disco_expunge_uids (CamelFolder *folder, GPtrArray *uids, + GCancellable *cancellable, GError **error) { CamelDiscoFolderClass *disco_folder_class; @@ -260,6 +268,7 @@ disco_expunge_uids (CamelFolder *folder, static gboolean disco_expunge (CamelFolder *folder, + GCancellable *cancellable, GError **error) { GPtrArray *uids; @@ -278,7 +287,7 @@ disco_expunge (CamelFolder *folder, camel_message_info_free (info); } - success = disco_expunge_uids (folder, uids, error); + success = disco_expunge_uids (folder, uids, cancellable, error); for (i = 0; i < uids->len; i++) g_free (uids->pdata[i]); @@ -292,6 +301,7 @@ disco_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error) { CamelDiscoFolderClass *disco_folder_class; @@ -304,19 +314,22 @@ disco_append_message (CamelFolder *folder, switch (camel_disco_store_status (CAMEL_DISCO_STORE (parent_store))) { case CAMEL_DISCO_STORE_ONLINE: success = disco_folder_class->append_online ( - folder, message, info, appended_uid, error); + folder, message, info, + appended_uid, cancellable, error); CAMEL_CHECK_GERROR (folder, append_online, success, error); return success; case CAMEL_DISCO_STORE_OFFLINE: success = disco_folder_class->append_offline ( - folder, message, info, appended_uid, error); + folder, message, info, + appended_uid, cancellable, error); CAMEL_CHECK_GERROR (folder, append_offline, success, error); return success; case CAMEL_DISCO_STORE_RESYNCING: success = disco_folder_class->append_resyncing ( - folder, message, info, appended_uid, error); + folder, message, info, + appended_uid, cancellable, error); CAMEL_CHECK_GERROR (folder, append_resyncing, success, error); return success; } @@ -330,6 +343,7 @@ disco_transfer_messages_to (CamelFolder *source, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error) { CamelDiscoFolderClass *disco_folder_class; @@ -343,21 +357,21 @@ disco_transfer_messages_to (CamelFolder *source, case CAMEL_DISCO_STORE_ONLINE: success = disco_folder_class->transfer_online ( source, uids, dest, transferred_uids, - delete_originals, error); + delete_originals, cancellable, error); CAMEL_CHECK_GERROR (source, transfer_online, success, error); return success; case CAMEL_DISCO_STORE_OFFLINE: success = disco_folder_class->transfer_offline ( source, uids, dest, transferred_uids, - delete_originals, error); + delete_originals, cancellable, error); CAMEL_CHECK_GERROR (source, transfer_offline, success, error); return success; case CAMEL_DISCO_STORE_RESYNCING: success = disco_folder_class->transfer_resyncing ( source, uids, dest, transferred_uids, - delete_originals, error); + delete_originals, cancellable, error); CAMEL_CHECK_GERROR (source, transfer_resyncing, success, error); return success; } @@ -368,6 +382,7 @@ disco_transfer_messages_to (CamelFolder *source, static gboolean disco_prepare_for_offline (CamelDiscoFolder *disco_folder, const gchar *expression, + GCancellable *cancellable, GError **error) { CamelFolder *folder = CAMEL_FOLDER (disco_folder); @@ -376,7 +391,7 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder, gboolean success = TRUE; camel_operation_start ( - NULL, _("Preparing folder '%s' for offline"), + cancellable, _("Preparing folder '%s' for offline"), camel_folder_get_full_name (folder)); if (expression) @@ -385,16 +400,15 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder, uids = camel_folder_get_uids (folder); if (!uids) { - camel_operation_end (NULL); + camel_operation_end (cancellable); return FALSE; } for (i = 0; i < uids->len && success; i++) { - gint pc = i * 100 / uids->len; - - camel_operation_progress (NULL, pc); + camel_operation_progress ( + cancellable, (i * 100) / uids->len); success = camel_disco_folder_cache_message ( - disco_folder, uids->pdata[i], error); + disco_folder, uids->pdata[i], cancellable, error); } if (expression) @@ -402,13 +416,14 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder, else camel_folder_free_uids (folder, uids); - camel_operation_end (NULL); + camel_operation_end (cancellable); return success; } static gboolean disco_refresh_info_online (CamelFolder *folder, + GCancellable *cancellable, GError **error) { return TRUE; @@ -494,6 +509,7 @@ camel_disco_folder_set_offline_sync (CamelDiscoFolder *disco_folder, * camel_disco_folder_expunge_uids: * @folder: a (disconnectable) folder * @uids: array of UIDs to expunge + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * This expunges the messages in @uids from @folder. It should take @@ -507,18 +523,20 @@ camel_disco_folder_set_offline_sync (CamelDiscoFolder *disco_folder, gboolean camel_disco_folder_expunge_uids (CamelFolder *folder, GPtrArray *uids, + GCancellable *cancellable, GError **error) { g_return_val_if_fail (CAMEL_IS_DISCO_FOLDER (folder), FALSE); g_return_val_if_fail (uids != NULL, FALSE); - return disco_expunge_uids (folder, uids, error); + return disco_expunge_uids (folder, uids, cancellable, error); } /** * camel_disco_folder_cache_message: * @disco_folder: the folder * @uid: the UID of the message to cache + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Requests that @disco_folder cache message @uid to disk. @@ -528,6 +546,7 @@ camel_disco_folder_expunge_uids (CamelFolder *folder, gboolean camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder, const gchar *uid, + GCancellable *cancellable, GError **error) { CamelDiscoFolderClass *class; @@ -539,7 +558,8 @@ camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder, class = CAMEL_DISCO_FOLDER_GET_CLASS (disco_folder); g_return_val_if_fail (class->cache_message != NULL, FALSE); - success = class->cache_message (disco_folder, uid, error); + success = class->cache_message ( + disco_folder, uid, cancellable, error); CAMEL_CHECK_GERROR (disco_folder, cache_message, success, error); return success; @@ -550,6 +570,7 @@ camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder, * @disco_folder: the folder * @expression: an expression describing messages to synchronize, or %NULL * if all messages should be sync'ed. + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * This prepares @disco_folder for offline operation, by downloading @@ -561,6 +582,7 @@ camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder, gboolean camel_disco_folder_prepare_for_offline (CamelDiscoFolder *disco_folder, const gchar *expression, + GCancellable *cancellable, GError **error) { CamelDiscoFolderClass *class; @@ -571,7 +593,8 @@ camel_disco_folder_prepare_for_offline (CamelDiscoFolder *disco_folder, class = CAMEL_DISCO_FOLDER_GET_CLASS (disco_folder); g_return_val_if_fail (class->prepare_for_offline != NULL, FALSE); - success = class->prepare_for_offline (disco_folder, expression, error); + success = class->prepare_for_offline ( + disco_folder, expression, cancellable, error); CAMEL_CHECK_GERROR (disco_folder, prepare_for_offline, success, error); return success; diff --git a/camel/camel-disco-folder.h b/camel/camel-disco-folder.h index 7df9fe7..f90ae49 100644 --- a/camel/camel-disco-folder.h +++ b/camel/camel-disco-folder.h @@ -66,6 +66,7 @@ struct _CamelDiscoFolderClass { CamelFolderClass parent_class; gboolean (*refresh_info_online) (CamelFolder *folder, + GCancellable *cancellable, GError **error); gboolean (*sync_online) (CamelFolder *folder, GError **error); @@ -87,40 +88,48 @@ struct _CamelDiscoFolderClass { CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error); gboolean (*append_offline) (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error); gboolean (*append_resyncing) (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error); gboolean (*transfer_online) (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error); gboolean (*transfer_offline) (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error); gboolean (*transfer_resyncing) (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error); gboolean (*cache_message) (CamelDiscoFolder *disco_folder, const gchar *uid, + GCancellable *cancellable, GError **error); gboolean (*prepare_for_offline) (CamelDiscoFolder *disco_folder, const gchar *expression, + GCancellable *cancellable, GError **error); void (*update_uid) (CamelFolder *folder, const gchar *old_uid, @@ -135,13 +144,16 @@ void camel_disco_folder_set_offline_sync gboolean offline_sync); gboolean camel_disco_folder_expunge_uids (CamelFolder *folder, GPtrArray *uids, + GCancellable *cancellable, GError **error); gboolean camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder, const gchar *uid, + GCancellable *cancellable, GError **error); gboolean camel_disco_folder_prepare_for_offline (CamelDiscoFolder *disco_folder, const gchar *expression, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/camel/camel-disco-store.c b/camel/camel-disco-store.c index b35c4b4..92fa78c 100644 --- a/camel/camel-disco-store.c +++ b/camel/camel-disco-store.c @@ -61,6 +61,7 @@ disco_store_construct (CamelService *service, static gboolean disco_store_connect (CamelService *service, + GCancellable *cancellable, GError **error) { CamelDiscoStore *store = CAMEL_DISCO_STORE (service); @@ -70,7 +71,7 @@ disco_store_connect (CamelService *service, status = camel_disco_store_status (store); if (status != CAMEL_DISCO_STORE_OFFLINE) { - if (!CAMEL_SERVICE_CLASS (camel_disco_store_parent_class)->connect (service, error)) { + if (!CAMEL_SERVICE_CLASS (camel_disco_store_parent_class)->connect (service, cancellable, error)) { status = camel_disco_store_status (store); if (status != CAMEL_DISCO_STORE_OFFLINE) return FALSE; @@ -81,7 +82,7 @@ disco_store_connect (CamelService *service, switch (status) { case CAMEL_DISCO_STORE_ONLINE: case CAMEL_DISCO_STORE_RESYNCING: - if (!CAMEL_DISCO_STORE_GET_CLASS (service)->connect_online (service, error)) + if (!CAMEL_DISCO_STORE_GET_CLASS (service)->connect_online (service, cancellable, error)) return FALSE; if (!store->diary) @@ -95,7 +96,7 @@ disco_store_connect (CamelService *service, disconnect could be called, which will remove store->diary and unref it */ store->status = CAMEL_DISCO_STORE_RESYNCING; diary = g_object_ref (store->diary); - camel_disco_diary_replay (diary, &local_error); + camel_disco_diary_replay (diary, cancellable, &local_error); g_object_unref (diary); store->status = CAMEL_DISCO_STORE_ONLINE; if (local_error != NULL) { @@ -108,7 +109,7 @@ disco_store_connect (CamelService *service, return camel_service_connect (service, error); case CAMEL_DISCO_STORE_OFFLINE: - return CAMEL_DISCO_STORE_GET_CLASS (service)->connect_offline (service, error); + return CAMEL_DISCO_STORE_GET_CLASS (service)->connect_offline (service, cancellable, error); } g_assert_not_reached (); @@ -118,25 +119,32 @@ disco_store_connect (CamelService *service, static gboolean disco_store_disconnect (CamelService *service, gboolean clean, + GCancellable *cancellable, GError **error) { CamelDiscoStore *store = CAMEL_DISCO_STORE (service); + CamelDiscoStoreClass *class; + + class = CAMEL_DISCO_STORE_GET_CLASS (service); switch (camel_disco_store_status (store)) { case CAMEL_DISCO_STORE_ONLINE: case CAMEL_DISCO_STORE_RESYNCING: - if (!CAMEL_DISCO_STORE_GET_CLASS (service)->disconnect_online (service, clean, error)) + if (!class->disconnect_online ( + service, clean, cancellable, error)) return FALSE; break; case CAMEL_DISCO_STORE_OFFLINE: - if (!CAMEL_DISCO_STORE_GET_CLASS (service)->disconnect_offline (service, clean, error)) + if (!class->disconnect_offline ( + service, clean, cancellable, error)) return FALSE; break; } - return CAMEL_SERVICE_CLASS (camel_disco_store_parent_class)->disconnect (service, clean, error); + return CAMEL_SERVICE_CLASS (camel_disco_store_parent_class)-> + disconnect (service, clean, cancellable, error); } static void @@ -153,6 +161,7 @@ static CamelFolder * disco_store_get_folder (CamelStore *store, const gchar *name, guint32 flags, + GCancellable *cancellable, GError **error) { CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (store); @@ -166,17 +175,20 @@ disco_store_get_folder (CamelStore *store, switch (camel_disco_store_status (disco_store)) { case CAMEL_DISCO_STORE_ONLINE: - folder = class->get_folder_online (store, name, flags, error); + folder = class->get_folder_online ( + store, name, flags, cancellable, error); CAMEL_CHECK_GERROR (store, get_folder_online, folder != NULL, error); return folder; case CAMEL_DISCO_STORE_OFFLINE: - folder = class->get_folder_offline (store, name, flags, error); + folder = class->get_folder_offline ( + store, name, flags, cancellable, error); CAMEL_CHECK_GERROR (store, get_folder_offline, folder != NULL, error); return folder; case CAMEL_DISCO_STORE_RESYNCING: - folder = class->get_folder_resyncing (store, name, flags, error); + folder = class->get_folder_resyncing ( + store, name, flags, cancellable, error); CAMEL_CHECK_GERROR (store, get_folder_resyncing, folder != NULL, error); return folder; } @@ -188,6 +200,7 @@ static CamelFolderInfo * disco_store_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (store); @@ -201,7 +214,8 @@ disco_store_get_folder_info (CamelStore *store, switch (camel_disco_store_status (disco_store)) { case CAMEL_DISCO_STORE_ONLINE: - info = class->get_folder_info_online (store, top, flags, error); + info = class->get_folder_info_online ( + store, top, flags, cancellable, error); if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) CAMEL_CHECK_GERROR (store, get_folder_info_online, info != NULL, error); return info; @@ -214,13 +228,15 @@ disco_store_get_folder_info (CamelStore *store, return NULL; } - info = class->get_folder_info_offline (store, top, flags, error); + info = class->get_folder_info_offline ( + store, top, flags, cancellable, error); if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) CAMEL_CHECK_GERROR (store, get_folder_info_offline, info != NULL, error); return info; case CAMEL_DISCO_STORE_RESYNCING: - info = class->get_folder_info_resyncing (store, top, flags, error); + info = class->get_folder_info_resyncing ( + store, top, flags, cancellable, error); if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) CAMEL_CHECK_GERROR (store, get_folder_info_resyncing, info != NULL, error); return info; @@ -232,6 +248,7 @@ disco_store_get_folder_info (CamelStore *store, static gboolean disco_store_set_status (CamelDiscoStore *disco_store, CamelDiscoStoreStatus status, + GCancellable *cancellable, GError **error) { CamelService *service = CAMEL_SERVICE (disco_store); @@ -261,7 +278,7 @@ disco_store_set_status (CamelDiscoStore *disco_store, folder = folders->pdata[i]; if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_DISCO_FOLDER) && (sync || camel_disco_folder_get_offline_sync (CAMEL_DISCO_FOLDER (folder)))) { - camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "", NULL); + camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "", cancellable, NULL); } g_object_unref (folder); } @@ -269,7 +286,9 @@ disco_store_set_status (CamelDiscoStore *disco_store, } } - camel_store_sync (CAMEL_STORE (disco_store), FALSE, NULL); + camel_store_sync ( + CAMEL_STORE (disco_store), + FALSE, cancellable, NULL); } if (!camel_service_disconnect (CAMEL_SERVICE (disco_store), network_available, error)) @@ -328,14 +347,16 @@ camel_disco_store_status (CamelDiscoStore *store) * camel_disco_store_set_status: * @store: a disconnectable store * @status: the new status + * @cancellable: optional #GCancellable method, or %NULL * @error: return location for a #GError, or %NULL * * Sets @store to @status. If an error occurrs and the status cannot - * be set to @status, @ex will be set. + * be set to @status, @error will be set. **/ gboolean camel_disco_store_set_status (CamelDiscoStore *store, CamelDiscoStoreStatus status, + GCancellable *cancellable, GError **error) { CamelDiscoStoreClass *class; @@ -346,7 +367,7 @@ camel_disco_store_set_status (CamelDiscoStore *store, class = CAMEL_DISCO_STORE_GET_CLASS (store); g_return_val_if_fail (class->set_status != NULL, FALSE); - success = class->set_status (store, status, error); + success = class->set_status (store, status, cancellable, error); CAMEL_CHECK_GERROR (store, set_status, success, error); return success; @@ -402,6 +423,7 @@ camel_disco_store_check_online (CamelDiscoStore *store, void camel_disco_store_prepare_for_offline (CamelDiscoStore *disco_store, + GCancellable *cancellable, GError **error) { CamelService *service; @@ -426,7 +448,7 @@ camel_disco_store_prepare_for_offline (CamelDiscoStore *disco_store, folder = folders->pdata[i]; if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_DISCO_FOLDER) && (sync || camel_disco_folder_get_offline_sync (CAMEL_DISCO_FOLDER (folder)))) { - camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "(match-all)", NULL); + camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "(match-all)", cancellable, NULL); } g_object_unref (folder); } @@ -434,6 +456,8 @@ camel_disco_store_prepare_for_offline (CamelDiscoStore *disco_store, } } - camel_store_sync (CAMEL_STORE (disco_store), FALSE, NULL); + camel_store_sync ( + CAMEL_STORE (disco_store), + FALSE, cancellable, NULL); } } diff --git a/camel/camel-disco-store.h b/camel/camel-disco-store.h index 5a77cd9..fa17bcd 100644 --- a/camel/camel-disco-store.h +++ b/camel/camel-disco-store.h @@ -74,60 +74,82 @@ struct _CamelDiscoStore { struct _CamelDiscoStoreClass { CamelStoreClass parent_class; - gboolean (*set_status) (CamelDiscoStore *, - CamelDiscoStoreStatus, - GError **error); - gboolean (*can_work_offline) (CamelDiscoStore *); - - gboolean (*connect_online) (CamelService *, - GError **error); - gboolean (*connect_offline) (CamelService *, - GError **error); - - gboolean (*disconnect_online) (CamelService *, gboolean, - GError **error); - gboolean (*disconnect_offline) (CamelService *, gboolean, - GError **error); - - CamelFolder * (*get_folder_online) (CamelStore *store, - const gchar *name, - guint32 flags, - GError **error); - CamelFolder * (*get_folder_offline) (CamelStore *store, - const gchar *name, - guint32 flags, - GError **error); - CamelFolder * (*get_folder_resyncing) (CamelStore *store, - const gchar *name, - guint32 flags, - GError **error); - - CamelFolderInfo * (*get_folder_info_online) (CamelStore *store, - const gchar *top, - guint32 flags, - GError **error); - CamelFolderInfo * (*get_folder_info_offline) (CamelStore *store, - const gchar *top, - guint32 flags, - GError **error); - CamelFolderInfo * (*get_folder_info_resyncing) (CamelStore *store, - const gchar *top, - guint32 flags, - GError **error); + gboolean (*set_status) (CamelDiscoStore *, + CamelDiscoStoreStatus, + GCancellable *cancellable, + GError **error); + gboolean (*can_work_offline) (CamelDiscoStore *); + + gboolean (*connect_online) (CamelService *service, + GCancellable *cancellable, + GError **error); + gboolean (*connect_offline) (CamelService *service, + GCancellable *cancellable, + GError **error); + + gboolean (*disconnect_online) (CamelService *service, + gboolean, + GCancellable *cancellable, + GError **error); + gboolean (*disconnect_offline) (CamelService *service, + gboolean, + GCancellable *cancellable, + GError **error); + + CamelFolder * (*get_folder_online) (CamelStore *store, + const gchar *name, + guint32 flags, + GCancellable *cancellable, + GError **error); + CamelFolder * (*get_folder_offline) (CamelStore *store, + const gchar *name, + guint32 flags, + GCancellable *cancellable, + GError **error); + CamelFolder * (*get_folder_resyncing) (CamelStore *store, + const gchar *name, + guint32 flags, + GCancellable *cancellable, + GError **error); + + CamelFolderInfo * + (*get_folder_info_online) + (CamelStore *store, + const gchar *top, + guint32 flags, + GCancellable *cancellable, + GError **error); + CamelFolderInfo * + (*get_folder_info_offline) + (CamelStore *store, + const gchar *top, + guint32 flags, + GCancellable *cancellable, + GError **error); + CamelFolderInfo * + (*get_folder_info_resyncing) + (CamelStore *store, + const gchar *top, + guint32 flags, + GCancellable *cancellable, + GError **error); }; -GType camel_disco_store_get_type (void); - -/* Public methods */ -CamelDiscoStoreStatus camel_disco_store_status (CamelDiscoStore *store); -gboolean camel_disco_store_set_status (CamelDiscoStore *store, - CamelDiscoStoreStatus status, - GError **error); -gboolean camel_disco_store_can_work_offline (CamelDiscoStore *store); - -/* Convenience functions */ -gboolean camel_disco_store_check_online (CamelDiscoStore *store, GError **error); -void camel_disco_store_prepare_for_offline (CamelDiscoStore *store, GError **error); +GType camel_disco_store_get_type (void); +CamelDiscoStoreStatus + camel_disco_store_status (CamelDiscoStore *store); +gboolean camel_disco_store_set_status (CamelDiscoStore *store, + CamelDiscoStoreStatus status, + GCancellable *cancellable, + GError **error); +gboolean camel_disco_store_can_work_offline + (CamelDiscoStore *store); +gboolean camel_disco_store_check_online (CamelDiscoStore *store, + GError **error); +void camel_disco_store_prepare_for_offline + (CamelDiscoStore *store, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/camel-file-utils.c b/camel/camel-file-utils.c index 1b8a426..bdf9d81 100644 --- a/camel/camel-file-utils.c +++ b/camel/camel-file-utils.c @@ -403,6 +403,7 @@ camel_file_util_safe_filename (const gchar *name) * @fd: file descriptor * @buf: buffer to fill * @n: number of bytes to read into @buf + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Cancellable libc read() replacement. @@ -417,25 +418,19 @@ gssize camel_read (gint fd, gchar *buf, gsize n, + GCancellable *cancellable, GError **error) { gssize nread; gint cancel_fd; - if (camel_operation_cancel_check (NULL)) { + if (g_cancellable_set_error_if_cancelled (cancellable, error)) { errno = EINTR; - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Cancelled")); return -1; } -#ifndef G_OS_WIN32 - cancel_fd = camel_operation_cancel_fd (NULL); -#else - cancel_fd = -1; -#endif + cancel_fd = g_cancellable_get_fd (cancellable); + if (cancel_fd == -1) { do { nread = read (fd, buf, n); @@ -481,18 +476,16 @@ camel_read (gint fd, #endif } - if (nread == -1) { - if (errno == EINTR) - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Cancelled")); - else - g_set_error ( - error, G_IO_ERROR, - g_io_error_from_errno (errno), - "%s", g_strerror (errno)); - } + g_cancellable_release_fd (cancellable); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + if (nread == -1) + g_set_error ( + error, G_IO_ERROR, + g_io_error_from_errno (errno), + "%s", g_strerror (errno)); return nread; } @@ -502,6 +495,7 @@ camel_read (gint fd, * @fd: file descriptor * @buf: buffer to write * @n: number of bytes of @buf to write + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Cancellable libc write() replacement. @@ -516,25 +510,19 @@ gssize camel_write (gint fd, const gchar *buf, gsize n, + GCancellable *cancellable, GError **error) { gssize w, written = 0; gint cancel_fd; - if (camel_operation_cancel_check (NULL)) { + if (g_cancellable_set_error_if_cancelled (cancellable, error)) { errno = EINTR; - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Cancelled")); return -1; } -#ifndef G_OS_WIN32 - cancel_fd = camel_operation_cancel_fd (NULL); -#else - cancel_fd = -1; -#endif + cancel_fd = g_cancellable_get_fd (cancellable); + if (cancel_fd == -1) { do { do { @@ -591,17 +579,16 @@ camel_write (gint fd, #endif } + g_cancellable_release_fd (cancellable); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + if (w == -1) { - if (errno == EINTR) - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Cancelled")); - else - g_set_error ( - error, G_IO_ERROR, - g_io_error_from_errno (errno), - "%s", g_strerror (errno)); + g_set_error ( + error, G_IO_ERROR, + g_io_error_from_errno (errno), + "%s", g_strerror (errno)); return -1; } @@ -613,6 +600,7 @@ camel_write (gint fd, * @fd: a socket * @buf: buffer to fill * @n: number of bytes to read into @buf + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Cancellable read() replacement for sockets. Code that intends to be @@ -627,23 +615,21 @@ gssize camel_read_socket (gint fd, gchar *buf, gsize n, + GCancellable *cancellable, GError **error) { #ifndef G_OS_WIN32 - return camel_read (fd, buf, n, error); + return camel_read (fd, buf, n, cancellable, error); #else gssize nread; gint cancel_fd; - if (camel_operation_cancel_check (NULL)) { + if (g_cancellable_set_error_if_cancelled (cancellable, error)) { errno = EINTR; - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Canceled")); return -1; } - cancel_fd = camel_operation_cancel_fd (NULL); + + cancel_fd = g_cancellable_get_fd (cancellable); if (cancel_fd == -1) { do { @@ -683,18 +669,16 @@ camel_read_socket (gint fd, ; } - if (nread == -1) { - if (errno == EINTR) - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Cancelled")); - else - g_set_error ( - error, G_IO_ERROR, - g_io_error_from_errno (errno), - "%s", g_strerror (errno)); - } + g_cancellable_release_fd (cancellable); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + if (nread == -1) + g_set_error ( + error, G_IO_ERROR, + g_io_error_from_errno (errno), + "%s", g_strerror (errno)); return nread; #endif @@ -718,15 +702,16 @@ gssize camel_write_socket (gint fd, const gchar *buf, gsize n, + GCancellable *cancellable, GError **error) { #ifndef G_OS_WIN32 - return camel_write (fd, buf, n, error); + return camel_write (fd, buf, n, cancellable, error); #else gssize w, written = 0; gint cancel_fd; - if (camel_operation_cancel_check (NULL)) { + if (g_cancellable_is_cancelled (cancellable)) { errno = EINTR; g_set_error ( error, G_IO_ERROR, @@ -735,7 +720,8 @@ camel_write_socket (gint fd, return -1; } - cancel_fd = camel_operation_cancel_fd (NULL); + cancel_fd = g_cancellable_get_fd (cancellable); + if (cancel_fd == -1) { do { do { @@ -783,17 +769,16 @@ camel_write_socket (gint fd, ioctlsocket (fd, FIONBIO, &arg); } + g_cancellable_release_fd (cancellable); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + if (w == -1) { - if (errno == EINTR) - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Canceled")); - else - g_set_error ( - error, G_IO_ERROR, - g_io_error_from_errno (errno), - "%s", g_strerror (errno)); + g_set_error ( + error, G_IO_ERROR, + g_io_error_from_errno (errno), + "%s", g_strerror (errno)); return -1; } diff --git a/camel/camel-file-utils.h b/camel/camel-file-utils.h index 2178902..e388d34 100644 --- a/camel/camel-file-utils.h +++ b/camel/camel-file-utils.h @@ -30,7 +30,7 @@ #ifndef CAMEL_FILE_UTILS_H #define CAMEL_FILE_UTILS_H -#include +#include #include #include #include @@ -66,13 +66,29 @@ gchar *camel_file_util_safe_filename (const gchar *name); * camel_read_socket() and camel_write_socket(). These are cancellable * also on Win32. */ -gssize camel_read (gint fd, gchar *buf, gsize n, GError **error); -gssize camel_write (gint fd, const gchar *buf, gsize n, GError **error); +gssize camel_read (gint fd, + gchar *buf, + gsize n, + GCancellable *cancellable, + GError **error); +gssize camel_write (gint fd, + const gchar *buf, + gsize n, + GCancellable *cancellable, + GError **error); -gssize camel_read_socket (gint fd, gchar *buf, gsize n, GError **error); -gssize camel_write_socket (gint fd, const gchar *buf, gsize n, GError **error); +gssize camel_read_socket (gint fd, + gchar *buf, + gsize n, + GCancellable *cancellable, + GError **error); +gssize camel_write_socket (gint fd, + const gchar *buf, + gsize n, + GCancellable *cancellable, + GError **error); -gchar *camel_file_util_savename (const gchar *filename); +gchar * camel_file_util_savename (const gchar *filename); G_END_DECLS diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c index 7d7f08e..5ba1eff 100644 --- a/camel/camel-filter-driver.c +++ b/camel/camel-filter-driver.c @@ -465,7 +465,10 @@ do_forward_to (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFil /* make sure we have the message... */ if (p->message == NULL) { - if (!(p->message = camel_folder_get_message (p->source, p->uid, &p->error))) + /* FIXME Pass a GCancellable */ + p->message = camel_folder_get_message ( + p->source, p->uid, NULL, &p->error); + if (p->message == NULL) return NULL; } @@ -501,16 +504,24 @@ do_copy (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilterDri uids = g_ptr_array_new (); g_ptr_array_add (uids, (gchar *) p->uid); - camel_folder_transfer_messages_to (p->source, uids, outbox, NULL, FALSE, &p->error); + /* FIXME Pass a GCancellable */ + camel_folder_transfer_messages_to ( + p->source, uids, outbox, NULL, + FALSE, NULL, &p->error); g_ptr_array_free (uids, TRUE); } else { if (p->message == NULL) - p->message = camel_folder_get_message (p->source, p->uid, &p->error); + /* FIXME Pass a GCancellable */ + p->message = camel_folder_get_message ( + p->source, p->uid, NULL, &p->error); if (!p->message) continue; - camel_folder_append_message (outbox, p->message, p->info, NULL, &p->error); + /* FIXME Pass a GCancellable */ + camel_folder_append_message ( + outbox, p->message, p->info, + NULL, NULL, &p->error); } if (p->error == NULL) @@ -554,27 +565,38 @@ do_move (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilterDri uids = g_ptr_array_new (); g_ptr_array_add (uids, (gchar *) p->uid); + /* FIXME Pass a GCancellable */ camel_folder_transfer_messages_to ( p->source, uids, outbox, NULL, - last, &p->error); + last, NULL, &p->error); g_ptr_array_free (uids, TRUE); } else { if (p->message == NULL) + /* FIXME Pass a GCancellable */ p->message = camel_folder_get_message ( - p->source, p->uid, &p->error); + p->source, p->uid, NULL, &p->error); if (!p->message) continue; + /* FIXME Pass a GCancellable */ camel_folder_append_message ( outbox, p->message, p->info, - NULL, &p->error); + NULL, NULL, &p->error); if (p->error == NULL && last) { if (p->source && p->uid && camel_folder_has_summary_capability (p->source)) - camel_folder_set_message_flags (p->source, p->uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0); + camel_folder_set_message_flags ( + p->source, p->uid, + CAMEL_MESSAGE_DELETED | + CAMEL_MESSAGE_SEEN, ~0); else - camel_message_info_set_flags (p->info, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED, ~0); + camel_message_info_set_flags ( + p->info, + CAMEL_MESSAGE_DELETED | + CAMEL_MESSAGE_SEEN | + CAMEL_MESSAGE_FOLDER_FLAGGED, + ~0); } } @@ -702,9 +724,12 @@ set_flag (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilterDr if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) { flags = camel_system_flag (argv[0]->value.string); if (p->source && p->uid && camel_folder_has_summary_capability (p->source)) - camel_folder_set_message_flags (p->source, p->uid, flags, ~0); + camel_folder_set_message_flags ( + p->source, p->uid, flags, ~0); else - camel_message_info_set_flags (p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, ~0); + camel_message_info_set_flags ( + p->info, flags | + CAMEL_MESSAGE_FOLDER_FLAGGED, ~0); camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set %s flag", argv[0]->value.string); } @@ -721,9 +746,12 @@ unset_flag (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilter if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) { flags = camel_system_flag (argv[0]->value.string); if (p->source && p->uid && camel_folder_has_summary_capability (p->source)) - camel_folder_set_message_flags (p->source, p->uid, flags, 0); + camel_folder_set_message_flags ( + p->source, p->uid, flags, 0); else - camel_message_info_set_flags (p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, 0); + camel_message_info_set_flags ( + p->info, flags | + CAMEL_MESSAGE_FOLDER_FLAGGED, 0); camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Unset %s flag", argv[0]->value.string); } @@ -779,7 +807,10 @@ pipe_to_system (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFi /* make sure we have the message... */ if (p->message == NULL) { - if (!(p->message = camel_folder_get_message (p->source, p->uid, &p->error))) + /* FIXME Pass a GCancellable */ + p->message = camel_folder_get_message ( + p->source, p->uid, NULL, &p->error); + if (p->message == NULL) return -1; } @@ -814,13 +845,13 @@ pipe_to_system (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFi g_ptr_array_free (args, TRUE); stream = camel_stream_fs_new_with_fd (pipe_to_child); - if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (p->message), stream, NULL) == -1) { + if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (p->message), stream, NULL, NULL) == -1) { g_object_unref (stream); close (pipe_from_child); goto wait; } - if (camel_stream_flush (stream, NULL) == -1) { + if (camel_stream_flush (stream, NULL, NULL) == -1) { g_object_unref (stream); close (pipe_from_child); goto wait; @@ -830,7 +861,7 @@ pipe_to_system (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFi stream = camel_stream_fs_new_with_fd (pipe_from_child); mem = camel_stream_mem_new (); - if (camel_stream_write_to_stream (stream, mem, NULL) == -1) { + if (camel_stream_write_to_stream (stream, mem, NULL, NULL) == -1) { g_object_unref (stream); g_object_unref (mem); goto wait; @@ -845,7 +876,7 @@ pipe_to_system (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFi g_object_unref (mem); message = camel_mime_message_new (); - if (camel_mime_part_construct_from_parser ((CamelMimePart *) message, parser, NULL) == -1) { + if (camel_mime_part_construct_from_parser ((CamelMimePart *) message, parser, NULL, NULL) == -1) { gint err = camel_mime_parser_errno (parser); g_set_error ( &p->error, G_IO_ERROR, @@ -1029,7 +1060,10 @@ close_folder (gpointer key, gpointer value, gpointer data) g_free (key); if (folder != FOLDER_INVALID) { - camel_folder_sync (folder, FALSE, (p->error != NULL) ? NULL : &p->error); + /* FIXME Pass a GCancellable */ + camel_folder_sync ( + folder, FALSE, NULL, + (p->error != NULL) ? NULL : &p->error); camel_folder_thaw (folder); g_object_unref (folder); } @@ -1207,6 +1241,7 @@ decode_flags_from_xev (const gchar *xev, CamelMessageInfoBase *mi) * @driver: CamelFilterDriver * @mbox: mbox filename to be filtered * @original_source_url: + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Filters an mbox file based on rules defined in the FilterDriver @@ -1221,6 +1256,7 @@ gint camel_filter_driver_filter_mbox (CamelFilterDriver *driver, const gchar *mbox, const gchar *original_source_url, + GCancellable *cancellable, GError **error) { struct _CamelFilterDriverPrivate *p = CAMEL_FILTER_DRIVER_GET_PRIVATE (driver); @@ -1271,7 +1307,8 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, message = camel_mime_message_new (); mime_part = CAMEL_MIME_PART (message); - if (camel_mime_part_construct_from_parser (mime_part, mp, error) == -1) { + if (camel_mime_part_construct_from_parser ( + mime_part, mp, cancellable, error) == -1) { report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Failed on message %d"), i); g_object_unref (message); goto fail; @@ -1288,8 +1325,8 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, last = camel_mime_parser_tell (mp); status = camel_filter_driver_filter_message ( driver, message, info, NULL, NULL, source_url, - original_source_url ? original_source_url : source_url, - &local_error); + original_source_url ? original_source_url : + source_url, cancellable, &local_error); g_object_unref (message); if (local_error != NULL || status == -1) { report_status ( @@ -1310,7 +1347,7 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, if (p->defaultfolder) { report_status(driver, CAMEL_FILTER_STATUS_PROGRESS, 100, _("Syncing folder")); - camel_folder_sync (p->defaultfolder, FALSE, NULL); + camel_folder_sync (p->defaultfolder, FALSE, cancellable, NULL); } report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Complete")); @@ -1331,8 +1368,10 @@ fail: * @driver: CamelFilterDriver * @folder: CamelFolder to be filtered * @cache: UID cache (needed for POP folders) - * @uids: message uids to be filtered or NULL (as a shortcut to filter all messages) + * @uids: message uids to be filtered or NULL (as a shortcut to filter + * all messages) * @remove: TRUE to mark filtered messages as deleted + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Filters a folder based on rules defined in the FilterDriver @@ -1348,6 +1387,7 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, CamelUIDCache *cache, GPtrArray *uids, gboolean remove, + GCancellable *cancellable, GError **error) { struct _CamelFilterDriverPrivate *p = CAMEL_FILTER_DRIVER_GET_PRIVATE (driver); @@ -1383,8 +1423,8 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, info = NULL; status = camel_filter_driver_filter_message ( - driver, NULL, info, uids->pdata[i], - folder, source_url, source_url, &local_error); + driver, NULL, info, uids->pdata[i], folder, + source_url, source_url, cancellable, &local_error); if (camel_folder_has_summary_capability (folder)) camel_folder_free_message_info (folder, info); @@ -1400,8 +1440,10 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, } if (remove) - camel_folder_set_message_flags (folder, uids->pdata[i], - CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, ~0); + camel_folder_set_message_flags ( + folder, uids->pdata[i], + CAMEL_MESSAGE_DELETED | + CAMEL_MESSAGE_SEEN, ~0); if (cache) camel_uid_cache_save_uid (cache, uids->pdata[i]); @@ -1409,7 +1451,7 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, if (p->defaultfolder) { report_status (driver, CAMEL_FILTER_STATUS_PROGRESS, 100, _("Syncing folder")); - camel_folder_sync (p->defaultfolder, FALSE, NULL); + camel_folder_sync (p->defaultfolder, FALSE, cancellable, NULL); } if (i == uids->len) @@ -1446,7 +1488,9 @@ get_message_cb (gpointer data, GError **error) else uid = camel_message_info_uid (p->info); - message = camel_folder_get_message (p->source, uid, error); + /* FIXME Pass a GCancellable */ + message = camel_folder_get_message ( + p->source, uid, NULL, error); } if (source_url && message && camel_mime_message_get_source (message) == NULL) @@ -1464,6 +1508,7 @@ get_message_cb (gpointer data, GError **error) * @source: source folder or NULL * @source_url: url of source folder or NULL * @original_source_url: url of original source folder (pre-movemail) or NULL + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Filters a message based on rules defined in the FilterDriver @@ -1484,6 +1529,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelFolder *source, const gchar *source_url, const gchar *original_source_url, + GCancellable *cancellable, GError **error) { struct _CamelFilterDriverPrivate *p = CAMEL_FILTER_DRIVER_GET_PRIVATE (driver); @@ -1505,7 +1551,8 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, if (message) { g_object_ref (message); } else { - message = camel_folder_get_message (source, uid, error); + message = camel_folder_get_message ( + source, uid, cancellable, error); if (!message) return -1; } @@ -1592,9 +1639,15 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, /* *Now* we can set the DELETED flag... */ if (p->deleted) { if (p->source && p->uid && camel_folder_has_summary_capability (p->source)) - camel_folder_set_message_flags (p->source, p->uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0); + camel_folder_set_message_flags ( + p->source, p->uid, + CAMEL_MESSAGE_DELETED | + CAMEL_MESSAGE_SEEN, ~0); else - camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED, ~0); + camel_message_info_set_flags ( + info, CAMEL_MESSAGE_DELETED | + CAMEL_MESSAGE_SEEN | + CAMEL_MESSAGE_FOLDER_FLAGGED, ~0); } /* Logic: if !Moved and there exists a default folder... */ @@ -1615,18 +1668,19 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, g_ptr_array_add (uids, (gchar *) p->uid); camel_folder_transfer_messages_to ( p->source, uids, p->defaultfolder, - NULL, FALSE, &p->error); + NULL, FALSE, cancellable, &p->error); g_ptr_array_free (uids, TRUE); } else { if (p->message == NULL) { - p->message = camel_folder_get_message (source, uid, error); + p->message = camel_folder_get_message ( + source, uid, cancellable, error); if (!p->message) goto error; } camel_folder_append_message ( p->defaultfolder, p->message, - p->info, NULL, &p->error); + p->info, NULL, cancellable, &p->error); } } diff --git a/camel/camel-filter-driver.h b/camel/camel-filter-driver.h index da22e9e..c509126 100644 --- a/camel/camel-filter-driver.h +++ b/camel/camel-filter-driver.h @@ -107,16 +107,29 @@ gint camel_filter_driver_remove_rule_by_name (CamelFilterDriver *d, const gcha void camel_filter_driver_flush (CamelFilterDriver *driver, GError **error); -gint camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage *message, - CamelMessageInfo *info, const gchar *uid, - CamelFolder *source, const gchar *source_url, - const gchar *original_source_url, GError **error); - -gint camel_filter_driver_filter_mbox (CamelFilterDriver *driver, const gchar *mbox, - const gchar *original_source_url, GError **error); - -gint camel_filter_driver_filter_folder (CamelFilterDriver *driver, CamelFolder *folder, CamelUIDCache *cache, - GPtrArray *uids, gboolean remove, GError **error); +gint camel_filter_driver_filter_message + (CamelFilterDriver *driver, + CamelMimeMessage *message, + CamelMessageInfo *info, + const gchar *uid, + CamelFolder *source, + const gchar *source_url, + const gchar *original_source_url, + GCancellable *cancellable, + GError **error); +gint camel_filter_driver_filter_mbox (CamelFilterDriver *driver, + const gchar *mbox, + const gchar *original_source_url, + GCancellable *cancellable, + GError **error); +gint camel_filter_driver_filter_folder + (CamelFilterDriver *driver, + CamelFolder *folder, + CamelUIDCache *cache, + GPtrArray *uids, + gboolean remove, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c index 03f3ed9..279786d 100644 --- a/camel/camel-filter-search.c +++ b/camel/camel-filter-search.c @@ -591,8 +591,8 @@ run_command (struct _ESExp *f, gint argc, struct _ESExpResult **argv, FilterMess stream = camel_stream_fs_new_with_fd (pipe_to_child); camel_data_wrapper_write_to_stream ( - CAMEL_DATA_WRAPPER (message), stream, NULL); - camel_stream_flush (stream, NULL); + CAMEL_DATA_WRAPPER (message), stream, NULL, NULL); + camel_stream_flush (stream, NULL, NULL); g_object_unref (stream); context = g_main_context_new (); diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c index 600fb36..e8061dd 100644 --- a/camel/camel-folder-search.c +++ b/camel/camel-folder-search.c @@ -1045,8 +1045,9 @@ get_current_message (CamelFolderSearch *search) if (!search || !search->folder || !search->current) return NULL; + /* FIXME Pass a GCancellable */ return camel_folder_get_message ( - search->folder, search->current->uid, NULL); + search->folder, search->current->uid, NULL, NULL); } static ESExpResult * @@ -1432,8 +1433,8 @@ match_words_1message (CamelDataWrapper *object, struct _camel_search_words *word stream = camel_stream_mem_new_with_byte_array (byte_array); /* FIXME: The match should be part of a stream op */ - camel_data_wrapper_decode_to_stream (containee, stream, NULL); - camel_stream_write (stream, "", 1, NULL); + camel_data_wrapper_decode_to_stream (containee, stream, NULL, NULL); + camel_stream_write (stream, "", 1, NULL, NULL); for (i=0;ilen;i++) { /* FIXME: This is horridly slow, and should use a real search algorithm */ if (camel_ustrstrcase ((const gchar *) byte_array->data, words->words[i]->word) != NULL) { @@ -1454,13 +1455,14 @@ static gboolean match_words_message (CamelFolder *folder, const gchar *uid, struct _camel_search_words *words, + GCancellable *cancellable, GError **error) { guint32 mask; CamelMimeMessage *msg; gint truth = FALSE; - msg = camel_folder_get_message (folder, uid, NULL); + msg = camel_folder_get_message (folder, uid, cancellable, error); if (msg) { mask = 0; truth = match_words_1message ((CamelDataWrapper *)msg, words, &mask); @@ -1473,6 +1475,7 @@ match_words_message (CamelFolder *folder, static GPtrArray * match_words_messages (CamelFolderSearch *search, struct _camel_search_words *words, + GCancellable *cancellable, GError **error) { gint i; @@ -1489,8 +1492,10 @@ match_words_messages (CamelFolderSearch *search, for (i=0;ilen;i++) { const gchar *uid = g_ptr_array_index (indexed, i); - if (match_words_message (search->folder, uid, words, error)) - g_ptr_array_add (matches, (gchar *)uid); + if (match_words_message ( + search->folder, uid, words, + cancellable, error)) + g_ptr_array_add(matches, (gchar *)uid); } g_ptr_array_free (indexed, TRUE); @@ -1500,8 +1505,10 @@ match_words_messages (CamelFolderSearch *search, for (i=0;ilen;i++) { gchar *uid = g_ptr_array_index (v, i); - if (match_words_message (search->folder, uid, words, error)) - g_ptr_array_add (matches, (gchar *)uid); + if (match_words_message ( + search->folder, uid, words, + cancellable, error)) + g_ptr_array_add(matches, (gchar *)uid); } } @@ -1532,7 +1539,8 @@ search_body_contains (struct _ESExp *f, gint argc, struct _ESExpResult **argv, C truth = match_message_index (search->body_index, camel_message_info_uid (search->current), words->words[j]->word, error); } else { /* TODO: cache current message incase of multiple body search terms */ - truth = match_words_message (search->folder, camel_message_info_uid (search->current), words, error); + /* FIXME Pass a GCancellable */ + truth = match_words_message(search->folder, camel_message_info_uid(search->current), words, NULL, error); } camel_search_words_free (words); } @@ -1562,7 +1570,8 @@ search_body_contains (struct _ESExp *f, gint argc, struct _ESExpResult **argv, C if ((words->type & CAMEL_SEARCH_WORD_COMPLEX) == 0 && search->body_index) { matches = match_words_index (search, words, error); } else { - matches = match_words_messages (search, words, error); + /* FIXME Pass a GCancellable */ + matches = match_words_messages(search, words, NULL, error); } for (j=0;jlen;j++) { g_hash_table_insert (ht, matches->pdata[j], matches->pdata[j]); @@ -1612,7 +1621,9 @@ search_body_regex (struct _ESExp *f, gint argc, struct _ESExpResult **argv, Came for (i = 0; i < v->len; i++) { gchar *uid = g_ptr_array_index (v, i); - message = camel_folder_get_message (search->folder, uid, NULL); + /* FIXME Pass a GCancellable */ + message = camel_folder_get_message ( + search->folder, uid, NULL, NULL); if (message) { if (camel_search_message_body_contains ((CamelDataWrapper *) message, &pattern)) { g_ptr_array_add (r->value.ptrarray, uid); @@ -1826,7 +1837,8 @@ search_message_location (struct _ESExp *f, gint argc, struct _ESExpResult **argv if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) { if (argv[0]->value.string && search->folder && parent_store && camel_folder_get_full_name (search->folder)) { - CamelFolderInfo *fi = camel_store_get_folder_info (parent_store, camel_folder_get_full_name (search->folder), 0, NULL); + /* FIXME Pass a GCancellable */ + CamelFolderInfo *fi = camel_store_get_folder_info (parent_store, camel_folder_get_full_name (search->folder), 0, NULL, NULL); if (fi) { same = g_str_equal (fi->uri ? fi->uri : "", argv[0]->value.string); diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index 421ad9e..421f535 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -1634,7 +1634,8 @@ msg_update_preview (const gchar *uid, gpointer value, CamelFolder *folder) full_name = camel_folder_get_full_name (folder); parent_store = camel_folder_get_parent_store (folder); - msg = camel_folder_get_message (folder, uid, NULL); + /* FIXME Pass a GCancellable */ + msg = camel_folder_get_message (folder, uid, NULL, NULL); if (msg != NULL) { if (camel_mime_message_build_preview ((CamelMimePart *)msg, (CamelMessageInfo *)info) && info->preview) camel_db_write_preview_record (parent_store->cdb_w, full_name, info->uid, info->preview, NULL); @@ -4043,8 +4044,8 @@ summary_build_content_info_message (CamelFolderSummary *s, CamelMessageInfo *msg p->filter_index); camel_data_wrapper_decode_to_stream ( - containee, p->filter_stream, NULL); - camel_stream_flush (p->filter_stream, NULL); + containee, p->filter_stream, NULL, NULL); + camel_stream_flush (p->filter_stream, NULL, NULL); camel_stream_filter_remove ( CAMEL_STREAM_FILTER (p->filter_stream), idx_id); diff --git a/camel/camel-folder.c b/camel/camel-folder.c index d27f658..101b9c9 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -102,7 +102,8 @@ static guint signals[LAST_SIGNAL]; G_DEFINE_ABSTRACT_TYPE (CamelFolder, camel_folder, CAMEL_TYPE_OBJECT) static void -filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg) +filter_filter (CamelSession *session, + CamelSessionThreadMsg *tmsg) { struct _folder_filter_msg *m = (struct _folder_filter_msg *) tmsg; CamelMessageInfo *info; @@ -121,44 +122,48 @@ 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 ( - NULL, ngettext ( + tmsg->cancellable, ngettext ( "Learning new spam message in '%s'", "Learning new spam messages in '%s'", m->junk->len), full_name); - for (i = 0; i < m->junk->len; i++) { - CamelMimeMessage *msg = camel_folder_get_message (m->folder, m->junk->pdata[i], NULL); + for (i = 0; i < m->junk->len; i ++) { + /* FIXME Pass a GCancellable */ + CamelMimeMessage *msg = camel_folder_get_message ( + m->folder, m->junk->pdata[i], NULL, NULL); gint pc = 100 * i / m->junk->len; - camel_operation_progress (NULL, pc); + camel_operation_progress (tmsg->cancellable, pc); if (msg) { camel_junk_plugin_report_junk (csp, msg); g_object_unref (msg); } } - camel_operation_end (NULL); + camel_operation_end (tmsg->cancellable); } if (m->notjunk) { /* Translators: The %s is replaced with a folder name where the operation is running. */ camel_operation_start ( - NULL, ngettext ( + tmsg->cancellable, ngettext ( "Learning new ham message in '%s'", "Learning new ham messages in '%s'", m->notjunk->len), full_name); - for (i = 0; i < m->notjunk->len; i++) { - CamelMimeMessage *msg = camel_folder_get_message (m->folder, m->notjunk->pdata[i], NULL); + for (i = 0; i < m->notjunk->len; i ++) { + /* FIXME Pass a GCancellable */ + CamelMimeMessage *msg = camel_folder_get_message ( + m->folder, m->notjunk->pdata[i], NULL, NULL); gint pc = 100 * i / m->notjunk->len; - camel_operation_progress (NULL, pc); + camel_operation_progress (tmsg->cancellable, pc); if (msg) { camel_junk_plugin_report_notjunk (csp, msg); g_object_unref (msg); } } - camel_operation_end (NULL); + camel_operation_end (tmsg->cancellable); } if (m->junk || m->notjunk) @@ -167,7 +172,7 @@ filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg) if (m->driver && m->recents) { /* Translators: The %s is replaced with a folder name where the operation is running. */ camel_operation_start ( - NULL, ngettext ( + tmsg->cancellable, ngettext ( "Filtering new message in '%s'", "Filtering new messages in '%s'", m->recents->len), full_name); @@ -191,7 +196,7 @@ filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg) gchar *uid = m->recents->pdata[i]; gint pc = 100 * i / m->recents->len; - camel_operation_progress (NULL, pc); + camel_operation_progress (tmsg->cancellable, pc); info = camel_folder_get_message_info (m->folder, uid); if (info == NULL) { @@ -199,7 +204,10 @@ filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg) continue; } - status = camel_filter_driver_filter_message (m->driver, NULL, info, uid, m->folder, source_url, source_url, NULL); + /* FIXME Pass a GCancellable */ + status = camel_filter_driver_filter_message ( + m->driver, NULL, info, uid, m->folder, + source_url, source_url, NULL, NULL); camel_folder_free_message_info (m->folder, info); } @@ -210,7 +218,7 @@ filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg) g_free (source_url); - camel_operation_end (NULL); + camel_operation_end (tmsg->cancellable); } } @@ -258,6 +266,7 @@ folder_transfer_message_to (CamelFolder *source, CamelFolder *dest, gchar **transferred_uid, gboolean delete_original, + GCancellable *cancellable, GError **error) { CamelMimeMessage *msg; @@ -266,7 +275,7 @@ folder_transfer_message_to (CamelFolder *source, /* Default implementation. */ - msg = camel_folder_get_message (source, uid, error); + msg = camel_folder_get_message (source, uid, cancellable, error); if (!msg) return; @@ -282,7 +291,8 @@ folder_transfer_message_to (CamelFolder *source, camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0); camel_folder_append_message ( - dest, msg, info, transferred_uid, &local_error); + dest, msg, info, transferred_uid, + cancellable, &local_error); g_object_unref (msg); if (local_error != NULL) @@ -421,6 +431,7 @@ folder_finalize (GObject *object) static gboolean folder_refresh_info (CamelFolder *folder, + GCancellable *cancellable, GError **error) { return TRUE; @@ -673,6 +684,7 @@ folder_transfer_messages_to (CamelFolder *source, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error) { gchar **ret_uid = NULL; @@ -685,9 +697,11 @@ folder_transfer_messages_to (CamelFolder *source, } if (delete_originals) - camel_operation_start (NULL, _("Moving messages")); + camel_operation_start ( + cancellable, _("Moving messages")); else - camel_operation_start (NULL, _("Copying messages")); + camel_operation_start ( + cancellable, _("Copying messages")); if (uids->len > 1) { camel_folder_freeze (dest); @@ -700,8 +714,9 @@ folder_transfer_messages_to (CamelFolder *source, ret_uid = (gchar **)&((*transferred_uids)->pdata[i]); folder_transfer_message_to ( source, uids->pdata[i], dest, ret_uid, - delete_originals, &local_error); - camel_operation_progress (NULL, i * 100 / uids->len); + delete_originals, cancellable, &local_error); + camel_operation_progress ( + cancellable, i * 100 / uids->len); } if (uids->len > 1) { @@ -710,7 +725,7 @@ folder_transfer_messages_to (CamelFolder *source, camel_folder_thaw (source); } - camel_operation_end (NULL); + camel_operation_end (cancellable); if (local_error != NULL) g_propagate_error (error, local_error); @@ -753,7 +768,7 @@ folder_freeze (CamelFolder *folder) } static void -folder_thaw (CamelFolder * folder) +folder_thaw (CamelFolder *folder) { CamelFolderChangeInfo *info = NULL; @@ -835,7 +850,9 @@ folder_changed (CamelFolder *folder, g_ptr_array_add (notjunk, g_strdup (info->uid_changed->pdata[i])); } /* reset junk learn flag so that we don't process it again*/ - camel_folder_set_message_flags (folder, info->uid_changed->pdata[i], CAMEL_MESSAGE_JUNK_LEARN, 0); + camel_folder_set_message_flags ( + folder, info->uid_changed->pdata [i], + CAMEL_MESSAGE_JUNK_LEARN, 0); } } } @@ -1098,6 +1115,7 @@ camel_folder_get_filename (CamelFolder *folder, * camel_folder_sync: * @folder: a #CamelFolder * @expunge: whether or not to expunge deleted messages + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Sync changes made to a folder to its backing store, possibly @@ -1108,6 +1126,7 @@ camel_folder_get_filename (CamelFolder *folder, gboolean camel_folder_sync (CamelFolder *folder, gboolean expunge, + GCancellable *cancellable, GError **error) { CamelFolderClass *class; @@ -1121,7 +1140,7 @@ camel_folder_sync (CamelFolder *folder, camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK); if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) { - success = class->sync (folder, expunge, error); + success = class->sync (folder, expunge, cancellable, error); CAMEL_CHECK_GERROR (folder, sync, success, error); } @@ -1133,6 +1152,7 @@ camel_folder_sync (CamelFolder *folder, /** * camel_folder_refresh_info: * @folder: a #CamelFolder + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Updates a folder's summary to be in sync with its backing store. @@ -1141,6 +1161,7 @@ camel_folder_sync (CamelFolder *folder, **/ gboolean camel_folder_refresh_info (CamelFolder *folder, + GCancellable *cancellable, GError **error) { CamelFolderClass *class; @@ -1153,7 +1174,7 @@ camel_folder_refresh_info (CamelFolder *folder, camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK); - success = class->refresh_info (folder, error); + success = class->refresh_info (folder, cancellable, error); CAMEL_CHECK_GERROR (folder, refresh_info, success, error); camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK); @@ -1296,6 +1317,7 @@ camel_folder_get_parent_store (CamelFolder *folder) /** * camel_folder_expunge: * @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" @@ -1304,6 +1326,7 @@ camel_folder_get_parent_store (CamelFolder *folder) **/ gboolean camel_folder_expunge (CamelFolder *folder, + GCancellable *cancellable, GError **error) { CamelFolderClass *class; @@ -1317,7 +1340,7 @@ camel_folder_expunge (CamelFolder *folder, camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK); if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) { - success = class->expunge (folder, error); + success = class->expunge (folder, cancellable, error); CAMEL_CHECK_GERROR (folder, expunge, success, error); } @@ -1387,6 +1410,7 @@ camel_folder_get_deleted_message_count (CamelFolder *folder) * 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 @@ -1399,6 +1423,7 @@ camel_folder_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error) { CamelFolderClass *class; @@ -1413,7 +1438,7 @@ camel_folder_append_message (CamelFolder *folder, camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK); success = class->append_message ( - folder, message, info, appended_uid, error); + folder, message, info, appended_uid, cancellable, error); CAMEL_CHECK_GERROR (folder, append_message, success, error); camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK); @@ -1727,6 +1752,7 @@ camel_folder_has_summary_capability (CamelFolder *folder) * camel_folder_get_message: * @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. @@ -1736,6 +1762,7 @@ camel_folder_has_summary_capability (CamelFolder *folder) CamelMimeMessage * camel_folder_get_message (CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error) { CamelFolderClass *class; @@ -1747,13 +1774,18 @@ camel_folder_get_message (CamelFolder *folder, class = CAMEL_FOLDER_GET_CLASS (folder); g_return_val_if_fail (class->get_message != NULL, NULL); + camel_operation_start ( + cancellable, _("Retrieving message '%s'"), uid); + camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK); - ret = class->get_message (folder, uid, error); + ret = class->get_message (folder, uid, cancellable, error); CAMEL_CHECK_GERROR (folder, get_message, 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); @@ -1768,6 +1800,7 @@ camel_folder_get_message (CamelFolder *folder, * camel_folder_sync_message: * @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 @@ -1780,6 +1813,7 @@ camel_folder_get_message (CamelFolder *folder, gboolean camel_folder_sync_message (CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error) { CamelFolderClass *class; @@ -1795,12 +1829,13 @@ camel_folder_sync_message (CamelFolder *folder, /* Use the sync_message method if the class implements it. */ if (class->sync_message != NULL) { - success = class->sync_message (folder, uid, error); + success = class->sync_message ( + folder, uid, cancellable, error); CAMEL_CHECK_GERROR (folder, sync_message, success, error); } else { CamelMimeMessage *message; - message = class->get_message (folder, uid, error); + message = class->get_message (folder, uid, cancellable, error); CAMEL_CHECK_GERROR (folder, get_message, message != NULL, error); if (message != NULL) { @@ -2139,6 +2174,7 @@ camel_folder_search_free (CamelFolder *folder, * @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 @@ -2153,6 +2189,7 @@ camel_folder_transfer_messages_to (CamelFolder *source, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error) { CamelFolderClass *class; @@ -2176,11 +2213,11 @@ camel_folder_transfer_messages_to (CamelFolder *source, class = CAMEL_FOLDER_GET_CLASS (source); success = class->transfer_messages_to ( source, uids, dest, transferred_uids, - delete_originals, error); + delete_originals, cancellable, error); } else success = folder_transfer_messages_to ( source, uids, dest, transferred_uids, - delete_originals, error); + delete_originals, cancellable, error); return success; } diff --git a/camel/camel-folder.h b/camel/camel-folder.h index 97a8fe8..1dff41a 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -145,24 +145,29 @@ struct _CamelFolderClass { /* Methods */ gboolean (*refresh_info) (CamelFolder *folder, + GCancellable *cancellable, GError **error); gboolean (*sync) (CamelFolder *folder, gboolean expunge, + GCancellable *cancellable, GError **error); gboolean (*expunge) (CamelFolder *folder, + GCancellable *cancellable, GError **error); gint (*get_message_count) (CamelFolder *folder); gboolean (*append_message) (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error); guint32 (*get_permanent_flags) (CamelFolder *folder); guint32 (*get_message_flags) (CamelFolder *folder, const gchar *uid); gboolean (*set_message_flags) (CamelFolder *folder, const gchar *uid, - guint32 flags, guint32 set); + guint32 flags, + guint32 set); gboolean (*get_message_user_flag)(CamelFolder *folder, const gchar *uid, const gchar *name); @@ -180,6 +185,7 @@ struct _CamelFolderClass { CamelMimeMessage * (*get_message) (CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error); GPtrArray * (*get_uids) (CamelFolder *folder); void (*free_uids) (CamelFolder *folder, @@ -214,6 +220,7 @@ struct _CamelFolderClass { CamelFolder *destination, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error); void (*delete) (CamelFolder *folder); void (*rename) (CamelFolder *folder, @@ -228,6 +235,7 @@ struct _CamelFolderClass { GError **error); gboolean (*sync_message) (CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error); GPtrArray * (*get_uncached_uids) (CamelFolder *folder, GPtrArray *uids, @@ -247,9 +255,11 @@ struct _CamelFolderClass { GType camel_folder_get_type (void); GQuark camel_folder_error_quark (void) G_GNUC_CONST; gboolean camel_folder_refresh_info (CamelFolder *folder, + GCancellable *cancellable, GError **error); gboolean camel_folder_sync (CamelFolder *folder, gboolean expunge, + GCancellable *cancellable, GError **error); void camel_folder_set_lock_async (CamelFolder *folder, gboolean skip_folder_lock); @@ -259,6 +269,7 @@ struct _CamelStore * /* delete operations */ gboolean camel_folder_expunge (CamelFolder *folder, + GCancellable *cancellable, GError **error); /* folder name operations */ @@ -312,6 +323,7 @@ gboolean camel_folder_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error); /* summary related operations */ @@ -336,15 +348,18 @@ void camel_folder_free_summary (CamelFolder *folder, CamelMimeMessage * camel_folder_get_message (CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error); gboolean camel_folder_sync_message (CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error); #define camel_folder_delete_message(folder, uid) \ - (camel_folder_set_message_flags \ - (folder, uid, CAMEL_MESSAGE_DELETED | \ - CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN)) + (camel_folder_set_message_flags ( \ + folder, uid, \ + CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, \ + CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN)) GPtrArray * camel_folder_get_uids (CamelFolder *folder); void camel_folder_free_uids (CamelFolder *folder, @@ -392,6 +407,7 @@ gboolean camel_folder_transfer_messages_to CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error); void camel_folder_delete (CamelFolder *folder); diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c index 51b3cfa..9f26313 100644 --- a/camel/camel-gpg-context.c +++ b/camel/camel-gpg-context.c @@ -88,61 +88,6 @@ enum { G_DEFINE_TYPE (CamelGpgContext, camel_gpg_context, CAMEL_TYPE_CIPHER_CONTEXT) -static const gchar * -gpg_hash_to_id (CamelCipherContext *context, CamelCipherHash hash) -{ - switch (hash) { - case CAMEL_CIPHER_HASH_MD2: - return "pgp-md2"; - case CAMEL_CIPHER_HASH_MD5: - return "pgp-md5"; - case CAMEL_CIPHER_HASH_SHA1: - case CAMEL_CIPHER_HASH_DEFAULT: - return "pgp-sha1"; - case CAMEL_CIPHER_HASH_SHA256: - return "pgp-sha256"; - case CAMEL_CIPHER_HASH_SHA384: - return "pgp-sha384"; - case CAMEL_CIPHER_HASH_SHA512: - return "pgp-sha512"; - case CAMEL_CIPHER_HASH_RIPEMD160: - return "pgp-ripemd160"; - case CAMEL_CIPHER_HASH_TIGER192: - return "pgp-tiger192"; - case CAMEL_CIPHER_HASH_HAVAL5160: - return "pgp-haval-5-160"; - } - - return NULL; -} - -static CamelCipherHash -gpg_id_to_hash (CamelCipherContext *context, const gchar *id) -{ - if (id) { - if (!strcmp (id, "pgp-md2")) - return CAMEL_CIPHER_HASH_MD2; - else if (!strcmp (id, "pgp-md5")) - return CAMEL_CIPHER_HASH_MD5; - else if (!strcmp (id, "pgp-sha1")) - return CAMEL_CIPHER_HASH_SHA1; - else if (!strcmp (id, "pgp-sha256")) - return CAMEL_CIPHER_HASH_SHA256; - else if (!strcmp (id, "pgp-sha384")) - return CAMEL_CIPHER_HASH_SHA384; - else if (!strcmp (id, "pgp-sha512")) - return CAMEL_CIPHER_HASH_SHA512; - else if (!strcmp (id, "pgp-ripemd160")) - return CAMEL_CIPHER_HASH_RIPEMD160; - else if (!strcmp (id, "tiger192")) - return CAMEL_CIPHER_HASH_TIGER192; - else if (!strcmp (id, "haval-5-160")) - return CAMEL_CIPHER_HASH_HAVAL5160; - } - - return CAMEL_CIPHER_HASH_DEFAULT; -} - enum _GpgCtxMode { GPG_CTX_MODE_SIGN, GPG_CTX_MODE_VERIFY, @@ -385,7 +330,7 @@ gpg_ctx_get_diagnostics (struct _GpgCtx *gpg) { if (!gpg->diagflushed) { gpg->diagflushed = TRUE; - camel_stream_flush (gpg->diagnostics, NULL); + camel_stream_flush (gpg->diagnostics, NULL, NULL); if (gpg->diagbuf->len == 0) return NULL; @@ -1122,11 +1067,12 @@ gpg_ctx_op_cancel (struct _GpgCtx *gpg) static gint gpg_ctx_op_step (struct _GpgCtx *gpg, + GCancellable *cancellable, GError **error) { #ifndef G_OS_WIN32 GPollFD polls[6]; - gint status, i, cancel_fd; + gint status, i; gboolean read_data = FALSE, wrote_data = FALSE; for (i=0;i<6;i++) { @@ -1153,8 +1099,7 @@ gpg_ctx_op_step (struct _GpgCtx *gpg, polls[3].events = G_IO_OUT; polls[4].fd = gpg->passwd_fd; polls[4].events = G_IO_OUT; - cancel_fd = camel_operation_cancel_fd (NULL); - polls[5].fd = cancel_fd; + polls[5].fd = g_cancellable_get_fd (cancellable); polls[5].events = G_IO_IN; do { @@ -1168,13 +1113,10 @@ gpg_ctx_op_step (struct _GpgCtx *gpg, else if (status == -1) goto exception; - if ((polls[5].revents & G_IO_IN) && camel_operation_cancel_check (NULL)) { - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Cancelled")); - gpg_ctx_op_cancel (gpg); + if ((polls[5].revents & G_IO_IN) && + g_cancellable_set_error_if_cancelled (cancellable, error)) { + gpg_ctx_op_cancel(gpg); return -1; } @@ -1221,7 +1163,8 @@ gpg_ctx_op_step (struct _GpgCtx *gpg, if (nread > 0) { gsize written = camel_stream_write ( - gpg->ostream, buffer, (gsize) nread, error); + gpg->ostream, buffer, (gsize) + nread, cancellable, error); if (written != nread) return -1; } else { @@ -1244,7 +1187,9 @@ gpg_ctx_op_step (struct _GpgCtx *gpg, goto exception; if (nread > 0) { - camel_stream_write (gpg->diagnostics, buffer, nread, error); + camel_stream_write ( + gpg->diagnostics, buffer, + nread, cancellable, error); } else { gpg->seen_eof2 = TRUE; } @@ -1286,7 +1231,8 @@ gpg_ctx_op_step (struct _GpgCtx *gpg, /* write our stream to gpg's stdin */ nread = camel_stream_read ( - gpg->istream, buffer, sizeof (buffer), NULL); + gpg->istream, buffer, + sizeof (buffer), cancellable, NULL); if (nread > 0) { gssize w, nwritten = 0; @@ -1402,12 +1348,171 @@ gpg_ctx_op_wait (struct _GpgCtx *gpg) #endif } +static gchar * +swrite (CamelMimePart *sigpart, + GCancellable *cancellable, + GError **error) +{ + CamelStream *ostream; + gchar *template; + gint fd, ret; + + template = g_build_filename (g_get_tmp_dir (), "evolution-pgp.XXXXXX", NULL); + if ((fd = g_mkstemp (template)) == -1) { + g_free (template); + return NULL; + } + + /* TODO: This should probably just write the decoded message content out, not the part + headers */ + + ostream = camel_stream_fs_new_with_fd (fd); + ret = camel_data_wrapper_write_to_stream ( + CAMEL_DATA_WRAPPER (sigpart), ostream, cancellable, error); + if (ret != -1) { + ret = camel_stream_flush (ostream, cancellable, error); + if (ret != -1) + ret = camel_stream_close (ostream, cancellable, error); + } + + g_object_unref (ostream); + + if (ret == -1) { + g_unlink (template); + g_free (template); + return NULL; + } + + return template; +} + +static void +add_signers (CamelCipherValidity *validity, const GString *signers) +{ + CamelInternetAddress *address; + gint i, count; + + g_return_if_fail (validity != NULL); + + if (!signers || !signers->str || !*signers->str) + return; + + address = camel_internet_address_new (); + g_return_if_fail (address != NULL); + + count = camel_address_decode (CAMEL_ADDRESS (address), signers->str); + for (i = 0; i < count; i++) { + const gchar *name = NULL, *email = NULL; + + if (!camel_internet_address_get (address, i, &name, &email)) + break; + + camel_cipher_validity_add_certinfo (validity, CAMEL_CIPHER_VALIDITY_SIGN, name, email); + } + + g_object_unref (address); +} + +/* ********************************************************************** */ + +static void +gpg_context_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ALWAYS_TRUST: + camel_gpg_context_set_always_trust ( + CAMEL_GPG_CONTEXT (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +gpg_context_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ALWAYS_TRUST: + g_value_set_boolean ( + value, + camel_gpg_context_get_always_trust ( + CAMEL_GPG_CONTEXT (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static const gchar * +gpg_hash_to_id (CamelCipherContext *context, + CamelCipherHash hash) +{ + switch (hash) { + case CAMEL_CIPHER_HASH_MD2: + return "pgp-md2"; + case CAMEL_CIPHER_HASH_MD5: + return "pgp-md5"; + case CAMEL_CIPHER_HASH_SHA1: + case CAMEL_CIPHER_HASH_DEFAULT: + return "pgp-sha1"; + case CAMEL_CIPHER_HASH_SHA256: + return "pgp-sha256"; + case CAMEL_CIPHER_HASH_SHA384: + return "pgp-sha384"; + case CAMEL_CIPHER_HASH_SHA512: + return "pgp-sha512"; + case CAMEL_CIPHER_HASH_RIPEMD160: + return "pgp-ripemd160"; + case CAMEL_CIPHER_HASH_TIGER192: + return "pgp-tiger192"; + case CAMEL_CIPHER_HASH_HAVAL5160: + return "pgp-haval-5-160"; + } + + return NULL; +} + +static CamelCipherHash +gpg_id_to_hash (CamelCipherContext *context, + const gchar *id) +{ + if (id) { + if (!strcmp (id, "pgp-md2")) + return CAMEL_CIPHER_HASH_MD2; + else if (!strcmp (id, "pgp-md5")) + return CAMEL_CIPHER_HASH_MD5; + else if (!strcmp (id, "pgp-sha1")) + return CAMEL_CIPHER_HASH_SHA1; + else if (!strcmp (id, "pgp-sha256")) + return CAMEL_CIPHER_HASH_SHA256; + else if (!strcmp (id, "pgp-sha384")) + return CAMEL_CIPHER_HASH_SHA384; + else if (!strcmp (id, "pgp-sha512")) + return CAMEL_CIPHER_HASH_SHA512; + else if (!strcmp (id, "pgp-ripemd160")) + return CAMEL_CIPHER_HASH_RIPEMD160; + else if (!strcmp (id, "tiger192")) + return CAMEL_CIPHER_HASH_TIGER192; + else if (!strcmp (id, "haval-5-160")) + return CAMEL_CIPHER_HASH_HAVAL5160; + } + + return CAMEL_CIPHER_HASH_DEFAULT; +} + static gint gpg_sign (CamelCipherContext *context, const gchar *userid, CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { struct _GpgCtx *gpg = NULL; @@ -1429,7 +1534,7 @@ gpg_sign (CamelCipherContext *context, ipart, CAMEL_MIME_FILTER_CANON_STRIP | CAMEL_MIME_FILTER_CANON_CRLF | CAMEL_MIME_FILTER_CANON_FROM, - istream, error) == -1) { + istream, NULL, error) == -1) { g_prefix_error ( error, _("Could not generate signing data: ")); goto fail; @@ -1465,7 +1570,7 @@ gpg_sign (CamelCipherContext *context, goto fail; while (!gpg_ctx_op_complete (gpg)) { - if (gpg_ctx_op_step (gpg, error) == -1) { + if (gpg_ctx_op_step (gpg, cancellable, error) == -1) { gpg_ctx_op_cancel (gpg); goto fail; } @@ -1487,7 +1592,7 @@ gpg_sign (CamelCipherContext *context, dw = camel_data_wrapper_new (); camel_stream_reset (ostream, NULL); - camel_data_wrapper_construct_from_stream (dw, ostream, NULL); + camel_data_wrapper_construct_from_stream (dw, ostream, NULL, NULL); sigpart = camel_mime_part_new (); ct = camel_content_type_new("application", "pgp-signature"); @@ -1523,72 +1628,10 @@ fail: return res; } -static gchar * -swrite (CamelMimePart *sigpart, - GError **error) -{ - CamelStream *ostream; - gchar *template; - gint fd, ret; - - template = g_build_filename (g_get_tmp_dir (), "evolution-pgp.XXXXXX", NULL); - if ((fd = g_mkstemp (template)) == -1) { - g_free (template); - return NULL; - } - - /* TODO: This should probably just write the decoded message content out, not the part + headers */ - - ostream = camel_stream_fs_new_with_fd (fd); - ret = camel_data_wrapper_write_to_stream ( - CAMEL_DATA_WRAPPER (sigpart), ostream, error); - if (ret != -1) { - ret = camel_stream_flush (ostream, error); - if (ret != -1) - ret = camel_stream_close (ostream, error); - } - - g_object_unref (ostream); - - if (ret == -1) { - g_unlink (template); - g_free (template); - return NULL; - } - - return template; -} - -static void -add_signers (CamelCipherValidity *validity, const GString *signers) -{ - CamelInternetAddress *address; - gint i, count; - - g_return_if_fail (validity != NULL); - - if (!signers || !signers->str || !*signers->str) - return; - - address = camel_internet_address_new (); - g_return_if_fail (address != NULL); - - count = camel_address_decode (CAMEL_ADDRESS (address), signers->str); - for (i = 0; i < count; i++) { - const gchar *name = NULL, *email = NULL; - - if (!camel_internet_address_get (address, i, &name, &email)) - break; - - camel_cipher_validity_add_certinfo (validity, CAMEL_CIPHER_VALIDITY_SIGN, name, email); - } - - g_object_unref (address); -} - static CamelCipherValidity * gpg_verify (CamelCipherContext *context, CamelMimePart *ipart, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -1645,7 +1688,8 @@ gpg_verify (CamelCipherContext *context, CamelDataWrapper *content; content = camel_medium_get_content ((CamelMedium *) ipart); istream = camel_stream_mem_new (); - camel_data_wrapper_decode_to_stream (content, istream, NULL); + camel_data_wrapper_decode_to_stream ( + content, istream, NULL, NULL); camel_stream_reset (istream, NULL); sigpart = NULL; } else { @@ -1689,7 +1733,7 @@ gpg_verify (CamelCipherContext *context, #endif if (sigpart) { - sigfile = swrite (sigpart, error); + sigfile = swrite (sigpart, cancellable, error); if (sigfile == NULL) { g_prefix_error ( error, _("Cannot verify message signature: ")); @@ -1706,7 +1750,7 @@ gpg_verify (CamelCipherContext *context, camel_stream_filter_add (CAMEL_STREAM_FILTER (filter), canon); g_object_unref (canon); - camel_stream_write_to_stream (istream, filter, NULL); + camel_stream_write_to_stream (istream, filter, NULL, NULL); g_object_unref (filter); camel_stream_reset (istream, NULL); @@ -1723,7 +1767,7 @@ gpg_verify (CamelCipherContext *context, goto exception; while (!gpg_ctx_op_complete (gpg)) { - if (gpg_ctx_op_step (gpg, error) == -1) { + if (gpg_ctx_op_step (gpg, cancellable, error) == -1) { gpg_ctx_op_cancel (gpg); goto exception; } @@ -1792,6 +1836,7 @@ gpg_encrypt (CamelCipherContext *context, GPtrArray *recipients, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -1809,7 +1854,7 @@ gpg_encrypt (CamelCipherContext *context, ostream = camel_stream_mem_new (); istream = camel_stream_mem_new (); if (camel_cipher_canonical_to_stream ( - ipart, CAMEL_MIME_FILTER_CANON_CRLF, istream, error) == -1) { + ipart, CAMEL_MIME_FILTER_CANON_CRLF, istream, NULL, error) == -1) { g_prefix_error ( error, _("Could not generate encrypting data: ")); goto fail1; @@ -1831,8 +1876,8 @@ gpg_encrypt (CamelCipherContext *context, goto fail; /* FIXME: move this to a common routine */ - while (!gpg_ctx_op_complete (gpg)) { - if (gpg_ctx_op_step (gpg, error) == -1) { + while (!gpg_ctx_op_complete(gpg)) { + if (gpg_ctx_op_step (gpg, cancellable, error) == -1) { gpg_ctx_op_cancel (gpg); goto fail; } @@ -1852,7 +1897,7 @@ gpg_encrypt (CamelCipherContext *context, res = 0; dw = camel_data_wrapper_new (); - camel_data_wrapper_construct_from_stream (dw, ostream, NULL); + camel_data_wrapper_construct_from_stream (dw, ostream, NULL, NULL); encpart = camel_mime_part_new (); ct = camel_content_type_new("application", "octet-stream"); @@ -1866,13 +1911,13 @@ gpg_encrypt (CamelCipherContext *context, camel_mime_part_set_description(encpart, _("This is a digitally encrypted message part")); vstream = camel_stream_mem_new (); - camel_stream_write (vstream, "Version: 1\n", strlen("Version: 1\n"), NULL); + camel_stream_write_string (vstream, "Version: 1\n", NULL, NULL); camel_stream_reset (vstream, NULL); verpart = camel_mime_part_new (); dw = camel_data_wrapper_new (); camel_data_wrapper_set_mime_type (dw, class->encrypt_protocol); - camel_data_wrapper_construct_from_stream (dw, vstream, NULL); + camel_data_wrapper_construct_from_stream (dw, vstream, NULL, NULL); g_object_unref (vstream); camel_medium_set_content ((CamelMedium *)verpart, dw); g_object_unref (dw); @@ -1905,6 +1950,7 @@ static CamelCipherValidity * gpg_decrypt (CamelCipherContext *context, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { struct _GpgCtx *gpg; @@ -1956,7 +2002,7 @@ gpg_decrypt (CamelCipherContext *context, } istream = camel_stream_mem_new (); - camel_data_wrapper_decode_to_stream (content, istream, NULL); + camel_data_wrapper_decode_to_stream (content, istream, NULL, NULL); camel_stream_reset (istream, NULL); ostream = camel_stream_mem_new (); @@ -1971,7 +2017,7 @@ gpg_decrypt (CamelCipherContext *context, goto fail; while (!gpg_ctx_op_complete (gpg)) { - if (gpg_ctx_op_step (gpg, error) == -1) { + if (gpg_ctx_op_step (gpg, cancellable, error) == -1) { gpg_ctx_op_cancel (gpg); goto fail; } @@ -1995,14 +2041,16 @@ gpg_decrypt (CamelCipherContext *context, /* Multipart encrypted - parse a full mime part */ rv = camel_data_wrapper_construct_from_stream ( - CAMEL_DATA_WRAPPER (opart), ostream, error); + CAMEL_DATA_WRAPPER (opart), + ostream, NULL, error); dw = camel_medium_get_content ((CamelMedium *)opart); - if (!camel_data_wrapper_decode_to_stream (dw, null, NULL)) { + if (!camel_data_wrapper_decode_to_stream (dw, null, cancellable, NULL)) { /* 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 (dw, ostream, error); + rv = camel_data_wrapper_construct_from_stream ( + dw, ostream, NULL, error); } g_object_unref (null); @@ -2010,7 +2058,8 @@ gpg_decrypt (CamelCipherContext *context, /* Inline signed - raw data (may not be a mime part) */ CamelDataWrapper *dw; dw = camel_data_wrapper_new (); - rv = camel_data_wrapper_construct_from_stream (dw, ostream, error); + rv = camel_data_wrapper_construct_from_stream ( + dw, ostream, NULL, error); camel_data_wrapper_set_mime_type(dw, "application/octet-stream"); camel_medium_set_content ((CamelMedium *)opart, dw); g_object_unref (dw); @@ -2052,6 +2101,7 @@ gpg_decrypt (CamelCipherContext *context, static gint gpg_import_keys (CamelCipherContext *context, CamelStream *istream, + GCancellable *cancellable, GError **error) { struct _GpgCtx *gpg; @@ -2065,7 +2115,7 @@ gpg_import_keys (CamelCipherContext *context, goto fail; while (!gpg_ctx_op_complete (gpg)) { - if (gpg_ctx_op_step (gpg, error) == -1) { + if (gpg_ctx_op_step (gpg, cancellable, error) == -1) { gpg_ctx_op_cancel (gpg); goto fail; } @@ -2093,6 +2143,7 @@ static gint gpg_export_keys (CamelCipherContext *context, GPtrArray *keys, CamelStream *ostream, + GCancellable *cancellable, GError **error) { struct _GpgCtx *gpg; @@ -2112,7 +2163,7 @@ gpg_export_keys (CamelCipherContext *context, goto fail; while (!gpg_ctx_op_complete (gpg)) { - if (gpg_ctx_op_step (gpg, error) == -1) { + if (gpg_ctx_op_step (gpg, cancellable, error) == -1) { gpg_ctx_op_cancel (gpg); goto fail; } @@ -2136,43 +2187,6 @@ fail: return res; } -/* ********************************************************************** */ - -static void -gpg_context_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ALWAYS_TRUST: - camel_gpg_context_set_always_trust ( - CAMEL_GPG_CONTEXT (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -gpg_context_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ALWAYS_TRUST: - g_value_set_boolean ( - value, - camel_gpg_context_get_always_trust ( - CAMEL_GPG_CONTEXT (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - static void camel_gpg_context_class_init (CamelGpgContextClass *class) { diff --git a/camel/camel-http-stream.c b/camel/camel-http-stream.c index 452898b..8bac0f2 100644 --- a/camel/camel-http-stream.c +++ b/camel/camel-http-stream.c @@ -56,6 +56,7 @@ G_DEFINE_TYPE (CamelHttpStream, camel_http_stream, CAMEL_TYPE_STREAM) static CamelStream * http_connect (CamelHttpStream *http, CamelURL *url, + GCancellable *cancellable, GError **error) { CamelTcpStream *tcp_stream; @@ -91,7 +92,8 @@ http_connect (CamelHttpStream *http, tcp_stream = CAMEL_TCP_STREAM (stream); - if (camel_tcp_stream_connect (tcp_stream, url->host, serv, 0, error) == -1) { + if (camel_tcp_stream_connect ( + tcp_stream, url->host, serv, 0, cancellable, error) == -1) { errsave = errno; g_object_unref (stream); errno = errsave; @@ -125,6 +127,7 @@ http_disconnect (CamelHttpStream *http) static gint http_method_invoke (CamelHttpStream *http, + GCancellable *cancellable, GError **error) { const gchar *method = NULL, *use_url; @@ -202,8 +205,8 @@ http_method_invoke (CamelHttpStream *http, } /* end the headers */ - if (camel_stream_write (http->raw, "\r\n", 2, error) == -1 || - camel_stream_flush (http->raw, error) == -1) { + if (camel_stream_write (http->raw, "\r\n", 2, cancellable, error) == -1 || + camel_stream_flush (http->raw, cancellable, error) == -1) { http_disconnect (http); return -1; } @@ -301,14 +304,15 @@ http_next_token (const guchar *in) static gint http_get_statuscode (CamelHttpStream *http, + GCancellable *cancellable, GError **error) { const gchar *token; gchar buffer[4096]; if (camel_stream_buffer_gets ( - CAMEL_STREAM_BUFFER (http->read), - buffer, sizeof (buffer), error) <= 0) + CAMEL_STREAM_BUFFER (http->read), buffer, + sizeof (buffer), cancellable, error) <= 0) return -1; d(printf("HTTP Status: %s\n", buffer)); @@ -383,6 +387,7 @@ static gssize http_stream_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelHttpStream *http = CAMEL_HTTP_STREAM (stream); @@ -404,15 +409,15 @@ http_stream_read (CamelStream *stream, if (!http->raw) { if (http_connect ( http, http->proxy ? http->proxy : - http->url, error) == NULL) + http->url, NULL, error) == NULL) return -1; - if (http_method_invoke (http, error) == -1) { + if (http_method_invoke (http, cancellable, error) == -1) { http_disconnect (http); return -1; } - if (http_get_statuscode (http, error) == -1) { + if (http_get_statuscode (http, cancellable, error) == -1) { http_disconnect (http); return -1; } @@ -486,6 +491,7 @@ static gssize http_stream_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { return -1; @@ -493,24 +499,26 @@ http_stream_write (CamelStream *stream, static gint http_stream_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelHttpStream *http = (CamelHttpStream *) stream; if (http->raw) - return camel_stream_flush (http->raw, error); + return camel_stream_flush (http->raw, cancellable, error); else return 0; } static gint http_stream_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelHttpStream *http = (CamelHttpStream *) stream; if (http->raw) { - if (camel_stream_close (http->raw, error) == -1) + if (camel_stream_close (http->raw, cancellable, error) == -1) return -1; http_disconnect (http); @@ -591,7 +599,7 @@ camel_http_stream_get_content_type (CamelHttpStream *http_stream) if (!http_stream->content_type && !http_stream->raw) { CamelStream *stream = CAMEL_STREAM (http_stream); - if (http_stream_read (stream, NULL, 0, NULL) == -1) + if (http_stream_read (stream, NULL, 0, NULL, NULL) == -1) return NULL; } diff --git a/camel/camel-index-control.c b/camel/camel-index-control.c index cf9dd32..bc41315 100644 --- a/camel/camel-index-control.c +++ b/camel/camel-index-control.c @@ -189,7 +189,7 @@ do_perf (gint argc, gchar **argv) CAMEL_MIME_FILTER_INDEX (filter_index), idn); name = g_strdup_printf("%s/%s", path, d->d_name); stream = camel_stream_fs_new_with_name (name, O_RDONLY, 0, NULL); - camel_stream_write_to_stream (stream, filter, NULL); + camel_stream_write_to_stream (stream, filter, NULL, NULL); g_object_unref (stream); g_free (name); diff --git a/camel/camel-lock-client.c b/camel/camel-lock-client.c index 8b4359e..538776c 100644 --- a/camel/camel-lock-client.c +++ b/camel/camel-lock-client.c @@ -225,7 +225,7 @@ again: error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Could not lock '%s'"), path); - d(printf("locking failed !status = %d\n", msg->id)); + d(printf("locking failed ! status = %d\n", msg->id)); break; } } else if (retry > 0) { diff --git a/camel/camel-mime-filter-progress.c b/camel/camel-mime-filter-progress.c index 6cdb3ce..30350f3 100644 --- a/camel/camel-mime-filter-progress.c +++ b/camel/camel-mime-filter-progress.c @@ -28,6 +28,7 @@ #include #include "camel-mime-filter-progress.h" +#include "camel-operation.h" #define CAMEL_MIME_FILTER_PROGRESS_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -37,7 +38,7 @@ #define w(x) struct _CamelMimeFilterProgressPrivate { - CamelOperation *operation; + GCancellable *cancellable; gsize total; gsize count; }; @@ -45,6 +46,22 @@ struct _CamelMimeFilterProgressPrivate { G_DEFINE_TYPE (CamelMimeFilterProgress, camel_mime_filter_progress, CAMEL_TYPE_MIME_FILTER) static void +mime_filter_progress_dispose (GObject *object) +{ + CamelMimeFilterProgressPrivate *priv; + + priv = CAMEL_MIME_FILTER_PROGRESS_GET_PRIVATE (object); + + if (priv->cancellable != NULL) { + g_object_unref (priv->cancellable); + priv->cancellable = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (camel_mime_filter_progress_parent_class)->dispose (object); +} + +static void mime_filter_progress_filter (CamelMimeFilter *mime_filter, const gchar *in, gsize len, @@ -64,7 +81,7 @@ mime_filter_progress_filter (CamelMimeFilter *mime_filter, else percent = 100.0; - camel_operation_progress (priv->operation, (gint) percent); + camel_operation_progress (priv->cancellable, (gint) percent); *outprespace = prespace; *outlen = len; @@ -98,10 +115,14 @@ mime_filter_progress_reset (CamelMimeFilter *mime_filter) static void camel_mime_filter_progress_class_init (CamelMimeFilterProgressClass *class) { + GObjectClass *object_class; CamelMimeFilterClass *mime_filter_class; g_type_class_add_private (class, sizeof (CamelMimeFilterProgressPrivate)); + object_class = G_OBJECT_CLASS (class); + object_class->dispose = mime_filter_progress_dispose; + mime_filter_class = CAMEL_MIME_FILTER_CLASS (class); mime_filter_class->filter = mime_filter_progress_filter; mime_filter_class->complete = mime_filter_progress_complete; @@ -116,29 +137,31 @@ camel_mime_filter_progress_init (CamelMimeFilterProgress *filter) /** * camel_mime_filter_progress_new: - * @operation: a #CamelOperation + * @cancellable: a #CamelOperation cast as a #GCancellable * @total: total number of bytes to report progress on * - * Create a new #CamelMimeFilterProgress object that will report - * streaming progress. + * Create a new #CamelMimeFilterProgress object that will report streaming + * progress. While the function will silently accept @cancellable being + * %NULL or a plain #GCancellable for convenience sake, no progress will be + * reported unless @cancellable is a #CamelOperation. * * Returns: a new #CamelMimeFilter object * * Since: 2.24 **/ CamelMimeFilter * -camel_mime_filter_progress_new (CamelOperation *operation, +camel_mime_filter_progress_new (GCancellable *cancellable, gsize total) { CamelMimeFilter *filter; CamelMimeFilterProgressPrivate *priv; - /* 'operation' can be NULL, then it means an active thread's operation */ - filter = g_object_new (CAMEL_TYPE_MIME_FILTER_PROGRESS, NULL); priv = CAMEL_MIME_FILTER_PROGRESS_GET_PRIVATE (filter); - priv->operation = operation; + if (CAMEL_IS_OPERATION (cancellable)) + priv->cancellable = cancellable; + priv->total = total; return filter; diff --git a/camel/camel-mime-filter-progress.h b/camel/camel-mime-filter-progress.h index 701aa94..437cd3f 100644 --- a/camel/camel-mime-filter-progress.h +++ b/camel/camel-mime-filter-progress.h @@ -27,7 +27,6 @@ #ifndef CAMEL_MIME_FILTER_PROGRESS_H #define CAMEL_MIME_FILTER_PROGRESS_H -#include #include /* Standard GObject macros */ @@ -71,7 +70,7 @@ struct _CamelMimeFilterProgressClass { GType camel_mime_filter_progress_get_type (void); CamelMimeFilter * - camel_mime_filter_progress_new (CamelOperation *operation, + camel_mime_filter_progress_new (GCancellable *cancellable, gsize total); G_END_DECLS diff --git a/camel/camel-mime-filter-save.c b/camel/camel-mime-filter-save.c index 3de1ef3..b7092f1 100644 --- a/camel/camel-mime-filter-save.c +++ b/camel/camel-mime-filter-save.c @@ -51,7 +51,7 @@ mime_filter_save_filter (CamelMimeFilter *mime_filter, priv = CAMEL_MIME_FILTER_SAVE_GET_PRIVATE (mime_filter); if (priv->stream != NULL) - camel_stream_write (priv->stream, in, len, NULL); + camel_stream_write (priv->stream, in, len, NULL, NULL); *out = (gchar *) in; *outlen = len; diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c index a79774b..3aefe96 100644 --- a/camel/camel-mime-message.c +++ b/camel/camel-mime-message.c @@ -218,6 +218,7 @@ mime_message_finalize (GObject *object) static gssize mime_message_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelDataWrapperClass *data_wrapper_class; @@ -244,8 +245,10 @@ mime_message_write_to_stream (CamelDataWrapper *data_wrapper, camel_medium_set_header ((CamelMedium *)mm, "Mime-Version", "1.0"); /* Chain up to parent's write_to_stream() method. */ - data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (camel_mime_message_parent_class); - return data_wrapper_class->write_to_stream (data_wrapper, stream, error); + data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS ( + camel_mime_message_parent_class); + return data_wrapper_class->write_to_stream ( + data_wrapper, stream, cancellable, error); } static void @@ -288,6 +291,7 @@ mime_message_remove_header (CamelMedium *medium, static gint mime_message_construct_from_parser (CamelMimePart *dw, CamelMimeParser *mp, + GCancellable *cancellable, GError **error) { CamelMimePartClass *mime_part_class; @@ -303,7 +307,8 @@ mime_message_construct_from_parser (CamelMimePart *dw, /* 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 (dw, mp, error); + ret = mime_part_class->construct_from_parser ( + dw, mp, cancellable, error); if (ret == -1) return -1; @@ -905,7 +910,7 @@ find_best_encoding (CamelMimePart *part, CamelBestencRequired required, CamelBes idb = camel_stream_filter_add ( CAMEL_STREAM_FILTER (filter), bestenc); d(printf("writing to checking stream\n")); - camel_data_wrapper_decode_to_stream (content, filter, NULL); + camel_data_wrapper_decode_to_stream (content, filter, NULL, NULL); camel_stream_filter_remove (CAMEL_STREAM_FILTER (filter), idb); if (idc != -1) { camel_stream_filter_remove (CAMEL_STREAM_FILTER (filter), idc); @@ -949,7 +954,7 @@ find_best_encoding (CamelMimePart *part, CamelBestencRequired required, CamelBes /* and write it to the new stream */ camel_data_wrapper_write_to_stream ( - content, filter, NULL); + content, filter, NULL, NULL); g_object_unref (charenc); } diff --git a/camel/camel-mime-parser.c b/camel/camel-mime-parser.c index 81c8bfd..2756924 100644 --- a/camel/camel-mime-parser.c +++ b/camel/camel-mime-parser.c @@ -917,7 +917,7 @@ folder_read (struct _header_scan_state *s) } if (s->stream) { len = camel_stream_read ( - s->stream, s->inbuf+inoffset, SCAN_BUF-inoffset, NULL); + s->stream, s->inbuf+inoffset, SCAN_BUF-inoffset, NULL, NULL); } else { len = read (s->fd, s->inbuf+inoffset, SCAN_BUF-inoffset); } diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c index 8bb6165..1cef03a 100644 --- a/camel/camel-mime-part-utils.c +++ b/camel/camel-mime-part-utils.c @@ -57,6 +57,7 @@ static gboolean simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw, CamelMimeParser *mp, + GCancellable *cancellable, GError **error) { gchar *buf; @@ -77,7 +78,8 @@ simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw, d(printf("message part kept in memory!\n")); mem = camel_stream_mem_new_with_byte_array (buffer); - retval = camel_data_wrapper_construct_from_stream (dw, mem, error); + retval = camel_data_wrapper_construct_from_stream ( + dw, mem, cancellable, error); g_object_unref (mem); return (retval == 0); @@ -91,6 +93,7 @@ simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw, gboolean camel_mime_part_construct_content_from_parser (CamelMimePart *dw, CamelMimeParser *mp, + GCancellable *cancellable, GError **error) { CamelDataWrapper *content = NULL; @@ -114,14 +117,14 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw, } else { content = camel_data_wrapper_new (); success = simple_data_wrapper_construct_from_parser ( - content, mp, error); + content, mp, cancellable, error); } break; 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 ( - (CamelMimePart *)content, mp, error) == 0); + (CamelMimePart *)content, mp, cancellable, error) == 0); break; case CAMEL_MIME_PARSER_STATE_MULTIPART: d(printf("Creating multi-part\n")); @@ -184,7 +187,7 @@ camel_mime_message_build_preview (CamelMimePart *msg, !camel_content_type_is (dw->mime_type, "text", "calendar")) { CamelStream *mstream, *bstream; mstream = camel_stream_mem_new (); - if (camel_data_wrapper_decode_to_stream (dw, mstream, NULL) > 0) { + if (camel_data_wrapper_decode_to_stream (dw, mstream, NULL, NULL) > 0) { gchar *line = NULL; GString *str = g_string_new (NULL); @@ -192,7 +195,7 @@ camel_mime_message_build_preview (CamelMimePart *msg, bstream = camel_stream_buffer_new (mstream, CAMEL_STREAM_BUFFER_READ|CAMEL_STREAM_BUFFER_BUFFER); /* We should fetch just 200 unquoted lines. */ - while ((line = camel_stream_buffer_read_line ((CamelStreamBuffer *)bstream, NULL)) && str->len < 200) { + while ((line = camel_stream_buffer_read_line ((CamelStreamBuffer *)bstream, NULL, NULL)) && str->len < 200) { gchar *tmp = line; if (!line) continue; diff --git a/camel/camel-mime-part-utils.h b/camel/camel-mime-part-utils.h index 3c18aaa..e28ea59 100644 --- a/camel/camel-mime-part-utils.h +++ b/camel/camel-mime-part-utils.h @@ -38,6 +38,7 @@ G_BEGIN_DECLS gboolean camel_mime_part_construct_content_from_parser (CamelMimePart *mime_part, CamelMimeParser *mp, + GCancellable *cancellable, GError **error); gboolean camel_mime_message_build_preview (CamelMimePart *mime_part, CamelMessageInfo *info); diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 90f9d23..a65dafa 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -93,34 +93,54 @@ static GHashTable *header_formatted_table; G_DEFINE_TYPE (CamelMimePart, camel_mime_part, CAMEL_TYPE_MEDIUM) static gssize -write_raw (CamelStream *stream, - struct _camel_header_raw *h) +write_header (CamelStream *stream, + const gchar *name, + const gchar *value, + GCancellable *cancellable, + GError **error) { - gchar *val = h->value; + GString *buffer; + gssize n_written; - return camel_stream_printf ( - stream, "%s%s%s\n", h->name, - isspace(val[0]) ? ":" : ": ", val); + buffer = g_string_new (name); + g_string_append_c (buffer, ':'); + if (!isspace (value[0])) + g_string_append_c (buffer, ' '); + g_string_append (buffer, value); + g_string_append_c (buffer, '\n'); + + n_written = camel_stream_write ( + stream, buffer->str, buffer->len, cancellable, error); + + g_string_free (buffer, TRUE); + + return n_written; } static gssize write_references (CamelStream *stream, - struct _camel_header_raw *h) + const gchar *name, + const gchar *value, + GCancellable *cancellable, + GError **error) { - gssize len, out, total; - gchar *value, *ids, *ide; - - /* this is only approximate, based on the next >, this way it retains any content - from the original which may not be properly formatted, etc. It also doesn't handle - the case where an individual messageid is too long, however thats a bad mail to - start with ... */ - - value = h->value; - len = strlen (h->name)+1; - total = camel_stream_printf ( - stream, "%s%s", h->name, isspace(value[0])?":":": "); - if (total == -1) - return -1; + GString *buffer; + const gchar *ids, *ide; + gssize n_written; + gsize len; + + /* this is only approximate, based on the next >, this way it retains + * any content from the original which may not be properly formatted, + * etc. It also doesn't handle the case where an individual messageid + * is too long, however thats a bad mail to start with ... */ + + buffer = g_string_new (name); + g_string_append_c (buffer, ':'); + if (!isspace (value[0])) + g_string_append_c (buffer, ' '); + + len = buffer->len; + while (*value) { ids = value; ide = strchr (ids+1, '>'); @@ -129,22 +149,23 @@ write_references (CamelStream *stream, else ide = value = strlen (ids)+ids; - if (len>0 && len + (ide - ids) >= CAMEL_FOLD_SIZE) { - out = camel_stream_printf (stream, "\n\t"); - if (out == -1) - return -1; - total += out; + if (len > 0 && len + (ide - ids) >= CAMEL_FOLD_SIZE) { + g_string_append_len (buffer, "\n\t", 2); len = 0; } - out = camel_stream_write (stream, ids, ide-ids, NULL); - if (out == -1) - return -1; - len += out; - total += out; + + g_string_append_len (buffer, ids, ide - ids); + len += (ide - ids); } - camel_stream_write (stream, "\n", 1, NULL); - return total; + g_string_append_c (buffer, '\n'); + + n_written = camel_stream_write ( + stream, buffer->str, buffer->len, cancellable, error); + + g_string_free (buffer, TRUE); + + return n_written; } /* loads in a hash table the set of header names we */ @@ -188,22 +209,22 @@ init_header_name_table (void) camel_strcase_hash, camel_strcase_equal); g_hash_table_insert ( header_formatted_table, - (gpointer) "Content-Type", write_raw); + (gpointer) "Content-Type", write_header); g_hash_table_insert ( header_formatted_table, - (gpointer) "Content-Disposition", write_raw); + (gpointer) "Content-Disposition", write_header); g_hash_table_insert ( header_formatted_table, - (gpointer) "From", write_raw); + (gpointer) "From", write_header); g_hash_table_insert ( header_formatted_table, - (gpointer) "Reply-To", write_raw); + (gpointer) "Reply-To", write_header); g_hash_table_insert ( header_formatted_table, - (gpointer) "Message-ID", write_raw); + (gpointer) "Message-ID", write_header); g_hash_table_insert ( header_formatted_table, - (gpointer) "In-Reply-To", write_raw); + (gpointer) "In-Reply-To", write_header); g_hash_table_insert ( header_formatted_table, (gpointer) "References", write_references); @@ -478,6 +499,7 @@ mime_part_set_content (CamelMedium *medium, static gssize mime_part_write_to_stream (CamelDataWrapper *dw, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelMimePart *mp = CAMEL_MIME_PART (dw); @@ -496,7 +518,11 @@ mime_part_write_to_stream (CamelDataWrapper *dw, if (mp->headers) { struct _camel_header_raw *h = mp->headers; gchar *val; - gssize (*writefn)(CamelStream *stream, struct _camel_header_raw *); + gssize (*writefn) (CamelStream *stream, + const gchar *name, + const gchar *value, + GCancellable *cancellable, + GError **error); /* fold/write the headers. But dont fold headers that are already formatted (e.g. ones with parameter-lists, that we know about, and have created) */ @@ -507,24 +533,23 @@ mime_part_write_to_stream (CamelDataWrapper *dw, count = 0; } else if ((writefn = g_hash_table_lookup (header_formatted_table, h->name)) == NULL) { val = camel_header_fold (val, strlen (h->name)); - count = camel_stream_printf(stream, "%s%s%s\n", h->name, isspace(val[0]) ? ":" : ": ", val); + count = write_header ( + stream, h->name, val, + cancellable, error); g_free (val); } else { - count = writefn (stream, h); + count = writefn ( + stream, h->name, h->value, + cancellable, error); } - if (count == -1) { - g_set_error ( - error, G_IO_ERROR, - g_io_error_from_errno (errno), - "%s", g_strerror (errno)); + if (count == -1) return -1; - } total += count; h = h->next; } } - count = camel_stream_write (stream, "\n", 1, error); + count = camel_stream_write (stream, "\n", 1, cancellable, error); if (count == -1) return -1; total += count; @@ -615,14 +640,14 @@ mime_part_write_to_stream (CamelDataWrapper *dw, if (reencode) count = camel_data_wrapper_decode_to_stream ( - content, stream, error); + content, stream, cancellable, error); else count = camel_data_wrapper_write_to_stream ( - content, stream, error); + content, stream, cancellable, error); if (filter_stream) { errnosav = errno; - camel_stream_flush (stream, NULL); + camel_stream_flush (stream, NULL, NULL); g_object_unref (filter_stream); errno = errnosav; } @@ -633,7 +658,8 @@ mime_part_write_to_stream (CamelDataWrapper *dw, total += count; if (reencode && mp->priv->encoding == CAMEL_TRANSFER_ENCODING_UUENCODE) { - count = camel_stream_write (ostream, "end\n", 4, error); + count = camel_stream_write ( + ostream, "end\n", 4, cancellable, error); if (count == -1) return -1; total += count; @@ -648,6 +674,7 @@ mime_part_write_to_stream (CamelDataWrapper *dw, static gint mime_part_construct_from_stream (CamelDataWrapper *dw, CamelStream *s, + GCancellable *cancellable, GError **error) { CamelMimeParser *mp; @@ -660,7 +687,7 @@ mime_part_construct_from_stream (CamelDataWrapper *dw, ret = -1; } else { ret = camel_mime_part_construct_from_parser ( - CAMEL_MIME_PART (dw), mp, error); + CAMEL_MIME_PART (dw), mp, cancellable, error); } g_object_unref (mp); return ret; @@ -669,6 +696,7 @@ mime_part_construct_from_stream (CamelDataWrapper *dw, static gint mime_part_construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *mp, + GCancellable *cancellable, GError **error) { CamelDataWrapper *dw = (CamelDataWrapper *) mime_part; @@ -708,7 +736,7 @@ mime_part_construct_from_parser (CamelMimePart *mime_part, } success = camel_mime_part_construct_content_from_parser ( - mime_part, mp, error); + mime_part, mp, cancellable, error); retval = success ? 0 : -1; break; default: @@ -1248,6 +1276,8 @@ camel_mime_part_get_content_type (CamelMimePart *mime_part) * camel_mime_part_construct_from_parser: * @mime_part: a #CamelMimePart object * @parser: a #CamelMimeParser object + * @cancellable: optional #GCancellable object, or %NULL + * @error: return location for a #GError, or %NULL * * Constructs a MIME part from a parser. * @@ -1256,6 +1286,7 @@ camel_mime_part_get_content_type (CamelMimePart *mime_part) gint camel_mime_part_construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *mp, + GCancellable *cancellable, GError **error) { CamelMimePartClass *class; @@ -1267,8 +1298,10 @@ camel_mime_part_construct_from_parser (CamelMimePart *mime_part, class = CAMEL_MIME_PART_GET_CLASS (mime_part); g_return_val_if_fail (class->construct_from_parser != NULL, -1); - retval = class->construct_from_parser (mime_part, mp, error); - CAMEL_CHECK_GERROR (mime_part, construct_from_parser, retval == 0, error); + retval = class->construct_from_parser ( + mime_part, mp, cancellable, error); + CAMEL_CHECK_GERROR ( + mime_part, construct_from_parser, retval == 0, error); return retval; } @@ -1312,7 +1345,8 @@ camel_mime_part_set_content (CamelMimePart *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 (dw, stream, NULL); + camel_data_wrapper_construct_from_stream ( + dw, stream, NULL, NULL); g_object_unref (stream); camel_medium_set_content (medium, dw); g_object_unref (dw); @@ -1333,7 +1367,7 @@ camel_mime_part_set_content (CamelMimePart *mime_part, gsize camel_mime_part_get_content_size (CamelMimePart *mime_part) { - CamelStreamNull *null; + CamelStream *null; CamelDataWrapper *dw; gsize size; @@ -1341,9 +1375,9 @@ camel_mime_part_get_content_size (CamelMimePart *mime_part) dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); - null = (CamelStreamNull *) camel_stream_null_new (); - camel_data_wrapper_decode_to_stream (dw, (CamelStream *) null, NULL); - size = null->written; + null = camel_stream_null_new (); + camel_data_wrapper_decode_to_stream (dw, null, NULL, NULL); + size = CAMEL_STREAM_NULL (null)->written; g_object_unref (null); diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h index 216a780..6259d19 100644 --- a/camel/camel-mime-part.h +++ b/camel/camel-mime-part.h @@ -69,53 +69,70 @@ struct _CamelMimePart { struct _CamelMimePartClass { CamelMediumClass parent_class; - gint (*construct_from_parser)(CamelMimePart *mime_part, + gint (*construct_from_parser) (CamelMimePart *mime_part, CamelMimeParser *parser, + GCancellable *cancellable, GError **error); }; -GType camel_mime_part_get_type (void); - -/* public methods */ -CamelMimePart * camel_mime_part_new (void); - -void camel_mime_part_set_description (CamelMimePart *mime_part, const gchar *description); -const gchar *camel_mime_part_get_description (CamelMimePart *mime_part); - -void camel_mime_part_set_disposition (CamelMimePart *mime_part, const gchar *disposition); -const gchar *camel_mime_part_get_disposition (CamelMimePart *mime_part); -const CamelContentDisposition *camel_mime_part_get_content_disposition (CamelMimePart *mime_part); - -void camel_mime_part_set_filename (CamelMimePart *mime_part, const gchar *filename); -const gchar *camel_mime_part_get_filename (CamelMimePart *mime_part); - -void camel_mime_part_set_content_id (CamelMimePart *mime_part, const gchar *contentid); -const gchar *camel_mime_part_get_content_id (CamelMimePart *mime_part); - -void camel_mime_part_set_content_md5 (CamelMimePart *mime_part, const gchar *md5sum); -const gchar *camel_mime_part_get_content_md5 (CamelMimePart *mime_part); - -void camel_mime_part_set_content_location (CamelMimePart *mime_part, const gchar *location); -const gchar *camel_mime_part_get_content_location (CamelMimePart *mime_part); - -void camel_mime_part_set_encoding (CamelMimePart *mime_part, CamelTransferEncoding encoding); -CamelTransferEncoding camel_mime_part_get_encoding (CamelMimePart *mime_part); - -void camel_mime_part_set_content_languages (CamelMimePart *mime_part, GList *content_languages); -const GList *camel_mime_part_get_content_languages (CamelMimePart *mime_part); +GType camel_mime_part_get_type (void); +CamelMimePart * camel_mime_part_new (void); +void camel_mime_part_set_description (CamelMimePart *mime_part, + const gchar *description); +const gchar * camel_mime_part_get_description (CamelMimePart *mime_part); +void camel_mime_part_set_disposition (CamelMimePart *mime_part, + const gchar *disposition); +const gchar * camel_mime_part_get_disposition (CamelMimePart *mime_part); +const CamelContentDisposition * + camel_mime_part_get_content_disposition + (CamelMimePart *mime_part); +void camel_mime_part_set_filename (CamelMimePart *mime_part, + const gchar *filename); +const gchar * camel_mime_part_get_filename (CamelMimePart *mime_part); +void camel_mime_part_set_content_id (CamelMimePart *mime_part, + const gchar *contentid); +const gchar * camel_mime_part_get_content_id (CamelMimePart *mime_part); +void camel_mime_part_set_content_md5 (CamelMimePart *mime_part, + const gchar *md5sum); +const gchar * camel_mime_part_get_content_md5 (CamelMimePart *mime_part); +void camel_mime_part_set_content_location + (CamelMimePart *mime_part, + const gchar *location); +const gchar * camel_mime_part_get_content_location + (CamelMimePart *mime_part); +void camel_mime_part_set_encoding (CamelMimePart *mime_part, + CamelTransferEncoding encoding); +CamelTransferEncoding + camel_mime_part_get_encoding (CamelMimePart *mime_part); +void camel_mime_part_set_content_languages + (CamelMimePart *mime_part, + GList *content_languages); +const GList * camel_mime_part_get_content_languages + (CamelMimePart *mime_part); /* FIXME: what about content-type parameters? what about major/minor parts? */ -void camel_mime_part_set_content_type (CamelMimePart *mime_part, const gchar *content_type); -CamelContentType *camel_mime_part_get_content_type (CamelMimePart *mime_part); +void camel_mime_part_set_content_type + (CamelMimePart *mime_part, + const gchar *content_type); +CamelContentType * + camel_mime_part_get_content_type + (CamelMimePart *mime_part); /* construction */ -gint camel_mime_part_construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *parser, GError **error); +gint camel_mime_part_construct_from_parser + (CamelMimePart *mime_part, + CamelMimeParser *parser, + GCancellable *cancellable, + GError **error); /* utility functions */ -void camel_mime_part_set_content (CamelMimePart *mime_part, - const gchar *data, gint length, const gchar *type); +void camel_mime_part_set_content (CamelMimePart *mime_part, + const gchar *data, + gint length, + const gchar *type); -gsize camel_mime_part_get_content_size (CamelMimePart *mime_part); +gsize camel_mime_part_get_content_size + (CamelMimePart *mime_part); G_END_DECLS diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c index 8798c58..cf620a6 100644 --- a/camel/camel-mime-utils.c +++ b/camel/camel-mime-utils.c @@ -4359,7 +4359,8 @@ camel_header_msgid_generate (void) retval = gethostname (host, sizeof (host)); if (retval == 0 && *host) { hints.ai_flags = AI_CANONNAME; - ai = camel_getaddrinfo (host, NULL, &hints, NULL); + ai = camel_getaddrinfo ( + host, NULL, &hints, NULL, NULL); if (ai && ai->ai_canonname) name = ai->ai_canonname; else diff --git a/camel/camel-multipart-signed.c b/camel/camel-multipart-signed.c index e52ba08..f61c08c 100644 --- a/camel/camel-multipart-signed.c +++ b/camel/camel-multipart-signed.c @@ -256,6 +256,7 @@ multipart_signed_set_mime_type_field (CamelDataWrapper *data_wrapper, static gssize multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelMultipartSigned *mps = (CamelMultipartSigned *)data_wrapper; @@ -275,7 +276,7 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper, if (data_wrapper->stream) { camel_stream_reset (data_wrapper->stream, NULL); return camel_stream_write_to_stream ( - data_wrapper->stream, stream, error); + data_wrapper->stream, stream, cancellable, error); } /* 3 */ @@ -297,7 +298,8 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper, /* 2 */ boundary = camel_multipart_get_boundary (mp); if (mp->preface) { - count = camel_stream_write_string (stream, mp->preface, error); + count = camel_stream_write_string ( + stream, mp->preface, cancellable, error); if (count == -1) return -1; total += count; @@ -311,7 +313,8 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper, /* output content part */ camel_stream_reset (mps->contentraw, NULL); - count = camel_stream_write_to_stream (mps->contentraw, stream, error); + count = camel_stream_write_to_stream ( + mps->contentraw, stream, cancellable, error); if (count == -1) return -1; total += count; @@ -324,7 +327,8 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper, /* signature */ count = camel_data_wrapper_write_to_stream ( - CAMEL_DATA_WRAPPER (mps->signature), stream, error); + CAMEL_DATA_WRAPPER (mps->signature), + stream, cancellable, error); if (count == -1) return -1; total += count; @@ -337,7 +341,8 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper, /* and finally the postface */ if (mp->postface) { - count = camel_stream_write_string (stream, mp->postface, error); + count = camel_stream_write_string ( + stream, mp->postface, cancellable, error); if (count == -1) return -1; total += count; @@ -357,12 +362,14 @@ file_error: static gint multipart_signed_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelMultipartSigned *mps = (CamelMultipartSigned *)data_wrapper; CamelStream *mem = camel_stream_mem_new (); - if (camel_stream_write_to_stream (stream, mem, error) == -1) + if (camel_stream_write_to_stream ( + stream, mem, cancellable, error) == -1) return -1; multipart_signed_set_stream (mps, mem); @@ -430,7 +437,7 @@ multipart_signed_get_part (CamelMultipart *multipart, camel_stream_reset (stream, NULL); mps->content = camel_mime_part_new (); camel_data_wrapper_construct_from_stream ( - CAMEL_DATA_WRAPPER (mps->content), stream, NULL); + CAMEL_DATA_WRAPPER (mps->content), stream, NULL, NULL); g_object_unref (stream); return mps->content; case CAMEL_MULTIPART_SIGNED_SIGNATURE: @@ -447,7 +454,8 @@ multipart_signed_get_part (CamelMultipart *multipart, camel_stream_reset (stream, NULL); mps->signature = camel_mime_part_new (); camel_data_wrapper_construct_from_stream ( - CAMEL_DATA_WRAPPER (mps->signature), stream, NULL); + CAMEL_DATA_WRAPPER (mps->signature), + stream, NULL, NULL); g_object_unref (stream); return mps->signature; default: @@ -499,7 +507,7 @@ multipart_signed_construct_from_parser (CamelMultipart *multipart, stream = camel_stream_mem_new (); while (camel_mime_parser_step (mp, &buf, &len) != CAMEL_MIME_PARSER_STATE_BODY_END) - camel_stream_write (stream, buf, len, NULL); + camel_stream_write (stream, buf, len, NULL, NULL); multipart_signed_set_stream (mps, stream); diff --git a/camel/camel-multipart.c b/camel/camel-multipart.c index 1f2ae22..cae7ea1 100644 --- a/camel/camel-multipart.c +++ b/camel/camel-multipart.c @@ -68,6 +68,7 @@ multipart_finalize (GObject *object) static gssize multipart_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper); @@ -89,7 +90,7 @@ multipart_write_to_stream (CamelDataWrapper *data_wrapper, */ if (multipart->preface) { count = camel_stream_write_string ( - stream, multipart->preface, error); + stream, multipart->preface, cancellable, error); if (count == -1) return -1; total += count; @@ -108,7 +109,8 @@ multipart_write_to_stream (CamelDataWrapper *data_wrapper, total += count; count = camel_data_wrapper_write_to_stream ( - CAMEL_DATA_WRAPPER (node->data), stream, error); + CAMEL_DATA_WRAPPER (node->data), + stream, cancellable, error); if (count == -1) return -1; total += count; @@ -125,7 +127,7 @@ multipart_write_to_stream (CamelDataWrapper *data_wrapper, /* and finally the postface */ if (multipart->postface) { count = camel_stream_write_string ( - stream, multipart->postface, error); + stream, multipart->postface, cancellable, error); if (count == -1) return -1; total += count; @@ -310,7 +312,8 @@ multipart_construct_from_parser (CamelMultipart *multipart, while (camel_mime_parser_step (mp, &buf, &len) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) { camel_mime_parser_unstep (mp); bodypart = camel_mime_part_new (); - camel_mime_part_construct_from_parser (bodypart, mp, NULL); + camel_mime_part_construct_from_parser ( + bodypart, mp, NULL, NULL); camel_multipart_add_part (multipart, bodypart); g_object_unref (bodypart); } diff --git a/camel/camel-net-utils.c b/camel/camel-net-utils.c index 02ab503..6769285 100644 --- a/camel/camel-net-utils.c +++ b/camel/camel-net-utils.c @@ -449,13 +449,14 @@ static gint cs_waitinfo (gpointer (worker)(gpointer), struct _addrinfo_msg *msg, const gchar *errmsg, + GCancellable *cancellable, GError **error) { CamelMsgPort *reply_port; GThread *thread; gint cancel_fd, cancel = 0, fd; - cancel_fd = camel_operation_cancel_fd (NULL); + cancel_fd = g_cancellable_get_fd (cancellable); if (cancel_fd == -1) { worker (msg); return 0; @@ -533,6 +534,8 @@ cs_waitinfo (gpointer (worker)(gpointer), } camel_msgport_destroy (reply_port); + g_cancellable_release_fd (cancellable); + return cancel; } @@ -675,6 +678,7 @@ struct addrinfo * camel_getaddrinfo (const gchar *name, const gchar *service, const struct addrinfo *hints, + GCancellable *cancellable, GError **error) { struct _addrinfo_msg *msg; @@ -684,15 +688,11 @@ camel_getaddrinfo (const gchar *name, #endif g_return_val_if_fail (name != NULL, NULL); - if (camel_operation_cancel_check (NULL)) { - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Cancelled")); + if (g_cancellable_set_error_if_cancelled (cancellable, error)) return NULL; - } - camel_operation_start_transient(NULL, _("Resolving: %s"), name); + camel_operation_start_transient ( + cancellable, _("Resolving: %s"), name); /* force ipv4 addresses only */ #ifndef ENABLE_IPv6 @@ -714,7 +714,10 @@ camel_getaddrinfo (const gchar *name, msg->hostbuflen = 1024; msg->hostbufmem = g_malloc (msg->hostbuflen); #endif - if (cs_waitinfo(cs_getaddrinfo, msg, _("Host lookup failed"), error) == 0) { + if (cs_waitinfo ( + cs_getaddrinfo, msg, _("Host lookup failed"), + cancellable, error) == 0) { + if (msg->result != 0) { g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, @@ -725,7 +728,8 @@ camel_getaddrinfo (const gchar *name, res = NULL; cs_freeinfo (msg); - camel_operation_end (NULL); + + camel_operation_end (cancellable); return res; } @@ -828,20 +832,17 @@ camel_getnameinfo (const struct sockaddr *sa, gchar **host, gchar **serv, gint flags, + GCancellable *cancellable, GError **error) { struct _addrinfo_msg *msg; gint result; - if (camel_operation_cancel_check (NULL)) { - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("Cancelled")); + if (g_cancellable_set_error_if_cancelled (cancellable, error)) return -1; - } - camel_operation_start_transient(NULL, _("Resolving address")); + camel_operation_start_transient ( + cancellable, _("Resolving address")); msg = g_malloc0 (sizeof (*msg)); msg->addr = sa; @@ -861,7 +862,9 @@ camel_getnameinfo (const struct sockaddr *sa, msg->hostbuflen = 1024; msg->hostbufmem = g_malloc (msg->hostbuflen); #endif - cs_waitinfo(cs_getnameinfo, msg, _("Name lookup failed"), error); + cs_waitinfo ( + cs_getnameinfo, msg, _("Name lookup failed"), + cancellable, error); if ((result = msg->result) != 0) g_set_error ( @@ -875,7 +878,8 @@ camel_getnameinfo (const struct sockaddr *sa, } cs_freeinfo (msg); - camel_operation_end (NULL); + + camel_operation_end (cancellable); return result; } diff --git a/camel/camel-net-utils.h b/camel/camel-net-utils.h index 0a36677..655e1b4 100644 --- a/camel/camel-net-utils.h +++ b/camel/camel-net-utils.h @@ -27,6 +27,7 @@ #ifndef CAMEL_NET_UTILS_H #define CAMEL_NET_UTILS_H +#include #include #ifndef _WIN32 @@ -88,11 +89,20 @@ struct addrinfo { #endif #endif -struct addrinfo *camel_getaddrinfo (const gchar *name, const gchar *service, - const struct addrinfo *hints, GError **error); -void camel_freeaddrinfo (struct addrinfo *host); -gint camel_getnameinfo (const struct sockaddr *sa, socklen_t salen, gchar **host, gchar **serv, - gint flags, GError **error); +struct addrinfo * + camel_getaddrinfo (const gchar *name, + const gchar *service, + const struct addrinfo *hints, + GCancellable *cancellable, + GError **error); +void camel_freeaddrinfo (struct addrinfo *host); +gint camel_getnameinfo (const struct sockaddr *sa, + socklen_t salen, + gchar **host, + gchar **serv, + gint flags, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/camel-offline-folder.c b/camel/camel-offline-folder.c index c643810..af31836 100644 --- a/camel/camel-offline-folder.c +++ b/camel/camel-offline-folder.c @@ -63,20 +63,28 @@ offline_downsync_sync (CamelSession *session, CamelSessionThreadMsg *mm) struct _offline_downsync_msg *m = (struct _offline_downsync_msg *) mm; gint i; - camel_operation_start (NULL, _("Downloading new messages for offline mode")); + camel_operation_start ( + mm->cancellable, + _("Downloading new messages for offline mode")); if (m->changes) { for (i = 0; i < m->changes->uid_added->len; i++) { gint pc = i * 100 / m->changes->uid_added->len; - camel_operation_progress (NULL, pc); - camel_folder_sync_message (m->folder, m->changes->uid_added->pdata[i], &mm->error); + camel_operation_progress (mm->cancellable, pc); + /* FIXME Pass a GCancellable */ + camel_folder_sync_message ( + m->folder, m->changes->uid_added->pdata[i], + NULL, &mm->error); } } else { - camel_offline_folder_downsync ((CamelOfflineFolder *) m->folder, "(match-all)", &mm->error); + /* FIXME Pass a GCancellable */ + camel_offline_folder_downsync ( + (CamelOfflineFolder *) m->folder, + "(match-all)", NULL, &mm->error); } - camel_operation_end (NULL); + camel_operation_end (mm->cancellable); } static void @@ -159,6 +167,7 @@ offline_folder_get_property (GObject *object, static gboolean offline_folder_downsync (CamelOfflineFolder *offline, const gchar *expression, + GCancellable *cancellable, GError **error) { CamelFolder *folder = (CamelFolder *) offline; @@ -166,7 +175,7 @@ offline_folder_downsync (CamelOfflineFolder *offline, gint i; camel_operation_start ( - NULL, _("Syncing messages in folder '%s' to disk"), + cancellable, _("Syncing messages in folder '%s' to disk"), camel_folder_get_full_name (folder)); if (expression) @@ -188,16 +197,17 @@ offline_folder_downsync (CamelOfflineFolder *offline, goto done; for (i = 0; i < uncached_uids->len; i++) { - gint pc = i * 100 / uncached_uids->len; - camel_folder_sync_message (folder, uncached_uids->pdata[i], NULL); - camel_operation_progress (NULL, pc); + camel_folder_sync_message ( + folder, uncached_uids->pdata[i], cancellable, NULL); + camel_operation_progress ( + cancellable, i * 100 / uncached_uids->len); } done: if (uncached_uids) camel_folder_free_uids (folder, uncached_uids); - camel_operation_end (NULL); + camel_operation_end (cancellable); return TRUE; } @@ -272,7 +282,9 @@ camel_offline_folder_set_offline_sync (CamelOfflineFolder *offline_folder, /** * camel_offline_folder_downsync: * @offline: a #CamelOfflineFolder object - * @expression: search expression describing which set of messages to downsync (%NULL for all) + * @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 @@ -283,6 +295,7 @@ camel_offline_folder_set_offline_sync (CamelOfflineFolder *offline_folder, gboolean camel_offline_folder_downsync (CamelOfflineFolder *offline, const gchar *expression, + GCancellable *cancellable, GError **error) { CamelOfflineFolderClass *class; @@ -293,7 +306,7 @@ camel_offline_folder_downsync (CamelOfflineFolder *offline, class = CAMEL_OFFLINE_FOLDER_GET_CLASS (offline); g_return_val_if_fail (class->downsync != NULL, FALSE); - success = class->downsync (offline, expression, error); + success = class->downsync (offline, expression, cancellable, error); CAMEL_CHECK_GERROR (offline, downsync, success, error); return success; diff --git a/camel/camel-offline-folder.h b/camel/camel-offline-folder.h index 9032abd..b8868db 100644 --- a/camel/camel-offline-folder.h +++ b/camel/camel-offline-folder.h @@ -64,6 +64,7 @@ struct _CamelOfflineFolderClass { gboolean (*downsync) (CamelOfflineFolder *folder, const gchar *expression, + GCancellable *cancellable, GError **error); }; @@ -75,6 +76,7 @@ void camel_offline_folder_set_offline_sync gboolean offline_sync); gboolean camel_offline_folder_downsync (CamelOfflineFolder *offline, const gchar *expression, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/camel/camel-offline-journal.c b/camel/camel-offline-journal.c index 76006cb..f76bc6a 100644 --- a/camel/camel-offline-journal.c +++ b/camel/camel-offline-journal.c @@ -179,6 +179,7 @@ camel_offline_journal_write (CamelOfflineJournal *journal, /** * camel_offline_journal_replay: * @journal: a #CamelOfflineJournal object + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Replay all entries in the journal. @@ -187,6 +188,7 @@ camel_offline_journal_write (CamelOfflineJournal *journal, **/ gint camel_offline_journal_replay (CamelOfflineJournal *journal, + GCancellable *cancellable, GError **error) { CamelDListNode *entry, *next; @@ -196,7 +198,8 @@ camel_offline_journal_replay (CamelOfflineJournal *journal, entry = journal->queue.head; while (entry->next) { next = entry->next; - if (CAMEL_OFFLINE_JOURNAL_GET_CLASS (journal)->entry_play (journal, entry, &local_error) == -1) { + if (CAMEL_OFFLINE_JOURNAL_GET_CLASS (journal)->entry_play ( + journal, entry, cancellable, &local_error) == -1) { if (failed == 0) { g_propagate_error (error, local_error); local_error = NULL; diff --git a/camel/camel-offline-journal.h b/camel/camel-offline-journal.h index f280449..c8cdda0 100644 --- a/camel/camel-offline-journal.h +++ b/camel/camel-offline-journal.h @@ -71,21 +71,31 @@ struct _CamelOfflineJournal { struct _CamelOfflineJournalClass { CamelObjectClass parent_class; - /* entry methods */ - void (* entry_free) (CamelOfflineJournal *journal, CamelDListNode *entry); - - CamelDListNode * (* entry_load) (CamelOfflineJournal *journal, FILE *in); - gint (* entry_write) (CamelOfflineJournal *journal, CamelDListNode *entry, FILE *out); - gint (* entry_play) (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error); + void (*entry_free) (CamelOfflineJournal *journal, + CamelDListNode *entry); + CamelDListNode *(*entry_load) (CamelOfflineJournal *journal, + FILE *in); + gint (*entry_write) (CamelOfflineJournal *journal, + CamelDListNode *entry, + FILE *out); + gint (*entry_play) (CamelOfflineJournal *journal, + CamelDListNode *entry, + GCancellable *cancellable, + GError **error); }; -GType camel_offline_journal_get_type (void); - -void camel_offline_journal_construct (CamelOfflineJournal *journal, struct _CamelFolder *folder, const gchar *filename); -void camel_offline_journal_set_filename (CamelOfflineJournal *journal, const gchar *filename); - -gint camel_offline_journal_write (CamelOfflineJournal *journal, GError **error); -gint camel_offline_journal_replay (CamelOfflineJournal *journal, GError **error); +GType camel_offline_journal_get_type (void); +void camel_offline_journal_construct (CamelOfflineJournal *journal, + CamelFolder *folder, + const gchar *filename); +void camel_offline_journal_set_filename + (CamelOfflineJournal *journal, + const gchar *filename); +gint camel_offline_journal_write (CamelOfflineJournal *journal, + GError **error); +gint camel_offline_journal_replay (CamelOfflineJournal *journal, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/camel-offline-store.c b/camel/camel-offline-store.c index aefd401..168657b 100644 --- a/camel/camel-offline-store.c +++ b/camel/camel-offline-store.c @@ -91,6 +91,7 @@ camel_offline_store_get_network_state (CamelOfflineStore *store, * camel_offline_store_set_network_state: * @store: a #CamelOfflineStore object * @state: the network state + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Set the network state to either #CAMEL_OFFLINE_STORE_NETWORK_AVAIL @@ -99,6 +100,7 @@ camel_offline_store_get_network_state (CamelOfflineStore *store, gboolean camel_offline_store_set_network_state (CamelOfflineStore *store, gint state, + GCancellable *cancellable, GError **error) { CamelService *service = CAMEL_SERVICE (store); @@ -126,7 +128,9 @@ camel_offline_store_set_network_state (CamelOfflineStore *store, if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_OFFLINE_FOLDER) && (sync || camel_offline_folder_get_offline_sync (CAMEL_OFFLINE_FOLDER (folder)))) { - camel_offline_folder_downsync ((CamelOfflineFolder *) folder, NULL, NULL); + camel_offline_folder_downsync ( + (CamelOfflineFolder *) folder, + NULL, cancellable, NULL); } g_object_unref (folder); @@ -135,7 +139,9 @@ camel_offline_store_set_network_state (CamelOfflineStore *store, g_ptr_array_free (folders, TRUE); } - camel_store_sync (CAMEL_STORE (store), FALSE, NULL); + camel_store_sync ( + CAMEL_STORE (store), + FALSE, cancellable, NULL); } if (!camel_service_disconnect (CAMEL_SERVICE (store), network_available, error)) @@ -161,6 +167,7 @@ camel_offline_store_set_network_state (CamelOfflineStore *store, **/ gboolean camel_offline_store_prepare_for_offline (CamelOfflineStore *store, + GCancellable *cancellable, GError **error) { CamelService *service = CAMEL_SERVICE (store); @@ -183,7 +190,7 @@ camel_offline_store_prepare_for_offline (CamelOfflineStore *store, if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_OFFLINE_FOLDER) && (sync || camel_offline_folder_get_offline_sync (CAMEL_OFFLINE_FOLDER (folder)))) { - camel_offline_folder_downsync ((CamelOfflineFolder *) folder, NULL, NULL); + camel_offline_folder_downsync ((CamelOfflineFolder *) folder, NULL, cancellable, NULL); } g_object_unref (folder); } @@ -191,7 +198,9 @@ camel_offline_store_prepare_for_offline (CamelOfflineStore *store, } } - camel_store_sync (CAMEL_STORE (store), FALSE, NULL); + camel_store_sync ( + CAMEL_STORE (store), + FALSE, cancellable, NULL); } return TRUE; diff --git a/camel/camel-offline-store.h b/camel/camel-offline-store.h index 8900f89..5d39870 100644 --- a/camel/camel-offline-store.h +++ b/camel/camel-offline-store.h @@ -67,15 +67,25 @@ struct _CamelOfflineStore { struct _CamelOfflineStoreClass { CamelStoreClass parent_class; - gboolean (* set_network_state) (CamelOfflineStore *store, gint state, GError **error); + gboolean (*set_network_state) (CamelOfflineStore *store, + gint state, + GCancellable *cancellable, + GError **error); }; -GType camel_offline_store_get_type (void); - -gboolean camel_offline_store_set_network_state (CamelOfflineStore *store, gint state, GError **error); -gint camel_offline_store_get_network_state (CamelOfflineStore *store, GError **error); - -gboolean camel_offline_store_prepare_for_offline (CamelOfflineStore *store, GError **error); +GType camel_offline_store_get_type (void); +gboolean camel_offline_store_set_network_state + (CamelOfflineStore *store, + gint state, + GCancellable *cancellable, + GError **error); +gint camel_offline_store_get_network_state + (CamelOfflineStore *store, + GError **error); +gboolean camel_offline_store_prepare_for_offline + (CamelOfflineStore *store, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/camel-operation.c b/camel/camel-operation.c index e03702f..82c6989 100644 --- a/camel/camel-operation.c +++ b/camel/camel-operation.c @@ -74,7 +74,6 @@ static GStaticRecMutex operation_lock = G_STATIC_REC_MUTEX_INIT; #define UNLOCK() g_static_rec_mutex_unlock (&operation_lock) static GQueue operation_list = G_QUEUE_INIT; -static GStaticPrivate operation_key = G_STATIC_PRIVATE_INIT; static guint signals[LAST_SIGNAL]; @@ -98,12 +97,6 @@ status_node_free (StatusNode *node) g_slice_free (StatusNode, node); } -static CamelOperation * -co_getcc (void) -{ - return (CamelOperation *) g_static_private_get (&operation_key); -} - static guint stamp (void) { @@ -262,22 +255,6 @@ camel_operation_new (void) } /** - * camel_operation_registered: - * - * Returns: the registered operation, or %NULL if none registered. - **/ -CamelOperation * -camel_operation_registered (void) -{ - CamelOperation *operation = co_getcc (); - - if (operation != NULL) - g_object_ref (operation); - - return operation; -} - -/** * camel_operation_cancel: * @operation: a #CamelOperation * @@ -325,8 +302,7 @@ camel_operation_cancel (CamelOperation *operation) * camel_operation_uncancel: * @operation: a #CamelOperation * - * Uncancel a cancelled operation. If @operation is %NULL then the current - * operation is uncancelled. + * Uncancel a cancelled operation. * * This is useful, if e.g. you need to do some cleaning up where a * cancellation lying around in the same thread will abort any @@ -335,9 +311,6 @@ camel_operation_cancel (CamelOperation *operation) void camel_operation_uncancel (CamelOperation *operation) { - if (operation == NULL) - operation = co_getcc (); - if (operation != NULL) { g_return_if_fail (CAMEL_IS_OPERATION (operation)); operation_flush_msgport (operation); @@ -346,45 +319,10 @@ camel_operation_uncancel (CamelOperation *operation) } /** - * camel_operation_register: - * @operation: a #CamelOperation - * - * Register a thread or the main thread for cancellation through @operation. - * If @operation is NULL, then a new cancellation is created for this thread. - * - * All calls to camel_operation_register() should save their value and - * call * camel_operation_register() again with that, to automatically - * stack * registrations. - * - * Returns: the previously registered operatoin. - **/ -CamelOperation * -camel_operation_register (CamelOperation *operation) -{ - CamelOperation *old_operation = co_getcc (); - - g_static_private_set (&operation_key, operation, NULL); - - return old_operation; -} - -/** - * camel_operation_unregister: - * - * Unregister the current thread for all cancellations. - **/ -void -camel_operation_unregister (void) -{ - g_static_private_set (&operation_key, NULL, NULL); -} - -/** * camel_operation_cancel_check: * @operation: a #CamelOperation * - * Check if cancellation has been applied to @operation. If @operation is - * %NULL, then the #CamelOperation registered for the current thread is used. + * Check if cancellation has been applied to @operation. * * Returns: %TRUE if the operation has been cancelled **/ @@ -394,9 +332,6 @@ camel_operation_cancel_check (CamelOperation *operation) gboolean cancelled; if (operation == NULL) - operation = co_getcc (); - - if (operation == NULL) return FALSE; LOCK (); @@ -425,9 +360,6 @@ gint camel_operation_cancel_fd (CamelOperation *operation) { if (operation == NULL) - operation = co_getcc (); - - if (operation == NULL) return -1; return g_cancellable_get_fd (G_CANCELLABLE (operation)); @@ -450,9 +382,6 @@ camel_operation_cancel_prfd (CamelOperation *operation) CamelOperationPrivate *priv; if (operation == NULL) - operation = co_getcc (); - - if (operation == NULL) return NULL; LOCK (); @@ -470,32 +399,41 @@ camel_operation_cancel_prfd (CamelOperation *operation) /** * camel_operation_start: - * @operation: a #CamelOperation + * @cancellable: a #GCancellable or %NULL * @what: action being performed (printf-style format string) * @Varargs: varargs * * Report the start of an operation. All start operations should have * similar end operations. + * + * 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 (CamelOperation *operation, +camel_operation_start (GCancellable *cancellable, const gchar *what, ...) { + CamelOperation *operation; const guint signal_id = signals[STATUS]; StatusNode *node; va_list ap; - if (operation == NULL) - operation = co_getcc (); + if (cancellable == NULL) + return; - if (operation == NULL) + if (G_OBJECT_TYPE (cancellable) == G_TYPE_CANCELLABLE) return; - if (!g_signal_has_handler_pending (operation, signal_id, 0, TRUE)) + 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, what); @@ -512,29 +450,38 @@ camel_operation_start (CamelOperation *operation, /** * camel_operation_start_transient: - * @operation: a #CamelOperation + * @cancellable: a #GCancellable or %NULL * @what: printf-style format string describing the action being performed * @Varargs: varargs * * 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. + * + * 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 (CamelOperation *operation, +camel_operation_start_transient (GCancellable *cancellable, const gchar *what, ...) { + CamelOperation *operation; StatusNode *node; va_list ap; - if (operation == NULL) - operation = co_getcc (); + if (cancellable == NULL) + return; - if (operation == NULL) + if (G_OBJECT_TYPE (cancellable) == G_TYPE_CANCELLABLE) return; + g_return_if_fail (CAMEL_IS_OPERATION (cancellable)); + LOCK (); + operation = CAMEL_OPERATION (cancellable); + operation->priv->status_update = 0; va_start (ap, what); @@ -551,36 +498,40 @@ camel_operation_start_transient (CamelOperation *operation, /** * camel_operation_progress: - * @operation: a #CamelOperation - * @pc: Percent complete, 0 to 100. + * @cancellable: a #GCancellable or %NULL + * @pc: percent complete, 0 to 100. * - * Report progress on the current operation. If @operation is %NULL, then - * the currently registered operation is used. @pc reports the current + * Report progress on the current operation. @pc reports the current * percentage of completion, which should be in the range of 0 to 100. * - * If the total percentage is not know, then use - * camel_operation_progress_count(). + * 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_progress (CamelOperation *operation, +camel_operation_progress (GCancellable *cancellable, gint pc) { + CamelOperation *operation; const guint signal_id = signals[STATUS]; CamelOperationPrivate *priv; guint now; StatusNode *node; - if (operation == NULL) - operation = co_getcc (); + if (cancellable == NULL) + return; - if (operation == NULL) + if (G_OBJECT_TYPE (cancellable) == G_TYPE_CANCELLABLE) return; - if (!g_signal_has_handler_pending (operation, signal_id, 0, TRUE)) + 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; if (g_queue_is_empty (&priv->status_stack)) { @@ -614,29 +565,37 @@ camel_operation_progress (CamelOperation *operation, /** * camel_operation_end: - * @operation: a #CamelOperation + * @cancellable: a #GCancellable * - * Report the end of an operation. If @operation is %NULL, then the - * currently registered operation is notified. + * 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 (CamelOperation *operation) +camel_operation_end (GCancellable *cancellable) { + CamelOperation *operation; const guint signal_id = signals[STATUS]; GQueue *status_stack; StatusNode *node; - if (operation == NULL) - operation = co_getcc (); + if (cancellable == NULL) + return; - if (operation == NULL) + if (G_OBJECT_TYPE (cancellable) == G_TYPE_CANCELLABLE) return; - if (!g_signal_has_handler_pending (operation, signal_id, 0, TRUE)) + 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) { diff --git a/camel/camel-operation.h b/camel/camel-operation.h index ec35a4f..6b6b549 100644 --- a/camel/camel-operation.h +++ b/camel/camel-operation.h @@ -71,10 +71,6 @@ CamelOperation *camel_operation_new (void); void camel_operation_cancel (CamelOperation *operation); void camel_operation_uncancel (CamelOperation *operation); -/* subthread functions */ -CamelOperation *camel_operation_register (CamelOperation *operation); -void camel_operation_unregister (void); - /* called internally by camel, for the current thread */ gboolean camel_operation_cancel_check (CamelOperation *operation); gint camel_operation_cancel_fd (CamelOperation *operation); @@ -83,18 +79,20 @@ struct PRFileDesc * camel_operation_cancel_prfd (CamelOperation *operation); #endif -/* return the registered operation for this thread, if there is one */ -CamelOperation *camel_operation_registered (void); +/* Since Camel methods pass around GCancellable pointers instead of + * CamelOperation pointers, it's more convenient to callers to take + * 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 (CamelOperation *cc, +void camel_operation_start (GCancellable *cancellable, const gchar *what, ...) G_GNUC_PRINTF (2, 3); -void camel_operation_start_transient (CamelOperation *cc, +void camel_operation_start_transient (GCancellable *cancellable, const gchar *what, ...) G_GNUC_PRINTF (2, 3); -void camel_operation_progress (CamelOperation *operation, +void camel_operation_progress (GCancellable *cancellable, gint pc); -void camel_operation_end (CamelOperation *operation); +void camel_operation_end (GCancellable *cancellable); G_END_DECLS diff --git a/camel/camel-sasl-anonymous.c b/camel/camel-sasl-anonymous.c index dbbb500..06bd930 100644 --- a/camel/camel-sasl-anonymous.c +++ b/camel/camel-sasl-anonymous.c @@ -56,6 +56,7 @@ sasl_anonymous_finalize (GObject *object) static GByteArray * sasl_anonymous_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error) { CamelSaslAnonymous *sasl_anon = CAMEL_SASL_ANONYMOUS (sasl); diff --git a/camel/camel-sasl-cram-md5.c b/camel/camel-sasl-cram-md5.c index ae4bb16..ed087e9 100644 --- a/camel/camel-sasl-cram-md5.c +++ b/camel/camel-sasl-cram-md5.c @@ -60,6 +60,7 @@ G_DEFINE_TYPE (CamelSaslCramMd5, camel_sasl_cram_md5, CAMEL_TYPE_SASL) static GByteArray * sasl_cram_md5_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error) { CamelService *service; diff --git a/camel/camel-sasl-digest-md5.c b/camel/camel-sasl-digest-md5.c index 36ea3db..a90a52f 100644 --- a/camel/camel-sasl-digest-md5.c +++ b/camel/camel-sasl-digest-md5.c @@ -789,6 +789,7 @@ sasl_digest_md5_finalize (GObject *object) static GByteArray * sasl_digest_md5_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error) { CamelSaslDigestMd5 *sasl_digest = CAMEL_SASL_DIGEST_MD5 (sasl); @@ -843,7 +844,10 @@ sasl_digest_md5_challenge (CamelSasl *sasl, memset (&hints, 0, sizeof (hints)); hints.ai_flags = AI_CANONNAME; - ai = camel_getaddrinfo(service->url->host?service->url->host:"localhost", NULL, &hints, NULL); + ai = camel_getaddrinfo ( + service->url->host ? + service->url->host : "localhost", + NULL, &hints, cancellable, NULL); if (ai && ai->ai_canonname) ptr = ai->ai_canonname; else diff --git a/camel/camel-sasl-gssapi.c b/camel/camel-sasl-gssapi.c index f736be9..8edaf00 100644 --- a/camel/camel-sasl-gssapi.c +++ b/camel/camel-sasl-gssapi.c @@ -243,6 +243,7 @@ send_dbus_message (gchar *name) static GByteArray * sasl_gssapi_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error) { CamelSaslGssapiPrivate *priv; @@ -267,7 +268,10 @@ sasl_gssapi_challenge (CamelSasl *sasl, case GSSAPI_STATE_INIT: memset (&hints, 0, sizeof (hints)); hints.ai_flags = AI_CANONNAME; - ai = camel_getaddrinfo(service->url->host?service->url->host:"localhost", NULL, &hints, error); + ai = camel_getaddrinfo ( + service->url->host ? + service->url->host : "localhost", + NULL, &hints, cancellable, error); if (ai == NULL) return NULL; diff --git a/camel/camel-sasl-login.c b/camel/camel-sasl-login.c index de3aba4..66554f8 100644 --- a/camel/camel-sasl-login.c +++ b/camel/camel-sasl-login.c @@ -59,6 +59,7 @@ G_DEFINE_TYPE (CamelSaslLogin, camel_sasl_login, CAMEL_TYPE_SASL) static GByteArray * sasl_login_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error) { CamelSaslLoginPrivate *priv; diff --git a/camel/camel-sasl-ntlm.c b/camel/camel-sasl-ntlm.c index bfa2b1d..b59f551 100644 --- a/camel/camel-sasl-ntlm.c +++ b/camel/camel-sasl-ntlm.c @@ -661,6 +661,7 @@ deskey (DES_KS k, guchar *key, gint decrypt) static GByteArray * sasl_ntlm_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error) { CamelService *service; diff --git a/camel/camel-sasl-plain.c b/camel/camel-sasl-plain.c index e27a6b9..3d67209 100644 --- a/camel/camel-sasl-plain.c +++ b/camel/camel-sasl-plain.c @@ -54,6 +54,7 @@ G_DEFINE_TYPE (CamelSaslPlain, camel_sasl_plain, CAMEL_TYPE_SASL) static GByteArray * sasl_plain_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error) { GByteArray *buf = NULL; diff --git a/camel/camel-sasl-popb4smtp.c b/camel/camel-sasl-popb4smtp.c index 870a109..d91f366 100644 --- a/camel/camel-sasl-popb4smtp.c +++ b/camel/camel-sasl-popb4smtp.c @@ -66,6 +66,7 @@ G_DEFINE_TYPE (CamelSaslPOPB4SMTP, camel_sasl_popb4smtp, CAMEL_TYPE_SASL) static GByteArray * sasl_popb4smtp_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error) { gchar *popuri; diff --git a/camel/camel-sasl.c b/camel/camel-sasl.c index 8a616ce..fe89e99 100644 --- a/camel/camel-sasl.c +++ b/camel/camel-sasl.c @@ -258,6 +258,7 @@ camel_sasl_init (CamelSasl *sasl) * camel_sasl_challenge: * @sasl: a #CamelSasl object * @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 @@ -265,12 +266,13 @@ camel_sasl_init (CamelSasl *sasl) * exchange.) Otherwise, @token is a challenge from the server, and * the return value is the response. * - * Returns: the SASL response or %NULL. If an error occurred, @ex will + * Returns: the SASL response or %NULL. If an error occurred, @error will * also be set. **/ GByteArray * camel_sasl_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error) { CamelSaslClass *class; @@ -281,7 +283,7 @@ camel_sasl_challenge (CamelSasl *sasl, class = CAMEL_SASL_GET_CLASS (sasl); g_return_val_if_fail (class->challenge != NULL, NULL); - response = class->challenge (sasl, token, error); + response = class->challenge (sasl, token, cancellable, error); if (token) CAMEL_CHECK_GERROR (sasl, challenge, response != NULL, error); @@ -292,6 +294,7 @@ camel_sasl_challenge (CamelSasl *sasl, * camel_sasl_challenge_base64: * @sasl: a #CamelSasl object * @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 @@ -302,6 +305,7 @@ camel_sasl_challenge (CamelSasl *sasl, gchar * camel_sasl_challenge_base64 (CamelSasl *sasl, const gchar *token, + GCancellable *cancellable, GError **error) { GByteArray *token_binary, *ret_binary; @@ -320,7 +324,8 @@ camel_sasl_challenge_base64 (CamelSasl *sasl, } else token_binary = NULL; - ret_binary = camel_sasl_challenge (sasl, token_binary, error); + ret_binary = camel_sasl_challenge ( + sasl, token_binary, cancellable, error); if (token_binary) g_byte_array_free (token_binary, TRUE); if (!ret_binary) diff --git a/camel/camel-sasl.h b/camel/camel-sasl.h index 3bf3dc8..01ff9d6 100644 --- a/camel/camel-sasl.h +++ b/camel/camel-sasl.h @@ -65,15 +65,18 @@ struct _CamelSaslClass { GByteArray * (*challenge) (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error); }; GType camel_sasl_get_type (void); GByteArray * camel_sasl_challenge (CamelSasl *sasl, GByteArray *token, + GCancellable *cancellable, GError **error); gchar * camel_sasl_challenge_base64 (CamelSasl *sasl, const gchar *token, + GCancellable *cancellable, GError **error); CamelSasl * camel_sasl_new (const gchar *service_name, const gchar *mechanism, diff --git a/camel/camel-search-private.c b/camel/camel-search-private.c index d4a6c31..3058d35 100644 --- a/camel/camel-search-private.c +++ b/camel/camel-search-private.c @@ -479,8 +479,8 @@ camel_search_message_body_contains (CamelDataWrapper *object, regex_t *pattern) byte_array = g_byte_array_new (); stream = camel_stream_mem_new_with_byte_array (byte_array); - camel_data_wrapper_write_to_stream (containee, stream, NULL); - camel_stream_write (stream, "", 1, NULL); + camel_data_wrapper_write_to_stream (containee, stream, NULL, NULL); + camel_stream_write (stream, "", 1, NULL, NULL); truth = regexec (pattern, (gchar *) byte_array->data, 0, NULL, 0) == 0; g_object_unref (stream); } diff --git a/camel/camel-seekable-substream.c b/camel/camel-seekable-substream.c index 93685ef..f75dee0 100644 --- a/camel/camel-seekable-substream.c +++ b/camel/camel-seekable-substream.c @@ -63,6 +63,7 @@ static gssize seekable_substream_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelSeekableStream *parent; @@ -90,7 +91,8 @@ seekable_substream_read (CamelStream *stream, return 0; } - v = camel_stream_read (CAMEL_STREAM (parent), buffer, n, error); + v = camel_stream_read ( + CAMEL_STREAM (parent), buffer, n, cancellable, error); /* ignore <0 - it's an error, let the caller deal */ if (v > 0) @@ -103,6 +105,7 @@ static gssize seekable_substream_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelSeekableStream *parent; @@ -130,7 +133,8 @@ seekable_substream_write (CamelStream *stream, return 0; } - v = camel_stream_write (CAMEL_STREAM (parent), buffer, n, error); + v = camel_stream_write ( + CAMEL_STREAM (parent), buffer, n, cancellable, error); /* ignore <0 - it's an error, let the caller deal */ if (v > 0) @@ -142,15 +146,18 @@ seekable_substream_write (CamelStream *stream, static gint seekable_substream_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelSeekableSubstream *sus = (CamelSeekableSubstream *)stream; - return camel_stream_flush (CAMEL_STREAM (sus->parent_stream), error); + return camel_stream_flush ( + CAMEL_STREAM (sus->parent_stream), cancellable, error); } static gint seekable_substream_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { /* we dont really want to close the substream ... */ diff --git a/camel/camel-service.c b/camel/camel-service.c index b767db5..c385b04 100644 --- a/camel/camel-service.c +++ b/camel/camel-service.c @@ -59,7 +59,8 @@ service_finalize (GObject *object) CamelService *service = CAMEL_SERVICE (object); if (service->status == CAMEL_SERVICE_CONNECTED) - CAMEL_SERVICE_GET_CLASS (service)->disconnect (service, TRUE, NULL); + CAMEL_SERVICE_GET_CLASS (service)->disconnect ( + service, TRUE, NULL, NULL); if (service->url) camel_url_free (service->url); @@ -118,6 +119,7 @@ fail: static gboolean service_connect (CamelService *service, + GCancellable *cancellable, GError **error) { /* Things like the CamelMboxStore can validly @@ -128,6 +130,7 @@ service_connect (CamelService *service, static gboolean service_disconnect (CamelService *service, gboolean clean, + GCancellable *cancellable, GError **error) { /* We let people get away with not having a disconnect @@ -138,11 +141,12 @@ service_disconnect (CamelService *service, static void service_cancel_connect (CamelService *service) { - camel_operation_cancel (service->connect_op); + g_cancellable_cancel (service->connect_op); } static GList * service_query_auth_types (CamelService *service, + GCancellable *cancellable, GError **error) { return NULL; @@ -293,8 +297,6 @@ camel_service_connect (CamelService *service, { CamelServiceClass *class; gboolean ret = FALSE; - gboolean unreg = FALSE; - CamelOperation *connect_op; g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE); g_return_val_if_fail (service->session != NULL, FALSE); @@ -313,28 +315,17 @@ camel_service_connect (CamelService *service, /* Register a separate operation for connecting, so that * the offline code can cancel it. */ camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK); - service->connect_op = camel_operation_registered (); - if (!service->connect_op) { - service->connect_op = camel_operation_new (); - camel_operation_register (service->connect_op); - unreg = TRUE; - } - connect_op = service->connect_op; + service->connect_op = (GCancellable *) camel_operation_new (); camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK); service->status = CAMEL_SERVICE_CONNECTING; - ret = class->connect (service, error); + ret = class->connect (service, service->connect_op, error); CAMEL_CHECK_GERROR (service, connect, ret, error); service->status = ret ? CAMEL_SERVICE_CONNECTED : CAMEL_SERVICE_DISCONNECTED; camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK); - if (connect_op) { - if (unreg && service->connect_op) - camel_operation_unregister (); - - g_object_unref (connect_op); - service->connect_op = NULL; - } + g_object_unref (service->connect_op); + service->connect_op = NULL; camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK); camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); @@ -360,7 +351,6 @@ camel_service_disconnect (CamelService *service, { CamelServiceClass *class; gboolean res = TRUE; - gint unreg = FALSE; g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE); @@ -372,23 +362,16 @@ camel_service_disconnect (CamelService *service, if (service->status != CAMEL_SERVICE_DISCONNECTED && service->status != CAMEL_SERVICE_DISCONNECTING) { camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK); - service->connect_op = camel_operation_registered (); - if (!service->connect_op) { - service->connect_op = camel_operation_new (); - camel_operation_register (service->connect_op); - unreg = TRUE; - } + service->connect_op = (GCancellable *) camel_operation_new (); camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK); service->status = CAMEL_SERVICE_DISCONNECTING; - res = class->disconnect (service, clean, error); + res = class->disconnect ( + service, clean, service->connect_op, error); CAMEL_CHECK_GERROR (service, disconnect, res, error); service->status = CAMEL_SERVICE_DISCONNECTED; camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK); - if (unreg) - camel_operation_unregister (); - g_object_unref (service->connect_op); service->connect_op = NULL; camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK); @@ -531,6 +514,7 @@ camel_service_get_provider (CamelService *service) /** * camel_service_query_auth_types: * @service: a #CamelService object + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * This is used by the mail source wizard to get the list of @@ -542,6 +526,7 @@ camel_service_get_provider (CamelService *service) **/ GList * camel_service_query_auth_types (CamelService *service, + GCancellable *cancellable, GError **error) { CamelServiceClass *class; @@ -555,7 +540,7 @@ camel_service_query_auth_types (CamelService *service, /* Note that we get the connect lock here, which means the * callee must not call the connect functions itself. */ camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); - ret = class->query_auth_types (service, error); + ret = class->query_auth_types (service, cancellable, error); camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return ret; diff --git a/camel/camel-service.h b/camel/camel-service.h index d1efa89..c500bed 100644 --- a/camel/camel-service.h +++ b/camel/camel-service.h @@ -106,7 +106,7 @@ struct _CamelService { struct _CamelSession *session; CamelProvider *provider; CamelServiceConnectionStatus status; - CamelOperation *connect_op; + GCancellable *connect_op; CamelURL *url; }; @@ -119,12 +119,15 @@ struct _CamelServiceClass { CamelURL *url, GError **error); gboolean (*connect) (CamelService *service, + GCancellable *cancellable, GError **error); gboolean (*disconnect) (CamelService *service, gboolean clean, + GCancellable *cancellable, GError **error); void (*cancel_connect) (CamelService *service); GList * (*query_auth_types) (CamelService *service, + GCancellable *cancellable, GError **error); gchar * (*get_name) (CamelService *service, gboolean brief); @@ -161,6 +164,7 @@ struct _CamelSession * camel_service_get_session (CamelService *service); CamelProvider * camel_service_get_provider (CamelService *service); GList * camel_service_query_auth_types (CamelService *service, + GCancellable *cancellable, GError **error); void camel_service_lock (CamelService *service, CamelServiceLock lock); diff --git a/camel/camel-session.c b/camel/camel-session.c index 8a08fbe..abf297d 100644 --- a/camel/camel-session.c +++ b/camel/camel-session.c @@ -83,7 +83,7 @@ enum { G_DEFINE_TYPE (CamelSession, camel_session, CAMEL_TYPE_OBJECT) static void -cs_thread_status (CamelOperation *op, +cs_thread_status (CamelOperation *operation, const gchar *what, gint pc, CamelSessionThreadMsg *msg) @@ -276,15 +276,16 @@ session_thread_msg_new (CamelSession *session, m = g_malloc0 (size); m->ops = ops; m->session = g_object_ref (session); - m->op = camel_operation_new (); - g_signal_connect ( - m->op, "status", - G_CALLBACK (cs_thread_status), m); + m->cancellable = (GCancellable *) camel_operation_new (); camel_session_lock (session, CAMEL_SESSION_THREAD_LOCK); m->id = session->priv->thread_id++; g_hash_table_insert (session->priv->thread_active, GINT_TO_POINTER (m->id), m); camel_session_unlock (session, CAMEL_SESSION_THREAD_LOCK); + g_signal_connect ( + m->cancellable, "status", + G_CALLBACK (cs_thread_status), m); + return m; } @@ -305,8 +306,8 @@ session_thread_msg_free (CamelSession *session, if (msg->ops->free) msg->ops->free (session, msg); - if (msg->op) - g_object_unref (msg->op); + if (msg->cancellable) + g_object_unref (msg->cancellable); g_clear_error (&msg->error); g_object_unref (msg->session); g_free (msg); @@ -316,13 +317,8 @@ static void session_thread_proxy (CamelSessionThreadMsg *msg, CamelSession *session) { - if (msg->ops->receive) { - CamelOperation *oldop; - - oldop = camel_operation_register (msg->op); + if (msg->ops->receive) msg->ops->receive (session, msg); - camel_operation_register (oldop); - } camel_session_thread_msg_free (session, msg); } diff --git a/camel/camel-session.h b/camel/camel-session.h index 5b4c032..59893fa 100644 --- a/camel/camel-session.h +++ b/camel/camel-session.h @@ -226,7 +226,7 @@ struct _CamelSessionThreadMsg { GError *error; CamelSessionThreadOps *ops; - CamelOperation *op; + GCancellable *cancellable; CamelSession *session; gpointer data; /* Free for implementation to define, not diff --git a/camel/camel-smime-context.c b/camel/camel-smime-context.c index fdb35ff..98b0466 100644 --- a/camel/camel-smime-context.c +++ b/camel/camel-smime-context.c @@ -97,7 +97,7 @@ smime_cert_data_clone (gpointer cert_data) static void sm_write_stream (gpointer arg, const gchar *buf, gulong len) { - camel_stream_write ((CamelStream *)arg, buf, len, NULL); + camel_stream_write ((CamelStream *)arg, buf, len, NULL, NULL); } static PK11SymKey * @@ -529,6 +529,7 @@ static CamelCipherValidity * sm_verify_cmsg (CamelCipherContext *context, NSSCMSMessage *cmsg, CamelStream *extstream, + GCancellable *cancellable, GError **error) { CamelSMIMEContextPrivate *p = ((CamelSMIMEContext *)context)->priv; @@ -587,7 +588,7 @@ sm_verify_cmsg (CamelCipherContext *context, buffer = g_byte_array_new (); mem = camel_stream_mem_new_with_byte_array (buffer); - camel_stream_write_to_stream (extstream, mem, NULL); + camel_stream_write_to_stream (extstream, mem, cancellable, NULL); NSS_CMSDigestContext_Update (digcx, buffer->data, buffer->len); g_object_unref (mem); @@ -764,6 +765,7 @@ smime_context_sign (CamelCipherContext *context, CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -816,7 +818,7 @@ smime_context_sign (CamelCipherContext *context, ipart, CAMEL_MIME_FILTER_CANON_STRIP | CAMEL_MIME_FILTER_CANON_CRLF | CAMEL_MIME_FILTER_CANON_FROM, - istream, error) == -1) { + istream, cancellable, error) == -1) { g_prefix_error ( error, _("Could not generate signing data: ")); goto fail; @@ -848,7 +850,7 @@ smime_context_sign (CamelCipherContext *context, dw = camel_data_wrapper_new (); camel_stream_reset (ostream, NULL); - camel_data_wrapper_construct_from_stream (dw, ostream, NULL); + camel_data_wrapper_construct_from_stream (dw, ostream, cancellable, NULL); dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY; if (((CamelSMIMEContext *)context)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN) { @@ -907,6 +909,7 @@ fail: static CamelCipherValidity * smime_context_verify (CamelCipherContext *context, CamelMimePart *ipart, + GCancellable *cancellable, GError **error) { CamelCipherContextClass *class; @@ -974,7 +977,8 @@ smime_context_verify (CamelCipherContext *context, NULL, NULL); /* decrypt key callback */ camel_data_wrapper_decode_to_stream ( - camel_medium_get_content (CAMEL_MEDIUM (sigpart)), mem, NULL); + camel_medium_get_content ( + CAMEL_MEDIUM (sigpart)), mem, cancellable, NULL); (void)NSS_CMSDecoder_Update (dec, (gchar *) buffer->data, buffer->len); cmsg = NSS_CMSDecoder_Finish (dec); if (cmsg == NULL) { @@ -982,7 +986,7 @@ smime_context_verify (CamelCipherContext *context, goto fail; } - valid = sm_verify_cmsg (context, cmsg, constream, error); + valid = sm_verify_cmsg (context, cmsg, constream, cancellable, error); NSS_CMSMessage_Destroy (cmsg); fail: @@ -999,6 +1003,7 @@ smime_context_encrypt (CamelCipherContext *context, GPtrArray *recipients, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { CamelSMIMEContextPrivate *p = ((CamelSMIMEContext *)context)->priv; @@ -1118,7 +1123,7 @@ smime_context_encrypt (CamelCipherContext *context, /* FIXME: Stream the input */ buffer = g_byte_array_new (); mem = camel_stream_mem_new_with_byte_array (buffer); - camel_cipher_canonical_to_stream (ipart, CAMEL_MIME_FILTER_CANON_CRLF, mem, NULL); + camel_cipher_canonical_to_stream (ipart, CAMEL_MIME_FILTER_CANON_CRLF, mem, NULL, NULL); if (NSS_CMSEncoder_Update (enc, (gchar *) buffer->data, buffer->len) != SECSuccess) { NSS_CMSEncoder_Cancel (enc); g_object_unref (mem); @@ -1139,7 +1144,7 @@ smime_context_encrypt (CamelCipherContext *context, PORT_FreeArena (poolp, PR_FALSE); dw = camel_data_wrapper_new (); - camel_data_wrapper_construct_from_stream (dw, ostream, NULL); + camel_data_wrapper_construct_from_stream (dw, ostream, NULL, NULL); g_object_unref (ostream); dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY; @@ -1181,6 +1186,7 @@ static CamelCipherValidity * smime_context_decrypt (CamelCipherContext *context, CamelMimePart *ipart, CamelMimePart *opart, + GCancellable *cancellable, GError **error) { NSSCMSDecoderContext *dec; @@ -1200,7 +1206,8 @@ smime_context_decrypt (CamelCipherContext *context, buffer = g_byte_array_new (); istream = camel_stream_mem_new_with_byte_array (buffer); camel_data_wrapper_decode_to_stream ( - camel_medium_get_content ((CamelMedium *)ipart), istream, NULL); + camel_medium_get_content (CAMEL_MEDIUM (ipart)), + istream, NULL, NULL); camel_stream_reset (istream, NULL); dec = NSS_CMSDecoder_Start (NULL, @@ -1231,11 +1238,12 @@ smime_context_decrypt (CamelCipherContext *context, #endif camel_stream_reset (ostream, NULL); - camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)opart, ostream, NULL); + camel_data_wrapper_construct_from_stream ( + CAMEL_DATA_WRAPPER (opart), ostream, NULL, NULL); if (NSS_CMSMessage_IsSigned (cmsg)) { camel_stream_reset (ostream, NULL); - valid = sm_verify_cmsg (context, cmsg, ostream, error); + valid = sm_verify_cmsg (context, cmsg, ostream, cancellable, error); } else { valid = camel_cipher_validity_new (); valid->encrypt.description = g_strdup (_("Encrypted content")); @@ -1344,7 +1352,7 @@ camel_smime_context_describe_part (CamelSMIMEContext *context, CamelMimePart *pa istream = camel_stream_mem_new_with_byte_array (buffer); camel_data_wrapper_decode_to_stream ( camel_medium_get_content ((CamelMedium *)part), - istream, NULL); + istream, NULL, NULL); camel_stream_reset (istream, NULL); dec = NSS_CMSDecoder_Start (NULL, diff --git a/camel/camel-store.c b/camel/camel-store.c index 8faf761..dfd598e 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -214,6 +214,7 @@ store_construct (CamelService *service, static CamelFolder * store_get_inbox (CamelStore *store, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -221,7 +222,7 @@ store_get_inbox (CamelStore *store, /* Assume the inbox's name is "inbox" and open with default flags. */ class = CAMEL_STORE_GET_CLASS (store); - folder = class->get_folder (store, "inbox", 0, error); + folder = class->get_folder (store, "inbox", 0, cancellable, error); CAMEL_CHECK_GERROR (store, get_folder, folder != NULL, error); return folder; @@ -229,6 +230,7 @@ store_get_inbox (CamelStore *store, static CamelFolder * store_get_trash (CamelStore *store, + GCancellable *cancellable, GError **error) { return store_get_special (store, CAMEL_VTRASH_FOLDER_TRASH); @@ -236,6 +238,7 @@ store_get_trash (CamelStore *store, static CamelFolder * store_get_junk (CamelStore *store, + GCancellable *cancellable, GError **error) { return store_get_special (store, CAMEL_VTRASH_FOLDER_JUNK); @@ -244,6 +247,7 @@ store_get_junk (CamelStore *store, static gboolean store_sync (CamelStore *store, gint expunge, + GCancellable *cancellable, GError **error) { GPtrArray *folders; @@ -263,7 +267,8 @@ store_sync (CamelStore *store, folder = folders->pdata[i]; if (!CAMEL_IS_VEE_FOLDER (folder) && local_error == NULL) { - camel_folder_sync (folder, expunge, &local_error); + camel_folder_sync ( + folder, expunge, cancellable, &local_error); ignore_no_such_table_exception (&local_error); } else if (CAMEL_IS_VEE_FOLDER (folder)) camel_vee_folder_sync_headers (folder, NULL); /* Literally don't care of vfolder exceptions */ @@ -282,6 +287,7 @@ store_sync (CamelStore *store, static gboolean store_noop (CamelStore *store, + GCancellable *cancellable, GError **error) { return TRUE; @@ -411,6 +417,7 @@ camel_store_error_quark (void) * @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. @@ -421,6 +428,7 @@ CamelFolder * camel_store_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -465,14 +473,15 @@ camel_store_get_folder (CamelStore *store, } } - if ((store->flags & CAMEL_STORE_VTRASH) && strcmp (folder_name, CAMEL_VTRASH_NAME) == 0) { - folder = class->get_trash (store, error); + if ((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0) { + folder = class->get_trash (store, cancellable, error); CAMEL_CHECK_GERROR (store, get_trash, folder != NULL, error); - } else if ((store->flags & CAMEL_STORE_VJUNK) && strcmp (folder_name, CAMEL_VJUNK_NAME) == 0) { - folder = class->get_junk (store, error); + } else if ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0) { + folder = class->get_junk (store, cancellable, error); CAMEL_CHECK_GERROR (store, get_junk, folder != NULL, error); } else { - folder = class->get_folder (store, folder_name, flags, error); + folder = class->get_folder ( + store, folder_name, flags, cancellable, error); CAMEL_CHECK_GERROR (store, get_folder, folder != NULL, error); if (folder) { @@ -511,6 +520,7 @@ camel_store_get_folder (CamelStore *store, * @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. @@ -523,6 +533,7 @@ CamelFolderInfo * camel_store_create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -546,8 +557,11 @@ camel_store_create_folder (CamelStore *store, } camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK); - fi = class->create_folder (store, parent_name, folder_name, error); + + fi = class->create_folder ( + store, parent_name, folder_name, cancellable, error); CAMEL_CHECK_GERROR (store, create_folder, fi != NULL, error); + camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK); return fi; @@ -555,7 +569,8 @@ camel_store_create_folder (CamelStore *store, /* deletes folder/removes it from the folder cache, if it's there */ static void -cs_delete_cached_folder (CamelStore *store, const gchar *folder_name) +cs_delete_cached_folder (CamelStore *store, + const gchar *folder_name) { CamelFolder *folder; @@ -564,14 +579,14 @@ cs_delete_cached_folder (CamelStore *store, const gchar *folder_name) CamelVeeFolder *vfolder; if ((store->flags & CAMEL_STORE_VTRASH) - && (vfolder = camel_object_bag_get (store->folders, CAMEL_VTRASH_NAME))) { + && (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); + && (vfolder = camel_object_bag_get(store->folders, CAMEL_VJUNK_NAME))) { + camel_vee_folder_remove_folder(vfolder, folder); g_object_unref (vfolder); } @@ -586,6 +601,7 @@ cs_delete_cached_folder (CamelStore *store, const gchar *folder_name) * camel_store_delete_folder: * @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. @@ -595,6 +611,7 @@ cs_delete_cached_folder (CamelStore *store, const gchar *folder_name) gboolean camel_store_delete_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -620,7 +637,8 @@ camel_store_delete_folder (CamelStore *store, camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK); - success = class->delete_folder (store, folder_name, &local_error); + success = class->delete_folder ( + store, folder_name, cancellable, &local_error); CAMEL_CHECK_GERROR (store, delete_folder, success, &local_error); /* ignore 'no such table' errors */ @@ -629,7 +647,7 @@ camel_store_delete_folder (CamelStore *store, g_clear_error (&local_error); if (local_error == NULL) - cs_delete_cached_folder (store, folder_name); + cs_delete_cached_folder(store, folder_name); else g_propagate_error (error, local_error); @@ -643,6 +661,7 @@ camel_store_delete_folder (CamelStore *store, * @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. @@ -653,6 +672,7 @@ gboolean camel_store_rename_folder (CamelStore *store, const gchar *old_namein, const gchar *new_name, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -714,7 +734,8 @@ camel_store_rename_folder (CamelStore *store, } /* Now try the real rename (will emit renamed signal) */ - success = class->rename_folder (store, old_name, new_name, error); + success = class->rename_folder ( + store, old_name, new_name, cancellable, error); CAMEL_CHECK_GERROR (store, rename_folder, success, error); /* If it worked, update all open folders/unlock them */ @@ -743,7 +764,8 @@ camel_store_rename_folder (CamelStore *store, if (store->flags & CAMEL_STORE_SUBSCRIPTIONS) flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED; - folder_info = class->get_folder_info (store, new_name, flags, error); + folder_info = class->get_folder_info ( + store, new_name, flags, cancellable, error); CAMEL_CHECK_GERROR (store, get_folder_info, folder_info != NULL, error); if (folder_info != NULL) { @@ -879,6 +901,7 @@ camel_store_folder_unsubscribed (CamelStore *store, /** * camel_store_get_inbox: * @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, @@ -886,6 +909,7 @@ camel_store_folder_unsubscribed (CamelStore *store, **/ CamelFolder * camel_store_get_inbox (CamelStore *store, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -898,7 +922,7 @@ camel_store_get_inbox (CamelStore *store, camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK); - folder = class->get_inbox (store, error); + folder = class->get_inbox (store, cancellable, error); CAMEL_CHECK_GERROR (store, get_inbox, folder != NULL, error); camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK); @@ -909,6 +933,7 @@ camel_store_get_inbox (CamelStore *store, /** * camel_store_get_trash: * @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 @@ -916,6 +941,7 @@ camel_store_get_inbox (CamelStore *store, **/ CamelFolder * camel_store_get_trash (CamelStore *store, + GCancellable *cancellable, GError **error) { g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); @@ -927,18 +953,20 @@ camel_store_get_trash (CamelStore *store, class = CAMEL_STORE_GET_CLASS (store); g_return_val_if_fail (class->get_trash != NULL, NULL); - folder = class->get_trash (store, error); + folder = class->get_trash (store, cancellable, error); CAMEL_CHECK_GERROR (store, get_trash, folder != NULL, error); return folder; } - return camel_store_get_folder (store, CAMEL_VTRASH_NAME, 0, error); + return camel_store_get_folder ( + store, CAMEL_VTRASH_NAME, 0, cancellable, error); } /** * camel_store_get_junk: * @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 @@ -946,6 +974,7 @@ camel_store_get_trash (CamelStore *store, **/ CamelFolder * camel_store_get_junk (CamelStore *store, + GCancellable *cancellable, GError **error) { g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); @@ -957,19 +986,21 @@ camel_store_get_junk (CamelStore *store, class = CAMEL_STORE_GET_CLASS (store); g_return_val_if_fail (class->get_junk != NULL, NULL); - folder = class->get_junk (store, error); + folder = class->get_junk (store, cancellable, error); CAMEL_CHECK_GERROR (store, get_junk, folder != NULL, error); return folder; } - return camel_store_get_folder (store, CAMEL_VJUNK_NAME, 0, error); + return camel_store_get_folder ( + store, CAMEL_VJUNK_NAME, 0, cancellable, error); } /** * camel_store_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 @@ -980,6 +1011,7 @@ camel_store_get_junk (CamelStore *store, gboolean camel_store_sync (CamelStore *store, gint expunge, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -990,7 +1022,7 @@ camel_store_sync (CamelStore *store, class = CAMEL_STORE_GET_CLASS (store); g_return_val_if_fail (class->sync != NULL, FALSE); - success = class->sync (store, expunge, error); + success = class->sync (store, expunge, cancellable, error); CAMEL_CHECK_GERROR (store, sync, success, error); return success; @@ -1081,20 +1113,21 @@ dump_fi (CamelFolderInfo *fi, gint depth) * @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, + * 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 + * %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 + * %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 + * %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 @@ -1109,6 +1142,7 @@ CamelFolderInfo * camel_store_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -1119,7 +1153,7 @@ camel_store_get_folder_info (CamelStore *store, class = CAMEL_STORE_GET_CLASS (store); g_return_val_if_fail (class->get_folder_info != NULL, NULL); - info = class->get_folder_info (store, top, flags, error); + info = class->get_folder_info (store, top, flags, cancellable, error); if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) CAMEL_CHECK_GERROR (store, get_folder_info, info != NULL, error); @@ -1461,6 +1495,7 @@ camel_store_folder_is_subscribed (CamelStore *store, * camel_store_subscribe_folder: * @store: a #CamelStore object * @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. @@ -1470,6 +1505,7 @@ camel_store_folder_is_subscribed (CamelStore *store, gboolean camel_store_subscribe_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -1484,7 +1520,8 @@ camel_store_subscribe_folder (CamelStore *store, camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK); - success = class->subscribe_folder (store, folder_name, error); + success = class->subscribe_folder ( + store, folder_name, cancellable, error); CAMEL_CHECK_GERROR (store, subscribe_folder, success, error); camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK); @@ -1496,6 +1533,7 @@ camel_store_subscribe_folder (CamelStore *store, * camel_store_unsubscribe_folder: * @store: a #CamelStore object * @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. @@ -1505,6 +1543,7 @@ camel_store_subscribe_folder (CamelStore *store, gboolean camel_store_unsubscribe_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -1519,7 +1558,8 @@ camel_store_unsubscribe_folder (CamelStore *store, camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK); - success = class->unsubscribe_folder (store, folder_name, error); + success = class->unsubscribe_folder ( + store, folder_name, cancellable, error); CAMEL_CHECK_GERROR (store, unsubscribe_folder, success, error); if (success) @@ -1533,6 +1573,7 @@ camel_store_unsubscribe_folder (CamelStore *store, /** * camel_store_noop: * @store: a #CamelStore object + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Pings @store so that its connection doesn't timeout. @@ -1541,6 +1582,7 @@ camel_store_unsubscribe_folder (CamelStore *store, **/ gboolean camel_store_noop (CamelStore *store, + GCancellable *cancellable, GError **error) { CamelStoreClass *class; @@ -1551,7 +1593,7 @@ camel_store_noop (CamelStore *store, class = CAMEL_STORE_GET_CLASS (store); g_return_val_if_fail (class->noop != NULL, FALSE); - success = class->noop (store, error); + success = class->noop (store, cancellable, error); CAMEL_CHECK_GERROR (store, noop, success, error); return success; diff --git a/camel/camel-store.h b/camel/camel-store.h index 2ad2c9d..1d75b6a 100644 --- a/camel/camel-store.h +++ b/camel/camel-store.h @@ -224,32 +224,41 @@ struct _CamelStoreClass { CamelFolder * (*get_folder) (CamelStore *store, const gchar *folder_name, guint32 flags, + GCancellable *cancellable, GError **error); CamelFolder * (*get_inbox) (CamelStore *store, + GCancellable *cancellable, GError **error); CamelFolder * (*get_trash) (CamelStore *store, + GCancellable *cancellable, GError **error); CamelFolder * (*get_junk) (CamelStore *store, + GCancellable *cancellable, GError **error); CamelFolderInfo * (*create_folder) (CamelStore *store, const gchar *parent_name, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean (*delete_folder) (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean (*rename_folder) (CamelStore *store, const gchar *old_name, const gchar *new_name, + GCancellable *cancellable, GError **error); gboolean (*sync) (CamelStore *store, gint expunge, + GCancellable *cancellable, GError **error); CamelFolderInfo * (*get_folder_info) (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error); void (*free_folder_info) (CamelStore *store, CamelFolderInfo *fi); @@ -257,11 +266,14 @@ struct _CamelStoreClass { const gchar *folder_name); gboolean (*subscribe_folder) (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean (*unsubscribe_folder) (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean (*noop) (CamelStore *store, + GCancellable *cancellable, GError **error); gboolean (*can_refresh_folder) (CamelStore *store, CamelFolderInfo *info, @@ -288,24 +300,31 @@ GQuark camel_store_error_quark (void) G_GNUC_CONST; CamelFolder * camel_store_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, + GCancellable *cancellable, GError **error); CamelFolder * camel_store_get_inbox (CamelStore *store, + GCancellable *cancellable, GError **error); CamelFolder * camel_store_get_trash (CamelStore *store, + GCancellable *cancellable, GError **error); CamelFolder * camel_store_get_junk (CamelStore *store, + GCancellable *cancellable, GError **error); CamelFolderInfo * camel_store_create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean camel_store_delete_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean camel_store_rename_folder (CamelStore *store, const gchar *old_namein, const gchar *new_name, + GCancellable *cancellable, GError **error); void camel_store_folder_created (CamelStore *store, CamelFolderInfo *info); @@ -320,11 +339,13 @@ void camel_store_folder_unsubscribed (CamelStore *store, CamelFolderInfo *info); gboolean camel_store_sync (CamelStore *store, gint expunge, + GCancellable *cancellable, GError **error); CamelFolderInfo * camel_store_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error); void camel_store_free_folder_info (CamelStore *store, CamelFolderInfo *fi); @@ -351,11 +372,14 @@ gboolean camel_store_folder_is_subscribed (CamelStore *store, const gchar *folder_name); gboolean camel_store_subscribe_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean camel_store_unsubscribe_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean camel_store_noop (CamelStore *store, + GCancellable *cancellable, GError **error); gint camel_store_folder_uri_equal (CamelStore *store, const gchar *uri0, diff --git a/camel/camel-stream-buffer.c b/camel/camel-stream-buffer.c index 7448fe4..1b858b5 100644 --- a/camel/camel-stream-buffer.c +++ b/camel/camel-stream-buffer.c @@ -64,12 +64,14 @@ static gssize stream_write_all (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { gsize left = n, w; while (left > 0) { - w = camel_stream_write (stream, buffer, left, error); + w = camel_stream_write ( + stream, buffer, left, cancellable, error); if (w == -1) return -1; left -= w; @@ -142,6 +144,7 @@ static gssize stream_buffer_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamBufferPrivate *priv; @@ -168,15 +171,16 @@ stream_buffer_read (CamelStream *stream, /* if we are reading a lot, then read directly to the destination buffer */ if (n >= priv->size/3) { bytes_read = camel_stream_read ( - priv->stream, bptr, n, &local_error); + priv->stream, bptr, n, + cancellable, &local_error); if (bytes_read>0) { n -= bytes_read; bptr += bytes_read; } } else { bytes_read = camel_stream_read ( - priv->stream, (gchar *) - priv->buf, priv->size, &local_error); + priv->stream, (gchar *) priv->buf, + priv->size, cancellable, &local_error); if (bytes_read>0) { gsize bytes_used = bytes_read > n ? n : bytes_read; priv->ptr = priv->buf; @@ -214,6 +218,7 @@ static gssize stream_buffer_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamBufferPrivate *priv; @@ -239,7 +244,7 @@ stream_buffer_write (CamelStream *stream, if (left == todo) { if (stream_write_all ( priv->stream, (gchar *) priv->buf, - priv->size, error) == -1) + priv->size, cancellable, error) == -1) return -1; priv->ptr = priv->buf; @@ -249,7 +254,8 @@ stream_buffer_write (CamelStream *stream, if (n > 0) { if (n >= priv->size/3) { if (stream_write_all ( - priv->stream, buffer, n, error) == -1) + priv->stream, buffer, n, + cancellable, error) == -1) return -1; } else { memcpy (priv->ptr, buffer, n); @@ -262,6 +268,7 @@ stream_buffer_write (CamelStream *stream, static gint stream_buffer_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamBufferPrivate *priv; @@ -272,7 +279,8 @@ stream_buffer_flush (CamelStream *stream, gsize len = priv->ptr - priv->buf; if (camel_stream_write ( - priv->stream, (gchar *) priv->buf, len, error) == -1) + priv->stream, (gchar *) priv->buf, + len, cancellable, error) == -1) return -1; priv->ptr = priv->buf; @@ -280,21 +288,22 @@ stream_buffer_flush (CamelStream *stream, /* nothing to do for read mode 'flush' */ } - return camel_stream_flush (priv->stream, error); + return camel_stream_flush (priv->stream, cancellable, error); } static gint stream_buffer_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamBufferPrivate *priv; priv = CAMEL_STREAM_BUFFER_GET_PRIVATE (stream); - if (stream_buffer_flush (stream, error) == -1) + if (stream_buffer_flush (stream, cancellable, error) == -1) return -1; - return camel_stream_close (priv->stream, error); + return camel_stream_close (priv->stream, cancellable, error); } static gboolean @@ -470,6 +479,7 @@ camel_stream_buffer_new_with_vbuf (CamelStream *stream, * @sbf: a #CamelStreamBuffer object * @buf: Memory to write the string to. * @max: Maxmimum number of characters to store. + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Read a line of characters up to the next newline character or @@ -485,6 +495,7 @@ gint camel_stream_buffer_gets (CamelStreamBuffer *sbf, gchar *buf, guint max, + GCancellable *cancellable, GError **error) { register gchar *outptr, *inptr, *inend, c, *outend; @@ -509,8 +520,8 @@ camel_stream_buffer_gets (CamelStreamBuffer *sbf, break; bytes_read = camel_stream_read ( - sbf->priv->stream, (gchar *) - sbf->priv->buf, sbf->priv->size, error); + sbf->priv->stream, (gchar *) sbf->priv->buf, + sbf->priv->size, cancellable, error); if (bytes_read == -1) { if (buf == outptr) return -1; @@ -532,6 +543,7 @@ camel_stream_buffer_gets (CamelStreamBuffer *sbf, /** * camel_stream_buffer_read_line: * @sbf: a #CamelStreamBuffer object + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a @GError, or %NULL * * This function reads a complete newline-terminated line from the stream @@ -543,6 +555,7 @@ camel_stream_buffer_gets (CamelStreamBuffer *sbf, **/ gchar * camel_stream_buffer_read_line (CamelStreamBuffer *sbf, + GCancellable *cancellable, GError **error) { guchar *p; @@ -553,7 +566,7 @@ camel_stream_buffer_read_line (CamelStreamBuffer *sbf, while (1) { nread = camel_stream_buffer_gets ( sbf, (gchar *) p, sbf->priv->linesize - - (p - sbf->priv->linebuf), error); + (p - sbf->priv->linebuf), cancellable, error); if (nread <=0) { if (p > sbf->priv->linebuf) break; diff --git a/camel/camel-stream-buffer.h b/camel/camel-stream-buffer.h index c1d82d6..62c23a7 100644 --- a/camel/camel-stream-buffer.h +++ b/camel/camel-stream-buffer.h @@ -95,8 +95,10 @@ CamelStream * camel_stream_buffer_new_with_vbuf gint camel_stream_buffer_gets (CamelStreamBuffer *sbf, gchar *buf, guint max, + GCancellable *cancellable, GError **error); gchar * camel_stream_buffer_read_line (CamelStreamBuffer *sbf, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/camel/camel-stream-filter.c b/camel/camel-stream-filter.c index e282323..0a67e8d 100644 --- a/camel/camel-stream-filter.c +++ b/camel/camel-stream-filter.c @@ -92,6 +92,7 @@ static gssize stream_filter_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamFilterPrivate *priv; @@ -108,7 +109,8 @@ stream_filter_read (CamelStream *stream, gsize presize = READ_PAD; size = camel_stream_read ( - priv->source, priv->buffer, READ_SIZE, error); + priv->source, priv->buffer, + READ_SIZE, cancellable, error); if (size <= 0) { /* this is somewhat untested */ if (camel_stream_eos (priv->source)) { @@ -168,6 +170,7 @@ static gssize stream_filter_write (CamelStream *stream, const gchar *buf, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamFilterPrivate *priv; @@ -207,7 +210,7 @@ stream_filter_write (CamelStream *stream, f = f->next; } - if (camel_stream_write (priv->source, buffer, len, error) != len) + if (camel_stream_write (priv->source, buffer, len, cancellable, error) != len) return -1; } @@ -218,6 +221,7 @@ stream_filter_write (CamelStream *stream, static gint stream_filter_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamFilterPrivate *priv; @@ -250,14 +254,15 @@ stream_filter_flush (CamelStream *stream, f = f->next; } - if (len > 0 && camel_stream_write (priv->source, buffer, len, error) == -1) + if (len > 0 && camel_stream_write (priv->source, buffer, len, cancellable, error) == -1) return -1; - return camel_stream_flush (priv->source, error); + return camel_stream_flush (priv->source, cancellable, error); } static gint stream_filter_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamFilterPrivate *priv; @@ -266,9 +271,9 @@ stream_filter_close (CamelStream *stream, /* Ignore errors while flushing. */ if (!priv->last_was_read) - stream_filter_flush (stream, NULL); + stream_filter_flush (stream, cancellable, NULL); - return camel_stream_close (priv->source, error); + return camel_stream_close (priv->source, cancellable, error); } static gboolean diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c index cea4758..1c577c7 100644 --- a/camel/camel-stream-fs.c +++ b/camel/camel-stream-fs.c @@ -67,6 +67,7 @@ static gssize stream_fs_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamFsPrivate *priv; @@ -79,7 +80,9 @@ stream_fs_read (CamelStream *stream, if (seekable->bound_end != CAMEL_STREAM_UNBOUND) n = MIN (seekable->bound_end - seekable->position, n); - if ((nread = camel_read (priv->fd, buffer, n, error)) > 0) + nread = camel_read (priv->fd, buffer, n, cancellable, error); + + if (nread > 0) seekable->position += nread; else if (nread == 0) stream->eos = TRUE; @@ -91,6 +94,7 @@ static gssize stream_fs_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamFsPrivate *priv; @@ -103,7 +107,9 @@ stream_fs_write (CamelStream *stream, if (seekable->bound_end != CAMEL_STREAM_UNBOUND) n = MIN (seekable->bound_end - seekable->position, n); - if ((nwritten = camel_write (priv->fd, buffer, n, error)) > 0) + nwritten = camel_write (priv->fd, buffer, n, cancellable, error); + + if (nwritten > 0) seekable->position += nwritten; return nwritten; @@ -111,6 +117,7 @@ stream_fs_write (CamelStream *stream, static gint stream_fs_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamFsPrivate *priv; @@ -130,6 +137,7 @@ stream_fs_flush (CamelStream *stream, static gint stream_fs_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamFsPrivate *priv; diff --git a/camel/camel-stream-mem.c b/camel/camel-stream-mem.c index 1649fe4..4ac97dd 100644 --- a/camel/camel-stream-mem.c +++ b/camel/camel-stream-mem.c @@ -89,6 +89,7 @@ static gssize stream_mem_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamMemPrivate *priv; @@ -114,6 +115,7 @@ static gssize stream_mem_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamMemPrivate *priv; diff --git a/camel/camel-stream-null.c b/camel/camel-stream-null.c index 0050744..6e208a6 100644 --- a/camel/camel-stream-null.c +++ b/camel/camel-stream-null.c @@ -34,6 +34,7 @@ static gssize stream_null_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CAMEL_STREAM_NULL (stream)->written += n; diff --git a/camel/camel-stream-process.c b/camel/camel-stream-process.c index b4880ba..2f699da 100644 --- a/camel/camel-stream-process.c +++ b/camel/camel-stream-process.c @@ -51,7 +51,7 @@ stream_process_finalize (GObject *object) { /* Ensure we clean up after ourselves -- kill the child process and reap it. */ - camel_stream_close (CAMEL_STREAM (object), NULL); + camel_stream_close (CAMEL_STREAM (object), NULL, NULL); /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (camel_stream_process_parent_class)->finalize (object); @@ -61,26 +61,31 @@ static gssize stream_process_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamProcess *stream_process = CAMEL_STREAM_PROCESS (stream); + gint fd = stream_process->sockfd; - return camel_read (stream_process->sockfd, buffer, n, error); + return camel_read (fd, buffer, n, cancellable, error); } static gssize stream_process_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamProcess *stream_process = CAMEL_STREAM_PROCESS (stream); + gint fd = stream_process->sockfd; - return camel_write (stream_process->sockfd, buffer, n, error); + return camel_write (fd, buffer, n, cancellable, error); } static gint stream_process_close (CamelStream *object, + GCancellable *cancellable, GError **error) { CamelStreamProcess *stream = CAMEL_STREAM_PROCESS (object); @@ -131,6 +136,7 @@ stream_process_close (CamelStream *object, static gint stream_process_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { return 0; @@ -228,7 +234,7 @@ camel_stream_process_connect (CamelStreamProcess *stream, g_return_val_if_fail (command != NULL, -1); if (stream->sockfd != -1 || stream->childpid) - camel_stream_close (CAMEL_STREAM (stream), NULL); + camel_stream_close (CAMEL_STREAM (stream), NULL, NULL); if (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfds)) return -1; diff --git a/camel/camel-stream-vfs.c b/camel/camel-stream-vfs.c index eb46c13..0c2dc69 100644 --- a/camel/camel-stream-vfs.c +++ b/camel/camel-stream-vfs.c @@ -54,6 +54,7 @@ static gssize stream_vfs_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream); @@ -62,7 +63,7 @@ stream_vfs_read (CamelStream *stream, nread = g_input_stream_read ( G_INPUT_STREAM (stream_vfs->stream), - buffer, n, NULL, &local_error); + buffer, n, cancellable, &local_error); if (nread == 0 || local_error != NULL) stream->eos = TRUE; @@ -77,6 +78,7 @@ static gssize stream_vfs_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream); @@ -85,26 +87,28 @@ stream_vfs_write (CamelStream *stream, success = g_output_stream_write_all ( G_OUTPUT_STREAM (stream_vfs->stream), - buffer, n, &bytes_written, NULL, error); + buffer, n, &bytes_written, cancellable, error); return success ? bytes_written : -1; } static gint stream_vfs_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream); gboolean success; success = g_output_stream_flush ( - G_OUTPUT_STREAM (stream_vfs->stream), NULL, error); + G_OUTPUT_STREAM (stream_vfs->stream), cancellable, error); return success ? 0 : -1; } static gint stream_vfs_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream); @@ -112,10 +116,12 @@ stream_vfs_close (CamelStream *stream, if (G_IS_OUTPUT_STREAM (stream_vfs->stream)) success = g_output_stream_close ( - G_OUTPUT_STREAM (stream_vfs->stream), NULL, error); + G_OUTPUT_STREAM (stream_vfs->stream), + cancellable, error); else success = g_input_stream_close ( - G_INPUT_STREAM (stream_vfs->stream), NULL, error); + G_INPUT_STREAM (stream_vfs->stream), + cancellable, error); if (success) { g_object_unref (stream_vfs->stream); diff --git a/camel/camel-stream.c b/camel/camel-stream.c index 38848b4..c649b26 100644 --- a/camel/camel-stream.c +++ b/camel/camel-stream.c @@ -38,6 +38,7 @@ static gssize stream_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { return 0; @@ -47,6 +48,7 @@ static gssize stream_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { return n; @@ -54,6 +56,7 @@ stream_write (CamelStream *stream, static gint stream_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { return 0; @@ -61,6 +64,7 @@ stream_close (CamelStream *stream, static gint stream_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { return 0; @@ -100,6 +104,7 @@ camel_stream_init (CamelStream *stream) * @stream: a #CamelStream object. * @buffer: output buffer * @n: max number of bytes to read. + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Attempts to read up to @len bytes from @stream into @buf. @@ -111,6 +116,7 @@ gssize camel_stream_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamClass *class; @@ -122,7 +128,7 @@ camel_stream_read (CamelStream *stream, class = CAMEL_STREAM_GET_CLASS (stream); g_return_val_if_fail (class->read != NULL, -1); - n_bytes = class->read (stream, buffer, n, error); + n_bytes = class->read (stream, buffer, n, cancellable, error); CAMEL_CHECK_GERROR (stream, read, n_bytes >= 0, error); return n_bytes; @@ -133,6 +139,7 @@ camel_stream_read (CamelStream *stream, * @stream: a #CamelStream object * @buffer: buffer to write. * @n: number of bytes to write + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Attempts to write up to @n bytes of @buffer into @stream. @@ -144,6 +151,7 @@ gssize camel_stream_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelStreamClass *class; @@ -155,7 +163,7 @@ camel_stream_write (CamelStream *stream, class = CAMEL_STREAM_GET_CLASS (stream); g_return_val_if_fail (class->write != NULL, -1); - n_bytes = class->write (stream, buffer, n, error); + n_bytes = class->write (stream, buffer, n, cancellable, error); CAMEL_CHECK_GERROR (stream, write, n_bytes >= 0, error); return n_bytes; @@ -164,6 +172,7 @@ camel_stream_write (CamelStream *stream, /** * camel_stream_flush: * @stream: a #CamelStream object + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Flushes any buffered data to the stream's backing store. Only @@ -173,6 +182,7 @@ camel_stream_write (CamelStream *stream, **/ gint camel_stream_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamClass *class; @@ -183,7 +193,7 @@ camel_stream_flush (CamelStream *stream, class = CAMEL_STREAM_GET_CLASS (stream); g_return_val_if_fail (class->flush != NULL, -1); - retval = class->flush (stream, error); + retval = class->flush (stream, cancellable, error); CAMEL_CHECK_GERROR (stream, flush, retval == 0, error); return retval; @@ -192,6 +202,7 @@ camel_stream_flush (CamelStream *stream, /** * camel_stream_close: * @stream: a #CamelStream object + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Closes the stream. @@ -200,6 +211,7 @@ camel_stream_flush (CamelStream *stream, **/ gint camel_stream_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelStreamClass *class; @@ -210,7 +222,7 @@ camel_stream_close (CamelStream *stream, class = CAMEL_STREAM_GET_CLASS (stream); g_return_val_if_fail (class->close != NULL, -1); - retval = class->close (stream, error); + retval = class->close (stream, cancellable, error); CAMEL_CHECK_GERROR (stream, close, retval == 0, error); return retval; @@ -281,12 +293,14 @@ camel_stream_reset (CamelStream *stream, gssize camel_stream_write_string (CamelStream *stream, const gchar *string, + GCancellable *cancellable, GError **error) { g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); g_return_val_if_fail (string != NULL, -1); - return camel_stream_write (stream, string, strlen (string), error); + return camel_stream_write ( + stream, string, strlen (string), cancellable, error); } /** @@ -307,6 +321,9 @@ camel_stream_printf (CamelStream *stream, gchar *string; gssize ret; + /* XXX This function needs to die. Use a GString to + * assemble formatted output. */ + g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); va_start (args, fmt); @@ -316,7 +333,8 @@ camel_stream_printf (CamelStream *stream, if (string == NULL) return -1; - ret = camel_stream_write (stream, string, strlen (string), NULL); + ret = camel_stream_write ( + stream, string, strlen (string), NULL, NULL); g_free (string); return ret; @@ -326,6 +344,7 @@ camel_stream_printf (CamelStream *stream, * camel_stream_write_to_stream: * @stream: source #CamelStream object * @output_stream: destination #CamelStream object + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Write all of a stream (until eos) into another stream, in a @@ -337,6 +356,7 @@ camel_stream_printf (CamelStream *stream, gssize camel_stream_write_to_stream (CamelStream *stream, CamelStream *output_stream, + GCancellable *cancellable, GError **error) { gchar tmp_buf[4096]; @@ -349,7 +369,8 @@ camel_stream_write_to_stream (CamelStream *stream, while (!camel_stream_eos (stream)) { nb_read = camel_stream_read ( - stream, tmp_buf, sizeof (tmp_buf), error); + stream, tmp_buf, sizeof (tmp_buf), + cancellable, error); if (nb_read < 0) return -1; else if (nb_read > 0) { @@ -357,8 +378,10 @@ camel_stream_write_to_stream (CamelStream *stream, while (nb_written < nb_read) { gssize len = camel_stream_write ( - output_stream, tmp_buf + nb_written, - nb_read - nb_written, error); + output_stream, + tmp_buf + nb_written, + nb_read - nb_written, + cancellable, error); if (len < 0) return -1; nb_written += len; diff --git a/camel/camel-stream.h b/camel/camel-stream.h index 3dac147..6b88919 100644 --- a/camel/camel-stream.h +++ b/camel/camel-stream.h @@ -69,14 +69,18 @@ struct _CamelStreamClass { gssize (*read) (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error); gssize (*write) (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error); gint (*close) (CamelStream *stream, + GCancellable *cancellable, GError **error); gint (*flush) (CamelStream *stream, + GCancellable *cancellable, GError **error); gboolean (*eos) (CamelStream *stream); gint (*reset) (CamelStream *stream, @@ -87,14 +91,18 @@ GType camel_stream_get_type (void); gssize camel_stream_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error); gssize camel_stream_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error); gint camel_stream_flush (CamelStream *stream, + GCancellable *cancellable, GError **error); gint camel_stream_close (CamelStream *stream, + GCancellable *cancellable, GError **error); gboolean camel_stream_eos (CamelStream *stream); gint camel_stream_reset (CamelStream *stream, @@ -103,6 +111,7 @@ gint camel_stream_reset (CamelStream *stream, /* utility macros and funcs */ gssize camel_stream_write_string (CamelStream *stream, const gchar *string, + GCancellable *cancellable, GError **error); gssize camel_stream_printf (CamelStream *stream, const gchar *fmt, @@ -115,6 +124,7 @@ gssize camel_stream_vprintf (CamelStream *stream, * either stream. */ gssize camel_stream_write_to_stream (CamelStream *stream, CamelStream *output_stream, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c index ac5fe96..74de8b9 100644 --- a/camel/camel-tcp-stream-raw.c +++ b/camel/camel-tcp-stream-raw.c @@ -261,18 +261,25 @@ _set_g_error_from_errno (GError **error, gboolean eintr_means_cancelled) } static gssize -read_from_prfd (PRFileDesc *fd, gchar *buffer, gsize n, GError **error) +read_from_prfd (PRFileDesc *fd, + gchar *buffer, + gsize n, + GCancellable *cancellable, + GError **error) { - PRFileDesc *cancel_fd; + PRFileDesc *cancel_fd = NULL; gssize nread; - if (camel_operation_cancel_check (NULL)) { + if (g_cancellable_is_cancelled (cancellable)) { errno = EINTR; _set_g_error_from_errno (error, TRUE); return -1; } - cancel_fd = camel_operation_cancel_prfd (NULL); + if (CAMEL_IS_OPERATION (cancellable)) + cancel_fd = camel_operation_cancel_prfd ( + CAMEL_OPERATION (cancellable)); + if (cancel_fd == NULL) { do { nread = PR_Read (fd, buffer, n); @@ -350,27 +357,35 @@ static gssize tcp_stream_raw_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream); CamelTcpStreamRawPrivate *priv = raw->priv; - return read_from_prfd (priv->sockfd, buffer, n, error); + return read_from_prfd (priv->sockfd, buffer, n, cancellable, error); } static gssize -write_to_prfd (PRFileDesc *fd, const gchar *buffer, gsize n, GError **error) +write_to_prfd (PRFileDesc *fd, + const gchar *buffer, + gsize n, + GCancellable *cancellable, + GError **error) { + PRFileDesc *cancel_fd = NULL; gssize w, written = 0; - PRFileDesc *cancel_fd; - if (camel_operation_cancel_check (NULL)) { + if (g_cancellable_is_cancelled (cancellable)) { errno = EINTR; _set_g_error_from_errno (error, TRUE); return -1; } - cancel_fd = camel_operation_cancel_prfd (NULL); + if (CAMEL_IS_OPERATION (cancellable)) + cancel_fd = camel_operation_cancel_prfd ( + CAMEL_OPERATION (cancellable)); + if (cancel_fd == NULL) { do { do { @@ -457,16 +472,18 @@ static gssize tcp_stream_raw_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream); CamelTcpStreamRawPrivate *priv = raw->priv; - return write_to_prfd (priv->sockfd, buffer, n, error); + return write_to_prfd (priv->sockfd, buffer, n, cancellable, error); } static gint tcp_stream_raw_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { #if 0 @@ -480,6 +497,7 @@ tcp_stream_raw_flush (CamelStream *stream, static gint tcp_stream_raw_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream); @@ -546,10 +564,12 @@ sockaddr_to_praddr (struct sockaddr *s, gint len, PRNetAddr *addr) } static PRFileDesc * -socket_connect (struct addrinfo *host, GError **error) +socket_connect (struct addrinfo *host, + GCancellable *cancellable, + GError **error) { PRNetAddr netaddr; - PRFileDesc *fd, *cancel_fd; + PRFileDesc *fd, *cancel_fd = NULL; if (sockaddr_to_praddr (host->ai_addr, host->ai_addrlen, &netaddr) != 0) { errno = EINVAL; @@ -564,7 +584,9 @@ socket_connect (struct addrinfo *host, GError **error) return NULL; } - cancel_fd = camel_operation_cancel_prfd (NULL); + if (CAMEL_IS_OPERATION (cancellable)) + cancel_fd = camel_operation_cancel_prfd ( + CAMEL_OPERATION (cancellable)); if (PR_Connect (fd, &netaddr, cancel_fd?0:CONNECT_TIMEOUT) == PR_FAILURE) { gint errnosave; @@ -629,7 +651,11 @@ out: * negotiate anything with the proxy; this is just to create the socket and connect. */ static PRFileDesc * -connect_to_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint proxy_port, GError **error) +connect_to_proxy (CamelTcpStreamRaw *raw, + const gchar *proxy_host, + gint proxy_port, + GCancellable *cancellable, + GError **error) { struct addrinfo *addr, *ai, hints; gchar serv[16]; @@ -645,7 +671,8 @@ connect_to_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint proxy_po memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_STREAM; - addr = camel_getaddrinfo (proxy_host, serv, &hints, error); + addr = camel_getaddrinfo ( + proxy_host, serv, &hints, cancellable, error); if (!addr) return NULL; @@ -653,7 +680,7 @@ connect_to_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint proxy_po ai = addr; while (ai) { - fd = socket_connect (ai, error); + fd = socket_connect (ai, cancellable, error); if (fd) goto out; @@ -679,7 +706,12 @@ out: * connect_addr; if you want to traverse all the addrinfos, call this function for each of them. */ static PRFileDesc * -connect_to_socks4_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint proxy_port, struct addrinfo *connect_addr, GError **error) +connect_to_socks4_proxy (CamelTcpStreamRaw *raw, + const gchar *proxy_host, + gint proxy_port, + struct addrinfo *connect_addr, + GCancellable *cancellable, + GError **error) { PRFileDesc *fd; gchar request[9]; @@ -689,7 +721,8 @@ connect_to_socks4_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint p g_assert (connect_addr->ai_addr->sa_family == AF_INET); - fd = connect_to_proxy (raw, proxy_host, proxy_port, error); + fd = connect_to_proxy ( + raw, proxy_host, proxy_port, cancellable, error); if (!fd) goto error; @@ -702,13 +735,13 @@ connect_to_socks4_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint p request[8] = 0x00; /* terminator */ d (g_print (" writing SOCKS4 request to connect to actual host\n")); - if (write_to_prfd (fd, request, sizeof (request), error) != sizeof (request)) { + if (write_to_prfd (fd, request, sizeof (request), cancellable, error) != sizeof (request)) { d (g_print (" failed: %d\n", errno)); goto error; } d (g_print (" reading SOCKS4 reply\n")); - if (read_from_prfd (fd, reply, sizeof (reply), error) != sizeof (reply)) { + if (read_from_prfd (fd, reply, sizeof (reply), cancellable, error) != sizeof (reply)) { d (g_print (" failed: %d\n", errno)); g_set_error (error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_PROXY_NOT_SUPPORTED, _("The proxy host does not support SOCKS4")); @@ -762,7 +795,10 @@ out: /* Resolves a port number using getaddrinfo(). Returns 0 if the port can't be resolved or if the operation is cancelled */ static gint -resolve_port (const gchar *service, gint fallback_port, GError **error) +resolve_port (const gchar *service, + gint fallback_port, + GCancellable *cancellable, + GError **error) { struct addrinfo *ai; GError *my_error; @@ -775,7 +811,8 @@ resolve_port (const gchar *service, gint fallback_port, GError **error) * from the standard getaddrinfo(), which lets you pass a NULL hostname * if you just want to resolve a port number. */ - ai = camel_getaddrinfo ("localhost", service, NULL, &my_error); + ai = camel_getaddrinfo ( + "localhost", service, NULL, cancellable, &my_error); if (ai == NULL && fallback_port != 0 && !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) port = fallback_port; else if (ai == NULL) { @@ -802,7 +839,10 @@ resolve_port (const gchar *service, gint fallback_port, GError **error) } static gboolean -socks5_initiate_and_request_authentication (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **error) +socks5_initiate_and_request_authentication (CamelTcpStreamRaw *raw, + PRFileDesc *fd, + GCancellable *cancellable, + GError **error) { gchar request[3]; gchar reply[2]; @@ -812,13 +852,13 @@ socks5_initiate_and_request_authentication (CamelTcpStreamRaw *raw, PRFileDesc * request[2] = 0; /* no authentication, please - extending this is left as an exercise for the reader */ d (g_print (" writing SOCKS5 request for authentication\n")); - if (write_to_prfd (fd, request, sizeof (request), error) != sizeof (request)) { + if (write_to_prfd (fd, request, sizeof (request), cancellable, error) != sizeof (request)) { d (g_print (" failed: %d\n", errno)); return FALSE; } d (g_print (" reading SOCKS5 reply\n")); - if (read_from_prfd (fd, reply, sizeof (reply), error) != sizeof (reply)) { + if (read_from_prfd (fd, reply, sizeof (reply), cancellable, error) != sizeof (reply)) { d (g_print (" failed: %d\n", errno)); g_clear_error (error); g_set_error (error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_PROXY_NOT_SUPPORTED, @@ -859,7 +899,10 @@ socks5_reply_error_to_string (gchar error_code) } static gboolean -socks5_consume_reply_address (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **error) +socks5_consume_reply_address (CamelTcpStreamRaw *raw, + PRFileDesc *fd, + GCancellable *cancellable, + GError **error) { gchar address_type; gint bytes_to_consume; @@ -867,7 +910,7 @@ socks5_consume_reply_address (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **e address_and_port = NULL; - if (read_from_prfd (fd, &address_type, sizeof (address_type), error) != sizeof (address_type)) + if (read_from_prfd (fd, &address_type, sizeof (address_type), cancellable, error) != sizeof (address_type)) goto incomplete_reply; if (address_type == 0x01) @@ -879,7 +922,7 @@ socks5_consume_reply_address (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **e /* we'll get an octet with the address length, and then the address itself */ - if (read_from_prfd (fd, (gchar *) &address_len, sizeof (address_len), error) != sizeof (address_len)) + if (read_from_prfd (fd, (gchar *) &address_len, sizeof (address_len), cancellable, error) != sizeof (address_len)) goto incomplete_reply; bytes_to_consume = address_len; @@ -891,7 +934,7 @@ socks5_consume_reply_address (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **e bytes_to_consume += 2; /* 2 octets for port number */ address_and_port = g_new (gchar, bytes_to_consume); - if (read_from_prfd (fd, address_and_port, bytes_to_consume, error) != bytes_to_consume) + if (read_from_prfd (fd, address_and_port, bytes_to_consume, cancellable, error) != bytes_to_consume) goto incomplete_reply; g_free (address_and_port); /* Currently we don't do anything to these; maybe some authenticated method will need them later */ @@ -907,7 +950,12 @@ incomplete_reply: } static gboolean -socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *host, gint port, GError **error) +socks5_request_connect (CamelTcpStreamRaw *raw, + PRFileDesc *fd, + const gchar *host, + gint port, + GCancellable *cancellable, + GError **error) { gchar *request; gchar reply[3]; @@ -934,7 +982,7 @@ socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *hos request[5 + host_len + 1] = port & 0xff; /* low byte of port */ d (g_print (" writing SOCKS5 request for connection\n")); - num_written = write_to_prfd (fd, request, request_len, error); + num_written = write_to_prfd (fd, request, request_len, cancellable, error); g_free (request); if (num_written != request_len) { @@ -943,7 +991,7 @@ socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *hos } d (g_print (" reading SOCKS5 reply\n")); - if (read_from_prfd (fd, reply, sizeof (reply), error) != sizeof (reply)) { + if (read_from_prfd (fd, reply, sizeof (reply), cancellable, error) != sizeof (reply)) { d (g_print (" failed: %d\n", errno)); return FALSE; } @@ -967,7 +1015,7 @@ socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *hos * identify to the final host. This is of variable length, so we must * consume it by hand. */ - if (!socks5_consume_reply_address (raw, fd, error)) + if (!socks5_consume_reply_address (raw, fd, cancellable, error)) return FALSE; return TRUE; @@ -976,25 +1024,30 @@ socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *hos /* RFC 1928 - SOCKS protocol version 5 */ static PRFileDesc * connect_to_socks5_proxy (CamelTcpStreamRaw *raw, - const gchar *proxy_host, gint proxy_port, - const gchar *host, const gchar *service, gint fallback_port, - GError **error) + const gchar *proxy_host, + gint proxy_port, + const gchar *host, + const gchar *service, + gint fallback_port, + GCancellable *cancellable, + GError **error) { PRFileDesc *fd; gint port; - fd = connect_to_proxy (raw, proxy_host, proxy_port, error); + fd = connect_to_proxy ( + raw, proxy_host, proxy_port, cancellable, error); if (!fd) goto error; - port = resolve_port (service, fallback_port, error); + port = resolve_port (service, fallback_port, cancellable, error); if (port == 0) goto error; - if (!socks5_initiate_and_request_authentication (raw, fd, error)) + if (!socks5_initiate_and_request_authentication (raw, fd, cancellable, error)) goto error; - if (!socks5_request_connect (raw, fd, host, port, error)) + if (!socks5_request_connect (raw, fd, host, port, cancellable, error)) goto error; d (g_print (" success\n")); @@ -1024,7 +1077,10 @@ out: static gint tcp_stream_raw_connect (CamelTcpStream *stream, - const gchar *host, const gchar *service, gint fallback_port, + const gchar *host, + const gchar *service, + gint fallback_port, + GCancellable *cancellable, GError **error) { CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream); @@ -1042,7 +1098,9 @@ tcp_stream_raw_connect (CamelTcpStream *stream, /* First, try SOCKS5, which does name resolution itself */ my_error = NULL; - priv->sockfd = connect_to_socks5_proxy (raw, proxy_host, proxy_port, host, service, fallback_port, &my_error); + priv->sockfd = connect_to_socks5_proxy ( + raw, proxy_host, proxy_port, host, service, + fallback_port, cancellable, &my_error); if (priv->sockfd) return 0; else if (g_error_matches (my_error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_CANT_AUTHENTICATE) @@ -1059,13 +1117,15 @@ tcp_stream_raw_connect (CamelTcpStream *stream, hints.ai_family = PF_UNSPEC; my_error = NULL; - addr = camel_getaddrinfo (host, service, &hints, &my_error); + addr = camel_getaddrinfo ( + host, service, &hints, cancellable, &my_error); if (addr == NULL && fallback_port != 0 && !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { gchar str_port[16]; g_clear_error (&my_error); sprintf (str_port, "%d", fallback_port); - addr = camel_getaddrinfo (host, str_port, &hints, &my_error); + addr = camel_getaddrinfo ( + host, str_port, &hints, cancellable, &my_error); } if (addr == NULL) { @@ -1079,9 +1139,11 @@ tcp_stream_raw_connect (CamelTcpStream *stream, if (proxy_host) { /* SOCKS4 only does IPv4 */ if (ai->ai_addr->sa_family == AF_INET) - priv->sockfd = connect_to_socks4_proxy (raw, proxy_host, proxy_port, ai, error); + priv->sockfd = connect_to_socks4_proxy ( + raw, proxy_host, proxy_port, + ai, cancellable, error); } else - priv->sockfd = socket_connect (ai, error); + priv->sockfd = socket_connect (ai, cancellable, error); if (priv->sockfd) { retval = 0; diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c index 02c7db8..057630f 100644 --- a/camel/camel-tcp-stream-ssl.c +++ b/camel/camel-tcp-stream-ssl.c @@ -384,11 +384,11 @@ camel_certdb_nss_cert_set (CamelCertDB *certdb, CamelCert *ccert, CERTCertificat if (stream != NULL) { if (camel_stream_write ( stream, (const gchar *) ccert->rawcert->data, - ccert->rawcert->len, NULL) == -1) { + ccert->rawcert->len, NULL, NULL) == -1) { g_warning ("Could not save cert: %s: %s", path, g_strerror (errno)); g_unlink (path); } - camel_stream_close (stream, NULL); + camel_stream_close (stream, NULL, NULL); g_object_unref (stream); } else { g_warning ("Could not save cert: %s: %s", path, g_strerror (errno)); @@ -706,12 +706,19 @@ rehandshake_ssl (PRFileDesc *fd, GError **error) } static gint -tcp_stream_ssl_connect (CamelTcpStream *stream, const gchar *host, const gchar *service, gint fallback_port, GError **error) +tcp_stream_ssl_connect (CamelTcpStream *stream, + const gchar *host, + const gchar *service, + gint fallback_port, + GCancellable *cancellable, + GError **error) { CamelTcpStreamSSL *ssl = CAMEL_TCP_STREAM_SSL (stream); gint retval; - retval = CAMEL_TCP_STREAM_CLASS (camel_tcp_stream_ssl_parent_class)->connect (stream, host, service, fallback_port, error); + retval = CAMEL_TCP_STREAM_CLASS (camel_tcp_stream_ssl_parent_class)-> + connect (stream, host, service, + fallback_port, cancellable, error); if (retval != 0) return retval; diff --git a/camel/camel-tcp-stream.c b/camel/camel-tcp-stream.c index a9d3587..f7945e5 100644 --- a/camel/camel-tcp-stream.c +++ b/camel/camel-tcp-stream.c @@ -85,6 +85,7 @@ camel_tcp_stream_init (CamelTcpStream *tcp_stream) * @host: Hostname for connection * @service: Service name or port number in string form * @fallback_port: Port number to retry if @service is not present in the system's services database, or 0 to avoid retrying. + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Create a socket and connect based upon the data provided. @@ -93,7 +94,10 @@ camel_tcp_stream_init (CamelTcpStream *tcp_stream) **/ gint camel_tcp_stream_connect (CamelTcpStream *stream, - const gchar *host, const gchar *service, gint fallback_port, + const gchar *host, + const gchar *service, + gint fallback_port, + GCancellable *cancellable, GError **error) { CamelTcpStreamClass *class; @@ -107,7 +111,8 @@ camel_tcp_stream_connect (CamelTcpStream *stream, class = CAMEL_TCP_STREAM_GET_CLASS (stream); g_return_val_if_fail (class->connect != NULL, -1); - retval = class->connect (stream, host, service, fallback_port, error); + retval = class->connect ( + stream, host, service, fallback_port, cancellable, error); CAMEL_CHECK_GERROR (stream, connect, retval == 0, error); return retval; diff --git a/camel/camel-tcp-stream.h b/camel/camel-tcp-stream.h index 217dc88..0340cf1 100644 --- a/camel/camel-tcp-stream.h +++ b/camel/camel-tcp-stream.h @@ -125,7 +125,10 @@ struct _CamelTcpStreamClass { CamelStreamClass parent_class; gint (*connect) (CamelTcpStream *stream, - const gchar *host, const gchar *service, gint fallback_port, + const gchar *host, + const gchar *service, + gint fallback_port, + GCancellable *cancellable, GError **error); gint (*getsockopt) (CamelTcpStream *stream, CamelSockOptData *data); @@ -143,7 +146,10 @@ struct _CamelTcpStreamClass { GType camel_tcp_stream_get_type (void); gint camel_tcp_stream_connect (CamelTcpStream *stream, - const gchar *host, const gchar *service, gint fallback_port, + const gchar *host, + const gchar *service, + gint fallback_port, + GCancellable *cancellable, GError **error); gint camel_tcp_stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data); diff --git a/camel/camel-transport.c b/camel/camel-transport.c index 7f07045..1f9af07 100644 --- a/camel/camel-transport.c +++ b/camel/camel-transport.c @@ -80,6 +80,7 @@ camel_transport_init (CamelTransport *transport) * @message: a #CamelMimeMessage to send * @from: a #CamelAddress to send from * @recipients: a #CamelAddress containing all recipients + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Sends the message to the given recipients, regardless of the contents @@ -93,6 +94,7 @@ camel_transport_send_to (CamelTransport *transport, CamelMimeMessage *message, CamelAddress *from, CamelAddress *recipients, + GCancellable *cancellable, GError **error) { CamelTransportClass *class; @@ -108,7 +110,8 @@ camel_transport_send_to (CamelTransport *transport, camel_transport_lock (transport, CAMEL_TRANSPORT_SEND_LOCK); - success = class->send_to (transport, message, from, recipients, error); + success = class->send_to ( + transport, message, from, recipients, cancellable, error); CAMEL_CHECK_GERROR (transport, send_to, success, error); camel_transport_unlock (transport, CAMEL_TRANSPORT_SEND_LOCK); diff --git a/camel/camel-transport.h b/camel/camel-transport.h index 92d88da..3456591 100644 --- a/camel/camel-transport.h +++ b/camel/camel-transport.h @@ -80,6 +80,7 @@ struct _CamelTransportClass { CamelMimeMessage *message, CamelAddress *from, CamelAddress *recipients, + GCancellable *cancellable, GError **error); }; @@ -88,6 +89,7 @@ gboolean camel_transport_send_to (CamelTransport *transport, CamelMimeMessage *message, CamelAddress *from, CamelAddress *recipients, + GCancellable *cancellable, GError **error); void camel_transport_lock (CamelTransport *transport, CamelTransportLock lock); diff --git a/camel/camel-uid-cache.c b/camel/camel-uid-cache.c index 17ea6c9..5a79c37 100644 --- a/camel/camel-uid-cache.c +++ b/camel/camel-uid-cache.c @@ -79,7 +79,7 @@ camel_uid_cache_new (const gchar *filename) buf = g_malloc (st.st_size + 1); - if (st.st_size > 0 && camel_read (fd, buf, st.st_size, NULL) == -1) { + if (st.st_size > 0 && camel_read (fd, buf, st.st_size, NULL, NULL) == -1) { close (fd); g_free (buf); return NULL; @@ -124,8 +124,8 @@ maybe_write_uid (gpointer key, gpointer value, gpointer data) return; if (state && state->level == cache->level && state->save) { - if (camel_write (cache->fd, key, strlen (key), NULL) == -1 || - camel_write (cache->fd, "\n", 1, NULL) == -1) { + if (camel_write (cache->fd, key, strlen (key), NULL, NULL) == -1 || + camel_write (cache->fd, "\n", 1, NULL, NULL) == -1) { cache->fd = -1; } else { cache->size += strlen (key) + 1; diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c index e89318a..233ea1a 100644 --- a/camel/camel-vee-folder.c +++ b/camel/camel-vee-folder.c @@ -840,7 +840,9 @@ folder_renamed (CamelFolder *sub, } static void -vee_folder_stop_folder (CamelVeeFolder *vf, CamelFolder *sub) +vee_folder_stop_folder (CamelVeeFolder *vf, + CamelFolder *sub, + GCancellable *cancellable) { CamelVeeFolderPrivate *p = CAMEL_VEE_FOLDER_GET_PRIVATE (vf); gint i; @@ -949,7 +951,7 @@ vee_folder_dispose (GObject *object) camel_folder_freeze ((CamelFolder *)vf); while (vf->priv->folders) { CamelFolder *f = vf->priv->folders->data; - vee_folder_stop_folder (vf, f); + vee_folder_stop_folder (vf, f, NULL); } camel_folder_thaw ((CamelFolder *)vf); } @@ -985,6 +987,7 @@ vee_folder_finalize (GObject *object) static gboolean vee_folder_refresh_info (CamelFolder *folder, + GCancellable *cancellable, GError **error) { CamelVeeFolder *vf = (CamelVeeFolder *)folder; @@ -1017,6 +1020,7 @@ vee_folder_refresh_info (CamelFolder *folder, static gboolean vee_folder_sync (CamelFolder *folder, gboolean expunge, + GCancellable *cancellable, GError **error) { CamelVeeFolder *vf = (CamelVeeFolder *)folder; @@ -1034,7 +1038,7 @@ vee_folder_sync (CamelFolder *folder, while (node) { CamelFolder *f = node->data; - if (!camel_folder_sync (f, expunge, &local_error)) { + if (!camel_folder_sync (f, expunge, cancellable, &local_error)) { if (strncmp (local_error->message, "no such table", 13) != 0) { const gchar *desc; @@ -1091,17 +1095,20 @@ vee_folder_sync (CamelFolder *folder, static gboolean vee_folder_expunge (CamelFolder *folder, + GCancellable *cancellable, GError **error) { /* Force it to rebuild the counts, when some folders were expunged. */ ((CamelVeeSummary *) folder->summary)->force_counts = TRUE; - return CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, TRUE, error); + return CAMEL_FOLDER_GET_CLASS (folder)-> + sync (folder, TRUE, cancellable, error); } static CamelMimeMessage * vee_folder_get_message (CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error) { CamelVeeMessageInfo *mi; @@ -1109,7 +1116,9 @@ vee_folder_get_message (CamelFolder *folder, mi = (CamelVeeMessageInfo *)camel_folder_summary_uid (folder->summary, uid); if (mi) { - msg = camel_folder_get_message (mi->summary->folder, camel_message_info_uid (mi)+8, error); + msg = camel_folder_get_message ( + mi->summary->folder, camel_message_info_uid (mi)+8, + cancellable, error); camel_message_info_free ((CamelMessageInfo *)mi); } else { g_set_error ( @@ -1127,10 +1136,11 @@ vee_folder_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error) { g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, + error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Cannot copy or move messages into a Virtual Folder")); return FALSE; @@ -1142,10 +1152,11 @@ vee_folder_transfer_messages_to (CamelFolder *folder, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error) { g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, + error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Cannot copy or move messages into a Virtual Folder")); return FALSE; @@ -2102,7 +2113,8 @@ camel_vee_folder_add_folder (CamelVeeFolder *vf, CamelFolder *sub) * Removed the source folder, @sub, from the virtual folder, @vf. **/ void -camel_vee_folder_remove_folder (CamelVeeFolder *vf, CamelFolder *sub) +camel_vee_folder_remove_folder (CamelVeeFolder *vf, + CamelFolder *sub) { CamelVeeFolderPrivate *p = CAMEL_VEE_FOLDER_GET_PRIVATE (vf); gint i; @@ -2189,7 +2201,9 @@ camel_vee_folder_rebuild_folder (CamelVeeFolder *vf, } static void -remove_folders (CamelFolder *folder, CamelFolder *foldercopy, CamelVeeFolder *vf) +remove_folders (CamelFolder *folder, + CamelFolder *foldercopy, + CamelVeeFolder *vf) { camel_vee_folder_remove_folder (vf, folder); g_object_unref (folder); diff --git a/camel/camel-vee-folder.h b/camel/camel-vee-folder.h index 3111c48..6909074 100644 --- a/camel/camel-vee-folder.h +++ b/camel/camel-vee-folder.h @@ -91,16 +91,25 @@ struct _CamelVeeFolderClass { /* TODO: Some of this may need some additional work/thinking through, it works for now*/ - void (*add_folder)(CamelVeeFolder *, CamelFolder *); - void (*remove_folder)(CamelVeeFolder *, CamelFolder *); - gint (*rebuild_folder)(CamelVeeFolder *, CamelFolder *, GError **error); + void (*add_folder) (CamelVeeFolder *vee_folder, + CamelFolder *folder); + void (*remove_folder) (CamelVeeFolder *vee_folder, + CamelFolder *folder); + gint (*rebuild_folder) (CamelVeeFolder *vee_folder, + CamelFolder *folder, + GError **error); - void (*set_expression)(CamelVeeFolder *, const gchar *); + void (*set_expression) (CamelVeeFolder *vee_folder, + const gchar *expression); /* Called for a folder-changed event on a source folder */ - void (*folder_changed)(CamelVeeFolder *, CamelFolder *sub, CamelFolderChangeInfo *changes); + void (*folder_changed) (CamelVeeFolder *vee_folder, + CamelFolder *subfolder, + CamelFolderChangeInfo *changes); /* Called for a folder-renamed event on a source folder */ - void (*folder_renamed)(CamelVeeFolder *, CamelFolder *sub, const gchar *old); + void (*folder_renamed) (CamelVeeFolder *vee_folder, + CamelFolder *subfolder, + const gchar *old); }; #define CAMEL_UNMATCHED_NAME "UNMATCHED" @@ -112,7 +121,8 @@ void camel_vee_folder_construct (CamelVeeFolder *vf, guint32 flags); CamelFolder *camel_vee_folder_get_location (CamelVeeFolder *vf, const struct _CamelVeeMessageInfo *vinfo, gchar **realuid); void camel_vee_folder_add_folder (CamelVeeFolder *vf, CamelFolder *sub); -void camel_vee_folder_remove_folder (CamelVeeFolder *vf, CamelFolder *sub); +void camel_vee_folder_remove_folder (CamelVeeFolder *vf, + CamelFolder *sub); void camel_vee_folder_set_folders (CamelVeeFolder *vf, GList *folders); gint camel_vee_folder_rebuild_folder (CamelVeeFolder *vf, CamelFolder *sub, GError **error); void camel_vee_folder_set_expression (CamelVeeFolder *vf, const gchar *expr); diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c index 027b679..6ccef77 100644 --- a/camel/camel-vee-store.c +++ b/camel/camel-vee-store.c @@ -157,6 +157,7 @@ static CamelFolder * vee_store_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, + GCancellable *cancellable, GError **error) { CamelVeeFolder *vf; @@ -199,6 +200,7 @@ static gboolean vee_store_rename_folder (CamelStore *store, const gchar *old, const gchar *new, + GCancellable *cancellable, GError **error) { CamelFolder *folder, *oldfolder; @@ -252,6 +254,7 @@ vee_store_rename_folder (CamelStore *store, static gboolean vee_store_delete_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelFolder *folder; @@ -298,6 +301,7 @@ static CamelFolderInfo * vee_store_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { CamelFolderInfo *info, *res = NULL, *tail; @@ -346,7 +350,9 @@ vee_store_get_folder_info (CamelStore *store, /* ensures unread is correct */ if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - camel_folder_refresh_info ((CamelFolder *)folder, NULL); + camel_folder_refresh_info ( + (CamelFolder *)folder, + cancellable, NULL); parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (folder)); @@ -433,6 +439,7 @@ vee_store_get_folder_info (CamelStore *store, static CamelFolder * vee_store_get_trash (CamelStore *store, + GCancellable *cancellable, GError **error) { return NULL; @@ -440,6 +447,7 @@ vee_store_get_trash (CamelStore *store, static CamelFolder * vee_store_get_junk (CamelStore *store, + GCancellable *cancellable, GError **error) { return NULL; diff --git a/camel/camel-vee-summary.c b/camel/camel-vee-summary.c index 369ac88..b9b9593 100644 --- a/camel/camel-vee-summary.c +++ b/camel/camel-vee-summary.c @@ -230,7 +230,9 @@ camel_vee_summary_load_check_unread_vfolder (CamelVeeSummary *vs) } static gboolean -vee_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set) +vee_info_set_flags (CamelMessageInfo *mi, + guint32 flags, + guint32 set) { gint res = FALSE; CamelVeeFolder *vf = (CamelVeeFolder *)mi->summary->folder; @@ -265,10 +267,10 @@ vee_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set) if (hacked_unread_folder) camel_vee_folder_mask_event_folder_changed ((CamelVeeFolder *)mi->summary->folder, rmi->summary->folder); - camel_folder_freeze (rmi->summary->folder); - res = camel_message_info_set_flags (rmi, flags, set); + camel_folder_freeze(rmi->summary->folder); + res = camel_message_info_set_flags(rmi, flags, set); ((CamelVeeMessageInfo *) mi)->old_flags = camel_message_info_flags (rmi); - camel_folder_thaw (rmi->summary->folder); + camel_folder_thaw(rmi->summary->folder); if (hacked_unread_folder) camel_vee_folder_unmask_event_folder_changed ((CamelVeeFolder *)mi->summary->folder, rmi->summary->folder); diff --git a/camel/camel-vtrash-folder.c b/camel/camel-vtrash-folder.c index f654501..b1f23c5 100644 --- a/camel/camel-vtrash-folder.c +++ b/camel/camel-vtrash-folder.c @@ -52,6 +52,7 @@ static struct { }; struct _transfer_data { + GCancellable *cancellable; CamelFolder *folder; CamelFolder *dest; GPtrArray *uids; @@ -68,10 +69,15 @@ transfer_messages (CamelFolder *folder, gint i; camel_folder_transfer_messages_to ( - md->folder, md->uids, md->dest, NULL, md->delete, error); + md->folder, md->uids, md->dest, + NULL, md->delete, md->cancellable, error); + + if (md->cancellable != NULL) + g_object_unref (md->cancellable); for (i=0;iuids->len;i++) g_free (md->uids->pdata[i]); + g_ptr_array_free (md->uids, TRUE); g_object_unref (md->folder); g_free (md); @@ -82,6 +88,7 @@ vtrash_folder_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error) { g_set_error ( @@ -97,6 +104,7 @@ vtrash_folder_transfer_messages_to (CamelFolder *source, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error) { CamelVeeMessageInfo *mi; @@ -125,7 +133,9 @@ vtrash_folder_transfer_messages_to (CamelFolder *source, /* Move to trash is the same as setting the message flag */ for (i = 0; i < uids->len; i++) - camel_folder_set_message_flags (source, uids->pdata[i], ((CamelVTrashFolder *)dest)->bit, ~0); + camel_folder_set_message_flags ( + source, uids->pdata[i], + ((CamelVTrashFolder *)dest)->bit, ~0); return TRUE; } @@ -144,17 +154,21 @@ vtrash_folder_transfer_messages_to (CamelFolder *source, if (dest == mi->summary->folder) { /* Just unset the flag on the original message */ - camel_folder_set_message_flags (source, uids->pdata[i], sbit, 0); + camel_folder_set_message_flags ( + source, uids->pdata[i], sbit, 0); } else { if (batch == NULL) batch = g_hash_table_new (NULL, NULL); md = g_hash_table_lookup (batch, mi->summary->folder); if (md == NULL) { - md = g_malloc0 (sizeof (*md)); + md = g_malloc0(sizeof(*md)); + md->cancellable = cancellable; md->folder = g_object_ref (mi->summary->folder); md->uids = g_ptr_array_new (); md->dest = dest; - g_hash_table_insert (batch, mi->summary->folder, md); + if (cancellable != NULL) + g_object_ref (cancellable); + g_hash_table_insert(batch, mi->summary->folder, md); } tuid = uids->pdata[i]; diff --git a/camel/providers/groupwise/camel-groupwise-folder.c b/camel/providers/groupwise/camel-groupwise-folder.c index 1bd761c..15e278f 100644 --- a/camel/providers/groupwise/camel-groupwise-folder.c +++ b/camel/providers/groupwise/camel-groupwise-folder.c @@ -77,20 +77,20 @@ struct _CamelGroupwiseFolderPrivate { extern gint camel_application_is_exiting; /*prototypes*/ -static gboolean groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, GPtrArray **transferred_uids, gboolean delete_originals, GError **error); +static gboolean groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, GPtrArray **transferred_uids, gboolean delete_originals, 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); -static void gw_update_all_items ( CamelFolder *folder, GList *item_list, GError **error); +static void gw_update_all_items ( CamelFolder *folder, GList *item_list, GCancellable *cancellable, GError **error); static void groupwise_populate_details_from_item (CamelMimeMessage *msg, EGwItem *item); static void groupwise_populate_msg_body_from_item (EGwConnection *cnc, CamelMultipart *multipart, EGwItem *item, gchar *body); static void groupwise_msg_set_recipient_list (CamelMimeMessage *msg, EGwItem *item); -static void gw_update_cache ( CamelFolder *folder, GList *item_list, GError **error, gboolean uid_flag); +static void gw_update_cache ( CamelFolder *folder, GList *item_list, gboolean uid_flag, GCancellable *cancellable, GError **error); static CamelMimeMessage *groupwise_folder_item_to_msg ( CamelFolder *folder, EGwItem *item, GError **error ); static gchar * groupwise_get_filename (CamelFolder *folder, const gchar *uid, GError **error); static const gchar *get_from_from_org (EGwItemOrganizer *org); -static void groupwise_refresh_folder (CamelFolder *folder, GError **error); -static gboolean groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, GError **error); +static void groupwise_refresh_folder (CamelFolder *folder, GCancellable *cancellable, GError **error); +static gboolean groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, GCancellable *cancellable, GError **error); #define d(x) @@ -109,7 +109,10 @@ groupwise_get_filename (CamelFolder *folder, const gchar *uid, GError **error) /* Get a message from cache if available otherwise get it from server */ static CamelMimeMessage * -groupwise_folder_get_message ( CamelFolder *folder, const gchar *uid, GError **error ) +groupwise_folder_get_message (CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { CamelMimeMessage *msg = NULL; CamelGroupwiseFolder *gw_folder; @@ -144,9 +147,9 @@ groupwise_folder_get_message ( CamelFolder *folder, const gchar *uid, GError **e if (cache_stream) { msg = camel_mime_message_new (); camel_stream_reset (stream, NULL); - camel_stream_write_to_stream (cache_stream, stream, NULL); + camel_stream_write_to_stream (cache_stream, stream, cancellable, NULL); camel_stream_reset (stream, NULL); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, stream, error) == -1) { + if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, stream, cancellable, error) == -1) { if (errno == EINTR) { g_object_unref (msg); g_object_unref (cache_stream); @@ -179,7 +182,7 @@ groupwise_folder_get_message ( CamelFolder *folder, const gchar *uid, GError **e } /* Check if we are really offline */ - if (!camel_groupwise_store_connected (gw_store, NULL)) { + if (!camel_groupwise_store_connected (gw_store, cancellable, NULL)) { g_set_error ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE, @@ -226,8 +229,8 @@ groupwise_folder_get_message ( CamelFolder *folder, const gchar *uid, GError **e /* add to cache */ CAMEL_GROUPWISE_FOLDER_REC_LOCK (folder, cache_lock); if ((cache_stream = camel_data_cache_add (gw_folder->cache, "cache", uid, NULL))) { - if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) msg, cache_stream, NULL) == -1 - || camel_stream_flush (cache_stream, NULL) == -1) + if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) msg, cache_stream, cancellable, NULL) == -1 + || camel_stream_flush (cache_stream, cancellable, NULL) == -1) camel_data_cache_remove (gw_folder->cache, "cache", uid, NULL); g_object_unref (cache_stream); } @@ -658,7 +661,10 @@ error: } static void -move_to_mailbox (CamelFolder *folder, CamelMessageInfo *info, GError **error) +move_to_mailbox (CamelFolder *folder, + CamelMessageInfo *info, + GCancellable *cancellable, + GError **error) { CamelFolder *dest; CamelStore *parent_store; @@ -670,10 +676,13 @@ move_to_mailbox (CamelFolder *folder, CamelMessageInfo *info, GError **error) uids = g_ptr_array_new (); g_ptr_array_add (uids, (gpointer) uid); - dest = camel_store_get_folder (parent_store, "Mailbox", 0, error); - camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN|CAMEL_GW_MESSAGE_NOJUNK|CAMEL_GW_MESSAGE_JUNK, 0); + dest = camel_store_get_folder (parent_store, "Mailbox", 0, cancellable, error); + camel_message_info_set_flags ( + info, CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_JUNK | + CAMEL_MESSAGE_JUNK_LEARN | CAMEL_GW_MESSAGE_NOJUNK | + CAMEL_GW_MESSAGE_JUNK, 0); if (dest) - groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, error); + groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, cancellable, error); else g_warning ("No Mailbox folder found"); @@ -681,7 +690,10 @@ move_to_mailbox (CamelFolder *folder, CamelMessageInfo *info, GError **error) } static void -move_to_junk (CamelFolder *folder, CamelMessageInfo *info, GError **error) +move_to_junk (CamelFolder *folder, + CamelMessageInfo *info, + GCancellable *cancellable, + GError **error) { CamelFolder *dest; CamelFolderInfo *fi; @@ -694,17 +706,17 @@ move_to_junk (CamelFolder *folder, CamelMessageInfo *info, GError **error) uids = g_ptr_array_new (); g_ptr_array_add (uids, (gpointer) uid); - dest = camel_store_get_folder (parent_store, JUNK_FOLDER, 0, error); + dest = camel_store_get_folder (parent_store, JUNK_FOLDER, 0, cancellable, error); if (dest) - groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, error); + groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, cancellable, error); else { fi = create_junk_folder (parent_store); - dest = camel_store_get_folder (parent_store, JUNK_FOLDER, 0, error); + dest = camel_store_get_folder (parent_store, JUNK_FOLDER, 0, cancellable, error); if (!dest) g_warning ("Could not get JunkFolder:Message not moved"); else - groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, error); + groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, cancellable, error); } update_junk_list (parent_store, info, ADD_JUNK_ENTRY); } @@ -765,7 +777,10 @@ sync_flags (CamelFolder *folder, GList *uids) } static gboolean -groupwise_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set) +groupwise_set_message_flags (CamelFolder *folder, + const gchar *uid, + guint32 flags, + guint32 set) { CamelMessageInfo *info; gint res; @@ -781,22 +796,31 @@ groupwise_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flag sync_immediately = g_getenv ("GW_SYNC_IMMEDIATE"); + /* FIXME groupwise_sync() blocks, but this method is + * not supposed to block. Potential hang here. */ if (sync_immediately) - groupwise_sync (folder, FALSE, info, NULL); + groupwise_sync (folder, FALSE, info, NULL, NULL); camel_message_info_free (info); return res; } static gboolean -groupwise_sync_all (CamelFolder *folder, gboolean expunge, GError **error) +groupwise_sync_all (CamelFolder *folder, + gboolean expunge, + GCancellable *cancellable, + GError **error) { - return groupwise_sync (folder, expunge, NULL, error); + return groupwise_sync (folder, expunge, NULL, cancellable, error); } /* This may need to be reorganized. */ static gboolean -groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, GError **error) +groupwise_sync (CamelFolder *folder, + gboolean expunge, + CamelMessageInfo *update_single, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *gw_store; CamelGroupwiseFolder *gw_folder; @@ -826,7 +850,7 @@ groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_ return groupwise_sync_summary (folder, error); camel_service_lock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); - if (!camel_groupwise_store_connected (gw_store, NULL)) { + if (!camel_groupwise_store_connected (gw_store, cancellable, NULL)) { camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); return TRUE; } @@ -866,7 +890,7 @@ groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_ if ((flags & CAMEL_MESSAGE_JUNK) && strcmp (camel_folder_get_name (folder), JUNK_FOLDER)) { /*marked a message junk*/ - move_to_junk (folder, info, error); + move_to_junk (folder, info, cancellable, error); camel_folder_summary_remove_uid (folder->summary, camel_message_info_uid (info)); camel_data_cache_remove (gw_folder->cache, "cache", camel_message_info_uid(info), NULL); continue; @@ -874,7 +898,7 @@ groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_ if ((flags & CAMEL_GW_MESSAGE_NOJUNK) && !strcmp (camel_folder_get_name (folder), JUNK_FOLDER)) { /*message was marked as junk, now unjunk*/ - move_to_mailbox (folder, info, error); + move_to_mailbox (folder, info, cancellable, error); camel_folder_summary_remove_uid (folder->summary, camel_message_info_uid (info)); camel_data_cache_remove (gw_folder->cache, "cache", camel_message_info_uid(info), NULL); continue; @@ -1040,7 +1064,11 @@ groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_ } CamelFolder * -camel_gw_folder_new (CamelStore *store, const gchar *folder_name, const gchar *folder_dir, GError **error) +camel_gw_folder_new (CamelStore *store, + const gchar *folder_name, + const gchar *folder_dir, + GCancellable *cancellable, + GError **error) { CamelFolder *folder; CamelGroupwiseFolder *gw_folder; @@ -1116,7 +1144,8 @@ struct _folder_update_msg { }; static void -update_update (CamelSession *session, CamelSessionThreadMsg *msg) +update_update (CamelSession *session, + CamelSessionThreadMsg *msg) { struct _folder_update_msg *m = (struct _folder_update_msg *)msg; EGwConnectionStatus status; @@ -1141,7 +1170,8 @@ update_update (CamelSession *session, CamelSessionThreadMsg *msg) } camel_operation_start ( - NULL, _("Checking for deleted messages %s"), + msg->cancellable, + _("Checking for deleted messages %s"), camel_folder_get_name (m->folder)); status = e_gw_connection_create_cursor (m->cnc, m->container_id, "id", NULL, &cursor); @@ -1211,13 +1241,13 @@ update_update (CamelSession *session, CamelSessionThreadMsg *msg) }*/ 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); - camel_operation_end (NULL); + gw_update_all_items (m->folder, items_full_list, NULL, NULL); + camel_operation_end (msg->cancellable); return; end1: camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); - camel_operation_end (NULL); + camel_operation_end (msg->cancellable); if (items_full_list) { g_list_foreach (items_full_list, (GFunc)g_free, NULL); g_list_free (items_full_list); @@ -1244,7 +1274,9 @@ static CamelSessionThreadOps update_ops = { }; static gboolean -groupwise_refresh_info (CamelFolder *folder, GError **error) +groupwise_refresh_info (CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelGroupwiseSummary *summary = (CamelGroupwiseSummary *) folder->summary; CamelStoreInfo *si; @@ -1263,7 +1295,7 @@ groupwise_refresh_info (CamelFolder *folder, GError **error) * should not interfere with the process */ if (summary->time_string && (strlen (summary->time_string) > 0)) { - groupwise_refresh_folder (folder, error); + groupwise_refresh_folder (folder, cancellable, error); si = camel_store_summary_path ((CamelStoreSummary *)((CamelGroupwiseStore *)parent_store)->summary, full_name); if (si) { guint32 unread, total; @@ -1285,7 +1317,7 @@ groupwise_refresh_info (CamelFolder *folder, GError **error) * so do a get_folder again. And hope that it works */ g_print("Reloading folder...something wrong with the summary....\n"); - gw_store_reload_folder (gw_store, folder, 0, error); + gw_store_reload_folder (gw_store, folder, 0, cancellable, error); } return TRUE; @@ -1375,7 +1407,9 @@ update_summary_string (CamelFolder *folder, const gchar *time_string) } static void -groupwise_refresh_folder (CamelFolder *folder, GError **error) +groupwise_refresh_folder (CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *gw_store; CamelGroupwiseFolder *gw_folder; @@ -1409,7 +1443,7 @@ groupwise_refresh_folder (CamelFolder *folder, GError **error) /* Sync-up the (un)read changes before getting updates, so that the getFolderList will reflect the most recent changes too */ - groupwise_sync_all (folder, FALSE, error); + groupwise_sync_all (folder, FALSE, cancellable, error); if (((CamelOfflineStore *) gw_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) { g_warning ("In offline mode. Cannot refresh!!!\n"); @@ -1432,7 +1466,7 @@ groupwise_refresh_folder (CamelFolder *folder, GError **error) camel_service_lock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); - if (!camel_groupwise_store_connected (gw_store, error)) + if (!camel_groupwise_store_connected (gw_store, cancellable, error)) goto end1; if (!strcmp (full_name, "Trash")) { @@ -1513,7 +1547,7 @@ groupwise_refresh_folder (CamelFolder *folder, GError **error) g_object_unref (container); if (list) - gw_update_cache (folder, list, error, FALSE); + gw_update_cache (folder, list, FALSE, cancellable, error); /* update the new_sync_time to summary */ update_summary_string (folder, new_sync_time); @@ -1616,7 +1650,11 @@ groupwise_folder_set_threading_data (CamelGroupwiseMessageInfo *mi, EGwItem *ite /* Update the GroupWise cache with the list of items passed. should happen in thread. */ static void -gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_flag) +gw_update_cache (CamelFolder *folder, + GList *list, + gboolean uid_flag, + GCancellable *cancellable, + GError **error) { CamelGroupwiseMessageInfo *mi = NULL; CamelMessageInfo *pmi = NULL; @@ -1667,7 +1705,8 @@ gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_ } camel_operation_start ( - NULL, _("Fetching summary information for new messages in %s"), + cancellable, + _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder)); for (; item_list != NULL; item_list = g_list_next (item_list) ) { @@ -1692,7 +1731,8 @@ gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_ } else id = (gchar *) item_list->data; - camel_operation_progress (NULL, (100*i)/total_items); + camel_operation_progress ( + cancellable, (i * 100) / total_items); if (folder_needs_caching) status = e_gw_connection_get_item (cnc, container_id, id, GET_ITEM_VIEW_WITH_CACHE, &item); @@ -1848,7 +1888,7 @@ gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_ CAMEL_GROUPWISE_FOLDER_REC_LOCK (folder, cache_lock); if ((cache_stream = camel_data_cache_add (gw_folder->cache, "cache", id, NULL))) { - if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) mail_msg, cache_stream, NULL) == -1 || camel_stream_flush (cache_stream, NULL) == -1) + if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) mail_msg, cache_stream, cancellable, NULL) == -1 || camel_stream_flush (cache_stream, cancellable, NULL) == -1) camel_data_cache_remove (gw_folder->cache, "cache", id, NULL); g_object_unref (cache_stream); } @@ -1862,7 +1902,9 @@ gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_ i++; g_object_unref (item); } - camel_operation_end (NULL); + + camel_operation_end (cancellable); + g_free (container_id); g_string_free (str_to, TRUE); g_string_free (str_cc, TRUE); @@ -1905,7 +1947,10 @@ get_from_from_org (EGwItemOrganizer *org) /* Update summary, if there is none existing, create one */ void -gw_update_summary (CamelFolder *folder, GList *list,GError **error) +gw_update_summary (CamelFolder *folder, + GList *list, + GCancellable *cancellable, + GError **error) { CamelGroupwiseMessageInfo *mi = NULL; CamelGroupwiseStore *gw_store; @@ -2204,7 +2249,7 @@ groupwise_folder_item_to_msg ( CamelFolder *folder, msg = camel_mime_message_new (); if (has_mime_822 && body) { temp_stream = camel_stream_mem_new_with_buffer (body, body_len); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, temp_stream, error) == -1) { + if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, temp_stream, NULL, error) == -1) { g_object_unref (msg); g_object_unref (temp_stream); msg = NULL; @@ -2415,7 +2460,10 @@ end: } static void -gw_update_all_items (CamelFolder *folder, GList *item_list, GError **error) +gw_update_all_items (CamelFolder *folder, + GList *item_list, + GCancellable *cancellable, + GError **error) { CamelGroupwiseFolder *gw_folder = CAMEL_GROUPWISE_FOLDER (folder); GPtrArray *summary = NULL; @@ -2460,7 +2508,7 @@ gw_update_all_items (CamelFolder *folder, GList *item_list, GError **error) parent_store = camel_folder_get_parent_store (folder); camel_service_lock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK); - gw_update_cache (folder, item_list, error, TRUE); + gw_update_cache (folder, item_list, TRUE, cancellable, error); camel_service_unlock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK); g_list_foreach (item_list, (GFunc)g_free, NULL); @@ -2471,9 +2519,12 @@ gw_update_all_items (CamelFolder *folder, GList *item_list, GError **error) } static gboolean -groupwise_append_message (CamelFolder *folder, CamelMimeMessage *message, - const CamelMessageInfo *info, gchar **appended_uid, - GError **error) +groupwise_append_message (CamelFolder *folder, + CamelMimeMessage *message, + const CamelMessageInfo *info, + gchar **appended_uid, + GCancellable *cancellable, + GError **error) { const gchar *container_id = NULL; CamelGroupwiseStore *gw_store; @@ -2508,7 +2559,7 @@ groupwise_append_message (CamelFolder *folder, CamelMimeMessage *message, offline = CAMEL_OFFLINE_STORE (parent_store); if (offline->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) { - camel_groupwise_journal_append ((CamelGroupwiseJournal *) ((CamelGroupwiseFolder *)folder)->journal, message, info, appended_uid, error); + camel_groupwise_journal_append ((CamelGroupwiseJournal *) ((CamelGroupwiseFolder *)folder)->journal, message, info, appended_uid, cancellable, error); return FALSE; } cnc = cnc_lookup (gw_store->priv); @@ -2587,9 +2638,13 @@ uid_compar (gconstpointer va, gconstpointer vb) /* move messages */ static gboolean -groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, GPtrArray **transferred_uids, - gboolean delete_originals, GError **error) +groupwise_transfer_messages_to (CamelFolder *source, + GPtrArray *uids, + CamelFolder *destination, + GPtrArray **transferred_uids, + gboolean delete_originals, + GCancellable *cancellable, + GError **error) { gint count, index = 0; GList *item_ids = NULL; @@ -2614,7 +2669,7 @@ groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, gw_store = CAMEL_GROUPWISE_STORE (source_parent_store); offline = CAMEL_OFFLINE_STORE (destination_parent_store); - if (destination == camel_store_get_trash (source_parent_store, NULL)) + if (destination == camel_store_get_trash (source_parent_store, cancellable, NULL)) destination_is_trash = TRUE; else destination_is_trash = FALSE; @@ -2655,10 +2710,10 @@ groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, if (!(info = camel_folder_summary_uid (source->summary, uids->pdata[i]))) continue; - if (!(message = groupwise_folder_get_message (source, camel_message_info_uid (info), error))) + if (!(message = groupwise_folder_get_message (source, camel_message_info_uid (info), cancellable, error))) break; - success = camel_groupwise_journal_transfer (journal, (CamelGroupwiseFolder *)source, message, info, uids->pdata[i], NULL, error); + success = camel_groupwise_journal_transfer (journal, (CamelGroupwiseFolder *)source, message, info, uids->pdata[i], NULL, cancellable, error); g_object_unref (message); if (!success) @@ -2788,7 +2843,7 @@ groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, /* Refresh the destination folder, if its not refreshed already */ if (gw_store->current_folder != destination ) - camel_folder_refresh_info (destination, error); + camel_folder_refresh_info (destination, cancellable, error); camel_folder_summary_touch (source->summary); camel_folder_summary_touch (destination->summary); @@ -2801,7 +2856,9 @@ groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, } static gboolean -groupwise_expunge (CamelFolder *folder, GError **error) +groupwise_expunge (CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *gw_store; CamelGroupwiseFolder *gw_folder; diff --git a/camel/providers/groupwise/camel-groupwise-folder.h b/camel/providers/groupwise/camel-groupwise-folder.h index f8c5c8c..c8e8b85 100644 --- a/camel/providers/groupwise/camel-groupwise-folder.h +++ b/camel/providers/groupwise/camel-groupwise-folder.h @@ -75,11 +75,16 @@ struct _CamelGroupwiseFolderClass { CamelOfflineFolderClass parent_class; }; -GType camel_groupwise_folder_get_type (void); - -/* implemented */ -CamelFolder * camel_gw_folder_new (CamelStore *store, const gchar *folder_dir, const gchar *folder_name, GError **error); -void gw_update_summary ( CamelFolder *folder, GList *item_list,GError **error); +GType camel_groupwise_folder_get_type (void); +CamelFolder * camel_gw_folder_new (CamelStore *store, + const gchar *folder_dir, + const gchar *folder_name, + GCancellable *cancellable, + GError **error); +void gw_update_summary (CamelFolder *folder, + GList *item_list, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/groupwise/camel-groupwise-journal.c b/camel/providers/groupwise/camel-groupwise-journal.c index 1734d9e..07a2601 100644 --- a/camel/providers/groupwise/camel-groupwise-journal.c +++ b/camel/providers/groupwise/camel-groupwise-journal.c @@ -44,7 +44,7 @@ static void groupwise_entry_free (CamelOfflineJournal *journal, CamelDListNode *entry); static CamelDListNode *groupwise_entry_load (CamelOfflineJournal *journal, FILE *in); static gint groupwise_entry_write (CamelOfflineJournal *journal, CamelDListNode *entry, FILE *out); -static gint groupwise_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error); +static gint groupwise_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GCancellable *cancellable, GError **error); G_DEFINE_TYPE (CamelGroupwiseJournal, camel_groupwise_journal, CAMEL_TYPE_OFFLINE_JOURNAL) @@ -156,7 +156,10 @@ gw_message_info_dup_to (CamelMessageInfoBase *dest, CamelMessageInfoBase *src) } static gint -groupwise_entry_play_append (CamelOfflineJournal *journal, CamelGroupwiseJournalEntry *entry, GError **error) +groupwise_entry_play_append (CamelOfflineJournal *journal, + CamelGroupwiseJournalEntry *entry, + GCancellable *cancellable, + GError **error) { CamelGroupwiseFolder *gw_folder = (CamelGroupwiseFolder *) journal->folder; CamelFolder *folder = journal->folder; @@ -172,7 +175,7 @@ groupwise_entry_play_append (CamelOfflineJournal *journal, CamelGroupwiseJournal } message = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, error) == -1) { + if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, cancellable, error) == -1) { g_object_unref (message); g_object_unref (stream); goto done; @@ -185,7 +188,7 @@ groupwise_entry_play_append (CamelOfflineJournal *journal, CamelGroupwiseJournal info = camel_message_info_new (NULL); } - success = camel_folder_append_message (folder, message, info, NULL, error); + success = camel_folder_append_message (folder, message, info, NULL, cancellable, error); camel_message_info_free (info); g_object_unref (message); @@ -198,7 +201,10 @@ done: } static gint -groupwise_entry_play_transfer (CamelOfflineJournal *journal, CamelGroupwiseJournalEntry *entry, GError **error) +groupwise_entry_play_transfer (CamelOfflineJournal *journal, + CamelGroupwiseJournalEntry *entry, + GCancellable *cancellable, + GError **error) { CamelGroupwiseFolder *gw_folder = (CamelGroupwiseFolder *) journal->folder; CamelFolder *folder = journal->folder; @@ -217,11 +223,11 @@ groupwise_entry_play_transfer (CamelOfflineJournal *journal, CamelGroupwiseJourn } name = camel_groupwise_store_folder_lookup ((CamelGroupwiseStore *) parent_store, entry->source_container); - if (name && (src = camel_store_get_folder (parent_store, name, 0, error))) { + if (name && (src = camel_store_get_folder (parent_store, name, 0, cancellable, error))) { uids = g_ptr_array_sized_new (1); g_ptr_array_add (uids, entry->original_uid); - if (camel_folder_transfer_messages_to (src, uids, folder, &xuids, FALSE, error)) { + if (camel_folder_transfer_messages_to (src, uids, folder, &xuids, FALSE, cancellable, error)) { real = (CamelGroupwiseMessageInfo *) camel_folder_summary_uid (folder->summary, xuids->pdata[0]); /* transfer all the system flags, user flags/tags, etc */ @@ -257,15 +263,18 @@ groupwise_entry_play_transfer (CamelOfflineJournal *journal, CamelGroupwiseJourn } static gint -groupwise_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error) +groupwise_entry_play (CamelOfflineJournal *journal, + CamelDListNode *entry, + GCancellable *cancellable, + GError **error) { CamelGroupwiseJournalEntry *groupwise_entry = (CamelGroupwiseJournalEntry *) entry; switch (groupwise_entry->type) { case CAMEL_GROUPWISE_JOURNAL_ENTRY_APPEND: - return groupwise_entry_play_append (journal, groupwise_entry, error); + return groupwise_entry_play_append (journal, groupwise_entry, cancellable, error); case CAMEL_GROUPWISE_JOURNAL_ENTRY_TRANSFER: - return groupwise_entry_play_transfer (journal, groupwise_entry, error); + return groupwise_entry_play_transfer (journal, groupwise_entry, cancellable, error); default: g_assert_not_reached (); return -1; @@ -286,8 +295,12 @@ camel_groupwise_journal_new (CamelGroupwiseFolder *folder, const gchar *filename } static gboolean -update_cache (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *message, - const CamelMessageInfo *mi, gchar **updated_uid, GError **error) +update_cache (CamelGroupwiseJournal *groupwise_journal, + CamelMimeMessage *message, + const CamelMessageInfo *mi, + gchar **updated_uid, + GCancellable *cancellable, + GError **error) { CamelOfflineJournal *journal = (CamelOfflineJournal *) groupwise_journal; CamelGroupwiseFolder *groupwise_folder = (CamelGroupwiseFolder *) journal->folder; @@ -314,8 +327,8 @@ update_cache (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *messag } if (camel_data_wrapper_write_to_stream ( - (CamelDataWrapper *) message, cache, error) == -1 - || camel_stream_flush (cache, error) == -1) { + (CamelDataWrapper *) message, cache, cancellable, error) == -1 + || camel_stream_flush (cache, cancellable, error) == -1) { g_prefix_error ( error, _("Cannot append message in offline mode: ")); camel_data_cache_remove (groupwise_folder->cache, "cache", uid, NULL); @@ -344,14 +357,18 @@ update_cache (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *messag } gboolean -camel_groupwise_journal_append (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *message, - const CamelMessageInfo *mi, gchar **appended_uid, GError **error) +camel_groupwise_journal_append (CamelGroupwiseJournal *groupwise_journal, + CamelMimeMessage *message, + const CamelMessageInfo *mi, + gchar **appended_uid, + GCancellable *cancellable, + GError **error) { CamelOfflineJournal *journal = (CamelOfflineJournal *) groupwise_journal; CamelGroupwiseJournalEntry *entry; gchar *uid; - if (!update_cache (groupwise_journal, message, mi, &uid, error)) + if (!update_cache (groupwise_journal, message, mi, &uid, cancellable, error)) return FALSE; entry = g_new (CamelGroupwiseJournalEntry, 1); @@ -367,10 +384,14 @@ camel_groupwise_journal_append (CamelGroupwiseJournal *groupwise_journal, CamelM } gboolean -camel_groupwise_journal_transfer (CamelGroupwiseJournal *groupwise_journal, CamelGroupwiseFolder *source_folder, - CamelMimeMessage *message, const CamelMessageInfo *mi, - const gchar *original_uid, gchar **transferred_uid, - GError **error) +camel_groupwise_journal_transfer (CamelGroupwiseJournal *groupwise_journal, + CamelGroupwiseFolder *source_folder, + CamelMimeMessage *message, + const CamelMessageInfo *mi, + const gchar *original_uid, + gchar **transferred_uid, + GCancellable *cancellable, + GError **error) { CamelOfflineJournal *journal = (CamelOfflineJournal *) groupwise_journal; CamelGroupwiseStore *gw_store; @@ -381,7 +402,7 @@ camel_groupwise_journal_transfer (CamelGroupwiseJournal *groupwise_journal, Came parent_store = camel_folder_get_parent_store (journal->folder); gw_store = CAMEL_GROUPWISE_STORE (parent_store); - if (!update_cache (groupwise_journal, message, mi, &uid, error)) + if (!update_cache (groupwise_journal, message, mi, &uid, cancellable, error)) return FALSE; entry = g_new (CamelGroupwiseJournalEntry, 1); diff --git a/camel/providers/groupwise/camel-groupwise-journal.h b/camel/providers/groupwise/camel-groupwise-journal.h index a58e31f..b32fe5a 100644 --- a/camel/providers/groupwise/camel-groupwise-journal.h +++ b/camel/providers/groupwise/camel-groupwise-journal.h @@ -78,15 +78,25 @@ struct _CamelGroupwiseJournalClass { }; -GType camel_groupwise_journal_get_type (void); - -CamelOfflineJournal *camel_groupwise_journal_new (struct _CamelGroupwiseFolder *folder, const gchar *filename); - -/* interfaces for adding a journal entry */ -gboolean camel_groupwise_journal_append (CamelGroupwiseJournal *journal, CamelMimeMessage *message, const CamelMessageInfo *mi, - gchar **appended_uid, GError **error); -gboolean camel_groupwise_journal_transfer (CamelGroupwiseJournal *journal, CamelGroupwiseFolder *source_folder, CamelMimeMessage *message, - const CamelMessageInfo *mi, const gchar *orginal_uid, gchar **transferred_uid, GError **error); +GType camel_groupwise_journal_get_type (void); +CamelOfflineJournal * + camel_groupwise_journal_new (CamelGroupwiseFolder *folder, + const gchar *filename); +gboolean camel_groupwise_journal_append (CamelGroupwiseJournal *journal, + CamelMimeMessage *message, + const CamelMessageInfo *mi, + gchar **appended_uid, + GCancellable *cancellable, + GError **error); +gboolean camel_groupwise_journal_transfer + (CamelGroupwiseJournal *journal, + CamelGroupwiseFolder *source_folder, + CamelMimeMessage *message, + const CamelMessageInfo *mi, + const gchar *orginal_uid, + gchar **transferred_uid, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/groupwise/camel-groupwise-store.c b/camel/providers/groupwise/camel-groupwise-store.c index 1dc4297..915f337 100644 --- a/camel/providers/groupwise/camel-groupwise-store.c +++ b/camel/providers/groupwise/camel-groupwise-store.c @@ -75,8 +75,8 @@ struct _CamelGroupwiseStorePrivate { }; extern CamelServiceAuthType camel_groupwise_password_authtype; /*for the query_auth_types function*/ -static CamelFolderInfo *convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, const gchar *url, GError **error); -static gboolean groupwise_folders_sync (CamelGroupwiseStore *store, GError **error); +static CamelFolderInfo *convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, const gchar *url, GCancellable *cancellable, GError **error); +static gboolean groupwise_folders_sync (CamelGroupwiseStore *store, GCancellable *cancellable, GError **error); static gint match_path (const gchar *path, const gchar *name); G_DEFINE_TYPE (CamelGroupwiseStore, camel_groupwise_store, CAMEL_TYPE_OFFLINE_STORE) @@ -171,7 +171,9 @@ groupwise_compare_folder_name (gconstpointer a, gconstpointer b) } static gboolean -groupwise_auth_loop (CamelService *service, GError **error) +groupwise_auth_loop (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelSession *session = camel_service_get_session (service); CamelStore *store = CAMEL_STORE (service); @@ -239,7 +241,9 @@ groupwise_auth_loop (CamelService *service, GError **error) } static gboolean -check_for_connection (CamelService *service, GError **error) +check_for_connection (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (service); CamelGroupwiseStorePrivate *priv = groupwise_store->priv; @@ -249,10 +253,10 @@ check_for_connection (CamelService *service, GError **error) memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_family = PF_UNSPEC; - ai = camel_getaddrinfo(priv->server_name, "groupwise", &hints, &local_error); + ai = camel_getaddrinfo(priv->server_name, "groupwise", &hints, cancellable, &local_error); if (ai == NULL && priv->port != NULL && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_clear_error (&local_error); - ai = camel_getaddrinfo (priv->server_name, priv->port, &hints, &local_error); + ai = camel_getaddrinfo (priv->server_name, priv->port, &hints, cancellable, &local_error); } if (ai == NULL) { @@ -285,7 +289,9 @@ groupwise_store_set_current_folder (CamelGroupwiseStore *groupwise_store, CamelF } static gboolean -groupwise_connect (CamelService *service, GError **error) +groupwise_connect (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *store = CAMEL_GROUPWISE_STORE (service); CamelGroupwiseStorePrivate *priv = store->priv; @@ -313,7 +319,7 @@ groupwise_connect (CamelService *service, GError **error) return TRUE; } - if (!check_for_connection (service, error) || !groupwise_auth_loop (service, error)) { + if (!check_for_connection (service, cancellable, error) || !groupwise_auth_loop (service, cancellable, error)) { camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); camel_service_disconnect (service, TRUE, NULL); return FALSE; @@ -404,7 +410,10 @@ groupwise_disconnect_cleanup (CamelService *service, gboolean clean, GError **er #endif static gboolean -groupwise_disconnect (CamelService *service, gboolean clean, GError **error) +groupwise_disconnect (CamelService *service, + gboolean clean, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (service); @@ -425,7 +434,9 @@ groupwise_disconnect (CamelService *service, gboolean clean, GError **error) } static GList* -groupwise_store_query_auth_types (CamelService *service, GError **error) +groupwise_store_query_auth_types (CamelService *service, + GCancellable *cancellable, + GError **error) { GList *auth_types = NULL; @@ -532,7 +543,11 @@ groupwise_forget_folder (CamelGroupwiseStore *gw_store, const gchar *folder_name } static CamelFolder * -groupwise_get_folder_from_disk (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error) +groupwise_get_folder_from_disk (CamelStore *store, + const gchar *folder_name, + guint32 flags, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store); CamelGroupwiseStorePrivate *priv = gw_store->priv; @@ -551,14 +566,18 @@ groupwise_get_folder_from_disk (CamelStore *store, const gchar *folder_name, gui return NULL; } - folder = camel_gw_folder_new (store, folder_name, folder_dir, error); + folder = camel_gw_folder_new (store, folder_name, folder_dir, cancellable, error); g_free (folder_dir); return folder; } static CamelFolder * -groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error) +groupwise_get_folder (CamelStore *store, + const gchar *folder_name, + guint32 flags, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store); CamelGroupwiseStorePrivate *priv = gw_store->priv; @@ -575,7 +594,7 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags GError *local_error = NULL; folder = groupwise_get_folder_from_disk ( - store, folder_name, flags, &local_error); + store, folder_name, flags, cancellable, &local_error); if (folder) { groupwise_store_set_current_folder (gw_store, folder); return folder; @@ -592,13 +611,13 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags groupwise_store_set_current_folder (gw_store, NULL); - if (!camel_groupwise_store_connected (gw_store, error)) { + if (!camel_groupwise_store_connected (gw_store, cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } if (!E_IS_GW_CONNECTION ( priv->cnc)) { - if (!groupwise_connect (CAMEL_SERVICE (store), error)) { + if (!groupwise_connect (CAMEL_SERVICE (store), cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } @@ -609,7 +628,7 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags storage_path = g_strdup_printf("%s/folders", priv->storage_path); folder_dir = e_path_to_physical (storage_path, folder_name); g_free (storage_path); - folder = camel_gw_folder_new (store, folder_name, folder_dir, NULL); + folder = camel_gw_folder_new (store, folder_name, folder_dir, cancellable, NULL); if (!folder) { camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); g_set_error ( @@ -651,7 +670,8 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags } camel_operation_start ( - NULL, _("Fetching summary information for new messages in %s"), + cancellable, + _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder)); camel_folder_summary_clear (folder->summary); @@ -669,15 +689,16 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags count += CURSOR_ITEM_LIMIT; if (total > 0) { - d(printf ("Doing readcursor : [total: %d] [count: %d]\n", total, count)); + d(printf ("Doing readcursor : [total: %d] [count: %d]\n", total, count)); - if (count > total) - count = total; + if (count > total) + count = total; - camel_operation_progress (NULL, (100*count)/total); + camel_operation_progress ( + cancellable, (100*count)/total); } - gw_update_summary (folder, list, error); + gw_update_summary (folder, list, cancellable, error); /* For shared-folders created by the user, we don't get the total number of messages, in the getFolderList call. So, we need to wait until an empty list is returned in the @@ -693,7 +714,7 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor); - camel_operation_end (NULL); + camel_operation_end (cancellable); } if (done && all_ok) { if (summary->time_string) @@ -712,7 +733,11 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags } gboolean -gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guint32 flags, GError **error) +gw_store_reload_folder (CamelGroupwiseStore *gw_store, + CamelFolder *folder, + guint32 flags, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStorePrivate *priv = gw_store->priv; CamelGroupwiseSummary *summary; @@ -732,13 +757,13 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin camel_service_lock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); - if (!camel_groupwise_store_connected (gw_store, error)) { + if (!camel_groupwise_store_connected (gw_store, cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); return FALSE; } if (!E_IS_GW_CONNECTION ( priv->cnc)) { - if (!groupwise_connect (CAMEL_SERVICE ((CamelStore*)gw_store), error)) { + if (!groupwise_connect (CAMEL_SERVICE ((CamelStore*)gw_store), cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK); return FALSE; } @@ -776,7 +801,8 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin } camel_operation_start ( - NULL, _("Fetching summary information for new messages in %s"), + cancellable, + _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder)); while (!done) { @@ -791,7 +817,7 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_INVALID, _("Authentication failed")); - camel_operation_end (NULL); + camel_operation_end (cancellable); g_free (container_id); return FALSE; } @@ -805,10 +831,11 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin if (count > total) count = total; - camel_operation_progress (NULL, (100*count)/total); + camel_operation_progress ( + cancellable, (100 * count) / total); } - gw_update_summary (folder, list, error); + gw_update_summary (folder, list, cancellable, error); /* For shared-folders created by the user, we don't get the total number of messages, in the getFolderList call. So, we need to wait until an empty list is returned in the @@ -824,7 +851,7 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor); - camel_operation_end (NULL); + camel_operation_end (cancellable); } if (done) { @@ -843,7 +870,11 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin } static CamelFolderInfo * -convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, const gchar *url, GError **error) +convert_to_folder_info (CamelGroupwiseStore *store, + EGwContainer *container, + const gchar *url, + GCancellable *cancellable, + GError **error) { const gchar *name = NULL, *id = NULL, *parent = NULL; gchar *par_name = NULL; @@ -934,7 +965,7 @@ convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, con if (store->current_folder && !strcmp (camel_folder_get_full_name (store->current_folder), fi->full_name) && type != E_GW_CONTAINER_TYPE_INBOX) { - CAMEL_FOLDER_GET_CLASS (store->current_folder)->refresh_info (store->current_folder, error); + CAMEL_FOLDER_GET_CLASS (store->current_folder)->refresh_info (store->current_folder, cancellable, error); } return fi; } @@ -947,7 +978,9 @@ get_folders_free (gpointer k, gpointer v, gpointer d) } static gboolean -groupwise_folders_sync (CamelGroupwiseStore *store, GError **error) +groupwise_folders_sync (CamelGroupwiseStore *store, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStorePrivate *priv = store->priv; gint status; @@ -1013,7 +1046,7 @@ groupwise_folders_sync (CamelGroupwiseStore *store, GError **error) if ((type == E_GW_CONTAINER_TYPE_CALENDAR) || (type == E_GW_CONTAINER_TYPE_CONTACTS)) continue; - info = convert_to_folder_info (store, E_GW_CONTAINER (folder_list->data), (const gchar *)url, error); + info = convert_to_folder_info (store, E_GW_CONTAINER (folder_list->data), (const gchar *)url, cancellable, error); if (info) { hfi = g_hash_table_lookup (present, info->full_name); if (hfi == NULL) @@ -1103,7 +1136,11 @@ groupwise_get_folder_info_offline (CamelStore *store, const gchar *top, } static CamelFolderInfo * -groupwise_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error) +groupwise_get_folder_info (CamelStore *store, + const gchar *top, + guint32 flags, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store); CamelFolderInfo *info = NULL; @@ -1116,7 +1153,7 @@ groupwise_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, G camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); - if (!groupwise_folders_sync (groupwise_store, error)) { + if (!groupwise_folders_sync (groupwise_store, cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } @@ -1170,9 +1207,10 @@ create_junk_folder (CamelStore *store) static CamelFolderInfo* groupwise_create_folder (CamelStore *store, - const gchar *parent_name, - const gchar *folder_name, - GError **error) + const gchar *parent_name, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store); CamelGroupwiseStorePrivate *priv = groupwise_store->priv; @@ -1211,7 +1249,7 @@ groupwise_create_folder (CamelStore *store, parent_id = ""; if (!E_IS_GW_CONNECTION ( priv->cnc)) { - if (!groupwise_connect (CAMEL_SERVICE (store), error)) { + if (!groupwise_connect (CAMEL_SERVICE (store), cancellable, error)) { return NULL; } } @@ -1235,8 +1273,9 @@ groupwise_create_folder (CamelStore *store, static gboolean groupwise_delete_folder (CamelStore *store, - const gchar *folder_name, - GError **error) + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store); CamelGroupwiseStorePrivate *priv = groupwise_store->priv; @@ -1245,7 +1284,7 @@ groupwise_delete_folder (CamelStore *store, camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); - if (!camel_groupwise_store_connected (groupwise_store, error)) { + if (!camel_groupwise_store_connected (groupwise_store, cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); return FALSE; } @@ -1273,9 +1312,10 @@ groupwise_delete_folder (CamelStore *store, static gboolean groupwise_rename_folder (CamelStore *store, - const gchar *old_name, - const gchar *new_name, - GError **error) + const gchar *old_name, + const gchar *new_name, + GCancellable *cancellable, + GError **error) { CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store); CamelGroupwiseStorePrivate *priv = groupwise_store->priv; @@ -1293,7 +1333,7 @@ groupwise_rename_folder (CamelStore *store, camel_service_lock (CAMEL_SERVICE (groupwise_store), CAMEL_SERVICE_REC_CONNECT_LOCK); - if (!camel_groupwise_store_connected (groupwise_store, error)) { + if (!camel_groupwise_store_connected (groupwise_store, cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (groupwise_store), CAMEL_SERVICE_REC_CONNECT_LOCK); return FALSE; } @@ -1386,9 +1426,13 @@ groupwise_base_url_lookup (CamelGroupwiseStorePrivate *priv) } static CamelFolder * -groupwise_get_trash (CamelStore *store, GError **error) +groupwise_get_trash (CamelStore *store, + GCancellable *cancellable, + GError **error) { - CamelFolder *folder = camel_store_get_folder(store, "Trash", 0, error); + CamelFolder *folder; + + folder = camel_store_get_folder(store, "Trash", 0, cancellable, error); if (folder) { CamelObject *object = CAMEL_OBJECT (folder); gchar *state = g_build_filename((CAMEL_GROUPWISE_STORE(store))->priv->storage_path, "folders", "Trash", "cmeta", NULL); @@ -1418,7 +1462,9 @@ groupwise_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError * * online. Based on an equivalient function in IMAP */ gboolean -camel_groupwise_store_connected (CamelGroupwiseStore *store, GError **error) +camel_groupwise_store_connected (CamelGroupwiseStore *store, + GCancellable *cancellable, + GError **error) { if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL && camel_service_connect ((CamelService *)store, error)) { @@ -1426,7 +1472,7 @@ camel_groupwise_store_connected (CamelGroupwiseStore *store, GError **error) CamelGroupwiseStorePrivate *priv = gw_store->priv; if (g_hash_table_size (priv->name_hash) == 0) - return groupwise_folders_sync ((CamelGroupwiseStore *) gw_store, error); + return groupwise_folders_sync ((CamelGroupwiseStore *) gw_store, cancellable, error); return TRUE; } diff --git a/camel/providers/groupwise/camel-groupwise-store.h b/camel/providers/groupwise/camel-groupwise-store.h index 2ebda32..7e901c3 100644 --- a/camel/providers/groupwise/camel-groupwise-store.h +++ b/camel/providers/groupwise/camel-groupwise-store.h @@ -76,19 +76,31 @@ struct _CamelGroupwiseStoreClass { CamelOfflineStoreClass parent_class; }; -GType camel_groupwise_store_get_type (void); -gchar * groupwise_get_name (CamelService *service, gboolean brief); - -/*IMplemented*/ -const gchar *camel_groupwise_store_container_id_lookup (CamelGroupwiseStore *gw_store, const gchar *folder_name); -const gchar *camel_groupwise_store_folder_lookup (CamelGroupwiseStore *gw_store, const gchar *container_id); -EGwConnection *cnc_lookup (CamelGroupwiseStorePrivate *priv); -gchar *storage_path_lookup (CamelGroupwiseStorePrivate *priv); -const gchar *groupwise_base_url_lookup (CamelGroupwiseStorePrivate *priv); -CamelFolderInfo * create_junk_folder (CamelStore *store); -gboolean camel_groupwise_store_connected (CamelGroupwiseStore *store, GError **error); -gboolean gw_store_reload_folder (CamelGroupwiseStore *store, CamelFolder *folder, guint32 flags, GError **error); -void groupwise_store_set_current_folder (CamelGroupwiseStore *groupwise_store, CamelFolder *folder); +GType camel_groupwise_store_get_type (void); +gchar * groupwise_get_name (CamelService *service, + gboolean brief); +const gchar * camel_groupwise_store_container_id_lookup + (CamelGroupwiseStore *store, + const gchar *folder_name); +const gchar * camel_groupwise_store_folder_lookup + (CamelGroupwiseStore *store, + const gchar *container_id); +EGwConnection * cnc_lookup (CamelGroupwiseStorePrivate *priv); +gchar * storage_path_lookup (CamelGroupwiseStorePrivate *priv); +const gchar * groupwise_base_url_lookup (CamelGroupwiseStorePrivate *priv); +CamelFolderInfo * + create_junk_folder (CamelStore *store); +gboolean camel_groupwise_store_connected (CamelGroupwiseStore *store, + GCancellable *cancellable, + GError **error); +gboolean gw_store_reload_folder (CamelGroupwiseStore *store, + CamelFolder *folder, + guint32 flags, + GCancellable *cancellable, + GError **error); +void groupwise_store_set_current_folder + (CamelGroupwiseStore *store, + CamelFolder *folder); G_END_DECLS diff --git a/camel/providers/groupwise/camel-groupwise-summary.c b/camel/providers/groupwise/camel-groupwise-summary.c index c1a0301..b155ddb 100644 --- a/camel/providers/groupwise/camel-groupwise-summary.c +++ b/camel/providers/groupwise/camel-groupwise-summary.c @@ -293,7 +293,9 @@ content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelM } static gboolean -gw_info_set_flags (CamelMessageInfo *info, guint32 flags, guint32 set) +gw_info_set_flags (CamelMessageInfo *info, + guint32 flags, + guint32 set) { guint32 old; CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info; @@ -357,7 +359,10 @@ gw_info_set_flags (CamelMessageInfo *info, guint32 flags, guint32 set) } void -camel_gw_summary_add_offline (CamelFolderSummary *summary, const gchar *uid, CamelMimeMessage *message, const CamelMessageInfo *info) +camel_gw_summary_add_offline (CamelFolderSummary *summary, + const gchar *uid, + CamelMimeMessage *message, + const CamelMessageInfo *info) { CamelGroupwiseMessageInfo *mi; const CamelFlag *flag; @@ -388,7 +393,9 @@ camel_gw_summary_add_offline (CamelFolderSummary *summary, const gchar *uid, Cam } void -camel_gw_summary_add_offline_uncached (CamelFolderSummary *summary, const gchar *uid, const CamelMessageInfo *info) +camel_gw_summary_add_offline_uncached (CamelFolderSummary *summary, + const gchar *uid, + const CamelMessageInfo *info) { CamelGroupwiseMessageInfo *mi; diff --git a/camel/providers/groupwise/camel-groupwise-summary.h b/camel/providers/groupwise/camel-groupwise-summary.h index fbe84b4..c0ed562 100644 --- a/camel/providers/groupwise/camel-groupwise-summary.h +++ b/camel/providers/groupwise/camel-groupwise-summary.h @@ -76,16 +76,22 @@ struct _CamelGroupwiseSummary { struct _CamelGroupwiseSummaryClass { CamelFolderSummaryClass parent_class; -} ; - -GType camel_groupwise_summary_get_type (void); - -CamelFolderSummary *camel_groupwise_summary_new (struct _CamelFolder *folder, const gchar *filename); - -void camel_gw_summary_add_offline (CamelFolderSummary *summary, const gchar *uid, CamelMimeMessage *messgae, const CamelMessageInfo *info); +}; -void camel_gw_summary_add_offline_uncached (CamelFolderSummary *summary, const gchar *uid, const CamelMessageInfo *info); -void groupwise_summary_clear (CamelFolderSummary *summary, gboolean uncache); +GType camel_groupwise_summary_get_type (void); +CamelFolderSummary * + camel_groupwise_summary_new (CamelFolder *folder, + const gchar *filename); +void camel_gw_summary_add_offline (CamelFolderSummary *summary, + const gchar *uid, + CamelMimeMessage *messgae, + const CamelMessageInfo *info); +void camel_gw_summary_add_offline_uncached + (CamelFolderSummary *summary, + const gchar *uid, + const CamelMessageInfo *info); +void groupwise_summary_clear (CamelFolderSummary *summary, + gboolean uncache); G_END_DECLS diff --git a/camel/providers/groupwise/camel-groupwise-transport.c b/camel/providers/groupwise/camel-groupwise-transport.c index ebccd13..99e621a 100644 --- a/camel/providers/groupwise/camel-groupwise-transport.c +++ b/camel/providers/groupwise/camel-groupwise-transport.c @@ -40,6 +40,7 @@ G_DEFINE_TYPE (CamelGroupwiseTransport, camel_groupwise_transport, CAMEL_TYPE_TR static gboolean groupwise_transport_connect (CamelService *service, + GCancellable *cancellable, GError **error) { return TRUE; @@ -64,6 +65,7 @@ groupwise_send_to (CamelTransport *transport, CamelMimeMessage *message, CamelAddress *from, CamelAddress *recipients, + GCancellable *cancellable, GError **error) { CamelService *service; @@ -92,7 +94,7 @@ groupwise_send_to (CamelTransport *transport, CAMEL_URL_HIDE_PARAMS | CAMEL_URL_HIDE_AUTH) ); - camel_operation_start (NULL, _("Sending Message") ); + camel_operation_start (cancellable, _("Sending Message") ); /*camel groupwise store and cnc*/ store = camel_session_get_store (service->session, url, NULL); @@ -111,7 +113,7 @@ groupwise_send_to (CamelTransport *transport, cnc = cnc_lookup (priv); if (!cnc) { g_warning ("||| Eh!!! Failure |||\n"); - camel_operation_end (NULL); + camel_operation_end (cancellable); g_set_error ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE, @@ -138,7 +140,7 @@ groupwise_send_to (CamelTransport *transport, status = e_gw_connection_send_item (cnc, item, &sent_item_list); if (status != E_GW_CONNECTION_STATUS_OK) { g_warning (" Error Sending mail"); - camel_operation_end (NULL); + camel_operation_end (cancellable); e_gw_item_set_link_info (item, NULL); g_object_unref (item); if (temp_item) @@ -167,7 +169,7 @@ groupwise_send_to (CamelTransport *transport, g_object_unref (temp_item); g_object_unref (item); - camel_operation_end (NULL); + camel_operation_end (cancellable); return TRUE; } diff --git a/camel/providers/groupwise/camel-groupwise-utils.c b/camel/providers/groupwise/camel-groupwise-utils.c index 2372914..c6bf0f6 100644 --- a/camel/providers/groupwise/camel-groupwise-utils.c +++ b/camel/providers/groupwise/camel-groupwise-utils.c @@ -424,7 +424,6 @@ camel_groupwise_util_item_from_message (EGwConnection *cnc, CamelMimeMessage *me mp = (CamelMultipart *)camel_medium_get_content (CAMEL_MEDIUM (message)); if (!mp) { g_warning ("ERROR: Could not get content object"); - camel_operation_end (NULL); return NULL; } @@ -465,14 +464,14 @@ camel_groupwise_util_item_from_message (EGwConnection *cnc, CamelMimeMessage *me filtered_stream = g_object_ref (content); } - camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL); - camel_stream_flush (filtered_stream, NULL); + camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL, NULL); + camel_stream_flush (filtered_stream, NULL, NULL); g_object_unref (filtered_stream); - camel_stream_write (content, "", 1, NULL); + camel_stream_write (content, "", 1, NULL, NULL); e_gw_item_set_message (item, (const gchar *)byte_array->data); } else { - camel_data_wrapper_decode_to_stream (dw, content, NULL); + camel_data_wrapper_decode_to_stream (dw, content, NULL, NULL); send_as_attachment (cnc, item, content, type, dw, NULL, NULL, &attach_list); } @@ -669,7 +668,7 @@ do_multipart (EGwConnection *cnc, EGwItem *item, CamelMultipart *mp, GSList **at if (temp_part) { is_alternative = TRUE; temp_dw = camel_medium_get_content (CAMEL_MEDIUM (temp_part)); - camel_data_wrapper_write_to_stream (temp_dw, temp_content, NULL); + camel_data_wrapper_write_to_stream (temp_dw, temp_content, NULL, NULL); filename = camel_mime_part_get_filename (temp_part); disposition = camel_mime_part_get_disposition (temp_part); cid = camel_mime_part_get_content_id (temp_part); @@ -700,18 +699,18 @@ do_multipart (EGwConnection *cnc, EGwItem *item, CamelMultipart *mp, GSList **at filtered_stream = g_object_ref (content); } - camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL); - camel_stream_flush (filtered_stream, NULL); + camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL, NULL); + camel_stream_flush (filtered_stream, NULL, NULL); g_object_unref (filtered_stream); - camel_stream_write (content, "", 1, NULL); + camel_stream_write (content, "", 1, NULL, NULL); e_gw_item_set_message (item, (const gchar *) buffer->data); } else { filename = camel_mime_part_get_filename (part); disposition = camel_mime_part_get_disposition (part); content_id = camel_mime_part_get_content_id (part); - camel_data_wrapper_decode_to_stream (dw, content, NULL); + camel_data_wrapper_decode_to_stream (dw, content, NULL, NULL); send_as_attachment (cnc, item, content, type, dw, filename, content_id, attach_list); } diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c index 1f6c369..da91e7b 100644 --- a/camel/providers/imap/camel-imap-command.c +++ b/camel/providers/imap/camel-imap-command.c @@ -44,11 +44,13 @@ extern gint camel_verbose_debug; static gboolean imap_command_start (CamelImapStore *store, CamelFolder *folder, - const gchar *cmd, GError **error); + const gchar *cmd, GCancellable *cancellable, + GError **error); static CamelImapResponse *imap_read_response (CamelImapStore *store, + GCancellable *cancellable, GError **error); static gchar *imap_read_untagged (CamelImapStore *store, gchar *line, - GError **error); + GCancellable *cancellable, GError **error); static gchar *imap_command_strdup_vprintf (CamelImapStore *store, const gchar *fmt, va_list ap); static gchar *imap_command_strdup_printf (CamelImapStore *store, @@ -59,6 +61,7 @@ static gchar *imap_command_strdup_printf (CamelImapStore *store, * @store: the IMAP store * @folder: The folder to perform the operation in (or %NULL if not * relevant). + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * @fmt: a sort of printf-style format string, followed by arguments * @@ -84,6 +87,7 @@ static gchar *imap_command_strdup_printf (CamelImapStore *store, CamelImapResponse * camel_imap_command (CamelImapStore *store, CamelFolder *folder, + GCancellable *cancellable, GError **error, const gchar *fmt, ...) { @@ -108,14 +112,14 @@ camel_imap_command (CamelImapStore *store, cmd = imap_command_strdup_printf (store, "SELECT %F", full_name); } - if (!imap_command_start (store, folder, cmd, error)) { + if (!imap_command_start (store, folder, cmd, cancellable, error)) { g_free (cmd); camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } g_free (cmd); - return imap_read_response (store, error); + return imap_read_response (store, cancellable, error); } /** @@ -123,6 +127,7 @@ camel_imap_command (CamelImapStore *store, * @store: the IMAP store * @folder: The folder to perform the operation in (or %NULL if not * relevant). + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * @fmt: a sort of printf-style format string, followed by arguments * @@ -155,6 +160,7 @@ camel_imap_command (CamelImapStore *store, gboolean camel_imap_command_start (CamelImapStore *store, CamelFolder *folder, + GCancellable *cancellable, GError **error, const gchar *fmt, ...) { @@ -167,7 +173,7 @@ camel_imap_command_start (CamelImapStore *store, va_end (ap); camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); - ok = imap_command_start (store, folder, cmd, error); + ok = imap_command_start (store, folder, cmd, cancellable, error); g_free (cmd); if (!ok) @@ -179,6 +185,7 @@ static gboolean imap_command_start (CamelImapStore *store, CamelFolder *folder, const gchar *cmd, + GCancellable *cancellable, GError **error) { gssize nwritten; @@ -204,11 +211,14 @@ imap_command_start (CamelImapStore *store, CamelImapResponse *response; GError *local_error = NULL; - response = camel_imap_command (store, folder, error, NULL); + response = camel_imap_command ( + store, folder, cancellable, error, NULL); if (!response) return FALSE; - camel_imap_folder_selected (folder, response, &local_error); + /* FIXME Pass a GCancellable */ + camel_imap_folder_selected ( + folder, response, NULL, &local_error); camel_imap_response_free (store, response); if (local_error != NULL) { @@ -276,6 +286,7 @@ CamelImapResponse * camel_imap_command_continuation (CamelImapStore *store, const gchar *cmd, gsize cmdlen, + GCancellable *cancellable, GError **error) { if (!camel_imap_store_connected (store, error)) @@ -297,20 +308,21 @@ camel_imap_command_continuation (CamelImapStore *store, return NULL; } - if (camel_stream_write (store->ostream, cmd, cmdlen, error) == -1 || - camel_stream_write (store->ostream, "\r\n", 2, error) == -1) { + if (camel_stream_write (store->ostream, cmd, cmdlen, cancellable, error) == -1 || + camel_stream_write (store->ostream, "\r\n", 2, cancellable, error) == -1) { camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL); camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); return NULL; } - return imap_read_response (store, error); + return imap_read_response (store, cancellable, error); } /** * camel_imap_command_response: * @store: the IMAP store * @response: a pointer to pass back the response data in + * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * This reads a single tagged, untagged, or continuation response from @@ -323,13 +335,15 @@ camel_imap_command_continuation (CamelImapStore *store, * command lock will be unlocked. **/ CamelImapResponseType -camel_imap_command_response (CamelImapStore *store, gchar **response, - GError **error) +camel_imap_command_response (CamelImapStore *store, + gchar **response, + GCancellable *cancellable, + GError **error) { CamelImapResponseType type; gchar *respbuf; - if (camel_imap_store_readline (store, &respbuf, error) < 0) { + if (camel_imap_store_readline (store, &respbuf, cancellable, error) < 0) { camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); return CAMEL_IMAP_RESPONSE_ERROR; } @@ -360,7 +374,8 @@ camel_imap_command_response (CamelImapStore *store, gchar **response, /* Read the rest of the response. */ type = CAMEL_IMAP_RESPONSE_UNTAGGED; - respbuf = imap_read_untagged (store, respbuf, error); + respbuf = imap_read_untagged ( + store, respbuf, cancellable, error); if (!respbuf) type = CAMEL_IMAP_RESPONSE_ERROR; else if (!g_ascii_strncasecmp (respbuf, "* OK [ALERT]", 12) @@ -394,7 +409,9 @@ camel_imap_command_response (CamelImapStore *store, gchar **response, } static CamelImapResponse * -imap_read_response (CamelImapStore *store, GError **error) +imap_read_response (CamelImapStore *store, + GCancellable *cancellable, + GError **error) { CamelImapResponse *response; CamelImapResponseType type; @@ -414,8 +431,9 @@ imap_read_response (CamelImapStore *store, GError **error) } */ response->untagged = g_ptr_array_new (); - while ((type = camel_imap_command_response (store, &respbuf, error)) - == CAMEL_IMAP_RESPONSE_UNTAGGED) + while ((type = camel_imap_command_response ( + store, &respbuf, cancellable, error)) + == CAMEL_IMAP_RESPONSE_UNTAGGED) g_ptr_array_add (response->untagged, respbuf); if (type == CAMEL_IMAP_RESPONSE_ERROR) { @@ -464,7 +482,10 @@ imap_read_response (CamelImapStore *store, GError **error) * of literals. */ static gchar * -imap_read_untagged (CamelImapStore *store, gchar *line, GError **error) +imap_read_untagged (CamelImapStore *store, + gchar *line, + GCancellable *cancellable, + GError **error) { gint fulllen, ldigits, nread, n, i, sexp = 0; guint length; @@ -514,7 +535,8 @@ imap_read_untagged (CamelImapStore *store, gchar *line, GError **error) n = camel_stream_read ( store->istream, str->str + nread + 1, - length - nread, error); + length - nread, + cancellable, error); if (n == -1) { camel_service_disconnect ( CAMEL_SERVICE (store), FALSE, NULL); @@ -583,7 +605,7 @@ imap_read_untagged (CamelImapStore *store, gchar *line, GError **error) /* Read the next line. */ do { - if (camel_imap_store_readline (store, &line, error) < 0) + if (camel_imap_store_readline (store, &line, cancellable, error) < 0) goto lose; /* MAJOR HACK ALERT, gropuwise sometimes sends an extra blank line after literals, check that here @@ -657,8 +679,10 @@ camel_imap_response_free (CamelImapStore *store, CamelImapResponse *response) if (response->folder) { if (exists > 0 || expunged) { /* Update the summary */ - camel_imap_folder_changed (response->folder, - exists, expunged, NULL); + /* FIXME Pass a GCancellable */ + camel_imap_folder_changed ( + response->folder, exists, + expunged, NULL, NULL); if (expunged) g_array_free (expunged, TRUE); } diff --git a/camel/providers/imap/camel-imap-command.h b/camel/providers/imap/camel-imap-command.h index 76b8f3d..4c82f5b 100644 --- a/camel/providers/imap/camel-imap-command.h +++ b/camel/providers/imap/camel-imap-command.h @@ -45,34 +45,41 @@ struct _CamelImapResponse { gchar *status; }; -CamelImapResponse *camel_imap_command (CamelImapStore *store, - CamelFolder *folder, - GError **error, - const gchar *fmt, ...); -CamelImapResponse *camel_imap_command_continuation (CamelImapStore *store, - const gchar *cmd, - gsize cmdlen, - GError **error); - -void camel_imap_response_free (CamelImapStore *store, - CamelImapResponse *response); -void camel_imap_response_free_without_processing (CamelImapStore *store, - CamelImapResponse *response); -gchar *camel_imap_response_extract (CamelImapStore *store, - CamelImapResponse *response, - const gchar *type, - GError **error); -gchar *camel_imap_response_extract_continuation (CamelImapStore *store, - CamelImapResponse *response, - GError **error); - -gboolean camel_imap_command_start (CamelImapStore *store, - CamelFolder *folder, - GError **error, - const gchar *fmt, ...); -CamelImapResponseType camel_imap_command_response (CamelImapStore *store, - gchar **response, - GError **error); +CamelImapResponse * + camel_imap_command (CamelImapStore *store, + CamelFolder *folder, + GCancellable *cancellable, + GError **error, + const gchar *fmt, ...); +CamelImapResponse * + camel_imap_command_continuation (CamelImapStore *store, + const gchar *cmd, + gsize cmdlen, + GCancellable *cancellable, + GError **error); +void camel_imap_response_free (CamelImapStore *store, + CamelImapResponse *response); +void camel_imap_response_free_without_processing + (CamelImapStore *store, + CamelImapResponse *response); +gchar * camel_imap_response_extract (CamelImapStore *store, + CamelImapResponse *response, + const gchar *type, + GError **error); +gchar * camel_imap_response_extract_continuation + (CamelImapStore *store, + CamelImapResponse *response, + GError **error); +gboolean camel_imap_command_start (CamelImapStore *store, + CamelFolder *folder, + GCancellable *cancellable, + GError **error, + const gchar *fmt, ...); +CamelImapResponseType + camel_imap_command_response (CamelImapStore *store, + gchar **response, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index f16252a..d1b1ca2 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -71,25 +71,26 @@ enum { extern gint camel_application_is_exiting; -static gboolean imap_rescan (CamelFolder *folder, gint exists, GError **error); -static gboolean imap_refresh_info (CamelFolder *folder, GError **error); +static gboolean imap_rescan (CamelFolder *folder, gint exists, GCancellable *cancellable, GError **error); +static gboolean imap_refresh_info (CamelFolder *folder, GCancellable *cancellable, GError **error); static gboolean imap_sync_offline (CamelFolder *folder, GError **error); -static gboolean imap_sync (CamelFolder *folder, gboolean expunge, GError **error); -static gboolean imap_expunge_uids_online (CamelFolder *folder, GPtrArray *uids, GError **error); -static gboolean imap_expunge_uids_offline (CamelFolder *folder, GPtrArray *uids, GError **error); -static gboolean imap_expunge (CamelFolder *folder, GError **error); +static gboolean imap_sync (CamelFolder *folder, gboolean expunge, GCancellable *cancellable, GError **error); +static gboolean imap_expunge_uids_online (CamelFolder *folder, GPtrArray *uids, GCancellable *cancellable, GError **error); +static gboolean imap_expunge_uids_offline (CamelFolder *folder, GPtrArray *uids, GCancellable *cancellable, GError **error); +static gboolean imap_expunge (CamelFolder *folder, GCancellable *cancellable, GError **error); /*static void imap_cache_message (CamelDiscoFolder *disco_folder, const gchar *uid, GError **error);*/ static void imap_rename (CamelFolder *folder, const gchar *new); static GPtrArray * imap_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, GError **error); static gchar * imap_get_filename (CamelFolder *folder, const gchar *uid, GError **error); /* message manipulation */ -static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid, +static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid, GCancellable *cancellable, GError **error); -static gboolean imap_sync_message (CamelFolder *folder, const gchar *uid, +static gboolean imap_sync_message (CamelFolder *folder, const gchar *uid, GCancellable *cancellable, GError **error); static gboolean imap_append_online (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error); static gboolean imap_append_offline (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, @@ -98,10 +99,12 @@ static gboolean imap_append_offline (CamelFolder *folder, CamelMimeMessage *mess 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); /* searching */ @@ -125,7 +128,7 @@ static gboolean imap_transfer_messages (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, gboolean can_call_sync, - GError **error); + GCancellable *cancellable, GError **error); #ifdef G_OS_WIN32 /* The strtok() in Microsoft's C library is MT-safe (but still uses @@ -308,7 +311,10 @@ camel_imap_folder_init (CamelImapFolder *imap_folder) } static void -replay_offline_journal (CamelImapStore *imap_store, CamelImapFolder *imap_folder, GError **error) +replay_offline_journal (CamelImapStore *imap_store, + CamelImapFolder *imap_folder, + GCancellable *cancellable, + GError **error) { CamelIMAPJournal *imap_journal; @@ -327,7 +333,8 @@ replay_offline_journal (CamelImapStore *imap_store, CamelImapFolder *imap_folder if (!imap_journal->rp_in_progress) { imap_journal->rp_in_progress++; - camel_offline_journal_replay (imap_folder->journal, error); + camel_offline_journal_replay ( + imap_folder->journal, cancellable, error); camel_imap_journal_close_folders (imap_journal); camel_offline_journal_write (imap_folder->journal, error); @@ -414,9 +421,6 @@ camel_imap_folder_new (CamelStore *parent, const gchar *folder_name, imap_folder->search = camel_imap_search_new (folder_dir); - /* do not do that here, as other folders for 'transfer' might not be opened yet - replay_offline_journal (imap_store, imap_folder, ex);*/ - return folder; } @@ -477,6 +481,7 @@ camel_imap_folder_set_check_folder (CamelImapFolder *imap_folder, gboolean camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response, + GCancellable *cancellable, GError **error) { CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); @@ -532,7 +537,8 @@ camel_imap_folder_selected (CamelFolder *folder, camel_imap_message_cache_clear (imap_folder->cache); CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock); imap_folder->need_rescan = FALSE; - return camel_imap_folder_changed (folder, exists, NULL, error); + return camel_imap_folder_changed ( + folder, exists, NULL, cancellable, error); } /* If we've lost messages, we have to rescan everything */ @@ -553,7 +559,7 @@ camel_imap_folder_selected (CamelFolder *folder, * is selected, and we don't want camel_imap_command * to worry about it.) */ - response = camel_imap_command (store, NULL, error, "FETCH %d UID", count); + response = camel_imap_command (store, NULL, cancellable, error, "FETCH %d UID", count); if (!response) return FALSE; uid = 0; @@ -587,13 +593,14 @@ camel_imap_folder_selected (CamelFolder *folder, /* Now rescan if we need to */ if (imap_folder->need_rescan) - return imap_rescan (folder, exists, error); + return imap_rescan (folder, exists, cancellable, error); /* If we don't need to rescan completely, but new messages * have been added, find out about them. */ if (exists > count) - camel_imap_folder_changed (folder, exists, NULL, error); + camel_imap_folder_changed ( + folder, exists, NULL, cancellable, error); /* And we're done. */ @@ -645,7 +652,11 @@ imap_rename (CamelFolder *folder, const gchar *new) /* called with connect_lock locked */ static gboolean -get_folder_status (CamelFolder *folder, guint32 *total, guint32 *unread, GError **error) +get_folder_status (CamelFolder *folder, + guint32 *total, + guint32 *unread, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelImapStore *imap_store; @@ -660,7 +671,7 @@ get_folder_status (CamelFolder *folder, guint32 *total, guint32 *unread, GError imap_store = CAMEL_IMAP_STORE (parent_store); - response = camel_imap_command (imap_store, folder, error, "STATUS %F (MESSAGES UNSEEN)", full_name); + response = camel_imap_command (imap_store, folder, cancellable, error, "STATUS %F (MESSAGES UNSEEN)", full_name); if (response) { gint i; @@ -724,6 +735,7 @@ get_folder_status (CamelFolder *folder, guint32 *total, guint32 *unread, GError static gboolean imap_refresh_info (CamelFolder *folder, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -757,15 +769,18 @@ imap_refresh_info (CamelFolder *folder, goto done; /* try to store local changes first, as the summary contains new local messages */ - replay_offline_journal (imap_store, imap_folder, &local_error); + replay_offline_journal ( + imap_store, imap_folder, cancellable, &local_error); full_name = camel_folder_get_full_name (folder); if (imap_store->current_folder != folder || g_ascii_strcasecmp (full_name, "INBOX") == 0) { - response = camel_imap_command (imap_store, folder, &local_error, NULL); + response = camel_imap_command (imap_store, folder, cancellable, &local_error, NULL); if (response) { - camel_imap_folder_selected (folder, response, &local_error); + camel_imap_folder_selected ( + folder, response, + cancellable, &local_error); camel_imap_response_free (imap_store, response); } } else if (imap_folder->need_rescan) { @@ -773,7 +788,9 @@ imap_refresh_info (CamelFolder *folder, * a NOOP to give the server a chance to tell us about new * messages. */ - imap_rescan (folder, camel_folder_summary_count (folder->summary), &local_error); + imap_rescan ( + folder, camel_folder_summary_count ( + folder->summary), cancellable, &local_error); check_rescan = 0; } else { #if 0 @@ -784,7 +801,7 @@ imap_refresh_info (CamelFolder *folder, camel_imap_response_free (imap_store, response); } #endif - response = camel_imap_command (imap_store, folder, &local_error, "NOOP"); + response = camel_imap_command (imap_store, folder, cancellable, &local_error, "NOOP"); camel_imap_response_free (imap_store, response); } @@ -813,7 +830,7 @@ imap_refresh_info (CamelFolder *folder, /* Check whether there are changes in total/unread messages in the folders and if so, then rescan whole summary */ - if (get_folder_status (folder, &server_total, &server_unread, &local_error)) { + if (get_folder_status (folder, &server_total, &server_unread, cancellable, &local_error)) { total = camel_folder_summary_count (folder->summary); unread = folder->summary->unread_count; @@ -824,7 +841,9 @@ imap_refresh_info (CamelFolder *folder, } if (check_rescan) - imap_rescan (folder, camel_folder_summary_count (folder->summary), &local_error); + imap_rescan ( + folder, camel_folder_summary_count ( + folder->summary), cancellable, &local_error); } done: camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); @@ -919,7 +938,10 @@ merge_custom_flags (CamelMessageInfo *mi, const gchar *custom_flags) /* Called with the store's connect_lock locked */ static gboolean -imap_rescan (CamelFolder *folder, gint exists, GError **error) +imap_rescan (CamelFolder *folder, + gint exists, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); @@ -951,33 +973,34 @@ imap_rescan (CamelFolder *folder, gint exists, GError **error) summary_len = camel_folder_summary_count (folder->summary); if (summary_len == 0) { if (exists) - return camel_imap_folder_changed (folder, exists, NULL, error); + return camel_imap_folder_changed ( + folder, exists, NULL, cancellable, error); return TRUE; } /* Check UIDs and flags of all messages we already know of. */ camel_operation_start ( - NULL, _("Scanning for changed messages in %s"), + 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 (NULL); + camel_operation_end (cancellable); return TRUE; } ok = camel_imap_command_start ( - store, folder, error, + store, folder, cancellable, error, "UID FETCH 1:%s (FLAGS)", uid); g_free (uid); if (!ok) { - camel_operation_end (NULL); + camel_operation_end (cancellable); return FALSE; } new = g_malloc0 (summary_len * sizeof (*new)); summary_got = 0; - while ((type = camel_imap_command_response (store, &resp, error)) == CAMEL_IMAP_RESPONSE_UNTAGGED && !camel_application_is_exiting) { + while ((type = camel_imap_command_response (store, &resp, cancellable, error)) == CAMEL_IMAP_RESPONSE_UNTAGGED && !camel_application_is_exiting) { GData *data; gchar *uid; guint32 flags; @@ -996,7 +1019,9 @@ imap_rescan (CamelFolder *folder, gint exists, GError **error) continue; } - camel_operation_progress (NULL, ++summary_got * 100 / summary_len); + camel_operation_progress ( + cancellable, ++summary_got * 100 / summary_len); + new[seq - 1].uid = g_strdup (uid); new[seq - 1].flags = flags; new[seq - 1].custom_flags = g_strdup (g_datalist_get_data (&data, "CUSTOM.FLAGS")); @@ -1004,12 +1029,14 @@ imap_rescan (CamelFolder *folder, gint exists, GError **error) } if (summary_got == 0 && summary_len == 0) { - camel_operation_end (NULL); + camel_operation_end (cancellable); camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); g_free (new); return TRUE; } - camel_operation_end (NULL); + + camel_operation_end (cancellable); + if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) { for (i = 0; i < summary_len && new[i].uid; i++) { g_free (new[i].uid); @@ -1231,7 +1258,8 @@ imap_rescan (CamelFolder *folder, gint exists, GError **error) } /* And finally update the summary. */ - success = camel_imap_folder_changed (folder, exists, removed, error); + success = camel_imap_folder_changed ( + folder, exists, removed, cancellable, error); g_array_free (removed, TRUE); return success; @@ -1445,6 +1473,7 @@ static void move_messages (CamelFolder *src_folder, GPtrArray *uids, CamelFolder *des_folder, + GCancellable *cancellable, GError **error) { g_return_if_fail (src_folder != NULL); @@ -1456,16 +1485,19 @@ move_messages (CamelFolder *src_folder, /* moving to the same folder means expunge only */ 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, error)) + if (!imap_transfer_messages ( + src_folder, uids, des_folder, NULL, + FALSE, FALSE, cancellable, error)) return; } - camel_imap_expunge_uids_only (src_folder, uids, error); + camel_imap_expunge_uids_only (src_folder, uids, cancellable, error); } static gboolean imap_sync (CamelFolder *folder, gboolean expunge, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -1486,7 +1518,7 @@ imap_sync (CamelFolder *folder, if (folder->permanent_flags == 0 || CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) { if (expunge) { - if (!imap_expunge (folder, error)) + if (!imap_expunge (folder, cancellable, error)) return FALSE; } return imap_sync_offline (folder, error); @@ -1495,7 +1527,7 @@ imap_sync (CamelFolder *folder, camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); /* write local changes first */ - replay_offline_journal (store, imap_folder, NULL); + replay_offline_journal (store, imap_folder, cancellable, NULL); /* Find a message with changed flags, find all of the other * messages like it, sync them as a group, mark them as @@ -1512,7 +1544,8 @@ imap_sync (CamelFolder *folder, real_trash = folder; g_object_ref (real_trash); } else { - real_trash = camel_store_get_trash (parent_store, NULL); + real_trash = camel_store_get_trash ( + parent_store, cancellable, NULL); if (!store->real_trash_path && real_trash) { /* failed to open real trash */ @@ -1531,7 +1564,8 @@ imap_sync (CamelFolder *folder, /* syncing the junk, but cannot move messages to itself, thus do nothing */ real_junk = NULL; } else { - real_junk = camel_store_get_junk (parent_store, NULL); + real_junk = camel_store_get_junk ( + parent_store, cancellable, NULL); if (!store->real_junk_path && real_junk) { /* failed to open real junk */ @@ -1605,7 +1639,7 @@ imap_sync (CamelFolder *folder, g_free (flaglist); flaglist = strdup ("(\\Seen)"); - response = camel_imap_command (store, folder, &local_error, + response = camel_imap_command (store, folder, cancellable, &local_error, "UID STORE %s +FLAGS.SILENT %s", set, flaglist); if (response) @@ -1620,7 +1654,7 @@ imap_sync (CamelFolder *folder, /* Note: to 'unset' flags, use -FLAGS.SILENT () */ if (local_error == NULL) { - response = camel_imap_command (store, folder, &local_error, + response = camel_imap_command (store, folder, cancellable, &local_error, "UID STORE %s %sFLAGS.SILENT %s", set, unset ? "-" : "", flaglist); } @@ -1680,9 +1714,13 @@ imap_sync (CamelFolder *folder, } if (local_error == NULL) - move_messages (folder, deleted_uids, real_trash, &local_error); + move_messages ( + folder, deleted_uids, real_trash, + cancellable, &local_error); if (local_error == NULL) - move_messages (folder, junked_uids, real_junk, &local_error); + move_messages ( + folder, junked_uids, real_junk, + cancellable, &local_error); if (deleted_uids) { g_ptr_array_foreach (deleted_uids, (GFunc) camel_pstring_free, NULL); @@ -1698,7 +1736,7 @@ imap_sync (CamelFolder *folder, g_object_unref (real_junk); if (expunge && local_error == NULL) - imap_expunge (folder, &local_error); + imap_expunge (folder, cancellable, &local_error); if (local_error != NULL) g_propagate_error (error, local_error); @@ -1733,6 +1771,7 @@ uid_compar (gconstpointer va, gconstpointer vb) static gboolean imap_expunge_uids_offline (CamelFolder *folder, GPtrArray *uids, + GCancellable *cancellable, GError **error) { CamelFolderChangeInfo *changes; @@ -1773,6 +1812,7 @@ imap_expunge_uids_offline (CamelFolder *folder, static gboolean imap_expunge_uids_online (CamelFolder *folder, GPtrArray *uids, + GCancellable *cancellable, GError **error) { CamelImapStore *store; @@ -1795,7 +1835,7 @@ imap_expunge_uids_online (CamelFolder *folder, camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); if ((store->capabilities & IMAP_CAPABILITY_UIDPLUS) == 0) { - if (!CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, 0, error)) { + if (!CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, 0, cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); return FALSE; } @@ -1805,7 +1845,7 @@ imap_expunge_uids_online (CamelFolder *folder, while (uid < uids->len) { set = imap_uid_array_to_set (folder->summary, uids, uid, UID_SET_LIMIT, &uid); - response = camel_imap_command (store, folder, error, + response = camel_imap_command (store, folder, cancellable, error, "UID STORE %s +FLAGS.SILENT (\\Deleted)", set); if (response) @@ -1820,7 +1860,7 @@ imap_expunge_uids_online (CamelFolder *folder, GError *local_error = NULL; response = camel_imap_command ( - store, folder, &local_error, + store, folder, cancellable, &local_error, "UID EXPUNGE %s", set); if (local_error != NULL) { @@ -1836,7 +1876,7 @@ imap_expunge_uids_online (CamelFolder *folder, } if (full_expunge) - response = camel_imap_command (store, folder, NULL, "EXPUNGE"); + response = camel_imap_command (store, folder, cancellable, NULL, "EXPUNGE"); if (response) camel_imap_response_free (store, response); @@ -1867,6 +1907,7 @@ imap_expunge_uids_online (CamelFolder *folder, static gboolean imap_expunge (CamelFolder *folder, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -1883,7 +1924,8 @@ imap_expunge (CamelFolder *folder, CamelFolder *trash; GError *local_error = NULL; - trash = camel_store_get_trash (parent_store, &local_error); + trash = camel_store_get_trash ( + parent_store, cancellable, &local_error); if (local_error == NULL && trash && (folder == trash || g_ascii_strcasecmp (full_name, camel_folder_get_full_name (trash)) == 0)) { /* it's a real trash folder, thus get all mails from there */ @@ -1901,9 +1943,11 @@ imap_expunge (CamelFolder *folder, return TRUE; if (CAMEL_OFFLINE_STORE (parent_store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL) - success = imap_expunge_uids_online (folder, uids, error); + success = imap_expunge_uids_online ( + folder, uids, cancellable, error); else - success = imap_expunge_uids_offline (folder, uids, error); + success = imap_expunge_uids_offline ( + folder, uids, cancellable, error); g_ptr_array_foreach (uids, (GFunc) camel_pstring_free, NULL); g_ptr_array_free (uids, TRUE); @@ -1914,6 +1958,7 @@ imap_expunge (CamelFolder *folder, gboolean camel_imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -1930,7 +1975,8 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder, return TRUE; if (store->capabilities & IMAP_CAPABILITY_UIDPLUS) - return imap_expunge_uids_online (folder, uids, error); + return imap_expunge_uids_online ( + folder, uids, cancellable, error); /* If we don't have UID EXPUNGE we need to avoid expunging any * of the wrong messages. So we search for deleted messages, @@ -1940,12 +1986,12 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder, camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); - if (!CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, 0, error)) { + if (!CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, 0, cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); return FALSE; } - response = camel_imap_command (store, folder, error, "UID SEARCH DELETED"); + response = camel_imap_command (store, folder, cancellable, error, "UID SEARCH DELETED"); if (!response) { camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); return FALSE; @@ -2004,7 +2050,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder, while (uid < keep_uids->len) { uidset = imap_uid_array_to_set (folder->summary, keep_uids, uid, UID_SET_LIMIT, &uid); - response = camel_imap_command (store, folder, error, + response = camel_imap_command (store, folder, cancellable, error, "UID STORE %s -FLAGS.SILENT (\\Deleted)", uidset); @@ -2028,7 +2074,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder, while (uid < mark_uids->len) { uidset = imap_uid_array_to_set (folder->summary, mark_uids, uid, UID_SET_LIMIT, &uid); - response = camel_imap_command (store, folder, error, + response = camel_imap_command (store, folder, cancellable, error, "UID STORE %s +FLAGS.SILENT (\\Deleted)", uidset); @@ -2048,7 +2094,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder, } /* Do the actual expunging */ - response = camel_imap_command (store, folder, NULL, "EXPUNGE"); + response = camel_imap_command (store, folder, cancellable, NULL, "EXPUNGE"); if (response) camel_imap_response_free (store, response); @@ -2060,7 +2106,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder, while (uid < keep_uids->len) { uidset = imap_uid_array_to_set (folder->summary, keep_uids, uid, UID_SET_LIMIT, &uid); - response = camel_imap_command (store, folder, NULL, + response = camel_imap_command (store, folder, cancellable, NULL, "UID STORE %s +FLAGS.SILENT (\\Deleted)", uidset); @@ -2083,6 +2129,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder, gboolean camel_imap_expunge_uids_only (CamelFolder *folder, GPtrArray *uids, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -2095,9 +2142,11 @@ camel_imap_expunge_uids_only (CamelFolder *folder, g_return_val_if_fail (uids != NULL, FALSE); if (CAMEL_OFFLINE_STORE (parent_store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL) - return camel_imap_expunge_uids_resyncing (folder, uids, error); + return camel_imap_expunge_uids_resyncing ( + folder, uids, cancellable, error); else - return imap_expunge_uids_offline (folder, uids, error); + return imap_expunge_uids_offline ( + folder, uids, cancellable, error); } static gchar * @@ -2130,7 +2179,8 @@ imap_append_offline (CamelFolder *folder, uid = get_temp_uid (); - camel_imap_summary_add_offline (folder->summary, uid, message, info); + camel_imap_summary_add_offline ( + folder->summary, uid, message, info); CAMEL_IMAP_FOLDER_REC_LOCK (folder, cache_lock); camel_imap_message_cache_insert_wrapper ( cache, uid, "", CAMEL_DATA_WRAPPER (message)); @@ -2177,6 +2227,7 @@ do_append (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **uid, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -2209,7 +2260,7 @@ do_append (CamelFolder *folder, camel_stream_filter_add ( CAMEL_STREAM_FILTER (streamfilter), crlf_filter); camel_data_wrapper_write_to_stream ( - CAMEL_DATA_WRAPPER (message), streamfilter, NULL); + CAMEL_DATA_WRAPPER (message), streamfilter, cancellable, NULL); g_object_unref (streamfilter); g_object_unref (crlf_filter); g_object_unref (memstream); @@ -2229,7 +2280,7 @@ retry: full_name = camel_folder_get_full_name (folder); response = camel_imap_command ( - store, NULL, &local_error, "APPEND %F%s%s {%d}", + store, NULL, cancellable, &local_error, "APPEND %F%s%s {%d}", full_name, flagstr ? " " : "", flagstr ? flagstr : "", ba->len); g_free (flagstr); @@ -2252,7 +2303,7 @@ retry: } /* send the rest of our data - the mime message */ - response2 = camel_imap_command_continuation (store, (const gchar *) ba->data, ba->len, error); + response2 = camel_imap_command_continuation (store, (const gchar *) ba->data, ba->len, cancellable, error); g_byte_array_free (ba, TRUE); /* free it only after message is sent. This may cause more FETCHes. */ @@ -2286,6 +2337,7 @@ imap_append_online (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -2299,11 +2351,12 @@ imap_append_online (CamelFolder *folder, store = CAMEL_IMAP_STORE (parent_store); if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) { - return imap_append_offline (folder, message, info, appended_uid, error); + return imap_append_offline ( + folder, message, info, appended_uid, error); } count = camel_folder_summary_count (folder->summary); - response = do_append (folder, message, info, &uid, error); + response = do_append (folder, message, info, &uid, cancellable, error); if (!response) return FALSE; @@ -2329,7 +2382,7 @@ imap_append_online (CamelFolder *folder, camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); if (store->current_folder != folder || camel_folder_summary_count (folder->summary) == count) - success = imap_refresh_info (folder, error); + success = imap_refresh_info (folder, cancellable, error); camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); return success; @@ -2340,6 +2393,7 @@ camel_imap_append_resyncing (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -2350,7 +2404,7 @@ camel_imap_append_resyncing (CamelFolder *folder, parent_store = camel_folder_get_parent_store (folder); store = CAMEL_IMAP_STORE (parent_store); - response = do_append (folder, message, info, &uid, error); + response = do_append (folder, message, info, &uid, cancellable, error); if (!response) return FALSE; @@ -2381,6 +2435,7 @@ imap_transfer_offline (CamelFolder *source, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -2422,13 +2477,16 @@ imap_transfer_offline (CamelFolder *source, mi = camel_folder_summary_uid (source->summary, uid); g_return_val_if_fail (mi != NULL, FALSE); - message = camel_folder_get_message (source, uid, NULL); + message = camel_folder_get_message ( + source, uid, cancellable, NULL); if (message) { - camel_imap_summary_add_offline (dest->summary, destuid, message, mi); + camel_imap_summary_add_offline ( + dest->summary, destuid, message, mi); g_object_unref (CAMEL_OBJECT (message)); } else - camel_imap_summary_add_offline_uncached (dest->summary, destuid, mi); + camel_imap_summary_add_offline_uncached ( + dest->summary, destuid, mi); camel_imap_message_cache_copy (sc, uid, dc, destuid); camel_message_info_free (mi); @@ -2522,7 +2580,8 @@ handle_copyuid (CamelImapResponse *response, CamelFolder *source, static void handle_copyuid_copy_user_tags (CamelImapResponse *response, CamelFolder *source, - CamelFolder *destination) + CamelFolder *destination, + GCancellable *cancellable) { CamelStore *parent_store; gchar *validity, *srcset, *destset; @@ -2548,11 +2607,11 @@ handle_copyuid_copy_user_tags (CamelImapResponse *response, parent_store = camel_folder_get_parent_store (destination); camel_imap_response_free ( CAMEL_IMAP_STORE (parent_store), camel_imap_command ( - CAMEL_IMAP_STORE (parent_store), destination, NULL, "NOOP")); + CAMEL_IMAP_STORE (parent_store), destination, cancellable, NULL, "NOOP")); /* refresh folder's summary first, we copied messages there on the server, but do not know about it in a local summary */ - if (!imap_refresh_info (destination, NULL)) + if (!imap_refresh_info (destination, cancellable, NULL)) goto lose; src = imap_uid_set_to_array (source->summary, srcset); @@ -2633,6 +2692,7 @@ do_copy (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, gint delete_originals, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -2654,26 +2714,27 @@ do_copy (CamelFolder *source, /* use XGWMOVE only when none of the moving messages has set any user tag */ if ((store->capabilities & IMAP_CAPABILITY_XGWMOVE) != 0 && delete_originals && !any_has_user_tag (source, uidset)) { response = camel_imap_command ( - store, source, &local_error, - "UID XGWMOVE %s %F", uidset, - full_name); + store, source, cancellable, &local_error, + "UID XGWMOVE %s %F", uidset, full_name); /* returns only 'A00012 OK UID XGWMOVE completed' '* 2 XGWMOVE' so nothing useful */ camel_imap_response_free (store, response); } else { response = camel_imap_command ( - store, source, &local_error, - "UID COPY %s %F", uidset, - full_name); + store, source, cancellable, &local_error, + "UID COPY %s %F", uidset, full_name); if (response && (store->capabilities & IMAP_CAPABILITY_UIDPLUS)) handle_copyuid (response, source, destination); if (response) - handle_copyuid_copy_user_tags (response, source, destination); + handle_copyuid_copy_user_tags ( + response, source, destination, + cancellable); camel_imap_response_free (store, response); } if (local_error == NULL && delete_originals) { for (i=last;ipdata[i]); + camel_folder_delete_message ( + source, uids->pdata[i]); last = uid; } g_free (uidset); @@ -2694,6 +2755,7 @@ imap_transfer_messages (CamelFolder *source, GPtrArray **transferred_uids, gboolean delete_originals, gboolean can_call_sync, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -2707,10 +2769,10 @@ imap_transfer_messages (CamelFolder *source, if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) return imap_transfer_offline ( source, uids, dest, transferred_uids, - delete_originals, error); + delete_originals, cancellable, error); /* Sync message flags if needed. */ - if (can_call_sync && !imap_sync (source, FALSE, error)) + if (can_call_sync && !imap_sync (source, FALSE, cancellable, error)) return FALSE; count = camel_folder_summary_count (dest->summary); @@ -2718,13 +2780,13 @@ imap_transfer_messages (CamelFolder *source, qsort (uids->pdata, uids->len, sizeof (gpointer), uid_compar); /* Now copy the messages */ - if (!do_copy (source, uids, dest, delete_originals, error)) + if (!do_copy (source, uids, dest, delete_originals, cancellable, error)) return FALSE; /* Make the destination notice its new messages */ if (store->current_folder != dest || camel_folder_summary_count (dest->summary) == count) - success = imap_refresh_info (dest, error); + success = imap_refresh_info (dest, cancellable, error); /* FIXME */ if (transferred_uids) @@ -2739,9 +2801,12 @@ imap_transfer_online (CamelFolder *source, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error) { - return imap_transfer_messages (source, uids, dest, transferred_uids, delete_originals, TRUE, error); + return imap_transfer_messages ( + source, uids, dest, transferred_uids, + delete_originals, TRUE, cancellable, error); } gboolean @@ -2750,6 +2815,7 @@ camel_imap_transfer_resyncing (CamelFolder *source, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, + GCancellable *cancellable, GError **error) { GPtrArray *realuids; @@ -2785,7 +2851,9 @@ camel_imap_transfer_resyncing (CamelFolder *source, /* If we saw any real UIDs, do a COPY */ if (i != first) { - do_copy (source, realuids, dest, delete_originals, &local_error); + do_copy ( + source, realuids, dest, delete_originals, + cancellable, &local_error); g_ptr_array_set_size (realuids, 0); if (i == uids->len || local_error != NULL) break; @@ -2796,7 +2864,8 @@ camel_imap_transfer_resyncing (CamelFolder *source, !isdigit (*(guchar *)(uids->pdata[i])) && local_error == NULL) { uid = uids->pdata[i]; - message = camel_folder_get_message (source, uid, NULL); + message = camel_folder_get_message ( + source, uid, cancellable, NULL); if (!message) { /* Message must have been expunged */ i++; @@ -2805,7 +2874,9 @@ camel_imap_transfer_resyncing (CamelFolder *source, info = camel_folder_get_message_info (source, uid); g_return_val_if_fail (info != NULL, FALSE); - imap_append_online (dest, message, info, NULL, &local_error); + imap_append_online ( + dest, message, info, + NULL, cancellable, &local_error); camel_folder_free_message_info (source, info); g_object_unref (CAMEL_OBJECT (message)); if (delete_originals && local_error == NULL) @@ -2909,6 +2980,7 @@ imap_search_free (CamelFolder *folder, GPtrArray *uids) static CamelMimeMessage *get_message (CamelImapFolder *imap_folder, const gchar *uid, CamelMessageContentInfo *ci, + GCancellable *cancellable, GError **error); struct _part_spec_stack { @@ -2998,10 +3070,13 @@ content_info_get_part_spec (CamelMessageContentInfo *ci) * of message @uid in @folder. */ static CamelDataWrapper * -get_content (CamelImapFolder *imap_folder, const gchar *uid, - CamelMimePart *part, CamelMessageContentInfo *ci, - gint frommsg, - GError **error) +get_content (CamelImapFolder *imap_folder, + const gchar *uid, + CamelMimePart *part, + CamelMessageContentInfo *ci, + gint frommsg, + GCancellable *cancellable, + GError **error) { CamelDataWrapper *content = NULL; CamelStream *stream; @@ -3032,10 +3107,10 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid, strcpy (spec, part_spec); g_free (part_spec); - stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, error); + stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, cancellable, error); if (stream) { ret = camel_data_wrapper_construct_from_stream ( - CAMEL_DATA_WRAPPER (body_mp), stream, error); + CAMEL_DATA_WRAPPER (body_mp), stream, cancellable, error); g_object_unref (CAMEL_OBJECT (stream)); if (ret == -1) { g_object_unref ( body_mp); @@ -3070,12 +3145,12 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid, num = 1; while (ci) { sprintf (child_spec + speclen, "%d.MIME", num++); - stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, FALSE, error); + stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, FALSE, cancellable, error); if (stream) { gint ret; part = camel_mime_part_new (); - ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (part), stream, error); + ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (part), stream, cancellable, error); g_object_unref (CAMEL_OBJECT (stream)); if (ret == -1) { g_object_unref (CAMEL_OBJECT (part)); @@ -3084,7 +3159,7 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid, return NULL; } - content = get_content (imap_folder, uid, part, ci, FALSE, error); + content = get_content (imap_folder, uid, part, ci, FALSE, cancellable, error); } if (!stream || !content) { @@ -3126,7 +3201,7 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid, return (CamelDataWrapper *) body_mp; } else if (camel_content_type_is (ci->type, "message", "rfc822")) { - content = (CamelDataWrapper *) get_message (imap_folder, uid, ci->childs, error); + content = (CamelDataWrapper *) get_message (imap_folder, uid, ci->childs, cancellable, error); g_free (part_spec); return content; } else { @@ -3148,9 +3223,11 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid, } static CamelMimeMessage * -get_message (CamelImapFolder *imap_folder, const gchar *uid, - CamelMessageContentInfo *ci, - GError **error) +get_message (CamelImapFolder *imap_folder, + const gchar *uid, + CamelMessageContentInfo *ci, + GCancellable *cancellable, + GError **error) { CamelFolder *folder; CamelStore *parent_store; @@ -3170,7 +3247,7 @@ get_message (CamelImapFolder *imap_folder, const gchar *uid, section_text = g_strdup_printf ("%s%s%s", part_spec, *part_spec ? "." : "", store->server_level >= IMAP_LEVEL_IMAP4REV1 ? "HEADER" : "0"); - stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, error); + stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, cancellable, error); g_free (section_text); g_free (part_spec); if (!stream) @@ -3178,14 +3255,14 @@ get_message (CamelImapFolder *imap_folder, const gchar *uid, msg = camel_mime_message_new (); ret = camel_data_wrapper_construct_from_stream ( - CAMEL_DATA_WRAPPER (msg), stream, error); + CAMEL_DATA_WRAPPER (msg), stream, cancellable, error); g_object_unref (CAMEL_OBJECT (stream)); if (ret == -1) { g_object_unref (CAMEL_OBJECT (msg)); return NULL; } - content = get_content (imap_folder, uid, CAMEL_MIME_PART (msg), ci, TRUE, error); + content = get_content (imap_folder, uid, CAMEL_MIME_PART (msg), ci, TRUE, cancellable, error); if (!content) { g_object_unref (CAMEL_OBJECT (msg)); return NULL; @@ -3210,22 +3287,25 @@ get_message (CamelImapFolder *imap_folder, const gchar *uid, #define IMAP_SMALL_BODY_SIZE 5120 static CamelMimeMessage * -get_message_simple (CamelImapFolder *imap_folder, const gchar *uid, - CamelStream *stream, GError **error) +get_message_simple (CamelImapFolder *imap_folder, + const gchar *uid, + CamelStream *stream, + GCancellable *cancellable, + GError **error) { CamelMimeMessage *msg; gint ret; if (!stream) { stream = camel_imap_folder_fetch_data (imap_folder, uid, "", - FALSE, error); + FALSE, cancellable, error); if (!stream) return NULL; } msg = camel_mime_message_new (); ret = camel_data_wrapper_construct_from_stream ( - CAMEL_DATA_WRAPPER (msg), stream, error); + CAMEL_DATA_WRAPPER (msg), stream, cancellable, error); g_object_unref (CAMEL_OBJECT (stream)); if (ret == -1) { g_prefix_error (error, _("Unable to retrieve message: ")); @@ -3272,6 +3352,7 @@ imap_folder_summary_uid_or_error (CamelFolderSummary *summary, const gchar * uid static CamelMimeMessage * imap_get_message (CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -3293,9 +3374,9 @@ imap_get_message (CamelFolder *folder, /* If its cached in full, just get it as is, this is only a shortcut, * since we get stuff from the cache anyway. It affects a busted * connection though. */ - stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, NULL); + stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, cancellable, NULL); if (stream != NULL) { - msg = get_message_simple (imap_folder, uid, stream, NULL); + msg = get_message_simple (imap_folder, uid, stream, cancellable, NULL); if (msg != NULL) goto done; } @@ -3313,7 +3394,7 @@ imap_get_message (CamelFolder *folder, || mi->info.size < IMAP_SMALL_BODY_SIZE || (!content_info_incomplete (mi->info.content) && !mi->info.content->childs)) { CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid); - msg = get_message_simple (imap_folder, uid, NULL, &local_error); + msg = get_message_simple (imap_folder, uid, NULL, cancellable, &local_error); if (info && !info->preview && msg && camel_folder_summary_get_need_preview (folder->summary)) { if (camel_mime_message_build_preview ((CamelMimePart *)msg, (CamelMessageInfo *)info) && info->preview) camel_folder_summary_add_preview (folder->summary, (CamelMessageInfo *)info); @@ -3342,7 +3423,7 @@ imap_get_message (CamelFolder *folder, goto fail; } - response = camel_imap_command (store, folder, &local_error, "UID FETCH %s BODY", uid); + response = camel_imap_command (store, folder, cancellable, &local_error, "UID FETCH %s BODY", uid); camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); if (response) { @@ -3388,9 +3469,9 @@ imap_get_message (CamelFolder *folder, * let the mailer's "bad MIME" code handle it. */ if (content_info_incomplete (mi->info.content)) - msg = get_message_simple (imap_folder, uid, NULL, &local_error); + msg = get_message_simple (imap_folder, uid, NULL, cancellable, &local_error); else - msg = get_message (imap_folder, uid, mi->info.content, &local_error); + msg = get_message (imap_folder, uid, mi->info.content, cancellable, &local_error); if (msg && camel_folder_summary_get_need_preview (folder->summary)) { CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid); if (info && !info->preview) { @@ -3459,6 +3540,7 @@ fail: static gboolean imap_sync_message (CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error) { CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); @@ -3482,11 +3564,11 @@ imap_sync_message (CamelFolder *folder, */ /* If its cached in full, just get it as is, this is only a shortcut, since we get stuff from the cache anyway. It affects a busted connection though. */ - if ((stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, NULL))) { + if ((stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, cancellable, NULL))) { g_object_unref (stream); return TRUE; } - msg = imap_get_message (folder, uid, error); + msg = imap_get_message (folder, uid, cancellable, error); if (msg != NULL) { g_object_unref (msg); success = TRUE; @@ -3616,8 +3698,11 @@ decode_internaldate (const guchar *in) } static void -add_message_from_data (CamelFolder *folder, GPtrArray *messages, - gint first, GData *data) +add_message_from_data (CamelFolder *folder, + GPtrArray *messages, + gint first, + GData *data, + GCancellable *cancellable) { CamelMimeMessage *msg; CamelStream *stream; @@ -3638,14 +3723,16 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages, msg = camel_mime_message_new (); if (camel_data_wrapper_construct_from_stream ( - CAMEL_DATA_WRAPPER (msg), stream, NULL) == -1) { + CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL) == -1) { g_object_unref (CAMEL_OBJECT (msg)); return; } bodystructure = g_datalist_get_data (&data, "BODY"); - mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg, bodystructure); + mi = (CamelImapMessageInfo *) + camel_folder_summary_info_new_from_message ( + folder->summary, msg, bodystructure); g_object_unref (CAMEL_OBJECT (msg)); if ((idate = g_datalist_get_data (&data, "INTERNALDATE"))) @@ -3743,6 +3830,7 @@ static gboolean imap_update_summary (CamelFolder *folder, gint exists, CamelFolderChangeInfo *changes, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -3804,14 +3892,16 @@ imap_update_summary (CamelFolder *folder, uidval = 0; got = 0; - if (!camel_imap_command_start (store, folder, error, + if (!camel_imap_command_start (store, folder, cancellable, error, "UID FETCH %d:* (FLAGS RFC822.SIZE INTERNALDATE BODYSTRUCTURE BODY.PEEK[%s])", uidval + 1, header_spec->str)) { g_string_free (header_spec, TRUE); return FALSE; } + camel_operation_start ( - NULL, _("Fetching summary information for new messages in %s"), + cancellable, + _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder)); /* Parse the responses. We can't add a message to the summary @@ -3821,7 +3911,7 @@ imap_update_summary (CamelFolder *folder, fetch_data = g_ptr_array_new (); messages = g_ptr_array_new (); ct = exists - seq; - while ((type = camel_imap_command_response (store, &resp, error)) == + while ((type = camel_imap_command_response (store, &resp, cancellable, error)) == CAMEL_IMAP_RESPONSE_UNTAGGED && !camel_application_is_exiting) { data = parse_fetch_response (imap_folder, resp); g_free (resp); @@ -3846,14 +3936,17 @@ imap_update_summary (CamelFolder *folder, /* Use the stream now so we don't tie up many * many fds if we're fetching many many messages. */ - add_message_from_data (folder, messages, first, data); + add_message_from_data ( + folder, messages, first, data, cancellable); g_datalist_set_data (&data, "BODY_PART_STREAM", NULL); } - camel_operation_progress (NULL, k * 100 / ct); + camel_operation_progress (cancellable, k * 100 / ct); + g_ptr_array_add (fetch_data, data); } - camel_operation_end (NULL); + + camel_operation_end (cancellable); if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) { if (type != CAMEL_IMAP_RESPONSE_ERROR && type != CAMEL_IMAP_RESPONSE_TAGGED) @@ -3889,23 +3982,24 @@ imap_update_summary (CamelFolder *folder, sizeof (gpointer), uid_compar); camel_operation_start ( - NULL, _("Fetching summary information for new messages in %s"), + cancellable, + _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder)); while (uid < needheaders->len && !camel_application_is_exiting) { uidset = imap_uid_array_to_set (folder->summary, needheaders, uid, UID_SET_LIMIT, &uid); - if (!camel_imap_command_start (store, folder, error, + if (!camel_imap_command_start (store, folder, cancellable, error, "UID FETCH %s BODYSTRUCTURE BODY.PEEK[%s]", uidset, header_spec->str)) { g_ptr_array_free (needheaders, TRUE); - camel_operation_end (NULL); + camel_operation_end (cancellable); g_free (uidset); g_string_free (header_spec, TRUE); goto lose; } g_free (uidset); - while ((type = camel_imap_command_response (store, &resp, error)) + while ((type = camel_imap_command_response (store, &resp, cancellable, error)) == CAMEL_IMAP_RESPONSE_UNTAGGED && !camel_application_is_exiting) { data = parse_fetch_response (imap_folder, resp); g_free (resp); @@ -3914,16 +4008,19 @@ imap_update_summary (CamelFolder *folder, stream = g_datalist_get_data (&data, "BODY_PART_STREAM"); if (stream) { - add_message_from_data (folder, messages, first, data); + add_message_from_data ( + folder, messages, first, + data, cancellable); got += IMAP_PRETEND_SIZEOF_HEADERS; - camel_operation_progress (NULL, got * 100 / size); + camel_operation_progress ( + cancellable, got * 100 / size); } g_datalist_clear (&data); } if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) { g_ptr_array_free (needheaders, TRUE); - camel_operation_end (NULL); + camel_operation_end (cancellable); if (type != CAMEL_IMAP_RESPONSE_ERROR && type != CAMEL_IMAP_RESPONSE_TAGGED) camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); @@ -3933,7 +4030,7 @@ imap_update_summary (CamelFolder *folder, } g_string_free (header_spec, TRUE); g_ptr_array_free (needheaders, TRUE); - camel_operation_end (NULL); + camel_operation_end (cancellable); } /* Now finish up summary entries (fix UIDs, set flags and size) */ @@ -4094,8 +4191,11 @@ imap_update_summary (CamelFolder *folder, /* Called with the store's connect_lock locked */ gboolean -camel_imap_folder_changed (CamelFolder *folder, gint exists, - GArray *expunged, GError **error) +camel_imap_folder_changed (CamelFolder *folder, + gint exists, + GArray *expunged, + GCancellable *cancellable, + GError **error) { CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); CamelFolderChangeInfo *changes; @@ -4137,7 +4237,8 @@ camel_imap_folder_changed (CamelFolder *folder, gint exists, len = camel_folder_summary_count (folder->summary); if (exists > len && !camel_application_is_exiting) - success = imap_update_summary (folder, exists, changes, error); + success = imap_update_summary ( + folder, exists, changes, cancellable, error); camel_folder_summary_save_to_db (folder->summary, NULL); if (camel_folder_change_info_changed (changes)) @@ -4157,17 +4258,22 @@ imap_thaw (CamelFolder *folder) if (camel_folder_is_frozen (folder)) return; + /* FIXME imap_refresh_info() may block, but camel_folder_thaw() + * is not supposed to block. Potential hang here. */ imap_folder = CAMEL_IMAP_FOLDER (folder); if (imap_folder->need_refresh) { imap_folder->need_refresh = FALSE; - imap_refresh_info (folder, NULL); + imap_refresh_info (folder, NULL, NULL); } } CamelStream * -camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const gchar *uid, - const gchar *section_text, gboolean cache_only, - GError **error) +camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, + const gchar *uid, + const gchar *section_text, + gboolean cache_only, + GCancellable *cancellable, + GError **error) { CamelFolder *folder = CAMEL_FOLDER (imap_folder); CamelStore *parent_store; @@ -4216,11 +4322,11 @@ camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const gchar *uid, if (store->server_level < IMAP_LEVEL_IMAP4REV1 && !*section_text) { response = camel_imap_command ( - store, folder, error, + store, folder, cancellable, error, "UID FETCH %s RFC822.PEEK", uid); } else { response = camel_imap_command ( - store, folder, error, + store, folder, cancellable, error, "UID FETCH %s BODY.PEEK[%s]", uid, section_text); } @@ -4393,7 +4499,7 @@ parse_fetch_response (CamelImapFolder *imap_folder, gchar *response) CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock); stream = camel_imap_message_cache_insert (imap_folder->cache, uid, part_spec, - body, body_len, NULL); + body, body_len, NULL, NULL); CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock); if (stream == NULL) stream = camel_stream_mem_new_with_buffer (body, body_len); @@ -4432,7 +4538,7 @@ imap_get_quota_info (CamelFolder *folder) CamelImapStoreNamespace *ns = camel_imap_store_summary_namespace_find_full (imap_store->summary, full_name); gchar *folder_name = camel_imap_store_summary_path_to_full (imap_store->summary, full_name, ns ? ns->sep : '/'); - response = camel_imap_command (imap_store, NULL, NULL, "GETQUOTAROOT \"%s\"", folder_name); + response = camel_imap_command (imap_store, NULL, NULL, NULL, "GETQUOTAROOT \"%s\"", folder_name); if (response) { gint i; diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h index 25b1b6f..e24bd96 100644 --- a/camel/providers/imap/camel-imap-folder.h +++ b/camel/providers/imap/camel-imap-folder.h @@ -87,33 +87,40 @@ void camel_imap_folder_set_check_folder gboolean check_folder); gboolean camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response, + GCancellable *cancellable, GError **error); gboolean camel_imap_folder_changed (CamelFolder *folder, gint exists, GArray *expunged, + GCancellable *cancellable, GError **error); CamelStream * camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const gchar *uid, const gchar *section_text, gboolean cache_only, + GCancellable *cancellable, GError **error); gboolean camel_imap_append_resyncing (CamelFolder *folder, CamelMimeMessage *message, const 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, + GCancellable *cancellable, GError **error); gboolean camel_imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, + GCancellable *cancellable, GError **error); gboolean camel_imap_expunge_uids_only (CamelFolder *folder, GPtrArray *uids, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/camel/providers/imap/camel-imap-journal.c b/camel/providers/imap/camel-imap-journal.c index b7cc289..f0dac00 100644 --- a/camel/providers/imap/camel-imap-journal.c +++ b/camel/providers/imap/camel-imap-journal.c @@ -44,10 +44,9 @@ static void imap_entry_free (CamelOfflineJournal *journal, CamelDListNode *entry); static CamelDListNode *imap_entry_load (CamelOfflineJournal *journal, FILE *in); static gint imap_entry_write (CamelOfflineJournal *journal, CamelDListNode *entry, FILE *out); -static gint imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error); +static gint imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GCancellable *cancellable, GError **error); static void unref_folder (gpointer key, gpointer value, gpointer data); static void free_uids (GPtrArray *array); -static void close_folder (gpointer name, gpointer folder, gpointer data); G_DEFINE_TYPE (CamelIMAPJournal, camel_imap_journal, CAMEL_TYPE_OFFLINE_JOURNAL) @@ -275,7 +274,9 @@ imap_entry_write (CamelOfflineJournal *journal, CamelDListNode *entry, FILE *out } static CamelFolder * -journal_decode_folder (CamelIMAPJournal *journal, const gchar *name) +journal_decode_folder (CamelIMAPJournal *journal, + const gchar *name, + GCancellable *cancellable) { CamelFolder *folder; CamelOfflineJournal *offline = CAMEL_OFFLINE_JOURNAL (journal); @@ -291,7 +292,8 @@ journal_decode_folder (CamelIMAPJournal *journal, const gchar *name) parent_store = camel_folder_get_parent_store ( CAMEL_OFFLINE_JOURNAL (journal)->folder); - folder = camel_store_get_folder (parent_store, name, 0, &local_error); + folder = camel_store_get_folder ( + parent_store, name, 0, cancellable, &local_error); if (folder) g_hash_table_insert (journal->folders, (gchar *) name, folder); else { @@ -310,7 +312,10 @@ journal_decode_folder (CamelIMAPJournal *journal, const gchar *name) } static gint -imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error) +imap_entry_play (CamelOfflineJournal *journal, + CamelDListNode *entry, + GCancellable *cancellable, + GError **error) { CamelIMAPJournalEntry *imap_entry = (CamelIMAPJournalEntry *) entry; @@ -319,7 +324,7 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e switch (imap_entry->type) { case CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE: camel_imap_expunge_uids_resyncing ( - journal->folder, imap_entry->uids, NULL); + journal->folder, imap_entry->uids, cancellable, NULL); return 0; case CAMEL_IMAP_JOURNAL_ENTRY_APPEND: { @@ -327,7 +332,9 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e CamelMimeMessage *message; CamelMessageInfo *info; - message = camel_folder_get_message (journal->folder, imap_entry->append_uid, error); + message = camel_folder_get_message ( + journal->folder, imap_entry->append_uid, + cancellable, error); if (!message) { /* it seems message gone, just ignore the error and continue; otherwise the entry would not be removed from the list */ @@ -337,7 +344,7 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e info = camel_folder_get_message_info (journal->folder, imap_entry->append_uid); camel_imap_append_resyncing ( - journal->folder, message, info, &ret_uid, NULL); + journal->folder, message, info, &ret_uid, cancellable, NULL); camel_folder_free_message_info (journal->folder, info); if (ret_uid) { @@ -353,7 +360,9 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e GPtrArray *ret_uids; gint i; - destination = journal_decode_folder ((CamelIMAPJournal *)journal, imap_entry->dest_folder_name); + destination = journal_decode_folder ( + (CamelIMAPJournal *) journal, + imap_entry->dest_folder_name, cancellable); if (!destination) { d(g_print ("Destination folder not found \n")); return -1; @@ -361,7 +370,7 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e if (!camel_imap_transfer_resyncing ( journal->folder, imap_entry->uids, destination, - &ret_uids, imap_entry->move, error)) + &ret_uids, imap_entry->move, cancellable, error)) return -1; if (ret_uids) { @@ -445,10 +454,11 @@ camel_imap_journal_log (CamelOfflineJournal *journal, CamelOfflineAction action, } static void -close_folder (gpointer name, gpointer folder, gpointer data) +close_folder (gchar *name, + CamelFolder *folder) { g_free (name); - camel_folder_sync (folder, FALSE, NULL); + camel_folder_sync (folder, FALSE, NULL, NULL); g_object_unref (folder); } @@ -459,7 +469,8 @@ camel_imap_journal_close_folders (CamelIMAPJournal *journal) if (!journal->folders) return; - g_hash_table_foreach (journal->folders, close_folder, journal); + g_hash_table_foreach ( + journal->folders, (GHFunc) close_folder, NULL); g_hash_table_remove_all (journal->folders); } diff --git a/camel/providers/imap/camel-imap-journal.h b/camel/providers/imap/camel-imap-journal.h index 8cc6f13..eb8c038 100644 --- a/camel/providers/imap/camel-imap-journal.h +++ b/camel/providers/imap/camel-imap-journal.h @@ -85,13 +85,19 @@ struct _CamelIMAPJournalClass { }; -GType camel_imap_journal_get_type (void); - -CamelOfflineJournal *camel_imap_journal_new (struct _CamelImapFolder *folder, const gchar *filename); -void camel_imap_journal_log (CamelOfflineJournal *journal, CamelOfflineAction action, ...); -void camel_imap_journal_uidmap_add (CamelIMAPJournal *journal, const gchar *old_uid, const gchar *n_uid); -const gchar *camel_imap_journal_uidmap_lookup (CamelIMAPJournal *journal, const gchar *uid); -void camel_imap_journal_close_folders (CamelIMAPJournal *journal); +GType camel_imap_journal_get_type (void); +CamelOfflineJournal * + camel_imap_journal_new (struct _CamelImapFolder *folder, + const gchar *filename); +void camel_imap_journal_log (CamelOfflineJournal *journal, + CamelOfflineAction action, + ...); +void camel_imap_journal_uidmap_add (CamelIMAPJournal *journal, + const gchar *old_uid, + const gchar *n_uid); +const gchar * camel_imap_journal_uidmap_lookup(CamelIMAPJournal *journal, + const gchar *uid); +void camel_imap_journal_close_folders(CamelIMAPJournal *journal); G_END_DECLS diff --git a/camel/providers/imap/camel-imap-message-cache.c b/camel/providers/imap/camel-imap-message-cache.c index 1b7f5b1..158064d 100644 --- a/camel/providers/imap/camel-imap-message-cache.c +++ b/camel/providers/imap/camel-imap-message-cache.c @@ -348,7 +348,7 @@ insert_finish (CamelImapMessageCache *cache, gchar *key, CamelStream *stream) { - camel_stream_flush (stream, NULL); + camel_stream_flush (stream, NULL, NULL); camel_stream_reset (stream, NULL); cache_put (cache, uid, key, stream); g_free (path); @@ -363,6 +363,8 @@ insert_finish (CamelImapMessageCache *cache, * @part_spec: the IMAP part_spec of the data * @data: the data * @len: length of @data + * @cancellable: optional #GCancellable object, or %NULL + * @error: return location for a #GError, or %NULL * * Caches the provided data into @cache. * @@ -375,6 +377,7 @@ camel_imap_message_cache_insert (CamelImapMessageCache *cache, const gchar *part_spec, const gchar *data, gint len, + GCancellable *cancellable, GError **error) { gchar *path, *key; @@ -384,7 +387,7 @@ camel_imap_message_cache_insert (CamelImapMessageCache *cache, if (!stream) return NULL; - if (camel_stream_write (stream, data, len, error) == -1) { + if (camel_stream_write (stream, data, len, cancellable, error) == -1) { g_prefix_error (error, _("Failed to cache message %s: "), uid); return insert_abort (path, stream); } @@ -414,7 +417,7 @@ camel_imap_message_cache_insert_stream (CamelImapMessageCache *cache, if (!stream) return; - if (camel_stream_write_to_stream (data_stream, stream, NULL) == -1) { + if (camel_stream_write_to_stream (data_stream, stream, NULL, NULL) == -1) { insert_abort (path, stream); } else { insert_finish (cache, uid, path, key, stream); @@ -444,7 +447,7 @@ camel_imap_message_cache_insert_wrapper (CamelImapMessageCache *cache, if (!stream) return; - if (camel_data_wrapper_write_to_stream (wrapper, stream, NULL) == -1) { + if (camel_data_wrapper_write_to_stream (wrapper, stream, NULL, NULL) == -1) { insert_abort (path, stream); } else { insert_finish (cache, uid, path, key, stream); diff --git a/camel/providers/imap/camel-imap-message-cache.h b/camel/providers/imap/camel-imap-message-cache.h index adb59f4..31fd81b 100644 --- a/camel/providers/imap/camel-imap-message-cache.h +++ b/camel/providers/imap/camel-imap-message-cache.h @@ -85,6 +85,7 @@ CamelStream *camel_imap_message_cache_insert (CamelImapMessageCache *cache, const gchar *part_spec, const gchar *data, gint len, + GCancellable *cancellable, GError **error); void camel_imap_message_cache_insert_stream (CamelImapMessageCache *cache, const gchar *uid, diff --git a/camel/providers/imap/camel-imap-search.c b/camel/providers/imap/camel-imap-search.c index b0ecfc9..1d9a9d5 100644 --- a/camel/providers/imap/camel-imap-search.c +++ b/camel/providers/imap/camel-imap-search.c @@ -243,10 +243,10 @@ save_match (CamelImapSearch *is, struct _match_record *mr) header.lastuid = mr->lastuid; header.validity = mr->validity; - if (camel_stream_write (stream, (gchar *)&header, sizeof (header), NULL) != sizeof (header) - || camel_stream_write (stream, mr->matches->data, mr->matches->len*sizeof (guint32), NULL) != mr->matches->len*sizeof (guint32) + if (camel_stream_write (stream, (gchar *)&header, sizeof (header), NULL, NULL) != sizeof (header) + || camel_stream_write (stream, mr->matches->data, mr->matches->len*sizeof (guint32), NULL, NULL) != mr->matches->len*sizeof (guint32) || camel_seekable_stream_seek ((CamelSeekableStream *)stream, 0, CAMEL_STREAM_SET, NULL) == -1 - || camel_stream_write (stream, (gchar *)&mark, sizeof (mark), NULL) != sizeof (mark)) { + || camel_stream_write (stream, (gchar *)&mark, sizeof (mark), NULL, NULL) != sizeof (mark)) { d(printf(" saving failed, removing cache entry\n")); camel_data_cache_remove(is->cache, "search/body-contains", mr->hash, NULL); ret = -1; @@ -287,13 +287,13 @@ load_match (CamelImapSearch *is, gchar hash[17], gint argc, struct _ESExpResult should be sufficient to key it */ /* This check should also handle endianness changes, we just throw away the data (its only a cache) */ - if (camel_stream_read (stream, (gchar *)&header, sizeof (header), NULL) == sizeof (header) + if (camel_stream_read (stream, (gchar *)&header, sizeof (header), NULL, NULL) == sizeof (header) && header.validity == is->validity && header.mark == MATCH_MARK && header.termcount == 0) { d(printf(" found %d matches\n", header.matchcount)); g_array_set_size (mr->matches, header.matchcount); - camel_stream_read (stream, mr->matches->data, sizeof (guint32)*header.matchcount, NULL); + camel_stream_read (stream, mr->matches->data, sizeof (guint32)*header.matchcount, NULL, NULL); } else { d(printf(" file format invalid/validity changed\n")); memset (&header, 0, sizeof (header)); @@ -354,14 +354,14 @@ sync_match (CamelImapSearch *is, struct _match_record *mr) /* We only try search using utf8 if its non us-ascii text? */ if ((words->type & CAMEL_SEARCH_WORD_8BIT) && (store->capabilities & IMAP_CAPABILITY_utf8_search)) { - response = camel_imap_command (store, folder, NULL, + response = camel_imap_command (store, folder, NULL, NULL, "UID SEARCH CHARSET UTF-8 %s", search->str); /* We can't actually tell if we got a NO response, so assume always */ if (response == NULL) store->capabilities &= ~IMAP_CAPABILITY_utf8_search; } if (response == NULL) - response = camel_imap_command (store, folder, NULL, + response = camel_imap_command (store, folder, NULL, NULL, "UID SEARCH %s", search->str); g_string_free (search, TRUE); diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index 00ca4db..e852154 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -66,29 +66,22 @@ extern gint camel_verbose_debug; static gchar imap_tag_prefix = 'A'; -static gboolean construct (CamelService *service, CamelSession *session, - CamelProvider *provider, CamelURL *url, - GError **error); - -static gchar *imap_get_name (CamelService *service, gboolean brief); - -static gboolean imap_noop (CamelStore *store, GError **error); -static CamelFolder *imap_get_junk (CamelStore *store, GError **error); -static CamelFolder *imap_get_trash (CamelStore *store, GError **error); -static GList *query_auth_types (CamelService *service, GError **error); +static gboolean imap_noop (CamelStore *store, GCancellable *cancellable, GError **error); +static CamelFolder *imap_get_junk(CamelStore *store, GCancellable *cancellable, GError **error); +static CamelFolder *imap_get_trash(CamelStore *store, GCancellable *cancellable, GError **error); static guint hash_folder_name (gconstpointer key); static gint compare_folder_name (gconstpointer a, gconstpointer b); -static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error); -static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error); -static gboolean rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name, GError **error); +static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GCancellable *cancellable, GError **error); +static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error); +static gboolean rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name, GCancellable *cancellable, GError **error); static gboolean folder_is_subscribed (CamelStore *store, const gchar *folder_name); static gboolean subscribe_folder (CamelStore *store, const gchar *folder_name, - GError **error); + GCancellable *cancellable, GError **error); static gboolean unsubscribe_folder (CamelStore *store, const gchar *folder_name, - GError **error); + GCancellable *cancellable, GError **error); -static gboolean get_folders_sync (CamelImapStore *imap_store, const gchar *pattern, GError **error); +static gboolean get_folders_sync (CamelImapStore *imap_store, const gchar *pattern, GCancellable *cancellable, GError **error); static gboolean imap_folder_effectively_unsubscribed (CamelImapStore *imap_store, const gchar *folder_name, GError **error); static gboolean imap_check_folder_still_extant (CamelImapStore *imap_store, const gchar *full_name, GError **error); @@ -96,234 +89,34 @@ static void imap_forget_folder (CamelImapStore *imap_store, const gchar *folder_ static void imap_set_server_level (CamelImapStore *store); static gboolean imap_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **error); -static gboolean imap_connect (CamelService *service, GError **error); -static gboolean imap_disconnect (CamelService *service, gboolean clean, GError **error); -static CamelFolder * get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error); -static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error); +static CamelFolder * get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error); +static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error); static CamelFolder * get_folder_offline (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error); static CamelFolderInfo * get_folder_info_offline (CamelStore *store, const gchar *top, guint32 flags, GError **error); -G_DEFINE_TYPE (CamelImapStore, camel_imap_store, CAMEL_TYPE_OFFLINE_STORE) - -static gboolean -free_key (gpointer key, gpointer value, gpointer user_data) -{ - g_free (key); - return TRUE; -} - -static void -imap_store_dispose (GObject *object) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (object); - - if (imap_store->summary != NULL) { - camel_store_summary_save ( - CAMEL_STORE_SUMMARY (imap_store->summary)); - g_object_unref (imap_store->summary); - imap_store->summary = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (camel_imap_store_parent_class)->dispose (object); -} - -static void -imap_store_finalize (GObject *object) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (object); - - /* This frees current_folder, folders, authtypes, streams, and namespace. */ - camel_service_disconnect (CAMEL_SERVICE (imap_store), TRUE, NULL); - - g_free (imap_store->base_url); - g_free (imap_store->storage_path); - g_free (imap_store->users_namespace); - g_free (imap_store->custom_headers); - g_free (imap_store->real_trash_path); - g_free (imap_store->real_junk_path); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (camel_imap_store_parent_class)->finalize (object); -} - -static void -camel_imap_store_class_init (CamelImapStoreClass *class) -{ - GObjectClass *object_class; - CamelServiceClass *service_class; - CamelStoreClass *store_class; - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = imap_store_dispose; - object_class->finalize = imap_store_finalize; - - service_class = CAMEL_SERVICE_CLASS (class); - service_class->construct = construct; - service_class->query_auth_types = query_auth_types; - service_class->get_name = imap_get_name; - service_class->connect = imap_connect; - service_class->disconnect = imap_disconnect; - - store_class = CAMEL_STORE_CLASS (class); - store_class->hash_folder_name = hash_folder_name; - store_class->compare_folder_name = compare_folder_name; - store_class->get_folder = get_folder; - store_class->create_folder = create_folder; - store_class->delete_folder = delete_folder; - store_class->rename_folder = rename_folder; - store_class->get_folder_info = get_folder_info; - store_class->free_folder_info = camel_store_free_folder_info_full; - store_class->folder_is_subscribed = folder_is_subscribed; - store_class->subscribe_folder = subscribe_folder; - store_class->unsubscribe_folder = unsubscribe_folder; - store_class->noop = imap_noop; - store_class->get_trash = imap_get_trash; - store_class->get_junk = imap_get_junk; - store_class->can_refresh_folder = imap_can_refresh_folder; -} - -static void -camel_imap_store_init (CamelImapStore *imap_store) -{ - imap_store->istream = NULL; - imap_store->ostream = NULL; - - /* TODO: support dir_sep per namespace */ - imap_store->dir_sep = '\0'; - imap_store->current_folder = NULL; - imap_store->connected = FALSE; - imap_store->preauthed = FALSE; - ((CamelStore *)imap_store)->flags |= CAMEL_STORE_SUBSCRIPTIONS; - - imap_store->tag_prefix = imap_tag_prefix++; - if (imap_tag_prefix > 'Z') - imap_tag_prefix = 'A'; -} - -static gboolean -construct (CamelService *service, CamelSession *session, - CamelProvider *provider, CamelURL *url, - GError **error) -{ - CamelServiceClass *service_class; - CamelImapStore *imap_store = CAMEL_IMAP_STORE (service); - CamelStore *store = CAMEL_STORE (service); - gchar *tmp; - CamelURL *summary_url; - - /* Chain up to parent's construct() method. */ - service_class = CAMEL_SERVICE_CLASS (camel_imap_store_parent_class); - if (!service_class->construct (service, session, provider, url, error)) - return FALSE; - - imap_store->storage_path = camel_session_get_storage_path (session, service, error); - if (!imap_store->storage_path) - return FALSE; - - /* FIXME */ - imap_store->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD | - CAMEL_URL_HIDE_PARAMS | - CAMEL_URL_HIDE_AUTH)); - - imap_store->parameters = 0; - if (camel_url_get_param (url, "use_lsub")) - imap_store->parameters |= IMAP_PARAM_SUBSCRIPTIONS; - if (camel_url_get_param (url, "override_namespace") && camel_url_get_param (url, "namespace")) { - imap_store->parameters |= IMAP_PARAM_OVERRIDE_NAMESPACE; - g_free (imap_store->users_namespace); - imap_store->users_namespace = g_strdup (camel_url_get_param (url, "namespace")); - } - if (camel_url_get_param (url, "check_all")) - imap_store->parameters |= IMAP_PARAM_CHECK_ALL; - if (camel_url_get_param (url, "check_lsub")) - imap_store->parameters |= IMAP_PARAM_CHECK_LSUB; - if (camel_url_get_param (url, "filter")) { - imap_store->parameters |= IMAP_PARAM_FILTER_INBOX; - store->flags |= CAMEL_STORE_FILTER_INBOX; - } - if (camel_url_get_param (url, "filter_junk")) - imap_store->parameters |= IMAP_PARAM_FILTER_JUNK; - if (camel_url_get_param (url, "filter_junk_inbox")) - imap_store->parameters |= IMAP_PARAM_FILTER_JUNK_INBOX; - - imap_store->headers = IMAP_FETCH_MAILING_LIST_HEADERS; - if (camel_url_get_param (url, "all_headers")) - imap_store->headers = IMAP_FETCH_ALL_HEADERS; - else if (camel_url_get_param (url, "basic_headers")) - imap_store->headers = IMAP_FETCH_MINIMAL_HEADERS; - - if (camel_url_get_param (url, "imap_custom_headers")) { - imap_store->custom_headers = g_strdup(camel_url_get_param (url, "imap_custom_headers")); - } - - imap_store->real_trash_path = g_strdup (camel_url_get_param (url, "real_trash_path")); - imap_store->real_junk_path = g_strdup (camel_url_get_param (url, "real_junk_path")); - - if (imap_store->real_trash_path && !*imap_store->real_trash_path) { - g_free (imap_store->real_trash_path); - imap_store->real_trash_path = NULL; - } - - if (imap_store->real_trash_path && *imap_store->real_trash_path) - store->flags &= ~CAMEL_STORE_VTRASH; - - if (imap_store->real_junk_path && !*imap_store->real_junk_path) { - g_free (imap_store->real_junk_path); - imap_store->real_junk_path = NULL; - } - - if (imap_store->real_junk_path && *imap_store->real_junk_path) { - store->flags &= ~CAMEL_STORE_VJUNK; - store->flags |= CAMEL_STORE_REAL_JUNK_FOLDER; - } - - /* setup/load the store summary */ - tmp = alloca (strlen (imap_store->storage_path)+32); - sprintf(tmp, "%s/.ev-store-summary", imap_store->storage_path); - imap_store->summary = camel_imap_store_summary_new (); - camel_store_summary_set_filename ((CamelStoreSummary *)imap_store->summary, tmp); - summary_url = camel_url_new (imap_store->base_url, NULL); - camel_store_summary_set_uri_base ((CamelStoreSummary *)imap_store->summary, summary_url); - camel_url_free (summary_url); - if (camel_store_summary_load ((CamelStoreSummary *)imap_store->summary) == 0) { - CamelImapStoreSummary *is = imap_store->summary; - - if (is->namespace) { - /* if namespace has changed, clear folder list */ - if (imap_store->users_namespace && strcmp (imap_store->users_namespace, is->namespace->full_name) != 0) { - camel_store_summary_clear ((CamelStoreSummary *)is); - } - } - - imap_store->capabilities = is->capabilities; - imap_set_server_level (imap_store); - } - - return TRUE; -} +enum { + MODE_CLEAR, + MODE_SSL, + MODE_TLS +}; -static gchar * -imap_get_name (CamelService *service, gboolean brief) -{ - if (brief) - return g_strdup_printf (_("IMAP server %s"), service->url->host); - else - return g_strdup_printf (_("IMAP service for %s on %s"), - service->url->user, service->url->host); -} +#ifdef HAVE_SSL +#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3) +#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS) +#endif -static void -imap_set_server_level (CamelImapStore *store) -{ - if (store->capabilities & IMAP_CAPABILITY_IMAP4REV1) { - store->server_level = IMAP_LEVEL_IMAP4REV1; - store->capabilities |= IMAP_CAPABILITY_STATUS; - } else if (store->capabilities & IMAP_CAPABILITY_IMAP4) - store->server_level = IMAP_LEVEL_IMAP4; - else - store->server_level = IMAP_LEVEL_UNKNOWN; -} +static struct { + const gchar *value; + const gchar *serv; + gint fallback_port; + gint mode; +} ssl_options[] = { + { "", "imaps", IMAPS_PORT, MODE_SSL }, /* really old (1.x) */ + { "always", "imaps", IMAPS_PORT, MODE_SSL }, + { "when-possible", "imap", IMAP_PORT, MODE_TLS }, + { "never", "imap", IMAP_PORT, MODE_CLEAR }, + { NULL, "imap", IMAP_PORT, MODE_CLEAR }, +}; static struct { const gchar *name; @@ -343,6 +136,10 @@ static struct { { NULL, 0 } }; +extern CamelServiceAuthType camel_imap_password_authtype; + +G_DEFINE_TYPE (CamelImapStore, camel_imap_store, CAMEL_TYPE_OFFLINE_STORE) + static void parse_capability (CamelImapStore *store, gchar *capa) { @@ -366,7 +163,9 @@ parse_capability (CamelImapStore *store, gchar *capa) } static gboolean -imap_get_capability (CamelService *service, GError **error) +imap_get_capability (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelImapStore *store = CAMEL_IMAP_STORE (service); CamelImapResponse *response; @@ -376,7 +175,7 @@ imap_get_capability (CamelService *service, GError **error) /* We assume we have utf8 capable search until a failed search tells us otherwise */ store->capabilities = IMAP_CAPABILITY_utf8_search; store->authtypes = g_hash_table_new (g_str_hash, g_str_equal); - response = camel_imap_command (store, NULL, error, "CAPABILITY"); + response = camel_imap_command (store, NULL, cancellable, error, "CAPABILITY"); if (!response) return FALSE; result = camel_imap_response_extract (store, response, "CAPABILITY ", error); @@ -390,7 +189,7 @@ imap_get_capability (CamelService *service, GError **error) /* dunno why the groupwise guys didn't just list this in capabilities */ if (store->capabilities & IMAP_CAPABILITY_XGWEXTENSIONS) { /* not critical if this fails */ - response = camel_imap_command (store, NULL, NULL, "XGWEXTENSIONS"); + response = camel_imap_command (store, NULL, cancellable, NULL, "XGWEXTENSIONS"); if (response && (result = camel_imap_response_extract (store, response, "XGWEXTENSIONS ", NULL))) { parse_capability (store, result+16); g_free (result); @@ -408,12 +207,6 @@ imap_get_capability (CamelService *service, GError **error) return TRUE; } -enum { - MODE_CLEAR, - MODE_SSL, - MODE_TLS -}; - #ifdef CAMEL_HAVE_SSL #define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3) #define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS) @@ -421,7 +214,12 @@ enum { static gboolean connect_to_server (CamelService *service, - const gchar *host, const gchar *serv, gint fallback_port, gint ssl_mode, GError **error) + const gchar *host, + const gchar *serv, + gint fallback_port, + gint ssl_mode, + GCancellable *cancellable, + GError **error) { CamelImapStore *store = (CamelImapStore *) service; CamelSession *session; @@ -461,7 +259,9 @@ connect_to_server (CamelService *service, g_free (socks_host); } - if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, host, serv, fallback_port, error) == -1) { + if (camel_tcp_stream_connect ( + CAMEL_TCP_STREAM (tcp_stream), host, serv, + fallback_port, cancellable, error) == -1) { g_prefix_error ( error, _("Could not connect to %s: "), service->url->host); @@ -487,7 +287,7 @@ connect_to_server (CamelService *service, camel_tcp_stream_setsockopt ((CamelTcpStream *)tcp_stream, &sockopt); /* Read the greeting, if any, and deal with PREAUTH */ - if (camel_imap_store_readline (store, &buf, error) < 0) { + if (camel_imap_store_readline (store, &buf, cancellable, error) < 0) { if (store->istream) { g_object_unref (store->istream); store->istream = NULL; @@ -537,7 +337,7 @@ connect_to_server (CamelService *service, g_free (buf); /* get the imap server capabilities */ - if (!imap_get_capability (service, error)) { + if (!imap_get_capability (service, cancellable, error)) { if (store->istream) { g_object_unref (store->istream); store->istream = NULL; @@ -575,7 +375,7 @@ connect_to_server (CamelService *service, goto exception; } - response = camel_imap_command (store, NULL, error, "STARTTLS"); + response = camel_imap_command (store, NULL, cancellable, error, "STARTTLS"); if (!response) { g_object_unref (store->istream); g_object_unref (store->ostream); @@ -603,7 +403,7 @@ connect_to_server (CamelService *service, /* rfc2595, section 4 states that after a successful STLS command, the client MUST discard prior CAPA responses */ - if (!imap_get_capability (service, error)) { + if (!imap_get_capability (service, cancellable, error)) { if (store->istream) { g_object_unref (store->istream); store->istream = NULL; @@ -634,7 +434,7 @@ exception: if (clean_quit && store->connected) { /* try to disconnect cleanly */ - response = camel_imap_command (store, NULL, error, "LOGOUT"); + response = camel_imap_command (store, NULL, cancellable, error, "LOGOUT"); if (response) camel_imap_response_free_without_processing (store, response); } @@ -659,7 +459,10 @@ exception: /* Using custom commands to connect to IMAP servers is not supported on Win32 */ static gboolean -connect_to_server_process (CamelService *service, const gchar *cmd, GError **error) +connect_to_server_process (CamelService *service, + const gchar *cmd, + GCancellable *cancellable, + GError **error) { CamelImapStore *store = (CamelImapStore *) service; CamelStream *cmd_stream; @@ -767,7 +570,7 @@ connect_to_server_process (CamelService *service, const gchar *cmd, GError **err store->command = 0; /* Read the greeting, if any, and deal with PREAUTH */ - if (camel_imap_store_readline (store, &buf, error) < 0) { + if (camel_imap_store_readline (store, &buf, cancellable, error) < 0) { if (store->istream) { g_object_unref (store->istream); store->istream = NULL; @@ -787,7 +590,7 @@ connect_to_server_process (CamelService *service, const gchar *cmd, GError **err g_free (buf); /* get the imap server capabilities */ - if (!imap_get_capability (service, error)) { + if (!imap_get_capability (service, cancellable, error)) { if (store->istream) { g_object_unref (store->istream); store->istream = NULL; @@ -808,21 +611,10 @@ connect_to_server_process (CamelService *service, const gchar *cmd, GError **err #endif -static struct { - const gchar *value; - const gchar *serv; - gint fallback_port; - gint mode; -} ssl_options[] = { - { "", "imaps", IMAPS_PORT, MODE_SSL }, /* really old (1.x) */ - { "always", "imaps", IMAPS_PORT, MODE_SSL }, - { "when-possible", "imap", IMAP_PORT, MODE_TLS }, - { "never", "imap", IMAP_PORT, MODE_CLEAR }, - { NULL, "imap", IMAP_PORT, MODE_CLEAR }, -}; - static gboolean -connect_to_server_wrapper (CamelService *service, GError **error) +connect_to_server_wrapper (CamelService *service, + GCancellable *cancellable, + GError **error) { const gchar *ssl_mode; gint mode, i; @@ -834,7 +626,7 @@ connect_to_server_wrapper (CamelService *service, GError **error) if (camel_url_get_param(service->url, "use_command") && (command = camel_url_get_param(service->url, "command"))) - return connect_to_server_process (service, command, error); + return connect_to_server_process (service, command, cancellable, error); #endif if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) { @@ -856,205 +648,23 @@ connect_to_server_wrapper (CamelService *service, GError **error) fallback_port = 0; } - return connect_to_server (service, service->url->host, serv, fallback_port, mode, error); + return connect_to_server ( + service, service->url->host, serv, + fallback_port, mode, cancellable, error); } -extern CamelServiceAuthType camel_imap_password_authtype; - -static GList * -query_auth_types (CamelService *service, GError **error) +static gboolean +try_auth (CamelImapStore *store, + const gchar *mech, + GCancellable *cancellable, + GError **error) { - CamelImapStore *store = CAMEL_IMAP_STORE (service); - CamelServiceAuthType *authtype; - GList *sasl_types, *t, *next; - gboolean connected; + CamelSasl *sasl; + CamelImapResponse *response; + gchar *resp; + gchar *sasl_resp; - if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) { - g_set_error ( - error, CAMEL_SERVICE_ERROR, - CAMEL_SERVICE_ERROR_UNAVAILABLE, - _("You must be working online to complete this operation")); - return NULL; - } - - camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); - connected = store->istream != NULL && store->connected; - if (!connected) - connected = connect_to_server_wrapper (service, error); - camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); - if (!connected) - return NULL; - - sasl_types = camel_sasl_authtype_list (FALSE); - for (t = sasl_types; t; t = next) { - authtype = t->data; - next = t->next; - - if (!g_hash_table_lookup (store->authtypes, authtype->authproto)) { - sasl_types = g_list_remove_link (sasl_types, t); - g_list_free_1 (t); - } - } - - return g_list_prepend (sasl_types, &camel_imap_password_authtype); -} - -/* folder_name is path name */ -static CamelFolderInfo * -imap_build_folder_info (CamelImapStore *imap_store, const gchar *folder_name) -{ - CamelURL *url; - const gchar *name; - CamelFolderInfo *fi; - - fi = camel_folder_info_new (); - fi->full_name = g_strdup (folder_name); - fi->unread = -1; - fi->total = -1; - - url = camel_url_new (imap_store->base_url, NULL); - g_free (url->path); - url->path = g_strdup_printf ("/%s", folder_name); - fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL); - camel_url_free (url); - name = strrchr (fi->full_name, '/'); - if (name == NULL) - name = fi->full_name; - else - name++; - if (!g_ascii_strcasecmp (fi->full_name, "INBOX")) - fi->name = g_strdup (_("Inbox")); - /* Do not localize the rest, these are from a server, thus shouldn't be localized */ - /*else if (!g_ascii_strcasecmp (fi->full_name, "Drafts")) - fi->name = g_strdup (_("Drafts")); - else if (!g_ascii_strcasecmp (fi->full_name, "Sent")) - fi->name = g_strdup (_("Sent")); - else if (!g_ascii_strcasecmp (fi->full_name, "Templates")) - fi->name = g_strdup (_("Templates")); - else if (!g_ascii_strcasecmp (fi->full_name, "Trash")) - fi->name = g_strdup (_("Trash"));*/ - else - fi->name = g_strdup (name); - - return fi; -} - -static gboolean -imap_folder_effectively_unsubscribed (CamelImapStore *imap_store, - const gchar *folder_name, - GError **error) -{ - CamelFolderInfo *fi; - CamelStoreInfo *si; - - si = camel_store_summary_path ((CamelStoreSummary *)imap_store->summary, folder_name); - if (si) { - if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) { - si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED; - camel_store_summary_touch ((CamelStoreSummary *)imap_store->summary); - camel_store_summary_save ((CamelStoreSummary *)imap_store->summary); - } - camel_store_summary_info_free ((CamelStoreSummary *)imap_store->summary, si); - } - - if (imap_store->renaming) { - /* we don't need to emit a "folder_unsubscribed" signal - if we are in the process of renaming folders, so we - are done here... */ - return TRUE; - - } - - fi = imap_build_folder_info (imap_store, folder_name); - camel_store_folder_unsubscribed (CAMEL_STORE (imap_store), fi); - camel_folder_info_free (fi); - - return TRUE; -} - -static void -imap_forget_folder (CamelImapStore *imap_store, const gchar *folder_name, GError **error) -{ - gchar *state_file; - gchar *journal_file; - gchar *folder_dir, *storage_path; - CamelFolderInfo *fi; - const gchar *name; - - name = strrchr (folder_name, imap_store->dir_sep); - if (name) - name++; - else - name = folder_name; - - storage_path = g_strdup_printf ("%s/folders", imap_store->storage_path); - folder_dir = imap_path_to_physical (storage_path, folder_name); - g_free (storage_path); - if (g_access (folder_dir, F_OK) != 0) { - g_free (folder_dir); - goto event; - } - - /* Delete summary and all the data */ - journal_file = g_strdup_printf ("%s/journal", folder_dir); - g_unlink (journal_file); - g_free (journal_file); - - state_file = g_strdup_printf ("%s/cmeta", folder_dir); - g_unlink (state_file); - g_free (state_file); - - camel_db_delete_folder (((CamelStore *)imap_store)->cdb_w, folder_name, NULL); - camel_imap_message_cache_delete (folder_dir, NULL); - - state_file = g_strdup_printf("%s/subfolders", folder_dir); - g_rmdir (state_file); - g_free (state_file); - - g_rmdir (folder_dir); - g_free (folder_dir); - - event: - - camel_store_summary_remove_path ((CamelStoreSummary *)imap_store->summary, folder_name); - camel_store_summary_save ((CamelStoreSummary *)imap_store->summary); - - fi = imap_build_folder_info (imap_store, folder_name); - camel_store_folder_deleted (CAMEL_STORE (imap_store), fi); - camel_folder_info_free (fi); -} - -static gboolean -imap_check_folder_still_extant (CamelImapStore *imap_store, const gchar *full_name, - GError **error) -{ - CamelImapResponse *response; - - response = camel_imap_command (imap_store, NULL, NULL, "LIST \"\" %F", - full_name); - - if (response) { - gboolean stillthere = response->untagged->len != 0; - - camel_imap_response_free_without_processing (imap_store, response); - - return stillthere; - } - - /* if the command was rejected, there must be some other error, - assume it worked so we dont blow away the folder unecessarily */ - return TRUE; -} - -static gboolean -try_auth (CamelImapStore *store, const gchar *mech, GError **error) -{ - CamelSasl *sasl; - CamelImapResponse *response; - gchar *resp; - gchar *sasl_resp; - - response = camel_imap_command (store, NULL, error, "AUTHENTICATE %s", mech); + response = camel_imap_command (store, NULL, cancellable, error, "AUTHENTICATE %s", mech); if (!response) return FALSE; @@ -1064,12 +674,13 @@ try_auth (CamelImapStore *store, const gchar *mech, GError **error) if (!resp) goto lose; - sasl_resp = camel_sasl_challenge_base64 (sasl, imap_next_word (resp), error); + sasl_resp = camel_sasl_challenge_base64 ( + sasl, imap_next_word (resp), cancellable, error); g_free (resp); if (!sasl_resp) goto break_and_lose; - response = camel_imap_command_continuation (store, sasl_resp, strlen (sasl_resp), error); + response = camel_imap_command_continuation (store, sasl_resp, strlen (sasl_resp), cancellable, error); g_free (sasl_resp); if (!response) goto lose; @@ -1090,7 +701,7 @@ try_auth (CamelImapStore *store, const gchar *mech, GError **error) break_and_lose: /* Get the server out of "waiting for continuation data" mode. */ - response = camel_imap_command_continuation (store, "*", 1, NULL); + response = camel_imap_command_continuation (store, "*", 1, cancellable, NULL); if (response) camel_imap_response_free (store, response); @@ -1101,7 +712,9 @@ try_auth (CamelImapStore *store, const gchar *mech, GError **error) } static gboolean -imap_auth_loop (CamelService *service, GError **error) +imap_auth_loop (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelImapStore *store = CAMEL_IMAP_STORE (service); CamelSession *session = camel_service_get_session (service); @@ -1144,7 +757,9 @@ imap_auth_loop (CamelService *service, GError **error) } if (!authtype->need_password) { - authenticated = try_auth (store, authtype->authproto, error); + authenticated = try_auth ( + store, authtype->authproto, + cancellable, error); if (!authenticated) return FALSE; } @@ -1193,14 +808,17 @@ imap_auth_loop (CamelService *service, GError **error) if (!store->connected) { /* Some servers (eg, courier) will disconnect on * a bad password. So reconnect here. */ - if (!connect_to_server_wrapper (service, error)) + if (!connect_to_server_wrapper ( + service, cancellable, error)) return FALSE; } if (authtype) - authenticated = try_auth (store, authtype->authproto, &local_error); + authenticated = try_auth ( + store, authtype->authproto, + cancellable, &local_error); else { - response = camel_imap_command (store, NULL, &local_error, + response = camel_imap_command (store, NULL, cancellable, &local_error, "LOGIN %S %S", service->url->user, service->url->passwd); @@ -1209,25 +827,228 @@ imap_auth_loop (CamelService *service, GError **error) authenticated = TRUE; } } - if (local_error != NULL) { - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || - g_error_matches (local_error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE)) { - g_propagate_error (error, local_error); - return FALSE; - } + if (local_error != NULL) { + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || + g_error_matches (local_error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE)) { + g_propagate_error (error, local_error); + return FALSE; + } + + errbuf = g_markup_printf_escaped ( + _("Unable to authenticate to IMAP server.\n%s\n\n"), + local_error->message); + g_clear_error (&local_error); + } + } + + return TRUE; +} + +static gboolean +free_key (gpointer key, gpointer value, gpointer user_data) +{ + g_free (key); + return TRUE; +} + +static void +imap_store_dispose (GObject *object) +{ + CamelImapStore *imap_store = CAMEL_IMAP_STORE (object); + + if (imap_store->summary != NULL) { + camel_store_summary_save ( + CAMEL_STORE_SUMMARY (imap_store->summary)); + g_object_unref (imap_store->summary); + imap_store->summary = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (camel_imap_store_parent_class)->dispose (object); +} + +static void +imap_store_finalize (GObject *object) +{ + CamelImapStore *imap_store = CAMEL_IMAP_STORE (object); + + /* This frees current_folder, folders, authtypes, streams, and namespace. */ + camel_service_disconnect (CAMEL_SERVICE (imap_store), TRUE, NULL); + + g_free (imap_store->base_url); + g_free (imap_store->storage_path); + g_free (imap_store->users_namespace); + g_free (imap_store->custom_headers); + g_free (imap_store->real_trash_path); + g_free (imap_store->real_junk_path); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (camel_imap_store_parent_class)->finalize (object); +} + +static gboolean +imap_store_construct (CamelService *service, + CamelSession *session, + CamelProvider *provider, + CamelURL *url, + GError **error) +{ + CamelServiceClass *service_class; + CamelImapStore *imap_store = CAMEL_IMAP_STORE (service); + CamelStore *store = CAMEL_STORE (service); + gchar *tmp; + CamelURL *summary_url; + + /* Chain up to parent's construct() method. */ + service_class = CAMEL_SERVICE_CLASS (camel_imap_store_parent_class); + if (!service_class->construct (service, session, provider, url, error)) + return FALSE; + + imap_store->storage_path = camel_session_get_storage_path (session, service, error); + if (!imap_store->storage_path) + return FALSE; + + /* FIXME */ + imap_store->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD | + CAMEL_URL_HIDE_PARAMS | + CAMEL_URL_HIDE_AUTH)); + + imap_store->parameters = 0; + if (camel_url_get_param (url, "use_lsub")) + imap_store->parameters |= IMAP_PARAM_SUBSCRIPTIONS; + if (camel_url_get_param (url, "override_namespace") && camel_url_get_param (url, "namespace")) { + imap_store->parameters |= IMAP_PARAM_OVERRIDE_NAMESPACE; + g_free(imap_store->users_namespace); + imap_store->users_namespace = g_strdup (camel_url_get_param (url, "namespace")); + } + if (camel_url_get_param (url, "check_all")) + imap_store->parameters |= IMAP_PARAM_CHECK_ALL; + if (camel_url_get_param (url, "check_lsub")) + imap_store->parameters |= IMAP_PARAM_CHECK_LSUB; + if (camel_url_get_param (url, "filter")) { + imap_store->parameters |= IMAP_PARAM_FILTER_INBOX; + store->flags |= CAMEL_STORE_FILTER_INBOX; + } + if (camel_url_get_param (url, "filter_junk")) + imap_store->parameters |= IMAP_PARAM_FILTER_JUNK; + if (camel_url_get_param (url, "filter_junk_inbox")) + imap_store->parameters |= IMAP_PARAM_FILTER_JUNK_INBOX; + + imap_store->headers = IMAP_FETCH_MAILING_LIST_HEADERS; + if (camel_url_get_param (url, "all_headers")) + imap_store->headers = IMAP_FETCH_ALL_HEADERS; + else if (camel_url_get_param (url, "basic_headers")) + imap_store->headers = IMAP_FETCH_MINIMAL_HEADERS; + + if (camel_url_get_param (url, "imap_custom_headers")) { + imap_store->custom_headers = g_strdup(camel_url_get_param (url, "imap_custom_headers")); + } + + imap_store->real_trash_path = g_strdup (camel_url_get_param (url, "real_trash_path")); + imap_store->real_junk_path = g_strdup (camel_url_get_param (url, "real_junk_path")); + + if (imap_store->real_trash_path && !*imap_store->real_trash_path) { + g_free (imap_store->real_trash_path); + imap_store->real_trash_path = NULL; + } + + if (imap_store->real_trash_path && *imap_store->real_trash_path) + store->flags &= ~CAMEL_STORE_VTRASH; + + if (imap_store->real_junk_path && !*imap_store->real_junk_path) { + g_free (imap_store->real_junk_path); + imap_store->real_junk_path = NULL; + } + + if (imap_store->real_junk_path && *imap_store->real_junk_path) { + store->flags &= ~CAMEL_STORE_VJUNK; + store->flags |= CAMEL_STORE_REAL_JUNK_FOLDER; + } + + /* setup/load the store summary */ + tmp = alloca(strlen(imap_store->storage_path)+32); + sprintf(tmp, "%s/.ev-store-summary", imap_store->storage_path); + imap_store->summary = camel_imap_store_summary_new(); + camel_store_summary_set_filename((CamelStoreSummary *)imap_store->summary, tmp); + summary_url = camel_url_new(imap_store->base_url, NULL); + camel_store_summary_set_uri_base((CamelStoreSummary *)imap_store->summary, summary_url); + camel_url_free(summary_url); + if (camel_store_summary_load((CamelStoreSummary *)imap_store->summary) == 0) { + CamelImapStoreSummary *is = imap_store->summary; + + if (is->namespace) { + /* if namespace has changed, clear folder list */ + if (imap_store->users_namespace && strcmp(imap_store->users_namespace, is->namespace->full_name) != 0) { + camel_store_summary_clear((CamelStoreSummary *)is); + } + } - errbuf = g_markup_printf_escaped ( - _("Unable to authenticate to IMAP server.\n%s\n\n"), - local_error->message); - g_clear_error (&local_error); - } + imap_store->capabilities = is->capabilities; + imap_set_server_level(imap_store); } return TRUE; } +static GList * +imap_store_query_auth_types (CamelService *service, + GCancellable *cancellable, + GError **error) +{ + CamelImapStore *store = CAMEL_IMAP_STORE (service); + CamelServiceAuthType *authtype; + GList *sasl_types, *t, *next; + gboolean connected; + + if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) { + g_set_error ( + error, CAMEL_SERVICE_ERROR, + CAMEL_SERVICE_ERROR_UNAVAILABLE, + _("You must be working online to complete this operation")); + return NULL; + } + + camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); + connected = store->istream != NULL && store->connected; + if (!connected) + connected = connect_to_server_wrapper ( + service, cancellable, error); + camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); + if (!connected) + return NULL; + + sasl_types = camel_sasl_authtype_list (FALSE); + for (t = sasl_types; t; t = next) { + authtype = t->data; + next = t->next; + + if (!g_hash_table_lookup (store->authtypes, authtype->authproto)) { + sasl_types = g_list_remove_link (sasl_types, t); + g_list_free_1 (t); + } + } + + return g_list_prepend (sasl_types, &camel_imap_password_authtype); +} + +static gchar * +imap_store_get_name (CamelService *service, + gboolean brief) +{ + if (brief) + return g_strdup_printf ( + _("IMAP server %s"), + service->url->host); + else + return g_strdup_printf ( + _("IMAP service for %s on %s"), + service->url->user, service->url->host); +} + static gboolean -imap_connect (CamelService *service, GError **error) +imap_store_connect (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelImapStore *store = CAMEL_IMAP_STORE (service); CamelImapResponse *response; @@ -1239,8 +1060,8 @@ imap_connect (CamelService *service, GError **error) return TRUE; camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); - if (!connect_to_server_wrapper (service, error) || - !imap_auth_loop (service, error)) { + if (!connect_to_server_wrapper (service, cancellable, error) || + !imap_auth_loop (service, cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); camel_service_disconnect (service, TRUE, NULL); return FALSE; @@ -1250,7 +1071,7 @@ imap_connect (CamelService *service, GError **error) if (store->capabilities & IMAP_CAPABILITY_NAMESPACE) { struct _namespaces *namespaces; - response = camel_imap_command (store, NULL, &local_error, "NAMESPACE"); + response = camel_imap_command (store, NULL, cancellable, &local_error, "NAMESPACE"); if (!response) goto done; @@ -1334,7 +1155,7 @@ imap_connect (CamelService *service, GError **error) /* This idiom means "tell me the hierarchy separator * for the given path, even if that path doesn't exist. */ - response = camel_imap_command (store, NULL, &local_error, + response = camel_imap_command (store, NULL, cancellable, &local_error, "LIST %G \"\"", use_namespace); } else { @@ -1342,7 +1163,7 @@ imap_connect (CamelService *service, GError **error) * to "tell me about this folder", which will fail if * the folder doesn't exist (eg, if namespace is ""). */ - response = camel_imap_command (store, NULL, &local_error, + response = camel_imap_command (store, NULL, cancellable, &local_error, "LIST \"\" %G", use_namespace); } @@ -1372,13 +1193,13 @@ imap_connect (CamelService *service, GError **error) CamelStoreInfo *si; /* look in all namespaces */ - if (!get_folders_sync (store, NULL, &local_error)) + if (!get_folders_sync (store, NULL, cancellable, &local_error)) goto done; /* Make sure INBOX is present/subscribed */ si = camel_store_summary_path((CamelStoreSummary *)store->summary, "INBOX"); if (si == NULL || (si->flags & CAMEL_FOLDER_SUBSCRIBED) == 0) { - response = camel_imap_command (store, NULL, &local_error, "SUBSCRIBE INBOX"); + response = camel_imap_command (store, NULL, cancellable, &local_error, "SUBSCRIBE INBOX"); if (response != NULL) { camel_imap_response_free (store, response); } @@ -1386,7 +1207,7 @@ imap_connect (CamelService *service, GError **error) camel_store_summary_info_free ((CamelStoreSummary *)store->summary, si); if (local_error != NULL) goto done; - get_folders_sync(store, "INBOX", &local_error); + get_folders_sync(store, "INBOX", cancellable, &local_error); } store->refresh_stamp = time (NULL); @@ -1408,25 +1229,28 @@ done: } static gboolean -imap_disconnect (CamelService *service, gboolean clean, GError **error) +imap_store_disconnect (CamelService *service, + gboolean clean, + GCancellable *cancellable, + GError **error) { CamelImapStore *store = CAMEL_IMAP_STORE (service); if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL && clean) { CamelImapResponse *response; - response = camel_imap_command (store, NULL, NULL, "LOGOUT"); + response = camel_imap_command (store, NULL, NULL, NULL, "LOGOUT"); camel_imap_response_free (store, response); } if (store->istream) { - camel_stream_close (store->istream, NULL); + camel_stream_close (store->istream, cancellable, NULL); g_object_unref (store->istream); store->istream = NULL; } if (store->ostream) { - camel_stream_close (store->ostream, NULL); + camel_stream_close (store->ostream, cancellable, NULL); g_object_unref (store->ostream); store->ostream = NULL; } @@ -1452,6 +1276,219 @@ imap_disconnect (CamelService *service, gboolean clean, GError **error) return TRUE; } +static void +camel_imap_store_class_init (CamelImapStoreClass *class) +{ + GObjectClass *object_class; + CamelServiceClass *service_class; + CamelStoreClass *store_class; + + object_class = G_OBJECT_CLASS (class); + object_class->dispose = imap_store_dispose; + object_class->finalize = imap_store_finalize; + + service_class = CAMEL_SERVICE_CLASS (class); + service_class->construct = imap_store_construct; + service_class->query_auth_types = imap_store_query_auth_types; + service_class->get_name = imap_store_get_name; + service_class->connect = imap_store_connect; + service_class->disconnect = imap_store_disconnect; + + store_class = CAMEL_STORE_CLASS (class); + store_class->hash_folder_name = hash_folder_name; + store_class->compare_folder_name = compare_folder_name; + store_class->get_folder = get_folder; + store_class->create_folder = create_folder; + store_class->delete_folder = delete_folder; + store_class->rename_folder = rename_folder; + store_class->get_folder_info = get_folder_info; + store_class->free_folder_info = camel_store_free_folder_info_full; + store_class->folder_is_subscribed = folder_is_subscribed; + store_class->subscribe_folder = subscribe_folder; + store_class->unsubscribe_folder = unsubscribe_folder; + store_class->noop = imap_noop; + store_class->get_trash = imap_get_trash; + store_class->get_junk = imap_get_junk; + store_class->can_refresh_folder = imap_can_refresh_folder; +} + +static void +camel_imap_store_init (CamelImapStore *imap_store) +{ + imap_store->istream = NULL; + imap_store->ostream = NULL; + + /* TODO: support dir_sep per namespace */ + imap_store->dir_sep = '\0'; + imap_store->current_folder = NULL; + imap_store->connected = FALSE; + imap_store->preauthed = FALSE; + ((CamelStore *)imap_store)->flags |= CAMEL_STORE_SUBSCRIPTIONS; + + imap_store->tag_prefix = imap_tag_prefix++; + if (imap_tag_prefix > 'Z') + imap_tag_prefix = 'A'; +} + +static void +imap_set_server_level (CamelImapStore *store) +{ + if (store->capabilities & IMAP_CAPABILITY_IMAP4REV1) { + store->server_level = IMAP_LEVEL_IMAP4REV1; + store->capabilities |= IMAP_CAPABILITY_STATUS; + } else if (store->capabilities & IMAP_CAPABILITY_IMAP4) + store->server_level = IMAP_LEVEL_IMAP4; + else + store->server_level = IMAP_LEVEL_UNKNOWN; +} + +/* folder_name is path name */ +static CamelFolderInfo * +imap_build_folder_info(CamelImapStore *imap_store, const gchar *folder_name) +{ + CamelURL *url; + const gchar *name; + CamelFolderInfo *fi; + + fi = camel_folder_info_new (); + fi->full_name = g_strdup(folder_name); + fi->unread = -1; + fi->total = -1; + + url = camel_url_new (imap_store->base_url, NULL); + g_free (url->path); + url->path = g_strdup_printf ("/%s", folder_name); + fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL); + camel_url_free(url); + name = strrchr (fi->full_name, '/'); + if (name == NULL) + name = fi->full_name; + else + name++; + if (!g_ascii_strcasecmp (fi->full_name, "INBOX")) + fi->name = g_strdup (_("Inbox")); + /* Do not localize the rest, these are from a server, thus shouldn't be localized */ + /*else if (!g_ascii_strcasecmp (fi->full_name, "Drafts")) + fi->name = g_strdup (_("Drafts")); + else if (!g_ascii_strcasecmp (fi->full_name, "Sent")) + fi->name = g_strdup (_("Sent")); + else if (!g_ascii_strcasecmp (fi->full_name, "Templates")) + fi->name = g_strdup (_("Templates")); + else if (!g_ascii_strcasecmp (fi->full_name, "Trash")) + fi->name = g_strdup (_("Trash"));*/ + else + fi->name = g_strdup (name); + + return fi; +} + +static gboolean +imap_folder_effectively_unsubscribed (CamelImapStore *imap_store, + const gchar *folder_name, + GError **error) +{ + CamelFolderInfo *fi; + CamelStoreInfo *si; + + si = camel_store_summary_path((CamelStoreSummary *)imap_store->summary, folder_name); + if (si) { + if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) { + si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED; + camel_store_summary_touch((CamelStoreSummary *)imap_store->summary); + camel_store_summary_save((CamelStoreSummary *)imap_store->summary); + } + camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si); + } + + if (imap_store->renaming) { + /* we don't need to emit a "folder_unsubscribed" signal + if we are in the process of renaming folders, so we + are done here... */ + return TRUE; + + } + + fi = imap_build_folder_info(imap_store, folder_name); + camel_store_folder_unsubscribed (CAMEL_STORE (imap_store), fi); + camel_folder_info_free (fi); + + return TRUE; +} + +static void +imap_forget_folder (CamelImapStore *imap_store, const gchar *folder_name, GError **error) +{ + gchar *state_file; + gchar *journal_file; + gchar *folder_dir, *storage_path; + CamelFolderInfo *fi; + const gchar *name; + + name = strrchr (folder_name, imap_store->dir_sep); + if (name) + name++; + else + name = folder_name; + + storage_path = g_strdup_printf ("%s/folders", imap_store->storage_path); + folder_dir = imap_path_to_physical (storage_path, folder_name); + g_free (storage_path); + if (g_access (folder_dir, F_OK) != 0) { + g_free (folder_dir); + goto event; + } + + /* Delete summary and all the data */ + journal_file = g_strdup_printf ("%s/journal", folder_dir); + g_unlink (journal_file); + g_free (journal_file); + + state_file = g_strdup_printf ("%s/cmeta", folder_dir); + g_unlink (state_file); + g_free (state_file); + + camel_db_delete_folder (((CamelStore *)imap_store)->cdb_w, folder_name, NULL); + camel_imap_message_cache_delete (folder_dir, NULL); + + state_file = g_strdup_printf("%s/subfolders", folder_dir); + g_rmdir(state_file); + g_free(state_file); + + g_rmdir (folder_dir); + g_free (folder_dir); + + event: + + camel_store_summary_remove_path((CamelStoreSummary *)imap_store->summary, folder_name); + camel_store_summary_save((CamelStoreSummary *)imap_store->summary); + + fi = imap_build_folder_info(imap_store, folder_name); + camel_store_folder_deleted (CAMEL_STORE (imap_store), fi); + camel_folder_info_free (fi); +} + +static gboolean +imap_check_folder_still_extant (CamelImapStore *imap_store, const gchar *full_name, + GError **error) +{ + CamelImapResponse *response; + + response = camel_imap_command (imap_store, NULL, NULL, NULL, "LIST \"\" %F", + full_name); + + if (response) { + gboolean stillthere = response->untagged->len != 0; + + camel_imap_response_free_without_processing (imap_store, response); + + return stillthere; + } + + /* if the command was rejected, there must be some other error, + assume it worked so we dont blow away the folder unecessarily */ + return TRUE; +} + static gboolean imap_summary_is_dirty (CamelFolderSummary *summary) { @@ -1473,6 +1510,7 @@ imap_summary_is_dirty (CamelFolderSummary *summary) static gboolean imap_noop (CamelStore *store, + GCancellable *cancellable, GError **error) { CamelImapStore *imap_store = (CamelImapStore *) store; @@ -1490,9 +1528,10 @@ imap_noop (CamelStore *store, current_folder = imap_store->current_folder; if (current_folder && imap_summary_is_dirty (current_folder->summary)) { /* let's sync the flags instead. NB: must avoid folder lock */ - success = CAMEL_FOLDER_GET_CLASS (current_folder)->sync (current_folder, FALSE, error); + success = CAMEL_FOLDER_GET_CLASS (current_folder)->sync ( + current_folder, FALSE, cancellable, error); } else { - response = camel_imap_command (imap_store, NULL, error, "NOOP"); + response = camel_imap_command (imap_store, NULL, cancellable, error, "NOOP"); if (response) camel_imap_response_free (imap_store, response); else @@ -1505,13 +1544,17 @@ done: } static CamelFolder * -imap_get_trash (CamelStore *store, GError **error) +imap_get_trash (CamelStore *store, + GCancellable *cancellable, + GError **error) { CamelFolder *folder = NULL; CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); if (imap_store->real_trash_path && *imap_store->real_trash_path) { - folder = camel_store_get_folder (store, imap_store->real_trash_path, 0, NULL); + folder = camel_store_get_folder ( + store, imap_store->real_trash_path, 0, + cancellable, NULL); if (!folder) { /* cannot find configured folder, just report on console and unset in a store structure to not try again */ g_free (imap_store->real_trash_path); @@ -1522,7 +1565,8 @@ imap_get_trash (CamelStore *store, GError **error) if (folder) return folder; - folder = CAMEL_STORE_CLASS (camel_imap_store_parent_class)->get_trash (store, error); + folder = CAMEL_STORE_CLASS (camel_imap_store_parent_class)-> + get_trash (store, cancellable, error); if (folder) { CamelObject *object = CAMEL_OBJECT (folder); @@ -1538,13 +1582,17 @@ imap_get_trash (CamelStore *store, GError **error) } static CamelFolder * -imap_get_junk (CamelStore *store, GError **error) +imap_get_junk (CamelStore *store, + GCancellable *cancellable, + GError **error) { CamelFolder *folder = NULL; CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); if (imap_store->real_junk_path && *imap_store->real_junk_path) { - folder = camel_store_get_folder (store, imap_store->real_junk_path, 0, NULL); + folder = camel_store_get_folder ( + store, imap_store->real_junk_path, 0, + cancellable, NULL); if (!folder) { /* cannot find configured folder, just report on console and unset in a store structure to not try again */ g_free (imap_store->real_junk_path); @@ -1555,7 +1603,8 @@ imap_get_junk (CamelStore *store, GError **error) if (folder) return folder; - folder = CAMEL_STORE_CLASS (camel_imap_store_parent_class)->get_junk (store, error); + folder = CAMEL_STORE_CLASS (camel_imap_store_parent_class)-> + get_junk (store, cancellable, error); if (folder) { CamelObject *object = CAMEL_OBJECT (folder); @@ -1619,7 +1668,7 @@ get_folder_status (CamelImapStore *imap_store, const gchar *folder_name, const g /* FIXME: we assume the server is STATUS-capable */ - response = camel_imap_command (imap_store, NULL, NULL, + response = camel_imap_command (imap_store, NULL, NULL, NULL, "STATUS %F (%s)", folder_name, type); @@ -1697,7 +1746,11 @@ get_folder_status (CamelImapStore *imap_store, const gchar *folder_name, const g } static CamelFolder * -get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error) +get_folder (CamelStore *store, + const gchar *folder_name, + guint32 flags, + GCancellable *cancellable, + GError **error) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); CamelImapResponse *response; @@ -1736,7 +1789,7 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError * imap_store->current_folder = NULL; } - response = camel_imap_command (imap_store, NULL, &local_error, "SELECT %F", folder_name); + response = camel_imap_command (imap_store, NULL, cancellable, &local_error, "SELECT %F", folder_name); if (!response) { gchar *folder_real, *parent_name, *parent_real; const gchar *c; @@ -1786,7 +1839,7 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError * gint flags; gint i; - if (!(response = camel_imap_command (imap_store, NULL, error, "LIST \"\" %G", parent_real))) { + if (!(response = camel_imap_command (imap_store, NULL, cancellable, error, "LIST \"\" %G", parent_real))) { camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); g_free (parent_name); g_free (parent_real); @@ -1840,7 +1893,8 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError * } /* delete the old parent and recreate it */ - if (!delete_folder (store, parent_name, error)) { + if (!delete_folder ( + store, parent_name, cancellable, error)) { camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK); g_free (parent_name); g_free (parent_real); @@ -1849,7 +1903,7 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError * /* add the dirsep to the end of parent_name */ name = g_strdup_printf ("%s%c", parent_real, imap_store->dir_sep); - response = camel_imap_command (imap_store, NULL, error, "CREATE %G", + response = camel_imap_command (imap_store, NULL, cancellable, error, "CREATE %G", name); g_free (name); @@ -1868,13 +1922,13 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError * g_free (parent_name); folder_real = camel_imap_store_summary_path_to_full (imap_store->summary, folder_name, imap_store->dir_sep); - response = camel_imap_command (imap_store, NULL, error, "CREATE %G", folder_real); + response = camel_imap_command (imap_store, NULL, cancellable, error, "CREATE %G", folder_real); if (response) { camel_imap_store_summary_add_from_full (imap_store->summary, folder_real, imap_store->dir_sep); camel_imap_response_free (imap_store, response); - response = camel_imap_command (imap_store, NULL, NULL, "SELECT %F", folder_name); + response = camel_imap_command (imap_store, NULL, NULL, NULL, "SELECT %F", folder_name); } g_free (folder_real); if (!response) { @@ -1901,7 +1955,8 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError * g_free (folder_dir); if (new_folder) { imap_store->current_folder = g_object_ref (new_folder); - if (!camel_imap_folder_selected (new_folder, response, error)) { + if (!camel_imap_folder_selected ( + new_folder, response, cancellable, error)) { g_object_unref (imap_store->current_folder); imap_store->current_folder = NULL; @@ -1958,6 +2013,7 @@ get_folder_offline (CamelStore *store, const gchar *folder_name, static gboolean delete_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); @@ -1972,7 +2028,7 @@ delete_folder (CamelStore *store, } /* make sure this folder isn't currently SELECTed */ - response = camel_imap_command (imap_store, NULL, error, "SELECT INBOX"); + response = camel_imap_command (imap_store, NULL, cancellable, error, "SELECT INBOX"); if (!response) { success = FALSE; goto fail; @@ -1984,7 +2040,7 @@ delete_folder (CamelStore *store, /* no need to actually create a CamelFolder for INBOX */ imap_store->current_folder = NULL; - response = camel_imap_command(imap_store, NULL, error, "DELETE %F", folder_name); + response = camel_imap_command(imap_store, NULL, cancellable, error, "DELETE %F", folder_name); if (response) { camel_imap_response_free (imap_store, response); imap_forget_folder (imap_store, folder_name, NULL); @@ -1998,7 +2054,10 @@ fail: } static void -manage_subscriptions (CamelStore *store, const gchar *old_name, gboolean subscribe) +manage_subscriptions (CamelStore *store, + const gchar *old_name, + gboolean subscribe, + GCancellable *cancellable) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); CamelStoreInfo *si; @@ -2013,9 +2072,11 @@ manage_subscriptions (CamelStore *store, const gchar *old_name, gboolean subscri path = camel_store_info_path (imap_store->summary, si); if (strncmp (path, old_name, olen) == 0) { if (subscribe) - subscribe_folder (store, path, NULL); + subscribe_folder ( + store, path, cancellable, NULL); else - unsubscribe_folder (store, path, NULL); + unsubscribe_folder ( + store, path, cancellable, NULL); } camel_store_summary_info_free ((CamelStoreSummary *)imap_store->summary, si); } @@ -2049,7 +2110,7 @@ rename_folder_info (CamelImapStore *imap_store, const gchar *old_name, const gch if (imap_store->dir_sep == '.') { CamelImapResponse *response; - response = camel_imap_command (imap_store, NULL, NULL, "RENAME %F %G", path, nfull); + response = camel_imap_command (imap_store, NULL, NULL, NULL, "RENAME %F %G", path, nfull); if (response) camel_imap_response_free (imap_store, response); } @@ -2069,6 +2130,7 @@ static gboolean rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name_in, + GCancellable *cancellable, GError **error) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); @@ -2086,7 +2148,7 @@ rename_folder (CamelStore *store, /* make sure this folder isn't currently SELECTed - it's actually possible to rename INBOX but if you do another INBOX will immediately be created by the server */ - response = camel_imap_command (imap_store, NULL, error, "SELECT INBOX"); + response = camel_imap_command (imap_store, NULL, cancellable, error, "SELECT INBOX"); if (!response) { success = FALSE; goto fail; @@ -2100,12 +2162,14 @@ rename_folder (CamelStore *store, imap_store->renaming = TRUE; if (imap_store->parameters & IMAP_PARAM_SUBSCRIPTIONS) - manage_subscriptions (store, old_name, FALSE); + manage_subscriptions ( + store, old_name, FALSE, cancellable); - response = camel_imap_command (imap_store, NULL, error, "RENAME %F %F", old_name, new_name_in); + response = camel_imap_command (imap_store, NULL, cancellable, error, "RENAME %F %F", old_name, new_name_in); if (!response) { if (imap_store->parameters & IMAP_PARAM_SUBSCRIPTIONS) - manage_subscriptions (store, old_name, TRUE); + manage_subscriptions ( + store, old_name, TRUE, cancellable); success = FALSE; goto fail; } @@ -2116,7 +2180,8 @@ rename_folder (CamelStore *store, rename_folder_info (imap_store, old_name, new_name_in); if (imap_store->parameters & IMAP_PARAM_SUBSCRIPTIONS) - manage_subscriptions (store, new_name_in, TRUE); + manage_subscriptions ( + store, new_name_in, TRUE, cancellable); storage_path = g_strdup_printf("%s/folders", imap_store->storage_path); oldpath = imap_path_to_physical (storage_path, old_name); @@ -2160,8 +2225,11 @@ fail: } static CamelFolderInfo * -create_folder (CamelStore *store, const gchar *parent_name, - const gchar *folder_name, GError **error) +create_folder (CamelStore *store, + const gchar *parent_name, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); gchar *full_name, *resp, *thisone, *parent_real, *real_name; @@ -2208,7 +2276,7 @@ create_folder (CamelStore *store, const gchar *parent_name, } need_convert = FALSE; - response = camel_imap_command (imap_store, NULL, error, "LIST \"\" %G", + response = camel_imap_command (imap_store, NULL, cancellable, error, "LIST \"\" %G", parent_real); if (!response) /* whoa, this is bad */ { g_free (parent_real); @@ -2260,12 +2328,12 @@ create_folder (CamelStore *store, const gchar *parent_name, } /* delete the old parent and recreate it */ - if (!delete_folder (store, parent_name, error)) + if (!delete_folder (store, parent_name, cancellable, error)) return NULL; /* add the dirsep to the end of parent_name */ name = g_strdup_printf ("%s%c", parent_real, imap_store->dir_sep); - response = camel_imap_command (imap_store, NULL, error, "CREATE %G", + response = camel_imap_command (imap_store, NULL, cancellable, error, "CREATE %G", name); g_free (name); @@ -2282,7 +2350,7 @@ create_folder (CamelStore *store, const gchar *parent_name, real_name = camel_imap_store_summary_path_to_full (imap_store->summary, folder_name, imap_store->dir_sep); full_name = imap_concat (imap_store, parent_real, real_name); g_free (real_name); - response = camel_imap_command (imap_store, NULL, error, "CREATE %G", full_name); + response = camel_imap_command (imap_store, NULL, cancellable, error, "CREATE %G", full_name); if (response) { CamelImapStoreInfo *si; @@ -2438,7 +2506,10 @@ get_folders_free (gpointer k, gpointer v, gpointer d) } static gboolean -get_folders_sync (CamelImapStore *imap_store, const gchar *ppattern, GError **error) +get_folders_sync (CamelImapStore *imap_store, + const gchar *ppattern, + GCancellable *cancellable, + GError **error) { CamelImapResponse *response; CamelFolderInfo *fi, *hfi; @@ -2474,7 +2545,7 @@ get_folders_sync (CamelImapStore *imap_store, const gchar *ppattern, GError **er } for (j = 0; j < 2; j++) { - response = camel_imap_command (imap_store, NULL, error, + response = camel_imap_command (imap_store, NULL, cancellable, error, "%s \"\" %G", j==1 ? "LSUB" : "LIST", pattern); if (!response) { @@ -2634,14 +2705,14 @@ refresh_refresh (CamelSession *session, CamelSessionThreadMsg *msg) goto done; if (store->users_namespace && store->users_namespace[0]) { - if (!get_folders_sync (store, "INBOX", &m->error)) + if (!get_folders_sync (store, "INBOX", NULL, &m->error)) goto done; } else { - get_folders_sync (store, "*", NULL); + get_folders_sync (store, "*", NULL, NULL); } /* look in all namespaces */ - get_folders_sync (store, NULL, &m->error); + get_folders_sync (store, NULL, NULL, &m->error); camel_store_summary_save ((CamelStoreSummary *)store->summary); done: camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); @@ -2665,6 +2736,7 @@ static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); @@ -2736,13 +2808,13 @@ get_folder_info (CamelStore *store, } ns = camel_imap_store_summary_get_main_namespace (imap_store->summary); - if (!get_folders_sync (imap_store, pattern, error)) + if (!get_folders_sync (imap_store, pattern, cancellable, error)) goto fail; if (pattern[0] != '*' && ns) { pattern[i] = ns->sep; pattern[i+1] = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)?'*':'%'; pattern[i+2] = 0; - get_folders_sync (imap_store, pattern, NULL); + get_folders_sync (imap_store, pattern, cancellable, NULL); } camel_store_summary_save ((CamelStoreSummary *)imap_store->summary); camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); @@ -2893,6 +2965,7 @@ folder_is_subscribed (CamelStore *store, static gboolean subscribe_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); @@ -2908,7 +2981,7 @@ subscribe_folder (CamelStore *store, goto done; } - response = camel_imap_command (imap_store, NULL, error, + response = camel_imap_command (imap_store, NULL, cancellable, error, "SUBSCRIBE %F", folder_name); if (!response) { success = FALSE; @@ -2948,6 +3021,7 @@ done: static gboolean unsubscribe_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); @@ -2961,7 +3035,7 @@ unsubscribe_folder (CamelStore *store, goto done; } - response = camel_imap_command (imap_store, NULL, error, + response = camel_imap_command (imap_store, NULL, cancellable, error, "UNSUBSCRIBE %F", folder_name); if (!response) { success = FALSE; @@ -3025,7 +3099,10 @@ camel_imap_store_connected (CamelImapStore *store, GError **error) } gssize -camel_imap_store_readline (CamelImapStore *store, gchar **dest, GError **error) +camel_imap_store_readline (CamelImapStore *store, + gchar **dest, + GCancellable *cancellable, + GError **error) { CamelStreamBuffer *stream; gchar linebuf[1024] = {0}; @@ -3048,7 +3125,7 @@ camel_imap_store_readline (CamelImapStore *store, gchar **dest, GError **error) stream = CAMEL_STREAM_BUFFER (store->istream); ba = g_byte_array_new (); - while ((nread = camel_stream_buffer_gets (stream, linebuf, sizeof (linebuf), error)) > 0) { + while ((nread = camel_stream_buffer_gets (stream, linebuf, sizeof (linebuf), cancellable, error)) > 0) { g_byte_array_append (ba, (const guint8 *) linebuf, nread); if (linebuf[nread - 1] == '\n') break; diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h index 8e38fe3..dffaa1c 100644 --- a/camel/providers/imap/camel-imap-store.h +++ b/camel/providers/imap/camel-imap-store.h @@ -172,7 +172,7 @@ GType camel_imap_store_get_type (void); gboolean camel_imap_store_connected (CamelImapStore *store, GError **error); -gssize camel_imap_store_readline (CamelImapStore *store, gchar **dest, GError **error); +gssize camel_imap_store_readline (CamelImapStore *store, gchar **dest, GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c index e7a1b77..f648740 100644 --- a/camel/providers/imap/camel-imap-summary.c +++ b/camel/providers/imap/camel-imap-summary.c @@ -384,16 +384,19 @@ content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelM } void -camel_imap_summary_add_offline (CamelFolderSummary *summary, const gchar *uid, - CamelMimeMessage *message, - const CamelMessageInfo *info) +camel_imap_summary_add_offline (CamelFolderSummary *summary, + const gchar *uid, + CamelMimeMessage *message, + const CamelMessageInfo *info) { CamelImapMessageInfo *mi; const CamelFlag *flag; const CamelTag *tag; /* Create summary entry */ - mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (summary, message, NULL); + mi = (CamelImapMessageInfo *) + camel_folder_summary_info_new_from_message ( + summary, message, NULL); /* Copy flags 'n' tags */ mi->info.flags = camel_message_info_flags (info); @@ -416,8 +419,9 @@ camel_imap_summary_add_offline (CamelFolderSummary *summary, const gchar *uid, } void -camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary, const gchar *uid, - const CamelMessageInfo *info) +camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary, + const gchar *uid, + const CamelMessageInfo *info) { CamelImapMessageInfo *mi; diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h index d7eefb1..1f01238 100644 --- a/camel/providers/imap/camel-imap-summary.h +++ b/camel/providers/imap/camel-imap-summary.h @@ -82,17 +82,18 @@ struct _CamelImapSummaryClass { }; -GType camel_imap_summary_get_type (void); -CamelFolderSummary *camel_imap_summary_new (struct _CamelFolder *folder, const gchar *filename); - -void camel_imap_summary_add_offline (CamelFolderSummary *summary, - const gchar *uid, - CamelMimeMessage *message, - const CamelMessageInfo *info); - -void camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary, - const gchar *uid, - const CamelMessageInfo *info); +GType camel_imap_summary_get_type (void); +CamelFolderSummary * + camel_imap_summary_new (CamelFolder *folder, + const gchar *filename); +void camel_imap_summary_add_offline (CamelFolderSummary *summary, + const gchar *uid, + CamelMimeMessage *message, + const CamelMessageInfo *info); +void camel_imap_summary_add_offline_uncached + (CamelFolderSummary *summary, + const gchar *uid, + const CamelMessageInfo *info); G_END_DECLS diff --git a/camel/providers/imap/camel-imap-wrapper.c b/camel/providers/imap/camel-imap-wrapper.c index d3088e9..099ac9b 100644 --- a/camel/providers/imap/camel-imap-wrapper.c +++ b/camel/providers/imap/camel-imap-wrapper.c @@ -92,6 +92,7 @@ imap_wrapper_finalize (GObject *object) static gssize imap_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream, + GCancellable *cancellable, GError **error) { CamelImapWrapper *imap_wrapper = CAMEL_IMAP_WRAPPER (data_wrapper); @@ -102,7 +103,7 @@ imap_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, datastream = camel_imap_folder_fetch_data ( imap_wrapper->folder, imap_wrapper->uid, - imap_wrapper->part_spec, FALSE, NULL); + imap_wrapper->part_spec, FALSE, cancellable, NULL); if (!datastream) { CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock); @@ -125,7 +126,7 @@ imap_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock); return CAMEL_DATA_WRAPPER_CLASS (camel_imap_wrapper_parent_class)-> - write_to_stream (data_wrapper, stream, error); + write_to_stream (data_wrapper, stream, cancellable, error); } static void @@ -181,7 +182,7 @@ camel_imap_wrapper_new (CamelImapFolder *imap_folder, /* Download the attachments if sync_offline is set, else skip them by checking only in cache */ stream = camel_imap_folder_fetch_data (imap_folder, uid, part_spec, - !sync_offline, NULL); + !sync_offline, NULL, NULL); if (stream) { imap_wrapper_hydrate (imap_wrapper, stream); diff --git a/camel/providers/imapx/camel-imapx-conn-manager.c b/camel/providers/imapx/camel-imapx-conn-manager.c index d73c77d..97517df 100644 --- a/camel/providers/imapx/camel-imapx-conn-manager.c +++ b/camel/providers/imapx/camel-imapx-conn-manager.c @@ -54,7 +54,7 @@ free_connection (gpointer data, gpointer user_data) ConnectionInfo *cinfo = (ConnectionInfo *) data; CamelIMAPXServer *conn = cinfo->conn; - camel_imapx_server_connect (conn, NULL); + camel_imapx_server_connect (conn, NULL, NULL); g_object_unref (conn); g_hash_table_destroy (cinfo->folders); @@ -242,7 +242,10 @@ imapx_find_connection (CamelIMAPXConnManager *con_man, const gchar *folder_name) } static CamelIMAPXServer * -imapx_create_new_connection (CamelIMAPXConnManager *con_man, const gchar *folder_name, GError **error) +imapx_create_new_connection (CamelIMAPXConnManager *con_man, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelIMAPXServer *conn; CamelStore *store = con_man->priv->store; @@ -253,7 +256,7 @@ imapx_create_new_connection (CamelIMAPXConnManager *con_man, const gchar *folder camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); conn = camel_imapx_server_new (CAMEL_STORE (store), CAMEL_SERVICE (store)->url); - if (camel_imapx_server_connect (conn, error)) { + if (camel_imapx_server_connect (conn, cancellable, error)) { g_object_ref (conn); } else { g_object_unref (conn); @@ -307,7 +310,10 @@ camel_imapx_conn_manager_set_n_connections (CamelIMAPXConnManager *con_man, guin } CamelIMAPXServer * -camel_imapx_conn_manager_get_connection (CamelIMAPXConnManager *con_man, const gchar *folder_name, GError **error) +camel_imapx_conn_manager_get_connection (CamelIMAPXConnManager *con_man, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelIMAPXServer *conn = NULL; @@ -317,7 +323,7 @@ camel_imapx_conn_manager_get_connection (CamelIMAPXConnManager *con_man, const g conn = imapx_find_connection (con_man, folder_name); if (!conn) - conn = imapx_create_new_connection (con_man, folder_name, error); + conn = imapx_create_new_connection (con_man, folder_name, cancellable, error); CON_UNLOCK (con_man); diff --git a/camel/providers/imapx/camel-imapx-conn-manager.h b/camel/providers/imapx/camel-imapx-conn-manager.h index ed866ba..65171bd 100644 --- a/camel/providers/imapx/camel-imapx-conn-manager.h +++ b/camel/providers/imapx/camel-imapx-conn-manager.h @@ -61,6 +61,7 @@ void camel_imapx_conn_manager_set_n_connections (CamelIMAPXConnManager *con_ma guint n_connections); CamelIMAPXServer * camel_imapx_conn_manager_get_connection (CamelIMAPXConnManager *con_man, const gchar *folder_name, + GCancellable *cancellable, GError **error); void camel_imapx_conn_manager_close_connections (CamelIMAPXConnManager *con_man); GSList * camel_imapx_conn_manager_get_connections (CamelIMAPXConnManager *con_man); diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c index e3cfa03..dcefdc9 100644 --- a/camel/providers/imapx/camel-imapx-folder.c +++ b/camel/providers/imapx/camel-imapx-folder.c @@ -147,7 +147,9 @@ imapx_folder_finalize (GObject *object) } static gboolean -imapx_refresh_info (CamelFolder *folder, GError **error) +imapx_refresh_info (CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelIMAPXStore *istore; @@ -168,9 +170,9 @@ imapx_refresh_info (CamelFolder *folder, GError **error) if (!camel_service_connect ((CamelService *)istore, error)) return FALSE; - server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error); + server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error); if (server != NULL) { - success = camel_imapx_server_refresh_info (server, folder, error); + success = camel_imapx_server_refresh_info (server, folder, cancellable, error); camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder)); g_object_unref (server); } @@ -179,7 +181,9 @@ imapx_refresh_info (CamelFolder *folder, GError **error) } static gboolean -imapx_expunge (CamelFolder *folder, GError **error) +imapx_expunge (CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelIMAPXStore *istore; @@ -196,9 +200,9 @@ imapx_expunge (CamelFolder *folder, GError **error) return FALSE; } - server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error); + server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error); if (server) { - camel_imapx_server_expunge (server, folder, error); + camel_imapx_server_expunge (server, folder, cancellable, error); camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder)); g_object_unref (server); return TRUE; @@ -208,7 +212,10 @@ imapx_expunge (CamelFolder *folder, GError **error) } static gboolean -imapx_sync (CamelFolder *folder, gboolean expunge, GError **error) +imapx_sync (CamelFolder *folder, + gboolean expunge, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelIMAPXStore *istore; @@ -225,17 +232,17 @@ imapx_sync (CamelFolder *folder, gboolean expunge, GError **error) return FALSE; } - server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error); + server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error); if (!server) return FALSE; - camel_imapx_server_sync_changes (server, folder, NULL); + camel_imapx_server_sync_changes (server, folder, cancellable NULL); /* Sync twice - make sure deleted flags are written out, then sync again incase expunge changed anything */ if (expunge) - camel_imapx_server_expunge (server, folder, NULL); + camel_imapx_server_expunge (server, folder, cancellable, NULL); camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder)); g_object_unref (server); @@ -244,7 +251,10 @@ imapx_sync (CamelFolder *folder, gboolean expunge, GError **error) } static CamelMimeMessage * -imapx_get_message (CamelFolder *folder, const gchar *uid, GError **error) +imapx_get_message (CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { CamelMimeMessage *msg = NULL; CamelStream *stream = NULL; @@ -283,9 +293,9 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, GError **error) return NULL; } - server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error); + server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error); if (server) { - stream = camel_imapx_server_get_message (server, folder, uid, error); + stream = camel_imapx_server_get_message (server, folder, uid, cancellable, error); camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder)); g_object_unref (server); } else @@ -296,7 +306,7 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, GError **error) msg = camel_mime_message_new (); g_mutex_lock (ifolder->stream_lock); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)msg, stream, error) == -1) { + if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)msg, stream, cancellable, error) == -1) { g_object_unref (msg); msg = NULL; } @@ -308,7 +318,10 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, GError **error) } static gboolean -imapx_sync_message (CamelFolder *folder, const gchar *uid, GError **error) +imapx_sync_message (CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelIMAPXStore *istore; @@ -326,11 +339,11 @@ imapx_sync_message (CamelFolder *folder, const gchar *uid, GError **error) return FALSE; } - server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error); + server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error); if (server == NULL) return FALSE; - success = camel_imapx_server_sync_message (server, folder, uid, error); + success = camel_imapx_server_sync_message (server, folder, uid, cancellable, error); camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder)); g_object_unref (server); @@ -338,9 +351,13 @@ imapx_sync_message (CamelFolder *folder, const gchar *uid, GError **error) } static gboolean -imapx_transfer_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *dest, GPtrArray **transferred_uids, - gboolean delete_originals, GError **error) +imapx_transfer_messages_to (CamelFolder *source, + GPtrArray *uids, + CamelFolder *dest, + GPtrArray **transferred_uids, + gboolean delete_originals, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelIMAPXStore *istore; @@ -358,20 +375,25 @@ imapx_transfer_messages_to (CamelFolder *source, GPtrArray *uids, return FALSE; } - server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (source), error); + server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (source), cancellable, error); if (server) { - success = camel_imapx_server_copy_message (server, source, dest, uids, delete_originals, error); + success = camel_imapx_server_copy_message (server, source, dest, uids, delete_originals, cancellable, error); camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (source)); g_object_unref (server); } - imapx_refresh_info (dest, NULL); + imapx_refresh_info (dest, cancellable, NULL); return success; } static gboolean -imapx_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, GError **error) +imapx_append_message (CamelFolder *folder, + CamelMimeMessage *message, + const CamelMessageInfo *info, + gchar **appended_uid, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelIMAPXStore *istore; @@ -392,9 +414,10 @@ imapx_append_message (CamelFolder *folder, CamelMimeMessage *message, const Came if (appended_uid) *appended_uid = NULL; - server = camel_imapx_store_get_server (istore, NULL, error); + server = camel_imapx_store_get_server (istore, NULL, cancellable, error); if (server) { - success = camel_imapx_server_append_message (server, folder, message, info, error); + success = camel_imapx_server_append_message ( + server, folder, message, info, cancellable, error); g_object_unref (server); } diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c index 760d0cc..35dd739 100644 --- a/camel/providers/imapx/camel-imapx-server.c +++ b/camel/providers/imapx/camel-imapx-server.c @@ -96,7 +96,7 @@ void imapx_uidset_init (struct _uidset_state *ss, gint total, gint limit); gint imapx_uidset_done (struct _uidset_state *ss, struct _CamelIMAPXCommand *ic); gint imapx_uidset_add (struct _uidset_state *ss, struct _CamelIMAPXCommand *ic, const gchar *uid); static gboolean imapx_command_idle_stop (CamelIMAPXServer *is, GError **error); -static gint imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error); +static gint imapx_continuation(CamelIMAPXServer *imap, gboolean litplus, GCancellable *cancellable, GError **error); static gboolean imapx_disconnect (CamelIMAPXServer *is); static gint imapx_uid_cmp (gconstpointer ap, gconstpointer bp, gpointer data); @@ -146,6 +146,7 @@ struct _CamelIMAPXCommand { /* If exception is set, it means we were not able to parse above status, it might be because user cancelled the operation or io error */ + GCancellable *cancellable; GError *error; guint32 tag; @@ -162,10 +163,10 @@ struct _CamelIMAPXCommand { struct _CamelIMAPXJob *job; }; -CamelIMAPXCommand *camel_imapx_command_new (CamelIMAPXServer *is, const gchar *name, CamelFolder *select, const gchar *fmt, ...); -void camel_imapx_command_add (CamelIMAPXCommand *ic, const gchar *fmt, ...); -void camel_imapx_command_free (CamelIMAPXCommand *ic); -void camel_imapx_command_close (CamelIMAPXCommand *ic); +CamelIMAPXCommand *camel_imapx_command_new(CamelIMAPXServer *is, const gchar *name, CamelFolder *select, GCancellable *cancellable, const gchar *fmt, ...); +void camel_imapx_command_add(CamelIMAPXCommand *ic, const gchar *fmt, ...); +void camel_imapx_command_free(CamelIMAPXCommand *ic); +void camel_imapx_command_close(CamelIMAPXCommand *ic); static gboolean imapx_is_command_queue_empty (CamelIMAPXServer *is); /* states for the connection? */ @@ -231,20 +232,17 @@ typedef struct _CamelIMAPXJob CamelIMAPXJob; struct _CamelIMAPXJob { CamelMsg msg; + GCancellable *cancellable; GError *error; void (*start)(CamelIMAPXServer *is, struct _CamelIMAPXJob *job); - // ?? - //CamelOperation *op; - gint noreply:1; /* dont wait for reply */ guint32 type; /* operation type */ gint pri; /* the command priority */ gshort commands; /* counts how many commands are outstanding */ CamelFolder *folder; - CamelOperation *op; union { struct { @@ -318,7 +316,7 @@ static void imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPX static void imapx_command_copy_messages_step_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic); static gint imapx_refresh_info_uid_cmp (gconstpointer ap, gconstpointer bp); static gint imapx_uids_array_cmp (gconstpointer ap, gconstpointer bp); -static gboolean imapx_server_sync_changes (CamelIMAPXServer *is, CamelFolder *folder, gint pri, GError **error); +static gboolean imapx_server_sync_changes(CamelIMAPXServer *is, CamelFolder *folder, gint pri, GCancellable *cancellable, GError **error); enum _idle_state { IMAPX_IDLE_OFF, @@ -349,7 +347,7 @@ static void imapx_start_idle (CamelIMAPXServer *is); static void imapx_exit_idle (CamelIMAPXServer *is); static void imapx_init_idle (CamelIMAPXServer *is); static gboolean imapx_stop_idle (CamelIMAPXServer *is, GError **error); -static gboolean camel_imapx_server_idle (CamelIMAPXServer *is, CamelFolder *folder, GError **error); +static gboolean camel_imapx_server_idle (CamelIMAPXServer *is, CamelFolder *folder, GCancellable *cancellable, GError **error); enum { USE_SSL_NEVER, @@ -360,7 +358,7 @@ enum { #define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3) #define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS) -static gboolean imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean force, GError **error); +static gboolean imapx_select(CamelIMAPXServer *is, CamelFolder *folder, gboolean force, GCancellable *cancellable, GError **error); G_DEFINE_TYPE (CamelIMAPXServer, camel_imapx_server, CAMEL_TYPE_OBJECT) @@ -462,10 +460,10 @@ imapx_command_add_part (CamelIMAPXCommand *ic, camel_imapx_command_part_t type, /* TODO: seekable streams we could just seek to the end and back */ null = (CamelStreamNull *)camel_stream_null_new (); if ( (type & CAMEL_IMAPX_COMMAND_MASK) == CAMEL_IMAPX_COMMAND_DATAWRAPPER) { - camel_data_wrapper_write_to_stream ((CamelDataWrapper *)ob, (CamelStream *)null, NULL); + camel_data_wrapper_write_to_stream ((CamelDataWrapper *)ob, (CamelStream *)null, NULL, NULL); } else { camel_stream_reset ((CamelStream *)ob, NULL); - camel_stream_write_to_stream ((CamelStream *)ob, (CamelStream *)null, NULL); + camel_stream_write_to_stream ((CamelStream *)ob, (CamelStream *)null, NULL, NULL); camel_stream_reset ((CamelStream *)ob, NULL); } type |= CAMEL_IMAPX_COMMAND_LITERAL_PLUS; @@ -568,11 +566,11 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap) switch (c) { case '%': if (*p == '%') { - camel_stream_write ((CamelStream *)ic->mem, ps, p-ps, NULL); + camel_stream_write ((CamelStream *)ic->mem, ps, p-ps, ic->cancellable, NULL); p++; ps = p; } else { - camel_stream_write ((CamelStream *)ic->mem, ps, p-ps-1, NULL); + camel_stream_write ((CamelStream *)ic->mem, ps, p-ps-1, ic->cancellable, NULL); start = p-1; width = 0; left = FALSE; @@ -625,7 +623,7 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap) break; case 't': /* token */ s = va_arg (ap, gchar *); - camel_stream_write ((CamelStream *)ic->mem, s, strlen (s), NULL); + camel_stream_write ((CamelStream *)ic->mem, s, strlen (s), ic->cancellable, NULL); break; case 's': /* simple string */ s = va_arg (ap, gchar *); @@ -635,27 +633,27 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap) guchar mask = imapx_is_mask (s); if (mask & IMAPX_TYPE_ATOM_CHAR) - camel_stream_write ((CamelStream *)ic->mem, s, strlen (s), NULL); + camel_stream_write ((CamelStream *)ic->mem, s, strlen (s), ic->cancellable, NULL); else if (mask & IMAPX_TYPE_TEXT_CHAR) { - camel_stream_write((CamelStream *)ic->mem, "\"", 1, NULL); + camel_stream_write((CamelStream *)ic->mem, "\"", 1, ic->cancellable, NULL); while (*s) { gchar *start = s; while (*s && imapx_is_quoted_char (*s)) s++; - camel_stream_write ((CamelStream *)ic->mem, start, s-start, NULL); + camel_stream_write ((CamelStream *)ic->mem, start, s-start, ic->cancellable, NULL); if (*s) { - camel_stream_write((CamelStream *)ic->mem, "\\", 1, NULL); - camel_stream_write ((CamelStream *)ic->mem, s, 1, NULL); + camel_stream_write((CamelStream *)ic->mem, "\\", 1, ic->cancellable, NULL); + camel_stream_write ((CamelStream *)ic->mem, s, 1, ic->cancellable, NULL); s++; } } - camel_stream_write((CamelStream *)ic->mem, "\"", 1, NULL); + camel_stream_write((CamelStream *)ic->mem, "\"", 1, ic->cancellable, NULL); } else { imapx_command_add_part (ic, CAMEL_IMAPX_COMMAND_STRING, s); } } else { - camel_stream_write((CamelStream *)ic->mem, "\"\"", 2, NULL); + camel_stream_write((CamelStream *)ic->mem, "\"\"", 2, ic->cancellable, NULL); } if (encoded) { g_free (encoded); @@ -678,18 +676,18 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap) s = encoded; goto output_string; } else - camel_stream_write((CamelStream *)ic->mem, "\"\"", 2, NULL); + camel_stream_write((CamelStream *)ic->mem, "\"\"", 2, ic->cancellable, NULL); break; case 'F': /* IMAP flags set */ f = va_arg (ap, guint32); F = va_arg (ap, CamelFlag *); - imapx_write_flags ((CamelStream *)ic->mem, f, F, NULL); + imapx_write_flags ((CamelStream *)ic->mem, f, F, ic->cancellable, NULL); break; case 'c': d = va_arg (ap, gint); ch = d; - camel_stream_write ((CamelStream *)ic->mem, &ch, 1, NULL); + camel_stream_write ((CamelStream *)ic->mem, &ch, 1, ic->cancellable, NULL); break; case 'd': /* int/unsigned */ case 'u': @@ -716,28 +714,36 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap) c = *p; if (c) { g_assert (c == '\\'); - camel_stream_write ((CamelStream *)ic->mem, ps, p-ps, NULL); + camel_stream_write ((CamelStream *)ic->mem, ps, p-ps, ic->cancellable, NULL); p++; ps = p; } } } - camel_stream_write ((CamelStream *)ic->mem, ps, p-ps-1, NULL); + camel_stream_write ((CamelStream *)ic->mem, ps, p-ps-1, ic->cancellable, NULL); } CamelIMAPXCommand * -camel_imapx_command_new (CamelIMAPXServer *is, const gchar *name, CamelFolder *select, const gchar *fmt, ...) +camel_imapx_command_new (CamelIMAPXServer *is, + const gchar *name, + CamelFolder *select, + GCancellable *cancellable, + const gchar *fmt, ...) { CamelIMAPXCommand *ic; static gint tag = 0; va_list ap; - ic = g_malloc0 (sizeof (*ic)); + if (cancellable != NULL) + g_object_ref (cancellable); + + ic = g_malloc0(sizeof(*ic)); ic->tag = tag++; ic->name = name; ic->mem = (CamelStreamMem *)camel_stream_mem_new (); ic->select = select; + ic->cancellable = cancellable; ic->is = is; camel_dlist_init (&ic->parts); @@ -791,6 +797,9 @@ camel_imapx_command_free (CamelIMAPXCommand *ic) g_free (cp); } + if (ic->cancellable != NULL) + g_object_unref (ic->cancellable); + /* Do NOT try to free the GError. If set it should have been * propagated to the CamelIMAPXJob, so it's either NULL or the * CamelIMAPXJob owns it now. */ @@ -852,7 +861,7 @@ imapx_command_start (CamelIMAPXServer *imap, CamelIMAPXCommand *ic) while (imap->literal == ic && ic->current->type & CAMEL_IMAPX_COMMAND_LITERAL_PLUS) { /* Sent LITERAL+ continuation immediately */ - if (!imapx_continuation (imap, TRUE, &ic->error)) + if (!imapx_continuation(imap, TRUE, ic->cancellable, &ic->error)) goto err; } @@ -895,7 +904,9 @@ static gboolean duplicate_fetch_or_refresh (CamelIMAPXServer *is, CamelIMAPXComm must have QUEUE lock */ static void -imapx_command_start_next (CamelIMAPXServer *is, GError **error) +imapx_command_start_next (CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic, *nc; gint count = 0; @@ -1007,7 +1018,7 @@ imapx_command_start_next (CamelIMAPXServer *is, GError **error) if (ic->select) { c(is->tagprefix, "Selecting folder '%s' for command '%s'(%p)\n", camel_folder_get_full_name (ic->select), ic->name, ic); - imapx_select (is, ic->select, FALSE, error); + imapx_select (is, ic->select, FALSE, cancellable, error); } else { pri = ic->pri; nc = ic->next; @@ -1039,7 +1050,8 @@ imapx_is_command_queue_empty (CamelIMAPXServer *is) } static void -imapx_command_queue (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_queue (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { CamelIMAPXCommand *scan; @@ -1079,7 +1091,7 @@ imapx_command_queue (CamelIMAPXServer *is, CamelIMAPXCommand *ic) scan->prev = ic; } - imapx_command_start_next (is, NULL); + imapx_command_start_next (is, ic->cancellable, NULL); QUEUE_UNLOCK (is); @@ -1222,7 +1234,9 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *imap, gchar *uid, gboolean uns /* handle any untagged responses */ static gint -imapx_untagged (CamelIMAPXServer *imap, GError **error) +imapx_untagged (CamelIMAPXServer *imap, + GCancellable *cancellable, + GError **error) { guint id, len; guchar *token, *p, c; @@ -1232,13 +1246,13 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) e(imap->tagprefix, "got untagged response\n"); id = 0; - tok = camel_imapx_stream_token (imap->stream, &token, &len, error); + tok = camel_imapx_stream_token (imap->stream, &token, &len, cancellable, error); if (tok < 0) return -1; if (tok == IMAPX_TOK_INT) { id = strtoul ((gchar *) token, NULL, 10); - tok = camel_imapx_stream_token (imap->stream, &token, &len, error); + tok = camel_imapx_stream_token (imap->stream, &token, &len, cancellable, error); if (tok < 0) return -1; } @@ -1259,7 +1273,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) case IMAPX_CAPABILITY: if (imap->cinfo) imapx_free_capability (imap->cinfo); - imap->cinfo = imapx_parse_capability (imap->stream, error); + imap->cinfo = imapx_parse_capability (imap->stream, cancellable, error); if (imap->cinfo == NULL) return -1; c(imap->tagprefix, "got capability flags %08x\n", imap->cinfo->capa); @@ -1293,21 +1307,21 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) guchar *token; gint tok; - tok = camel_imapx_stream_token (imap->stream, &token, &len, error); + tok = camel_imapx_stream_token (imap->stream, &token, &len, cancellable, error); if (tok < 0) return -1; if (tok == '(') { unsolicited = FALSE; while (tok != ')') { /* We expect this to be 'EARLIER' */ - tok = camel_imapx_stream_token (imap->stream, &token, &len, error); + tok = camel_imapx_stream_token (imap->stream, &token, &len, cancellable, error); if (tok < 0) return -1; } } else camel_imapx_stream_ungettoken (imap->stream, tok, token, len); - uids = imapx_parse_uids (imap->stream, error); + uids = imapx_parse_uids (imap->stream, cancellable, error); if (uids == NULL) return -1; for (i = 0; i < uids->len; i++) { @@ -1321,7 +1335,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) case IMAPX_NAMESPACE: { CamelIMAPXNamespaceList *nsl = NULL; - nsl = imapx_parse_namespace_list (imap->stream, error); + nsl = imapx_parse_namespace_list (imap->stream, cancellable, error); if (nsl != NULL) { CamelIMAPXStore *imapx_store = (CamelIMAPXStore *) imap->store; CamelIMAPXStoreNamespace *ns; @@ -1353,7 +1367,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) case IMAPX_FLAGS: { guint32 flags; - imapx_parse_flags (imap->stream, &flags, NULL, error); + imapx_parse_flags (imap->stream, &flags, NULL, cancellable, error); c(imap->tagprefix, "flags: %08x\n", flags); break; @@ -1361,7 +1375,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) case IMAPX_FETCH: { struct _fetch_info *finfo; - finfo = imapx_parse_fetch (imap->stream, error); + finfo = imapx_parse_fetch (imap->stream, cancellable, error); if (finfo == NULL) { imapx_free_fetch (finfo); return -1; @@ -1379,7 +1393,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) camel_seekable_stream_seek ((CamelSeekableStream *)job->u.get_message.stream, finfo->offset, CAMEL_STREAM_SET, NULL); } - job->u.get_message.body_len = camel_stream_write_to_stream (finfo->body, job->u.get_message.stream, &job->error); + job->u.get_message.body_len = camel_stream_write_to_stream (finfo->body, job->u.get_message.stream, job->cancellable, &job->error); if (job->u.get_message.body_len == -1) g_prefix_error ( &job->error, @@ -1541,6 +1555,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) if (!camel_folder_summary_check_uid (job->folder->summary, mi->uid)) { CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)job->folder; + gint cnt; camel_folder_summary_add (job->folder->summary, mi); imapx_set_message_info_flags_for_new_message (mi, server_flags, server_user_flags, job->folder); @@ -1551,10 +1566,8 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) g_hash_table_remove (ifolder->ignore_recent, mi->uid); } - if (job->op) { - gint cnt = (camel_folder_summary_count (job->folder->summary) * 100 )/ifolder->exists_on_server; - camel_operation_progress (job->op, cnt?cnt:1); - } + cnt = (camel_folder_summary_count (job->folder->summary) * 100 )/ifolder->exists_on_server; + camel_operation_progress (job->cancellable, cnt?cnt:1); } if (free_user_flags && server_user_flags) @@ -1570,7 +1583,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) case IMAPX_LSUB: lsub = TRUE; case IMAPX_LIST: { - struct _list_info *linfo = imapx_parse_list (imap->stream, error); + struct _list_info *linfo = imapx_parse_list (imap->stream, cancellable, error); CamelIMAPXJob *job; if (!linfo) @@ -1602,7 +1615,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) imap->recent = id; break; case IMAPX_STATUS: { - struct _state_info *sinfo = imapx_parse_status_info (imap->stream, error); + struct _state_info *sinfo = imapx_parse_status_info (imap->stream, cancellable, error); if (sinfo) { CamelIMAPXStoreSummary *s = ((CamelIMAPXStore *)imap->store)->summary; CamelIMAPXStoreNamespace *ns; @@ -1615,7 +1628,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) path_name = camel_imapx_store_summary_full_to_path (s, sinfo->name, ns->sep); c(imap->tagprefix, "Got folder path '%s' for full '%s'\n", path_name, sinfo->name); if (path_name) { - ifolder = (gpointer)camel_store_get_folder (imap->store, path_name, 0, error); + ifolder = (gpointer)camel_store_get_folder (imap->store, path_name, 0, cancellable, error); g_free (path_name); } } @@ -1637,7 +1650,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) case IMAPX_BYE: { guchar *token; - if (camel_imapx_stream_text (imap->stream, &token, NULL)) { + if (camel_imapx_stream_text (imap->stream, &token, cancellable, NULL)) { c(imap->tagprefix, "BYE: %s\n", token); g_set_error ( error, CAMEL_IMAPX_ERROR, 1, @@ -1655,7 +1668,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) /* TODO: validate which ones of these can happen as unsolicited responses */ /* TODO: handle bye/preauth differently */ camel_imapx_stream_ungettoken (imap->stream, tok, token, len); - sinfo = imapx_parse_status (imap->stream, error); + sinfo = imapx_parse_status (imap->stream, cancellable, error); if (sinfo == NULL) return -1; switch (sinfo->condition) { @@ -1714,13 +1727,16 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error) c(imap->tagprefix, "unknown token: %s\n", token); } - return camel_imapx_stream_skip (imap->stream, error); + return camel_imapx_stream_skip (imap->stream, cancellable, error); } /* handle any continuation requests either data continuations, or auth continuation */ static gint -imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error) +imapx_continuation (CamelIMAPXServer *imap, + gboolean litplus, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic, *newliteral = NULL; CamelIMAPXCommandPart *cp; @@ -1730,7 +1746,7 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error) ohter lock here. All other writes go through queue-lock */ if (imapx_idle_supported (imap) && imapx_in_idle (imap)) { - camel_imapx_stream_skip (imap->stream, error); + camel_imapx_stream_skip (imap->stream, cancellable, error); c(imap->tagprefix, "Got continuation response for IDLE \n"); IDLE_LOCK (imap->idle); @@ -1754,8 +1770,8 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error) QUEUE_LOCK (imap); imap->literal = NULL; - imapx_command_start_next (imap, error); - QUEUE_UNLOCK (imap); + imapx_command_start_next (imap, cancellable, error); + QUEUE_UNLOCK(imap); return 1; } @@ -1763,7 +1779,7 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error) ic = imap->literal; if (!litplus) { if (ic == NULL) { - camel_imapx_stream_skip (imap->stream, error); + camel_imapx_stream_skip (imap->stream, cancellable, error); c(imap->tagprefix, "got continuation response with no outstanding continuation requests?\n"); return 1; } @@ -1776,26 +1792,28 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error) switch (cp->type & CAMEL_IMAPX_COMMAND_MASK) { case CAMEL_IMAPX_COMMAND_DATAWRAPPER: c(imap->tagprefix, "writing data wrapper to literal\n"); - camel_data_wrapper_write_to_stream ((CamelDataWrapper *)cp->ob, (CamelStream *)imap->stream, NULL); + camel_data_wrapper_write_to_stream ((CamelDataWrapper *)cp->ob, (CamelStream *)imap->stream, cancellable, NULL); break; case CAMEL_IMAPX_COMMAND_STREAM: c(imap->tagprefix, "writing stream to literal\n"); - camel_stream_write_to_stream ((CamelStream *)cp->ob, (CamelStream *)imap->stream, NULL); + camel_stream_write_to_stream ((CamelStream *)cp->ob, (CamelStream *)imap->stream, cancellable, NULL); break; case CAMEL_IMAPX_COMMAND_AUTH: { gchar *resp; guchar *token; - if (camel_imapx_stream_text (imap->stream, &token, error)) + if (camel_imapx_stream_text (imap->stream, &token, cancellable, error)) return -1; - - resp = camel_sasl_challenge_base64 ((CamelSasl *)cp->ob, (const gchar *) token, error); - g_free (token); + + resp = camel_sasl_challenge_base64 ( + (CamelSasl *) cp->ob, (const gchar *) token, + cancellable, error); + g_free(token); if (resp == NULL) return -1; c(imap->tagprefix, "got auth continuation, feeding token '%s' back to auth mech\n", resp); - camel_stream_write ((CamelStream *)imap->stream, resp, strlen (resp), NULL); + camel_stream_write ((CamelStream *)imap->stream, resp, strlen (resp), cancellable, NULL); g_free (resp); /* we want to keep getting called until we get a status reponse from the server ignore what sasl tells us */ @@ -1810,14 +1828,14 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error) // FIXME: errors if (cp->ob && (file = camel_stream_fs_new_with_name (cp->ob, O_RDONLY, 0, NULL))) { - camel_stream_write_to_stream (file, (CamelStream *)imap->stream, NULL); + camel_stream_write_to_stream (file, (CamelStream *)imap->stream, cancellable, NULL); g_object_unref (file); } else if (cp->ob_size > 0) { // Server is expecting data ... ummm, send it zeros? abort? } break; } case CAMEL_IMAPX_COMMAND_STRING: - camel_stream_write ((CamelStream *)imap->stream, cp->ob, cp->ob_size, NULL); + camel_stream_write ((CamelStream *)imap->stream, cp->ob, cp->ob_size, cancellable, NULL); break; default: /* should we just ignore? */ @@ -1829,7 +1847,7 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error) } if (!litplus) - camel_imapx_stream_skip (imap->stream, error); + camel_imapx_stream_skip (imap->stream, cancellable, error); noskip: cp = cp->next; if (cp->next) { @@ -1850,15 +1868,19 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error) imap->literal = newliteral; if (!litplus) - imapx_command_start_next (imap, error); - QUEUE_UNLOCK (imap); + imapx_command_start_next(imap, cancellable, error); + QUEUE_UNLOCK(imap); return 1; } /* handle a completion line */ static gint -imapx_completion (CamelIMAPXServer *imap, guchar *token, gint len, GError **error) +imapx_completion (CamelIMAPXServer *imap, + guchar *token, + gint len, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; guint tag; @@ -1923,36 +1945,38 @@ imapx_completion (CamelIMAPXServer *imap, guchar *token, gint len, GError **erro camel_dlist_remove ((CamelDListNode *) ic); QUEUE_UNLOCK (imap); - ic->status = imapx_parse_status (imap->stream, error); + ic->status = imapx_parse_status (imap->stream, cancellable, error); if (ic->complete) ic->complete (imap, ic); - QUEUE_LOCK (imap); - imapx_command_start_next (imap, error); - QUEUE_UNLOCK (imap); + QUEUE_LOCK(imap); + imapx_command_start_next(imap, cancellable, error); + QUEUE_UNLOCK(imap); return 1; } static void -imapx_step (CamelIMAPXServer *is, GError **error) +imapx_step (CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { guint len; guchar *token; gint tok; // poll ? wait for other stuff? loop? - tok = camel_imapx_stream_token (is->stream, &token, &len, error); + tok = camel_imapx_stream_token (is->stream, &token, &len, cancellable, error); if (tok < 0) return; if (tok == '*') - imapx_untagged (is, error); + imapx_untagged (is, cancellable, error); else if (tok == IMAPX_TOK_TOKEN) - imapx_completion (is, token, len, error); + imapx_completion (is, token, len, cancellable, error); else if (tok == '+') - imapx_continuation (is, FALSE, error); + imapx_continuation (is, FALSE, cancellable, error); else g_set_error ( error, CAMEL_IMAPX_ERROR, 1, @@ -1972,7 +1996,7 @@ imapx_command_run (CamelIMAPXServer *is, CamelIMAPXCommand *ic) QUEUE_UNLOCK (is); while (ic->status == NULL && ic->error == NULL) - imapx_step (is, &ic->error); + imapx_step (is, ic->cancellable, &ic->error); if (is->literal == ic) is->literal = NULL; @@ -2012,6 +2036,20 @@ imapx_command_run_sync (CamelIMAPXServer *is, CamelIMAPXCommand *ic) /* ********************************************************************** */ /* Should be called when there are no more commands needed to complete the job */ +static CamelIMAPXJob * +imapx_job_new (GCancellable *cancellable) +{ + CamelIMAPXJob *job; + + if (cancellable != NULL) + g_object_ref (cancellable); + + job = g_malloc0 (sizeof (CamelIMAPXJob)); + job->cancellable = cancellable; + + return job; +} + static void imapx_job_done (CamelIMAPXServer *is, CamelIMAPXJob *job) { @@ -2115,7 +2153,8 @@ imapx_command_idle_stop (CamelIMAPXServer *is, GError **error) } static void -imapx_command_idle_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_idle_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { CamelIMAPXIdle *idle = is->idle; @@ -2137,7 +2176,8 @@ imapx_command_idle_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_idle_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_idle_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; CamelIMAPXCommandPart *cp; @@ -2145,7 +2185,9 @@ imapx_job_idle_start (CamelIMAPXServer *is, CamelIMAPXJob *job) full_name = camel_folder_get_full_name (job->folder); - ic = camel_imapx_command_new (is, "IDLE", job->folder, "IDLE"); + ic = camel_imapx_command_new ( + is, "IDLE", job->folder, + job->cancellable, "IDLE"); ic->job = job; ic->pri = job->pri; ic->complete = imapx_command_idle_done; @@ -2169,12 +2211,15 @@ imapx_job_idle_start (CamelIMAPXServer *is, CamelIMAPXJob *job) } static gboolean -camel_imapx_server_idle (CamelIMAPXServer *is, CamelFolder *folder, GError **error) +camel_imapx_server_idle (CamelIMAPXServer *is, + CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; gboolean success; - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_IDLE; job->start = imapx_job_idle_start; job->folder = folder; @@ -2191,19 +2236,19 @@ imapx_server_fetch_new_messages (CamelIMAPXServer *is, CamelFolder *folder, gboolean async, gboolean update_unseen, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; gboolean success; - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_FETCH_NEW_MESSAGES; job->start = imapx_job_fetch_new_messages_start; job->folder = folder; job->noreply = async; job->u.refresh_info.changes = camel_folder_change_info_new (); job->u.refresh_info.update_unseen = update_unseen; - job->op = camel_operation_registered (); success = imapx_submit_job (is, job, error); @@ -2217,8 +2262,11 @@ static gpointer imapx_idle_thread (gpointer data) { CamelIMAPXServer *is = (CamelIMAPXServer *) data; + GCancellable *cancellable; GError *local_error = NULL; + cancellable = g_object_ref (is->cancellable); + while (TRUE) { CamelIMAPXFolder *ifolder; @@ -2237,11 +2285,12 @@ imapx_idle_thread (gpointer data) continue; } IDLE_UNLOCK (is->idle); - camel_imapx_server_idle (is, (gpointer)ifolder, &local_error); + + camel_imapx_server_idle (is, (gpointer)ifolder, cancellable, &local_error); if (local_error == NULL && ifolder->exists_on_server > camel_folder_summary_count (((CamelFolder *) ifolder)->summary) && imapx_is_command_queue_empty (is)) - imapx_server_fetch_new_messages (is, is->select_folder, TRUE, TRUE, &local_error); + imapx_server_fetch_new_messages (is, is->select_folder, TRUE, TRUE, cancellable, &local_error); if (local_error != NULL) { e (is->tagprefix, "Caught exception in idle thread: %s \n", local_error->message); @@ -2258,6 +2307,8 @@ imapx_idle_thread (gpointer data) break; } + g_object_unref (cancellable); + g_clear_error (&local_error); is->idle->idle_thread = NULL; return NULL; @@ -2454,7 +2505,7 @@ imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) ifolder->exists_on_server = is->exists; ifolder->modseq_on_server = is->highestmodseq; if (ifolder->uidnext_on_server < is->uidnext) { - imapx_server_fetch_new_messages (is, is->select_pending, TRUE, TRUE, NULL); + imapx_server_fetch_new_messages (is, is->select_pending, TRUE, TRUE, NULL, NULL); /* We don't do this right now because we want the new messages to update the unseen count. */ //ifolder->uidnext_on_server = is->uidnext; @@ -2482,7 +2533,11 @@ imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) /* Should have a queue lock. TODO Change the way select is written */ static gboolean -imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, GError **error) +imapx_select (CamelIMAPXServer *is, + CamelFolder *folder, + gboolean forced, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; const gchar *full_name; @@ -2533,7 +2588,7 @@ imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, GError /* Hrm, what about reconnecting? */ is->state = IMAPX_INITIALISED; - ic = camel_imapx_command_new(is, "SELECT", NULL, "SELECT %f", folder); + ic = camel_imapx_command_new(is, "SELECT", NULL, cancellable, "SELECT %f", folder); if (is->use_qresync) { CamelIMAPXSummary *isum = (CamelIMAPXSummary *)folder->summary; @@ -2716,7 +2771,9 @@ connect_to_server_process (CamelIMAPXServer *is, const gchar *cmd, GError **erro #endif /* G_OS_WIN32 */ gboolean -imapx_connect_to_server (CamelIMAPXServer *is, GError **error) +imapx_connect_to_server (CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelStream * tcp_stream = NULL; gchar *socks_host; @@ -2781,7 +2838,9 @@ imapx_connect_to_server (CamelIMAPXServer *is, GError **error) g_free (socks_host); } - ret = camel_tcp_stream_connect (CAMEL_TCP_STREAM (tcp_stream), is->url->host, serv, fallback_port, error); + ret = camel_tcp_stream_connect ( + CAMEL_TCP_STREAM (tcp_stream), is->url->host, serv, + fallback_port, cancellable, error); if (ret == -1) { g_prefix_error ( error, _("Could not connect to %s (port %s): "), @@ -2815,24 +2874,26 @@ imapx_connect_to_server (CamelIMAPXServer *is, GError **error) return FALSE; } - tok = camel_imapx_stream_token (is->stream, &token, &len, error); + tok = camel_imapx_stream_token (is->stream, &token, &len, cancellable, error); if (tok < 0) return FALSE; if (tok == '*') { - imapx_untagged (is, error); + imapx_untagged (is, cancellable, error); break; } camel_imapx_stream_ungettoken (is->stream, tok, token, len); - if (camel_imapx_stream_text (is->stream, &token, error)) + if (camel_imapx_stream_text (is->stream, &token, cancellable, error)) return FALSE; e(is->tagprefix, "Got unexpected line before greeting: '%s'\n", token); g_free (token); } if (!is->cinfo) { - ic = camel_imapx_command_new(is, "CAPABILITY", NULL, "CAPABILITY"); - imapx_command_run (is, ic); + ic = camel_imapx_command_new ( + is, "CAPABILITY", NULL, + cancellable, "CAPABILITY"); + imapx_command_run(is, ic); if (ic->error != NULL || ic->status->result != IMAPX_OK) { if (ic->error == NULL) @@ -2862,7 +2923,9 @@ imapx_connect_to_server (CamelIMAPXServer *is, GError **error) goto exit; } - ic = camel_imapx_command_new (is, "STARTTLS", NULL, "STARTTLS"); + ic = camel_imapx_command_new ( + is, "STARTTLS", NULL, + cancellable, "STARTTLS"); imapx_command_run (is, ic); if (ic->error != NULL || ic->status->result != IMAPX_OK) { @@ -2899,7 +2962,9 @@ imapx_connect_to_server (CamelIMAPXServer *is, GError **error) } /* Get new capabilities if they weren't already given */ if (!is->cinfo) { - ic = camel_imapx_command_new(is, "CAPABILITY", NULL, "CAPABILITY"); + ic = camel_imapx_command_new ( + is, "CAPABILITY", NULL, + cancellable, "CAPABILITY"); if (!imapx_command_run (is, ic)) { g_propagate_error (&local_error, ic->error); camel_imapx_command_free (ic); @@ -2931,7 +2996,9 @@ exit: } static gboolean -imapx_reconnect (CamelIMAPXServer *is, GError **error) +imapx_reconnect (CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelSasl *sasl; CamelIMAPXCommand *ic; @@ -2950,7 +3017,7 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error) service->url->passwd = NULL; } - if (!imapx_connect_to_server (is, error)) + if (!imapx_connect_to_server (is, cancellable, error)) goto exception; if (is->state == IMAPX_AUTHENTICATED) @@ -3010,10 +3077,15 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error) } } if (authtype && (sasl = camel_sasl_new ("imap", authtype->authproto, service))) { - ic = camel_imapx_command_new (is, "AUTHENTICATE", NULL, "AUTHENTICATE %A", sasl); + ic = camel_imapx_command_new ( + is, "AUTHENTICATE", NULL, cancellable, + "AUTHENTICATE %A", sasl); g_object_unref (sasl); } else { - ic = camel_imapx_command_new(is, "LOGIN", NULL, "LOGIN %s %s", service->url->user, service->url->passwd); + ic = camel_imapx_command_new ( + is, "LOGIN", NULL, cancellable, + "LOGIN %s %s", service->url->user, + service->url->passwd); } imapx_command_run (is, ic); @@ -3052,7 +3124,9 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error) /* After login we re-capa unless the server already told us */ if (!is->cinfo) { - ic = camel_imapx_command_new(is, "CAPABILITY", NULL, "CAPABILITY"); + ic = camel_imapx_command_new ( + is, "CAPABILITY", NULL, + cancellable, "CAPABILITY"); if (!imapx_command_run (is, ic)) { g_propagate_error (error, ic->error); camel_imapx_command_free (ic); @@ -3075,7 +3149,9 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error) /* Fetch namespaces */ if (is->cinfo->capa & IMAPX_CAPABILITY_NAMESPACE) { - ic = camel_imapx_command_new (is, "NAMESPACE", NULL, "NAMESPACE"); + ic = camel_imapx_command_new ( + is, "NAMESPACE", NULL, + cancellable, "NAMESPACE"); if (!imapx_command_run (is, ic)) { g_propagate_error (error, ic->error); camel_imapx_command_free (ic); @@ -3087,7 +3163,9 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error) if (((CamelIMAPXStore *)is->store)->rec_options & IMAPX_USE_QRESYNC && is->cinfo->capa & IMAPX_CAPABILITY_QRESYNC) { - ic = camel_imapx_command_new (is, "ENABLE", NULL, "ENABLE CONDSTORE QRESYNC"); + ic = camel_imapx_command_new ( + is, "ENABLE", NULL, cancellable, + "ENABLE CONDSTORE QRESYNC"); if (!imapx_command_run (is, ic)) { g_propagate_error (error, ic->error); camel_imapx_command_free (ic); @@ -3162,11 +3240,13 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) if (job->u.get_message.fetch_offset < job->u.get_message.size || job->u.get_message.fetch_offset == really_fetched) { camel_imapx_command_free (ic); - if (job->op) - camel_operation_progress (job->op, (job->u.get_message.fetch_offset *100)/job->u.get_message.size); + camel_operation_progress ( + job->cancellable, + (job->u.get_message.fetch_offset *100)/job->u.get_message.size); - ic = camel_imapx_command_new(is, "FETCH", job->folder, - "UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid); + ic = camel_imapx_command_new ( + is, "FETCH", job->folder, job->cancellable, + "UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid); camel_imapx_command_add(ic, "<%u.%u>", job->u.get_message.fetch_offset, MULTI_SIZE); camel_imapx_command_add(ic, ")"); ic->complete = imapx_command_fetch_message_done; @@ -3199,7 +3279,7 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) if (stream) { gchar *tmp = camel_data_cache_get_filename (ifolder->cache, "tmp", job->u.get_message.uid, NULL); - if (camel_stream_flush (stream, &job->error) == 0 && camel_stream_close (stream, &job->error) == 0) { + if (camel_stream_flush (stream, job->cancellable, &job->error) == 0 && camel_stream_close (stream, job->cancellable, &job->error) == 0) { gchar *cache_file = camel_data_cache_get_filename (ifolder->cache, "cur", job->u.get_message.uid, NULL); gchar *temp = g_strrstr (cache_file, "/"), *dir; @@ -3237,8 +3317,9 @@ imapx_job_get_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job) if (job->u.get_message.use_multi_fetch) { for (i=0; i < 3 && job->u.get_message.fetch_offset < job->u.get_message.size;i++) { - ic = camel_imapx_command_new(is, "FETCH", job->folder, - "UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid); + ic = camel_imapx_command_new ( + is, "FETCH", job->folder, job->cancellable, + "UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid); camel_imapx_command_add(ic, "<%u.%u>", job->u.get_message.fetch_offset, MULTI_SIZE); camel_imapx_command_add(ic, ")"); ic->complete = imapx_command_fetch_message_done; @@ -3249,8 +3330,9 @@ imapx_job_get_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job) imapx_command_queue (is, ic); } } else { - ic = camel_imapx_command_new(is, "FETCH", job->folder, - "UID FETCH %t (BODY.PEEK[])", job->u.get_message.uid); + ic = camel_imapx_command_new ( + is, "FETCH", job->folder, job->cancellable, + "UID FETCH %t (BODY.PEEK[])", job->u.get_message.uid); ic->complete = imapx_command_fetch_message_done; ic->job = job; ic->pri = job->pri; @@ -3262,13 +3344,16 @@ imapx_job_get_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job) /* ********************************************************************** */ static void -imapx_command_copy_messages_step_start (CamelIMAPXServer *is, CamelIMAPXJob *job, gint index) +imapx_command_copy_messages_step_start (CamelIMAPXServer *is, + CamelIMAPXJob *job, gint index) { CamelIMAPXCommand *ic; GPtrArray *uids = job->u.copy_messages.uids; gint i = index; - ic = camel_imapx_command_new (is, "COPY", job->folder, "UID COPY "); + ic = camel_imapx_command_new ( + is, "COPY", job->folder, + job->cancellable, "UID COPY "); ic->complete = imapx_command_copy_messages_step_done; ic->job = job; ic->pri = job->pri; @@ -3296,7 +3381,8 @@ imapx_command_copy_messages_step_start (CamelIMAPXServer *is, CamelIMAPXJob *job } static void -imapx_command_copy_messages_step_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_copy_messages_step_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { CamelIMAPXJob *job = ic->job; gint i = job->u.copy_messages.index; @@ -3349,9 +3435,11 @@ cleanup: } static void -imapx_job_copy_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_copy_messages_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { - if (!imapx_server_sync_changes (is, job->folder, job->pri, &job->error)) + if (!imapx_server_sync_changes ( + is, job->folder, job->pri, job->cancellable, &job->error)) imapx_job_done (is, job); g_ptr_array_sort (job->u.copy_messages.uids, (GCompareFunc) imapx_uids_array_cmp); @@ -3362,7 +3450,8 @@ imapx_job_copy_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job) /* ********************************************************************** */ static void -imapx_command_append_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_append_message_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { CamelIMAPXJob *job = ic->job; CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) job->folder; @@ -3426,17 +3515,18 @@ imapx_command_append_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_append_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_append_message_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; /* TODO: we could supply the original append date from the file timestamp */ - ic = camel_imapx_command_new(is, "APPEND", NULL, - "APPEND %f %F %P", - job->folder, - ((CamelMessageInfoBase *)job->u.append_message.info)->flags, - ((CamelMessageInfoBase *)job->u.append_message.info)->user_flags, - job->u.append_message.path); + ic = camel_imapx_command_new ( + is, "APPEND", NULL, job->cancellable, + "APPEND %f %F %P", job->folder, + ((CamelMessageInfoBase *)job->u.append_message.info)->flags, + ((CamelMessageInfoBase *)job->u.append_message.info)->user_flags, + job->u.append_message.path); ic->complete = imapx_command_append_message_done; ic->job = job; ic->pri = job->pri; @@ -3509,7 +3599,8 @@ imapx_index_next (GPtrArray *uids, CamelFolderSummary *s, guint index) } static void -imapx_command_step_fetch_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_step_fetch_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)ic->job->folder; CamelIMAPXSummary *isum = (CamelIMAPXSummary *)ic->job->folder->summary; @@ -3539,7 +3630,9 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) if (ilen) { camel_imapx_command_free (ic); - ic = camel_imapx_command_new(is, "FETCH", job->folder, "UID FETCH "); + ic = camel_imapx_command_new ( + is, "FETCH", job->folder, + job->cancellable, "UID FETCH "); ic->complete = imapx_command_step_fetch_done; ic->job = job; ic->pri = job->pri - 1; @@ -3623,7 +3716,8 @@ imapx_uid_cmp (gconstpointer ap, gconstpointer bp, gpointer data) } static void -imapx_job_scan_changes_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_job_scan_changes_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { CamelIMAPXJob *job = ic->job; gint i; @@ -3754,7 +3848,8 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) /* If we have any new messages, download their headers, but only a few (100?) at a time */ if (fetch_new) { camel_operation_start ( - job->op, _("Fetching summary information for new messages in %s"), + job->cancellable, + _("Fetching summary information for new messages in %s"), camel_folder_get_name (job->folder)); imapx_uidset_init (&job->u.refresh_info.uidset, BATCH_FETCH_COUNT, 0); /* These are new messages which arrived since we last knew the unseen count; @@ -3789,16 +3884,19 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_scan_changes_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_scan_changes_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; camel_operation_start ( - job->op, _("Scanning for changed messages in %s"), + job->cancellable, + _("Scanning for changed messages in %s"), camel_folder_get_name (job->folder)); - ic = camel_imapx_command_new (is, "FETCH", job->folder, - "UID FETCH 1:* (UID FLAGS)"); + ic = camel_imapx_command_new ( + is, "FETCH", job->folder, job->cancellable, + "UID FETCH 1:* (UID FLAGS)"); ic->job = job; ic->complete = imapx_job_scan_changes_done; ic->pri = job->pri; @@ -3807,7 +3905,8 @@ imapx_job_scan_changes_start (CamelIMAPXServer *is, CamelIMAPXJob *job) } static void -imapx_command_fetch_new_messages_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_fetch_new_messages_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { CamelIMAPXSummary *isum = (CamelIMAPXSummary *)ic->job->folder->summary; CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)ic->job->folder; @@ -3849,15 +3948,13 @@ imapx_command_fetch_new_messages_done (CamelIMAPXServer *is, CamelIMAPXCommand * exception: camel_folder_change_info_free (ic->job->u.refresh_info.changes); - if (ic->job->op) - g_object_unref (ic->job->op); - imapx_job_done (is, ic->job); camel_imapx_command_free (ic); } static void -imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; CamelFolder *folder = job->folder; @@ -3878,19 +3975,22 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job) uid = g_strdup ("1"); camel_operation_start ( - job->op, _("Fetching summary information for new messages in %s"), + job->cancellable, + _("Fetching summary information for new messages in %s"), camel_folder_get_name (folder)); if (diff > BATCH_FETCH_COUNT) { - ic = camel_imapx_command_new (is, "FETCH", job->folder, - "UID FETCH %s:* (UID FLAGS)", uid); - imapx_uidset_init (&job->u.refresh_info.uidset, BATCH_FETCH_COUNT, 0); - job->u.refresh_info.infos = g_array_new (0, 0, sizeof (struct _refresh_info)); + ic = camel_imapx_command_new ( + is, "FETCH", job->folder, job->cancellable, + "UID FETCH %s:* (UID FLAGS)", uid); + imapx_uidset_init(&job->u.refresh_info.uidset, BATCH_FETCH_COUNT, 0); + job->u.refresh_info.infos = g_array_new (0, 0, sizeof(struct _refresh_info)); ic->pri = job->pri; ic->complete = imapx_command_step_fetch_done; } else { - ic = camel_imapx_command_new (is, "FETCH", job->folder, - "UID FETCH %s:* (RFC822.SIZE RFC822.HEADER FLAGS)", uid); + ic = camel_imapx_command_new ( + is, "FETCH", job->folder, job->cancellable, + "UID FETCH %s:* (RFC822.SIZE RFC822.HEADER FLAGS)", uid); ic->pri = job->pri; ic->complete = imapx_command_fetch_new_messages_done; } @@ -3901,7 +4001,8 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job) } static void -imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_refresh_info_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { guint32 total; CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) job->folder; @@ -3916,7 +4017,9 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job) /* Sync changes first, else unread count will not match. Need to think about better ways for this */ - if (!imapx_server_sync_changes (is, folder, job->pri, &job->error)) + if (!imapx_server_sync_changes ( + is, folder, job->pri, + job->cancellable, &job->error)) goto done; #if 0 /* There are issues with this still; continue with the buggy behaviour @@ -3953,21 +4056,27 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job) if (!imapx_stop_idle (is, &job->error)) goto done; /* This doesn't work -- this is an immediate command, not queued */ - if (!imapx_select (is, folder, TRUE, &job->error)) + if (!imapx_select ( + is, folder, TRUE, + job->cancellable, &job->error)) goto done; } else { /* Or maybe just NOOP, unless we're in IDLE in which case do nothing */ - if (!imapx_idle_supported (is) || !imapx_in_idle (is)) { - if (!camel_imapx_server_noop (is, folder, &job->error)) + if (!imapx_idle_supported(is) || !imapx_in_idle(is)) { + if (!camel_imapx_server_noop (is, folder, job->cancellable, &job->error)) goto done; } } } else { if (is->cinfo->capa & IMAPX_CAPABILITY_CONDSTORE) - ic = camel_imapx_command_new (is, "STATUS", NULL, "STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT HIGHESTMODSEQ)", folder); + ic = camel_imapx_command_new ( + is, "STATUS", NULL, job->cancellable, + "STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT HIGHESTMODSEQ)", folder); else - ic = camel_imapx_command_new (is, "STATUS", NULL, "STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT)", folder); - + ic = camel_imapx_command_new ( + is, "STATUS", NULL, job->cancellable, + "STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT)", folder); + ic->job = job; ic->pri = job->pri; @@ -4013,7 +4122,9 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job) if (!total) need_rescan = FALSE; - if (!imapx_server_fetch_new_messages (is, folder, FALSE, FALSE, &job->error)) + if (!imapx_server_fetch_new_messages ( + is, folder, FALSE, FALSE, + job->cancellable, &job->error)) goto done; /* If QRESYNC-capable we'll have got all flags changes in SELECT */ @@ -4026,7 +4137,7 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job) if (can_qresync) { /* Actually we only want to select it; no need for the NOOP */ - camel_imapx_server_noop (is, folder, &job->error); + camel_imapx_server_noop (is, folder, job->cancellable, &job->error); qresync_done: isum->modseq = ifolder->modseq_on_server; total = camel_folder_summary_count (job->folder->summary); @@ -4056,7 +4167,8 @@ done: /* ********************************************************************** */ static void -imapx_command_expunge_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_expunge_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { if (ic->error != NULL || ic->status->result != IMAPX_OK) { if (ic->error == NULL) @@ -4113,14 +4225,19 @@ imapx_command_expunge_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_expunge_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_expunge_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; - imapx_server_sync_changes (is, job->folder, job->pri, &job->error); + imapx_server_sync_changes ( + is, job->folder, job->pri, + job->cancellable, &job->error); /* TODO handle UIDPLUS capability */ - ic = camel_imapx_command_new(is, "EXPUNGE", job->folder, "EXPUNGE"); + ic = camel_imapx_command_new ( + is, "EXPUNGE", job->folder, + job->cancellable, "EXPUNGE"); ic->job = job; ic->pri = job->pri; ic->complete = imapx_command_expunge_done; @@ -4130,7 +4247,8 @@ imapx_job_expunge_start (CamelIMAPXServer *is, CamelIMAPXJob *job) /* ********************************************************************** */ static void -imapx_command_list_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_list_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { if (ic->error != NULL || ic->status->result != IMAPX_OK) { if (ic->error == NULL) @@ -4147,13 +4265,17 @@ imapx_command_list_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_list_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_list_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; - ic = camel_imapx_command_new(is, "LIST", NULL, "%s \"\" %s", - (job->u.list.flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)?"LSUB":"LIST", - job->u.list.pattern); + ic = camel_imapx_command_new ( + is, "LIST", NULL, job->cancellable, + "%s \"\" %s", + (job->u.list.flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) ? + "LSUB" : "LIST", + job->u.list.pattern); if (job->u.list.ext) { /* Hm, we need a way to add atoms _without_ quoting or using literals */ camel_imapx_command_add(ic, " "); @@ -4182,7 +4304,8 @@ imapx_encode_folder_name (CamelIMAPXStore *istore, const gchar *folder_name) } static void -imapx_command_subscription_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_subscription_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { if (ic->error != NULL || ic->status->result != IMAPX_OK) { if (ic->error == NULL) @@ -4198,7 +4321,8 @@ imapx_command_subscription_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_manage_subscription_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_manage_subscription_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; const gchar *str = NULL; @@ -4209,8 +4333,12 @@ imapx_job_manage_subscription_start (CamelIMAPXServer *is, CamelIMAPXJob *job) else str = "UNSUBSCRIBE"; - encoded_fname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.manage_subscriptions.folder_name); - ic = camel_imapx_command_new (is, str, NULL, "%s %s", str, encoded_fname); + encoded_fname = imapx_encode_folder_name ( + (CamelIMAPXStore *) is->store, + job->u.manage_subscriptions.folder_name); + ic = camel_imapx_command_new ( + is, str, NULL, job->cancellable, + "%s %s", str, encoded_fname); ic->pri = job->pri; ic->job = job; @@ -4223,7 +4351,8 @@ imapx_job_manage_subscription_start (CamelIMAPXServer *is, CamelIMAPXJob *job) /* ********************************************************************** */ static void -imapx_command_create_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_create_folder_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { if (ic->error != NULL || ic->status->result != IMAPX_OK) { if (ic->error == NULL) @@ -4239,13 +4368,16 @@ imapx_command_create_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_create_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_create_folder_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; gchar *encoded_fname = NULL; encoded_fname = camel_utf8_utf7 (job->u.folder_name); - ic = camel_imapx_command_new (is, "CREATE", NULL, "CREATE %s", encoded_fname); + ic = camel_imapx_command_new ( + is, "CREATE", NULL, job->cancellable, + "CREATE %s", encoded_fname); ic->pri = job->pri; ic->job = job; ic->complete = imapx_command_create_folder_done; @@ -4257,7 +4389,8 @@ imapx_job_create_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job) /* ********************************************************************** */ static void -imapx_command_delete_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_delete_folder_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { if (ic->error != NULL || ic->status->result != IMAPX_OK) { if (ic->error == NULL) @@ -4273,17 +4406,21 @@ imapx_command_delete_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_delete_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_delete_folder_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; gchar *encoded_fname = NULL; encoded_fname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.folder_name); - job->folder = camel_store_get_folder(is->store, "INBOX", 0, &job->error); + job->folder = camel_store_get_folder ( + is->store, "INBOX", 0, job->cancellable, &job->error); /* make sure to-be-deleted folder is not selected by selecting INBOX for this operation */ - ic = camel_imapx_command_new (is, "DELETE", job->folder, "DELETE %s", encoded_fname); + ic = camel_imapx_command_new ( + is, "DELETE", job->folder, job->cancellable, + "DELETE %s", encoded_fname); ic->pri = job->pri; ic->job = job; ic->complete = imapx_command_delete_folder_done; @@ -4295,7 +4432,8 @@ imapx_job_delete_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job) /* ********************************************************************** */ static void -imapx_command_rename_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_rename_folder_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { if (ic->error != NULL || ic->status->result != IMAPX_OK) { if (ic->error == NULL) @@ -4311,17 +4449,21 @@ imapx_command_rename_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_rename_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_rename_folder_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; gchar *en_ofname = NULL, *en_nfname = NULL; - job->folder = camel_store_get_folder(is->store, "INBOX", 0, &job->error); + job->folder = camel_store_get_folder ( + is->store, "INBOX", 0, job->cancellable, &job->error); en_ofname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.ofolder_name); en_nfname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.nfolder_name); - ic = camel_imapx_command_new (is, "RENAME", job->folder, "RENAME %s %s", en_ofname, en_nfname); + ic = camel_imapx_command_new ( + is, "RENAME", job->folder, job->cancellable, + "RENAME %s %s", en_ofname, en_nfname); ic->pri = job->pri; ic->job = job; ic->complete = imapx_command_rename_folder_done; @@ -4334,7 +4476,8 @@ imapx_job_rename_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job) /* ********************************************************************** */ static void -imapx_command_noop_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) +imapx_command_noop_done (CamelIMAPXServer *is, + CamelIMAPXCommand *ic) { if (ic->error != NULL || ic->status->result != IMAPX_OK) { if (ic->error == NULL) @@ -4350,11 +4493,13 @@ imapx_command_noop_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } static void -imapx_job_noop_start (CamelIMAPXServer *is, CamelIMAPXJob *job) +imapx_job_noop_start (CamelIMAPXServer *is, + CamelIMAPXJob *job) { CamelIMAPXCommand *ic; - ic = camel_imapx_command_new (is, "NOOP", job->folder, "NOOP"); + ic = camel_imapx_command_new ( + is, "NOOP", job->folder, job->cancellable, "NOOP"); ic->job = job; ic->complete = imapx_command_noop_done; @@ -4512,7 +4657,9 @@ imapx_job_sync_changes_start (CamelIMAPXServer *is, CamelIMAPXJob *job) if ( (on && (((flags ^ sflags) & flags) & flag)) || (!on && (((flags ^ sflags) & ~flags) & flag))) { if (ic == NULL) { - ic = camel_imapx_command_new(is, "STORE", job->folder, "UID STORE "); + ic = camel_imapx_command_new ( + is, "STORE", job->folder, + job->cancellable, "UID STORE "); ic->complete = imapx_command_sync_changes_done; ic->job = job; ic->pri = job->pri; @@ -4548,7 +4695,9 @@ imapx_job_sync_changes_start (CamelIMAPXServer *is, CamelIMAPXJob *job) CamelIMAPXMessageInfo *info = c->infos->pdata[i]; if (ic == NULL) { - ic = camel_imapx_command_new(is, "STORE", job->folder, "UID STORE "); + ic = camel_imapx_command_new ( + is, "STORE", job->folder, + job->cancellable, "UID STORE "); ic->complete = imapx_command_sync_changes_done; ic->job = job; ic->pri = job->pri; @@ -4606,13 +4755,15 @@ cancel_all_jobs (CamelIMAPXServer *is, GError *error) /* ********************************************************************** */ static void -parse_contents (CamelIMAPXServer *is, GError **error) +parse_contents (CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { gint buffered = 0; GError *local_error = NULL; do { - imapx_step (is, &local_error); + imapx_step (is, cancellable, &local_error); buffered = camel_imapx_stream_buffered (is->stream); @@ -4633,15 +4784,13 @@ static gpointer imapx_parser_thread (gpointer d) { CamelIMAPXServer *is = d; - CamelOperation *op; + GCancellable *cancellable; GError *local_error = NULL; - op = camel_operation_new (); - camel_operation_register (op); - is->op = op; + cancellable = g_object_ref (is->cancellable); while (local_error == NULL && is->stream) { - camel_operation_uncancel (op); + g_cancellable_reset (cancellable); #ifndef G_OS_WIN32 if (is->is_process_stream) { GPollFD fds[2] = { {0, 0, 0}, {0, 0, 0} }; @@ -4649,7 +4798,7 @@ imapx_parser_thread (gpointer d) fds[0].fd = ((CamelStreamProcess *)is->stream->source)->sockfd; fds[0].events = G_IO_IN; - fds[1].fd = camel_operation_cancel_fd (op); + fds[1].fd = g_cancellable_get_fd (cancellable); fds[1].events = G_IO_IN; res = g_poll (fds, 2, 1000*30); if (res == -1) @@ -4657,9 +4806,10 @@ imapx_parser_thread (gpointer d) else if (res == 0) /* timed out */; else if (fds[0].revents & G_IO_IN) { - parse_contents (is, &local_error); + parse_contents (is, cancellable, &local_error); } else if (fds[1].revents & G_IO_IN) errno = EINTR; + g_cancellable_release_fd (cancellable); } else #endif { @@ -4668,7 +4818,7 @@ imapx_parser_thread (gpointer d) pollfds[0].fd = camel_tcp_stream_get_file_desc (CAMEL_TCP_STREAM (is->stream->source)); pollfds[0].in_flags = PR_POLL_READ; - pollfds[1].fd = camel_operation_cancel_prfd (op); + pollfds[1].fd = camel_operation_cancel_prfd (CAMEL_OPERATION (cancellable)); pollfds[1].in_flags = PR_POLL_READ; #include @@ -4679,7 +4829,7 @@ imapx_parser_thread (gpointer d) else if (res == 0) { /* timed out */ } else if ((pollfds[0].out_flags & PR_POLL_READ)) { - parse_contents (is, &local_error); + parse_contents (is, cancellable, &local_error); } else if (pollfds[1].out_flags & PR_POLL_READ) errno = EINTR; } @@ -4692,7 +4842,7 @@ imapx_parser_thread (gpointer d) break; } - if (camel_operation_cancel_check (op)) { + if (camel_operation_cancel_check (CAMEL_OPERATION (cancellable))) { gint is_empty; QUEUE_LOCK (is); @@ -4700,7 +4850,7 @@ imapx_parser_thread (gpointer d) QUEUE_UNLOCK (is); if ((is_empty || (imapx_idle_supported (is) && imapx_in_idle (is)))) - camel_operation_uncancel (op); + camel_operation_uncancel (CAMEL_OPERATION (cancellable)); else g_set_error ( &local_error, G_IO_ERROR, @@ -4717,11 +4867,7 @@ imapx_parser_thread (gpointer d) g_clear_error (&local_error); - if (op) { - camel_operation_unregister (); - g_object_unref (op); - } - is->op = NULL; + g_object_unref (cancellable); is->parser_thread = NULL; is->parser_quit = FALSE; @@ -4772,8 +4918,12 @@ imapx_server_dispose (GObject *object) QUEUE_UNLOCK (server); server->parser_quit = TRUE; - if (server->op) - camel_operation_cancel (server->op); + + if (server->cancellable != NULL) { + g_cancellable_cancel (server->cancellable); + g_object_unref (server->cancellable); + server->cancellable = NULL; + } if (server->parser_thread) g_thread_join (server->parser_thread); @@ -4873,7 +5023,7 @@ imapx_disconnect (CamelIMAPXServer *is) g_static_rec_mutex_lock (&is->ostream_lock); if (is->stream) { - if (camel_stream_close (is->stream->source, NULL) == -1) + if (camel_stream_close (is->stream->source, NULL, NULL) == -1) ret = FALSE; g_object_unref (CAMEL_OBJECT (is->stream)); @@ -4905,7 +5055,9 @@ imapx_disconnect (CamelIMAPXServer *is) /* Client commands */ gboolean -camel_imapx_server_connect (CamelIMAPXServer *is, GError **error) +camel_imapx_server_connect (CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { gboolean success; @@ -4918,7 +5070,7 @@ camel_imapx_server_connect (CamelIMAPXServer *is, GError **error) return TRUE; g_static_rec_mutex_lock (&is->ostream_lock); - success = imapx_reconnect (is, error); + success = imapx_reconnect (is, cancellable, error); g_static_rec_mutex_unlock (&is->ostream_lock); if (!success) @@ -4929,7 +5081,12 @@ camel_imapx_server_connect (CamelIMAPXServer *is, GError **error) } static CamelStream * -imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, CamelOperation *op, const gchar *uid, gint pri, GError **error) +imapx_server_get_message (CamelIMAPXServer *is, + CamelFolder *folder, + const gchar *uid, + gint pri, + GCancellable *cancellable, + GError **error) { CamelStream *stream = NULL, *tmp_stream; CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder; @@ -4980,12 +5137,11 @@ imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, CamelOperat tmp_stream = camel_data_cache_add (ifolder->cache, "tmp", uid, NULL); - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->pri = pri; job->type = IMAPX_JOB_GET_MESSAGE; job->start = imapx_job_get_message_start; job->folder = folder; - job->op = op; job->u.get_message.uid = (gchar *)uid; job->u.get_message.stream = tmp_stream; @@ -5018,20 +5174,28 @@ imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, CamelOperat } CamelStream * -camel_imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, GError **error) +camel_imapx_server_get_message (CamelIMAPXServer *is, + CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { CamelStream *stream; - CamelOperation *op = camel_operation_registered (); - stream = imapx_server_get_message (is, folder, op, uid, IMAPX_PRIORITY_GET_MESSAGE, error); - if (op) - g_object_unref (op); + stream = imapx_server_get_message ( + is, folder, uid, + IMAPX_PRIORITY_GET_MESSAGE, + cancellable, error); return stream; } gboolean -camel_imapx_server_sync_message (CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, GError **error) +camel_imapx_server_sync_message (CamelIMAPXServer *is, + CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { gchar *cache_file = NULL; CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder; @@ -5043,7 +5207,10 @@ camel_imapx_server_sync_message (CamelIMAPXServer *is, CamelFolder *folder, cons return TRUE; } - stream = imapx_server_get_message (is, folder, NULL, uid, IMAPX_PRIORITY_SYNC_MESSAGE, error); + stream = imapx_server_get_message ( + is, folder, uid, + IMAPX_PRIORITY_SYNC_MESSAGE, + cancellable, error); if (stream == NULL) return FALSE; @@ -5054,11 +5221,17 @@ camel_imapx_server_sync_message (CamelIMAPXServer *is, CamelFolder *folder, cons } gboolean -camel_imapx_server_copy_message (CamelIMAPXServer *is, CamelFolder *source, CamelFolder *dest, GPtrArray *uids, gboolean delete_originals, GError **error) +camel_imapx_server_copy_message (CamelIMAPXServer *is, + CamelFolder *source, + CamelFolder *dest, + GPtrArray *uids, + gboolean delete_originals, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->pri = IMAPX_PRIORITY_APPEND_MESSAGE; job->type = IMAPX_JOB_COPY_MESSAGE; job->start = imapx_job_copy_messages_start; @@ -5074,7 +5247,12 @@ camel_imapx_server_copy_message (CamelIMAPXServer *is, CamelFolder *source, Came } gboolean -camel_imapx_server_append_message (CamelIMAPXServer *is, CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *mi, GError **error) +camel_imapx_server_append_message (CamelIMAPXServer *is, + CamelFolder *folder, + CamelMimeMessage *message, + const CamelMessageInfo *mi, + GCancellable *cancellable, + GError **error) { gchar *uid = NULL, *tmp = NULL; CamelStream *stream, *filter; @@ -5108,7 +5286,7 @@ camel_imapx_server_append_message (CamelIMAPXServer *is, CamelFolder *folder, Ca canon = camel_mime_filter_canon_new (CAMEL_MIME_FILTER_CANON_CRLF); camel_stream_filter_add ((CamelStreamFilter *)filter, canon); res = camel_data_wrapper_write_to_stream ( - (CamelDataWrapper *)message, filter, error); + (CamelDataWrapper *)message, filter, cancellable, error); g_object_unref (canon); g_object_unref (filter); @@ -5130,7 +5308,7 @@ camel_imapx_server_append_message (CamelIMAPXServer *is, CamelFolder *folder, Ca mechanism is used for normal uploading as well as offline re-syncing when we go back online */ - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->pri = IMAPX_PRIORITY_APPEND_MESSAGE; job->type = IMAPX_JOB_APPEND_MESSAGE; job->start = imapx_job_append_message_start; @@ -5147,12 +5325,15 @@ camel_imapx_server_append_message (CamelIMAPXServer *is, CamelFolder *folder, Ca } gboolean -camel_imapx_server_noop (CamelIMAPXServer *is, CamelFolder *folder, GError **error) +camel_imapx_server_noop (CamelIMAPXServer *is, + CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; gboolean success; - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_NOOP; job->start = imapx_job_noop_start; job->folder = folder; @@ -5166,7 +5347,10 @@ camel_imapx_server_noop (CamelIMAPXServer *is, CamelFolder *folder, GError **err } gboolean -camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, GError **error) +camel_imapx_server_refresh_info (CamelIMAPXServer *is, + CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; gboolean registered = TRUE; @@ -5182,12 +5366,11 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, GErr return TRUE; } - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_REFRESH_INFO; job->start = imapx_job_refresh_info_start; job->folder = folder; - job->op = camel_operation_registered (); - job->u.refresh_info.changes = camel_folder_change_info_new (); + job->u.refresh_info.changes = camel_folder_change_info_new(); job->pri = IMAPX_PRIORITY_REFRESH_INFO; if (g_ascii_strcasecmp(full_name, "INBOX") == 0) @@ -5204,8 +5387,8 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, GErr camel_folder_change_info_free (job->u.refresh_info.changes); - if (job->op) - g_object_unref (job->op); + if (job->cancellable) + g_object_unref (job->cancellable); g_free (job); return success; @@ -5236,7 +5419,11 @@ imapx_sync_free_user (GArray *user_set) } static gboolean -imapx_server_sync_changes (CamelIMAPXServer *is, CamelFolder *folder, gint pri, GError **error) +imapx_server_sync_changes (CamelIMAPXServer *is, + CamelFolder *folder, + gint pri, + GCancellable *cancellable, + GError **error) { guint i, on_orset, off_orset; GPtrArray *uids; @@ -5361,7 +5548,7 @@ imapx_server_sync_changes (CamelIMAPXServer *is, CamelFolder *folder, gint pri, goto done; } - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_SYNC_CHANGES; job->start = imapx_job_sync_changes_start; job->pri = pri; @@ -5390,14 +5577,22 @@ done: } gboolean -camel_imapx_server_sync_changes (CamelIMAPXServer *is, CamelFolder *folder, GError **error) +camel_imapx_server_sync_changes (CamelIMAPXServer *is, + CamelFolder *folder, + GCancellable *cancellable, + GError **error) { - return imapx_server_sync_changes (is, folder, IMAPX_PRIORITY_SYNC_CHANGES, error); + return imapx_server_sync_changes ( + is, folder, IMAPX_PRIORITY_SYNC_CHANGES, + cancellable, error); } /* expunge-uids? */ gboolean -camel_imapx_server_expunge (CamelIMAPXServer *is, CamelFolder *folder, GError **error) +camel_imapx_server_expunge (CamelIMAPXServer *is, + CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; gboolean registered; @@ -5411,7 +5606,7 @@ camel_imapx_server_expunge (CamelIMAPXServer *is, CamelFolder *folder, GError ** return TRUE; } - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_EXPUNGE; job->start = imapx_job_expunge_start; job->pri = IMAPX_PRIORITY_EXPUNGE; @@ -5471,6 +5666,7 @@ camel_imapx_server_list (CamelIMAPXServer *is, const gchar *top, guint32 flags, const gchar *ext, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -5479,7 +5675,7 @@ camel_imapx_server_list (CamelIMAPXServer *is, encoded_name = camel_utf8_utf7 (top); - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_LIST; job->start = imapx_job_list_start; job->pri = IMAPX_PRIORITY_LIST; @@ -5510,12 +5706,16 @@ camel_imapx_server_list (CamelIMAPXServer *is, } gboolean -camel_imapx_server_manage_subscription (CamelIMAPXServer *is, const gchar *folder_name, gboolean subscribe, GError **error) +camel_imapx_server_manage_subscription (CamelIMAPXServer *is, + const gchar *folder_name, + gboolean subscribe, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; gboolean success; - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_MANAGE_SUBSCRIPTION; job->start = imapx_job_manage_subscription_start; job->pri = IMAPX_PRIORITY_MANAGE_SUBSCRIPTION; @@ -5530,12 +5730,15 @@ camel_imapx_server_manage_subscription (CamelIMAPXServer *is, const gchar *folde } gboolean -camel_imapx_server_create_folder (CamelIMAPXServer *is, const gchar *folder_name, GError **error) +camel_imapx_server_create_folder (CamelIMAPXServer *is, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; gboolean success; - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_CREATE_FOLDER; job->start = imapx_job_create_folder_start; job->pri = IMAPX_PRIORITY_CREATE_FOLDER; @@ -5549,12 +5752,15 @@ camel_imapx_server_create_folder (CamelIMAPXServer *is, const gchar *folder_name } gboolean -camel_imapx_server_delete_folder (CamelIMAPXServer *is, const gchar *folder_name, GError **error) +camel_imapx_server_delete_folder (CamelIMAPXServer *is, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; gboolean success; - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_DELETE_FOLDER; job->start = imapx_job_delete_folder_start; job->pri = IMAPX_PRIORITY_DELETE_FOLDER; @@ -5568,12 +5774,16 @@ camel_imapx_server_delete_folder (CamelIMAPXServer *is, const gchar *folder_name } gboolean -camel_imapx_server_rename_folder (CamelIMAPXServer *is, const gchar *old_name, const gchar *new_name, GError **error) +camel_imapx_server_rename_folder (CamelIMAPXServer *is, + const gchar *old_name, + const gchar *new_name, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; gboolean success; - job = g_malloc0 (sizeof (*job)); + job = imapx_job_new (cancellable); job->type = IMAPX_JOB_RENAME_FOLDER; job->start = imapx_job_rename_folder_start; job->pri = IMAPX_PRIORITY_RENAME_FOLDER; diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h index 9ef6b6c..340eb6a 100644 --- a/camel/providers/imapx/camel-imapx-server.h +++ b/camel/providers/imapx/camel-imapx-server.h @@ -110,7 +110,7 @@ struct _CamelIMAPXServer { commands. Input stream does not require a lock since only parser_thread can operate on it */ GStaticRecMutex ostream_lock; /* Used for canceling operations as well as signaling parser thread to disconnnect/quit */ - CamelOperation *op; + GCancellable *cancellable; gboolean parser_quit; /* Idle */ @@ -138,60 +138,75 @@ CamelIMAPXServer * camel_imapx_server_new (CamelStore *store, CamelURL *url); gboolean camel_imapx_server_connect (CamelIMAPXServer *is, + GCancellable *cancellable, GError **error); gboolean imapx_connect_to_server (CamelIMAPXServer *is, + GCancellable *cancellable, GError **error); GPtrArray * camel_imapx_server_list (CamelIMAPXServer *is, const gchar *top, guint32 flags, const gchar *ext, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_sync_changes (CamelIMAPXServer *is, CamelFolder *folder, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_expunge (CamelIMAPXServer *is, CamelFolder *folder, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_noop (CamelIMAPXServer *is, CamelFolder *folder, + GCancellable *cancellable, GError **error); CamelStream * camel_imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_copy_message (CamelIMAPXServer *is, CamelFolder *source, CamelFolder *dest, GPtrArray *uids, gboolean delete_originals, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_append_message (CamelIMAPXServer *is, CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *mi, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_sync_message (CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_manage_subscription (CamelIMAPXServer *is, const gchar *folder_name, gboolean subscribe, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_create_folder (CamelIMAPXServer *is, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_delete_folder (CamelIMAPXServer *is, const gchar *folder_name, + GCancellable *cancellable, GError **error); gboolean camel_imapx_server_rename_folder (CamelIMAPXServer *is, const gchar *old_name, const gchar *new_name, + GCancellable *cancellable, GError **error); struct _IMAPXJobQueueInfo * camel_imapx_server_get_job_queue_info diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c index dd7621a..b29ebc2 100644 --- a/camel/providers/imapx/camel-imapx-store.c +++ b/camel/providers/imapx/camel-imapx-store.c @@ -178,7 +178,9 @@ imapx_construct (CamelService *service, CamelSession *session, CamelProvider *pr extern CamelServiceAuthType camel_imapx_password_authtype; static GList * -imapx_query_auth_types (CamelService *service, GError **error) +imapx_query_auth_types (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelIMAPXStore *istore = CAMEL_IMAPX_STORE (service); CamelServiceAuthType *authtype; @@ -200,7 +202,7 @@ imapx_query_auth_types (CamelService *service, GError **error) connected = server->stream != NULL; if (!connected) - connected = imapx_connect_to_server (server, error); + connected = imapx_connect_to_server (server, cancellable, error); camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); if (!connected) return NULL; @@ -232,7 +234,10 @@ imapx_get_name (CamelService *service, gboolean brief) } CamelIMAPXServer * -camel_imapx_store_get_server (CamelIMAPXStore *istore, const gchar *folder_name, GError **error) +camel_imapx_store_get_server (CamelIMAPXStore *istore, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelIMAPXServer *server = NULL; @@ -243,7 +248,7 @@ camel_imapx_store_get_server (CamelIMAPXStore *istore, const gchar *folder_name, } camel_service_lock (CAMEL_SERVICE (istore), CAMEL_SERVICE_REC_CONNECT_LOCK); - server = camel_imapx_conn_manager_get_connection (istore->con_man, folder_name, error); + server = camel_imapx_conn_manager_get_connection (istore->con_man, folder_name, cancellable, error); camel_service_unlock (CAMEL_SERVICE (istore), CAMEL_SERVICE_REC_CONNECT_LOCK); @@ -259,12 +264,14 @@ camel_imapx_store_op_done (CamelIMAPXStore *istore, CamelIMAPXServer *server, co } static gboolean -imapx_connect (CamelService *service, GError **error) +imapx_connect (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelIMAPXStore *istore = (CamelIMAPXStore *)service; CamelIMAPXServer *server; - server = camel_imapx_store_get_server (istore, NULL, error); + server = camel_imapx_store_get_server (istore, NULL, cancellable, error); if (server) { g_object_unref (server); return TRUE; @@ -274,13 +281,16 @@ imapx_connect (CamelService *service, GError **error) } static gboolean -imapx_disconnect (CamelService *service, gboolean clean, GError **error) +imapx_disconnect (CamelService *service, + gboolean clean, + GCancellable *cancellable, + GError **error) { CamelIMAPXStore *istore = CAMEL_IMAPX_STORE (service); CamelServiceClass *service_class; service_class = CAMEL_SERVICE_CLASS (camel_imapx_store_parent_class); - if (!service_class->disconnect (service, clean, error)) + if (!service_class->disconnect (service, clean, cancellable, error)) return FALSE; camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); @@ -295,13 +305,15 @@ imapx_disconnect (CamelService *service, gboolean clean, GError **error) } static CamelFolder * -imapx_get_junk (CamelStore *store, GError **error) +imapx_get_junk (CamelStore *store, + GCancellable *cancellable, + GError **error) { CamelFolder *folder; CamelStoreClass *store_class; store_class = CAMEL_STORE_CLASS (camel_imapx_store_parent_class); - folder = store_class->get_junk (store, error); + folder = store_class->get_junk (store, cancellable, error); if (folder) { CamelObject *object = CAMEL_OBJECT (folder); @@ -317,13 +329,15 @@ imapx_get_junk (CamelStore *store, GError **error) } static CamelFolder * -imapx_get_trash (CamelStore *store, GError **error) +imapx_get_trash (CamelStore *store, + GCancellable *cancellable, + GError **error) { CamelFolder *folder; CamelStoreClass *store_class; store_class = CAMEL_STORE_CLASS (camel_imapx_store_parent_class); - folder = store_class->get_trash (store, error); + folder = store_class->get_trash (store, cancellable, error); if (folder) { CamelObject *object = CAMEL_OBJECT (folder); @@ -339,7 +353,9 @@ imapx_get_trash (CamelStore *store, GError **error) } static gboolean -imapx_noop (CamelStore *store, GError **error) +imapx_noop (CamelStore *store, + GCancellable *cancellable, + GError **error) { CamelIMAPXStore *istore = (CamelIMAPXStore *) store; GSList *servers = NULL, *l; @@ -354,7 +370,7 @@ imapx_noop (CamelStore *store, GError **error) CamelIMAPXServer *server = CAMEL_IMAPX_SERVER (l->data); /* we just return last noops value, technically not correct though */ - success = camel_imapx_server_noop (server, NULL, error); + success = camel_imapx_server_noop (server, NULL, cancellable, error); g_object_unref (server); } @@ -425,7 +441,11 @@ get_folder_offline (CamelStore *store, const gchar *folder_name, } static CamelFolder * -imapx_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error) +imapx_get_folder (CamelStore *store, + const gchar *folder_name, + guint32 flags, + GCancellable *cancellable, + GError **error) { CamelFolder *folder; @@ -610,7 +630,11 @@ imapx_mark_folder_subscribed (CamelIMAPXStore *istore, const gchar *folder_name, } static gboolean -imapx_subscribe_folder (CamelStore *store, const gchar *folder_name, gboolean emit_signal, GError **error) +imapx_subscribe_folder (CamelStore *store, + const gchar *folder_name, + gboolean emit_signal, + GCancellable *cancellable, + GError **error) { CamelIMAPXStore *istore = (CamelIMAPXStore *) store; CamelIMAPXServer *server; @@ -619,12 +643,13 @@ imapx_subscribe_folder (CamelStore *store, const gchar *folder_name, gboolean em if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) return TRUE; - server = camel_imapx_store_get_server (istore, NULL, error); + server = camel_imapx_store_get_server (istore, NULL, cancellable, error); if (!server) return FALSE; - success = camel_imapx_server_manage_subscription (server, folder_name, TRUE, error); - g_object_unref (server); + success = camel_imapx_server_manage_subscription ( + server, folder_name, TRUE, cancellable, error); + g_object_unref(server); if (success) imapx_mark_folder_subscribed (istore, folder_name, emit_signal); @@ -633,7 +658,11 @@ imapx_subscribe_folder (CamelStore *store, const gchar *folder_name, gboolean em } static gboolean -imapx_unsubscribe_folder (CamelStore *store, const gchar *folder_name, gboolean emit_signal, GError **error) +imapx_unsubscribe_folder (CamelStore *store, + const gchar *folder_name, + gboolean emit_signal, + GCancellable *cancellable, + GError **error) { CamelIMAPXStore *istore = (CamelIMAPXStore *) store; CamelIMAPXServer *server; @@ -642,12 +671,13 @@ imapx_unsubscribe_folder (CamelStore *store, const gchar *folder_name, gboolean if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) return TRUE; - server = camel_imapx_store_get_server (istore, NULL, error); + server = camel_imapx_store_get_server (istore, NULL, cancellable, error); if (!server) return FALSE; - success = camel_imapx_server_manage_subscription (server, folder_name, FALSE, error); - g_object_unref (server); + success = camel_imapx_server_manage_subscription ( + server, folder_name, FALSE, cancellable, error); + g_object_unref(server); if (success) imapx_unmark_folder_subscribed (istore, folder_name, emit_signal); @@ -656,15 +686,23 @@ imapx_unsubscribe_folder (CamelStore *store, const gchar *folder_name, gboolean } static gboolean -imapx_store_subscribe_folder (CamelStore *store, const gchar *folder_name, GError **error) +imapx_store_subscribe_folder (CamelStore *store, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { - return imapx_subscribe_folder (store, folder_name, TRUE, error); + return imapx_subscribe_folder ( + store, folder_name, TRUE, cancellable, error); } static gboolean -imapx_store_unsubscribe_folder (CamelStore *store, const gchar *folder_name, GError **error) +imapx_store_unsubscribe_folder (CamelStore *store, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { - return imapx_unsubscribe_folder (store, folder_name, TRUE, error); + return imapx_unsubscribe_folder ( + store, folder_name, TRUE, cancellable, error); } static void @@ -707,7 +745,10 @@ imapx_delete_folder_from_cache (CamelIMAPXStore *istore, const gchar *folder_nam } static gboolean -imapx_delete_folder (CamelStore *store, const gchar *folder_name, GError **error) +imapx_delete_folder (CamelStore *store, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelIMAPXStore *istore = (CamelIMAPXStore *) store; CamelIMAPXServer *server; @@ -722,11 +763,12 @@ imapx_delete_folder (CamelStore *store, const gchar *folder_name, GError **error } /* Use INBOX connection as the implementation would try to select inbox to ensure we are not selected on the folder being deleted */ - server = camel_imapx_store_get_server (istore, "INBOX", error); + server = camel_imapx_store_get_server (istore, "INBOX", cancellable, error); if (!server) return FALSE; - success = camel_imapx_server_delete_folder (server, folder_name, error); + success = camel_imapx_server_delete_folder ( + server, folder_name, cancellable, error); g_object_unref (server); if (success) @@ -769,7 +811,11 @@ rename_folder_info (CamelIMAPXStore *istore, const gchar *old_name, const gchar } static gboolean -imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error) +imapx_rename_folder (CamelStore *store, + const gchar *old, + const gchar *new, + GCancellable *cancellable, + GError **error) { CamelIMAPXStore *istore = (CamelIMAPXStore *) store; CamelIMAPXServer *server; @@ -785,18 +831,19 @@ imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GErr } if (istore->rec_options & IMAPX_SUBSCRIPTIONS) - imapx_unsubscribe_folder (store, old, FALSE, NULL); + imapx_unsubscribe_folder (store, old, FALSE, cancellable, NULL); /* Use INBOX connection as the implementation would try to select inbox to ensure we are not selected on the folder being renamed */ - server = camel_imapx_store_get_server(istore, "INBOX", error); + server = camel_imapx_store_get_server(istore, "INBOX", cancellable, error); if (server) { - success = camel_imapx_server_rename_folder (server, old, new, error); + success = camel_imapx_server_rename_folder ( + server, old, new, cancellable, error); g_object_unref (server); } if (!success) { - imapx_subscribe_folder (store, old, FALSE, NULL); + imapx_subscribe_folder (store, old, FALSE, cancellable, NULL); return FALSE; } @@ -804,7 +851,8 @@ imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GErr rename_folder_info (istore, old, new); if (istore->rec_options & IMAPX_SUBSCRIPTIONS) - success = imapx_subscribe_folder (store, new, FALSE, error); + success = imapx_subscribe_folder ( + store, new, FALSE, cancellable, error); storage_path = g_strdup_printf("%s/folders", istore->storage_path); oldpath = imapx_path_to_physical (storage_path, old); @@ -824,7 +872,11 @@ imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GErr } static CamelFolderInfo * -imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error) +imapx_create_folder (CamelStore *store, + const gchar *parent_name, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelStoreInfo *si; CamelIMAPXStoreNamespace *ns; @@ -843,7 +895,7 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f return NULL; } - server = camel_imapx_store_get_server (istore, NULL, error); + server = camel_imapx_store_get_server (istore, NULL, cancellable, error); if (!server) return NULL; @@ -893,7 +945,8 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f full_name = imapx_concat (istore, parent_real, real_name); g_free (real_name); - success = camel_imapx_server_create_folder (server, full_name, error); + success = camel_imapx_server_create_folder ( + server, full_name, cancellable, error); g_object_unref (server); if (success) { @@ -1110,11 +1163,13 @@ fetch_folders_for_pattern (CamelIMAPXStore *istore, guint32 flags, const gchar *ext, GHashTable *table, + GCancellable *cancellable, GError **error) { GPtrArray *folders; - folders = camel_imapx_server_list (server, pattern, flags, ext, error); + folders = camel_imapx_server_list ( + server, pattern, flags, ext, cancellable, error); if (folders == NULL) return FALSE; @@ -1145,13 +1200,17 @@ get_namespaces (CamelIMAPXStore *istore) } static GHashTable * -fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gboolean sync, GError **error) +fetch_folders_for_namespaces (CamelIMAPXStore *istore, + const gchar *pattern, + gboolean sync, + GCancellable *cancellable, + GError **error) { CamelIMAPXServer *server; GHashTable *folders = NULL; GSList *namespaces = NULL, *l; - server = camel_imapx_store_get_server (istore, NULL, error); + server = camel_imapx_store_get_server (istore, NULL, cancellable, error); if (!server) return NULL; @@ -1182,7 +1241,9 @@ fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gbo list_ext = "RETURN (SUBSCRIBED)"; flags |= CAMEL_STORE_FOLDER_INFO_RECURSIVE; - if (!fetch_folders_for_pattern (istore, server, pat, flags, list_ext, folders, error)) { + if (!fetch_folders_for_pattern ( + istore, server, pat, flags, list_ext, + folders, cancellable, error)) { g_free (pat); goto exception; } @@ -1190,7 +1251,9 @@ fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gbo /* If the server doesn't support LIST-EXTENDED then we have to issue LSUB to list the subscribed folders separately */ flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED; - if (!fetch_folders_for_pattern (istore, server, pat, flags, NULL, folders, error)) { + if (!fetch_folders_for_pattern ( + istore, server, pat, flags, NULL, + folders, cancellable, error)) { g_free (pat); goto exception; } @@ -1214,12 +1277,17 @@ exception: } static gboolean -sync_folders (CamelIMAPXStore *istore, const gchar *pattern, gboolean sync, GError **error) +sync_folders (CamelIMAPXStore *istore, + const gchar *pattern, + gboolean sync, + GCancellable *cancellable, + GError **error) { GHashTable *folders_from_server; gint i, total; - folders_from_server = fetch_folders_for_namespaces (istore, pattern, sync, error); + folders_from_server = fetch_folders_for_namespaces ( + istore, pattern, sync, cancellable, error); if (folders_from_server == NULL) return FALSE; @@ -1274,9 +1342,7 @@ sync_folders (CamelIMAPXStore *istore, const gchar *pattern, gboolean sync, GErr struct _imapx_refresh_msg { CamelSessionThreadMsg msg; - CamelStore *store; - GError *error; }; static void @@ -1288,11 +1354,11 @@ imapx_refresh_finfo (CamelSession *session, CamelSessionThreadMsg *msg) if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) return; - if (!camel_service_connect ((CamelService *)istore, &m->error)) + if (!camel_service_connect ((CamelService *)istore, &msg->error)) return; /* look in all namespaces */ - sync_folders (istore, "", FALSE, &m->error); + sync_folders (istore, "", FALSE, msg->cancellable, &msg->error); camel_store_summary_save ((CamelStoreSummary *)istore->summary); } @@ -1302,7 +1368,6 @@ imapx_refresh_free (CamelSession *session, CamelSessionThreadMsg *msg) struct _imapx_refresh_msg *m = (struct _imapx_refresh_msg *)msg; g_object_unref (m->store); - g_clear_error (&m->error); } static CamelSessionThreadOps imapx_refresh_ops = { @@ -1311,15 +1376,16 @@ static CamelSessionThreadOps imapx_refresh_ops = { }; static void -discover_inbox (CamelStore *store) +discover_inbox (CamelStore *store, + GCancellable *cancellable) { CamelStoreInfo *si; CamelIMAPXStore *istore = (CamelIMAPXStore *)store; si = camel_store_summary_path((CamelStoreSummary *) istore->summary, "INBOX"); if (si == NULL || (si->flags & CAMEL_FOLDER_SUBSCRIBED) == 0) { - if (imapx_subscribe_folder (store, "INBOX", FALSE, NULL) && !si) - sync_folders (istore, "INBOX", TRUE, NULL); + if (imapx_subscribe_folder (store, "INBOX", FALSE, cancellable, NULL) && !si) + sync_folders (istore, "INBOX", TRUE, cancellable, NULL); if (si) camel_store_summary_info_free ((CamelStoreSummary *) istore->summary, si); @@ -1327,7 +1393,11 @@ discover_inbox (CamelStore *store) } static CamelFolderInfo * -imapx_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error) +imapx_get_folder_info (CamelStore *store, + const gchar *top, + guint32 flags, + GCancellable *cancellable, + GError **error) { CamelIMAPXStore *istore = (CamelIMAPXStore *)store; CamelFolderInfo * fi= NULL; @@ -1358,7 +1428,7 @@ imapx_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GErro istore->last_refresh_time = time (NULL); m = camel_session_thread_msg_new (((CamelService *)store)->session, &imapx_refresh_ops, sizeof (*m)); m->store = g_object_ref (store); - camel_session_thread_queue (((CamelService *)store)->session, &m->msg, 0); + camel_session_thread_queue(((CamelService *)store)->session, &m->msg, 0); } fi = get_folder_info_offline (store, top, flags, error); @@ -1394,7 +1464,7 @@ imapx_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GErro pattern[0] = '\0'; } - if (!sync_folders (istore, pattern, TRUE, error)) { + if (!sync_folders (istore, pattern, TRUE, cancellable, error)) { g_mutex_unlock (istore->get_finfo_lock); return NULL; } @@ -1403,7 +1473,7 @@ imapx_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GErro /* ensure the INBOX is subscribed if lsub was preferred*/ if (initial_setup && istore->rec_options & IMAPX_SUBSCRIPTIONS) - discover_inbox (store); + discover_inbox (store, cancellable); fi = get_folder_info_offline (store, top, flags, error); g_mutex_unlock (istore->get_finfo_lock); diff --git a/camel/providers/imapx/camel-imapx-store.h b/camel/providers/imapx/camel-imapx-store.h index e4853d6..be5ce65 100644 --- a/camel/providers/imapx/camel-imapx-store.h +++ b/camel/providers/imapx/camel-imapx-store.h @@ -95,6 +95,7 @@ struct _CamelIMAPXStoreClass { GType camel_imapx_store_get_type (void); CamelIMAPXServer * camel_imapx_store_get_server (CamelIMAPXStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error); void camel_imapx_store_op_done (CamelIMAPXStore *istore, CamelIMAPXServer *server, diff --git a/camel/providers/imapx/camel-imapx-stream.c b/camel/providers/imapx/camel-imapx-stream.c index 94d629f..c87a88f 100644 --- a/camel/providers/imapx/camel-imapx-stream.c +++ b/camel/providers/imapx/camel-imapx-stream.c @@ -41,6 +41,7 @@ G_DEFINE_TYPE (CamelIMAPXStream, camel_imapx_stream, CAMEL_TYPE_STREAM) static gint imapx_stream_fill (CamelIMAPXStream *is, + GCancellable *cancellable, GError **error) { gint left = 0; @@ -52,7 +53,8 @@ imapx_stream_fill (CamelIMAPXStream *is, is->ptr = is->buf; left = camel_stream_read ( is->source, (gchar *) is->end, - is->bufsize - (is->end - is->buf), error); + is->bufsize - (is->end - is->buf), + cancellable, error); if (left > 0) { is->end += left; io(is->tagprefix, "camel_imapx_read: buffer is '%.*s'\n", (gint)(is->end - is->ptr), is->ptr); @@ -108,6 +110,7 @@ static gssize imapx_stream_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelIMAPXStream *is = (CamelIMAPXStream *)stream; @@ -124,7 +127,7 @@ imapx_stream_read (CamelStream *stream, is->ptr += max; } else { max = MIN (is->literal, n); - max = camel_stream_read (is->source, buffer, max, error); + max = camel_stream_read (is->source, buffer, max, cancellable, error); if (max <= 0) return max; } @@ -140,17 +143,19 @@ static gssize imapx_stream_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelIMAPXStream *is = (CamelIMAPXStream *)stream; io(is->tagprefix, "camel_imapx_write: '%.*s'\n", (gint)n, buffer); - return camel_stream_write (is->source, buffer, n, error); + return camel_stream_write (is->source, buffer, n, cancellable, error); } static gint imapx_stream_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { /* nop? */ @@ -159,6 +164,7 @@ imapx_stream_close (CamelStream *stream, static gint imapx_stream_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { /* nop? */ @@ -306,12 +312,17 @@ skip_ws (CamelIMAPXStream *is, guchar *pp, guchar *pe) /* FIXME: these should probably handle it themselves, and get rid of the token interface? */ gint -camel_imapx_stream_atom (CamelIMAPXStream *is, guchar **data, guint *lenp, GError **error) +camel_imapx_stream_atom (CamelIMAPXStream *is, + guchar **data, + guint *lenp, + GCancellable *cancellable, + GError **error) { guchar *p, c; + GError *local_error = NULL; /* this is only 'approximate' atom */ - switch (camel_imapx_stream_token (is, data, lenp, NULL)) { + switch (camel_imapx_stream_token (is, data, lenp, cancellable, &local_error)) { case IMAPX_TOK_TOKEN: p = *data; while ((c = *p)) @@ -319,9 +330,14 @@ camel_imapx_stream_atom (CamelIMAPXStream *is, guchar **data, guint *lenp, GErro case IMAPX_TOK_INT: return 0; case IMAPX_TOK_ERROR: + if (local_error != NULL) + g_propagate_error (error, local_error); return IMAPX_TOK_ERROR; default: - g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting atom"); + if (local_error == NULL) + g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting atom"); + else + g_propagate_error (error, local_error); io(is->tagprefix, "expecting atom!\n"); return IMAPX_TOK_PROTOCOL; } @@ -329,13 +345,17 @@ camel_imapx_stream_atom (CamelIMAPXStream *is, guchar **data, guint *lenp, GErro /* gets an atom, a quoted_string, or a literal */ gint -camel_imapx_stream_astring (CamelIMAPXStream *is, guchar **data, GError **error) +camel_imapx_stream_astring (CamelIMAPXStream *is, + guchar **data, + GCancellable *cancellable, + GError **error) { guchar *p, *start; guint len, inlen; gint ret; + GError *local_error = NULL; - switch (camel_imapx_stream_token (is, data, &len, NULL)) { + switch (camel_imapx_stream_token (is, data, &len, cancellable, &local_error)) { case IMAPX_TOK_TOKEN: case IMAPX_TOK_INT: case IMAPX_TOK_STRING: @@ -346,7 +366,7 @@ camel_imapx_stream_astring (CamelIMAPXStream *is, guchar **data, GError **error) p = is->tokenbuf; camel_imapx_stream_set_literal (is, len); do { - ret = camel_imapx_stream_getl (is, &start, &inlen); + ret = camel_imapx_stream_getl (is, &start, &inlen, cancellable, error); if (ret < 0) return ret; memcpy (p, start, inlen); @@ -357,9 +377,14 @@ camel_imapx_stream_astring (CamelIMAPXStream *is, guchar **data, GError **error) return 0; case IMAPX_TOK_ERROR: /* wont get unless no exception hanlder*/ + if (local_error != NULL) + g_propagate_error (error, local_error); return IMAPX_TOK_ERROR; default: - g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting astring"); + if (local_error == NULL) + g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting astring"); + else + g_propagate_error (error, local_error); io(is->tagprefix, "expecting astring!\n"); return IMAPX_TOK_PROTOCOL; } @@ -367,13 +392,17 @@ camel_imapx_stream_astring (CamelIMAPXStream *is, guchar **data, GError **error) /* check for NIL or (small) quoted_string or literal */ gint -camel_imapx_stream_nstring (CamelIMAPXStream *is, guchar **data, GError **error) +camel_imapx_stream_nstring (CamelIMAPXStream *is, + guchar **data, + GCancellable *cancellable, + GError **error) { guchar *p, *start; guint len, inlen; gint ret; + GError *local_error = NULL; - switch (camel_imapx_stream_token (is, data, &len, NULL)) { + switch (camel_imapx_stream_token (is, data, &len, cancellable, &local_error)) { case IMAPX_TOK_STRING: return 0; case IMAPX_TOK_LITERAL: @@ -382,7 +411,7 @@ camel_imapx_stream_nstring (CamelIMAPXStream *is, guchar **data, GError **error) p = is->tokenbuf; camel_imapx_stream_set_literal (is, len); do { - ret = camel_imapx_stream_getl (is, &start, &inlen); + ret = camel_imapx_stream_getl (is, &start, &inlen, cancellable, error); if (ret < 0) return ret; memcpy (p, start, inlen); @@ -398,10 +427,15 @@ camel_imapx_stream_nstring (CamelIMAPXStream *is, guchar **data, GError **error) return 0; } default: - g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting nstring"); + if (local_error == NULL) + g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting nstring"); + else + g_propagate_error (error, local_error); return IMAPX_TOK_PROTOCOL; case IMAPX_TOK_ERROR: /* we'll never get this unless there are no exception handlers anyway */ + if (local_error != NULL) + g_propagate_error (error, local_error); return IMAPX_TOK_ERROR; } @@ -409,17 +443,21 @@ camel_imapx_stream_nstring (CamelIMAPXStream *is, guchar **data, GError **error) /* parse an nstring as a stream */ gint -camel_imapx_stream_nstring_stream (CamelIMAPXStream *is, CamelStream **stream, GError **error) +camel_imapx_stream_nstring_stream (CamelIMAPXStream *is, + CamelStream **stream, + GCancellable *cancellable, + GError **error) /* throws IO,PARSE exception */ { guchar *token; guint len; gint ret = 0; CamelStream * mem = NULL; + GError *local_error = NULL; *stream = NULL; - switch (camel_imapx_stream_token (is, &token, &len, NULL)) { + switch (camel_imapx_stream_token (is, &token, &len, cancellable, &local_error)) { case IMAPX_TOK_STRING: mem = camel_stream_mem_new_with_buffer ((gchar *)token, len); *stream = mem; @@ -428,7 +466,7 @@ camel_imapx_stream_nstring_stream (CamelIMAPXStream *is, CamelStream **stream, G /* if len is big, we could automatically use a file backing */ camel_imapx_stream_set_literal (is, len); mem = camel_stream_mem_new (); - if (camel_stream_write_to_stream ((CamelStream *)is, mem, error) == -1) { + if (camel_stream_write_to_stream ((CamelStream *)is, mem, cancellable, error) == -1) { g_object_unref (mem); ret = -1; break; @@ -443,20 +481,29 @@ camel_imapx_stream_nstring_stream (CamelIMAPXStream *is, CamelStream **stream, G } default: ret = -1; - g_set_error (error, CAMEL_IMAPX_ERROR, 1, "nstring: token not string"); + if (local_error == NULL) + g_set_error (error, CAMEL_IMAPX_ERROR, 1, "nstring: token not string"); + else + g_propagate_error (error, local_error); } return ret; } guint64 -camel_imapx_stream_number (CamelIMAPXStream *is, GError **error) +camel_imapx_stream_number (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { guchar *token; guint len; + GError *local_error = NULL; - if (camel_imapx_stream_token (is, &token, &len, NULL) != IMAPX_TOK_INT) { - g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting number"); + if (camel_imapx_stream_token (is, &token, &len, cancellable, &local_error) != IMAPX_TOK_INT) { + if (local_error == NULL) + g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting number"); + else + g_propagate_error (error, local_error); return 0; } @@ -464,7 +511,10 @@ camel_imapx_stream_number (CamelIMAPXStream *is, GError **error) } gint -camel_imapx_stream_text (CamelIMAPXStream *is, guchar **text, GError **error) +camel_imapx_stream_text (CamelIMAPXStream *is, + guchar **text, + GCancellable *cancellable, + GError **error) { GByteArray *build = g_byte_array_new (); guchar *token; @@ -485,9 +535,8 @@ camel_imapx_stream_text (CamelIMAPXStream *is, guchar **text, GError **error) } do { - tok = camel_imapx_stream_gets (is, &token, &len); + tok = camel_imapx_stream_gets (is, &token, &len, cancellable, error); if (tok < 0) { - g_set_error (error, CAMEL_IMAPX_ERROR, 1, "io error: %s", strerror(errno)); *text = NULL; g_byte_array_free (build, TRUE); return -1; @@ -506,7 +555,11 @@ camel_imapx_stream_text (CamelIMAPXStream *is, guchar **text, GError **error) /* Get one token from the imap stream */ camel_imapx_token_t /* throws IO,PARSE exception */ -camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GError **error) +camel_imapx_stream_token (CamelIMAPXStream *is, + guchar **data, + guint *len, + GCancellable *cancellable, + GError **error) { register guchar c, *oe; guchar *o, *p, *e; @@ -531,7 +584,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro do { while (p >= e ) { is->ptr = p; - if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR) + if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR) return IMAPX_TOK_ERROR; p = is->ptr; e = is->end; @@ -565,7 +618,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro } } is->ptr = p; - if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR) + if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR) return IMAPX_TOK_ERROR; p = is->ptr; e = is->end; @@ -580,7 +633,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro } } is->ptr = p; - if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR) + if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR) return IMAPX_TOK_ERROR; p = is->ptr; e = is->end; @@ -594,7 +647,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro if (c == '\\') { while (p >= e) { is->ptr = p; - if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR) + if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR) return IMAPX_TOK_ERROR; p = is->ptr; e = is->end; @@ -620,7 +673,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro *o++ = c; } is->ptr = p; - if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR) + if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR) return IMAPX_TOK_ERROR; p = is->ptr; e = is->end; @@ -655,7 +708,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro *o++ = c; } is->ptr = p; - if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR) + if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR) return IMAPX_TOK_ERROR; p = is->ptr; e = is->end; @@ -686,7 +739,12 @@ camel_imapx_stream_ungettoken (CamelIMAPXStream *is, camel_imapx_token_t tok, gu } /* returns -1 on error, 0 if last lot of data, >0 if more remaining */ -gint camel_imapx_stream_gets (CamelIMAPXStream *is, guchar **start, guint *len) +gint +camel_imapx_stream_gets (CamelIMAPXStream *is, + guchar **start, + guint *len, + GCancellable *cancellable, + GError **error) { gint max; guchar *end; @@ -695,7 +753,7 @@ gint camel_imapx_stream_gets (CamelIMAPXStream *is, guchar **start, guint *len) max = is->end - is->ptr; if (max == 0) { - max = imapx_stream_fill (is, NULL); + max = imapx_stream_fill (is, cancellable, error); if (max <= 0) return max; } @@ -717,7 +775,12 @@ void camel_imapx_stream_set_literal (CamelIMAPXStream *is, guint literal) } /* returns -1 on erorr, 0 if last data, >0 if more data left */ -gint camel_imapx_stream_getl (CamelIMAPXStream *is, guchar **start, guint *len) +gint +camel_imapx_stream_getl (CamelIMAPXStream *is, + guchar **start, + guint *len, + GCancellable *cancellable, + GError **error) { gint max; @@ -726,7 +789,7 @@ gint camel_imapx_stream_getl (CamelIMAPXStream *is, guchar **start, guint *len) if (is->literal > 0) { max = is->end - is->ptr; if (max == 0) { - max = imapx_stream_fill (is, NULL); + max = imapx_stream_fill (is, cancellable, error); if (max <= 0) return max; } @@ -746,17 +809,19 @@ gint camel_imapx_stream_getl (CamelIMAPXStream *is, guchar **start, guint *len) /* skip the rest of the line of tokens */ gint -camel_imapx_stream_skip (CamelIMAPXStream *is, GError **error) +camel_imapx_stream_skip (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { gint tok; guchar *token; guint len; do { - tok = camel_imapx_stream_token (is, &token, &len, error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, error); if (tok == IMAPX_TOK_LITERAL) { camel_imapx_stream_set_literal (is, len); - while ((tok = camel_imapx_stream_getl (is, &token, &len)) > 0) { + while ((tok = camel_imapx_stream_getl (is, &token, &len, cancellable, error)) > 0) { io(is->tagprefix, "Skip literal data '%.*s'\n", (gint)len, token); } } diff --git a/camel/providers/imapx/camel-imapx-stream.h b/camel/providers/imapx/camel-imapx-stream.h index 4ed5e58..a6de847 100644 --- a/camel/providers/imapx/camel-imapx-stream.h +++ b/camel/providers/imapx/camel-imapx-stream.h @@ -94,6 +94,7 @@ camel_imapx_token_t camel_imapx_stream_token (CamelIMAPXStream *is, guchar **start, guint *len, + GCancellable *cancellable, GError **error); void camel_imapx_stream_ungettoken (CamelIMAPXStream *is, @@ -104,10 +105,14 @@ void camel_imapx_stream_set_literal (CamelIMAPXStream *is, guint literal); gint camel_imapx_stream_gets (CamelIMAPXStream *is, guchar **start, - guint *len); + guint *len, + GCancellable *cancellable, + GError **error); gint camel_imapx_stream_getl (CamelIMAPXStream *is, guchar **start, - guint *len); + guint *len, + GCancellable *cancellable, + GError **error); /* all throw IO,PARSE exceptions */ @@ -115,31 +120,38 @@ gint camel_imapx_stream_getl (CamelIMAPXStream *is, gint camel_imapx_stream_atom (CamelIMAPXStream *is, guchar **start, guint *len, + GCancellable *cancellable, GError **error); /* gets an atom or string */ gint camel_imapx_stream_astring (CamelIMAPXStream *is, guchar **start, + GCancellable *cancellable, GError **error); /* gets a NIL or a string, start==NULL if NIL */ gint camel_imapx_stream_nstring (CamelIMAPXStream *is, guchar **start, + GCancellable *cancellable, GError **error); /* gets a NIL or string into a stream, stream==NULL if NIL */ gint camel_imapx_stream_nstring_stream (CamelIMAPXStream *is, CamelStream **stream, + GCancellable *cancellable, GError **error); /* gets 'text' */ gint camel_imapx_stream_text (CamelIMAPXStream *is, guchar **text, + GCancellable *cancellable, GError **error); /* gets a 'number' */ guint64 camel_imapx_stream_number (CamelIMAPXStream *is, + GCancellable *cancellable, GError **error); /* skips the rest of a line, including literals, etc */ gint camel_imapx_stream_skip (CamelIMAPXStream *is, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/camel/providers/imapx/camel-imapx-utils.c b/camel/providers/imapx/camel-imapx-utils.c index 5e5caf3..d3d569a 100644 --- a/camel/providers/imapx/camel-imapx-utils.c +++ b/camel/providers/imapx/camel-imapx-utils.c @@ -97,7 +97,11 @@ static struct { shoudl this be part of imapx-driver? */ /* mabye this should be a stream op? */ void -imapx_parse_flags (CamelIMAPXStream *stream, guint32 *flagsp, CamelFlag **user_flagsp, GError **error) +imapx_parse_flags (CamelIMAPXStream *stream, + guint32 *flagsp, + CamelFlag **user_flagsp, + GCancellable *cancellable, + GError **error) /* throws IO,PARSE exception */ { gint tok, i; @@ -107,10 +111,10 @@ imapx_parse_flags (CamelIMAPXStream *stream, guint32 *flagsp, CamelFlag **user_f *flagsp = flags; - tok = camel_imapx_stream_token (stream, &token, &len, NULL); + tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL); if (tok == '(') { do { - tok = camel_imapx_stream_token (stream, &token, &len, NULL); + tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL); if (tok == IMAPX_TOK_TOKEN || tok == IMAPX_TOK_INT) { gchar *upper = g_ascii_strup ((gchar *) token, len); @@ -177,13 +181,17 @@ rename_label_flag (const gchar *flag, gint len, gboolean server_to_evo) } void -imapx_write_flags (CamelStream *stream, guint32 flags, CamelFlag *user_flags, GError **error) +imapx_write_flags (CamelStream *stream, + guint32 flags, + CamelFlag *user_flags, + GCancellable *cancellable, + GError **error) /* throws IO exception */ { gint i; gboolean first = TRUE; - if (camel_stream_write(stream, "(", 1, error) == -1) { + if (camel_stream_write(stream, "(", 1, cancellable, error) == -1) { return; } @@ -191,11 +199,11 @@ imapx_write_flags (CamelStream *stream, guint32 flags, CamelFlag *user_flags, GE if (flag_table[i].flag & flags) { if (flags & CAMEL_IMAPX_MESSAGE_RECENT) continue; - if (!first && camel_stream_write(stream, " ", 1, error) == -1) { + if (!first && camel_stream_write(stream, " ", 1, cancellable, error) == -1) { return; } first = FALSE; - if (camel_stream_write (stream, flag_table[i].name, strlen (flag_table[i].name), error) == -1) { + if (camel_stream_write (stream, flag_table[i].name, strlen (flag_table[i].name), cancellable, error) == -1) { return; } @@ -206,18 +214,18 @@ imapx_write_flags (CamelStream *stream, guint32 flags, CamelFlag *user_flags, GE while (user_flags) { const gchar *flag_name = rename_label_flag (user_flags->name, strlen (user_flags->name), FALSE); - if (!first && camel_stream_write(stream, " ", 1, error) == -1) { + if (!first && camel_stream_write(stream, " ", 1, cancellable, error) == -1) { return; } first = FALSE; - if (camel_stream_write (stream, flag_name, strlen (flag_name), error) == -1) { + if (camel_stream_write (stream, flag_name, strlen (flag_name), cancellable, error) == -1) { return; } user_flags = user_flags->next; } - if (camel_stream_write(stream, ")", 1, error) == -1) { + if (camel_stream_write(stream, ")", 1, cancellable, error) == -1) { return; } } @@ -443,7 +451,9 @@ struct { }; struct _capability_info * -imapx_parse_capability (CamelIMAPXStream *stream, GError **error) +imapx_parse_capability (CamelIMAPXStream *stream, + GCancellable *cancellable, + GError **error) { gint tok, i; guint len; @@ -456,7 +466,7 @@ imapx_parse_capability (CamelIMAPXStream *stream, GError **error) cinfo->auth_types = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL); /* FIXME: handle auth types */ - while ((tok = camel_imapx_stream_token (stream, &token, &len, &local_error)) != '\n' && + while ((tok = camel_imapx_stream_token (stream, &token, &len, cancellable, &local_error)) != '\n' && local_error == NULL) { switch (tok) { case ']': @@ -510,7 +520,9 @@ void imapx_free_capability (struct _capability_info *cinfo) } struct _CamelIMAPXNamespaceList * -imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error) +imapx_parse_namespace_list (CamelIMAPXStream *stream, + GCancellable *cancellable, + GError **error) { CamelIMAPXStoreNamespace *namespaces[3], *node, *tail; CamelIMAPXNamespaceList *nsl = NULL; @@ -524,16 +536,16 @@ imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error) nsl->shared = NULL; nsl->other = NULL; - tok = camel_imapx_stream_token (stream, &token, &len, NULL); + tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL); do { namespaces[n] = NULL; tail = (CamelIMAPXStoreNamespace *) &namespaces[n]; if (tok == '(') { - tok = camel_imapx_stream_token (stream, &token, &len, NULL); + tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL); while (tok == '(') { - tok = camel_imapx_stream_token (stream, &token, &len, NULL); + tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL); if (tok != IMAPX_TOK_STRING) { g_set_error (error, 1, CAMEL_IMAPX_ERROR, "namespace: expected a string path name"); goto exception; @@ -543,7 +555,7 @@ imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error) node->next = NULL; node->path = g_strdup ((gchar *) token); - tok = camel_imapx_stream_token (stream, &token, &len, NULL); + tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL); if (tok == IMAPX_TOK_STRING) { if (strlen ((gchar *) token) == 1) { @@ -577,13 +589,13 @@ imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error) /* TODO remove full_name later. not required */ node->full_name = g_strdup (node->path); - tok = camel_imapx_stream_token (stream, &token, &len, NULL); + tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL); if (tok != ')') { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "namespace: expected a ')'"); goto exception; } - tok = camel_imapx_stream_token (stream, &token, &len, NULL); + tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL); } if (tok != ')') { @@ -598,7 +610,7 @@ imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error) goto exception; } - tok = camel_imapx_stream_token (stream, &token, &len, NULL); + tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL); n++; } while (n < 3); @@ -754,7 +766,10 @@ imapx_free_body (struct _CamelMessageContentInfo *cinfo) } gboolean -imapx_parse_param_list (CamelIMAPXStream *is, struct _camel_header_param **plist, GError **error) +imapx_parse_param_list (CamelIMAPXStream *is, + struct _camel_header_param **plist, + GCancellable *cancellable, + GError **error) { gint tok; guint len; @@ -764,18 +779,18 @@ imapx_parse_param_list (CamelIMAPXStream *is, struct _camel_header_param **plist p(is->tagprefix, "body_fld_param\n"); /* body_fld_param ::= "(" 1#(string SPACE string) ")" / nil */ - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok == '(') { while (1) { - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok == ')') break; camel_imapx_stream_ungettoken (is, tok, token, len); - camel_imapx_stream_astring (is, &token, NULL); + camel_imapx_stream_astring (is, &token, cancellable, NULL); param = alloca (strlen ((gchar *) token)+1); strcpy (param, (gchar *) token); - camel_imapx_stream_astring (is, &token, NULL); + camel_imapx_stream_astring (is, &token, cancellable, NULL); camel_header_set_param (plist, param, (gchar *) token); } } /* else check nil? no need */ @@ -784,7 +799,9 @@ imapx_parse_param_list (CamelIMAPXStream *is, struct _camel_header_param **plist } struct _CamelContentDisposition * -imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error) +imapx_parse_ext_optional (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { gint tok; guint len; @@ -809,16 +826,16 @@ imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error) /* body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil */ - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); switch (tok) { case '(': dinfo = g_malloc0 (sizeof (*dinfo)); dinfo->refcount = 1; /* should be string */ - camel_imapx_stream_astring (is, &token, NULL); + camel_imapx_stream_astring (is, &token, cancellable, NULL); dinfo->disposition = g_strdup ((gchar *) token); - imapx_parse_param_list (is, &dinfo->params, NULL); + imapx_parse_param_list (is, &dinfo->params, cancellable, NULL); case IMAPX_TOK_TOKEN: d(is->tagprefix, "body_fld_dsp: NIL\n"); break; @@ -833,11 +850,11 @@ imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error) /* we just drop the lang string/list, save it somewhere? */ - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); switch (tok) { case '(': while (1) { - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); if (tok == ')') { break; } else if (tok != IMAPX_TOK_STRING) { @@ -857,7 +874,7 @@ imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error) case IMAPX_TOK_LITERAL: /* we have a literal string */ camel_imapx_stream_set_literal (is, len); - while ((tok = camel_imapx_stream_getl (is, &token, &len)) > 0) { + while ((tok = camel_imapx_stream_getl (is, &token, &len, cancellable, NULL)) > 0) { d(is->tagprefix, "Skip literal data '%.*s'\n", (gint)len, token); } break; @@ -875,7 +892,9 @@ imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error) } struct _CamelMessageContentInfo * -imapx_parse_body_fields (CamelIMAPXStream *is, GError **error) +imapx_parse_body_fields (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { guchar *token; gchar *type; @@ -891,34 +910,34 @@ imapx_parse_body_fields (CamelIMAPXStream *is, GError **error) cinfo = g_malloc0 (sizeof (*cinfo)); /* this should be string not astring */ - if (camel_imapx_stream_astring (is, &token, error)) + if (camel_imapx_stream_astring (is, &token, cancellable, error)) goto error; type = alloca (strlen ( (gchar *) token)+1); strcpy (type, (gchar *) token); - if (camel_imapx_stream_astring (is, &token, error)) + if (camel_imapx_stream_astring (is, &token, cancellable, error)) goto error; cinfo->type = camel_content_type_new (type, (gchar *) token); - if (!imapx_parse_param_list (is, &cinfo->type->params, error)) + if (!imapx_parse_param_list (is, &cinfo->type->params, cancellable, error)) goto error; /* body_fld_id ::= nstring */ - if (!camel_imapx_stream_nstring (is, &token, error)) + if (!camel_imapx_stream_nstring (is, &token, cancellable, error)) goto error; cinfo->id = g_strdup ((gchar *) token); /* body_fld_desc ::= nstring */ - if (!camel_imapx_stream_nstring (is, &token, error)) + if (!camel_imapx_stream_nstring (is, &token, cancellable, error)) goto error; cinfo->description = g_strdup ((gchar *) token); /* body_fld_enc ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/ "QUOTED-PRINTABLE") <">) / string */ - if (camel_imapx_stream_astring (is, &token, error)) + if (camel_imapx_stream_astring (is, &token, cancellable, error)) goto error; cinfo->encoding = g_strdup ((gchar *) token); /* body_fld_octets ::= number */ - cinfo->size = camel_imapx_stream_number (is, &local_error); + cinfo->size = camel_imapx_stream_number (is, cancellable, &local_error); if (local_error != NULL) { g_propagate_error (error, local_error); goto error; @@ -931,7 +950,9 @@ error: } struct _camel_header_address * -imapx_parse_address_list (CamelIMAPXStream *is, GError **error) +imapx_parse_address_list (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) /* throws PARSE,IO exception */ { gint tok; @@ -943,14 +964,14 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error) /* "(" 1*address ")" / nil */ - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); if (tok == '(') { while (1) { struct _camel_header_address *addr, *group = NULL; /* address ::= "(" addr_name SPACE addr_adl SPACE addr_mailbox SPACE addr_host ")" */ - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); if (tok == ')') break; if (tok != '(') { @@ -962,10 +983,10 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error) addr = camel_header_address_new (); addr->type = CAMEL_HEADER_ADDRESS_NAME; - tok = camel_imapx_stream_nstring (is, &token, &local_error); + tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error); addr->name = g_strdup ((gchar *) token); /* we ignore the route, nobody uses it in the real world */ - tok = camel_imapx_stream_nstring (is, &token, &local_error); + tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error); /* [RFC-822] group syntax is indicated by a special form of address structure in which the host name @@ -975,9 +996,9 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error) non-NIL, this is a start of group marker, and the mailbox name field holds the group name phrase. */ - tok = camel_imapx_stream_nstring (is,(guchar **) &mbox, &local_error); + tok = camel_imapx_stream_nstring (is,(guchar **) &mbox, cancellable, &local_error); mbox = g_strdup (mbox); - tok = camel_imapx_stream_nstring (is, &host, &local_error); + tok = camel_imapx_stream_nstring (is, &host, cancellable, &local_error); if (host == NULL) { if (mbox == NULL) { group = NULL; @@ -999,7 +1020,7 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error) camel_header_address_list_append (&list, addr); } do { - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); } while (tok != ')'); } } else { @@ -1014,7 +1035,9 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error) } struct _CamelMessageInfo * -imapx_parse_envelope (CamelIMAPXStream *is, GError **error) +imapx_parse_envelope (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { gint tok; guint len; @@ -1033,7 +1056,7 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error) minfo = (CamelMessageInfoBase *)camel_message_info_new (NULL); - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); if (tok != '(') { g_clear_error (&local_error); camel_message_info_free (minfo); @@ -1042,20 +1065,20 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error) } /* env_date ::= nstring */ - camel_imapx_stream_nstring (is, &token, &local_error); + camel_imapx_stream_nstring (is, &token, cancellable, &local_error); minfo->date_sent = camel_header_decode_date ((gchar *) token, NULL); /* env_subject ::= nstring */ - tok = camel_imapx_stream_nstring (is, &token, &local_error); + tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error); minfo->subject = camel_pstring_strdup ((gchar *) token); /* we merge from/sender into from, append should probably merge more smartly? */ /* env_from ::= "(" 1*address ")" / nil */ - addr_from = imapx_parse_address_list (is, &local_error); + addr_from = imapx_parse_address_list (is, cancellable, &local_error); /* env_sender ::= "(" 1*address ")" / nil */ - addr = imapx_parse_address_list (is, &local_error); + addr = imapx_parse_address_list (is, cancellable, &local_error); if (addr_from) { camel_header_address_list_clear (&addr); #if 0 @@ -1077,11 +1100,11 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error) /* we dont keep reply_to */ /* env_reply_to ::= "(" 1*address ")" / nil */ - addr = imapx_parse_address_list (is, &local_error); + addr = imapx_parse_address_list (is, cancellable, &local_error); camel_header_address_list_clear (&addr); /* env_to ::= "(" 1*address ")" / nil */ - addr = imapx_parse_address_list (is, &local_error); + addr = imapx_parse_address_list (is, cancellable, &local_error); if (addr) { addrstr = camel_header_address_list_format (addr); minfo->to = camel_pstring_strdup (addrstr); @@ -1090,7 +1113,7 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error) } /* env_cc ::= "(" 1*address ")" / nil */ - addr = imapx_parse_address_list (is, &local_error); + addr = imapx_parse_address_list (is, cancellable, &local_error); if (addr) { addrstr = camel_header_address_list_format (addr); minfo->cc = camel_pstring_strdup (addrstr); @@ -1101,20 +1124,20 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error) /* we dont keep bcc either */ /* env_bcc ::= "(" 1*address ")" / nil */ - addr = imapx_parse_address_list (is, &local_error); + addr = imapx_parse_address_list (is, cancellable, &local_error); camel_header_address_list_clear (&addr); /* FIXME: need to put in-reply-to into references hash list */ /* env_in_reply_to ::= nstring */ - tok = camel_imapx_stream_nstring (is, &token, &local_error); + tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error); /* FIXME: need to put message-id into message-id hash */ /* env_message_id ::= nstring */ - tok = camel_imapx_stream_nstring (is, &token, &local_error); + tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error); - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); if (tok != ')') { g_clear_error (&local_error); camel_message_info_free (minfo); @@ -1130,7 +1153,9 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error) } struct _CamelMessageContentInfo * -imapx_parse_body (CamelIMAPXStream *is, GError **error) +imapx_parse_body (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { gint tok; guint len; @@ -1145,14 +1170,14 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error) p(is->tagprefix, "body\n"); - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); if (tok != '(') { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "body: expecting '('"); return NULL; } /* 1*body (optional for multiparts) */ - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); camel_imapx_stream_ungettoken (is, tok, token, len); if (tok == '(') { /* body_type_mpart ::= 1*body SPACE media_subtype @@ -1161,17 +1186,17 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error) cinfo = g_malloc0 (sizeof (*cinfo)); last = (struct _CamelMessageContentInfo *)&cinfo->childs; do { - subinfo = imapx_parse_body (is, &local_error); + subinfo = imapx_parse_body (is, cancellable, &local_error); last->next = subinfo; last = subinfo; subinfo->parent = cinfo; - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); camel_imapx_stream_ungettoken (is, tok, token, len); } while (tok == '('); d(is->tagprefix, "media_subtype\n"); - camel_imapx_stream_astring (is, &token, &local_error); + camel_imapx_stream_astring (is, &token, cancellable, &local_error); cinfo->type = camel_content_type_new("multipart", (gchar *) token); /* body_ext_mpart ::= body_fld_param @@ -1182,17 +1207,17 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error) d(is->tagprefix, "body_ext_mpart\n"); - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); camel_imapx_stream_ungettoken (is, tok, token, len); if (tok == '(') { - imapx_parse_param_list (is, &cinfo->type->params, &local_error); + imapx_parse_param_list (is, &cinfo->type->params, cancellable, &local_error); /* body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil */ - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); camel_imapx_stream_ungettoken (is, tok, token, len); if (tok == '(' || tok == IMAPX_TOK_TOKEN) { - dinfo = imapx_parse_ext_optional (is, &local_error); + dinfo = imapx_parse_ext_optional (is, cancellable, &local_error); /* other extension fields?, soaked up below */ } else { camel_imapx_stream_ungettoken (is, tok, token, len); @@ -1209,16 +1234,16 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error) d(is->tagprefix, "Single part body\n"); - cinfo = imapx_parse_body_fields (is, &local_error); + cinfo = imapx_parse_body_fields (is, cancellable, &local_error); d(is->tagprefix, "envelope?\n"); /* do we have an envelope following */ - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); camel_imapx_stream_ungettoken (is, tok, token, len); if (tok == '(') { /* what do we do with the envelope?? */ - minfo = imapx_parse_envelope (is, &local_error); + minfo = imapx_parse_envelope (is, cancellable, &local_error); /* what do we do with the message content info?? */ //((CamelMessageInfoBase *)minfo)->content = imapx_parse_body (is); camel_message_info_free (minfo); @@ -1229,10 +1254,10 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error) d(is->tagprefix, "fld_lines?\n"); /* do we have fld_lines following? */ - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); if (tok == IMAPX_TOK_INT) { d(is->tagprefix, "field lines: %s\n", token); - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); } camel_imapx_stream_ungettoken (is, tok, token, len); @@ -1245,16 +1270,16 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error) d(is->tagprefix, "extension data?\n"); if (tok != ')') { - camel_imapx_stream_nstring (is, &token, &local_error); + camel_imapx_stream_nstring (is, &token, cancellable, &local_error); d(is->tagprefix, "md5: %s\n", token?(gchar *)token:"NIL"); /* body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil */ - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); camel_imapx_stream_ungettoken (is, tok, token, len); if (tok == '(' || tok == IMAPX_TOK_TOKEN) { - dinfo = imapx_parse_ext_optional (is, &local_error); + dinfo = imapx_parse_ext_optional (is, cancellable, &local_error); /* then other extension fields, soaked up below */ } } @@ -1263,7 +1288,7 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error) /* soak up any other extension fields that may be present */ /* there should only be simple tokens, no lists */ do { - tok = camel_imapx_stream_token (is, &token, &len, &local_error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error); if (tok != ')') { d(is->tagprefix, "Dropping extension data '%s'\n", token); } @@ -1289,7 +1314,9 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error) } gchar * -imapx_parse_section (CamelIMAPXStream *is, GError **error) +imapx_parse_section (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { gint tok; guint len; @@ -1307,13 +1334,13 @@ imapx_parse_section (CamelIMAPXStream *is, GError **error) SPACE header_list / "TEXT" */ - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok != '[') { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "section: expecting '['"); return NULL; } - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok == IMAPX_TOK_INT || tok == IMAPX_TOK_TOKEN) section = g_strdup ((gchar *) token); else if (tok == ']') { @@ -1328,10 +1355,10 @@ imapx_parse_section (CamelIMAPXStream *is, GError **error) header_fld_name ::= astring */ /* we dont need the header specifiers */ - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok == '(') { do { - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok == IMAPX_TOK_STRING || tok == IMAPX_TOK_TOKEN || tok == IMAPX_TOK_INT) { /* ?do something? */ } else if (tok != ')') { @@ -1340,7 +1367,7 @@ imapx_parse_section (CamelIMAPXStream *is, GError **error) return NULL; } } while (tok != ')'); - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); } if (tok != ']') { @@ -1353,23 +1380,25 @@ imapx_parse_section (CamelIMAPXStream *is, GError **error) } static guint64 -imapx_parse_modseq (CamelIMAPXStream *is, GError **error) +imapx_parse_modseq (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { guint64 ret; gint tok; guint len; guchar *token; - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok != '(') { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "fetch: expecting '('"); return 0; } - ret = camel_imapx_stream_number (is, error); + ret = camel_imapx_stream_number (is, cancellable, error); if (ret == 0) return 0; - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok != ')') { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "fetch: expecting '('"); return 0; @@ -1417,17 +1446,17 @@ imapx_dump_fetch (struct _fetch_info *finfo) sout = camel_stream_fs_new_with_fd (fd); if (finfo->body) { camel_stream_printf(sout, "Body content:\n"); - camel_stream_write_to_stream (finfo->body, sout, NULL); + camel_stream_write_to_stream (finfo->body, sout, NULL, NULL); camel_stream_reset (finfo->body, NULL); } if (finfo->text) { camel_stream_printf(sout, "Text content:\n"); - camel_stream_write_to_stream (finfo->text, sout, NULL); + camel_stream_write_to_stream (finfo->text, sout, NULL, NULL); camel_stream_reset (finfo->text, NULL); } if (finfo->header) { camel_stream_printf(sout, "Header content:\n"); - camel_stream_write_to_stream (finfo->header, sout, NULL); + camel_stream_write_to_stream (finfo->header, sout, NULL, NULL); camel_stream_reset (finfo->header, NULL); } if (finfo->minfo) { @@ -1454,7 +1483,9 @@ imapx_dump_fetch (struct _fetch_info *finfo) } struct _fetch_info * -imapx_parse_fetch (CamelIMAPXStream *is, GError **error) +imapx_parse_fetch (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { gint tok; guint len; @@ -1463,14 +1494,14 @@ imapx_parse_fetch (CamelIMAPXStream *is, GError **error) finfo = g_malloc0 (sizeof (*finfo)); - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok != '(') { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "fetch: expecting '('"); g_free (finfo); return NULL; } - while ((tok = camel_imapx_stream_token (is, &token, &len, NULL)) == IMAPX_TOK_TOKEN) { + while ((tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL)) == IMAPX_TOK_TOKEN) { p = token; while ((c=*p)) @@ -1478,55 +1509,55 @@ imapx_parse_fetch (CamelIMAPXStream *is, GError **error) switch (imapx_tokenise ((gchar *) token, len)) { case IMAPX_ENVELOPE: - finfo->minfo = imapx_parse_envelope (is, NULL); + finfo->minfo = imapx_parse_envelope (is, cancellable, NULL); finfo->got |= FETCH_MINFO; break; case IMAPX_FLAGS: - imapx_parse_flags (is, &finfo->flags, &finfo->user_flags, NULL); + imapx_parse_flags (is, &finfo->flags, &finfo->user_flags, cancellable, NULL); finfo->got |= FETCH_FLAGS; break; case IMAPX_INTERNALDATE: - camel_imapx_stream_nstring (is, &token, NULL); + camel_imapx_stream_nstring (is, &token, cancellable, NULL); /* TODO: convert to camel format? */ finfo->date = g_strdup ((gchar *) token); finfo->got |= FETCH_DATE; break; case IMAPX_RFC822_HEADER: - camel_imapx_stream_nstring_stream (is, &finfo->header, NULL); + camel_imapx_stream_nstring_stream (is, &finfo->header, cancellable, NULL); finfo->got |= FETCH_HEADER; break; case IMAPX_RFC822_TEXT: - camel_imapx_stream_nstring_stream (is, &finfo->text, NULL); + camel_imapx_stream_nstring_stream (is, &finfo->text, cancellable, NULL); finfo->got |= FETCH_TEXT; break; case IMAPX_RFC822_SIZE: - finfo->size = camel_imapx_stream_number (is, NULL); + finfo->size = camel_imapx_stream_number (is, cancellable, NULL); finfo->got |= FETCH_SIZE; break; case IMAPX_BODYSTRUCTURE: - finfo->cinfo = imapx_parse_body (is, NULL); + finfo->cinfo = imapx_parse_body (is, cancellable, NULL); finfo->got |= FETCH_CINFO; break; case IMAPX_MODSEQ: - finfo->modseq = imapx_parse_modseq (is, NULL); + finfo->modseq = imapx_parse_modseq (is, cancellable, NULL); finfo->got |= FETCH_MODSEQ; break; case IMAPX_BODY: - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); camel_imapx_stream_ungettoken (is, tok, token, len); if (tok == '(') { - finfo->cinfo = imapx_parse_body (is, NULL); + finfo->cinfo = imapx_parse_body (is, cancellable, NULL); finfo->got |= FETCH_CINFO; } else if (tok == '[') { - finfo->section = imapx_parse_section (is, NULL); + finfo->section = imapx_parse_section (is, cancellable, NULL); finfo->got |= FETCH_SECTION; - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (token[0] == '<') { finfo->offset = strtoul ((gchar *) token+1, NULL, 10); } else { camel_imapx_stream_ungettoken (is, tok, token, len); } - camel_imapx_stream_nstring_stream (is, &finfo->body, NULL); + camel_imapx_stream_nstring_stream (is, &finfo->body, cancellable, NULL); finfo->got |= FETCH_BODY; } else { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "unknown body response"); @@ -1535,7 +1566,7 @@ imapx_parse_fetch (CamelIMAPXStream *is, GError **error) } break; case IMAPX_UID: - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok != IMAPX_TOK_INT) { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "uid not integer"); } @@ -1560,7 +1591,9 @@ imapx_parse_fetch (CamelIMAPXStream *is, GError **error) } struct _state_info * -imapx_parse_status_info (struct _CamelIMAPXStream *is, GError **error) +imapx_parse_status_info (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { struct _state_info *sinfo; gint tok; @@ -1570,38 +1603,38 @@ imapx_parse_status_info (struct _CamelIMAPXStream *is, GError **error) sinfo = g_malloc0 (sizeof (*sinfo)); /* skip the folder name */ - if (camel_imapx_stream_astring (is, &token, error)) { + if (camel_imapx_stream_astring (is, &token, cancellable, error)) { g_free (sinfo); return NULL; } sinfo->name = camel_utf7_utf8 ((gchar *)token); - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok != '(') { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "parse status info: expecting '('"); g_free (sinfo); return NULL; } - while ((tok = camel_imapx_stream_token (is, &token, &len, NULL)) == IMAPX_TOK_TOKEN) { + while ((tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL)) == IMAPX_TOK_TOKEN) { switch (imapx_tokenise ((gchar *) token, len)) { case IMAPX_MESSAGES: - sinfo->messages = camel_imapx_stream_number (is, NULL); + sinfo->messages = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_RECENT: - sinfo->recent = camel_imapx_stream_number (is, NULL); + sinfo->recent = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_UIDNEXT: - sinfo->uidnext = camel_imapx_stream_number (is, NULL); + sinfo->uidnext = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_UIDVALIDITY: - sinfo->uidvalidity = camel_imapx_stream_number (is, NULL); + sinfo->uidvalidity = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_UNSEEN: - sinfo->unseen = camel_imapx_stream_number (is, NULL); + sinfo->unseen = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_HIGHESTMODSEQ: - sinfo->highestmodseq = camel_imapx_stream_number (is, NULL); + sinfo->highestmodseq = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_NOMODSEQ: break; @@ -1631,7 +1664,9 @@ generate_uids_from_sequence (GPtrArray *uids, guint32 begin_uid, guint32 end_uid } GPtrArray * -imapx_parse_uids (CamelIMAPXStream *is, GError **error) +imapx_parse_uids (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { GPtrArray *uids = g_ptr_array_new (); guchar *token; @@ -1639,7 +1674,7 @@ imapx_parse_uids (CamelIMAPXStream *is, GError **error) guint len, str_len; gint tok, i; - tok = camel_imapx_stream_token (is, &token, &len, error); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, error); if (tok < 0) return NULL; @@ -1668,7 +1703,9 @@ imapx_parse_uids (CamelIMAPXStream *is, GError **error) /* rfc 2060 section 7.1 Status Responses */ /* shoudl this start after [ or before the [? token_unget anyone? */ struct _status_info * -imapx_parse_status (CamelIMAPXStream *is, GError **error) +imapx_parse_status (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) { gint tok; guint len; @@ -1677,7 +1714,7 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error) sinfo = g_malloc0 (sizeof (*sinfo)); - camel_imapx_stream_atom (is, &token, &len, NULL); + camel_imapx_stream_atom (is, &token, &len, cancellable, NULL); /* resp_cond_auth ::= ("OK" / "PREAUTH") SPACE resp_text @@ -1703,9 +1740,9 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error) return NULL; } - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok == '[') { - camel_imapx_stream_atom (is, &token, &len, NULL); + camel_imapx_stream_atom (is, &token, &len, cancellable, NULL); sinfo->condition = imapx_tokenise ((gchar *) token, len); /* parse any details */ @@ -1718,39 +1755,39 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error) case IMAPX_CLOSED: break; case IMAPX_APPENDUID: - sinfo->u.appenduid.uidvalidity = camel_imapx_stream_number (is, NULL); - sinfo->u.appenduid.uid = camel_imapx_stream_number (is, NULL); + sinfo->u.appenduid.uidvalidity = camel_imapx_stream_number (is, cancellable, NULL); + sinfo->u.appenduid.uid = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_COPYUID: - sinfo->u.copyuid.uidvalidity = camel_imapx_stream_number (is, NULL); - sinfo->u.copyuid.uids = imapx_parse_uids (is, NULL); - sinfo->u.copyuid.copied_uids = imapx_parse_uids (is, NULL); + sinfo->u.copyuid.uidvalidity = camel_imapx_stream_number (is, cancellable, NULL); + sinfo->u.copyuid.uids = imapx_parse_uids (is, cancellable, NULL); + sinfo->u.copyuid.copied_uids = imapx_parse_uids (is, cancellable, NULL); break; case IMAPX_NEWNAME: /* the rfc doesn't specify the bnf for this */ - camel_imapx_stream_astring (is, &token, NULL); + camel_imapx_stream_astring (is, &token, cancellable, NULL); sinfo->u.newname.oldname = g_strdup ((gchar *) token); - camel_imapx_stream_astring (is, &token, NULL); + camel_imapx_stream_astring (is, &token, cancellable, NULL); sinfo->u.newname.newname = g_strdup ((gchar *) token); break; case IMAPX_PERMANENTFLAGS: /* we only care about \* for permanent flags, not user flags */ - imapx_parse_flags (is, &sinfo->u.permanentflags, NULL, NULL); + imapx_parse_flags (is, &sinfo->u.permanentflags, NULL, cancellable, NULL); break; case IMAPX_UIDVALIDITY: - sinfo->u.uidvalidity = camel_imapx_stream_number (is, NULL); + sinfo->u.uidvalidity = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_UIDNEXT: - sinfo->u.uidnext = camel_imapx_stream_number (is, NULL); + sinfo->u.uidnext = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_UNSEEN: - sinfo->u.unseen = camel_imapx_stream_number (is, NULL); + sinfo->u.unseen = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_HIGHESTMODSEQ: - sinfo->u.highestmodseq = camel_imapx_stream_number (is, NULL); + sinfo->u.highestmodseq = camel_imapx_stream_number (is, cancellable, NULL); break; case IMAPX_CAPABILITY: - sinfo->u.cinfo = imapx_parse_capability (is, NULL); + sinfo->u.cinfo = imapx_parse_capability (is, cancellable, NULL); break; default: sinfo->condition = IMAPX_UNKNOWN; @@ -1759,7 +1796,7 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error) /* ignore anything we dont know about */ do { - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok == '\n' || tok < 0) { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "server response truncated"); imapx_free_status (sinfo); @@ -1771,7 +1808,7 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error) } /* and take the human readable response */ - camel_imapx_stream_text (is, (guchar **)&sinfo->text, NULL); + camel_imapx_stream_text (is, (guchar **)&sinfo->text, cancellable, NULL); return sinfo; } @@ -1833,7 +1870,9 @@ static struct { }; struct _list_info * -imapx_parse_list (CamelIMAPXStream *is, GError **error) +imapx_parse_list (CamelIMAPXStream *is, + GCancellable *cancellable, + GError **error) /* throws io, parse */ { gint tok, i; @@ -1847,14 +1886,14 @@ imapx_parse_list (CamelIMAPXStream *is, GError **error) "\Noselect" / "\Unmarked" / flag_extension) ")" SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox */ - tok = camel_imapx_stream_token (is, &token, &len, NULL); + tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL); if (tok != '(') { g_set_error (error, CAMEL_IMAPX_ERROR, 1, "list: expecting '('"); g_free (linfo); return NULL; } - while ((tok = camel_imapx_stream_token (is, &token, &len, NULL)) != ')') { + while ((tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL)) != ')') { if (tok == IMAPX_TOK_STRING || tok == IMAPX_TOK_TOKEN) { p = token; while ((c=*p)) @@ -1869,9 +1908,9 @@ imapx_parse_list (CamelIMAPXStream *is, GError **error) } } - camel_imapx_stream_nstring (is, &token, NULL); + camel_imapx_stream_nstring (is, &token, cancellable, NULL); linfo->separator = token?*token:0; - camel_imapx_stream_astring (is, &token, NULL); + camel_imapx_stream_astring (is, &token, cancellable, NULL); linfo->name = camel_utf7_utf8 ((gchar *) token); return linfo; diff --git a/camel/providers/imapx/camel-imapx-utils.h b/camel/providers/imapx/camel-imapx-utils.h index ac19685..baa23cf 100644 --- a/camel/providers/imapx/camel-imapx-utils.h +++ b/camel/providers/imapx/camel-imapx-utils.h @@ -84,9 +84,9 @@ enum { /* ********************************************************************** */ -GPtrArray *imapx_parse_uids (struct _CamelIMAPXStream *is, GError **error); -void imapx_parse_flags (struct _CamelIMAPXStream *stream, guint32 *flagsp, struct _CamelFlag **user_flagsp, GError **error); -void imapx_write_flags (CamelStream *stream, guint32 flags, struct _CamelFlag *user_flags, GError **error); +GPtrArray *imapx_parse_uids (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error); +void imapx_parse_flags (struct _CamelIMAPXStream *stream, guint32 *flagsp, struct _CamelFlag **user_flagsp, GCancellable *cancellable, GError **error); +void imapx_write_flags (CamelStream *stream, guint32 flags, struct _CamelFlag *user_flags, GCancellable *cancellable, GError **error); gboolean imapx_update_message_info_flags (CamelMessageInfo *info, guint32 server_flags, CamelFlag *server_user_flags, CamelFolder *folder, gboolean unsolicited); void imapx_set_message_info_flags_for_new_message (CamelMessageInfo *info, guint32 server_flags, CamelFlag *server_user_flags, CamelFolder *folder); @@ -114,16 +114,16 @@ struct _capability_info { GHashTable *auth_types; }; -struct _capability_info *imapx_parse_capability (struct _CamelIMAPXStream *stream, GError **error); +struct _capability_info *imapx_parse_capability (struct _CamelIMAPXStream *stream, GCancellable *cancellable, GError **error); void imapx_free_capability (struct _capability_info *); -gboolean imapx_parse_param_list (struct _CamelIMAPXStream *is, struct _camel_header_param **plist, GError **error) /* IO,PARSE */; -struct _CamelContentDisposition *imapx_parse_ext_optional (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */; -struct _CamelMessageContentInfo *imapx_parse_body_fields (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */; -struct _camel_header_address *imapx_parse_address_list (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */; -struct _CamelMessageInfo *imapx_parse_envelope (struct _CamelIMAPXStream *is, GError **error) /* IO, PARSE */; -struct _CamelMessageContentInfo *imapx_parse_body (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */; -gchar *imapx_parse_section (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */; +gboolean imapx_parse_param_list (struct _CamelIMAPXStream *is, struct _camel_header_param **plist, GCancellable *cancellable, GError **error) /* IO,PARSE */; +struct _CamelContentDisposition *imapx_parse_ext_optional (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */; +struct _CamelMessageContentInfo *imapx_parse_body_fields (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */; +struct _camel_header_address *imapx_parse_address_list (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */; +struct _CamelMessageInfo *imapx_parse_envelope (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO, PARSE */; +struct _CamelMessageContentInfo *imapx_parse_body (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */; +gchar *imapx_parse_section (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */; void imapx_free_body (struct _CamelMessageContentInfo *cinfo); /* ********************************************************************** */ @@ -159,7 +159,7 @@ struct _fetch_info { #define FETCH_UID (1<<10) #define FETCH_MODSEQ (1<<11) -struct _fetch_info *imapx_parse_fetch (struct _CamelIMAPXStream *is, GError **error); +struct _fetch_info *imapx_parse_fetch (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error); void imapx_free_fetch (struct _fetch_info *finfo); void imapx_dump_fetch (struct _fetch_info *finfo); @@ -194,7 +194,7 @@ struct _status_info { gchar *text; }; -struct _status_info *imapx_parse_status (struct _CamelIMAPXStream *is, GError **error); +struct _status_info *imapx_parse_status (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error); struct _status_info *imapx_copy_status (struct _status_info *sinfo); void imapx_free_status (struct _status_info *sinfo); @@ -211,7 +211,7 @@ struct _state_info { }; /* use g_free to free the return value */ -struct _state_info *imapx_parse_status_info (struct _CamelIMAPXStream *is, GError **error); +struct _state_info *imapx_parse_status_info (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error); /* ********************************************************************** */ @@ -223,7 +223,7 @@ struct _list_info { gchar *name; }; -struct _list_info *imapx_parse_list (struct _CamelIMAPXStream *is, GError **error); +struct _list_info *imapx_parse_list (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error); gchar *imapx_list_get_path (struct _list_info *li); void imapx_free_list (struct _list_info *linfo); @@ -286,7 +286,7 @@ gchar *imapx_concat (struct _CamelIMAPXStore *imapx_store, const gchar *prefix, gchar * imapx_get_temp_uid (void); void camel_imapx_namespace_list_clear (struct _CamelIMAPXNamespaceList *nsl); -struct _CamelIMAPXNamespaceList * imapx_parse_namespace_list (struct _CamelIMAPXStream *stream, GError **error); +struct _CamelIMAPXNamespaceList * imapx_parse_namespace_list (struct _CamelIMAPXStream *stream, GCancellable *cancellable, GError **error); struct _CamelIMAPXNamespaceList *camel_imapx_namespace_list_copy (const struct _CamelIMAPXNamespaceList *nsl); #endif diff --git a/camel/providers/imapx/test-imapx.c b/camel/providers/imapx/test-imapx.c index ede8d65..9c154ae 100644 --- a/camel/providers/imapx/test-imapx.c +++ b/camel/providers/imapx/test-imapx.c @@ -47,9 +47,11 @@ main (gint argc, gchar *argv[]) service = camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, NULL); camel_service_connect (service, NULL); - camel_store_get_folder_info ((CamelStore *)service, "", 3, NULL); - folder = camel_store_get_folder ((CamelStore *)service, "INBOX", 0, NULL); - camel_folder_refresh_info (folder, NULL); + camel_store_get_folder_info ( + CAMEL_STORE (service), "", 3, NULL, NULL); + folder = camel_store_get_folder ( + CAMEL_STORE (service), "INBOX", 0, NULL, NULL); + camel_folder_refresh_info (folder, NULL, NULL); while (1) { diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c index 0f2b543..cab3a7b 100644 --- a/camel/providers/local/camel-local-folder.c +++ b/camel/providers/local/camel-local-folder.c @@ -62,23 +62,6 @@ enum { PROP_INDEX_BODY = 0x2400 }; -static gint local_lock (CamelLocalFolder *lf, CamelLockType type, GError **error); -static void local_unlock (CamelLocalFolder *lf); - -static gboolean local_refresh_info (CamelFolder *folder, GError **error); - -static gboolean local_sync (CamelFolder *folder, gboolean expunge, GError **error); -static gboolean local_expunge (CamelFolder *folder, GError **error); - -static GPtrArray *local_search_by_expression (CamelFolder *folder, const gchar *expression, GError **error); -static guint32 local_count_by_expression (CamelFolder *folder, const gchar *expression, GError **error); -static GPtrArray *local_search_by_uids (CamelFolder *folder, const gchar *expression, GPtrArray *uids, GError **error); -static void local_search_free (CamelFolder *folder, GPtrArray * result); -static GPtrArray * local_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, GError **error); - -static void local_delete (CamelFolder *folder); -static void local_rename (CamelFolder *folder, const gchar *newname); - G_DEFINE_TYPE (CamelLocalFolder, camel_local_folder, CAMEL_TYPE_FOLDER) static void @@ -127,7 +110,7 @@ local_folder_dispose (GObject *object) if (folder->summary != NULL) { camel_local_summary_sync ( CAMEL_LOCAL_SUMMARY (folder->summary), - FALSE, local_folder->changes, NULL); + FALSE, local_folder->changes, NULL, NULL); g_object_unref (folder->summary); folder->summary = NULL; } @@ -233,6 +216,220 @@ local_folder_constructed (GObject *object) g_free (path); } +static gboolean +local_folder_refresh_info (CamelFolder *folder, + GCancellable *cancellable, + GError **error) +{ + CamelLocalFolder *lf = (CamelLocalFolder *)folder; + + if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error) == -1) + return FALSE; + + if (camel_folder_change_info_changed (lf->changes)) { + camel_folder_changed (folder, lf->changes); + camel_folder_change_info_clear (lf->changes); + } + + return TRUE; +} + +static gboolean +local_folder_sync (CamelFolder *folder, + gboolean expunge, + GCancellable *cancellable, + GError **error) +{ + CamelLocalFolder *lf = CAMEL_LOCAL_FOLDER (folder); + gboolean success; + + d(printf("local sync '%s' , expunge=%s\n", folder->full_name, expunge?"true":"false")); + + if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) + return FALSE; + + camel_object_state_write (CAMEL_OBJECT (lf)); + + /* if sync fails, we'll pass it up on exit through ex */ + success = (camel_local_summary_sync ( + (CamelLocalSummary *)folder->summary, + expunge, lf->changes, cancellable, error) == 0); + camel_local_folder_unlock (lf); + + if (camel_folder_change_info_changed (lf->changes)) { + camel_folder_changed (folder, lf->changes); + camel_folder_change_info_clear (lf->changes); + } + + return success; +} + +static gboolean +local_folder_expunge (CamelFolder *folder, + GCancellable *cancellable, + GError **error) +{ + /* Just do a sync with expunge, serves the same purpose */ + /* call the callback directly, to avoid locking problems */ + return CAMEL_FOLDER_GET_CLASS (folder)->sync ( + folder, TRUE, cancellable, error); +} + +static GPtrArray * +local_folder_search_by_expression (CamelFolder *folder, + const gchar *expression, + GError **error) +{ + CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder); + GPtrArray *matches; + + CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock); + + if (local_folder->search == NULL) + local_folder->search = camel_folder_search_new (); + + camel_folder_search_set_folder (local_folder->search, folder); + camel_folder_search_set_body_index (local_folder->search, local_folder->index); + matches = camel_folder_search_search (local_folder->search, expression, NULL, error); + + CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock); + + return matches; +} + +static GPtrArray * +local_folder_search_by_uids (CamelFolder *folder, + const gchar *expression, + GPtrArray *uids, + GError **error) +{ + CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder); + GPtrArray *matches; + + if (uids->len == 0) + return g_ptr_array_new (); + + CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock); + + if (local_folder->search == NULL) + local_folder->search = camel_folder_search_new (); + + camel_folder_search_set_folder (local_folder->search, folder); + camel_folder_search_set_body_index (local_folder->search, local_folder->index); + matches = camel_folder_search_search (local_folder->search, expression, uids, error); + + CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock); + + return matches; +} + +static void +local_folder_search_free (CamelFolder *folder, + GPtrArray *result) +{ + CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder); + + /* we need to lock this free because of the way search_free_result works */ + /* FIXME: put the lock inside search_free_result */ + CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock); + + camel_folder_search_free_result (local_folder->search, result); + + CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock); +} + +static void +local_folder_delete (CamelFolder *folder) +{ + CamelLocalFolder *lf = (CamelLocalFolder *)folder; + + if (lf->index) + camel_index_delete (lf->index); + + CAMEL_FOLDER_CLASS (camel_local_folder_parent_class)->delete (folder); +} + +static void +local_folder_rename (CamelFolder *folder, + const gchar *newname) +{ + CamelLocalFolder *lf = (CamelLocalFolder *)folder; + gchar *statepath; + CamelLocalStore *ls; + CamelStore *parent_store; + + parent_store = camel_folder_get_parent_store (folder); + ls = CAMEL_LOCAL_STORE (parent_store); + + d(printf("renaming local folder paths to '%s'\n", newname)); + + /* Sync? */ + + g_free (lf->folder_path); + g_free (lf->summary_path); + g_free (lf->index_path); + + lf->folder_path = camel_local_store_get_full_path (ls, newname); + lf->summary_path = camel_local_store_get_meta_path(ls, newname, ".ev-summary"); + lf->index_path = camel_local_store_get_meta_path(ls, newname, ".ibex"); + statepath = camel_local_store_get_meta_path(ls, newname, ".cmeta"); + camel_object_set_state_filename (CAMEL_OBJECT (lf), statepath); + g_free (statepath); + + /* FIXME: Poke some internals, sigh */ + camel_folder_summary_set_filename (folder->summary, lf->summary_path); + g_free (((CamelLocalSummary *)folder->summary)->folder_path); + ((CamelLocalSummary *)folder->summary)->folder_path = g_strdup (lf->folder_path); + + CAMEL_FOLDER_CLASS (camel_local_folder_parent_class)->rename (folder, newname); +} + +static guint32 +local_folder_count_by_expression (CamelFolder *folder, + const gchar *expression, + GError **error) +{ + CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder); + gint matches; + + CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock); + + if (local_folder->search == NULL) + local_folder->search = camel_folder_search_new (); + + camel_folder_search_set_folder (local_folder->search, folder); + camel_folder_search_set_body_index (local_folder->search, local_folder->index); + matches = camel_folder_search_count (local_folder->search, expression, error); + + CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock); + + return matches; +} + +static GPtrArray * +local_folder_get_uncached_uids (CamelFolder *folder, + GPtrArray *uids, + GError **error) +{ + /* By default, we would have everything local. + * No need to fetch from anywhere. */ + return g_ptr_array_new (); +} + +static gint +local_folder_lock (CamelLocalFolder *lf, + CamelLockType type, + GError **error) +{ + return 0; +} + +static void +local_folder_unlock (CamelLocalFolder *lf) +{ + /* nothing */ +} + static void camel_local_folder_class_init (CamelLocalFolderClass *class) { @@ -249,19 +446,19 @@ camel_local_folder_class_init (CamelLocalFolderClass *class) object_class->constructed = local_folder_constructed; folder_class = CAMEL_FOLDER_CLASS (class); - folder_class->refresh_info = local_refresh_info; - folder_class->sync = local_sync; - folder_class->expunge = local_expunge; - folder_class->get_uncached_uids = local_get_uncached_uids; - folder_class->search_by_expression = local_search_by_expression; - folder_class->count_by_expression = local_count_by_expression; - folder_class->search_by_uids = local_search_by_uids; - folder_class->search_free = local_search_free; - folder_class->delete = local_delete; - folder_class->rename = local_rename; - - class->lock = local_lock; - class->unlock = local_unlock; + folder_class->refresh_info = local_folder_refresh_info; + folder_class->sync = local_folder_sync; + folder_class->expunge = local_folder_expunge; + folder_class->search_by_expression = local_folder_search_by_expression; + folder_class->search_by_uids = local_folder_search_by_uids; + folder_class->search_free = local_folder_search_free; + folder_class->delete = local_folder_delete; + folder_class->rename = local_folder_rename; + folder_class->count_by_expression = local_folder_count_by_expression; + folder_class->get_uncached_uids = local_folder_get_uncached_uids; + + class->lock = local_folder_lock; + class->unlock = local_folder_unlock; g_object_class_install_property ( object_class, @@ -296,7 +493,10 @@ camel_local_folder_init (CamelLocalFolder *local_folder) } CamelLocalFolder * -camel_local_folder_construct (CamelLocalFolder *lf, guint32 flags, GError **error) +camel_local_folder_construct (CamelLocalFolder *lf, + guint32 flags, + GCancellable *cancellable, + GError **error) { CamelFolder *folder; CamelFolderInfo *fi; @@ -387,9 +587,9 @@ camel_local_folder_construct (CamelLocalFolder *lf, guint32 flags, GError **erro folder->summary = (CamelFolderSummary *)CAMEL_LOCAL_FOLDER_GET_CLASS (lf)->create_summary (lf, lf->summary_path, lf->folder_path, lf->index); if (!(flags & CAMEL_STORE_IS_MIGRATING) && camel_local_summary_load ((CamelLocalSummary *)folder->summary, forceindex, NULL) == -1) { /* ? */ - if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error) == 0) { + if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error) == 0) { /* we sync here so that any hard work setting up the folder isn't lost */ - if (camel_local_summary_sync ((CamelLocalSummary *)folder->summary, FALSE, lf->changes, error) == -1) { + if (camel_local_summary_sync ((CamelLocalSummary *)folder->summary, FALSE, lf->changes, cancellable, error) == -1) { g_object_unref (CAMEL_OBJECT (folder)); return NULL; } @@ -452,7 +652,10 @@ camel_local_folder_set_index_body (CamelLocalFolder *local_folder, /* lock the folder, may be called repeatedly (with matching unlock calls), with type the same or less than the first call */ -gint camel_local_folder_lock (CamelLocalFolder *lf, CamelLockType type, GError **error) +gint +camel_local_folder_lock (CamelLocalFolder *lf, + CamelLockType type, + GError **error) { if (lf->locked > 0) { /* lets be anal here - its important the code knows what its doing */ @@ -469,7 +672,8 @@ gint camel_local_folder_lock (CamelLocalFolder *lf, CamelLockType type, GError * } /* unlock folder */ -gint camel_local_folder_unlock (CamelLocalFolder *lf) +gint +camel_local_folder_unlock (CamelLocalFolder *lf) { g_assert (lf->locked>0); lf->locked--; @@ -479,202 +683,6 @@ gint camel_local_folder_unlock (CamelLocalFolder *lf) return 0; } -static gint -local_lock (CamelLocalFolder *lf, CamelLockType type, GError **error) -{ - return 0; -} - -static void -local_unlock (CamelLocalFolder *lf) -{ - /* nothing */ -} - -/* for auto-check to work */ -static gboolean -local_refresh_info (CamelFolder *folder, GError **error) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - - if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error) == -1) - return FALSE; - - if (camel_folder_change_info_changed (lf->changes)) { - camel_folder_changed (folder, lf->changes); - camel_folder_change_info_clear (lf->changes); - } - - return TRUE; -} - -static GPtrArray * -local_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, GError **error) -{ - GPtrArray *result = g_ptr_array_new (); - /* By default, we would have everything local. No need to fetch from anywhere. */ - return result; -} - -static gboolean -local_sync (CamelFolder *folder, gboolean expunge, GError **error) -{ - CamelLocalFolder *lf = CAMEL_LOCAL_FOLDER (folder); - gboolean success; - - d(printf("local sync '%s' , expunge=%s\n", folder->full_name, expunge?"true":"false")); - - if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) - return FALSE; - - camel_object_state_write (CAMEL_OBJECT (lf)); - - /* if sync fails, we'll pass it up on exit through ex */ - success = (camel_local_summary_sync ( - (CamelLocalSummary *)folder->summary, - expunge, lf->changes, error) == 0); - camel_local_folder_unlock (lf); - - if (camel_folder_change_info_changed (lf->changes)) { - camel_folder_changed (folder, lf->changes); - camel_folder_change_info_clear (lf->changes); - } - - return success; -} - -static gboolean -local_expunge (CamelFolder *folder, GError **error) -{ - d(printf("expunge\n")); - - /* Just do a sync with expunge, serves the same purpose */ - /* call the callback directly, to avoid locking problems */ - return CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, TRUE, error); -} - -static void -local_delete (CamelFolder *folder) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - - if (lf->index) - camel_index_delete (lf->index); - - CAMEL_FOLDER_CLASS (camel_local_folder_parent_class)->delete (folder); -} - -static void -local_rename (CamelFolder *folder, const gchar *newname) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - gchar *statepath; - CamelLocalStore *ls; - CamelStore *parent_store; - - parent_store = camel_folder_get_parent_store (folder); - ls = CAMEL_LOCAL_STORE (parent_store); - - d(printf("renaming local folder paths to '%s'\n", newname)); - - /* Sync? */ - - g_free (lf->folder_path); - g_free (lf->summary_path); - g_free (lf->index_path); - - lf->folder_path = camel_local_store_get_full_path (ls, newname); - lf->summary_path = camel_local_store_get_meta_path(ls, newname, ".ev-summary"); - lf->index_path = camel_local_store_get_meta_path(ls, newname, ".ibex"); - statepath = camel_local_store_get_meta_path(ls, newname, ".cmeta"); - camel_object_set_state_filename (CAMEL_OBJECT (lf), statepath); - g_free (statepath); - - /* FIXME: Poke some internals, sigh */ - camel_folder_summary_set_filename (folder->summary, lf->summary_path); - g_free (((CamelLocalSummary *)folder->summary)->folder_path); - ((CamelLocalSummary *)folder->summary)->folder_path = g_strdup (lf->folder_path); - - CAMEL_FOLDER_CLASS (camel_local_folder_parent_class)->rename (folder, newname); -} - -static GPtrArray * -local_search_by_expression (CamelFolder *folder, const gchar *expression, GError **error) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder); - GPtrArray *matches; - - CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock); - - if (local_folder->search == NULL) - local_folder->search = camel_folder_search_new (); - - camel_folder_search_set_folder (local_folder->search, folder); - camel_folder_search_set_body_index (local_folder->search, local_folder->index); - matches = camel_folder_search_search (local_folder->search, expression, NULL, error); - - CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock); - - return matches; -} - -static guint32 -local_count_by_expression (CamelFolder *folder, const gchar *expression, GError **error) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder); - gint matches; - - CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock); - - if (local_folder->search == NULL) - local_folder->search = camel_folder_search_new (); - - camel_folder_search_set_folder (local_folder->search, folder); - camel_folder_search_set_body_index (local_folder->search, local_folder->index); - matches = camel_folder_search_count (local_folder->search, expression, error); - - CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock); - - return matches; -} - -static GPtrArray * -local_search_by_uids (CamelFolder *folder, const gchar *expression, GPtrArray *uids, GError **error) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder); - GPtrArray *matches; - - if (uids->len == 0) - return g_ptr_array_new (); - - CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock); - - if (local_folder->search == NULL) - local_folder->search = camel_folder_search_new (); - - camel_folder_search_set_folder (local_folder->search, folder); - camel_folder_search_set_body_index (local_folder->search, local_folder->index); - matches = camel_folder_search_search (local_folder->search, expression, uids, error); - - CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock); - - return matches; -} - -static void -local_search_free (CamelFolder *folder, GPtrArray * result) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder); - - /* we need to lock this free because of the way search_free_result works */ - /* FIXME: put the lock inside search_free_result */ - CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock); - - camel_folder_search_free_result (local_folder->search, result); - - CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock); -} - void set_cannot_get_message_ex (GError **error, gint err_code, const gchar *msgID, const gchar *folder_path, const gchar *detailErr) { diff --git a/camel/providers/local/camel-local-folder.h b/camel/providers/local/camel-local-folder.h index 1d3b077..02415dd 100644 --- a/camel/providers/local/camel-local-folder.h +++ b/camel/providers/local/camel-local-folder.h @@ -76,13 +76,19 @@ struct _CamelLocalFolderClass { /* Virtual methods */ /* summary factory, only used at init */ - CamelLocalSummary *(*create_summary)(CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index); + CamelLocalSummary * + (*create_summary) (CamelLocalFolder *lf, + const gchar *path, + const gchar *folder, + CamelIndex *index); /* Lock the folder for my operations */ - gint (*lock)(CamelLocalFolder *, CamelLockType type, GError **error); + gint (*lock) (CamelLocalFolder *lf, + CamelLockType type, + GError **error); /* Unlock the folder for my operations */ - void (*unlock)(CamelLocalFolder *); + void (*unlock) (CamelLocalFolder *); }; GType camel_local_folder_get_type (void); @@ -91,6 +97,7 @@ GType camel_local_folder_get_type (void); CamelLocalFolder * camel_local_folder_construct (CamelLocalFolder *local_folder, guint32 flags, + GCancellable *cancellable, GError **error); gboolean camel_local_folder_get_index_body (CamelLocalFolder *local_folder); diff --git a/camel/providers/local/camel-local-store.c b/camel/providers/local/camel-local-store.c index 5f09297..d3ef901 100644 --- a/camel/providers/local/camel-local-store.c +++ b/camel/providers/local/camel-local-store.c @@ -38,15 +38,15 @@ #define d(x) static gboolean construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, GError **error); -static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error); +static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error); static gchar *get_name (CamelService *service, gboolean brief); -static CamelFolder *local_get_inbox (CamelStore *store, GError **error); -static CamelFolder *local_get_junk (CamelStore *store, GError **error); -static CamelFolder *local_get_trash (CamelStore *store, GError **error); -static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error); -static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error); -static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error); -static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error); +static CamelFolder *local_get_inbox (CamelStore *store, GCancellable *cancellable, GError **error); +static CamelFolder *local_get_junk (CamelStore *store, GCancellable *cancellable, GError **error); +static CamelFolder *local_get_trash (CamelStore *store, GCancellable *cancellable, GError **error); +static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error); +static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error); +static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GCancellable *cancellable, GError **error); +static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GCancellable *cancellable, GError **error); static gboolean local_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **error); static gchar *local_get_full_path (CamelLocalStore *lf, const gchar *full_name); @@ -132,7 +132,11 @@ camel_local_store_get_toplevel_dir (CamelLocalStore *store) } static CamelFolder * -get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error) +get_folder (CamelStore *store, + const gchar *folder_name, + guint32 flags, + GCancellable *cancellable, + GError **error) { gint len = strlen (((CamelLocalStore *)store)->toplevel_dir); gchar *path = g_alloca (len + 1); @@ -185,7 +189,9 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError * } static CamelFolder * -local_get_inbox (CamelStore *store, GError **error) +local_get_inbox (CamelStore *store, + GCancellable *cancellable, + GError **error) { g_set_error ( error, CAMEL_STORE_ERROR, @@ -197,12 +203,14 @@ local_get_inbox (CamelStore *store, GError **error) static CamelFolder * local_get_trash (CamelStore *store, + GCancellable *cancellable, GError **error) { CamelFolder *folder; /* Chain up to parent's get_trash() method. */ - folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)->get_trash (store, error); + folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)-> + get_trash (store, cancellable, error); if (folder) { CamelObject *object = CAMEL_OBJECT (folder); @@ -219,12 +227,14 @@ local_get_trash (CamelStore *store, static CamelFolder * local_get_junk (CamelStore *store, + GCancellable *cancellable, GError **error) { CamelFolder *folder; /* Chain up to parent's get_junk() method. */ - folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)->get_junk (store, error); + folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)-> + get_junk (store, cancellable, error); if (folder) { CamelObject *object = CAMEL_OBJECT (folder); @@ -251,8 +261,11 @@ get_name (CamelService *service, gboolean brief) } static CamelFolderInfo * -get_folder_info (CamelStore *store, const gchar *top, - guint32 flags, GError **error) +get_folder_info (CamelStore *store, + const gchar *top, + guint32 flags, + GCancellable *cancellable, + GError **error) { /* FIXME: This is broken, but it corresponds to what was * there before. @@ -267,6 +280,7 @@ static CamelFolderInfo * create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, + GCancellable *cancellable, GError **error) { gchar *path = ((CamelLocalStore *)store)->toplevel_dir; @@ -308,11 +322,11 @@ create_folder (CamelStore *store, name = g_strdup_printf("%s", folder_name); folder = CAMEL_STORE_GET_CLASS (store)->get_folder ( - store, name, CAMEL_STORE_FOLDER_CREATE, error); + store, name, CAMEL_STORE_FOLDER_CREATE, cancellable, error); if (folder) { g_object_unref (folder); info = CAMEL_STORE_GET_CLASS (store)->get_folder_info ( - store, name, 0, error); + store, name, 0, cancellable, error); } g_free (name); @@ -369,6 +383,7 @@ static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, + GCancellable *cancellable, GError **error) { gchar *path = CAMEL_LOCAL_STORE (store)->toplevel_dir; @@ -444,6 +459,7 @@ ibex_failed: static gboolean delete_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelFolderInfo *fi; @@ -467,7 +483,7 @@ delete_folder (CamelStore *store, g_free (str); str = NULL; - if ((lf = camel_store_get_folder (store, folder_name, 0, NULL))) { + if ((lf = camel_store_get_folder (store, folder_name, 0, cancellable, NULL))) { CamelObject *object = CAMEL_OBJECT (lf); const gchar *state_filename; diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c index 28c1f9e..3e13f9f 100644 --- a/camel/providers/local/camel-local-summary.c +++ b/camel/providers/local/camel-local-summary.c @@ -55,8 +55,8 @@ static gint local_summary_decode_x_evolution (CamelLocalSummary *cls, const gcha static gchar *local_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi); static gint local_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error); -static gint local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error); -static gint local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); +static gint local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); +static gint local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); static CamelMessageInfo *local_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error); static gint local_summary_need_index (void); @@ -268,13 +268,14 @@ do_stat_mi (CamelLocalSummary *cls, struct _stat_info *info, CamelMessageInfo *m gint camel_local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, GError **error) { CamelLocalSummaryClass *local_summary_class; gint ret; local_summary_class = CAMEL_LOCAL_SUMMARY_GET_CLASS (cls); - ret = local_summary_class->check (cls, changeinfo, error); + ret = local_summary_class->check (cls, changeinfo, cancellable, error); #ifdef DOSTATS if (ret != -1) { @@ -304,13 +305,14 @@ gint camel_local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, GError **error) { CamelLocalSummaryClass *local_summary_class; local_summary_class = CAMEL_LOCAL_SUMMARY_GET_CLASS (cls); - return local_summary_class->sync (cls, expunge, changeinfo, error); + return local_summary_class->sync (cls, expunge, changeinfo, cancellable, error); } CamelMessageInfo * @@ -416,7 +418,10 @@ camel_local_summary_write_headers (gint fd, struct _camel_header_raw *header, co } static gint -local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error) +local_summary_check (CamelLocalSummary *cls, + CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, + GError **error) { /* FIXME: sync index here ? */ return 0; @@ -426,6 +431,7 @@ static gint local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, GError **error) { CamelFolderSummary *folder_summary; @@ -485,7 +491,11 @@ update_summary (CamelFolderSummary *summary, CamelMessageInfoBase *info, CamelMe } static CamelMessageInfo * -local_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, GError **error) +local_summary_add (CamelLocalSummary *cls, + CamelMimeMessage *msg, + const CamelMessageInfo *info, + CamelFolderChangeInfo *ci, + GError **error) { CamelLocalMessageInfo *mi; CamelFolderSummary *s = (CamelFolderSummary *)cls; @@ -520,7 +530,7 @@ local_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMes if (mi->info.size == 0) { CamelStreamNull *sn = (CamelStreamNull *)camel_stream_null_new (); - camel_data_wrapper_write_to_stream ((CamelDataWrapper *)msg, (CamelStream *)sn, NULL); + camel_data_wrapper_write_to_stream ((CamelDataWrapper *)msg, (CamelStream *)sn, NULL, NULL); mi->info.size = sn->written; g_object_unref (sn); } diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h index d5a7ce8..54be594 100644 --- a/camel/providers/local/camel-local-summary.h +++ b/camel/providers/local/camel-local-summary.h @@ -76,8 +76,8 @@ struct _CamelLocalSummaryClass { CamelFolderSummaryClass parent_class; gint (*load)(CamelLocalSummary *cls, gint forceindex, GError **error); - gint (*check)(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error); - gint (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); + gint (*check)(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); + gint (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); CamelMessageInfo *(*add)(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error); gchar *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelLocalMessageInfo *info); @@ -91,9 +91,9 @@ void camel_local_summary_construct (CamelLocalSummary *new, const gchar *filenam /* load/check the summary */ gint camel_local_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error); /* check for new/removed messages */ -gint camel_local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *, GError **error); +gint camel_local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *, GCancellable *cancellable, GError **error); /* perform a folder sync or expunge, if needed */ -gint camel_local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *, GError **error); +gint camel_local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *, GCancellable *cancellable, GError **error); /* add a new message to the summary */ CamelMessageInfo *camel_local_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error); diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c index 934ada9..5281d5a 100644 --- a/camel/providers/local/camel-maildir-folder.c +++ b/camel/providers/local/camel-maildir-folder.c @@ -41,89 +41,15 @@ #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ -static CamelLocalSummary *maildir_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index); - -static gboolean maildir_append_message (CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, gchar **appended_uid, GError **error); -static CamelMimeMessage *maildir_get_message (CamelFolder * folder, const gchar * uid, GError **error); -static gchar * maildir_get_filename (CamelFolder *folder, const gchar *uid, GError **error); -static gint maildir_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2); -static void maildir_sort_uids (CamelFolder *folder, GPtrArray *uids); -static gboolean maildir_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, GError **error); - G_DEFINE_TYPE (CamelMaildirFolder, camel_maildir_folder, CAMEL_TYPE_LOCAL_FOLDER) -static void -camel_maildir_folder_class_init (CamelMaildirFolderClass *class) -{ - CamelFolderClass *folder_class; - CamelLocalFolderClass *local_folder_class; - - folder_class = CAMEL_FOLDER_CLASS (class); - folder_class->append_message = maildir_append_message; - folder_class->get_message = maildir_get_message; - folder_class->get_filename = maildir_get_filename; - folder_class->cmp_uids = maildir_cmp_uids; - folder_class->sort_uids = maildir_sort_uids; - folder_class->transfer_messages_to = maildir_transfer_messages_to; - - local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class); - local_folder_class->create_summary = maildir_create_summary; -} - -static void -camel_maildir_folder_init (CamelMaildirFolder *maildir_folder) -{ -} - -CamelFolder * -camel_maildir_folder_new (CamelStore *parent_store, - const gchar *full_name, - guint32 flags, - GError **error) -{ - CamelFolder *folder; - gchar *basename; - - d(printf("Creating maildir folder: %s\n", full_name)); - - if (g_strcmp0 (full_name, ".") == 0) - basename = g_strdup (_("Inbox")); - else - basename = g_path_get_basename (full_name); - - folder = g_object_new ( - CAMEL_TYPE_MAILDIR_FOLDER, - "name", basename, "full-name", full_name, - "parent-store", parent_store, NULL); - - if (parent_store->flags & CAMEL_STORE_FILTER_INBOX - && strcmp(full_name, ".") == 0) - folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT; - - folder = (CamelFolder *) camel_local_folder_construct ( - CAMEL_LOCAL_FOLDER (folder), flags, error); - - g_free (basename); - - return folder; -} - -static CamelLocalSummary * -maildir_create_summary (CamelLocalFolder *lf, - const gchar *path, - const gchar *folder, - CamelIndex *index) -{ - return (CamelLocalSummary *) camel_maildir_summary_new ( - CAMEL_FOLDER (lf), path, folder, index); -} - static gboolean -maildir_append_message (CamelFolder *folder, - CamelMimeMessage *message, - const CamelMessageInfo *info, - gchar **appended_uid, - GError **error) +maildir_folder_append_message (CamelFolder *folder, + CamelMimeMessage *message, + const CamelMessageInfo *info, + gchar **appended_uid, + GCancellable *cancellable, + GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelStream *output_stream; @@ -160,8 +86,8 @@ maildir_append_message (CamelFolder *folder, goto fail_write; if (camel_data_wrapper_write_to_stream ( - (CamelDataWrapper *)message, output_stream, error) == -1 - || camel_stream_close (output_stream, error) == -1) + (CamelDataWrapper *)message, output_stream, cancellable, error) == -1 + || camel_stream_close (output_stream, cancellable, error) == -1) goto fail_write; /* now move from tmp to cur (bypass new, does it matter?) */ @@ -216,38 +142,11 @@ maildir_append_message (CamelFolder *folder, return success; } -static gchar * -maildir_get_filename (CamelFolder *folder, - const gchar *uid, - GError **error) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - CamelMaildirMessageInfo *mdi; - CamelMessageInfo *info; - gchar *res; - - /* get the message summary info */ - if ((info = camel_folder_summary_uid (folder->summary, uid)) == NULL) { - set_cannot_get_message_ex ( - error, CAMEL_FOLDER_ERROR_INVALID_UID, - uid, lf->folder_path, _("No such message")); - return NULL; - } - - mdi = (CamelMaildirMessageInfo *)info; - - /* what do we do if the message flags (and :info data) changes? filename mismatch - need to recheck I guess */ - res = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); - - camel_message_info_free (info); - - return res; -} - static CamelMimeMessage * -maildir_get_message (CamelFolder *folder, - const gchar *uid, - GError **error) +maildir_folder_get_message (CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelStream *message_stream = NULL; @@ -286,7 +185,7 @@ maildir_get_message (CamelFolder *folder, } message = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream, error) == -1) { + if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream, cancellable, error) == -1) { g_prefix_error ( error, _("Cannot get message %s from folder %s: "), uid, lf->folder_path); @@ -309,9 +208,9 @@ maildir_get_message (CamelFolder *folder, } static gint -maildir_cmp_uids (CamelFolder *folder, - const gchar *uid1, - const gchar *uid2) +maildir_folder_cmp_uids (CamelFolder *folder, + const gchar *uid1, + const gchar *uid2) { CamelMessageInfo *a, *b; time_t tma, tmb; @@ -335,8 +234,8 @@ maildir_cmp_uids (CamelFolder *folder, } static void -maildir_sort_uids (CamelFolder *folder, - GPtrArray *uids) +maildir_folder_sort_uids (CamelFolder *folder, + GPtrArray *uids) { g_return_if_fail (camel_maildir_folder_parent_class != NULL); g_return_if_fail (folder != NULL); @@ -349,12 +248,13 @@ maildir_sort_uids (CamelFolder *folder, } static gboolean -maildir_transfer_messages_to (CamelFolder *source, - GPtrArray *uids, - CamelFolder *dest, - GPtrArray **transferred_uids, - gboolean delete_originals, - GError **error) +maildir_folder_transfer_messages_to (CamelFolder *source, + GPtrArray *uids, + CamelFolder *dest, + GPtrArray **transferred_uids, + gboolean delete_originals, + GCancellable *cancellable, + GError **error) { gboolean fallback = FALSE; @@ -363,7 +263,7 @@ maildir_transfer_messages_to (CamelFolder *source, CamelLocalFolder *lf = (CamelLocalFolder *) source; CamelLocalFolder *df = (CamelLocalFolder *) dest; - camel_operation_start(NULL, _("Moving messages")); + camel_operation_start (cancellable, _("Moving messages")); camel_folder_freeze (dest); camel_folder_freeze (source); @@ -402,7 +302,9 @@ maildir_transfer_messages_to (CamelFolder *source, break; } } else { - camel_folder_set_message_flags (source, uid, CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, ~0); + camel_folder_set_message_flags ( + source, uid, CAMEL_MESSAGE_DELETED | + CAMEL_MESSAGE_SEEN, ~0); camel_folder_summary_remove (source->summary, info); } @@ -414,7 +316,7 @@ maildir_transfer_messages_to (CamelFolder *source, camel_folder_thaw (source); camel_folder_thaw (dest); - camel_operation_end (NULL); + camel_operation_end (cancellable); } else fallback = TRUE; @@ -425,8 +327,104 @@ maildir_transfer_messages_to (CamelFolder *source, folder_class = CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class); return folder_class->transfer_messages_to ( source, uids, dest, transferred_uids, - delete_originals, error); + delete_originals, cancellable, error); } return TRUE; } + +static gchar * +maildir_folder_get_filename (CamelFolder *folder, + const gchar *uid, + GError **error) +{ + CamelLocalFolder *lf = (CamelLocalFolder *)folder; + CamelMaildirMessageInfo *mdi; + CamelMessageInfo *info; + gchar *res; + + /* get the message summary info */ + if ((info = camel_folder_summary_uid (folder->summary, uid)) == NULL) { + set_cannot_get_message_ex ( + error, CAMEL_FOLDER_ERROR_INVALID_UID, + uid, lf->folder_path, _("No such message")); + return NULL; + } + + mdi = (CamelMaildirMessageInfo *)info; + + /* what do we do if the message flags (and :info data) changes? filename mismatch - need to recheck I guess */ + res = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); + + camel_message_info_free (info); + + return res; +} + +static CamelLocalSummary * +maildir_folder_create_summary (CamelLocalFolder *lf, + const gchar *path, + const gchar *folder, + CamelIndex *index) +{ + return (CamelLocalSummary *) camel_maildir_summary_new ( + CAMEL_FOLDER (lf), path, folder, index); +} + +static void +camel_maildir_folder_class_init (CamelMaildirFolderClass *class) +{ + CamelFolderClass *folder_class; + CamelLocalFolderClass *local_folder_class; + + folder_class = CAMEL_FOLDER_CLASS (class); + folder_class->append_message = maildir_folder_append_message; + folder_class->get_message = maildir_folder_get_message; + folder_class->cmp_uids = maildir_folder_cmp_uids; + folder_class->sort_uids = maildir_folder_sort_uids; + folder_class->transfer_messages_to = maildir_folder_transfer_messages_to; + folder_class->get_filename = maildir_folder_get_filename; + + local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class); + local_folder_class->create_summary = maildir_folder_create_summary; +} + +static void +camel_maildir_folder_init (CamelMaildirFolder *maildir_folder) +{ +} + +CamelFolder * +camel_maildir_folder_new (CamelStore *parent_store, + const gchar *full_name, + guint32 flags, + GCancellable *cancellable, + GError **error) +{ + CamelFolder *folder; + gchar *basename; + + d(printf("Creating maildir folder: %s\n", full_name)); + + if (g_strcmp0 (full_name, ".") == 0) + basename = g_strdup (_("Inbox")); + else + basename = g_path_get_basename (full_name); + + folder = g_object_new ( + CAMEL_TYPE_MAILDIR_FOLDER, + "name", basename, "full-name", full_name, + "parent-store", parent_store, NULL); + + if (parent_store->flags & CAMEL_STORE_FILTER_INBOX + && strcmp(full_name, ".") == 0) + folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT; + + folder = (CamelFolder *) camel_local_folder_construct ( + CAMEL_LOCAL_FOLDER (folder), flags, cancellable, error); + + g_free (basename); + + return folder; +} + diff --git a/camel/providers/local/camel-maildir-folder.h b/camel/providers/local/camel-maildir-folder.h index 5f2915b..169537e 100644 --- a/camel/providers/local/camel-maildir-folder.h +++ b/camel/providers/local/camel-maildir-folder.h @@ -57,10 +57,12 @@ struct _CamelMaildirFolderClass { CamelLocalFolderClass parent_class; }; -/* public methods */ -CamelFolder *camel_maildir_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error); - -GType camel_maildir_folder_get_type (void); +GType camel_maildir_folder_get_type (void); +CamelFolder * camel_maildir_folder_new (CamelStore *parent_store, + const gchar *full_name, + guint32 flags, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/local/camel-maildir-store.c b/camel/providers/local/camel-maildir-store.c index be8473e..0ced756 100644 --- a/camel/providers/local/camel-maildir-store.c +++ b/camel/providers/local/camel-maildir-store.c @@ -39,12 +39,12 @@ #define d(x) -static CamelFolder *get_folder (CamelStore * store, const gchar *folder_name, guint32 flags, GError **error); -static CamelFolder *get_inbox (CamelStore *store, GError **error); -static gboolean delete_folder (CamelStore * store, const gchar *folder_name, GError **error); -static gboolean maildir_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error); +static CamelFolder *get_folder (CamelStore * store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error); +static CamelFolder *get_inbox (CamelStore *store, GCancellable *cancellable, GError **error); +static gboolean delete_folder (CamelStore * store, const gchar *folder_name, GCancellable *cancellable, GError **error); +static gboolean maildir_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GCancellable *cancellable, GError **error); -static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error); +static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error); static gboolean maildir_compare_folder_name (gconstpointer a, gconstpointer b); static guint maildir_hash_folder_name (gconstpointer a); @@ -103,6 +103,7 @@ static CamelFolder * get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, + GCancellable *cancellable, GError **error) { CamelStoreClass *store_class; @@ -114,7 +115,7 @@ get_folder (CamelStore *store, /* Chain up to parent's get_folder() method. */ store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class); - if (!store_class->get_folder (store, folder_name, flags, error)) + if (!store_class->get_folder (store, folder_name, flags, cancellable, error)) return NULL; name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); @@ -141,7 +142,7 @@ get_folder (CamelStore *store, goto fail; } } - folder = camel_maildir_folder_new (store, folder_name, flags, error); + folder = camel_maildir_folder_new (store, folder_name, flags, cancellable, error); } else if (g_stat (name, &st) == -1) { /* folder doesn't exist, see if we should create it */ if (errno != ENOENT) { @@ -171,7 +172,7 @@ get_folder (CamelStore *store, rmdir (new); rmdir (name); } else { - folder = camel_maildir_folder_new (store, folder_name, flags, error); + folder = camel_maildir_folder_new (store, folder_name, flags, cancellable, error); } } } else if (!S_ISDIR (st.st_mode) @@ -189,7 +190,7 @@ get_folder (CamelStore *store, _("Cannot create folder '%s': folder exists."), folder_name); } else { - folder = camel_maildir_folder_new (store, folder_name, flags, error); + folder = camel_maildir_folder_new (store, folder_name, flags, cancellable, error); } fail: g_free (name); @@ -202,15 +203,17 @@ fail: static CamelFolder * get_inbox (CamelStore *store, + GCancellable *cancellable, GError **error) { return camel_store_get_folder ( - store, ".", CAMEL_STORE_FOLDER_CREATE, error); + store, ".", CAMEL_STORE_FOLDER_CREATE, cancellable, error); } static gboolean delete_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { gchar *name, *tmp, *cur, *new; @@ -287,7 +290,7 @@ delete_folder (CamelStore *store, /* Chain up to parent's delete_folder() method. */ store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class); success = store_class->delete_folder ( - store, folder_name, error); + store, folder_name, cancellable, error); } } @@ -303,6 +306,7 @@ static gboolean maildir_rename_folder (CamelStore *store, const gchar *old, const gchar *new, + GCancellable *cancellable, GError **error) { CamelStoreClass *store_class; @@ -318,13 +322,14 @@ maildir_rename_folder (CamelStore *store, /* Chain up to parent's rename_folder() method. */ store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class); - return store_class->rename_folder (store, old, new, error); + return store_class->rename_folder (store, old, new, cancellable, error); } static void fill_fi (CamelStore *store, CamelFolderInfo *fi, - guint32 flags) + guint32 flags, + GCancellable *cancellable) { CamelFolder *folder; @@ -332,11 +337,11 @@ fill_fi (CamelStore *store, if (folder == NULL && (flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - folder = camel_store_get_folder (store, fi->full_name, 0, NULL); + folder = camel_store_get_folder (store, fi->full_name, 0, cancellable, NULL); if (folder) { if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - camel_folder_refresh_info (folder, NULL); + camel_folder_refresh_info (folder, cancellable, NULL); fi->unread = camel_folder_get_unread_message_count (folder); fi->total = camel_folder_get_message_count (folder); g_object_unref (folder); @@ -397,7 +402,8 @@ scan_fi (CamelStore *store, guint32 flags, CamelURL *url, const gchar *full, - const gchar *name) + const gchar *name, + GCancellable *cancellable) { CamelFolderInfo *fi; gchar *tmp, *cur, *new; @@ -431,7 +437,7 @@ scan_fi (CamelStore *store, g_free (cur); g_free (tmp); - fill_fi (store, fi, flags); + fill_fi (store, fi, flags, cancellable); return fi; } @@ -441,6 +447,7 @@ scan_dirs (CamelStore *store, guint32 flags, CamelFolderInfo *topfi, CamelURL *url, + GCancellable *cancellable, GError **error) { CamelDList queue = CAMEL_DLIST_INITIALISER (queue); @@ -512,7 +519,7 @@ scan_dirs (CamelStore *store, full = g_strdup (d->d_name); else full = g_strdup_printf("%s/%s", sn->fi->full_name, d->d_name); - snew->fi = scan_fi (store, flags, url, full, d->d_name); + snew->fi = scan_fi (store, flags, url, full, d->d_name, cancellable); g_free (full); last->next = snew->fi; @@ -546,6 +553,7 @@ static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { CamelFolderInfo *fi = NULL; @@ -559,8 +567,8 @@ get_folder_info (CamelStore *store, CamelFolderInfo *scan; /* create a dummy "." parent inbox, use to scan, then put back at the top level */ - fi = scan_fi(store, flags, url, ".", _("Inbox")); - if (scan_dirs (store, flags, fi, url, error) == -1) + fi = scan_fi(store, flags, url, ".", _("Inbox"), cancellable); + if (scan_dirs (store, flags, fi, url, cancellable, error) == -1) goto fail; fi->next = fi->child; scan = fi->child; @@ -572,13 +580,13 @@ get_folder_info (CamelStore *store, fi->flags &= ~CAMEL_FOLDER_CHILDREN; fi->flags |= CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_TYPE_INBOX; } else if (!strcmp(top, ".")) { - fi = scan_fi(store, flags, url, ".", _("Inbox")); + fi = scan_fi(store, flags, url, ".", _("Inbox"), cancellable); fi->flags |= CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_TYPE_INBOX; } else { const gchar *name = strrchr (top, '/'); - fi = scan_fi (store, flags, url, top, name?name+1:top); - if (scan_dirs (store, flags, fi, url, error) == -1) + fi = scan_fi (store, flags, url, top, name?name+1:top, cancellable); + if (scan_dirs (store, flags, fi, url, cancellable, error) == -1) goto fail; } diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c index 61b8e4c..dca9bb8 100644 --- a/camel/providers/local/camel-maildir-summary.c +++ b/camel/providers/local/camel-maildir-summary.c @@ -51,8 +51,8 @@ static CamelMessageInfo *message_info_new_from_header (CamelFolderSummary *, str static void message_info_free (CamelFolderSummary *, CamelMessageInfo *mi); static gint maildir_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error); -static gint maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error); -static gint maildir_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); +static gint maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); +static gint maildir_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); static CamelMessageInfo *maildir_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error); static gchar *maildir_summary_next_uid_string (CamelFolderSummary *s); @@ -473,7 +473,10 @@ maildir_summary_load (CamelLocalSummary *cls, } static gint -camel_maildir_summary_add (CamelLocalSummary *cls, const gchar *name, gint forceindex) +camel_maildir_summary_add (CamelLocalSummary *cls, + const gchar *name, + gint forceindex, + GCancellable *cancellable) { CamelMaildirSummary *maildirs = (CamelMaildirSummary *)cls; gchar *filename = g_strdup_printf("%s/cur/%s", cls->folder_path, name); @@ -524,7 +527,10 @@ remove_summary (gchar *key, CamelMessageInfo *info, struct _remove_data *rd) } static gint -maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, GError **error) +maildir_summary_check (CamelLocalSummary *cls, + CamelFolderChangeInfo *changes, + GCancellable *cancellable, + GError **error) { DIR *dir; struct dirent *d; @@ -546,7 +552,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G d(printf("checking summary ...\n")); - camel_operation_start(NULL, _("Checking folder consistency")); + camel_operation_start (cancellable, _("Checking folder consistency")); /* scan the directory, check for mail files not in the index, or index entries that no longer exist */ @@ -559,7 +565,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G cls->folder_path, g_strerror (errno)); g_free (cur); g_free (new); - camel_operation_end (NULL); + camel_operation_end (cancellable); g_mutex_unlock (((CamelMaildirSummary *) cls)->priv->summary_lock); return -1; } @@ -586,7 +592,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G while ((d = readdir (dir))) { gint pc = count * 100 / total; - camel_operation_progress (NULL, pc); + camel_operation_progress (cancellable, pc); count++; /* FIXME: also run stat to check for regular file */ @@ -610,7 +616,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G info = camel_folder_summary_uid ((CamelFolderSummary *)cls, uid); if (info == NULL) { /* must be a message incorporated by another client, this is not a 'recent' uid */ - if (camel_maildir_summary_add (cls, d->d_name, forceindex) == 0) + if (camel_maildir_summary_add (cls, d->d_name, forceindex, cancellable) == 0) if (changes) camel_folder_change_info_add_uid (changes, uid); } else { @@ -618,7 +624,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G if (cls->index && (!camel_index_has_name (cls->index, uid))) { /* message_info_new will handle duplicates */ - camel_maildir_summary_add (cls, d->d_name, forceindex); + camel_maildir_summary_add (cls, d->d_name, forceindex, cancellable); } mdi = (CamelMaildirMessageInfo *)info; @@ -636,9 +642,9 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G g_hash_table_foreach (left, (GHFunc)remove_summary, &rd); g_hash_table_destroy (left); - camel_operation_end (NULL); + camel_operation_end (cancellable); - camel_operation_start(NULL, _("Checking for new messages")); + camel_operation_start (cancellable, _("Checking for new messages")); /* now, scan new for new messages, and copy them to cur, and so forth */ dir = opendir (new); @@ -654,7 +660,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G gchar *src, *dest; gint pc = count * 100 / total; - camel_operation_progress (NULL, pc); + camel_operation_progress (cancellable, pc); count++; name = d->d_name; @@ -682,7 +688,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G /* FIXME: This should probably use link/unlink */ if (g_rename (src, dest) == 0) { - camel_maildir_summary_add (cls, destfilename, forceindex); + camel_maildir_summary_add (cls, destfilename, forceindex, cancellable); if (changes) { camel_folder_change_info_add_uid (changes, destname); camel_folder_change_info_recent_uid (changes, destname); @@ -698,7 +704,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G g_free (src); g_free (dest); } - camel_operation_end (NULL); + camel_operation_end (cancellable); closedir (dir); } @@ -715,6 +721,7 @@ static gint maildir_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changes, + GCancellable *cancellable, GError **error) { CamelLocalSummaryClass *local_summary_class; @@ -726,15 +733,15 @@ maildir_summary_sync (CamelLocalSummary *cls, d(printf("summary_sync(expunge=%s)\n", expunge?"true":"false")); - if (camel_local_summary_check (cls, changes, error) == -1) + if (camel_local_summary_check (cls, changes, cancellable, error) == -1) return -1; - camel_operation_start(NULL, _("Storing folder")); + camel_operation_start (cancellable, _("Storing folder")); camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *)cls, error); count = camel_folder_summary_count ((CamelFolderSummary *)cls); for (i=count-1;i>=0;i--) { - camel_operation_progress (NULL, (count-i)*100/count); + camel_operation_progress (cancellable, (count-i)*100/count); info = camel_folder_summary_index ((CamelFolderSummary *)cls, i); mdi = (CamelMaildirMessageInfo *)info; @@ -785,10 +792,10 @@ maildir_summary_sync (CamelLocalSummary *cls, camel_message_info_free (info); } - camel_operation_end (NULL); + camel_operation_end (cancellable); /* Chain up to parent's sync() method. */ local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (camel_maildir_summary_parent_class); - return local_summary_class->sync (cls, expunge, changes, error); + return local_summary_class->sync (cls, expunge, changes, cancellable, error); } diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c index 0db0e54..774ab7e 100644 --- a/camel/providers/local/camel-mbox-folder.c +++ b/camel/providers/local/camel-mbox-folder.c @@ -46,113 +46,15 @@ #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ -static gint mbox_lock (CamelLocalFolder *lf, CamelLockType type, GError **error); -static void mbox_unlock (CamelLocalFolder *lf); - -static gboolean mbox_append_message (CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, gchar **appended_uid, GError **error); -static CamelMimeMessage *mbox_get_message (CamelFolder *folder, const gchar * uid, GError **error); -static CamelLocalSummary *mbox_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index); -static gchar * mbox_get_filename (CamelFolder *folder, const gchar *uid, GError **error); -static gint mbox_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2); -static void mbox_sort_uids (CamelFolder *folder, GPtrArray *uids); - G_DEFINE_TYPE (CamelMboxFolder, camel_mbox_folder, CAMEL_TYPE_LOCAL_FOLDER) -static void -camel_mbox_folder_class_init (CamelMboxFolderClass *class) -{ - CamelFolderClass *folder_class; - CamelLocalFolderClass *local_folder_class; - - folder_class = CAMEL_FOLDER_CLASS (class); - folder_class->append_message = mbox_append_message; - folder_class->get_message = mbox_get_message; - folder_class->get_filename = mbox_get_filename; - folder_class->cmp_uids = mbox_cmp_uids; - folder_class->sort_uids = mbox_sort_uids; - - local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class); - local_folder_class->create_summary = mbox_create_summary; - local_folder_class->lock = mbox_lock; - local_folder_class->unlock = mbox_unlock; -} - -static void -camel_mbox_folder_init (CamelMboxFolder *mbox_folder) -{ - mbox_folder->lockfd = -1; -} - -CamelFolder * -camel_mbox_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error) -{ - CamelFolder *folder; - gchar *basename; - - basename = g_path_get_basename (full_name); - - folder = g_object_new ( - CAMEL_TYPE_MBOX_FOLDER, - "name", basename, "full-name", full_name, - "parent-store", parent_store, NULL); - folder = (CamelFolder *)camel_local_folder_construct ( - (CamelLocalFolder *)folder, flags, error); - - g_free (basename); - - return folder; -} - -static CamelLocalSummary *mbox_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index) -{ - return (CamelLocalSummary *)camel_mbox_summary_new ((CamelFolder *)lf, path, folder, index); -} - -static gint mbox_lock (CamelLocalFolder *lf, CamelLockType type, GError **error) -{ -#ifndef G_OS_WIN32 - CamelMboxFolder *mf = (CamelMboxFolder *)lf; - - /* make sure we have matching unlocks for locks, camel-local-folder class should enforce this */ - g_assert (mf->lockfd == -1); - - mf->lockfd = open (lf->folder_path, O_RDWR|O_LARGEFILE, 0); - if (mf->lockfd == -1) { - g_set_error ( - error, G_IO_ERROR, - g_io_error_from_errno (errno), - _("Cannot create folder lock on %s: %s"), - lf->folder_path, g_strerror (errno)); - return -1; - } - - if (camel_lock_folder (lf->folder_path, mf->lockfd, type, error) == -1) { - close (mf->lockfd); - mf->lockfd = -1; - return -1; - } -#endif - return 0; -} - -static void mbox_unlock (CamelLocalFolder *lf) -{ -#ifndef G_OS_WIN32 - CamelMboxFolder *mf = (CamelMboxFolder *)lf; - - g_assert (mf->lockfd != -1); - camel_unlock_folder (lf->folder_path, mf->lockfd); - close (mf->lockfd); - mf->lockfd = -1; -#endif -} - static gboolean -mbox_append_message (CamelFolder *folder, - CamelMimeMessage *message, - const CamelMessageInfo *info, - gchar **appended_uid, - GError **error) +mbox_folder_append_message (CamelFolder *folder, + CamelMimeMessage *message, + const CamelMessageInfo *info, + gchar **appended_uid, + GCancellable *cancellable, + GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelStream *output_stream = NULL, *filter_stream = NULL; @@ -172,7 +74,7 @@ mbox_append_message (CamelFolder *folder, d(printf("Appending message\n")); /* first, check the summary is correct (updates folder_size too) */ - retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error); + retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error); if (retval == -1) goto fail; @@ -210,7 +112,7 @@ mbox_append_message (CamelFolder *folder, /* we must write this to the non-filtered stream ... */ fromline = camel_mime_message_build_mbox_from (message); - if (camel_stream_write (output_stream, fromline, strlen (fromline), error) == -1) + if (camel_stream_write (output_stream, fromline, strlen (fromline), cancellable, error) == -1) goto fail_write; /* and write the content to the filtering stream, that translates '\nFrom' into '\n>From' */ @@ -220,9 +122,9 @@ mbox_append_message (CamelFolder *folder, g_object_unref (filter_from); if (camel_data_wrapper_write_to_stream ( - (CamelDataWrapper *) message, filter_stream, error) == -1 || - camel_stream_write (filter_stream, "\n", 1, error) == -1 || - camel_stream_flush (filter_stream, error) == -1) + (CamelDataWrapper *) message, filter_stream, cancellable, error) == -1 || + camel_stream_write (filter_stream, "\n", 1, cancellable, error) == -1 || + camel_stream_flush (filter_stream, cancellable, error) == -1) goto fail_write; /* filter stream ref's the output stream itself, so we need to unref it too */ @@ -300,55 +202,11 @@ fail: return FALSE; } -static gchar * -mbox_get_filename (CamelFolder *folder, const gchar *uid, GError **error) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - CamelMboxMessageInfo *info; - goffset frompos; - gchar *filename = NULL; - - d(printf("Getting message %s\n", uid)); - - /* lock the folder first, burn if we can't, need write lock for summary check */ - if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) - return NULL; - - /* check for new messages always */ - if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error) == -1) { - camel_local_folder_unlock (lf); - return NULL; - } - - /* get the message summary info */ - info = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid); - - if (info == NULL) { - set_cannot_get_message_ex ( - error, CAMEL_FOLDER_ERROR_INVALID_UID, - uid, lf->folder_path, _("No such message")); - goto fail; - } - - if (info->frompos == -1) { - camel_message_info_free ((CamelMessageInfo *)info); - goto fail; - } - - frompos = info->frompos; - camel_message_info_free ((CamelMessageInfo *)info); - - filename = g_strdup_printf ("%s%s!%" PRId64, lf->folder_path, G_DIR_SEPARATOR_S, (gint64) frompos); - -fail: - /* and unlock now we're finished with it */ - camel_local_folder_unlock (lf); - - return filename; -} - static CamelMimeMessage * -mbox_get_message (CamelFolder *folder, const gchar * uid, GError **error) +mbox_folder_get_message (CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelMimeMessage *message = NULL; @@ -365,7 +223,7 @@ mbox_get_message (CamelFolder *folder, const gchar * uid, GError **error) return NULL; /* check for new messages always */ - if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error) == -1) { + if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error) == -1) { camel_local_folder_unlock (lf); return NULL; } @@ -422,7 +280,7 @@ retry: if (!retried) { retried = TRUE; camel_local_summary_check_force ((CamelLocalSummary *)folder->summary); - retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error); + retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error); if (retval != -1) goto retry; } @@ -435,7 +293,7 @@ retry: } message = camel_mime_message_new (); - if (camel_mime_part_construct_from_parser ((CamelMimePart *)message, parser, error) == -1) { + if (camel_mime_part_construct_from_parser ((CamelMimePart *)message, parser, cancellable, error) == -1) { g_prefix_error ( error, _("Cannot get message %s from folder %s: "), uid, lf->folder_path); @@ -463,7 +321,9 @@ fail: } static gint -mbox_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2) +mbox_folder_cmp_uids (CamelFolder *folder, + const gchar *uid1, + const gchar *uid2) { CamelMboxMessageInfo *a, *b; gint res; @@ -486,7 +346,8 @@ mbox_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2) } static void -mbox_sort_uids (CamelFolder *folder, GPtrArray *uids) +mbox_folder_sort_uids (CamelFolder *folder, + GPtrArray *uids) { g_return_if_fail (camel_mbox_folder_parent_class != NULL); g_return_if_fail (folder != NULL); @@ -496,3 +357,154 @@ mbox_sort_uids (CamelFolder *folder, GPtrArray *uids) CAMEL_FOLDER_CLASS (camel_mbox_folder_parent_class)->sort_uids (folder, uids); } + +static gchar * +mbox_folder_get_filename (CamelFolder *folder, + const gchar *uid, + GError **error) +{ + CamelLocalFolder *lf = (CamelLocalFolder *)folder; + CamelMboxMessageInfo *info; + goffset frompos; + gchar *filename = NULL; + + d(printf("Getting message %s\n", uid)); + + /* lock the folder first, burn if we can't, need write lock for summary check */ + if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) + return NULL; + + /* check for new messages always */ + if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, NULL, error) == -1) { + camel_local_folder_unlock (lf); + return NULL; + } + + /* get the message summary info */ + info = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid); + + if (info == NULL) { + set_cannot_get_message_ex ( + error, CAMEL_FOLDER_ERROR_INVALID_UID, + uid, lf->folder_path, _("No such message")); + goto fail; + } + + if (info->frompos == -1) { + camel_message_info_free ((CamelMessageInfo *)info); + goto fail; + } + + frompos = info->frompos; + camel_message_info_free ((CamelMessageInfo *)info); + + filename = g_strdup_printf ("%s%s!%" PRId64, lf->folder_path, G_DIR_SEPARATOR_S, (gint64) frompos); + +fail: + /* and unlock now we're finished with it */ + camel_local_folder_unlock (lf); + + return filename; +} + +static CamelLocalSummary * +mbox_folder_create_summary (CamelLocalFolder *lf, + const gchar *path, + const gchar *folder, + CamelIndex *index) +{ + return (CamelLocalSummary *)camel_mbox_summary_new ((CamelFolder *)lf, path, folder, index); +} + +static gint +mbox_folder_lock (CamelLocalFolder *lf, + CamelLockType type, + GError **error) +{ +#ifndef G_OS_WIN32 + CamelMboxFolder *mf = (CamelMboxFolder *)lf; + + /* make sure we have matching unlocks for locks, camel-local-folder class should enforce this */ + g_assert (mf->lockfd == -1); + + mf->lockfd = open (lf->folder_path, O_RDWR|O_LARGEFILE, 0); + if (mf->lockfd == -1) { + g_set_error ( + error, G_IO_ERROR, + g_io_error_from_errno (errno), + _("Cannot create folder lock on %s: %s"), + lf->folder_path, g_strerror (errno)); + return -1; + } + + if (camel_lock_folder (lf->folder_path, mf->lockfd, type, error) == -1) { + close (mf->lockfd); + mf->lockfd = -1; + return -1; + } +#endif + return 0; +} + +static void +mbox_folder_unlock (CamelLocalFolder *lf) +{ +#ifndef G_OS_WIN32 + CamelMboxFolder *mf = (CamelMboxFolder *)lf; + + g_assert (mf->lockfd != -1); + camel_unlock_folder (lf->folder_path, mf->lockfd); + close (mf->lockfd); + mf->lockfd = -1; +#endif +} + +static void +camel_mbox_folder_class_init (CamelMboxFolderClass *class) +{ + CamelFolderClass *folder_class; + CamelLocalFolderClass *local_folder_class; + + folder_class = CAMEL_FOLDER_CLASS (class); + folder_class->append_message = mbox_folder_append_message; + folder_class->get_message = mbox_folder_get_message; + folder_class->cmp_uids = mbox_folder_cmp_uids; + folder_class->sort_uids = mbox_folder_sort_uids; + folder_class->get_filename = mbox_folder_get_filename; + + local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class); + local_folder_class->create_summary = mbox_folder_create_summary; + local_folder_class->lock = mbox_folder_lock; + local_folder_class->unlock = mbox_folder_unlock; +} + +static void +camel_mbox_folder_init (CamelMboxFolder *mbox_folder) +{ + mbox_folder->lockfd = -1; +} + +CamelFolder * +camel_mbox_folder_new (CamelStore *parent_store, + const gchar *full_name, + guint32 flags, + GCancellable *cancellable, + GError **error) +{ + CamelFolder *folder; + gchar *basename; + + basename = g_path_get_basename (full_name); + + folder = g_object_new ( + CAMEL_TYPE_MBOX_FOLDER, + "name", basename, "full-name", full_name, + "parent-store", parent_store, NULL); + folder = (CamelFolder *)camel_local_folder_construct ( + (CamelLocalFolder *)folder, flags, cancellable, error); + + g_free (basename); + + return folder; +} + diff --git a/camel/providers/local/camel-mbox-folder.h b/camel/providers/local/camel-mbox-folder.h index b3379bb..90500b5 100644 --- a/camel/providers/local/camel-mbox-folder.h +++ b/camel/providers/local/camel-mbox-folder.h @@ -59,11 +59,12 @@ struct _CamelMboxFolderClass { CamelLocalFolderClass parent_class; }; -/* public methods */ -/* flags are taken from CAMEL_STORE_FOLDER_* flags */ -CamelFolder *camel_mbox_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error); - -GType camel_mbox_folder_get_type (void); +GType camel_mbox_folder_get_type (void); +CamelFolder * camel_mbox_folder_new (CamelStore *parent_store, + const gchar *full_name, + guint32 flags, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/local/camel-mbox-store.c b/camel/providers/local/camel-mbox-store.c index 22f3247..9830155 100644 --- a/camel/providers/local/camel-mbox-store.c +++ b/camel/providers/local/camel-mbox-store.c @@ -38,11 +38,11 @@ #define d(x) -static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error); -static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error); -static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error); -static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error); -static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error); +static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error); +static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error); +static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GCancellable *cancellable, GError **error); +static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GCancellable *cancellable, GError **error); +static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error); static gchar *mbox_get_meta_path (CamelLocalStore *ls, const gchar *full_name, const gchar *ext); static gchar *mbox_get_full_path (CamelLocalStore *ls, const gchar *full_name); @@ -102,6 +102,7 @@ static CamelFolder * get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, + GCancellable *cancellable, GError **error) { CamelStoreClass *store_class; @@ -110,7 +111,7 @@ get_folder (CamelStore *store, /* Chain up to parent's get_folder() method. */ store_class = CAMEL_STORE_CLASS (camel_mbox_store_parent_class); - if (!store_class->get_folder (store, folder_name, flags, error)) + if (!store_class->get_folder (store, folder_name, flags, cancellable, error)) return NULL; name = camel_local_store_get_full_path (store, folder_name); @@ -197,11 +198,14 @@ get_folder (CamelStore *store, } else g_free (name); - return camel_mbox_folder_new (store, folder_name, flags, error); + return camel_mbox_folder_new (store, folder_name, flags, cancellable, error); } static gboolean -delete_folder (CamelStore *store, const gchar *folder_name, GError **error) +delete_folder (CamelStore *store, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelFolderInfo *fi; CamelFolder *lf; @@ -311,7 +315,7 @@ delete_folder (CamelStore *store, const gchar *folder_name, GError **error) g_free (path); path = NULL; - if ((lf = camel_store_get_folder (store, folder_name, 0, NULL))) { + if ((lf = camel_store_get_folder (store, folder_name, 0, cancellable, NULL))) { CamelObject *object = CAMEL_OBJECT (lf); const gchar *state_filename; @@ -354,7 +358,11 @@ delete_folder (CamelStore *store, const gchar *folder_name, GError **error) } static CamelFolderInfo * -create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error) +create_folder (CamelStore *store, + const gchar *parent_name, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { /* FIXME: this is almost an exact copy of CamelLocalStore::create_folder() except that we use * different path schemes... need to find a way to share parent's code? */ @@ -421,11 +429,11 @@ create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_ g_free (path); folder = CAMEL_STORE_GET_CLASS (store)->get_folder ( - store, name, CAMEL_STORE_FOLDER_CREATE, error); + store, name, CAMEL_STORE_FOLDER_CREATE, cancellable, error); if (folder) { g_object_unref (folder); info = CAMEL_STORE_GET_CLASS (store)->get_folder_info ( - store, name, 0, error); + store, name, 0, cancellable, error); } g_free (name); @@ -495,7 +503,11 @@ xrename (CamelStore *store, const gchar *old_name, const gchar *new_name, const } static gboolean -rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error) +rename_folder (CamelStore *store, + const gchar *old, + const gchar *new, + GCancellable *cancellable, + GError **error) { CamelLocalFolder *folder = NULL; gchar *oldibex, *newibex, *newdir; @@ -644,7 +656,9 @@ inode_free (gpointer k, gpointer v, gpointer d) /* NB: duplicated in maildir store */ static void -fill_fi (CamelStore *store, CamelFolderInfo *fi, guint32 flags) +fill_fi (CamelStore *store, + CamelFolderInfo *fi, + guint32 flags) { CamelFolder *folder; @@ -653,7 +667,7 @@ fill_fi (CamelStore *store, CamelFolderInfo *fi, guint32 flags) folder = camel_object_bag_get (store->folders, fi->full_name); if (folder) { if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - camel_folder_refresh_info (folder, NULL); + camel_folder_refresh_info (folder, NULL, NULL); fi->unread = camel_folder_get_unread_message_count (folder); fi->total = camel_folder_get_message_count (folder); g_object_unref (folder); @@ -798,7 +812,11 @@ scan_dir (CamelStore *store, CamelURL *url, GHashTable *visited, CamelFolderInfo } static CamelFolderInfo * -get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error) +get_folder_info (CamelStore *store, + const gchar *top, + guint32 flags, + GCancellable *cancellable, + GError **error) { GHashTable *visited; #ifndef G_OS_WIN32 diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c index c0e3f38..86d0562 100644 --- a/camel/providers/local/camel-mbox-summary.c +++ b/camel/providers/local/camel-mbox-summary.c @@ -61,14 +61,14 @@ static CamelMessageInfo * message_info_migrate (CamelFolderSummary *, FILE *); static gchar *mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi); -static gint mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error); -static gint mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); +static gint mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); +static gint mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); #ifdef STATUS_PINE static CamelMessageInfo *mbox_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, GError **error); #endif -static gint mbox_summary_sync_quick (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); -static gint mbox_summary_sync_full (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); +static gint mbox_summary_sync_quick (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); +static gint mbox_summary_sync_full (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); #ifdef STATUS_PINE /* Which status flags are stored in each separate header */ @@ -107,7 +107,9 @@ mbox_info_set_user_tag (CamelMessageInfo *mi, const gchar *name, const gchar *va #ifdef STATUS_PINE static gboolean -mbox_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set) +mbox_info_set_flags (CamelMessageInfo *mi, + guint32 flags, + guint32 set) { /* Basically, if anything could change the Status line, presume it does */ if (((CamelMboxSummary *)mi->summary)->xstatus @@ -116,7 +118,8 @@ mbox_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set) set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED; } - return CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->info_set_flags (mi, flags, set); + return CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)-> + info_set_flags (mi, flags, set); } #endif @@ -443,7 +446,11 @@ message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info) /* like summary_rebuild, but also do changeinfo stuff (if supplied) */ static gint -summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *changeinfo, GError **error) +summary_update (CamelLocalSummary *cls, + goffset offset, + CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, + GError **error) { gint i, count; CamelFolderSummary *s = (CamelFolderSummary *)cls; @@ -462,7 +469,7 @@ summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *c cls->index_force = FALSE; - camel_operation_start(NULL, _("Storing folder")); + camel_operation_start (cancellable, _("Storing folder")); fd = g_open (cls->folder_path, O_LARGEFILE | O_RDONLY | O_BINARY, 0); if (fd == -1) { @@ -472,7 +479,7 @@ summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *c g_io_error_from_errno (errno), _("Could not open folder: %s: %s"), cls->folder_path, g_strerror (errno)); - camel_operation_end (NULL); + camel_operation_end (cancellable); return -1; } @@ -515,7 +522,8 @@ summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *c CamelMessageInfo *info; goffset pc = camel_mime_parser_tell_start_from (mp) + 1; - camel_operation_progress (NULL, (gint) (((gfloat) pc / size) * 100)); + camel_operation_progress ( + cancellable, (gint) (((gfloat) pc / size) * 100)); info = camel_folder_summary_add_from_parser (s, mp); if (info == NULL) { @@ -590,13 +598,16 @@ summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *c } } - camel_operation_end (NULL); + camel_operation_end (cancellable); return ok; } static gint -mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, GError **error) +mbox_summary_check (CamelLocalSummary *cls, + CamelFolderChangeInfo *changes, + GCancellable *cancellable, + GError **error) { CamelMboxSummary *mbs = (CamelMboxSummary *)cls; CamelFolderSummary *s = (CamelFolderSummary *)cls; @@ -642,10 +653,10 @@ mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, GErr if (mbs->folder_size < st.st_size) { /* this will automatically rescan from 0 if there is a problem */ d(printf("folder grew, attempting to rebuild from %d\n", mbs->folder_size)); - ret = summary_update (cls, mbs->folder_size, changes, error); + ret = summary_update (cls, mbs->folder_size, changes, cancellable, error); } else { d(printf("folder shrank! rebuilding from start\n")); - ret = summary_update (cls, 0, changes, error); + ret = summary_update (cls, 0, changes, cancellable, error); } } else { d(printf("Folder unchanged, do nothing\n")); @@ -667,7 +678,11 @@ mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, GErr /* perform a full sync */ static gint -mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error) +mbox_summary_sync_full (CamelMboxSummary *mbs, + gboolean expunge, + CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, + GError **error) { CamelLocalSummary *cls = (CamelLocalSummary *)mbs; gint fd = -1, fdout = -1; @@ -676,7 +691,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan d(printf("performing full summary/sync\n")); - camel_operation_start(NULL, _("Storing folder")); + camel_operation_start (cancellable, _("Storing folder")); fd = g_open (cls->folder_path, O_LARGEFILE | O_RDONLY | O_BINARY, 0); if (fd == -1) { @@ -685,7 +700,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan g_io_error_from_errno (errno), _("Could not open file: %s: %s"), cls->folder_path, g_strerror (errno)); - camel_operation_end (NULL); + camel_operation_end (cancellable); return -1; } @@ -702,7 +717,9 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan goto error; } - if (camel_mbox_summary_sync_mbox ((CamelMboxSummary *)cls, flags, changeinfo, fd, fdout, error) == -1) + if (camel_mbox_summary_sync_mbox ( + (CamelMboxSummary *)cls, flags, changeinfo, + fd, fdout, cancellable, error) == -1) goto error; d(printf("Closing folders\n")); @@ -746,7 +763,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan } tmpname = NULL; - camel_operation_end (NULL); + camel_operation_end (cancellable); return 0; error: @@ -759,7 +776,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan if (tmpname) g_unlink (tmpname); - camel_operation_end (NULL); + camel_operation_end (cancellable); return -1; } @@ -790,7 +807,11 @@ cms_sort_frompos (gpointer a, gpointer b, gpointer data) /* perform a quick sync - only system flags have changed */ static gint -mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error) +mbox_summary_sync_quick (CamelMboxSummary *mbs, + gboolean expunge, + CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, + GError **error) { CamelLocalSummary *cls = (CamelLocalSummary *)mbs; CamelFolderSummary *s = (CamelFolderSummary *)mbs; @@ -806,7 +827,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha d(printf("Performing quick summary sync\n")); - camel_operation_start(NULL, _("Storing folder")); + camel_operation_start (cancellable, _("Storing folder")); fd = g_open (cls->folder_path, O_LARGEFILE|O_RDWR|O_BINARY, 0); if (fd == -1) { @@ -816,7 +837,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha _("Could not open file: %s: %s"), cls->folder_path, g_strerror (errno)); - camel_operation_end (NULL); + camel_operation_end (cancellable); return -1; } @@ -847,7 +868,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha gint xevoffset; gint pc = (i+1)*100/summary->len; - camel_operation_progress (NULL, pc); + camel_operation_progress (cancellable, pc); info = (CamelMboxMessageInfo *)camel_folder_summary_uid (s, summary->pdata[i]); @@ -939,7 +960,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha g_ptr_array_free (summary, TRUE); g_object_unref (mp); - camel_operation_end (NULL); + camel_operation_end (cancellable); camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK); return 0; @@ -953,14 +974,18 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha if (info) camel_message_info_free ((CamelMessageInfo *)info); - camel_operation_end (NULL); + camel_operation_end (cancellable); camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK); return -1; } static gint -mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error) +mbox_summary_sync (CamelLocalSummary *cls, + gboolean expunge, + CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, + GError **error) { struct stat st; CamelMboxSummary *mbs = (CamelMboxSummary *)cls; @@ -973,7 +998,7 @@ mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn GPtrArray *summary = NULL; /* first, sync ourselves up, just to make sure */ - if (camel_local_summary_check (cls, changeinfo, error) == -1) + if (camel_local_summary_check (cls, changeinfo, cancellable, error) == -1) return -1; full_name = camel_folder_get_full_name (s->folder); @@ -1009,7 +1034,8 @@ mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn ret = -1; if (quick) { if (work) { - ret = CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_quick (mbs, expunge, changeinfo, NULL); + ret = CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_quick ( + mbs, expunge, changeinfo, cancellable, NULL); if (ret == -1) g_warning("failed a quick-sync, trying a full sync"); } else { @@ -1018,7 +1044,8 @@ mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn } if (ret == -1) - ret = CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_full (mbs, expunge, changeinfo, error); + ret = CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_full ( + mbs, expunge, changeinfo, cancellable, error); if (ret == -1) return -1; @@ -1036,11 +1063,17 @@ mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn camel_folder_summary_touch (s); } - return CAMEL_LOCAL_SUMMARY_CLASS (camel_mbox_summary_parent_class)->sync (cls, expunge, changeinfo, error); + return CAMEL_LOCAL_SUMMARY_CLASS (camel_mbox_summary_parent_class)->sync (cls, expunge, changeinfo, cancellable, error); } gint -camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, guint32 flags, CamelFolderChangeInfo *changeinfo, gint fd, gint fdout, GError **error) +camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, + guint32 flags, + CamelFolderChangeInfo *changeinfo, + gint fd, + gint fdout, + GCancellable *cancellable, + GError **error) { CamelMboxSummary *mbs = (CamelMboxSummary *)cls; CamelFolderSummary *s = (CamelFolderSummary *)mbs; @@ -1083,7 +1116,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, guint32 flags, CamelFolderC for (i = 0; i < count; i++) { gint pc = (i + 1) * 100 / count; - camel_operation_progress (NULL, pc); + camel_operation_progress (cancellable, pc); info = (CamelMboxMessageInfo *)camel_folder_summary_index (s, i); @@ -1272,7 +1305,11 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, guint32 flags, CamelFolderC #ifdef STATUS_PINE static CamelMessageInfo * -mbox_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, GError **error) +mbox_summary_add (CamelLocalSummary *cls, + CamelMimeMessage *msg, + const CamelMessageInfo *info, + CamelFolderChangeInfo *ci, + GError **error) { CamelLocalSummaryClass *local_summary_class; CamelMboxMessageInfo *mi; diff --git a/camel/providers/local/camel-mbox-summary.h b/camel/providers/local/camel-mbox-summary.h index 1bf8d1d..b6409fd 100644 --- a/camel/providers/local/camel-mbox-summary.h +++ b/camel/providers/local/camel-mbox-summary.h @@ -75,19 +75,39 @@ struct _CamelMboxSummaryClass { CamelLocalSummaryClass parent_class; /* sync in-place */ - gint (*sync_quick)(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); + gint (*sync_quick) (CamelMboxSummary *cls, + gboolean expunge, + CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, + GError **error); + /* sync requires copy */ - gint (*sync_full)(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); + gint (*sync_full) (CamelMboxSummary *cls, + gboolean expunge, + CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, + GError **error); }; GType camel_mbox_summary_get_type (void); -CamelMboxSummary *camel_mbox_summary_new (struct _CamelFolder *, const gchar *filename, const gchar *mbox_name, CamelIndex *index); +CamelMboxSummary * + camel_mbox_summary_new (CamelFolder *folder, + const gchar *filename, + const gchar *mbox_name, + CamelIndex *index); -/* do we honour/use xstatus headers, etc */ -void camel_mbox_summary_xstatus (CamelMboxSummary *mbs, gint state); +/* do we honor/use xstatus headers, etc */ +void camel_mbox_summary_xstatus (CamelMboxSummary *mbs, + gint state); /* build a new mbox from an existing mbox storing summary information */ -gint camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, guint32 flags, CamelFolderChangeInfo *changeinfo, gint fd, gint fdout, GError **error); +gint camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, + guint32 flags, + CamelFolderChangeInfo *changeinfo, + gint fd, + gint fdout, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c index 3e0752a..7b4cd1c 100644 --- a/camel/providers/local/camel-mh-folder.c +++ b/camel/providers/local/camel-mh-folder.c @@ -40,75 +40,15 @@ #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ -static CamelLocalSummary *mh_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index); - -static gboolean mh_append_message (CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo *info, gchar **appended_uid, GError **error); -static CamelMimeMessage *mh_get_message (CamelFolder *folder, const gchar *uid, GError **error); -static gchar * mh_get_filename (CamelFolder *folder, const gchar *uid, GError **error); - G_DEFINE_TYPE (CamelMhFolder, camel_mh_folder, CAMEL_TYPE_LOCAL_FOLDER) -static void -camel_mh_folder_class_init (CamelMhFolderClass *class) -{ - CamelFolderClass *folder_class; - CamelLocalFolderClass *local_folder_class; - - folder_class = CAMEL_FOLDER_CLASS (class); - folder_class->append_message = mh_append_message; - folder_class->get_message = mh_get_message; - folder_class->get_filename = mh_get_filename; - - local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class); - local_folder_class->create_summary = mh_create_summary; -} - -static void -camel_mh_folder_init (CamelMhFolder *mh_folder) -{ -} - -CamelFolder * -camel_mh_folder_new (CamelStore *parent_store, - const gchar *full_name, - guint32 flags, - GError **error) -{ - CamelFolder *folder; - gchar *basename; - - d(printf("Creating mh folder: %s\n", full_name)); - - basename = g_path_get_basename (full_name); - - folder = g_object_new ( - CAMEL_TYPE_MH_FOLDER, - "name", basename, "full-name", full_name, - "parent-store", parent_store, NULL); - folder = (CamelFolder *) camel_local_folder_construct ( - CAMEL_LOCAL_FOLDER (folder), flags, error); - - g_free (basename); - - return folder; -} - -static CamelLocalSummary * -mh_create_summary (CamelLocalFolder *lf, - const gchar *path, - const gchar *folder, - CamelIndex *index) -{ - return (CamelLocalSummary *) camel_mh_summary_new ( - CAMEL_FOLDER (lf), path, folder, index); -} - static gboolean -mh_append_message (CamelFolder *folder, - CamelMimeMessage *message, - const CamelMessageInfo *info, - gchar **appended_uid, - GError **error) +mh_folder_append_message (CamelFolder *folder, + CamelMimeMessage *message, + const CamelMessageInfo *info, + gchar **appended_uid, + GCancellable *cancellable, + GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelStream *output_stream; @@ -141,8 +81,8 @@ mh_append_message (CamelFolder *folder, goto fail_write; if (camel_data_wrapper_write_to_stream ( - (CamelDataWrapper *)message, output_stream, error) == -1 - || camel_stream_close (output_stream, error) == -1) + (CamelDataWrapper *)message, output_stream, cancellable, error) == -1 + || camel_stream_close (output_stream, cancellable, error) == -1) goto fail_write; /* close this? */ @@ -182,20 +122,11 @@ mh_append_message (CamelFolder *folder, return TRUE; } -static gchar * -mh_get_filename (CamelFolder *folder, - const gchar *uid, - GError **error) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - - return g_strdup_printf("%s/%s", lf->folder_path, uid); -} - static CamelMimeMessage * -mh_get_message (CamelFolder *folder, - const gchar *uid, - GError **error) +mh_folder_get_message (CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelStream *message_stream = NULL; @@ -230,7 +161,7 @@ mh_get_message (CamelFolder *folder, } message = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream, error) == -1) { + if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream, cancellable, error) == -1) { g_prefix_error ( error, _("Cannot get message %s from folder %s: "), name, lf->folder_path); @@ -252,3 +183,70 @@ mh_get_message (CamelFolder *folder, return message; } + +static gchar * +mh_folder_get_filename (CamelFolder *folder, + const gchar *uid, + GError **error) +{ + CamelLocalFolder *lf = (CamelLocalFolder *)folder; + + return g_strdup_printf("%s/%s", lf->folder_path, uid); +} + +static CamelLocalSummary * +mh_folder_create_summary (CamelLocalFolder *lf, + const gchar *path, + const gchar *folder, + CamelIndex *index) +{ + return (CamelLocalSummary *) camel_mh_summary_new ( + CAMEL_FOLDER (lf), path, folder, index); +} + +static void +camel_mh_folder_class_init (CamelMhFolderClass *class) +{ + CamelFolderClass *folder_class; + CamelLocalFolderClass *local_folder_class; + + folder_class = CAMEL_FOLDER_CLASS (class); + folder_class->append_message = mh_folder_append_message; + folder_class->get_message = mh_folder_get_message; + folder_class->get_filename = mh_folder_get_filename; + + local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class); + local_folder_class->create_summary = mh_folder_create_summary; +} + +static void +camel_mh_folder_init (CamelMhFolder *mh_folder) +{ +} + +CamelFolder * +camel_mh_folder_new (CamelStore *parent_store, + const gchar *full_name, + guint32 flags, + GCancellable *cancellable, + GError **error) +{ + CamelFolder *folder; + gchar *basename; + + d(printf("Creating mh folder: %s\n", full_name)); + + basename = g_path_get_basename (full_name); + + folder = g_object_new ( + CAMEL_TYPE_MH_FOLDER, + "name", basename, "full-name", full_name, + "parent-store", parent_store, NULL); + folder = (CamelFolder *) camel_local_folder_construct ( + CAMEL_LOCAL_FOLDER (folder), flags, cancellable, error); + + g_free (basename); + + return folder; +} + diff --git a/camel/providers/local/camel-mh-folder.h b/camel/providers/local/camel-mh-folder.h index 11dbf4e..bb75e59 100644 --- a/camel/providers/local/camel-mh-folder.h +++ b/camel/providers/local/camel-mh-folder.h @@ -56,10 +56,12 @@ struct _CamelMhFolderClass { CamelLocalFolderClass parent_class; }; -/* public methods */ -CamelFolder *camel_mh_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error); - -GType camel_mh_folder_get_type (void); +GType camel_mh_folder_get_type (void); +CamelFolder * camel_mh_folder_new (CamelStore *parent_store, + const gchar *full_name, + guint32 flags, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/local/camel-mh-store.c b/camel/providers/local/camel-mh-store.c index f64923b..a842bc2 100644 --- a/camel/providers/local/camel-mh-store.c +++ b/camel/providers/local/camel-mh-store.c @@ -39,11 +39,11 @@ #define d(x) static gboolean construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, GError **error); -static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error); -static CamelFolder *get_inbox (CamelStore *store, GError **error); -static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error); -static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error); -static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error); +static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error); +static CamelFolder *get_inbox (CamelStore *store, GCancellable *cancellable, GError **error); +static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error); +static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GCancellable *cancellable, GError **error); +static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error); G_DEFINE_TYPE (CamelMhStore, camel_mh_store, CAMEL_TYPE_LOCAL_STORE) @@ -102,7 +102,8 @@ static void folders_update (const gchar *root, gint mode, const gchar *folder, - const gchar *new) + const gchar *new, + GCancellable *cancellable) { gchar *tmp, *tmpnew, *line = NULL; CamelStream *stream, *in = NULL, *out = NULL; @@ -129,7 +130,7 @@ folders_update (const gchar *root, goto done; } - while ((line = camel_stream_buffer_read_line ((CamelStreamBuffer *)in, NULL))) { + while ((line = camel_stream_buffer_read_line ((CamelStreamBuffer *)in, cancellable, NULL))) { gint copy = TRUE; switch (mode) { @@ -140,9 +141,9 @@ folders_update (const gchar *root, case UPDATE_RENAME: if (strncmp (line, folder, flen) == 0 && (line[flen] == 0 || line[flen] == '/')) { - if (camel_stream_write (out, new, strlen (new), NULL) == -1 - || camel_stream_write (out, line+flen, strlen (line)-flen, NULL) == -1 - || camel_stream_write(out, "\n", 1, NULL) == -1) + if (camel_stream_write (out, new, strlen (new), cancellable, NULL) == -1 + || camel_stream_write (out, line+flen, strlen (line)-flen, cancellable, NULL) == -1 + || camel_stream_write(out, "\n", 1, cancellable, NULL) == -1) goto fail; copy = FALSE; } @@ -175,7 +176,7 @@ folders_update (const gchar *root, if (mode == UPDATE_ADD && camel_stream_printf(out, "%s\n", folder) == -1) goto fail; - if (camel_stream_close (out, NULL) == -1) + if (camel_stream_close (out, cancellable, NULL) == -1) goto fail; done: @@ -194,6 +195,7 @@ static CamelFolder * get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, + GCancellable *cancellable, GError **error) { CamelStoreClass *store_class; @@ -202,7 +204,7 @@ get_folder (CamelStore *store, /* Chain up to parent's get_folder() method. */ store_class = CAMEL_STORE_CLASS (camel_mh_store_parent_class); - if (store_class->get_folder (store, folder_name, flags, error) == NULL) + if (store_class->get_folder (store, folder_name, flags, cancellable, error) == NULL) return NULL; name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); @@ -240,7 +242,7 @@ get_folder (CamelStore *store, /* add to .folders if we are supposed to */ /* FIXME: throw exception on error */ if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) - folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_ADD, folder_name, NULL); + folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_ADD, folder_name, NULL, cancellable); } else if (!S_ISDIR (st.st_mode)) { g_set_error ( error, CAMEL_STORE_ERROR, @@ -260,19 +262,21 @@ get_folder (CamelStore *store, g_free (name); - return camel_mh_folder_new (store, folder_name, flags, error); + return camel_mh_folder_new (store, folder_name, flags, cancellable, error); } static CamelFolder * get_inbox (CamelStore *store, + GCancellable *cancellable, GError **error) { - return get_folder (store, "inbox", 0, error); + return get_folder (store, "inbox", 0, cancellable, error); } static gboolean delete_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelStoreClass *store_class; @@ -293,29 +297,30 @@ delete_folder (CamelStore *store, /* remove from .folders if we are supposed to */ if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) - folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_REMOVE, folder_name, NULL); + folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_REMOVE, folder_name, NULL, cancellable); /* Chain up to parent's delete_folder() method. */ store_class = CAMEL_STORE_CLASS (camel_mh_store_parent_class); - return store_class->delete_folder (store, folder_name, error); + return store_class->delete_folder (store, folder_name, cancellable, error); } static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, + GCancellable *cancellable, GError **error) { CamelStoreClass *store_class; /* Chain up to parent's rename_folder() method. */ store_class = CAMEL_STORE_CLASS (camel_mh_store_parent_class); - if (!store_class->rename_folder (store, old, new, error)) + if (!store_class->rename_folder (store, old, new, cancellable, error)) return FALSE; if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) { /* yeah this is messy, but so is mh! */ - folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_RENAME, old, new); + folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_RENAME, old, new, cancellable); } return TRUE; @@ -324,7 +329,8 @@ rename_folder (CamelStore *store, static void fill_fi (CamelStore *store, CamelFolderInfo *fi, - guint32 flags) + guint32 flags, + GCancellable *cancellable) { CamelFolder *folder; @@ -332,11 +338,11 @@ fill_fi (CamelStore *store, if (folder == NULL && (flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - folder = camel_store_get_folder (store, fi->full_name, 0, NULL); + folder = camel_store_get_folder (store, fi->full_name, 0, cancellable, NULL); if (folder) { if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - camel_folder_refresh_info (folder, NULL); + camel_folder_refresh_info (folder, cancellable, NULL); fi->unread = camel_folder_get_unread_message_count (folder); fi->total = camel_folder_get_message_count (folder); g_object_unref (folder); @@ -370,7 +376,8 @@ folder_info_new (CamelStore *store, CamelURL *url, const gchar *root, const gchar *path, - guint32 flags) + guint32 flags, + GCancellable *cancellable) { /* FIXME: need to set fi->flags = CAMEL_FOLDER_NOSELECT (and possibly others) when appropriate */ CamelFolderInfo *fi; @@ -385,7 +392,7 @@ folder_info_new (CamelStore *store, fi->uri = camel_url_to_string (url, 0); fi->full_name = g_strdup (path); fi->name = g_strdup (base?base+1:path); - fill_fi (store, fi, flags); + fill_fi (store, fi, flags, cancellable); d(printf("New folderinfo:\n '%s'\n '%s'\n '%s'\n", fi->full_name, fi->uri, fi->path)); @@ -408,7 +415,8 @@ recursive_scan (CamelStore *store, GHashTable *visited, const gchar *root, const gchar *path, - guint32 flags) + guint32 flags, + GCancellable *cancellable) { gchar *fullpath, *tmp; DIR *dp; @@ -439,7 +447,7 @@ recursive_scan (CamelStore *store, g_hash_table_insert (visited, inew, inew); /* link in ... */ - fi = folder_info_new (store, url, root, path, flags); + fi = folder_info_new (store, url, root, path, flags, cancellable); fi->parent = parent; fi->next = *fip; *fip = fi; @@ -465,10 +473,10 @@ recursive_scan (CamelStore *store, /* otherwise, treat at potential node, and recurse, a bit more expensive than needed, but tough! */ if (path[0]) { tmp = g_strdup_printf("%s/%s", path, d->d_name); - recursive_scan (store, url, &fi->child, fi, visited, root, tmp, flags); + recursive_scan (store, url, &fi->child, fi, visited, root, tmp, flags, cancellable); g_free (tmp); } else { - recursive_scan (store, url, &fi->child, fi, visited, root, d->d_name, flags); + recursive_scan (store, url, &fi->child, fi, visited, root, d->d_name, flags, cancellable); } } @@ -483,7 +491,8 @@ folders_scan (CamelStore *store, const gchar *root, const gchar *top, CamelFolderInfo **fip, - guint32 flags) + guint32 flags, + GCancellable *cancellable) { CamelFolderInfo *fi; gchar line[512], *path, *tmp; @@ -507,7 +516,7 @@ folders_scan (CamelStore *store, visited = g_hash_table_new (g_str_hash, g_str_equal); folders = g_ptr_array_new (); - while ( (len = camel_stream_buffer_gets ((CamelStreamBuffer *)in, line, sizeof (line), NULL)) > 0) { + while ( (len = camel_stream_buffer_gets ((CamelStreamBuffer *)in, line, sizeof (line), cancellable, NULL)) > 0) { /* ignore blank lines */ if (len <= 1) continue; @@ -547,7 +556,7 @@ folders_scan (CamelStore *store, path = g_strdup_printf("%s/%s", root, line); if (g_stat (path, &st) == 0 && S_ISDIR (st.st_mode)) { - fi = folder_info_new (store, url, root, line, flags); + fi = folder_info_new (store, url, root, line, flags, cancellable); g_ptr_array_add (folders, fi); } g_free (path); @@ -590,6 +599,7 @@ static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { CamelFolderInfo *fi = NULL; @@ -602,14 +612,14 @@ get_folder_info (CamelStore *store, /* use .folders if we are supposed to */ if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) { - folders_scan (store, url, root, top, &fi, flags); + folders_scan (store, url, root, top, &fi, flags, cancellable); } else { GHashTable *visited = g_hash_table_new (inode_hash, inode_equal); if (top == NULL) top = ""; - recursive_scan (store, url, &fi, NULL, visited, root, top, flags); + recursive_scan (store, url, &fi, NULL, visited, root, top, flags, cancellable); /* if we actually scanned from root, we have a "" root node we dont want */ if (fi != NULL && top[0] == 0) { diff --git a/camel/providers/local/camel-mh-summary.c b/camel/providers/local/camel-mh-summary.c index 033be93..fa693e8 100644 --- a/camel/providers/local/camel-mh-summary.c +++ b/camel/providers/local/camel-mh-summary.c @@ -45,8 +45,8 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), CAMEL_TYPE_MH_SUMMARY, CamelMhSummaryPrivate)) -static gint mh_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error); -static gint mh_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); +static gint mh_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); +static gint mh_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); /*static gint mh_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error);*/ static gchar *mh_summary_next_uid_string (CamelFolderSummary *s); @@ -155,7 +155,8 @@ mh_summary_next_uid_string (CamelFolderSummary *s) static gint camel_mh_summary_add (CamelLocalSummary *cls, const gchar *name, - gint forceindex) + gint forceindex, + GCancellable *cancellable) { CamelMhSummary *mhs = (CamelMhSummary *)cls; gchar *filename = g_strdup_printf("%s/%s", cls->folder_path, name); @@ -203,6 +204,7 @@ remove_summary (gchar *key, static gint mh_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, GError **error) { DIR *dir; @@ -258,7 +260,7 @@ mh_summary_check (CamelLocalSummary *cls, camel_folder_summary_remove ((CamelFolderSummary *)cls, info); camel_message_info_free (info); } - camel_mh_summary_add (cls, d->d_name, forceindex); + camel_mh_summary_add (cls, d->d_name, forceindex, cancellable); } else { const gchar *uid = camel_message_info_uid (info); CamelMessageInfo *old = g_hash_table_lookup (left, uid); @@ -287,6 +289,7 @@ static gint mh_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changes, + GCancellable *cancellable, GError **error) { CamelLocalSummaryClass *local_summary_class; @@ -299,7 +302,7 @@ mh_summary_sync (CamelLocalSummary *cls, /* we could probably get away without this ... but why not use it, esp if we're going to be doing any significant io already */ - if (camel_local_summary_check (cls, changes, error) == -1) + if (camel_local_summary_check (cls, changes, cancellable, error) == -1) return -1; /* FIXME: need to update/honour .mh_sequences or whatever it is */ @@ -331,5 +334,5 @@ mh_summary_sync (CamelLocalSummary *cls, /* Chain up to parent's sync() method. */ local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (camel_mh_summary_parent_class); - return local_summary_class->sync (cls, expunge, changes, error); + return local_summary_class->sync (cls, expunge, changes, cancellable, error); } diff --git a/camel/providers/local/camel-spool-folder.c b/camel/providers/local/camel-spool-folder.c index 1923c32..8063002 100644 --- a/camel/providers/local/camel-spool-folder.c +++ b/camel/providers/local/camel-spool-folder.c @@ -40,77 +40,22 @@ #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ -static CamelLocalSummary *spool_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index); - -static gint spool_lock (CamelLocalFolder *lf, CamelLockType type, GError **error); -static void spool_unlock (CamelLocalFolder *lf); - G_DEFINE_TYPE (CamelSpoolFolder, camel_spool_folder, CAMEL_TYPE_MBOX_FOLDER) -static void -camel_spool_folder_class_init (CamelSpoolFolderClass *class) -{ - CamelLocalFolderClass *local_folder_class; - - local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class); - local_folder_class->create_summary = spool_create_summary; - local_folder_class->lock = spool_lock; - local_folder_class->unlock = spool_unlock; -} - -static void -camel_spool_folder_init (CamelSpoolFolder *spool_folder) -{ - spool_folder->lockid = -1; -} - -CamelFolder * -camel_spool_folder_new (CamelStore *parent_store, - const gchar *full_name, - guint32 flags, - GError **error) -{ - CamelFolder *folder; - gchar *basename; - - basename = g_path_get_basename (full_name); - - folder = g_object_new ( - CAMEL_TYPE_SPOOL_FOLDER, - "name", basename, "full-name", full_name, - "parent-store", parent_store, NULL); - - if (parent_store->flags & CAMEL_STORE_FILTER_INBOX - && strcmp(full_name, "INBOX") == 0) - folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT; - flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX; - - folder = (CamelFolder *)camel_local_folder_construct ( - (CamelLocalFolder *)folder, flags, error); - if (folder) { - if (camel_url_get_param(((CamelService *)parent_store)->url, "xstatus")) - camel_mbox_summary_xstatus ((CamelMboxSummary *)folder->summary, TRUE); - } - - g_free (basename); - - return folder; -} - static CamelLocalSummary * -spool_create_summary (CamelLocalFolder *lf, - const gchar *path, - const gchar *folder, - CamelIndex *index) +spool_folder_create_summary (CamelLocalFolder *lf, + const gchar *path, + const gchar *folder, + CamelIndex *index) { return (CamelLocalSummary *) camel_spool_summary_new ( CAMEL_FOLDER (lf), folder); } static gint -spool_lock (CamelLocalFolder *lf, - CamelLockType type, - GError **error) +spool_folder_lock (CamelLocalFolder *lf, + CamelLockType type, + GError **error) { gint retry = 0; CamelMboxFolder *mf = (CamelMboxFolder *)lf; @@ -154,7 +99,7 @@ spool_lock (CamelLocalFolder *lf, } static void -spool_unlock (CamelLocalFolder *lf) +spool_folder_unlock (CamelLocalFolder *lf) { CamelMboxFolder *mf = (CamelMboxFolder *)lf; CamelSpoolFolder *sf = (CamelSpoolFolder *)lf; @@ -167,3 +112,55 @@ spool_unlock (CamelLocalFolder *lf) close (mf->lockfd); mf->lockfd = -1; } + +static void +camel_spool_folder_class_init (CamelSpoolFolderClass *class) +{ + CamelLocalFolderClass *local_folder_class; + + local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class); + local_folder_class->create_summary = spool_folder_create_summary; + local_folder_class->lock = spool_folder_lock; + local_folder_class->unlock = spool_folder_unlock; +} + +static void +camel_spool_folder_init (CamelSpoolFolder *spool_folder) +{ + spool_folder->lockid = -1; +} + +CamelFolder * +camel_spool_folder_new (CamelStore *parent_store, + const gchar *full_name, + guint32 flags, + GCancellable *cancellable, + GError **error) +{ + CamelFolder *folder; + gchar *basename; + + basename = g_path_get_basename (full_name); + + folder = g_object_new ( + CAMEL_TYPE_SPOOL_FOLDER, + "name", basename, "full-name", full_name, + "parent-store", parent_store, NULL); + + if (parent_store->flags & CAMEL_STORE_FILTER_INBOX + && strcmp(full_name, "INBOX") == 0) + folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT; + flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX; + + folder = (CamelFolder *)camel_local_folder_construct ( + (CamelLocalFolder *)folder, flags, cancellable, error); + if (folder) { + if (camel_url_get_param(((CamelService *)parent_store)->url, "xstatus")) + camel_mbox_summary_xstatus ((CamelMboxSummary *)folder->summary, TRUE); + } + + g_free (basename); + + return folder; +} + diff --git a/camel/providers/local/camel-spool-folder.h b/camel/providers/local/camel-spool-folder.h index fd96fe0..b7b0bbb 100644 --- a/camel/providers/local/camel-spool-folder.h +++ b/camel/providers/local/camel-spool-folder.h @@ -61,9 +61,12 @@ struct _CamelSpoolFolderClass { CamelMboxFolderClass parent_class; }; -GType camel_spool_folder_get_type (void); - -CamelFolder *camel_spool_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error); +GType camel_spool_folder_get_type (void); +CamelFolder * camel_spool_folder_new (CamelStore *parent_store, + const gchar *full_name, + guint32 flags, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/local/camel-spool-store.c b/camel/providers/local/camel-spool-store.c index b5f8e77..04f173f 100644 --- a/camel/providers/local/camel-spool-store.c +++ b/camel/providers/local/camel-spool-store.c @@ -41,14 +41,14 @@ #define d(x) static gboolean construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, GError **error); -static CamelFolder *get_folder (CamelStore* store, const gchar *folder_name, guint32 flags, GError **error); +static CamelFolder *get_folder (CamelStore* store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error); static gchar *get_name (CamelService *service, gboolean brief); -static CamelFolder *get_inbox (CamelStore *store, GError **error); -static gboolean rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name, GError **error); -static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error); +static CamelFolder *get_inbox (CamelStore *store, GCancellable *cancellable, GError **error); +static gboolean rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name, GCancellable *cancellable, GError **error); +static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error); static void free_folder_info (CamelStore *store, CamelFolderInfo *fi); -static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error); +static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error); static gchar *spool_get_meta_path (CamelLocalStore *ls, const gchar *full_name, const gchar *ext); static gchar *spool_get_full_path (CamelLocalStore *ls, const gchar *full_name); @@ -141,6 +141,7 @@ static CamelFolder * get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, + GCancellable *cancellable, GError **error) { CamelFolder *folder = NULL; @@ -158,7 +159,7 @@ get_folder (CamelStore *store, _("Folder '%s/%s' does not exist."), ((CamelService *)store)->url->path, folder_name); } else { - folder = camel_spool_folder_new (store, folder_name, flags, error); + folder = camel_spool_folder_new (store, folder_name, flags, cancellable, error); } } else { name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); @@ -183,7 +184,7 @@ get_folder (CamelStore *store, _("Could not create folder '%s':\n%s"), folder_name, g_strerror (errno)); } else { - folder = camel_spool_folder_new (store, folder_name, flags, error); + folder = camel_spool_folder_new (store, folder_name, flags, cancellable, error); } } } else if (!S_ISREG (st.st_mode)) { @@ -192,7 +193,7 @@ get_folder (CamelStore *store, CAMEL_STORE_ERROR_NO_FOLDER, _("'%s' is not a mailbox file."), name); } else { - folder = camel_spool_folder_new (store, folder_name, flags, error); + folder = camel_spool_folder_new (store, folder_name, flags, cancellable, error); } g_free (name); } @@ -202,10 +203,11 @@ get_folder (CamelStore *store, static CamelFolder * get_inbox (CamelStore *store, + GCancellable *cancellable, GError **error) { if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX) - return get_folder (store, "INBOX", CAMEL_STORE_FOLDER_CREATE, error); + return get_folder (store, "INBOX", CAMEL_STORE_FOLDER_CREATE, cancellable, error); else { g_set_error ( error, CAMEL_STORE_ERROR, @@ -231,6 +233,7 @@ static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, + GCancellable *cancellable, GError **error) { g_set_error ( @@ -244,6 +247,7 @@ rename_folder (CamelStore *store, static gboolean delete_folder (CamelStore *store, const gchar *folder_name, + GCancellable *cancellable, GError **error) { g_set_error ( @@ -269,7 +273,8 @@ free_folder_info (CamelStore *store, static void spool_fill_fi (CamelStore *store, CamelFolderInfo *fi, - guint32 flags) + guint32 flags, + GCancellable *cancellable) { CamelFolder *folder; @@ -278,7 +283,7 @@ spool_fill_fi (CamelStore *store, folder = camel_object_bag_get (store->folders, fi->full_name); if (folder) { if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - camel_folder_refresh_info (folder, NULL); + camel_folder_refresh_info (folder, cancellable, NULL); fi->unread = camel_folder_get_unread_message_count (folder); fi->total = camel_folder_get_message_count (folder); g_object_unref (folder); @@ -337,6 +342,7 @@ scan_dir (CamelStore *store, guint32 flags, CamelFolderInfo *parent, CamelFolderInfo **fip, + GCancellable *cancellable, GError **error) { DIR *dir; @@ -367,7 +373,7 @@ scan_dir (CamelStore *store, /* incase we start scanning from a file. messy duplication :-/ */ if (path) { fi = spool_new_fi (store, parent, fip, path, CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_NOCHILDREN); - spool_fill_fi (store, fi, flags); + spool_fill_fi (store, fi, flags, cancellable); } return 0; } @@ -417,7 +423,7 @@ scan_dir (CamelStore *store, if (folder != NULL || isfolder) { fi = spool_new_fi (store, parent, fip, fname, CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_NOCHILDREN); - spool_fill_fi (store, fi, flags); + spool_fill_fi (store, fi, flags, cancellable); } if (folder) g_object_unref (folder); @@ -432,7 +438,7 @@ scan_dir (CamelStore *store, *inew = in; g_hash_table_insert (visited, inew, inew); - if (scan_dir (store, visited, root, fname, flags, parent, fip, error) == -1) { + if (scan_dir (store, visited, root, fname, flags, parent, fip, cancellable, error) == -1) { g_free (tmp); g_free (fname); closedir (dir); @@ -476,6 +482,7 @@ static CamelFolderInfo * get_folder_info_elm (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { CamelFolderInfo *fi = NULL; @@ -483,7 +490,7 @@ get_folder_info_elm (CamelStore *store, visited = g_hash_table_new (inode_hash, inode_equal); - if (scan_dir (store, visited, ((CamelService *)store)->url->path, top, flags, NULL, &fi, error) == -1 && fi != NULL) { + if (scan_dir (store, visited, ((CamelService *)store)->url->path, top, flags, NULL, &fi, cancellable, error) == -1 && fi != NULL) { camel_store_free_folder_info_full (store, fi); fi = NULL; } @@ -498,6 +505,7 @@ static CamelFolderInfo * get_folder_info_mbox (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { CamelFolderInfo *fi = NULL, *fip = NULL; @@ -506,7 +514,7 @@ get_folder_info_mbox (CamelStore *store, fi = spool_new_fi(store, NULL, &fip, "INBOX", CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_SYSTEM); g_free (fi->name); fi->name = g_strdup(_("Inbox")); - spool_fill_fi (store, fi, flags); + spool_fill_fi (store, fi, flags, cancellable); } return fi; @@ -516,12 +524,13 @@ static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX) - return get_folder_info_mbox (store, top, flags, error); + return get_folder_info_mbox (store, top, flags, cancellable, error); else - return get_folder_info_elm (store, top, flags, error); + return get_folder_info_elm (store, top, flags, cancellable, error); } static gchar * diff --git a/camel/providers/local/camel-spool-summary.c b/camel/providers/local/camel-spool-summary.c index 57e02a4..30fc168 100644 --- a/camel/providers/local/camel-spool-summary.c +++ b/camel/providers/local/camel-spool-summary.c @@ -45,9 +45,9 @@ #define CAMEL_SPOOL_SUMMARY_VERSION (0x400) static gint spool_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error); -static gint spool_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error); +static gint spool_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); -static gint spool_summary_sync_full (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error); +static gint spool_summary_sync_full (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error); static gint spool_summary_need_index (void); G_DEFINE_TYPE (CamelSpoolSummary, camel_spool_summary, CAMEL_TYPE_MBOX_SUMMARY) @@ -115,6 +115,7 @@ static gint spool_summary_sync_full (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, GError **error) { gint fd = -1, fdout = -1; @@ -127,7 +128,7 @@ spool_summary_sync_full (CamelMboxSummary *cls, d(printf("performing full summary/sync\n")); - camel_operation_start(NULL, _("Storing folder")); + camel_operation_start (cancellable, _("Storing folder")); fd = open (((CamelLocalSummary *)cls)->folder_path, O_RDWR|O_LARGEFILE); if (fd == -1) { @@ -137,7 +138,7 @@ spool_summary_sync_full (CamelMboxSummary *cls, _("Could not open file: %s: %s"), ((CamelLocalSummary *)cls)->folder_path, g_strerror (errno)); - camel_operation_end (NULL); + camel_operation_end (cancellable); return -1; } @@ -154,7 +155,9 @@ spool_summary_sync_full (CamelMboxSummary *cls, goto error; } - if (camel_mbox_summary_sync_mbox ((CamelMboxSummary *)cls, flags, changeinfo, fd, fdout, error) == -1) + if (camel_mbox_summary_sync_mbox ( + (CamelMboxSummary *)cls, flags, changeinfo, + fd, fdout, cancellable, error) == -1) goto error; /* sync out content */ @@ -283,7 +286,7 @@ spool_summary_sync_full (CamelMboxSummary *cls, if (tmpname[0] != '\0') unlink (tmpname); - camel_operation_end (NULL); + camel_operation_end (cancellable); return 0; error: @@ -296,7 +299,7 @@ spool_summary_sync_full (CamelMboxSummary *cls, if (tmpname[0] != '\0') unlink (tmpname); - camel_operation_end (NULL); + camel_operation_end (cancellable); return -1; } @@ -304,13 +307,14 @@ spool_summary_sync_full (CamelMboxSummary *cls, static gint spool_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, + GCancellable *cancellable, GError **error) { gint i, work, count; struct stat st; CamelFolderSummary *s = (CamelFolderSummary *)cls; - if (CAMEL_LOCAL_SUMMARY_CLASS (camel_spool_summary_parent_class)->check (cls, changeinfo, error) == -1) + if (CAMEL_LOCAL_SUMMARY_CLASS (camel_spool_summary_parent_class)->check (cls, changeinfo, cancellable, error) == -1) return -1; /* check to see if we need to copy/update the file; missing xev headers prompt this */ @@ -327,7 +331,9 @@ spool_summary_check (CamelLocalSummary *cls, /* if we do, then write out the headers using sync_full, etc */ if (work) { d(printf("Have to add new headers, re-syncing from the start to accomplish this\n")); - if (CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_full (CAMEL_MBOX_SUMMARY (cls), FALSE, changeinfo, error) == -1) + if (CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_full ( + CAMEL_MBOX_SUMMARY (cls), FALSE, + changeinfo, cancellable, error) == -1) return -1; if (g_stat (cls->folder_path, &st) == -1) { diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c index 08ed6f2..14c1757 100644 --- a/camel/providers/nntp/camel-nntp-folder.c +++ b/camel/providers/nntp/camel-nntp-folder.c @@ -72,6 +72,7 @@ nntp_folder_finalize (GObject *object) gboolean camel_nntp_folder_selected (CamelNNTPFolder *nntp_folder, gchar *line, + GCancellable *cancellable, GError **error) { CamelFolder *folder; @@ -83,11 +84,13 @@ camel_nntp_folder_selected (CamelNNTPFolder *nntp_folder, return camel_nntp_summary_check ( CAMEL_NNTP_SUMMARY (folder->summary), CAMEL_NNTP_STORE (parent_store), - line, nntp_folder->changes, error); + line, nntp_folder->changes, + cancellable, error); } static gboolean nntp_folder_refresh_info_online (CamelFolder *folder, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -107,7 +110,7 @@ nntp_folder_refresh_info_online (CamelFolder *folder, /* When invoked with no fmt, camel_nntp_command() just selects the folder and should return zero. */ success = !camel_nntp_command ( - nntp_store, error, nntp_folder, &line, NULL); + nntp_store, cancellable, error, nntp_folder, &line, NULL); if (camel_folder_change_info_changed (nntp_folder->changes)) { changes = nntp_folder->changes; @@ -203,7 +206,11 @@ nntp_get_filename (CamelFolder *folder, const gchar *uid, GError **error) } static CamelStream * -nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const gchar *id, const gchar *msgid, GError **error) +nntp_folder_download_message (CamelNNTPFolder *nntp_folder, + const gchar *id, + const gchar *msgid, + GCancellable *cancellable, + GError **error) { CamelFolder *folder; CamelStore *parent_store; @@ -216,11 +223,11 @@ nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const gchar *id, con parent_store = camel_folder_get_parent_store (folder); nntp_store = CAMEL_NNTP_STORE (parent_store); - ret = camel_nntp_command (nntp_store, error, nntp_folder, &line, "article %s", id); + ret = camel_nntp_command (nntp_store, cancellable, error, nntp_folder, &line, "article %s", id); if (ret == 220) { stream = camel_data_cache_add (nntp_store->cache, "cache", msgid, NULL); if (stream) { - if (camel_stream_write_to_stream ((CamelStream *) nntp_store->stream, stream, error) == -1) + if (camel_stream_write_to_stream ((CamelStream *) nntp_store->stream, stream, cancellable, error) == -1) goto fail; if (camel_stream_reset (stream, error) == -1) goto fail; @@ -249,6 +256,7 @@ fail: static gboolean nntp_folder_cache_message (CamelDiscoFolder *disco_folder, const gchar *uid, + GCancellable *cancellable, GError **error) { CamelFolder *folder; @@ -276,7 +284,7 @@ nntp_folder_cache_message (CamelDiscoFolder *disco_folder, camel_service_lock (CAMEL_SERVICE (nntp_store), CAMEL_SERVICE_REC_CONNECT_LOCK); stream = nntp_folder_download_message ( - (CamelNNTPFolder *) disco_folder, article, msgid, error); + (CamelNNTPFolder *) disco_folder, article, msgid, cancellable, error); if (stream) g_object_unref (stream); else @@ -288,7 +296,10 @@ nntp_folder_cache_message (CamelDiscoFolder *disco_folder, } static CamelMimeMessage * -nntp_folder_get_message (CamelFolder *folder, const gchar *uid, GError **error) +nntp_folder_get_message (CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelMimeMessage *message = NULL; @@ -327,13 +338,13 @@ nntp_folder_get_message (CamelFolder *folder, const gchar *uid, GError **error) goto fail; } - stream = nntp_folder_download_message (nntp_folder, article, msgid, error); + stream = nntp_folder_download_message (nntp_folder, article, msgid, cancellable, error); if (stream == NULL) goto fail; } message = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, error) == -1) { + if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, cancellable, error) == -1) { g_prefix_error (error, _("Cannot get message %s: "), uid); g_object_unref (message); message = NULL; @@ -433,6 +444,7 @@ nntp_folder_append_message_online (CamelFolder *folder, CamelMimeMessage *mime_message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error) { CamelStore *parent_store; @@ -456,7 +468,7 @@ nntp_folder_append_message_online (CamelFolder *folder, camel_service_lock (CAMEL_SERVICE (nntp_store), CAMEL_SERVICE_REC_CONNECT_LOCK); /* send 'POST' command */ - ret = camel_nntp_command (nntp_store, error, NULL, &line, "post"); + ret = camel_nntp_command (nntp_store, cancellable, error, NULL, &line, "post"); if (ret != 340) { if (ret == 440) { g_set_error ( @@ -505,11 +517,11 @@ nntp_folder_append_message_online (CamelFolder *folder, } /* write the message */ - if (camel_stream_write (stream, group, strlen (group), error) == -1 - || camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (mime_message), filtered_stream, error) == -1 - || camel_stream_flush (filtered_stream, error) == -1 - || camel_stream_write (stream, "\r\n.\r\n", 5, error) == -1 - || (ret = camel_nntp_stream_line (nntp_store->stream, (guchar **)&line, &u, error)) == -1) { + if (camel_stream_write (stream, group, strlen (group), cancellable, error) == -1 + || camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (mime_message), filtered_stream, cancellable, error) == -1 + || camel_stream_flush (filtered_stream, cancellable, error) == -1 + || camel_stream_write (stream, "\r\n.\r\n", 5, cancellable, error) == -1 + || (ret = camel_nntp_stream_line (nntp_store->stream, (guchar **)&line, &u, cancellable, error)) == -1) { g_prefix_error (error, _("Posting failed: ")); success = FALSE; } else if (atoi (line) != 240) { @@ -533,6 +545,7 @@ nntp_folder_append_message_offline (CamelFolder *folder, CamelMimeMessage *mime_message, const CamelMessageInfo *info, gchar **appended_uid, + GCancellable *cancellable, GError **error) { g_set_error ( @@ -552,6 +565,7 @@ nntp_folder_transfer_message (CamelFolder *source, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_orig, + GCancellable *cancellable, GError **error) { g_set_error ( @@ -610,6 +624,7 @@ camel_nntp_folder_init (CamelNNTPFolder *nntp_folder) CamelFolder * camel_nntp_folder_new (CamelStore *parent, const gchar *folder_name, + GCancellable *cancellable, GError **error) { CamelFolder *folder; @@ -656,7 +671,8 @@ camel_nntp_folder_new (CamelStore *parent, camel_store_summary_info_free ((CamelStoreSummary *) ((CamelNNTPStore*) parent)->summary, si); } - if (subscribed && !camel_folder_refresh_info (folder, error)) { + if (subscribed && !camel_folder_refresh_info ( + folder, cancellable, error)) { g_object_unref (folder); folder = NULL; } diff --git a/camel/providers/nntp/camel-nntp-folder.h b/camel/providers/nntp/camel-nntp-folder.h index 4a72539..2f6a226 100644 --- a/camel/providers/nntp/camel-nntp-folder.h +++ b/camel/providers/nntp/camel-nntp-folder.h @@ -66,11 +66,15 @@ struct _CamelNNTPFolderClass { CamelDiscoFolderClass parent; }; -GType camel_nntp_folder_get_type (void); - -CamelFolder *camel_nntp_folder_new (CamelStore *parent, const gchar *folder_name, GError **error); - -gboolean camel_nntp_folder_selected (CamelNNTPFolder *folder, gchar *line, GError **error); +GType camel_nntp_folder_get_type (void); +CamelFolder * camel_nntp_folder_new (CamelStore *parent, + const gchar *folder_name, + GCancellable *cancellable, + GError **error); +gboolean camel_nntp_folder_selected (CamelNNTPFolder *folder, + gchar *line, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c index b61bb67..c3b5b22 100644 --- a/camel/providers/nntp/camel-nntp-store.c +++ b/camel/providers/nntp/camel-nntp-store.c @@ -58,10 +58,80 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), CAMEL_TYPE_NNTP_STORE, CamelNNTPStorePrivate)) -static gint camel_nntp_try_authenticate (CamelNNTPStore *store, GError **error); - G_DEFINE_TYPE (CamelNNTPStore, camel_nntp_store, CAMEL_TYPE_DISCO_STORE) +static gint +camel_nntp_try_authenticate (CamelNNTPStore *store, + GCancellable *cancellable, + GError **error) +{ + CamelService *service = (CamelService *) store; + CamelSession *session = camel_service_get_session (service); + gint ret; + gchar *line = NULL; + GError *local_error = NULL; + + if (!service->url->user) { + g_set_error ( + error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, + _("Authentication requested but no username provided")); + return -1; + } + + /* if nessecary, prompt for the password */ + if (!service->url->passwd) { + gchar *prompt, *base; + retry: + base = camel_session_build_password_prompt ( + "NNTP", service->url->user, service->url->host); + if (line) { + gchar *top = g_markup_printf_escaped ( + _("Cannot authenticate to server: %s"), line); + + prompt = g_strdup_printf("%s\n\n%s", top, base); + g_free (top); + } else { + prompt = base; + base = NULL; + } + + service->url->passwd = + camel_session_get_password (session, service, NULL, + prompt, "password", CAMEL_SESSION_PASSWORD_SECRET | (store->password_reprompt ? CAMEL_SESSION_PASSWORD_REPROMPT : 0), error); + g_free (prompt); + g_free (base); + + if (!service->url->passwd) + return -1; + + store->password_reprompt = FALSE; + } + + /* now, send auth info (currently, only authinfo user/pass is supported) */ + ret = camel_nntp_raw_command(store, cancellable, &local_error, &line, "authinfo user %s", service->url->user); + if (ret == NNTP_AUTH_CONTINUE) + ret = camel_nntp_raw_command(store, cancellable, &local_error, &line, "authinfo pass %s", service->url->passwd); + + if (ret != NNTP_AUTH_ACCEPTED) { + if (ret != -1) { + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || + g_error_matches (local_error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE)) { + g_propagate_error (error, local_error); + return ret; + } + + /* To force password reprompt */ + store->password_reprompt = TRUE; + g_free (service->url->passwd); + service->url->passwd = NULL; + goto retry; + } + return -1; + } + + return ret; +} + static void nntp_store_dispose (GObject *object) { @@ -142,7 +212,9 @@ static struct { }; static gint -xover_setup (CamelNNTPStore *store, GError **error) +xover_setup (CamelNNTPStore *store, + GCancellable *cancellable, + GError **error) { gint ret, i; gchar *line; @@ -154,7 +226,7 @@ xover_setup (CamelNNTPStore *store, GError **error) if (store->xover || getenv("CAMEL_NNTP_DISABLE_XOVER") != NULL) return 0; - ret = camel_nntp_raw_command_auth(store, error, &line, "list overview.fmt"); + ret = camel_nntp_raw_command_auth(store, cancellable, error, &line, "list overview.fmt"); if (ret == -1) { return -1; } else if (ret != 215) @@ -164,7 +236,7 @@ xover_setup (CamelNNTPStore *store, GError **error) last = (struct _xover_header *)&store->xover; /* supported command */ - while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len, error)) > 0) { + while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len, cancellable, error)) > 0) { p = (guchar *) line; xover = g_malloc0 (sizeof (*xover)); last->next = xover; @@ -205,7 +277,13 @@ enum { #endif static gboolean -connect_to_server (CamelService *service, const gchar *host, const gchar *serv, gint fallback_port, gint ssl_mode, GError **error) +connect_to_server (CamelService *service, + const gchar *host, + const gchar *serv, + gint fallback_port, + gint ssl_mode, + GCancellable *cancellable, + GError **error) { CamelNNTPStore *store = (CamelNNTPStore *) service; CamelDiscoStore *disco_store = (CamelDiscoStore*) service; @@ -247,7 +325,9 @@ connect_to_server (CamelService *service, const gchar *host, const gchar *serv, g_free (socks_host); } - if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, host, serv, fallback_port, error) == -1) { + if (camel_tcp_stream_connect ( + CAMEL_TCP_STREAM (tcp_stream), host, serv, + fallback_port, cancellable, error) == -1) { g_prefix_error ( error, _("Could not connect to %s: "), service->url->host); @@ -260,7 +340,7 @@ connect_to_server (CamelService *service, const gchar *host, const gchar *serv, g_object_unref (tcp_stream); /* Read the greeting, if any. */ - if (camel_nntp_stream_line (store->stream, &buf, &len, error) == -1) { + if (camel_nntp_stream_line (store->stream, &buf, &len, cancellable, error) == -1) { g_prefix_error ( error, _("Could not read greeting from %s: "), service->url->host); @@ -287,15 +367,15 @@ connect_to_server (CamelService *service, const gchar *host, const gchar *serv, /* if we have username, try it here */ if (service->url->user != NULL && service->url->user[0] - && camel_nntp_try_authenticate (store, error) != NNTP_AUTH_ACCEPTED) + && camel_nntp_try_authenticate (store, cancellable, error) != NNTP_AUTH_ACCEPTED) goto fail; /* set 'reader' mode & ignore return code, also ping the server, inn goes offline very quickly otherwise */ - if (camel_nntp_raw_command_auth (store, error, (gchar **) &buf, "mode reader") == -1 - || camel_nntp_raw_command_auth (store, error, (gchar **) &buf, "date") == -1) + if (camel_nntp_raw_command_auth (store, cancellable, error, (gchar **) &buf, "mode reader") == -1 + || camel_nntp_raw_command_auth (store, cancellable, error, (gchar **) &buf, "date") == -1) goto fail; - if (xover_setup (store, error) == -1) + if (xover_setup (store, cancellable, error) == -1) goto fail; if (!disco_store->diary) { @@ -328,7 +408,9 @@ static struct { }; static gboolean -nntp_connect_online (CamelService *service, GError **error) +nntp_connect_online (CamelService *service, + GCancellable *cancellable, + GError **error) { const gchar *ssl_mode; gint mode, i; @@ -354,11 +436,15 @@ nntp_connect_online (CamelService *service, GError **error) fallback_port = 0; } - return connect_to_server (service, service->url->host, serv, fallback_port, mode, error); + return connect_to_server ( + service, service->url->host, serv, + fallback_port, mode, cancellable, error); } static gboolean -nntp_connect_offline (CamelService *service, GError **error) +nntp_connect_offline (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (service); CamelDiscoStore *disco_store = (CamelDiscoStore *) nntp_store; @@ -392,7 +478,10 @@ nntp_connect_offline (CamelService *service, GError **error) } static gboolean -nntp_disconnect_online (CamelService *service, gboolean clean, GError **error) +nntp_disconnect_online (CamelService *service, + gboolean clean, + GCancellable *cancellable, + GError **error) { CamelNNTPStore *store = CAMEL_NNTP_STORE (service); gchar *line; @@ -400,7 +489,7 @@ nntp_disconnect_online (CamelService *service, gboolean clean, GError **error) camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); if (clean) - camel_nntp_raw_command (store, NULL, &line, "quit"); + camel_nntp_raw_command (store, cancellable, NULL, &line, "quit"); g_object_unref (store->stream); store->stream = NULL; @@ -413,7 +502,10 @@ nntp_disconnect_online (CamelService *service, gboolean clean, GError **error) } static gboolean -nntp_disconnect_offline (CamelService *service, gboolean clean, GError **error) +nntp_disconnect_offline (CamelService *service, + gboolean clean, + GCancellable *cancellable, + GError **error) { CamelDiscoStore *disco = CAMEL_DISCO_STORE (service); @@ -438,22 +530,33 @@ nntp_store_get_name (CamelService *service, gboolean brief) extern CamelServiceAuthType camel_nntp_password_authtype; static GList * -nntp_store_query_auth_types (CamelService *service, GError **error) +nntp_store_query_auth_types (CamelService *service, + GCancellable *cancellable, + GError **error) { return g_list_append (NULL, &camel_nntp_password_authtype); } static CamelFolder * -nntp_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error) +nntp_get_folder (CamelStore *store, + const gchar *folder_name, + guint32 flags, + GCancellable *cancellable, + GError **error) { CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); CamelFolder *folder; - camel_service_lock (CAMEL_SERVICE (nntp_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_lock ( + CAMEL_SERVICE (nntp_store), + CAMEL_SERVICE_REC_CONNECT_LOCK); - folder = camel_nntp_folder_new (store, folder_name, error); + folder = camel_nntp_folder_new ( + store, folder_name, cancellable, error); - camel_service_unlock (CAMEL_SERVICE (nntp_store), CAMEL_SERVICE_REC_CONNECT_LOCK); + camel_service_unlock ( + CAMEL_SERVICE (nntp_store), + CAMEL_SERVICE_REC_CONNECT_LOCK); return folder; } @@ -613,7 +716,11 @@ nntp_store_info_update (CamelNNTPStore *store, gchar *line) } static CamelFolderInfo * -nntp_store_get_subscribed_folder_info (CamelNNTPStore *store, const gchar *top, guint flags, GError **error) +nntp_store_get_subscribed_folder_info (CamelNNTPStore *store, + const gchar *top, + guint flags, + GCancellable *cancellable, + GError **error) { gint i; CamelStoreInfo *si; @@ -634,12 +741,15 @@ nntp_store_get_subscribed_folder_info (CamelNNTPStore *store, const gchar *top, CamelNNTPFolder *folder; gchar *line; - folder = (CamelNNTPFolder *)camel_store_get_folder ((CamelStore *)store, si->path, 0, NULL); + folder = (CamelNNTPFolder *) + camel_store_get_folder ( + (CamelStore *)store, si->path, + 0, cancellable, NULL); if (folder) { CamelFolderChangeInfo *changes = NULL; camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK); - camel_nntp_command (store, NULL, folder, &line, NULL); + camel_nntp_command (store, cancellable, NULL, folder, &line, NULL); if (camel_folder_change_info_changed (folder->changes)) { changes = folder->changes; folder->changes = camel_folder_change_info_new (); @@ -831,12 +941,29 @@ nntp_store_get_cached_folder_info (CamelNNTPStore *store, const gchar *orig_top, return first; } +static void +store_info_remove (gpointer key, gpointer value, gpointer data) +{ + CamelStoreSummary *summary = data; + CamelStoreInfo *si = value; + + camel_store_summary_remove (summary, si); +} + +static gint +store_info_sort (gconstpointer a, gconstpointer b) +{ + return strcmp ((*(CamelNNTPStoreInfo**) a)->full_name, (*(CamelNNTPStoreInfo**) b)->full_name); +} + /* retrieves the date from the NNTP server */ static gboolean -nntp_get_date (CamelNNTPStore *nntp_store, GError **error) +nntp_get_date (CamelNNTPStore *nntp_store, + GCancellable *cancellable, + GError **error) { guchar *line; - gint ret = camel_nntp_command(nntp_store, error, NULL, (gchar **)&line, "date"); + gint ret = camel_nntp_command(nntp_store, cancellable, error, NULL, (gchar **)&line, "date"); gchar *ptr; nntp_store->summary->last_newslist[0] = 0; @@ -854,23 +981,13 @@ nntp_get_date (CamelNNTPStore *nntp_store, GError **error) return FALSE; } -static void -store_info_remove (gpointer key, gpointer value, gpointer data) -{ - CamelStoreSummary *summary = data; - CamelStoreInfo *si = value; - - camel_store_summary_remove (summary, si); -} - -static gint -store_info_sort (gconstpointer a, gconstpointer b) -{ - return strcmp ((*(CamelNNTPStoreInfo**) a)->full_name, (*(CamelNNTPStoreInfo**) b)->full_name); -} - static CamelFolderInfo * -nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, guint32 flags, gboolean online, GError **error) +nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, + const gchar *top, + guint32 flags, + gboolean online, + GCancellable *cancellable, + GError **error) { CamelNNTPStoreSummary *summary = nntp_store->summary; CamelNNTPStoreInfo *si; @@ -894,10 +1011,10 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu date[13] = '\0'; /* Some servers don't support date (!), so fallback if they dont */ - if (!nntp_get_date (nntp_store, NULL)) + if (!nntp_get_date (nntp_store, cancellable, NULL)) goto do_complete_list_nodate; - ret = camel_nntp_command (nntp_store, error, NULL, (gchar **) &line, "newgroups %s", date); + ret = camel_nntp_command (nntp_store, cancellable, error, NULL, (gchar **) &line, "newgroups %s", date); if (ret == -1) goto error; else if (ret != 231) { @@ -906,7 +1023,7 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu goto do_complete_list; } - while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len, error)) > 0) + while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len, cancellable, error)) > 0) nntp_store_info_update (nntp_store, (gchar *) line); } else { GHashTable *all; @@ -915,9 +1032,9 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu do_complete_list: /* seems we do need a complete list */ /* at first, we do a DATE to find out the last load occasion */ - nntp_get_date (nntp_store, NULL); + nntp_get_date (nntp_store, cancellable, NULL); do_complete_list_nodate: - ret = camel_nntp_command (nntp_store, error, NULL, (gchar **)&line, "list"); + ret = camel_nntp_command (nntp_store, cancellable, error, NULL, (gchar **)&line, "list"); if (ret == -1) goto error; else if (ret != 215) { @@ -932,7 +1049,7 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu for (i = 0; (si = (CamelNNTPStoreInfo *)camel_store_summary_index ((CamelStoreSummary *)nntp_store->summary, i)); i++) g_hash_table_insert (all, si->info.path, si); - while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len, error)) > 0) { + while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len, cancellable, error)) > 0) { si = nntp_store_info_update (nntp_store, (gchar *) line); g_hash_table_remove (all, si->info.path); } @@ -957,7 +1074,12 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu } static CamelFolderInfo * -nntp_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, gboolean online, GError **error) +nntp_get_folder_info (CamelStore *store, + const gchar *top, + guint32 flags, + gboolean online, + GCancellable *cancellable, + GError **error) { CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); CamelFolderInfo *first = NULL; @@ -970,23 +1092,34 @@ nntp_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, gboole top?top:"")); if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) - first = nntp_store_get_subscribed_folder_info (nntp_store, top, flags, error); + first = nntp_store_get_subscribed_folder_info ( + nntp_store, top, flags, cancellable, error); else - first = nntp_store_get_folder_info_all (nntp_store, top, flags, online, error); + first = nntp_store_get_folder_info_all (nntp_store, top, flags, online, cancellable, error); return first; } static CamelFolderInfo * -nntp_get_folder_info_online (CamelStore *store, const gchar *top, guint32 flags, GError **error) +nntp_get_folder_info_online (CamelStore *store, + const gchar *top, + guint32 flags, + GCancellable *cancellable, + GError **error) { - return nntp_get_folder_info (store, top, flags, TRUE, error); + return nntp_get_folder_info ( + store, top, flags, TRUE, cancellable, error); } static CamelFolderInfo * -nntp_get_folder_info_offline (CamelStore *store, const gchar *top, guint32 flags, GError **error) +nntp_get_folder_info_offline (CamelStore *store, + const gchar *top, + guint32 flags, + GCancellable *cancellable, + GError **error) { - return nntp_get_folder_info (store, top, flags, FALSE, error); + return nntp_get_folder_info ( + store, top, flags, FALSE, cancellable, error); } static gboolean @@ -1006,8 +1139,10 @@ nntp_store_folder_is_subscribed (CamelStore *store, const gchar *folder_name) } static gboolean -nntp_store_subscribe_folder (CamelStore *store, const gchar *folder_name, - GError **error) +nntp_store_subscribe_folder (CamelStore *store, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); CamelStoreInfo *si; @@ -1045,8 +1180,10 @@ nntp_store_subscribe_folder (CamelStore *store, const gchar *folder_name, } static gboolean -nntp_store_unsubscribe_folder (CamelStore *store, const gchar *folder_name, - GError **error) +nntp_store_unsubscribe_folder (CamelStore *store, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); CamelFolderInfo *fi; @@ -1085,8 +1222,11 @@ nntp_store_unsubscribe_folder (CamelStore *store, const gchar *folder_name, /* stubs for various folder operations we're not implementing */ static CamelFolderInfo * -nntp_create_folder (CamelStore *store, const gchar *parent_name, - const gchar *folder_name, GError **error) +nntp_create_folder (CamelStore *store, + const gchar *parent_name, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { g_set_error ( error, CAMEL_FOLDER_ERROR, @@ -1098,7 +1238,11 @@ nntp_create_folder (CamelStore *store, const gchar *parent_name, } static gboolean -nntp_rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name_in, GError **error) +nntp_rename_folder (CamelStore *store, + const gchar *old_name, + const gchar *new_name_in, + GCancellable *cancellable, + GError **error) { g_set_error ( error, CAMEL_FOLDER_ERROR, @@ -1109,9 +1253,12 @@ nntp_rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_n } static gboolean -nntp_delete_folder (CamelStore *store, const gchar *folder_name, GError **error) +nntp_delete_folder (CamelStore *store, + const gchar *folder_name, + GCancellable *cancellable, + GError **error) { - nntp_store_unsubscribe_folder (store, folder_name, NULL); + nntp_store_unsubscribe_folder (store, folder_name, cancellable, NULL); g_set_error ( error, CAMEL_FOLDER_ERROR, @@ -1242,79 +1389,14 @@ camel_nntp_store_init (CamelNNTPStore *nntp_store) nntp_store->priv = CAMEL_NNTP_STORE_GET_PRIVATE (nntp_store); } -static gint -camel_nntp_try_authenticate (CamelNNTPStore *store, GError **error) -{ - CamelService *service = (CamelService *) store; - CamelSession *session = camel_service_get_session (service); - gint ret; - gchar *line = NULL; - GError *local_error = NULL; - - if (!service->url->user) { - g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, - _("Authentication requested but no username provided")); - return -1; - } - - /* if nessecary, prompt for the password */ - if (!service->url->passwd) { - gchar *prompt, *base; - retry: - base = camel_session_build_password_prompt ( - "NNTP", service->url->user, service->url->host); - if (line) { - gchar *top = g_markup_printf_escaped ( - _("Cannot authenticate to server: %s"), line); - - prompt = g_strdup_printf("%s\n\n%s", top, base); - g_free (top); - } else { - prompt = base; - base = NULL; - } - - service->url->passwd = - camel_session_get_password (session, service, NULL, - prompt, "password", CAMEL_SESSION_PASSWORD_SECRET | (store->password_reprompt ? CAMEL_SESSION_PASSWORD_REPROMPT : 0), error); - g_free (prompt); - g_free (base); - - if (!service->url->passwd) - return -1; - - store->password_reprompt = FALSE; - } - - /* now, send auth info (currently, only authinfo user/pass is supported) */ - ret = camel_nntp_raw_command(store, &local_error, &line, "authinfo user %s", service->url->user); - if (ret == NNTP_AUTH_CONTINUE) - ret = camel_nntp_raw_command(store, &local_error, &line, "authinfo pass %s", service->url->passwd); - - if (ret != NNTP_AUTH_ACCEPTED) { - if (ret != -1) { - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || - g_error_matches (local_error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE)) { - g_propagate_error (error, local_error); - return ret; - } - - /* To force password reprompt */ - store->password_reprompt = TRUE; - g_free (service->url->passwd); - service->url->passwd = NULL; - goto retry; - } - return -1; - } - - return ret; -} - /* Enter owning lock */ gint -camel_nntp_raw_commandv (CamelNNTPStore *store, GError **error, gchar **line, const gchar *fmt, va_list ap) +camel_nntp_raw_commandv (CamelNNTPStore *store, + GCancellable *cancellable, + GError **error, + gchar **line, + const gchar *fmt, + va_list ap) { GByteArray *byte_array; const guchar *p, *ps; @@ -1334,12 +1416,12 @@ camel_nntp_raw_commandv (CamelNNTPStore *store, GError **error, gchar **line, co switch (c) { case '%': c = *p++; - camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p - ps - (c == '%' ? 1 : 2), NULL); + camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p - ps - (c == '%' ? 1 : 2), NULL, NULL); ps = p; switch (c) { case 's': s = va_arg (ap, gchar *); - camel_stream_write ((CamelStream *)store->mem, s, strlen (s), NULL); + camel_stream_write ((CamelStream *)store->mem, s, strlen (s), NULL, NULL); break; case 'd': d = va_arg (ap, gint); @@ -1368,19 +1450,19 @@ camel_nntp_raw_commandv (CamelNNTPStore *store, GError **error, gchar **line, co } } - camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p-ps-1, NULL); - camel_stream_write ((CamelStream *) store->mem, "\r\n", 2, NULL); + camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p-ps-1, NULL, NULL); + camel_stream_write ((CamelStream *) store->mem, "\r\n", 2, NULL, NULL); byte_array = camel_stream_mem_get_byte_array (store->mem); - if (camel_stream_write ((CamelStream *) store->stream, (const gchar *) byte_array->data, byte_array->len, error) == -1) + if (camel_stream_write ((CamelStream *) store->stream, (const gchar *) byte_array->data, byte_array->len, cancellable, error) == -1) goto ioerror; /* FIXME: hack */ camel_stream_reset ((CamelStream *) store->mem, NULL); g_byte_array_set_size (byte_array, 0); - if (camel_nntp_stream_line (store->stream, (guchar **) line, &u, error) == -1) + if (camel_nntp_stream_line (store->stream, (guchar **) line, &u, cancellable, error) == -1) goto ioerror; u = strtoul (*line, NULL, 10); @@ -1397,13 +1479,18 @@ ioerror: } gint -camel_nntp_raw_command (CamelNNTPStore *store, GError **error, gchar **line, const gchar *fmt, ...) +camel_nntp_raw_command (CamelNNTPStore *store, + GCancellable *cancellable, + GError **error, + gchar **line, + const gchar *fmt, + ...) { gint ret; va_list ap; va_start (ap, fmt); - ret = camel_nntp_raw_commandv (store, error, line, fmt, ap); + ret = camel_nntp_raw_commandv (store, cancellable, error, line, fmt, ap); va_end (ap); return ret; @@ -1411,7 +1498,12 @@ camel_nntp_raw_command (CamelNNTPStore *store, GError **error, gchar **line, con /* use this where you also need auth to be handled, i.e. most cases where you'd try raw command */ gint -camel_nntp_raw_command_auth (CamelNNTPStore *store, GError **error, gchar **line, const gchar *fmt, ...) +camel_nntp_raw_command_auth (CamelNNTPStore *store, + GCancellable *cancellable, + GError **error, + gchar **line, + const gchar *fmt, + ...) { gint ret, retry, go; va_list ap; @@ -1423,11 +1515,11 @@ camel_nntp_raw_command_auth (CamelNNTPStore *store, GError **error, gchar **line retry++; va_start (ap, fmt); - ret = camel_nntp_raw_commandv (store, error, line, fmt, ap); + ret = camel_nntp_raw_commandv (store, cancellable, error, line, fmt, ap); va_end (ap); if (ret == NNTP_AUTH_REQUIRED) { - if (camel_nntp_try_authenticate (store, error) != NNTP_AUTH_ACCEPTED) + if (camel_nntp_try_authenticate (store, cancellable, error) != NNTP_AUTH_ACCEPTED) return -1; go = TRUE; } @@ -1437,7 +1529,13 @@ camel_nntp_raw_command_auth (CamelNNTPStore *store, GError **error, gchar **line } gint -camel_nntp_command (CamelNNTPStore *store, GError **error, CamelNNTPFolder *folder, gchar **line, const gchar *fmt, ...) +camel_nntp_command (CamelNNTPStore *store, + GCancellable *cancellable, + GError **error, + CamelNNTPFolder *folder, + gchar **line, + const gchar *fmt, + ...) { const gchar *full_name = NULL; const guchar *p; @@ -1468,18 +1566,18 @@ camel_nntp_command (CamelNNTPStore *store, GError **error, CamelNNTPFolder *fold /* Check for unprocessed data, !*/ if (store->stream->mode == CAMEL_NNTP_STREAM_DATA) { g_warning("Unprocessed data left in stream, flushing"); - while (camel_nntp_stream_getd (store->stream, (guchar **)&p, &u) > 0) + while (camel_nntp_stream_getd (store->stream, (guchar **)&p, &u, cancellable, error) > 0) ; } camel_nntp_stream_set_mode (store->stream, CAMEL_NNTP_STREAM_LINE); if (folder != NULL && (store->current_folder == NULL || strcmp (store->current_folder, full_name) != 0)) { - ret = camel_nntp_raw_command_auth(store, &local_error, line, "group %s", full_name); + ret = camel_nntp_raw_command_auth(store, cancellable, &local_error, line, "group %s", full_name); if (ret == 211) { g_free (store->current_folder); store->current_folder = g_strdup (full_name); - if (camel_nntp_folder_selected (folder, *line, &local_error) < 0) { + if (camel_nntp_folder_selected (folder, *line, NULL, &local_error) < 0) { ret = -1; goto error; } @@ -1493,12 +1591,12 @@ camel_nntp_command (CamelNNTPStore *store, GError **error, CamelNNTPFolder *fold return 0; va_start (ap, fmt); - ret = camel_nntp_raw_commandv (store, &local_error, line, fmt, ap); + ret = camel_nntp_raw_commandv (store, cancellable, &local_error, line, fmt, ap); va_end (ap); error: switch (ret) { case NNTP_AUTH_REQUIRED: - if (camel_nntp_try_authenticate (store, error) != NNTP_AUTH_ACCEPTED) + if (camel_nntp_try_authenticate (store, cancellable, error) != NNTP_AUTH_ACCEPTED) return -1; retry--; ret = -1; diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h index 1e968c2..074789a 100644 --- a/camel/providers/nntp/camel-nntp-store.h +++ b/camel/providers/nntp/camel-nntp-store.h @@ -109,10 +109,10 @@ struct _CamelNNTPStoreClass { GType camel_nntp_store_get_type (void); -gint camel_nntp_raw_commandv (CamelNNTPStore *store, struct _GError **error, gchar **line, const gchar *fmt, va_list ap); -gint camel_nntp_raw_command (CamelNNTPStore *store, struct _GError **error, gchar **line, const gchar *fmt, ...); -gint camel_nntp_raw_command_auth (CamelNNTPStore *store, struct _GError **error, gchar **line, const gchar *fmt, ...); -gint camel_nntp_command (CamelNNTPStore *store, struct _GError **error, struct _CamelNNTPFolder *folder, gchar **line, const gchar *fmt, ...); +gint camel_nntp_raw_commandv (CamelNNTPStore *store, GCancellable *cancellable, GError **error, gchar **line, const gchar *fmt, va_list ap); +gint camel_nntp_raw_command (CamelNNTPStore *store, GCancellable *cancellable, GError **error, gchar **line, const gchar *fmt, ...); +gint camel_nntp_raw_command_auth (CamelNNTPStore *store, GCancellable *cancellable, GError **error, gchar **line, const gchar *fmt, ...); +gint camel_nntp_command (CamelNNTPStore *store, GCancellable *cancellable, GError **error, struct _CamelNNTPFolder *folder, gchar **line, const gchar *fmt, ...); G_END_DECLS diff --git a/camel/providers/nntp/camel-nntp-stream.c b/camel/providers/nntp/camel-nntp-stream.c index 33d6605..bce5b68 100644 --- a/camel/providers/nntp/camel-nntp-stream.c +++ b/camel/providers/nntp/camel-nntp-stream.c @@ -70,6 +70,7 @@ nntp_stream_finalize (GObject *object) static gint nntp_stream_fill (CamelNNTPStream *is, + GCancellable *cancellable, GError **error) { gint left = 0; @@ -81,7 +82,8 @@ nntp_stream_fill (CamelNNTPStream *is, is->ptr = is->buf; left = camel_stream_read ( is->source, (gchar *) is->end, - CAMEL_NNTP_STREAM_SIZE - (is->end - is->buf), error); + CAMEL_NNTP_STREAM_SIZE - (is->end - is->buf), + cancellable, error); if (left > 0) { is->end += left; is->end[0] = '\n'; @@ -106,6 +108,7 @@ static gssize nntp_stream_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelNNTPStream *is = (CamelNNTPStream *)stream; @@ -129,7 +132,7 @@ nntp_stream_read (CamelStream *stream, case 0: /* start of line, always read at least 3 chars */ while (e - p < 3) { is->ptr = p; - if (nntp_stream_fill (is, error) == -1) + if (nntp_stream_fill (is, cancellable, error) == -1) return -1; p = is->ptr; e = is->end; @@ -153,7 +156,7 @@ nntp_stream_read (CamelStream *stream, /* end of input sentinal check */ if (p > e) { is->ptr = e; - if (nntp_stream_fill (is, error) == -1) + if (nntp_stream_fill (is, cancellable, error) == -1) return -1; p = is->ptr; e = is->end; @@ -181,15 +184,17 @@ static gssize nntp_stream_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelNNTPStream *is = (CamelNNTPStream *)stream; - return camel_stream_write (is->source, buffer, n, error); + return camel_stream_write (is->source, buffer, n, cancellable, error); } static gint nntp_stream_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { /* nop? */ @@ -198,6 +203,7 @@ nntp_stream_close (CamelStream *stream, static gint nntp_stream_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { /* nop? */ @@ -278,6 +284,7 @@ gint camel_nntp_stream_line (CamelNNTPStream *is, guchar **data, guint *len, + GCancellable *cancellable, GError **error) { register guchar c, *p, *o, *oe; @@ -300,7 +307,7 @@ camel_nntp_stream_line (CamelNNTPStream *is, /* need at least 3 chars in buffer */ while (e-p < 3) { is->ptr = p; - if (nntp_stream_fill (is, error) == -1) + if (nntp_stream_fill (is, cancellable, error) == -1) return -1; p = is->ptr; e = is->end; @@ -330,7 +337,7 @@ camel_nntp_stream_line (CamelNNTPStream *is, /* sentinal? */ if (p> e) { is->ptr = e; - if (nntp_stream_fill (is, error) == -1) + if (nntp_stream_fill (is, cancellable, error) == -1) return -1; p = is->ptr; e = is->end; @@ -363,7 +370,9 @@ camel_nntp_stream_line (CamelNNTPStream *is, gint camel_nntp_stream_gets (CamelNNTPStream *is, guchar **start, - guint *len) + guint *len, + GCancellable *cancellable, + GError **error) { gint max; guchar *end; @@ -372,7 +381,7 @@ camel_nntp_stream_gets (CamelNNTPStream *is, max = is->end - is->ptr; if (max == 0) { - max = nntp_stream_fill (is, NULL); + max = nntp_stream_fill (is, cancellable, error); if (max <= 0) return max; } @@ -401,7 +410,9 @@ camel_nntp_stream_set_mode (CamelNNTPStream *is, gint camel_nntp_stream_getd (CamelNNTPStream *is, guchar **start, - guint *len) + guint *len, + GCancellable *cancellable, + GError **error) { guchar *p, *e, *s; gint state; @@ -422,7 +433,7 @@ camel_nntp_stream_getd (CamelNNTPStream *is, while (e - p < 3) { is->ptr = p; - if (nntp_stream_fill (is, NULL) == -1) + if (nntp_stream_fill (is, cancellable, error) == -1) return -1; p = is->ptr; e = is->end; diff --git a/camel/providers/nntp/camel-nntp-stream.h b/camel/providers/nntp/camel-nntp-stream.h index 6675243..66f22e3 100644 --- a/camel/providers/nntp/camel-nntp-stream.h +++ b/camel/providers/nntp/camel-nntp-stream.h @@ -78,13 +78,18 @@ void camel_nntp_stream_set_mode (CamelNNTPStream *is, gint camel_nntp_stream_line (CamelNNTPStream *is, guchar **data, guint *len, + GCancellable *cancellable, GError **error); gint camel_nntp_stream_gets (CamelNNTPStream *is, guchar **start, - guint *len); + guint *len, + GCancellable *cancellable, + GError **error); gint camel_nntp_stream_getd (CamelNNTPStream *is, guchar **start, - guint *len); + guint *len, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c index b0df90d..1076171 100644 --- a/camel/providers/nntp/camel-nntp-summary.c +++ b/camel/providers/nntp/camel-nntp-summary.c @@ -220,7 +220,13 @@ summary_header_save (CamelFolderSummary *s, FILE *out) /* Note: This will be called from camel_nntp_command, so only use camel_nntp_raw_command */ static gint -add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint low, CamelFolderChangeInfo *changes, GError **error) +add_range_xover (CamelNNTPSummary *cns, + CamelNNTPStore *store, + guint high, + guint low, + CamelFolderChangeInfo *changes, + GCancellable *cancellable, + GError **error) { CamelFolderSummary *s; CamelMessageInfoBase *mi; @@ -235,14 +241,16 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint s = (CamelFolderSummary *)cns; summary_table = camel_folder_summary_get_hashtable (s); - camel_operation_start (NULL, _("%s: Scanning new messages"), ((CamelService *)store)->url->host); + camel_operation_start ( + cancellable, _("%s: Scanning new messages"), + ((CamelService *)store)->url->host); - ret = camel_nntp_raw_command_auth (store, error, &line, "over %r", low, high); + ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "over %r", low, high); if (ret != 224) - ret = camel_nntp_raw_command_auth (store, error, &line, "xover %r", low, high); + ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "xover %r", low, high); if (ret != 224) { - camel_operation_end (NULL); + camel_operation_end (cancellable); if (ret != -1) g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, @@ -252,8 +260,8 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint count = 0; total = high-low+1; - while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len, error)) > 0) { - camel_operation_progress (NULL, (count * 100) / total); + while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len, cancellable, error)) > 0) { + camel_operation_progress (cancellable, (count * 100) / total); count++; n = strtoul (line, &tab, 10); if (*tab != '\t') @@ -295,7 +303,8 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint /* truncated line? ignore? */ if (xover == NULL) { if (!GPOINTER_TO_INT (g_hash_table_lookup (summary_table, cns->priv->uid))) { - mi = (CamelMessageInfoBase *)camel_folder_summary_add_from_header (s, headers); + mi = (CamelMessageInfoBase *) + camel_folder_summary_add_from_header (s, headers); if (mi) { mi->size = size; cns->high = n; @@ -312,7 +321,7 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint camel_header_raw_clear (&headers); } - camel_operation_end (NULL); + camel_operation_end (cancellable); camel_folder_summary_free_hashtable (summary_table); @@ -321,7 +330,13 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint /* Note: This will be called from camel_nntp_command, so only use camel_nntp_raw_command */ static gint -add_range_head (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint low, CamelFolderChangeInfo *changes, GError **error) +add_range_head (CamelNNTPSummary *cns, + CamelNNTPStore *store, + guint high, + guint low, + CamelFolderChangeInfo *changes, + GCancellable *cancellable, + GError **error) { CamelFolderSummary *s; gint ret = -1; @@ -337,14 +352,16 @@ add_range_head (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint mp = camel_mime_parser_new (); - camel_operation_start (NULL, _("%s: Scanning new messages"), ((CamelService *)store)->url->host); + camel_operation_start ( + cancellable, _("%s: Scanning new messages"), + ((CamelService *)store)->url->host); count = 0; total = high-low+1; for (i=low;ihigh < f) cns->high = f-1; - if (store->xover) { - ret = add_range_xover (cns, store, l, cns->high+1, changes, error); - } else { - ret = add_range_head (cns, store, l, cns->high+1, changes, error); - } + if (store->xover) + ret = add_range_xover ( + cns, store, l, cns->high+1, + changes, cancellable, error); + else + ret = add_range_head ( + cns, store, l, cns->high+1, + changes, cancellable, error); } /* TODO: not from here */ diff --git a/camel/providers/nntp/camel-nntp-summary.h b/camel/providers/nntp/camel-nntp-summary.h index 39c3f2c..98236e0 100644 --- a/camel/providers/nntp/camel-nntp-summary.h +++ b/camel/providers/nntp/camel-nntp-summary.h @@ -63,10 +63,16 @@ struct _CamelNNTPSummaryClass { CamelFolderSummaryClass parent_class; }; -GType camel_nntp_summary_get_type (void); -CamelNNTPSummary *camel_nntp_summary_new (struct _CamelFolder *folder, const gchar *path); - -gint camel_nntp_summary_check (CamelNNTPSummary *cns, struct _CamelNNTPStore *store, gchar *line, struct _CamelFolderChangeInfo *changes, struct _GError **error); +GType camel_nntp_summary_get_type (void); +CamelNNTPSummary * + camel_nntp_summary_new (CamelFolder *folder, + const gchar *path); +gint camel_nntp_summary_check (CamelNNTPSummary *cns, + struct _CamelNNTPStore *store, + gchar *line, + CamelFolderChangeInfo *changes, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/nntp/camel-nntp-types.h b/camel/providers/nntp/camel-nntp-types.h deleted file mode 100644 index b31eb0d..0000000 --- a/camel/providers/nntp/camel-nntp-types.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-grouplist.h : getting/updating the list of newsgroups on the server. */ - -/* - * Author : Chris Toshok - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU Lesser General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef CAMEL_NNTP_TYPES_H -#define CAMEL_NNTP_TYPES_H - -G_BEGIN_DECLS - -typedef struct CamelNNTPGroupList CamelNNTPGroupList; -typedef struct CamelNNTPGroupListEntry CamelNNTPGroupListEntry; -typedef struct CamelNNTPOverField CamelNNTPOverField; -typedef struct CamelNNTPStore CamelNNTPStore; -typedef struct CamelNNTPStoreClass CamelNNTPStoreClass; - -G_END_DECLS - -#endif /* CAMEL_NNTP_TYPES_H */ diff --git a/camel/providers/pop3/camel-pop3-engine.c b/camel/providers/pop3/camel-pop3-engine.c index e8eec31..2fe371c 100644 --- a/camel/providers/pop3/camel-pop3-engine.c +++ b/camel/providers/pop3/camel-pop3-engine.c @@ -252,7 +252,7 @@ engine_command_queue (CamelPOP3Engine *pe, CamelPOP3Command *pc) } /* ??? */ - if (camel_stream_write ((CamelStream *)pe->stream, pc->data, strlen (pc->data), NULL) == -1) { + if (camel_stream_write ((CamelStream *)pe->stream, pc->data, strlen (pc->data), NULL, NULL) == -1) { camel_dlist_addtail (&pe->queue, (CamelDListNode *)pc); return FALSE; } @@ -333,7 +333,7 @@ camel_pop3_engine_iterate (CamelPOP3Engine *pe, CamelPOP3Command *pcwait) && pe->current != NULL) break; - if (camel_stream_write ((CamelStream *)pe->stream, pw->data, strlen (pw->data), NULL) == -1) + if (camel_stream_write ((CamelStream *)pe->stream, pw->data, strlen (pw->data), NULL, NULL) == -1) goto ioerror; camel_dlist_remove ((CamelDListNode *)pw); diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c index b77129e..c01e8eb 100644 --- a/camel/providers/pop3/camel-pop3-folder.c +++ b/camel/providers/pop3/camel-pop3-folder.c @@ -38,99 +38,45 @@ #define d(x) -static gboolean pop3_refresh_info (CamelFolder *folder, GError **error); -static gboolean pop3_sync (CamelFolder *folder, gboolean expunge, GError **error); -static gint pop3_get_message_count (CamelFolder *folder); -static GPtrArray *pop3_get_uids (CamelFolder *folder); -static CamelMimeMessage *pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error); -static gboolean pop3_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set); -static gchar * pop3_get_filename (CamelFolder *folder, const gchar *uid, GError **error); - G_DEFINE_TYPE (CamelPOP3Folder, camel_pop3_folder, CAMEL_TYPE_FOLDER) static void -pop3_folder_dispose (GObject *object) +cmd_uidl (CamelPOP3Engine *pe, + CamelPOP3Stream *stream, + gpointer data) { - CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (object); - CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata; - CamelPOP3Store *pop3_store; - CamelStore *parent_store; - gint i; - - parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (object)); - if (parent_store) { - pop3_store = CAMEL_POP3_STORE (parent_store); + gint ret; + guint len; + guchar *line; + gchar uid[1025]; + guint id; + CamelPOP3FolderInfo *fi; + CamelPOP3Folder *folder = data; - if (pop3_folder->uids) { - for (i = 0; i < pop3_folder->uids->len; i++, fi++) { - if (fi[0]->cmd) { - while (camel_pop3_engine_iterate (pop3_store->engine, fi[0]->cmd) > 0) - ; - camel_pop3_engine_command_free (pop3_store->engine, fi[0]->cmd); + do { + ret = camel_pop3_stream_line(stream, &line, &len); + if (ret>=0) { + if (strlen((gchar *) line) > 1024) + line[1024] = 0; + if (sscanf((gchar *) line, "%u %s", &id, uid) == 2) { + fi = g_hash_table_lookup(folder->uids_id, GINT_TO_POINTER(id)); + if (fi) { + camel_operation_progress (NULL, (fi->index+1) * 100 / folder->uids->len); + fi->uid = g_strdup(uid); + g_hash_table_insert(folder->uids_uid, fi->uid, fi); + } else { + g_warning("ID %u (uid: %s) not in previous LIST output", id, uid); } - - g_free (fi[0]->uid); - g_free (fi[0]); } - - g_ptr_array_free (pop3_folder->uids, TRUE); - g_hash_table_destroy (pop3_folder->uids_uid); } - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (camel_pop3_folder_parent_class)->dispose (object); -} - -static void -camel_pop3_folder_class_init (CamelPOP3FolderClass *class) -{ - GObjectClass *object_class; - CamelFolderClass *folder_class; - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = pop3_folder_dispose; - - folder_class = CAMEL_FOLDER_CLASS (class); - folder_class->refresh_info = pop3_refresh_info; - folder_class->sync = pop3_sync; - folder_class->get_message_count = pop3_get_message_count; - folder_class->get_uids = pop3_get_uids; - folder_class->free_uids = camel_folder_free_shallow; - folder_class->get_filename = pop3_get_filename; - folder_class->get_message = pop3_get_message; - folder_class->set_message_flags = pop3_set_message_flags; -} - -static void -camel_pop3_folder_init (CamelPOP3Folder *pop3_folder) -{ -} - -CamelFolder * -camel_pop3_folder_new (CamelStore *parent, GError **error) -{ - CamelFolder *folder; - - d(printf("opening pop3 INBOX folder\n")); - - folder = g_object_new ( - CAMEL_TYPE_POP3_FOLDER, - "full-name", "inbox", "name", "inbox", - "parent-store", parent, NULL); - - /* mt-ok, since we dont have the folder-lock for new() */ - if (!camel_folder_refresh_info (folder, error)) { /* mt-ok */ - g_object_unref (folder); - folder = NULL; - } - - return folder; + } while (ret>0); } /* create a uid from md5 of 'top' output */ static void -cmd_builduid (CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data) +cmd_builduid (CamelPOP3Engine *pe, + CamelPOP3Stream *stream, + gpointer data) { GChecksum *checksum; CamelPOP3FolderInfo *fi = data; @@ -206,37 +152,88 @@ cmd_list (CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data) } static void -cmd_uidl (CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data) +cmd_tocache (CamelPOP3Engine *pe, + CamelPOP3Stream *stream, + gpointer data) { - gint ret; - guint len; - guchar *line; - gchar uid[1025]; - guint id; - CamelPOP3FolderInfo *fi; - CamelPOP3Folder *folder = data; + CamelPOP3FolderInfo *fi = data; + gchar buffer[2048]; + gint w = 0, n; - do { - ret = camel_pop3_stream_line (stream, &line, &len); - if (ret>=0) { - if (strlen ((gchar *) line) > 1024) - line[1024] = 0; - if (sscanf((gchar *) line, "%u %s", &id, uid) == 2) { - fi = g_hash_table_lookup (folder->uids_id, GINT_TO_POINTER (id)); - if (fi) { - camel_operation_progress (NULL, (fi->index+1) * 100 / folder->uids->len); - fi->uid = g_strdup (uid); - g_hash_table_insert (folder->uids_uid, fi->uid, fi); - } else { - g_warning("ID %u (uid: %s) not in previous LIST output", id, uid); + /* What if it fails? */ + + /* We write an '*' to the start of the stream to say its not complete yet */ + /* This should probably be part of the cache code */ + if ((n = camel_stream_write (fi->stream, "*", 1, NULL, NULL)) == -1) + goto done; + + while ((n = camel_stream_read((CamelStream *)stream, buffer, sizeof(buffer), NULL, NULL)) > 0) { + n = camel_stream_write(fi->stream, buffer, n, NULL, NULL); + if (n == -1) + break; + + w += n; + if (w > fi->size) + w = fi->size; + if (fi->size != 0) + camel_operation_progress(NULL, (w * 100) / fi->size); + } + + /* it all worked, output a '#' to say we're a-ok */ + if (n != -1) { + camel_stream_reset(fi->stream, NULL); + n = camel_stream_write(fi->stream, "#", 1, NULL, NULL); + } +done: + if (n == -1) { + fi->err = errno; + g_warning("POP3 retrieval failed: %s", g_strerror(errno)); + } else { + fi->err = 0; + } + + g_object_unref (fi->stream); + fi->stream = NULL; +} + +static void +pop3_folder_dispose (GObject *object) +{ + CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (object); + CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata; + CamelPOP3Store *pop3_store; + CamelStore *parent_store; + gint i; + + parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (object)); + if (parent_store) { + pop3_store = CAMEL_POP3_STORE (parent_store); + + if (pop3_folder->uids) { + for (i = 0; i < pop3_folder->uids->len; i++, fi++) { + if (fi[0]->cmd) { + while (camel_pop3_engine_iterate (pop3_store->engine, fi[0]->cmd) > 0) + ; + camel_pop3_engine_command_free (pop3_store->engine, fi[0]->cmd); } + + g_free (fi[0]->uid); + g_free (fi[0]); } + + g_ptr_array_free (pop3_folder->uids, TRUE); + g_hash_table_destroy (pop3_folder->uids_uid); } - } while (ret>0); + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (camel_pop3_folder_parent_class)->dispose (object); } static gboolean -pop3_refresh_info (CamelFolder *folder, GError **error) +pop3_folder_refresh_info (CamelFolder *folder, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelPOP3Store *pop3_store; @@ -248,7 +245,7 @@ pop3_refresh_info (CamelFolder *folder, GError **error) parent_store = camel_folder_get_parent_store (folder); pop3_store = CAMEL_POP3_STORE (parent_store); - camel_operation_start (NULL, _("Retrieving POP summary")); + camel_operation_start (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); @@ -297,15 +294,16 @@ pop3_refresh_info (CamelFolder *folder, GError **error) /* dont need this anymore */ g_hash_table_destroy (pop3_folder->uids_id); - camel_operation_end (NULL); + camel_operation_end (cancellable); return success; } static gboolean -pop3_sync (CamelFolder *folder, - gboolean expunge, - GError **error) +pop3_folder_sync (CamelFolder *folder, + gboolean expunge, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelPOP3Folder *pop3_folder; @@ -321,15 +319,17 @@ pop3_sync (CamelFolder *folder, if (pop3_store->delete_after && !expunge) { d(printf("%s(%d): pop3_store->delete_after = [%d], expunge=[%d]\n", __FILE__, __LINE__, pop3_store->delete_after, expunge)); - camel_operation_start(NULL, _("Expunging old messages")); - camel_pop3_delete_old (folder, pop3_store->delete_after, error); + camel_operation_start (cancellable, _("Expunging old messages")); + camel_pop3_delete_old ( + folder, pop3_store->delete_after, + cancellable, error); } if (!expunge) { return TRUE; } - camel_operation_start(NULL, _("Expunging deleted messages")); + camel_operation_start (cancellable, _("Expunging deleted messages")); for (i = 0; i < pop3_folder->uids->len; i++) { fi = pop3_folder->uids->pdata[i]; @@ -364,189 +364,45 @@ pop3_sync (CamelFolder *folder, camel_pop3_engine_command_free (pop3_store->engine, fi->cmd); fi->cmd = NULL; } - camel_operation_progress (NULL, (i+1) * 100 / pop3_folder->uids->len); + camel_operation_progress ( + cancellable, (i+1) * 100 / pop3_folder->uids->len); } - camel_operation_end (NULL); + camel_operation_end (cancellable); camel_pop3_store_expunge (pop3_store, error); return TRUE; } -static gboolean -pop3_get_message_time_from_cache (CamelFolder *folder, const gchar *uid, time_t *message_time) +static gint +pop3_folder_get_message_count (CamelFolder *folder) { - CamelStore *parent_store; - CamelPOP3Store *pop3_store; - CamelStream *stream = NULL; - gchar buffer[1]; - gboolean res = FALSE; - - g_return_val_if_fail (folder != NULL, FALSE); - g_return_val_if_fail (uid != NULL, FALSE); - g_return_val_if_fail (message_time != NULL, FALSE); - - parent_store = camel_folder_get_parent_store (folder); - pop3_store = CAMEL_POP3_STORE (parent_store); - - g_return_val_if_fail (pop3_store->cache != NULL, FALSE); - - if ((stream = camel_data_cache_get (pop3_store->cache, "cache", uid, NULL)) != NULL - && camel_stream_read (stream, buffer, 1, NULL) == 1 - && buffer[0] == '#') { - CamelMimeMessage *message; - - message = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, stream, NULL) == -1) { - g_warning (_("Cannot get message %s: %s"), uid, g_strerror (errno)); - g_object_unref (message); - message = NULL; - } - - if (message) { - res = TRUE; - *message_time = message->date + message->date_offset; - - g_object_unref (message); - } - } + CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder); - if (stream) { - g_object_unref (stream); - } - return res; + return pop3_folder->uids->len; } -gint -camel_pop3_delete_old (CamelFolder *folder, - gint days_to_delete, - GError **error) +static GPtrArray * +pop3_folder_get_uids (CamelFolder *folder) { - CamelStore *parent_store; - CamelPOP3Folder *pop3_folder; - CamelPOP3FolderInfo *fi; + CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder); + GPtrArray *uids = g_ptr_array_new(); + CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata; gint i; - CamelPOP3Store *pop3_store; - CamelMimeMessage *message; - time_t temp, message_time = 0; - - parent_store = camel_folder_get_parent_store (folder); - pop3_folder = CAMEL_POP3_FOLDER (folder); - pop3_store = CAMEL_POP3_STORE (parent_store); - temp = time (&temp); - - d(printf("%s(%d): pop3_folder->uids->len=[%d]\n", __FILE__, __LINE__, pop3_folder->uids->len)); - for (i = 0; i < pop3_folder->uids->len; i++) { - fi = pop3_folder->uids->pdata[i]; - - d(printf("%s(%d): fi->uid=[%s]\n", __FILE__, __LINE__, fi->uid)); - if (!pop3_get_message_time_from_cache (folder, fi->uid, &message_time)) { - d(printf("could not get message time from cache, trying from pop3\n")); - message = pop3_get_message (folder, fi->uid, error); - if (message) { - message_time = message->date + message->date_offset; - g_object_unref (message); - } - } - - if (message_time) { - gdouble time_diff = difftime (temp,message_time); - gint day_lag = time_diff/(60*60*24); - - d(printf("%s(%d): message_time= [%ld]\n", __FILE__, __LINE__, message_time)); - d(printf("%s(%d): day_lag=[%d] \t days_to_delete=[%d]\n", - __FILE__, __LINE__, day_lag, days_to_delete)); - - if (day_lag > days_to_delete) { - if (fi->cmd) { - while (camel_pop3_engine_iterate (pop3_store->engine, fi->cmd) > 0) { - ; /* do nothing - iterating until end */ - } - - camel_pop3_engine_command_free (pop3_store->engine, fi->cmd); - fi->cmd = NULL; - } - d(printf("%s(%d): Deleting old messages\n", __FILE__, __LINE__)); - fi->cmd = camel_pop3_engine_command_new (pop3_store->engine, - 0, - NULL, - NULL, - "DELE %u\r\n", - fi->id); - /* also remove from cache */ - if (pop3_store->cache && fi->uid) { - camel_data_cache_remove(pop3_store->cache, "cache", fi->uid, NULL); - } - } - } - } - - for (i = 0; i < pop3_folder->uids->len; i++) { - fi = pop3_folder->uids->pdata[i]; - /* wait for delete commands to finish */ - if (fi->cmd) { - while (camel_pop3_engine_iterate (pop3_store->engine, fi->cmd) > 0) - ; - camel_pop3_engine_command_free (pop3_store->engine, fi->cmd); - fi->cmd = NULL; - } - camel_operation_progress (NULL, (i+1) * 100 / pop3_folder->uids->len); - } - - camel_operation_end (NULL); - - camel_pop3_store_expunge (pop3_store, error); - - return 0; -} - -static void -cmd_tocache (CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data) -{ - CamelPOP3FolderInfo *fi = data; - gchar buffer[2048]; - gint w = 0, n; - - /* What if it fails? */ - - /* We write an '*' to the start of the stream to say its not complete yet */ - /* This should probably be part of the cache code */ - if ((n = camel_stream_write (fi->stream, "*", 1, NULL)) == -1) - goto done; - - while ((n = camel_stream_read ((CamelStream *)stream, buffer, sizeof (buffer), NULL)) > 0) { - n = camel_stream_write (fi->stream, buffer, n, NULL); - if (n == -1) - break; - - w += n; - if (w > fi->size) - w = fi->size; - if (fi->size != 0) - camel_operation_progress (NULL, (w * 100) / fi->size); - } - - /* it all worked, output a '#' to say we're a-ok */ - if (n != -1) { - camel_stream_reset (fi->stream, NULL); - n = camel_stream_write(fi->stream, "#", 1, NULL); - } -done: - if (n == -1) { - fi->err = errno; - g_warning("POP3 retrieval failed: %s", g_strerror(errno)); - } else { - fi->err = 0; + for (i=0;iuids->len;i++,fi++) { + if (fi[0]->uid) + g_ptr_array_add(uids, fi[0]->uid); } - g_object_unref (fi->stream); - fi->stream = NULL; + return uids; } static gchar * -pop3_get_filename (CamelFolder *folder, const gchar *uid, GError **error) +pop3_folder_get_filename (CamelFolder *folder, + const gchar *uid, + GError **error) { CamelStore *parent_store; CamelPOP3Folder *pop3_folder; @@ -558,7 +414,7 @@ pop3_get_filename (CamelFolder *folder, const gchar *uid, GError **error) pop3_folder = CAMEL_POP3_FOLDER (folder); pop3_store = CAMEL_POP3_STORE (parent_store); - fi = g_hash_table_lookup (pop3_folder->uids_uid, uid); + fi = g_hash_table_lookup(pop3_folder->uids_uid, uid); if (fi == NULL) { g_set_error ( error, CAMEL_FOLDER_ERROR, @@ -567,11 +423,15 @@ pop3_get_filename (CamelFolder *folder, const gchar *uid, GError **error) return NULL; } - return camel_data_cache_get_filename (pop3_store->cache, "cache", fi->uid, NULL); + return camel_data_cache_get_filename ( + pop3_store->cache, "cache", fi->uid, NULL); } static CamelMimeMessage * -pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error) +pop3_folder_get_message (CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelMimeMessage *message = NULL; @@ -600,7 +460,8 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error) /* Sigh, most of the crap in this function is so that the cancel button returns the proper exception code. Sigh. */ - camel_operation_start_transient(NULL, _("Retrieving POP message %d"), fi->id); + camel_operation_start_transient ( + cancellable, _("Retrieving POP message %d"), fi->id); /* If we have an oustanding retrieve message running, wait for that to complete & then retrieve from cache, otherwise, start a new one, and similar */ @@ -636,7 +497,7 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error) /* check to see if we have safely written flag set */ if (pop3_store->cache == NULL || (stream = camel_data_cache_get(pop3_store->cache, "cache", fi->uid, NULL)) == NULL - || camel_stream_read (stream, buffer, 1, NULL) != 1 + || camel_stream_read (stream, buffer, 1, cancellable, NULL) != 1 || buffer[0] != '#') { /* Initiate retrieval, if disk backing fails, use a memory backing */ @@ -697,7 +558,8 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error) goto done; } - if (camel_stream_read (stream, buffer, 1, error) == -1) + if (camel_stream_read ( + stream, buffer, 1, cancellable, error) == -1) goto done; if (buffer[0] != '#') { @@ -710,7 +572,8 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error) } message = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, stream, error) == -1) { + if (camel_data_wrapper_construct_from_stream ( + CAMEL_DATA_WRAPPER (message), stream, cancellable, error) == -1) { g_prefix_error (error, _("Cannot get message %s: "), uid); g_object_unref (message); message = NULL; @@ -718,13 +581,16 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error) done: g_object_unref (stream); fail: - camel_operation_end (NULL); + camel_operation_end (cancellable); return message; } static gboolean -pop3_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set) +pop3_folder_set_message_flags (CamelFolder *folder, + const gchar *uid, + guint32 flags, + guint32 set) { CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder); CamelPOP3FolderInfo *fi; @@ -743,26 +609,182 @@ pop3_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, gu return res; } -static gint -pop3_get_message_count (CamelFolder *folder) +static void +camel_pop3_folder_class_init (CamelPOP3FolderClass *class) { - CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder); + GObjectClass *object_class; + CamelFolderClass *folder_class; - return pop3_folder->uids->len; + object_class = G_OBJECT_CLASS (class); + object_class->dispose = pop3_folder_dispose; + + folder_class = CAMEL_FOLDER_CLASS (class); + folder_class->refresh_info = pop3_folder_refresh_info; + folder_class->sync = pop3_folder_sync; + folder_class->get_message_count = pop3_folder_get_message_count; + folder_class->get_uids = pop3_folder_get_uids; + folder_class->free_uids = camel_folder_free_shallow; + folder_class->get_filename = pop3_folder_get_filename; + folder_class->get_message = pop3_folder_get_message; + folder_class->set_message_flags = pop3_folder_set_message_flags; } -static GPtrArray * -pop3_get_uids (CamelFolder *folder) +static void +camel_pop3_folder_init (CamelPOP3Folder *pop3_folder) { - CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder); - GPtrArray *uids = g_ptr_array_new (); - CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata; +} + +CamelFolder * +camel_pop3_folder_new (CamelStore *parent, + GCancellable *cancellable, + GError **error) +{ + CamelFolder *folder; + + d(printf("opening pop3 INBOX folder\n")); + + folder = g_object_new ( + CAMEL_TYPE_POP3_FOLDER, + "full-name", "inbox", "name", "inbox", + "parent-store", parent, NULL); + + /* mt-ok, since we dont have the folder-lock for new() */ + if (!camel_folder_refresh_info (folder, cancellable, error)) { + g_object_unref (folder); + folder = NULL; + } + + return folder; +} + +static gboolean +pop3_get_message_time_from_cache (CamelFolder *folder, const gchar *uid, time_t *message_time) +{ + CamelStore *parent_store; + CamelPOP3Store *pop3_store; + CamelStream *stream = NULL; + gchar buffer[1]; + gboolean res = FALSE; + + g_return_val_if_fail (folder != NULL, FALSE); + g_return_val_if_fail (uid != NULL, FALSE); + g_return_val_if_fail (message_time != NULL, FALSE); + + parent_store = camel_folder_get_parent_store (folder); + pop3_store = CAMEL_POP3_STORE (parent_store); + + g_return_val_if_fail (pop3_store->cache != NULL, FALSE); + + if ((stream = camel_data_cache_get (pop3_store->cache, "cache", uid, NULL)) != NULL + && camel_stream_read (stream, buffer, 1, NULL, NULL) == 1 + && buffer[0] == '#') { + CamelMimeMessage *message; + + message = camel_mime_message_new (); + if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, stream, NULL, NULL) == -1) { + g_warning (_("Cannot get message %s: %s"), uid, g_strerror (errno)); + g_object_unref (message); + message = NULL; + } + + if (message) { + res = TRUE; + *message_time = message->date + message->date_offset; + + g_object_unref (message); + } + } + + if (stream) { + g_object_unref (stream); + } + return res; +} + +gint +camel_pop3_delete_old (CamelFolder *folder, + gint days_to_delete, + GCancellable *cancellable, + GError **error) +{ + CamelStore *parent_store; + CamelPOP3Folder *pop3_folder; + CamelPOP3FolderInfo *fi; gint i; + CamelPOP3Store *pop3_store; + CamelMimeMessage *message; + time_t temp, message_time = 0; - for (i=0;iuids->len;i++,fi++) { - if (fi[0]->uid) - g_ptr_array_add (uids, fi[0]->uid); + parent_store = camel_folder_get_parent_store (folder); + + pop3_folder = CAMEL_POP3_FOLDER (folder); + pop3_store = CAMEL_POP3_STORE (parent_store); + temp = time(&temp); + + d(printf("%s(%d): pop3_folder->uids->len=[%d]\n", __FILE__, __LINE__, pop3_folder->uids->len)); + for (i = 0; i < pop3_folder->uids->len; i++) { + fi = pop3_folder->uids->pdata[i]; + + d(printf("%s(%d): fi->uid=[%s]\n", __FILE__, __LINE__, fi->uid)); + if (!pop3_get_message_time_from_cache (folder, fi->uid, &message_time)) { + d(printf("could not get message time from cache, trying from pop3\n")); + message = pop3_folder_get_message ( + folder, fi->uid, cancellable, error); + if (message) { + message_time = message->date + message->date_offset; + g_object_unref (message); + } + } + + if (message_time) { + gdouble time_diff = difftime(temp,message_time); + gint day_lag = time_diff/(60*60*24); + + d(printf("%s(%d): message_time= [%ld]\n", __FILE__, __LINE__, message_time)); + d(printf("%s(%d): day_lag=[%d] \t days_to_delete=[%d]\n", + __FILE__, __LINE__, day_lag, days_to_delete)); + + if (day_lag > days_to_delete) { + if (fi->cmd) { + while (camel_pop3_engine_iterate(pop3_store->engine, fi->cmd) > 0) { + ; /* do nothing - iterating until end */ + } + + camel_pop3_engine_command_free(pop3_store->engine, fi->cmd); + fi->cmd = NULL; + } + d(printf("%s(%d): Deleting old messages\n", __FILE__, __LINE__)); + fi->cmd = camel_pop3_engine_command_new(pop3_store->engine, + 0, + NULL, + NULL, + "DELE %u\r\n", + fi->id); + /* also remove from cache */ + if (pop3_store->cache && fi->uid) { + camel_data_cache_remove(pop3_store->cache, "cache", fi->uid, NULL); + } + } + } } - return uids; + for (i = 0; i < pop3_folder->uids->len; i++) { + fi = pop3_folder->uids->pdata[i]; + /* wait for delete commands to finish */ + if (fi->cmd) { + while (camel_pop3_engine_iterate(pop3_store->engine, fi->cmd) > 0) + ; + camel_pop3_engine_command_free(pop3_store->engine, fi->cmd); + fi->cmd = NULL; + } + camel_operation_progress ( + cancellable, (i+1) * 100 / pop3_folder->uids->len); + } + + camel_operation_end (cancellable); + + camel_pop3_store_expunge (pop3_store, error); + + return 0; } + diff --git a/camel/providers/pop3/camel-pop3-folder.h b/camel/providers/pop3/camel-pop3-folder.h index d5edd0d..6a5592a 100644 --- a/camel/providers/pop3/camel-pop3-folder.h +++ b/camel/providers/pop3/camel-pop3-folder.h @@ -76,12 +76,14 @@ struct _CamelPOP3FolderClass { CamelFolderClass parent_class; }; -/* public methods */ -CamelFolder *camel_pop3_folder_new (CamelStore *parent, GError **error); - -GType camel_pop3_folder_get_type (void); - -gint camel_pop3_delete_old (CamelFolder *folder, gint days_to_delete, GError **error); +GType camel_pop3_folder_get_type (void); +CamelFolder * camel_pop3_folder_new (CamelStore *parent, + GCancellable *cancellable, + GError **error); +gint camel_pop3_delete_old (CamelFolder *folder, + gint days_to_delete, + GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c index 1c92143..39cc238 100644 --- a/camel/providers/pop3/camel-pop3-store.c +++ b/camel/providers/pop3/camel-pop3-store.c @@ -103,8 +103,11 @@ get_valid_utf8_error (const gchar *text) static gboolean connect_to_server (CamelService *service, - const gchar *host, const gchar *serv, gint fallback_port, + const gchar *host, + const gchar *serv, + gint fallback_port, gint ssl_mode, + GCancellable *cancellable, GError **error) { CamelPOP3Store *store = CAMEL_POP3_STORE (service); @@ -141,17 +144,21 @@ connect_to_server (CamelService *service, camel_session_get_socks_proxy (session, &socks_host, &socks_port); if (socks_host) { - camel_tcp_stream_set_socks_proxy ((CamelTcpStream *) tcp_stream, socks_host, socks_port); + camel_tcp_stream_set_socks_proxy ( + CAMEL_TCP_STREAM (tcp_stream), + socks_host, socks_port); g_free (socks_host); } - if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, host, serv, fallback_port, error) == -1) { + if (camel_tcp_stream_connect ( + CAMEL_TCP_STREAM (tcp_stream), host, serv, + fallback_port, cancellable, error) == -1) { g_object_unref (tcp_stream); return FALSE; } /* parent class connect initialization */ - if (CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class)->connect (service, error) == FALSE) { + if (CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class)->connect (service, cancellable, error) == FALSE) { g_object_unref (tcp_stream); return FALSE; } @@ -252,6 +259,7 @@ connect_to_server (CamelService *service, static gboolean connect_to_server_wrapper (CamelService *service, + GCancellable *cancellable, GError **error) { const gchar *ssl_mode; @@ -278,12 +286,15 @@ connect_to_server_wrapper (CamelService *service, fallback_port = 0; } - return connect_to_server (service, service->url->host, serv, fallback_port, mode, error); + return connect_to_server ( + service, service->url->host, serv, + fallback_port, mode, cancellable, error); } static gint try_sasl (CamelPOP3Store *store, const gchar *mech, + GCancellable *cancellable, GError **error) { CamelPOP3Stream *stream = store->engine->stream; @@ -330,8 +341,8 @@ try_sasl (CamelPOP3Store *store, /* If we dont get continuation, or the sasl object's run out of work, or we dont get a challenge, its a protocol error, so fail, and try reset the server */ if (strncmp((gchar *) line, "+ ", 2) != 0 - || camel_sasl_get_authenticated (sasl) - || (resp = (guchar *) camel_sasl_challenge_base64 (sasl, (const gchar *) line+2, error)) == NULL) { + || camel_sasl_get_authenticated(sasl) + || (resp = (guchar *) camel_sasl_challenge_base64(sasl, (const gchar *) line+2, cancellable, NULL)) == NULL) { camel_stream_printf((CamelStream *)stream, "*\r\n"); camel_pop3_stream_line (stream, &line, &len); g_set_error ( @@ -366,6 +377,7 @@ static gint pop3_try_authenticate (CamelService *service, gboolean reprompt, const gchar *errmsg, + GCancellable *cancellable, GError **error) { CamelPOP3Store *store = (CamelPOP3Store *)service; @@ -441,8 +453,10 @@ pop3_try_authenticate (CamelService *service, l = store->engine->auth; while (l) { auth = l->data; - if (strcmp (auth->authproto, service->url->authmech) == 0) - return try_sasl (store, service->url->authmech, error); + if (strcmp(auth->authproto, service->url->authmech) == 0) + return try_sasl ( + store, service->url->authmech, + cancellable, error); l = l->next; } @@ -452,6 +466,7 @@ pop3_try_authenticate (CamelService *service, _("Unable to connect to POP server %s: " "No support for requested authentication mechanism."), CAMEL_SERVICE (store)->url->host); + return 0; } @@ -530,6 +545,7 @@ pop3_store_finalize (GObject *object) static gboolean pop3_store_connect (CamelService *service, + GCancellable *cancellable, GError **error) { CamelPOP3Store *store = (CamelPOP3Store *)service; @@ -556,12 +572,13 @@ pop3_store_connect (CamelService *service, } } - if (!connect_to_server_wrapper (service, error)) + if (!connect_to_server_wrapper (service, cancellable, error)) return FALSE; while (1) { status = pop3_try_authenticate ( - service, reprompt, errbuf, &local_error); + service, reprompt, errbuf, + cancellable, &local_error); g_free (errbuf); errbuf = NULL; @@ -600,6 +617,7 @@ pop3_store_connect (CamelService *service, static gboolean pop3_store_disconnect (CamelService *service, gboolean clean, + GCancellable *cancellable, GError **error) { CamelServiceClass *service_class; @@ -616,7 +634,7 @@ pop3_store_disconnect (CamelService *service, /* Chain up to parent's disconnect() method. */ service_class = CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class); - if (!service_class->disconnect (service, clean, error)) + if (!service_class->disconnect (service, clean, cancellable, error)) return FALSE; g_object_unref (store->engine); @@ -627,6 +645,7 @@ pop3_store_disconnect (CamelService *service, static GList * pop3_store_query_auth_types (CamelService *service, + GCancellable *cancellable, GError **error) { CamelServiceClass *service_class; @@ -636,16 +655,17 @@ pop3_store_query_auth_types (CamelService *service, /* Chain up to parent's query_auth_types() method. */ service_class = CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class); - types = service_class->query_auth_types (service, &local_error); + types = service_class->query_auth_types ( + service, cancellable, &local_error); if (local_error != NULL) { g_propagate_error (error, local_error); return NULL; } - if (connect_to_server_wrapper (service, NULL)) { + if (connect_to_server_wrapper (service, cancellable, NULL)) { types = g_list_concat (types, g_list_copy (store->engine->auth)); - pop3_store_disconnect (service, TRUE, NULL); + pop3_store_disconnect (service, TRUE, cancellable, NULL); } else { g_set_error ( error, CAMEL_SERVICE_ERROR, @@ -676,6 +696,7 @@ static CamelFolder * pop3_store_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, + GCancellable *cancellable, GError **error) { if (g_ascii_strcasecmp (folder_name, "inbox") != 0) { @@ -686,11 +707,12 @@ pop3_store_get_folder (CamelStore *store, return NULL; } - return camel_pop3_folder_new (store, error); + return camel_pop3_folder_new (store, cancellable, error); } static CamelFolder * pop3_store_get_trash (CamelStore *store, + GCancellable *cancellable, GError **error) { /* no-op */ @@ -701,6 +723,7 @@ static CamelFolderInfo * pop3_store_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, + GCancellable *cancellable, GError **error) { g_set_error ( diff --git a/camel/providers/pop3/camel-pop3-stream.c b/camel/providers/pop3/camel-pop3-stream.c index 39ed3c5..76f8d91 100644 --- a/camel/providers/pop3/camel-pop3-stream.c +++ b/camel/providers/pop3/camel-pop3-stream.c @@ -69,6 +69,7 @@ pop3_stream_finalize (GObject *object) static gint stream_fill (CamelPOP3Stream *is, + GCancellable *cancellable, GError **error) { gint left = 0; @@ -80,7 +81,8 @@ stream_fill (CamelPOP3Stream *is, is->ptr = is->buf; left = camel_stream_read ( is->source, (gchar *) is->end, - CAMEL_POP3_STREAM_SIZE - (is->end - is->buf), error); + CAMEL_POP3_STREAM_SIZE - (is->end - is->buf), + cancellable, error); if (left > 0) { is->end += left; is->end[0] = '\n'; @@ -96,6 +98,7 @@ static gssize stream_read (CamelStream *stream, gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelPOP3Stream *is = (CamelPOP3Stream *)stream; @@ -119,7 +122,7 @@ stream_read (CamelStream *stream, case 0: /* start of line, always read at least 3 chars */ while (e - p < 3) { is->ptr = p; - if (stream_fill (is, error) == -1) + if (stream_fill (is, cancellable, error) == -1) return -1; p = is->ptr; e = is->end; @@ -143,7 +146,7 @@ stream_read (CamelStream *stream, /* end of input sentinal check */ if (p > e) { is->ptr = e; - if (stream_fill (is, error) == -1) + if (stream_fill (is, cancellable, error) == -1) return -1; p = is->ptr; e = is->end; @@ -171,6 +174,7 @@ static gssize stream_write (CamelStream *stream, const gchar *buffer, gsize n, + GCancellable *cancellable, GError **error) { CamelPOP3Stream *is = (CamelPOP3Stream *)stream; @@ -180,11 +184,12 @@ stream_write (CamelStream *stream, else dd (printf ("POP3_STREAM_WRITE (%d):\nPASS xxxxxxxx\n", (gint)n)); - return camel_stream_write (is->source, buffer, n, error); + return camel_stream_write (is->source, buffer, n, cancellable, error); } static gint stream_close (CamelStream *stream, + GCancellable *cancellable, GError **error) { /* nop? */ @@ -193,6 +198,7 @@ stream_close (CamelStream *stream, static gint stream_flush (CamelStream *stream, + GCancellable *cancellable, GError **error) { /* nop? */ @@ -292,7 +298,7 @@ camel_pop3_stream_line (CamelPOP3Stream *is, guchar **data, guint *len) /* need at least 3 chars in buffer */ while (e-p < 3) { is->ptr = p; - if (stream_fill (is, NULL) == -1) + if (stream_fill (is, NULL, NULL) == -1) return -1; p = is->ptr; e = is->end; @@ -322,7 +328,7 @@ camel_pop3_stream_line (CamelPOP3Stream *is, guchar **data, guint *len) /* sentinal? */ if (p> e) { is->ptr = e; - if (stream_fill (is, NULL) == -1) + if (stream_fill (is, NULL, NULL) == -1) return -1; p = is->ptr; e = is->end; @@ -363,7 +369,7 @@ gint camel_pop3_stream_gets (CamelPOP3Stream *is, guchar **start, guint *len) max = is->end - is->ptr; if (max == 0) { - max = stream_fill (is, NULL); + max = stream_fill (is, NULL, NULL); if (max <= 0) return max; } @@ -408,7 +414,7 @@ gint camel_pop3_stream_getd (CamelPOP3Stream *is, guchar **start, guint *len) while (e - p < 3) { is->ptr = p; - if (stream_fill (is, NULL) == -1) + if (stream_fill (is, NULL, NULL) == -1) return -1; p = is->ptr; e = is->end; diff --git a/camel/providers/sendmail/camel-sendmail-transport.c b/camel/providers/sendmail/camel-sendmail-transport.c index d857dad..5226bac 100644 --- a/camel/providers/sendmail/camel-sendmail-transport.c +++ b/camel/providers/sendmail/camel-sendmail-transport.c @@ -37,31 +37,18 @@ #include "camel-sendmail-transport.h" -static gchar *get_name (CamelService *service, gboolean brief); +G_DEFINE_TYPE ( + CamelSendmailTransport, + camel_sendmail_transport, CAMEL_TYPE_TRANSPORT) -static gboolean sendmail_send_to (CamelTransport *transport, - CamelMimeMessage *message, - CamelAddress *from, CamelAddress *recipients, - GError **error); - -G_DEFINE_TYPE (CamelSendmailTransport, camel_sendmail_transport, CAMEL_TYPE_TRANSPORT) - -static void -camel_sendmail_transport_class_init (CamelSendmailTransportClass *class) -{ - CamelServiceClass *service_class; - CamelTransportClass *transport_class; - - service_class = CAMEL_SERVICE_CLASS (class); - service_class->get_name = get_name; - - transport_class = CAMEL_TRANSPORT_CLASS (class); - transport_class->send_to = sendmail_send_to; -} - -static void -camel_sendmail_transport_init (CamelSendmailTransport *sendmail_transport) +static gchar * +sendmail_get_name (CamelService *service, + gboolean brief) { + if (brief) + return g_strdup (_("sendmail")); + else + return g_strdup (_("Mail delivery via the sendmail program")); } static gboolean @@ -69,6 +56,7 @@ sendmail_send_to (CamelTransport *transport, CamelMimeMessage *message, CamelAddress *from, CamelAddress *recipients, + GCancellable *cancellable, GError **error) { struct _camel_header_raw *header, *savedbcc, *n, *tail; @@ -188,8 +176,8 @@ sendmail_send_to (CamelTransport *transport, out = (CamelStream *) filter; if (camel_data_wrapper_write_to_stream ( - CAMEL_DATA_WRAPPER (message), out, error) == -1 - || camel_stream_close (out, error) == -1) { + CAMEL_DATA_WRAPPER (message), out, cancellable, error) == -1 + || camel_stream_close (out, cancellable, error) == -1) { g_object_unref (CAMEL_OBJECT (out)); g_prefix_error (error, _("Could not send message: ")); @@ -241,11 +229,21 @@ sendmail_send_to (CamelTransport *transport, return TRUE; } -static gchar * -get_name (CamelService *service, gboolean brief) +static void +camel_sendmail_transport_class_init (CamelSendmailTransportClass *class) +{ + CamelServiceClass *service_class; + CamelTransportClass *transport_class; + + service_class = CAMEL_SERVICE_CLASS (class); + service_class->get_name = sendmail_get_name; + + transport_class = CAMEL_TRANSPORT_CLASS (class); + transport_class->send_to = sendmail_send_to; +} + +static void +camel_sendmail_transport_init (CamelSendmailTransport *sendmail_transport) { - if (brief) - return g_strdup (_("sendmail")); - else - return g_strdup (_("Mail delivery via the sendmail program")); } + diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c index 428b3c8..09c4748 100644 --- a/camel/providers/smtp/camel-smtp-transport.c +++ b/camel/providers/smtp/camel-smtp-transport.c @@ -54,121 +54,42 @@ extern gint camel_verbose_debug; #define SMTP_PORT 25 #define SMTPS_PORT 465 -/* camel smtp transport class prototypes */ -static gboolean smtp_send_to (CamelTransport *transport, CamelMimeMessage *message, - CamelAddress *from, CamelAddress *recipients, GError **error); - /* support prototypes */ -static gboolean smtp_connect (CamelService *service, GError **error); -static gboolean smtp_disconnect (CamelService *service, gboolean clean, GError **error); -static GHashTable *esmtp_get_authtypes (const guchar *buffer); -static GList *query_auth_types (CamelService *service, GError **error); -static gchar *get_name (CamelService *service, gboolean brief); - -static gboolean smtp_helo (CamelSmtpTransport *transport, GError **error); -static gboolean smtp_auth (CamelSmtpTransport *transport, const gchar *mech, GError **error); -static gboolean smtp_mail (CamelSmtpTransport *transport, const gchar *sender, - gboolean has_8bit_parts, GError **error); -static gboolean smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error); -static gboolean smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **error); -static gboolean smtp_rset (CamelSmtpTransport *transport, GError **error); -static gboolean smtp_quit (CamelSmtpTransport *transport, GError **error); - -static void smtp_set_error (CamelSmtpTransport *transport, const gchar *respbuf, GError **error); - -G_DEFINE_TYPE (CamelSmtpTransport, camel_smtp_transport, CAMEL_TYPE_TRANSPORT) - -static void -camel_smtp_transport_class_init (CamelSmtpTransportClass *class) -{ - CamelTransportClass *transport_class; - CamelServiceClass *service_class; - - service_class = CAMEL_SERVICE_CLASS (class); - service_class->connect = smtp_connect; - service_class->disconnect = smtp_disconnect; - service_class->query_auth_types = query_auth_types; - service_class->get_name = get_name; - - transport_class = CAMEL_TRANSPORT_CLASS (class); - transport_class->send_to = smtp_send_to; -} - -static void -camel_smtp_transport_init (CamelSmtpTransport *smtp) -{ - smtp->flags = 0; - smtp->connected = FALSE; -} - -static const gchar * -smtp_error_string (gint error) -{ - /* SMTP error codes grabbed from rfc821 */ - switch (error) { - case 0: - /* looks like a read problem, check errno */ - if (errno) - return g_strerror (errno); - else - return _("Unknown"); - case 500: - return _("Syntax error, command unrecognized"); - case 501: - return _("Syntax error in parameters or arguments"); - case 502: - return _("Command not implemented"); - case 504: - return _("Command parameter not implemented"); - case 211: - return _("System status, or system help reply"); - case 214: - return _("Help message"); - case 220: - return _("Service ready"); - case 221: - return _("Service closing transmission channel"); - case 421: - return _("Service not available, closing transmission channel"); - case 250: - return _("Requested mail action okay, completed"); - case 251: - return _("User not local; will forward to "); - case 450: - return _("Requested mail action not taken: mailbox unavailable"); - case 550: - return _("Requested action not taken: mailbox unavailable"); - case 451: - return _("Requested action aborted: error in processing"); - case 551: - return _("User not local; please try "); - case 452: - return _("Requested action not taken: insufficient system storage"); - case 552: - return _("Requested mail action aborted: exceeded storage allocation"); - case 553: - return _("Requested action not taken: mailbox name not allowed"); - case 354: - return _("Start mail input; end with ."); - case 554: - return _("Transaction failed"); - - /* AUTH error codes: */ - case 432: - return _("A password transition is needed"); - case 534: - return _("Authentication mechanism is too weak"); - case 538: - return _("Encryption required for requested authentication mechanism"); - case 454: - return _("Temporary authentication failure"); - case 530: - return _("Authentication required"); - - default: - return _("Unknown"); - } -} +static gboolean smtp_disconnect (CamelService *service, + gboolean clean, + GCancellable *cancellable, + GError **error); +static GHashTable * esmtp_get_authtypes (const guchar *buffer); +static gboolean smtp_helo (CamelSmtpTransport *transport, + GCancellable *cancellable, + GError **error); +static gboolean smtp_auth (CamelSmtpTransport *transport, + const gchar *mech, + GCancellable *cancellable, + GError **error); +static gboolean smtp_mail (CamelSmtpTransport *transport, + const gchar *sender, + gboolean has_8bit_parts, + GCancellable *cancellable, + GError **error); +static gboolean smtp_rcpt (CamelSmtpTransport *transport, + const gchar *recipient, + GCancellable *cancellable, + GError **error); +static gboolean smtp_data (CamelSmtpTransport *transport, + CamelMimeMessage *message, + GCancellable *cancellable, + GError **error); +static gboolean smtp_rset (CamelSmtpTransport *transport, + GCancellable *cancellable, + GError **error); +static gboolean smtp_quit (CamelSmtpTransport *transport, + GCancellable *cancellable, + GError **error); +static void smtp_set_error (CamelSmtpTransport *transport, + const gchar *respbuf, + GCancellable *cancellable, + GError **error); enum { MODE_CLEAR, @@ -181,10 +102,28 @@ enum { #define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS) #endif +static struct { + const gchar *value; + const gchar *serv; + gint fallback_port; + gint mode; +} ssl_options[] = { + { "", "smtps", SMTPS_PORT, MODE_SSL }, /* really old (1.x) */ + { "always", "smtps", SMTPS_PORT, MODE_SSL }, + { "when-possible", "smtp", SMTP_PORT, MODE_TLS }, + { "never", "smtp", SMTP_PORT, MODE_CLEAR }, + { NULL, "smtp", SMTP_PORT, MODE_CLEAR } +}; + +G_DEFINE_TYPE (CamelSmtpTransport, camel_smtp_transport, CAMEL_TYPE_TRANSPORT) + static gboolean connect_to_server (CamelService *service, - const gchar *host, const gchar *serv, gint fallback_port, + const gchar *host, + const gchar *serv, + gint fallback_port, gint ssl_mode, + GCancellable *cancellable, GError **error) { CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service); @@ -194,7 +133,8 @@ connect_to_server (CamelService *service, CamelStream *tcp_stream; gchar *respbuf = NULL; - if (!CAMEL_SERVICE_CLASS (camel_smtp_transport_parent_class)->connect (service, error)) + if (!CAMEL_SERVICE_CLASS (camel_smtp_transport_parent_class)-> + connect (service, cancellable, error)) return FALSE; /* set some smtp transport defaults */ @@ -225,11 +165,15 @@ connect_to_server (CamelService *service, camel_session_get_socks_proxy (session, &socks_host, &socks_port); if (socks_host) { - camel_tcp_stream_set_socks_proxy ((CamelTcpStream *) tcp_stream, socks_host, socks_port); + camel_tcp_stream_set_socks_proxy ( + CAMEL_TCP_STREAM (tcp_stream), + socks_host, socks_port); g_free (socks_host); } - if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, host, serv, fallback_port, error) == -1) { + if (camel_tcp_stream_connect ( + CAMEL_TCP_STREAM (tcp_stream), host, serv, + fallback_port, cancellable, error) == -1) { g_object_unref (tcp_stream); return FALSE; } @@ -247,14 +191,16 @@ connect_to_server (CamelService *service, /* Check for "220" */ g_free (respbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); if (respbuf == NULL) { g_prefix_error (error, _("Welcome response error: ")); transport->connected = FALSE; return FALSE; } if (strncmp (respbuf, "220", 3)) { - smtp_set_error (transport, respbuf, error); + smtp_set_error ( + transport, respbuf, cancellable, error); g_prefix_error (error, _("Welcome response error: ")); g_free (respbuf); return FALSE; @@ -264,7 +210,7 @@ connect_to_server (CamelService *service, /* Try sending EHLO */ transport->flags |= CAMEL_SMTP_TRANSPORT_IS_ESMTP; - if (!smtp_helo (transport, error)) { + if (!smtp_helo (transport, cancellable, error)) { if (!transport->connected) return FALSE; @@ -272,7 +218,7 @@ connect_to_server (CamelService *service, g_clear_error (error); transport->flags &= ~CAMEL_SMTP_TRANSPORT_IS_ESMTP; - if (!smtp_helo (transport, error)) { + if (!smtp_helo (transport, cancellable, error)) { camel_service_disconnect ((CamelService *) transport, TRUE, NULL); return FALSE; @@ -298,7 +244,8 @@ connect_to_server (CamelService *service, } d(fprintf (stderr, "sending : STARTTLS\r\n")); - if (camel_stream_write (tcp_stream, "STARTTLS\r\n", 10, error) == -1) { + if (camel_stream_write ( + tcp_stream, "STARTTLS\r\n", 10, cancellable, error) == -1) { g_prefix_error (error, _("STARTTLS command failed: ")); goto exception_cleanup; } @@ -309,14 +256,16 @@ connect_to_server (CamelService *service, /* Check for "220 Ready for TLS" */ g_free (respbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); if (respbuf == NULL) { g_prefix_error (error, _("STARTTLS command failed: ")); transport->connected = FALSE; goto exception_cleanup; } if (strncmp (respbuf, "220", 3) != 0) { - smtp_set_error (transport, respbuf, error); + smtp_set_error ( + transport, respbuf, cancellable, error); g_prefix_error (error, _("STARTTLS command failed: ")); g_free (respbuf); goto exception_cleanup; @@ -342,7 +291,7 @@ connect_to_server (CamelService *service, /* We are supposed to re-EHLO after a successful STARTTLS to re-fetch any supported extensions. */ - if (!smtp_helo (transport, error)) { + if (!smtp_helo (transport, cancellable, error)) { camel_service_disconnect ((CamelService *) transport, TRUE, NULL); return FALSE; @@ -362,21 +311,9 @@ connect_to_server (CamelService *service, return FALSE; } -static struct { - const gchar *value; - const gchar *serv; - gint fallback_port; - gint mode; -} ssl_options[] = { - { "", "smtps", SMTPS_PORT, MODE_SSL }, /* really old (1.x) */ - { "always", "smtps", SMTPS_PORT, MODE_SSL }, - { "when-possible", "smtp", SMTP_PORT, MODE_TLS }, - { "never", "smtp", SMTP_PORT, MODE_CLEAR }, - { NULL, "smtp", SMTP_PORT, MODE_CLEAR }, -}; - static gboolean connect_to_server_wrapper (CamelService *service, + GCancellable *cancellable, GError **error) { const gchar *ssl_mode; @@ -403,11 +340,21 @@ connect_to_server_wrapper (CamelService *service, fallback_port = 0; } - return connect_to_server (service, service->url->host, serv, fallback_port, mode, error); + return connect_to_server ( + service, service->url->host, serv, + fallback_port, mode, cancellable, error); +} + +static void +authtypes_free (gpointer key, gpointer value, gpointer data) +{ + g_free (value); } static gboolean -smtp_connect (CamelService *service, GError **error) +smtp_connect (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service); gboolean has_authtypes; @@ -419,7 +366,7 @@ smtp_connect (CamelService *service, GError **error) CamelSasl *sasl; sasl = camel_sasl_new ("smtp", "POPB4SMTP", service); - chal = camel_sasl_challenge (sasl, NULL, error); + chal = camel_sasl_challenge (sasl, NULL, cancellable, error); truth = camel_sasl_get_authenticated (sasl); if (chal) g_byte_array_free (chal, TRUE); @@ -428,10 +375,10 @@ smtp_connect (CamelService *service, GError **error) if (!truth) return FALSE; - return connect_to_server_wrapper (service, error); + return connect_to_server_wrapper (service, cancellable, error); } - if (!connect_to_server_wrapper (service, error)) + if (!connect_to_server_wrapper (service, cancellable, error)) return FALSE; /* check to see if AUTH is required, if so...then AUTH ourselves */ @@ -469,7 +416,8 @@ smtp_connect (CamelService *service, GError **error) /* authentication mechanism doesn't need a password, so if it fails there's nothing we can do */ authenticated = smtp_auth ( - transport, authtype->authproto, error); + transport, authtype->authproto, + cancellable, error); if (!authenticated) { camel_service_disconnect (service, TRUE, NULL); return FALSE; @@ -516,9 +464,10 @@ smtp_connect (CamelService *service, GError **error) } authenticated = smtp_auth ( - transport, authtype->authproto, &local_error); + transport, authtype->authproto, + cancellable, &local_error); if (!authenticated) { - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || + if (g_cancellable_is_cancelled (cancellable) || g_error_matches (local_error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE)) return FALSE; @@ -543,15 +492,10 @@ smtp_connect (CamelService *service, GError **error) return TRUE; } -static void -authtypes_free (gpointer key, gpointer value, gpointer data) -{ - g_free (value); -} - static gboolean smtp_disconnect (CamelService *service, gboolean clean, + GCancellable *cancellable, GError **error) { CamelServiceClass *service_class; @@ -563,12 +507,12 @@ smtp_disconnect (CamelService *service, if (transport->connected && clean) { /* send the QUIT command to the SMTP server */ - smtp_quit (transport, NULL); + smtp_quit (transport, cancellable, NULL); } /* Chain up to parent's disconnect() method. */ service_class = CAMEL_SERVICE_CLASS (camel_smtp_transport_parent_class); - if (!service_class->disconnect (service, clean, error)) + if (!service_class->disconnect (service, clean, cancellable, error)) return FALSE; if (transport->authtypes) { @@ -595,54 +539,20 @@ smtp_disconnect (CamelService *service, return TRUE; } -static GHashTable * -esmtp_get_authtypes (const guchar *buffer) -{ - const guchar *start, *end; - GHashTable *table = NULL; - - /* advance to the first token */ - start = buffer; - while (isspace ((gint) *start) || *start == '=') - start++; - - if (!*start) - return NULL; - - table = g_hash_table_new (g_str_hash, g_str_equal); - - for (; *start; ) { - gchar *type; - - /* advance to the end of the token */ - end = start; - while (*end && !isspace ((gint) *end)) - end++; - - type = g_strndup ((gchar *) start, end - start); - g_hash_table_insert (table, type, type); - - /* advance to the next token */ - start = end; - while (isspace ((gint) *start)) - start++; - } - - return table; -} - static GList * -query_auth_types (CamelService *service, GError **error) +smtp_query_auth_types (CamelService *service, + GCancellable *cancellable, + GError **error) { CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service); CamelServiceAuthType *authtype; GList *types, *t, *next; - if (!connect_to_server_wrapper (service, error)) + if (!connect_to_server_wrapper (service, cancellable, error)) return NULL; if (!transport->authtypes) { - smtp_disconnect (service, TRUE, NULL); + smtp_disconnect (service, TRUE, cancellable, NULL); return NULL; } @@ -657,26 +567,31 @@ query_auth_types (CamelService *service, GError **error) } } - smtp_disconnect (service, TRUE, NULL); + smtp_disconnect (service, TRUE, cancellable, NULL); return types; } static gchar * -get_name (CamelService *service, gboolean brief) +smtp_get_name (CamelService *service, gboolean brief) { if (brief) - return g_strdup_printf (_("SMTP server %s"), service->url->host); - else { - return g_strdup_printf (_("SMTP mail delivery via %s"), - service->url->host); - } + return g_strdup_printf ( + _("SMTP server %s"), + service->url->host); + else + return g_strdup_printf ( + _("SMTP mail delivery via %s"), + service->url->host); } static gboolean -smtp_send_to (CamelTransport *transport, CamelMimeMessage *message, - CamelAddress *from, CamelAddress *recipients, - GError **error) +smtp_send_to (CamelTransport *transport, + CamelMimeMessage *message, + CamelAddress *from, + CamelAddress *recipients, + GCancellable *cancellable, + GError **error) { CamelSmtpTransport *smtp_transport = CAMEL_SMTP_TRANSPORT (transport); CamelInternetAddress *cia; @@ -699,15 +614,16 @@ smtp_send_to (CamelTransport *transport, CamelMimeMessage *message, return FALSE; } - camel_operation_start (NULL, _("Sending message")); + camel_operation_start (cancellable, _("Sending message")); /* find out if the message has 8bit mime parts */ has_8bit_parts = camel_mime_message_has_8bit_parts (message); /* rfc1652 (8BITMIME) requires that you notify the ESMTP daemon that you'll be sending an 8bit mime message at "MAIL FROM:" time. */ - if (!smtp_mail (smtp_transport, addr, has_8bit_parts, error)) { - camel_operation_end (NULL); + if (!smtp_mail ( + smtp_transport, addr, has_8bit_parts, cancellable, error)) { + camel_operation_end (cancellable); return FALSE; } @@ -716,7 +632,7 @@ smtp_send_to (CamelTransport *transport, CamelMimeMessage *message, g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Cannot send message: no recipients defined.")); - camel_operation_end (NULL); + camel_operation_end (cancellable); return FALSE; } @@ -729,32 +645,160 @@ smtp_send_to (CamelTransport *transport, CamelMimeMessage *message, error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Cannot send message: " "one or more invalid recipients")); - camel_operation_end (NULL); + camel_operation_end (cancellable); return FALSE; } enc = camel_internet_address_encode_address (NULL, NULL, addr); - if (!smtp_rcpt (smtp_transport, enc, error)) { + if (!smtp_rcpt (smtp_transport, enc, cancellable, error)) { g_free (enc); - camel_operation_end (NULL); + camel_operation_end (cancellable); return FALSE; } g_free (enc); } - if (!smtp_data (smtp_transport, message, error)) { - camel_operation_end (NULL); + if (!smtp_data (smtp_transport, message, cancellable, error)) { + camel_operation_end (cancellable); return FALSE; } /* reset the service for our next transfer session */ - smtp_rset (smtp_transport, NULL); + smtp_rset (smtp_transport, cancellable, NULL); - camel_operation_end (NULL); + camel_operation_end (cancellable); return TRUE; } +static void +camel_smtp_transport_class_init (CamelSmtpTransportClass *class) +{ + CamelTransportClass *transport_class; + CamelServiceClass *service_class; + + service_class = CAMEL_SERVICE_CLASS (class); + service_class->connect = smtp_connect; + service_class->disconnect = smtp_disconnect; + service_class->query_auth_types = smtp_query_auth_types; + service_class->get_name = smtp_get_name; + + transport_class = CAMEL_TRANSPORT_CLASS (class); + transport_class->send_to = smtp_send_to; +} + +static void +camel_smtp_transport_init (CamelSmtpTransport *smtp) +{ + smtp->flags = 0; + smtp->connected = FALSE; +} + +static const gchar * +smtp_error_string (gint error) +{ + /* SMTP error codes grabbed from rfc821 */ + switch (error) { + case 0: + /* looks like a read problem, check errno */ + if (errno) + return g_strerror (errno); + else + return _("Unknown"); + case 500: + return _("Syntax error, command unrecognized"); + case 501: + return _("Syntax error in parameters or arguments"); + case 502: + return _("Command not implemented"); + case 504: + return _("Command parameter not implemented"); + case 211: + return _("System status, or system help reply"); + case 214: + return _("Help message"); + case 220: + return _("Service ready"); + case 221: + return _("Service closing transmission channel"); + case 421: + return _("Service not available, closing transmission channel"); + case 250: + return _("Requested mail action okay, completed"); + case 251: + return _("User not local; will forward to "); + case 450: + return _("Requested mail action not taken: mailbox unavailable"); + case 550: + return _("Requested action not taken: mailbox unavailable"); + case 451: + return _("Requested action aborted: error in processing"); + case 551: + return _("User not local; please try "); + case 452: + return _("Requested action not taken: insufficient system storage"); + case 552: + return _("Requested mail action aborted: exceeded storage allocation"); + case 553: + return _("Requested action not taken: mailbox name not allowed"); + case 354: + return _("Start mail input; end with ."); + case 554: + return _("Transaction failed"); + + /* AUTH error codes: */ + case 432: + return _("A password transition is needed"); + case 534: + return _("Authentication mechanism is too weak"); + case 538: + return _("Encryption required for requested authentication mechanism"); + case 454: + return _("Temporary authentication failure"); + case 530: + return _("Authentication required"); + + default: + return _("Unknown"); + } +} + +static GHashTable * +esmtp_get_authtypes (const guchar *buffer) +{ + const guchar *start, *end; + GHashTable *table = NULL; + + /* advance to the first token */ + start = buffer; + while (isspace ((gint) *start) || *start == '=') + start++; + + if (!*start) + return NULL; + + table = g_hash_table_new (g_str_hash, g_str_equal); + + for (; *start; ) { + gchar *type; + + /* advance to the end of the token */ + end = start; + while (*end && !isspace ((gint) *end)) + end++; + + type = g_strndup ((gchar *) start, end - start); + g_hash_table_insert (table, type, type); + + /* advance to the next token */ + start = end; + while (isspace ((gint) *start)) + start++; + } + + return table; +} + static const gchar * smtp_next_token (const gchar *buf) { @@ -863,6 +907,7 @@ convert_to_local (GString *str) static void smtp_set_error (CamelSmtpTransport *transport, const gchar *respbuf, + GCancellable *cancellable, GError **error) { const gchar *token, *rbuf = respbuf; @@ -901,7 +946,8 @@ smtp_set_error (CamelSmtpTransport *transport, if (*(rbuf + 3) == '-') { g_free (buffer); buffer = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), NULL); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, NULL); g_string_append_c (string, '\n'); } else { g_free (buffer); @@ -944,7 +990,9 @@ smtp_set_error (CamelSmtpTransport *transport, } static gboolean -smtp_helo (CamelSmtpTransport *transport, GError **error) +smtp_helo (CamelSmtpTransport *transport, + GCancellable *cancellable, + GError **error) { gchar *name = NULL, *cmdbuf = NULL, *respbuf = NULL; const gchar *token, *numeric = NULL; @@ -963,12 +1011,14 @@ smtp_helo (CamelSmtpTransport *transport, GError **error) transport->authtypes = NULL; } - camel_operation_start_transient (NULL, _("SMTP Greeting")); + camel_operation_start_transient (cancellable, _("SMTP Greeting")); addr = transport->localaddr; addrlen = transport->localaddrlen; - if (camel_getnameinfo (addr, addrlen, &name, NULL, NI_NUMERICHOST, NULL) != 0) { + if (camel_getnameinfo ( + addr, addrlen, &name, NULL, + NI_NUMERICHOST, cancellable, NULL) != 0) { name = g_strdup ("localhost.localdomain"); } else { if (addr->sa_family == AF_INET6) @@ -985,10 +1035,11 @@ smtp_helo (CamelSmtpTransport *transport, GError **error) g_free (name); d(fprintf (stderr, "sending : %s", cmdbuf)); - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) { + if (camel_stream_write_string ( + transport->ostream, cmdbuf, cancellable, error) == -1) { g_free (cmdbuf); g_prefix_error (error, _("HELO command failed: ")); - camel_operation_end (NULL); + camel_operation_end (cancellable); camel_service_disconnect ((CamelService *) transport, FALSE, NULL); @@ -1000,17 +1051,19 @@ smtp_helo (CamelSmtpTransport *transport, GError **error) /* Check for "250" */ g_free (respbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); if (respbuf == NULL) { g_prefix_error (error, _("HELO command failed: ")); transport->connected = FALSE; - camel_operation_end (NULL); + camel_operation_end (cancellable); return FALSE; } if (strncmp (respbuf, "250", 3)) { - smtp_set_error (transport, respbuf, error); + smtp_set_error ( + transport, respbuf, cancellable, error); g_prefix_error (error, _("HELO command failed: ")); - camel_operation_end (NULL); + camel_operation_end (cancellable); g_free (respbuf); return FALSE; } @@ -1059,7 +1112,7 @@ smtp_helo (CamelSmtpTransport *transport, GError **error) } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */ g_free (respbuf); - camel_operation_end (NULL); + camel_operation_end (cancellable); return TRUE; } @@ -1067,6 +1120,7 @@ smtp_helo (CamelSmtpTransport *transport, GError **error) static gboolean smtp_auth (CamelSmtpTransport *transport, const gchar *mech, + GCancellable *cancellable, GError **error) { CamelService *service; @@ -1076,18 +1130,19 @@ smtp_auth (CamelSmtpTransport *transport, service = CAMEL_SERVICE (transport); - camel_operation_start_transient (NULL, _("SMTP Authentication")); + camel_operation_start_transient (cancellable, _("SMTP Authentication")); sasl = camel_sasl_new ("smtp", mech, service); if (!sasl) { - camel_operation_end (NULL); + camel_operation_end (cancellable); g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Error creating SASL authentication object.")); return FALSE; } - challenge = camel_sasl_challenge_base64 (sasl, NULL, error); + challenge = camel_sasl_challenge_base64 ( + sasl, NULL, cancellable, error); if (challenge) { auth_challenge = TRUE; cmdbuf = g_strdup_printf ("AUTH %s %s\r\n", mech, challenge); @@ -1097,7 +1152,9 @@ smtp_auth (CamelSmtpTransport *transport, } d(fprintf (stderr, "sending : %s", cmdbuf)); - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) { + if (camel_stream_write_string ( + transport->ostream, cmdbuf, + cancellable, error) == -1) { g_free (cmdbuf); g_prefix_error (error, _("AUTH command failed: ")); goto lose; @@ -1105,7 +1162,8 @@ smtp_auth (CamelSmtpTransport *transport, g_free (cmdbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); while (!camel_sasl_get_authenticated (sasl)) { if (!respbuf) { @@ -1116,7 +1174,8 @@ smtp_auth (CamelSmtpTransport *transport, /* the server challenge/response should follow a 334 code */ if (strncmp (respbuf, "334", 3) != 0) { - smtp_set_error (transport, respbuf, error); + smtp_set_error ( + transport, respbuf, cancellable, error); g_prefix_error (error, _("AUTH command failed: ")); goto lose; } @@ -1133,7 +1192,8 @@ smtp_auth (CamelSmtpTransport *transport, /* eat whtspc */ for (challenge = respbuf + 4; isspace (*challenge); challenge++); - challenge = camel_sasl_challenge_base64 (sasl, challenge, error); + challenge = camel_sasl_challenge_base64 ( + sasl, challenge, cancellable, error); if (challenge == NULL) goto break_and_lose; @@ -1143,7 +1203,9 @@ smtp_auth (CamelSmtpTransport *transport, cmdbuf = g_strdup_printf ("%s\r\n", challenge); g_free (challenge); d(fprintf (stderr, "sending : %s", cmdbuf)); - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) { + if (camel_stream_write_string ( + transport->ostream, cmdbuf, + cancellable, error) == -1) { g_free (cmdbuf); goto lose; } @@ -1151,7 +1213,8 @@ smtp_auth (CamelSmtpTransport *transport, /* get the server's response */ respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); } if (respbuf == NULL) @@ -1178,7 +1241,7 @@ smtp_auth (CamelSmtpTransport *transport, } g_object_unref (sasl); - camel_operation_end (NULL); + camel_operation_end (cancellable); g_free (respbuf); @@ -1187,14 +1250,14 @@ smtp_auth (CamelSmtpTransport *transport, break_and_lose: /* Get the server out of "waiting for continuation data" mode. */ d(fprintf (stderr, "sending : *\n")); - camel_stream_write (transport->ostream, "*\r\n", 3, NULL); + camel_stream_write (transport->ostream, "*\r\n", 3, cancellable, NULL); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), NULL); + CAMEL_STREAM_BUFFER (transport->istream), cancellable, NULL); d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); lose: g_object_unref (sasl); - camel_operation_end (NULL); + camel_operation_end (cancellable); g_free (respbuf); @@ -1202,7 +1265,11 @@ smtp_auth (CamelSmtpTransport *transport, } static gboolean -smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit_parts, GError **error) +smtp_mail (CamelSmtpTransport *transport, + const gchar *sender, + gboolean has_8bit_parts, + GCancellable *cancellable, + GError **error) { /* we gotta tell the smtp server who we are. (our email addy) */ gchar *cmdbuf, *respbuf = NULL; @@ -1214,7 +1281,8 @@ smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit d(fprintf (stderr, "sending : %s", cmdbuf)); - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) { + if (camel_stream_write_string ( + transport->ostream, cmdbuf, cancellable, error) == -1) { g_free (cmdbuf); g_prefix_error (error, _("MAIL FROM command failed: ")); camel_service_disconnect ((CamelService *) transport, FALSE, NULL); @@ -1226,7 +1294,8 @@ smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit /* Check for "250 Sender OK..." */ g_free (respbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); if (respbuf == NULL) { g_prefix_error (error, _("MAIL FROM command failed: ")); camel_service_disconnect ( @@ -1234,8 +1303,10 @@ smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit return FALSE; } if (strncmp (respbuf, "250", 3)) { - smtp_set_error (transport, respbuf, error); - g_prefix_error (error, _("MAIL FROM command failed: ")); + smtp_set_error ( + transport, respbuf, cancellable, error); + g_prefix_error ( + error, _("MAIL FROM command failed: ")); g_free (respbuf); return FALSE; } @@ -1246,7 +1317,10 @@ smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit } static gboolean -smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error) +smtp_rcpt (CamelSmtpTransport *transport, + const gchar *recipient, + GCancellable *cancellable, + GError **error) { /* we gotta tell the smtp server who we are going to be sending * our email to */ @@ -1256,7 +1330,8 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error d(fprintf (stderr, "sending : %s", cmdbuf)); - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) { + if (camel_stream_write_string ( + transport->ostream, cmdbuf, cancellable, error) == -1) { g_free (cmdbuf); g_prefix_error (error, _("RCPT TO command failed: ")); camel_service_disconnect ((CamelService *) transport, FALSE, NULL); @@ -1269,7 +1344,8 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error /* Check for "250 Recipient OK..." */ g_free (respbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); if (respbuf == NULL) { g_prefix_error ( error, _("RCPT TO <%s> failed: "), recipient); @@ -1278,7 +1354,8 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error return FALSE; } if (strncmp (respbuf, "250", 3)) { - smtp_set_error (transport, respbuf, error); + smtp_set_error ( + transport, respbuf, cancellable, error); g_prefix_error ( error, _("RCPT TO <%s> failed: "), recipient); g_free (respbuf); @@ -1292,7 +1369,10 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error } static gboolean -smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **error) +smtp_data (CamelSmtpTransport *transport, + CamelMimeMessage *message, + GCancellable *cancellable, + GError **error) { struct _camel_header_raw *header, *savedbcc, *n, *tail; CamelBestencEncoding enctype = CAMEL_BESTENC_8BIT; @@ -1316,7 +1396,8 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er d(fprintf (stderr, "sending : %s", cmdbuf)); - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) { + if (camel_stream_write_string ( + transport->ostream, cmdbuf, cancellable, error) == -1) { g_free (cmdbuf); g_prefix_error (error, _("DATA command failed: ")); camel_service_disconnect ((CamelService *) transport, FALSE, NULL); @@ -1325,7 +1406,7 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er g_free (cmdbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), cancellable, error); if (respbuf == NULL) { g_prefix_error (error, _("DATA command failed: ")); camel_service_disconnect ( @@ -1336,7 +1417,7 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er /* We should have gotten instructions on how to use the DATA * command: 354 Enter mail, end with "." on a line by itself */ - smtp_set_error (transport, respbuf, error); + smtp_set_error (transport, respbuf, cancellable, error); g_prefix_error (error, _("DATA command failed: ")); g_free (respbuf); return FALSE; @@ -1367,12 +1448,13 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er /* find out how large the message is... */ null = CAMEL_STREAM_NULL (camel_stream_null_new ()); camel_data_wrapper_write_to_stream ( - CAMEL_DATA_WRAPPER (message), CAMEL_STREAM (null), NULL); + CAMEL_DATA_WRAPPER (message), + CAMEL_STREAM (null), NULL, NULL); filtered_stream = camel_stream_filter_new (transport->ostream); /* setup progress reporting for message sending... */ - filter = camel_mime_filter_progress_new (NULL, null->written); + filter = camel_mime_filter_progress_new (cancellable, null->written); camel_stream_filter_add ( CAMEL_STREAM_FILTER (filtered_stream), filter); g_object_unref (filter); @@ -1388,7 +1470,8 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er /* write the message */ ret = camel_data_wrapper_write_to_stream ( - CAMEL_DATA_WRAPPER (message), filtered_stream, error); + CAMEL_DATA_WRAPPER (message), + filtered_stream, cancellable, error); /* restore the bcc headers */ header->next = savedbcc; @@ -1402,14 +1485,16 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er return FALSE; } - camel_stream_flush (filtered_stream, NULL); + camel_stream_flush (filtered_stream, cancellable, NULL); g_object_unref (filtered_stream); /* terminate the message body */ d(fprintf (stderr, "sending : \\r\\n.\\r\\n\n")); - if (camel_stream_write (transport->ostream, "\r\n.\r\n", 5, error) == -1) { + if (camel_stream_write ( + transport->ostream, "\r\n.\r\n", 5, + cancellable, error) == -1) { g_prefix_error (error, _("DATA command failed: ")); camel_service_disconnect ((CamelService *) transport, FALSE, NULL); return FALSE; @@ -1419,7 +1504,8 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er /* Check for "250 Sender OK..." */ g_free (respbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); if (respbuf == NULL) { g_prefix_error (error, _("DATA command failed: ")); camel_service_disconnect ( @@ -1427,7 +1513,8 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er return FALSE; } if (strncmp (respbuf, "250", 3) != 0) { - smtp_set_error (transport, respbuf, error); + smtp_set_error ( + transport, respbuf, cancellable, error); g_prefix_error (error, _("DATA command failed: ")); g_free (respbuf); return FALSE; @@ -1439,7 +1526,9 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er } static gboolean -smtp_rset (CamelSmtpTransport *transport, GError **error) +smtp_rset (CamelSmtpTransport *transport, + GCancellable *cancellable, + GError **error) { /* we are going to reset the smtp server (just to be nice) */ gchar *cmdbuf, *respbuf = NULL; @@ -1448,7 +1537,8 @@ smtp_rset (CamelSmtpTransport *transport, GError **error) d(fprintf (stderr, "sending : %s", cmdbuf)); - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) { + if (camel_stream_write_string ( + transport->ostream, cmdbuf, cancellable, error) == -1) { g_free (cmdbuf); g_prefix_error (error, _("RSET command failed: ")); camel_service_disconnect ((CamelService *) transport, FALSE, NULL); @@ -1460,7 +1550,8 @@ smtp_rset (CamelSmtpTransport *transport, GError **error) /* Check for "250" */ g_free (respbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); if (respbuf == NULL) { g_prefix_error (error, _("RSET command failed: ")); camel_service_disconnect ( @@ -1468,7 +1559,8 @@ smtp_rset (CamelSmtpTransport *transport, GError **error) return FALSE; } if (strncmp (respbuf, "250", 3) != 0) { - smtp_set_error (transport, respbuf, error); + smtp_set_error ( + transport, respbuf, cancellable, error); g_prefix_error (error, _("RSET command failed: ")); g_free (respbuf); return FALSE; @@ -1480,7 +1572,9 @@ smtp_rset (CamelSmtpTransport *transport, GError **error) } static gboolean -smtp_quit (CamelSmtpTransport *transport, GError **error) +smtp_quit (CamelSmtpTransport *transport, + GCancellable *cancellable, + GError **error) { /* we are going to reset the smtp server (just to be nice) */ gchar *cmdbuf, *respbuf = NULL; @@ -1489,7 +1583,8 @@ smtp_quit (CamelSmtpTransport *transport, GError **error) d(fprintf (stderr, "sending : %s", cmdbuf)); - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) { + if (camel_stream_write_string ( + transport->ostream, cmdbuf, cancellable, error) == -1) { g_free (cmdbuf); g_prefix_error (error, _("QUIT command failed: ")); return FALSE; @@ -1500,7 +1595,8 @@ smtp_quit (CamelSmtpTransport *transport, GError **error) /* Check for "221" */ g_free (respbuf); respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (transport->istream), error); + CAMEL_STREAM_BUFFER (transport->istream), + cancellable, error); d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); if (respbuf == NULL) { @@ -1509,7 +1605,8 @@ smtp_quit (CamelSmtpTransport *transport, GError **error) return FALSE; } if (strncmp (respbuf, "221", 3) != 0) { - smtp_set_error (transport, respbuf, error); + smtp_set_error ( + transport, respbuf, cancellable, error); g_prefix_error (error, _("QUIT command failed: ")); g_free (respbuf); return FALSE; diff --git a/docs/reference/camel/tmpl/camel-cipher-context.sgml b/docs/reference/camel/tmpl/camel-cipher-context.sgml index a6343eb..768a8a6 100644 --- a/docs/reference/camel/tmpl/camel-cipher-context.sgml +++ b/docs/reference/camel/tmpl/camel-cipher-context.sgml @@ -146,6 +146,7 @@ CamelCipherContext @hash: @ipart: @opart: +@cancellable: @error: @Returns: @@ -157,6 +158,7 @@ CamelCipherContext @context: @ipart: +@cancellable: @error: @Returns: @@ -171,6 +173,7 @@ CamelCipherContext @recipients: @ipart: @opart: +@cancellable: @error: @Returns: @@ -183,6 +186,7 @@ CamelCipherContext @context: @ipart: @opart: +@cancellable: @error: @Returns: @@ -194,6 +198,7 @@ CamelCipherContext @context: @istream: +@cancellable: @error: @Returns: @@ -206,6 +211,7 @@ CamelCipherContext @context: @keys: @ostream: +@cancellable: @error: @Returns: @@ -480,6 +486,20 @@ CamelCipherContext @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: @@ -508,6 +528,7 @@ CamelCipherContext @part: @flags: @ostream: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-data-wrapper.sgml b/docs/reference/camel/tmpl/camel-data-wrapper.sgml index b75b0a4..499158e 100644 --- a/docs/reference/camel/tmpl/camel-data-wrapper.sgml +++ b/docs/reference/camel/tmpl/camel-data-wrapper.sgml @@ -42,6 +42,7 @@ CamelDataWrapper @data_wrapper: @stream: +@cancellable: @error: @Returns: @@ -53,6 +54,7 @@ CamelDataWrapper @data_wrapper: @stream: +@cancellable: @error: @Returns: @@ -100,6 +102,7 @@ CamelDataWrapper @data_wrapper: @stream: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-disco-diary.sgml b/docs/reference/camel/tmpl/camel-disco-diary.sgml index f9bd316..2f8be84 100644 --- a/docs/reference/camel/tmpl/camel-disco-diary.sgml +++ b/docs/reference/camel/tmpl/camel-disco-diary.sgml @@ -72,6 +72,7 @@ CamelDiscoDiary @diary: +@cancellable: @error: diff --git a/docs/reference/camel/tmpl/camel-disco-folder.sgml b/docs/reference/camel/tmpl/camel-disco-folder.sgml index db6605d..4bd260d 100644 --- a/docs/reference/camel/tmpl/camel-disco-folder.sgml +++ b/docs/reference/camel/tmpl/camel-disco-folder.sgml @@ -56,6 +56,7 @@ CamelDiscoFolder @folder: @uids: +@cancellable: @error: @Returns: @@ -67,6 +68,7 @@ CamelDiscoFolder @disco_folder: @uid: +@cancellable: @error: @Returns: @@ -78,6 +80,7 @@ CamelDiscoFolder @disco_folder: @expression: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-disco-store.sgml b/docs/reference/camel/tmpl/camel-disco-store.sgml index d33bc16..1f80692 100644 --- a/docs/reference/camel/tmpl/camel-disco-store.sgml +++ b/docs/reference/camel/tmpl/camel-disco-store.sgml @@ -51,6 +51,7 @@ CamelDiscoStore @store: @status: +@cancellable: @error: @Returns: @@ -80,6 +81,7 @@ CamelDiscoStore @store: +@cancellable: @error: diff --git a/docs/reference/camel/tmpl/camel-file-utils.sgml b/docs/reference/camel/tmpl/camel-file-utils.sgml index a4780e6..9069ab4 100644 --- a/docs/reference/camel/tmpl/camel-file-utils.sgml +++ b/docs/reference/camel/tmpl/camel-file-utils.sgml @@ -186,6 +186,7 @@ camel-file-utils @fd: @buf: @n: +@cancellable: @error: @Returns: @@ -198,6 +199,7 @@ camel-file-utils @fd: @buf: @n: +@cancellable: @error: @Returns: @@ -210,6 +212,7 @@ camel-file-utils @fd: @buf: @n: +@cancellable: @error: @Returns: @@ -222,6 +225,7 @@ camel-file-utils @fd: @buf: @n: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-filter-driver.sgml b/docs/reference/camel/tmpl/camel-filter-driver.sgml index dd2cb2c..d46023b 100644 --- a/docs/reference/camel/tmpl/camel-filter-driver.sgml +++ b/docs/reference/camel/tmpl/camel-filter-driver.sgml @@ -157,6 +157,7 @@ CamelFilterDriver @source: @source_url: @original_source_url: +@cancellable: @error: @Returns: @@ -169,6 +170,7 @@ CamelFilterDriver @driver: @mbox: @original_source_url: +@cancellable: @error: @Returns: @@ -183,6 +185,7 @@ CamelFilterDriver @cache: @uids: @remove: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-folder.sgml b/docs/reference/camel/tmpl/camel-folder.sgml index 147dcde..e337f03 100644 --- a/docs/reference/camel/tmpl/camel-folder.sgml +++ b/docs/reference/camel/tmpl/camel-folder.sgml @@ -166,6 +166,7 @@ CamelFolder @folder: +@cancellable: @error: @Returns: @@ -177,6 +178,7 @@ CamelFolder @folder: @expunge: +@cancellable: @error: @Returns: @@ -205,6 +207,7 @@ CamelFolder @folder: +@cancellable: @error: @Returns: @@ -347,6 +350,7 @@ CamelFolder @message: @info: @appended_uid: +@cancellable: @error: @Returns: @@ -412,6 +416,7 @@ CamelFolder @folder: @uid: +@cancellable: @error: @Returns: @@ -423,6 +428,7 @@ CamelFolder @folder: @uid: +@cancellable: @error: @Returns: @@ -575,6 +581,7 @@ CamelFolder @dest: @transferred_uids: @delete_originals: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-mime-filter-progress.sgml b/docs/reference/camel/tmpl/camel-mime-filter-progress.sgml index ab2d1f1..b115427 100644 --- a/docs/reference/camel/tmpl/camel-mime-filter-progress.sgml +++ b/docs/reference/camel/tmpl/camel-mime-filter-progress.sgml @@ -31,7 +31,7 @@ CamelMimeFilterProgress -@operation: +@cancellable: @total: @Returns: diff --git a/docs/reference/camel/tmpl/camel-mime-part.sgml b/docs/reference/camel/tmpl/camel-mime-part.sgml index 26bb04a..4083d8b 100644 --- a/docs/reference/camel/tmpl/camel-mime-part.sgml +++ b/docs/reference/camel/tmpl/camel-mime-part.sgml @@ -233,6 +233,7 @@ CamelMimePart @mime_part: @parser: +@cancellable: @error: @Returns: @@ -264,6 +265,7 @@ CamelMimePart @mime_part: @mp: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-net-utils.sgml b/docs/reference/camel/tmpl/camel-net-utils.sgml index 1463976..5ed463c 100644 --- a/docs/reference/camel/tmpl/camel-net-utils.sgml +++ b/docs/reference/camel/tmpl/camel-net-utils.sgml @@ -161,6 +161,7 @@ camel-net-utils @name: @service: @hints: +@cancellable: @error: @Returns: @@ -183,6 +184,7 @@ camel-net-utils @host: @serv: @flags: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-offline-folder.sgml b/docs/reference/camel/tmpl/camel-offline-folder.sgml index 87b2b59..81ba68e 100644 --- a/docs/reference/camel/tmpl/camel-offline-folder.sgml +++ b/docs/reference/camel/tmpl/camel-offline-folder.sgml @@ -56,6 +56,7 @@ CamelOfflineFolder @offline: @expression: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-offline-journal.sgml b/docs/reference/camel/tmpl/camel-offline-journal.sgml index 1ed0a27..6274a7e 100644 --- a/docs/reference/camel/tmpl/camel-offline-journal.sgml +++ b/docs/reference/camel/tmpl/camel-offline-journal.sgml @@ -67,6 +67,7 @@ CamelOfflineJournal @journal: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-offline-store.sgml b/docs/reference/camel/tmpl/camel-offline-store.sgml index 4a1f37b..592e59e 100644 --- a/docs/reference/camel/tmpl/camel-offline-store.sgml +++ b/docs/reference/camel/tmpl/camel-offline-store.sgml @@ -33,6 +33,7 @@ CamelOfflineStore @store: @state: +@cancellable: @error: @Returns: @@ -53,6 +54,7 @@ CamelOfflineStore @store: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-operation.sgml b/docs/reference/camel/tmpl/camel-operation.sgml index a2fdedc..3660bc7 100644 --- a/docs/reference/camel/tmpl/camel-operation.sgml +++ b/docs/reference/camel/tmpl/camel-operation.sgml @@ -53,23 +53,6 @@ camel-operation @operation: - - - - - -@operation: -@Returns: - - - - - - - -@void: - - @@ -97,21 +80,12 @@ camel-operation @Returns: - - - - - -@void: -@Returns: - - -@cc: +@cancellable: @what: @Varargs: @@ -121,7 +95,7 @@ camel-operation -@cc: +@cancellable: @what: @Varargs: @@ -131,7 +105,7 @@ camel-operation -@operation: +@cancellable: @pc: @@ -140,6 +114,6 @@ camel-operation -@operation: +@cancellable: diff --git a/docs/reference/camel/tmpl/camel-sasl.sgml b/docs/reference/camel/tmpl/camel-sasl.sgml index 2a7e348..a855001 100644 --- a/docs/reference/camel/tmpl/camel-sasl.sgml +++ b/docs/reference/camel/tmpl/camel-sasl.sgml @@ -53,6 +53,7 @@ CamelSasl @sasl: @token: +@cancellable: @error: @Returns: @@ -64,6 +65,7 @@ CamelSasl @sasl: @token: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-service.sgml b/docs/reference/camel/tmpl/camel-service.sgml index 1d809ec..7120ef6 100644 --- a/docs/reference/camel/tmpl/camel-service.sgml +++ b/docs/reference/camel/tmpl/camel-service.sgml @@ -158,6 +158,7 @@ CamelService @service: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-session.sgml b/docs/reference/camel/tmpl/camel-session.sgml index f8ed9ee..7070939 100644 --- a/docs/reference/camel/tmpl/camel-session.sgml +++ b/docs/reference/camel/tmpl/camel-session.sgml @@ -76,7 +76,7 @@ CamelSession @id: @error: @ops: -@op: +@cancellable: @session: @data: diff --git a/docs/reference/camel/tmpl/camel-store.sgml b/docs/reference/camel/tmpl/camel-store.sgml index 64e1e98..f9b7aea 100644 --- a/docs/reference/camel/tmpl/camel-store.sgml +++ b/docs/reference/camel/tmpl/camel-store.sgml @@ -379,6 +379,7 @@ CamelStore @store: @folder_name: @flags: +@cancellable: @error: @Returns: @@ -389,6 +390,7 @@ CamelStore @store: +@cancellable: @error: @Returns: @@ -399,6 +401,7 @@ CamelStore @store: +@cancellable: @error: @Returns: @@ -409,6 +412,7 @@ CamelStore @store: +@cancellable: @error: @Returns: @@ -421,6 +425,7 @@ CamelStore @store: @parent_name: @folder_name: +@cancellable: @error: @Returns: @@ -432,6 +437,7 @@ CamelStore @store: @folder_name: +@cancellable: @error: @Returns: @@ -444,6 +450,7 @@ CamelStore @store: @old_namein: @new_name: +@cancellable: @error: @Returns: @@ -501,6 +508,7 @@ CamelStore @store: @expunge: +@cancellable: @error: @Returns: @@ -513,6 +521,7 @@ CamelStore @store: @top: @flags: +@cancellable: @error: @Returns: @@ -608,6 +617,7 @@ CamelStore @store: @folder_name: +@cancellable: @error: @Returns: @@ -619,6 +629,7 @@ CamelStore @store: @folder_name: +@cancellable: @error: @Returns: @@ -629,6 +640,7 @@ CamelStore @store: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-stream-buffer.sgml b/docs/reference/camel/tmpl/camel-stream-buffer.sgml index 12206f4..48955a1 100644 --- a/docs/reference/camel/tmpl/camel-stream-buffer.sgml +++ b/docs/reference/camel/tmpl/camel-stream-buffer.sgml @@ -67,6 +67,7 @@ CamelStreamBuffer @sbf: @buf: @max: +@cancellable: @error: @Returns: @@ -77,6 +78,7 @@ CamelStreamBuffer @sbf: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-stream.sgml b/docs/reference/camel/tmpl/camel-stream.sgml index ca4f3c8..e7dea6b 100644 --- a/docs/reference/camel/tmpl/camel-stream.sgml +++ b/docs/reference/camel/tmpl/camel-stream.sgml @@ -34,6 +34,7 @@ CamelStream @stream: @buffer: @n: +@cancellable: @error: @Returns: @@ -46,6 +47,7 @@ CamelStream @stream: @buffer: @n: +@cancellable: @error: @Returns: @@ -56,6 +58,7 @@ CamelStream @stream: +@cancellable: @error: @Returns: @@ -66,6 +69,7 @@ CamelStream @stream: +@cancellable: @error: @Returns: @@ -96,6 +100,7 @@ CamelStream @stream: @string: +@cancellable: @error: @Returns: @@ -129,6 +134,7 @@ CamelStream @stream: @output_stream: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-tcp-stream.sgml b/docs/reference/camel/tmpl/camel-tcp-stream.sgml index b15841d..69d4ba8 100644 --- a/docs/reference/camel/tmpl/camel-tcp-stream.sgml +++ b/docs/reference/camel/tmpl/camel-tcp-stream.sgml @@ -71,6 +71,7 @@ CamelTcpStream @host: @service: @fallback_port: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-transport.sgml b/docs/reference/camel/tmpl/camel-transport.sgml index 04e6225..9efc6e7 100644 --- a/docs/reference/camel/tmpl/camel-transport.sgml +++ b/docs/reference/camel/tmpl/camel-transport.sgml @@ -35,6 +35,7 @@ CamelTransport @message: @from: @recipients: +@cancellable: @error: @Returns: diff --git a/docs/reference/camel/tmpl/camel-unused.sgml b/docs/reference/camel/tmpl/camel-unused.sgml index 5f8af4f..fff8076 100644 --- a/docs/reference/camel/tmpl/camel-unused.sgml +++ b/docs/reference/camel/tmpl/camel-unused.sgml @@ -7318,6 +7318,22 @@ streams @cc: + + + + + +@operation: +@Returns: + + + + + + +@void: +@Returns: + @@ -7333,6 +7349,13 @@ streams @cc: + + + + + +@void: +