changeset 1824:1acb38d177cf HEAD

If maildir contains dovecot-shared file Dovecot does two things differently: it allows some flags to be private and stored only in index file (currently hardcoded to \Seen flag only) and new mails are created with dovecot-shared file's mode & 0666. So if you set filesystem permissions correctly, you should have fully functioning shared mailboxes.
author Timo Sirainen <tss@iki.fi>
date Mon, 20 Oct 2003 09:01:08 +0300
parents cf9fa86e2a91
children ffd430238c32
files src/lib-index/mail-index.h src/lib-index/maildir/maildir-index.c src/lib-index/maildir/maildir-index.h src/lib-index/maildir/maildir-sync.c src/lib-index/maildir/maildir-update-flags.c src/lib-storage/index/index-storage.h src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/maildir/maildir-storage.c
diffstat 8 files changed, 41 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index.h	Mon Oct 20 08:10:05 2003 +0300
+++ b/src/lib-index/mail-index.h	Mon Oct 20 09:01:08 2003 +0300
@@ -329,6 +329,8 @@
 	mail_lock_notify_callback_t *lock_notify_cb;
 	void *lock_notify_context;
 
+	unsigned int private_flags_mask;
+
 	/* these fields are OR'ed to the fields in index header once we
 	   get around grabbing exclusive lock */
 	unsigned int set_flags;
@@ -364,7 +366,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 #endif
 
 /* defaults - same as above but prefixed with mail_index_. */
--- a/src/lib-index/maildir/maildir-index.c	Mon Oct 20 08:10:05 2003 +0300
+++ b/src/lib-index/maildir/maildir-index.c	Mon Oct 20 09:01:08 2003 +0300
@@ -131,7 +131,7 @@
 	}
 }
 
-int maildir_create_tmp(struct mail_index *index, const char *dir,
+int maildir_create_tmp(struct mail_index *index, const char *dir, mode_t mode,
 		       const char **fname)
 {
 	const char *path, *tmp_fname;
@@ -149,7 +149,9 @@
 		path = p_strconcat(pool, dir, "/", tmp_fname, NULL);
 		if (stat(path, &st) < 0 && errno == ENOENT) {
 			/* doesn't exist */
-			fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
+			mode_t old_mask = umask(0);
+			fd = open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
+			umask(old_mask);
 			if (fd != -1 || errno != EEXIST)
 				break;
 		}
--- a/src/lib-index/maildir/maildir-index.h	Mon Oct 20 08:10:05 2003 +0300
+++ b/src/lib-index/maildir/maildir-index.h	Mon Oct 20 09:01:08 2003 +0300
@@ -19,7 +19,7 @@
 
 /* Return new filename base to save into tmp/ */
 const char *maildir_generate_tmp_filename(const struct timeval *tv);
-int maildir_create_tmp(struct mail_index *index, const char *dir,
+int maildir_create_tmp(struct mail_index *index, const char *dir, mode_t mode,
 		       const char **path);
 
 const char *maildir_get_location(struct mail_index *index,
--- a/src/lib-index/maildir/maildir-sync.c	Mon Oct 20 08:10:05 2003 +0300
+++ b/src/lib-index/maildir/maildir-sync.c	Mon Oct 20 09:01:08 2003 +0300
@@ -289,6 +289,9 @@
 		return TRUE;
 
 	flags = maildir_filename_get_flags(new_fname, rec->msg_flags);
+	flags &= ~ctx->index->private_flags_mask;
+	flags |= rec->msg_flags & ctx->index->private_flags_mask;
+
 	if (flags != rec->msg_flags) {
 		if (!ctx->index->update_flags(ctx->index, rec,
 					      seq, MODIFY_REPLACE, flags, TRUE))
--- a/src/lib-index/maildir/maildir-update-flags.c	Mon Oct 20 08:10:05 2003 +0300
+++ b/src/lib-index/maildir/maildir-update-flags.c	Mon Oct 20 09:01:08 2003 +0300
@@ -116,7 +116,8 @@
 		new_flags = old_flags & ~ctx->flags;
 		break;
 	case MODIFY_REPLACE:
-		new_flags = ctx->flags;
+		new_flags = ctx->flags |
+			(old_flags & index->private_flags_mask);
 		break;
 	default:
 		new_flags = 0;
@@ -128,14 +129,20 @@
 						    fname+1 : path, new_flags);
 
 	if (old_flags == new_flags) {
-		/* it's what we wanted. verify that the file exists. */
+		/* it's what we wanted. verify that the file exists, but
+		   only if something actually could have changed
+		   (ie. do nothing with private flag changes in shared
+		   mailboxes). */
 		struct stat st;
 
-		if (stat(path, &st) < 0) {
-			if (errno == ENOENT)
-				return 0;
-			index_file_set_syscall_error(index, path, "stat()");
-			return -1;
+		if (ctx->flags != 0) {
+			if (stat(path, &st) < 0) {
+				if (errno == ENOENT)
+					return 0;
+				index_file_set_syscall_error(index, path,
+							     "stat()");
+				return -1;
+			}
 		}
 		ctx->found = TRUE;
 		return 1;
@@ -193,7 +200,7 @@
 
 	memset(&ctx, 0, sizeof(ctx));
 	ctx.modify_type = modify_type;
-	ctx.flags = flags;
+	ctx.flags = flags & ~index->private_flags_mask;
 
 	t_push();
 	if (!maildir_file_do(index, rec, do_rename, &ctx)) {
--- a/src/lib-storage/index/index-storage.h	Mon Oct 20 08:10:05 2003 +0300
+++ b/src/lib-storage/index/index-storage.h	Mon Oct 20 09:01:08 2003 +0300
@@ -29,6 +29,8 @@
         enum mailbox_lock_type lock_type;
 	struct mail_cache_transaction_ctx *trans_ctx;
 
+	mode_t mail_create_mode; /* for maildir */
+
 	struct timeout *autosync_to;
 	struct index_autosync_file *autosync_files;
         struct index_autosync_io *autosync_ios;
--- a/src/lib-storage/index/maildir/maildir-save.c	Mon Oct 20 08:10:05 2003 +0300
+++ b/src/lib-storage/index/maildir/maildir-save.c	Mon Oct 20 09:01:08 2003 +0300
@@ -37,7 +37,8 @@
 	struct ostream *output;
 	int fd;
 
-	fd = maildir_create_tmp(ibox->index, dir, &path);
+	fd = maildir_create_tmp(ibox->index, dir,
+				ibox->mail_create_mode, &path);
 	if (fd == -1)
 		return NULL;
 
--- a/src/lib-storage/index/maildir/maildir-storage.c	Mon Oct 20 08:10:05 2003 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Mon Oct 20 09:01:08 2003 +0300
@@ -398,6 +398,7 @@
 	struct index_mailbox *ibox;
 	struct mail_index *index;
 	const char *path, *index_dir, *control_dir;
+	struct stat st;
 
 	path = maildir_get_path(storage, name);
 	index_dir = maildir_get_index_path(storage, name);
@@ -413,6 +414,16 @@
 					  index, name, flags);
 	if (ibox != NULL)
 		ibox->mail_init = maildir_mail_init;
+
+	/* for shared mailboxes get the create mode from the
+	   permissions of dovecot-shared file */
+	if (stat(t_strconcat(path, "/dovecot-shared", NULL), &st) < 0)
+		ibox->mail_create_mode = 0600;
+	else {
+		ibox->mail_create_mode = st.st_mode & 0666;
+		index->private_flags_mask = MAIL_SEEN;
+	}
+
 	return (struct mailbox *) ibox;
 }