<<< Date Index >>>     <<< Thread Index >>>

Re: How to implement save_empty on maildir?



On Sun, Jun 28, 2009 at 07:42:53PM +0000, Jörg Sommer wrote:
> Hi,
> 
> Rocco Rutte <pdmef@xxxxxxx> wrote:
> > * Wu, Yue wrote:
> >> I want to let mutt deletes empty maildirs automatically, but 'save_empty' 
> >> only
> >> works for mbox, why? How to achieve it for maildir?
> >
> > It doesn't work for maildir. I'm not sure why, but probably because
> > removing an empty maildir has the potential to break something as it
> > cannot be done atomically.
> 
> Mutt can rename the maildir to $maildir-mutt-remove and then remove the
> subdirectories and then the $maildir-mutt-remove. The rename can be done
> atomically.

At first glance, this seems like a good solution, but actually it is
not:

1. There may be an existing directory by that name already.  
   Even if Mutt checks for the existence of it first, it is not safe,
   because the user could (without knowing the behavior of Mutt)
   create such a directory in between the time that Mutt checks, and
   executes the rename().

2. $maildir may be a symlink. I'm not sure how mutt handles the
   general case of a maildir being a symlink, but assuming that's
   allowed, then in this case, it would fail briliantly.  Mutt would
   rename() the symlink, and then delete it.  The user may be using
   something like fetchmail to deliver mail to the maildir (the actual
   directory which was the target of the symlink) in which case Mutt
   will NEVER AGAIN see new mail in that directory, at least until
   such time as the user realizes what happened and takes some action
   to fix the problem.  It would effectively make it impossible to use
   symlinks.

3. In some cases, it may be possible that the directories $maildir and
   ${maildir}-mutt-remove would not be on the same file system (e.g.
   if $maildir happened to be an NFS mount, or a bind mount, or some
   other wacky filesystem, like some arbitrary filesystem
   implementation that sits on top of FUSE).  In such a case, the
   rename() would either fail or not be atomic (since you would need
   to copy the files between filesystems in that case).  Granted,
   doing this is crazy; but as a long-time sysadmin I've known a
   surprising number of people who do crazy things with their mail,
   simply because they can...

As far as I can see, there is no safe way to atomically ensure that
none of these three cases are true, and in the case of weird file
system implementations, may even be impossible (though, I suppose it
would not be completely unreasonable for Mutt to ignore those cases).
I can't be sure, but I believe it is not possible to implement this
safely on any modern operating system in common usage.  However I
believe a better alternative exists:  Instead of physically removing
the files, make Mutt simply avoid showing them to you if they contain
no messages.  For mbox this is trivial (and yes, I think the behavior
should be consistent between the formats); for maildir you would need
to determine the number of files in each of the subdirectories of
$maildir; or rather determine that there are non-zero numbers of
messages in them.

-- 
Derek D. Martin    http://www.pizzashack.org/   GPG Key ID: 0xDFBEAD02
-=-=-=-=-
This message is posted from an invalid address.  Replying to it will result in
undeliverable mail due to spam prevention.  Sorry for the inconvenience.

Attachment: pgp3lcdwjUwa7.pgp
Description: PGP signature