Mercurial > dovecot > core-2.2
changeset 15047:f82dbf27ba79
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.
author | Stephan Bosch <stephan@rename-it.nl> |
---|---|
date | Fri, 14 Sep 2012 21:11:42 +0300 |
parents | 584681a1845c |
children | b74e8de5f3d9 |
files | src/imap/cmd-append.c src/lib-imap-storage/imap-msgpart-url.c src/lib-imap-storage/imap-msgpart-url.h |
diffstat | 3 files changed, 87 insertions(+), 65 deletions(-) [+] |
line wrap: on
line diff
--- 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;
--- 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); - if (ret > 0) - imap_msgpart_free(&msgpart); + ret = imap_msgpart_url_open_mail(mpurl, &mail, error_r); return ret; } @@ -249,8 +256,10 @@ *_mpurl = NULL; - if (mpurl->input != NULL) - i_stream_unref(&mpurl->input); + if (mpurl->result.input != NULL) + i_stream_unref(&mpurl->result.input); + if (mpurl->part != NULL) + imap_msgpart_free(&mpurl->part); if (mpurl->mail != NULL) mail_free(&mpurl->mail); if (mpurl->trans != NULL)
--- a/src/lib-imap-storage/imap-msgpart-url.h Fri Sep 14 21:04:01 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart-url.h Fri Sep 14 21:11:42 2012 +0300 @@ -1,28 +1,41 @@ #ifndef IMAP_MSGPART_URL_H #define IMAP_MSGPART_URL_H +#include "imap-msgpart.h" + struct imap_url; +struct imap_msgpart; struct imap_msgpart_url; /* Functions returning int return 1 on success, 0 if URL doesn't point to valid mail, -1 on storage error. */ -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 **url_r, + const char **error_r); int imap_msgpart_url_parse(struct mail_user *user, struct mailbox *selected_box, const char *urlstr, struct imap_msgpart_url **url_r, const char **error_r); 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 *imap_msgpart_url_get_mailbox(struct imap_msgpart_url *mpurl); int imap_msgpart_url_open_mail(struct imap_msgpart_url *mpurl, struct mail **mail_r, const char **error_r); +struct imap_msgpart * +imap_msgpart_url_get_part(struct imap_msgpart_url *mpurl); + +/* Decode MIME parts with Content-Transfer-Encoding: base64/quoted-printable + to binary data (IMAP BINARY extension). If something can't be decoded, fails + with storage error set to MAIL_ERROR_CONVERSION. */ +void imap_msgpart_url_set_decode_to_binary(struct imap_msgpart_url *mpurl); + /* stream_r is set to NULL when part has zero length, e.g. when partial offset is larger than the size of the referenced 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); int imap_msgpart_url_verify(struct imap_msgpart_url *mpurl, const char **error_r);