dovecot-2.2: lib-imap-storage: Added support for getting BODYPAR...

dovecot at dovecot.org dovecot at dovecot.org
Sat Sep 15 19:00:53 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/a69c48fa4f32
changeset: 15058:a69c48fa4f32
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Sep 15 19:00:32 2012 +0300
description:
lib-imap-storage: Added support for getting BODYPARTSTRUCTURE
Based on patch by Stephan Bosch.

diffstat:

 src/lib-imap-storage/imap-msgpart-url.c |  23 +++++++-
 src/lib-imap-storage/imap-msgpart-url.h |   5 +
 src/lib-imap-storage/imap-msgpart.c     |  95 +++++++++++++++++++++++++++++++++
 src/lib-imap-storage/imap-msgpart.h     |   5 +
 4 files changed, 127 insertions(+), 1 deletions(-)

diffs (189 lines):

diff -r d1f084a39708 -r a69c48fa4f32 src/lib-imap-storage/imap-msgpart-url.c
--- a/src/lib-imap-storage/imap-msgpart-url.c	Sat Sep 15 18:58:48 2012 +0300
+++ b/src/lib-imap-storage/imap-msgpart-url.c	Sat Sep 15 19:00:32 2012 +0300
@@ -180,7 +180,8 @@
 
 	/* start transaction */
 	t = mailbox_transaction_begin(box, 0);
-	mail = mail_alloc(t, 0, NULL);
+	mail = mail_alloc(t, MAIL_FETCH_MESSAGE_PARTS |
+			  MAIL_FETCH_IMAP_BODYSTRUCTURE, NULL);
 
 	/* find the message */
 	if (!mail_set_uid(mail, mpurl->uid)) {
@@ -250,6 +251,26 @@
 	return ret;
 }
 
