dovecot-2.2: lib-imap-storage: Changed imap_msgpart_url API.

dovecot at dovecot.org dovecot at dovecot.org
Fri Sep 14 21:12:07 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/f82dbf27ba79
changeset: 15047:f82dbf27ba79
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Fri Sep 14 21:11:42 2012 +0300
description:
lib-imap-storage: Changed imap_msgpart_url API.

Adds enum mail_error return value to imap_msgpart_url_open_mailbox().

Now parses msgpart at the beginning and adds function to access underlying
imap_msgpart object directly.

diffstat:

 src/imap/cmd-append.c                   |   24 +++---
 src/lib-imap-storage/imap-msgpart-url.c |  107 +++++++++++++++++--------------
 src/lib-imap-storage/imap-msgpart-url.h |   21 +++++-
 3 files changed, 87 insertions(+), 65 deletions(-)

diffs (truncated from 368 to 300 lines):

diff -r 584681a1845c -r f82dbf27ba79 src/imap/cmd-append.c
--- a/src/imap/cmd-append.c	Fri Sep 14 21:04:01 2012 +0300
+++ b/src/imap/cmd-append.c	Fri Sep 14 21:11:42 2012 +0300
@@ -160,8 +160,8 @@
 {
 	struct cmd_append_context *ctx = cmd->context;
 	struct imap_msgpart_url *mpurl;
-	struct istream *input;
-	uoff_t size, newsize;
+	struct imap_msgpart_open_result mpresult;
+	uoff_t newsize;
 	const char *error;
 	int ret;
 
@@ -182,7 +182,7 @@
 	}
 
 	/* catenate URL */
-	ret = imap_msgpart_url_read_part(mpurl, &input, &size, &error);
+	ret = imap_msgpart_url_read_part(mpurl, &mpresult, &error);
 	if (ret < 0) {
 		client_send_storage_error(cmd, ctx->storage);
 		return -1;
@@ -193,13 +193,13 @@
 			t_strdup_printf("NO [BADURL %s] %s.", caturl, error));
 		return -1;
 	}
