From: Timo Sirainen Date: Mon, 20 Oct 2003 06:01:08 +0000 (+0300) Subject: If maildir contains dovecot-shared file Dovecot does two things differently: X-Git-Tag: 1.1.alpha1~4282 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=05d8b39defaa5bcaea31ab9f8ff2bd8e119c7d52;p=thirdparty%2Fdovecot%2Fcore.git 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. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-index.h b/src/lib-index/mail-index.h index c15629b1d3..ae5b7dc490 100644 --- a/src/lib-index/mail-index.h +++ b/src/lib-index/mail-index.h @@ -329,6 +329,8 @@ struct mail_index { 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 @@ struct mail_index { 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_. */ diff --git a/src/lib-index/maildir/maildir-index.c b/src/lib-index/maildir/maildir-index.c index 5b9c1de4a7..7a24eb7841 100644 --- a/src/lib-index/maildir/maildir-index.c +++ b/src/lib-index/maildir/maildir-index.c @@ -131,7 +131,7 @@ 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 **fname) { const char *path, *tmp_fname; @@ -149,7 +149,9 @@ int maildir_create_tmp(struct mail_index *index, const char *dir, 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; } diff --git a/src/lib-index/maildir/maildir-index.h b/src/lib-index/maildir/maildir-index.h index 5e12813eed..a9fb3026f1 100644 --- a/src/lib-index/maildir/maildir-index.h +++ b/src/lib-index/maildir/maildir-index.h @@ -19,7 +19,7 @@ maildir_index_alloc(const char *maildir, const char *index_dir, /* 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, diff --git a/src/lib-index/maildir/maildir-sync.c b/src/lib-index/maildir/maildir-sync.c index b454fba7c8..95456d9ee7 100644 --- a/src/lib-index/maildir/maildir-sync.c +++ b/src/lib-index/maildir/maildir-sync.c @@ -289,6 +289,9 @@ static int maildir_update_flags(struct maildir_sync_context *ctx, 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)) diff --git a/src/lib-index/maildir/maildir-update-flags.c b/src/lib-index/maildir/maildir-update-flags.c index dff013af2e..a9d8c87172 100644 --- a/src/lib-index/maildir/maildir-update-flags.c +++ b/src/lib-index/maildir/maildir-update-flags.c @@ -116,7 +116,8 @@ static int do_rename(struct mail_index *index, const char *path, void *context) 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 @@ static int do_rename(struct mail_index *index, const char *path, void *context) 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 @@ int maildir_index_update_flags(struct mail_index *index, 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)) { diff --git a/src/lib-storage/index/index-storage.h b/src/lib-storage/index/index-storage.h index eba3509bb4..311b4c263f 100644 --- a/src/lib-storage/index/index-storage.h +++ b/src/lib-storage/index/index-storage.h @@ -29,6 +29,8 @@ struct index_mailbox { 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; diff --git a/src/lib-storage/index/maildir/maildir-save.c b/src/lib-storage/index/maildir/maildir-save.c index 852fe718b0..93b5942187 100644 --- a/src/lib-storage/index/maildir/maildir-save.c +++ b/src/lib-storage/index/maildir/maildir-save.c @@ -37,7 +37,8 @@ maildir_read_into_tmp(struct index_mailbox *ibox, const char *dir, 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; diff --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index 165e395a8d..d17727560e 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -398,6 +398,7 @@ maildir_open(struct mail_storage *storage, const char *name, 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 @@ maildir_open(struct mail_storage *storage, const char *name, 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; }