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;
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_. */
}
}
-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;
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;
}
/* 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,
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))
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;
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;
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)) {
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;
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;
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);
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;
}