-	if (size == 0) {
+	if (mpresult.size == 0) {
 		/* empty input */
 		imap_msgpart_url_free(&mpurl);
 		return 0;
 	}
 
-	newsize = ctx->cat_msg_size + size;
+	newsize = ctx->cat_msg_size + mpresult.size;
 	if (newsize < ctx->cat_msg_size) {
 		client_send_tagline(cmd,
 			"NO [TOOBIG] Composed message grows too big.");
@@ -209,23 +209,23 @@
 
 	ctx->cat_msg_size = newsize;
 	/* add this input stream to chain */
-	i_stream_chain_append(ctx->catchain, input);
+	i_stream_chain_append(ctx->catchain, mpresult.input);
 	/* save by reading the chain stream */
-	while (!i_stream_is_eof(input)) {
-		ret = i_stream_read(input);
+	while (!i_stream_is_eof(mpresult.input)) {
+		ret = i_stream_read(mpresult.input);
 		i_assert(ret != 0); /* we can handle only blocking input here */
 		if (mailbox_save_continue(ctx->save_ctx) < 0 || ret == -1)
 			break;
 	}
 
-	if (input->stream_errno != 0) {
-		errno = input->stream_errno;
+	if (mpresult.input->stream_errno != 0) {
+		errno = mpresult.input->stream_errno;
 		mail_storage_set_critical(ctx->box->storage,
 			"read(%s) failed: %m (for CATENATE URL %s)",
-			i_stream_get_name(input), caturl);
+			i_stream_get_name(mpresult.input), caturl);
 		client_send_storage_error(cmd, ctx->storage);
 		ret = -1;
-	} else if (!input->eof) {
+	} else if (!mpresult.input->eof) {
 		/* save failed */
 		client_send_storage_error(cmd, ctx->storage);
 		ret = -1;
diff -r 584681a1845c -r f82dbf27ba79 src/lib-imap-storage/imap-msgpart-url.c
--- a/src/lib-imap-storage/imap-msgpart-url.c	Fri Sep 14 21:04:01 2012 +0300
+++ b/src/lib-imap-storage/imap-msgpart-url.c	Fri Sep 14 21:11:42 2012 +0300
@@ -17,25 +17,37 @@
 	char *section;
 	uoff_t partial_offset, partial_size;
 
+	struct imap_msgpart *part;
+
 	struct mail_user *user;
 	struct mailbox *selected_box;
 	struct mailbox *box;
 	struct mailbox_transaction_context *trans;
 	struct mail *mail;
 	
-	struct istream *input;
-	uoff_t part_size;
+	struct imap_msgpart_open_result result;
+
+	unsigned int decode_cte_to_binary:1;
 };
 
-struct imap_msgpart_url *
-imap_msgpart_url_create(struct mail_user *user, const struct imap_url *url)
+int imap_msgpart_url_create(struct mail_user *user, const struct imap_url *url,
+			    struct imap_msgpart_url **mpurl_r,
+			    const char **error_r)
 {
+	const char *section = url->section == NULL ? "" : url->section;
 	struct imap_msgpart_url *mpurl;
+	struct imap_msgpart *msgpart;
 
 	i_assert(url->mailbox != NULL && url->uid != 0 &&
 		 url->search_program == NULL);
 
+	if (imap_msgpart_parse(section, &msgpart) < 0) {
+		*error_r = "Invalid section";
+		return -1;
+	}
+
 	mpurl = i_new(struct imap_msgpart_url, 1);
+	mpurl->part = msgpart;
 	mpurl->user = user;
 	mpurl->mailbox = i_strdup(url->mailbox);
 	mpurl->uidvalidity = url->uidvalidity;
@@ -44,11 +56,17 @@
 		mpurl->section = i_strdup(url->section);
 	mpurl->partial_offset = url->partial_offset;
 	mpurl->partial_size = url->partial_size;
-	return mpurl;
+
+	imap_msgpart_set_partial(msgpart, url->partial_offset,
+				 url->partial_size == 0 ?
+				 (uoff_t)-1 : url->partial_size);
+
+	*mpurl_r = mpurl;
+	return 0;
 }
 
 int imap_msgpart_url_parse(struct mail_user *user, struct mailbox *selected_box,
-			   const char *urlstr, struct imap_msgpart_url **url_r,
+			   const char *urlstr, struct imap_msgpart_url **mpurl_r,
 			   const char **error_r)
 {
 	struct mailbox_status box_status;
@@ -78,8 +96,9 @@
 		*error_r = "Invalid messagepart IMAP URL";
 		return 0;
 	}
-	*url_r = imap_msgpart_url_create(user, url);
-	(*url_r)->selected_box = selected_box;
+	if (imap_msgpart_url_create(user, url, mpurl_r, error_r) < 0)
+		return -1;
+	(*mpurl_r)->selected_box = selected_box;
 	return 1;
 }
 
@@ -89,16 +108,17 @@
 }
 
 int imap_msgpart_url_open_mailbox(struct imap_msgpart_url *mpurl,
-				  struct mailbox **box_r, const char **error_r)
+				  struct mailbox **box_r, enum mail_error *error_code_r,
+				  const char **error_r)
 {
 	struct mailbox_status box_status;
-	enum mail_error error_code;
 	enum mailbox_flags flags = MAILBOX_FLAG_READONLY;
 	struct mail_namespace *ns;
 	struct mailbox *box;
 
 	if (mpurl->box != NULL) {
 		*box_r = mpurl->box;
+		*error_code_r = MAIL_ERROR_NONE;
 		return 1;
 	}
 
@@ -106,6 +126,7 @@
 	ns = mail_namespace_find(mpurl->user->namespaces, mpurl->mailbox);
 	if (ns == NULL) {
 		*error_r = "Nonexistent mailbox namespace";
+		*error_code_r = MAIL_ERROR_NOTFOUND;
 		return 0;
 	}
 
@@ -117,10 +138,10 @@
 		box = mailbox_alloc(ns->list, mpurl->mailbox, flags);
 	if (mailbox_open(box) < 0) {
 		*error_r = mail_storage_get_last_error(mailbox_get_storage(box),
-						       &error_code);
+						       error_code_r);
 		if (box != mpurl->selected_box)
 			mailbox_free(&box);
-		return error_code == MAIL_ERROR_TEMP ? -1 : 0;
+		return *error_code_r == MAIL_ERROR_TEMP ? -1 : 0;
 	}
 
 	/* verify UIDVALIDITY */
