]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
deliver: Added -c parameter to provide path to delivered mail. This allows
authorTimo Sirainen <tss@iki.fi>
Mon, 2 Jun 2008 16:18:54 +0000 (19:18 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 2 Jun 2008 16:18:54 +0000 (19:18 +0300)
maildir to save it using hard links.

--HG--
branch : HEAD

src/deliver/deliver.c
src/lib-storage/index/maildir/maildir-copy.c
src/lib-storage/index/raw/raw-mail.c
src/lib-storage/index/raw/raw-storage.c
src/lib-storage/index/raw/raw-storage.h

index 289ef837d33ce29234430fb91abc469c12a79deb..9ed93f62e1153cbba2aa0d3bc769a6ba66b6ab6d 100644 (file)
@@ -711,7 +711,7 @@ int main(int argc, char *argv[])
        const char *config_path = DEFAULT_CONFIG_FILE;
        const char *mailbox = "INBOX";
        const char *auth_socket;
-       const char *home, *destaddr, *user, *value, *errstr;
+       const char *home, *destaddr, *user, *value, *errstr, *path;
        ARRAY_TYPE(string) extra_fields;
        struct mail_namespace *ns, *raw_ns;
        struct mail_storage *storage;
@@ -743,7 +743,7 @@ int main(int argc, char *argv[])
         lib_signals_ignore(SIGXFSZ, TRUE);
 #endif
 
-       destaddr = user = NULL;
+       destaddr = user = path = NULL;
        for (i = 1; i < argc; i++) {
                if (strcmp(argv[i], "-a") == 0) {
                        /* destination address */
@@ -758,6 +758,12 @@ int main(int argc, char *argv[])
                                i_fatal_status(EX_USAGE, "Missing -d argument");
                        user = argv[i];
                        user_auth = TRUE;
+               } else if (strcmp(argv[i], "-p") == 0) {
+                       /* input path */
+                       i++;
+                       if (i == argc)
+                               i_fatal_status(EX_USAGE, "Missing -p argument");
+                       path = argv[i];
                } else if (strcmp(argv[i], "-e") == 0) {
                        stderr_rejection = TRUE;
                } else if (strcmp(argv[i], "-c") == 0) {
@@ -938,11 +944,19 @@ int main(int argc, char *argv[])
        raw_ns = mail_namespaces_init_empty(namespace_pool);
        raw_ns->flags |= NAMESPACE_FLAG_INTERNAL;
        if (mail_storage_create(raw_ns, "raw", "/tmp", user,
-                               0, FILE_LOCK_METHOD_FCNTL, &errstr) < 0)
+                               MAIL_STORAGE_FLAG_FULL_FS_ACCESS,
+                               FILE_LOCK_METHOD_FCNTL, &errstr) < 0)
                i_fatal("Couldn't create internal raw storage: %s", errstr);
-       input = create_raw_stream(0, &mtime);
-       box = mailbox_open(raw_ns->storage, "Dovecot Delivery Mail", input,
-                          MAILBOX_OPEN_NO_INDEX_FILES);
+       if (path == NULL) {
+               input = create_raw_stream(0, &mtime);
+               box = mailbox_open(raw_ns->storage, "Dovecot Delivery Mail",
+                                  input, MAILBOX_OPEN_NO_INDEX_FILES);
+               i_stream_unref(&input);
+       } else {
+               mtime = (time_t)-1;
+               box = mailbox_open(raw_ns->storage, path, NULL,
+                                  MAILBOX_OPEN_NO_INDEX_FILES);
+       }
        if (box == NULL)
                i_fatal("Can't open delivery mail as raw");
        if (mailbox_sync(box, 0, 0, NULL) < 0) {
@@ -978,13 +992,11 @@ int main(int argc, char *argv[])
 
        if (ret < 0 && !tried_default_save) {
                /* plugins didn't handle this. save into the default mailbox. */
-               i_stream_seek(input, 0);
                ret = deliver_save(ns, &storage, mailbox, mail, 0, NULL);
        }
        if (ret < 0 && strcasecmp(mailbox, "INBOX") != 0) {
                /* still didn't work. try once more to save it
                   to INBOX. */
-               i_stream_seek(input, 0);
                ret = deliver_save(ns, &storage, "INBOX", mail, 0, NULL);
        }
 
@@ -1025,7 +1037,6 @@ int main(int argc, char *argv[])
                        return ret < 0 ? EX_TEMPFAIL : ret;
                /* ok, rejection sent */
        }
-       i_stream_unref(&input);
        i_free(explicit_envelope_sender);
 
        mail_free(&mail);
index 3fa44855bbfd25c51a16d96a4c4f4e968c80b3c4..8f277ac20f18f0564dac73861da62b1d09295660 100644 (file)
@@ -106,18 +106,20 @@ maildir_copy_hardlink(struct maildir_transaction_context *t, struct mail *mail,
 {
        struct maildir_mailbox *dest_mbox =
                (struct maildir_mailbox *)t->ictx.ibox;
-       struct maildir_mailbox *src_mbox =
-               (struct maildir_mailbox *)mail->box;
+       struct maildir_mailbox *src_mbox;
        struct maildir_save_context *ctx;
        struct hardlink_ctx do_ctx;
-       const char *filename = NULL;
+       const char *path, *filename = NULL;
        uint32_t seq;
 
        i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
 
        if (strcmp(mail->box->storage->name, MAILDIR_STORAGE_NAME) == 0)
                src_mbox = (struct maildir_mailbox *)mail->box;
-       else {
+       else if (strcmp(mail->box->storage->name, "raw") == 0) {
+               /* deliver uses raw format */
+               src_mbox = NULL;
+       } else {
                /* Can't hard link files from the source storage */
                return 0;
        }
@@ -134,7 +136,7 @@ maildir_copy_hardlink(struct maildir_transaction_context *t, struct mail *mail,
        memset(&do_ctx, 0, sizeof(do_ctx));
        do_ctx.dest_path = str_new(default_pool, 512);
 
-       if (dest_mbox->storage->copy_preserve_filename) {
+       if (dest_mbox->storage->copy_preserve_filename && src_mbox != NULL) {
                enum maildir_uidlist_rec_flag src_flags;
                const char *src_fname;
 
@@ -182,15 +184,26 @@ maildir_copy_hardlink(struct maildir_transaction_context *t, struct mail *mail,
                }
        } else
 #endif
-{
+       {
                /* keywords, hardlink to tmp/ with basename and later when we
                   have uidlist locked, move it to new/cur. */
                str_printfa(do_ctx.dest_path, "%s/tmp/%s",
                            dest_mbox->path, do_ctx.dest_fname);
                do_ctx.base_end_pos = str_len(do_ctx.dest_path);
        }
-       if (maildir_file_do(src_mbox, mail->uid, do_hardlink, &do_ctx) < 0)
-               return -1;
+       if (src_mbox != NULL) {
+               /* maildir */
+               if (maildir_file_do(src_mbox, mail->uid,
+                                   do_hardlink, &do_ctx) < 0)
+                       return -1;
+       } else {
+               /* raw / deliver */
+               if (mail_get_special(mail, MAIL_FETCH_UIDL_FILE_NAME,
+                                    &path) < 0 || *path == '\0')
+                       return 0;
+               if (do_hardlink(dest_mbox, path, &do_ctx) < 0)
+                       return -1;
+       }
 
        if (!do_ctx.success) {
                /* couldn't copy with hardlinking, fallback to copying */
index 147311e9c9cd2aed5ab648adafabd37c34fc5b22..06e1c8ed54f9e8023f7c7f273cbb3150a7afa3a4 100644 (file)
@@ -98,6 +98,9 @@ raw_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
        case MAIL_FETCH_FROM_ENVELOPE:
                *value_r = mbox->envelope_sender;
                return 0;
+       case MAIL_FETCH_UIDL_FILE_NAME:
+               *value_r = mbox->have_filename ? mbox->path : "";
+               return 0;
        default:
                return index_mail_get_special(_mail, field, value_r);
        }
index c8317e78261252a8ce9f86970dd82981a22b0d3b..839dbb0424e622134fe3a1a35ea37ef8a84176cd 100644 (file)
@@ -162,8 +162,10 @@ raw_mailbox_open(struct mail_storage *_storage, const char *name,
 
        if (stream)
                mbox->mtime = mbox->ctime = ioloop_time;
-       else
+       else {
                mbox->mtime = mbox->ctime = (time_t)-1;
+               mbox->have_filename = TRUE;
+       }
        mbox->size = (uoff_t)-1;
 
        index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE);
index 9a120814a20582c09732f35d711f60e9adc6435e..c9267945cba184f758c4119d0a2a92d967b4b62f 100644 (file)
@@ -24,6 +24,7 @@ struct raw_mailbox {
        const char *envelope_sender;
 
        unsigned int synced:1;
+       unsigned int have_filename:1;
 };
 
 extern struct mail_vfuncs raw_mail_vfuncs;