]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-lda: Added mail_deliver_save_open() for merging code with sieve.
authorTimo Sirainen <tss@iki.fi>
Fri, 25 Jun 2010 19:18:55 +0000 (20:18 +0100)
committerTimo Sirainen <tss@iki.fi>
Fri, 25 Jun 2010 19:18:55 +0000 (20:18 +0100)
--HG--
branch : HEAD

src/lib-lda/mail-deliver.c
src/lib-lda/mail-deliver.h

index 4d11c897b4d16735cbcbdb6349d9f582db99297c..1d66eff95df1631a9a6050366eb73ce3154fa774 100644 (file)
@@ -83,10 +83,19 @@ void mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...)
        va_end(args);
 }
 
-static struct mailbox *
-mailbox_open_or_create_synced(struct mail_deliver_context *ctx, 
-                             const char *name, struct mail_namespace **ns_r,
-                             const char **error_r)
+static const char *mailbox_name_to_mutf7(const char *mailbox_utf8)
+{
+       string_t *str = t_str_new(128);
+
+       if (imap_utf8_to_utf7(mailbox_utf8, str) < 0)
+               return mailbox_utf8;
+       else
+               return str_c(str);
+}
+
+int mail_deliver_save_open(struct mail_deliver_save_open_context *ctx,
+                          const char *name, struct mailbox **box_r,
+                          const char **error_r)
 {
        struct mail_namespace *ns;
        struct mail_storage *storage;
@@ -96,46 +105,46 @@ mailbox_open_or_create_synced(struct mail_deliver_context *ctx,
                MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_SAVEONLY |
                MAILBOX_FLAG_POST_SESSION;
 
+       *box_r = NULL;
        *error_r = NULL;
 
-       if (strcasecmp(name, "INBOX") == 0) {
-               /* deliveries to INBOX must always succeed,
-                  regardless of ACLs */
-               flags |= MAILBOX_FLAG_IGNORE_ACLS;
+       name = mailbox_name_to_mutf7(name);
+       ns = mail_namespace_find(ctx->user->namespaces, &name);
+       if (ns == NULL) {
+               *error_r = "Unknown namespace";
+               return -1;
        }
 
-       *ns_r = ns = mail_namespace_find(ctx->dest_user->namespaces, &name);
-       if (*ns_r == NULL)
-               return NULL;
-
        if (*name == '\0' && (ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
                /* delivering to a namespace prefix means we actually want to
                   deliver to the INBOX instead */
-               *error_r = "Trying to deliver to namespace prefix";
-               return NULL;
+               name = "INBOX";
+               ns = mail_namespace_find_inbox(ctx->user->namespaces);
        }
 
-       box = mailbox_alloc(ns->list, name, flags);
+       if (strcasecmp(name, "INBOX") == 0) {
+               /* deliveries to INBOX must always succeed,
+                  regardless of ACLs */
+               flags |= MAILBOX_FLAG_IGNORE_ACLS;
+       }
+
+       *box_r = box = mailbox_alloc(ns->list, name, flags);
        if (mailbox_open(box) == 0)
-               return box;
+               return 0;
 
        storage = mailbox_get_storage(box);
        *error_r = mail_storage_get_last_error(storage, &error);
-       if (!ctx->set->lda_mailbox_autocreate || error != MAIL_ERROR_NOTFOUND) {
-               mailbox_free(&box);
-               return NULL;
-       }
+       if (!ctx->lda_mailbox_autocreate || error != MAIL_ERROR_NOTFOUND)
+               return -1;
 
        /* try creating it. */
        if (mailbox_create(box, NULL, FALSE) < 0) {
                *error_r = mail_storage_get_last_error(storage, &error);
-               if (error != MAIL_ERROR_EXISTS) {
-                       mailbox_free(&box);
-                       return NULL;
-               }
+               if (error != MAIL_ERROR_EXISTS)
+                       return -1;
                /* someone else just created it */
        }
-       if (ctx->set->lda_mailbox_autosubscribe) {
+       if (ctx->lda_mailbox_autosubscribe) {
                /* (try to) subscribe to it */
                (void)mailbox_list_set_subscribed(ns->list, name, TRUE);
        }
@@ -143,27 +152,16 @@ mailbox_open_or_create_synced(struct mail_deliver_context *ctx,
        /* and try opening again */
        if (mailbox_sync(box, 0) < 0) {
                *error_r = mail_storage_get_last_error(storage, &error);
-               mailbox_free(&box);
-               return NULL;
+               return -1;
        }
-       return box;
-}
-
-static const char *mailbox_name_to_mutf7(const char *mailbox_utf8)
-{
-       string_t *str = t_str_new(128);
-
-       if (imap_utf8_to_utf7(mailbox_utf8, str) < 0)
-               return mailbox_utf8;
-       else
-               return str_c(str);
+       return 0;
 }
 
 int mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
                      enum mail_flags flags, const char *const *keywords,
                      struct mail_storage **storage_r)
 {
-       struct mail_namespace *ns;
+       struct mail_deliver_save_open_context open_ctx;
        struct mailbox *box;
        enum mailbox_transaction_flags trans_flags;
        struct mailbox_transaction_context *t;
@@ -182,20 +180,15 @@ int mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
        if (default_save)
                ctx->tried_default_save = TRUE;
 
+       memset(&open_ctx, 0, sizeof(open_ctx));
+       open_ctx.user = ctx->dest_user;
+       open_ctx.lda_mailbox_autocreate = ctx->set->lda_mailbox_autocreate;
+       open_ctx.lda_mailbox_autosubscribe = ctx->set->lda_mailbox_autosubscribe;
+
        mailbox_name = str_sanitize(mailbox, 80);
-       mailbox = mailbox_name_to_mutf7(mailbox);
-       box = mailbox_open_or_create_synced(ctx, mailbox, &ns, &errstr);
-       if (box == NULL) {
-               if (ns == NULL) {
-                       mail_deliver_log(ctx,
-                                        "save failed to %s: Unknown namespace",
-                                        mailbox_name);
-                       return -1;
-               }
-               if (default_save && strcmp(ns->prefix, mailbox) == 0) {
-                       /* silently store to the INBOX instead */
-                       return -1;
-               }
+       if (mail_deliver_save_open(&open_ctx, mailbox, &box, &errstr) < 0) {
+               if (box != NULL)
+                       mailbox_free(&box);
                mail_deliver_log(ctx, "save failed to %s: %s",
                                 mailbox_name, errstr);
                return -1;
index 307106e9a0ceb0fceda143c61dd0a782e39454d8..b3c25159fcb0a4be85fc26bee75b7bdab47ced30 100644 (file)
@@ -3,6 +3,7 @@
 
 enum mail_flags;
 struct mail_storage;
+struct mailbox;
 
 struct mail_deliver_context {
        pool_t pool;
@@ -35,6 +36,12 @@ struct mail_deliver_context {
        bool save_dest_mail;
 };
 
+struct mail_deliver_save_open_context {
+       struct mail_user *user;
+       bool lda_mailbox_autocreate;
+       bool lda_mailbox_autosubscribe;
+};
+
 typedef int deliver_mail_func_t(struct mail_deliver_context *ctx,
                                struct mail_storage **storage_r);
 
@@ -49,6 +56,11 @@ const char *mail_deliver_get_address(struct mail *mail, const char *header);
 const char *mail_deliver_get_return_address(struct mail_deliver_context *ctx);
 const char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx);
 
+/* Try to open mailbox for saving. Returns 0 if ok, -1 if error. The box may
+   be returned even with -1, and the caller must free it then. */
+int mail_deliver_save_open(struct mail_deliver_save_open_context *ctx,
+                          const char *name, struct mailbox **box_r,
+                          const char **error_r);
 int mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
                      enum mail_flags flags, const char *const *keywords,
                      struct mail_storage **storage_r);