@@ -128,6 +149,7 @@
 	if (mpurl->uidvalidity > 0 &&
 	    box_status.uidvalidity != mpurl->uidvalidity) {
 		*error_r = "Invalid UIDVALIDITY";
+		*error_code_r = MAIL_ERROR_EXPUNGED;
 		if (box != mpurl->selected_box)
 			mailbox_free(&box);
 		return 0;
@@ -142,6 +164,7 @@
 {
 	struct mailbox_transaction_context *t;
 	struct mailbox *box;
+	enum mail_error error_code;
 	struct mail *mail;
 	int ret;
 
@@ -151,7 +174,8 @@
 	}
 
 	/* open mailbox if it is not yet open */
-	if ((ret = imap_msgpart_url_open_mailbox(mpurl, &box, error_r)) <= 0)
+	if ((ret = imap_msgpart_url_open_mailbox(mpurl, &box, &error_code,
+						 error_r)) <= 0)
 		return ret;
 
 	/* start transaction */
@@ -172,57 +196,43 @@
 	return 1;
 }
 
-static int
-imap_msgpart_url_open_part(struct imap_msgpart_url *mpurl, struct mail **mail_r,
-			   struct imap_msgpart **msgpart_r, const char **error_r)
+struct imap_msgpart *
+imap_msgpart_url_get_part(struct imap_msgpart_url *mpurl)
 {
-	const char *section = mpurl->section == NULL ? "" : mpurl->section;
-	int ret;
+	return mpurl->part;
+}
 
-	if ((ret = imap_msgpart_url_open_mail(mpurl, mail_r, error_r)) <= 0)
-		return ret;
-
-	if (imap_msgpart_parse(section, msgpart_r) < 0) {
-		*error_r = "Invalid section";
-		return 0;
-	}
-	imap_msgpart_set_partial(*msgpart_r, mpurl->partial_offset,
-				 mpurl->partial_size == 0 ? (uoff_t)-1 :
-				 mpurl->partial_size);
-	return 1;
+void imap_msgpart_url_set_decode_to_binary(struct imap_msgpart_url *mpurl)
+{
+	imap_msgpart_set_decode_to_binary(mpurl->part);
 }
 
 int imap_msgpart_url_read_part(struct imap_msgpart_url *mpurl,
-			       struct istream **stream_r, uoff_t *size_r,
+			       struct imap_msgpart_open_result *result_r,
 			       const char **error_r)
 {
 	struct mail *mail;
-	struct imap_msgpart *msgpart;
-	struct imap_msgpart_open_result result;
 	int ret;
 
-	if (mpurl->input != NULL) {
-		i_stream_seek(mpurl->input, 0);
-		*stream_r = mpurl->input;
-		*size_r = mpurl->part_size;
+	if (mpurl->result.input != NULL) {
+		i_stream_seek(mpurl->result.input, 0);
+		*result_r = mpurl->result;
 		return 1;
 	}
 
 	/* open mail if it is not yet open */
-	ret = imap_msgpart_url_open_part(mpurl, &mail, &msgpart, error_r);
+	ret = imap_msgpart_url_open_mail(mpurl, &mail, error_r);
 	if (ret <= 0)
 		return ret;
 
 	/* open the referenced part as a stream */
-	ret = imap_msgpart_open(mail, msgpart, &result);
-	imap_msgpart_free(&msgpart);
+	ret = imap_msgpart_open(mail, mpurl->part, result_r);
 	if (ret < 0) {
-		*error_r = mailbox_get_last_error(mail->box, NULL);
+		*error_r = mailbox_get_last_error(mpurl->box, NULL);
 		return ret;
 	}
 
-	*stream_r = mpurl->input = result.input;
-	*size_r = mpurl->part_size = result.size;
+	mpurl->result = *result_r;
 	return 1;
 }
 
@@ -230,16 +240,13 @@
 			    const char **error_r)
 {
 	struct mail *mail;
-	struct imap_msgpart *msgpart;
 	int ret;
 
-	if (mpurl->input != NULL)
+	if (mpurl->result.input != NULL)
 		return 1;
 
 	/* open mail if it is not yet open */
-	ret = imap_msgpart_url_open_part(mpurl, &mail, &msgpart, error_r);


More information about the dovecot-cvs mailing list