[evolution-mapi] Moved MIME parsing code from camel-mapi-transport to camel-mapi-utils.
- From: Johnny Jacob <jjohnny src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Moved MIME parsing code from camel-mapi-transport to camel-mapi-utils.
- Date: Mon, 10 Aug 2009 03:39:44 +0000 (UTC)
commit 8d455ad70bb9191ca307083885ab2d0f64180430
Author: Johnny Jacob <jjohnny novell com>
Date: Mon Aug 10 09:00:56 2009 +0530
Moved MIME parsing code from camel-mapi-transport to camel-mapi-utils.
src/camel/Makefile.am | 2 +
src/camel/camel-mapi-transport.c | 360 ++--------------------------------
src/camel/camel-mapi-utils.c | 404 ++++++++++++++++++++++++++++++++++++++
src/camel/camel-mapi-utils.h | 40 ++++
4 files changed, 461 insertions(+), 345 deletions(-)
---
diff --git a/src/camel/Makefile.am b/src/camel/Makefile.am
index 3527a33..b2f710c 100644
--- a/src/camel/Makefile.am
+++ b/src/camel/Makefile.am
@@ -18,6 +18,7 @@ libcamelmapi_la_SOURCES = \
camel-mapi-store.c \
camel-mapi-store-summary.c \
camel-mapi-summary.c \
+ camel-mapi-utils.c \
camel-mapi-transport.c
noinst_HEADERS = \
@@ -26,6 +27,7 @@ noinst_HEADERS = \
camel-mapi-store-summary.h \
camel-mapi-summary.h \
camel-mapi-transport.h \
+ camel-mapi-utils.h \
camel-mapi-private.h \
camel-private.h
diff --git a/src/camel/camel-mapi-transport.c b/src/camel/camel-mapi-transport.c
index 4904dd7..1bef7de 100644
--- a/src/camel/camel-mapi-transport.c
+++ b/src/camel/camel-mapi-transport.c
@@ -62,6 +62,7 @@
#include "camel-mapi-store.h"
#include "camel-mapi-folder.h"
#include "camel-mapi-store-summary.h"
+#include "camel-mapi-utils.h"
#include <camel/camel-session.h>
#include <camel/camel-store-summary.h>
#define d(x) x
@@ -75,265 +76,40 @@ CamelStore *get_store(void);
void set_store(CamelStore *);
-static void
-mapi_item_add_recipient (const char *recipients, OlMailRecipientType type, GSList **recipient_list);
-static mapi_id_t
-mapi_message_item_send (MapiItem *item, GSList *attachments, GSList *recipients);
-
-#if 0
-static void
-mapi_item_debug_dump (MapiItem *item)
-{
- printf("-----------------\n\n");
- printf("%s:%s: \n", G_STRLOC, G_STRFUNC);
- printf("item->header.from : %s\n",item->header.from);
- //Use Recipient List
- printf("item->header.subject : %s\n",item->header.subject);
- //printf("item->msg.body_stream : %s\n",item->msg.body_stream);
- printf("-----------------\n\n");
-}
-#endif
-
-static void
-mapi_item_set_from(MapiItem *item, const char *from)
-{
- if (item->header.from) {
- free(item->header.from);
- }
- item->header.from = strdup(from);
-}
-
-static void
-mapi_item_set_subject(MapiItem *item, const char *subject)
-{
- if (item->header.subject)
- free(item->header.subject);
-
- item->header.subject = g_strdup(subject);
-}
-
-#define MAX_READ_SIZE 0x1000
-
-static void
-mapi_item_set_body_stream (MapiItem *item, CamelStream *body, MapiItemPartType part_type)
-{
- guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
- guint32 read_size = 0;
- ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
-
- camel_seekable_stream_seek((CamelSeekableStream *)body, 0, CAMEL_STREAM_SET);
-
- stream->value = g_byte_array_new ();
-
- while((read_size = camel_stream_read(body, (char *)buf, STREAM_SIZE))){
- if (read_size == -1)
- return;
-
- stream->value = g_byte_array_append (stream->value, buf, read_size);
- }
-
- switch (part_type) {
- case PART_TYPE_TEXT_HTML :
- stream->proptag = PR_HTML;
- break;
- case PART_TYPE_PLAIN_TEXT:
- stream->proptag = PR_BODY_UNICODE;
- break;
- }
-
- if (stream->value->len < MAX_READ_SIZE)
- item->msg.body_parts = g_slist_append (item->msg.body_parts, stream);
- else
- item->generic_streams = g_slist_append (item->generic_streams, stream);
-}
-
-static gboolean
-mapi_item_add_attach (MapiItem *item, CamelMimePart *part, CamelStream *content_stream)
+/*CreateItem would return the MID of the new message or '0' if we fail.*/
+static mapi_id_t
+mapi_message_item_send (MapiItem *item)
{
- guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
- const gchar *content_id = NULL;
- guint32 read_size, flag, i = 0;
-
- ExchangeMAPIAttachment *item_attach;
- ExchangeMAPIStream *stream;
-
- const gchar *filename = camel_mime_part_get_filename (part);
-
- item_attach = g_new0 (ExchangeMAPIAttachment, 1);
-
- item_attach->lpProps = g_new0 (struct SPropValue, 5);
-
- flag = ATTACH_BY_VALUE;
- set_SPropValue_proptag(&(item_attach->lpProps[i++]), PR_ATTACH_METHOD, (const void *) (&flag));
-
- /* MSDN Documentation: When the supplied offset is -1 (0xFFFFFFFF), the
- * attachment is not rendered using the PR_RENDERING_POSITION property.
- * All values other than -1 indicate the position within PR_BODY at which
- * the attachment is to be rendered.
- */
- flag = 0xFFFFFFFF;
- set_SPropValue_proptag(&(item_attach->lpProps[i++]), PR_RENDERING_POSITION, (const void *) (&flag));
-
- if (filename) {
- set_SPropValue_proptag(&(item_attach->lpProps[i++]),
- PR_ATTACH_FILENAME,
- (const void *) g_strdup(filename));
-
- set_SPropValue_proptag(&(item_attach->lpProps[i++]),
- PR_ATTACH_LONG_FILENAME,
- (const void *) g_strdup(filename));
- }
-
- /* mime type : multipart/related */
- content_id = camel_mime_part_get_content_id (part);
- if (content_id) {
- set_SPropValue_proptag(&(item_attach->lpProps[i++]),
- PR_ATTACH_CONTENT_ID,
- (const void *) g_strdup(content_id));
- }
-
- item_attach->cValues = i;
-
- stream = g_new0 (ExchangeMAPIStream, 1);
- stream->proptag = PR_ATTACH_DATA_BIN;
- stream->value = g_byte_array_new ();
-
- camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET);
- while((read_size = camel_stream_read(content_stream, (char *)buf, STREAM_SIZE))){
- stream->value = g_byte_array_append (stream->value, buf, read_size);
- }
-
- item_attach->streams = g_slist_append (item_attach->streams, stream);
- item->attachments = g_slist_append(item->attachments, item_attach);
-
- return TRUE;
-}
+ guint64 fid = 0;
+ mapi_id_t mid = 0;
-static gboolean
-mapi_do_multipart(CamelMultipart *mp, MapiItem *item)
-{
- CamelDataWrapper *dw;
- CamelStream *content_stream;
- CamelContentType *type;
- CamelMimePart *part;
- gint n_part, i_part;
- const gchar *filename;
- const gchar *description;
- const gchar *content_id;
- gint content_size;
-
- n_part = camel_multipart_get_number(mp);
- for (i_part = 0; i_part < n_part; i_part++) {
- /* getting part */
- part = camel_multipart_get_part(mp, i_part);
- dw = camel_medium_get_content_object (CAMEL_MEDIUM (part));
- if (CAMEL_IS_MULTIPART(dw)) {
- /* recursive */
- if (!mapi_do_multipart(CAMEL_MULTIPART(dw), item))
- return FALSE;
- continue ;
- }
- /* filename */
- filename = camel_mime_part_get_filename(part);
-
- content_stream = camel_stream_mem_new();
- content_size = camel_data_wrapper_decode_to_stream (dw, (CamelStream *) content_stream);
- camel_stream_write ((CamelStream *) content_stream, "", 1);
-
- camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET);
-
- description = camel_mime_part_get_description(part);
- content_id = camel_mime_part_get_content_id(part);
-
- type = camel_mime_part_get_content_type(part);
-
- if (i_part == 0 && camel_content_type_is (type, "text", "plain")) {
- mapi_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
- } else if (camel_content_type_is (type, "text", "html")) {
- mapi_item_set_body_stream (item, content_stream, PART_TYPE_TEXT_HTML);
- } else {
- mapi_item_add_attach (item, part, content_stream);
- }
- }
+ mid = exchange_mapi_create_item (olFolderOutbox, fid, NULL, NULL,
+ camel_mapi_utils_create_item_build_props,
+ item, item->recipients,
+ item->attachments, item->generic_streams, 0);
- return TRUE;
+ return mid;
}
-
static gboolean
mapi_send_to (CamelTransport *transport, CamelMimeMessage *message,
CamelAddress *from, CamelAddress *recipients, CamelException *ex)
{
- CamelDataWrapper *dw = NULL;
- CamelContentType *type;
- CamelStream *content_stream;
- CamelMultipart *multipart;
- const CamelInternetAddress *to, *cc, *bcc;
- MapiItem *item = g_new0 (MapiItem, 1);
+ MapiItem *item = NULL;
const char *namep;
const char *addressp;
- const char *content_type;
mapi_id_t st = 0;
- ssize_t content_size;
- GSList *recipient_list = NULL;
- GSList *attach_list = NULL;
- gint i = 0;
- /* headers */
if (!camel_internet_address_get((const CamelInternetAddress *)from, 0, &namep, &addressp)) {
- printf("index\n");
return (FALSE);
}
- /** WARNING: double check **/
- mapi_item_set_from (item, namep);
-
- to = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_TO);
- for (i = 0; camel_internet_address_get(to, i, &namep, &addressp); i++){
- mapi_item_add_recipient (addressp, olTo, &recipient_list);
- }
-
- cc = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_CC);
- for (i = 0; camel_internet_address_get(cc, i, &namep, &addressp); i++) {
- mapi_item_add_recipient (addressp, olCC, &recipient_list);
- }
- bcc = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_BCC);
- for (i = 0; camel_internet_address_get(bcc, i, &namep, &addressp); i++) {
- mapi_item_add_recipient (addressp, olBCC, &recipient_list);
- }
-
- if (camel_mime_message_get_subject(message)) {
- mapi_item_set_subject(item, camel_mime_message_get_subject(message));
- }
-
- /*Add message threading properties */
- item->header.references = g_strdup (camel_medium_get_header ((CamelMedium *) message, "References"));
- item->header.in_reply_to = g_strdup (camel_medium_get_header ((CamelMedium *) message, "In-Reply-To"));
- item->header.message_id = g_strdup (camel_medium_get_header ((CamelMedium *) message, "Message-Id"));
-
- /* contents body */
- multipart = (CamelMultipart *)camel_medium_get_content_object (CAMEL_MEDIUM (message));
-
- if (CAMEL_IS_MULTIPART(multipart)) {
- if (mapi_do_multipart(CAMEL_MULTIPART(multipart), item))
- printf("camel message multi part error\n");
- } else {
- dw = camel_medium_get_content_object (CAMEL_MEDIUM (message));
- if (dw) {
- type = camel_mime_part_get_content_type((CamelMimePart *)message);
- content_type = camel_content_type_simple (type);
+ /* Convert MIME to MAPIItem, attacment lists and recipient list.*/
+ item = camel_mapi_utils_mime_to_item (message, from, recipients, ex);
- content_stream = (CamelStream *)camel_stream_mem_new();
- content_size = camel_data_wrapper_write_to_stream(dw, (CamelStream *)content_stream);
- camel_stream_write ((CamelStream *) content_stream, "", 1);
-
- mapi_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
- }
- }
-
/* send */
- st = mapi_message_item_send(item, attach_list, recipient_list);
+ st = mapi_message_item_send(item);
if (st == 0) {
/*Fixme : Set a better error message. Would be helful in troubleshooting. */
@@ -395,109 +171,3 @@ camel_mapi_transport_get_type (void)
return camel_mapi_transport_type;
}
-static gint
-mail_build_props (struct SPropValue **value, struct SPropTagArray *SPropTagArray, gpointer data)
-{
-
- MapiItem *item = (MapiItem *) data;
- struct SPropValue *props;
- GSList *l;
-
- uint32_t *msgflag = g_new0 (uint32_t, 1);
- int i=0;
-
- props = g_new0 (struct SPropValue, 9);
-
- set_SPropValue_proptag(&props[i++], PR_CONVERSATION_TOPIC_UNICODE, g_strdup (item->header.subject));
- set_SPropValue_proptag(&props[i++], PR_NORMALIZED_SUBJECT_UNICODE, g_strdup (item->header.subject));
-
- *msgflag = MSGFLAG_UNSENT;
- set_SPropValue_proptag(&props[i++], PR_MESSAGE_FLAGS, (void *)msgflag);
-
- /* Message threading information */
- if (item->header.references)
- set_SPropValue_proptag(&props[i++], PR_INTERNET_REFERENCES, g_strdup (item->header.references));
-
- if (item->header.in_reply_to)
- set_SPropValue_proptag(&props[i++], PR_IN_REPLY_TO_ID, g_strdup (item->header.in_reply_to));
-
- if (item->header.message_id)
- set_SPropValue_proptag(&props[i++], PR_INTERNET_MESSAGE_ID, g_strdup (item->header.message_id));
-
- for (l = item->msg.body_parts; l; l = l->next) {
- ExchangeMAPIStream *stream = (ExchangeMAPIStream *) (l->data);
- struct SBinary_short *bin = g_new0 (struct SBinary_short, 1);
-
- bin->cb = stream->value->len;
- bin->lpb = (uint8_t *)stream->value->data;
- if (stream->proptag == PR_HTML)
- set_SPropValue_proptag(&props[i++], stream->proptag, (void *)bin);
- else if (stream->proptag == PR_BODY_UNICODE)
- set_SPropValue_proptag(&props[i++], stream->proptag, (void *)stream->value->data);
- }
-
- /* FIXME : */
- /* editor = EDITOR_FORMAT_PLAINTEXT; */
- /* set_SPropValue_proptag(&props[i++], PR_MSG_EDITOR_FORMAT, (const void *)editor); */
-
- *value = props;
- return i;
-}
-
-static void
-mapi_item_add_recipient (const char *recipients, OlMailRecipientType type, GSList **recipient_list)
-{
- ExchangeMAPIRecipient *recipient;
- uint32_t val = 0;
- const char *str = NULL;
-
- if (!recipients)
- return ;
-
- recipient = g_new0 (ExchangeMAPIRecipient, 1);
-
- recipient->email_id = recipients;
-
- /* this memory should be freed somewhere, perhaps in the existing
- * exchange_mapi_util_free_recipient_list() */
- recipient->in.req_lpProps = g_new0 (struct SPropValue, 2);
- recipient->in.req_cValues = 2;
-
- set_SPropValue_proptag (&(recipient->in.req_lpProps[0]), PR_RECIPIENT_TYPE, (const void *) &type);
-
- val = 0;
- set_SPropValue_proptag (&(recipient->in.req_lpProps[1]), PR_SEND_INTERNET_ENCODING, (const void *)&val);
-
- /* External recipient properties - set them only when the recipient is unresolved */
- recipient->in.ext_lpProps = g_new0 (struct SPropValue, 7);
- recipient->in.ext_cValues = 7;
-
- val = DT_MAILUSER;
- set_SPropValue_proptag (&(recipient->in.ext_lpProps[0]), PR_DISPLAY_TYPE, (const void *)&val);
- val = MAPI_MAILUSER;
- set_SPropValue_proptag (&(recipient->in.ext_lpProps[1]), PR_OBJECT_TYPE, (const void *)&val);
- str = "SMTP";
- set_SPropValue_proptag (&(recipient->in.ext_lpProps[2]), PR_ADDRTYPE, (const void *)(str));
- str = recipient->email_id;
- set_SPropValue_proptag (&(recipient->in.ext_lpProps[3]), PR_SMTP_ADDRESS, (const void *)(str));
- /* FIXME: Please add the correct names here instead of the e-mail ID */
- set_SPropValue_proptag (&(recipient->in.ext_lpProps[4]), PR_GIVEN_NAME, (const void *)(str));
- set_SPropValue_proptag (&(recipient->in.ext_lpProps[5]), PR_DISPLAY_NAME, (const void *)(str));
- set_SPropValue_proptag (&(recipient->in.ext_lpProps[6]), PR_7BIT_DISPLAY_NAME, (const void *)(str));
-
- *recipient_list = g_slist_append (*recipient_list, recipient);
-}
-
-/*CreateItem would return the MID of the new message or '0' if we fail.*/
-static mapi_id_t
-mapi_message_item_send (MapiItem *item, GSList *attachments, GSList *recipients)
-{
- guint64 fid = 0;
- mapi_id_t mid = 0;
-
- mid = exchange_mapi_create_item (olFolderOutbox, fid, NULL, NULL,
- mail_build_props, item, recipients,
- item->attachments, item->generic_streams, 0);
-
- return mid;
-}
diff --git a/src/camel/camel-mapi-utils.c b/src/camel/camel-mapi-utils.c
new file mode 100644
index 0000000..329197b
--- /dev/null
+++ b/src/camel/camel-mapi-utils.c
@@ -0,0 +1,404 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Johnny Jacob <jjohnny novell com>
+ *
+ * Copyright (C) 1999-2009 Novell, Inc. (www.novell.com)
+ *
+ */
+
+
+/* -- Generate MIME to ITEM -- */
+
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/exchange.h>
+
+#include <camel/camel-data-wrapper.h>
+#include <camel/camel-exception.h>
+#include <camel/camel-mime-filter-crlf.h>
+#include <camel/camel-mime-message.h>
+#include <camel/camel-multipart.h>
+#include <camel/camel-session.h>
+#include <camel/camel-stream-filter.h>
+#include <camel/camel-stream-mem.h>
+
+#include <camel/camel-private.h>
+#include <camel/camel-i18n.h>
+#include <camel/camel-net-utils.h>
+#include <camel/camel-seekable-stream.h>
+#include <camel/camel-sasl.h>
+#include <camel/camel-utf8.h>
+#include <camel/camel-tcp-stream-raw.h>
+
+#ifdef HAVE_SSL
+#include <camel/camel-tcp-stream-ssl.h>
+#endif
+
+#include <exchange-mapi-defs.h>
+
+#include "camel-mapi-store.h"
+#include "camel-mapi-folder.h"
+#include "camel-mapi-store-summary.h"
+#include "camel-mapi-utils.h"
+
+#define d(x) x
+
+#define STREAM_SIZE 4000
+
+static void
+mapi_item_add_recipient (const char *recipients, OlMailRecipientType type, GSList **recipient_list)
+{
+ ExchangeMAPIRecipient *recipient;
+ uint32_t val = 0;
+ const char *str = NULL;
+
+ if (!recipients)
+ return ;
+
+ recipient = g_new0 (ExchangeMAPIRecipient, 1);
+
+ recipient->email_id = recipients;
+
+ /* this memory should be freed somewhere, perhaps in the existing
+ * exchange_mapi_util_free_recipient_list() */
+ recipient->in.req_lpProps = g_new0 (struct SPropValue, 2);
+ recipient->in.req_cValues = 2;
+
+ set_SPropValue_proptag (&(recipient->in.req_lpProps[0]), PR_RECIPIENT_TYPE, (const void *) &type);
+
+ val = 0;
+ set_SPropValue_proptag (&(recipient->in.req_lpProps[1]), PR_SEND_INTERNET_ENCODING, (const void *)&val);
+
+ /* External recipient properties - set them only when the recipient is unresolved */
+ recipient->in.ext_lpProps = g_new0 (struct SPropValue, 7);
+ recipient->in.ext_cValues = 7;
+
+ val = DT_MAILUSER;
+ set_SPropValue_proptag (&(recipient->in.ext_lpProps[0]), PR_DISPLAY_TYPE, (const void *)&val);
+ val = MAPI_MAILUSER;
+ set_SPropValue_proptag (&(recipient->in.ext_lpProps[1]), PR_OBJECT_TYPE, (const void *)&val);
+ str = "SMTP";
+ set_SPropValue_proptag (&(recipient->in.ext_lpProps[2]), PR_ADDRTYPE, (const void *)(str));
+ str = recipient->email_id;
+ set_SPropValue_proptag (&(recipient->in.ext_lpProps[3]), PR_SMTP_ADDRESS, (const void *)(str));
+ /* FIXME: Please add the correct names here instead of the e-mail ID */
+ set_SPropValue_proptag (&(recipient->in.ext_lpProps[4]), PR_GIVEN_NAME, (const void *)(str));
+ set_SPropValue_proptag (&(recipient->in.ext_lpProps[5]), PR_DISPLAY_NAME, (const void *)(str));
+ set_SPropValue_proptag (&(recipient->in.ext_lpProps[6]), PR_7BIT_DISPLAY_NAME, (const void *)(str));
+
+ *recipient_list = g_slist_append (*recipient_list, recipient);
+}
+
+static void
+mapi_item_set_from(MapiItem *item, const char *from)
+{
+ if (item->header.from) {
+ free(item->header.from);
+ }
+ item->header.from = strdup(from);
+}
+
+static void
+mapi_item_set_subject(MapiItem *item, const char *subject)
+{
+ if (item->header.subject)
+ free(item->header.subject);
+
+ item->header.subject = g_strdup(subject);
+}
+
+#define MAX_READ_SIZE 0x1000
+
+static void
+mapi_item_set_body_stream (MapiItem *item, CamelStream *body, MapiItemPartType part_type)
+{
+ guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
+ guint32 read_size = 0;
+ ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
+
+ camel_seekable_stream_seek((CamelSeekableStream *)body, 0, CAMEL_STREAM_SET);
+
+ stream->value = g_byte_array_new ();
+
+ while((read_size = camel_stream_read(body, (char *)buf, STREAM_SIZE))){
+ if (read_size == -1)
+ return;
+
+ stream->value = g_byte_array_append (stream->value, buf, read_size);
+ }
+
+ switch (part_type) {
+ case PART_TYPE_TEXT_HTML :
+ stream->proptag = PR_HTML;
+ break;
+ case PART_TYPE_PLAIN_TEXT:
+ stream->proptag = PR_BODY_UNICODE;
+ break;
+ }
+
+ if (stream->value->len < MAX_READ_SIZE)
+ item->msg.body_parts = g_slist_append (item->msg.body_parts, stream);
+ else
+ item->generic_streams = g_slist_append (item->generic_streams, stream);
+
+}
+
+static gboolean
+mapi_item_add_attach (MapiItem *item, CamelMimePart *part, CamelStream *content_stream)
+{
+ guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
+ const gchar *content_id = NULL;
+ guint32 read_size, flag, i = 0;
+
+ ExchangeMAPIAttachment *item_attach;
+ ExchangeMAPIStream *stream;
+
+ const gchar *filename = camel_mime_part_get_filename (part);
+
+ item_attach = g_new0 (ExchangeMAPIAttachment, 1);
+
+ item_attach->lpProps = g_new0 (struct SPropValue, 5);
+
+ flag = ATTACH_BY_VALUE;
+ set_SPropValue_proptag(&(item_attach->lpProps[i++]), PR_ATTACH_METHOD, (const void *) (&flag));
+
+ /* MSDN Documentation: When the supplied offset is -1 (0xFFFFFFFF), the
+ * attachment is not rendered using the PR_RENDERING_POSITION property.
+ * All values other than -1 indicate the position within PR_BODY at which
+ * the attachment is to be rendered.
+ */
+ flag = 0xFFFFFFFF;
+ set_SPropValue_proptag(&(item_attach->lpProps[i++]), PR_RENDERING_POSITION, (const void *) (&flag));
+
+ if (filename) {
+ set_SPropValue_proptag(&(item_attach->lpProps[i++]),
+ PR_ATTACH_FILENAME,
+ (const void *) g_strdup(filename));
+
+ set_SPropValue_proptag(&(item_attach->lpProps[i++]),
+ PR_ATTACH_LONG_FILENAME,
+ (const void *) g_strdup(filename));
+ }
+
+ /* mime type : multipart/related */
+ content_id = camel_mime_part_get_content_id (part);
+ if (content_id) {
+ set_SPropValue_proptag(&(item_attach->lpProps[i++]),
+ PR_ATTACH_CONTENT_ID,
+ (const void *) g_strdup(content_id));
+ }
+
+ item_attach->cValues = i;
+
+ stream = g_new0 (ExchangeMAPIStream, 1);
+ stream->proptag = PR_ATTACH_DATA_BIN;
+ stream->value = g_byte_array_new ();
+
+ camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET);
+ while((read_size = camel_stream_read(content_stream, (char *)buf, STREAM_SIZE))){
+ stream->value = g_byte_array_append (stream->value, buf, read_size);
+ }
+
+ item_attach->streams = g_slist_append (item_attach->streams, stream);
+ item->attachments = g_slist_append(item->attachments, item_attach);
+
+ return TRUE;
+}
+
+static gboolean
+mapi_do_multipart(CamelMultipart *mp, MapiItem *item)
+{
+ CamelDataWrapper *dw;
+ CamelStream *content_stream;
+ CamelContentType *type;
+ CamelMimePart *part;
+ gint n_part, i_part;
+ const gchar *filename;
+ const gchar *description;
+ const gchar *content_id;
+ gint content_size;
+
+ n_part = camel_multipart_get_number(mp);
+ for (i_part = 0; i_part < n_part; i_part++) {
+ /* getting part */
+ part = camel_multipart_get_part(mp, i_part);
+ dw = camel_medium_get_content_object (CAMEL_MEDIUM (part));
+ if (CAMEL_IS_MULTIPART(dw)) {
+ /* recursive */
+ if (!mapi_do_multipart(CAMEL_MULTIPART(dw), item))
+ return FALSE;
+ continue ;
+ }
+ /* filename */
+ filename = camel_mime_part_get_filename(part);
+
+ content_stream = camel_stream_mem_new();
+ content_size = camel_data_wrapper_decode_to_stream (dw, (CamelStream *) content_stream);
+ camel_stream_write ((CamelStream *) content_stream, "", 1);
+
+ camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET);
+
+ description = camel_mime_part_get_description(part);
+ content_id = camel_mime_part_get_content_id(part);
+
+ type = camel_mime_part_get_content_type(part);
+
+ if (i_part == 0 && camel_content_type_is (type, "text", "plain")) {
+ mapi_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
+ } else if (camel_content_type_is (type, "text", "html")) {
+ mapi_item_set_body_stream (item, content_stream, PART_TYPE_TEXT_HTML);
+ } else {
+ mapi_item_add_attach (item, part, content_stream);
+ }
+ }
+
+ return TRUE;
+}
+
+
+MapiItem *
+camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, CamelAddress *recipients,
+ CamelException *ex)
+{
+ CamelDataWrapper *dw = NULL;
+ CamelContentType *type;
+ CamelStream *content_stream;
+ CamelMultipart *multipart;
+ const CamelInternetAddress *to, *cc, *bcc;
+ MapiItem *item = g_new0 (MapiItem, 1);
+ const char *namep;
+ const char *addressp;
+ const char *content_type;
+
+ ssize_t content_size;
+ GSList *recipient_list = NULL;
+ gint i = 0;
+
+ /* headers */
+
+ if (!camel_internet_address_get((const CamelInternetAddress *)from, 0, &namep, &addressp)) {
+ printf("index\n");
+ return (FALSE);
+ }
+
+ /** WARNING: double check **/
+ mapi_item_set_from (item, namep);
+
+ to = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_TO);
+ for (i = 0; camel_internet_address_get(to, i, &namep, &addressp); i++){
+ mapi_item_add_recipient (addressp, olTo, &recipient_list);
+ }
+
+ cc = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_CC);
+ for (i = 0; camel_internet_address_get(cc, i, &namep, &addressp); i++) {
+ mapi_item_add_recipient (addressp, olCC, &recipient_list);
+ }
+
+ bcc = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_BCC);
+ for (i = 0; camel_internet_address_get(bcc, i, &namep, &addressp); i++) {
+ mapi_item_add_recipient (addressp, olBCC, &recipient_list);
+ }
+
+ if (camel_mime_message_get_subject(message)) {
+ mapi_item_set_subject(item, camel_mime_message_get_subject(message));
+ }
+
+ /*Add message threading properties */
+ item->header.references = g_strdup (camel_medium_get_header ((CamelMedium *) message, "References"));
+ item->header.in_reply_to = g_strdup (camel_medium_get_header ((CamelMedium *) message, "In-Reply-To"));
+ item->header.message_id = g_strdup (camel_medium_get_header ((CamelMedium *) message, "Message-Id"));
+
+ /* contents body */
+ multipart = (CamelMultipart *)camel_medium_get_content_object (CAMEL_MEDIUM (message));
+
+ if (CAMEL_IS_MULTIPART(multipart)) {
+ if (mapi_do_multipart(CAMEL_MULTIPART(multipart), item))
+ printf("camel message multi part error\n");
+ } else {
+ dw = camel_medium_get_content_object (CAMEL_MEDIUM (message));
+ if (dw) {
+ type = camel_mime_part_get_content_type((CamelMimePart *)message);
+ content_type = camel_content_type_simple (type);
+
+ content_stream = (CamelStream *)camel_stream_mem_new();
+ content_size = camel_data_wrapper_write_to_stream(dw, (CamelStream *)content_stream);
+ camel_stream_write ((CamelStream *) content_stream, "", 1);
+
+ mapi_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
+ }
+ }
+
+ item->attachments = attach_list;
+ item->recipients = recipient_list;
+
+ return item;
+}
+
+gint
+camel_mapi_utils_create_item_build_props (struct SPropValue **value, struct SPropTagArray *SPropTagArray, gpointer data)
+{
+
+ MapiItem *item = (MapiItem *) data;
+ struct SPropValue *props;
+ GSList *l;
+
+ uint32_t *msgflag = g_new0 (uint32_t, 1);
+ int i=0;
+
+ props = g_new0 (struct SPropValue, 9);
+
+ set_SPropValue_proptag(&props[i++], PR_CONVERSATION_TOPIC_UNICODE, g_strdup (item->header.subject));
+ set_SPropValue_proptag(&props[i++], PR_NORMALIZED_SUBJECT_UNICODE, g_strdup (item->header.subject));
+
+ *msgflag = MSGFLAG_UNSENT;
+ set_SPropValue_proptag(&props[i++], PR_MESSAGE_FLAGS, (void *)msgflag);
+
+ /* Message threading information */
+ if (item->header.references)
+ set_SPropValue_proptag(&props[i++], PR_INTERNET_REFERENCES, g_strdup (item->header.references));
+
+ if (item->header.in_reply_to)
+ set_SPropValue_proptag(&props[i++], PR_IN_REPLY_TO_ID, g_strdup (item->header.in_reply_to));
+
+ if (item->header.message_id)
+ set_SPropValue_proptag(&props[i++], PR_INTERNET_MESSAGE_ID, g_strdup (item->header.message_id));
+
+ for (l = item->msg.body_parts; l; l = l->next) {
+ ExchangeMAPIStream *stream = (ExchangeMAPIStream *) (l->data);
+ struct SBinary_short *bin = g_new0 (struct SBinary_short, 1);
+
+ bin->cb = stream->value->len;
+ bin->lpb = (uint8_t *)stream->value->data;
+ if (stream->proptag == PR_HTML)
+ set_SPropValue_proptag(&props[i++], stream->proptag, (void *)bin);
+ else if (stream->proptag == PR_BODY_UNICODE)
+ set_SPropValue_proptag(&props[i++], stream->proptag, (void *)stream->value->data);
+ }
+
+ /* FIXME : */
+ /* editor = EDITOR_FORMAT_PLAINTEXT; */
+ /* set_SPropValue_proptag(&props[i++], PR_MSG_EDITOR_FORMAT, (const void *)editor); */
+
+ *value = props;
+ return i;
+}
+
+/* -- Generate MIME to ITEM -- */
diff --git a/src/camel/camel-mapi-utils.h b/src/camel/camel-mapi-utils.h
new file mode 100644
index 0000000..ca200ad
--- /dev/null
+++ b/src/camel/camel-mapi-utils.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Johnny Jacob <jjohnny novell com>
+ *
+ * Copyright (C) 1999-2009 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __CAMEL_MAPI_UTILS_H__
+#define __CAMEL_MAPI_UTILS_H__
+
+G_BEGIN_DECLS
+
+MapiItem *
+camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from,
+ CamelAddress *recipients, CamelException *ex);
+
+gint
+camel_mapi_utils_create_item_build_props (struct SPropValue **value,
+ struct SPropTagArray *SPropTagArray,
+ gpointer data);
+
+G_END_DECLS
+
+#endif /* CAMEL_MAPI_UTILS_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]