On Mon, 2003-02-17 at 20:59, Andreas Aardal Hanssen wrote:
From maildir-storage.c, line 325:
while (rename(src, dest) < 0 && count < 2) { if (errno != EEXIST) {
rename can never return EEXIST in errno.
Sure it can:
ENOTEMPTY or EEXIST
newpath is a non-empty directory, i.e., contains entries other
than "." and "..".
But looks like I've missed the ENOTEMPTY check there, adding. I'm renaming directories there, not files.
/* move the file into new/ directory - syncing will pick it up from there */ if (rename(tmp_path, new_path) == 0) failed = FALSE;
Here you can lose emails if the new/ folder contains a message whose base name is equal.
In theory, yes. In practice, I'd say not. It can only happen with broken MUAs, are there any? User could of course deliberately break it, but is there some gain in it?
The only way to avoid this is:
- use link and unlink, not rename
..and if it crashes (or loses NFS link) between those calls, you'll suddenly see two mails. I prefer atomic operations.
Anyway, Maildir has a strict consistency criteria which says that all messages that are linked from tmp/ into new/ _must_ use time(NULL) plus a number that is guaranteed not to lapse within one second, and which does not collide with other messages in new/. new/ is the single entry point into cur/, and messages in new/ can not be "older" than the messages in cur/.
It only has requirement that the file name is unique. There's other ways to do that than time(NULL). http://cr.yp.to/proto/maildir.html lists some.
- leave messages that have a time_t part equal to or higher than time(NULL). .. The simple reasoning for this is that you can never guarantee that there is no message in cur/ that has the same base name, but perhaps different flags. It follows that when moving a message from new/ to cur/, it is required that the server only picks messages that are older than one second.
I'm not sure what you mean by this.. What's special in files that were just created? What changes after it's older than one second? Or are you changing the base name when moving it to cur/? (What makes you sure that the new base name still doesn't exist?)
I don't think you should rely on checking timestamps in any case. What if the maildir is accessed via NFS and some other computer with different time created the file?
But about the flags, looks like maildir spec says they could be used only in cur/ directory, so I guess my code is broken because it allows setting them already in new/.. Well, I'll fix it anyway later by moving mails directly from tmp/ into cur/ when implementing UIDPLUS extension.