Mercurial > dovecot > original-hg > dovecot-1.2
changeset 4960:4714befe2604 HEAD
Added maildir_copy_preserve_filename setting.
author | Timo Sirainen <timo.sirainen@movial.fi> |
---|---|
date | Fri, 22 Dec 2006 16:20:36 +0200 |
parents | 4ba6b31ae15e |
children | e13de4a0bf90 |
files | dovecot-example.conf src/lib-storage/index/maildir/maildir-copy.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/maildir/maildir-storage.h src/lib-storage/index/maildir/maildir-uidlist.c src/lib-storage/index/maildir/maildir-uidlist.h src/master/mail-process.c src/master/master-settings.c src/master/master-settings.h |
diffstat | 9 files changed, 64 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Fri Dec 22 01:54:17 2006 +0200 +++ b/dovecot-example.conf Fri Dec 22 16:20:36 2006 +0200 @@ -409,6 +409,14 @@ # the performance much better, and it's unlikely to have any side effects. #maildir_copy_with_hardlinks = no +# When copying a message, try to preserve the base filename. Only if the +# destination mailbox already contains the same name (ie. the mail is being +# copied there twice), a new name is given. The destination filename check is +# done only by looking at dovecot-uidlist file, so if something outside +# Dovecot does similar filename preserving copies, you may run into problems. +# NOTE: This setting requires maildir_copy_with_hardlinks = yes to work. +#maildir_copy_preserve_filename = no + ## ## mbox-specific settings ##
--- a/src/lib-storage/index/maildir/maildir-copy.c Fri Dec 22 01:54:17 2006 +0200 +++ b/src/lib-storage/index/maildir/maildir-copy.c Fri Dec 22 16:20:36 2006 +0200 @@ -22,6 +22,7 @@ unsigned int size_set:1; unsigned int success:1; + unsigned int preserve_filename:1; }; static int do_save_mail_size(struct maildir_mailbox *mbox, const char *path, @@ -59,7 +60,8 @@ { int ret; - if (mbox->storage->save_size_in_filename && !ctx->size_set) { + if (!ctx->preserve_filename && mbox->storage->save_size_in_filename && + !ctx->size_set) { if ((ret = do_save_mail_size(mbox, path, ctx)) <= 0) return ret; } @@ -73,7 +75,11 @@ "Not enough disk space"); return -1; } - if (errno == EACCES || ECANTLINK(errno)) + + /* we could handle the EEXIST condition by changing the + filename, but it practically never happens so just fallback + to standard copying for the rare cases when it does. */ + if (errno == EACCES || ECANTLINK(errno) || errno == EEXIST) return 1; mail_storage_set_critical(STORAGE(mbox->storage), @@ -97,6 +103,7 @@ (struct maildir_mailbox *)mail->box; struct maildir_save_context *ctx; struct hardlink_ctx do_ctx; + const char *filename = NULL; uint32_t seq; i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0); @@ -113,9 +120,31 @@ memset(&do_ctx, 0, sizeof(do_ctx)); do_ctx.dest_path = str_new(default_pool, 512); - /* the generated filename is _always_ unique, so we don't bother - trying to check if it already exists */ - do_ctx.dest_fname = maildir_generate_tmp_filename(&ioloop_timeval); + if (dest_mbox->storage->copy_preserve_filename) { + enum maildir_uidlist_rec_flag src_flags; + const char *src_fname; + + /* see if the filename exists in destination maildir's + uidlist. if it doesn't, we can use it. otherwise generate + a new filename */ + src_fname = maildir_uidlist_lookup(src_mbox->uidlist, + mail->uid, &src_flags); + if (src_fname != NULL && + maildir_uidlist_update(dest_mbox->uidlist) >= 0 && + maildir_uidlist_get_full_filename(dest_mbox->uidlist, + src_fname) == NULL) + filename = t_strcut(src_fname, ':'); + } + if (filename == NULL) { + /* the generated filename is _always_ unique, so we don't + bother trying to check if it already exists */ + do_ctx.dest_fname = + maildir_generate_tmp_filename(&ioloop_timeval); + } else { + do_ctx.dest_fname = filename; + do_ctx.preserve_filename = TRUE; + } + if (keywords == NULL || keywords->count == 0) { /* no keywords, hardlink directly to destination */ if (flags == MAIL_RECENT) {
--- a/src/lib-storage/index/maildir/maildir-storage.c Fri Dec 22 01:54:17 2006 +0200 +++ b/src/lib-storage/index/maildir/maildir-storage.c Fri Dec 22 16:20:36 2006 +0200 @@ -177,6 +177,8 @@ storage->copy_with_hardlinks = getenv("MAILDIR_COPY_WITH_HARDLINKS") != NULL; + storage->copy_preserve_filename = + getenv("MAILDIR_COPY_PRESERVE_FILENAME") != NULL; storage->stat_dirs = getenv("MAILDIR_STAT_DIRS") != NULL; storage->temp_prefix = mailbox_list_get_temp_prefix(list);
--- a/src/lib-storage/index/maildir/maildir-storage.h Fri Dec 22 01:54:17 2006 +0200 +++ b/src/lib-storage/index/maildir/maildir-storage.h Fri Dec 22 16:20:36 2006 +0200 @@ -49,6 +49,7 @@ const char *temp_prefix; unsigned int copy_with_hardlinks:1; + unsigned int copy_preserve_filename:1; unsigned int save_size_in_filename:1; unsigned int stat_dirs:1; };
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Fri Dec 22 01:54:17 2006 +0200 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Fri Dec 22 16:20:36 2006 +0200 @@ -813,6 +813,16 @@ return rec == NULL ? NULL : rec->filename; } +const char * +maildir_uidlist_get_full_filename(struct maildir_uidlist *uidlist, + const char *filename) +{ + struct maildir_uidlist_rec *rec; + + rec = hash_lookup(uidlist->files, filename); + return rec == NULL ? NULL : rec->filename; +} + static int maildir_time_cmp(const void *p1, const void *p2) { const struct maildir_uidlist_rec *const *rec1 = p1, *const *rec2 = p2;
--- a/src/lib-storage/index/maildir/maildir-uidlist.h Fri Dec 22 01:54:17 2006 +0200 +++ b/src/lib-storage/index/maildir/maildir-uidlist.h Fri Dec 22 16:20:36 2006 +0200 @@ -55,6 +55,10 @@ void maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx); int maildir_uidlist_sync_deinit(struct maildir_uidlist_sync_ctx **ctx); +const char * +maildir_uidlist_get_full_filename(struct maildir_uidlist *uidlist, + const char *filename); + void maildir_uidlist_add_flags(struct maildir_uidlist *uidlist, const char *filename, enum maildir_uidlist_rec_flag flags);
--- a/src/master/mail-process.c Fri Dec 22 01:54:17 2006 +0200 +++ b/src/master/mail-process.c Fri Dec 22 16:20:36 2006 +0200 @@ -235,6 +235,8 @@ env_put("MAILDIR_STAT_DIRS=1"); if (set->maildir_copy_with_hardlinks) env_put("MAILDIR_COPY_WITH_HARDLINKS=1"); + if (set->maildir_copy_preserve_filename) + env_put("MAILDIR_COPY_PRESERVE_FILENAME=1"); if (set->mail_debug) env_put("DEBUG=1"); if (set->mail_full_filesystem_access)
--- a/src/master/master-settings.c Fri Dec 22 01:54:17 2006 +0200 +++ b/src/master/master-settings.c Fri Dec 22 16:20:36 2006 +0200 @@ -125,6 +125,7 @@ DEF(SET_STR, lock_method), DEF(SET_BOOL, maildir_stat_dirs), DEF(SET_BOOL, maildir_copy_with_hardlinks), + DEF(SET_BOOL, maildir_copy_preserve_filename), DEF(SET_STR, mbox_read_locks), DEF(SET_STR, mbox_write_locks), DEF(SET_INT, mbox_lock_timeout), @@ -338,6 +339,7 @@ MEMBER(lock_method) "fcntl", MEMBER(maildir_stat_dirs) FALSE, MEMBER(maildir_copy_with_hardlinks) FALSE, + MEMBER(maildir_copy_preserve_filename) FALSE, MEMBER(mbox_read_locks) "fcntl", MEMBER(mbox_write_locks) "dotlock fcntl", MEMBER(mbox_lock_timeout) 300,
--- a/src/master/master-settings.h Fri Dec 22 01:54:17 2006 +0200 +++ b/src/master/master-settings.h Fri Dec 22 16:20:36 2006 +0200 @@ -84,6 +84,7 @@ const char *lock_method; bool maildir_stat_dirs; bool maildir_copy_with_hardlinks; + bool maildir_copy_preserve_filename; const char *mbox_read_locks; const char *mbox_write_locks; unsigned int mbox_lock_timeout;