]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Renamed deliver to dovecot-lda and moved most of its code to lib-lda.
authorTimo Sirainen <tss@iki.fi>
Mon, 13 Apr 2009 19:45:17 +0000 (15:45 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 13 Apr 2009 19:45:17 +0000 (15:45 -0400)
--HG--
branch : HEAD

18 files changed:
.hgignore
configure.in
src/Makefile.am
src/deliver/deliver.h [deleted file]
src/deliver/mail-send.h [deleted file]
src/lda/Makefile.am [moved from src/deliver/Makefile.am with 51% similarity]
src/lda/main.c [moved from src/deliver/deliver.c with 54% similarity]
src/lib-lda/Makefile.am [new file with mode: 0644]
src/lib-lda/duplicate.c [moved from src/deliver/duplicate.c with 99% similarity]
src/lib-lda/duplicate.h [moved from src/deliver/duplicate.h with 91% similarity]
src/lib-lda/lda-settings.c [moved from src/deliver/deliver-settings.c with 51% similarity]
src/lib-lda/lda-settings.h [moved from src/deliver/deliver-settings.h with 60% similarity]
src/lib-lda/mail-deliver.c [new file with mode: 0644]
src/lib-lda/mail-deliver.h [new file with mode: 0644]
src/lib-lda/mail-send.c [moved from src/deliver/mail-send.c with 85% similarity]
src/lib-lda/mail-send.h [new file with mode: 0644]
src/lib-lda/smtp-client.c [moved from src/deliver/smtp-client.c with 86% similarity]
src/lib-lda/smtp-client.h [moved from src/deliver/smtp-client.h with 67% similarity]

index 7d7db71a1fbba4891fdf565838d18e6a5ce9061e..28f032ac607e9dd2e2099dbd7ed2dc5a604716b1 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -55,7 +55,7 @@ src/auth/checkpassword-reply
 src/auth/dovecot-auth
 src/config/all-settings.c
 src/config/doveconf
-src/deliver/deliver
+src/lda/dovecot-lda
 src/dict/dict
 src/imap-login/imap-login
 src/imap/imap
index 98cc501a56ddf0f0c68d77b66fba3ee1fff889d6..418f1b4582161bec6a0fe9496e2cf9382f8cfc59 100644 (file)
@@ -2360,6 +2360,7 @@ src/lib-charset/Makefile
 src/lib-dict/Makefile
 src/lib-imap/Makefile
 src/lib-index/Makefile
+src/lib-lda/Makefile
 src/lib-mail/Makefile
 src/lib-master/Makefile
 src/lib-ntlm/Makefile
@@ -2378,7 +2379,7 @@ src/lib-storage/index/shared/Makefile
 src/lib-storage/register/Makefile
 src/auth/Makefile
 src/config/Makefile
-src/deliver/Makefile
+src/lda/Makefile
 src/dict/Makefile
 src/imap/Makefile
 src/imap-login/Makefile
index d23981a8fbe941b5115a9f1f007b6710a565effb..da4660a5ca581c9da878b9826112f9865f502972 100644 (file)
@@ -24,7 +24,7 @@ SUBDIRS = \
        imap \
        pop3-login \
        pop3 \
-       deliver \
+       lda \
        config \
        tests \
        util \
diff --git a/src/deliver/deliver.h b/src/deliver/deliver.h
deleted file mode 100644 (file)
index 5c4bafd..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef DELIVER_H
-#define DELIVER_H
-
-#include <sysexits.h>
-
-#ifndef EX_CONFIG
-#  define EX_CONFIG 78 /* HP-UX */
-#endif
-
-#include "lib.h"
-#include "mail-storage.h"
-#include "deliver-settings.h"
-
-extern const struct deliver_settings *deliver_set;
-extern bool mailbox_autosubscribe;
-extern bool mailbox_autocreate;
-extern bool tried_default_save;
-
-typedef int deliver_mail_func_t(struct mail_namespace *namespaces,
-                               struct mail_storage **storage_r,
-                               struct mail *mail,
-                               const char *destaddr, const char *mailbox);
-
-extern deliver_mail_func_t *deliver_mail;
-
-/* Save a mail into given mailbox with given flags and keywords. */
-int deliver_save(struct mail_namespace *namespaces,
-                struct mail_storage **storage_r, const char *mailbox,
-                struct mail *mail, enum mail_flags flags,
-                const char *const *keywords);
-
-/* Extracts user@domain from Return-Path header. Returns NULL if not found. */
-const char *deliver_get_return_address(struct mail *mail);
-
-/* Returns a new unique Message-ID */
-const char *deliver_get_new_message_id(void);
-
-#endif
diff --git a/src/deliver/mail-send.h b/src/deliver/mail-send.h
deleted file mode 100644 (file)
index fd1e05e..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef MAIL_SEND_H
-#define MAIL_SEND_H
-
-struct mail;
-
-int mail_send_rejection(struct mail *mail, const char *recipient,
-                       const char *reason);
-int mail_send_forward(struct mail *mail, const char *forwardto);
-
-#endif
similarity index 51%
rename from src/deliver/Makefile.am
rename to src/lda/Makefile.am
index c3d2d0add55203b2078d94d40c5412f102f482cc..3eae845cd98910da706124c672ac079ea2117d7d 100644 (file)
@@ -1,6 +1,6 @@
 pkglibexecdir = $(libexecdir)/dovecot
 
-pkglibexec_PROGRAMS = deliver
+pkglibexec_PROGRAMS = dovecot-lda
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
@@ -9,38 +9,22 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib-imap \
        -I$(top_srcdir)/src/lib-index \
        -I$(top_srcdir)/src/lib-master \
+       -I$(top_srcdir)/src/lib-lda \
        -I$(top_srcdir)/src/lib-storage \
        -I$(top_srcdir)/src/lib-storage/index \
        -I$(top_srcdir)/src/lib-storage/index/raw \
        -DPKG_RUNDIR=\""$(rundir)"\"
 
-deliver_LDFLAGS = -export-dynamic
+dovecot_lda_LDFLAGS = -export-dynamic
 
 libs = \
+       ../lib-lda/liblda.a \
        ../lib-storage/libdovecot-storage.la \
        ../lib-dovecot/libdovecot.la
 
-deliver_LDADD = $(libs)
+dovecot_lda_LDADD = $(libs)
 
-deliver_DEPENDENCIES = $(libs)
+dovecot_lda_DEPENDENCIES = $(libs)
 
-deliver_SOURCES = \
-       deliver.c \
-       deliver-settings.c \
-       duplicate.c \
-       mail-send.c \
-       smtp-client.c
-
-headers = \
-       deliver.h \
-       deliver-settings.h \
-       duplicate.h \
-       mail-send.h \
-       smtp-client.h
-
-if INSTALL_HEADERS
-  pkginc_libdir=$(pkgincludedir)/src/deliver
-  pkginc_lib_HEADERS = $(headers)
-else
-  noinst_HEADERS = $(headers)
-endif
+dovecot_lda_SOURCES = \
+       main.c
similarity index 54%
rename from src/deliver/deliver.c
rename to src/lda/main.c
index a55d775fa0d99b9f4279e125f130c29d1d0e6d58..2dc560e8a1933c692cfdf698faeb50d184b71692 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "lib-signals.h"
-#include "ioloop.h"
 #include "env-util.h"
 #include "fd-set-nonblock.h"
 #include "istream.h"
@@ -10,7 +9,6 @@
 #include "str.h"
 #include "str-sanitize.h"
 #include "strescape.h"
-#include "var-expand.h"
 #include "rfc822-parser.h"
 #include "message-address.h"
 #include "imap-utf7.h"
 #include "mail-storage-service.h"
 #include "mail-namespace.h"
 #include "raw-storage.h"
+#include "mail-deliver.h"
 #include "mail-send.h"
 #include "duplicate.h"
 #include "mbox-from.h"
-#include "deliver.h"
+#include "lda-settings.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <pwd.h>
+#include <sysexits.h>
+
+#ifndef EX_CONFIG
+#  define EX_CONFIG 78 /* for HP-UX */
+#endif
 
 #define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON"
 
@@ -40,219 +44,8 @@ static const char *wanted_headers[] = {
        NULL
 };
 
-const struct deliver_settings *deliver_set;
-deliver_mail_func_t *deliver_mail = NULL;
-bool mailbox_autosubscribe;
-bool mailbox_autocreate;
-bool tried_default_save = FALSE;
-
-/* FIXME: these two should be in some context struct instead of as globals.. */
-static const char *default_mailbox_name = NULL;
-static bool saved_mail = FALSE;
-static char *explicit_envelope_sender = NULL;
-
 static struct master_service *service;
 
-static const char *deliver_get_address(struct mail *mail, const char *header)
-{
-       struct message_address *addr;
-       const char *str;
-
-       if (mail_get_first_header(mail, header, &str) <= 0)
-               return NULL;
-       addr = message_address_parse(pool_datastack_create(),
-                                    (const unsigned char *)str,
-                                    strlen(str), 1, FALSE);
-       return addr == NULL || addr->mailbox == NULL || addr->domain == NULL ||
-               *addr->mailbox == '\0' || *addr->domain == '\0' ?
-               NULL : t_strconcat(addr->mailbox, "@", addr->domain, NULL);
-}
-
-static const struct var_expand_table *
-get_log_var_expand_table(struct mail *mail, const char *message)
-{
-       static struct var_expand_table static_tab[] = {
-               { '$', NULL, NULL },
-               { 'm', NULL, "msgid" },
-               { 's', NULL, "subject" },
-               { 'f', NULL, "from" },
-               { '\0', NULL, NULL }
-       };
-       struct var_expand_table *tab;
-       unsigned int i;
-
-       tab = t_malloc(sizeof(static_tab));
-       memcpy(tab, static_tab, sizeof(static_tab));
-
-       tab[0].value = message;
-       (void)mail_get_first_header(mail, "Message-ID", &tab[1].value);
-       (void)mail_get_first_header(mail, "Subject", &tab[2].value);
-       tab[3].value = deliver_get_address(mail, "From");
-       for (i = 1; tab[i].key != '\0'; i++)
-               tab[i].value = str_sanitize(tab[i].value, 80);
-       return tab;
-}
-
-static void
-deliver_log(struct mail *mail, const char *fmt, ...) ATTR_FORMAT(2, 3);
-
-static void deliver_log(struct mail *mail, const char *fmt, ...)
-{
-       va_list args;
-       string_t *str;
-       const char *msg;
-
-       va_start(args, fmt);
-       msg = t_strdup_vprintf(fmt, args);
-
-       str = t_str_new(256);
-       var_expand(str, deliver_set->deliver_log_format,
-                  get_log_var_expand_table(mail, msg));
-       i_info("%s", str_c(str));
-       va_end(args);
-}
-
-static struct mailbox *
-mailbox_open_or_create_synced(struct mail_namespace *namespaces,
-                             struct mail_storage **storage_r,
-                             const char *name)
-{
-       struct mail_namespace *ns;
-       struct mailbox *box;
-       enum mail_error error;
-       enum mailbox_open_flags open_flags = MAILBOX_OPEN_FAST |
-               MAILBOX_OPEN_KEEP_RECENT | MAILBOX_OPEN_SAVEONLY |
-               MAILBOX_OPEN_POST_SESSION;
-
-       if (strcasecmp(name, "INBOX") == 0) {
-               /* deliveries to INBOX must always succeed,
-                  regardless of ACLs */
-               open_flags |= MAILBOX_OPEN_IGNORE_ACLS;
-       }
-
-       ns = mail_namespace_find(namespaces, &name);
-       if (ns == NULL) {
-               *storage_r = NULL;
-               return NULL;
-       }
-       *storage_r = ns->storage;
-
-       if (*name == '\0') {
-               /* delivering to a namespace prefix means we actually want to
-                  deliver to the INBOX instead */
-               return NULL;
-       }
-
-       box = mailbox_open(storage_r, name, NULL, open_flags);
-       if (box != NULL || !mailbox_autocreate)
-               return box;
-
-       (void)mail_storage_get_last_error(*storage_r, &error);
-       if (error != MAIL_ERROR_NOTFOUND)
-               return NULL;
-
-       /* try creating it. */
-       if (mail_storage_mailbox_create(*storage_r, name, FALSE) < 0)
-               return NULL;
-       if (mailbox_autosubscribe) {
-               /* (try to) subscribe to it */
-               (void)mailbox_list_set_subscribed(ns->list, name, TRUE);
-       }
-
-       /* and try opening again */
-       box = mailbox_open(storage_r, name, NULL, open_flags);
-       if (box == NULL)
-               return NULL;
-
-       if (mailbox_sync(box, 0, 0, NULL) < 0) {
-               mailbox_close(&box);
-               return NULL;
-       }
-       return box;
-}
-
-int deliver_save(struct mail_namespace *namespaces,
-                struct mail_storage **storage_r, const char *mailbox,
-                struct mail *mail, enum mail_flags flags,
-                const char *const *keywords)
-{
-       struct mailbox *box;
-       struct mailbox_transaction_context *t;
-       struct mail_save_context *save_ctx;
-       struct mail_keywords *kw;
-       enum mail_error error;
-       const char *mailbox_name;
-       bool default_save;
-       int ret = 0;
-
-       default_save = strcmp(mailbox, default_mailbox_name) == 0;
-       if (default_save)
-               tried_default_save = TRUE;
-
-       mailbox_name = str_sanitize(mailbox, 80);
-       box = mailbox_open_or_create_synced(namespaces, storage_r, mailbox);
-       if (box == NULL) {
-               if (*storage_r == NULL) {
-                       deliver_log(mail,
-                                   "save failed to %s: Unknown namespace",
-                                   mailbox_name);
-                       return -1;
-               }
-               if (default_save &&
-                   strcmp((*storage_r)->ns->prefix, mailbox) == 0) {
-                       /* silently store to the INBOX instead */
-                       return -1;
-               }
-               deliver_log(mail, "save failed to %s: %s", mailbox_name,
-                           mail_storage_get_last_error(*storage_r, &error));
-               return -1;
-       }
-
-       t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
-
-       kw = str_array_length(keywords) == 0 ? NULL :
-               mailbox_keywords_create_valid(box, keywords);
-       save_ctx = mailbox_save_alloc(t);
-       mailbox_save_set_flags(save_ctx, flags, kw);
-       if (mailbox_copy(&save_ctx, mail) < 0)
-               ret = -1;
-       mailbox_keywords_free(box, &kw);
-
-       if (ret < 0)
-               mailbox_transaction_rollback(&t);
-       else
-               ret = mailbox_transaction_commit(&t);
-
-       if (ret == 0) {
-               saved_mail = TRUE;
-               deliver_log(mail, "saved mail to %s", mailbox_name);
-       } else {
-               deliver_log(mail, "save failed to %s: %s", mailbox_name,
-                           mail_storage_get_last_error(*storage_r, &error));
-       }
-
-       mailbox_close(&box);
-       return ret;
-}
-
-const char *deliver_get_return_address(struct mail *mail)
-{
-       if (explicit_envelope_sender != NULL)
-               return explicit_envelope_sender;
-
-       return deliver_get_address(mail, "Return-Path");
-}
-
-const char *deliver_get_new_message_id(void)
-{
-       static int count = 0;
-
-       return t_strdup_printf("<dovecot-%s-%s-%d@%s>",
-                              dec2str(ioloop_timeval.tv_sec),
-                              dec2str(ioloop_timeval.tv_usec),
-                              count++, deliver_set->hostname);
-}
-
 static const char *escape_local_part(const char *local_part)
 {
        const char *p;
@@ -293,7 +86,8 @@ static const char *address_sanitize(const char *address)
 
 
 static struct istream *
-create_raw_stream(const char *temp_path_prefix, int fd, time_t *mtime_r)
+create_raw_stream(struct mail_deliver_context *ctx,
+                 const char *temp_path_prefix, int fd, time_t *mtime_r)
 {
        struct istream *input, *input2, *input_list[2];
        const unsigned char *data;
@@ -326,10 +120,10 @@ create_raw_stream(const char *temp_path_prefix, int fd, time_t *mtime_r)
                }
        }
 
-       if (sender != NULL && explicit_envelope_sender == NULL) {
+       if (sender != NULL && ctx->src_envelope_sender == NULL) {
                /* use the envelope sender from From_-line, but only if it
                   hasn't been specified with -f already. */
-               explicit_envelope_sender = i_strdup(sender);
+               ctx->src_envelope_sender = p_strdup(ctx->pool, sender);
        }
        i_free(sender);
 
@@ -377,15 +171,15 @@ static void print_help(void)
 {
        printf(
 "Usage: deliver [-c <config file>] [-a <address>] [-d <username>] [-p <path>]\n"
-"               [-f <envelope sender>] [-m <mailbox>] [-n] [-s] [-e] [-k]\n");
+"               [-f <envelope sender>] [-m <mailbox>] [-e] [-k]\n");
 }
 
 int main(int argc, char *argv[])
 {
+       struct mail_deliver_context ctx;
        enum mail_storage_service_flags service_flags = 0;
-       const char *mailbox = "INBOX";
-       const char *destaddr, *user, *errstr, *path, *getopt_str;
-       struct mail_user *mail_user, *raw_mail_user;
+       const char *user, *errstr, *path, *getopt_str;
+       struct mail_user *raw_mail_user;
        struct mail_namespace *raw_ns;
        struct mail_namespace_settings raw_ns_set;
        struct mail_storage *storage;
@@ -394,7 +188,6 @@ int main(int argc, char *argv[])
        struct istream *input;
        struct mailbox_transaction_context *t;
        struct mailbox_header_lookup_ctx *headers_ctx;
-       struct mail *mail;
        char cwd[PATH_MAX];
        void **sets;
        uid_t process_euid;
@@ -430,8 +223,10 @@ int main(int argc, char *argv[])
         lib_signals_ignore(SIGXFSZ, TRUE);
 #endif
 
-       mailbox_autocreate = TRUE;
-       destaddr = path = NULL;
+       memset(&ctx, 0, sizeof(ctx));
+       ctx.pool = pool_alloconly_create("mail deliver context", 256);
+       ctx.dest_mailbox_name = "INBOX";
+       path = NULL;
 
        user = getenv("USER");
        getopt_str = t_strconcat("a:d:p:ekm:nsf:",
@@ -440,7 +235,7 @@ int main(int argc, char *argv[])
                switch (c) {
                case 'a':
                        /* destination address */
-                       destaddr = optarg;
+                       ctx.dest_addr = optarg;
                        break;
                case 'd':
                        /* destination user */
@@ -464,25 +259,20 @@ int main(int argc, char *argv[])
                        /* destination mailbox.
                           Ignore -m "". This allows doing -m ${extension}
                           in Postfix to handle user+mailbox */
-                       if (*optarg != '\0') {
+                       if (*optarg != '\0') T_BEGIN {
                                str = t_str_new(256);
                                if (imap_utf8_to_utf7(optarg, str) < 0) {
                                        i_fatal("Mailbox name not UTF-8: %s",
-                                               mailbox);
+                                               optarg);
                                }
-                               mailbox = str_c(str);
-                       }
-                       break;
-               case 'n':
-                       mailbox_autocreate = FALSE;
-                       break;
-               case 's':
-                       mailbox_autosubscribe = TRUE;
+                               ctx.dest_mailbox_name =
+                                       p_strdup(ctx.pool, str_c(str));
+                       } T_END;
                        break;
                case 'f':
                        /* envelope sender address */
-                       explicit_envelope_sender =
-                               i_strdup(address_sanitize(optarg));
+                       ctx.src_envelope_sender =
+                               p_strdup(ctx.pool, address_sanitize(optarg));
                        break;
                default:
                        if (!master_service_parse_option(service, c, optarg)) {
@@ -524,10 +314,10 @@ int main(int argc, char *argv[])
        }
 
        service_flags |= MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT;
-       mail_user = mail_storage_service_init_user(service, user,
-                               &deliver_setting_parser_info, service_flags);
-       deliver_set = mail_storage_service_get_settings(service);
-        duplicate_init(mail_user_set_get_storage_set(mail_user->set));
+       ctx.dest_user = mail_storage_service_init_user(service, user,
+                               &lda_setting_parser_info, service_flags);
+       ctx.set = mail_storage_service_get_settings(service);
+        duplicate_init(mail_user_set_get_storage_set(ctx.dest_user->set));
 
        /* create a separate mail user for the internal namespace */
        if (master_service_set(service, "mail_full_filesystem_access=yes") < 0)
@@ -547,8 +337,8 @@ int main(int argc, char *argv[])
        if (mail_storage_create(raw_ns, "raw", 0, &errstr) < 0)
                i_fatal("Couldn't create internal raw storage: %s", errstr);
        if (path == NULL) {
-               const char *prefix = mail_user_get_temp_prefix(mail_user);
-               input = create_raw_stream(prefix, 0, &mtime);
+               const char *prefix = mail_user_get_temp_prefix(ctx.dest_user);
+               input = create_raw_stream(&ctx, prefix, 0, &mtime);
                box = mailbox_open(&raw_ns->storage, "Dovecot Delivery Mail",
                                   input, MAILBOX_OPEN_NO_INDEX_FILES);
                i_stream_unref(&input);
@@ -566,53 +356,25 @@ int main(int argc, char *argv[])
                        mail_storage_get_last_error(raw_ns->storage, &error));
        }
        raw_box = (struct raw_mailbox *)box;
-       raw_box->envelope_sender = explicit_envelope_sender != NULL ?
-               explicit_envelope_sender : DEFAULT_ENVELOPE_SENDER;
+       raw_box->envelope_sender = ctx.src_envelope_sender != NULL ?
+               ctx.src_envelope_sender : DEFAULT_ENVELOPE_SENDER;
        raw_box->mtime = mtime;
 
        t = mailbox_transaction_begin(box, 0);
        headers_ctx = mailbox_header_lookup_init(box, wanted_headers);
-       mail = mail_alloc(t, 0, headers_ctx);
-       mail_set_seq(mail, 1);
-
-       if (destaddr == NULL) {
-               destaddr = deliver_get_address(mail, "Envelope-To");
-               if (destaddr == NULL) {
-                       destaddr = strchr(user, '@') != NULL ? user :
-                               t_strconcat(user, "@",
-                                           deliver_set->hostname, NULL);
+       ctx.src_mail = mail_alloc(t, 0, headers_ctx);
+       mail_set_seq(ctx.src_mail, 1);
+
+       if (ctx.dest_addr == NULL) {
+               ctx.dest_addr = mail_deliver_get_address(&ctx, "Envelope-To");
+               if (ctx.dest_addr == NULL) {
+                       ctx.dest_addr = strchr(user, '@') != NULL ? user :
+                               t_strconcat(user, "@", ctx.set->hostname, NULL);
                }
        }
 
-       storage = NULL;
-       default_mailbox_name = mailbox;
-       if (deliver_mail == NULL)
-               ret = -1;
-       else {
-               if (deliver_mail(mail_user->namespaces, &storage, mail,
-                                destaddr, mailbox) <= 0) {
-                       /* if message was saved, don't bounce it even though
-                          the script failed later. */
-                       ret = saved_mail ? 0 : -1;
-               } else {
-                       /* success. message may or may not have been saved. */
-                       ret = 0;
-               }
-       }
-
-       if (ret < 0 && !tried_default_save) {
-               /* plugins didn't handle this. save into the default mailbox. */
-               ret = deliver_save(mail_user->namespaces,
-                                  &storage, mailbox, mail, 0, NULL);
-       }
-       if (ret < 0 && strcasecmp(mailbox, "INBOX") != 0) {
-               /* still didn't work. try once more to save it
-                  to INBOX. */
-               ret = deliver_save(mail_user->namespaces,
-                                  &storage, "INBOX", mail, 0, NULL);
-       }
-
-       if (ret < 0 ) {
+       ret = mail_deliver(&ctx, &storage);
+       if (ret < 0) {
                if (storage == NULL) {
                        /* This shouldn't happen */
                        i_error("BUG: Saving failed for unknown storage");
@@ -628,7 +390,7 @@ int main(int argc, char *argv[])
                }
 
                if (error != MAIL_ERROR_NOSPACE ||
-                   deliver_set->quota_full_tempfail) {
+                   ctx.set->quota_full_tempfail) {
                        /* Saving to INBOX should always work unless
                           we're over quota. If it didn't, it's probably a
                           configuration problem. */
@@ -636,26 +398,26 @@ int main(int argc, char *argv[])
                }
 
                /* we'll have to reply with permanent failure */
-               deliver_log(mail, "rejected: %s",
-                           str_sanitize(errstr, 512));
+               mail_deliver_log(&ctx, "rejected: %s",
+                                str_sanitize(errstr, 512));
 
                if (stderr_rejection)
                        return EX_NOPERM;
-               ret = mail_send_rejection(mail, user, errstr);
+               ret = mail_send_rejection(&ctx, user, errstr);
                if (ret != 0)
                        return ret < 0 ? EX_TEMPFAIL : ret;
                /* ok, rejection sent */
        }
-       i_free(explicit_envelope_sender);
 
-       mail_free(&mail);
+       mail_free(&ctx.src_mail);
        mailbox_header_lookup_unref(&headers_ctx);
        mailbox_transaction_rollback(&t);
        mailbox_close(&box);
 
-       mail_user_unref(&mail_user);
+       mail_user_unref(&ctx.dest_user);
        mail_user_unref(&raw_mail_user);
        duplicate_deinit();
+       pool_unref(&ctx.pool);
 
        mail_storage_service_deinit_user();
        master_service_deinit(&service);
diff --git a/src/lib-lda/Makefile.am b/src/lib-lda/Makefile.am
new file mode 100644 (file)
index 0000000..d7e967c
--- /dev/null
@@ -0,0 +1,29 @@
+noinst_LIBRARIES = liblda.a
+
+AM_CPPFLAGS = \
+       -I$(top_srcdir)/src/lib \
+       -I$(top_srcdir)/src/lib-settings \
+       -I$(top_srcdir)/src/lib-master \
+       -I$(top_srcdir)/src/lib-mail \
+       -I$(top_srcdir)/src/lib-storage
+
+liblda_a_SOURCES = \
+       lda-settings.c \
+       duplicate.c \
+       mail-deliver.c \
+       mail-send.c \
+       smtp-client.c
+
+headers = \
+       lda-settings.h \
+       duplicate.h \
+       mail-deliver.h \
+       mail-send.h \
+       smtp-client.h
+
+if INSTALL_HEADERS
+  pkginc_libdir=$(pkgincludedir)/src/lib-lda
+  pkginc_lib_HEADERS = $(headers)
+else
+  noinst_HEADERS = $(headers)
+endif
similarity index 99%
rename from src/deliver/duplicate.c
rename to src/lib-lda/duplicate.c
index 45884a562809dfad33609d7d53bb2d138ac5f15d..fd88c68ba83cf297e1272da80b45b537b7ef2ba4 100644 (file)
@@ -7,6 +7,7 @@
 #include "home-expand.h"
 #include "file-dotlock.h"
 #include "hash.h"
+#include "mail-storage-settings.h"
 #include "duplicate.h"
 
 #include <stdlib.h>
similarity index 91%
rename from src/deliver/duplicate.h
rename to src/lib-lda/duplicate.h
index 4f220ae47e42c4a28169de1099d1c0519f13a3d9..5e8745376c3e9b0abadddfd7339ec65cbae5993f 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DUPLICATE_H
 #define DUPLICATE_H
 
-#include "mail-storage-settings.h"
+struct mail_storage_settings;
 
 #define DUPLICATE_DEFAULT_KEEP (3600 * 24)
 
similarity index 51%
rename from src/deliver/deliver-settings.c
rename to src/lib-lda/lda-settings.c
index 858008f87d665536bbd9fd1db6a8d0158e9106fd..5f3bc7b827a86aaf2ee079905dd56d709e68d6d0 100644 (file)
@@ -1,26 +1,21 @@
 /* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
 
-#include "deliver.h"
-#include "array.h"
-#include "hostpid.h"
-#include "istream.h"
+#include "lib.h"
 #include "settings-parser.h"
-#include "mail-storage-settings.h"
-#include "deliver-settings.h"
+#include "lda-settings.h"
 
 #include <stddef.h>
-#include <stdlib.h>
 
-static bool deliver_settings_check(void *_set, pool_t pool, const char **error_r);
+static bool lda_settings_check(void *_set, pool_t pool, const char **error_r);
 
 #undef DEF
 #undef DEFLIST
 #define DEF(type, name) \
-       { type, #name, offsetof(struct deliver_settings, name), NULL }
+       { type, #name, offsetof(struct lda_settings, name), NULL }
 #define DEFLIST(field, name, defines) \
-       { SET_DEFLIST, name, offsetof(struct deliver_settings, field), defines }
+       { SET_DEFLIST, name, offsetof(struct lda_settings, field), defines }
 
-static struct setting_define deliver_setting_defines[] = {
+static struct setting_define lda_setting_defines[] = {
        DEF(SET_STR, postmaster_address),
        DEF(SET_STR, hostname),
        DEF(SET_STR, sendmail_path),
@@ -28,13 +23,15 @@ static struct setting_define deliver_setting_defines[] = {
        DEF(SET_STR, rejection_reason),
        DEF(SET_STR, deliver_log_format),
        DEF(SET_BOOL, quota_full_tempfail),
+       DEF(SET_BOOL, lda_mailbox_autocreate),
+       DEF(SET_BOOL, lda_mailbox_autosubscribe),
 
-       { SET_STRLIST, "plugin", offsetof(struct deliver_settings, plugin_envs), NULL },
+       { SET_STRLIST, "plugin", offsetof(struct lda_settings, plugin_envs), NULL },
 
        SETTING_DEFINE_LIST_END
 };
 
-static struct deliver_settings deliver_default_settings = {
+static struct lda_settings lda_default_settings = {
        MEMBER(postmaster_address) "",
        MEMBER(hostname) "",
        MEMBER(sendmail_path) "/usr/lib/sendmail",
@@ -42,30 +39,32 @@ static struct deliver_settings deliver_default_settings = {
        MEMBER(rejection_reason)
                "Your message to <%t> was automatically rejected:%n%r",
        MEMBER(deliver_log_format) "msgid=%m: %$",
-       MEMBER(quota_full_tempfail) FALSE
+       MEMBER(quota_full_tempfail) FALSE,
+       MEMBER(lda_mailbox_autocreate) FALSE,
+       MEMBER(lda_mailbox_autosubscribe) FALSE
 };
 
-struct setting_parser_info deliver_setting_parser_info = {
-       MEMBER(defines) deliver_setting_defines,
-       MEMBER(defaults) &deliver_default_settings,
+struct setting_parser_info lda_setting_parser_info = {
+       MEMBER(defines) lda_setting_defines,
+       MEMBER(defaults) &lda_default_settings,
 
        MEMBER(parent) NULL,
        MEMBER(dynamic_parsers) NULL,
 
        MEMBER(parent_offset) (size_t)-1,
        MEMBER(type_offset) (size_t)-1,
-       MEMBER(struct_size) sizeof(struct deliver_settings),
+       MEMBER(struct_size) sizeof(struct lda_settings),
 #ifdef CONFIG_BINARY
        MEMBER(check_func) NULL
 #else
-       MEMBER(check_func) deliver_settings_check
+       MEMBER(check_func) lda_settings_check
 #endif
 };
 
-static bool deliver_settings_check(void *_set, pool_t pool ATTR_UNUSED,
-                                  const char **error_r)
+static bool lda_settings_check(void *_set, pool_t pool ATTR_UNUSED,
+                              const char **error_r)
 {
-       struct deliver_settings *set = _set;
+       struct lda_settings *set = _set;
 
        if (*set->postmaster_address == '\0') {
                *error_r = "postmaster_address setting not given";
similarity index 60%
rename from src/deliver/deliver-settings.h
rename to src/lib-lda/lda-settings.h
index 92a8d50fa305f891b5f70cbeda25b8bd43b13c72..51dd95961b39935460440dee56d05af1c0e34c5a 100644 (file)
@@ -1,9 +1,9 @@
-#ifndef DELIVER_SETTINGS_H
-#define DELIVER_SETTINGS_H
+#ifndef LDA_SETTINGS_H
+#define LDA_SETTINGS_H
 
 struct mail_user_settings;
 
-struct deliver_settings {
+struct lda_settings {
        const char *postmaster_address;
        const char *hostname;
        const char *sendmail_path;
@@ -11,10 +11,12 @@ struct deliver_settings {
        const char *rejection_reason;
        const char *deliver_log_format;
        bool quota_full_tempfail;
+       bool lda_mailbox_autocreate;
+       bool lda_mailbox_autosubscribe;
 
        ARRAY_DEFINE(plugin_envs, const char *);
 };
 
-extern struct setting_parser_info deliver_setting_parser_info;
+extern struct setting_parser_info lda_setting_parser_info;
 
 #endif
diff --git a/src/lib-lda/mail-deliver.c b/src/lib-lda/mail-deliver.c
new file mode 100644 (file)
index 0000000..89874ee
--- /dev/null
@@ -0,0 +1,244 @@
+/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "str.h"
+#include "str-sanitize.h"
+#include "var-expand.h"
+#include "message-address.h"
+#include "lda-settings.h"
+#include "mail-storage.h"
+#include "mail-namespace.h"
+#include "mail-deliver.h"
+
+deliver_mail_func_t *deliver_mail = NULL;
+
+const char *mail_deliver_get_address(struct mail_deliver_context *ctx,
+                                    const char *header)
+{
+       struct message_address *addr;
+       const char *str;
+
+       if (mail_get_first_header(ctx->src_mail, header, &str) <= 0)
+               return NULL;
+       addr = message_address_parse(pool_datastack_create(),
+                                    (const unsigned char *)str,
+                                    strlen(str), 1, FALSE);
+       return addr == NULL || addr->mailbox == NULL || addr->domain == NULL ||
+               *addr->mailbox == '\0' || *addr->domain == '\0' ?
+               NULL : t_strconcat(addr->mailbox, "@", addr->domain, NULL);
+}
+
+static const struct var_expand_table *
+get_log_var_expand_table(struct mail_deliver_context *ctx, const char *message)
+{
+       static struct var_expand_table static_tab[] = {
+               { '$', NULL, NULL },
+               { 'm', NULL, "msgid" },
+               { 's', NULL, "subject" },
+               { 'f', NULL, "from" },
+               { '\0', NULL, NULL }
+       };
+       struct var_expand_table *tab;
+       unsigned int i;
+
+       tab = t_malloc(sizeof(static_tab));
+       memcpy(tab, static_tab, sizeof(static_tab));
+
+       tab[0].value = message;
+       (void)mail_get_first_header(ctx->src_mail, "Message-ID", &tab[1].value);
+       (void)mail_get_first_header(ctx->src_mail, "Subject", &tab[2].value);
+       tab[3].value = mail_deliver_get_address(ctx, "From");
+       for (i = 1; tab[i].key != '\0'; i++)
+               tab[i].value = str_sanitize(tab[i].value, 80);
+       return tab;
+}
+
+void mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...)
+{
+       va_list args;
+       string_t *str;
+       const char *msg;
+
+       va_start(args, fmt);
+       msg = t_strdup_vprintf(fmt, args);
+
+       str = t_str_new(256);
+       var_expand(str, ctx->set->deliver_log_format,
+                  get_log_var_expand_table(ctx, msg));
+       i_info("%s", str_c(str));
+       va_end(args);
+}
+
+static struct mailbox *
+mailbox_open_or_create_synced(struct mail_deliver_context *ctx, 
+                             struct mail_storage **storage_r,
+                             const char *name)
+{
+       struct mail_namespace *ns;
+       struct mailbox *box;
+       enum mail_error error;
+       enum mailbox_open_flags open_flags = MAILBOX_OPEN_FAST |
+               MAILBOX_OPEN_KEEP_RECENT | MAILBOX_OPEN_SAVEONLY |
+               MAILBOX_OPEN_POST_SESSION;
+
+       if (strcasecmp(name, "INBOX") == 0) {
+               /* deliveries to INBOX must always succeed,
+                  regardless of ACLs */
+               open_flags |= MAILBOX_OPEN_IGNORE_ACLS;
+       }
+
+       ns = mail_namespace_find(ctx->dest_user->namespaces, &name);
+       if (ns == NULL) {
+               *storage_r = NULL;
+               return NULL;
+       }
+       *storage_r = ns->storage;
+
+       if (*name == '\0') {
+               /* delivering to a namespace prefix means we actually want to
+                  deliver to the INBOX instead */
+               return NULL;
+       }
+
+       box = mailbox_open(storage_r, name, NULL, open_flags);
+       if (box != NULL || !ctx->set->lda_mailbox_autocreate)
+               return box;
+
+       (void)mail_storage_get_last_error(*storage_r, &error);
+       if (error != MAIL_ERROR_NOTFOUND)
+               return NULL;
+
+       /* try creating it. */
+       if (mail_storage_mailbox_create(*storage_r, name, FALSE) < 0)
+               return NULL;
+       if (ctx->set->lda_mailbox_autosubscribe) {
+               /* (try to) subscribe to it */
+               (void)mailbox_list_set_subscribed(ns->list, name, TRUE);
+       }
+
+       /* and try opening again */
+       box = mailbox_open(storage_r, name, NULL, open_flags);
+       if (box == NULL)
+               return NULL;
+
+       if (mailbox_sync(box, 0, 0, NULL) < 0) {
+               mailbox_close(&box);
+               return NULL;
+       }
+       return box;
+}
+
+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 mailbox *box;
+       struct mailbox_transaction_context *t;
+       struct mail_save_context *save_ctx;
+       struct mail_keywords *kw;
+       enum mail_error error;
+       const char *mailbox_name;
+       bool default_save;
+       int ret = 0;
+
+       default_save = strcmp(mailbox, ctx->dest_mailbox_name) == 0;
+       if (default_save)
+               ctx->tried_default_save = TRUE;
+
+       mailbox_name = str_sanitize(mailbox, 80);
+       box = mailbox_open_or_create_synced(ctx, storage_r, mailbox);
+       if (box == NULL) {
+               if (*storage_r == NULL) {
+                       mail_deliver_log(ctx,
+                                        "save failed to %s: Unknown namespace",
+                                        mailbox_name);
+                       return -1;
+               }
+               ns = mail_storage_get_namespace(*storage_r);
+               if (default_save && strcmp(ns->prefix, mailbox) == 0) {
+                       /* silently store to the INBOX instead */
+                       return -1;
+               }
+               mail_deliver_log(ctx, "save failed to %s: %s", mailbox_name,
+                                mail_storage_get_last_error(*storage_r, &error));
+               return -1;
+       }
+
+       t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
+
+       kw = str_array_length(keywords) == 0 ? NULL :
+               mailbox_keywords_create_valid(box, keywords);
+       save_ctx = mailbox_save_alloc(t);
+       mailbox_save_set_flags(save_ctx, flags, kw);
+       if (mailbox_copy(&save_ctx, ctx->src_mail) < 0)
+               ret = -1;
+       mailbox_keywords_free(box, &kw);
+
+       if (ret < 0)
+               mailbox_transaction_rollback(&t);
+       else
+               ret = mailbox_transaction_commit(&t);
+
+       if (ret == 0) {
+               ctx->saved_mail = TRUE;
+               mail_deliver_log(ctx, "saved mail to %s", mailbox_name);
+       } else {
+               mail_deliver_log(ctx, "save failed to %s: %s", mailbox_name,
+                                mail_storage_get_last_error(*storage_r, &error));
+       }
+
+       mailbox_close(&box);
+       return ret;
+}
+
+const char *mail_deliver_get_return_address(struct mail_deliver_context *ctx)
+{
+       if (ctx->src_envelope_sender != NULL)
+               return ctx->src_envelope_sender;
+
+       return mail_deliver_get_address(ctx, "Return-Path");
+}
+
+const char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx)
+{
+       static int count = 0;
+
+       return t_strdup_printf("<dovecot-%s-%s-%d@%s>",
+                              dec2str(ioloop_timeval.tv_sec),
+                              dec2str(ioloop_timeval.tv_usec),
+                              count++, ctx->set->hostname);
+}
+
+int mail_deliver(struct mail_deliver_context *ctx,
+                struct mail_storage **storage_r)
+{
+       int ret;
+
+       *storage_r = NULL;
+       if (deliver_mail == NULL)
+               ret = -1;
+       else {
+               if (deliver_mail(ctx, storage_r) <= 0) {
+                       /* if message was saved, don't bounce it even though
+                          the script failed later. */
+                       ret = ctx->saved_mail ? 0 : -1;
+               } else {
+                       /* success. message may or may not have been saved. */
+                       ret = 0;
+               }
+       }
+
+       if (ret < 0 && !ctx->tried_default_save) {
+               /* plugins didn't handle this. save into the default mailbox. */
+               ret = mail_deliver_save(ctx, ctx->dest_mailbox_name, 0, NULL,
+                                       storage_r);
+       }
+       if (ret < 0 && strcasecmp(ctx->dest_mailbox_name, "INBOX") != 0) {
+               /* still didn't work. try once more to save it
+                  to INBOX. */
+               ret = mail_deliver_save(ctx, "INBOX", 0, NULL, storage_r);
+       }
+       return ret;
+}
diff --git a/src/lib-lda/mail-deliver.h b/src/lib-lda/mail-deliver.h
new file mode 100644 (file)
index 0000000..b622108
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef MAIL_DELIVER_H
+#define MAIL_DELIVER_H
+
+enum mail_flags;
+struct mail_storage;
+
+struct mail_deliver_context {
+       pool_t pool;
+       const struct lda_settings *set;
+
+       /* Mail to save */
+       struct mail *src_mail;
+       /* Envelope sender, if known. */
+       const char *src_envelope_sender;
+
+       /* Destination user */
+       struct mail_user *dest_user;
+       /* Destination email address */
+       const char *dest_addr;
+       /* Mailbox where mail should be saved, unless e.g. Sieve does
+          something to it. */
+       const char *dest_mailbox_name;
+
+       bool tried_default_save;
+       bool saved_mail;
+};
+
+typedef int deliver_mail_func_t(struct mail_deliver_context *ctx,
+                               struct mail_storage **storage_r);
+
+extern deliver_mail_func_t *deliver_mail;
+
+void mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...)
+       ATTR_FORMAT(2, 3);
+
+const char *mail_deliver_get_address(struct mail_deliver_context *ctx,
+                                    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);
+
+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);
+
+int mail_deliver(struct mail_deliver_context *ctx,
+                struct mail_storage **storage_r);
+
+#endif
similarity index 85%
rename from src/deliver/mail-send.c
rename to src/lib-lda/mail-send.c
index fbdf6f98b755b207e4cd97ca03c8b880395ace99..6380771ba8393af21cd4681fc54c8cc46186fd30 100644 (file)
@@ -9,11 +9,12 @@
 #include "var-expand.h"
 #include "message-date.h"
 #include "message-size.h"
