[evolution-data-server/camel-gobject: 44/67] Add GError to the stream API and watch the pretty ripples.
- From: Matthew Barnes <mbarnes src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [evolution-data-server/camel-gobject: 44/67] Add GError to the stream API and watch the pretty ripples.
- Date: Sun, 27 Dec 2009 05:35:31 +0000 (UTC)
commit 63ffa6aee509e8cca146d5385af30b80161a215e
Author: Matthew Barnes <mbarnes redhat com>
Date: Sun Nov 29 17:08:38 2009 -0500
Add GError to the stream API and watch the pretty ripples.
camel/camel-block-file.c | 42 +-
camel/camel-block-file.h | 43 +-
camel/camel-cipher-context.c | 12 +-
camel/camel-cipher-context.h | 2 +-
camel/camel-data-cache.c | 6 +-
camel/camel-data-wrapper.c | 279 +++---
camel/camel-data-wrapper.h | 80 +-
camel/camel-file-utils.c | 77 ++-
camel/camel-file-utils.h | 8 +-
camel/camel-filter-driver.c | 20 +-
camel/camel-filter-search.c | 5 +-
camel/camel-folder-search.c | 4 +-
camel/camel-folder-summary.c | 5 +-
camel/camel-gpg-context.c | 97 +-
camel/camel-http-stream.c | 482 +++++-----
camel/camel-http-stream.h | 32 +-
camel/camel-index-control.c | 35 +-
camel/camel-index.c | 20 +-
camel/camel-index.h | 98 ++-
camel/camel-mime-filter-save.c | 2 +-
camel/camel-mime-message.c | 420 ++++----
camel/camel-mime-parser.c | 21 +-
camel/camel-mime-parser.h | 2 +-
camel/camel-mime-part-utils.c | 38 +-
camel/camel-mime-part-utils.h | 5 +-
camel/camel-mime-part.c | 1074 ++++++++++----------
camel/camel-mime-part.h | 7 +-
camel/camel-multipart-signed.c | 568 ++++++-----
camel/camel-multipart.c | 541 +++++-----
camel/camel-partition-table.c | 148 ++-
camel/camel-partition-table.h | 62 +-
camel/camel-search-private.c | 4 +-
camel/camel-seekable-stream.c | 22 +-
camel/camel-seekable-stream.h | 32 +-
camel/camel-seekable-substream.c | 46 +-
camel/camel-smime-context.c | 48 +-
camel/camel-stream-buffer.c | 52 +-
camel/camel-stream-buffer.h | 6 +-
camel/camel-stream-filter.c | 34 +-
camel/camel-stream-fs.c | 79 ++-
camel/camel-stream-fs.h | 6 +-
camel/camel-stream-mem.c | 9 +-
camel/camel-stream-null.c | 6 +-
camel/camel-stream-process.c | 24 +-
camel/camel-stream-vfs.c | 15 +-
camel/camel-stream.c | 81 +-
camel/camel-stream.h | 65 +-
camel/camel-tcp-stream-raw.c | 28 +-
camel/camel-tcp-stream-ssl.c | 56 +-
camel/camel-tcp-stream.c | 6 +-
camel/camel-tcp-stream.h | 46 +-
camel/camel-text-index.c | 194 +++--
camel/camel-text-index.h | 22 +-
camel/camel-uid-cache.c | 6 +-
camel/providers/groupwise/camel-groupwise-folder.c | 16 +-
.../providers/groupwise/camel-groupwise-journal.c | 13 +-
camel/providers/groupwise/camel-groupwise-utils.c | 18 +-
camel/providers/imap/camel-imap-command.c | 53 +-
camel/providers/imap/camel-imap-folder.c | 29 +-
camel/providers/imap/camel-imap-message-cache.c | 55 +-
camel/providers/imap/camel-imap-search.c | 12 +-
camel/providers/imap/camel-imap-store.c | 27 +-
camel/providers/imap/camel-imap-wrapper.c | 103 +-
camel/providers/local/camel-local-folder.c | 4 +-
camel/providers/local/camel-local-summary.c | 26 +-
camel/providers/local/camel-maildir-folder.c | 34 +-
camel/providers/local/camel-mbox-folder.c | 55 +-
camel/providers/local/camel-mh-folder.c | 28 +-
camel/providers/local/camel-mh-store.c | 27 +-
camel/providers/nntp/camel-nntp-folder.c | 58 +-
camel/providers/nntp/camel-nntp-store.c | 80 +-
camel/providers/nntp/camel-nntp-stream.c | 69 +-
camel/providers/nntp/camel-nntp-stream.h | 27 +-
camel/providers/nntp/camel-nntp-summary.c | 20 +-
camel/providers/pop3/camel-pop3-engine.c | 4 +-
camel/providers/pop3/camel-pop3-folder.c | 36 +-
camel/providers/pop3/camel-pop3-store.c | 38 +-
camel/providers/pop3/camel-pop3-stream.c | 22 +-
.../providers/sendmail/camel-sendmail-transport.c | 12 +-
camel/providers/smtp/camel-smtp-transport.c | 340 ++-----
.../libedata-cal/tmpl/e-data-cal-common.sgml | 1 +
81 files changed, 3306 insertions(+), 3023 deletions(-)
---
diff --git a/camel/camel-block-file.c b/camel/camel-block-file.c
index d940e9f..e4b162d 100644
--- a/camel/camel-block-file.c
+++ b/camel/camel-block-file.c
@@ -32,7 +32,9 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include <gio/gio.h>
#include <glib/gstdio.h>
+#include <glib/gi18n-lib.h>
#include "camel-block-file.h"
#include "camel-file-utils.h"
@@ -363,6 +365,7 @@ camel_cache_remove(c, key);
* @path:
* @:
* @block_size:
+ * @error: return location for a #GError, or %NULL
*
* Allocate a new block file, stored at @path. @version contains an 8 character
* version string which must match the head of the file, or the file will be
@@ -372,7 +375,12 @@ camel_cache_remove(c, key);
*
* Return value: The new block file, or NULL if it could not be created.
**/
-CamelBlockFile *camel_block_file_new(const gchar *path, gint flags, const gchar version[8], gsize block_size)
+CamelBlockFile *
+camel_block_file_new (const gchar *path,
+ gint flags,
+ const gchar version[8],
+ gsize block_size,
+ GError **error)
{
CamelBlockFileClass *class;
CamelBlockFile *bs;
@@ -382,7 +390,7 @@ CamelBlockFile *camel_block_file_new(const gchar *path, gint flags, const gchar
bs->path = g_strdup(path);
bs->flags = flags;
- bs->root_block = camel_block_file_get_block(bs, 0);
+ bs->root_block = camel_block_file_get_block (bs, 0, error);
if (bs->root_block == NULL) {
g_object_unref (bs);
return NULL;
@@ -475,25 +483,28 @@ camel_block_file_delete(CamelBlockFile *bs)
/**
* camel_block_file_new_block:
* @bs:
+ * @error: return location for a #GError, or %NULL
*
* Allocate a new block, return a pointer to it. Old blocks
* may be flushed to disk during this call.
*
* Return value: The block, or NULL if an error occured.
**/
-CamelBlock *camel_block_file_new_block(CamelBlockFile *bs)
+CamelBlock *
+camel_block_file_new_block (CamelBlockFile *bs,
+ GError **error)
{
CamelBlock *bl;
CAMEL_BLOCK_FILE_LOCK(bs, root_lock);
if (bs->root->free) {
- bl = camel_block_file_get_block(bs, bs->root->free);
+ bl = camel_block_file_get_block (bs, bs->root->free, error);
if (bl == NULL)
goto fail;
bs->root->free = ((camel_block_t *)bl->data)[0];
} else {
- bl = camel_block_file_get_block(bs, bs->root->last);
+ bl = camel_block_file_get_block(bs, bs->root->last, error);
if (bl == NULL)
goto fail;
bs->root->last += CAMEL_BLOCK_SIZE;
@@ -513,14 +524,18 @@ fail:
* camel_block_file_free_block:
* @bs:
* @id:
+ * @error: return location for a #GError, or %NULL
*
*
**/
-gint camel_block_file_free_block(CamelBlockFile *bs, camel_block_t id)
+gint
+camel_block_file_free_block (CamelBlockFile *bs,
+ camel_block_t id,
+ GError **error)
{
CamelBlock *bl;
- bl = camel_block_file_get_block(bs, id);
+ bl = camel_block_file_get_block (bs, id, error);
if (bl == NULL)
return -1;
@@ -541,13 +556,17 @@ gint camel_block_file_free_block(CamelBlockFile *bs, camel_block_t id)
* camel_block_file_get_block:
* @bs:
* @id:
+ * @error: return location for a #GError, or %NULL
*
* Retreive a block @id.
*
* Return value: The block, or NULL if blockid is invalid or a file error
* occured.
**/
-CamelBlock *camel_block_file_get_block(CamelBlockFile *bs, camel_block_t id)
+CamelBlock *
+camel_block_file_get_block (CamelBlockFile *bs,
+ camel_block_t id,
+ GError **error)
{
CamelBlock *bl, *flush, *prev;
@@ -556,7 +575,10 @@ CamelBlock *camel_block_file_get_block(CamelBlockFile *bs, camel_block_t id)
if ((bs->root == NULL && id != 0)
|| (bs->root != NULL && (id > bs->root->last || id == 0))
|| (id % bs->block_size) != 0) {
- errno = EINVAL;
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Invalid block file"));
return NULL;
}
@@ -576,7 +598,7 @@ CamelBlock *camel_block_file_get_block(CamelBlockFile *bs, camel_block_t id)
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) == -1) {
+ camel_read (bs->fd, (gchar *) bl->data, CAMEL_BLOCK_SIZE, error) == -1) {
block_file_unuse(bs);
CAMEL_BLOCK_FILE_UNLOCK(bs, cache_lock);
g_free(bl);
diff --git a/camel/camel-block-file.h b/camel/camel-block-file.h
index 209be9a..da2b980 100644
--- a/camel/camel-block-file.h
+++ b/camel/camel-block-file.h
@@ -138,21 +138,34 @@ struct _CamelBlockFileClass {
gint (*init_root)(CamelBlockFile *);
};
-GType camel_block_file_get_type(void);
-
-CamelBlockFile *camel_block_file_new(const gchar *path, gint flags, const gchar version[8], gsize block_size);
-gint camel_block_file_rename(CamelBlockFile *bs, const gchar *path);
-gint camel_block_file_delete(CamelBlockFile *kf);
-
-CamelBlock *camel_block_file_new_block(CamelBlockFile *bs);
-gint camel_block_file_free_block(CamelBlockFile *bs, camel_block_t id);
-CamelBlock *camel_block_file_get_block(CamelBlockFile *bs, camel_block_t id);
-void camel_block_file_detach_block(CamelBlockFile *bs, CamelBlock *bl);
-void camel_block_file_attach_block(CamelBlockFile *bs, CamelBlock *bl);
-void camel_block_file_touch_block(CamelBlockFile *bs, CamelBlock *bl);
-void camel_block_file_unref_block(CamelBlockFile *bs, CamelBlock *bl);
-gint camel_block_file_sync_block(CamelBlockFile *bs, CamelBlock *bl);
-gint camel_block_file_sync(CamelBlockFile *bs);
+GType camel_block_file_get_type (void);
+CamelBlockFile *camel_block_file_new (const gchar *path,
+ gint flags,
+ const gchar version[8],
+ gsize block_size,
+ GError **error);
+gint camel_block_file_rename (CamelBlockFile *bs,
+ const gchar *path);
+gint camel_block_file_delete (CamelBlockFile *kf);
+CamelBlock * camel_block_file_new_block (CamelBlockFile *bs,
+ GError **error);
+gint camel_block_file_free_block (CamelBlockFile *bs,
+ camel_block_t id,
+ GError **error);
+CamelBlock * camel_block_file_get_block (CamelBlockFile *bs,
+ camel_block_t id,
+ GError **error);
+void camel_block_file_detach_block (CamelBlockFile *bs,
+ CamelBlock *bl);
+void camel_block_file_attach_block (CamelBlockFile *bs,
+ CamelBlock *bl);
+void camel_block_file_touch_block (CamelBlockFile *bs,
+ CamelBlock *bl);
+void camel_block_file_unref_block (CamelBlockFile *bs,
+ CamelBlock *bl);
+gint camel_block_file_sync_block (CamelBlockFile *bs,
+ CamelBlock *bl);
+gint camel_block_file_sync (CamelBlockFile *bs);
/* ********************************************************************** */
diff --git a/camel/camel-cipher-context.c b/camel/camel-cipher-context.c
index ce4265f..c1648d1 100644
--- a/camel/camel-cipher-context.c
+++ b/camel/camel-cipher-context.c
@@ -827,6 +827,7 @@ cc_prepare_sign (CamelMimePart *part)
* @part: Part to write.
* @flags: flags for the canonicalisation filter (CamelMimeFilterCanon)
* @ostream: stream to write canonicalised output to.
+ * @error: return location for a #GError, or %NULL
*
* Writes a part to a stream in a canonicalised format, suitable for signing/encrypting.
*
@@ -835,7 +836,10 @@ cc_prepare_sign (CamelMimePart *part)
* Return value: -1 on error;
**/
gint
-camel_cipher_canonical_to_stream (CamelMimePart *part, guint32 flags, CamelStream *ostream)
+camel_cipher_canonical_to_stream (CamelMimePart *part,
+ guint32 flags,
+ CamelStream *ostream,
+ GError **error)
{
CamelStream *filter;
CamelMimeFilter *canon;
@@ -849,12 +853,12 @@ camel_cipher_canonical_to_stream (CamelMimePart *part, guint32 flags, CamelStrea
camel_stream_filter_add (CAMEL_STREAM_FILTER (filter), canon);
g_object_unref (canon);
- if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)part, filter) != -1
- && camel_stream_flush (filter) != -1)
+ if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)part, filter, error) != -1
+ && camel_stream_flush (filter, error) != -1)
res = 0;
g_object_unref (filter);
- camel_stream_reset (ostream);
+ camel_stream_reset (ostream, NULL);
return res;
}
diff --git a/camel/camel-cipher-context.h b/camel/camel-cipher-context.h
index 4679f79..9c3fd34 100644
--- a/camel/camel-cipher-context.h
+++ b/camel/camel-cipher-context.h
@@ -218,7 +218,7 @@ void camel_cipher_validity_envelope(CamelCipherValidity *parent, CamelCiph
void camel_cipher_validity_free (CamelCipherValidity *validity);
/* utility functions */
-gint camel_cipher_canonical_to_stream(CamelMimePart *part, guint32 flags, CamelStream *ostream);
+gint camel_cipher_canonical_to_stream(CamelMimePart *part, guint32 flags, CamelStream *ostream, GError **error);
G_END_DECLS
diff --git a/camel/camel-data-cache.c b/camel/camel-data-cache.c
index f7dbcf2..82756be 100644
--- a/camel/camel-data-cache.c
+++ b/camel/camel-data-cache.c
@@ -390,7 +390,8 @@ camel_data_cache_add (CamelDataCache *cdc,
}
} while (stream != NULL);
- stream = camel_stream_fs_new_with_name(real, O_RDWR|O_CREAT|O_TRUNC, 0600);
+ stream = camel_stream_fs_new_with_name (
+ real, O_RDWR|O_CREAT|O_TRUNC, 0600, error);
if (stream)
camel_object_bag_add(cdc->priv->busy_bag, real, stream);
else
@@ -427,7 +428,8 @@ camel_data_cache_get (CamelDataCache *cdc,
real = data_cache_path(cdc, FALSE, path, key);
stream = camel_object_bag_reserve(cdc->priv->busy_bag, real);
if (!stream) {
- stream = camel_stream_fs_new_with_name(real, O_RDWR, 0600);
+ stream = camel_stream_fs_new_with_name (
+ real, O_RDWR, 0600, error);
if (stream)
camel_object_bag_add(cdc->priv->busy_bag, real, stream);
else
diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c
index 3da4195..e377513 100644
--- a/camel/camel-data-wrapper.c
+++ b/camel/camel-data-wrapper.c
@@ -41,15 +41,6 @@
static gpointer parent_class;
-static gint construct_from_stream(CamelDataWrapper *, CamelStream *);
-static gssize write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
-static gssize decode_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
-static void set_mime_type (CamelDataWrapper *data_wrapper, const gchar *mime_type);
-static gchar *get_mime_type (CamelDataWrapper *data_wrapper);
-static CamelContentType *get_mime_type_field (CamelDataWrapper *data_wrapper);
-static void set_mime_type_field (CamelDataWrapper *data_wrapper, CamelContentType *mime_type);
-static gboolean is_offline (CamelDataWrapper *data_wrapper);
-
static void
data_wrapper_dispose (GObject *object)
{
@@ -80,6 +71,129 @@ data_wrapper_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static gssize
+data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error)
+{
+ gssize ret;
+
+ if (data_wrapper->stream == NULL) {
+ return -1;
+ }
+
+ CAMEL_DATA_WRAPPER_LOCK (data_wrapper, stream_lock);
+ if (camel_stream_reset (data_wrapper->stream, error) == -1) {
+ CAMEL_DATA_WRAPPER_UNLOCK (data_wrapper, stream_lock);
+ return -1;
+ }
+
+ ret = camel_stream_write_to_stream (
+ data_wrapper->stream, stream, error);
+
+ CAMEL_DATA_WRAPPER_UNLOCK (data_wrapper, stream_lock);
+
+ return ret;
+}
+
+static gssize
+data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error)
+{
+ CamelMimeFilter *filter;
+ CamelStream *fstream;
+ gssize ret;
+
+ fstream = camel_stream_filter_new (stream);
+
+ switch (data_wrapper->encoding) {
+ case CAMEL_TRANSFER_ENCODING_BASE64:
+ filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
+ g_object_unref (filter);
+ break;
+ case CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE:
+ filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_QP_DEC);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
+ g_object_unref (filter);
+ break;
+ case CAMEL_TRANSFER_ENCODING_UUENCODE:
+ filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_UU_DEC);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
+ g_object_unref (filter);
+ break;
+ default:
+ break;
+ }
+
+ if (camel_content_type_is (data_wrapper->mime_type, "text", "*")) {
+ filter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE,
+ CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
+ g_object_unref (filter);
+ }
+
+ ret = camel_data_wrapper_write_to_stream (
+ data_wrapper, fstream, error);
+
+ camel_stream_flush (fstream, NULL);
+ g_object_unref (fstream);
+
+ return ret;
+}
+
+static void
+data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
+ const gchar *mime_type)
+{
+ if (data_wrapper->mime_type)
+ camel_content_type_unref (data_wrapper->mime_type);
+ data_wrapper->mime_type = camel_content_type_decode (mime_type);
+}
+
+static gchar *
+data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper)
+{
+ return camel_content_type_simple (data_wrapper->mime_type);
+}
+
+static CamelContentType *
+data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper)
+{
+ return data_wrapper->mime_type;
+}
+
+static void
+data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
+ CamelContentType *mime_type)
+{
+ if (mime_type)
+ camel_content_type_ref (mime_type);
+ if (data_wrapper->mime_type)
+ camel_content_type_unref (data_wrapper->mime_type);
+ data_wrapper->mime_type = mime_type;
+}
+
+static gint
+data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error)
+{
+ if (data_wrapper->stream)
+ g_object_unref (data_wrapper->stream);
+
+ data_wrapper->stream = stream;
+ g_object_ref (stream);
+ return 0;
+}
+
+static gboolean
+data_wrapper_is_offline (CamelDataWrapper *data_wrapper)
+{
+ return data_wrapper->offline;
+}
+
static void
data_wrapper_class_init (CamelDataWrapperClass *class)
{
@@ -92,14 +206,14 @@ data_wrapper_class_init (CamelDataWrapperClass *class)
object_class->dispose = data_wrapper_dispose;
object_class->finalize = data_wrapper_finalize;
- class->write_to_stream = write_to_stream;
- class->decode_to_stream = decode_to_stream;
- class->set_mime_type = set_mime_type;
- class->get_mime_type = get_mime_type;
- class->get_mime_type_field = get_mime_type_field;
- class->set_mime_type_field = set_mime_type_field;
- class->construct_from_stream = construct_from_stream;
- class->is_offline = is_offline;
+ class->write_to_stream = data_wrapper_write_to_stream;
+ class->decode_to_stream = data_wrapper_decode_to_stream;
+ class->set_mime_type = data_wrapper_set_mime_type;
+ class->get_mime_type = data_wrapper_get_mime_type;
+ class->get_mime_type_field = data_wrapper_get_mime_type_field;
+ class->set_mime_type_field = data_wrapper_set_mime_type_field;
+ class->construct_from_stream = data_wrapper_construct_from_stream;
+ class->is_offline = data_wrapper_is_offline;
}
static void
@@ -146,32 +260,11 @@ camel_data_wrapper_new (void)
return g_object_new (CAMEL_TYPE_DATA_WRAPPER, NULL);
}
-static gssize
-write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
-{
- gssize ret;
-
- if (data_wrapper->stream == NULL) {
- return -1;
- }
-
- CAMEL_DATA_WRAPPER_LOCK (data_wrapper, stream_lock);
- if (camel_stream_reset (data_wrapper->stream) == -1) {
- CAMEL_DATA_WRAPPER_UNLOCK (data_wrapper, stream_lock);
- return -1;
- }
-
- ret = camel_stream_write_to_stream (data_wrapper->stream, stream);
-
- CAMEL_DATA_WRAPPER_UNLOCK (data_wrapper, stream_lock);
-
- return ret;
-}
-
/**
* camel_data_wrapper_write_to_stream:
* @data_wrapper: a #CamelDataWrapper object
* @stream: a #CamelStream for output
+ * @error: return location for a #GError, or %NULL
*
* Writes the content of @data_wrapper to @stream in a machine-independent
* format appropriate for the data. It should be possible to construct an
@@ -182,7 +275,8 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
**/
gssize
camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
- CamelStream *stream)
+ CamelStream *stream,
+ GError **error)
{
CamelDataWrapperClass *class;
@@ -192,56 +286,14 @@ 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);
- return class->write_to_stream (data_wrapper, stream);
-}
-
-static gssize
-decode_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
-{
- CamelMimeFilter *filter;
- CamelStream *fstream;
- gssize ret;
-
- fstream = camel_stream_filter_new (stream);
-
- switch (data_wrapper->encoding) {
- case CAMEL_TRANSFER_ENCODING_BASE64:
- filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
- camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
- g_object_unref (filter);
- break;
- case CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE:
- filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_QP_DEC);
- camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
- g_object_unref (filter);
- break;
- case CAMEL_TRANSFER_ENCODING_UUENCODE:
- filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_UU_DEC);
- camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
- g_object_unref (filter);
- break;
- default:
- break;
- }
-
- if (camel_content_type_is (data_wrapper->mime_type, "text", "*")) {
- filter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE,
- CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
- g_object_unref (filter);
- }
-
- ret = camel_data_wrapper_write_to_stream (data_wrapper, fstream);
- camel_stream_flush (fstream);
- g_object_unref (fstream);
-
- return ret;
+ return class->write_to_stream (data_wrapper, stream, error);
}
/**
* camel_data_wrapper_decode_to_stream:
* @data_wrapper: a #CamelDataWrapper object
* @stream: a #CamelStream for decoded data to be written to
+ * @error: return location for a #GError, or %NULL
*
* Writes the decoded data content to @stream.
*
@@ -249,7 +301,8 @@ decode_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
**/
gssize
camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
- CamelStream *stream)
+ CamelStream *stream,
+ GError **error)
{
CamelDataWrapperClass *class;
@@ -259,24 +312,14 @@ 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);
- return class->decode_to_stream (data_wrapper, stream);
-}
-
-static gint
-construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
-{
- if (data_wrapper->stream)
- g_object_unref (data_wrapper->stream);
-
- data_wrapper->stream = stream;
- g_object_ref (stream);
- return 0;
+ return class->decode_to_stream (data_wrapper, stream, error);
}
/**
* camel_data_wrapper_construct_from_stream:
* @data_wrapper: a #CamelDataWrapper object
* @stream: an input #CamelStream
+ * @error: return location for a #GError, or %NULL
*
* Constructs the content of @data_wrapper from the supplied @stream.
*
@@ -284,7 +327,8 @@ construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
**/
gint
camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
- CamelStream *stream)
+ CamelStream *stream,
+ GError **error)
{
CamelDataWrapperClass *class;
@@ -294,15 +338,7 @@ 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);
- return class->construct_from_stream (data_wrapper, stream);
-}
-
-static void
-set_mime_type (CamelDataWrapper *data_wrapper, const gchar *mime_type)
-{
- if (data_wrapper->mime_type)
- camel_content_type_unref (data_wrapper->mime_type);
- data_wrapper->mime_type = camel_content_type_decode (mime_type);
+ return class->construct_from_stream (data_wrapper, stream, error);
}
/**
@@ -333,12 +369,6 @@ camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
class->set_mime_type (data_wrapper, mime_type);
}
-static gchar *
-get_mime_type (CamelDataWrapper *data_wrapper)
-{
- return camel_content_type_simple (data_wrapper->mime_type);
-}
-
/**
* camel_data_wrapper_get_mime_type:
* @data_wrapper: a #CamelDataWrapper object
@@ -358,12 +388,6 @@ camel_data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper)
return class->get_mime_type (data_wrapper);
}
-static CamelContentType *
-get_mime_type_field (CamelDataWrapper *data_wrapper)
-{
- return data_wrapper->mime_type;
-}
-
/**
* camel_data_wrapper_get_mime_type_field:
* @data_wrapper: a #CamelDataWrapper object
@@ -383,17 +407,6 @@ camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper)
return class->get_mime_type_field (data_wrapper);
}
-static void
-set_mime_type_field (CamelDataWrapper *data_wrapper,
- CamelContentType *mime_type)
-{
- if (mime_type)
- camel_content_type_ref (mime_type);
- if (data_wrapper->mime_type)
- camel_content_type_unref (data_wrapper->mime_type);
- data_wrapper->mime_type = mime_type;
-}
-
/**
* camel_data_wrapper_set_mime_type_field:
* @data_wrapper: a #CamelDataWrapper object
@@ -417,12 +430,6 @@ camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
class->set_mime_type_field (data_wrapper, mime_type);
}
-static gboolean
-is_offline (CamelDataWrapper *data_wrapper)
-{
- return data_wrapper->offline;
-}
-
/**
* camel_data_wrapper_is_offline:
* @data_wrapper: a #CamelDataWrapper object
diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h
index 5ed47eb..013ade4 100644
--- a/camel/camel-data-wrapper.h
+++ b/camel/camel-data-wrapper.h
@@ -75,46 +75,50 @@ struct _CamelDataWrapper {
struct _CamelDataWrapperClass {
CamelObjectClass parent_class;
- /* Virtual methods */
- void (*set_mime_type) (CamelDataWrapper *data_wrapper,
- const gchar *mime_type);
- gchar * (*get_mime_type) (CamelDataWrapper *data_wrapper);
- CamelContentType * (*get_mime_type_field) (CamelDataWrapper *data_wrapper);
- void (*set_mime_type_field) (CamelDataWrapper *data_wrapper,
- CamelContentType *mime_type_field);
-
- gssize (*write_to_stream) (CamelDataWrapper *data_wrapper,
- CamelStream *stream);
-
- gssize (*decode_to_stream) (CamelDataWrapper *data_wrapper,
- CamelStream *stream);
-
- gint (*construct_from_stream) (CamelDataWrapper *data_wrapper,
- CamelStream *);
-
- gboolean (*is_offline) (CamelDataWrapper *data_wrapper);
+ void (*set_mime_type) (CamelDataWrapper *data_wrapper,
+ const gchar *mime_type);
+ gchar * (*get_mime_type) (CamelDataWrapper *data_wrapper);
+ CamelContentType *
+ (*get_mime_type_field) (CamelDataWrapper *data_wrapper);
+ void (*set_mime_type_field) (CamelDataWrapper *data_wrapper,
+ CamelContentType *mime_type_field);
+ gssize (*write_to_stream) (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error);
+ gssize (*decode_to_stream) (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error);
+ gint (*construct_from_stream)(CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error);
+ gboolean (*is_offline) (CamelDataWrapper *data_wrapper);
};
-GType camel_data_wrapper_get_type (void);
-
-/* public methods */
-CamelDataWrapper *camel_data_wrapper_new(void);
-gssize camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
- CamelStream *stream);
-gssize camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
- CamelStream *stream);
-
-void camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
- const gchar *mime_type);
-gchar *camel_data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper);
-CamelContentType *camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper);
-void camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
- CamelContentType *mime_type);
-
-gint camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
- CamelStream *stream);
-
-gboolean camel_data_wrapper_is_offline (CamelDataWrapper *data_wrapper);
+GType camel_data_wrapper_get_type (void);
+CamelDataWrapper *
+ camel_data_wrapper_new (void);
+gssize camel_data_wrapper_write_to_stream
+ (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error);
+gssize camel_data_wrapper_decode_to_stream
+ (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error);
+void camel_data_wrapper_set_mime_type(CamelDataWrapper *data_wrapper,
+ const gchar *mime_type);
+gchar * camel_data_wrapper_get_mime_type(CamelDataWrapper *data_wrapper);
+CamelContentType *
+ camel_data_wrapper_get_mime_type_field
+ (CamelDataWrapper *data_wrapper);
+void camel_data_wrapper_set_mime_type_field
+ (CamelDataWrapper *data_wrapper,
+ CamelContentType *mime_type);
+gint camel_data_wrapper_construct_from_stream
+ (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error);
+gboolean camel_data_wrapper_is_offline (CamelDataWrapper *data_wrapper);
G_END_DECLS
diff --git a/camel/camel-file-utils.c b/camel/camel-file-utils.c
index f266e0f..9f77c25 100644
--- a/camel/camel-file-utils.c
+++ b/camel/camel-file-utils.c
@@ -38,6 +38,9 @@
#define EWOULDBLOCK EAGAIN
#endif
+#include <gio/gio.h>
+#include <glib/gi18n-lib.h>
+
#include <libedataserver/e-data-server-util.h>
#include "camel-file-utils.h"
@@ -402,6 +405,7 @@ camel_file_util_safe_filename (const gchar *name)
* @fd: file descriptor
* @buf: buffer to fill
* @n: number of bytes to read into @buf
+ * @error: return location for a #GError, or %NULL
*
* Cancellable libc read() replacement.
*
@@ -412,12 +416,19 @@ camel_file_util_safe_filename (const gchar *name)
* be set appropriately.
**/
gssize
-camel_read (gint fd, gchar *buf, gsize n)
+camel_read (gint fd,
+ gchar *buf,
+ gsize n,
+ GError **error)
{
gssize nread;
gint cancel_fd;
if (camel_operation_cancel_check (NULL)) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ _("Cancelled read"));
errno = EINTR;
return -1;
}
@@ -471,6 +482,14 @@ camel_read (gint fd, gchar *buf, gsize n)
#endif
}
+ if (errno != 0) {
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
+ return -1;
+ }
+
return nread;
}
@@ -479,6 +498,7 @@ camel_read (gint fd, gchar *buf, gsize n)
* @fd: file descriptor
* @buf: buffer to write
* @n: number of bytes of @buf to write
+ * @error: return location for a #GError, or %NULL
*
* Cancellable libc write() replacement.
*
@@ -489,12 +509,19 @@ camel_read (gint fd, gchar *buf, gsize n)
* be set appropriately.
**/
gssize
-camel_write (gint fd, const gchar *buf, gsize n)
+camel_write (gint fd,
+ const gchar *buf,
+ gsize n,
+ GError **error)
{
gssize w, written = 0;
gint cancel_fd;
if (camel_operation_cancel_check (NULL)) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ _("Cancelled write"));
errno = EINTR;
return -1;
}
@@ -559,8 +586,13 @@ camel_write (gint fd, const gchar *buf, gsize n)
#endif
}
- if (w == -1)
+ if (errno != 0) {
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
return -1;
+ }
return written;
}
@@ -570,6 +602,7 @@ camel_write (gint fd, const gchar *buf, gsize n)
* @fd: a socket
* @buf: buffer to fill
* @n: number of bytes to read into @buf
+ * @error: return location for a #GError, or %NULL
*
* Cancellable read() replacement for sockets. Code that intends to be
* portable to Win32 should call this function only on sockets
@@ -580,15 +613,22 @@ camel_write (gint fd, const gchar *buf, gsize n)
* camel_read_socket() will retry the read until it gets something.
**/
gssize
-camel_read_socket (gint fd, gchar *buf, gsize n)
+camel_read_socket (gint fd,
+ gchar *buf,
+ gsize n,
+ GError **error)
{
#ifndef G_OS_WIN32
- return camel_read (fd, buf, n);
+ return camel_read (fd, buf, n, error);
#else
gssize nread;
gint cancel_fd;
if (camel_operation_cancel_check (NULL)) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ _("Cancelled read"));
errno = EINTR;
return -1;
}
@@ -632,6 +672,14 @@ camel_read_socket (gint fd, gchar *buf, gsize n)
;
}
+ if (errno != 0) {
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
+ return -1;
+ }
+
return nread;
#endif
}
@@ -641,6 +689,7 @@ camel_read_socket (gint fd, gchar *buf, gsize n)
* @fd: file descriptor
* @buf: buffer to write
* @n: number of bytes of @buf to write
+ * @error: return location for a #GError, or %NULL
*
* Cancellable write() replacement for sockets. Code that intends to
* be portable to Win32 should call this function only on sockets
@@ -650,15 +699,22 @@ camel_read_socket (gint fd, gchar *buf, gsize n)
* be set appropriately.
**/
gssize
-camel_write_socket (gint fd, const gchar *buf, gsize n)
+camel_write_socket (gint fd,
+ const gchar *buf,
+ gsize n,
+ GError **error)
{
#ifndef G_OS_WIN32
- return camel_write (fd, buf, n);
+ return camel_write (fd, buf, n, error);
#else
gssize w, written = 0;
gint cancel_fd;
if (camel_operation_cancel_check (NULL)) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ _("Cancelled read"));
errno = EINTR;
return -1;
}
@@ -711,8 +767,13 @@ camel_write_socket (gint fd, const gchar *buf, gsize n)
ioctlsocket (fd, FIONBIO, &arg);
}
- if (w == -1)
+ if (errno != 0) {
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
return -1;
+ }
return written;
#endif
diff --git a/camel/camel-file-utils.h b/camel/camel-file-utils.h
index 7f031d9..8e5c3ed 100644
--- a/camel/camel-file-utils.h
+++ b/camel/camel-file-utils.h
@@ -66,11 +66,11 @@ 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);
-gssize camel_write (gint fd, const gchar *buf, gsize n);
+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_socket (gint fd, gchar *buf, gsize n);
-gssize camel_write_socket (gint fd, const gchar *buf, gsize n);
+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);
gchar *camel_file_util_savename(const gchar *filename);
diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c
index a2fc9a9..6ddb363 100644
--- a/camel/camel-filter-driver.c
+++ b/camel/camel-filter-driver.c
@@ -834,13 +834,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) == -1) {
+ if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (p->message), stream, NULL) == -1) {
g_object_unref (stream);
close (pipe_from_child);
goto wait;
}
- if (camel_stream_flush (stream) == -1) {
+ if (camel_stream_flush (stream, NULL) == -1) {
g_object_unref (stream);
close (pipe_from_child);
goto wait;
@@ -850,22 +850,22 @@ 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) == -1) {
+ if (camel_stream_write_to_stream (stream, mem, NULL) == -1) {
g_object_unref (stream);
g_object_unref (mem);
goto wait;
}
g_object_unref (stream);
- camel_stream_reset (mem);
+ camel_stream_reset (mem, NULL);
parser = camel_mime_parser_new ();
- camel_mime_parser_init_with_stream (parser, mem);
+ camel_mime_parser_init_with_stream (parser, mem, NULL);
camel_mime_parser_scan_from (parser, FALSE);
g_object_unref (mem);
message = camel_mime_message_new ();
- if (camel_mime_part_construct_from_parser ((CamelMimePart *) message, parser) == -1) {
+ if (camel_mime_part_construct_from_parser ((CamelMimePart *) message, parser, NULL) == -1) {
g_set_error (
&p->error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
_("Invalid message stream received from %s: %s"),
@@ -1290,13 +1290,7 @@ 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) == -1) {
- g_set_error (
- error, CAMEL_ERROR,
- (errno == EINTR) ?
- CAMEL_ERROR_USER_CANCEL :
- CAMEL_ERROR_SYSTEM,
- _("Cannot open message"));
+ if (camel_mime_part_construct_from_parser (mime_part, mp, error) == -1) {
report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Failed on message %d"), i);
g_object_unref (message);
goto fail;
diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c
index 5eeea2a..a0ce715 100644
--- a/camel/camel-filter-search.c
+++ b/camel/camel-filter-search.c
@@ -614,8 +614,9 @@ run_command (struct _ESExp *f, gint argc, struct _ESExpResult **argv, FilterMess
message = camel_filter_search_get_message (fms, f);
stream = camel_stream_fs_new_with_fd (pipe_to_child);
- camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), stream);
- camel_stream_flush (stream);
+ camel_data_wrapper_write_to_stream (
+ CAMEL_DATA_WRAPPER (message), stream, NULL);
+ camel_stream_flush (stream, 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 128a4cd..7febee4 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -1484,8 +1484,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);
- camel_stream_write (stream, "", 1);
+ camel_data_wrapper_decode_to_stream (containee, stream, NULL);
+ camel_stream_write (stream, "", 1, NULL);
for (i=0;i<words->len;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) {
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 5c7fd29..17ebd64 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -4384,8 +4384,9 @@ summary_build_content_info_message(CamelFolderSummary *s, CamelMessageInfo *msgi
CAMEL_STREAM_FILTER (p->filter_stream),
p->filter_index);
- camel_data_wrapper_decode_to_stream(containee, p->filter_stream);
- camel_stream_flush(p->filter_stream);
+ camel_data_wrapper_decode_to_stream (
+ containee, p->filter_stream, NULL);
+ camel_stream_flush(p->filter_stream, NULL);
camel_stream_filter_remove (
CAMEL_STREAM_FILTER (p->filter_stream), idx_id);
diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c
index 28f404f..ce2d747 100644
--- a/camel/camel-gpg-context.c
+++ b/camel/camel-gpg-context.c
@@ -368,7 +368,7 @@ gpg_ctx_get_diagnostics (struct _GpgCtx *gpg)
{
if (!gpg->diagflushed) {
gpg->diagflushed = TRUE;
- camel_stream_flush (gpg->diagnostics);
+ camel_stream_flush (gpg->diagnostics, NULL);
if (gpg->diagbuf->len == 0)
return NULL;
@@ -1115,7 +1115,8 @@ gpg_ctx_op_step (struct _GpgCtx *gpg,
goto exception;
if (nread > 0) {
- gsize written = camel_stream_write (gpg->ostream, buffer, (gsize) nread);
+ gsize written = camel_stream_write (
+ gpg->ostream, buffer, (gsize) nread, NULL);
if (written != nread)
goto exception;
} else {
@@ -1136,7 +1137,7 @@ gpg_ctx_op_step (struct _GpgCtx *gpg,
goto exception;
if (nread > 0) {
- camel_stream_write (gpg->diagnostics, buffer, nread);
+ camel_stream_write (gpg->diagnostics, buffer, nread, NULL);
} else {
gpg->seen_eof2 = TRUE;
}
@@ -1177,7 +1178,8 @@ gpg_ctx_op_step (struct _GpgCtx *gpg,
d(printf ("writing to gpg's stdin...\n"));
/* write our stream to gpg's stdin */
- nread = camel_stream_read (gpg->istream, buffer, sizeof (buffer));
+ nread = camel_stream_read (
+ gpg->istream, buffer, sizeof (buffer), error);
if (nread > 0) {
gssize w, nwritten = 0;
@@ -1315,13 +1317,13 @@ gpg_sign (CamelCipherContext *context,
/* FIXME: stream this, we stream output at least */
istream = camel_stream_mem_new();
- if (camel_cipher_canonical_to_stream(ipart, CAMEL_MIME_FILTER_CANON_STRIP|CAMEL_MIME_FILTER_CANON_CRLF|CAMEL_MIME_FILTER_CANON_FROM,
- istream) == -1) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Could not generate signing data: %s"),
- g_strerror (errno));
+ if (camel_cipher_canonical_to_stream(
+ ipart, CAMEL_MIME_FILTER_CANON_STRIP |
+ CAMEL_MIME_FILTER_CANON_CRLF |
+ CAMEL_MIME_FILTER_CANON_FROM,
+ istream, error) == -1) {
+ g_prefix_error (
+ error, _("Could not generate signing data: "));
goto fail;
}
@@ -1380,8 +1382,8 @@ gpg_sign (CamelCipherContext *context,
res = 0;
dw = camel_data_wrapper_new();
- camel_stream_reset(ostream);
- camel_data_wrapper_construct_from_stream(dw, ostream);
+ camel_stream_reset(ostream, NULL);
+ camel_data_wrapper_construct_from_stream(dw, ostream, NULL);
sigpart = camel_mime_part_new();
ct = camel_content_type_new("application", "pgp-signature");
@@ -1404,7 +1406,7 @@ gpg_sign (CamelCipherContext *context,
mps->signature = sigpart;
mps->contentraw = istream;
- camel_stream_reset(istream);
+ camel_stream_reset(istream, NULL);
g_object_ref (istream);
camel_medium_set_content ((CamelMedium *)opart, (CamelDataWrapper *)mps);
@@ -1418,7 +1420,8 @@ fail:
}
static gchar *
-swrite (CamelMimePart *sigpart)
+swrite (CamelMimePart *sigpart,
+ GError **error)
{
CamelStream *ostream;
gchar *template;
@@ -1433,11 +1436,12 @@ swrite (CamelMimePart *sigpart)
/* 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((CamelDataWrapper *)sigpart, ostream);
+ ret = camel_data_wrapper_write_to_stream (
+ CAMEL_DATA_WRAPPER (sigpart), ostream, error);
if (ret != -1) {
- ret = camel_stream_flush (ostream);
+ ret = camel_stream_flush (ostream, error);
if (ret != -1)
- ret = camel_stream_close (ostream);
+ ret = camel_stream_close (ostream, error);
}
g_object_unref (ostream);
@@ -1510,8 +1514,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);
- camel_stream_reset(istream);
+ camel_data_wrapper_decode_to_stream (content, istream, NULL);
+ camel_stream_reset(istream, NULL);
sigpart = NULL;
} else {
/* Invalid Mimetype */
@@ -1554,18 +1558,15 @@ gpg_verify (CamelCipherContext *context,
#endif
if (sigpart) {
- sigfile = swrite (sigpart);
+ sigfile = swrite (sigpart, error);
if (sigfile == NULL) {
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
- _("Cannot verify message signature: "
- "could not create temp file: %s"),
- g_strerror (errno));
+ g_prefix_error (
+ error, _("Cannot verify message signature: "));
goto exception;
}
}
- camel_stream_reset(istream);
+ camel_stream_reset (istream, NULL);
canon_stream = camel_stream_mem_new ();
/* strip trailing white-spaces */
@@ -1574,12 +1575,12 @@ gpg_verify (CamelCipherContext *context,
camel_stream_filter_add (CAMEL_STREAM_FILTER (filter), canon);
g_object_unref (canon);
- camel_stream_write_to_stream (istream, filter);
+ camel_stream_write_to_stream (istream, filter, NULL);
g_object_unref (filter);
- camel_stream_reset (istream);
+ camel_stream_reset (istream, NULL);
- camel_stream_reset (canon_stream);
+ camel_stream_reset (canon_stream, NULL);
gpg = gpg_ctx_new (context);
gpg_ctx_set_mode (gpg, GPG_CTX_MODE_VERIFY);
@@ -1675,11 +1676,10 @@ 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) == -1) {
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
- _("Could not generate encrypting data: %s"),
- g_strerror (errno));
+ if (camel_cipher_canonical_to_stream (
+ ipart, CAMEL_MIME_FILTER_CANON_CRLF, istream, error) == -1) {
+ g_prefix_error (
+ error, _("Could not generate encrypting data: "));
goto fail1;
}
@@ -1722,7 +1722,7 @@ gpg_encrypt (CamelCipherContext *context,
res = 0;
dw = camel_data_wrapper_new();
- camel_data_wrapper_construct_from_stream(dw, ostream);
+ camel_data_wrapper_construct_from_stream (dw, ostream, NULL);
encpart = camel_mime_part_new();
ct = camel_content_type_new("application", "octet-stream");
@@ -1736,13 +1736,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"));
- camel_stream_reset(vstream);
+ camel_stream_write (vstream, "Version: 1\n", strlen("Version: 1\n"), 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);
+ camel_data_wrapper_construct_from_stream (dw, vstream, NULL);
g_object_unref (vstream);
camel_medium_set_content ((CamelMedium *)verpart, dw);
g_object_unref (dw);
@@ -1827,8 +1827,8 @@ gpg_decrypt (CamelCipherContext *context,
}
istream = camel_stream_mem_new();
- camel_data_wrapper_decode_to_stream (content, istream);
- camel_stream_reset(istream);
+ camel_data_wrapper_decode_to_stream (content, istream, NULL);
+ camel_stream_reset (istream, NULL);
ostream = camel_stream_mem_new();
camel_stream_mem_set_secure((CamelStreamMem *)ostream);
@@ -1861,20 +1861,21 @@ gpg_decrypt (CamelCipherContext *context,
goto fail;
}
- camel_stream_reset(ostream);
+ camel_stream_reset (ostream, NULL);
if (camel_content_type_is(ct, "multipart", "encrypted")) {
CamelDataWrapper *dw;
CamelStream *null = camel_stream_null_new ();
/* Multipart encrypted - parse a full mime part */
- rv = camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)opart, ostream);
+ rv = camel_data_wrapper_construct_from_stream (
+ CAMEL_DATA_WRAPPER (opart), ostream, error);
dw = camel_medium_get_content ((CamelMedium *)opart);
- if (!camel_data_wrapper_decode_to_stream (dw, null)) {
+ if (!camel_data_wrapper_decode_to_stream (dw, null, 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);
+ rv = camel_data_wrapper_construct_from_stream (dw, ostream, error);
}
g_object_unref (null);
@@ -1882,7 +1883,7 @@ 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);
+ rv = camel_data_wrapper_construct_from_stream (dw, ostream, error);
camel_data_wrapper_set_mime_type(dw, "application/octet-stream");
camel_medium_set_content ((CamelMedium *)opart, dw);
g_object_unref (dw);
@@ -1909,10 +1910,6 @@ gpg_decrypt (CamelCipherContext *context,
valid->sign.status = CAMEL_CIPHER_VALIDITY_SIGN_BAD;
}
}
- } else {
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
- _("Unable to parse message content"));
}
fail:
diff --git a/camel/camel-http-stream.c b/camel/camel-http-stream.c
index 493c434..0f3138d 100644
--- a/camel/camel-http-stream.c
+++ b/camel/camel-http-stream.c
@@ -30,6 +30,9 @@
#include <stdlib.h>
#include <string.h>
+#include <gio/gio.h>
+#include <glib/gi18n-lib.h>
+
#include "camel-http-stream.h"
#include "camel-mime-utils.h"
#include "camel-net-utils.h"
@@ -42,150 +45,18 @@
#include "camel-tcp-stream-ssl.h"
#endif
+#define SSL_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
+
#define d(x)
static gpointer parent_class;
-static gssize stream_read (CamelStream *stream, gchar *buffer, gsize n);
-static gssize stream_write (CamelStream *stream, const gchar *buffer, gsize n);
-static gint stream_flush (CamelStream *stream);
-static gint stream_close (CamelStream *stream);
-static gint stream_reset (CamelStream *stream);
-
-static void
-http_stream_dispose (GObject *object)
-{
- CamelHttpStream *http = CAMEL_HTTP_STREAM (object);
-
- if (http->parser != NULL) {
- g_object_unref (http->parser);
- http->parser = NULL;
- }
-
- if (http->content_type != NULL) {
- camel_content_type_unref (http->content_type);
- http->content_type = NULL;
- }
-
- if (http->session != NULL) {
- g_object_unref (http->session);
- http->session = NULL;
- }
-
- if (http->raw != NULL) {
- g_object_unref (http->raw);
- http->raw = NULL;
- }
-
- if (http->read != NULL) {
- g_object_unref (http->read);
- http->read = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-http_stream_finalize (GObject *object)
-{
- CamelHttpStream *http = CAMEL_HTTP_STREAM (object);
-
- camel_header_raw_clear (http->raw_headers);
- g_queue_free (http->raw_headers);
-
- if (http->url != NULL)
- camel_url_free (http->url);
-
- if (http->proxy)
- camel_url_free (http->proxy);
-
- g_free (http->authrealm);
- g_free (http->authpass);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-http_stream_class_init (CamelHttpStreamClass *class)
-{
- GObjectClass *object_class;
- CamelStreamClass *stream_class;
-
- parent_class = g_type_class_peek_parent (class);
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = http_stream_dispose;
- object_class->finalize = http_stream_finalize;
-
- stream_class = CAMEL_STREAM_CLASS (class);
- stream_class->read = stream_read;
- stream_class->write = stream_write;
- stream_class->flush = stream_flush;
- stream_class->close = stream_close;
- stream_class->reset = stream_reset;
-}
-
-static void
-http_stream_init (CamelHttpStream *http)
-{
- http->raw_headers = g_queue_new ();
-}
-
-GType
-camel_http_stream_get_type (void)
-{
- static GType type = G_TYPE_INVALID;
-
- if (G_UNLIKELY (type == G_TYPE_INVALID))
- type = g_type_register_static_simple (
- CAMEL_TYPE_STREAM,
- "CamelHttpStream",
- sizeof (CamelHttpStreamClass),
- (GClassInitFunc) http_stream_class_init,
- sizeof (CamelHttpStream),
- (GInstanceInitFunc) http_stream_init,
- 0);
-
- return type;
-}
-
-/**
- * camel_http_stream_new:
- * @method: HTTP method
- * @session: active session
- * @url: URL to act upon
- *
- * Return value: a http stream
- **/
-CamelStream *
-camel_http_stream_new (CamelHttpMethod method, struct _CamelSession *session, CamelURL *url)
-{
- CamelHttpStream *stream;
- gchar *str;
-
- g_return_val_if_fail(CAMEL_IS_SESSION(session), NULL);
- g_return_val_if_fail(url != NULL, NULL);
-
- stream = g_object_new (CAMEL_TYPE_HTTP_STREAM, NULL);
-
- stream->method = method;
- stream->session = session;
- g_object_ref (session);
-
- str = camel_url_to_string (url, 0);
- stream->url = camel_url_new (str, NULL);
- g_free (str);
-
- return (CamelStream *)stream;
-}
-
-#define SSL_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
-
static CamelStream *
-http_connect (CamelHttpStream *http, CamelURL *url)
+http_connect (CamelHttpStream *http,
+ CamelURL *url,
+ GError **error)
{
+ CamelTcpStream *tcp_stream;
CamelStream *stream = NULL;
struct addrinfo *ai, hints = { 0 };
gint errsave;
@@ -220,7 +91,9 @@ http_connect (CamelHttpStream *http, CamelURL *url)
return NULL;
}
- if (camel_tcp_stream_connect (CAMEL_TCP_STREAM (stream), ai) == -1) {
+ tcp_stream = CAMEL_TCP_STREAM (stream);
+
+ if (camel_tcp_stream_connect (tcp_stream, ai, error) == -1) {
errsave = errno;
g_object_unref (stream);
camel_freeaddrinfo(ai);
@@ -237,7 +110,7 @@ http_connect (CamelHttpStream *http, CamelURL *url)
}
static void
-http_disconnect(CamelHttpStream *http)
+http_disconnect (CamelHttpStream *http)
{
if (http->raw) {
g_object_unref (http->raw);
@@ -255,41 +128,80 @@ http_disconnect(CamelHttpStream *http)
}
}
-static const gchar *
-http_next_token (const guchar *in)
+static gint
+http_method_invoke (CamelHttpStream *http,
+ GError **error)
{
- const guchar *inptr = in;
+ const gchar *method = NULL, *use_url;
+ gchar *url;
- while (*inptr && !isspace ((gint) *inptr))
- inptr++;
+ switch (http->method) {
+ case CAMEL_HTTP_METHOD_GET:
+ method = "GET";
+ break;
+ case CAMEL_HTTP_METHOD_HEAD:
+ method = "HEAD";
+ break;
+ default:
+ g_assert_not_reached ();
+ }
- while (*inptr && isspace ((gint) *inptr))
- inptr++;
+ url = camel_url_to_string (http->url, 0);
- return (const gchar *) inptr;
-}
+ if (http->proxy) {
+ use_url = url;
+ } else if (http->url->host && *http->url->host) {
+ use_url = strstr (url, http->url->host) + strlen (http->url->host);
+ } else {
+ use_url = http->url->path;
+ }
-static gint
-http_get_statuscode (CamelHttpStream *http)
-{
- const gchar *token;
- gchar buffer[4096];
+ d(printf("HTTP Stream Sending: %s %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\n",
+ method,
+ use_url,
+ http->user_agent ? http->user_agent : "CamelHttpStream/1.0",
+ http->url->host));
+ if (camel_stream_printf (
+ http->raw, error,
+ "%s %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\n",
+ method, use_url, http->user_agent ? http->user_agent :
+ "CamelHttpStream/1.0", http->url->host) == -1) {
+ http_disconnect(http);
+ g_free (url);
+ return -1;
+ }
+ g_free (url);
+
+ if (http->authrealm) {
+ d(printf("HTTP Stream Sending: WWW-Authenticate: %s\n", http->authrealm));
+ }
- if (camel_stream_buffer_gets ((CamelStreamBuffer *)http->read, buffer, sizeof (buffer)) <= 0)
+ if (http->authrealm && camel_stream_printf (
+ http->raw, error, "WWW-Authenticate: %s\r\n",
+ http->authrealm) == -1) {
+ http_disconnect(http);
return -1;
+ }
- d(printf("HTTP Status: %s\n", buffer));
+ if (http->authpass && http->proxy) {
+ d(printf("HTTP Stream Sending: Proxy-Aurhorization: Basic %s\n", http->authpass));
+ }
- /* parse the HTTP status code */
- if (!g_ascii_strncasecmp (buffer, "HTTP/", 5)) {
- token = http_next_token ((const guchar *) buffer);
- http->statuscode = camel_header_decode_int (&token);
- return http->statuscode;
+ if (http->authpass && http->proxy && camel_stream_printf (
+ http->raw, error, "Proxy-Authorization: Basic %s\r\n",
+ http->authpass) == -1) {
+ http_disconnect(http);
+ return -1;
}
- http_disconnect(http);
+ /* end the headers */
+ if (camel_stream_write (http->raw, "\r\n", 2, error) == -1 ||
+ camel_stream_flush (http->raw, error) == -1) {
+ http_disconnect(http);
+ return -1;
+ }
- return -1;
+ return 0;
}
static gint
@@ -306,7 +218,7 @@ http_get_headers (CamelHttpStream *http)
g_object_unref (http->parser);
http->parser = camel_mime_parser_new ();
- camel_mime_parser_init_with_stream (http->parser, http->read);
+ camel_mime_parser_init_with_stream (http->parser, http->read, NULL);
switch (camel_mime_parser_step (http->parser, &buf, &len)) {
case CAMEL_MIME_PARSER_STATE_MESSAGE:
@@ -361,79 +273,106 @@ http_get_headers (CamelHttpStream *http)
return -1;
}
-static gint
-http_method_invoke (CamelHttpStream *http)
+static const gchar *
+http_next_token (const guchar *in)
{
- const gchar *method = NULL, *use_url;
- gchar *url;
+ const guchar *inptr = in;
- switch (http->method) {
- case CAMEL_HTTP_METHOD_GET:
- method = "GET";
- break;
- case CAMEL_HTTP_METHOD_HEAD:
- method = "HEAD";
- break;
- default:
- g_assert_not_reached ();
- }
+ while (*inptr && !isspace ((gint) *inptr))
+ inptr++;
- url = camel_url_to_string (http->url, 0);
+ while (*inptr && isspace ((gint) *inptr))
+ inptr++;
- if (http->proxy) {
- use_url = url;
- } else if (http->url->host && *http->url->host) {
- use_url = strstr (url, http->url->host) + strlen (http->url->host);
- } else {
- use_url = http->url->path;
- }
+ return (const gchar *) inptr;
+}
- d(printf("HTTP Stream Sending: %s %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\n",
- method,
- use_url,
- http->user_agent ? http->user_agent : "CamelHttpStream/1.0",
- http->url->host));
- if (camel_stream_printf (http->raw, "%s %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\n",
- method,
- use_url,
- http->user_agent ? http->user_agent : "CamelHttpStream/1.0",
- http->url->host) == -1) {
- http_disconnect(http);
- g_free (url);
+static gint
+http_get_statuscode (CamelHttpStream *http,
+ GError **error)
+{
+ const gchar *token;
+ gchar buffer[4096];
+
+ if (camel_stream_buffer_gets (
+ CAMEL_STREAM_BUFFER (http->read),
+ buffer, sizeof (buffer), error) <= 0)
return -1;
+
+ d(printf("HTTP Status: %s\n", buffer));
+
+ /* parse the HTTP status code */
+ if (!g_ascii_strncasecmp (buffer, "HTTP/", 5)) {
+ token = http_next_token ((const guchar *) buffer);
+ http->statuscode = camel_header_decode_int (&token);
+ return http->statuscode;
}
- g_free (url);
- if (http->authrealm) {
- d(printf("HTTP Stream Sending: WWW-Authenticate: %s\n", http->authrealm));
+ http_disconnect(http);
+
+ return -1;
+}
+
+static void
+http_stream_dispose (GObject *object)
+{
+ CamelHttpStream *http = CAMEL_HTTP_STREAM (object);
+
+ if (http->parser != NULL) {
+ g_object_unref (http->parser);
+ http->parser = NULL;
}
- if (http->authrealm && camel_stream_printf (http->raw, "WWW-Authenticate: %s\r\n", http->authrealm) == -1) {
- http_disconnect(http);
- return -1;
+ if (http->content_type != NULL) {
+ camel_content_type_unref (http->content_type);
+ http->content_type = NULL;
}
- if (http->authpass && http->proxy) {
- d(printf("HTTP Stream Sending: Proxy-Aurhorization: Basic %s\n", http->authpass));
+ if (http->session != NULL) {
+ g_object_unref (http->session);
+ http->session = NULL;
}
- if (http->authpass && http->proxy && camel_stream_printf (http->raw, "Proxy-Authorization: Basic %s\r\n",
- http->authpass) == -1) {
- http_disconnect(http);
- return -1;
+ if (http->raw != NULL) {
+ g_object_unref (http->raw);
+ http->raw = NULL;
}
- /* end the headers */
- if (camel_stream_write (http->raw, "\r\n", 2) == -1 || camel_stream_flush (http->raw) == -1) {
- http_disconnect(http);
- return -1;
+ if (http->read != NULL) {
+ g_object_unref (http->read);
+ http->read = NULL;
}
- return 0;
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+http_stream_finalize (GObject *object)
+{
+ CamelHttpStream *http = CAMEL_HTTP_STREAM (object);
+
+ camel_header_raw_clear (http->raw_headers);
+ g_queue_free (http->raw_headers);
+
+ if (http->url != NULL)
+ camel_url_free (http->url);
+
+ if (http->proxy)
+ camel_url_free (http->proxy);
+
+ g_free (http->authrealm);
+ g_free (http->authpass);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gssize
-stream_read (CamelStream *stream, gchar *buffer, gsize n)
+http_stream_read (CamelStream *stream,
+ gchar *buffer,
+ gsize n,
+ GError **error)
{
CamelHttpStream *http = CAMEL_HTTP_STREAM (stream);
const gchar *parser_buf;
@@ -447,15 +386,17 @@ stream_read (CamelStream *stream, gchar *buffer, gsize n)
redirect:
if (!http->raw) {
- if (http_connect (http, http->proxy ? http->proxy : http->url) == NULL)
+ if (http_connect (
+ http, http->proxy ? http->proxy :
+ http->url, error) == NULL)
return -1;
- if (http_method_invoke (http) == -1) {
+ if (http_method_invoke (http, error) == -1) {
http_disconnect(http);
return -1;
}
- if (http_get_statuscode (http) == -1) {
+ if (http_get_statuscode (http, error) == -1) {
http_disconnect(http);
return -1;
}
@@ -526,29 +467,38 @@ stream_read (CamelStream *stream, gchar *buffer, gsize n)
}
static gssize
-stream_write (CamelStream *stream, const gchar *buffer, gsize n)
+http_stream_write (CamelStream *stream,
+ const gchar *buffer,
+ gsize n,
+ GError **error)
{
+ g_set_error (
+ error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Cannot write to HTTP streams"));
+
return -1;
}
static gint
-stream_flush (CamelStream *stream)
+http_stream_flush (CamelStream *stream,
+ GError **error)
{
CamelHttpStream *http = (CamelHttpStream *) stream;
if (http->raw)
- return camel_stream_flush (http->raw);
+ return camel_stream_flush (http->raw, error);
else
return 0;
}
static gint
-stream_close (CamelStream *stream)
+http_stream_close (CamelStream *stream,
+ GError **error)
{
CamelHttpStream *http = (CamelHttpStream *) stream;
if (http->raw) {
- if (camel_stream_close (http->raw) == -1)
+ if (camel_stream_close (http->raw, error) == -1)
return -1;
http_disconnect(http);
@@ -558,7 +508,8 @@ stream_close (CamelStream *stream)
}
static gint
-stream_reset (CamelStream *stream)
+http_stream_reset (CamelStream *stream,
+ GError **error)
{
CamelHttpStream *http = CAMEL_HTTP_STREAM (stream);
@@ -568,13 +519,90 @@ stream_reset (CamelStream *stream)
return 0;
}
+static void
+http_stream_class_init (CamelHttpStreamClass *class)
+{
+ GObjectClass *object_class;
+ CamelStreamClass *stream_class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = http_stream_dispose;
+ object_class->finalize = http_stream_finalize;
+
+ stream_class = CAMEL_STREAM_CLASS (class);
+ stream_class->read = http_stream_read;
+ stream_class->write = http_stream_write;
+ stream_class->flush = http_stream_flush;
+ stream_class->close = http_stream_close;
+ stream_class->reset = http_stream_reset;
+}
+
+static void
+http_stream_init (CamelHttpStream *http)
+{
+ http->raw_headers = g_queue_new ();
+}
+
+GType
+camel_http_stream_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
+
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ type = g_type_register_static_simple (
+ CAMEL_TYPE_STREAM,
+ "CamelHttpStream",
+ sizeof (CamelHttpStreamClass),
+ (GClassInitFunc) http_stream_class_init,
+ sizeof (CamelHttpStream),
+ (GInstanceInitFunc) http_stream_init,
+ 0);
+
+ return type;
+}
+
+/**
+ * camel_http_stream_new:
+ * @method: HTTP method
+ * @session: active session
+ * @url: URL to act upon
+ *
+ * Return value: a http stream
+ **/
+CamelStream *
+camel_http_stream_new (CamelHttpMethod method, struct _CamelSession *session, CamelURL *url)
+{
+ CamelHttpStream *stream;
+ gchar *str;
+
+ g_return_val_if_fail(CAMEL_IS_SESSION(session), NULL);
+ g_return_val_if_fail(url != NULL, NULL);
+
+ stream = g_object_new (CAMEL_TYPE_HTTP_STREAM, NULL);
+
+ stream->method = method;
+ stream->session = session;
+ g_object_ref (session);
+
+ str = camel_url_to_string (url, 0);
+ stream->url = camel_url_new (str, NULL);
+ g_free (str);
+
+ return (CamelStream *)stream;
+}
+
CamelContentType *
-camel_http_stream_get_content_type (CamelHttpStream *http_stream)
+camel_http_stream_get_content_type (CamelHttpStream *http_stream,
+ GError **error)
{
g_return_val_if_fail (CAMEL_IS_HTTP_STREAM (http_stream), NULL);
if (!http_stream->content_type && !http_stream->raw) {
- if (stream_read (CAMEL_STREAM (http_stream), NULL, 0) == -1)
+ CamelStream *stream = CAMEL_STREAM (http_stream);
+
+ if (http_stream_read (stream, NULL, 0, error) == -1)
return NULL;
}
diff --git a/camel/camel-http-stream.h b/camel/camel-http-stream.h
index 5458b18..ce892bf 100644
--- a/camel/camel-http-stream.h
+++ b/camel/camel-http-stream.h
@@ -93,22 +93,26 @@ struct _CamelHttpStream {
struct _CamelHttpStreamClass {
CamelStreamClass parent_class;
-
- /* Virtual methods */
};
-GType camel_http_stream_get_type (void);
-
-/* public methods */
-CamelStream *camel_http_stream_new (CamelHttpMethod method, struct _CamelSession *session, CamelURL *url);
-
-void camel_http_stream_set_user_agent (CamelHttpStream *http_stream, const gchar *user_agent);
-
-void camel_http_stream_set_proxy (CamelHttpStream *http_stream, const gchar *proxy_url);
-void camel_http_stream_set_proxy_authrealm (CamelHttpStream *http_stream, const gchar *proxy_authrealm);
-void camel_http_stream_set_proxy_authpass (CamelHttpStream *http_stream, const gchar *proxy_authpass);
-
-CamelContentType *camel_http_stream_get_content_type (CamelHttpStream *http_stream);
+GType camel_http_stream_get_type (void);
+CamelStream * camel_http_stream_new (CamelHttpMethod method,
+ struct _CamelSession *session,
+ CamelURL *url);
+void camel_http_stream_set_user_agent(CamelHttpStream *http_stream,
+ const gchar *user_agent);
+void camel_http_stream_set_proxy (CamelHttpStream *http_stream,
+ const gchar *proxy_url);
+void camel_http_stream_set_proxy_authrealm
+ (CamelHttpStream *http_stream,
+ const gchar *proxy_authrealm);
+void camel_http_stream_set_proxy_authpass
+ (CamelHttpStream *http_stream,
+ const gchar *proxy_authpass);
+CamelContentType *
+ camel_http_stream_get_content_type
+ (CamelHttpStream *http_stream,
+ GError **error);
G_END_DECLS
diff --git a/camel/camel-index-control.c b/camel/camel-index-control.c
index d1f9693..a9c55dd 100644
--- a/camel/camel-index-control.c
+++ b/camel/camel-index-control.c
@@ -37,19 +37,21 @@ do_compress(gint argc, gchar **argv)
{
gint i;
CamelIndex *idx;
+ GError *error = NULL;
for (i=2;i<argc;i++) {
printf("Opening index file: %s\n", argv[i]);
- idx = (CamelIndex *)camel_text_index_new(argv[i], O_RDWR);
+ idx = (CamelIndex *)camel_text_index_new(argv[i], O_RDWR, &error);
if (idx) {
printf(" Compressing ...\n");
- if (camel_index_compress(idx) == -1) {
+ if (camel_index_compress (idx, &error) == -1) {
g_object_unref (idx);
return 1;
}
g_object_unref (idx);
} else {
- printf(" Failed: %s\n", g_strerror (errno));
+ printf(" Failed: %s\n", error->message);
+ g_error_free (error);
return 1;
}
}
@@ -61,16 +63,18 @@ do_dump(gint argc, gchar **argv)
{
gint i;
CamelIndex *idx;
+ GError *error = NULL;
for (i=2;i<argc;i++) {
printf("Opening index file: %s\n", argv[i]);
- idx = (CamelIndex *)camel_text_index_new(argv[i], O_RDONLY);
+ idx = (CamelIndex *)camel_text_index_new(argv[i], O_RDONLY, &error);
if (idx) {
printf(" Dumping ...\n");
camel_text_index_dump((CamelTextIndex *)idx);
g_object_unref (idx);
} else {
- printf(" Failed: %s\n", g_strerror (errno));
+ printf(" Failed: %s\n", error->message);
+ g_error_free (error);
return 1;
}
}
@@ -82,15 +86,17 @@ do_info(gint argc, gchar **argv)
{
gint i;
CamelIndex *idx;
+ GError *error = NULL;
for (i=2;i<argc;i++) {
printf("Opening index file: %s\n", argv[i]);
- idx = (CamelIndex *)camel_text_index_new(argv[i], O_RDONLY);
+ idx = (CamelIndex *)camel_text_index_new(argv[i], O_RDONLY, &error);
if (idx) {
camel_text_index_info((CamelTextIndex *)idx);
g_object_unref (idx);
} else {
- printf(" Failed: %s\n", g_strerror (errno));
+ printf(" Failed: %s\n", error->message);
+ g_error_free (error);
return 0;
}
}
@@ -102,15 +108,17 @@ do_check(gint argc, gchar **argv)
{
gint i;
CamelIndex *idx;
+ GError *error = NULL;
for (i=2;i<argc;i++) {
printf("Opening index file: %s\n", argv[i]);
- idx = (CamelIndex *)camel_text_index_new(argv[i], O_RDONLY);
+ idx = (CamelIndex *)camel_text_index_new(argv[i], O_RDONLY, &error);
if (idx) {
camel_text_index_validate((CamelTextIndex *)idx);
g_object_unref (idx);
} else {
- printf(" Failed: %s\n", g_strerror (errno));
+ printf(" Failed: %s\n", error->message);
+ g_error_free (error);
return 0;
}
}
@@ -167,7 +175,8 @@ do_perf(gint argc, gchar **argv)
return 1;
}
- idx = (CamelIndex *)camel_text_index_new("/tmp/index", O_TRUNC|O_CREAT|O_RDWR);
+ idx = (CamelIndex *) camel_text_index_new (
+ "/tmp/index", O_TRUNC|O_CREAT|O_RDWR, NULL);
if (idx == NULL) {
perror("open index");
closedir(dir);
@@ -187,8 +196,8 @@ do_perf(gint argc, gchar **argv)
camel_mime_filter_index_set_name(
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);
- camel_stream_write_to_stream(stream, filter);
+ stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0, NULL);
+ camel_stream_write_to_stream(stream, filter, NULL);
g_object_unref (stream);
g_free(name);
@@ -200,7 +209,7 @@ do_perf(gint argc, gchar **argv)
closedir(dir);
- camel_index_sync(idx);
+ camel_index_sync(idx, NULL);
g_object_unref (idx);
g_object_unref (filter);
diff --git a/camel/camel-index.c b/camel/camel-index.c
index ef4ef8d..dc345c3 100644
--- a/camel/camel-index.c
+++ b/camel/camel-index.c
@@ -30,6 +30,8 @@
#include <unistd.h>
#include <sys/stat.h>
+#include <glib/gi18n-lib.h>
+
#include "camel-index.h"
#include "camel-object.h"
@@ -148,7 +150,8 @@ camel_index_set_normalise (CamelIndex *idx, CamelIndexNorm func, gpointer data)
}
gint
-camel_index_sync (CamelIndex *idx)
+camel_index_sync (CamelIndex *idx,
+ GError **error)
{
CamelIndexClass *class;
@@ -158,15 +161,18 @@ camel_index_sync (CamelIndex *idx)
g_return_val_if_fail (class->sync != NULL, -1);
if ((idx->state & CAMEL_INDEX_DELETED) == 0)
- return class->sync (idx);
+ return class->sync (idx, error);
else {
- errno = ENOENT;
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
+ _("Index has been deleted"));
return -1;
}
}
gint
-camel_index_compress (CamelIndex *idx)
+camel_index_compress (CamelIndex *idx,
+ GError **error)
{
CamelIndexClass *class;
@@ -176,9 +182,11 @@ camel_index_compress (CamelIndex *idx)
g_return_val_if_fail (class->compress != NULL, -1);
if ((idx->state & CAMEL_INDEX_DELETED) == 0)
- return class->compress (idx);
+ return class->compress (idx, error);
else {
- errno = ENOENT;
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
+ _("Index has been deleted"));
return -1;
}
}
diff --git a/camel/camel-index.h b/camel/camel-index.h
index 69535a9..21e2a68 100644
--- a/camel/camel-index.h
+++ b/camel/camel-index.h
@@ -168,47 +168,73 @@ struct _CamelIndex {
struct _CamelIndexClass {
CamelObjectClass parent_class;
- gint (*sync)(CamelIndex *idx);
- gint (*compress)(CamelIndex *idx);
- gint (*delete)(CamelIndex *idx);
-
- gint (*rename)(CamelIndex *idx, const gchar *path);
-
- gint (*has_name)(CamelIndex *idx, const gchar *name);
- CamelIndexName * (*add_name)(CamelIndex *idx, const gchar *name);
- gint (*write_name)(CamelIndex *idx, CamelIndexName *idn);
- CamelIndexCursor * (*find_name)(CamelIndex *idx, const gchar *name);
- void (*delete_name)(CamelIndex *idx, const gchar *name);
- CamelIndexCursor * (*find)(CamelIndex *idx, const gchar *word);
-
- CamelIndexCursor * (*words)(CamelIndex *idx);
- CamelIndexCursor * (*names)(CamelIndex *idx);
+ gint (*sync) (CamelIndex *idx,
+ GError **error);
+ gint (*compress) (CamelIndex *idx,
+ GError **error);
+ gint (*delete) (CamelIndex *idx);
+
+ gint (*rename) (CamelIndex *idx,
+ const gchar *path);
+
+ gint (*has_name) (CamelIndex *idx,
+ const gchar *name);
+ CamelIndexName *(*add_name) (CamelIndex *idx,
+ const gchar *name);
+ gint (*write_name) (CamelIndex *idx,
+ CamelIndexName *idn);
+ CamelIndexCursor *
+ (*find_name) (CamelIndex *idx,
+ const gchar *name);
+ void (*delete_name) (CamelIndex *idx,
+ const gchar *name);
+ CamelIndexCursor *
+ (*find) (CamelIndex *idx,
+ const gchar *word);
+ CamelIndexCursor *
+ (*words) (CamelIndex *idx);
+ CamelIndexCursor *
+ (*names) (CamelIndex *idx);
};
/* flags, stored in 'state', set with set_state */
#define CAMEL_INDEX_DELETED (1<<0)
-GType camel_index_get_type (void);
-
-CamelIndex *camel_index_new(const gchar *path, gint flags);
-void camel_index_construct(CamelIndex *, const gchar *path, gint flags);
-gint camel_index_rename(CamelIndex *, const gchar *path);
-
-void camel_index_set_normalise(CamelIndex *idx, CamelIndexNorm func, gpointer data);
-
-gint camel_index_sync(CamelIndex *idx);
-gint camel_index_compress(CamelIndex *idx);
-gint camel_index_delete(CamelIndex *idx);
-
-gint camel_index_has_name(CamelIndex *idx, const gchar *name);
-CamelIndexName *camel_index_add_name(CamelIndex *idx, const gchar *name);
-gint camel_index_write_name(CamelIndex *idx, CamelIndexName *idn);
-CamelIndexCursor *camel_index_find_name(CamelIndex *idx, const gchar *name);
-void camel_index_delete_name(CamelIndex *idx, const gchar *name);
-CamelIndexCursor *camel_index_find(CamelIndex *idx, const gchar *word);
-
-CamelIndexCursor *camel_index_words(CamelIndex *idx);
-CamelIndexCursor *camel_index_names(CamelIndex *idx);
+GType camel_index_get_type (void);
+CamelIndex * camel_index_new (const gchar *path,
+ gint flags);
+void camel_index_construct (CamelIndex *index,
+ const gchar *path,
+ gint flags);
+gint camel_index_rename (CamelIndex *index,
+ const gchar *path);
+void camel_index_set_normalise
+ (CamelIndex *idx,
+ CamelIndexNorm func,
+ gpointer data);
+gint camel_index_sync (CamelIndex *idx,
+ GError **error);
+gint camel_index_compress (CamelIndex *idx,
+ GError **error);
+gint camel_index_delete (CamelIndex *idx);
+gint camel_index_has_name (CamelIndex *idx,
+ const gchar *name);
+CamelIndexName *camel_index_add_name (CamelIndex *idx,
+ const gchar *name);
+gint camel_index_write_name (CamelIndex *idx,
+ CamelIndexName *idn);
+CamelIndexCursor *
+ camel_index_find_name (CamelIndex *idx,
+ const gchar *name);
+void camel_index_delete_name (CamelIndex *idx,
+ const gchar *name);
+CamelIndexCursor *
+ camel_index_find (CamelIndex *idx,
+ const gchar *word);
+CamelIndexCursor *
+ camel_index_words (CamelIndex *idx);
+CamelIndexCursor *
+ camel_index_names (CamelIndex *idx);
G_END_DECLS
diff --git a/camel/camel-mime-filter-save.c b/camel/camel-mime-filter-save.c
index fa5aed0..1b98b89 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);
+ camel_stream_write (priv->stream, in, len, NULL);
*out = (gchar *) in;
*outlen = len;
diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c
index 71fad18..fb1b2f5 100644
--- a/camel/camel-mime-message.c
+++ b/camel/camel-mime-message.c
@@ -87,12 +87,98 @@ static const gchar *recipient_names[] = {
static gpointer parent_class;
static GHashTable *header_name_table;
-static gssize write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
-static void add_header (CamelMedium *medium, const gchar *name, gconstpointer value);
-static void set_header (CamelMedium *medium, const gchar *name, gconstpointer value);
-static void remove_header (CamelMedium *medium, const gchar *name);
-static gint construct_from_parser (CamelMimePart *, CamelMimeParser *);
-static void unref_recipient (gpointer key, gpointer value, gpointer user_data);
+/* FIXME: check format of fields. */
+static gboolean
+process_header (CamelMedium *medium,
+ const gchar *name,
+ const gchar *value)
+{
+ CamelHeaderType header_type;
+ CamelMimeMessage *message = CAMEL_MIME_MESSAGE (medium);
+ CamelInternetAddress *addr;
+ const gchar *charset;
+ gchar *unfolded;
+
+ header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, name);
+ switch (header_type) {
+ case HEADER_FROM:
+ addr = camel_internet_address_new();
+ unfolded = camel_header_unfold (value);
+ if (camel_address_decode ((CamelAddress *) addr, unfolded) <= 0) {
+ g_object_unref (addr);
+ } else {
+ if (message->from)
+ g_object_unref (message->from);
+ message->from = addr;
+ }
+ g_free (unfolded);
+ break;
+ case HEADER_REPLY_TO:
+ addr = camel_internet_address_new();
+ unfolded = camel_header_unfold (value);
+ if (camel_address_decode ((CamelAddress *) addr, unfolded) <= 0) {
+ g_object_unref (addr);
+ } else {
+ if (message->reply_to)
+ g_object_unref (message->reply_to);
+ message->reply_to = addr;
+ }
+ g_free (unfolded);
+ break;
+ case HEADER_SUBJECT:
+ g_free (message->subject);
+ if (((CamelDataWrapper *) message)->mime_type) {
+ charset = camel_content_type_param (((CamelDataWrapper *) message)->mime_type, "charset");
+ charset = camel_iconv_charset_name (charset);
+ } else
+ charset = NULL;
+
+ unfolded = camel_header_unfold (value);
+ message->subject = g_strstrip (camel_header_decode_string (unfolded, charset));
+ g_free (unfolded);
+ break;
+ case HEADER_TO:
+ case HEADER_CC:
+ case HEADER_BCC:
+ case HEADER_RESENT_TO:
+ case HEADER_RESENT_CC:
+ case HEADER_RESENT_BCC:
+ addr = g_hash_table_lookup (message->recipients, name);
+ if (value) {
+ unfolded = camel_header_unfold (value);
+ camel_address_decode (CAMEL_ADDRESS (addr), unfolded);
+ g_free (unfolded);
+ } else {
+ camel_address_remove (CAMEL_ADDRESS (addr), -1);
+ }
+ return FALSE;
+ case HEADER_DATE:
+ if (value) {
+ message->date = camel_header_decode_date (value, &message->date_offset);
+ } else {
+ message->date = CAMEL_MESSAGE_DATE_CURRENT;
+ message->date_offset = 0;
+ }
+ break;
+ case HEADER_MESSAGE_ID:
+ g_free (message->message_id);
+ if (value)
+ message->message_id = camel_header_msgid_decode (value);
+ else
+ message->message_id = NULL;
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+unref_recipient (gpointer key, gpointer value, gpointer user_data)
+{
+ g_object_unref (value);
+}
static void
mime_message_dispose (GObject *object)
@@ -129,6 +215,124 @@ mime_message_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static gssize
+mime_message_write_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error)
+{
+ CamelDataWrapperClass *data_wrapper_class;
+ CamelMimeMessage *mm = CAMEL_MIME_MESSAGE (data_wrapper);
+
+ /* force mandatory headers ... */
+ if (mm->from == NULL) {
+ /* FIXME: should we just abort? Should we make one up? */
+ g_warning ("No from set for message");
+ camel_medium_set_header ((CamelMedium *)mm, "From", "");
+ }
+ if (!camel_medium_get_header ((CamelMedium *)mm, "Date"))
+ camel_mime_message_set_date (mm, CAMEL_MESSAGE_DATE_CURRENT, 0);
+
+ if (mm->subject == NULL)
+ camel_mime_message_set_subject (mm, "No Subject");
+
+ if (mm->message_id == NULL)
+ camel_mime_message_set_message_id (mm, NULL);
+
+ /* FIXME: "To" header needs to be set explicitly as well ... */
+
+ if (!camel_medium_get_header ((CamelMedium *)mm, "Mime-Version"))
+ 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 (parent_class);
+ return data_wrapper_class->write_to_stream (data_wrapper, stream, error);
+}
+
+static void
+mime_message_add_header (CamelMedium *medium,
+ const gchar *name,
+ gconstpointer value)
+{
+ CamelMediumClass *medium_class;
+
+ medium_class = CAMEL_MEDIUM_CLASS (parent_class);
+
+ /* if we process it, then it must be forced unique as well ... */
+ if (process_header (medium, name, value))
+ medium_class->set_header (medium, name, value);
+ else
+ medium_class->add_header (medium, name, value);
+}
+
+static void
+mime_message_set_header (CamelMedium *medium,
+ const gchar *name,
+ gconstpointer value)
+{
+ process_header (medium, name, value);
+
+ /* Chain up to parent's set_header() method. */
+ CAMEL_MEDIUM_CLASS (parent_class)->set_header (medium, name, value);
+}
+
+static void
+mime_message_remove_header (CamelMedium *medium,
+ const gchar *name)
+{
+ process_header (medium, name, NULL);
+
+ /* Chain up to parent's remove_header() method. */
+ CAMEL_MEDIUM_CLASS (parent_class)->remove_header (medium, name);
+}
+
+static gint
+mime_message_construct_from_parser (CamelMimePart *dw,
+ CamelMimeParser *mp,
+ GError **error)
+{
+ CamelMimePartClass *mime_part_class;
+ gchar *buf;
+ gsize len;
+ gint state;
+ gint ret;
+ gint err;
+
+ d(printf("constructing mime-message\n"));
+
+ d(printf("mime_message::construct_from_parser()\n"));
+
+ /* let the mime-part construct the guts ... */
+ mime_part_class = CAMEL_MIME_PART_CLASS (parent_class);
+ ret = mime_part_class->construct_from_parser (dw, mp, error);
+
+ if (ret == -1)
+ return -1;
+
+ /* ... then clean up the follow-on state */
+ state = camel_mime_parser_step (mp, &buf, &len);
+ switch (state) {
+ case CAMEL_MIME_PARSER_STATE_EOF:
+ case CAMEL_MIME_PARSER_STATE_FROM_END:
+ /* these doesn't belong to us */
+ camel_mime_parser_unstep (mp);
+ case CAMEL_MIME_PARSER_STATE_MESSAGE_END:
+ break;
+ default:
+ g_error ("Bad parser state: Expecing MESSAGE_END or EOF or EOM, got: %u", camel_mime_parser_state (mp));
+ camel_mime_parser_unstep (mp);
+ return -1;
+ }
+
+ d(printf("mime_message::construct_from_parser() leaving\n"));
+ err = camel_mime_parser_errno(mp);
+ if (err != 0) {
+ errno = err;
+ ret = -1;
+ }
+
+ return ret;
+}
+
static void
mime_message_class_init (CamelMimeMessageClass *class)
{
@@ -145,16 +349,16 @@ mime_message_class_init (CamelMimeMessageClass *class)
object_class->finalize = mime_message_finalize;
data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
- data_wrapper_class->write_to_stream = write_to_stream;
- data_wrapper_class->decode_to_stream = write_to_stream;
+ data_wrapper_class->write_to_stream = mime_message_write_to_stream;
+ data_wrapper_class->decode_to_stream = mime_message_write_to_stream;
medium_class = CAMEL_MEDIUM_CLASS (class);
- medium_class->add_header = add_header;
- medium_class->set_header = set_header;
- medium_class->remove_header = remove_header;
+ medium_class->add_header = mime_message_add_header;
+ medium_class->set_header = mime_message_set_header;
+ medium_class->remove_header = mime_message_remove_header;
mime_part_class = CAMEL_MIME_PART_CLASS (class);
- mime_part_class->construct_from_parser = construct_from_parser;
+ mime_part_class->construct_from_parser = mime_message_construct_from_parser;
header_name_table = g_hash_table_new (
camel_strcase_hash, camel_strcase_equal);
@@ -208,12 +412,6 @@ camel_mime_message_get_type (void)
return type;
}
-static void
-unref_recipient (gpointer key, gpointer value, gpointer user_data)
-{
- g_object_unref (value);
-}
-
/**
* camel_mime_message_new:
*
@@ -590,188 +788,6 @@ camel_mime_message_get_source (CamelMimeMessage *mime_message)
return src;
}
-/* mime_message */
-static gint
-construct_from_parser (CamelMimePart *dw, CamelMimeParser *mp)
-{
- gchar *buf;
- gsize len;
- gint state;
- gint ret;
- gint err;
-
- d(printf("constructing mime-message\n"));
-
- d(printf("mime_message::construct_from_parser()\n"));
-
- /* let the mime-part construct the guts ... */
- ret = ((CamelMimePartClass *)parent_class)->construct_from_parser(dw, mp);
-
- if (ret == -1)
- return -1;
-
- /* ... then clean up the follow-on state */
- state = camel_mime_parser_step (mp, &buf, &len);
- switch (state) {
- case CAMEL_MIME_PARSER_STATE_EOF:
- case CAMEL_MIME_PARSER_STATE_FROM_END:
- /* these doesn't belong to us */
- camel_mime_parser_unstep (mp);
- case CAMEL_MIME_PARSER_STATE_MESSAGE_END:
- break;
- default:
- g_error ("Bad parser state: Expecing MESSAGE_END or EOF or EOM, got: %u", camel_mime_parser_state (mp));
- camel_mime_parser_unstep (mp);
- return -1;
- }
-
- d(printf("mime_message::construct_from_parser() leaving\n"));
- err = camel_mime_parser_errno(mp);
- if (err != 0) {
- errno = err;
- ret = -1;
- }
-
- return ret;
-}
-
-static gssize
-write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
-{
- CamelMimeMessage *mm = CAMEL_MIME_MESSAGE (data_wrapper);
-
- /* force mandatory headers ... */
- if (mm->from == NULL) {
- /* FIXME: should we just abort? Should we make one up? */
- g_warning ("No from set for message");
- camel_medium_set_header ((CamelMedium *)mm, "From", "");
- }
- if (!camel_medium_get_header ((CamelMedium *)mm, "Date"))
- camel_mime_message_set_date (mm, CAMEL_MESSAGE_DATE_CURRENT, 0);
-
- if (mm->subject == NULL)
- camel_mime_message_set_subject (mm, "No Subject");
-
- if (mm->message_id == NULL)
- camel_mime_message_set_message_id (mm, NULL);
-
- /* FIXME: "To" header needs to be set explicitly as well ... */
-
- if (!camel_medium_get_header ((CamelMedium *)mm, "Mime-Version"))
- camel_medium_set_header ((CamelMedium *)mm, "Mime-Version", "1.0");
-
- return CAMEL_DATA_WRAPPER_CLASS (parent_class)->write_to_stream (data_wrapper, stream);
-}
-
-/* FIXME: check format of fields. */
-static gboolean
-process_header (CamelMedium *medium, const gchar *name, const gchar *value)
-{
- CamelHeaderType header_type;
- CamelMimeMessage *message = CAMEL_MIME_MESSAGE (medium);
- CamelInternetAddress *addr;
- const gchar *charset;
- gchar *unfolded;
-
- header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, name);
- switch (header_type) {
- case HEADER_FROM:
- addr = camel_internet_address_new();
- unfolded = camel_header_unfold (value);
- if (camel_address_decode ((CamelAddress *) addr, unfolded) <= 0) {
- g_object_unref (addr);
- } else {
- if (message->from)
- g_object_unref (message->from);
- message->from = addr;
- }
- g_free (unfolded);
- break;
- case HEADER_REPLY_TO:
- addr = camel_internet_address_new();
- unfolded = camel_header_unfold (value);
- if (camel_address_decode ((CamelAddress *) addr, unfolded) <= 0) {
- g_object_unref (addr);
- } else {
- if (message->reply_to)
- g_object_unref (message->reply_to);
- message->reply_to = addr;
- }
- g_free (unfolded);
- break;
- case HEADER_SUBJECT:
- g_free (message->subject);
- if (((CamelDataWrapper *) message)->mime_type) {
- charset = camel_content_type_param (((CamelDataWrapper *) message)->mime_type, "charset");
- charset = camel_iconv_charset_name (charset);
- } else
- charset = NULL;
-
- unfolded = camel_header_unfold (value);
- message->subject = g_strstrip (camel_header_decode_string (unfolded, charset));
- g_free (unfolded);
- break;
- case HEADER_TO:
- case HEADER_CC:
- case HEADER_BCC:
- case HEADER_RESENT_TO:
- case HEADER_RESENT_CC:
- case HEADER_RESENT_BCC:
- addr = g_hash_table_lookup (message->recipients, name);
- if (value) {
- unfolded = camel_header_unfold (value);
- camel_address_decode (CAMEL_ADDRESS (addr), unfolded);
- g_free (unfolded);
- } else {
- camel_address_remove (CAMEL_ADDRESS (addr), -1);
- }
- return FALSE;
- case HEADER_DATE:
- if (value) {
- message->date = camel_header_decode_date (value, &message->date_offset);
- } else {
- message->date = CAMEL_MESSAGE_DATE_CURRENT;
- message->date_offset = 0;
- }
- break;
- case HEADER_MESSAGE_ID:
- g_free (message->message_id);
- if (value)
- message->message_id = camel_header_msgid_decode (value);
- else
- message->message_id = NULL;
- break;
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-set_header (CamelMedium *medium, const gchar *name, gconstpointer value)
-{
- process_header (medium, name, value);
- CAMEL_MEDIUM_CLASS (parent_class)->set_header (medium, name, value);
-}
-
-static void
-add_header (CamelMedium *medium, const gchar *name, gconstpointer value)
-{
- /* if we process it, then it must be forced unique as well ... */
- if (process_header (medium, name, value))
- CAMEL_MEDIUM_CLASS (parent_class)->set_header (medium, name, value);
- else
- CAMEL_MEDIUM_CLASS (parent_class)->add_header (medium, name, value);
-}
-
-static void
-remove_header (CamelMedium *medium, const gchar *name)
-{
- process_header (medium, name, NULL);
- CAMEL_MEDIUM_CLASS (parent_class)->remove_header (medium, name);
-}
-
typedef gboolean (*CamelPartFunc)(CamelMimeMessage *, CamelMimePart *, gpointer data);
static gboolean
@@ -905,7 +921,7 @@ find_best_encoding (CamelMimePart *part, CamelBestencRequired required, CamelBes
bestenc = camel_mime_filter_bestenc_new (flags);
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);
+ camel_data_wrapper_decode_to_stream (content, filter, NULL);
camel_stream_filter_remove (CAMEL_STREAM_FILTER (filter), idb);
if (idc != -1) {
camel_stream_filter_remove (CAMEL_STREAM_FILTER (filter), idc);
@@ -948,7 +964,7 @@ find_best_encoding (CamelMimePart *part, CamelBestencRequired required, CamelBes
CAMEL_STREAM_FILTER (filter), bestenc);
/* and write it to the new stream */
- camel_data_wrapper_write_to_stream (content, filter);
+ camel_data_wrapper_write_to_stream (content, filter, NULL);
g_object_unref (charenc);
}
diff --git a/camel/camel-mime-parser.c b/camel/camel-mime-parser.c
index bc2f2db..757a408 100644
--- a/camel/camel-mime-parser.c
+++ b/camel/camel-mime-parser.c
@@ -139,7 +139,7 @@ struct _header_scan_filter {
static void folder_scan_step(struct _header_scan_state *s, gchar **databuffer, gsize *datalength);
static void folder_scan_drop_step(struct _header_scan_state *s);
static gint folder_scan_init_with_fd(struct _header_scan_state *s, gint fd);
-static gint folder_scan_init_with_stream(struct _header_scan_state *s, CamelStream *stream);
+static gint folder_scan_init_with_stream(struct _header_scan_state *s, CamelStream *stream, GError **error);
static struct _header_scan_state *folder_scan_init(void);
static void folder_scan_close(struct _header_scan_state *s);
static struct _header_scan_stack *folder_scan_content(struct _header_scan_state *s, gint *lastone, gchar **data, gsize *length);
@@ -452,6 +452,7 @@ camel_mime_parser_init_with_fd(CamelMimeParser *m, gint fd)
* camel_mime_parser_init_with_stream:
* @m:
* @stream:
+ * @error: return location for a #GError, or %NULL
*
* Initialise the scanner with a source stream. The scanner's
* offsets will be relative to the current file position of
@@ -461,11 +462,13 @@ camel_mime_parser_init_with_fd(CamelMimeParser *m, gint fd)
* Return value: -1 on error.
**/
gint
-camel_mime_parser_init_with_stream(CamelMimeParser *m, CamelStream *stream)
+camel_mime_parser_init_with_stream (CamelMimeParser *parser,
+ CamelStream *stream,
+ GError **error)
{
- struct _header_scan_state *s = _PRIVATE(m);
+ struct _header_scan_state *s = _PRIVATE (parser);
- return folder_scan_init_with_stream(s, stream);
+ return folder_scan_init_with_stream (s, stream, error);
}
/**
@@ -895,7 +898,7 @@ folder_read(struct _header_scan_state *s)
memmove(s->inbuf, s->inptr, inoffset);
}
if (s->stream) {
- len = camel_stream_read(s->stream, s->inbuf+inoffset, SCAN_BUF-inoffset);
+ len = camel_stream_read(s->stream, s->inbuf+inoffset, SCAN_BUF-inoffset, NULL);
} else {
len = read(s->fd, s->inbuf+inoffset, SCAN_BUF-inoffset);
}
@@ -942,7 +945,9 @@ folder_seek(struct _header_scan_state *s, off_t offset, gint whence)
if (CAMEL_IS_SEEKABLE_STREAM(s->stream)) {
/* NOTE: assumes whence seekable stream == whence libc, which is probably
the case (or bloody well should've been) */
- newoffset = camel_seekable_stream_seek((CamelSeekableStream *)s->stream, offset, whence);
+ newoffset = camel_seekable_stream_seek (
+ CAMEL_SEEKABLE_STREAM (s->stream),
+ offset, whence, NULL);
} else {
newoffset = -1;
errno = EINVAL;
@@ -1469,7 +1474,9 @@ folder_scan_init_with_fd(struct _header_scan_state *s, gint fd)
}
static gint
-folder_scan_init_with_stream(struct _header_scan_state *s, CamelStream *stream)
+folder_scan_init_with_stream (struct _header_scan_state *s,
+ CamelStream *stream,
+ GError **error)
{
folder_scan_reset(s);
s->stream = stream;
diff --git a/camel/camel-mime-parser.h b/camel/camel-mime-parser.h
index 8f1528a..50e6a71 100644
--- a/camel/camel-mime-parser.h
+++ b/camel/camel-mime-parser.h
@@ -103,7 +103,7 @@ gint camel_mime_parser_errno (CamelMimeParser *parser);
/* using an fd will be a little faster, but not much (over a simple stream) */
gint camel_mime_parser_init_with_fd (CamelMimeParser *m, gint fd);
-gint camel_mime_parser_init_with_stream (CamelMimeParser *m, CamelStream *stream);
+gint camel_mime_parser_init_with_stream (CamelMimeParser *m, CamelStream *stream, GError **error);
/* get the stream or fd back of the parser */
CamelStream *camel_mime_parser_stream (CamelMimeParser *parser);
diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c
index e79c978..6c69fa8 100644
--- a/camel/camel-mime-part-utils.c
+++ b/camel/camel-mime-part-utils.c
@@ -54,13 +54,16 @@
#include <stdio.h>*/
/* simple data wrapper */
-static void
-simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw, CamelMimeParser *mp)
+static gboolean
+simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw,
+ CamelMimeParser *mp,
+ GError **error)
{
gchar *buf;
GByteArray *buffer;
CamelStream *mem;
gsize len;
+ gint retval;
d(printf ("simple_data_wrapper_construct_from_parser()\n"));
@@ -74,20 +77,24 @@ simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw, CamelMimeParser
d(printf("message part kept in memory!\n"));
mem = camel_stream_mem_new_with_byte_array (buffer);
- camel_data_wrapper_construct_from_stream (dw, mem);
+ retval = camel_data_wrapper_construct_from_stream (dw, mem, error);
g_object_unref (mem);
+
+ return (retval == 0);
}
/* This replaces the data wrapper repository ... and/or could be replaced by it? */
-void
-camel_mime_part_construct_content_from_parser (CamelMimePart *dw, CamelMimeParser *mp)
+gboolean
+camel_mime_part_construct_content_from_parser (CamelMimePart *dw,
+ CamelMimeParser *mp,
+ GError **error)
{
CamelDataWrapper *content = NULL;
CamelContentType *ct;
gchar *encoding;
+ gboolean success = TRUE;
- if (!dw)
- return;
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (dw), FALSE);
ct = camel_mime_parser_content_type (mp);
@@ -102,13 +109,15 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw, CamelMimeParse
camel_multipart_construct_from_parser ((CamelMultipart *) content, mp);
} else {
content = camel_data_wrapper_new ();
- simple_data_wrapper_construct_from_parser (content, mp);
+ success = simple_data_wrapper_construct_from_parser (
+ content, mp, error);
}
break;
case CAMEL_MIME_PARSER_STATE_MESSAGE:
d(printf("Creating message part\n"));
content = (CamelDataWrapper *) camel_mime_message_new ();
- camel_mime_part_construct_from_parser ((CamelMimePart *)content, mp);
+ success = (camel_mime_part_construct_from_parser (
+ (CamelMimePart *)content, mp, error) == 0);
break;
case CAMEL_MIME_PARSER_STATE_MULTIPART:
d(printf("Creating multi-part\n"));
@@ -137,10 +146,13 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw, CamelMimeParse
}
g_free (encoding);
+
+ return success;
}
gboolean
-camel_mime_message_build_preview (CamelMimePart *msg, CamelMessageInfo *info)
+camel_mime_message_build_preview (CamelMimePart *msg,
+ CamelMessageInfo *info)
{
CamelDataWrapper *dw;
gboolean got_plain = FALSE;
@@ -163,15 +175,15 @@ camel_mime_message_build_preview (CamelMimePart *msg, CamelMessageInfo *info)
!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) > 0) {
+ if (camel_data_wrapper_decode_to_stream (dw, mstream, NULL) > 0) {
gchar *line = NULL;
GString *str = g_string_new (NULL);
- camel_stream_reset (mstream);
+ camel_stream_reset (mstream, NULL);
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)) && str->len < 200) {
+ while ((line = camel_stream_buffer_read_line((CamelStreamBuffer *)bstream, 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 6691c9e..774822d 100644
--- a/camel/camel-mime-part-utils.h
+++ b/camel/camel-mime-part-utils.h
@@ -35,7 +35,10 @@
G_BEGIN_DECLS
-void camel_mime_part_construct_content_from_parser(CamelMimePart *, CamelMimeParser *mp);
+gboolean camel_mime_part_construct_content_from_parser
+ (CamelMimePart *mime_part,
+ CamelMimeParser *mp,
+ GError **error);
gboolean camel_mime_message_build_preview (CamelMimePart *msg, CamelMessageInfo *info);
G_END_DECLS
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index a0e0060..2e5ed96 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -93,29 +93,70 @@ static GHashTable *header_formatted_table;
static gpointer parent_class;
-/* from CamelDataWrapper */
-static gssize write_to_stream (CamelDataWrapper *dw, CamelStream *stream);
-static gint construct_from_stream (CamelDataWrapper *dw, CamelStream *stream);
+static gssize
+write_raw (CamelStream *stream,
+ CamelHeaderRaw *header_raw,
+ GError **error)
+{
+ const gchar *name;
+ const gchar *value;
-/* from CamelMedium */
-static void add_header (CamelMedium *medium, const gchar *name, gconstpointer value);
-static void set_header (CamelMedium *medium, const gchar *name, gconstpointer value);
-static void remove_header (CamelMedium *medium, const gchar *name);
-static const void *get_header (CamelMedium *medium, const gchar *name);
-static GArray *get_headers (CamelMedium *medium);
-static void free_headers (CamelMedium *medium, GArray *headers);
+ name = camel_header_raw_get_name (header_raw);
+ value = camel_header_raw_get_value (header_raw);
-static void set_content (CamelMedium *medium, CamelDataWrapper *content);
+ return camel_stream_printf (
+ stream, error, "%s%s%s\n", name,
+ isspace(value[0]) ? ":" : ": ", value);
+}
-/* from camel mime parser */
-static gint construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *mp);
+static gssize
+write_references (CamelStream *stream,
+ CamelHeaderRaw *raw_header,
+ GError **error)
+{
+ gssize len, out, total;
+ const gchar *ids, *ide;
+ const gchar *name;
+ const gchar *value;
-/* forward references */
-static void set_disposition (CamelMimePart *mime_part, const gchar *disposition);
+ /* 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 ... */
-/* format output of headers */
-static gssize write_references(CamelStream *stream, CamelHeaderRaw *raw_header);
-static gssize write_raw(CamelStream *stream, CamelHeaderRaw *raw_header);
+ name = camel_header_raw_get_name (raw_header);
+ value = camel_header_raw_get_value (raw_header);
+
+ len = strlen(name)+1;
+ total = camel_stream_printf (
+ stream, error, "%s%s", name, isspace(value[0])?":":": ");
+ if (total == -1)
+ return -1;
+ while (*value) {
+ ids = value;
+ ide = strchr(ids+1, '>');
+ if (ide)
+ value = ++ide;
+ else
+ ide = value = strlen(ids)+ids;
+
+ if (len>0 && len + (ide - ids) >= CAMEL_FOLD_SIZE) {
+ out = camel_stream_printf (stream, error, "\n\t");
+ if (out == -1)
+ return -1;
+ total += out;
+ len = 0;
+ }
+ out = camel_stream_write (stream, ids, ide-ids, error);
+ if (out == -1)
+ return -1;
+ len += out;
+ total += out;
+ }
+ camel_stream_write (stream, "\n", 1, NULL);
+
+ return total;
+}
/* loads in a hash table the set of header names we */
/* recognize and associate them with a unique enum */
@@ -180,6 +221,74 @@ init_header_name_table(void)
}
static void
+mime_part_set_disposition (CamelMimePart *mime_part,
+ const gchar *disposition)
+{
+ camel_content_disposition_unref(mime_part->priv->disposition);
+ if (disposition)
+ mime_part->priv->disposition =
+ camel_content_disposition_decode (disposition);
+ else
+ mime_part->priv->disposition = NULL;
+}
+
+static gboolean
+mime_part_process_header (CamelMedium *medium,
+ const gchar *name,
+ const gchar *value)
+{
+ CamelMimePart *mime_part = CAMEL_MIME_PART (medium);
+ CamelHeaderType header_type;
+ const gchar *charset;
+ gchar *text;
+
+ /* Try to parse the header pair. If it corresponds to something */
+ /* known, the job is done in the parsing routine. If not, */
+ /* we simply add the header in a raw fashion */
+
+ header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, name);
+ switch (header_type) {
+ case HEADER_DESCRIPTION: /* raw header->utf8 conversion */
+ g_free (mime_part->priv->description);
+ if (((CamelDataWrapper *) mime_part)->mime_type) {
+ charset = camel_content_type_param (((CamelDataWrapper *) mime_part)->mime_type, "charset");
+ charset = camel_iconv_charset_name (charset);
+ } else
+ charset = NULL;
+ mime_part->priv->description = g_strstrip (camel_header_decode_string (value, charset));
+ break;
+ case HEADER_DISPOSITION:
+ mime_part_set_disposition (mime_part, value);
+ break;
+ case HEADER_CONTENT_ID:
+ g_free (mime_part->priv->content_id);
+ mime_part->priv->content_id = camel_header_contentid_decode (value);
+ break;
+ case HEADER_ENCODING:
+ text = camel_header_token_decode (value);
+ mime_part->priv->encoding = camel_transfer_encoding_from_string (text);
+ g_free (text);
+ break;
+ case HEADER_CONTENT_MD5:
+ g_free (mime_part->priv->content_md5);
+ mime_part->priv->content_md5 = g_strdup (value);
+ break;
+ case HEADER_CONTENT_LOCATION:
+ g_free (mime_part->priv->content_location);
+ mime_part->priv->content_location = camel_header_location_decode (value);
+ break;
+ case HEADER_CONTENT_TYPE:
+ if (((CamelDataWrapper *) mime_part)->mime_type)
+ camel_content_type_unref (((CamelDataWrapper *) mime_part)->mime_type);
+ ((CamelDataWrapper *) mime_part)->mime_type = camel_content_type_decode (value);
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
mime_part_set_property (GObject *object,
guint property_id,
const GValue *value,
@@ -284,6 +393,391 @@ mime_part_finalize (GObject *object)
}
static void
+mime_part_add_header (CamelMedium *medium,
+ const gchar *name,
+ gconstpointer value)
+{
+ CamelMimePart *part = CAMEL_MIME_PART (medium);
+ GQueue *header_queue;
+
+ header_queue = camel_mime_part_get_raw_headers (part);
+
+ /* Try to parse the header pair. If it corresponds to something */
+ /* known, the job is done in the parsing routine. If not, */
+ /* we simply add the header in a raw fashion */
+
+ /* If it was one of the headers we handled, it must be unique, set it instead of add */
+ if (mime_part_process_header (medium, name, value))
+ camel_header_raw_remove (header_queue, name);
+ camel_header_raw_append (header_queue, name, value, -1);
+}
+
+static void
+mime_part_set_header (CamelMedium *medium,
+ const gchar *name,
+ gconstpointer value)
+{
+ CamelMimePart *part = CAMEL_MIME_PART (medium);
+ GQueue *header_queue;
+
+ header_queue = camel_mime_part_get_raw_headers (part);
+
+ mime_part_process_header (medium, name, value);
+ camel_header_raw_remove (header_queue, name);
+ camel_header_raw_append (header_queue, name, value, -1);
+}
+
+static void
+mime_part_remove_header (CamelMedium *medium,
+ const gchar *name)
+{
+ CamelMimePart *part = (CamelMimePart *)medium;
+ GQueue *header_queue;
+
+ header_queue = camel_mime_part_get_raw_headers (part);
+
+ mime_part_process_header (medium, name, NULL);
+ camel_header_raw_remove (header_queue, name);
+}
+
+static gconstpointer
+mime_part_get_header (CamelMedium *medium,
+ const gchar *name)
+{
+ CamelMimePart *part = (CamelMimePart *)medium;
+ GQueue *header_queue;
+
+ header_queue = camel_mime_part_get_raw_headers (part);
+
+ return camel_header_raw_find (header_queue, name, NULL);
+}
+
+static GArray *
+mime_part_get_headers (CamelMedium *medium)
+{
+ CamelMimePart *part = (CamelMimePart *)medium;
+ GArray *headers;
+ CamelMediumHeader header;
+ GQueue *header_queue;
+ GList *link;
+
+ header_queue = camel_mime_part_get_raw_headers (part);
+ link = g_queue_peek_head_link (header_queue);
+
+ headers = g_array_new (FALSE, FALSE, sizeof (CamelMediumHeader));
+
+ while (link != NULL) {
+ CamelHeaderRaw *raw_header = link->data;
+
+ header.name = camel_header_raw_get_name (raw_header);
+ header.value = camel_header_raw_get_value (raw_header);
+ g_array_append_val (headers, header);
+
+ link = g_list_next (link);
+ }
+
+ return headers;
+}
+
+static void
+mime_part_free_headers (CamelMedium *medium,
+ GArray *headers)
+{
+ g_array_free (headers, TRUE);
+}
+
+static void
+mime_part_set_content (CamelMedium *medium,
+ CamelDataWrapper *content)
+{
+ CamelDataWrapper *mime_part = CAMEL_DATA_WRAPPER (medium);
+ CamelMediumClass *medium_class;
+ CamelContentType *content_type;
+
+ /* Chain up to parent's set_content() method. */
+ medium_class = CAMEL_MEDIUM_CLASS (parent_class);
+ medium_class->set_content (medium, content);
+
+ content_type = camel_data_wrapper_get_mime_type_field (content);
+ if (mime_part->mime_type != content_type) {
+ gchar *txt;
+
+ txt = camel_content_type_format (content_type);
+ camel_medium_set_header (medium, "Content-Type", txt);
+ g_free (txt);
+ }
+}
+
+static gssize
+mime_part_write_to_stream (CamelDataWrapper *dw,
+ CamelStream *stream,
+ GError **error)
+{
+ CamelMimePart *mp = CAMEL_MIME_PART (dw);
+ CamelMedium *medium = CAMEL_MEDIUM (dw);
+ CamelStream *ostream = stream;
+ CamelDataWrapper *content;
+ GQueue *header_queue;
+ gssize total = 0;
+ gssize count;
+ gint errnosav;
+
+ d(printf("mime_part::write_to_stream\n"));
+
+ /* FIXME: something needs to be done about this ... */
+ /* TODO: content-languages header? */
+
+ header_queue = camel_mime_part_get_raw_headers (mp);
+
+ if (!g_queue_is_empty (header_queue)) {
+ GList *link;
+ gssize (*writefn)(CamelStream *stream, CamelHeaderRaw *);
+
+ link = g_queue_peek_head_link (header_queue);
+
+ /* 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) */
+ while (link != NULL) {
+ CamelHeaderRaw *raw_header = link->data;
+ const gchar *name, *value;
+
+ name = camel_header_raw_get_name (raw_header);
+ value = camel_header_raw_get_value (raw_header);
+
+ if (value == NULL) {
+ g_warning("value is NULL here for %s", name);
+ count = 0;
+ } else if ((writefn = g_hash_table_lookup(header_formatted_table, name)) == NULL) {
+ gchar *folded;
+
+ folded = camel_header_fold(value, strlen(name));
+ count = camel_stream_printf (
+ stream, error, "%s%s%s\n", name,
+ isspace (folded[0]) ? ":" : ": ",
+ folded);
+ g_free(folded);
+ } else {
+ count = writefn(stream, raw_header);
+ }
+ if (count == -1)
+ return -1;
+ total += count;
+
+ link = g_list_next (link);
+ }
+ }
+
+ count = camel_stream_write (stream, "\n", 1, error);
+ if (count == -1)
+ return -1;
+ total += count;
+
+ content = camel_medium_get_content (medium);
+ if (content) {
+ CamelMimeFilter *filter = NULL;
+ CamelStream *filter_stream = NULL;
+ CamelMimeFilter *charenc = NULL;
+ const gchar *content_charset = NULL;
+ const gchar *part_charset = NULL;
+ gboolean reencode = FALSE;
+ const gchar *filename;
+
+ if (camel_content_type_is (dw->mime_type, "text", "*")) {
+ content_charset = camel_content_type_param (content->mime_type, "charset");
+ part_charset = camel_content_type_param (dw->mime_type, "charset");
+
+ if (content_charset && part_charset) {
+ content_charset = camel_iconv_charset_name (content_charset);
+ part_charset = camel_iconv_charset_name (part_charset);
+ }
+ }
+
+ if (mp->priv->encoding != content->encoding) {
+ switch (mp->priv->encoding) {
+ case CAMEL_TRANSFER_ENCODING_BASE64:
+ filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_BASE64_ENC);
+ break;
+ case CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE:
+ filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_QP_ENC);
+ break;
+ case CAMEL_TRANSFER_ENCODING_UUENCODE:
+ filename = camel_mime_part_get_filename (mp);
+ count = camel_stream_printf (
+ ostream, error, "begin 644 %s\n",
+ filename ? filename : "untitled");
+ if (count == -1)
+ return -1;
+ total += count;
+ filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_UU_ENC);
+ break;
+ default:
+ /* content is encoded but the part doesn't want to be... */
+ reencode = TRUE;
+ break;
+ }
+ }
+
+ if (content_charset && part_charset && part_charset != content_charset)
+ charenc = camel_mime_filter_charset_new (content_charset, part_charset);
+
+ if (filter || charenc) {
+ filter_stream = camel_stream_filter_new (stream);
+
+ /* if we have a character encoder, add that always */
+ if (charenc) {
+ camel_stream_filter_add (
+ CAMEL_STREAM_FILTER (filter_stream),
+ charenc);
+ g_object_unref (charenc);
+ }
+
+ /* we only re-do crlf on encoded blocks */
+ if (filter && camel_content_type_is (dw->mime_type, "text", "*")) {
+ CamelMimeFilter *crlf = camel_mime_filter_crlf_new(CAMEL_MIME_FILTER_CRLF_ENCODE,
+ CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
+
+ camel_stream_filter_add (
+ CAMEL_STREAM_FILTER (filter_stream),
+ crlf);
+ g_object_unref (crlf);
+ }
+
+ if (filter) {
+ camel_stream_filter_add (
+ CAMEL_STREAM_FILTER (filter_stream),
+ filter);
+ g_object_unref (filter);
+ }
+
+ stream = filter_stream;
+
+ reencode = TRUE;
+ }
+
+ if (reencode)
+ count = camel_data_wrapper_decode_to_stream (
+ content, stream, error);
+ else
+ count = camel_data_wrapper_write_to_stream (
+ content, stream, error);
+
+ if (filter_stream) {
+ errnosav = errno;
+ camel_stream_flush (stream, NULL);
+ g_object_unref (filter_stream);
+ errno = errnosav;
+ }
+
+ if (count == -1)
+ return -1;
+
+ total += count;
+
+ if (reencode && mp->priv->encoding == CAMEL_TRANSFER_ENCODING_UUENCODE) {
+ count = camel_stream_write (
+ ostream, "end\n", 4, error);
+ if (count == -1)
+ return -1;
+ total += count;
+ }
+ } else {
+ g_warning("No content for medium, nothing to write");
+ }
+
+ return total;
+}
+
+static gint
+mime_part_construct_from_stream (CamelDataWrapper *dw,
+ CamelStream *s,
+ GError **error)
+{
+ CamelMimeParser *mp;
+ gint ret;
+
+ d(printf("mime_part::construct_from_stream()\n"));
+
+ mp = camel_mime_parser_new();
+ if (camel_mime_parser_init_with_stream (mp, s, error) == -1) {
+ ret = -1;
+ } else {
+ ret = camel_mime_part_construct_from_parser (
+ CAMEL_MIME_PART (dw), mp, error);
+ }
+ g_object_unref (mp);
+ return ret;
+}
+
+static gint
+mime_part_construct_from_parser (CamelMimePart *mime_part,
+ CamelMimeParser *mp,
+ GError **error)
+{
+ CamelDataWrapper *dw = (CamelDataWrapper *) mime_part;
+ GQueue *header_queue;
+ GList *link;
+ const gchar *content;
+ gchar *buf;
+ gsize len;
+ gint err;
+ gboolean retval = 0;
+
+ d(printf("mime_part::construct_from_parser()\n"));
+
+ switch (camel_mime_parser_step(mp, &buf, &len)) {
+ case CAMEL_MIME_PARSER_STATE_MESSAGE:
+ /* set the default type of a message always */
+ if (dw->mime_type)
+ camel_content_type_unref (dw->mime_type);
+ dw->mime_type = camel_content_type_decode ("message/rfc822");
+ case CAMEL_MIME_PARSER_STATE_HEADER:
+ case CAMEL_MIME_PARSER_STATE_MULTIPART:
+ /* we have the headers, build them into 'us' */
+ header_queue = camel_mime_parser_headers_raw(mp);
+
+ /* if content-type exists, process it first, set for fallback charset in headers */
+ content = camel_header_raw_find(header_queue, "content-type", NULL);
+ if (content)
+ mime_part_process_header (
+ (CamelMedium *)dw, "content-type", content);
+
+ link = g_queue_peek_head_link (header_queue);
+
+ while (link != NULL) {
+ CamelHeaderRaw *raw_header = link->data;
+ const gchar *name;
+ const gchar *value;
+
+ name = camel_header_raw_get_name (raw_header);
+ value = camel_header_raw_get_value (raw_header);
+
+ if (g_ascii_strcasecmp(name, "content-type") == 0
+ && value != content)
+ camel_medium_add_header((CamelMedium *)dw, "X-Invalid-Content-Type", value);
+ else
+ camel_medium_add_header((CamelMedium *)dw, name, value);
+
+ link = g_list_next (link);
+ }
+
+ retval = camel_mime_part_construct_content_from_parser (
+ mime_part, mp, error);
+ break;
+ default:
+ g_warning("Invalid state encountered???: %u", camel_mime_parser_state(mp));
+ }
+
+ d(printf("mime_part::construct_from_parser() leaving\n"));
+ err = camel_mime_parser_errno(mp);
+ if (err != 0) {
+ errno = err;
+ retval = -1;
+ }
+
+ return retval;
+}
+
+static void
mime_part_class_init (CamelMimePartClass *class)
{
GObjectClass *object_class;
@@ -299,19 +793,19 @@ mime_part_class_init (CamelMimePartClass *class)
object_class->finalize = mime_part_finalize;
medium_class = CAMEL_MEDIUM_CLASS (class);
- medium_class->add_header = add_header;
- medium_class->set_header = set_header;
- medium_class->get_header = get_header;
- medium_class->remove_header = remove_header;
- medium_class->get_headers = get_headers;
- medium_class->free_headers = free_headers;
- medium_class->set_content = set_content;
+ medium_class->add_header = mime_part_add_header;
+ medium_class->set_header = mime_part_set_header;
+ medium_class->remove_header = mime_part_remove_header;
+ medium_class->get_header = mime_part_get_header;
+ medium_class->get_headers = mime_part_get_headers;
+ medium_class->free_headers = mime_part_free_headers;
+ medium_class->set_content = mime_part_set_content;
data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
- data_wrapper_class->write_to_stream = write_to_stream;
- data_wrapper_class->construct_from_stream = construct_from_stream;
+ data_wrapper_class->write_to_stream = mime_part_write_to_stream;
+ data_wrapper_class->construct_from_stream = mime_part_construct_from_stream;
- class->construct_from_parser = construct_from_parser;
+ class->construct_from_parser = mime_part_construct_from_parser;
g_object_class_install_property (
object_class,
@@ -391,149 +885,6 @@ camel_mime_part_get_type (void)
return type;
}
-/* **** */
-
-static gboolean
-process_header(CamelMedium *medium, const gchar *name, const gchar *value)
-{
- CamelMimePart *mime_part = CAMEL_MIME_PART (medium);
- CamelHeaderType header_type;
- const gchar *charset;
- gchar *text;
-
- /* Try to parse the header pair. If it corresponds to something */
- /* known, the job is done in the parsing routine. If not, */
- /* we simply add the header in a raw fashion */
-
- header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, name);
- switch (header_type) {
- case HEADER_DESCRIPTION: /* raw header->utf8 conversion */
- g_free (mime_part->priv->description);
- if (((CamelDataWrapper *) mime_part)->mime_type) {
- charset = camel_content_type_param (((CamelDataWrapper *) mime_part)->mime_type, "charset");
- charset = camel_iconv_charset_name (charset);
- } else
- charset = NULL;
- mime_part->priv->description = g_strstrip (camel_header_decode_string (value, charset));
- break;
- case HEADER_DISPOSITION:
- set_disposition (mime_part, value);
- break;
- case HEADER_CONTENT_ID:
- g_free (mime_part->priv->content_id);
- mime_part->priv->content_id = camel_header_contentid_decode (value);
- break;
- case HEADER_ENCODING:
- text = camel_header_token_decode (value);
- mime_part->priv->encoding = camel_transfer_encoding_from_string (text);
- g_free (text);
- break;
- case HEADER_CONTENT_MD5:
- g_free (mime_part->priv->content_md5);
- mime_part->priv->content_md5 = g_strdup (value);
- break;
- case HEADER_CONTENT_LOCATION:
- g_free (mime_part->priv->content_location);
- mime_part->priv->content_location = camel_header_location_decode (value);
- break;
- case HEADER_CONTENT_TYPE:
- if (((CamelDataWrapper *) mime_part)->mime_type)
- camel_content_type_unref (((CamelDataWrapper *) mime_part)->mime_type);
- ((CamelDataWrapper *) mime_part)->mime_type = camel_content_type_decode (value);
- break;
- default:
- return FALSE;
- }
- return TRUE;
-}
-
-static void
-set_header (CamelMedium *medium, const gchar *name, gconstpointer value)
-{
- CamelMimePart *part = CAMEL_MIME_PART (medium);
- GQueue *header_queue;
-
- header_queue = camel_mime_part_get_raw_headers (part);
-
- process_header (medium, name, value);
- camel_header_raw_remove (header_queue, name);
- camel_header_raw_append (header_queue, name, value, -1);
-}
-
-static void
-add_header (CamelMedium *medium, const gchar *name, gconstpointer value)
-{
- CamelMimePart *part = CAMEL_MIME_PART (medium);
- GQueue *header_queue;
-
- header_queue = camel_mime_part_get_raw_headers (part);
-
- /* Try to parse the header pair. If it corresponds to something */
- /* known, the job is done in the parsing routine. If not, */
- /* we simply add the header in a raw fashion */
-
- /* If it was one of the headers we handled, it must be unique, set it instead of add */
- if (process_header(medium, name, value))
- camel_header_raw_remove (header_queue, name);
- camel_header_raw_append (header_queue, name, value, -1);
-}
-
-static void
-remove_header (CamelMedium *medium, const gchar *name)
-{
- CamelMimePart *part = (CamelMimePart *)medium;
- GQueue *header_queue;
-
- header_queue = camel_mime_part_get_raw_headers (part);
-
- process_header (medium, name, NULL);
- camel_header_raw_remove (header_queue, name);
-}
-
-static gconstpointer
-get_header (CamelMedium *medium, const gchar *name)
-{
- CamelMimePart *part = (CamelMimePart *)medium;
- GQueue *header_queue;
-
- header_queue = camel_mime_part_get_raw_headers (part);
-
- return camel_header_raw_find (header_queue, name, NULL);
-}
-
-static GArray *
-get_headers (CamelMedium *medium)
-{
- CamelMimePart *part = (CamelMimePart *)medium;
- GArray *headers;
- CamelMediumHeader header;
- GQueue *header_queue;
- GList *link;
-
- header_queue = camel_mime_part_get_raw_headers (part);
- link = g_queue_peek_head_link (header_queue);
-
- headers = g_array_new (FALSE, FALSE, sizeof (CamelMediumHeader));
-
- while (link != NULL) {
- CamelHeaderRaw *raw_header = link->data;
-
- header.name = camel_header_raw_get_name (raw_header);
- header.value = camel_header_raw_get_value (raw_header);
- g_array_append_val (headers, header);
-
- link = g_list_next (link);
- }
-
- return headers;
-}
-
-static void
-free_headers (CamelMedium *medium, GArray *gheaders)
-{
- g_array_free (gheaders, TRUE);
-}
-
/* **** Content-Description */
/**
@@ -580,17 +931,6 @@ camel_mime_part_get_description (CamelMimePart *mime_part)
/* **** Content-Disposition */
-static void
-set_disposition (CamelMimePart *mime_part, const gchar *disposition)
-{
- camel_content_disposition_unref(mime_part->priv->disposition);
- if (disposition)
- mime_part->priv->disposition =
- camel_content_disposition_decode (disposition);
- else
- mime_part->priv->disposition = NULL;
-}
-
/**
* camel_mime_part_set_disposition:
* @mime_part: a #CamelMimePart object
@@ -611,7 +951,7 @@ camel_mime_part_set_disposition (CamelMimePart *mime_part,
/* we poke in a new disposition (so we dont lose 'filename', etc) */
if (mime_part->priv->disposition == NULL)
- set_disposition(mime_part, disposition);
+ mime_part_set_disposition (mime_part, disposition);
if (mime_part->priv->disposition != NULL) {
g_free (mime_part->priv->disposition->disposition);
@@ -961,346 +1301,11 @@ camel_mime_part_get_raw_headers (CamelMimePart *mime_part)
return mime_part->priv->raw_headers;
}
-static void
-set_content (CamelMedium *medium,
- CamelDataWrapper *content)
-{
- CamelDataWrapper *mime_part = CAMEL_DATA_WRAPPER (medium);
- CamelMediumClass *medium_class;
- CamelContentType *content_type;
-
- /* Chain up to parent's set_content() method. */
- medium_class = CAMEL_MEDIUM_CLASS (parent_class);
- medium_class->set_content (medium, content);
-
- content_type = camel_data_wrapper_get_mime_type_field (content);
- if (mime_part->mime_type != content_type) {
- gchar *txt;
-
- txt = camel_content_type_format (content_type);
- camel_medium_set_header (medium, "Content-Type", txt);
- g_free (txt);
- }
-}
-
-/**********************************************************************/
-
-static gssize
-write_references (CamelStream *stream,
- CamelHeaderRaw *raw_header)
-{
- gssize len, out, total;
- const gchar *ids, *ide;
- const gchar *name;
- const gchar *value;
-
- /* 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 ... */
-
- name = camel_header_raw_get_name (raw_header);
- value = camel_header_raw_get_value (raw_header);
-
- len = strlen(name)+1;
- total = camel_stream_printf(stream, "%s%s", name, isspace(value[0])?":":": ");
- if (total == -1)
- return -1;
- while (*value) {
- ids = value;
- ide = strchr(ids+1, '>');
- if (ide)
- value = ++ide;
- 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;
- len = 0;
- }
- out = camel_stream_write(stream, ids, ide-ids);
- if (out == -1)
- return -1;
- len += out;
- total += out;
- }
- camel_stream_write(stream, "\n", 1);
-
- return total;
-}
-
-#if 0
-/* not needed - yet - handled by default case */
-static gssize
-write_fold(CamelStream *stream, struct _camel_header_raw *h)
-{
- gchar *val;
- gint count;
-
- val = camel_header_fold(h->value, strlen(h->name));
- count = camel_stream_printf(stream, "%s%s%s\n", h->name, isspace(val[0]) ? ":" : ": ", val);
- g_free(val);
-
- return count;
-}
-#endif
-
-static gssize
-write_raw (CamelStream *stream,
- CamelHeaderRaw *header_raw)
-{
- const gchar *name;
- const gchar *value;
-
- name = camel_header_raw_get_name (header_raw);
- value = camel_header_raw_get_value (header_raw);
-
- return camel_stream_printf (
- stream, "%s%s%s\n", name,
- isspace(value[0]) ? ":" : ": ", value);
-}
-
-static gssize
-write_to_stream (CamelDataWrapper *dw, CamelStream *stream)
-{
- CamelMimePart *mp = CAMEL_MIME_PART (dw);
- CamelMedium *medium = CAMEL_MEDIUM (dw);
- CamelStream *ostream = stream;
- CamelDataWrapper *content;
- GQueue *header_queue;
- gssize total = 0;
- gssize count;
- gint errnosav;
-
- d(printf("mime_part::write_to_stream\n"));
-
- /* FIXME: something needs to be done about this ... */
- /* TODO: content-languages header? */
-
- header_queue = camel_mime_part_get_raw_headers (mp);
-
- if (!g_queue_is_empty (header_queue)) {
- GList *link;
- gssize (*writefn)(CamelStream *stream, CamelHeaderRaw *);
-
- link = g_queue_peek_head_link (header_queue);
-
- /* 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) */
- while (link != NULL) {
- CamelHeaderRaw *raw_header = link->data;
- const gchar *name, *value;
-
- name = camel_header_raw_get_name (raw_header);
- value = camel_header_raw_get_value (raw_header);
-
- if (value == NULL) {
- g_warning("value is NULL here for %s", name);
- count = 0;
- } else if ((writefn = g_hash_table_lookup(header_formatted_table, name)) == NULL) {
- gchar *folded;
-
- folded = camel_header_fold(value, strlen(name));
- count = camel_stream_printf(stream, "%s%s%s\n", name, isspace(folded[0]) ? ":" : ": ", folded);
- g_free(folded);
- } else {
- count = writefn(stream, raw_header);
- }
- if (count == -1)
- return -1;
- total += count;
-
- link = g_list_next (link);
- }
- }
-
- count = camel_stream_write(stream, "\n", 1);
- if (count == -1)
- return -1;
- total += count;
-
- content = camel_medium_get_content (medium);
- if (content) {
- CamelMimeFilter *filter = NULL;
- CamelStream *filter_stream = NULL;
- CamelMimeFilter *charenc = NULL;
- const gchar *content_charset = NULL;
- const gchar *part_charset = NULL;
- gboolean reencode = FALSE;
- const gchar *filename;
-
- if (camel_content_type_is (dw->mime_type, "text", "*")) {
- content_charset = camel_content_type_param (content->mime_type, "charset");
- part_charset = camel_content_type_param (dw->mime_type, "charset");
-
- if (content_charset && part_charset) {
- content_charset = camel_iconv_charset_name (content_charset);
- part_charset = camel_iconv_charset_name (part_charset);
- }
- }
-
- if (mp->priv->encoding != content->encoding) {
- switch (mp->priv->encoding) {
- case CAMEL_TRANSFER_ENCODING_BASE64:
- filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_BASE64_ENC);
- break;
- case CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE:
- filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_QP_ENC);
- break;
- case CAMEL_TRANSFER_ENCODING_UUENCODE:
- filename = camel_mime_part_get_filename (mp);
- count = camel_stream_printf (ostream, "begin 644 %s\n", filename ? filename : "untitled");
- if (count == -1)
- return -1;
- total += count;
- filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_UU_ENC);
- break;
- default:
- /* content is encoded but the part doesn't want to be... */
- reencode = TRUE;
- break;
- }
- }
-
- if (content_charset && part_charset && part_charset != content_charset)
- charenc = camel_mime_filter_charset_new (content_charset, part_charset);
-
- if (filter || charenc) {
- filter_stream = camel_stream_filter_new (stream);
-
- /* if we have a character encoder, add that always */
- if (charenc) {
- camel_stream_filter_add (
- CAMEL_STREAM_FILTER (filter_stream),
- charenc);
- g_object_unref (charenc);
- }
-
- /* we only re-do crlf on encoded blocks */
- if (filter && camel_content_type_is (dw->mime_type, "text", "*")) {
- CamelMimeFilter *crlf = camel_mime_filter_crlf_new(CAMEL_MIME_FILTER_CRLF_ENCODE,
- CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
-
- camel_stream_filter_add (
- CAMEL_STREAM_FILTER (filter_stream),
- crlf);
- g_object_unref (crlf);
- }
-
- if (filter) {
- camel_stream_filter_add (
- CAMEL_STREAM_FILTER (filter_stream),
- filter);
- g_object_unref (filter);
- }
-
- stream = filter_stream;
-
- reencode = TRUE;
- }
-
- if (reencode)
- count = camel_data_wrapper_decode_to_stream (content, stream);
- else
- count = camel_data_wrapper_write_to_stream (content, stream);
-
- if (filter_stream) {
- errnosav = errno;
- camel_stream_flush (stream);
- g_object_unref (filter_stream);
- errno = errnosav;
- }
-
- if (count == -1)
- return -1;
-
- total += count;
-
- if (reencode && mp->priv->encoding == CAMEL_TRANSFER_ENCODING_UUENCODE) {
- count = camel_stream_write (ostream, "end\n", 4);
- if (count == -1)
- return -1;
- total += count;
- }
- } else {
- g_warning("No content for medium, nothing to write");
- }
-
- return total;
-}
-
-/* mime_part */
-static gint
-construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *mp)
-{
- CamelDataWrapper *dw = (CamelDataWrapper *) mime_part;
- GQueue *header_queue;
- GList *link;
- const gchar *content;
- gchar *buf;
- gsize len;
- gint err;
-
- d(printf("mime_part::construct_from_parser()\n"));
-
- switch (camel_mime_parser_step(mp, &buf, &len)) {
- case CAMEL_MIME_PARSER_STATE_MESSAGE:
- /* set the default type of a message always */
- if (dw->mime_type)
- camel_content_type_unref (dw->mime_type);
- dw->mime_type = camel_content_type_decode ("message/rfc822");
- case CAMEL_MIME_PARSER_STATE_HEADER:
- case CAMEL_MIME_PARSER_STATE_MULTIPART:
- /* we have the headers, build them into 'us' */
- header_queue = camel_mime_parser_headers_raw(mp);
-
- /* if content-type exists, process it first, set for fallback charset in headers */
- content = camel_header_raw_find(header_queue, "content-type", NULL);
- if (content)
- process_header((CamelMedium *)dw, "content-type", content);
-
- link = g_queue_peek_head_link (header_queue);
-
- while (link != NULL) {
- CamelHeaderRaw *raw_header = link->data;
- const gchar *name;
- const gchar *value;
-
- name = camel_header_raw_get_name (raw_header);
- value = camel_header_raw_get_value (raw_header);
-
- if (g_ascii_strcasecmp(name, "content-type") == 0
- && value != content)
- camel_medium_add_header((CamelMedium *)dw, "X-Invalid-Content-Type", value);
- else
- camel_medium_add_header((CamelMedium *)dw, name, value);
-
- link = g_list_next (link);
- }
-
- camel_mime_part_construct_content_from_parser (mime_part, mp);
- break;
- default:
- g_warning("Invalid state encountered???: %u", camel_mime_parser_state(mp));
- }
-
- d(printf("mime_part::construct_from_parser() leaving\n"));
- err = camel_mime_parser_errno(mp);
- if (err != 0) {
- errno = err;
- return -1;
- }
-
- return 0;
-}
-
/**
* camel_mime_part_construct_from_parser:
* @mime_part: a #CamelMimePart object
* @parser: a #CamelMimeParser object
+ * @error: return location for a #GError, or %NULL
*
* Constructs a MIME part from a parser.
*
@@ -1308,7 +1313,8 @@ construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *mp)
**/
gint
camel_mime_part_construct_from_parser (CamelMimePart *mime_part,
- CamelMimeParser *mp)
+ CamelMimeParser *mp,
+ GError **error)
{
CamelMimePartClass *class;
@@ -1318,31 +1324,9 @@ 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);
- return class->construct_from_parser (mime_part, mp);
-}
-
-static gint
-construct_from_stream(CamelDataWrapper *dw, CamelStream *s)
-{
- CamelMimeParser *mp;
- gint ret;
-
- d(printf("mime_part::construct_from_stream()\n"));
-
- mp = camel_mime_parser_new();
- if (camel_mime_parser_init_with_stream(mp, s) == -1) {
- g_warning("Cannot create parser for stream");
- ret = -1;
- } else {
- ret = camel_mime_part_construct_from_parser((CamelMimePart *)dw, mp);
- }
- g_object_unref (mp);
- return ret;
+ return class->construct_from_parser (mime_part, mp, error);
}
-/******************************/
-/** Misc utility functions **/
-
/**
* camel_mime_part_new:
*
@@ -1382,7 +1366,7 @@ 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);
+ camel_data_wrapper_construct_from_stream (dw, stream, NULL);
g_object_unref (stream);
camel_medium_set_content (medium, dw);
g_object_unref (dw);
@@ -1410,7 +1394,7 @@ 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);
+ camel_data_wrapper_decode_to_stream (dw, (CamelStream *) null, NULL);
size = null->written;
g_object_unref (null);
diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h
index 96a51fd..413dd34 100644
--- a/camel/camel-mime-part.h
+++ b/camel/camel-mime-part.h
@@ -67,8 +67,9 @@ struct _CamelMimePart {
struct _CamelMimePartClass {
CamelMediumClass parent_class;
- /* Virtual methods */
- gint (*construct_from_parser) (CamelMimePart *, CamelMimeParser *);
+ gint (*construct_from_parser)(CamelMimePart *mime_part,
+ CamelMimeParser *parser,
+ GError **error);
};
GType camel_mime_part_get_type (void);
@@ -107,7 +108,7 @@ CamelContentType *camel_mime_part_get_content_type (CamelMimePart *mime_part);
GQueue * camel_mime_part_get_raw_headers (CamelMimePart *mime_part);
/* construction */
-gint camel_mime_part_construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *parser);
+gint camel_mime_part_construct_from_parser (CamelMimePart *mime_part, CamelMimeParser *parser, GError **error);
/* utility functions */
void camel_mime_part_set_content (CamelMimePart *mime_part,
diff --git a/camel/camel-multipart-signed.c b/camel/camel-multipart-signed.c
index 3c3e52c..ab41f83 100644
--- a/camel/camel-multipart-signed.c
+++ b/camel/camel-multipart-signed.c
@@ -50,152 +50,10 @@
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))
#include <stdio.h>;*/
-static void signed_add_part (CamelMultipart *multipart, CamelMimePart *part);
-static void signed_add_part_at (CamelMultipart *multipart, CamelMimePart *part, guint index);
-static void signed_remove_part (CamelMultipart *multipart, CamelMimePart *part);
-static CamelMimePart *signed_remove_part_at (CamelMultipart *multipart, guint index);
-static CamelMimePart *signed_get_part (CamelMultipart *multipart, guint index);
-static guint signed_get_number (CamelMultipart *multipart);
-
-static gssize write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
-static void set_mime_type_field (CamelDataWrapper *data_wrapper, CamelContentType *mime_type);
-static gint construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
-static gint signed_construct_from_parser (CamelMultipart *multipart, struct _CamelMimeParser *mp);
-
static gpointer parent_class;
-static void
-multipart_signed_dispose (GObject *object)
-{
- CamelMultipartSigned *multipart;
-
- multipart = CAMEL_MULTIPART_SIGNED (object);
-
- if (multipart->signature != NULL) {
- g_object_unref (multipart->signature);
- multipart->signature = NULL;
- }
-
- if (multipart->content != NULL) {
- g_object_unref (multipart->content);
- multipart->content = NULL;
- }
-
- if (multipart->contentraw != NULL) {
- g_object_unref (multipart->contentraw);
- multipart->contentraw = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-multipart_signed_finalize (GObject *object)
-{
- CamelMultipartSigned *multipart;
-
- multipart = CAMEL_MULTIPART_SIGNED (object);
-
- g_free (multipart->protocol);
- g_free (multipart->micalg);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-multipart_signed_class_init (CamelMultipartSignedClass *class)
-{
- GObjectClass *object_class;
- CamelDataWrapperClass *data_wrapper_class;
- CamelMultipartClass *multipart_class;
-
- parent_class = g_type_class_peek_parent (class);
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = multipart_signed_dispose;
- object_class->finalize = multipart_signed_finalize;
-
- data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
- data_wrapper_class->construct_from_stream = construct_from_stream;
- data_wrapper_class->write_to_stream = write_to_stream;
- data_wrapper_class->decode_to_stream = write_to_stream;
- data_wrapper_class->set_mime_type_field = set_mime_type_field;
-
- multipart_class = CAMEL_MULTIPART_CLASS (class);
- multipart_class->add_part = signed_add_part;
- multipart_class->add_part_at = signed_add_part_at;
- multipart_class->remove_part = signed_remove_part;
- multipart_class->remove_part_at = signed_remove_part_at;
- multipart_class->get_part = signed_get_part;
- multipart_class->get_number = signed_get_number;
- multipart_class->construct_from_parser = signed_construct_from_parser;
-}
-
-static void
-multipart_signed_init (CamelMultipartSigned *multipart)
-{
- camel_data_wrapper_set_mime_type (
- CAMEL_DATA_WRAPPER (multipart), "multipart/signed");
-
- multipart->start1 = -1;
-}
-
-GType
-camel_multipart_signed_get_type (void)
-{
- static GType type = G_TYPE_INVALID;
-
- if (G_UNLIKELY (type == G_TYPE_INVALID))
- type = g_type_register_static_simple (
- CAMEL_TYPE_MULTIPART,
- "CamelMultipartSigned",
- sizeof (CamelMultipartSignedClass),
- (GClassInitFunc) multipart_signed_class_init,
- sizeof (CamelMultipartSigned),
- (GInstanceInitFunc) multipart_signed_init,
- 0);
-
- return type;
-}
-
-/**
- * camel_multipart_signed_new:
- *
- * Create a new #CamelMultipartSigned object.
- *
- * A MultipartSigned should be used to store and create parts of
- * type "multipart/signed". This is because multipart/signed is
- * entirely broken-by-design (tm) and uses completely
- * different semantics to other mutlipart types. It must be treated
- * as opaque data by any transport. See rfc 3156 for details.
- *
- * There are 3 ways to create the part:
- * Use construct_from_stream. If this is used, then you must
- * set the mime_type appropriately to match the data uses, so
- * that the multiple parts my be extracted.
- *
- * Use construct_from_parser. The parser MUST be in the #CAMEL_MIME_PARSER_STATE_HEADER
- * state, and the current content_type MUST be "multipart/signed" with
- * the appropriate boundary and it SHOULD include the appropriate protocol
- * and hash specifiers.
- *
- * Use sign_part. A signature part will automatically be created
- * and the whole part may be written using write_to_stream to
- * create a 'transport-safe' version (as safe as can be expected with
- * such a broken specification).
- *
- * Returns: a new #CamelMultipartSigned object
- **/
-CamelMultipartSigned *
-camel_multipart_signed_new (void)
-{
- return g_object_new (CAMEL_TYPE_MULTIPART_SIGNED, NULL);
-}
-
static gint
-skip_content(CamelMimeParser *cmp)
+multipart_signed_skip_content (CamelMimeParser *cmp)
{
gchar *buf;
gsize len;
@@ -210,7 +68,7 @@ skip_content(CamelMimeParser *cmp)
case CAMEL_MIME_PARSER_STATE_MESSAGE:
/* message body part */
(void)camel_mime_parser_step(cmp, &buf, &len);
- skip_content(cmp);
+ multipart_signed_skip_content (cmp);
/* clean up followon state if any, see camel-mime-message.c */
state = camel_mime_parser_step(cmp, &buf, &len);
@@ -229,7 +87,7 @@ skip_content(CamelMimeParser *cmp)
case CAMEL_MIME_PARSER_STATE_MULTIPART:
/* embedded multipart */
while ((state = camel_mime_parser_step(cmp, &buf, &len)) != CAMEL_MIME_PARSER_STATE_MULTIPART_END)
- skip_content(cmp);
+ multipart_signed_skip_content (cmp);
break;
default:
g_warning("Invalid state encountered???: %u", camel_mime_parser_state (cmp));
@@ -239,7 +97,7 @@ skip_content(CamelMimeParser *cmp)
}
static gint
-parse_content(CamelMultipartSigned *mps)
+multipart_signed_parse_content (CamelMultipartSigned *mps)
{
CamelMimeParser *cmp;
CamelMultipart *mp = (CamelMultipart *)mps;
@@ -250,24 +108,18 @@ parse_content(CamelMultipartSigned *mps)
gint state;
boundary = camel_multipart_get_boundary(mp);
- if (boundary == NULL) {
- g_warning("Trying to get multipart/signed content without setting boundary first");
- return -1;
- }
+ g_return_val_if_fail (boundary != NULL, -1);
stream = ((CamelDataWrapper *)mps)->stream;
- if (stream == NULL) {
- g_warning("Trying to parse multipart/signed without constructing first");
- return -1;
- }
+ g_return_val_if_fail (stream != NULL, -1);
/* This is all seriously complex.
This is so we can parse all cases properly, without altering the content.
All we are doing is finding part offsets. */
- camel_stream_reset(stream);
- cmp = camel_mime_parser_new();
- camel_mime_parser_init_with_stream(cmp, stream);
+ camel_stream_reset (stream, NULL);
+ cmp = camel_mime_parser_new ();
+ camel_mime_parser_init_with_stream (cmp, stream, NULL);
camel_mime_parser_push_state(cmp, CAMEL_MIME_PARSER_STATE_MULTIPART, boundary);
mps->start1 = -1;
@@ -294,7 +146,7 @@ parse_content(CamelMultipartSigned *mps)
break;
}
- if (skip_content(cmp) == -1)
+ if (multipart_signed_skip_content (cmp) == -1)
break;
}
@@ -314,13 +166,84 @@ parse_content(CamelMultipartSigned *mps)
return 0;
}
-/* we snoop the mime type to get boundary and hash info */
static void
-set_mime_type_field(CamelDataWrapper *data_wrapper, CamelContentType *mime_type)
+multipart_signed_set_stream (CamelMultipartSigned *mps,
+ CamelStream *stream)
{
+ CamelDataWrapper *dw = (CamelDataWrapper *)mps;
+
+ if (dw->stream)
+ g_object_unref (dw->stream);
+ dw->stream = stream;
+
+ mps->start1 = -1;
+ if (mps->content) {
+ g_object_unref (mps->content);
+ mps->content = NULL;
+ }
+ if (mps->contentraw) {
+ g_object_unref (mps->contentraw);
+ mps->contentraw = NULL;
+ }
+ if (mps->signature) {
+ g_object_unref (mps->signature);
+ mps->signature = NULL;
+ }
+}
+
+static void
+multipart_signed_dispose (GObject *object)
+{
+ CamelMultipartSigned *multipart;
+
+ multipart = CAMEL_MULTIPART_SIGNED (object);
+
+ if (multipart->signature != NULL) {
+ g_object_unref (multipart->signature);
+ multipart->signature = NULL;
+ }
+
+ if (multipart->content != NULL) {
+ g_object_unref (multipart->content);
+ multipart->content = NULL;
+ }
+
+ if (multipart->contentraw != NULL) {
+ g_object_unref (multipart->contentraw);
+ multipart->contentraw = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+multipart_signed_finalize (GObject *object)
+{
+ CamelMultipartSigned *multipart;
+
+ multipart = CAMEL_MULTIPART_SIGNED (object);
+
+ g_free (multipart->protocol);
+ g_free (multipart->micalg);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+multipart_signed_set_mime_type_field (CamelDataWrapper *data_wrapper,
+ CamelContentType *mime_type)
+{
+ CamelDataWrapperClass *data_wrapper_class;
CamelMultipartSigned *mps = (CamelMultipartSigned *)data_wrapper;
- ((CamelDataWrapperClass *)parent_class)->set_mime_type_field(data_wrapper, mime_type);
+ /* we snoop the mime type to get boundary and hash info */
+
+ /* Chain up to parent's set_mime_type_field() method. */
+ data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (parent_class);
+ data_wrapper_class->set_mime_type_field(data_wrapper, mime_type);
+
if (mime_type) {
const gchar *micalg, *protocol;
@@ -334,33 +257,140 @@ set_mime_type_field(CamelDataWrapper *data_wrapper, CamelContentType *mime_type)
}
}
+static gssize
+multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error)
+{
+ CamelMultipartSigned *mps = (CamelMultipartSigned *)data_wrapper;
+ CamelMultipart *mp = (CamelMultipart *)mps;
+ const gchar *boundary;
+ gssize total = 0;
+ gssize count;
+
+ /* we have 3 basic cases:
+ 1. constructed, we write out the data wrapper stream we got
+ 2. signed content, we create and write out a new stream
+ 3. invalid
+ */
+
+ /* 1 */
+ /* FIXME: locking? */
+ if (data_wrapper->stream) {
+ camel_stream_reset (data_wrapper->stream, NULL);
+ return camel_stream_write_to_stream (
+ data_wrapper->stream, stream, error);
+ }
+
+ /* 3 */
+ if (mps->signature == NULL || mps->contentraw == NULL)
+ return -1;
+
+ /* 2 */
+ boundary = camel_multipart_get_boundary(mp);
+ if (mp->preface) {
+ count = camel_stream_write_string (
+ stream, mp->preface, error);
+ if (count == -1)
+ return -1;
+ total += count;
+ }
+
+ /* first boundary */
+ count = camel_stream_printf (stream, error, "\n--%s\n", boundary);
+ if (count == -1)
+ return -1;
+ total += count;
+
+ /* output content part */
+ camel_stream_reset (mps->contentraw, NULL);
+ count = camel_stream_write_to_stream (
+ mps->contentraw, stream, error);
+ if (count == -1)
+ return -1;
+ total += count;
+
+ /* boundary */
+ count = camel_stream_printf (stream, error, "\n--%s\n", boundary);
+ if (count == -1)
+ return -1;
+ total += count;
+
+ /* signature */
+ count = camel_data_wrapper_write_to_stream (
+ (CamelDataWrapper *) mps->signature, stream, error);
+ if (count == -1)
+ return -1;
+ total += count;
+
+ /* write the terminating boudary delimiter */
+ count = camel_stream_printf (stream, error, "\n--%s--\n", boundary);
+ if (count == -1)
+ return -1;
+ total += count;
+
+ /* and finally the postface */
+ if (mp->postface) {
+ count = camel_stream_write_string (
+ stream, mp->postface, error);
+ if (count == -1)
+ return -1;
+ total += count;
+ }
+
+ return total;
+}
+
+static gint
+multipart_signed_construct_from_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error)
+{
+ CamelMultipartSigned *mps = (CamelMultipartSigned *)data_wrapper;
+ CamelStream *mem = camel_stream_mem_new();
+
+ if (camel_stream_write_to_stream (stream, mem, error) == -1)
+ return -1;
+
+ multipart_signed_set_stream (mps, mem);
+
+ return 0;
+}
+
static void
-signed_add_part(CamelMultipart *multipart, CamelMimePart *part)
+multipart_signed_add_part (CamelMultipart *multipart,
+ CamelMimePart *part)
{
g_warning("Cannot add parts to a signed part using add_part");
}
static void
-signed_add_part_at(CamelMultipart *multipart, CamelMimePart *part, guint index)
+multipart_signed_add_part_at (CamelMultipart *multipart,
+ CamelMimePart *part,
+ guint index)
{
g_warning("Cannot add parts to a signed part using add_part_at");
}
static void
-signed_remove_part(CamelMultipart *multipart, CamelMimePart *part)
+multipart_signed_remove_part (CamelMultipart *multipart,
+ CamelMimePart *part)
{
g_warning("Cannot remove parts from a signed part using remove_part");
}
static CamelMimePart *
-signed_remove_part_at (CamelMultipart *multipart, guint index)
+multipart_signed_remove_part_at (CamelMultipart *multipart,
+ guint index)
{
g_warning("Cannot remove parts from a signed part using remove_part");
+
return NULL;
}
static CamelMimePart *
-signed_get_part(CamelMultipart *multipart, guint index)
+multipart_signed_get_part (CamelMultipart *multipart,
+ guint index)
{
CamelMultipartSigned *mps = (CamelMultipartSigned *)multipart;
CamelDataWrapper *dw = (CamelDataWrapper *)multipart;
@@ -374,7 +404,7 @@ signed_get_part(CamelMultipart *multipart, guint index)
stream = mps->contentraw;
g_object_ref (stream);
} else if (mps->start1 == -1
- && parse_content(mps) == -1
+ && multipart_signed_parse_content(mps) == -1
&& (stream = ((CamelDataWrapper *)mps)->stream) == NULL) {
g_warning("Trying to get content on an invalid multipart/signed");
return NULL;
@@ -386,25 +416,27 @@ signed_get_part(CamelMultipart *multipart, guint index)
} else {
stream = camel_seekable_substream_new((CamelSeekableStream *)dw->stream, mps->start1, mps->end1);
}
- camel_stream_reset(stream);
+ camel_stream_reset (stream, NULL);
mps->content = camel_mime_part_new();
- camel_data_wrapper_construct_from_stream((CamelDataWrapper *)mps->content, stream);
+ camel_data_wrapper_construct_from_stream (
+ CAMEL_DATA_WRAPPER (mps->content), stream, NULL);
g_object_unref (stream);
return mps->content;
case CAMEL_MULTIPART_SIGNED_SIGNATURE:
if (mps->signature)
return mps->signature;
if (mps->start1 == -1
- && parse_content(mps) == -1) {
+ && multipart_signed_parse_content(mps) == -1) {
g_warning("Trying to get signature on invalid multipart/signed");
return NULL;
} else if (dw->stream == NULL) {
return NULL;
}
stream = camel_seekable_substream_new((CamelSeekableStream *)dw->stream, mps->start2, mps->end2);
- camel_stream_reset(stream);
+ camel_stream_reset (stream, NULL);
mps->signature = camel_mime_part_new();
- camel_data_wrapper_construct_from_stream((CamelDataWrapper *)mps->signature, stream);
+ camel_data_wrapper_construct_from_stream (
+ CAMEL_DATA_WRAPPER (mps->signature), stream, NULL);
g_object_unref (stream);
return mps->signature;
default:
@@ -415,7 +447,7 @@ signed_get_part(CamelMultipart *multipart, guint index)
}
static guint
-signed_get_number(CamelMultipart *multipart)
+multipart_signed_get_number (CamelMultipart *multipart)
{
CamelDataWrapper *dw = (CamelDataWrapper *)multipart;
CamelMultipartSigned *mps = (CamelMultipartSigned *)multipart;
@@ -425,7 +457,7 @@ signed_get_number(CamelMultipart *multipart)
if ((mps->content || mps->contentraw) && mps->signature)
return 2;
- if (mps->start1 == -1 && parse_content(mps) == -1) {
+ if (mps->start1 == -1 && multipart_signed_parse_content(mps) == -1) {
if (dw->stream == NULL)
return 0;
else
@@ -435,46 +467,9 @@ signed_get_number(CamelMultipart *multipart)
}
}
-static void
-set_stream(CamelMultipartSigned *mps, CamelStream *stream)
-{
- CamelDataWrapper *dw = (CamelDataWrapper *)mps;
-
- if (dw->stream)
- g_object_unref (dw->stream);
- dw->stream = stream;
-
- mps->start1 = -1;
- if (mps->content) {
- g_object_unref (mps->content);
- mps->content = NULL;
- }
- if (mps->contentraw) {
- g_object_unref (mps->contentraw);
- mps->contentraw = NULL;
- }
- if (mps->signature) {
- g_object_unref (mps->signature);
- mps->signature = NULL;
- }
-}
-
static gint
-construct_from_stream(CamelDataWrapper *data_wrapper, CamelStream *stream)
-{
- CamelMultipartSigned *mps = (CamelMultipartSigned *)data_wrapper;
- CamelStream *mem = camel_stream_mem_new();
-
- if (camel_stream_write_to_stream(stream, mem) == -1)
- return -1;
-
- set_stream(mps, mem);
-
- return 0;
-}
-
-static gint
-signed_construct_from_parser(CamelMultipart *multipart, struct _CamelMimeParser *mp)
+multipart_signed_construct_from_parser (CamelMultipart *multipart,
+ CamelMimeParser *mp)
{
gint err;
CamelContentType *content_type;
@@ -493,9 +488,9 @@ signed_construct_from_parser(CamelMultipart *multipart, struct _CamelMimeParser
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);
+ camel_stream_write(stream, buf, len, NULL);
- set_stream(mps, stream);
+ multipart_signed_set_stream (mps, stream);
err = camel_mime_parser_errno(mp);
if (err != 0) {
@@ -505,81 +500,94 @@ signed_construct_from_parser(CamelMultipart *multipart, struct _CamelMimeParser
return 0;
}
-static gssize
-write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
+static void
+multipart_signed_class_init (CamelMultipartSignedClass *class)
{
- CamelMultipartSigned *mps = (CamelMultipartSigned *)data_wrapper;
- CamelMultipart *mp = (CamelMultipart *)mps;
- const gchar *boundary;
- gssize total = 0;
- gssize count;
-
- /* we have 3 basic cases:
- 1. constructed, we write out the data wrapper stream we got
- 2. signed content, we create and write out a new stream
- 3. invalid
- */
+ GObjectClass *object_class;
+ CamelDataWrapperClass *data_wrapper_class;
+ CamelMultipartClass *multipart_class;
- /* 1 */
- /* FIXME: locking? */
- if (data_wrapper->stream) {
- camel_stream_reset(data_wrapper->stream);
- return camel_stream_write_to_stream(data_wrapper->stream, stream);
- }
+ parent_class = g_type_class_peek_parent (class);
- /* 3 */
- if (mps->signature == NULL || mps->contentraw == NULL)
- return -1;
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = multipart_signed_dispose;
+ object_class->finalize = multipart_signed_finalize;
- /* 2 */
- boundary = camel_multipart_get_boundary(mp);
- if (mp->preface) {
- count = camel_stream_write_string(stream, mp->preface);
- if (count == -1)
- return -1;
- total += count;
- }
+ data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
+ data_wrapper_class->set_mime_type_field = multipart_signed_set_mime_type_field;
+ data_wrapper_class->write_to_stream = multipart_signed_write_to_stream;
+ data_wrapper_class->decode_to_stream = multipart_signed_write_to_stream;
+ data_wrapper_class->construct_from_stream = multipart_signed_construct_from_stream;
- /* first boundary */
- count = camel_stream_printf(stream, "\n--%s\n", boundary);
- if (count == -1)
- return -1;
- total += count;
+ multipart_class = CAMEL_MULTIPART_CLASS (class);
+ multipart_class->add_part = multipart_signed_add_part;
+ multipart_class->add_part_at = multipart_signed_add_part_at;
+ multipart_class->remove_part = multipart_signed_remove_part;
+ multipart_class->remove_part_at = multipart_signed_remove_part_at;
+ multipart_class->get_part = multipart_signed_get_part;
+ multipart_class->get_number = multipart_signed_get_number;
+ multipart_class->construct_from_parser = multipart_signed_construct_from_parser;
+}
- /* output content part */
- camel_stream_reset(mps->contentraw);
- count = camel_stream_write_to_stream(mps->contentraw, stream);
- if (count == -1)
- return -1;
- total += count;
+static void
+multipart_signed_init (CamelMultipartSigned *multipart)
+{
+ camel_data_wrapper_set_mime_type (
+ CAMEL_DATA_WRAPPER (multipart), "multipart/signed");
- /* boundary */
- count = camel_stream_printf(stream, "\n--%s\n", boundary);
- if (count == -1)
- return -1;
- total += count;
+ multipart->start1 = -1;
+}
- /* signature */
- count = camel_data_wrapper_write_to_stream((CamelDataWrapper *)mps->signature, stream);
- if (count == -1)
- return -1;
- total += count;
+GType
+camel_multipart_signed_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
- /* write the terminating boudary delimiter */
- count = camel_stream_printf(stream, "\n--%s--\n", boundary);
- if (count == -1)
- return -1;
- total += count;
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ type = g_type_register_static_simple (
+ CAMEL_TYPE_MULTIPART,
+ "CamelMultipartSigned",
+ sizeof (CamelMultipartSignedClass),
+ (GClassInitFunc) multipart_signed_class_init,
+ sizeof (CamelMultipartSigned),
+ (GInstanceInitFunc) multipart_signed_init,
+ 0);
- /* and finally the postface */
- if (mp->postface) {
- count = camel_stream_write_string(stream, mp->postface);
- if (count == -1)
- return -1;
- total += count;
- }
+ return type;
+}
- return total;
+/**
+ * camel_multipart_signed_new:
+ *
+ * Create a new #CamelMultipartSigned object.
+ *
+ * A MultipartSigned should be used to store and create parts of
+ * type "multipart/signed". This is because multipart/signed is
+ * entirely broken-by-design (tm) and uses completely
+ * different semantics to other mutlipart types. It must be treated
+ * as opaque data by any transport. See rfc 3156 for details.
+ *
+ * There are 3 ways to create the part:
+ * Use construct_from_stream. If this is used, then you must
+ * set the mime_type appropriately to match the data uses, so
+ * that the multiple parts my be extracted.
+ *
+ * Use construct_from_parser. The parser MUST be in the #CAMEL_MIME_PARSER_STATE_HEADER
+ * state, and the current content_type MUST be "multipart/signed" with
+ * the appropriate boundary and it SHOULD include the appropriate protocol
+ * and hash specifiers.
+ *
+ * Use sign_part. A signature part will automatically be created
+ * and the whole part may be written using write_to_stream to
+ * create a 'transport-safe' version (as safe as can be expected with
+ * such a broken specification).
+ *
+ * Returns: a new #CamelMultipartSigned object
+ **/
+CamelMultipartSigned *
+camel_multipart_signed_new (void)
+{
+ return g_object_new (CAMEL_TYPE_MULTIPART_SIGNED, NULL);
}
/**
@@ -607,7 +615,7 @@ camel_multipart_signed_get_content_stream (CamelMultipartSigned *mps,
CamelStream *sub;
CamelMimeFilter *canon_filter;
- if (mps->start1 == -1 && parse_content(mps) == -1) {
+ if (mps->start1 == -1 && multipart_signed_parse_content(mps) == -1) {
g_set_error (
error, CAMEL_ERROR,
CAMEL_ERROR_SYSTEM,
diff --git a/camel/camel-multipart.c b/camel/camel-multipart.c
index dbf03e7..1b853a5 100644
--- a/camel/camel-multipart.c
+++ b/camel/camel-multipart.c
@@ -37,27 +37,6 @@
#define d(x)
-static gboolean is_offline (CamelDataWrapper *data_wrapper);
-static void add_part (CamelMultipart *multipart,
- CamelMimePart *part);
-static void add_part_at (CamelMultipart *multipart,
- CamelMimePart *part,
- guint index);
-static void remove_part (CamelMultipart *multipart,
- CamelMimePart *part);
-static CamelMimePart * remove_part_at (CamelMultipart *multipart,
- guint index);
-static CamelMimePart * get_part (CamelMultipart *multipart,
- guint index);
-static guint get_number (CamelMultipart *multipart);
-static void set_boundary (CamelMultipart *multipart,
- const gchar *boundary);
-static const gchar * get_boundary (CamelMultipart *multipart);
-static gssize write_to_stream (CamelDataWrapper *data_wrapper,
- CamelStream *stream);
-
-static gint construct_from_parser(CamelMultipart *multipart, struct _CamelMimeParser *mp);
-
static gpointer parent_class;
static void
@@ -85,6 +64,260 @@ multipart_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+/* this is MIME specific, doesn't belong here really */
+static gssize
+multipart_write_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error)
+{
+ CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper);
+ const gchar *boundary;
+ gssize total = 0;
+ gssize count;
+ GList *node;
+
+ /* get the bundary text */
+ boundary = camel_multipart_get_boundary (multipart);
+
+ /* we cannot write a multipart without a boundary string */
+ g_return_val_if_fail (boundary, -1);
+
+ /*
+ * write the preface text (usually something like
+ * "This is a mime message, if you see this, then
+ * your mail client probably doesn't support ...."
+ */
+ if (multipart->preface) {
+ count = camel_stream_write_string (
+ stream, multipart->preface, error);
+ if (count == -1)
+ return -1;
+ total += count;
+ }
+
+ /*
+ * Now, write all the parts, separated by the boundary
+ * delimiter
+ */
+ node = multipart->parts;
+ while (node) {
+ count = camel_stream_printf (
+ stream, error, "\n--%s\n", boundary);
+ if (count == -1)
+ return -1;
+ total += count;
+
+ count = camel_data_wrapper_write_to_stream (
+ CAMEL_DATA_WRAPPER (node->data), stream, error);
+ if (count == -1)
+ return -1;
+ total += count;
+ node = node->next;
+ }
+
+ /* write the terminating boudary delimiter */
+ count = camel_stream_printf (
+ stream, error, "\n--%s--\n", boundary);
+ if (count == -1)
+ return -1;
+ total += count;
+
+ /* and finally the postface */
+ if (multipart->postface) {
+ count = camel_stream_write_string (
+ stream, multipart->postface, error);
+ if (count == -1)
+ return -1;
+ total += count;
+ }
+
+ return total;
+}
+
+static gboolean
+multipart_is_offline (CamelDataWrapper *data_wrapper)
+{
+ CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper);
+ GList *node;
+ CamelDataWrapper *part;
+
+ if (CAMEL_DATA_WRAPPER_CLASS (parent_class)->is_offline (data_wrapper))
+ return TRUE;
+ for (node = multipart->parts; node; node = node->next) {
+ part = node->data;
+ if (camel_data_wrapper_is_offline (part))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+multipart_add_part (CamelMultipart *multipart, CamelMimePart *part)
+{
+ multipart->parts = g_list_append (
+ multipart->parts, g_object_ref (part));
+}
+
+static void
+multipart_add_part_at (CamelMultipart *multipart,
+ CamelMimePart *part,
+ guint index)
+{
+ multipart->parts = g_list_insert (
+ multipart->parts, g_object_ref (part), index);
+}
+
+static void
+multipart_remove_part (CamelMultipart *multipart,
+ CamelMimePart *part)
+{
+ /* Make sure we don't unref a part we don't have. */
+ if (g_list_find (multipart->parts, part) == NULL)
+ return;
+
+ multipart->parts = g_list_remove (multipart->parts, part);
+ g_object_unref (part);
+}
+
+static CamelMimePart *
+multipart_remove_part_at (CamelMultipart *multipart,
+ guint index)
+{
+ CamelMimePart *removed_part;
+ GList *link;
+
+ if (!(multipart->parts))
+ return NULL;
+
+ link = g_list_nth (multipart->parts, index);
+ if (link == NULL) {
+ g_warning ("CamelMultipart::remove_part_at: "
+ "part to remove is NULL\n");
+ return NULL;
+ }
+ removed_part = CAMEL_MIME_PART (link->data);
+
+ multipart->parts = g_list_remove_link (multipart->parts, link);
+ if (link->data)
+ g_object_unref (link->data);
+ g_list_free_1 (link);
+
+ return removed_part;
+}
+
+static CamelMimePart *
+multipart_get_part (CamelMultipart *multipart,
+ guint index)
+{
+ GList *part;
+
+ if (!(multipart->parts))
+ return NULL;
+
+ part = g_list_nth (multipart->parts, index);
+ if (part)
+ return CAMEL_MIME_PART (part->data);
+ else
+ return NULL;
+}
+
+static guint
+multipart_get_number (CamelMultipart *multipart)
+{
+ return g_list_length (multipart->parts);
+}
+
+static void
+multipart_set_boundary (CamelMultipart *multipart,
+ const gchar *boundary)
+{
+ CamelDataWrapper *cdw = CAMEL_DATA_WRAPPER (multipart);
+ gchar *bgen, bbuf[27], *p;
+ guint8 *digest;
+ gsize length;
+ gint state, save;
+
+ g_return_if_fail (cdw->mime_type != NULL);
+
+ length = g_checksum_type_get_length (G_CHECKSUM_MD5);
+ digest = g_alloca (length);
+
+ if (!boundary) {
+ GChecksum *checksum;
+
+ /* Generate a fairly random boundary string. */
+ bgen = g_strdup_printf ("%p:%lu:%lu", (gpointer) multipart,
+ (gulong) getpid(),
+ (gulong) time(NULL));
+
+ checksum = g_checksum_new (G_CHECKSUM_MD5);
+ g_checksum_update (checksum, (guchar *) bgen, -1);
+ g_checksum_get_digest (checksum, digest, &length);
+ g_checksum_free (checksum);
+
+ g_free (bgen);
+ strcpy (bbuf, "=-");
+ p = bbuf + 2;
+ state = save = 0;
+ p += g_base64_encode_step (
+ (guchar *) digest, length, FALSE, p, &state, &save);
+ *p = '\0';
+
+ boundary = bbuf;
+ }
+
+ camel_content_type_set_param (cdw->mime_type, "boundary", boundary);
+}
+
+static const gchar *
+multipart_get_boundary (CamelMultipart *multipart)
+{
+ CamelDataWrapper *cdw = CAMEL_DATA_WRAPPER (multipart);
+
+ g_return_val_if_fail (cdw->mime_type != NULL, NULL);
+ return camel_content_type_param (cdw->mime_type, "boundary");
+}
+
+static gint
+multipart_construct_from_parser (CamelMultipart *multipart,
+ CamelMimeParser *mp)
+{
+ gint err;
+ CamelContentType *content_type;
+ CamelMimePart *bodypart;
+ gchar *buf;
+ gsize len;
+
+ g_assert(camel_mime_parser_state(mp) == CAMEL_MIME_PARSER_STATE_MULTIPART);
+
+ /* FIXME: we should use a came-mime-mutlipart, not jsut a camel-multipart, but who cares */
+ d(printf("Creating multi-part\n"));
+
+ content_type = camel_mime_parser_content_type(mp);
+ camel_multipart_set_boundary(multipart,
+ camel_content_type_param(content_type, "boundary"));
+
+ 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_multipart_add_part(multipart, bodypart);
+ g_object_unref (bodypart);
+ }
+
+ /* these are only return valid data in the MULTIPART_END state */
+ camel_multipart_set_preface(multipart, camel_mime_parser_preface (mp));
+ camel_multipart_set_postface(multipart, camel_mime_parser_postface (mp));
+
+ err = camel_mime_parser_errno(mp);
+ if (err != 0) {
+ errno = err;
+ return -1;
+ } else
+ return 0;
+}
+
static void
multipart_class_init (CamelMultipartClass *class)
{
@@ -98,19 +331,19 @@ multipart_class_init (CamelMultipartClass *class)
object_class->finalize = multipart_finalize;
data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
- data_wrapper_class->write_to_stream = write_to_stream;
- data_wrapper_class->decode_to_stream = write_to_stream;
- data_wrapper_class->is_offline = is_offline;
-
- class->add_part = add_part;
- class->add_part_at = add_part_at;
- class->remove_part = remove_part;
- class->remove_part_at = remove_part_at;
- class->get_part = get_part;
- class->get_number = get_number;
- class->set_boundary = set_boundary;
- class->get_boundary = get_boundary;
- class->construct_from_parser = construct_from_parser;
+ data_wrapper_class->write_to_stream = multipart_write_to_stream;
+ data_wrapper_class->decode_to_stream = multipart_write_to_stream;
+ data_wrapper_class->is_offline = multipart_is_offline;
+
+ class->add_part = multipart_add_part;
+ class->add_part_at = multipart_add_part_at;
+ class->remove_part = multipart_remove_part;
+ class->remove_part_at = multipart_remove_part_at;
+ class->get_part = multipart_get_part;
+ class->get_number = multipart_get_number;
+ class->set_boundary = multipart_set_boundary;
+ class->get_boundary = multipart_get_boundary;
+ class->construct_from_parser = multipart_construct_from_parser;
}
static void
@@ -161,13 +394,6 @@ camel_multipart_new (void)
return multipart;
}
-static void
-add_part (CamelMultipart *multipart, CamelMimePart *part)
-{
- multipart->parts = g_list_append (multipart->parts, part);
- g_object_ref (part);
-}
-
/**
* camel_multipart_add_part:
* @multipart: a #CamelMultipart object
@@ -190,13 +416,6 @@ camel_multipart_add_part (CamelMultipart *multipart,
class->add_part (multipart, part);
}
-static void
-add_part_at (CamelMultipart *multipart, CamelMimePart *part, guint index)
-{
- multipart->parts = g_list_insert (multipart->parts, part, index);
- g_object_ref (part);
-}
-
/**
* camel_multipart_add_part_at:
* @multipart: a #CamelMultipart object
@@ -222,15 +441,6 @@ camel_multipart_add_part_at (CamelMultipart *multipart,
class->add_part_at (multipart, part, index);
}
-static void
-remove_part (CamelMultipart *multipart, CamelMimePart *part)
-{
- if (!multipart->parts)
- return;
- multipart->parts = g_list_remove (multipart->parts, part);
- g_object_unref (part);
-}
-
/**
* camel_multipart_remove_part:
* @multipart: a #CamelMultipart object
@@ -253,33 +463,6 @@ camel_multipart_remove_part (CamelMultipart *multipart,
class->remove_part (multipart, part);
}
-static CamelMimePart *
-remove_part_at (CamelMultipart *multipart, guint index)
-{
- GList *parts_list;
- GList *part_to_remove;
- CamelMimePart *removed_part;
-
- if (!(multipart->parts))
- return NULL;
-
- parts_list = multipart->parts;
- part_to_remove = g_list_nth (parts_list, index);
- if (!part_to_remove) {
- g_warning ("CamelMultipart::remove_part_at: "
- "part to remove is NULL\n");
- return NULL;
- }
- removed_part = CAMEL_MIME_PART (part_to_remove->data);
-
- multipart->parts = g_list_remove_link (parts_list, part_to_remove);
- if (part_to_remove->data)
- g_object_unref (part_to_remove->data);
- g_list_free_1 (part_to_remove);
-
- return removed_part;
-}
-
/**
* camel_multipart_remove_part_at:
* @multipart: a #CamelMultipart object
@@ -304,21 +487,6 @@ camel_multipart_remove_part_at (CamelMultipart *multipart,
return class->remove_part_at (multipart, index);
}
-static CamelMimePart *
-get_part (CamelMultipart *multipart, guint index)
-{
- GList *part;
-
- if (!(multipart->parts))
- return NULL;
-
- part = g_list_nth (multipart->parts, index);
- if (part)
- return CAMEL_MIME_PART (part->data);
- else
- return NULL;
-}
-
/**
* camel_multipart_get_part:
* @multipart: a #CamelMultipart object
@@ -340,12 +508,6 @@ camel_multipart_get_part (CamelMultipart *multipart,
return class->get_part (multipart, index);
}
-static guint
-get_number (CamelMultipart *multipart)
-{
- return g_list_length (multipart->parts);
-}
-
/**
* camel_multipart_get_number:
* @multipart: a #CamelMultipart object
@@ -365,47 +527,6 @@ camel_multipart_get_number (CamelMultipart *multipart)
return class->get_number (multipart);
}
-static void
-set_boundary (CamelMultipart *multipart, const gchar *boundary)
-{
- CamelDataWrapper *cdw = CAMEL_DATA_WRAPPER (multipart);
- gchar *bgen, bbuf[27], *p;
- guint8 *digest;
- gsize length;
- gint state, save;
-
- g_return_if_fail (cdw->mime_type != NULL);
-
- length = g_checksum_type_get_length (G_CHECKSUM_MD5);
- digest = g_alloca (length);
-
- if (!boundary) {
- GChecksum *checksum;
-
- /* Generate a fairly random boundary string. */
- bgen = g_strdup_printf ("%p:%lu:%lu", (gpointer) multipart,
- (gulong) getpid(),
- (gulong) time(NULL));
-
- checksum = g_checksum_new (G_CHECKSUM_MD5);
- g_checksum_update (checksum, (guchar *) bgen, -1);
- g_checksum_get_digest (checksum, digest, &length);
- g_checksum_free (checksum);
-
- g_free (bgen);
- strcpy (bbuf, "=-");
- p = bbuf + 2;
- state = save = 0;
- p += g_base64_encode_step (
- (guchar *) digest, length, FALSE, p, &state, &save);
- *p = '\0';
-
- boundary = bbuf;
- }
-
- camel_content_type_set_param (cdw->mime_type, "boundary", boundary);
-}
-
/**
* camel_multipart_set_boundary:
* @multipart: a #CamelMultipart object
@@ -430,15 +551,6 @@ camel_multipart_set_boundary (CamelMultipart *multipart,
class->set_boundary (multipart, boundary);
}
-static const gchar *
-get_boundary (CamelMultipart *multipart)
-{
- CamelDataWrapper *cdw = CAMEL_DATA_WRAPPER (multipart);
-
- g_return_val_if_fail (cdw->mime_type != NULL, NULL);
- return camel_content_type_param (cdw->mime_type, "boundary");
-}
-
/**
* camel_multipart_get_boundary:
* @multipart: a #CamelMultipart object
@@ -458,87 +570,6 @@ camel_multipart_get_boundary (CamelMultipart *multipart)
return class->get_boundary (multipart);
}
-static gboolean
-is_offline (CamelDataWrapper *data_wrapper)
-{
- CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper);
- GList *node;
- CamelDataWrapper *part;
-
- if (CAMEL_DATA_WRAPPER_CLASS (parent_class)->is_offline (data_wrapper))
- return TRUE;
- for (node = multipart->parts; node; node = node->next) {
- part = node->data;
- if (camel_data_wrapper_is_offline (part))
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* this is MIME specific, doesn't belong here really */
-static gssize
-write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
-{
- CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper);
- const gchar *boundary;
- gssize total = 0;
- gssize count;
- GList *node;
-
- /* get the bundary text */
- boundary = camel_multipart_get_boundary (multipart);
-
- /* we cannot write a multipart without a boundary string */
- g_return_val_if_fail (boundary, -1);
-
- /*
- * write the preface text (usually something like
- * "This is a mime message, if you see this, then
- * your mail client probably doesn't support ...."
- */
- if (multipart->preface) {
- count = camel_stream_write_string (stream, multipart->preface);
- if (count == -1)
- return -1;
- total += count;
- }
-
- /*
- * Now, write all the parts, separated by the boundary
- * delimiter
- */
- node = multipart->parts;
- while (node) {
- count = camel_stream_printf (stream, "\n--%s\n", boundary);
- if (count == -1)
- return -1;
- total += count;
-
- count = camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (node->data), stream);
- if (count == -1)
- return -1;
- total += count;
- node = node->next;
- }
-
- /* write the terminating boudary delimiter */
- count = camel_stream_printf (stream, "\n--%s--\n", boundary);
- if (count == -1)
- return -1;
- total += count;
-
- /* and finally the postface */
- if (multipart->postface) {
- count = camel_stream_write_string (stream, multipart->postface);
- if (count == -1)
- return -1;
- total += count;
- }
-
- return total;
-}
-
/**
* camel_multipart_set_preface:
* @multipart: a #CamelMultipart object
@@ -583,44 +614,6 @@ camel_multipart_set_postface(CamelMultipart *multipart, const gchar *postface)
}
}
-static gint
-construct_from_parser(CamelMultipart *multipart, struct _CamelMimeParser *mp)
-{
- gint err;
- CamelContentType *content_type;
- CamelMimePart *bodypart;
- gchar *buf;
- gsize len;
-
- g_assert(camel_mime_parser_state(mp) == CAMEL_MIME_PARSER_STATE_MULTIPART);
-
- /* FIXME: we should use a came-mime-mutlipart, not jsut a camel-multipart, but who cares */
- d(printf("Creating multi-part\n"));
-
- content_type = camel_mime_parser_content_type(mp);
- camel_multipart_set_boundary(multipart,
- camel_content_type_param(content_type, "boundary"));
-
- 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);
- camel_multipart_add_part(multipart, bodypart);
- g_object_unref (bodypart);
- }
-
- /* these are only return valid data in the MULTIPART_END state */
- camel_multipart_set_preface(multipart, camel_mime_parser_preface (mp));
- camel_multipart_set_postface(multipart, camel_mime_parser_postface (mp));
-
- err = camel_mime_parser_errno(mp);
- if (err != 0) {
- errno = err;
- return -1;
- } else
- return 0;
-}
-
/**
* camel_multipart_construct_from_parser:
* @multipart: a #CamelMultipart object
diff --git a/camel/camel-partition-table.c b/camel/camel-partition-table.c
index 66260e6..08aa629 100644
--- a/camel/camel-partition-table.c
+++ b/camel/camel-partition-table.c
@@ -31,6 +31,8 @@
#include <sys/types.h>
#include <unistd.h>
+#include <glib/gi18n-lib.h>
+
#include "camel-block-file.h"
#include "camel-list-utils.h"
#include "camel-partition-table.h"
@@ -195,7 +197,10 @@ static CamelBlock *find_partition (CamelPartitionTable *cpi, camel_hash_t id, gi
return NULL;
}
-CamelPartitionTable *camel_partition_table_new (struct _CamelBlockFile *bs, camel_block_t root)
+CamelPartitionTable *
+camel_partition_table_new (struct _CamelBlockFile *bs,
+ camel_block_t root,
+ GError **error)
{
CamelPartitionTable *cpi;
CamelPartitionMapBlock *ptb;
@@ -209,7 +214,7 @@ CamelPartitionTable *camel_partition_table_new (struct _CamelBlockFile *bs, came
/* read the partition table into memory */
do {
- block = camel_block_file_get_block (bs, root);
+ block = camel_block_file_get_block (bs, root, error);
if (block == NULL)
goto fail;
@@ -219,7 +224,7 @@ CamelPartitionTable *camel_partition_table_new (struct _CamelBlockFile *bs, came
/* if we have no data, prime initial block */
if (ptb->used == 0 && camel_dlist_empty (&cpi->partition) && ptb->next == 0) {
- pblock = camel_block_file_new_block (bs);
+ pblock = camel_block_file_new_block (bs, error);
if (pblock == NULL) {
camel_block_file_unref_block (bs, block);
goto fail;
@@ -275,7 +280,10 @@ fail:
return ret;
}
-camel_key_t camel_partition_table_lookup (CamelPartitionTable *cpi, const gchar *key)
+camel_key_t
+camel_partition_table_lookup (CamelPartitionTable *cpi,
+ const gchar *key,
+ GError **error)
{
CamelPartitionKeyBlock *pkb;
CamelPartitionMapBlock *ptb;
@@ -294,7 +302,8 @@ camel_key_t camel_partition_table_lookup (CamelPartitionTable *cpi, const gchar
return 0;
}
ptb = (CamelPartitionMapBlock *)&ptblock->data;
- block = camel_block_file_get_block (cpi->blocks, ptb->partition[index].blockid);
+ block = camel_block_file_get_block (
+ cpi->blocks, ptb->partition[index].blockid, error);
if (block == NULL) {
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
return 0;
@@ -319,7 +328,10 @@ camel_key_t camel_partition_table_lookup (CamelPartitionTable *cpi, const gchar
return keyid;
}
-void camel_partition_table_remove (CamelPartitionTable *cpi, const gchar *key)
+gboolean
+camel_partition_table_remove (CamelPartitionTable *cpi,
+ const gchar *key,
+ GError **error)
{
CamelPartitionKeyBlock *pkb;
CamelPartitionMapBlock *ptb;
@@ -334,13 +346,14 @@ void camel_partition_table_remove (CamelPartitionTable *cpi, const gchar *key)
ptblock = find_partition (cpi, hashid, &index);
if (ptblock == NULL) {
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
- return;
+ return TRUE;
}
ptb = (CamelPartitionMapBlock *)&ptblock->data;
- block = camel_block_file_get_block (cpi->blocks, ptb->partition[index].blockid);
+ block = camel_block_file_get_block (
+ cpi->blocks, ptb->partition[index].blockid, error);
if (block == NULL) {
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
- return;
+ return FALSE;
}
pkb = (CamelPartitionKeyBlock *)&block->data;
@@ -364,6 +377,8 @@ void camel_partition_table_remove (CamelPartitionTable *cpi, const gchar *key)
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
camel_block_file_unref_block (cpi->blocks, block);
+
+ return TRUE;
}
static gint
@@ -381,7 +396,10 @@ keys_cmp (gconstpointer ap, gconstpointer bp)
}
gint
-camel_partition_table_add (CamelPartitionTable *cpi, const gchar *key, camel_key_t keyid)
+camel_partition_table_add (CamelPartitionTable *cpi,
+ const gchar *key,
+ camel_key_t keyid,
+ GError **error)
{
camel_hash_t hashid, partid;
gint index, newindex = 0; /* initialisation of this and pkb/nkb is just to silence compiler */
@@ -401,7 +419,8 @@ camel_partition_table_add (CamelPartitionTable *cpi, const gchar *key, camel_key
return -1;
}
ptb = (CamelPartitionMapBlock *)&ptblock->data;
- block = camel_block_file_get_block (cpi->blocks, ptb->partition[index].blockid);
+ block = camel_block_file_get_block (
+ cpi->blocks, ptb->partition[index].blockid, error);
if (block == NULL) {
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
return -1;
@@ -423,13 +442,17 @@ camel_partition_table_add (CamelPartitionTable *cpi, const gchar *key, camel_key
/* TODO: Should look at next/previous partition table block as well ... */
if (index > 0) {
- pblock = camel_block_file_get_block (cpi->blocks, ptb->partition[index-1].blockid);
+ pblock = camel_block_file_get_block (
+ cpi->blocks, ptb->partition[index-1].blockid,
+ error);
if (pblock == NULL)
goto fail;
pkb = (CamelPartitionKeyBlock *)&pblock->data;
}
if (index < (ptb->used-1)) {
- nblock = camel_block_file_get_block (cpi->blocks, ptb->partition[index+1].blockid);
+ nblock = camel_block_file_get_block (
+ cpi->blocks, ptb->partition[index+1].blockid,
+ error);
if (nblock == NULL) {
if (pblock)
camel_block_file_unref_block (cpi->blocks, pblock);
@@ -463,7 +486,7 @@ camel_partition_table_add (CamelPartitionTable *cpi, const gchar *key, camel_key
/* See if we have room in the partition table for this block or need to split that too */
if (ptb->used >= G_N_ELEMENTS (ptb->partition)) {
/* TODO: Could check next block to see if it'll fit there first */
- ptnblock = camel_block_file_new_block (cpi->blocks);
+ ptnblock = camel_block_file_new_block (cpi->blocks, error);
if (ptnblock == NULL) {
if (nblock)
camel_block_file_unref_block (cpi->blocks, nblock);
@@ -505,7 +528,7 @@ camel_partition_table_add (CamelPartitionTable *cpi, const gchar *key, camel_key
}
/* try get newblock before modifying existing */
- newblock = camel_block_file_new_block (cpi->blocks);
+ newblock = camel_block_file_new_block (cpi->blocks, error);
if (newblock == NULL) {
if (nblock)
camel_block_file_unref_block (cpi->blocks, nblock);
@@ -663,7 +686,9 @@ camel_key_table_get_type (void)
}
CamelKeyTable *
-camel_key_table_new (CamelBlockFile *bs, camel_block_t root)
+camel_key_table_new (CamelBlockFile *bs,
+ camel_block_t root,
+ GError **error)
{
CamelKeyTable *ki;
@@ -673,7 +698,7 @@ camel_key_table_new (CamelBlockFile *bs, camel_block_t root)
g_object_ref (bs);
ki->rootid = root;
- ki->root_block = camel_block_file_get_block (bs, ki->rootid);
+ ki->root_block = camel_block_file_get_block (bs, ki->rootid, error);
if (ki->root_block == NULL) {
g_object_unref (ki);
ki = NULL;
@@ -699,7 +724,11 @@ camel_key_table_sync (CamelKeyTable *ki)
}
camel_key_t
-camel_key_table_add (CamelKeyTable *ki, const gchar *key, camel_block_t data, guint flags)
+camel_key_table_add (CamelKeyTable *ki,
+ const gchar *key,
+ camel_block_t data,
+ guint flags,
+ GError **error)
{
CamelBlock *last, *next;
CamelKeyBlock *kblast, *kbnext;
@@ -715,14 +744,15 @@ camel_key_table_add (CamelKeyTable *ki, const gchar *key, camel_block_t data, gu
CAMEL_KEY_TABLE_LOCK (ki, lock);
if (ki->root->last == 0) {
- last = camel_block_file_new_block (ki->blocks);
+ last = camel_block_file_new_block (ki->blocks, error);
if (last == NULL)
goto fail;
ki->root->last = ki->root->first = last->id;
camel_block_file_touch_block (ki->blocks, ki->root_block);
k (printf ("adding first block, first = %u\n", ki->root->first));
} else {
- last = camel_block_file_get_block (ki->blocks, ki->root->last);
+ last = camel_block_file_get_block (
+ ki->blocks, ki->root->last, error);
if (last == NULL)
goto fail;
}
@@ -740,7 +770,7 @@ camel_key_table_add (CamelKeyTable *ki, const gchar *key, camel_block_t data, gu
sizeof (kblast->u.keydata) - kblast->u.keys[kblast->used-1].offset,
left, len));
if (left < len) {
- next = camel_block_file_new_block (ki->blocks);
+ next = camel_block_file_new_block (ki->blocks, error);
if (next == NULL) {
camel_block_file_unref_block (ki->blocks, last);
goto fail;
@@ -792,23 +822,25 @@ fail:
return keyid;
}
-void
-camel_key_table_set_data (CamelKeyTable *ki, camel_key_t keyid, camel_block_t data)
+gboolean
+camel_key_table_set_data (CamelKeyTable *ki,
+ camel_key_t keyid,
+ camel_block_t data,
+ GError **error)
{
CamelBlock *bl;
camel_block_t blockid;
gint index;
CamelKeyBlock *kb;
- if (keyid == 0)
- return;
+ g_return_val_if_fail (keyid != 0, FALSE);
blockid = keyid & (~(CAMEL_BLOCK_SIZE-1));
index = keyid & (CAMEL_BLOCK_SIZE-1);
- bl = camel_block_file_get_block (ki->blocks, blockid);
+ bl = camel_block_file_get_block (ki->blocks, blockid, error);
if (bl == NULL)
- return;
+ return FALSE;
kb = (CamelKeyBlock *)&bl->data;
CAMEL_KEY_TABLE_LOCK (ki, lock);
@@ -821,10 +853,16 @@ camel_key_table_set_data (CamelKeyTable *ki, camel_key_t keyid, camel_block_t da
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
camel_block_file_unref_block (ki->blocks, bl);
+
+ return TRUE;
}
-void
-camel_key_table_set_flags (CamelKeyTable *ki, camel_key_t keyid, guint flags, guint set)
+gboolean
+camel_key_table_set_flags (CamelKeyTable *ki,
+ camel_key_t keyid,
+ guint flags,
+ guint set,
+ GError **error)
{
CamelBlock *bl;
camel_block_t blockid;
@@ -832,26 +870,23 @@ camel_key_table_set_flags (CamelKeyTable *ki, camel_key_t keyid, guint flags, gu
CamelKeyBlock *kb;
guint old;
- if (keyid == 0)
- return;
+ g_return_val_if_fail (keyid != 0, FALSE);
blockid = keyid & (~(CAMEL_BLOCK_SIZE-1));
index = keyid & (CAMEL_BLOCK_SIZE-1);
- bl = camel_block_file_get_block (ki->blocks, blockid);
+ bl = camel_block_file_get_block (ki->blocks, blockid, error);
if (bl == NULL)
- return;
+ return FALSE;
kb = (CamelKeyBlock *)&bl->data;
-#if 0
- g_assert (kb->used < 127); /* this should be more accurate */
- g_assert (index < kb->used);
-#else
if (kb->used >=127 || index >= kb->used) {
- g_warning ("Block %x: Invalid index or content: index %d used %d\n", blockid, index, kb->used);
- return;
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
+ _("Block %x: Invalid index or content: "
+ "index %d used %d"), blockid, index, kb->used);
+ return FALSE;
}
-#endif
CAMEL_KEY_TABLE_LOCK (ki, lock);
@@ -864,10 +899,16 @@ camel_key_table_set_flags (CamelKeyTable *ki, camel_key_t keyid, guint flags, gu
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
camel_block_file_unref_block (ki->blocks, bl);
+
+ return TRUE;
}
camel_block_t
-camel_key_table_lookup (CamelKeyTable *ki, camel_key_t keyid, gchar **keyp, guint *flags)
+camel_key_table_lookup (CamelKeyTable *ki,
+ camel_key_t keyid,
+ gchar **keyp,
+ guint *flags,
+ GError **error)
{
CamelBlock *bl;
camel_block_t blockid;
@@ -875,31 +916,29 @@ camel_key_table_lookup (CamelKeyTable *ki, camel_key_t keyid, gchar **keyp, guin
gchar *key;
CamelKeyBlock *kb;
+ g_return_val_if_fail (keyid != 0, 0);
+
if (keyp)
*keyp = NULL;
if (flags)
*flags = 0;
- if (keyid == 0)
- return 0;
blockid = keyid & (~(CAMEL_BLOCK_SIZE-1));
index = keyid & (CAMEL_BLOCK_SIZE-1);
- bl = camel_block_file_get_block (ki->blocks, blockid);
+ bl = camel_block_file_get_block (ki->blocks, blockid, error);
if (bl == NULL)
return 0;
kb = (CamelKeyBlock *)&bl->data;
-#if 0
- g_assert (kb->used < 127); /* this should be more accurate */
- g_assert (index < kb->used);
-#else
if (kb->used >=127 || index >= kb->used) {
- g_warning ("Block %x: Invalid index or content: index %d used %d\n", blockid, index, kb->used);
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
+ _("Block %x: Invalid index or content: "
+ "index %d used %d\n"), blockid, index, kb->used);
return 0;
}
-#endif
CAMEL_KEY_TABLE_LOCK (ki, lock);
@@ -927,7 +966,12 @@ camel_key_table_lookup (CamelKeyTable *ki, camel_key_t keyid, gchar **keyp, guin
/* iterate through all keys */
camel_key_t
-camel_key_table_next (CamelKeyTable *ki, camel_key_t next, gchar **keyp, guint *flagsp, camel_block_t *datap)
+camel_key_table_next (CamelKeyTable *ki,
+ camel_key_t next,
+ gchar **keyp,
+ guint *flagsp,
+ camel_block_t *datap,
+ GError **error)
{
CamelBlock *bl;
CamelKeyBlock *kb;
@@ -956,7 +1000,7 @@ camel_key_table_next (CamelKeyTable *ki, camel_key_t next, gchar **keyp, guint *
blockid = next & (~(CAMEL_BLOCK_SIZE-1));
index = next & (CAMEL_BLOCK_SIZE-1);
- bl = camel_block_file_get_block (ki->blocks, blockid);
+ bl = camel_block_file_get_block (ki->blocks, blockid, error);
if (bl == NULL) {
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
return 0;
diff --git a/camel/camel-partition-table.h b/camel/camel-partition-table.h
index 8b22e57..6a8f6d5 100644
--- a/camel/camel-partition-table.h
+++ b/camel/camel-partition-table.h
@@ -123,13 +123,22 @@ struct _CamelPartitionTableClass {
CamelObjectClass parent;
};
-GType camel_partition_table_get_type(void);
-
-CamelPartitionTable *camel_partition_table_new(struct _CamelBlockFile *bs, camel_block_t root);
-gint camel_partition_table_sync(CamelPartitionTable *cpi);
-gint camel_partition_table_add(CamelPartitionTable *cpi, const gchar *key, camel_key_t keyid);
-camel_key_t camel_partition_table_lookup(CamelPartitionTable *cpi, const gchar *key);
-void camel_partition_table_remove(CamelPartitionTable *cpi, const gchar *key);
+GType camel_partition_table_get_type (void);
+CamelPartitionTable *
+ camel_partition_table_new (struct _CamelBlockFile *bs,
+ camel_block_t root,
+ GError **error);
+gint camel_partition_table_sync (CamelPartitionTable *cpi);
+gint camel_partition_table_add (CamelPartitionTable *cpi,
+ const gchar *key,
+ camel_key_t keyid,
+ GError **error);
+camel_key_t camel_partition_table_lookup (CamelPartitionTable *cpi,
+ const gchar *key,
+ GError **error);
+gboolean camel_partition_table_remove (CamelPartitionTable *cpi,
+ const gchar *key,
+ GError **error);
/* ********************************************************************** */
@@ -181,15 +190,36 @@ struct _CamelKeyTableClass {
CamelObjectClass parent;
};
-GType camel_key_table_get_type(void);
-
-CamelKeyTable * camel_key_table_new(CamelBlockFile *bs, camel_block_t root);
-gint camel_key_table_sync(CamelKeyTable *ki);
-camel_key_t camel_key_table_add(CamelKeyTable *ki, const gchar *key, camel_block_t data, guint flags);
-void camel_key_table_set_data(CamelKeyTable *ki, camel_key_t keyid, camel_block_t data);
-void camel_key_table_set_flags(CamelKeyTable *ki, camel_key_t keyid, guint flags, guint set);
-camel_block_t camel_key_table_lookup(CamelKeyTable *ki, camel_key_t keyid, gchar **key, guint *flags);
-camel_key_t camel_key_table_next(CamelKeyTable *ki, camel_key_t next, gchar **keyp, guint *flagsp, camel_block_t *datap);
+GType camel_key_table_get_type (void);
+CamelKeyTable * camel_key_table_new (CamelBlockFile *bs,
+ camel_block_t root,
+ GError **error);
+gint camel_key_table_sync (CamelKeyTable *ki);
+camel_key_t camel_key_table_add (CamelKeyTable *ki,
+ const gchar *key,
+ camel_block_t data,
+ guint flags,
+ GError **error);
+gboolean camel_key_table_set_data (CamelKeyTable *ki,
+ camel_key_t keyid,
+ camel_block_t data,
+ GError **error);
+gboolean camel_key_table_set_flags (CamelKeyTable *ki,
+ camel_key_t keyid,
+ guint flags,
+ guint set,
+ GError **error);
+camel_block_t camel_key_table_lookup (CamelKeyTable *ki,
+ camel_key_t keyid,
+ gchar **key,
+ guint *flags,
+ GError **error);
+camel_key_t camel_key_table_next (CamelKeyTable *ki,
+ camel_key_t next,
+ gchar **keyp,
+ guint *flagsp,
+ camel_block_t *datap,
+ GError **error);
G_END_DECLS
diff --git a/camel/camel-search-private.c b/camel/camel-search-private.c
index da3efc0..757c05f 100644
--- a/camel/camel-search-private.c
+++ b/camel/camel-search-private.c
@@ -481,8 +481,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);
- camel_stream_write (stream, "", 1);
+ camel_data_wrapper_write_to_stream (containee, stream, NULL);
+ camel_stream_write (stream, "", 1, NULL);
truth = regexec (pattern, (gchar *) byte_array->data, 0, NULL, 0) == 0;
g_object_unref (stream);
}
diff --git a/camel/camel-seekable-stream.c b/camel/camel-seekable-stream.c
index e18b34c..d956d1b 100644
--- a/camel/camel-seekable-stream.c
+++ b/camel/camel-seekable-stream.c
@@ -30,7 +30,8 @@
static gpointer parent_class;
static gint
-seekable_stream_reset (CamelStream *stream)
+seekable_stream_reset (CamelStream *stream,
+ GError **error)
{
CamelSeekableStream *seekable_stream;
@@ -38,7 +39,7 @@ seekable_stream_reset (CamelStream *stream)
return camel_seekable_stream_seek (
seekable_stream, seekable_stream->bound_start,
- CAMEL_STREAM_SET);
+ CAMEL_STREAM_SET, error);
}
static off_t
@@ -50,7 +51,8 @@ seekable_stream_tell (CamelSeekableStream *stream)
static gint
seekable_stream_set_bounds (CamelSeekableStream *stream,
off_t start,
- off_t end)
+ off_t end,
+ GError **error)
{
/* store the bounds */
stream->bound_start = start;
@@ -58,7 +60,7 @@ seekable_stream_set_bounds (CamelSeekableStream *stream,
if (start > stream->position)
return camel_seekable_stream_seek (
- stream, start, CAMEL_STREAM_SET);
+ stream, start, CAMEL_STREAM_SET, error);
return 0;
}
@@ -107,6 +109,7 @@ camel_seekable_stream_get_type (void)
* @stream: a #CamelStream object
* @offset: offset value
* @policy: what to do with the offset
+ * @error: return location for a #GError, or %NULL
*
* Seek to the specified position in @stream.
*
@@ -127,7 +130,8 @@ camel_seekable_stream_get_type (void)
off_t
camel_seekable_stream_seek (CamelSeekableStream *stream,
off_t offset,
- CamelStreamSeekPolicy policy)
+ CamelStreamSeekPolicy policy,
+ GError **error)
{
CamelSeekableStreamClass *class;
@@ -136,7 +140,7 @@ camel_seekable_stream_seek (CamelSeekableStream *stream,
class = CAMEL_SEEKABLE_STREAM_GET_CLASS (stream);
g_return_val_if_fail (class->seek != NULL, -1);
- return class->seek (stream, offset, policy);
+ return class->seek (stream, offset, policy, error);
}
/**
@@ -165,6 +169,7 @@ camel_seekable_stream_tell (CamelSeekableStream *stream)
* @stream: a #CamelSeekableStream object
* @start: the first valid position
* @end: the first invalid position, or #CAMEL_STREAM_UNBOUND
+ * @error: return location for a #GError, or %NULL
*
* Set the range of valid data this stream is allowed to cover. If
* there is to be no @end value, then @end should be set to
@@ -175,7 +180,8 @@ camel_seekable_stream_tell (CamelSeekableStream *stream)
gint
camel_seekable_stream_set_bounds (CamelSeekableStream *stream,
off_t start,
- off_t end)
+ off_t end,
+ GError **error)
{
CamelSeekableStreamClass *class;
@@ -185,5 +191,5 @@ camel_seekable_stream_set_bounds (CamelSeekableStream *stream,
class = CAMEL_SEEKABLE_STREAM_GET_CLASS (stream);
g_return_val_if_fail (class->set_bounds != NULL, -1);
- return class->set_bounds (stream, start, end);
+ return class->set_bounds (stream, start, end, error);
}
diff --git a/camel/camel-seekable-stream.h b/camel/camel-seekable-stream.h
index b7743a9..1cf2801 100644
--- a/camel/camel-seekable-stream.h
+++ b/camel/camel-seekable-stream.h
@@ -76,21 +76,27 @@ struct _CamelSeekableStream {
struct _CamelSeekableStreamClass {
CamelStreamClass parent_class;
- /* Virtual methods */
- off_t (*seek) (CamelSeekableStream *stream, off_t offset,
- CamelStreamSeekPolicy policy);
- off_t (*tell) (CamelSeekableStream *stream);
- gint (*set_bounds) (CamelSeekableStream *stream,
- off_t start, off_t end);
+ off_t (*seek) (CamelSeekableStream *stream,
+ off_t offset,
+ CamelStreamSeekPolicy policy,
+ GError **error);
+ off_t (*tell) (CamelSeekableStream *stream);
+ gint (*set_bounds) (CamelSeekableStream *stream,
+ off_t start,
+ off_t end,
+ GError **error);
};
-GType camel_seekable_stream_get_type (void);
-
-/* public methods */
-off_t camel_seekable_stream_seek (CamelSeekableStream *stream, off_t offset,
- CamelStreamSeekPolicy policy);
-off_t camel_seekable_stream_tell (CamelSeekableStream *stream);
-gint camel_seekable_stream_set_bounds (CamelSeekableStream *stream, off_t start, off_t end);
+GType camel_seekable_stream_get_type (void);
+off_t camel_seekable_stream_seek (CamelSeekableStream *stream,
+ off_t offset,
+ CamelStreamSeekPolicy policy,
+ GError **error);
+off_t camel_seekable_stream_tell (CamelSeekableStream *stream);
+gint camel_seekable_stream_set_bounds(CamelSeekableStream *stream,
+ off_t start,
+ off_t end,
+ GError **error);
G_END_DECLS
diff --git a/camel/camel-seekable-substream.c b/camel/camel-seekable-substream.c
index 7c8d8fe..a6ec79c 100644
--- a/camel/camel-seekable-substream.c
+++ b/camel/camel-seekable-substream.c
@@ -38,7 +38,9 @@ seekable_substream_parent_reset (CamelSeekableSubstream *seekable_substream,
if (camel_seekable_stream_tell (parent) == seekable_stream->position)
return TRUE;
- return camel_seekable_stream_seek (parent, (off_t) seekable_stream->position, CAMEL_STREAM_SET) == seekable_stream->position;
+ return camel_seekable_stream_seek (
+ parent, (off_t) seekable_stream->position,
+ CAMEL_STREAM_SET, NULL) == seekable_stream->position;
}
static void
@@ -60,7 +62,8 @@ seekable_substream_dispose (GObject *object)
static gssize
seekable_substream_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelSeekableStream *parent;
CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream);
@@ -87,7 +90,7 @@ seekable_substream_read (CamelStream *stream,
return 0;
}
- v = camel_stream_read (CAMEL_STREAM (parent), buffer, n);
+ v = camel_stream_read (CAMEL_STREAM (parent), buffer, n, error);
/* ignore <0 - it's an error, let the caller deal */
if (v > 0)
@@ -99,7 +102,8 @@ seekable_substream_read (CamelStream *stream,
static gssize
seekable_substream_write (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelSeekableStream *parent;
CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM(stream);
@@ -126,7 +130,7 @@ seekable_substream_write (CamelStream *stream,
return 0;
}
- v = camel_stream_write((CamelStream *)parent, buffer, n);
+ v = camel_stream_write (CAMEL_STREAM (parent), buffer, n, error);
/* ignore <0 - it's an error, let the caller deal */
if (v > 0)
@@ -137,15 +141,17 @@ seekable_substream_write (CamelStream *stream,
}
static gint
-seekable_substream_flush (CamelStream *stream)
+seekable_substream_flush (CamelStream *stream,
+ GError **error)
{
CamelSeekableSubstream *sus = (CamelSeekableSubstream *)stream;
- return camel_stream_flush(CAMEL_STREAM(sus->parent_stream));
+ return camel_stream_flush (CAMEL_STREAM (sus->parent_stream), error);
}
static gint
-seekable_substream_close (CamelStream *stream)
+seekable_substream_close (CamelStream *stream,
+ GError **error)
{
/* we dont really want to close the substream ... */
return 0;
@@ -178,12 +184,16 @@ seekable_substream_eos (CamelStream *stream)
static off_t
seekable_substream_seek (CamelSeekableStream *seekable_stream,
off_t offset,
- CamelStreamSeekPolicy policy)
+ CamelStreamSeekPolicy policy,
+ GError **error)
{
- CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM(seekable_stream);
- CamelStream *stream = CAMEL_STREAM(seekable_stream);
+ CamelStream *stream;
+ CamelSeekableSubstream *seekable_substream;
off_t real_offset = 0;
+ stream = CAMEL_STREAM (seekable_stream);
+ seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (seekable_stream);
+
stream->eos = FALSE;
switch (policy) {
@@ -197,9 +207,9 @@ seekable_substream_seek (CamelSeekableStream *seekable_stream,
case CAMEL_STREAM_END:
if (seekable_stream->bound_end == CAMEL_STREAM_UNBOUND) {
- real_offset = camel_seekable_stream_seek(seekable_substream->parent_stream,
- offset,
- CAMEL_STREAM_END);
+ real_offset = camel_seekable_stream_seek(
+ seekable_substream->parent_stream,
+ offset, CAMEL_STREAM_END, error);
if (real_offset != -1) {
if (real_offset<seekable_stream->bound_start)
real_offset = seekable_stream->bound_start;
@@ -218,6 +228,7 @@ seekable_substream_seek (CamelSeekableStream *seekable_stream,
real_offset = seekable_stream->bound_start;
seekable_stream->position = real_offset;
+
return real_offset;
}
@@ -295,9 +306,10 @@ camel_seekable_substream_new(CamelSeekableStream *parent_stream, off_t start, of
g_object_ref (parent_stream);
/* Set the bound of the substream. We can ignore any possible error
- * here, because if we fail to seek now, it will try again later.
- */
- camel_seekable_stream_set_bounds ((CamelSeekableStream *)seekable_substream, start, end);
+ * here, because if we fail to seek now, it will try again later. */
+ camel_seekable_stream_set_bounds (
+ CAMEL_SEEKABLE_STREAM (seekable_substream),
+ start, end, NULL);
return CAMEL_STREAM (seekable_substream);
}
diff --git a/camel/camel-smime-context.c b/camel/camel-smime-context.c
index 621d246..ca0a387 100644
--- a/camel/camel-smime-context.c
+++ b/camel/camel-smime-context.c
@@ -81,7 +81,7 @@ static gpointer parent_class;
static void
sm_write_stream (gpointer arg, const gchar *buf, gulong len)
{
- camel_stream_write ((CamelStream *)arg, buf, len);
+ camel_stream_write ((CamelStream *)arg, buf, len, NULL);
}
static PK11SymKey *
@@ -547,7 +547,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);
+ camel_stream_write_to_stream (extstream, mem, NULL);
NSS_CMSDigestContext_Update (digcx, buffer->data, buffer->len);
g_object_unref (mem);
@@ -725,15 +725,13 @@ smime_context_sign (CamelCipherContext *context,
buffer = g_byte_array_new ();
istream = camel_stream_mem_new_with_byte_array (buffer);
- if (camel_cipher_canonical_to_stream (ipart,
- CAMEL_MIME_FILTER_CANON_STRIP
- |CAMEL_MIME_FILTER_CANON_CRLF
- |CAMEL_MIME_FILTER_CANON_FROM, istream) == -1) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Could not generate signing data: %s"),
- g_strerror (errno));
+ if (camel_cipher_canonical_to_stream (
+ ipart, CAMEL_MIME_FILTER_CANON_STRIP |
+ CAMEL_MIME_FILTER_CANON_CRLF |
+ CAMEL_MIME_FILTER_CANON_FROM,
+ istream, error) == -1) {
+ g_prefix_error (
+ error, _("Could not generate signing data: "));
goto fail;
}
@@ -762,8 +760,8 @@ smime_context_sign (CamelCipherContext *context,
res = 0;
dw = camel_data_wrapper_new ();
- camel_stream_reset (ostream);
- camel_data_wrapper_construct_from_stream (dw, ostream);
+ camel_stream_reset (ostream, NULL);
+ camel_data_wrapper_construct_from_stream (dw, ostream, NULL);
dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY;
if (((CamelSMIMEContext *)context)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN) {
@@ -792,7 +790,7 @@ smime_context_sign (CamelCipherContext *context,
mps->signature = sigpart;
mps->contentraw = istream;
- camel_stream_reset (istream);
+ camel_stream_reset (istream, NULL);
g_object_ref (istream);
camel_medium_set_content ((CamelMedium *)opart, (CamelDataWrapper *)mps);
@@ -888,7 +886,9 @@ smime_context_verify (CamelCipherContext *context,
NULL, NULL, /* password callback */
NULL, NULL); /* decrypt key callback */
- camel_data_wrapper_decode_to_stream (camel_medium_get_content ((CamelMedium *)sigpart), mem);
+ camel_data_wrapper_decode_to_stream (
+ camel_medium_get_content (CAMEL_MEDIUM (sigpart)),
+ mem, NULL);
(void)NSS_CMSDecoder_Update (dec, (gchar *) buffer->data, buffer->len);
cmsg = NSS_CMSDecoder_Finish (dec);
if (cmsg == NULL) {
@@ -1033,7 +1033,7 @@ smime_context_encrypt (CamelCipherContext *context,
/* FIXME: Canonicalise the input? */
buffer = g_byte_array_new ();
mem = camel_stream_mem_new_with_byte_array (buffer);
- camel_data_wrapper_write_to_stream ((CamelDataWrapper *)ipart, mem);
+ camel_data_wrapper_write_to_stream ((CamelDataWrapper *)ipart, mem, NULL);
if (NSS_CMSEncoder_Update (enc, (gchar *) buffer->data, buffer->len) != SECSuccess) {
NSS_CMSEncoder_Cancel (enc);
g_object_unref (mem);
@@ -1054,7 +1054,7 @@ smime_context_encrypt (CamelCipherContext *context,
PORT_FreeArena (poolp, PR_FALSE);
dw = camel_data_wrapper_new ();
- camel_data_wrapper_construct_from_stream (dw, ostream);
+ camel_data_wrapper_construct_from_stream (dw, ostream, NULL);
g_object_unref (ostream);
dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY;
@@ -1114,8 +1114,8 @@ smime_context_decrypt (CamelCipherContext *context,
/* FIXME: stream this to the decoder incrementally */
buffer = g_byte_array_new ();
istream = camel_stream_mem_new_with_byte_array (buffer);
- camel_data_wrapper_decode_to_stream (camel_medium_get_content ((CamelMedium *)ipart), istream);
- camel_stream_reset (istream);
+ camel_data_wrapper_decode_to_stream (camel_medium_get_content ((CamelMedium *)ipart), istream, NULL);
+ camel_stream_reset (istream, NULL);
dec = NSS_CMSDecoder_Start (NULL,
sm_write_stream, ostream, /* content callback */
@@ -1144,11 +1144,11 @@ smime_context_decrypt (CamelCipherContext *context,
}
#endif
- camel_stream_reset (ostream);
- camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)opart, ostream);
+ camel_stream_reset (ostream, NULL);
+ camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)opart, ostream, NULL);
if (NSS_CMSMessage_IsSigned (cmsg)) {
- camel_stream_reset (ostream);
+ camel_stream_reset (ostream, NULL);
valid = sm_verify_cmsg (context, cmsg, ostream, error);
} else {
valid = camel_cipher_validity_new ();
@@ -1275,8 +1275,8 @@ camel_smime_context_describe_part (CamelSMIMEContext *context, CamelMimePart *pa
/* FIXME: stream this to the decoder incrementally */
buffer = g_byte_array_new ();
istream = camel_stream_mem_new_with_byte_array (buffer);
- camel_data_wrapper_decode_to_stream (camel_medium_get_content ((CamelMedium *)part), istream);
- camel_stream_reset (istream);
+ camel_data_wrapper_decode_to_stream (camel_medium_get_content ((CamelMedium *)part), istream, NULL);
+ camel_stream_reset (istream, NULL);
dec = NSS_CMSDecoder_Start (NULL,
NULL, NULL,
diff --git a/camel/camel-stream-buffer.c b/camel/camel-stream-buffer.c
index 1dca0ee..3752a32 100644
--- a/camel/camel-stream-buffer.c
+++ b/camel/camel-stream-buffer.c
@@ -63,12 +63,13 @@ enum {
static gssize
stream_write_all (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
gsize left = n, w;
while (left > 0) {
- w = camel_stream_write (stream, buffer, left);
+ w = camel_stream_write (stream, buffer, left, error);
if (w == -1)
return -1;
left -= w;
@@ -140,7 +141,8 @@ stream_buffer_finalize (GObject *object)
static gssize
stream_buffer_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamBufferPrivate *priv;
gssize bytes_read = 1;
@@ -165,7 +167,7 @@ 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);
+ priv->stream, bptr, n, error);
if (bytes_read>0) {
n -= bytes_read;
bptr += bytes_read;
@@ -173,7 +175,7 @@ stream_buffer_read (CamelStream *stream,
} else {
bytes_read = camel_stream_read (
priv->stream, (gchar *)
- priv->buf, priv->size);
+ priv->buf, priv->size, error);
if (bytes_read>0) {
gsize bytes_used = bytes_read > n ? n : bytes_read;
priv->ptr = priv->buf;
@@ -198,7 +200,8 @@ stream_buffer_read (CamelStream *stream,
static gssize
stream_buffer_write (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamBufferPrivate *priv;
gssize total = n;
@@ -222,8 +225,8 @@ stream_buffer_write (CamelStream *stream,
/* if we've filled the buffer, write it out, reset buffer */
if (left == todo) {
if (stream_write_all (
- priv->stream, (gchar *)
- priv->buf, priv->size) == -1)
+ priv->stream, (gchar *) priv->buf,
+ priv->size, error) == -1)
return -1;
priv->ptr = priv->buf;
@@ -232,7 +235,8 @@ stream_buffer_write (CamelStream *stream,
/* if we still have more, write directly, or copy to buffer */
if (n > 0) {
if (n >= priv->size/3) {
- if (stream_write_all(priv->stream, buffer, n) == -1)
+ if (stream_write_all (
+ priv->stream, buffer, n, error) == -1)
return -1;
} else {
memcpy(priv->ptr, buffer, n);
@@ -244,7 +248,8 @@ stream_buffer_write (CamelStream *stream,
}
static gint
-stream_buffer_flush (CamelStream *stream)
+stream_buffer_flush (CamelStream *stream,
+ GError **error)
{
CamelStreamBufferPrivate *priv;
@@ -254,7 +259,7 @@ stream_buffer_flush (CamelStream *stream)
gsize len = priv->ptr - priv->buf;
if (camel_stream_write (
- priv->stream, (gchar *) priv->buf, len) == -1)
+ priv->stream, (gchar *) priv->buf, len, error) == -1)
return -1;
priv->ptr = priv->buf;
@@ -262,20 +267,21 @@ stream_buffer_flush (CamelStream *stream)
/* nothing to do for read mode 'flush' */
}
- return camel_stream_flush (priv->stream);
+ return camel_stream_flush (priv->stream, error);
}
static gint
-stream_buffer_close (CamelStream *stream)
+stream_buffer_close (CamelStream *stream,
+ GError **error)
{
CamelStreamBufferPrivate *priv;
priv = CAMEL_STREAM_BUFFER_GET_PRIVATE (stream);
- if (stream_buffer_flush (stream) == -1)
+ if (stream_buffer_flush (stream, error) == -1)
return -1;
- return camel_stream_close (priv->stream);
+ return camel_stream_close (priv->stream, error);
}
static gboolean
@@ -467,6 +473,7 @@ camel_stream_buffer_new_with_vbuf (CamelStream *stream, CamelStreamBufferMode mo
* @sbf: a #CamelStreamBuffer object
* @buf: Memory to write the string to.
* @max: Maxmimum number of characters to store.
+ * @error: return location for a #GError, or %NULL
*
* Read a line of characters up to the next newline character or
* @max-1 characters.
@@ -478,7 +485,10 @@ camel_stream_buffer_new_with_vbuf (CamelStream *stream, CamelStreamBufferMode mo
* and %-1 on error.
**/
gint
-camel_stream_buffer_gets(CamelStreamBuffer *sbf, gchar *buf, guint max)
+camel_stream_buffer_gets (CamelStreamBuffer *sbf,
+ gchar *buf,
+ guint max,
+ GError **error)
{
register gchar *outptr, *inptr, *inend, c, *outend;
gint bytes_read;
@@ -503,7 +513,7 @@ camel_stream_buffer_gets(CamelStreamBuffer *sbf, gchar *buf, guint max)
bytes_read = camel_stream_read (
sbf->priv->stream, (gchar *)
- sbf->priv->buf, sbf->priv->size);
+ sbf->priv->buf, sbf->priv->size, error);
if (bytes_read == -1) {
if (buf == outptr)
return -1;
@@ -523,8 +533,9 @@ camel_stream_buffer_gets(CamelStreamBuffer *sbf, gchar *buf, guint max)
}
/**
- * camel_stream_buffer_read_line: read a complete line from the stream
+ * camel_stream_buffer_read_line:
* @sbf: a #CamelStreamBuffer object
+ * @error: return location for a #GError, or %NULL
*
* This function reads a complete newline-terminated line from the stream
* and returns it in allocated memory. The trailing newline (and carriage
@@ -534,7 +545,8 @@ camel_stream_buffer_gets(CamelStreamBuffer *sbf, gchar *buf, guint max)
* or %NULL on eof. If an error occurs, @ex will be set.
**/
gchar *
-camel_stream_buffer_read_line (CamelStreamBuffer *sbf)
+camel_stream_buffer_read_line (CamelStreamBuffer *sbf,
+ GError **error)
{
guchar *p;
gint nread;
@@ -544,7 +556,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));
+ (p - sbf->priv->linebuf), 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 2ccbe08..ee15f6e 100644
--- a/camel/camel-stream-buffer.h
+++ b/camel/camel-stream-buffer.h
@@ -96,8 +96,10 @@ CamelStream * camel_stream_buffer_new_with_vbuf
/* read a line of characters */
gint camel_stream_buffer_gets (CamelStreamBuffer *sbf,
gchar *buf,
- guint max);
-gchar * camel_stream_buffer_read_line (CamelStreamBuffer *sbf);
+ guint max,
+ GError **error);
+gchar * camel_stream_buffer_read_line (CamelStreamBuffer *sbf,
+ GError **error);
G_END_DECLS
diff --git a/camel/camel-stream-filter.c b/camel/camel-stream-filter.c
index 71f4d93..d5b6cec 100644
--- a/camel/camel-stream-filter.c
+++ b/camel/camel-stream-filter.c
@@ -90,7 +90,8 @@ stream_filter_finalize (GObject *object)
static gssize
stream_filter_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamFilterPrivate *priv;
gssize size;
@@ -105,7 +106,8 @@ stream_filter_read (CamelStream *stream,
if (priv->filteredlen<=0) {
gsize presize = READ_PAD;
- size = camel_stream_read(priv->source, priv->buffer, READ_SIZE);
+ size = camel_stream_read (
+ priv->source, priv->buffer, READ_SIZE, error);
if (size <= 0) {
/* this is somewhat untested */
if (camel_stream_eos(priv->source)) {
@@ -162,7 +164,8 @@ stream_filter_read (CamelStream *stream,
static gssize
stream_filter_write (CamelStream *stream,
const gchar *buf,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamFilterPrivate *priv;
struct _filter *f;
@@ -201,7 +204,7 @@ stream_filter_write (CamelStream *stream,
f = f->next;
}
- if (camel_stream_write(priv->source, buffer, len) != len)
+ if (camel_stream_write (priv->source, buffer, len, error) != len)
return -1;
}
@@ -211,7 +214,8 @@ stream_filter_write (CamelStream *stream,
}
static gint
-stream_filter_flush (CamelStream *stream)
+stream_filter_flush (CamelStream *stream,
+ GError **error)
{
CamelStreamFilterPrivate *priv;
struct _filter *f;
@@ -242,22 +246,25 @@ stream_filter_flush (CamelStream *stream)
f = f->next;
}
- if (len > 0 && camel_stream_write(priv->source, buffer, len) == -1)
+
+ if (len > 0 && camel_stream_write (priv->source, buffer, len, error) == -1)
return -1;
- return camel_stream_flush(priv->source);
+
+ return camel_stream_flush (priv->source, error);
}
static gint
-stream_filter_close (CamelStream *stream)
+stream_filter_close (CamelStream *stream,
+ GError **error)
{
CamelStreamFilterPrivate *priv;
priv = CAMEL_STREAM_FILTER_GET_PRIVATE (stream);
if (!priv->last_was_read)
- stream_filter_flush(stream);
+ stream_filter_flush (stream, NULL);
- return camel_stream_close(priv->source);
+ return camel_stream_close (priv->source, error);
}
static gboolean
@@ -277,7 +284,8 @@ stream_filter_eos (CamelStream *stream)
}
static gint
-stream_filter_reset (CamelStream *stream)
+stream_filter_reset (CamelStream *stream,
+ GError **error)
{
CamelStreamFilterPrivate *priv;
struct _filter *f;
@@ -290,11 +298,11 @@ stream_filter_reset (CamelStream *stream)
/* and reset filters */
f = priv->filters;
while (f) {
- camel_mime_filter_reset(f->filter);
+ camel_mime_filter_reset (f->filter);
f = f->next;
}
- return camel_stream_reset(priv->source);
+ return camel_stream_reset (priv->source, error);
}
static void
diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c
index ebc3bfc..efb5cd1 100644
--- a/camel/camel-stream-fs.c
+++ b/camel/camel-stream-fs.c
@@ -32,6 +32,7 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include <gio/gio.h>
#include <glib/gstdio.h>
#include "camel-file-utils.h"
@@ -66,7 +67,8 @@ stream_fs_finalize (GObject *object)
static gssize
stream_fs_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamFsPrivate *priv;
CamelSeekableStream *seekable;
@@ -78,7 +80,7 @@ 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)) > 0)
+ if ((nread = camel_read (priv->fd, buffer, n, error)) > 0)
seekable->position += nread;
else if (nread == 0)
stream->eos = TRUE;
@@ -89,7 +91,8 @@ stream_fs_read (CamelStream *stream,
static gssize
stream_fs_write (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamFsPrivate *priv;
CamelSeekableStream *seekable;
@@ -101,31 +104,47 @@ 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)) > 0)
+ if ((nwritten = camel_write (priv->fd, buffer, n, error)) > 0)
seekable->position += nwritten;
return nwritten;
}
static gint
-stream_fs_flush (CamelStream *stream)
+stream_fs_flush (CamelStream *stream,
+ GError **error)
{
CamelStreamFsPrivate *priv;
+ gint retval;
priv = CAMEL_STREAM_FS_GET_PRIVATE (stream);
- return fsync (priv->fd);
+ retval = fsync (priv->fd);
+
+ if (retval == -1)
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
+
+ return retval;
}
static gint
-stream_fs_close (CamelStream *stream)
+stream_fs_close (CamelStream *stream,
+ GError **error)
{
CamelStreamFsPrivate *priv;
priv = CAMEL_STREAM_FS_GET_PRIVATE (stream);
- if (close (priv->fd) == -1)
+ if (close (priv->fd) == -1) {
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
return -1;
+ }
priv->fd = -1;
@@ -135,7 +154,8 @@ stream_fs_close (CamelStream *stream)
static off_t
stream_fs_seek (CamelSeekableStream *stream,
off_t offset,
- CamelStreamSeekPolicy policy)
+ CamelStreamSeekPolicy policy,
+ GError **error)
{
CamelStreamFsPrivate *priv;
off_t real = 0;
@@ -156,7 +176,11 @@ stream_fs_seek (CamelSeekableStream *stream,
if (real<stream->bound_start)
real = stream->bound_start;
stream->position = real;
- }
+ } else
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
return real;
}
real = stream->bound_end + offset;
@@ -168,8 +192,13 @@ stream_fs_seek (CamelSeekableStream *stream,
real = MAX (real, stream->bound_start);
real = lseek(priv->fd, real, SEEK_SET);
- if (real == -1)
+ if (real == -1) {
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
return -1;
+ }
if (real != stream->position && ((CamelStream *)stream)->eos)
((CamelStream *)stream)->eos = FALSE;
@@ -279,7 +308,7 @@ camel_stream_fs_new_with_fd_and_bounds (gint fd, off_t start, off_t end)
stream = camel_stream_fs_new_with_fd (fd);
camel_seekable_stream_set_bounds (
- CAMEL_SEEKABLE_STREAM (stream), start, end);
+ CAMEL_SEEKABLE_STREAM (stream), start, end, NULL);
return stream;
}
@@ -289,6 +318,7 @@ camel_stream_fs_new_with_fd_and_bounds (gint fd, off_t start, off_t end)
* @name: a local filename
* @flags: flags as in open(2)
* @mode: a file mode
+ * @error: return location for a #GError, or %NULL
*
* Creates a new #CamelStreamFs corresponding to the named file, flags,
* and mode.
@@ -296,12 +326,19 @@ camel_stream_fs_new_with_fd_and_bounds (gint fd, off_t start, off_t end)
* Returns: the new stream, or %NULL on error.
**/
CamelStream *
-camel_stream_fs_new_with_name (const gchar *name, gint flags, mode_t mode)
+camel_stream_fs_new_with_name (const gchar *name,
+ gint flags,
+ mode_t mode,
+ GError **error)
{
gint fd;
fd = g_open (name, flags|O_BINARY, mode);
if (fd == -1) {
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
return NULL;
}
@@ -315,23 +352,29 @@ camel_stream_fs_new_with_name (const gchar *name, gint flags, mode_t mode)
* @mode: a file mode
* @start: the first valid position in the file
* @end: the first invalid position in the file, or #CAMEL_STREAM_UNBOUND
+ * @error: return location for a #GError, or %NULL
*
* Creates a new CamelStream corresponding to the given arguments.
*
* Returns: the stream, or %NULL on error.
**/
CamelStream *
-camel_stream_fs_new_with_name_and_bounds (const gchar *name, gint flags,
- mode_t mode, off_t start, off_t end)
+camel_stream_fs_new_with_name_and_bounds (const gchar *name,
+ gint flags,
+ mode_t mode,
+ off_t start,
+ off_t end,
+ GError **error)
{
CamelStream *stream;
- stream = camel_stream_fs_new_with_name (name, flags, mode);
+ stream = camel_stream_fs_new_with_name (name, flags, mode, error);
if (stream == NULL)
return NULL;
- camel_seekable_stream_set_bounds (CAMEL_SEEKABLE_STREAM (stream),
- start, end);
+ camel_seekable_stream_set_bounds (
+ CAMEL_SEEKABLE_STREAM (stream),
+ start, end, error);
return stream;
}
diff --git a/camel/camel-stream-fs.h b/camel/camel-stream-fs.h
index 4223318..78b8546 100644
--- a/camel/camel-stream-fs.h
+++ b/camel/camel-stream-fs.h
@@ -72,13 +72,15 @@ struct _CamelStreamFsClass {
GType camel_stream_fs_get_type (void);
CamelStream * camel_stream_fs_new_with_name (const gchar *name,
gint flags,
- mode_t mode);
+ mode_t mode,
+ GError **error);
CamelStream * camel_stream_fs_new_with_name_and_bounds
(const gchar *name,
gint flags,
mode_t mode,
off_t start,
- off_t end);
+ off_t end,
+ GError **error);
CamelStream * camel_stream_fs_new_with_fd (gint fd);
CamelStream * camel_stream_fs_new_with_fd_and_bounds
(gint fd,
diff --git a/camel/camel-stream-mem.c b/camel/camel-stream-mem.c
index 8b770a4..c98ada5 100644
--- a/camel/camel-stream-mem.c
+++ b/camel/camel-stream-mem.c
@@ -88,7 +88,8 @@ stream_mem_finalize (GObject *object)
static gssize
stream_mem_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamMemPrivate *priv;
CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream);
@@ -112,7 +113,8 @@ stream_mem_read (CamelStream *stream,
static gssize
stream_mem_write (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamMemPrivate *priv;
CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream);
@@ -149,7 +151,8 @@ stream_mem_eos (CamelStream *stream)
static off_t
stream_mem_seek (CamelSeekableStream *stream,
off_t offset,
- CamelStreamSeekPolicy policy)
+ CamelStreamSeekPolicy policy,
+ GError **error)
{
CamelStreamMemPrivate *priv;
off_t position;
diff --git a/camel/camel-stream-null.c b/camel/camel-stream-null.c
index fd6d249..e495fea 100644
--- a/camel/camel-stream-null.c
+++ b/camel/camel-stream-null.c
@@ -33,7 +33,8 @@ static gpointer parent_class;
static gssize
stream_null_write (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CAMEL_STREAM_NULL (stream)->written += n;
@@ -47,7 +48,8 @@ stream_null_eos (CamelStream *stream)
}
static gint
-stream_null_reset (CamelStream *stream)
+stream_null_reset (CamelStream *stream,
+ GError **error)
{
CAMEL_STREAM_NULL (stream)->written = 0;
diff --git a/camel/camel-stream-process.c b/camel/camel-stream-process.c
index a469f02..9a54210 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));
+ camel_stream_close (CAMEL_STREAM (object), NULL);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -60,25 +60,28 @@ stream_process_finalize (GObject *object)
static gssize
stream_process_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamProcess *stream_process = CAMEL_STREAM_PROCESS (stream);
- return camel_read (stream_process->sockfd, buffer, n);
+ return camel_read (stream_process->sockfd, buffer, n, error);
}
static gssize
stream_process_write (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamProcess *stream_process = CAMEL_STREAM_PROCESS (stream);
- return camel_write (stream_process->sockfd, buffer, n);
+ return camel_write (stream_process->sockfd, buffer, n, error);
}
static gint
-stream_process_close (CamelStream *object)
+stream_process_close (CamelStream *object,
+ GError **error)
{
CamelStreamProcess *stream = CAMEL_STREAM_PROCESS (object);
@@ -127,7 +130,8 @@ stream_process_close (CamelStream *object)
}
static gint
-stream_process_flush (CamelStream *stream)
+stream_process_flush (CamelStream *stream,
+ GError **error)
{
return 0;
}
@@ -234,12 +238,14 @@ do_exec_command (gint fd, const gchar *command, gchar **env)
}
gint
-camel_stream_process_connect (CamelStreamProcess *stream, const gchar *command, const gchar **env)
+camel_stream_process_connect (CamelStreamProcess *stream,
+ const gchar *command,
+ const gchar **env)
{
gint sockfds[2];
if (stream->sockfd != -1 || stream->childpid)
- camel_stream_close (CAMEL_STREAM (stream));
+ camel_stream_close (CAMEL_STREAM (stream), 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 c526e27..adaa0e9 100644
--- a/camel/camel-stream-vfs.c
+++ b/camel/camel-stream-vfs.c
@@ -54,24 +54,21 @@ stream_vfs_dispose (GObject *object)
static gssize
stream_vfs_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
gssize nread;
- GError *error = NULL;
CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
g_return_val_if_fail (G_IS_INPUT_STREAM (stream_vfs->stream), 0);
- nread = g_input_stream_read (G_INPUT_STREAM (stream_vfs->stream), buffer, n, NULL, &error);
+ nread = g_input_stream_read (
+ G_INPUT_STREAM (stream_vfs->stream),
+ buffer, n, NULL, error);
- if (nread == 0 || error)
+ if (nread <= 0)
stream->eos = TRUE;
- if (error) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
return nread;
}
diff --git a/camel/camel-stream.c b/camel/camel-stream.c
index f05df4a..14b2a21 100644
--- a/camel/camel-stream.c
+++ b/camel/camel-stream.c
@@ -35,7 +35,8 @@ static gpointer parent_class;
static gssize
stream_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
return 0;
}
@@ -43,19 +44,22 @@ stream_read (CamelStream *stream,
static gssize
stream_write (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
return n;
}
static gint
-stream_close (CamelStream *stream)
+stream_close (CamelStream *stream,
+ GError **error)
{
return 0;
}
static gint
-stream_flush (CamelStream *stream)
+stream_flush (CamelStream *stream,
+ GError **error)
{
return 0;
}
@@ -67,7 +71,8 @@ stream_eos (CamelStream *stream)
}
static gint
-stream_reset (CamelStream *stream)
+stream_reset (CamelStream *stream,
+ GError **error)
{
return 0;
}
@@ -108,16 +113,17 @@ camel_stream_get_type (void)
* @stream: a #CamelStream object.
* @buffer: output buffer
* @n: max number of bytes to read.
+ * @error: return location for a #GError, or %NULL
*
* Attempts to read up to @len bytes from @stream into @buf.
*
- * Returns: the number of bytes actually read, or %-1 on error and set
- * errno.
+ * Returns: the number of bytes actually read, or %-1 on error
**/
gssize
camel_stream_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamClass *class;
@@ -127,7 +133,7 @@ camel_stream_read (CamelStream *stream,
class = CAMEL_STREAM_GET_CLASS (stream);
g_return_val_if_fail (class->read != NULL, -1);
- return class->read (stream, buffer, n);
+ return class->read (stream, buffer, n, error);
}
/**
@@ -135,6 +141,7 @@ camel_stream_read (CamelStream *stream,
* @stream: a #CamelStream object
* @buffer: buffer to write.
* @n: number of bytes to write
+ * @error: return location for a #GError, or %NULL
*
* Attempts to write up to @n bytes of @buffer into @stream.
*
@@ -144,7 +151,8 @@ camel_stream_read (CamelStream *stream,
gssize
camel_stream_write (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelStreamClass *class;
@@ -154,12 +162,13 @@ camel_stream_write (CamelStream *stream,
class = CAMEL_STREAM_GET_CLASS (stream);
g_return_val_if_fail (class->write != NULL, -1);
- return class->write (stream, buffer, n);
+ return class->write (stream, buffer, n, error);
}
/**
* camel_stream_flush:
* @stream: a #CamelStream object
+ * @error: return location for a #GError, or %NULL
*
* Flushes any buffered data to the stream's backing store. Only
* meaningful for writable streams.
@@ -167,7 +176,8 @@ camel_stream_write (CamelStream *stream,
* Returns: %0 on success or %-1 on fail along with setting errno.
**/
gint
-camel_stream_flush (CamelStream *stream)
+camel_stream_flush (CamelStream *stream,
+ GError **error)
{
CamelStreamClass *class;
@@ -176,19 +186,21 @@ camel_stream_flush (CamelStream *stream)
class = CAMEL_STREAM_GET_CLASS (stream);
g_return_val_if_fail (class->flush != NULL, -1);
- return class->flush (stream);
+ return class->flush (stream, error);
}
/**
* camel_stream_close:
* @stream: a #CamelStream object
+ * @error: return location for a #GError, or %NULL
*
* Closes the stream.
*
* Returns: %0 on success or %-1 on error.
**/
gint
-camel_stream_close (CamelStream *stream)
+camel_stream_close (CamelStream *stream,
+ GError **error)
{
CamelStreamClass *class;
@@ -197,7 +209,7 @@ camel_stream_close (CamelStream *stream)
class = CAMEL_STREAM_GET_CLASS (stream);
g_return_val_if_fail (class->close != NULL, -1);
- return class->close (stream);
+ return class->close (stream, error);
}
/**
@@ -224,15 +236,17 @@ camel_stream_eos (CamelStream *stream)
/**
* camel_stream_reset:
* @stream: a #CamelStream object
+ * @error: return location for a #GError, or %NULL
*
* Resets the stream. That is, put it in a state where it can be read
* from the beginning again. Not all streams in Camel are seekable,
* but they must all be resettable.
*
- * Returns: %0 on success or %-1 on error along with setting errno.
+ * Returns: %0 on success or %-1 on error
**/
gint
-camel_stream_reset (CamelStream *stream)
+camel_stream_reset (CamelStream *stream,
+ GError **error)
{
CamelStreamClass *class;
@@ -241,7 +255,7 @@ camel_stream_reset (CamelStream *stream)
class = CAMEL_STREAM_GET_CLASS (stream);
g_return_val_if_fail (class->reset != NULL, -1);
- return class->reset (stream);
+ return class->reset (stream, error);
}
/***************** Utility functions ********************/
@@ -250,20 +264,24 @@ camel_stream_reset (CamelStream *stream)
* camel_stream_write_string:
* @stream: a #CamelStream object
* @string: a string
+ * @error: return location for a #GError, or %NULL
*
* Writes the string to the stream.
*
* Returns: the number of characters written or %-1 on error.
**/
gssize
-camel_stream_write_string (CamelStream *stream, const gchar *string)
+camel_stream_write_string (CamelStream *stream,
+ const gchar *string,
+ GError **error)
{
- return camel_stream_write (stream, string, strlen (string));
+ return camel_stream_write (stream, string, strlen (string), error);
}
/**
* camel_stream_printf:
* @stream: a #CamelStream object
+ * @error: return location for a #GError, or %NULL
* @fmt: a printf-style format string
*
* Write formatted output to a stream.
@@ -271,7 +289,9 @@ camel_stream_write_string (CamelStream *stream, const gchar *string)
* Returns: the number of characters written or %-1 on error.
**/
gssize
-camel_stream_printf (CamelStream *stream, const gchar *fmt, ... )
+camel_stream_printf (CamelStream *stream,
+ GError **error,
+ const gchar *fmt, ... )
{
va_list args;
gchar *string;
@@ -283,11 +303,9 @@ camel_stream_printf (CamelStream *stream, const gchar *fmt, ... )
string = g_strdup_vprintf (fmt, args);
va_end (args);
- if (!string)
- return -1;
-
- ret = camel_stream_write (stream, string, strlen (string));
+ ret = camel_stream_write (stream, string, strlen (string), error);
g_free (string);
+
return ret;
}
@@ -295,6 +313,7 @@ camel_stream_printf (CamelStream *stream, const gchar *fmt, ... )
* camel_stream_write_to_stream:
* @stream: source #CamelStream object
* @output_stream: destination #CamelStream object
+ * @error: return location for a #GError, or %NULL
*
* Write all of a stream (until eos) into another stream, in a
* blocking fashion.
@@ -303,7 +322,9 @@ camel_stream_printf (CamelStream *stream, const gchar *fmt, ... )
* copied across streams.
**/
gssize
-camel_stream_write_to_stream (CamelStream *stream, CamelStream *output_stream)
+camel_stream_write_to_stream (CamelStream *stream,
+ CamelStream *output_stream,
+ GError **error)
{
gchar tmp_buf[4096];
gssize total = 0;
@@ -314,15 +335,17 @@ camel_stream_write_to_stream (CamelStream *stream, CamelStream *output_stream)
g_return_val_if_fail (CAMEL_IS_STREAM (output_stream), -1);
while (!camel_stream_eos (stream)) {
- nb_read = camel_stream_read (stream, tmp_buf, sizeof (tmp_buf));
+ nb_read = camel_stream_read (
+ stream, tmp_buf, sizeof (tmp_buf), error);
if (nb_read < 0)
return -1;
else if (nb_read > 0) {
nb_written = 0;
while (nb_written < nb_read) {
- gssize len = camel_stream_write (output_stream, tmp_buf + nb_written,
- nb_read - nb_written);
+ gssize len = camel_stream_write (
+ output_stream, tmp_buf + nb_written,
+ nb_read - nb_written, error);
if (len < 0)
return -1;
nb_written += len;
diff --git a/camel/camel-stream.h b/camel/camel-stream.h
index 51d450c..03ddf0f 100644
--- a/camel/camel-stream.h
+++ b/camel/camel-stream.h
@@ -66,35 +66,54 @@ struct _CamelStream {
struct _CamelStreamClass {
CamelObjectClass parent_class;
- /* Virtual methods */
-
- gssize (*read) (CamelStream *stream, gchar *buffer, gsize n);
- gssize (*write) (CamelStream *stream, const gchar *buffer, gsize n);
- gint (*close) (CamelStream *stream);
- gint (*flush) (CamelStream *stream);
- gboolean (*eos) (CamelStream *stream);
- gint (*reset) (CamelStream *stream);
+ gssize (*read) (CamelStream *stream,
+ gchar *buffer,
+ gsize n,
+ GError **error);
+ gssize (*write) (CamelStream *stream,
+ const gchar *buffer,
+ gsize n,
+ GError **error);
+ gint (*close) (CamelStream *stream,
+ GError **error);
+ gint (*flush) (CamelStream *stream,
+ GError **error);
+ gboolean (*eos) (CamelStream *stream);
+ gint (*reset) (CamelStream *stream,
+ GError **error);
};
-GType camel_stream_get_type (void);
-
-/* public methods */
-gssize camel_stream_read (CamelStream *stream, gchar *buffer, gsize n);
-gssize camel_stream_write (CamelStream *stream, const gchar *buffer, gsize n);
-gint camel_stream_flush (CamelStream *stream);
-gint camel_stream_close (CamelStream *stream);
-gboolean camel_stream_eos (CamelStream *stream);
-gint camel_stream_reset (CamelStream *stream);
+GType camel_stream_get_type (void);
+gssize camel_stream_read (CamelStream *stream,
+ gchar *buffer,
+ gsize n,
+ GError **error);
+gssize camel_stream_write (CamelStream *stream,
+ const gchar *buffer,
+ gsize n,
+ GError **error);
+gint camel_stream_flush (CamelStream *stream,
+ GError **error);
+gint camel_stream_close (CamelStream *stream,
+ GError **error);
+gboolean camel_stream_eos (CamelStream *stream);
+gint camel_stream_reset (CamelStream *stream,
+ GError **error);
/* utility macros and funcs */
-gssize camel_stream_write_string (CamelStream *stream, const gchar *string);
-gssize camel_stream_printf (CamelStream *stream, const gchar *fmt, ... ) G_GNUC_PRINTF (2, 3);
-gssize camel_stream_vprintf (CamelStream *stream, const gchar *fmt, va_list ap);
+gssize camel_stream_write_string (CamelStream *stream,
+ const gchar *string,
+ GError **error);
+gssize camel_stream_printf (CamelStream *stream,
+ GError **error,
+ const gchar *fmt,
+ ...) G_GNUC_PRINTF (3, 4);
/* Write a whole stream to another stream, until eof or error on
- * either stream.
- */
-gssize camel_stream_write_to_stream (CamelStream *stream, CamelStream *output_stream);
+ * either stream. */
+gssize camel_stream_write_to_stream (CamelStream *stream,
+ CamelStream *output_stream,
+ GError **error);
G_END_DECLS
diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c
index e0f649e..29e4472 100644
--- a/camel/camel-tcp-stream-raw.c
+++ b/camel/camel-tcp-stream-raw.c
@@ -32,6 +32,8 @@
#include <sys/time.h>
#include <sys/types.h>
+#include <gio/gio.h>
+
#include "camel-file-utils.h"
#include "camel-operation.h"
#include "camel-tcp-stream-raw.h"
@@ -334,34 +336,43 @@ tcp_stream_raw_finalize (GObject *object)
static gssize
tcp_stream_raw_read (CamelStream *stream,
gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
- return camel_read_socket (raw->sockfd, buffer, n);
+ return camel_read_socket (raw->sockfd, buffer, n, error);
}
static gssize
tcp_stream_raw_write (CamelStream *stream,
const gchar *buffer,
- gsize n)
+ gsize n,
+ GError **error)
{
CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
- return camel_write_socket (raw->sockfd, buffer, n);
+ return camel_write_socket (raw->sockfd, buffer, n, error);
}
static gint
-tcp_stream_raw_flush (CamelStream *stream)
+tcp_stream_raw_flush (CamelStream *stream,
+ GError **error)
{
return 0;
}
static gint
-tcp_stream_raw_close (CamelStream *stream)
+tcp_stream_raw_close (CamelStream *stream,
+ GError **error)
{
- if (SOCKET_CLOSE (((CamelTcpStreamRaw *)stream)->sockfd) == -1)
+ if (SOCKET_CLOSE (((CamelTcpStreamRaw *)stream)->sockfd) == -1) {
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
return -1;
+ }
((CamelTcpStreamRaw *)stream)->sockfd = -1;
return 0;
@@ -369,7 +380,8 @@ tcp_stream_raw_close (CamelStream *stream)
static gint
tcp_stream_raw_connect (CamelTcpStream *stream,
- struct addrinfo *host)
+ struct addrinfo *host,
+ GError **error)
{
CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index 8155cbe..204f127 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -49,6 +49,7 @@
#include <certdb.h>
#include <pk11func.h>
+#include <gio/gio.h>
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
@@ -69,14 +70,14 @@
static gpointer parent_class;
-static gssize stream_read (CamelStream *stream, gchar *buffer, gsize n);
-static gssize stream_write (CamelStream *stream, const gchar *buffer, gsize n);
-static gint stream_flush (CamelStream *stream);
-static gint stream_close (CamelStream *stream);
+static gssize stream_read (CamelStream *stream, gchar *buffer, gsize n, GError **error);
+static gssize stream_write (CamelStream *stream, const gchar *buffer, gsize n, GError **error);
+static gint stream_flush (CamelStream *stream, GError **error);
+static gint stream_close (CamelStream *stream, GError **error);
static PRFileDesc *enable_ssl (CamelTcpStreamSSL *ssl, PRFileDesc *fd);
-static gint stream_connect (CamelTcpStream *stream, struct addrinfo *host);
+static gint stream_connect (CamelTcpStream *stream, struct addrinfo *host, GError **error);
static gint stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
static gint stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
static struct sockaddr *stream_get_local_address (CamelTcpStream *stream, socklen_t *len);
@@ -343,13 +344,17 @@ camel_tcp_stream_ssl_enable_ssl (CamelTcpStreamSSL *ssl)
}
static gssize
-stream_read (CamelStream *stream, gchar *buffer, gsize n)
+stream_read (CamelStream *stream, gchar *buffer, gsize n, GError **error)
{
CamelTcpStreamSSL *tcp_stream_ssl = CAMEL_TCP_STREAM_SSL (stream);
PRFileDesc *cancel_fd;
gssize nread;
if (camel_operation_cancel_check (NULL)) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ _("Cancelled read"));
errno = EINTR;
return -1;
}
@@ -426,13 +431,20 @@ stream_read (CamelStream *stream, gchar *buffer, gsize n)
}
static gssize
-stream_write (CamelStream *stream, const gchar *buffer, gsize n)
+stream_write (CamelStream *stream,
+ const gchar *buffer,
+ gsize n,
+ GError **error)
{
CamelTcpStreamSSL *tcp_stream_ssl = CAMEL_TCP_STREAM_SSL (stream);
gssize w, written = 0;
PRFileDesc *cancel_fd;
if (camel_operation_cancel_check (NULL)) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ _("Cancelled write"));
errno = EINTR;
return -1;
}
@@ -514,23 +526,34 @@ stream_write (CamelStream *stream, const gchar *buffer, gsize n)
errno = error;
}
- if (w == -1)
+ if (errno != 0) {
+ g_set_error (
+ error, G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
return -1;
+ }
return written;
}
static gint
-stream_flush (CamelStream *stream)
+stream_flush (CamelStream *stream,
+ GError **error)
{
/*return PR_Sync (((CamelTcpStreamSSL *)stream)->priv->sockfd);*/
return 0;
}
static gint
-stream_close (CamelStream *stream)
+stream_close (CamelStream *stream,
+ GError **error)
{
if (((CamelTcpStreamSSL *)stream)->priv->sockfd == NULL) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Cannot close SSL stream"));
errno = EINVAL;
return -1;
}
@@ -811,13 +834,16 @@ camel_certdb_nss_cert_set(CamelCertDB *certdb, CamelCert *ccert, CERTCertificate
path = g_strdup_printf ("%s/%s", dir, fingerprint);
g_free (dir);
- stream = camel_stream_fs_new_with_name (path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ stream = camel_stream_fs_new_with_name (
+ path, O_WRONLY | O_CREAT | O_TRUNC, 0600, NULL);
if (stream != NULL) {
- if (camel_stream_write (stream, (const gchar *) ccert->rawcert->data, ccert->rawcert->len) == -1) {
+ if (camel_stream_write (
+ stream, (const gchar *) ccert->rawcert->data,
+ ccert->rawcert->len, NULL) == -1) {
g_warning ("Could not save cert: %s: %s", path, g_strerror (errno));
g_unlink (path);
}
- camel_stream_close (stream);
+ camel_stream_close (stream, NULL);
g_object_unref (stream);
} else {
g_warning ("Could not save cert: %s: %s", path, g_strerror (errno));
@@ -1230,7 +1256,9 @@ socket_connect(CamelTcpStream *stream, struct addrinfo *host)
}
static gint
-stream_connect(CamelTcpStream *stream, struct addrinfo *host)
+stream_connect (CamelTcpStream *stream,
+ struct addrinfo *host,
+ GError **error)
{
while (host) {
if (socket_connect(stream, host) == 0)
diff --git a/camel/camel-tcp-stream.c b/camel/camel-tcp-stream.c
index a6c726d..2943f69 100644
--- a/camel/camel-tcp-stream.c
+++ b/camel/camel-tcp-stream.c
@@ -61,6 +61,7 @@ camel_tcp_stream_get_type (void)
* @stream: a #CamelTcpStream object
* @host: a linked list of addrinfo structures to try to connect, in
* the order of most likely to least likely to work.
+ * @error: return location for a #GError, or %NULL
*
* Create a socket and connect based upon the data provided.
*
@@ -68,7 +69,8 @@ camel_tcp_stream_get_type (void)
**/
gint
camel_tcp_stream_connect (CamelTcpStream *stream,
- struct addrinfo *host)
+ struct addrinfo *host,
+ GError **error)
{
CamelTcpStreamClass *class;
@@ -77,7 +79,7 @@ camel_tcp_stream_connect (CamelTcpStream *stream,
class = CAMEL_TCP_STREAM_GET_CLASS (stream);
g_return_val_if_fail (class->connect != NULL, -1);
- return class->connect (stream, host);
+ return class->connect (stream, host, error);
}
/**
diff --git a/camel/camel-tcp-stream.h b/camel/camel-tcp-stream.h
index 778c61d..f4ffddc 100644
--- a/camel/camel-tcp-stream.h
+++ b/camel/camel-tcp-stream.h
@@ -116,24 +116,38 @@ struct _CamelTcpStream {
struct _CamelTcpStreamClass {
CamelStreamClass parent_class;
- /* Virtual methods */
- gint (*connect) (CamelTcpStream *stream, struct addrinfo *host);
- gint (*getsockopt) (CamelTcpStream *stream, CamelSockOptData *data);
- gint (*setsockopt) (CamelTcpStream *stream, const CamelSockOptData *data);
-
- struct sockaddr * (*get_local_address) (CamelTcpStream *stream, socklen_t *len);
- struct sockaddr * (*get_remote_address) (CamelTcpStream *stream, socklen_t *len);
+ gint (*connect) (CamelTcpStream *stream,
+ struct addrinfo *host,
+ GError **error);
+ gint (*getsockopt) (CamelTcpStream *stream,
+ CamelSockOptData *data);
+ gint (*setsockopt) (CamelTcpStream *stream,
+ const CamelSockOptData *data);
+
+ struct sockaddr *
+ (*get_local_address) (CamelTcpStream *stream,
+ socklen_t *len);
+ struct sockaddr *
+ (*get_remote_address) (CamelTcpStream *stream,
+ socklen_t *len);
};
-GType camel_tcp_stream_get_type (void);
-
-/* public methods */
-gint camel_tcp_stream_connect (CamelTcpStream *stream, struct addrinfo *host);
-gint camel_tcp_stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
-gint camel_tcp_stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
-
-struct sockaddr *camel_tcp_stream_get_local_address (CamelTcpStream *stream, socklen_t *len);
-struct sockaddr *camel_tcp_stream_get_remote_address (CamelTcpStream *stream, socklen_t *len);
+GType camel_tcp_stream_get_type (void);
+gint camel_tcp_stream_connect (CamelTcpStream *stream,
+ struct addrinfo *host,
+ GError **error);
+gint camel_tcp_stream_getsockopt (CamelTcpStream *stream,
+ CamelSockOptData *data);
+gint camel_tcp_stream_setsockopt (CamelTcpStream *stream,
+ const CamelSockOptData *data);
+struct sockaddr *
+ camel_tcp_stream_get_local_address
+ (CamelTcpStream *stream,
+ socklen_t *len);
+struct sockaddr *
+ camel_tcp_stream_get_remote_address
+ (CamelTcpStream *stream,
+ socklen_t *len);
G_END_DECLS
diff --git a/camel/camel-text-index.c b/camel/camel-text-index.c
index 8b3ae22..0bb6210 100644
--- a/camel/camel-text-index.c
+++ b/camel/camel-text-index.c
@@ -34,6 +34,7 @@
#include <sys/types.h>
#include <glib/gstdio.h>
+#include <glib/gi18n-lib.h>
#include <libedataserver/e-memory.h>
@@ -58,7 +59,7 @@
#define CAMEL_TEXT_INDEX_UNLOCK(kf, lock) \
(g_static_rec_mutex_unlock (&((CamelTextIndex *)kf)->priv->lock))
-static gint text_index_compress_nosync (CamelIndex *idx);
+static gint text_index_compress_nosync (CamelIndex *idx, GError **error);
/* ********************************************************************** */
@@ -181,7 +182,7 @@ text_index_dispose (GObject *object)
/* Only run this the first time. */
if (priv->word_index != NULL)
- camel_index_sync (CAMEL_INDEX (object));
+ camel_index_sync (CAMEL_INDEX (object), NULL);
if (priv->word_index != NULL) {
g_object_unref (priv->word_index);
@@ -236,8 +237,11 @@ text_index_finalize (GObject *object)
}
/* call locked */
-static void
-text_index_add_name_to_word (CamelIndex *idx, const gchar *word, camel_key_t nameid)
+static gboolean
+text_index_add_name_to_word (CamelIndex *idx,
+ const gchar *word,
+ camel_key_t nameid,
+ GError **error)
{
struct _CamelTextIndexWord *w, *wp, *ww;
CamelTextIndexPrivate *p = CAMEL_TEXT_INDEX_GET_PRIVATE (idx);
@@ -247,28 +251,34 @@ text_index_add_name_to_word (CamelIndex *idx, const gchar *word, camel_key_t nam
w = g_hash_table_lookup (p->words, word);
if (w == NULL) {
- wordid = camel_partition_table_lookup (p->word_hash, word);
+ wordid = camel_partition_table_lookup (p->word_hash, word, NULL);
if (wordid == 0) {
data = 0;
- wordid = camel_key_table_add (p->word_index, word, 0, 0);
+ wordid = camel_key_table_add (
+ p->word_index, word, 0, 0, error);
if (wordid == 0) {
- g_warning ("Could not create key entry for word '%s': %s\n",
- word, g_strerror (errno));
- return;
+ g_prefix_error (
+ error, _("Could not create key "
+ "entry for word '%s': "), word);
+ return FALSE;
}
- if (camel_partition_table_add (p->word_hash, word, wordid) == -1) {
- g_warning ("Could not create hash entry for word '%s': %s\n",
- word, g_strerror (errno));
- return;
+ if (camel_partition_table_add (
+ p->word_hash, word, wordid, error) == -1) {
+ g_prefix_error (
+ error, _("Could not create hash "
+ "entry for word '%s': "), word);
+ return FALSE;
}
rb->words++;
camel_block_file_touch_block (p->blocks, p->blocks->root_block);
} else {
- data = camel_key_table_lookup (p->word_index, wordid, NULL, NULL);
+ data = camel_key_table_lookup (
+ p->word_index, wordid, NULL, NULL, error);
if (data == 0) {
- g_warning ("Could not find key entry for word '%s': %s\n",
- word, g_strerror (errno));
- return;
+ g_prefix_error (
+ error, _("Could not find key "
+ "entry for word '%s': "), word);
+ return FALSE;
}
}
@@ -291,7 +301,9 @@ text_index_add_name_to_word (CamelIndex *idx, const gchar *word, camel_key_t nam
rb->keys++;
camel_block_file_touch_block (p->blocks, p->blocks->root_block);
/* if this call fails - we still point to the old data - not fatal */
- camel_key_table_set_data (p->word_index, ww->wordid, ww->data);
+ camel_key_table_set_data (
+ p->word_index, ww->wordid,
+ ww->data, NULL);
camel_dlist_remove ((CamelDListNode *)ww);
g_hash_table_remove (p->words, ww->word);
g_free (ww->word);
@@ -312,16 +324,21 @@ text_index_add_name_to_word (CamelIndex *idx, const gchar *word, camel_key_t nam
rb->keys++;
camel_block_file_touch_block (p->blocks, p->blocks->root_block);
/* if this call fails - we still point to the old data - not fatal */
- camel_key_table_set_data (p->word_index, w->wordid, w->data);
+ camel_key_table_set_data (
+ p->word_index, w->wordid,
+ w->data, NULL);
}
/* FIXME: what to on error? lost data? */
w->used = 0;
}
}
+
+ return TRUE;
}
static gint
-text_index_sync (CamelIndex *idx)
+text_index_sync (CamelIndex *idx,
+ GError **error)
{
CamelTextIndexPrivate *p = CAMEL_TEXT_INDEX_GET_PRIVATE (idx);
struct _CamelTextIndexWord *ww;
@@ -355,7 +372,9 @@ text_index_sync (CamelIndex *idx)
io (printf (" new data [%x]\n", ww->data));
rb->keys++;
camel_block_file_touch_block (p->blocks, p->blocks->root_block);
- camel_key_table_set_data (p->word_index, ww->wordid, ww->data);
+ camel_key_table_set_data (
+ p->word_index, ww->wordid,
+ ww->data, NULL);
} else {
ret = -1;
}
@@ -380,10 +399,11 @@ text_index_sync (CamelIndex *idx)
if (ret == 0) {
if (wfrag > 30 || nfrag > 20)
- ret = text_index_compress_nosync (idx);
+ ret = text_index_compress_nosync (idx, error);
}
- ret = camel_block_file_sync (p->blocks);
+ if (ret == 0)
+ ret = camel_block_file_sync (p->blocks);
CAMEL_TEXT_INDEX_UNLOCK (idx, lock);
@@ -405,15 +425,16 @@ static void tmp_name (const gchar *in, gchar *o)
}
static gint
-text_index_compress (CamelIndex *idx)
+text_index_compress (CamelIndex *idx,
+ GError **error)
{
gint ret;
CAMEL_TEXT_INDEX_LOCK (idx, lock);
- ret = camel_index_sync (idx);
+ ret = camel_index_sync (idx, error);
if (ret != -1)
- ret = text_index_compress_nosync (idx);
+ ret = text_index_compress_nosync (idx, error);
CAMEL_TEXT_INDEX_UNLOCK (idx, lock);
@@ -422,7 +443,8 @@ text_index_compress (CamelIndex *idx)
/* Attempt to recover index space by compressing the indices */
static gint
-text_index_compress_nosync (CamelIndex *idx)
+text_index_compress_nosync (CamelIndex *idx,
+ GError **error)
{
CamelTextIndex *newidx;
CamelTextIndexPrivate *newp, *oldp;
@@ -454,7 +476,7 @@ text_index_compress_nosync (CamelIndex *idx)
d (printf ("New: %s\n", newpath));
d (printf ("Save: %s\n", savepath));
- newidx = camel_text_index_new (newpath, O_RDWR|O_CREAT);
+ newidx = camel_text_index_new (newpath, O_RDWR|O_CREAT, error);
if (newidx == NULL)
return -1;
@@ -483,14 +505,16 @@ text_index_compress_nosync (CamelIndex *idx)
remap = g_hash_table_new (NULL, NULL);
oldkeyid = 0;
deleted = 0;
- while ( (oldkeyid = camel_key_table_next (oldp->name_index, oldkeyid, &name, &flags, &data)) ) {
+ while ( (oldkeyid = camel_key_table_next (oldp->name_index, oldkeyid, &name, &flags, &data, NULL)) ) {
if ((flags&1) == 0) {
io (printf ("copying name '%s'\n", name));
- newkeyid = camel_key_table_add (newp->name_index, name, data, flags);
+ newkeyid = camel_key_table_add (
+ newp->name_index, name, data, flags, error);
if (newkeyid == 0)
goto fail;
rb->names++;
- camel_partition_table_add (newp->name_hash, name, newkeyid);
+ camel_partition_table_add (
+ newp->name_hash, name, newkeyid, NULL);
g_hash_table_insert (remap, GINT_TO_POINTER (oldkeyid), GINT_TO_POINTER (newkeyid));
} else {
io (printf ("deleted name '%s'\n", name));
@@ -504,7 +528,7 @@ text_index_compress_nosync (CamelIndex *idx)
/* We re-block the data into 256 entry lots while we're at it, since we only
have to do 1 at a time and its cheap */
oldkeyid = 0;
- while ( (oldkeyid = camel_key_table_next (oldp->word_index, oldkeyid, &name, &flags, &data)) ) {
+ while ( (oldkeyid = camel_key_table_next (oldp->word_index, oldkeyid, &name, &flags, &data, NULL)) ) {
io (printf ("copying word '%s'\n", name));
newdata = 0;
newcount = 0;
@@ -539,10 +563,12 @@ text_index_compress_nosync (CamelIndex *idx)
}
if (newdata != 0) {
- newkeyid = camel_key_table_add (newp->word_index, name, newdata, flags);
+ newkeyid = camel_key_table_add (
+ newp->word_index, name, newdata, flags, error);
if (newkeyid == 0)
goto fail;
- camel_partition_table_add (newp->word_hash, name, newkeyid);
+ camel_partition_table_add (
+ newp->word_hash, name, newkeyid, NULL);
}
g_free (name);
name = NULL;
@@ -550,7 +576,7 @@ text_index_compress_nosync (CamelIndex *idx)
camel_block_file_touch_block (newp->blocks, newp->blocks->root_block);
- if (camel_index_sync ((CamelIndex *)newidx) == -1)
+ if (camel_index_sync (CAMEL_INDEX (newidx), error) == -1)
goto fail;
/* Rename underlying files to match */
@@ -648,7 +674,7 @@ text_index_has_name (CamelIndex *idx, const gchar *name)
{
CamelTextIndexPrivate *p = CAMEL_TEXT_INDEX_GET_PRIVATE (idx);
- return camel_partition_table_lookup (p->name_hash, name) != 0;
+ return camel_partition_table_lookup (p->name_hash, name, NULL) != 0;
}
static CamelIndexName *
@@ -668,18 +694,18 @@ text_index_add_name (CamelIndex *idx, const gchar *name)
}
/* If we have it already replace it */
- keyid = camel_partition_table_lookup (p->name_hash, name);
+ keyid = camel_partition_table_lookup (p->name_hash, name, NULL);
if (keyid != 0) {
/* TODO: We could just update the partition table's
key pointer rather than having to delete it */
rb->deleted++;
- camel_key_table_set_flags (p->name_index, keyid, 1, 1);
- camel_partition_table_remove (p->name_hash, name);
+ camel_key_table_set_flags (p->name_index, keyid, 1, 1, NULL);
+ camel_partition_table_remove (p->name_hash, name, NULL);
}
- keyid = camel_key_table_add (p->name_index, name, 0, 0);
+ keyid = camel_key_table_add (p->name_index, name, 0, 0, NULL);
if (keyid != 0) {
- camel_partition_table_add (p->name_hash, name, keyid);
+ camel_partition_table_add (p->name_hash, name, keyid, NULL);
rb->names++;
}
@@ -701,7 +727,7 @@ hash_write_word (gchar *word, gpointer data, CamelIndexName *idn)
{
CamelTextIndexName *tin = (CamelTextIndexName *)idn;
- text_index_add_name_to_word (idn->index, word, tin->priv->nameid);
+ text_index_add_name_to_word (idn->index, word, tin->priv->nameid, NULL);
}
static gint
@@ -742,12 +768,12 @@ text_index_delete_name (CamelIndex *idx, const gchar *name)
CAMEL_TEXT_INDEX_LOCK (idx, lock);
/* We just mark the key deleted, and remove it from the hash table */
- keyid = camel_partition_table_lookup (p->name_hash, name);
+ keyid = camel_partition_table_lookup (p->name_hash, name, NULL);
if (keyid != 0) {
rb->deleted++;
camel_block_file_touch_block (p->blocks, p->blocks->root_block);
- camel_key_table_set_flags (p->name_index, keyid, 1, 1);
- camel_partition_table_remove (p->name_hash, name);
+ camel_key_table_set_flags (p->name_index, keyid, 1, 1, NULL);
+ camel_partition_table_remove (p->name_hash, name, NULL);
}
CAMEL_TEXT_INDEX_UNLOCK (idx, lock);
@@ -764,9 +790,10 @@ text_index_find (CamelIndex *idx, const gchar *word)
CAMEL_TEXT_INDEX_LOCK (idx, lock);
- keyid = camel_partition_table_lookup (p->word_hash, word);
+ keyid = camel_partition_table_lookup (p->word_hash, word, NULL);
if (keyid != 0) {
- data = camel_key_table_lookup (p->word_index, keyid, NULL, &flags);
+ data = camel_key_table_lookup (
+ p->word_index, keyid, NULL, &flags, NULL);
if (flags & 1)
data = 0;
}
@@ -870,7 +897,9 @@ text_index_normalise (CamelIndex *idx, const gchar *in, gpointer data)
}
CamelTextIndex *
-camel_text_index_new (const gchar *path, gint flags)
+camel_text_index_new (const gchar *path,
+ gint flags,
+ GError **error)
{
CamelTextIndex *idx = g_object_new (CAMEL_TYPE_TEXT_INDEX, NULL);
CamelTextIndexPrivate *p = CAMEL_TEXT_INDEX_GET_PRIVATE (idx);
@@ -881,18 +910,23 @@ camel_text_index_new (const gchar *path, gint flags)
camel_index_construct ((CamelIndex *)idx, path, flags);
camel_index_set_normalise ((CamelIndex *)idx, text_index_normalise, NULL);
- p->blocks = camel_block_file_new (idx->parent.path, flags, CAMEL_TEXT_INDEX_VERSION, CAMEL_BLOCK_SIZE);
+ p->blocks = camel_block_file_new (
+ idx->parent.path, flags, CAMEL_TEXT_INDEX_VERSION,
+ CAMEL_BLOCK_SIZE, error);
+ if (p->blocks == NULL)
+ goto fail;
+
link = alloca (strlen (idx->parent.path)+7);
sprintf (link, "%s.data", idx->parent.path);
p->links = camel_key_file_new (link, flags, CAMEL_TEXT_INDEX_KEY_VERSION);
- if (p->blocks == NULL || p->links == NULL)
+ if (p->links == NULL)
goto fail;
rb = (struct _CamelTextIndexRoot *)p->blocks->root;
if (rb->word_index_root == 0) {
- bl = camel_block_file_new_block (p->blocks);
+ bl = camel_block_file_new_block (p->blocks, error);
if (bl == NULL)
goto fail;
@@ -903,7 +937,7 @@ camel_text_index_new (const gchar *path, gint flags)
}
if (rb->word_hash_root == 0) {
- bl = camel_block_file_new_block (p->blocks);
+ bl = camel_block_file_new_block (p->blocks, error);
if (bl == NULL)
goto fail;
@@ -914,7 +948,7 @@ camel_text_index_new (const gchar *path, gint flags)
}
if (rb->name_index_root == 0) {
- bl = camel_block_file_new_block (p->blocks);
+ bl = camel_block_file_new_block (p->blocks, error);
if (bl == NULL)
goto fail;
@@ -925,7 +959,7 @@ camel_text_index_new (const gchar *path, gint flags)
}
if (rb->name_hash_root == 0) {
- bl = camel_block_file_new_block (p->blocks);
+ bl = camel_block_file_new_block (p->blocks, error);
if (bl == NULL)
goto fail;
@@ -935,16 +969,25 @@ camel_text_index_new (const gchar *path, gint flags)
camel_block_file_touch_block (p->blocks, p->blocks->root_block);
}
- p->word_index = camel_key_table_new (p->blocks, rb->word_index_root);
- p->word_hash = camel_partition_table_new (p->blocks, rb->word_hash_root);
- p->name_index = camel_key_table_new (p->blocks, rb->name_index_root);
- p->name_hash = camel_partition_table_new (p->blocks, rb->name_hash_root);
+ p->word_index = camel_key_table_new (
+ p->blocks, rb->word_index_root, error);
+ if (p->word_index == NULL)
+ goto fail;
- if (p->word_index == NULL || p->word_hash == NULL
- || p->name_index == NULL || p->name_hash == NULL) {
- g_object_unref (idx);
- idx = NULL;
- }
+ p->word_hash = camel_partition_table_new (
+ p->blocks, rb->word_hash_root, error);
+ if (p->word_hash == NULL)
+ goto fail;
+
+ p->name_index = camel_key_table_new (
+ p->blocks, rb->name_index_root, error);
+ if (p->name_index == NULL)
+ goto fail;
+
+ p->name_hash = camel_partition_table_new (
+ p->blocks, rb->name_hash_root, NULL);
+ if (p->name_hash == NULL)
+ goto fail;
return idx;
@@ -955,7 +998,8 @@ fail:
/* returns 0 if the index exists, is valid, and synced, -1 otherwise */
gint
-camel_text_index_check (const gchar *path)
+camel_text_index_check (const gchar *path,
+ GError **error)
{
gchar *block, *key;
CamelBlockFile *blocks;
@@ -963,11 +1007,11 @@ camel_text_index_check (const gchar *path)
block = alloca (strlen (path)+7);
sprintf (block, "%s.index", path);
- blocks = camel_block_file_new (block, O_RDONLY, CAMEL_TEXT_INDEX_VERSION, CAMEL_BLOCK_SIZE);
- if (blocks == NULL) {
- io (printf ("Check failed: No block file: %s\n", g_strerror (errno)));
+ blocks = camel_block_file_new (
+ block, O_RDONLY, CAMEL_TEXT_INDEX_VERSION,
+ CAMEL_BLOCK_SIZE, error);
+ if (blocks == NULL)
return -1;
- }
key = alloca (strlen (path)+12);
sprintf (key, "%s.index.data", path);
keys = camel_key_file_new (key, O_RDONLY, CAMEL_TEXT_INDEX_KEY_VERSION);
@@ -1251,7 +1295,7 @@ camel_text_index_dump (CamelTextIndex *idx)
printf ("UID's in index\n");
keyid = 0;
- while ( (keyid = camel_key_table_next (p->name_index, keyid, &word, &flags, &data)) ) {
+ while ( (keyid = camel_key_table_next (p->name_index, keyid, &word, &flags, &data, NULL)) ) {
if ((flags & 1) == 0)
printf (" %s\n", word);
else
@@ -1262,7 +1306,7 @@ camel_text_index_dump (CamelTextIndex *idx)
printf ("Word's in index\n");
keyid = 0;
- while ( (keyid = camel_key_table_next (p->word_index, keyid, &word, &flags, &data)) ) {
+ while ( (keyid = camel_key_table_next (p->word_index, keyid, &word, &flags, &data, NULL)) ) {
CamelIndexCursor *idc;
printf ("Word: '%s':\n", word);
@@ -1324,7 +1368,7 @@ camel_text_index_validate (CamelTextIndex *idx)
printf ("Checking UID consistency\n");
keyid = 0;
- while ( (keyid = camel_key_table_next (p->name_index, keyid, &word, &flags, &data)) ) {
+ while ( (keyid = camel_key_table_next (p->name_index, keyid, &word, &flags, &data, NULL)) ) {
if ((oldword = g_hash_table_lookup (names, GINT_TO_POINTER (keyid))) != NULL
|| (oldword = g_hash_table_lookup (deleted, GINT_TO_POINTER (keyid))) != NULL) {
printf ("Warning, name '%s' duplicates key (%x) with name '%s'\n", word, keyid, oldword);
@@ -1342,7 +1386,7 @@ camel_text_index_validate (CamelTextIndex *idx)
printf ("Checking WORD member consistency\n");
keyid = 0;
- while ( (keyid = camel_key_table_next (p->word_index, keyid, &word, &flags, &data)) ) {
+ while ( (keyid = camel_key_table_next (p->word_index, keyid, &word, &flags, &data, NULL)) ) {
CamelIndexCursor *idc;
GHashTable *used;
@@ -1660,7 +1704,9 @@ text_index_cursor_next (CamelIndexCursor *idc)
}
g_free (p->current);
- camel_key_table_lookup (tip->name_index, p->records[p->record_index], &p->current, &flags);
+ camel_key_table_lookup (
+ tip->name_index, p->records[p->record_index],
+ &p->current, &flags, NULL);
if (flags & 1) {
g_free (p->current);
p->current = NULL;
@@ -1790,7 +1836,7 @@ text_index_key_cursor_next (CamelIndexCursor *idc)
g_free (p->current);
p->current = NULL;
- while ( (p->keyid = camel_key_table_next (p->table, p->keyid, &p->current, &p->flags, &p->data)) ) {
+ while ( (p->keyid = camel_key_table_next (p->table, p->keyid, &p->current, &p->flags, &p->data, NULL)) ) {
if ((p->flags & 1) == 0) {
return p->current;
} else {
diff --git a/camel/camel-text-index.h b/camel/camel-text-index.h
index 75da888..b8952e9 100644
--- a/camel/camel-text-index.h
+++ b/camel/camel-text-index.h
@@ -172,17 +172,21 @@ struct _CamelTextIndexClass {
CamelIndexClass parent_class;
};
-GType camel_text_index_get_type (void);
-CamelTextIndex *camel_text_index_new(const gchar *path, gint flags);
+GType camel_text_index_get_type (void);
+CamelTextIndex *camel_text_index_new (const gchar *path,
+ gint flags,
+ GError **error);
/* static utility functions */
-gint camel_text_index_check(const gchar *path);
-gint camel_text_index_rename(const gchar *old, const gchar *new);
-gint camel_text_index_remove(const gchar *old);
-
-void camel_text_index_dump(CamelTextIndex *idx);
-void camel_text_index_info(CamelTextIndex *idx);
-void camel_text_index_validate(CamelTextIndex *idx);
+gint camel_text_index_check (const gchar *path,
+ GError **error);
+gint camel_text_index_rename (const gchar *old,
+ const gchar *new);
+gint camel_text_index_remove (const gchar *old);
+
+void camel_text_index_dump (CamelTextIndex *idx);
+void camel_text_index_info (CamelTextIndex *idx);
+void camel_text_index_validate (CamelTextIndex *idx);
G_END_DECLS
diff --git a/camel/camel-uid-cache.c b/camel/camel-uid-cache.c
index 0a5c5a5..8880f0a 100644
--- a/camel/camel-uid-cache.c
+++ b/camel/camel-uid-cache.c
@@ -81,7 +81,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) == -1) {
+ if (st.st_size > 0 && camel_read (fd, buf, st.st_size, NULL) == -1) {
close (fd);
g_free (buf);
return NULL;
@@ -126,8 +126,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)) == -1 ||
- camel_write (cache->fd, "\n", 1) == -1) {
+ if (camel_write (cache->fd, key, strlen (key), NULL) == -1 ||
+ camel_write (cache->fd, "\n", 1, NULL) == -1) {
cache->fd = -1;
} else {
cache->size += strlen (key) + 1;
diff --git a/camel/providers/groupwise/camel-groupwise-folder.c b/camel/providers/groupwise/camel-groupwise-folder.c
index c5e30f4..5e5ee80 100644
--- a/camel/providers/groupwise/camel-groupwise-folder.c
+++ b/camel/providers/groupwise/camel-groupwise-folder.c
@@ -140,10 +140,10 @@ groupwise_folder_get_message( CamelFolder *folder, const gchar *uid, GError **er
stream = camel_stream_mem_new ();
if (cache_stream) {
msg = camel_mime_message_new ();
- camel_stream_reset (stream);
- camel_stream_write_to_stream (cache_stream, stream);
- camel_stream_reset (stream);
- if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, stream) == -1) {
+ camel_stream_reset (stream, NULL);
+ camel_stream_write_to_stream (cache_stream, stream, NULL);
+ camel_stream_reset (stream, NULL);
+ if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, stream, NULL) == -1) {
if (errno == EINTR) {
g_set_error (
error, CAMEL_ERROR,
@@ -230,8 +230,8 @@ groupwise_folder_get_message( CamelFolder *folder, const gchar *uid, GError **er
/* 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) == -1
- || camel_stream_flush (cache_stream) == -1)
+ if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) msg, cache_stream, error) == -1
+ || camel_stream_flush (cache_stream, error) == -1)
camel_data_cache_remove (gw_folder->cache, "cache", uid, NULL);
g_object_unref (cache_stream);
}
@@ -1721,7 +1721,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) == -1 || camel_stream_flush (cache_stream) == -1)
+ if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) mail_msg, cache_stream, error) == -1 || camel_stream_flush (cache_stream, error) == -1)
camel_data_cache_remove (gw_folder->cache, "cache", id, NULL);
g_object_unref (cache_stream);
}
@@ -2063,7 +2063,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) == -1) {
+ if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, temp_stream, error) == -1) {
g_object_unref (msg);
g_object_unref (temp_stream);
msg = NULL;
diff --git a/camel/providers/groupwise/camel-groupwise-journal.c b/camel/providers/groupwise/camel-groupwise-journal.c
index 0aff116..29520db 100644
--- a/camel/providers/groupwise/camel-groupwise-journal.c
+++ b/camel/providers/groupwise/camel-groupwise-journal.c
@@ -185,7 +185,7 @@ groupwise_entry_play_append (CamelOfflineJournal *journal, CamelGroupwiseJournal
goto done;
message = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream) == -1) {
+ if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, error) == -1) {
g_object_unref (message);
g_object_unref (stream);
goto done;
@@ -327,13 +327,10 @@ update_cache (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *messag
return FALSE;
}
- if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) message, cache) == -1
- || camel_stream_flush (cache) == -1) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Cannot append message in offline mode: %s"),
- g_strerror (errno));
+ if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) message, cache, error) == -1
+ || camel_stream_flush (cache, error) == -1) {
+ g_prefix_error (
+ error, _("Cannot append message in offline mode: "));
camel_data_cache_remove (groupwise_folder->cache, "cache", uid, NULL);
folder->summary->nextuid--;
g_object_unref (cache);
diff --git a/camel/providers/groupwise/camel-groupwise-utils.c b/camel/providers/groupwise/camel-groupwise-utils.c
index 01e7a6b..2765924 100644
--- a/camel/providers/groupwise/camel-groupwise-utils.c
+++ b/camel/providers/groupwise/camel-groupwise-utils.c
@@ -445,14 +445,14 @@ camel_groupwise_util_item_from_message (EGwConnection *cnc, CamelMimeMessage *me
g_object_ref (content);
}
- camel_data_wrapper_decode_to_stream (dw, filtered_stream);
- camel_stream_flush (filtered_stream);
+ camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL);
+ camel_stream_flush (filtered_stream, NULL);
g_object_unref (filtered_stream);
- camel_stream_write (content, "", 1);
+ camel_stream_write (content, "", 1, NULL);
e_gw_item_set_message (item, (const gchar *)buffer->data);
} else {
- camel_data_wrapper_decode_to_stream (dw, (CamelStream *) content);
+ camel_data_wrapper_decode_to_stream (dw, (CamelStream *) content, NULL);
send_as_attachment (cnc, item, content, type, dw, NULL, NULL, &attach_list);
}
@@ -649,7 +649,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);
+ camel_data_wrapper_write_to_stream(temp_dw, temp_content, 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);
@@ -681,18 +681,18 @@ do_multipart (EGwConnection *cnc, EGwItem *item, CamelMultipart *mp, GSList **at
g_object_ref (content);
}
- camel_data_wrapper_decode_to_stream (dw, filtered_stream);
- camel_stream_flush (filtered_stream);
+ camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL);
+ camel_stream_flush (filtered_stream, NULL);
g_object_unref (filtered_stream);
- camel_stream_write (content, "", 1);
+ camel_stream_write (content, "", 1, 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);
+ camel_data_wrapper_decode_to_stream (dw, content, 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 ccb14fd..22141be 100644
--- a/camel/providers/imap/camel-imap-command.c
+++ b/camel/providers/imap/camel-imap-command.c
@@ -229,21 +229,11 @@ imap_command_start (CamelImapStore *store,
fprintf (stderr, "sending : %c%.5u %s\r\n", store->tag_prefix, store->command, mask);
}
- nwritten = camel_stream_printf (store->ostream, "%c%.5u %s\r\n",
- store->tag_prefix, store->command++, cmd);
+ nwritten = camel_stream_printf (
+ store->ostream, error, "%c%.5u %s\r\n",
+ store->tag_prefix, store->command++, cmd);
if (nwritten == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Operation cancelled"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- "%s", g_strerror (errno));
-
camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
return FALSE;
}
@@ -256,7 +246,7 @@ imap_command_start (CamelImapStore *store,
* @store: the IMAP store
* @cmd: buffer containing the response/request data
* @cmdlen: command length
- * @ex: a CamelException
+ * @error: return location for a #GError, or %NULL
*
* This method is for sending continuing responses to the IMAP server
* after camel_imap_command() or camel_imap_command_response() returns
@@ -292,18 +282,13 @@ camel_imap_command_continuation (CamelImapStore *store,
return NULL;
}
- if (camel_stream_write (store->ostream, cmd, cmdlen) == -1 ||
- camel_stream_write (store->ostream, "\r\n", 2) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Operation cancelled"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- "%s", g_strerror (errno));
+ if (camel_stream_write (store->ostream, cmd, cmdlen, error) == -1) {
+ camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+ CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+ return NULL;
+ }
+
+ if (camel_stream_write (store->ostream, "\r\n", 2, error) == -1) {
camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
return NULL;
@@ -516,17 +501,11 @@ imap_read_untagged (CamelImapStore *store, gchar *line, GError **error)
nread = 0;
do {
- if ((n = camel_stream_read (store->istream, str->str + nread + 1, length - nread)) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Operation cancelled"));
- else
- g_set_error (
- error, CAMEL_SERVICE_ERROR,
- CAMEL_SERVICE_ERROR_UNAVAILABLE,
- "%s", g_strerror (errno));
+ n = camel_stream_read (
+ store->istream,
+ str->str + nread + 1,
+ length - nread, error);
+ if (n == -1) {
camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
g_string_free (str, TRUE);
goto lose;
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 35c1e7a..1e9570c 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -1993,12 +1993,13 @@ do_append (CamelFolder *folder,
camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (memstream), ba);
streamfilter = camel_stream_filter_new (memstream);
- crlf_filter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE,
- CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
+ crlf_filter = camel_mime_filter_crlf_new (
+ CAMEL_MIME_FILTER_CRLF_ENCODE,
+ CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
camel_stream_filter_add (
CAMEL_STREAM_FILTER (streamfilter), crlf_filter);
camel_data_wrapper_write_to_stream (
- CAMEL_DATA_WRAPPER (message), streamfilter);
+ CAMEL_DATA_WRAPPER (message), streamfilter, NULL);
g_object_unref (streamfilter);
g_object_unref (crlf_filter);
g_object_unref (memstream);
@@ -2798,7 +2799,8 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid,
stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, error);
if (stream) {
- ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (body_mp), stream);
+ ret = camel_data_wrapper_construct_from_stream (
+ CAMEL_DATA_WRAPPER (body_mp), stream, error);
g_object_unref (CAMEL_OBJECT (stream));
if (ret == -1) {
g_object_unref ( body_mp);
@@ -2839,7 +2841,8 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid,
gint ret;
part = camel_mime_part_new ();
- ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (part), stream);
+ ret = camel_data_wrapper_construct_from_stream (
+ CAMEL_DATA_WRAPPER (part), stream, error);
g_object_unref (CAMEL_OBJECT (stream));
if (ret == -1) {
g_object_unref (CAMEL_OBJECT (part));
@@ -2935,7 +2938,8 @@ get_message (CamelImapFolder *imap_folder, const gchar *uid,
return NULL;
msg = camel_mime_message_new ();
- ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream);
+ ret = camel_data_wrapper_construct_from_stream (
+ CAMEL_DATA_WRAPPER (msg), stream, error);
g_object_unref (CAMEL_OBJECT (stream));
if (ret == -1) {
g_object_unref (CAMEL_OBJECT (msg));
@@ -2981,15 +2985,11 @@ get_message_simple (CamelImapFolder *imap_folder, const gchar *uid,
}
msg = camel_mime_message_new ();
- ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg),
- stream);
+ ret = camel_data_wrapper_construct_from_stream (
+ CAMEL_DATA_WRAPPER (msg), stream, error);
g_object_unref (CAMEL_OBJECT (stream));
if (ret == -1) {
- g_set_error (
- error, CAMEL_SERVICE_ERROR,
- CAMEL_SERVICE_ERROR_UNAVAILABLE,
- _("Unable to retrieve message: %s"),
- g_strerror (errno));
+ g_prefix_error (error, _("Unable to retrieve message: "));
g_object_unref (CAMEL_OBJECT (msg));
return NULL;
}
@@ -3386,7 +3386,8 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
g_ptr_array_set_size (messages, seq - first + 1);
msg = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream) == -1) {
+ if (camel_data_wrapper_construct_from_stream (
+ CAMEL_DATA_WRAPPER (msg), stream, NULL) == -1) {
g_object_unref (CAMEL_OBJECT (msg));
return;
}
diff --git a/camel/providers/imap/camel-imap-message-cache.c b/camel/providers/imap/camel-imap-message-cache.c
index c714c7d..f200ec3 100644
--- a/camel/providers/imap/camel-imap-message-cache.c
+++ b/camel/providers/imap/camel-imap-message-cache.c
@@ -356,11 +356,14 @@ insert_abort (gchar *path, CamelStream *stream)
}
static CamelStream *
-insert_finish (CamelImapMessageCache *cache, const gchar *uid, gchar *path,
- gchar *key, CamelStream *stream)
+insert_finish (CamelImapMessageCache *cache,
+ const gchar *uid,
+ gchar *path,
+ gchar *key,
+ CamelStream *stream)
{
- camel_stream_flush (stream);
- camel_stream_reset (stream);
+ camel_stream_flush (stream, NULL);
+ camel_stream_reset (stream, NULL);
cache_put (cache, uid, key, stream);
g_free (path);
@@ -395,12 +398,9 @@ camel_imap_message_cache_insert (CamelImapMessageCache *cache,
if (!stream)
return NULL;
- if (camel_stream_write (stream, data, len) == -1) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Failed to cache message %s: %s"),
- uid, g_strerror (errno));
+ if (camel_stream_write (stream, data, len, error) == -1) {
+ g_prefix_error (
+ error, _("Failed to cache message %s: "), uid);
return insert_abort (path, stream);
}
@@ -430,12 +430,9 @@ camel_imap_message_cache_insert_stream (CamelImapMessageCache *cache,
if (!stream)
return;
- if (camel_stream_write_to_stream (data_stream, stream) == -1) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Failed to cache message %s: %s"),
- uid, g_strerror (errno));
+ if (camel_stream_write_to_stream (data_stream, stream, error) == -1) {
+ g_prefix_error (
+ error, _("Failed to cache message %s: "), uid);
insert_abort (path, stream);
} else {
insert_finish (cache, uid, path, key, stream);
@@ -466,12 +463,9 @@ camel_imap_message_cache_insert_wrapper (CamelImapMessageCache *cache,
if (!stream)
return;
- if (camel_data_wrapper_write_to_stream (wrapper, stream) == -1) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Failed to cache message %s: %s"),
- uid, g_strerror (errno));
+ if (camel_data_wrapper_write_to_stream (wrapper, stream, error) == -1) {
+ g_prefix_error (
+ error, _("Failed to cache message %s: "), uid);
insert_abort (path, stream);
} else {
insert_finish (cache, uid, path, key, stream);
@@ -539,22 +533,17 @@ camel_imap_message_cache_get (CamelImapMessageCache *cache, const gchar *uid,
stream = g_hash_table_lookup (cache->parts, key);
if (stream) {
- camel_stream_reset (CAMEL_STREAM (stream));
- g_object_ref (CAMEL_OBJECT (stream));
+ camel_stream_reset (CAMEL_STREAM (stream), NULL);
+ g_object_ref (stream);
g_free (path);
return stream;
}
- stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0);
- if (stream) {
+ stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0, error);
+ if (stream)
cache_put (cache, uid, key, stream);
- } else {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Failed to cache %s: %s"),
- part_spec, g_strerror (errno));
- }
+ else
+ g_prefix_error (error, _("Failed to cache %s: "), part_spec);
g_free (path);
diff --git a/camel/providers/imap/camel-imap-search.c b/camel/providers/imap/camel-imap-search.c
index f84df81..b49f2ab 100644
--- a/camel/providers/imap/camel-imap-search.c
+++ b/camel/providers/imap/camel-imap-search.c
@@ -265,10 +265,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)) != sizeof(header)
- || camel_stream_write(stream, mr->matches->data, mr->matches->len*sizeof(guint32)) != mr->matches->len*sizeof(guint32)
- || camel_seekable_stream_seek((CamelSeekableStream *)stream, 0, CAMEL_STREAM_SET) == -1
- || camel_stream_write(stream, (gchar *)&mark, sizeof(mark)) != sizeof(mark)) {
+ 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)
+ || camel_seekable_stream_seek((CamelSeekableStream *)stream, 0, CAMEL_STREAM_SET, NULL) == -1
+ || camel_stream_write(stream, (gchar *)&mark, sizeof(mark), 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;
@@ -309,13 +309,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)) == sizeof(header)
+ if (camel_stream_read(stream, (gchar *)&header, sizeof(header), 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);
+ camel_stream_read(stream, mr->matches->data, sizeof(guint32)*header.matchcount, NULL);
} else {
d(printf(" file format invalid/validity changed\n"));
memset(&header, 0, sizeof(header));
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index e0d83c9..1c38beb 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -557,7 +557,9 @@ connect_to_server (CamelService *service, struct addrinfo *ai, gint ssl_mode, GE
else
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_UNAVAILABLE,
_("Could not connect to %s: %s"),
service->url->host, _("SSL unavailable"));
@@ -567,20 +569,11 @@ connect_to_server (CamelService *service, struct addrinfo *ai, gint ssl_mode, GE
} else
tcp_stream = camel_tcp_stream_raw_new ();
- if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_USER_CANCEL,
- _("Connection cancelled"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Could not connect to %s: %s"),
- service->url->host, g_strerror (errno));
-
+ if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai, error) == -1) {
+ g_prefix_error (
+ error, _("Could not connect to %s: "),
+ service->url->host);
g_object_unref (tcp_stream);
-
return FALSE;
}
@@ -1605,13 +1598,13 @@ imap_disconnect (CamelService *service, gboolean clean, GError **error)
}
if (store->istream) {
- camel_stream_close(store->istream);
+ camel_stream_close(store->istream, NULL);
g_object_unref (store->istream);
store->istream = NULL;
}
if (store->ostream) {
- camel_stream_close(store->ostream);
+ camel_stream_close(store->ostream, NULL);
g_object_unref (store->ostream);
store->ostream = NULL;
}
@@ -3156,7 +3149,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))) > 0) {
+ while ((nread = camel_stream_buffer_gets (stream, linebuf, sizeof (linebuf), NULL)) > 0) {
g_byte_array_append (ba, (const guint8 *) linebuf, nread);
if (linebuf[nread - 1] == '\n')
break;
diff --git a/camel/providers/imap/camel-imap-wrapper.c b/camel/providers/imap/camel-imap-wrapper.c
index 8674390..26550fd 100644
--- a/camel/providers/imap/camel-imap-wrapper.c
+++ b/camel/providers/imap/camel-imap-wrapper.c
@@ -44,7 +44,23 @@ struct _CamelImapWrapperPrivate {
static gpointer parent_class;
-static gssize write_to_stream (CamelDataWrapper *imap_wrapper, CamelStream *stream);
+static void
+imap_wrapper_hydrate (CamelImapWrapper *imap_wrapper,
+ CamelStream *stream)
+{
+ CamelDataWrapper *data_wrapper = (CamelDataWrapper *) imap_wrapper;
+
+ g_object_ref (stream);
+ data_wrapper->stream = stream;
+ data_wrapper->offline = FALSE;
+
+ g_object_unref (imap_wrapper->folder);
+ imap_wrapper->folder = NULL;
+ g_free (imap_wrapper->uid);
+ imap_wrapper->uid = NULL;
+ g_free (imap_wrapper->part_spec);
+ imap_wrapper->part_spec = NULL;
+}
static void
imap_wrapper_dispose (GObject *object)
@@ -74,6 +90,40 @@ imap_wrapper_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static gssize
+imap_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream,
+ GError **error)
+{
+ CamelImapWrapper *imap_wrapper = CAMEL_IMAP_WRAPPER (data_wrapper);
+
+ CAMEL_IMAP_WRAPPER_LOCK (imap_wrapper, lock);
+ if (data_wrapper->offline) {
+ CamelStream *datastream;
+
+ datastream = camel_imap_folder_fetch_data (
+ imap_wrapper->folder, imap_wrapper->uid,
+ imap_wrapper->part_spec, FALSE, NULL);
+ if (!datastream) {
+ CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
+#ifdef ENETUNREACH
+ errno = ENETUNREACH;
+#else
+/* FIXME[disk-summary] what errno to use if no ENETUNREACH */
+ errno = EINVAL;
+#endif
+ return -1;
+ }
+
+ imap_wrapper_hydrate (imap_wrapper, datastream);
+ g_object_unref (datastream);
+ }
+ CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
+
+ return CAMEL_DATA_WRAPPER_CLASS (parent_class)->
+ write_to_stream (data_wrapper, stream, error);
+}
+
static void
imap_wrapper_class_init (CamelImapWrapperClass *class)
{
@@ -88,7 +138,7 @@ imap_wrapper_class_init (CamelImapWrapperClass *class)
object_class->finalize = imap_wrapper_finalize;
data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
- data_wrapper_class->write_to_stream = write_to_stream;
+ data_wrapper_class->write_to_stream = imap_wrapper_write_to_stream;
}
static void
@@ -116,55 +166,6 @@ camel_imap_wrapper_get_type (void)
return type;
}
-static void
-imap_wrapper_hydrate (CamelImapWrapper *imap_wrapper, CamelStream *stream)
-{
- CamelDataWrapper *data_wrapper = (CamelDataWrapper *) imap_wrapper;
-
- g_object_ref (stream);
- data_wrapper->stream = stream;
- data_wrapper->offline = FALSE;
-
- g_object_unref (imap_wrapper->folder);
- imap_wrapper->folder = NULL;
- g_free (imap_wrapper->uid);
- imap_wrapper->uid = NULL;
- g_free (imap_wrapper->part_spec);
- imap_wrapper->part_spec = NULL;
-}
-
-static gssize
-write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
-{
- CamelImapWrapper *imap_wrapper = CAMEL_IMAP_WRAPPER (data_wrapper);
-
- CAMEL_IMAP_WRAPPER_LOCK (imap_wrapper, lock);
- if (data_wrapper->offline) {
- CamelStream *datastream;
-
- datastream = camel_imap_folder_fetch_data (
- imap_wrapper->folder, imap_wrapper->uid,
- imap_wrapper->part_spec, FALSE, NULL);
- if (!datastream) {
- CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
-#ifdef ENETUNREACH
- errno = ENETUNREACH;
-#else
-/* FIXME[disk-summary] what errno to use if no ENETUNREACH */
- errno = EINVAL;
-#endif
- return -1;
- }
-
- imap_wrapper_hydrate (imap_wrapper, datastream);
- g_object_unref (datastream);
- }
- CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
-
- return CAMEL_DATA_WRAPPER_CLASS (parent_class)->
- write_to_stream (data_wrapper, stream);
-}
-
CamelDataWrapper *
camel_imap_wrapper_new (CamelImapFolder *imap_folder,
CamelContentType *type, CamelTransferEncoding encoding,
diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c
index a4a4772..54b10c5 100644
--- a/camel/providers/local/camel-local-folder.c
+++ b/camel/providers/local/camel-local-folder.c
@@ -282,14 +282,14 @@ camel_local_folder_construct(CamelLocalFolder *lf, CamelStore *parent_store, con
/* FIXME: Need to run indexing off of the setv method */
/* if we have no/invalid index file, force it */
- forceindex = camel_text_index_check(lf->index_path) == -1;
+ forceindex = camel_text_index_check(lf->index_path, NULL) == -1;
if (lf->flags & CAMEL_STORE_FOLDER_BODY_INDEX) {
gint flag = O_RDWR|O_CREAT;
if (forceindex)
flag |= O_TRUNC;
- lf->index = (CamelIndex *)camel_text_index_new(lf->index_path, flag);
+ lf->index = (CamelIndex *)camel_text_index_new(lf->index_path, flag, NULL);
if (lf->index == NULL) {
/* yes, this isn't fatal at all */
g_warning("Could not open/create index file: %s: indexing not performed", g_strerror (errno));
diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c
index 1553021..88ae044 100644
--- a/camel/providers/local/camel-local-summary.c
+++ b/camel/providers/local/camel-local-summary.c
@@ -458,18 +458,24 @@ local_summary_sync (CamelLocalSummary *cls,
CamelFolderChangeInfo *changeinfo,
GError **error)
{
- gint ret = 0;
+ CamelFolderSummary *folder_summary;
- ret = camel_folder_summary_save_to_db ((CamelFolderSummary *)cls, error);
- if (ret == -1) {
- g_warning ("Could not save summary for local providers");
- return -1;
- }
+ folder_summary = CAMEL_FOLDER_SUMMARY (cls);
- if (cls->index && camel_index_sync(cls->index) == -1)
- g_warning ("Could not sync index for %s: %s", cls->folder_path, g_strerror (errno));
+ if (camel_folder_summary_save_to_db (folder_summary, error) == -1)
+ goto error;
- return ret;
+ if (cls->index && camel_index_sync(cls->index, error) == -1)
+ goto error;
+
+ return 0;
+
+error:
+ g_prefix_error (
+ error, _("Could not sync index for %s: "),
+ cls->folder_path);
+
+ return -1;
}
static gint
@@ -547,7 +553,7 @@ local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMess
if (mi->info.size == 0) {
CamelStreamNull *sn = (CamelStreamNull *)camel_stream_null_new();
- camel_data_wrapper_write_to_stream((CamelDataWrapper *)msg, (CamelStream *)sn);
+ camel_data_wrapper_write_to_stream((CamelDataWrapper *)msg, (CamelStream *)sn, NULL);
mi->info.size = sn->written;
g_object_unref (sn);
}
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
index fe5f826..8b734f9 100644
--- a/camel/providers/local/camel-maildir-folder.c
+++ b/camel/providers/local/camel-maildir-folder.c
@@ -194,12 +194,13 @@ maildir_append_message (CamelFolder *folder,
/* write it out to tmp, use the uid we got from the summary */
name = g_strdup_printf ("%s/tmp/%s", lf->folder_path, camel_message_info_uid(mi));
- output_stream = camel_stream_fs_new_with_name (name, O_WRONLY|O_CREAT, 0600);
+ output_stream = camel_stream_fs_new_with_name (
+ name, O_WRONLY|O_CREAT, 0600, error);
if (output_stream == NULL)
goto fail_write;
- if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)message, output_stream) == -1
- || camel_stream_close (output_stream) == -1)
+ if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)message, output_stream, error) == -1
+ || camel_stream_close (output_stream, error) == -1)
goto fail_write;
/* now move from tmp to cur (bypass new, does it matter?) */
@@ -316,29 +317,18 @@ maildir_get_message (CamelFolder *folder,
camel_message_info_free(info);
- if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Cannot get message: %s from folder %s\n %s"),
- uid, lf->folder_path, g_strerror(errno));
+ if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0, error)) == NULL) {
+ g_prefix_error (
+ error, _("Cannot get message: %s from "
+ "folder %s\n "), uid, lf->folder_path);
goto fail;
}
message = camel_mime_message_new();
- if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Cannot get message: %s from folder %s\n %s"),
- uid, lf->folder_path, _("Invalid message contents"));
- else
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_SYSTEM,
- _("Cannot get message: %s from folder %s\n %s"),
- uid, lf->folder_path, _("Invalid message contents"));
+ if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream, error) == -1) {
+ g_prefix_error (
+ error, _("Cannot get message: %s from "
+ "folder %s\n "), uid, lf->folder_path);
g_object_unref (message);
message = NULL;
diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c
index fdcd87b..d1723cb 100644
--- a/camel/providers/local/camel-mbox-folder.c
+++ b/camel/providers/local/camel-mbox-folder.c
@@ -200,13 +200,13 @@ mbox_append_message (CamelFolder *folder,
if ((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !camel_mime_message_has_attachment (message))
camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, 0);
- output_stream = camel_stream_fs_new_with_name(lf->folder_path, O_WRONLY | O_APPEND | O_LARGEFILE, 0666);
+ output_stream = camel_stream_fs_new_with_name (
+ lf->folder_path, O_WRONLY | O_APPEND |
+ O_LARGEFILE, 0666, error);
if (output_stream == NULL) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Cannot open mailbox: %s: %s\n"),
- lf->folder_path, g_strerror (errno));
+ g_prefix_error (
+ error, _("Cannot open mailbox: %s"),
+ lf->folder_path);
goto fail;
}
@@ -224,7 +224,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)) == -1)
+ if (camel_stream_write(output_stream, fromline, strlen(fromline), error) == -1)
goto fail_write;
/* and write the content to the filtering stream, that translates '\nFrom' into '\n>From' */
@@ -233,9 +233,9 @@ mbox_append_message (CamelFolder *folder,
camel_stream_filter_add((CamelStreamFilter *) filter_stream, filter_from);
g_object_unref (filter_from);
- if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) message, filter_stream) == -1 ||
- camel_stream_write (filter_stream, "\n", 1) == -1 ||
- camel_stream_flush (filter_stream) == -1)
+ 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)
goto fail_write;
/* filter stream ref's the output stream itself, so we need to unref it too */
@@ -269,17 +269,9 @@ mbox_append_message (CamelFolder *folder,
return TRUE;
fail_write:
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Mail append canceled"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Cannot append message to mbox file: %s: %s"),
- lf->folder_path, g_strerror (errno));
+ g_prefix_error (
+ error, _("Cannot append message to mbox file: %s"),
+ lf->folder_path);
if (output_stream) {
gint fd;
@@ -464,21 +456,12 @@ retry:
}
message = camel_mime_message_new();
- if (camel_mime_part_construct_from_parser((CamelMimePart *)message, parser) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Cannot get message: %s from folder %s\n %s"),
- uid, lf->folder_path,
- _("Message construction failed."));
- else
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_SYSTEM,
- _("Cannot get message: %s from folder %s\n %s"),
- uid, lf->folder_path,
- _("Message construction failed."));
+ if (camel_mime_part_construct_from_parser((CamelMimePart *)message, parser, error) == -1) {
+ g_set_error (
+ error, CAMEL_ERROR,
+ CAMEL_ERROR_USER_CANCEL,
+ _("Cannot get message: %s from folder %s\n "),
+ uid, lf->folder_path);
g_object_unref (message);
message = NULL;
goto fail;
diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c
index 5129d8d..1b5756f 100644
--- a/camel/providers/local/camel-mh-folder.c
+++ b/camel/providers/local/camel-mh-folder.c
@@ -142,12 +142,13 @@ mh_append_message (CamelFolder *folder,
/* write it out, use the uid we got from the summary */
name = g_strdup_printf("%s/%s", lf->folder_path, camel_message_info_uid(mi));
- output_stream = camel_stream_fs_new_with_name(name, O_WRONLY|O_CREAT, 0600);
+ output_stream = camel_stream_fs_new_with_name (
+ name, O_WRONLY|O_CREAT, 0600, error);
if (output_stream == NULL)
goto fail_write;
- if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)message, output_stream) == -1
- || camel_stream_close (output_stream) == -1)
+ if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)message, output_stream, error) == -1
+ || camel_stream_close (output_stream, error) == -1)
goto fail_write;
/* close this? */
@@ -236,23 +237,18 @@ mh_get_message (CamelFolder *folder,
camel_message_info_free(info);
name = g_strdup_printf("%s/%s", lf->folder_path, uid);
- if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Cannot get message: %s from folder %s\n %s"),
- name, lf->folder_path, g_strerror (errno));
+ if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0, error)) == NULL) {
+ g_prefix_error (
+ error, _("Cannot get message: %s from "
+ "folder %s\n "), name, lf->folder_path);
goto fail;
}
message = camel_mime_message_new();
- if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream) == -1) {
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_SYSTEM,
- _("Cannot get message: %s from folder %s\n %s"),
- name, lf->folder_path,
- _("Message construction failed."));
+ if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream, error) == -1) {
+ g_prefix_error (
+ error, _("Cannot get message: %s from "
+ "folder %s\n "), name, lf->folder_path);
g_object_unref (message);
message = NULL;
diff --git a/camel/providers/local/camel-mh-store.c b/camel/providers/local/camel-mh-store.c
index f0d16dc..ec8f750 100644
--- a/camel/providers/local/camel-mh-store.c
+++ b/camel/providers/local/camel-mh-store.c
@@ -125,24 +125,25 @@ folders_update (const gchar *root,
tmpnew = g_alloca (strlen (root) + 16);
sprintf (tmpnew, "%s.folders~", root);
- out = camel_stream_fs_new_with_name(tmpnew, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ out = camel_stream_fs_new_with_name (
+ tmpnew, O_WRONLY|O_CREAT|O_TRUNC, 0666, NULL);
if (out == NULL)
goto fail;
tmp = g_alloca (strlen (root) + 16);
sprintf (tmp, "%s.folders", root);
- stream = camel_stream_fs_new_with_name(tmp, O_RDONLY, 0);
+ stream = camel_stream_fs_new_with_name (tmp, O_RDONLY, 0, NULL);
if (stream) {
in = camel_stream_buffer_new(stream, CAMEL_STREAM_BUFFER_READ);
g_object_unref (stream);
}
if (in == NULL || stream == NULL) {
- if (mode == UPDATE_ADD && camel_stream_printf(out, "%s\n", folder) == -1)
+ if (mode == UPDATE_ADD && camel_stream_printf (out, NULL, "%s\n", folder) == -1)
goto fail;
goto done;
}
- while ((line = camel_stream_buffer_read_line((CamelStreamBuffer *)in))) {
+ while ((line = camel_stream_buffer_read_line((CamelStreamBuffer *)in, NULL))) {
gint copy = TRUE;
switch (mode) {
@@ -153,9 +154,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)) == -1
- || camel_stream_write(out, line+flen, strlen(line)-flen) == -1
- || camel_stream_write(out, "\n", 1) == -1)
+ 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)
goto fail;
copy = FALSE;
}
@@ -165,7 +166,7 @@ folders_update (const gchar *root,
if (cmp > 0) {
/* found insertion point */
- if (camel_stream_printf(out, "%s\n", folder) == -1)
+ if (camel_stream_printf(out, NULL, "%s\n", folder) == -1)
goto fail;
mode = UPDATE_NONE;
} else if (tmp == NULL) {
@@ -177,7 +178,7 @@ folders_update (const gchar *root,
break;
}
- if (copy && camel_stream_printf(out, "%s\n", line) == -1)
+ if (copy && camel_stream_printf(out, NULL, "%s\n", line) == -1)
goto fail;
g_free(line);
@@ -185,10 +186,10 @@ folders_update (const gchar *root,
}
/* add to end? */
- if (mode == UPDATE_ADD && camel_stream_printf(out, "%s\n", folder) == -1)
+ if (mode == UPDATE_ADD && camel_stream_printf(out, NULL, "%s\n", folder) == -1)
goto fail;
- if (camel_stream_close(out) == -1)
+ if (camel_stream_close(out, NULL) == -1)
goto fail;
done:
@@ -509,7 +510,7 @@ folders_scan (CamelStore *store,
tmp = g_alloca (strlen (root) + 16);
sprintf (tmp, "%s/.folders", root);
- stream = camel_stream_fs_new_with_name(tmp, 0, O_RDONLY);
+ stream = camel_stream_fs_new_with_name(tmp, 0, O_RDONLY, NULL);
if (stream == NULL)
return;
@@ -521,7 +522,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))) > 0) {
+ while ( (len = camel_stream_buffer_gets((CamelStreamBuffer *)in, line, sizeof(line), NULL)) > 0) {
/* ignore blank lines */
if (len <= 1)
continue;
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
index 1998f91..62fa70e 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -164,9 +164,9 @@ nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const gchar *id, con
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) == -1)
+ if (camel_stream_write_to_stream ((CamelStream *) nntp_store->stream, stream, error) == -1)
goto fail;
- if (camel_stream_reset (stream) == -1)
+ if (camel_stream_reset (stream, error) == -1)
goto fail;
} else {
stream = (CamelStream *) nntp_store->stream;
@@ -185,18 +185,8 @@ nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const gchar *id, con
return stream;
- fail:
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("User canceled"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Cannot get message %s: %s"),
- msgid, g_strerror (errno));
+fail:
+ g_prefix_error (error, _("Cannot get message %s: "), msgid);
return NULL;
}
@@ -279,18 +269,8 @@ nntp_folder_get_message (CamelFolder *folder, const gchar *uid, GError **error)
}
message = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("User canceled"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Cannot get message %s: %s"),
- uid, g_strerror (errno));
+ if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, error) == -1) {
+ g_prefix_error (error, _("Cannot get message %s: "), uid);
g_object_unref (message);
message = NULL;
}
@@ -442,25 +422,13 @@ nntp_folder_append_message_online (CamelFolder *folder,
camel_header_raw_extract (header_queue, &save_queue, "Bcc");
/* write the message */
- if (camel_stream_write(stream, group, strlen(group)) == -1
- || camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (mime_message), filtered_stream) == -1
- || camel_stream_flush (filtered_stream) == -1
- || camel_stream_write (stream, "\r\n.\r\n", 5) == -1
- || (ret = camel_nntp_stream_line (nntp_store->stream, (guchar **)&line, &u)) == -1) {
- if (errno == EINTR) {
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("User canceled"));
- success = FALSE;
- } else {
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Posting failed: %s"),
- g_strerror (errno));
- success = FALSE;
- }
+ 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) {
+ g_prefix_error (error, "Posting failed: ");
+ success = FALSE;
} else if (atoi(line) != 240) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
index fc7a221..c0705a4 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -161,7 +161,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)) > 0) {
+ while ((ret = camel_nntp_stream_line(store->stream, (guchar **)&line, &len, error)) > 0) {
p = (guchar *) line;
xover = g_malloc0(sizeof(*xover));
last->next = xover;
@@ -227,28 +227,17 @@ connect_to_server (CamelService *service, struct addrinfo *ai, gint ssl_mode, GE
CAMEL_SERVICE_ERROR_UNAVAILABLE,
_("Could not connect to %s: %s"),
service->url->host, _("SSL unavailable"));
-
goto fail;
#endif /* HAVE_SSL */
} else {
tcp_stream = camel_tcp_stream_raw_new ();
}
- if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Connection canceled"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Could not connect to %s: %s"),
- service->url->host, g_strerror (errno));
-
+ if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai, error) == -1) {
+ g_prefix_error (
+ error, _("Could not connect to %s: "),
+ service->url->host);
g_object_unref (tcp_stream);
-
goto fail;
}
@@ -256,19 +245,10 @@ connect_to_server (CamelService *service, struct addrinfo *ai, gint ssl_mode, GE
g_object_unref (tcp_stream);
/* Read the greeting, if any. */
- if (camel_nntp_stream_line (store->stream, &buf, &len) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Connection canceled"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Could not read greeting from %s: %s"),
- service->url->host, g_strerror (errno));
-
+ if (camel_nntp_stream_line (store->stream, &buf, &len, error) == -1) {
+ g_prefix_error (
+ error, _("Could not read greeting from %s: "),
+ service->url->host);
g_object_unref (store->stream);
store->stream = NULL;
@@ -864,7 +844,7 @@ nntp_store_get_folder_info_all(CamelNNTPStore *nntp_store, const gchar *top, gui
goto do_complete_list;
}
- while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len)) > 0)
+ while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len, error)) > 0)
nntp_store_info_update(nntp_store, (gchar *) line);
} else {
GHashTable *all;
@@ -890,7 +870,7 @@ nntp_store_get_folder_info_all(CamelNNTPStore *nntp_store, const gchar *top, gui
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)) > 0) {
+ while ((ret = camel_nntp_stream_line(nntp_store->stream, &line, &len, error)) > 0) {
si = nntp_store_info_update(nntp_store, (gchar *) line);
g_hash_table_remove(all, si->info.path);
}
@@ -1307,32 +1287,32 @@ 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));
+ camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p - ps - (c == '%' ? 1 : 2), NULL);
ps = p;
switch (c) {
case 's':
s = va_arg(ap, gchar *);
- camel_stream_write((CamelStream *)store->mem, s, strlen(s));
+ camel_stream_write((CamelStream *)store->mem, s, strlen(s), NULL);
break;
case 'd':
d = va_arg(ap, gint);
- camel_stream_printf((CamelStream *)store->mem, "%d", d);
+ camel_stream_printf((CamelStream *)store->mem, NULL, "%d", d);
break;
case 'u':
u = va_arg(ap, guint);
- camel_stream_printf((CamelStream *)store->mem, "%u", u);
+ camel_stream_printf((CamelStream *)store->mem, NULL, "%u", u);
break;
case 'm':
s = va_arg(ap, gchar *);
- camel_stream_printf((CamelStream *)store->mem, "<%s>", s);
+ camel_stream_printf((CamelStream *)store->mem, NULL, "<%s>", s);
break;
case 'r':
u = va_arg(ap, guint);
u2 = va_arg(ap, guint);
if (u == u2)
- camel_stream_printf((CamelStream *)store->mem, "%u", u);
+ camel_stream_printf((CamelStream *)store->mem, NULL, "%u", u);
else
- camel_stream_printf((CamelStream *)store->mem, "%u-%u", u, u2);
+ camel_stream_printf((CamelStream *)store->mem, NULL, "%u-%u", u, u2);
break;
default:
g_warning("Passing unknown format to nntp_command: %c\n", c);
@@ -1341,19 +1321,19 @@ camel_nntp_raw_commandv (CamelNNTPStore *store, GError **error, gchar **line, co
}
}
- camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p-ps-1);
- camel_stream_write ((CamelStream *) store->mem, "\r\n", 2);
+ camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p-ps-1, NULL);
+ camel_stream_write ((CamelStream *) store->mem, "\r\n", 2, NULL);
buffer = camel_stream_mem_get_byte_array (store->mem);
- if (camel_stream_write((CamelStream *) store->stream, (const gchar *) buffer->data, buffer->len) == -1)
+ if (camel_stream_write((CamelStream *) store->stream, (const gchar *) buffer->data, buffer->len, error) == -1)
goto ioerror;
/* FIXME: hack */
- camel_stream_reset ((CamelStream *) store->mem);
+ camel_stream_reset ((CamelStream *) store->mem, NULL);
g_byte_array_set_size (buffer, 0);
- if (camel_nntp_stream_line (store->stream, (guchar **) line, &u) == -1)
+ if (camel_nntp_stream_line (store->stream, (guchar **) line, &u, error) == -1)
goto ioerror;
u = strtoul (*line, NULL, 10);
@@ -1365,17 +1345,7 @@ camel_nntp_raw_commandv (CamelNNTPStore *store, GError **error, gchar **line, co
return u;
ioerror:
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Canceled."));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("NNTP Command failed: %s"),
- g_strerror(errno));
+ g_prefix_error (error, _("NNTP Command failed: "));
return -1;
}
@@ -1448,7 +1418,7 @@ 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, NULL) > 0)
;
}
camel_nntp_stream_set_mode(store->stream, CAMEL_NNTP_STREAM_LINE);
diff --git a/camel/providers/nntp/camel-nntp-stream.c b/camel/providers/nntp/camel-nntp-stream.c
index c03432d..6d5d5c0 100644
--- a/camel/providers/nntp/camel-nntp-stream.c
+++ b/camel/providers/nntp/camel-nntp-stream.c
@@ -68,7 +68,8 @@ nntp_stream_finalize (GObject *object)
}
static gint
-stream_fill (CamelNNTPStream *is)
+nntp_stream_fill (CamelNNTPStream *is,
+ GError **error)
{
gint left = 0;
@@ -77,7 +78,7 @@ stream_fill (CamelNNTPStream *is)
memcpy (is->buf, is->ptr, left);
is->end = is->buf + left;
is->ptr = is->buf;
- left = camel_stream_read (is->source, (gchar *) is->end, CAMEL_NNTP_STREAM_SIZE - (is->end - is->buf));
+ left = camel_stream_read (is->source, (gchar *) is->end, CAMEL_NNTP_STREAM_SIZE - (is->end - is->buf), error);
if (left > 0) {
is->end += left;
is->end[0] = '\n';
@@ -94,7 +95,10 @@ stream_fill (CamelNNTPStream *is)
}
static gssize
-stream_read (CamelStream *stream, gchar *buffer, gsize n)
+nntp_stream_read (CamelStream *stream,
+ gchar *buffer,
+ gsize n,
+ GError **error)
{
CamelNNTPStream *is = (CamelNNTPStream *)stream;
gchar *o, *oe;
@@ -117,7 +121,7 @@ stream_read (CamelStream *stream, gchar *buffer, gsize n)
case 0: /* start of line, always read at least 3 chars */
while (e - p < 3) {
is->ptr = p;
- if (stream_fill (is) == -1)
+ if (nntp_stream_fill (is, error) == -1)
return -1;
p = is->ptr;
e = is->end;
@@ -141,7 +145,7 @@ stream_read (CamelStream *stream, gchar *buffer, gsize n)
/* end of input sentinal check */
if (p > e) {
is->ptr = e;
- if (stream_fill (is) == -1)
+ if (nntp_stream_fill (is, error) == -1)
return -1;
p = is->ptr;
e = is->end;
@@ -166,29 +170,34 @@ stream_read (CamelStream *stream, gchar *buffer, gsize n)
}
static gssize
-stream_write (CamelStream *stream, const gchar *buffer, gsize n)
+nntp_stream_write (CamelStream *stream,
+ const gchar *buffer,
+ gsize n,
+ GError **error)
{
CamelNNTPStream *is = (CamelNNTPStream *)stream;
- return camel_stream_write (is->source, buffer, n);
+ return camel_stream_write (is->source, buffer, n, error);
}
static gint
-stream_close (CamelStream *stream)
+nntp_stream_close (CamelStream *stream,
+ GError **error)
{
/* nop? */
return 0;
}
static gint
-stream_flush (CamelStream *stream)
+nntp_stream_flush (CamelStream *stream,
+ GError **error)
{
/* nop? */
return 0;
}
static gboolean
-stream_eos (CamelStream *stream)
+nntp_stream_eos (CamelStream *stream)
{
CamelNNTPStream *is = (CamelNNTPStream *)stream;
@@ -196,7 +205,8 @@ stream_eos (CamelStream *stream)
}
static gint
-stream_reset (CamelStream *stream)
+nntp_stream_reset (CamelStream *stream,
+ GError **error)
{
/* nop? reset literal mode? */
return 0;
@@ -215,12 +225,12 @@ nntp_stream_class_init (CamelStreamClass *class)
object_class->finalize = nntp_stream_finalize;
stream_class = CAMEL_STREAM_CLASS (class);
- stream_class->read = stream_read;
- stream_class->write = stream_write;
- stream_class->close = stream_close;
- stream_class->flush = stream_flush;
- stream_class->eos = stream_eos;
- stream_class->reset = stream_reset;
+ stream_class->read = nntp_stream_read;
+ stream_class->write = nntp_stream_write;
+ stream_class->close = nntp_stream_close;
+ stream_class->flush = nntp_stream_flush;
+ stream_class->eos = nntp_stream_eos;
+ stream_class->reset = nntp_stream_reset;
}
static void
@@ -277,7 +287,10 @@ camel_nntp_stream_new (CamelStream *source)
/* Get one line from the nntp stream */
gint
-camel_nntp_stream_line (CamelNNTPStream *is, guchar **data, guint *len)
+camel_nntp_stream_line (CamelNNTPStream *is,
+ guchar **data,
+ guint *len,
+ GError **error)
{
register guchar c, *p, *o, *oe;
gint newlen, oldlen;
@@ -299,7 +312,7 @@ camel_nntp_stream_line (CamelNNTPStream *is, guchar **data, guint *len)
/* need at least 3 chars in buffer */
while (e-p < 3) {
is->ptr = p;
- if (stream_fill (is) == -1)
+ if (nntp_stream_fill (is, error) == -1)
return -1;
p = is->ptr;
e = is->end;
@@ -329,7 +342,7 @@ camel_nntp_stream_line (CamelNNTPStream *is, guchar **data, guint *len)
/* sentinal? */
if (p> e) {
is->ptr = e;
- if (stream_fill (is) == -1)
+ if (nntp_stream_fill (is, error) == -1)
return -1;
p = is->ptr;
e = is->end;
@@ -361,7 +374,11 @@ camel_nntp_stream_line (CamelNNTPStream *is, guchar **data, guint *len)
}
/* returns -1 on error, 0 if last lot of data, >0 if more remaining */
-gint camel_nntp_stream_gets (CamelNNTPStream *is, guchar **start, guint *len)
+gint
+camel_nntp_stream_gets (CamelNNTPStream *is,
+ guchar **start,
+ guint *len,
+ GError **error)
{
gint max;
guchar *end;
@@ -370,7 +387,7 @@ gint camel_nntp_stream_gets (CamelNNTPStream *is, guchar **start, guint *len)
max = is->end - is->ptr;
if (max == 0) {
- max = stream_fill (is);
+ max = nntp_stream_fill (is, error);
if (max <= 0)
return max;
}
@@ -394,7 +411,11 @@ void camel_nntp_stream_set_mode (CamelNNTPStream *is, camel_nntp_stream_mode_t m
}
/* returns -1 on erorr, 0 if last data, >0 if more data left */
-gint camel_nntp_stream_getd (CamelNNTPStream *is, guchar **start, guint *len)
+gint
+camel_nntp_stream_getd (CamelNNTPStream *is,
+ guchar **start,
+ guint *len,
+ GError **error)
{
guchar *p, *e, *s;
gint state;
@@ -415,7 +436,7 @@ gint camel_nntp_stream_getd (CamelNNTPStream *is, guchar **start, guint *len)
while (e - p < 3) {
is->ptr = p;
- if (stream_fill (is) == -1)
+ if (nntp_stream_fill (is, 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 38171c5..b6e212d 100644
--- a/camel/providers/nntp/camel-nntp-stream.h
+++ b/camel/providers/nntp/camel-nntp-stream.h
@@ -69,15 +69,24 @@ struct _CamelNNTPStreamClass {
CamelStreamClass parent_class;
};
-GType camel_nntp_stream_get_type (void);
-
-CamelStream *camel_nntp_stream_new (CamelStream *source);
-
-void camel_nntp_stream_set_mode (CamelNNTPStream *is, camel_nntp_stream_mode_t mode);
-
-gint camel_nntp_stream_line (CamelNNTPStream *is, guchar **data, guint *len);
-gint camel_nntp_stream_gets (CamelNNTPStream *is, guchar **start, guint *len);
-gint camel_nntp_stream_getd (CamelNNTPStream *is, guchar **start, guint *len);
+GType camel_nntp_stream_get_type (void);
+
+CamelStream * camel_nntp_stream_new (CamelStream *source);
+
+void camel_nntp_stream_set_mode (CamelNNTPStream *is,
+ camel_nntp_stream_mode_t mode);
+gint camel_nntp_stream_line (CamelNNTPStream *is,
+ guchar **data,
+ guint *len,
+ GError **error);
+gint camel_nntp_stream_gets (CamelNNTPStream *is,
+ guchar **start,
+ guint *len,
+ GError **error);
+gint camel_nntp_stream_getd (CamelNNTPStream *is,
+ guchar **start,
+ guint *len,
+ GError **error);
G_END_DECLS
diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c
index b27b137..5657c1c 100644
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ b/camel/providers/nntp/camel-nntp-summary.c
@@ -268,7 +268,7 @@ 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)) > 0) {
+ while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len, error)) > 0) {
camel_operation_progress (NULL, (count * 100) / total);
count++;
n = strtoul (line, &tab, 10);
@@ -385,7 +385,7 @@ add_range_head (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
line[1] = 0;
cns->priv->uid = g_strdup_printf ("%u,%s\n", n, msgid);
if (!GPOINTER_TO_INT (g_hash_table_lookup (summary_table, cns->priv->uid))) {
- if (camel_mime_parser_init_with_stream (mp, (CamelStream *)store->stream) == -1)
+ if (camel_mime_parser_init_with_stream (mp, (CamelStream *)store->stream, error) == -1)
goto error;
mi = camel_folder_summary_add_from_parser (s, mp);
while (camel_mime_parser_step (mp, NULL, NULL) != CAMEL_MIME_PARSER_STATE_EOF)
@@ -404,23 +404,11 @@ add_range_head (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
}
ret = 0;
+
error:
+ g_prefix_error (error, _("Operation failed: "));
- if (ret == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("User cancel"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Operation failed: %s"),
- g_strerror (errno));
- }
ioerror:
-
if (cns->priv->uid) {
g_free (cns->priv->uid);
cns->priv->uid = NULL;
diff --git a/camel/providers/pop3/camel-pop3-engine.c b/camel/providers/pop3/camel-pop3-engine.c
index 993343a..028615e 100644
--- a/camel/providers/pop3/camel-pop3-engine.c
+++ b/camel/providers/pop3/camel-pop3-engine.c
@@ -271,7 +271,7 @@ engine_command_queue(CamelPOP3Engine *pe, CamelPOP3Command *pc)
}
/* ??? */
- if (camel_stream_write((CamelStream *)pe->stream, pc->data, strlen(pc->data)) == -1) {
+ if (camel_stream_write((CamelStream *)pe->stream, pc->data, strlen(pc->data), NULL) == -1) {
camel_dlist_addtail(&pe->queue, (CamelDListNode *)pc);
return FALSE;
}
@@ -352,7 +352,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)) == -1)
+ if (camel_stream_write((CamelStream *)pe->stream, pw->data, strlen(pw->data), 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 eb9b5d9..f43fc52 100644
--- a/camel/providers/pop3/camel-pop3-folder.c
+++ b/camel/providers/pop3/camel-pop3-folder.c
@@ -156,7 +156,7 @@ cmd_builduid(CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
checksum = g_checksum_new (G_CHECKSUM_MD5);
mp = camel_mime_parser_new();
- camel_mime_parser_init_with_stream(mp, (CamelStream *)stream);
+ camel_mime_parser_init_with_stream(mp, (CamelStream *)stream, NULL);
switch (camel_mime_parser_step(mp, NULL, NULL)) {
case CAMEL_MIME_PARSER_STATE_HEADER:
case CAMEL_MIME_PARSER_STATE_MESSAGE:
@@ -396,12 +396,12 @@ pop3_get_message_time_from_cache (CamelFolder *folder, const gchar *uid, time_t
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) == 1
+ && 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) == -1) {
+ 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;
@@ -504,11 +504,11 @@ cmd_tocache(CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
/* 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)) == -1)
+ if ((n = camel_stream_write (fi->stream, "*", 1, NULL)) == -1)
goto done;
- while ((n = camel_stream_read((CamelStream *)stream, buffer, sizeof(buffer))) > 0) {
- n = camel_stream_write(fi->stream, buffer, n);
+ 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;
@@ -521,8 +521,8 @@ cmd_tocache(CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
/* it all worked, output a '#' to say we're a-ok */
if (n != -1) {
- camel_stream_reset(fi->stream);
- n = camel_stream_write(fi->stream, "#", 1);
+ camel_stream_reset(fi->stream, NULL);
+ n = camel_stream_write(fi->stream, "#", 1, NULL);
}
done:
if (n == -1) {
@@ -615,7 +615,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) != 1
+ || camel_stream_read(stream, buffer, 1, NULL) != 1
|| buffer[0] != '#') {
/* Initiate retrieval, if disk backing fails, use a memory backing */
@@ -659,7 +659,7 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error)
/* getting error code? */
/*g_assert (pcr->state == CAMEL_POP3_COMMAND_DATA);*/
camel_pop3_engine_command_free(pop3_store->engine, pcr);
- camel_stream_reset(stream);
+ camel_stream_reset(stream, NULL);
/* Check to see we have safely written flag set */
if (fi->err != 0) {
@@ -677,7 +677,7 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error)
goto done;
}
- if (camel_stream_read(stream, buffer, 1) != 1 || buffer[0] != '#') {
+ if (camel_stream_read(stream, buffer, 1, NULL) != 1 || buffer[0] != '#') {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
_("Cannot get message %s: %s"),
@@ -687,18 +687,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) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("User canceled"));
- else
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_SYSTEM,
- _("Cannot get message %s: %s"),
- uid, g_strerror (errno));
+ if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, stream, error) == -1) {
+ g_prefix_error (error, _("Cannot get message %s: "), uid);
g_object_unref (message);
message = NULL;
}
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index af8601b..87ed14c 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -161,20 +161,10 @@ connect_to_server (CamelService *service,
} else
tcp_stream = camel_tcp_stream_raw_new ();
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Connection canceled"));
- else
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_SERVICE_ERROR_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host,
- g_strerror (errno));
-
+ if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai, error)) == -1) {
+ g_prefix_error (
+ error, _("Could not connect to %s: "),
+ service->url->host);
g_object_unref (tcp_stream);
return FALSE;
@@ -418,7 +408,7 @@ try_sasl (CamelPOP3Store *store,
return -1;
}
- if (camel_stream_printf((CamelStream *)stream, "AUTH %s\r\n", mech) == -1)
+ if (camel_stream_printf((CamelStream *)stream, error, "AUTH %s\r\n", mech) == -1)
goto ioerror;
while (1) {
@@ -439,7 +429,7 @@ try_sasl (CamelPOP3Store *store,
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_stream_printf((CamelStream *)stream, "*\r\n");
+ camel_stream_printf((CamelStream *)stream, NULL, "*\r\n");
camel_pop3_stream_line(stream, &line, &len);
g_set_error (
error, CAMEL_SERVICE_ERROR,
@@ -450,7 +440,7 @@ try_sasl (CamelPOP3Store *store,
goto done;
}
- ret = camel_stream_printf((CamelStream *)stream, "%s\r\n", resp);
+ ret = camel_stream_printf((CamelStream *)stream, error, "%s\r\n", resp);
g_free(resp);
if (ret == -1)
goto ioerror;
@@ -460,16 +450,10 @@ try_sasl (CamelPOP3Store *store,
return 0;
ioerror:
- if (errno == EINTR) {
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL, _("Canceled"));
- } else {
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_SYSTEM,
- _("Failed to authenticate on POP server %s: %s"),
- CAMEL_SERVICE (store)->url->host, g_strerror (errno));
- }
+ g_prefix_error (
+ error, _("Failed to authenticate on POP server %s: "),
+ CAMEL_SERVICE (store)->url->host);
+
done:
g_object_unref (sasl);
return -1;
diff --git a/camel/providers/pop3/camel-pop3-stream.c b/camel/providers/pop3/camel-pop3-stream.c
index 7413f60..780e651 100644
--- a/camel/providers/pop3/camel-pop3-stream.c
+++ b/camel/providers/pop3/camel-pop3-stream.c
@@ -76,7 +76,9 @@ stream_fill (CamelPOP3Stream *is)
memmove (is->buf, is->ptr, left);
is->end = is->buf + left;
is->ptr = is->buf;
- left = camel_stream_read (is->source, (gchar *) is->end, CAMEL_POP3_STREAM_SIZE - (is->end - is->buf));
+ left = camel_stream_read (
+ is->source, (gchar *) is->end,
+ CAMEL_POP3_STREAM_SIZE - (is->end - is->buf), NULL);
if (left > 0) {
is->end += left;
is->end[0] = '\n';
@@ -91,7 +93,7 @@ stream_fill (CamelPOP3Stream *is)
}
static gssize
-stream_read (CamelStream *stream, gchar *buffer, gsize n)
+stream_read (CamelStream *stream, gchar *buffer, gsize n, GError **error)
{
CamelPOP3Stream *is = (CamelPOP3Stream *)stream;
gchar *o, *oe;
@@ -163,7 +165,10 @@ stream_read (CamelStream *stream, gchar *buffer, gsize n)
}
static gssize
-stream_write (CamelStream *stream, const gchar *buffer, gsize n)
+stream_write (CamelStream *stream,
+ const gchar *buffer,
+ gsize n,
+ GError **error)
{
CamelPOP3Stream *is = (CamelPOP3Stream *)stream;
@@ -172,18 +177,20 @@ stream_write (CamelStream *stream, const gchar *buffer, gsize n)
else
dd (printf ("POP3_STREAM_WRITE (%d):\nPASS xxxxxxxx\n", (gint)n));
- return camel_stream_write (is->source, buffer, n);
+ return camel_stream_write (is->source, buffer, n, error);
}
static gint
-stream_close (CamelStream *stream)
+stream_close (CamelStream *stream,
+ GError **error)
{
/* nop? */
return 0;
}
static gint
-stream_flush (CamelStream *stream)
+stream_flush (CamelStream *stream,
+ GError **error)
{
/* nop? */
return 0;
@@ -198,7 +205,8 @@ stream_eos (CamelStream *stream)
}
static gint
-stream_reset (CamelStream *stream)
+stream_reset (CamelStream *stream,
+ GError **error)
{
/* nop? reset literal mode? */
return 0;
diff --git a/camel/providers/sendmail/camel-sendmail-transport.c b/camel/providers/sendmail/camel-sendmail-transport.c
index 9eb98c0..7760ef9 100644
--- a/camel/providers/sendmail/camel-sendmail-transport.c
+++ b/camel/providers/sendmail/camel-sendmail-transport.c
@@ -186,14 +186,12 @@ sendmail_send_to (CamelTransport *transport,
g_object_unref (out);
out = filter;
- if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), out) == -1
- || camel_stream_close (out) == -1) {
+ if (camel_data_wrapper_write_to_stream (
+ CAMEL_DATA_WRAPPER (message), out, error) == -1 ||
+ camel_stream_close (out, error) == -1) {
+
g_object_unref (CAMEL_OBJECT (out));
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Could not send message: %s"),
- g_strerror (errno));
+ g_prefix_error (error, _("Could not send message: "));
/* Wait for sendmail to exit. */
while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index ff9ed7c..413b171 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -231,18 +231,10 @@ connect_to_server (CamelService *service,
tcp_stream = camel_tcp_stream_raw_new ();
}
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("Connection canceled"));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Could not connect to %s: %s"),
- service->url->host, g_strerror (errno));
+ if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai, error)) == -1) {
+ g_prefix_error (
+ error, _("Could not connect to %s: "),
+ service->url->host);
g_object_unref (tcp_stream);
@@ -261,9 +253,14 @@ connect_to_server (CamelService *service,
do {
/* Check for "220" */
g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
- if (!respbuf || strncmp (respbuf, "220", 3)) {
- smtp_set_exception (transport, FALSE, respbuf, _("Welcome response error"), error);
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
+ if (respbuf == NULL)
+ return FALSE;
+ if (strncmp (respbuf, "220", 3) != 0) {
+ smtp_set_exception (
+ transport, FALSE, respbuf,
+ _("Welcome response error"), error);
g_free (respbuf);
return FALSE;
}
@@ -306,19 +303,8 @@ connect_to_server (CamelService *service,
}
d(fprintf (stderr, "sending : STARTTLS\r\n"));
- if (camel_stream_write (tcp_stream, "STARTTLS\r\n", 10) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("STARTTLS command failed: %s"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("STARTTLS command failed: %s"),
- g_strerror (errno));
+ if (camel_stream_write (tcp_stream, "STARTTLS\r\n", 10, error) == -1) {
+ g_prefix_error (error, _("STARTTLS command failed: "));
goto exception_cleanup;
}
@@ -327,12 +313,14 @@ connect_to_server (CamelService *service,
do {
/* Check for "220 Ready for TLS" */
g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "220", 3)) {
- smtp_set_exception (transport, FALSE, respbuf, _("STARTTLS command failed"), error);
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
+ if (respbuf == NULL)
+ goto exception_cleanup;
+ if (strncmp (respbuf, "220", 3) != 0) {
+ smtp_set_exception (
+ transport, FALSE, respbuf,
+ _("STARTTLS command failed"), error);
g_free (respbuf);
goto exception_cleanup;
}
@@ -932,7 +920,8 @@ smtp_set_exception (CamelSmtpTransport *transport,
g_string_append (string, token);
if (*(rbuf + 3) == '-') {
g_free (buffer);
- buffer = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
+ buffer = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), NULL);
g_string_append_c (string, '\n');
} else {
g_free (buffer);
@@ -1022,20 +1011,9 @@ smtp_helo (CamelSmtpTransport *transport, GError **error)
g_free (name);
d(fprintf (stderr, "sending : %s", cmdbuf));
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
+ if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
g_free (cmdbuf);
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("HELO command failed: %s"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("HELO command failed: %s"),
- g_strerror (errno));
+ g_prefix_error (error, _("HELO command failed: "));
camel_operation_end (NULL);
camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
@@ -1047,15 +1025,18 @@ smtp_helo (CamelSmtpTransport *transport, GError **error)
do {
/* Check for "250" */
g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
- smtp_set_exception (transport, FALSE, respbuf, _("HELO command failed"), error);
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
+ if (respbuf == NULL) {
+ camel_operation_end (NULL);
+ return FALSE;
+ }
+ if (strncmp (respbuf, "250", 3) != 0) {
+ smtp_set_exception (
+ transport, FALSE, respbuf,
+ _("HELO command failed"), error);
camel_operation_end (NULL);
g_free (respbuf);
-
return FALSE;
}
@@ -1141,46 +1122,28 @@ smtp_auth (CamelSmtpTransport *transport,
}
d(fprintf (stderr, "sending : %s", cmdbuf));
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
+ if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
g_free (cmdbuf);
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_USER_CANCEL,
- _("AUTH command failed: %s"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("AUTH command failed: %s"),
- g_strerror (errno));
+ g_prefix_error (error, _("AUTH command failed: "));
goto lose;
}
g_free (cmdbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
while (!camel_sasl_get_authenticated (sasl)) {
- if (!respbuf) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("AUTH command failed: %s"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("AUTH command failed: %s"),
- g_strerror (errno));
+
+ if (respbuf == NULL) {
+ g_prefix_error (error, _("AUTH command failed: "));
goto lose;
}
/* the server challenge/response should follow a 334 code */
if (strncmp (respbuf, "334", 3) != 0) {
- smtp_set_exception (transport, FALSE, respbuf, _("AUTH command failed"), error);
+ smtp_set_exception (
+ transport, FALSE, respbuf,
+ _("AUTH command failed"), error);
goto lose;
}
@@ -1206,19 +1169,15 @@ 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)) == -1) {
- g_set_error (
- error, CAMEL_SERVICE_ERROR,
- CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
- _("Bad authentication response from server."));
+ if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
g_free (cmdbuf);
goto lose;
}
g_free (cmdbuf);
/* get the server's response */
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
}
if (respbuf == NULL) {
@@ -1257,8 +1216,9 @@ 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);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
+ camel_stream_write (transport->ostream, "*\r\n", 3, NULL);
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), NULL);
d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
lose:
@@ -1283,22 +1243,10 @@ 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)) == -1) {
+ if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
g_free (cmdbuf);
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_USER_CANCEL,
- _("MAIL FROM command failed: %s: mail not sent"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("MAIL FROM command failed: %s: mail not sent"),
- g_strerror (errno));
-
+ g_prefix_error (error, _("MAIL FROM command failed: "));
camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
-
return FALSE;
}
g_free (cmdbuf);
@@ -1306,12 +1254,14 @@ smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit
do {
/* Check for "250 Sender OK..." */
g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
- smtp_set_exception (transport, TRUE, respbuf, _("MAIL FROM command failed"), error);
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
+ if (respbuf == NULL)
+ return FALSE;
+ if (strncmp (respbuf, "250", 3) != 0) {
+ smtp_set_exception (
+ transport, TRUE, respbuf,
+ _("MAIL FROM command failed"), error);
g_free (respbuf);
return FALSE;
}
@@ -1332,20 +1282,9 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error
d(fprintf (stderr, "sending : %s", cmdbuf));
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
+ if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
g_free (cmdbuf);
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_USER_CANCEL,
- _("RCPT TO command failed: %s: mail not sent"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("RCPT TO command failed: %s: mail not sent"),
- g_strerror (errno));
-
+ g_prefix_error (error, _("RCPT TO command failed: "));
camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
return FALSE;
@@ -1355,17 +1294,20 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error
do {
/* Check for "250 Recipient OK..." */
g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
+ if (respbuf == NULL)
+ return FALSE;
+ if (strncmp (respbuf, "250", 3) != 0) {
gchar *message;
- message = g_strdup_printf (_("RCPT TO <%s> failed"), recipient);
- smtp_set_exception (transport, TRUE, respbuf, message, error);
+ message = g_strdup_printf (
+ _("RCPT TO <%s> failed"), recipient);
+ smtp_set_exception (
+ transport, TRUE, respbuf, message, error);
g_free (message);
g_free (respbuf);
+
return FALSE;
}
} while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */
@@ -1401,35 +1343,25 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
d(fprintf (stderr, "sending : %s", cmdbuf));
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
+ if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
g_free (cmdbuf);
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_USER_CANCEL,
- _("DATA command failed: %s: mail not sent"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("DATA command failed: %s: mail not sent"),
- g_strerror (errno));
-
+ g_prefix_error (error, _("DATA command failed: "));
camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
-
return FALSE;
}
g_free (cmdbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "354", 3)) {
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
+ if (respbuf == NULL)
+ return FALSE;
+ if (strncmp (respbuf, "354", 3) != 0) {
/* we should have gotten instructions on how to use the DATA command:
* 354 Enter mail, end with "." on a line by itself
*/
- smtp_set_exception (transport, TRUE, respbuf, _("DATA command failed"), error);
+ smtp_set_exception (
+ transport, TRUE, respbuf,
+ _("DATA command failed"), error);
g_free (respbuf);
return FALSE;
}
@@ -1445,7 +1377,7 @@ 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));
+ CAMEL_DATA_WRAPPER (message), CAMEL_STREAM (null), NULL);
filtered_stream = camel_stream_filter_new (transport->ostream);
@@ -1466,65 +1398,42 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
/* write the message */
ret = camel_data_wrapper_write_to_stream (
- CAMEL_DATA_WRAPPER (message), filtered_stream);
+ CAMEL_DATA_WRAPPER (message), filtered_stream, error);
/* restore the bcc headers */
camel_header_raw_append_queue (header_queue, &bcc_queue);
if (ret == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_USER_CANCEL,
- _("DATA command failed: %s: mail not sent"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("DATA command failed: %s: mail not sent"),
- g_strerror (errno));
-
+ g_prefix_error (error, _("DATA command failed: "));
g_object_unref (filtered_stream);
-
camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
-
return FALSE;
}
- camel_stream_flush (filtered_stream);
+ camel_stream_flush (filtered_stream, 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) == -1) {
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR, CAMEL_ERROR_USER_CANCEL,
- _("DATA command failed: %s: mail not sent"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("DATA command failed: %s: mail not sent"),
- g_strerror (errno));
-
+ if (camel_stream_write (transport->ostream, "\r\n.\r\n", 5, error) == -1) {
+ g_prefix_error (error, _("DATA command failed: "));
camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
-
return FALSE;
}
do {
/* Check for "250 Sender OK..." */
g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
- smtp_set_exception (transport, TRUE, respbuf, _("DATA command failed"), error);
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
+ if (respbuf == NULL)
+ return FALSE;
+ if (strncmp (respbuf, "250", 3) != 0) {
+ smtp_set_exception (
+ transport, TRUE, respbuf,
+ _("DATA command failed"), error);
g_free (respbuf);
return FALSE;
}
@@ -1544,23 +1453,10 @@ smtp_rset (CamelSmtpTransport *transport, GError **error)
d(fprintf (stderr, "sending : %s", cmdbuf));
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
+ if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
g_free (cmdbuf);
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("RSET command failed: %s"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("RSET command failed: %s"),
- g_strerror (errno));
-
+ g_prefix_error (error, _("RSET command failed: "));
camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
-
return FALSE;
}
g_free (cmdbuf);
@@ -1568,11 +1464,11 @@ smtp_rset (CamelSmtpTransport *transport, GError **error)
do {
/* Check for "250" */
g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
+ if (respbuf == NULL)
+ return FALSE;
+ if (strncmp (respbuf, "250", 3) != 0) {
smtp_set_exception (
transport, TRUE, respbuf,
_("RSET command failed"), error);
@@ -1595,21 +1491,9 @@ smtp_quit (CamelSmtpTransport *transport, GError **error)
d(fprintf (stderr, "sending : %s", cmdbuf));
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
+ if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
g_free (cmdbuf);
- if (errno == EINTR)
- g_set_error (
- error, CAMEL_ERROR,
- CAMEL_ERROR_USER_CANCEL,
- _("QUIT command failed: %s"),
- g_strerror (errno));
- else
- g_set_error (
- error, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("QUIT command failed: %s"),
- g_strerror (errno));
-
+ g_prefix_error (error, _("QUIT command failed: "));
return FALSE;
}
g_free (cmdbuf);
@@ -1617,11 +1501,11 @@ smtp_quit (CamelSmtpTransport *transport, GError **error)
do {
/* Check for "221" */
g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "221", 3)) {
+ respbuf = camel_stream_buffer_read_line (
+ CAMEL_STREAM_BUFFER (transport->istream), error);
+ if (respbuf == NULL)
+ return FALSE;
+ if (strncmp (respbuf, "221", 3) != 0) {
smtp_set_exception (
transport, FALSE, respbuf,
_("QUIT command failed"), error);
diff --git a/docs/reference/calendar/libedata-cal/tmpl/e-data-cal-common.sgml b/docs/reference/calendar/libedata-cal/tmpl/e-data-cal-common.sgml
index 5da7a51..5a9808a 100644
--- a/docs/reference/calendar/libedata-cal/tmpl/e-data-cal-common.sgml
+++ b/docs/reference/calendar/libedata-cal/tmpl/e-data-cal-common.sgml
@@ -79,6 +79,7 @@ e-data-cal-common
@get_ldap_attribute:
@get_static_capabilities:
@open:
+ refresh:
@remove:
@create_object:
@modify_object:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]