From 4e161d3b48a1cc0ab48cbfb33a76d3bf5dbd7d89 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Thu, 19 Jul 1984 22:43:05 -0800 Subject: [PATCH] use flock for mailbox locking SCCS-vsn: libexec/mail.local/mail.local.c 4.22 SCCS-vsn: usr.bin/mail/collect.c 2.16 SCCS-vsn: usr.bin/mail/main.c 2.13 SCCS-vsn: usr.bin/mail/Makefile 2.16 SCCS-vsn: usr.bin/mail/getname.c 2.3 SCCS-vsn: usr.bin/mail/quit.c 2.8 --- usr/src/libexec/mail.local/mail.local.c | 544 ++++++++++-------------- usr/src/usr.bin/mail/Makefile | 6 +- usr/src/usr.bin/mail/collect.c | 15 +- usr/src/usr.bin/mail/getname.c | 137 +----- usr/src/usr.bin/mail/main.c | 4 +- usr/src/usr.bin/mail/quit.c | 58 +-- 6 files changed, 286 insertions(+), 478 deletions(-) diff --git a/usr/src/libexec/mail.local/mail.local.c b/usr/src/libexec/mail.local/mail.local.c index f93f2f4e10..61fcd47db7 100644 --- a/usr/src/libexec/mail.local/mail.local.c +++ b/usr/src/libexec/mail.local/mail.local.c @@ -1,30 +1,30 @@ #ifndef lint -static char sccsid[] = "@(#)mail.local.c 4.21 (Berkeley) %G%"; +static char sccsid[] = "@(#)mail.local.c 4.22 (Berkeley) %G%"; #endif +#include +#include +#include + #include #include #include #include #include -#include -#include #include #include #define SENDMAIL "/usr/lib/sendmail" + /* copylet flags */ +#define REMOTE 1 /* remote mail, add rmtmsg */ +#define ORDINARY 2 +#define ZAP 3 /* zap header and trailing empty line */ +#define FORWARD 4 -/*copylet flags */ - /*remote mail, add rmtmsg */ -#define REMOTE 1 - /* zap header and trailing empty line */ -#define ZAP 3 -#define ORDINARY 2 -#define FORWARD 4 -#define LSIZE 256 -#define MAXLET 300 /* maximum number of letters */ -#define MAILMODE (~0600) /* mode of created mail */ +#define LSIZE 256 +#define MAXLET 300 /* maximum number of letters */ +#define MAILMODE 0600 /* mode of created mail */ char line[LSIZE]; char resp[LSIZE]; @@ -41,19 +41,17 @@ char lettmp[] = "/tmp/maXXXXX"; char maildir[] = "/usr/spool/mail/"; char mailfile[] = "/usr/spool/mail/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; char dead[] = "dead.letter"; -char *netname = "vax"; char forwmsg[] = " forwarded\n"; FILE *tmpf; FILE *malf; char *my_name; char *getlogin(); -struct passwd *getpwuid(); int error; int changed; int forward; char from[] = "From "; long ftell(); -int delete(); +int delex(); char *ctime(); int flgf; int flgp; @@ -66,13 +64,11 @@ main(argc, argv) char **argv; { register i; - char sobuf[BUFSIZ]; - setbuf(stdout, sobuf); mktemp(lettmp); unlink(lettmp); my_name = getlogin(); - if (my_name == NULL || strlen(my_name) == 0) { + if (my_name == NULL || *my_name == '\0') { struct passwd *pwent; pwent = getpwuid(getuid()); if (pwent==NULL) @@ -80,14 +76,18 @@ char **argv; else my_name = pwent->pw_name; } - if(setjmp(sjbuf)) done(); - for (i=SIGHUP; i<=SIGTERM; i++) - setsig(i, delete); - tmpf = fopen(lettmp, "w"); - if (tmpf == NULL) { - fprintf(stderr, "mail: cannot open %s for writing\n", lettmp); + if (setjmp(sjbuf)) done(); - } + for (i=SIGHUP; i<=SIGTERM; i++) + setsig(i, delex); + tmpf = fopen(lettmp, "w+r"); + if (tmpf == NULL) + panic("mail: %s: cannot open for writing", lettmp); + /* + * This protects against others reading mail from temp file and + * if we exit, the file will be deleted already. + */ + unlink(lettmp); if (argv[0][0] == 'r') rmail++; if (argv[0][0] != 'r' && /* no favors for rmail*/ @@ -102,7 +102,7 @@ setsig(i, f) int i; int (*f)(); { - if(signal(i, SIG_IGN)!=SIG_IGN) + if (signal(i, SIG_IGN) != SIG_IGN) signal(i, f); } @@ -118,7 +118,7 @@ any(c, str) } printmail(argc, argv) -char **argv; + char **argv; { int flg, i, j, print; char *p, *getarg(); @@ -126,53 +126,57 @@ char **argv; setuid(getuid()); cat(mailfile, maildir, my_name); +#ifdef notdef if (stat(mailfile, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) { strcat(mailfile, "/"); strcat(mailfile, my_name); } - for (; argc>1; argv++, argc--) { - if (argv[1][0]=='-') { - if (argv[1][1]=='q') - delflg = 0; - else if (argv[1][1]=='p') { - flgp++; - delflg = 0; - } else if (argv[1][1]=='f') { - if (argc>=3) { - strcpy(mailfile, argv[2]); - argv++; - argc--; - } - } else if (argv[1][1]=='r') { - forward = 1; - } else if (argv[1][1]=='h') { - forward = 1; - } else { - fprintf(stderr, "mail: unknown option %c\n", argv[1][1]); - done(); +#endif + for (; argc > 1; argv++, argc--) { + if (argv[1][0] != '-') + break; + switch (argv[1][1]) { + + case 'p': + flgp++; + /* fall thru... */ + case 'q': + delflg = 0; + break; + + case 'f': + if (argc >= 3) { + strcpy(mailfile, argv[2]); + argv++, argc--; } - } else break; + + case 'b': + forward = 1; + break; + + default: + panic("unknown option %c", argv[1][1]); + /*NOTREACHED*/ + } } malf = fopen(mailfile, "r"); if (malf == NULL) { - fprintf(stdout, "No mail.\n"); + printf("No mail.\n"); return; } - lock(mailfile); + flock(fileno(malf), LOCK_SH); copymt(malf, tmpf); - fclose(malf); - fclose(tmpf); - unlock(); - tmpf = fopen(lettmp, "r"); + fclose(malf); /* implicit unlock */ + fseek(tmpf, 0, L_SET); changed = 0; print = 1; for (i = 0; i < nlet; ) { j = forward ? i : nlet - i - 1; - if(setjmp(sjbuf)) { - print=0; + if (setjmp(sjbuf)) { + print = 0; } else { if (print) copylet(j, stdout, ORDINARY); @@ -183,26 +187,26 @@ char **argv; continue; } setjmp(sjbuf); - fprintf(stdout, "? "); + fputs("? ", stdout); fflush(stdout); if (fgets(resp, LSIZE, stdin) == NULL) break; switch (resp[0]) { default: - fprintf(stderr, "usage\n"); + printf("usage\n"); case '?': print = 0; - fprintf(stderr, "q\tquit\n"); - fprintf(stderr, "x\texit without changing mail\n"); - fprintf(stderr, "p\tprint\n"); - fprintf(stderr, "s[file]\tsave (default mbox)\n"); - fprintf(stderr, "w[file]\tsame without header\n"); - fprintf(stderr, "-\tprint previous\n"); - fprintf(stderr, "d\tdelete\n"); - fprintf(stderr, "+\tnext (no delete)\n"); - fprintf(stderr, "m user\tmail to user\n"); - fprintf(stderr, "! cmd\texecute cmd\n"); + printf("q\tquit\n"); + printf("x\texit without changing mail\n"); + printf("p\tprint\n"); + printf("s[file]\tsave (default mbox)\n"); + printf("w[file]\tsame without header\n"); + printf("-\tprint previous\n"); + printf("d\tdelete\n"); + printf("+\tnext (no delete)\n"); + printf("m user\tmail to user\n"); + printf("! cmd\texecute cmd\n"); break; case '+': @@ -233,7 +237,7 @@ char **argv; } if (resp[1] == '\n' || resp[1] == '\0') { p = getenv("HOME"); - if(p != 0) + if (p != 0) cat(resp+1, p, "/mbox"); else cat(resp+1, "", "mbox"); @@ -241,7 +245,8 @@ char **argv; for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) { malf = fopen(lfil, "a"); if (malf == NULL) { - fprintf(stdout, "mail: cannot append to %s\n", lfil); + printf("mail: %s: cannot append\n", + lfil); flg++; continue; } @@ -269,7 +274,7 @@ char **argv; continue; } for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) - if (!sendrmt(j, lfil, "/bin/mail")) /* couldn't send it */ + if (!sendrmt(j, lfil, "/bin/mail")) flg++; if (flg) print = 0; @@ -298,54 +303,46 @@ char **argv; copyback(); } -copyback() /* copy temp or whatever back to /usr/spool/mail */ +/* copy temp or whatever back to /usr/spool/mail */ +copyback() { - register i, n, c; - int new = 0; + register i, c; + int fd, new = 0, oldmask; struct stat stbuf; - signal(SIGINT, SIG_IGN); - signal(SIGHUP, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - lock(mailfile); - stat(mailfile, &stbuf); +#define mask(s) (1 << ((s) - 1)) + oldmask = sigblock(mask(SIGINT)|mask(SIGHUP)|mask(SIGQUIT)); +#undef mask + fd = open(mailfile, O_RDWR | O_CREAT, MAILMODE); + if (fd >= 0) { + flock(fd, LOCK_EX); + malf = fdopen(fd, "r+w"); + } + if (fd < 0 || malf == NULL) + panic("can't rewrite %s", lfil); + fstat(fd, &stbuf); if (stbuf.st_size != let[nlet].adr) { /* new mail has arrived */ - malf = fopen(mailfile, "r"); - if (malf == NULL) { - fprintf(stdout, "mail: can't re-read %s\n", mailfile); - done(); - } - fseek(malf, let[nlet].adr, 0); - fclose(tmpf); - tmpf = fopen(lettmp, "a"); - fseek(tmpf, let[nlet].adr, 0); - while ((c = fgetc(malf)) != EOF) - fputc(c, tmpf); - fclose(malf); - fclose(tmpf); - tmpf = fopen(lettmp, "r"); + fseek(malf, let[nlet].adr, L_SET); + fseek(tmpf, let[nlet].adr, L_SET); + while ((c = getc(malf)) != EOF) + putc(c, tmpf); let[++nlet].adr = stbuf.st_size; new = 1; + fseek(malf, 0, L_SET); } - malf = fopen(mailfile, "w"); - if (malf == NULL) { - fprintf(stderr, "mail: can't rewrite %s\n", lfil); - done(); - } - n = 0; + ftruncate(fd, 0); for (i = 0; i < nlet; i++) - if (let[i].change != 'd') { + if (let[i].change != 'd') copylet(i, malf, ORDINARY); - n++; - } - fclose(malf); + fclose(malf); /* implict unlock */ if (new) - fprintf(stdout, "new mail arrived\n"); - unlock(); + printf("New mail has arrived.\n"); + sigsetmask(oldmask); } -copymt(f1, f2) /* copy mail (f1) to temp (f2) */ -FILE *f1, *f2; +/* copy mail (f1) to temp (f2) */ +copymt(f1, f2) + FILE *f1, *f2; { long nextadr; @@ -365,23 +362,37 @@ copylet(n, f, type) { int ch; long k; + char hostname[32]; - fseek(tmpf, let[n].adr, 0); + fseek(tmpf, let[n].adr, L_SET); k = let[n+1].adr - let[n].adr; - while(k-- > 1 && (ch=fgetc(tmpf))!='\n') - if(type!=ZAP) fputc(ch,f); - if(type==REMOTE) { - char hostname[32]; + while (k-- > 1 && (ch = getc(tmpf)) != '\n') + if (type != ZAP) + putc(ch, f); + switch (type) { + + case REMOTE: gethostname(hostname, sizeof (hostname)); fprintf(f, " remote from %s\n", hostname); - } else if (type==FORWARD) + break; + + case FORWARD: fprintf(f, forwmsg); - else if(type==ORDINARY) - fputc(ch,f); - while(k-->1) - fputc(ch=fgetc(tmpf), f); - if(type!=ZAP || ch!= '\n') - fputc(fgetc(tmpf), f); + break; + + case ORDINARY: + putc(ch, f); + break; + + default: + panic("Bad letter type %d to copylet.", type); + } + while (k-- > 1) { + ch = getc(tmpf); + putc(ch, f); + } + if (type != ZAP || ch != '\n') + putc(getc(tmpf), f); } isfrom(lp) @@ -408,15 +419,14 @@ char **argv; int dflag; dflag = 0; - if (argc < 1) + if (argc < 1) { fprintf(stderr, "puke\n"); + return; + } for (vp = argv, ap = newargv + 1; (*ap = *vp++) != 0; ap++) - { if (ap[0][0] == '-' && ap[0][1] == 'd') dflag++; - } - if (!dflag) - { + if (!dflag) { /* give it to sendmail, rah rah! */ unlink(lettmp); ap = newargv+1; @@ -442,10 +452,8 @@ char **argv; argc--; switch (cp[1]) { case 'r': - if (argc <= 0) { + if (argc <= 1) usage(); - done(); - } if (strcmp(my_name, "root") == 0 || strcmp(my_name, "daemon") == 0 || strcmp(my_name, "network") == 0 || @@ -461,10 +469,8 @@ char **argv; break; case 'h': - if (argc <= 0) { + if (argc <= 1) usage(); - done(); - } hseqno = atoi(argv[1]); argv++; argc--; @@ -475,69 +481,52 @@ char **argv; default: usage(); - done(); } } - if (argc <= 1) { + if (argc <= 1) usage(); - done(); - } if (gaver == 0) strcpy(truename, my_name); - /* - if (argc > 4 && strcmp(argv[1], "-r") == 0) { - strcpy(truename, argv[2]); - argc -= 2; - argv += 2; - fgets(line, LSIZE, stdin); - if (strncmp("From", line, 4) == 0) - line[0] = '\0'; - } else - strcpy(truename, my_name); - */ time(&iop); fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop)); iop = ftell(tmpf); - flgf = 1; - for (first = 1;; first = 0) { - if (first && line[0] == '\0' && fgets(line, LSIZE, stdin) == NULL) - break; - if (!first && fgets(line, LSIZE, stdin) == NULL) - break; - if (line[0] == '.' && line[1] == '\n' && isatty(fileno(stdin))) + flgf = first = 1; + for (;;) { + if (first) { + first = 0; + if (*line == '\0' && fgets(line, LSIZE, stdin) == NULL) + break; + } else { + if (fgets(line, LSIZE, stdin) == NULL) + break; + } + if (*line == '.' && line[1] == '\n' && isatty(fileno(stdin))) break; if (isfrom(line)) - fputs(">", tmpf); + putc('>', tmpf); fputs(line, tmpf); flgf = 0; } - fputs("\n", tmpf); + putc('\n', tmpf); nlet = 1; let[0].adr = 0; let[1].adr = ftell(tmpf); - fclose(tmpf); if (flgf) return; - tmpf = fopen(lettmp, "r"); - if (tmpf == NULL) { - fprintf(stderr, "mail: cannot reopen %s for reading\n", lettmp); - return; - } - while (--argc > 0) { + while (--argc > 0) if (!sendmail(0, *++argv, truename)) error++; - } if (error && safefile(dead)) { setuid(getuid()); malf = fopen(dead, "w"); if (malf == NULL) { - fprintf(stdout, "mail: cannot open %s\n", dead); + printf("mail: cannot open %s\n", dead); fclose(tmpf); return; } copylet(0, malf, ZAP); fclose(malf); - fprintf(stdout, "Mail saved in %s\n", dead); + printf("Mail saved in %s\n", dead); } fclose(tmpf); } @@ -572,7 +561,7 @@ char *rcmd; } *p = '\0'; if ((!local && *name=='\0') || (local && *rsys=='\0')) { - fprintf(stdout, "null name\n"); + printf("null name\n"); return(0); } skip: @@ -607,194 +596,113 @@ usage() fprintf(stderr, "Usage: mail [ -f ] people . . .\n"); error = EX_USAGE; + done(); } #include #include #include -struct sockaddr_in biffaddr; + +notifybiff(msg) + char *msg; +{ + static struct sockaddr_in addr; + static int f = -1; + + if (addr.sin_family == 0) { + struct hostent *hp = gethostbyname("localhost"); + struct servent *sp = getservbyname("biff", "udp"); + + if (hp && sp) { + addr.sin_family = hp->h_addrtype; + bcopy(hp->h_addr, &addr.sin_addr, hp->h_length); + addr.sin_port = sp->s_port; + } + } + if (addr.sin_family) { + if (f < 0) + f = socket(AF_INET, SOCK_DGRAM, 0); + sendto(f, msg, strlen(msg)+1, 0, &addr, sizeof (addr)); + } +} sendmail(n, name, fromaddr) -int n; -char *name; -char *fromaddr; + int n; + char *name, *fromaddr; { - char file[100]; - register char *p; - register mask; - struct passwd *pw, *getpwnam(); + char file[256]; + int mask, fd; + struct passwd *pw; +#ifdef notdef struct stat statb; +#endif char buf[128]; - int f; - struct hostent *hp = NULL; - struct servent *sp = NULL; - for(p=name; *p!='!'&&*p!='^' &&*p!='\0'; p++) - ; - if (*p == '!'|| *p=='^') - return(sendrmt(n, name, 0)); + if (any(name, "!^")) + return (sendrmt(n, name, 0)); if ((pw = getpwnam(name)) == NULL) { - fprintf(stdout, "mail: can't send to %s\n", name); + printf("mail: can't send to %s\n", name); return(0); } cat(file, maildir, name); +#ifdef notdef if (stat(file, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) { strcat(file, "/"); strcat(file, name); } - mask = umask(MAILMODE); +#endif if (!safefile(file)) return(0); - lock(file); - malf = fopen(file, "a"); - umask(mask); - if (malf == NULL) { - unlock(); - fprintf(stdout, "mail: cannot append to %s\n", file); - return(0); + fd = open(file, O_WRONLY | O_CREAT, MAILMODE); + if (fd >= 0) { + flock(fd, LOCK_EX); + malf = fdopen(fd, "a"); } - chown(file, pw->pw_uid, pw->pw_gid); - { - hp = gethostbyname("localhost"); - sp = getservbyname("biff", "udp"); - if (hp && sp) { - f = socket(AF_INET, SOCK_DGRAM, 0, 0); - sprintf(buf, "%s@%d\n", name, ftell(malf)); - } + if (fd < 0 || malf == NULL) { + close(fd); + printf("mail: %s: cannot append\n", file); + return(0); } + fchown(fd, pw->pw_uid, pw->pw_gid); + sprintf(buf, "%s@%d\n", name, ftell(malf)); copylet(n, malf, ORDINARY); fclose(malf); - if (hp && sp) { - biffaddr.sin_family = hp->h_addrtype; - bcopy(hp->h_addr, &biffaddr.sin_addr, hp->h_length); - biffaddr.sin_port = sp->s_port; - sendto(f, buf, strlen(buf)+1, 0, &biffaddr, sizeof (biffaddr)); - close(f); - } - unlock(); + notifybiff(buf); return(1); } -delete(i) +delex(i) { - setsig(i, delete); - fprintf(stderr, "\n"); - if(delflg) + setsig(i, delex); + putc('\n', stderr); + if (delflg) longjmp(sjbuf, 1); done(); } -/* - * Lock the specified mail file by setting the file mailfile.lock. - * We must, of course, be careful to unlink the lock file by a call - * to unlock before we stop. The algorithm used here is to see if - * the lock exists, and if it does, to check its modify time. If it - * is older than 30 seconds, we assume error and set our own file. - * Otherwise, we wait for 5 seconds and try again. - */ - -char *maillock = ".lock"; /* Lock suffix for mailname */ -char *lockname = "/usr/spool/mail/tmXXXXXX"; -char locktmp[30]; /* Usable lock temporary */ -char curlock[50]; /* Last used name of lock */ -int locked; /* To note that we locked it */ - -lock(file) -char *file; -{ - register int f; - struct stat sbuf; - long curtime; - int statfailed; - - if (locked || flgf) - return(0); - strcpy(curlock, file); - strcat(curlock, maillock); - strcpy(locktmp, lockname); - mktemp(locktmp); - unlink(locktmp); - statfailed = 0; - for (;;) { - f = lock1(locktmp, curlock); - if (f == 0) { - locked = 1; - return(0); - } - if (stat(curlock, &sbuf) < 0) { - if (statfailed++ > 5) - return(-1); - sleep(5); - continue; - } - statfailed = 0; - time(&curtime); - if (curtime < sbuf.st_ctime + 30) { - sleep(5); - continue; - } - unlink(curlock); - } -} - -/* - * Remove the mail lock, and note that we no longer - * have it locked. - */ - -unlock() -{ - - unlink(curlock); - locked = 0; -} - -/* - * Attempt to set the lock by creating the temporary file, - * then doing a link/unlink. If it fails, return -1 else 0 - */ - -lock1(tempfile, name) - char tempfile[], name[]; -{ - register int fd; - - fd = creat(tempfile, 0); - if (fd < 0) - return(-1); - close(fd); - if (link(tempfile, name) < 0) { - unlink(tempfile); - return(-1); - } - unlink(tempfile); - return(0); -} - done() { - if(locked) - unlock(); + unlink(lettmp); - unlink(locktmp); exit(error); } cat(to, from1, from2) -char *to, *from1, *from2; + char *to, *from1, *from2; { - int i, j; - - j = 0; - for (i=0; from1[i]; i++) - to[j++] = from1[i]; - for (i=0; from2[i]; i++) - to[j++] = from2[i]; - to[j] = 0; + register char *cp, *dp; + + cp = to; + for (dp = from1; *cp = *dp++; cp++) + ; + for (dp = from2; *cp++ = *dp++; ) + ; } -char *getarg(s, p) /* copy p... into s, update p */ -register char *s, *p; +/* copy p... into s, update p */ +char * +getarg(s, p) + register char *s, *p; { while (*p == ' ' || *p == '\t') p++; @@ -814,8 +722,20 @@ safefile(f) if (lstat(f, &statb) < 0) return (1); if (statb.st_nlink != 1 || (statb.st_mode & S_IFMT) == S_IFLNK) { - fprintf(stderr, "mail: %s has more than one link or is a symbolic link\n", f); + fprintf(stderr, + "mail: %s has more than one link or is a symbolic link\n", + f); return (0); } return (1); } + +panic(msg, a1, a2, a3) + char *msg; +{ + + fprintf(stderr, "mail: "); + fprintf(stderr, msg, a1, a2, a3); + fprintf(stderr, "\n"); + done(); +} diff --git a/usr/src/usr.bin/mail/Makefile b/usr/src/usr.bin/mail/Makefile index 75557e113c..2d035c6889 100644 --- a/usr/src/usr.bin/mail/Makefile +++ b/usr/src/usr.bin/mail/Makefile @@ -1,4 +1,4 @@ -# Makefile 2.15 83/08/18 +# Makefile 2.16 84/07/19 # # Berkeley Mail # @@ -17,11 +17,11 @@ AS= -as RM= -rm OBJS= version.o aux.o cmd1.o cmd2.o cmd3.o cmdtab.o collect.o \ config.o edit.o fio.o \ - getname.o head.o v7.local.o lock.o lex.o list.o main.o \ + getname.o head.o v7.local.o lex.o list.o main.o \ names.o optim.o popen.o quit.o send.o strings.o temp.o tty.o \ vars.o str.o SRCS= aux.c cmd1.c cmd2.c cmd3.c cmdtab.c collect.c config.c edit.c fio.c \ - getname.c head.c v7.local.c lock.c lex.c list.c main.c \ + getname.c head.c v7.local.c lex.c list.c main.c \ names.c optim.c popen.c quit.c send.c strings.c temp.c tty.c vars.c \ version.c HDRS= rcv.h configdefs.h def.h glob.h v7.local.h local.h diff --git a/usr/src/usr.bin/mail/collect.c b/usr/src/usr.bin/mail/collect.c index 267ae743e3..4708f00d51 100644 --- a/usr/src/usr.bin/mail/collect.c +++ b/usr/src/usr.bin/mail/collect.c @@ -1,5 +1,5 @@ #ifndef lint -static char sccsid[] = "@(#)collect.c 2.15 (Berkeley) %G%"; +static char sccsid[] = "@(#)collect.c 2.16 (Berkeley) %G%"; #endif /* @@ -48,6 +48,7 @@ collect(hp) extern char tempMail[]; int notify(); extern collintsig(), collhupsig(); + char getsub; noreset++; ibuf = obuf = NULL; @@ -89,15 +90,13 @@ collect(hp) */ t = GTO|GSUBJECT|GCC|GNL; - c = 0; + getsub = 0; if (intty && sflag == NOSTR && hp->h_subject == NOSTR && value("ask")) - t &= ~GNL, c++; + t &= ~GNL, getsub++; if (hp->h_seq != 0) { puthead(hp, stdout, t); fflush(stdout); } - if (c) - grabh(hp, GSUBJECT); escape = ESCAPE; if ((cp = value("escape")) != NOSTR) escape = *cp; @@ -115,6 +114,11 @@ collect(hp) signal(SIGHUP, collhupsig); # endif VMUNIX flush(); + if (getsub) { + grabh(hp, GSUBJECT); + getsub = 0; + continue; + } if (readline(stdin, linebuf) <= 0) { if (intty && value("ignoreeof") != NOSTR) { if (++eof > 35) @@ -390,7 +394,6 @@ collect(hp) ibuf = newi; printf("(continue)\n"); break; - break; } } eofl: diff --git a/usr/src/usr.bin/mail/getname.c b/usr/src/usr.bin/mail/getname.c index 1f6186458a..2c1a9b8bf1 100644 --- a/usr/src/usr.bin/mail/getname.c +++ b/usr/src/usr.bin/mail/getname.c @@ -1,23 +1,16 @@ #ifndef lint -static char sccsid[] = "@(#)getname.c 2.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)getname.c 2.3 (Berkeley) %G%"; #endif +#include /* - * Getname / getuserid for those with no + * Getname / getuserid for those with * hashed passwd data base). - * Do not compile this module in if you DO have hashed - * passwd's -- this is slower. * - * Also provided here is a getpw routine which can share - * the open file. This is used for the Version 6 getenv - * implementation. */ #include "rcv.h" -static FILE *pwfile = NULL; /* Pw file held open */ -static char *pwname = "/etc/passwd"; /* Name of passwd file */ - /* * Search the passwd file for a uid. Return name through ref parameter * if found, indicating success with 0 return. Return -1 on error. @@ -27,86 +20,15 @@ static char *pwname = "/etc/passwd"; /* Name of passwd file */ getname(uid, namebuf) char namebuf[]; { - register char *cp, *cp2; - char linebuf[BUFSIZ]; - - if (uid == -1) { - if (pwfile != NULL) - fclose(pwfile); - pwfile = NULL; - return(0); - } - if (pwfile == NULL && (pwfile = fopen(pwname, "r")) == NULL) - return(-1); - rewind(pwfile); - while (fgets(linebuf, BUFSIZ, pwfile) != NULL) - if (pweval(linebuf) == uid) { - for (cp = linebuf, cp2 = namebuf; *cp != ':'; - *cp2++ = *cp++) - ; - *cp2 = '\0'; - return(0); - } - return(-1); -} - -/* - * Read the users password file line into the passed line - * buffer. - */ - -getpw(uid, linebuf) - char linebuf[]; -{ - register char *cp, *cp2; + struct passwd *pw; if (uid == -1) { - if (pwfile != NULL) - fclose(pwfile); - pwfile = NULL; - return(0); - } - if (pwfile == NULL && (pwfile = fopen(pwname, "r")) == NULL) - return(-1); - rewind(pwfile); - while (fgets(linebuf, BUFSIZ, pwfile) != NULL) - if (pweval(linebuf) == uid) { - if (linebuf[0] != '\0') - linebuf[strlen(linebuf)-1] = '\0'; - return(0); - } - return(-1); -} - -/* - * Look for passwd line belonging to 'name' - */ - -getpwnam(name, linebuf) - char name[], linebuf[]; -{ - register char *cp, *cp2; - - if (name == NOSTR) { - if (pwfile != NULL) - fclose(pwfile); - pwfile = NULL; return(0); } - if (pwfile == NULL && (pwfile = fopen(pwname, "r")) == NULL) { - perror(pwname); + if ((pw = getpwuid(uid)) == NULL) return(-1); - } - rewind(pwfile); - while (fgets(linebuf, BUFSIZ, pwfile) != NULL) { - cp = linebuf; - cp2 = name; - while (*cp2++ == *cp++) - ; - if (*--cp == ':' && *--cp2 == 0) - return(0); - } - return(-1); + strcpy(namebuf, pw->pw_name); + return 0; } /* @@ -117,49 +39,12 @@ getpwnam(name, linebuf) getuserid(name) char name[]; { - register char *cp, *cp2; - char linebuf[BUFSIZ]; + struct passwd *pw; if (name == (char *) -1) { - if (pwfile != NULL) - fclose(pwfile); - pwfile = NULL; return(0); } - if (pwfile == NULL && (pwfile = fopen(pwname, "r")) == NULL) - return(-1); - rewind(pwfile); - while (fgets(linebuf, BUFSIZ, pwfile) != NULL) { - for (cp = name, cp2 = linebuf; *cp++ == *cp2++;) - ; - if (*--cp == '\0' && *--cp2 == ':') - return(pweval(linebuf)); - } - return(-1); -} - -/* - * Evaluate the user id of the passed passwd line and return it. - */ - -static -pweval(line) - char line[]; -{ - register char *cp; - register int i; - register int uid; - - for (cp = line, i = 0; i < 2; i += (*cp++ == ':')) - ; - uid = atoi(cp); - -#ifdef UIDGID - while (*cp && *cp != ':') - cp++; - cp++; - uid |= atoi(cp) << 8; -#endif - - return(uid); + if ((pw = getpwnam(name)) == NULL) + return 0; + return pw->pw_uid; } diff --git a/usr/src/usr.bin/mail/main.c b/usr/src/usr.bin/mail/main.c index e1526ad2fb..bba5c0b1fe 100644 --- a/usr/src/usr.bin/mail/main.c +++ b/usr/src/usr.bin/mail/main.c @@ -1,5 +1,5 @@ #ifndef lint -static char sccsid[] = "@(#)main.c 2.12 (Berkeley) %G%"; +static char sccsid[] = "@(#)main.c 2.13 (Berkeley) %G%"; #endif #include "rcv.h" @@ -31,7 +31,6 @@ main(argc, argv) register int i, argp; int mustsend, uflag, hdrstop(), (*prevint)(), f; FILE *ibuf, *ftat; - extern char _sobuf[]; struct sgttyb tbuf; #ifdef signal @@ -60,7 +59,6 @@ main(argc, argv) else baud = B9600; image = -1; - setbuf(stdout, _sobuf); /* * Now, determine how we are being used. diff --git a/usr/src/usr.bin/mail/quit.c b/usr/src/usr.bin/mail/quit.c index f2b2e8dd17..16076a4cb6 100644 --- a/usr/src/usr.bin/mail/quit.c +++ b/usr/src/usr.bin/mail/quit.c @@ -1,9 +1,10 @@ #ifndef lint -static char sccsid[] = "@(#)quit.c 2.7 (Berkeley) %G%"; +static char sccsid[] = "@(#)quit.c 2.8 (Berkeley) %G%"; #endif #include "rcv.h" #include +#include /* * Rcv -- receive mail rationally. @@ -20,7 +21,7 @@ static char sccsid[] = "@(#)quit.c 2.7 (Berkeley) %G%"; quit() { int mcount, p, modify, autohold, anystat, holdbit, nohold; - FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat; + FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf; register struct message *mp; register int c; extern char tempQuit[], tempResid[]; @@ -47,19 +48,21 @@ quit() * anything with the mailbox, unless mail locking works. */ - lock(mailname); + fbuf = fopen(mailname, "r"); + if (fbuf == NULL) + goto newmail; + flock(fileno(fbuf), LOCK_EX); #ifndef CANLOCK if (selfsent) { printf("You have new mail.\n"); - unlock(); + fclose(fbuf); return; } #endif rbuf = NULL; - if (stat(mailname, &minfo) >= 0 && minfo.st_size > mailsize) { + if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) { printf("New mail has arrived.\n"); rbuf = fopen(tempResid, "w"); - fbuf = fopen(mailname, "r"); if (rbuf == NULL || fbuf == NULL) goto newmail; #ifdef APPEND @@ -75,7 +78,6 @@ quit() putc(c, rbuf); } #endif - fclose(fbuf); fclose(rbuf); if ((rbuf = fopen(tempResid, "r")) == NULL) goto newmail; @@ -129,13 +131,13 @@ quit() printf("Held 1 message in %s\n", mailname); else printf("Held %2d messages in %s\n", p, mailname); - unlock(); + fclose(fbuf); return; } if (c == 0) { if (p != 0) { writeback(rbuf); - unlock(); + fclose(fbuf); return; } goto cream; @@ -152,27 +154,27 @@ quit() if (value("append") == NOSTR) { if ((obuf = fopen(tempQuit, "w")) == NULL) { perror(tempQuit); - unlock(); + fclose(fbuf); return; } if ((ibuf = fopen(tempQuit, "r")) == NULL) { perror(tempQuit); remove(tempQuit); fclose(obuf); - unlock(); + fclose(fbuf); return; } remove(tempQuit); - if ((fbuf = fopen(mbox, "r")) != NULL) { - while ((c = getc(fbuf)) != EOF) + if ((abuf = fopen(mbox, "r")) != NULL) { + while ((c = getc(abuf)) != EOF) putc(c, obuf); - fclose(fbuf); + fclose(abuf); } if (ferror(obuf)) { perror(tempQuit); fclose(ibuf); fclose(obuf); - unlock(); + fclose(fbuf); return; } fclose(obuf); @@ -180,14 +182,14 @@ quit() if ((obuf = fopen(mbox, "r+")) == NULL) { perror(mbox); fclose(ibuf); - unlock(); + fclose(fbuf); return; } } if (value("append") != NOSTR) if ((obuf = fopen(mbox, "a")) == NULL) { perror(mbox); - unlock(); + fclose(fbuf); return; } for (mp = &message[0]; mp < &message[msgCount]; mp++) @@ -196,7 +198,7 @@ quit() perror(mbox); fclose(ibuf); fclose(obuf); - unlock(); + fclose(fbuf); return; } @@ -222,7 +224,7 @@ quit() if (ferror(obuf)) { perror(mbox); fclose(obuf); - unlock(); + fclose(fbuf); return; } fclose(obuf); @@ -238,7 +240,7 @@ quit() if (p != 0) { writeback(rbuf); - unlock(); + fclose(fbuf); return; } @@ -249,25 +251,25 @@ quit() cream: if (rbuf != NULL) { - fbuf = fopen(mailname, "r+"); - if (fbuf == NULL) + abuf = fopen(mailname, "r+"); + if (abuf == NULL) goto newmail; while ((c = getc(rbuf)) != EOF) - putc(c, fbuf); + putc(c, abuf); fclose(rbuf); - trunc(fbuf); - fclose(fbuf); + trunc(abuf); + fclose(abuf); alter(mailname); - unlock(); + fclose(fbuf); return; } demail(); - unlock(); + fclose(fbuf); return; newmail: printf("Thou hast new mail.\n"); - unlock(); + fclose(fbuf); } /* -- 2.20.1