+int imap_msgpart_url_get_bodypartstructure(struct imap_msgpart_url *mpurl,
+					   const char **bpstruct_r,
+					   const char **error_r)
+{
+	struct mail *mail;
+	int ret;
+
+	/* open mail if it is not yet open */
+	ret = imap_msgpart_url_open_mail(mpurl, &mail, error_r);
+	if (ret <= 0)
+		return ret;
+
+	ret = imap_msgpart_bodypartstructure(mail, mpurl->part, bpstruct_r);
+	if (ret < 0)
+		*error_r = mailbox_get_last_error(mpurl->box, NULL);
+	else if (ret == 0)
+		*error_r = "Message part not found";
+	return ret;
+}
+
 void imap_msgpart_url_free(struct imap_msgpart_url **_mpurl)
 {
 	struct imap_msgpart_url *mpurl = *_mpurl;
diff -r d1f084a39708 -r a69c48fa4f32 src/lib-imap-storage/imap-msgpart-url.h
--- a/src/lib-imap-storage/imap-msgpart-url.h	Sat Sep 15 18:58:48 2012 +0300
+++ b/src/lib-imap-storage/imap-msgpart-url.h	Sat Sep 15 19:00:32 2012 +0300
@@ -37,6 +37,11 @@
 int imap_msgpart_url_read_part(struct imap_msgpart_url *mpurl,
 			       struct imap_msgpart_open_result *result_r,
 			       const char **error_r);
+
+int imap_msgpart_url_get_bodypartstructure(struct imap_msgpart_url *mpurl,
+					   const char **bpstruct_r,
+					   const char **error_r);
+
 int imap_msgpart_url_verify(struct imap_msgpart_url *mpurl,
 			    const char **error_r);
 void imap_msgpart_url_free(struct imap_msgpart_url **mpurl);
diff -r d1f084a39708 -r a69c48fa4f32 src/lib-imap-storage/imap-msgpart.c
--- a/src/lib-imap-storage/imap-msgpart.c	Sat Sep 15 18:58:48 2012 +0300
+++ b/src/lib-imap-storage/imap-msgpart.c	Sat Sep 15 19:00:32 2012 +0300
@@ -1,6 +1,7 @@
 /* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "str.h"
 #include "array.h"
 #include "istream.h"
 #include "istream-crlf.h"
@@ -13,6 +14,7 @@
 #include "message-decoder.h"
 #include "mail-storage-private.h"
 #include "mail-namespace.h"
+#include "imap-bodystructure.h"
 #include "imap-parser.h"
 #include "imap-msgpart.h"
 
@@ -734,6 +736,99 @@
 	return mail_get_binary_size(mail, part, include_hdr, size_r);
 }
 
+static int
+imap_msgpart_parse_bodystructure(struct mail *mail,
+				 struct message_part *all_parts)
+{
+	struct mail_private *pmail = (struct mail_private *)mail;
+	const char *bodystructure, *error;
+
+	if (mail_get_special(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE,
+			     &bodystructure) < 0)
+		return -1;
+	if (all_parts->context != NULL) {
+		/* we just parsed the bodystructure */
+		return 0;
+	}
+
+	if (imap_bodystructure_parse(bodystructure, pmail->data_pool,
+				     all_parts, &error) < 0) {
+		mail_storage_set_critical(mail->box->storage,
+			"Invalid message_part/BODYSTRUCTURE %s: %s",
+			bodystructure, error);
+		mail_set_cache_corrupted(mail, MAIL_FETCH_MESSAGE_PARTS);
+		mail_set_cache_corrupted(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE);
+		return -1;
+	}
+	return 0;
+}
+
+static int
+imap_msgpart_vsizes_to_binary(struct mail *mail, const struct message_part *part,
+			      struct message_part **binpart_r)
+{
+	struct message_part **pos;
+	uoff_t size;
+
+	if (mail_get_binary_size(mail, part, FALSE, &size) < 0)
+		return -1;
+
+	*binpart_r = t_new(struct message_part, 1);
+	**binpart_r = *part;
+	(*binpart_r)->body_size.virtual_size = size;
+
+	pos = &(*binpart_r)->children;
+	for (part = part->children; part != NULL; part = part->next) {
+		if (imap_msgpart_vsizes_to_binary(mail, part, pos) < 0)
+			return -1;
+		pos = &(*pos)->next;
+	}
+	return 0;
+}
+
+int imap_msgpart_bodypartstructure(struct mail *mail,
+				   struct imap_msgpart *msgpart,
+				   const char **bpstruct_r)
+{
+	struct message_part *all_parts, *part;
+	string_t *bpstruct;
+	int ret;
+
+	/* if we start parsing the body in here, make sure we also parse the
+	   BODYSTRUCTURE */
+	mail_add_temp_wanted_fields(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE, NULL);
+
+	if ((ret = imap_msgpart_find_part(mail, msgpart, &part)) < 0)
+		return -1;
+	if (ret == 0) {
+		/* MIME part not found. */
+		*bpstruct_r = NULL;
+		return 0;
+	}
+
+	if (mail_get_parts(mail, &all_parts) < 0)
+		return -1;
+	if (all_parts->context == NULL) {
+		if (imap_msgpart_parse_bodystructure(mail, all_parts) < 0)
+			return -1;
+	}
+	if (part == NULL)
+		part = all_parts;
+
+	T_BEGIN {
+		if (msgpart->decode_cte_to_binary)
+			ret = imap_msgpart_vsizes_to_binary(mail, part, &part);
+
+		if (ret >= 0) {
+			bpstruct = t_str_new(256);
+			imap_bodystructure_write(part, bpstruct, TRUE);
+			*bpstruct_r = str_c(bpstruct);
+		}
+	} T_END;
+	return ret < 0 ? -1 : 1;
+}
+
+
 void imap_msgpart_close_mailbox(struct imap_msgpart *msgpart)
 {
 	if (msgpart->header_ctx != NULL)
diff -r d1f084a39708 -r a69c48fa4f32 src/lib-imap-storage/imap-msgpart.h
--- a/src/lib-imap-storage/imap-msgpart.h	Sat Sep 15 18:58:48 2012 +0300
+++ b/src/lib-imap-storage/imap-msgpart.h	Sat Sep 15 19:00:32 2012 +0300
@@ -45,6 +45,11 @@
 int imap_msgpart_size(struct mail *mail, struct imap_msgpart *msgpart,
 		      size_t *size_r);
 
+/* Return msgpart's IMAP BODYPARTSTRUCTURE */
+int imap_msgpart_bodypartstructure(struct mail *mail,
+				   struct imap_msgpart *msgpart,
+				   const char **bpstruct_r);
+
 /* Header context is automatically created by imap_msgpart_open() and destroyed
    by imap_msgpart_free(), but if you want to use the same imap_msgpart across
    multiple mailboxes, you need to close the part before closing the mailbox. */


More information about the dovecot-cvs mailing list