[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-copy.c, 1.43.2.2, 1.43.2.3 maildir-storage.c, 1.115.2.16, 1.115.2.17 maildir-storage.h, 1.49.2.3, 1.49.2.4 maildir-uidlist.c, 1.51.2.1, 1.51.2.2 maildir-uidlist.h, 1.17.2.1, 1.17.2.2

tss-movial at dovecot.org tss-movial at dovecot.org
Fri Dec 22 14:20:33 UTC 2006


Update of /var/lib/cvs/dovecot/src/lib-storage/index/maildir
In directory talvi:/tmp/cvs-serv3147/src/lib-storage/index/maildir

Modified Files:
      Tag: branch_1_0
	maildir-copy.c maildir-storage.c maildir-storage.h 
	maildir-uidlist.c maildir-uidlist.h 
Log Message:
Added maildir_copy_preserve_filename setting.



Index: maildir-copy.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-copy.c,v
retrieving revision 1.43.2.2
retrieving revision 1.43.2.3
diff -u -d -r1.43.2.2 -r1.43.2.3
--- maildir-copy.c	17 Jun 2006 15:56:58 -0000	1.43.2.2
+++ maildir-copy.c	22 Dec 2006 14:20:31 -0000	1.43.2.3
@@ -21,6 +21,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 @@
 	struct hardlink_ctx *ctx = context;
 	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) {

Index: maildir-storage.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-storage.c,v
retrieving revision 1.115.2.16
retrieving revision 1.115.2.17
diff -u -d -r1.115.2.16 -r1.115.2.17
--- maildir-storage.c	15 Dec 2006 23:08:40 -0000	1.115.2.16
+++ maildir-storage.c	22 Dec 2006 14:20:31 -0000	1.115.2.17
@@ -164,6 +164,8 @@
 	storage->control_dir = p_strdup(pool, home_expand(control_dir));
 	storage->copy_with_hardlinks =
 		getenv("MAILDIR_COPY_WITH_HARDLINKS") != NULL;
+	storage->copy_preserve_filename =
+		getenv("MAILDIR_COPY_PRESERVE_FILENAME") != NULL;
 
 	istorage = INDEX_STORAGE(storage);
 	istorage->storage = maildir_storage;

Index: maildir-storage.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-storage.h,v
retrieving revision 1.49.2.3
retrieving revision 1.49.2.4
diff -u -d -r1.49.2.3 -r1.49.2.4
--- maildir-storage.h	17 Dec 2006 14:10:40 -0000	1.49.2.3
+++ maildir-storage.h	22 Dec 2006 14:20:31 -0000	1.49.2.4
@@ -53,6 +53,7 @@
 
 	const char *control_dir;
 	unsigned int copy_with_hardlinks:1;
+	unsigned int copy_preserve_filename:1;
 	unsigned int save_size_in_filename:1;
 };
 

Index: maildir-uidlist.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-uidlist.c,v
retrieving revision 1.51.2.1
retrieving revision 1.51.2.2
diff -u -d -r1.51.2.1 -r1.51.2.2
--- maildir-uidlist.c	17 Jun 2006 13:55:28 -0000	1.51.2.1
+++ maildir-uidlist.c	22 Dec 2006 14:20:31 -0000	1.51.2.2
@@ -814,6 +814,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;

Index: maildir-uidlist.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-uidlist.h,v
retrieving revision 1.17.2.1
retrieving revision 1.17.2.2
diff -u -d -r1.17.2.1 -r1.17.2.2
--- maildir-uidlist.h	17 Jun 2006 13:55:28 -0000	1.17.2.1
+++ maildir-uidlist.h	22 Dec 2006 14:20:31 -0000	1.17.2.2
@@ -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);



More information about the dovecot-cvs mailing list