dovecot-2.2: Created lib-imap-storage for IMAP-specific function...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Jun 2 19:02:27 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/07e6ca397a72
changeset: 14591:07e6ca397a72
user: Stephan Bosch <stephan at rename-it.nl>
date: Sat Jun 02 17:56:27 2012 +0300
description:
Created lib-imap-storage for IMAP-specific functionality that uses lib-storage.
This is done to prevent introducing dependencies on lib-storage in
lib-imap. It contains IMAP message part access functionality, including
URL-based access.
diffstat:
configure.in | 5 +-
src/Makefile.am | 1 +
src/imap/Makefile.am | 2 +-
src/imap/imap-fetch-body.c | 53 +----
src/lib-imap-storage/Makefile.am | 21 +
src/lib-imap-storage/imap-msgpart-url.c | 230 +++++++++++++++++++
src/lib-imap-storage/imap-msgpart-url.h | 29 ++
src/lib-imap-storage/imap-msgpart.c | 371 ++++++++++++++++++++++++++++++++
src/lib-imap-storage/imap-msgpart.h | 24 ++
src/lib-storage/Makefile.am | 1 +
10 files changed, 683 insertions(+), 54 deletions(-)
diffs (truncated from 839 to 300 lines):
diff -r 9eef4f7b0187 -r 07e6ca397a72 configure.in
--- a/configure.in Sat Jun 02 17:53:31 2012 +0300
+++ b/configure.in Sat Jun 02 17:56:27 2012 +0300
@@ -2512,13 +2512,13 @@
if test "$want_shared_libs" = "yes"; then
LIBDOVECOT_DEPS='$(top_builddir)/src/lib-dovecot/libdovecot.la'
LIBDOVECOT="$LIBDOVECOT_DEPS"
- LIBDOVECOT_STORAGE_DEPS='$(top_builddir)/src/lib-storage/libdovecot-storage.la'
+ LIBDOVECOT_STORAGE_DEPS='$(top_builddir)/src/lib-storage/libdovecot-storage.la $(top_builddir)/src/lib-imap-storage/libimap-storage.la'
LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/libdovecot-login.la'
LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/libdovecot-lda.la'
else
LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib/liblib.la'
LIBDOVECOT="$LIBDOVECOT_DEPS \$(LIBICONV)"
- LIBDOVECOT_STORAGE_LAST='$(top_builddir)/src/lib-storage/list/libstorage_list.la $(top_builddir)/src/lib-storage/index/libstorage_index.la $(top_builddir)/src/lib-storage/libstorage.la $(top_builddir)/src/lib-index/libindex.la'
+ LIBDOVECOT_STORAGE_LAST='$(top_builddir)/src/lib-storage/list/libstorage_list.la $(top_builddir)/src/lib-storage/index/libstorage_index.la $(top_builddir)/src/lib-storage/libstorage.la $(top_builddir)/src/lib-index/libindex.la $(top_builddir)/src/lib-imap-storage/libimap-storage.la'
LIBDOVECOT_STORAGE_FIRST='$(top_builddir)/src/lib-storage/libstorage_service.la $(top_builddir)/src/lib-storage/register/libstorage_register.la'
LIBDOVECOT_STORAGE_DEPS="$LIBDOVECOT_STORAGE_FIRST $LINKED_STORAGE_LIBS $LIBDOVECOT_STORAGE_LAST"
LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la'
@@ -2748,6 +2748,7 @@
src/lib-dns/Makefile
src/lib-fs/Makefile
src/lib-imap/Makefile
+src/lib-imap-storage/Makefile
src/lib-imap-client/Makefile
src/lib-index/Makefile
src/lib-lda/Makefile
diff -r 9eef4f7b0187 -r 07e6ca397a72 src/Makefile.am
--- a/src/Makefile.am Sat Jun 02 17:53:31 2012 +0300
+++ b/src/Makefile.am Sat Jun 02 17:56:27 2012 +0300
@@ -6,6 +6,7 @@
lib-fs \
lib-mail \
lib-imap \
+ lib-imap-storage \
lib-master \
lib-dict \
lib-settings
diff -r 9eef4f7b0187 -r 07e6ca397a72 src/imap/Makefile.am
--- a/src/imap/Makefile.am Sat Jun 02 17:53:31 2012 +0300
+++ b/src/imap/Makefile.am Sat Jun 02 17:56:27 2012 +0300
@@ -9,6 +9,7 @@
-I$(top_srcdir)/src/lib-master \
-I$(top_srcdir)/src/lib-mail \
-I$(top_srcdir)/src/lib-imap \
+ -I$(top_srcdir)/src/lib-imap-storage \
-I$(top_srcdir)/src/lib-index \
-I$(top_srcdir)/src/lib-storage
@@ -78,7 +79,6 @@
mail-storage-callbacks.c \
main.c
-
headers = \
imap-client.h \
imap-commands.h \
diff -r 9eef4f7b0187 -r 07e6ca397a72 src/imap/imap-fetch-body.c
--- a/src/imap/imap-fetch-body.c Sat Jun 02 17:53:31 2012 +0300
+++ b/src/imap/imap-fetch-body.c Sat Jun 02 17:56:27 2012 +0300
@@ -11,6 +11,7 @@
#include "message-send.h"
#include "mail-storage-private.h"
#include "imap-parser.h"
+#include "imap-msgpart.h"
#include "imap-fetch.h"
#include <stdlib.h>
@@ -464,63 +465,13 @@
return fetch_data(ctx, body, &size);
}
-/* Find message_part for section (eg. 1.3.4) */
-static int part_find(struct mail *mail, const struct imap_fetch_body_data *body,
- const struct message_part **part_r, const char **section_r)
-{
- struct message_part *part;
- const char *path;
- unsigned int num;
-
- if (mail_get_parts(mail, &part) < 0)
- return -1;
-
- path = body->section;
- while (*path >= '0' && *path <= '9' && part != NULL) {
- /* get part number, we have already verified its validity */
- num = 0;
- while (*path != '\0' && *path != '.') {
- i_assert(*path >= '0' && *path <= '9');
-
- num = num*10 + (*path - '0');
- path++;
- }
-
- if (*path == '.')
- path++;
-
- if (part->flags & MESSAGE_PART_FLAG_MULTIPART) {
- /* find the part */
- part = part->children;
- for (; num > 1 && part != NULL; num--)
- part = part->next;
- } else {
- /* only 1 allowed with non-multipart messages */
- if (num != 1)
- part = NULL;
- }
-
- if (part != NULL &&
- (part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) &&
- (*path >= '0' && *path <= '9')) {
- /* if we continue inside the message/rfc822, skip this
- body part */
- part = part->children;
- }
- }
-
- *part_r = part;
- *section_r = path;
- return 0;
-}
-
static int fetch_body_mime(struct imap_fetch_context *ctx, struct mail *mail,
const struct imap_fetch_body_data *body)
{
const struct message_part *part;
const char *section;
- if (part_find(mail, body, &part, §ion) < 0)
+ if (imap_msgpart_find(mail, body->section, &part, §ion) < 0)
return -1;
if (part == NULL) {
diff -r 9eef4f7b0187 -r 07e6ca397a72 src/lib-imap-storage/Makefile.am
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-imap-storage/Makefile.am Sat Jun 02 17:56:27 2012 +0300
@@ -0,0 +1,21 @@
+noinst_LTLIBRARIES = libimap-storage.la
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/lib-test \
+ -I$(top_srcdir)/src/lib-charset \
+ -I$(top_srcdir)/src/lib-mail \
+ -I$(top_srcdir)/src/lib-storage \
+ -I$(top_srcdir)/src/lib-imap
+
+libimap_storage_la_SOURCES = \
+ imap-msgpart.c \
+ imap-msgpart-url.c
+
+headers = \
+ imap-msgpart.h \
+ imap-msgpart-url.h
+
+pkginc_libdir=$(pkgincludedir)
+pkginc_lib_HEADERS = $(headers)
+
diff -r 9eef4f7b0187 -r 07e6ca397a72 src/lib-imap-storage/imap-msgpart-url.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-imap-storage/imap-msgpart-url.c Sat Jun 02 17:56:27 2012 +0300
@@ -0,0 +1,230 @@
+#include "lib.h"
+#include "network.h"
+#include "istream.h"
+#include "message-parser.h"
+#include "mail-storage.h"
+#include "mail-namespace.h"
+#include "imap-url.h"
+#include "imap-msgpart.h"
+#include "imap-msgpart-url.h"
+
+struct imap_msgpart_url {
+ char *mailbox;
+ uint32_t uidvalidity;
+ uint32_t uid;
+ char *section;
+ uoff_t partial_offset, partial_size;
+
+ struct mail_user *user;
+ struct mailbox *box;
+ struct mailbox_transaction_context *trans;
+ struct mail *mail;
+
+ struct istream *input;
+ uoff_t part_size;
+};
+
+struct imap_msgpart_url *
+imap_msgpart_url_create(struct mail_user *user, const struct imap_url *url)
+{
+ struct imap_msgpart_url *mpurl;
+
+ i_assert(url->mailbox != NULL && url->uid != 0 &&
+ url->search_program == NULL);
+
+ mpurl = i_new(struct imap_msgpart_url, 1);
+ mpurl->user = user;
+ mpurl->mailbox = i_strdup(url->mailbox);
+ mpurl->uidvalidity = url->uidvalidity;
+ mpurl->uid = url->uid;
+ if (url->section != NULL)
+ mpurl->section = i_strdup(url->section);
+ mpurl->partial_offset = url->partial_offset;
+ mpurl->partial_size = url->partial_size;
+ return mpurl;
+}
+
+struct imap_msgpart_url *
+imap_msgpart_url_parse(struct mail_user *user, struct mailbox *selected_box,
+ const char *urlstr, const char **error_r)
+{
+ struct mailbox_status box_status;
+ struct imap_url base_url, *url;
+ const char *error;
+
+ /* build base url */
+ memset(&base_url, 0, sizeof(base_url));
+ if (selected_box != NULL) {
+ mailbox_get_open_status(selected_box, STATUS_UIDVALIDITY,
+ &box_status);
+ base_url.mailbox = mailbox_get_vname(selected_box);
+ base_url.uidvalidity = box_status.uidvalidity;
+ }
+
+ /* parse url */
+ url = imap_url_parse(urlstr, NULL, &base_url,
+ IMAP_URL_PARSE_REQUIRE_RELATIVE, &error);
+ if (url == NULL) {
+ *error_r = t_strconcat("Invalid IMAP URL: ", error, NULL);
+ return NULL;
+ }
+ if (url->mailbox == NULL) {
+ *error_r = "Mailbox-relative IMAP URL, but no mailbox selected";
+ return NULL;
+ }
+ if (url->uid == 0 || url->search_program != NULL) {
+ *error_r = "Invalid messagepart IMAP URL";
+ return NULL;
+ }
+ return imap_msgpart_url_create(user, url);
+}
+
+struct mailbox *imap_msgpart_url_get_mailbox(struct imap_msgpart_url *mpurl)
+{
+ return mpurl->box;
+}
+
+struct mailbox *
+imap_msgpart_url_open_mailbox(struct imap_msgpart_url *mpurl,
+ 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)
+ return mpurl->box;
+
+ /* find mailbox namespace */
+ ns = mail_namespace_find(mpurl->user->namespaces, mpurl->mailbox);
+ if (ns == NULL) {
+ *error_r = "Nonexistent mailbox namespace";
+ return NULL;
+ }
+
+ /* open mailbox */
+ 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);
+ mailbox_free(&box);
+ return NULL;
+ }
+
+ /* verify UIDVALIDITY */
+ mailbox_get_open_status(box, STATUS_UIDVALIDITY, &box_status);
+ if (mpurl->uidvalidity > 0 &&
+ box_status.uidvalidity != mpurl->uidvalidity) {
+ *error_r = "Invalid UIDVALIDITY";
+ mailbox_free(&box);
+ return NULL;
+ }
+ mpurl->box = box;
+ return box;
+}
+
+struct mail *
+imap_msgpart_url_open_mail(struct imap_msgpart_url *mpurl, const char **error_r)
+{
+ struct mailbox_transaction_context *t;
+ struct mail *mail;
+
+ if (mpurl->mail != NULL)
+ return mpurl->mail;
+
+ /* open mailbox if it is not yet open */
+ if (mpurl->box == NULL) {
More information about the dovecot-cvs
mailing list