From cad9356826a0e540190964f748e271d1722ca03d Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sun, 18 May 2003 15:56:14 +0300 Subject: [PATCH] Some fixes to handling read-only maildirs. --HG-- branch : HEAD --- src/lib-index/mail-custom-flags.c | 33 +++++++++++++------- src/lib-index/maildir/maildir-index.c | 1 + src/lib-index/maildir/maildir-sync.c | 20 ++++++------ src/lib-index/maildir/maildir-uidlist.c | 4 +++ src/lib-index/maildir/maildir-update-flags.c | 2 +- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/lib-index/mail-custom-flags.c b/src/lib-index/mail-custom-flags.c index 9b2b52328f..4a8f1b36d0 100644 --- a/src/lib-index/mail-custom-flags.c +++ b/src/lib-index/mail-custom-flags.c @@ -62,7 +62,10 @@ static int update_mmap(struct mail_custom_flags *mcf) index_cf_set_syscall_error(mcf, "munmap()"); } - mcf->mmap_base = mmap_rw_file(mcf->fd, &mcf->mmap_length); + + mcf->mmap_base = mcf->noupdate ? + mmap_ro_file(mcf->fd, &mcf->mmap_length) : + mmap_rw_file(mcf->fd, &mcf->mmap_length); if (mcf->mmap_base == MAP_FAILED) { mcf->mmap_base = NULL; return index_cf_set_syscall_error(mcf, "mmap()"); @@ -166,7 +169,7 @@ static void custom_flags_sync(struct mail_custom_flags *mcf) static int custom_flags_check_sync(struct mail_custom_flags *mcf) { - if (mcf->noupdate) + if (mcf->fd == -1) return TRUE; if (mcf->mmap_length != 0 && @@ -177,7 +180,7 @@ static int custom_flags_check_sync(struct mail_custom_flags *mcf) if (!update_mmap(mcf)) return FALSE; - if (mcf->mmap_length < HEADER_SIZE) { + if (mcf->mmap_length < HEADER_SIZE && !mcf->noupdate) { /* it's broken, rewrite header */ if (mcf->lock_type == F_RDLCK) (void)lock_file(mcf, F_UNLCK); @@ -236,41 +239,49 @@ int mail_custom_flags_open_or_create(struct mail_index *index) { struct mail_custom_flags *mcf; const char *path; - int fd; + int fd, readonly; path = t_strconcat(index->control_dir, "/", CUSTOM_FLAGS_FILE_NAME, NULL); - if (path == NULL) - fd = -1; - else { - fd = open(path, O_RDWR | O_CREAT, 0660); - if (fd == -1) + readonly = index->mailbox_readonly; + fd = !index->mailbox_readonly ? + open(path, O_RDWR | O_CREAT, 0660) : open(path, O_RDONLY); + if (fd == -1) { + if (errno == EACCES) { + fd = open(path, O_RDONLY); + readonly = TRUE; + } + if (errno != EACCES && errno != ENOENT && !ENOSPACE(errno)) { index_file_set_syscall_error(index, path, "open()"); + return FALSE; + } } mcf = i_new(struct mail_custom_flags, 1); mcf->index = index; mcf->filepath = i_strdup(path); mcf->fd = fd; + mcf->noupdate = mcf->fd == -1 || readonly; if (fd != -1) { if (!update_mmap(mcf)) { (void)close(mcf->fd); mcf->fd = -1; + mcf->noupdate = TRUE; } - if (mcf->mmap_length < HEADER_SIZE) { + if (mcf->mmap_length < HEADER_SIZE && !mcf->noupdate) { /* we just created it, write the header */ mcf->syncing = TRUE; if (!custom_flags_init(mcf) || !update_mmap(mcf)) { (void)close(mcf->fd); mcf->fd = -1; + mcf->noupdate = TRUE; } mcf->syncing = FALSE; } } - mcf->noupdate = mcf->fd == -1; mcf->index->allow_new_custom_flags = mcf->fd != -1; custom_flags_sync(mcf); diff --git a/src/lib-index/maildir/maildir-index.c b/src/lib-index/maildir/maildir-index.c index f671b06211..31d3a1633a 100644 --- a/src/lib-index/maildir/maildir-index.c +++ b/src/lib-index/maildir/maildir-index.c @@ -227,6 +227,7 @@ maildir_index_alloc(const char *maildir, const char *index_dir, index->maildir_lock_fd = -1; index->mailbox_path = i_strdup(maildir); index->control_dir = i_strdup(control_dir); + index->mailbox_readonly = access(maildir, W_OK) < 0; mail_index_init(index, index_dir); return index; } diff --git a/src/lib-index/maildir/maildir-sync.c b/src/lib-index/maildir/maildir-sync.c index d2d12faa71..fac90d8cd1 100644 --- a/src/lib-index/maildir/maildir-sync.c +++ b/src/lib-index/maildir/maildir-sync.c @@ -704,18 +704,16 @@ static int maildir_index_full_sync_dirs(struct maildir_sync_context *ctx) DIR *dirp; int failed; - if (ctx->index->maildir_have_new || ctx->index->maildir_keep_new) { - if (ctx->new_dirp == NULL) { - if (!maildir_new_scan_first_file(ctx)) - return FALSE; - } + if (ctx->new_dirp == NULL && + (ctx->index->maildir_have_new || ctx->index->maildir_keep_new)) { + if (!maildir_new_scan_first_file(ctx)) + return FALSE; + } - if (ctx->new_dent != NULL) { - if (!maildir_index_full_sync_dir(ctx, ctx->new_dir, - TRUE, ctx->new_dirp, - ctx->new_dent)) - return FALSE; - } + if (ctx->new_dent != NULL) { + if (!maildir_index_full_sync_dir(ctx, ctx->new_dir, TRUE, + ctx->new_dirp, ctx->new_dent)) + return FALSE; } dirp = opendir(ctx->cur_dir); diff --git a/src/lib-index/maildir/maildir-uidlist.c b/src/lib-index/maildir/maildir-uidlist.c index 8862ea6ecf..c99e404938 100644 --- a/src/lib-index/maildir/maildir-uidlist.c +++ b/src/lib-index/maildir/maildir-uidlist.c @@ -33,6 +33,10 @@ int maildir_uidlist_try_lock(struct mail_index *index) break; if (errno != EEXIST) { + if (errno == EACCES) { + /* read-only mailbox */ + return 0; + } index_file_set_syscall_error(index, path, "open()"); return -1; } diff --git a/src/lib-index/maildir/maildir-update-flags.c b/src/lib-index/maildir/maildir-update-flags.c index 7b9405edaa..ea91868228 100644 --- a/src/lib-index/maildir/maildir-update-flags.c +++ b/src/lib-index/maildir/maildir-update-flags.c @@ -17,7 +17,7 @@ static int handle_error(struct mail_index *index, return -2; } - if (errno == EPERM) + if (errno == EACCES) index->mailbox_readonly = TRUE; else { index_set_error(index, "rename(%s, %s) failed: %m", -- 2.47.3