Hi Jörg, On Thu, Jul 02, 2009 at 08:10:21AM +0000, Jörg Sommer wrote: > So, create the directory yourself to ensure it's there and yours. > > % cat rename-test.c > #include <stdio.h> > #include <sys/stat.h> > > int main(void) > { > mkdir("mdir-mutt-delete", 0) /* this is a temporary directory to > ensure rename doesn't replace an > existing directory */ > > || rename("mdir", "mdir-mutt-delete"); > > return 0; > } There are several problems with this. If the directory exists when you do the mkdir, it fails with no clear course of action to take to fix the failure; that seems like clearly a bug to me. Also, if some process puts a file in mdir-mutt-delete before you rename it, the rename will fail. In either case, Mutt didn't do what you told it to do (remove the maildir when it's empty). You can't code stuff that works sometimes in applications that other people are going to use... Also, while this test may work as you expect on your system, not all operating systems on which Mutt runs may have the same semantics. More importantly these operations are not atomic, and therefore can not be done safely. It is possible, for example, for the user to do exacty the same thing, in between the time you create the directory, and the time you rename the maildir. It also means the user can not use ${maildir}-mutt-delete as a mailbox name (or anything else). Which in turn means that the user must KNOW that they can't use it safely. That's yucky (to say the least)... the user should not need to know the intimate details of the implementation of your software in order to use it safely, by and large. > > 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. > > If the maildir is a symlink, the question is what behaviour is expected? Presumably the expected behavior is that it should work exactly the same way whether it's a symlink or not. For the most part, this is the point of symlinks; to make transparent the ability to have files appear to exist someplace other than where they actually exist. > If it's enough to remove the symlink, that's pretty easy. If mutt should > remove the target of the symlink, mutt can do it as described above. As I described previously, this is clearly unacceptable. New mail will accumulate, but Mutt won't see it, because it's configured to look at a non-existant symlink. > > 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. > > Because the tool rm removes the symlink, I think the user should expect > that the symlink gets removed and not the target. Why should the user expect that it gets removed? Even if you document it, the user may set it up as a symlink, and then set this option on the folder at a later time, and never make the connection between what they just did and the problem they just caused. This is exactly why most sysadmins have a job. ;-) > > > 3. In some cases, it may be possible that the directories $maildir and > > ${maildir}-mutt-remove would not be on the same file system > > As mutt creates the temporary directory, mutt can say where the > directory should be created. If mutt creates the temporary directory > in the same directory as the maildir is, I see no problems. I already gave you two examples where it IS a problem. I'll spell it out: /home/user/mail: root of user's mail directory /home/user/mail/maildir1: a specific folder which is NFS-mounted from another system (because the user is slightly crazy). /home/user/mail/maildir1-mutt-delete: a directory under /home/user/mail, on the same device In other words, the user executed something like: /sbin/mount -t NFS server:/my/other/maildir /home/user/mail/maildir1 Now you have maildir1 and maildir1-mutt-delete on two different physical filesystems. That won't work (a call to rename will fail; you need to copy the files to the new location, and unlink() the old ones). Another case: The user ran out of space in /home, so created a directory in /var for more folders. But they still want the maildir structure to look like it's all in one place, so they do this: /sbin/mount -o bindmount /var/my/new/maildr /home/user/mail/maildir1 Same problem as before. This may seem weird to you (and it probably should), but I promise you, people really do this stuff. Because they can, and because they think it's cool. And for the most part, it works just fine... until an application like Mutt comes along and makes assumptions about the arrangement of the filesystem. Some filesystems (like ENCFS) are not really file systems at all... they make files that exist elsewhere look like a filesystem. I don't know how that would work, to be honest, but I can imagine there might be problems, depending on the file system implementation. For what it's worth, there are probably other problems with this that I didn't think of. But someone would find them... ;-) The point is, you can't do any of this atomically, which means it's not reliably safe to do, which means you just can't do it. > Otherwise, I thinks it's no problem to fall back to the current behaviour > and do _nothing_ or print an error message. Don't care for special cases. > The main case can be handled as described above. Nope, that's unacceptable. Because it means your solution only works *sometimes*, and other times the behavior is undefined. That's a recipe for bad application design. -- 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:
pgpQF6C_d6rHX.pgp
Description: PGP signature