-#include "duplicate.h"
 #include "istream-header-filter.h"
+#include "mail-storage.h"
 #include "mail-storage-settings.h"
+#include "lda-settings.h"
+#include "mail-deliver.h"
 #include "smtp-client.h"
-#include "deliver.h"
 #include "mail-send.h"
 
 #include <stdlib.h>
@@ -48,9 +49,10 @@ get_var_expand_table(struct mail *mail, const char *reason,
        return tab;
 }
 
-int mail_send_rejection(struct mail *mail, const char *recipient,
+int mail_send_rejection(struct mail_deliver_context *ctx, const char *recipient,
                        const char *reason)
 {
+    struct mail *mail = ctx->src_mail;
     struct istream *input;
     struct smtp_client *smtp_client;
     FILE *f;
@@ -64,7 +66,7 @@ int mail_send_rejection(struct mail *mail, const char *recipient,
 
     if (mail_get_first_header(mail, "Message-ID", &orig_msgid) < 0)
            orig_msgid = NULL;
-    return_addr = deliver_get_return_address(mail);
+    return_addr = mail_deliver_get_return_address(ctx);
     if (return_addr == NULL) {
            i_info("msgid=%s: Return-Path missing, rejection reason: %s",
                   orig_msgid == NULL ? "" : str_sanitize(orig_msgid, 80),
@@ -77,15 +79,15 @@ int mail_send_rejection(struct mail *mail, const char *recipient,
                   str_sanitize(reason, 512));
     }
 
-    smtp_client = smtp_client_open(return_addr, NULL, &f);
+    smtp_client = smtp_client_open(ctx, return_addr, NULL, &f);
 
-    msgid = deliver_get_new_message_id();
-    boundary = t_strdup_printf("%s/%s", my_pid, deliver_set->hostname);
+    msgid = mail_deliver_get_new_message_id(ctx);
+    boundary = t_strdup_printf("%s/%s", my_pid, ctx->set->hostname);
 
     fprintf(f, "Message-ID: %s\r\n", msgid);
     fprintf(f, "Date: %s\r\n", message_date_create(ioloop_time));
     fprintf(f, "From: Mail Delivery Subsystem <%s>\r\n",
-           deliver_set->postmaster_address);
+           ctx->set->postmaster_address);
     fprintf(f, "To: <%s>\r\n", return_addr);
     fprintf(f, "MIME-Version: 1.0\r\n");
     fprintf(f, "Content-Type: "
@@ -93,7 +95,7 @@ int mail_send_rejection(struct mail *mail, const char *recipient,
            "\tboundary=\"%s\"\r\n", boundary);
 
     str = t_str_new(256);
-    var_expand(str, deliver_set->rejection_subject,
+    var_expand(str, ctx->set->rejection_subject,
               get_var_expand_table(mail, reason, recipient));
     fprintf(f, "Subject: %s\r\n", str_c(str));
 
@@ -108,7 +110,7 @@ int mail_send_rejection(struct mail *mail, const char *recipient,
     fprintf(f, "Content-Transfer-Encoding: 8bit\r\n\r\n");
 
     str_truncate(str, 0);
-    var_expand(str, deliver_set->rejection_reason,
+    var_expand(str, ctx->set->rejection_reason,
               get_var_expand_table(mail, reason, recipient));
     fprintf(f, "%s\r\n", str_c(str));
 
@@ -117,7 +119,7 @@ int mail_send_rejection(struct mail *mail, const char *recipient,
            "Content-Type: message/disposition-notification\r\n\r\n",
            boundary);
     fprintf(f, "Reporting-UA: %s; Dovecot Mail Delivery Agent\r\n",
-           deliver_set->hostname);
+           ctx->set->hostname);
     if (mail_get_first_header(mail, "Original-Recipient", &hdr) > 0)
            fprintf(f, "Original-Recipient: rfc822; %s\r\n", hdr);
     fprintf(f, "Final-Recipient: rfc822; %s\r\n", recipient);
@@ -160,7 +162,7 @@ int mail_send_rejection(struct mail *mail, const char *recipient,
     return smtp_client_close(smtp_client);
 }
 
-int mail_send_forward(struct mail *mail, const char *forwardto)
+int mail_send_forward(struct mail_deliver_context *ctx, const char *forwardto)
 {
     static const char *hide_headers[] = {
         "Return-Path"
@@ -173,18 +175,18 @@ int mail_send_forward(struct mail *mail, const char *forwardto)
     size_t size;
     int ret;
 
-    if (mail_get_stream(mail, NULL, NULL, &input) < 0)
+    if (mail_get_stream(ctx->src_mail, NULL, NULL, &input) < 0)
            return -1;
 
-    if (mail_get_first_header(mail, "Return-Path", &return_path) <= 0)
+    if (mail_get_first_header(ctx->src_mail, "Return-Path", &return_path) <= 0)
            return_path = "";
 
-    if (mailbox_get_settings(mail->box)->mail_debug) {
+    if (mailbox_get_settings(ctx->src_mail->box)->mail_debug) {
            i_info("Sending a forward to <%s> with return path <%s>",
                   forwardto, return_path);
     }
 
-    smtp_client = smtp_client_open(forwardto, return_path, &f);
+    smtp_client = smtp_client_open(ctx, forwardto, return_path, &f);
 
     input = i_stream_create_header_filter(input, HEADER_FILTER_EXCLUDE |
                                           HEADER_FILTER_NO_CR, hide_headers,
@@ -200,4 +202,3 @@ int mail_send_forward(struct mail *mail, const char *forwardto)
 
     return smtp_client_close(smtp_client);
 }
-
diff --git a/src/lib-lda/mail-send.h b/src/lib-lda/mail-send.h
new file mode 100644 (file)
index 0000000..5c7c009
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef MAIL_SEND_H
+#define MAIL_SEND_H
+
+struct mail;
+struct mail_deliver_context;
+
+int mail_send_rejection(struct mail_deliver_context *ctx, const char *recipient,
+                       const char *reason);
+int mail_send_forward(struct mail_deliver_context *ctx, const char *forwardto);
+
+#endif
similarity index 86%
rename from src/deliver/smtp-client.c
rename to src/lib-lda/smtp-client.c
index fb3ad80ba97013caf31d4c02def67c90429783bf..aed7ba1e7b49bfe41d28c3bf22da5639a04bed3f 100644 (file)
@@ -1,12 +1,14 @@
 /* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
-#include "deliver.h"
 #include "master-service.h"
+#include "lda-settings.h"
+#include "mail-deliver.h"
 #include "smtp-client.h"
 
 #include <unistd.h>
 #include <sys/wait.h>
+#include <sysexits.h>
 
 struct smtp_client {
        FILE *f;
@@ -26,14 +28,15 @@ static struct smtp_client *smtp_client_devnull(FILE **file_r)
 }
 
 static void ATTR_NORETURN
-smtp_client_run_sendmail(const char *destination,
+smtp_client_run_sendmail(struct mail_deliver_context *ctx,
+                        const char *destination,
                         const char *return_path, int fd)
 {
        const char *argv[7], *sendmail_path;
 
        /* deliver_set's contents may point to environment variables.
           deliver_env_clean() cleans them up, so they have to be copied. */
-       sendmail_path = t_strdup(deliver_set->sendmail_path);
+       sendmail_path = t_strdup(ctx->set->sendmail_path);
 
        argv[0] = sendmail_path;
        argv[1] = "-i"; /* ignore dots */
@@ -53,7 +56,8 @@ smtp_client_run_sendmail(const char *destination,
        i_fatal("execv(%s) failed: %m", sendmail_path);
 }
 
-struct smtp_client *smtp_client_open(const char *destination,
+struct smtp_client *smtp_client_open(struct mail_deliver_context *ctx,
+                                    const char *destination,
                                     const char *return_path, FILE **file_r)
 {
        struct smtp_client *client;
@@ -73,7 +77,7 @@ struct smtp_client *smtp_client_open(const char *destination,
        if (pid == 0) {
                /* child */
                (void)close(fd[1]);
-               smtp_client_run_sendmail(destination, return_path, fd[0]);
+               smtp_client_run_sendmail(ctx, destination, return_path, fd[0]);
        }
        (void)close(fd[0]);
 
similarity index 67%
rename from src/deliver/smtp-client.h
rename to src/lib-lda/smtp-client.h
index 482998d04befe6b9058609d0a49614b4568c3ae5..24b14b2f5ea4d073152b06f75196d45c7a702aea 100644 (file)
@@ -3,7 +3,8 @@
 
 #include <stdio.h>
 
-struct smtp_client *smtp_client_open(const char *destination,
+struct smtp_client *smtp_client_open(struct mail_deliver_context *ctx,
+                                    const char *destination,
                                     const char *return_path, FILE **file_r);
 /* Returns sysexits-compatible return value */
 int smtp_client_close(struct smtp_client *client);