From 7abdfe2ff2af36afc99d02dc0980d52e976af966 Mon Sep 17 00:00:00 2001 From: Richard Russon Date: Wed, 2 Oct 2019 23:58:39 +0100 Subject: [PATCH] fix read-only mbox If an mbox Mailbox doesn't have write privs, try opening it read-only. Before the architectural changes, there could be multiple open Mailbox objects representing a single folder. By default a folder would be given a read-only Mailbox. When the folder needed to be written to, another Mailbox would be opened read-write. This lead to synchronisation problems between the two Mailboxes. Co-authored-by: Pietro Cerutti --- mbox/mbox.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/mbox/mbox.c b/mbox/mbox.c index 7f1021b3b..7f55bb8d3 100644 --- a/mbox/mbox.c +++ b/mbox/mbox.c @@ -899,6 +899,36 @@ int mbox_ac_add(struct Account *a, struct Mailbox *m) return 0; } +/** + * mbox_open_readwrite - Open an mbox read-write + * @param m Mailbox + * @retval ptr FILE handle + * + * This function ensures that the FILE and readonly flag are changed atomically. + */ +static FILE *mbox_open_readwrite(struct Mailbox *m) +{ + FILE *fp = fopen(mailbox_path(m), "r+"); + if (fp) + m->readonly = false; + return fp; +} + +/** + * mbox_open_readwrite - Open an mbox read-only + * @param m Mailbox + * @retval ptr FILE handle + * + * This function ensures that the FILE and readonly flag are changed atomically. + */ +static FILE *mbox_open_readonly(struct Mailbox *m) +{ + FILE *fp = fopen(mailbox_path(m), "r"); + if (fp) + m->readonly = true; + return fp; +} + /** * mbox_mbox_open - Open a Mailbox - Implements MxOps::mbox_open() */ @@ -911,12 +941,17 @@ static int mbox_mbox_open(struct Mailbox *m) if (!adata) return -1; - adata->fp = fopen(mailbox_path(m), "r+"); + adata->fp = mbox_open_readwrite(m); + if (!adata->fp) + { + adata->fp = mbox_open_readonly(m); + } if (!adata->fp) { mutt_perror(mailbox_path(m)); return -1; } + mutt_sig_block(); if (mbox_lock_mailbox(m, false, true) == -1) { -- 2.40.0