From: Timo Sirainen Date: Fri, 25 Jun 2010 19:18:55 +0000 (+0100) Subject: lib-lda: Added mail_deliver_save_open() for merging code with sieve. X-Git-Tag: 2.0.rc1~81 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f9db221d0793f05c4631885e71f98145428a7e1b;p=thirdparty%2Fdovecot%2Fcore.git lib-lda: Added mail_deliver_save_open() for merging code with sieve. --HG-- branch : HEAD --- diff --git a/src/lib-lda/mail-deliver.c b/src/lib-lda/mail-deliver.c index 4d11c897b4..1d66eff95d 100644 --- a/src/lib-lda/mail-deliver.c +++ b/src/lib-lda/mail-deliver.c @@ -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; diff --git a/src/lib-lda/mail-deliver.h b/src/lib-lda/mail-deliver.h index 307106e9a0..b3c25159fc 100644 --- a/src/lib-lda/mail-deliver.h +++ b/src/lib-lda/mail-deliver.h @@ -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);