mail.local can now use username.lock files as well as flock(). Use the

-l flag in your favorite sendmail.cf file.
This commit is contained in:
deraadt 1993-05-24 07:30:36 +00:00
parent 1047beea02
commit 5840201f38
2 changed files with 44 additions and 24 deletions

View File

@ -39,6 +39,7 @@
.Nd store mail in a mailbox
.Sh SYNOPSIS
.Nm mail.local
.Op Fl l
.Op Fl f Ar from
.Ar user ...
.Sh DESCRIPTION
@ -52,9 +53,13 @@ The
must be a valid user name.
.Pp
The options are as follows:
.Bl -tag -width xxxfrom
.Bl -tag -width xxxxxxx
.It Fl f Ar from
Specify the sender's name.
.It Fl l
Request that
.Nm username.lock
files be used for locking.
.El
.Pp
Individual mail messages in the mailbox are delimited by an empty
@ -65,7 +70,11 @@ A blank line is appended to each message.
A greater-than character (``>'') is prepended to any line in the message
which could be mistaken for a ``From '' delimiter line.
.Pp
The mail files are exclusively locked with
If the
.Op Fl l
flag is specified mailbox locking is done with
.Nm username.lock
files. Otherwise, the mailbox is exclusively locked with
.Xr flock 2
while mail is appended.
.Pp
@ -100,6 +109,6 @@ A superset of
.Nm mail.local
(handling mailbox reading as well as mail delivery)
appeared in
.At v7 .
.At v7
as the program
.Nm mail .

View File

@ -60,7 +60,7 @@ static char sccsid[] = "@(#)mail.local.c 5.6 (Berkeley) 6/19/91";
#define FATAL 1
#define NOTFATAL 0
int deliver __P((int, char *));
int deliver __P((int, char *, int));
void err __P((int, const char *, ...));
void notifybiff __P((char *));
int store __P((char *));
@ -73,7 +73,7 @@ main(argc, argv)
extern int optind;
extern char *optarg;
struct passwd *pw;
int ch, fd, eval;
int ch, fd, eval, lockfile=0;
uid_t uid;
char *from;
@ -90,6 +90,9 @@ main(argc, argv)
err(FATAL, "multiple -f options");
from = optarg;
break;
case 'l':
lockfile++;
break;
case '?':
default:
usage();
@ -112,7 +115,7 @@ main(argc, argv)
fd = store(from);
for (eval = 0; *argv; ++argv)
eval |= deliver(fd, *argv);
eval |= deliver(fd, *argv, lockfile);
exit(eval);
}
@ -159,14 +162,15 @@ store(from)
return(fd);
}
deliver(fd, name)
deliver(fd, name, lockfile)
int fd;
char *name;
int lockfile;
{
struct stat sb;
struct passwd *pw;
int created, mbfd, nr, nw, off, rval;
char biffmsg[100], buf[8*1024], path[MAXPATHLEN];
int created, mbfd, nr, nw, off, rval, lfd=-1;
char biffmsg[100], buf[8*1024], path[MAXPATHLEN], lpath[MAXPATHLEN];
off_t curoff, lseek();
/*
@ -180,28 +184,28 @@ deliver(fd, name)
(void)sprintf(path, "%s/%s", _PATH_MAILDIR, name);
if(lockfile) {
(void)sprintf(lpath, "%s/%s.lock", _PATH_MAILDIR, name);
if((lfd = open(lpath, O_CREAT|O_WRONLY|O_EXCL,
S_IRUSR|S_IWUSR)) < 0) {
err(NOTFATAL, "%s: %s", lpath, strerror(errno));
return(1);
}
}
if (!(created = lstat(path, &sb)) &&
(sb.st_nlink != 1 || S_ISLNK(sb.st_mode))) {
err(NOTFATAL, "%s: linked file", path);
return(1);
}
/*
* There's a race here -- two processes think they both created
* the file. This means the file cannot be unlinked.
*/
if ((mbfd =
open(path, O_APPEND|O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
if((mbfd = open(path, O_APPEND|O_WRONLY|O_EXLOCK,
S_IRUSR|S_IWUSR)) < 0) {
if ((mbfd = open(path, O_APPEND|O_CREAT|O_WRONLY|O_EXLOCK,
S_IRUSR|S_IWUSR)) < 0) {
err(NOTFATAL, "%s: %s", path, strerror(errno));
return(1);
}
rval = 0;
/* XXX: Open should allow flock'ing the file; see 4.4BSD. */
if (flock(mbfd, LOCK_EX)) {
err(NOTFATAL, "%s: %s", path, strerror(errno));
rval = 1;
goto bad;
}
curoff = lseek(mbfd, 0L, SEEK_END);
@ -230,7 +234,14 @@ trunc: (void)ftruncate(mbfd, curoff);
* ownership or permissions were changed there was a reason for doing
* so.
*/
bad: if (created)
bad:
if(lockfile) {
if(lfd >= 0) {
unlink(lpath);
close(lfd);
}
}
if (created)
(void)fchown(mbfd, pw->pw_uid, pw->pw_gid);
(void)fsync(mbfd); /* Don't wait for update. */