]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
If maildir contains dovecot-shared file Dovecot does two things differently:
authorTimo Sirainen <tss@iki.fi>
Mon, 20 Oct 2003 06:01:08 +0000 (09:01 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 20 Oct 2003 06:01:08 +0000 (09:01 +0300)
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

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

index c15629b1d38baad8dc358d634879d672db82e8c7..ae5b7dc490fce14a71916f9ed2953fe8c1908693 100644 (file)
@@ -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_. */
index 5b9c1de4a70f5761bb76a072d8b0afc9f8080056..7a24eb78415c914b8bbe7206d2bed97b12b92b77 100644 (file)
@@ -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;
                }
index 5e12813eed796bca3dbe75c12fec14caa5c5a765..a9fb3026f118257af1c570dcec53ebc2d0f18de9 100644 (file)
@@ -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,
index b454fba7c88ce96c39228e2ee56504b452df69c7..95456d9ee75f316f80563e6c000eb5b4b9f3d0bb 100644 (file)
@@ -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))
index dff013af2edce70ec55a563d4cfe420a173778d5..a9d8c87172f009f9f2f972d24ed54ac104b186ad 100644 (file)
@@ -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)) {
index eba3509bb4414095de8c97bddf191522e1388835..311b4c263f015d1f1021f69d8d025783557bc1e1 100644 (file)
@@ -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;
index 852fe718b0c6ebdfbf211cbc9bc0ba96e153d36e..93b59421871641175dff9fa3e0c8a7bb07fc9baf 100644 (file)
@@ -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;
 
index 165e395a8df8cdce2590075b61b65892a706ec48..d17727560e05c8c6a4350e86e2811e3539bc1b4d 100644 (file)
@@ -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;
 }