]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Some fixes to handling read-only maildirs.
authorTimo Sirainen <tss@iki.fi>
Sun, 18 May 2003 12:56:14 +0000 (15:56 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 18 May 2003 12:56:14 +0000 (15:56 +0300)
--HG--
branch : HEAD

src/lib-index/mail-custom-flags.c
src/lib-index/maildir/maildir-index.c
src/lib-index/maildir/maildir-sync.c
src/lib-index/maildir/maildir-uidlist.c
src/lib-index/maildir/maildir-update-flags.c

index 9b2b52328fa57f1b24c452acb8c251cbe0726c17..4a8f1b36d0587493868e15993c21f1c2b5bdd870 100644 (file)
@@ -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);
index f671b06211bde0a18b4766fd86b08de63411d79a..31d3a1633aa0108b46446adbbc296b61e5f0d374 100644 (file)
@@ -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;
 }
index d2d12faa713e591064ba2815ed2d8fb9688fe853..fac90d8cd11b991c71fcdb3809451d89ccd7a064 100644 (file)
@@ -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);
index 8862ea6ecfc05dcc63478bbc5e5184bc6703e9a6..c99e4049386ea241ce36bedd9f79f7447f16efd5 100644 (file)
@@ -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;
                }
index 7b9405edaa5ee516f729bd958994f4f92db73833..ea91868228efd320f9f6b46d37929691d6daca5b 100644 (file)
@@ -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",