aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-multipart.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-multipart.c')
-rw-r--r--camel/camel-multipart.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/camel/camel-multipart.c b/camel/camel-multipart.c
index 44ae7dfbf6..948a68e387 100644
--- a/camel/camel-multipart.c
+++ b/camel/camel-multipart.c
@@ -506,3 +506,140 @@ _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
g_free (end_boundary_line);
CAMEL_LOG_FULL_DEBUG ("Leaving CamelMultipart::_construct_from_stream\n");
}
+
+
+
+
+
+
+
+
+
+/**********************/
+/* new implementation */
+
+
+/**
+ * _localize_part: localize one part in a multipart environement.
+ * @stream: the stream to read the lines from.
+ * @normal_boundary: end of part bundary.
+ * @end_boundary: end of multipart boundary.
+ * @end_position : end position of the mime part
+ *
+ * This routine is a bit special: RFC 2046 says that, in a multipart
+ * environment, the last crlf before a boundary belongs to the boundary.
+ * Thus, if there is no blank line before the boundary, the last crlf
+ * of the last line of the part is removed.
+ *
+ * Return value: true if the last boundary element has been found or if no more data was available from the stream, flase otherwise
+ **/
+
+static gboolean
+_localize_part (CamelStream *stream,
+ gchar *normal_boundary,
+ gchar *end_boundary,
+ guint32 *end_position)
+{
+ gchar *new_line = NULL;
+ gboolean end_of_part = FALSE;
+ gboolean last_part = FALSE;
+ gboolean first_line = TRUE;
+ guint32 last_position;
+
+ /* Note for future enhancements */
+ /* RFC 2046 precises that when parsing the content of a multipart
+ * element, the program should not think it will find the last boundary,
+ * and in particular, the message could have been damaged during
+ * transport, the parsing should still be OK */
+ CAMEL_LOG_FULL_DEBUG ("CamelMultipart:: Entering _localize_part\n");
+
+ last_position = camel_seekable_stream_get_current_position (stream);
+ new_line = gmime_read_line_from_stream (stream);
+ while (new_line && !end_of_part && !last_part) {
+ end_of_part = (strcmp (new_line, normal_boundary) == 0);
+ last_part = (strcmp (new_line, end_boundary) == 0);
+ if (!end_of_part && !last_part) {
+
+ g_free (new_line);
+
+ last_position = camel_seekable_stream_get_current_position (stream);
+ new_line = gmime_read_line_from_stream (stream);
+ }
+ }
+
+ if (new_line) g_free (new_line);
+ else last_part = TRUE;
+
+ *end_position = last_position
+
+ CAMEL_LOG_FULL_DEBUG ("CamelMultipart:: Leaving _localize_part\n");
+ return (last_part);
+}
+
+
+
+
+static void
+_set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
+{
+ CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper);
+ const gchar *boundary;
+ gchar *real_boundary_line;
+ gchar *end_boundary_line;
+ CamelStream *new_part_stream;
+ gboolean end_of_multipart;
+ CamelMimeBodyPart *body_part;
+ guint32 part_begining, part_end;
+ CamelSeekableSubstream *body_part_input_stream;
+
+ CAMEL_LOG_FULL_DEBUG ("Entering CamelMultipart::_construct_from_stream\n");
+ boundary = camel_multipart_get_boundary (multipart);
+ g_return_if_fail (boundary);
+
+ real_boundary_line = g_strdup_printf ("--%s", boundary);
+ end_boundary_line = g_strdup_printf ("--%s--", boundary);
+
+
+ /* read the prefix if any */
+ end_of_multipart = _localize_part (stream,
+ real_boundary_line,
+ end_boundary_line,
+ &part_end);
+ if (multipart->preface) g_free (multipart->preface);
+
+ /* if ( (new_part->str)[0] != '\0') multipart->preface = g_strdup (new_part->str); */
+
+ /* read all the real parts */
+ while (!end_of_multipart) {
+ /* determine the position of the begining of the part */
+ part_begining = camel_seekable_stream_get_current_position (stream);
+
+ CAMEL_LOG_FULL_DEBUG ("CamelMultipart::construct_from_stream, detected a new part\n");
+ body_part = camel_mime_body_part_new ();
+
+ end_of_multipart = _localize_part (stream,
+ real_boundary_line,
+ end_boundary_line,
+ &part_end);
+ body_part_input_stream =
+ camel_seekable_substream_new_with_seekable_stream_and_bounds (seekable_stream,
+ part_begining,
+ part_end);
+
+ camel_data_wrapper_set_input_stream (CAMEL_DATA_WRAPPER (body_part), body_part_input_stream);
+ camel_multipart_add_part (multipart, body_part);
+
+ }
+
+ /* g_string_assign (new_part, ""); */
+ /* _localize_part (new_part, stream, real_boundary_line, end_boundary_line); */
+
+ if (multipart->postface) g_free (multipart->postface);
+ /* if ( (new_part->str)[0] != '\0') multipart->postface = g_strdup (new_part->str); */
+
+ /* g_string_free (new_part, TRUE); */
+
+ g_free (real_boundary_line);
+ g_free (end_boundary_line);
+ CAMEL_LOG_FULL_DEBUG ("Leaving CamelMultipart::_construct_from_stream\n");
+}