aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNotZed <NotZed@HelixCode.com>2000-04-22 13:22:20 +0800
committerMichael Zucci <zucchi@src.gnome.org>2000-04-22 13:22:20 +0800
commit0d82053015309f173335c41052356f20ef1c6227 (patch)
treee8013c96a9b77ea821f59e8df4e4aa1a84bac685
parent05a7bb9ef8ed8327fde0b04a0cab854d2c4a5d36 (diff)
downloadgsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.tar.gz
gsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.tar.zst
gsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.zip
Ref the folder after setting it in the new message.
2000-04-22 NotZed <NotZed@HelixCode.com> * providers/mbox/camel-mbox-folder.c (_get_message_by_uid): Ref the folder after setting it in the new message. * camel-mime-part.c (my_set_content_object): Have the headers follow the content-type change here too. (my_write_to_stream): Dont write content-type here, automatically stored in the headers ... (my_write_to_stream): Use header_disposition_format() to format the content-disposition header. (my_write_to_stream): Removed old code, all headers are now stored in the camel-medium level, always. Need to do the same with camel-mime-message i suppose ... * camel-mime-utils.c (header_content_type_is): Handle empty types. * gmime-content-field.c (gmime_content_field_write_to_stream): Use header_content_type_format() to format it. 2000-04-21 NotZed <NotZed@HelixCode.com> * camel-mime-utils.h: Add prototype for header_param_list_free. * camel-recipient.c: New function to remove all the types of a recipient list. I think this whole object needs a major review. * camel-mime-message.c (camel_mime_message_class_init): Removed parse_header_pair override, override add_header instead. (_parse_header_pair): Renamed to add_header. (remove_header): Add this method, to make sure we keep upto date with removed headers too. (_set_field): If given a NULL value, clear it out. (_set_recipient_list_from_string): Constify. (set_header): Override set_header from camel_medium. (process_header): Local function to handle set/add/remove of each header we know about. * camel-mime-part.c (camel_mime_part_class_init): Removed parse_header_pair setup. (my_parse_header_pair): Moved into add_header(), removed. (my_set_disposition): Allow a NULL disposition to clear it. (my_set_content_id): Allow NULL content id to clear it. (remove_header): Track removed headers. (my_set_description): Allow NULL description to clear it. (my_set_content_MD5): Make sure we copy the md5 value, and allow a NULL value to reset it. (my_set_filename): Copy the filename. (my_set_header_lines): Removed. Nothing uses it, it doesn't actually serve any purpose. (camel_mime_part_set_header_lines): Ditto. (my_get_header_lines): Ditto. (camel_mime_part_get_header_lines): Ditto. (camel_mime_part_class_init): Remove *_header_lines setup. (camel_mime_part_init): Remove header_lines init. (my_finalize): Remove header_lines finalise. (my_write_to_stream): Write the headers here. This is just WRONG, camel_medium should be doing this. (my_get_output_stream): Kill a warning. (camel_mime_part_encoding_to_string): Ditto. (camel_mime_part_set_description): Unvirtualiase, use add_header() to do the processing. (my_set_description): Removed. (set_disposition): Renamed from my_set_disposition. (camel_mime_part_get_description): Get the descriptionf rom the get_header method. (my_get_description): Removed. (my_set_filename): Removed. (camel_mime_part_get_filename): Get the parameter from the disposition. (camel_mime_part_encoding_from_string): Handle NULL string. (camel_mime_part_init): Remove reference to filename. (my_finalize): Dont free filename. * camel-mime-part.h (CamelMimePartClass): Removed parse_header_pair() method, it doesn't add anything that add_header() can't be used for. (CamelMimePartClass): Remove *_header_lines methods. (struct _CamelMimePart): Remove header_lines list. (struct _CamelMimePart): Removed filename attribute. * camel-medium.c (camel_medium_init): Init headers to null, not a hashtable. (add_header): Append the headers as a list. (remove_header): Remove headers as a list. (get_header): Likewise for lookup. (free_header): Removed, no longer needed. (finalize): Free headers using header_raw_clear(). (camel_medium_set_header): New function, to reset and override all values of a header with a new value. * camel-medium.h (struct _CamelMedium): Changed to use a header_raw struct rather than a hash table, to store headers (many headers can occur multiple times). * camel-mime-utils.c (header_raw_find_next): New function, allows you to find multi-valued header fields. (header_disposition_format): New function to format/create content-disposition header string. (header_param_list_format_append): Function to format parameter lists into a GString. (header_content_type_format): Function to format content-type into a usable format. (header_set_param): allow NULL value to remove the parameter. (decode_token): Renamed from header_decode_token. (header_decode_token): New interface for external use. (quoted_decode): Made static to kill annoying warnings. (g_strdup_len): Killed, replaced with calls to g_strndup(). (rfc2047_decode_word): Made static to kill warnings. (decode_coded_string): Terminated. (g_string_append_len): Made static to kill warnings. (header_decode_text): Made static to kill warnings. (header_decode_text): Constify. (rfc2047_decode_word): Constify. (header_param): Constify. (header_content_type_new): Copy the type/subtype strings. (header_param_list_decode): Made static. (header_param_list_format_append): Made static. (quoted_decode): Constify. (g_string_append_len): Constify. (header_token_decode): New function to decode a single token. * providers/mbox/camel-mbox-summary.c (header_write): Append a trailing \n when writing headers. (strdup_trim): Killed a warning. (camel_mbox_summary_set_uid): Make sure the next uid is at least 1 higher than any existing one. (header_evolution_decode): Use header_token_decode to get the token. * camel-mime-parser.c (folder_scan_header): Strip the trailing \n of the end of all header lines. svn path=/trunk/; revision=2551
-rw-r--r--camel/ChangeLog133
-rw-r--r--camel/camel-medium.c86
-rw-r--r--camel/camel-medium.h31
-rw-r--r--camel/camel-mime-message.c93
-rw-r--r--camel/camel-mime-parser.c4
-rw-r--r--camel/camel-mime-part.c538
-rw-r--r--camel/camel-mime-part.h55
-rw-r--r--camel/camel-mime-utils.c202
-rw-r--r--camel/camel-mime-utils.h20
-rw-r--r--camel/camel-recipient.c28
-rw-r--r--camel/camel-recipient.h3
-rw-r--r--camel/gmime-content-field.c21
-rw-r--r--camel/providers/mbox/camel-mbox-folder.c1
-rw-r--r--camel/providers/mbox/camel-mbox-summary.c17
14 files changed, 655 insertions, 577 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 3575fe6f52..bc276d86a1 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,136 @@
+2000-04-22 NotZed <NotZed@HelixCode.com>
+
+ * providers/mbox/camel-mbox-folder.c (_get_message_by_uid): Ref
+ the folder after setting it in the new message.
+
+ * camel-mime-part.c (my_set_content_object): Have the headers
+ follow the content-type change here too.
+ (my_write_to_stream): Dont write content-type here, automatically
+ stored in the headers ...
+ (my_write_to_stream): Use header_disposition_format() to format
+ the content-disposition header.
+ (my_write_to_stream): Removed old code, all headers are now stored
+ in the camel-medium level, always. Need to do the same with
+ camel-mime-message i suppose ...
+
+ * camel-mime-utils.c (header_content_type_is): Handle empty types.
+
+ * gmime-content-field.c (gmime_content_field_write_to_stream): Use
+ header_content_type_format() to format it.
+
+2000-04-21 NotZed <NotZed@HelixCode.com>
+
+ * camel-mime-utils.h: Add prototype for header_param_list_free.
+
+ * camel-recipient.c: New function to remove all the types of a
+ recipient list. I think this whole object needs a major review.
+
+ * camel-mime-message.c (camel_mime_message_class_init): Removed
+ parse_header_pair override, override add_header instead.
+ (_parse_header_pair): Renamed to add_header.
+ (remove_header): Add this method, to make sure we keep upto date
+ with removed headers too.
+ (_set_field): If given a NULL value, clear it out.
+ (_set_recipient_list_from_string): Constify.
+ (set_header): Override set_header from camel_medium.
+ (process_header): Local function to handle set/add/remove of each
+ header we know about.
+
+ * camel-mime-part.c (camel_mime_part_class_init): Removed
+ parse_header_pair setup.
+ (my_parse_header_pair): Moved into add_header(), removed.
+ (my_set_disposition): Allow a NULL disposition to clear it.
+ (my_set_content_id): Allow NULL content id to clear it.
+ (remove_header): Track removed headers.
+ (my_set_description): Allow NULL description to clear it.
+ (my_set_content_MD5): Make sure we copy the md5 value, and allow a
+ NULL value to reset it.
+ (my_set_filename): Copy the filename.
+ (my_set_header_lines): Removed. Nothing uses it, it doesn't
+ actually serve any purpose.
+ (camel_mime_part_set_header_lines): Ditto.
+ (my_get_header_lines): Ditto.
+ (camel_mime_part_get_header_lines): Ditto.
+ (camel_mime_part_class_init): Remove *_header_lines setup.
+ (camel_mime_part_init): Remove header_lines init.
+ (my_finalize): Remove header_lines finalise.
+ (my_write_to_stream): Write the headers here. This is just WRONG,
+ camel_medium should be doing this.
+ (my_get_output_stream): Kill a warning.
+ (camel_mime_part_encoding_to_string): Ditto.
+ (camel_mime_part_set_description): Unvirtualiase, use add_header()
+ to do the processing.
+ (my_set_description): Removed.
+ (set_disposition): Renamed from my_set_disposition.
+ (camel_mime_part_get_description): Get the descriptionf rom the
+ get_header method.
+ (my_get_description): Removed.
+ (my_set_filename): Removed.
+ (camel_mime_part_get_filename): Get the parameter from the
+ disposition.
+ (camel_mime_part_encoding_from_string): Handle NULL string.
+ (camel_mime_part_init): Remove reference to filename.
+ (my_finalize): Dont free filename.
+
+ * camel-mime-part.h (CamelMimePartClass): Removed
+ parse_header_pair() method, it doesn't add anything that
+ add_header() can't be used for.
+ (CamelMimePartClass): Remove *_header_lines methods.
+ (struct _CamelMimePart): Remove header_lines list.
+ (struct _CamelMimePart): Removed filename attribute.
+
+ * camel-medium.c (camel_medium_init): Init headers to null, not a
+ hashtable.
+ (add_header): Append the headers as a list.
+ (remove_header): Remove headers as a list.
+ (get_header): Likewise for lookup.
+ (free_header): Removed, no longer needed.
+ (finalize): Free headers using header_raw_clear().
+ (camel_medium_set_header): New function, to reset and override all
+ values of a header with a new value.
+
+ * camel-medium.h (struct _CamelMedium): Changed to use a
+ header_raw struct rather than a hash table, to store headers
+ (many headers can occur multiple times).
+
+ * camel-mime-utils.c (header_raw_find_next): New function, allows
+ you to find multi-valued header fields.
+ (header_disposition_format): New function to format/create
+ content-disposition header string.
+ (header_param_list_format_append): Function to format parameter
+ lists into a GString.
+ (header_content_type_format): Function to format content-type into
+ a usable format.
+ (header_set_param): allow NULL value to remove the parameter.
+ (decode_token): Renamed from header_decode_token.
+ (header_decode_token): New interface for external use.
+ (quoted_decode): Made static to kill annoying warnings.
+ (g_strdup_len): Killed, replaced with calls to g_strndup().
+ (rfc2047_decode_word): Made static to kill warnings.
+ (decode_coded_string): Terminated.
+ (g_string_append_len): Made static to kill warnings.
+ (header_decode_text): Made static to kill warnings.
+ (header_decode_text): Constify.
+ (rfc2047_decode_word): Constify.
+ (header_param): Constify.
+ (header_content_type_new): Copy the type/subtype strings.
+ (header_param_list_decode): Made static.
+ (header_param_list_format_append): Made static.
+ (quoted_decode): Constify.
+ (g_string_append_len): Constify.
+ (header_token_decode): New function to decode a single token.
+
+ * providers/mbox/camel-mbox-summary.c (header_write): Append a
+ trailing \n when writing headers.
+ (strdup_trim): Killed a warning.
+ (camel_mbox_summary_set_uid): Make sure the next uid is at least 1
+ higher than any existing one.
+ (header_evolution_decode): Use header_token_decode to get the
+ token.
+
+ * camel-mime-parser.c (folder_scan_header): Strip the trailing \n
+ of the end of all header lines.
+
2000-04-20 NotZed <NotZed@HelixCode.com>
* providers/mbox/camel-mbox-utils.[ch]: Removed.
diff --git a/camel/camel-medium.c b/camel/camel-medium.c
index 1fd77c28ad..fe87911b14 100644
--- a/camel/camel-medium.c
+++ b/camel/camel-medium.c
@@ -3,8 +3,8 @@
/*
*
- * Author :
- * Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Michael Zucchi <notzed@helixcode.com>
*
* Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com)
*
@@ -40,6 +40,7 @@ static CamelDataWrapperClass *parent_class = NULL;
static void add_header (CamelMedium *medium, const gchar *header_name,
const gchar *header_value);
+static void set_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value);
static void remove_header (CamelMedium *medium, const gchar *header_name);
static const gchar *get_header (CamelMedium *medium, const gchar *header_name);
@@ -61,6 +62,7 @@ camel_medium_class_init (CamelMediumClass *camel_medium_class)
/* virtual method definition */
camel_medium_class->add_header = add_header;
+ camel_medium_class->set_header = set_header;
camel_medium_class->remove_header = remove_header;
camel_medium_class->get_header = get_header;
@@ -75,8 +77,7 @@ camel_medium_init (gpointer object, gpointer klass)
{
CamelMedium *camel_medium = CAMEL_MEDIUM (object);
- camel_medium->headers = g_hash_table_new (g_strcase_hash,
- g_strcase_equal);
+ camel_medium->headers = NULL;
camel_medium->content = NULL;
}
@@ -105,23 +106,12 @@ camel_medium_get_type (void)
return camel_medium_type;
}
-
-static void
-free_header (gpointer key, gpointer value, gpointer data)
-{
- g_free (key);
- g_free (value);
-}
-
static void
finalize (GtkObject *object)
{
CamelMedium *medium = CAMEL_MEDIUM (object);
- if (medium->headers) {
- g_hash_table_foreach (medium->headers, free_header, NULL);
- g_hash_table_destroy (medium->headers);
- }
+ header_raw_clear(&medium->headers);
if (medium->content)
gtk_object_unref (GTK_OBJECT (medium->content));
@@ -129,24 +119,11 @@ finalize (GtkObject *object)
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
-
-
static void
add_header (CamelMedium *medium, const gchar *header_name,
const gchar *header_value)
{
- gpointer old_name;
- gpointer old_value;
-
- /* FIXME: This only allows each header to occur once. */
- if (g_hash_table_lookup_extended (medium->headers, header_name,
- &old_name, &old_value)) {
- g_hash_table_remove (medium->headers, old_name);
- g_free (old_name);
- g_free (old_value);
- }
- g_hash_table_insert (medium->headers, g_strdup (header_name),
- g_strdup (header_value));
+ header_raw_append(&medium->headers, header_name, header_value, -1);
}
/**
@@ -159,7 +136,7 @@ add_header (CamelMedium *medium, const gchar *header_name,
*
* FIXME: Where does it add it? We need to be able to prepend and
* append headers, and also be able to insert them relative to other
- * headers.
+ * headers. No we dont, order isn't important! Z
**/
void
camel_medium_add_header (CamelMedium *medium, const gchar *header_name,
@@ -172,20 +149,35 @@ camel_medium_add_header (CamelMedium *medium, const gchar *header_name,
CM_CLASS (medium)->add_header (medium, header_name, header_value);
}
+static void
+set_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value)
+{
+ header_raw_replace(&medium->headers, header_name, header_value, -1);
+}
+
+/**
+ * camel_medium_set_header:
+ * @medium: a CamelMedium
+ * @header_name: name of the header
+ * @header_value: value of the header
+ *
+ * Sets the value of a header. Any other occurances of the header
+ * will be removed.
+ **/
+void
+camel_medium_set_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value)
+{
+ g_return_if_fail (CAMEL_IS_MEDIUM (medium));
+ g_return_if_fail (header_name != NULL);
+ g_return_if_fail (header_value != NULL);
+
+ CM_CLASS (medium)->add_header (medium, header_name, header_value);
+}
static void
remove_header (CamelMedium *medium, const gchar *header_name)
{
- gpointer old_name;
- gpointer old_value;
-
- /* FIXME: This only allows each header to occur once. */
- if (g_hash_table_lookup_extended (medium->headers, header_name,
- &old_name, &old_value)) {
- g_hash_table_remove (medium->headers, header_name);
- g_free (old_name);
- g_free (old_value);
- }
+ header_raw_remove(&medium->headers, header_name);
}
/**
@@ -193,10 +185,8 @@ remove_header (CamelMedium *medium, const gchar *header_name)
* @medium: a medium
* @header_name: the name of the header
*
- * Removes the named header from the medium.
- *
- * FIXME: If there are multiple occurrences of the header, which
- * gets/get removed?
+ * Removes the named header from the medium. All occurances of the
+ * header are removed.
**/
void
camel_medium_remove_header (CamelMedium *medium, const gchar *header_name)
@@ -211,11 +201,7 @@ camel_medium_remove_header (CamelMedium *medium, const gchar *header_name)
static const gchar *
get_header (CamelMedium *medium, const gchar *header_name)
{
- gchar *header_value;
-
- header_value = (gchar *)g_hash_table_lookup (medium->headers,
- header_name);
- return header_value;
+ return header_raw_find(&medium->headers, header_name, NULL);
}
/**
diff --git a/camel/camel-medium.h b/camel/camel-medium.h
index 7c85bd2ed7..91693439e2 100644
--- a/camel/camel-medium.h
+++ b/camel/camel-medium.h
@@ -3,8 +3,8 @@
/*
*
- * Author :
- * Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Michael Zucchi <notzed@helixcode.com>
*
* Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com)
*
@@ -35,8 +35,9 @@ extern "C" {
#endif /* __cplusplus }*/
#include <gtk/gtk.h>
-#include "camel-types.h"
-#include "camel-data-wrapper.h"
+#include <camel/camel-types.h>
+#include <camel/camel-data-wrapper.h>
+#include <camel/camel-mime-utils.h>
#define CAMEL_MEDIUM_TYPE (camel_medium_get_type ())
#define CAMEL_MEDIUM(obj) (GTK_CHECK_CAST((obj), CAMEL_MEDIUM_TYPE, CamelMedium))
@@ -48,7 +49,7 @@ struct _CamelMedium
{
CamelDataWrapper parent_object;
- GHashTable *headers;
+ struct _header_raw *headers;
/* The content of the medium, as opposed to our parent
* CamelDataWrapper, which wraps both the headers and the
@@ -64,15 +65,13 @@ typedef struct {
CamelDataWrapperClass parent_class;
/* Virtual methods */
- void (*add_header) (CamelMedium *medium, const gchar *header_name,
- const gchar *header_value);
+ void (*add_header) (CamelMedium *medium, const gchar *header_name, const gchar *header_value);
+ void (*set_header) (CamelMedium *medium, const gchar *header_name, const gchar *header_value);
void (*remove_header) (CamelMedium *medium, const gchar *header_name);
- const gchar * (*get_header) (CamelMedium *medium,
- const gchar *header_name);
+ const gchar * (*get_header) (CamelMedium *medium, const gchar *header_name);
CamelDataWrapper * (*get_content_object) (CamelMedium *medium);
- void (*set_content_object) (CamelMedium *medium,
- CamelDataWrapper *content);
+ void (*set_content_object) (CamelMedium *medium, CamelDataWrapper *content);
} CamelMediumClass;
@@ -83,12 +82,10 @@ GtkType camel_medium_get_type (void);
/* public methods */
-void camel_medium_add_header (CamelMedium *medium, const gchar *header_name,
- const gchar *header_value);
-void camel_medium_remove_header (CamelMedium *medium,
- const gchar *header_name);
-const gchar *camel_medium_get_header (CamelMedium *medium,
- const gchar *header_name);
+void camel_medium_add_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value);
+void camel_medium_set_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value);
+void camel_medium_remove_header (CamelMedium *medium, const gchar *header_name);
+const gchar *camel_medium_get_header (CamelMedium *medium, const gchar *header_name);
CamelDataWrapper *camel_medium_get_content_object (CamelMedium *medium);
diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c
index 88a0828973..7ae14766d5 100644
--- a/camel/camel-mime-message.c
+++ b/camel/camel-mime-message.c
@@ -72,8 +72,10 @@ static GList *_get_flag_list (CamelMimeMessage *mime_message);
static void _set_message_number (CamelMimeMessage *mime_message, guint number);
static guint _get_message_number (CamelMimeMessage *mime_message);
static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
-static gboolean _parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_value);
static void _finalize (GtkObject *object);
+static void add_header (CamelMedium *medium, const char *header_name, const char *header_value);
+static void set_header (CamelMedium *medium, const char *header_name, const char *header_value);
+static void remove_header (CamelMedium *medium, const char *header_name);
/* Returns the class for a CamelMimeMessage */
#define CMM_CLASS(so) CAMEL_MIME_MESSAGE_CLASS (GTK_OBJECT(so)->klass)
@@ -97,8 +99,9 @@ static void
camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class)
{
CamelDataWrapperClass *camel_data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (camel_mime_message_class);
- CamelMimePartClass *camel_mime_part_class = CAMEL_MIME_PART_CLASS (camel_mime_message_class);
+ /*CamelMimePartClass *camel_mime_part_class = CAMEL_MIME_PART_CLASS (camel_mime_message_class);*/
GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_mime_message_class);
+ CamelMediumClass *camel_medium_class = CAMEL_MEDIUM_CLASS (camel_mime_message_class);
parent_class = gtk_type_class (camel_mime_part_get_type ());
_init_header_name_table();
@@ -130,7 +133,10 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class)
/* virtual method overload */
camel_data_wrapper_class->write_to_stream = _write_to_stream;
- camel_mime_part_class->parse_header_pair = _parse_header_pair;
+
+ camel_medium_class->add_header = add_header;
+ camel_medium_class->set_header = set_header;
+ camel_medium_class->remove_header = remove_header;
gtk_object_class->finalize = _finalize;
}
@@ -223,7 +229,10 @@ _set_field (CamelMimeMessage *mime_message, gchar *name, const gchar *value, gch
{
if (variable) {
g_free (*variable);
- *variable = g_strdup (value);
+ if (value)
+ *variable = g_strdup (value);
+ else
+ *variable = NULL;
}
}
@@ -579,6 +588,7 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
{
CamelMimeMessage *mm = CAMEL_MIME_MESSAGE (data_wrapper);
+#warning each header should be stored in the raw headers
WHPT (stream, "From", mm->from);
WHPT (stream, "Reply-To", mm->reply_to);
_write_recipients_to_stream (mm, stream);
@@ -595,11 +605,13 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
/*******************************/
/* mime message header parsing */
+/* FIXME: This is totally totally broken */
static void
-_set_recipient_list_from_string (CamelMimeMessage *message, gchar *recipient_type, gchar *recipients_string)
+_set_recipient_list_from_string (CamelMimeMessage *message, const char *recipient_type, const char *recipients_string)
{
GList *recipients_list;
+#warning need to parse receipient lists properly - <feddy>BROKEN!!!</feddy>
recipients_list = string_split (
recipients_string, ',', "\t ",
STRING_TRIM_STRIP_TRAILING | STRING_TRIM_STRIP_LEADING);
@@ -608,54 +620,69 @@ _set_recipient_list_from_string (CamelMimeMessage *message, gchar *recipient_typ
}
+/* FIXME: check format of fields. */
static gboolean
-_parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_value)
+process_header(CamelMedium *medium, const char *header_name, const char *header_value)
{
CamelHeaderType header_type;
- CamelMimeMessage *message = CAMEL_MIME_MESSAGE (mime_part);
- gboolean header_handled = FALSE;
-
-
+ CamelMimeMessage *message = CAMEL_MIME_MESSAGE (medium);
+
header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, header_name);
switch (header_type) {
-
case HEADER_FROM:
camel_mime_message_set_from (message, header_value);
- header_handled = TRUE;
break;
-
case HEADER_REPLY_TO:
camel_mime_message_set_reply_to (message, header_value);
- header_handled = TRUE;
break;
-
case HEADER_SUBJECT:
camel_mime_message_set_subject (message, header_value);
- header_handled = TRUE;
break;
-
case HEADER_TO:
- _set_recipient_list_from_string (message, "To", header_value);
- header_handled = TRUE;
+ if (header_value)
+ _set_recipient_list_from_string (message, "To", header_value);
+ else
+ camel_recipient_table_remove_type (message->recipients, "To");
break;
-
case HEADER_CC:
- _set_recipient_list_from_string (message, "Cc", header_value);
- header_handled = TRUE;
+ if (header_value)
+ _set_recipient_list_from_string (message, "Cc", header_value);
+ else
+ camel_recipient_table_remove_type (message->recipients, "Cc");
break;
-
case HEADER_BCC:
- _set_recipient_list_from_string (message, "Bcc", header_value);
- header_handled = TRUE;
+ if (header_value)
+ _set_recipient_list_from_string (message, "Bcc", header_value);
+ else
+ camel_recipient_table_remove_type (message->recipients, "Bcc");
break;
-
-
+ default:
+ return FALSE;
}
- if (header_handled) {
- return TRUE;
- } else
- return parent_class->parse_header_pair (mime_part, header_name, header_value);
-
-
+ return TRUE;
+}
+
+static void
+set_header(CamelMedium *medium, const char *header_name, const char *header_value)
+{
+ process_header(medium, header_name, header_value);
+ parent_class->parent_class.set_header (medium, header_name, header_value);
+}
+
+static void
+add_header(CamelMedium *medium, const char *header_name, const char *header_value)
+{
+ /* if we process it, then it must be forced unique as well ... */
+ if (process_header(medium, header_name, header_value))
+ parent_class->parent_class.set_header (medium, header_name, header_value);
+ else
+ parent_class->parent_class.add_header (medium, header_name, header_value);
+}
+
+static void
+remove_header(CamelMedium *medium, const char *header_name)
+{
+ process_header(medium, header_name, NULL);
+ parent_class->parent_class.remove_header (medium, header_name);
}
diff --git a/camel/camel-mime-parser.c b/camel/camel-mime-parser.c
index cee6454707..3ed9dde427 100644
--- a/camel/camel-mime-parser.c
+++ b/camel/camel-mime-parser.c
@@ -613,6 +613,8 @@ retry:
goto header_done;
}
+ if (s->outptr[0] == '\n' && s->outptr>s->outbuf)
+ s->outptr--;
s->outptr[0] = 0;
d(printf("header %.10s at %d\n", s->outbuf, s->header_start));
@@ -674,6 +676,8 @@ header_truncated:
memcpy(s->outptr, start, headerlen);
s->outptr += headerlen;
}
+ if (s->outptr[0] == '\n' && s->outptr>s->outbuf)
+ s->outptr--;
s->outptr[0] = 0;
if (s->header_start == -1)
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index 67be67d248..bda4f932ed 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -1,11 +1,9 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* camelMimePart.c : Abstract class for a mime_part */
-
/*
- *
- * Author :
- * Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Michael Zucchi <notzed@helixcode.com>
*
* Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com)
*
@@ -25,9 +23,6 @@
* USA
*/
-
-
-
#include <config.h>
#include <string.h>
#include "camel-mime-part.h"
@@ -42,7 +37,7 @@
#include "camel-seekable-substream.h"
#include "camel-stream-filter.h"
#include "camel-mime-filter-basic.h"
-
+#include <ctype.h>
typedef enum {
HEADER_UNKNOWN,
@@ -64,6 +59,7 @@ static CamelMediumClass *parent_class=NULL;
/* Returns the class for a CamelMimePart */
#define CMP_CLASS(so) CAMEL_MIME_PART_CLASS (GTK_OBJECT(so)->klass)
#define CDW_CLASS(so) CAMEL_DATA_WRAPPER_CLASS (GTK_OBJECT(so)->klass)
+#define CMD_CLASS(so) CAMEL_MEDIUM_CLASS (GTK_OBJECT(so)->klass)
/* from GtkObject */
static void my_finalize (GtkObject *object);
@@ -79,49 +75,16 @@ static CamelStream * my_get_output_stream (CamelDataWrapper *data_w
/* from CamelMedia */
-static void my_add_header (CamelMedium *medium,
- gchar *header_name,
- gchar *header_value);
+static void add_header (CamelMedium *medium, const char *header_name, const char *header_value);
+static void set_header (CamelMedium *medium, const char *header_name, const char *header_value);
+static void remove_header (CamelMedium *medium, const char *header_name);
static void my_set_content_object (CamelMedium *medium,
CamelDataWrapper *content);
static CamelDataWrapper *my_get_content_object (CamelMedium *medium);
-
-
-/* from CamelMimePart */
-static void my_set_description (CamelMimePart *mime_part,
- const gchar *description);
-static const gchar * my_get_description (CamelMimePart *mime_part);
-static void my_set_disposition (CamelMimePart *mime_part,
- const gchar *disposition);
-static const gchar * my_get_disposition (CamelMimePart *mime_part);
-static void my_set_filename (CamelMimePart *mime_part,
- gchar *filename);
-static const gchar * my_get_filename (CamelMimePart *mime_part);
-static void my_set_content_id (CamelMimePart *mime_part,
- gchar *content_id);
-static const gchar * my_get_content_id (CamelMimePart *mime_part);
-static void my_set_content_MD5 (CamelMimePart *mime_part,
- gchar *content_MD5);
-static const gchar * my_get_content_MD5 (CamelMimePart *mime_part);
-static void my_set_encoding (CamelMimePart *mime_part,
- CamelMimePartEncodingType encoding);
-static CamelMimePartEncodingType my_get_encoding (CamelMimePart *mime_part);
-static void my_set_content_languages (CamelMimePart *mime_part,
- GList *content_languages);
-static const GList * my_get_content_languages (CamelMimePart *mime_part);
-static void my_set_header_lines (CamelMimePart *mime_part,
- GList *header_lines);
-static const GList * my_get_header_lines (CamelMimePart *mime_part);
-static void my_set_content_type (CamelMimePart *mime_part,
- const gchar *content_type);
-static GMimeContentField *my_get_content_type (CamelMimePart *mime_part);
-
-static gboolean my_parse_header_pair (CamelMimePart *mime_part,
- gchar *header_name,
- gchar *header_value);
-
+/* forward references */
+static void set_disposition (CamelMimePart *mime_part, const gchar *disposition);
/* loads in a hash table the set of header names we */
@@ -150,30 +113,10 @@ camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class)
parent_class = gtk_type_class (camel_medium_get_type ());
my_init_header_name_table();
- /* virtual method definition */
- camel_mime_part_class->set_description = my_set_description;
- camel_mime_part_class->get_description = my_get_description;
- camel_mime_part_class->set_disposition = my_set_disposition;
- camel_mime_part_class->get_disposition = my_get_disposition;
- camel_mime_part_class->set_filename = my_set_filename;
- camel_mime_part_class->get_filename = my_get_filename;
- camel_mime_part_class->set_content_id = my_set_content_id;
- camel_mime_part_class->get_content_id = my_get_content_id;
- camel_mime_part_class->set_content_MD5 = my_set_content_MD5;
- camel_mime_part_class->get_content_MD5 = my_get_content_MD5;
- camel_mime_part_class->set_encoding = my_set_encoding;
- camel_mime_part_class->get_encoding = my_get_encoding;
- camel_mime_part_class->set_content_languages = my_set_content_languages;
- camel_mime_part_class->get_content_languages = my_get_content_languages;
- camel_mime_part_class->set_header_lines = my_set_header_lines;
- camel_mime_part_class->get_header_lines = my_get_header_lines;
- camel_mime_part_class->set_content_type = my_set_content_type;
- camel_mime_part_class->get_content_type = my_get_content_type;
-
- camel_mime_part_class->parse_header_pair = my_parse_header_pair;
-
/* virtual method overload */
- camel_medium_class->add_header = my_add_header;
+ camel_medium_class->add_header = add_header;
+ camel_medium_class->set_header = set_header;
+ camel_medium_class->remove_header = remove_header;
camel_medium_class->set_content_object = my_set_content_object;
camel_medium_class->get_content_object = my_get_content_object;
@@ -197,8 +140,6 @@ camel_mime_part_init (gpointer object, gpointer klass)
camel_mime_part->content_MD5 = NULL;
camel_mime_part->content_languages = NULL;
camel_mime_part->encoding = CAMEL_MIME_PART_ENCODING_DEFAULT;
- camel_mime_part->filename = NULL;
- camel_mime_part->header_lines = NULL;
camel_mime_part->temp_message_buffer = NULL;
camel_mime_part->content_input_stream = NULL;
@@ -241,9 +182,7 @@ my_finalize (GtkObject *object)
g_free (mime_part->content_id);
g_free (mime_part->content_MD5);
string_list_free (mime_part->content_languages);
- g_free (mime_part->filename);
header_disposition_unref(mime_part->disposition);
- if (mime_part->header_lines) string_list_free (mime_part->header_lines);
if (mime_part->content_type) gmime_content_field_unref (mime_part->content_type);
if (mime_part->temp_message_buffer) g_byte_array_free (mime_part->temp_message_buffer, TRUE);
@@ -253,323 +192,277 @@ my_finalize (GtkObject *object)
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
-
/* **** */
-static void
-my_add_header (CamelMedium *medium, gchar *header_name, gchar *header_value)
+static gboolean
+process_header(CamelMedium *medium, const char *header_name, const char *header_value)
{
CamelMimePart *mime_part = CAMEL_MIME_PART (medium);
-
+ CamelHeaderType header_type;
+ char *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 */
- if (! CMP_CLASS(mime_part)->parse_header_pair (mime_part, header_name, header_value) )
- parent_class->add_header (medium, header_name, header_value);
+
+ /* FIXMME: MUST check fields for validity before adding them! */
+
+ header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, header_name);
+ switch (header_type) {
+ case HEADER_DESCRIPTION: /* raw header->utf8 conversion */
+ text = header_decode_string(header_value);
+ g_free(mime_part->description);
+ mime_part->description = text;
+ break;
+ case HEADER_DISPOSITION:
+ set_disposition (mime_part, header_value);
+ break;
+ case HEADER_CONTENT_ID:
+ text = header_msgid_decode(header_value);
+ g_free(mime_part->content_id);
+ mime_part->content_id = text;
+ break;
+ case HEADER_ENCODING:
+ text = header_token_decode(header_value);
+ camel_mime_part_set_encoding(mime_part, camel_mime_part_encoding_from_string (text));
+ g_free(text);
+ break;
+ case HEADER_CONTENT_MD5:
+ g_free(mime_part->content_MD5);
+ mime_part->content_MD5 = g_strdup(header_value);
+ break;
+ case HEADER_CONTENT_TYPE:
+ gmime_content_field_construct_from_string (mime_part->content_type, header_value);
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
}
+static void
+set_header (CamelMedium *medium, const char *header_name, const char *header_value)
+{
+ process_header(medium, header_name, header_value);
+ parent_class->set_header (medium, header_name, header_value);
+}
+static void
+add_header (CamelMedium *medium, const char *header_name, const char *header_value)
+{
+ /* 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 */
+ /* FIXMME: MUST check fields for validity before adding them! */
+ /* If it was one of the headers we handled, it must be unique, set it instead of add */
+ if (process_header(medium, header_name, header_value))
+ parent_class->set_header (medium, header_name, header_value);
+ else
+ parent_class->add_header (medium, header_name, header_value);
+}
static void
-my_set_description (CamelMimePart *mime_part, const gchar *description)
+remove_header (CamelMedium *medium, const char *header_name)
{
- g_free (mime_part->description);
- mime_part->description = g_strdup (description);
+ process_header(medium, header_name, NULL);
+ parent_class->remove_header (medium, header_name);
}
+
+/* **** Content-Description */
void
camel_mime_part_set_description (CamelMimePart *mime_part, const gchar *description)
{
- CMP_CLASS(mime_part)->set_description (mime_part, description);
-}
-
-
-
-/* **** */
+ char *text;
+ /* FIXME: convert header, internationalise, etc. */
+ text = g_strdup(description);
+ /* text = header_encode_string(description); */
+ g_free(mime_part->description);
+ mime_part->description = text;
-static const gchar *
-my_get_description (CamelMimePart *mime_part)
-{
- return mime_part->description;
+ parent_class->set_header ((CamelMedium *)mime_part, "Content-Description", text);
}
const gchar *
camel_mime_part_get_description (CamelMimePart *mime_part)
{
- return CMP_CLASS(mime_part)->get_description (mime_part);
+ return mime_part->description;
}
-
-
-/* **** */
-
+/* **** Content-Disposition */
static void
-my_set_disposition (CamelMimePart *mime_part, const gchar *disposition)
+set_disposition (CamelMimePart *mime_part, const gchar *disposition)
{
header_disposition_unref(mime_part->disposition);
- mime_part->disposition = header_disposition_decode(disposition);
+ if (disposition)
+ mime_part->disposition = header_disposition_decode(disposition);
+ else
+ mime_part->disposition = NULL;
}
void
camel_mime_part_set_disposition (CamelMimePart *mime_part, const gchar *disposition)
{
- CMP_CLASS(mime_part)->set_disposition (mime_part, disposition);
-}
-
-
-/* **** */
+ char *text;
+ /* we poke in a new disposition (so we dont lose 'filename', etc) */
+ if (mime_part->disposition == NULL) {
+ set_disposition(mime_part, disposition);
+ }
+ if (mime_part->disposition != NULL) {
+ g_free(mime_part->disposition->disposition);
+ mime_part->disposition->disposition = g_strdup(disposition);
+ }
+ text = header_disposition_format(mime_part->disposition);
+ parent_class->set_header ((CamelMedium *)mime_part, "Content-Description", text);
-static const gchar *
-my_get_disposition (CamelMimePart *mime_part)
-{
- if (!mime_part->disposition) return NULL;
- return (mime_part->disposition)->disposition;
+ g_free(text);
}
-
const gchar *
camel_mime_part_get_disposition (CamelMimePart *mime_part)
{
- return CMP_CLASS(mime_part)->get_disposition (mime_part);
+ if (mime_part->disposition)
+ return (mime_part->disposition)->disposition;
+ else
+ return NULL;
}
-
-static void
-my_set_filename (CamelMimePart *mime_part, gchar *filename)
-{
- g_free(mime_part->filename);
- mime_part->filename = filename;
-}
-
+/* **** Content-Disposition: filename="xxx" */
void
camel_mime_part_set_filename (CamelMimePart *mime_part, gchar *filename)
{
- CMP_CLASS(mime_part)->set_filename (mime_part, filename);
-}
-
+ char *str;
+ if (mime_part->disposition == NULL)
+ mime_part->disposition = header_disposition_decode("attachment");
+ header_set_param(&mime_part->disposition->params, "filename", filename);
+ str = header_disposition_format(mime_part->disposition);
-/* **** */
-
-
-static const gchar *
-my_get_filename (CamelMimePart *mime_part)
-{
- return mime_part->filename;
+ /* we dont want to override what we just created ... */
+ parent_class->set_header ((CamelMedium *)mime_part, "Content-Disposition", str);
+ g_free(str);
}
-
const gchar *
camel_mime_part_get_filename (CamelMimePart *mime_part)
{
- return CMP_CLASS(mime_part)->get_filename (mime_part);
+ if (mime_part->disposition)
+ return header_param(mime_part->disposition->params, "filename");
+ return NULL;
}
-/* **** */
-
+/* **** Content-ID: */
-/* this routine must not be public */
-static void
-my_set_content_id (CamelMimePart *mime_part, gchar *content_id)
+void
+camel_mime_part_set_content_id (CamelMimePart *mime_part, const char *contentid)
{
- g_free(mime_part->content_id);
- mime_part->content_id = g_strdup(content_id);
-}
+ char *text;
-
-static const gchar *
-my_get_content_id (CamelMimePart *mime_part)
-{
- return mime_part->content_id;
+ /* perform a syntax check, just 'cause we can */
+ text = header_msgid_decode(contentid);
+ if (text == NULL) {
+ g_warning("Invalid content id being set: '%s'", contentid);
+ } else {
+ g_free(text);
+ }
+ g_free(mime_part->content_id);
+ mime_part->content_id = g_strdup(contentid);
+ parent_class->set_header ((CamelMedium *)mime_part, "Content-ID", contentid);
}
-
-/* **** */
-
-
const gchar *
camel_mime_part_get_content_id (CamelMimePart *mime_part)
{
- return CMP_CLASS(mime_part)->get_content_id (mime_part);
+ return mime_part->content_id;
}
+/* **** Content-MD5: */
-/* this routine must not be public */
-static void
-my_set_content_MD5 (CamelMimePart *mime_part, gchar *content_MD5)
+void
+camel_mime_part_set_content_MD5 (CamelMimePart *mime_part, const char *md5)
{
g_free(mime_part->content_MD5);
- mime_part->content_MD5 = content_MD5;
-}
-
-
-/* **** */
-
-
-static const gchar *
-my_get_content_MD5 (CamelMimePart *mime_part)
-{
- return mime_part->content_MD5;
+ mime_part->content_MD5 = g_strdup(md5);
+ parent_class->set_header ((CamelMedium *)mime_part, "Content-MD5", md5);
}
const gchar *
camel_mime_part_get_content_MD5 (CamelMimePart *mime_part)
{
- return CMP_CLASS(mime_part)->get_content_MD5 (mime_part);
+ return mime_part->content_MD5;
}
-
-/* **** */
-
-
-
-static void
-my_set_encoding (CamelMimePart *mime_part, CamelMimePartEncodingType encoding)
-{
- mime_part->encoding = encoding;
-}
+/* **** Content-Transfer-Encoding: */
void
camel_mime_part_set_encoding (CamelMimePart *mime_part,
CamelMimePartEncodingType encoding)
{
- CMP_CLASS(mime_part)->set_encoding (mime_part, encoding);
-}
-
-
-/* **** */
-
+ const char *text;
+ mime_part->encoding = encoding;
+ text = camel_mime_part_encoding_to_string (encoding);
+ if (text[0])
+ text = g_strdup(text);
+ else
+ text = NULL;
-static CamelMimePartEncodingType
-my_get_encoding (CamelMimePart *mime_part)
-{
- return mime_part->encoding;
+ parent_class->set_header ((CamelMedium *)mime_part, "Content-Transfer-Encoding", text);
}
const CamelMimePartEncodingType
camel_mime_part_get_encoding (CamelMimePart *mime_part)
{
- return CMP_CLASS(mime_part)->get_encoding (mime_part);
+ return mime_part->encoding;
}
-
-
-/* **** */
-
-
-
-static void
-my_set_content_languages (CamelMimePart *mime_part, GList *content_languages)
-{
- if (mime_part->content_languages) string_list_free (mime_part->content_languages);
- mime_part->content_languages = content_languages;
-}
+/* FIXME: do something with this stuff ... */
void
camel_mime_part_set_content_languages (CamelMimePart *mime_part, GList *content_languages)
{
- CMP_CLASS(mime_part)->set_content_languages (mime_part, content_languages);
-}
-
-
-/* **** */
-
-
+ if (mime_part->content_languages) string_list_free (mime_part->content_languages);
+ mime_part->content_languages = content_languages;
-static const GList *
-my_get_content_languages (CamelMimePart *mime_part)
-{
- return mime_part->content_languages;
+ /* FIXME: translate to a header and set it */
}
-
const GList *
camel_mime_part_get_content_languages (CamelMimePart *mime_part)
{
- return CMP_CLASS(mime_part)->get_content_languages (mime_part);
-}
-
-
-/* **** */
-
-
-
-static void
-my_set_header_lines (CamelMimePart *mime_part, GList *header_lines)
-{
- if (mime_part->header_lines) string_list_free (mime_part->header_lines);
- mime_part->header_lines = header_lines;
-}
-
-void
-camel_mime_part_set_header_lines (CamelMimePart *mime_part, GList *header_lines)
-{
- CMP_CLASS(mime_part)->set_header_lines (mime_part, header_lines);
-}
-
-
-/* **** */
-
-
-
-static const GList *
-my_get_header_lines (CamelMimePart *mime_part)
-{
- return mime_part->header_lines;
-}
-
-
-
-const GList *
-camel_mime_part_get_header_lines (CamelMimePart *mime_part)
-{
- return CMP_CLASS(mime_part)->get_header_lines (mime_part);
+ return mime_part->content_languages;
}
/* **** */
-
-
-static void
-my_set_content_type (CamelMimePart *mime_part, const gchar *content_type)
-{
- g_assert (content_type);
- gmime_content_field_construct_from_string (mime_part->content_type, content_type);
-}
+/* **** Content-Type: */
void
camel_mime_part_set_content_type (CamelMimePart *mime_part, gchar *content_type)
{
- CMP_CLASS(mime_part)->set_content_type (mime_part, content_type);
-}
-
-/* **** */
-
-
-static GMimeContentField *
-my_get_content_type (CamelMimePart *mime_part)
-{
- return mime_part->content_type;
+ /* FIXME: need a way to specify content-type parameters without putting them
+ in a string ... */
+ gmime_content_field_construct_from_string (mime_part->content_type, content_type);
+ parent_class->set_header ((CamelMedium *)mime_part, "Content-Type", content_type);
}
GMimeContentField *
camel_mime_part_get_content_type (CamelMimePart *mime_part)
{
- return CMP_CLASS(mime_part)->get_content_type (mime_part);
+ return mime_part->content_type;
}
/*********/
@@ -585,9 +478,15 @@ my_set_content_object (CamelMedium *medium, CamelDataWrapper *content)
parent_class->set_content_object (medium, content);
object_content_field = camel_data_wrapper_get_mime_type_field (content);
- if (mime_part->content_type && (mime_part->content_type != object_content_field))
+ if (mime_part->content_type && (mime_part->content_type != object_content_field)) {
+ char *txt;
+
gmime_content_field_unref (mime_part->content_type);
+ txt = header_content_type_format(object_content_field?object_content_field->content_type:NULL);
+ parent_class->set_header ((CamelMedium *)mime_part, "Content-Type", txt);
+ }
mime_part->content_type = object_content_field;
+
gmime_content_field_ref (object_content_field);
}
@@ -604,19 +503,14 @@ my_get_content_object (CamelMedium *medium)
decoded_stream = stream;
switch (mime_part->encoding) {
-
- case CAMEL_MIME_PART_ENCODING_DEFAULT:
- case CAMEL_MIME_PART_ENCODING_7BIT:
- case CAMEL_MIME_PART_ENCODING_8BIT:
- break;
-
case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE:
mf = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC);
break;
-
case CAMEL_MIME_PART_ENCODING_BASE64:
mf = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
break;
+ default:
+ break;
}
if (mf) {
@@ -689,7 +583,7 @@ my_write_content_to_stream (CamelMimePart *mime_part, CamelStream *stream)
/* encode the data wrapper output stream in the filtered encoding */
wrapper_stream = camel_data_wrapper_get_output_stream (content);
camel_stream_reset (wrapper_stream);
- stream_encode = camel_stream_filter_new_with_stream (wrapper_stream);
+ stream_encode = (CamelStream *)camel_stream_filter_new_with_stream (wrapper_stream);
camel_stream_filter_add((CamelStreamFilter *)stream_encode, mf);
/* ... and write it to the output stream in a blocking way */
@@ -704,6 +598,7 @@ my_write_content_to_stream (CamelMimePart *mime_part, CamelStream *stream)
+/* FIXME: this is just totally broken broken broken broken */
static void
my_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
@@ -711,91 +606,24 @@ my_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
CamelMimePart *mp = CAMEL_MIME_PART (data_wrapper);
CamelMedium *medium = CAMEL_MEDIUM (data_wrapper);
- if (mp->disposition) {
- struct _header_param *p;
+ /* FIXME: something needs to be done about this ... */
+ gmime_write_header_with_glist_to_stream (stream, "Content-Language", mp->content_languages,", ");
- camel_stream_write_strings(stream, "Content-Disposition: ", mp->disposition->disposition, NULL);
- /* FIXME: use proper quoting rules here ... */
- p = mp->disposition->params;
- while (p) {
- camel_stream_write_strings (stream, ";\n ", p->name, "= \"", p->value, "\"", NULL);
- p = p->next;
+#warning This class should NOT BE WRITING the headers out
+ if (medium->headers) {
+ struct _header_raw *h = medium->headers;
+ while (h) {
+ camel_stream_write_strings (stream, h->name, isspace(h->value[0])?":":": ", h->value, "\n", NULL);
+ h = h->next;
}
- camel_stream_write_string (stream, "\n");
}
- WHPT (stream, "Content-Transfer-Encoding",
- camel_mime_part_encoding_to_string (mp->encoding));
- WHPT (stream, "Content-Description", mp->description);
- WHPT (stream, "Content-MD5", mp->content_MD5);
- WHPT (stream, "Content-id", mp->content_id);
- gmime_write_header_with_glist_to_stream (stream, "Content-Language", mp->content_languages,", ");
- gmime_write_header_table_to_stream (stream, medium->headers);
- gmime_content_field_write_to_stream (mp->content_type, stream);
-
+
camel_stream_write_string(stream,"\n");
my_write_content_to_stream (mp, stream);
}
-/*******************************/
-/* mime part parsing */
-
-static gboolean
-my_parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_value)
-{
- CamelHeaderType header_type;
- gboolean header_handled = FALSE;
-
-
- header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, header_name);
- switch (header_type) {
-
- case HEADER_DESCRIPTION:
- camel_mime_part_set_description (mime_part, header_value);
- header_handled = TRUE;
- break;
-
- case HEADER_DISPOSITION:
- camel_mime_part_set_disposition (mime_part, header_value);
- header_handled = TRUE;
- break;
-
- case HEADER_CONTENT_ID:
- CMP_CLASS(mime_part)->set_content_id (mime_part, header_value);
- header_handled = TRUE;
- break;
-
- case HEADER_ENCODING:
- camel_mime_part_set_encoding
- (mime_part,
- camel_mime_part_encoding_from_string (header_value));
- header_handled = TRUE;
- break;
-
- case HEADER_CONTENT_MD5:
- CMP_CLASS(mime_part)->set_content_MD5 (mime_part, header_value);
- header_handled = TRUE;
- break;
-
- case HEADER_CONTENT_TYPE:
- gmime_content_field_construct_from_string (mime_part->content_type, header_value);
- header_handled = TRUE;
- break;
-
-
- }
-
-
- if (header_handled) {
- return TRUE;
- } else return FALSE;
-
-}
-
-
-
-
static void
my_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
{
@@ -871,6 +699,8 @@ my_get_output_stream (CamelDataWrapper *data_wrapper)
case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE:
return input_stream;
+ default:
+ break;
}
return NULL;
@@ -890,6 +720,8 @@ camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding)
return "base64";
case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE:
return "quoted-printable";
+ default:
+ break;
}
return "";
}
@@ -900,7 +732,9 @@ camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding)
CamelMimePartEncodingType
camel_mime_part_encoding_from_string (const gchar *string)
{
- if (strcmp (string, "7bit") == 0)
+ if (string == NULL)
+ return CAMEL_MIME_PART_ENCODING_DEFAULT;
+ else if (strcmp (string, "7bit") == 0)
return CAMEL_MIME_PART_ENCODING_7BIT;
else if (strcmp (string, "8bit") == 0)
return CAMEL_MIME_PART_ENCODING_8BIT;
diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h
index 37118c8384..89409dab5f 100644
--- a/camel/camel-mime-part.h
+++ b/camel/camel-mime-part.h
@@ -69,8 +69,6 @@ struct _CamelMimePart
gchar *content_MD5;
GList *content_languages;
CamelMimePartEncodingType encoding;
- gchar *filename;
- GList *header_lines;
GByteArray *temp_message_buffer;
GMimeContentField *content_type;
@@ -84,29 +82,6 @@ typedef struct {
CamelMediumClass parent_class;
/* Virtual methods */
- void (*set_description) (CamelMimePart *mime_part, const gchar *description);
- const gchar * (*get_description) (CamelMimePart *mime_part);
- void (*set_disposition) (CamelMimePart *mime_part, const gchar *disposition);
- const gchar * (*get_disposition) (CamelMimePart *mime_part);
- void (*set_filename) (CamelMimePart *mime_part, gchar *filename);
- const gchar * (*get_filename) (CamelMimePart *mime_part);
- void (*set_content_id) (CamelMimePart *mime_part, gchar *content_id);
- const gchar * (*get_content_id) (CamelMimePart *mime_part);
- void (*set_content_MD5) (CamelMimePart *mime_part, gchar *content_MD5);
- const gchar * (*get_content_MD5) (CamelMimePart *mime_part);
- void (*set_encoding) (CamelMimePart *mime_part, CamelMimePartEncodingType type);
- const CamelMimePartEncodingType (*get_encoding) (CamelMimePart *mime_part);
- void (*set_content_languages) (CamelMimePart *mime_part, GList *content_languages);
- const GList * (*get_content_languages) (CamelMimePart *mime_part);
- void (*set_header_lines) (CamelMimePart *mime_part, GList *header_lines);
- const GList * (*get_header_lines) (CamelMimePart *mime_part);
-
- void (*set_content_type) (CamelMimePart *mime_part, const gchar *content_type);
- GMimeContentField * (*get_content_type) (CamelMimePart *mime_part);
-
- gboolean (*parse_header_pair) (CamelMimePart *mime_part, gchar *header_name, gchar *header_value);
-
-
} CamelMimePartClass;
@@ -116,30 +91,32 @@ GtkType camel_mime_part_get_type (void);
/* public methods */
-void camel_mime_part_set_description (CamelMimePart *mime_part,
- const gchar *description);
+void camel_mime_part_set_description (CamelMimePart *mime_part, const gchar *description);
const gchar *camel_mime_part_get_description (CamelMimePart *mime_part);
-void camel_mime_part_set_disposition (CamelMimePart *mime_part,
- const gchar *disposition);
+
+void camel_mime_part_set_disposition (CamelMimePart *mime_part, const gchar *disposition);
const gchar *camel_mime_part_get_disposition (CamelMimePart *mime_part);
-void camel_mime_part_set_filename (CamelMimePart *mime_part,
- gchar *filename);
+
+void camel_mime_part_set_filename (CamelMimePart *mime_part, gchar *filename);
const gchar *camel_mime_part_get_filename (CamelMimePart *mime_part);
+
+void camel_mime_part_set_content_id (CamelMimePart *mime_part, const char *contentid);
const gchar *camel_mime_part_get_content_id (CamelMimePart *mime_part);
+
+void camel_mime_part_set_content_MD5 (CamelMimePart *mime_part, const char *);
const gchar *camel_mime_part_get_content_MD5 (CamelMimePart *mime_part);
-void camel_mime_part_set_encoding (CamelMimePart *mime_part,
- CamelMimePartEncodingType type);
+
+void camel_mime_part_set_encoding (CamelMimePart *mime_part, CamelMimePartEncodingType type);
CamelMimePartEncodingType camel_mime_part_get_encoding (CamelMimePart *mime_part);
-void camel_mime_part_set_content_languages (CamelMimePart *mime_part,
- GList *content_languages);
+
+void camel_mime_part_set_content_languages (CamelMimePart *mime_part, GList *content_languages);
const GList *camel_mime_part_get_content_languages (CamelMimePart *mime_part);
-void camel_mime_part_set_header_lines (CamelMimePart *mime_part,
- GList *header_lines);
-const GList *camel_mime_part_get_header_lines (CamelMimePart *mime_part);
+/* FIXME: what about content-type parameters? what about major/minor parts? */
+void camel_mime_part_set_content_type (CamelMimePart *mime_part, gchar *content_type);
GMimeContentField *camel_mime_part_get_content_type (CamelMimePart *mime_part);
-const gchar *camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding);
+const gchar * camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding);
CamelMimePartEncodingType camel_mime_part_encoding_from_string (const gchar *string);
/* utility functions */
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 94ede343e6..7b1ad93cd0 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -542,11 +542,13 @@ quoted_decode_step(unsigned char *in, int len, unsigned char *out, int *savestat
this is for the "Q" encoding of international words,
which is slightly different than plain quoted-printable
*/
-int
-quoted_decode(unsigned char *in, int len, unsigned char *out)
+static int
+quoted_decode(const unsigned char *in, int len, unsigned char *out)
{
- register unsigned char *inptr, *outptr;
- unsigned char *inend, c, c1;
+ register const unsigned char *inptr;
+ register unsigned char *outptr;
+ unsigned const char *inend;
+ unsigned char c, c1;
int ret = 0;
inend = in+len;
@@ -619,22 +621,12 @@ header_decode_lwsp(const char **in)
*in = inptr;
}
-char *
-g_strdup_len(const char *start, int len)
-{
- char *d = g_malloc(len+1);
- memcpy(d, start, len);
- d[len] = 0;
- return d;
-}
-
-
/* decode rfc 2047 encoded string segment */
-char *
-rfc2047_decode_word(char *in, int len)
+static char *
+rfc2047_decode_word(const char *in, int len)
{
- char *inptr = in+2;
- char *inend = in+len-2;
+ const char *inptr = in+2;
+ const char *inend = in+len-2;
char *encname;
int tmplen;
int ret;
@@ -668,7 +660,7 @@ rfc2047_decode_word(char *in, int len)
case 'B': {
int state=0;
unsigned int save=0;
- inlen = base64_decode_step(inptr+2, tmplen, decword, &state, &save);
+ inlen = base64_decode_step((char *)inptr+2, tmplen, decword, &state, &save);
/* if state != 0 then error? */
break;
}
@@ -704,15 +696,9 @@ rfc2047_decode_word(char *in, int len)
return decoded;
}
-char *
-decode_coded_string(char *in)
-{
- return rfc2047_decode_word(in, strlen(in));
-}
-
/* grrr, glib should have this ! */
-GString *
-g_string_append_len(GString *st, char *s, int l)
+static GString *
+g_string_append_len(GString *st, const char *s, int l)
{
char *tmp;
@@ -723,12 +709,12 @@ g_string_append_len(GString *st, char *s, int l)
}
/* decodes a simple text, rfc822 */
-char *
-header_decode_text(char *in, int inlen)
+static char *
+header_decode_text(const char *in, int inlen)
{
GString *out;
- char *inptr = in;
- char *inend = in+inlen;
+ const char *inptr = in;
+ const char *inend = in+inlen;
char *encstart, *encend;
char *decword;
@@ -748,9 +734,9 @@ header_decode_text(char *in, int inlen)
}
g_string_append_len(out, inptr, inend-inptr);
- inptr = out->str;
+ encstart = out->str;
g_string_free(out, FALSE);
- return inptr;
+ return encstart;
}
char *
@@ -764,8 +750,8 @@ header_decode_string(const char *in)
/* these are all internal parser functions */
-char *
-header_decode_token(const char **in)
+static char *
+decode_token(const char **in)
{
const char *inptr = *in;
const char *start;
@@ -776,12 +762,21 @@ header_decode_token(const char **in)
inptr++;
if (inptr>start) {
*in = inptr;
- return g_strdup_len(start, inptr-start);
+ return g_strndup(start, inptr-start);
} else {
return NULL;
}
}
+char *
+header_token_decode(const char *in)
+{
+ if (in == NULL)
+ return NULL;
+
+ return decode_token(&in);
+}
+
/*
<"> * ( <any char except <"> \, cr / \ <any char> ) <">
*/
@@ -832,7 +827,7 @@ header_decode_atom(const char **in)
inptr++;
*in = inptr;
if (inptr > start)
- return g_strdup_len(start, inptr-start);
+ return g_strndup(start, inptr-start);
else
return NULL;
}
@@ -864,7 +859,7 @@ header_decode_value(const char **in)
} else if (is_ttoken(*inptr)) {
d(printf("decoding token\n"));
/* this may not have the right specials for all params? */
- return header_decode_token(in);
+ return decode_token(in);
}
return NULL;
}
@@ -891,7 +886,7 @@ header_decode_param(const char **in, char **paramp, char **valuep)
const char *inptr = *in;
char *param, *value=NULL;
- param = header_decode_token(&inptr);
+ param = decode_token(&inptr);
header_decode_lwsp(&inptr);
if (*inptr == '=') {
inptr++;
@@ -911,7 +906,7 @@ header_decode_param(const char **in, char **paramp, char **valuep)
}
char *
-header_param(struct _header_param *p, char *name)
+header_param(struct _header_param *p, const char *name)
{
while (p && strcasecmp(p->name, name) != 0)
p = p->next;
@@ -929,12 +924,21 @@ header_set_param(struct _header_param **l, const char *name, const char *value)
pn = p->next;
if (!strcasecmp(pn->name, name)) {
g_free(pn->value);
- pn->value = g_strdup(value);
- return pn;
+ if (value) {
+ pn->value = g_strdup(value);
+ return pn;
+ } else {
+ p->next = pn->next;
+ g_free(pn);
+ return NULL;
+ }
}
p = pn;
}
+ if (value == NULL)
+ return NULL;
+
pn = g_malloc(sizeof(*pn));
pn->next = 0;
pn->name = g_strdup(name);
@@ -972,6 +976,8 @@ void header_content_type_set_param(struct _header_content_type *t, const char *n
int
header_content_type_is(struct _header_content_type *ct, const char *type, const char *subtype)
{
+ printf("type = %s / %s\n", type, subtype);
+
/* no type == text/plain or text/"*" */
if (ct==NULL) {
return (!strcasecmp(type, "text")
@@ -979,9 +985,11 @@ header_content_type_is(struct _header_content_type *ct, const char *type, const
|| !strcasecmp(subtype, "*")));
}
- return ((!strcasecmp(ct->type, type)
- && (!strcasecmp(ct->subtype, subtype)
- || !strcasecmp("*", subtype))));
+ return (ct->type != NULL
+ && (!strcasecmp(ct->type, type)
+ && ((ct->subtype != NULL
+ && !strcasecmp(ct->subtype, subtype))
+ || !strcasecmp("*", subtype))));
}
void
@@ -1003,8 +1011,8 @@ header_content_type_new(const char *type, const char *subtype)
{
struct _header_content_type *t = g_malloc(sizeof(*t));
- t->type = type;
- t->subtype = subtype;
+ t->type = g_strdup(type);
+ t->subtype = g_strdup(subtype);
t->params = NULL;
t->refcount = 1;
return t;
@@ -1332,6 +1340,8 @@ header_to_decode(const char *in)
d(printf("decoding To: '%s'\n", in));
+#warning header_to_decode needs to return some structure
+
if (in == NULL)
return NULL;
@@ -1362,6 +1372,8 @@ header_mime_decode(const char *in)
d(printf("decoding MIME-Version: '%s'\n", in));
+#warning header_mime_decode needs to return the version
+
if (in == NULL)
return NULL;
@@ -1380,7 +1392,7 @@ header_mime_decode(const char *in)
d(printf("major = %d, minor = %d\n", major, minor));
}
-struct _header_param *
+static struct _header_param *
header_param_list_decode(const char **in)
{
const char *inptr = *in;
@@ -1411,6 +1423,23 @@ header_param_list_decode(const char **in)
return head;
}
+static void
+header_param_list_format_append(GString *out, struct _header_param *p)
+{
+ int len = out->len;
+ while (p) {
+ int here = out->len;
+ if (len+strlen(p->name)+strlen(p->value)>60) {
+ g_string_append(out, "\n\t");
+ len = 0;
+ }
+ /* FIXME: format the value properly */
+ g_string_sprintfa(out, " ; %s=\"%s\"", p->name, p->value);
+ len += (out->len - here);
+ p = p->next;
+ }
+}
+
struct _header_content_type *
header_content_type_decode(const char *in)
{
@@ -1421,12 +1450,12 @@ header_content_type_decode(const char *in)
if (in==NULL)
return NULL;
- type = header_decode_token(&inptr);
+ type = decode_token(&inptr);
header_decode_lwsp(&inptr);
if (type) {
if (*inptr == '/') {
inptr++;
- subtype = header_decode_token(&inptr);
+ subtype = decode_token(&inptr);
}
if (subtype == NULL && (!strcasecmp(type, "text"))) {
g_warning("text type with no subtype, resorting to text/plain: %s", in);
@@ -1467,10 +1496,39 @@ header_content_type_dump(struct _header_content_type *ct)
}
char *
+header_content_type_format(struct _header_content_type *ct)
+{
+ GString *out;
+ char *ret;
+
+ if (ct==NULL)
+ return NULL;
+
+ out = g_string_new("");
+ if (ct->type == NULL) {
+ g_string_sprintfa(out, "text/plain");
+ g_warning("Content-Type with no main type");
+ } else if (ct->subtype == NULL) {
+ g_warning("Content-Type with no sub type: %s", ct->type);
+ if (!strcasecmp(ct->type, "multipart"))
+ g_string_sprintfa(out, "%s/mixed", ct->type);
+ else
+ g_string_sprintfa(out, "%s", ct->type);
+ } else {
+ g_string_sprintfa(out, "%s/%s", ct->type, ct->subtype);
+ }
+ header_param_list_format_append(out, ct->params);
+
+ ret = out->str;
+ g_string_free(out, FALSE);
+ return ret;
+}
+
+char *
header_content_encoding_decode(const char *in)
{
if (in)
- return header_decode_token(&in);
+ return decode_token(&in);
return NULL;
}
@@ -1484,7 +1542,7 @@ CamelMimeDisposition *header_disposition_decode(const char *in)
d = g_malloc(sizeof(*d));
d->refcount = 1;
- d->disposition = header_decode_token(&inptr);
+ d->disposition = decode_token(&inptr);
if (d->disposition == NULL)
g_warning("Empty disposition type");
d->params = header_param_list_decode(&inptr);
@@ -1509,6 +1567,26 @@ void header_disposition_unref(CamelMimeDisposition *d)
}
}
+char *header_disposition_format(CamelMimeDisposition *d)
+{
+ GString *out;
+ char *ret;
+
+ if (d==NULL)
+ return NULL;
+
+ out = g_string_new("");
+ if (d->disposition)
+ g_string_append(out, d->disposition);
+ else
+ g_string_append(out, "attachment");
+ header_param_list_format_append(out, d->params);
+
+ ret = out->str;
+ g_string_free(out, FALSE);
+ return ret;
+}
+
/* hrm, is there a library for this shit? */
static struct {
char *name;
@@ -1583,7 +1661,7 @@ header_decode_date(const char *in, int *saveoffset)
header_decode_lwsp(&inptr);
if (!isdigit(*inptr)) {
- char *day = header_decode_token(&inptr);
+ char *day = decode_token(&inptr);
/* we dont really care about the day, its only for display */
if (day) {
d(printf("got day: %s\n", day));
@@ -1596,7 +1674,7 @@ header_decode_date(const char *in, int *saveoffset)
}
}
tm.tm_mday = header_decode_int(&inptr);
- monthname = header_decode_token(&inptr);
+ monthname = decode_token(&inptr);
if (monthname) {
for (i=0;i<sizeof(tz_months)/sizeof(tz_months[0]);i++) {
if (!strcasecmp(tz_months[i], monthname)) {
@@ -1632,7 +1710,7 @@ header_decode_date(const char *in, int *saveoffset)
offset = header_decode_int(&inptr);
d(printf("abs offset = %d\n", offset));
} else {
- char *tz = header_decode_token(&inptr);
+ char *tz = decode_token(&inptr);
if (tz) {
for (i=0;i<sizeof(tz_offsets)/sizeof(tz_offsets[0]);i++) {
@@ -1792,6 +1870,20 @@ header_raw_find(struct _header_raw **list, const char *name, int *offset)
return NULL;
}
+const char *
+header_raw_find_next(struct _header_raw **list, const char *name, int *offset, const char *last)
+{
+ struct _header_raw *l;
+
+ if (last == NULL || name == NULL)
+ return NULL;
+
+ l = *list;
+ while (l && l->value != last)
+ l = l->next;
+ return header_raw_find(&l, name, offset);
+}
+
static void
header_raw_free(struct _header_raw *l)
{
diff --git a/camel/camel-mime-utils.h b/camel/camel-mime-utils.h
index 931e479a99..57d6d3ffb5 100644
--- a/camel/camel-mime-utils.h
+++ b/camel/camel-mime-utils.h
@@ -52,6 +52,12 @@ typedef struct _CamelMimeDisposition {
unsigned int refcount;
} CamelMimeDisposition;
+/* structured header prameters */
+char *header_param(struct _header_param *p, const char *name);
+struct _header_param *header_set_param(struct _header_param **l, const char *name, const char *value);
+void header_param_list_free(struct _header_param *p);
+
+/* Content-Type header */
struct _header_content_type *header_content_type_new(const char *type, const char *subtype);
struct _header_content_type *header_content_type_decode(const char *in);
void header_content_type_unref(struct _header_content_type *ct);
@@ -59,27 +65,31 @@ void header_content_type_ref(struct _header_content_type *ct);
const char *header_content_type_param(struct _header_content_type *t, const char *name);
void header_content_type_set_param(struct _header_content_type *t, const char *name, const char *value);
int header_content_type_is(struct _header_content_type *ct, const char *type, const char *subtype);
+char *header_content_type_format(struct _header_content_type *ct);
-char *header_param(struct _header_param *p, char *name);
-struct _header_param *header_set_param(struct _header_param **l, const char *name, const char *value);
+/* DEBUGGING function */
+void header_content_type_dump(struct _header_content_type *ct);
+/* Content-Disposition header */
CamelMimeDisposition *header_disposition_decode(const char *in);
void header_disposition_ref(CamelMimeDisposition *);
void header_disposition_unref(CamelMimeDisposition *);
+char *header_disposition_format(CamelMimeDisposition *d);
/* decode the contents of a content-encoding header */
char *header_content_encoding_decode(const char *in);
-/* working with lists of headers */
+/* raw headers */
void header_raw_append(struct _header_raw **list, const char *name, const char *value, int offset);
void header_raw_append_parse(struct _header_raw **list, const char *header, int offset);
const char *header_raw_find(struct _header_raw **list, const char *name, int *ofset);
+const char *header_raw_find_next(struct _header_raw **list, const char *name, int *ofset, const char *last);
void header_raw_replace(struct _header_raw **list, const char *name, const char *value, int offset);
void header_raw_remove(struct _header_raw **list, const char *name);
void header_raw_clear(struct _header_raw **list);
-/* raw header parsing functions */
-char *header_decode_token(const char **in);
+/* decode a header which is a simple token */
+char *header_token_decode(const char *in);
/* decode a string type, like a subject line */
char *header_decode_string(const char *in);
diff --git a/camel/camel-recipient.c b/camel/camel-recipient.c
index 66fd94f925..0ed028763b 100644
--- a/camel/camel-recipient.c
+++ b/camel/camel-recipient.c
@@ -3,8 +3,8 @@
/*
*
- * Author :
- * Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Michael Zucchi <notzed@helixcode.com>
*
* Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com)
*
@@ -239,7 +239,29 @@ camel_recipient_table_remove (CamelRecipientTable *recipient_table,
}
}
-
+void
+camel_recipient_table_remove_type (CamelRecipientTable *recipient_table,
+ const gchar *recipient_type)
+{
+ GList *l, *n;
+ gchar *old_recipient_type;
+
+ /* if the recipient type section does not exist, do nothing */
+ if (! g_hash_table_lookup_extended (recipient_table->recipient_hash_table,
+ recipient_type,
+ (gpointer)&(old_recipient_type),
+ (void *)&l))
+ return;
+
+ g_hash_table_remove(recipient_table->recipient_hash_table, old_recipient_type);
+ g_free(old_recipient_type);
+ n = l;
+ while (l) {
+ g_free(l->data);
+ l = l->next;
+ }
+ g_list_free(n);
+}
/**
* camel_recipient_table_get: Get the recipients corresponding to a recipient type.
diff --git a/camel/camel-recipient.h b/camel/camel-recipient.h
index 25bc49bea7..1136cf36ae 100644
--- a/camel/camel-recipient.h
+++ b/camel/camel-recipient.h
@@ -70,7 +70,8 @@ void camel_recipient_table_add_list (CamelRecipientTable *recipient_table,
void camel_recipient_table_remove (CamelRecipientTable *recipient_table,
const gchar *recipient_type,
const gchar *recipient);
-
+void camel_recipient_table_remove_type (CamelRecipientTable *recipient_table,
+ const gchar *recipient_type);
const GList *camel_recipient_table_get (CamelRecipientTable *recipient_table,
const gchar *recipient_type);
diff --git a/camel/gmime-content-field.c b/camel/gmime-content-field.c
index 6d0abce4e8..53d5135c23 100644
--- a/camel/gmime-content-field.c
+++ b/camel/gmime-content-field.c
@@ -123,22 +123,15 @@ gmime_content_field_set_parameter (GMimeContentField *content_field, const gchar
void
gmime_content_field_write_to_stream (GMimeContentField *content_field, CamelStream *stream)
{
- struct _header_param *p;
+ char *txt;
- if (!content_field) return;
+ if (!content_field)
+ return;
- g_assert (stream);
- if (content_field->content_type) {
- camel_stream_write_strings (stream, "Content-Type: ", content_field->content_type->type?content_field->content_type->type:"text",
- "/", content_field->content_type->subtype?content_field->content_type->subtype:"plain", NULL);
-
- /* print all parameters */
- p = content_field->content_type->params;
- while (p) {
- camel_stream_write_strings (stream, ";\n ", p->name, "= \"", p->value, "\"", NULL);
- p = p->next;
- }
- camel_stream_write_string (stream, "\n");
+ txt = header_content_type_format(content_field->content_type);
+ if (txt) {
+ camel_stream_write_strings (stream, "Content-Type: ", txt, "\n", NULL);
+ g_free(txt);
}
}
diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c
index 268ecaf3ab..75eb217e74 100644
--- a/camel/providers/mbox/camel-mbox-folder.c
+++ b/camel/providers/mbox/camel-mbox-folder.c
@@ -860,6 +860,7 @@ _get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex)
/* init other fields? */
message->folder = folder;
+ gtk_object_ref((GtkObject *)folder);
message->message_uid = g_strdup(uid);
return message;
diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c
index c2aad8317a..aa6f85610a 100644
--- a/camel/providers/mbox/camel-mbox-summary.c
+++ b/camel/providers/mbox/camel-mbox-summary.c
@@ -343,7 +343,7 @@ body_part_new(CamelMimeParser *mp, CamelMboxMessageContentInfo *parent, int star
static char *strdup_trim(const char *s)
{
- char *end;
+ const char *end;
if (s == NULL)
return NULL;
@@ -353,8 +353,7 @@ static char *strdup_trim(const char *s)
end = s+strlen(s)-1;
while (end>s && isspace(*end))
end--;
- end = g_strndup(s, end-s+1);
- return end;
+ return g_strndup(s, end-s+1);
}
static CamelMboxMessageInfo *
@@ -549,7 +548,7 @@ header_evolution_decode(const char *in, unsigned int *uid, unsigned int *flags)
{
char *header;
if (in
- && (header = header_decode_token(&in))) {
+ && (header = header_token_decode(in))) {
if (strlen(header) == strlen("00000000-0000")
&& sscanf(header, "%08x-%04x", uid, flags) == 2) {
g_free(header);
@@ -583,11 +582,13 @@ safe_write(int fd, char *buffer, size_t towrite)
static int
header_write(int fd, struct _header_raw *header, unsigned int uid, unsigned int flags)
{
- struct iovec iv[3];
+ struct iovec iv[4];
int outlen = 0;
iv[1].iov_base = ":";
iv[1].iov_len = 1;
+ iv[3].iov_base = "\n";
+ iv[3].iov_len = 1;
while (header) {
if (strcasecmp(header->name, "x-evolution")) {
@@ -599,7 +600,7 @@ header_write(int fd, struct _header_raw *header, unsigned int uid, unsigned int
iv[2].iov_len = strlen(header->value);
do {
- len = writev(fd, iv, 3);
+ len = writev(fd, iv, 4);
} while (len == -1 && errno == EINTR);
if (len == -1)
@@ -1250,8 +1251,8 @@ guint32 camel_mbox_summary_next_uid(CamelMboxSummary *s)
guint32 camel_mbox_summary_set_uid(CamelMboxSummary *s, guint32 uid)
{
- if (s->nextuid < uid) {
- s->nextuid = uid;
+ if (s->nextuid <= uid) {
+ s->nextuid = uid+1;
summary_header_save(s);
}
return s->nextuid;