summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
5ca5cba)
(deliver): In rev 1582 i changed this from using rename(2) to
the recommended link(2) + unlink(2). But in minc i was using
open(2) + rename(2) instead, which is just as safe as link +
unlink but with one advantage. So switch to that model.
minc/current/minc:
(store_message): Document the open + rename procedure and
explain why it is used instead of link + unlink.
deliver(char *maildir, char *newfn)
{
char fn[TMPNAMLEN];
deliver(char *maildir, char *newfn)
{
char fn[TMPNAMLEN];
char buf[BUFSIZ]; /* Allocated here only as an (early,
* evil) space optimization. */
char buf[BUFSIZ]; /* Allocated here only as an (early,
* evil) space optimization. */
strcpy(newfn, fn);
memcpy(newfn, "new", 3);
strcpy(newfn, fn);
memcpy(newfn, "new", 3);
- if (link(fn, newfn) != 0) {
- save_errno( unlink(fn) );
- err(MDELIVER_EXITCODE, "Failed link(%s, new)", fn);
+ tmpfd = open(newfn, O_WRONLY | O_EXCL | O_CREAT, 0600);
+ if (tmpfd < 0) {
+ /* XXX: what error message to use? */
+ err(MDELIVER_EXITCODE, "Failed open(%s)", newfn);
+ if (rename(fn, newfn) != 0) {
+ save_errno( unlink(newfn) );
+ save_errno( unlink(fn) );
+ err(MDELIVER_EXITCODE, "Failed rename(%s, new)", fn);
+ }
}
/* Run a program to process the new message. */
}
/* Run a program to process the new message. */