diff -urN mailx-8.1.1.orig/Makefile mailx-8.1.1/Makefile --- mailx-8.1.1.orig/Makefile 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/Makefile 2003-03-26 13:03:39.000000000 -0800 @@ -1,38 +1,45 @@ -# $OpenBSD: Makefile,v 1.8 1997/09/21 11:49:50 deraadt Exp $ +# $OpenBSD: Makefile,v 1.8 1996/06/08 19:48:09 christos Exp $ +# $NetBSD: Makefile,v 1.8 1996/06/08 19:48:09 christos Exp $ PROG= mail +CC=gcc + +# use second line starting from hamm release +#CPPFLAGS=-I/usr/include/bsd -D_BSD_SOURCE -DIOSAFE +CPPFLAGS=-D_BSD_SOURCE + +CFLAGS=-g SRCS= version.c aux.c cmd1.c cmd2.c cmd3.c cmdtab.c collect.c \ edit.c fio.c getname.c head.c v7.local.c lex.c list.c main.c names.c \ popen.c quit.c send.c strings.c temp.c tty.c vars.c -SFILES= mail.help mail.tildehelp -EFILES= mail.rc -LINKS= ${BINDIR}/mail ${BINDIR}/Mail ${BINDIR}/mail ${BINDIR}/mailx -MLINKS= mail.1 Mail.1 mail.1 mailx.1 - -CC=gcc OBJS=$(SRCS:%.c=%.o) LIBS=-llockfile -default: all +SFILES= mail.help mail.tildehelp +EFILES= mail.rc +LINKS= ${BINDIR}/mail ${BINDIR}/Mail ${BINDIR}/mail ${BINDIR}/mailx +MFILES= mail.1 -all: $(PROG) +default: all -$(PROG): $(OBJS) + all: $(PROG) + + $(PROG): $(OBJS) $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJS) $(LIBS) - -.c.o: + + .c.o: $(CC) $(CPPFLAGS) $(CFLAGS) -c $< - -.y.c: + + .y.c: bison $< mv -f $*.tab.c $@ - -clean: + + clean: rm -f $(PROG) *.o *~ - -install: - install -c -m 755 -o root -g mail -s $(PROG) $(DESTDIR)/bin/ - install -c -m 644 $(MFILES) $(DESTDIR)/usr/share/man/man1/ + + install: + install -c -m 755 -o root -g mail -s $(PROG) $(DESTDIR)/usr/bin/ + install -c -m 644 $(MFILES) $(DESTDIR)/usr/man/man1/ cd misc && install -c -m 644 $(EFILES) $(DESTDIR)/etc/ cd misc && install -c -m 644 $(SFILES) $(DESTDIR)/usr/lib/ diff -urN mailx-8.1.1.orig/USD.doc/Makefile mailx-8.1.1/USD.doc/Makefile --- mailx-8.1.1.orig/USD.doc/Makefile 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/Makefile 2003-03-26 13:03:39.000000000 -0800 @@ -1,12 +1,13 @@ -# $OpenBSD: Makefile,v 1.3 1997/07/13 23:35:48 millert Exp $ -# @(#)Makefile 8.1 (Berkeley) 6/8/93 +# $OpenBSD: Makefile,v 1.1 1994/06/29 05:09:54 deraadt Exp $ DIR= usd/07.mail SRCS= mail0.nr mail1.nr mail2.nr mail3.nr mail4.nr mail5.nr mail6.nr \ mail7.nr mail8.nr mail9.nr maila.nr MACROS= -me +TBL=tbl +manual.ps: ${SRCS} + ${TBL} ${SRCS} | groff ${MACROS} -Tps > $@ -paper.ps: ${SRCS} - ${TBL} ${SRCS} | ${ROFF} > ${.TARGET} +clean : + -rm manual.ps -.include diff -urN mailx-8.1.1.orig/USD.doc/mail0.nr mailx-8.1.1/USD.doc/mail0.nr --- mailx-8.1.1.orig/USD.doc/mail0.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail0.nr 1996-06-14 01:27:10.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail0.nr,v 1.2 1996/06/11 12:54:18 deraadt Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. diff -urN mailx-8.1.1.orig/USD.doc/mail1.nr mailx-8.1.1/USD.doc/mail1.nr --- mailx-8.1.1.orig/USD.doc/mail1.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail1.nr 1996-06-14 01:27:10.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail1.nr,v 1.2 1996/06/11 12:54:18 deraadt Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. diff -urN mailx-8.1.1.orig/USD.doc/mail2.nr mailx-8.1.1/USD.doc/mail2.nr --- mailx-8.1.1.orig/USD.doc/mail2.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail2.nr 1996-06-14 01:27:12.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail2.nr,v 1.3 1997/07/13 23:35:49 millert Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,8 +31,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)mail2.nr 8.2 (Berkeley) 5/16/94 +.\" @(#)mail2.nr 8.1 (Berkeley) 6/8/93 .\" +.bp .sh 1 "Common usage" .pp The diff -urN mailx-8.1.1.orig/USD.doc/mail3.nr mailx-8.1.1/USD.doc/mail3.nr --- mailx-8.1.1.orig/USD.doc/mail3.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail3.nr 1996-06-14 01:27:12.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail3.nr,v 1.2 1996/06/11 12:54:20 deraadt Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. diff -urN mailx-8.1.1.orig/USD.doc/mail4.nr mailx-8.1.1/USD.doc/mail4.nr --- mailx-8.1.1.orig/USD.doc/mail4.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail4.nr 1996-06-14 01:27:13.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail4.nr,v 1.3 1997/07/13 23:35:49 millert Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,8 +31,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)mail4.nr 8.2 (Berkeley) 5/16/94 +.\" @(#)mail4.nr 8.1 (Berkeley) 6/8/93 .\" +.bp .sh 1 "More about sending mail" .sh 2 "Tilde escapes" .pp diff -urN mailx-8.1.1.orig/USD.doc/mail5.nr mailx-8.1.1/USD.doc/mail5.nr --- mailx-8.1.1.orig/USD.doc/mail5.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail5.nr 1996-06-14 01:27:16.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail5.nr,v 1.3 1997/07/13 23:35:50 millert Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,8 +31,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)mail5.nr 8.2 (Berkeley) 5/16/94 +.\" @(#)mail5.nr 8.1 (Berkeley) 6/8/93 .\" +.bp .sh 1 "Additional features" .pp This section describes some additional commands useful for diff -urN mailx-8.1.1.orig/USD.doc/mail6.nr mailx-8.1.1/USD.doc/mail6.nr --- mailx-8.1.1.orig/USD.doc/mail6.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail6.nr 1996-06-14 01:27:17.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail6.nr,v 1.3 1997/07/13 23:35:50 millert Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,8 +31,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)mail6.nr 8.2 (Berkeley) 5/16/94 +.\" @(#)mail6.nr 8.1 (Berkeley) 6/8/93 .\" +.bp .sh 1 "Command line options" .pp This section describes command line options for diff -urN mailx-8.1.1.orig/USD.doc/mail7.nr mailx-8.1.1/USD.doc/mail7.nr --- mailx-8.1.1.orig/USD.doc/mail7.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail7.nr 1996-06-14 01:27:17.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail7.nr,v 1.2 1996/06/11 12:54:23 deraadt Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. diff -urN mailx-8.1.1.orig/USD.doc/mail8.nr mailx-8.1.1/USD.doc/mail8.nr --- mailx-8.1.1.orig/USD.doc/mail8.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail8.nr 1996-06-14 01:27:17.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail8.nr,v 1.3 1997/07/13 23:35:51 millert Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,8 +31,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)mail8.nr 8.2 (Berkeley) 5/16/94 +.\" @(#)mail8.nr 8.1 (Berkeley) 6/8/93 .\" +.bp .sh 1 "Glossary" .pp This section contains the definitions of a few phrases diff -urN mailx-8.1.1.orig/USD.doc/mail9.nr mailx-8.1.1/USD.doc/mail9.nr --- mailx-8.1.1.orig/USD.doc/mail9.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/mail9.nr 1996-06-14 01:27:17.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mail9.nr,v 1.3 1997/07/13 23:35:51 millert Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,8 +31,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)mail9.nr 8.2 (Berkeley) 5/16/94 +.\" @(#)mail9.nr 8.1 (Berkeley) 6/8/93 .\" +.bp .sh 1 "Summary of commands, options, and escapes" .pp This section gives a quick summary of the @@ -100,6 +101,7 @@ xit Same as \fBexit\fP z Scroll to next/previous screenful of headers .TE +.bp .(b .pp The following table describes the options. Each option is diff -urN mailx-8.1.1.orig/USD.doc/maila.nr mailx-8.1.1/USD.doc/maila.nr --- mailx-8.1.1.orig/USD.doc/maila.nr 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/USD.doc/maila.nr 1996-06-14 01:27:17.000000000 -0700 @@ -1,4 +1,4 @@ -.\" $OpenBSD: maila.nr,v 1.2 1996/06/11 12:54:25 deraadt Exp $ +.\" $OpenBSD$ .\" .\" Copyright (c) 1980, 1993 .\" The Regents of the University of California. All rights reserved. diff -urN mailx-8.1.1.orig/aux.c mailx-8.1.1/aux.c --- mailx-8.1.1.orig/aux.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/aux.c 2003-03-26 13:03:39.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: aux.c,v 1.20 2001/11/21 15:26:39 millert Exp $ */ -/* $NetBSD: aux.c,v 1.5 1997/05/13 06:15:52 mikel Exp $ */ +/* $OpenBSD: aux.c,v 1.4 1996/06/08 19:48:10 christos Exp $ */ +/* $NetBSD: aux.c,v 1.4 1996/06/08 19:48:10 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)aux.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)aux.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: aux.c,v 1.20 2001/11/21 15:26:39 millert Exp $"; +static char rcsid[] = "$OpenBSD: aux.c,v 1.4 1996/06/08 19:48:10 christos Exp $"; #endif #endif /* not lint */ @@ -50,40 +50,74 @@ * * Auxiliary functions. */ -static char *save2str(char *, char *); +static char *save2str __P((char *, char *)); /* * Return a pointer to a dynamic copy of the argument. */ char * -savestr(char *str) +savestr(str) + char *str; { char *new; int size = strlen(str) + 1; - if ((new = salloc(size)) != NULL) - (void)memcpy(new, str, size); - return(new); + if ((new = salloc(size)) != NOSTR) + bcopy(str, new, size); + return new; } /* * Make a copy of new argument incorporating old one. */ static char * -save2str(char *str, char *old) +save2str(str, old) + char *str, *old; { char *new; int newsize = strlen(str) + 1; int oldsize = old ? strlen(old) + 1 : 0; - if ((new = salloc(newsize + oldsize)) != NULL) { + if ((new = salloc(newsize + oldsize)) != NOSTR) { if (oldsize) { - (void)memcpy(new, old, oldsize); + bcopy(old, new, oldsize); new[oldsize - 1] = ' '; } - (void)memcpy(new + oldsize, str, newsize); + bcopy(str, new + oldsize, newsize); } - return(new); + return new; +} + +/* + * Announce a fatal error and die. + */ +#if __STDC__ +#include +#else +#include +#endif + +void +#if __STDC__ +panic(const char *fmt, ...) +#else +panic(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)fprintf(stderr, "panic: "); + vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + fflush(stderr); + abort(); } /* @@ -92,7 +126,8 @@ * back to the system mailbox on exit. */ void -touch(struct message *mp) +touch(mp) + register struct message *mp; { mp->m_flag |= MTOUCH; @@ -105,53 +140,57 @@ * Return true if it is. */ int -isdir(char *name) +isdir(name) + char name[]; { struct stat sbuf; if (stat(name, &sbuf) < 0) return(0); - return(S_ISDIR(sbuf.st_mode)); + return((sbuf.st_mode & S_IFMT) == S_IFDIR); } /* * Count the number of arguments in the given string raw list. */ int -argcount(char **argv) +argcount(argv) + char **argv; { - char **ap; + register char **ap; - for (ap = argv; *ap++ != NULL;) + for (ap = argv; *ap++ != NOSTR;) ; - return(ap - argv - 1); + return ap - argv - 1; } /* * Return the desired header line from the passed message - * pointer (or NULL if the desired header field is not available). + * pointer (or NOSTR if the desired header field is not available). */ char * -hfield(char *field, struct message *mp) +hfield(field, mp) + char field[]; + struct message *mp; { - FILE *ibuf; + register FILE *ibuf; char linebuf[LINESIZE]; - int lc; - char *hfield; - char *colon, *oldhfield = NULL; + register int lc; + register char *hfield; + char *colon, *oldhfield = NOSTR; ibuf = setinput(mp); if ((lc = mp->m_lines - 1) < 0) - return(NULL); - if (readline(ibuf, linebuf, LINESIZE, NULL) < 0) - return(NULL); + return NOSTR; + if (readline(ibuf, linebuf, LINESIZE) < 0) + return NOSTR; while (lc > 0) { if ((lc = gethfield(ibuf, linebuf, lc, &colon)) < 0) - return(oldhfield); + return oldhfield; if ((hfield = ishfield(linebuf, colon, field)) != NULL) oldhfield = save2str(hfield, oldhfield); } - return(oldhfield); + return oldhfield; } /* @@ -161,17 +200,21 @@ * Must deal with \ continuations & other such fraud. */ int -gethfield(FILE *f, char *linebuf, int rem, char **colon) +gethfield(f, linebuf, rem, colon) + register FILE *f; + char linebuf[]; + register int rem; + char **colon; { char line2[LINESIZE]; - char *cp, *cp2; - int c; + register char *cp, *cp2; + register int c; for (;;) { if (--rem < 0) - return(-1); - if ((c = readline(f, linebuf, LINESIZE, NULL)) <= 0) - return(-1); + return -1; + if ((c = readline(f, linebuf, LINESIZE)) <= 0) + return -1; for (cp = linebuf; isprint(*cp) && *cp != ' ' && *cp != ':'; cp++) ; @@ -192,7 +235,7 @@ ungetc(c = getc(f), f); if (c != ' ' && c != '\t') break; - if ((c = readline(f, line2, LINESIZE, NULL)) < 0) + if ((c = readline(f, line2, LINESIZE)) < 0) break; rem--; for (cp2 = line2; *cp2 == ' ' || *cp2 == '\t'; cp2++) @@ -201,11 +244,11 @@ if (cp + c >= linebuf + LINESIZE - 2) break; *cp++ = ' '; - (void)memcpy(cp, cp2, c); + bcopy(cp2, cp, c); cp += c; } *cp = 0; - return(rem); + return rem; } /* NOTREACHED */ } @@ -216,51 +259,43 @@ */ char* -ishfield(char *linebuf, char *colon, char *field) +ishfield(linebuf, colon, field) + char linebuf[], field[]; + char *colon; { - char *cp = colon; + register char *cp = colon; *cp = 0; if (strcasecmp(linebuf, field) != 0) { *cp = ':'; - return(0); + return 0; } *cp = ':'; for (cp++; *cp == ' ' || *cp == '\t'; cp++) ; - return(cp); + return cp; } /* - * Copy a string, lowercasing it as we go. ``dsize'' should be - * the real size (not len) of the dest string (guarantee NUL term). + * Copy a string, lowercasing it as we go. */ -size_t -istrcpy(char *dst, const char *src, size_t dsize) -{ - char *d = dst; - const char *s = src; - size_t n = dsize; - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) { - do { - if (isupper(*s)) - *d++ = tolower(*s++); - else if ((*d++ = *s++) == 0) - break; - } while (--n != 0); - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (dsize != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; +void +istrcpy(dest, src, size) + register char *dest, *src; + int size; +{ + register char *max; + + max=dest+size-1; + while (dest<=max) { + if (isupper(*src)) { + *dest++ = tolower(*src); + } else { + *dest++ = *src; + } + if (*src++ == 0) + break; } - - return(s - src - 1); /* count does not include NUL */ } /* @@ -268,6 +303,7 @@ * commands. All but the current file pointer are saved on * the stack. */ + static int ssp; /* Top of file stack */ struct sstack { FILE *s_file; /* File we were in. */ @@ -281,21 +317,22 @@ * that they are no longer reading from a tty (in all probability). */ int -source(void *v) +source(v) + void *v; { char **arglist = v; FILE *fi; char *cp; - if ((cp = expand(*arglist)) == NULL) + if ((cp = expand(*arglist)) == NOSTR) return(1); if ((fi = Fopen(cp, "r")) == NULL) { - warn("%s", cp); + perror(cp); return(1); } if (ssp >= NOFILE - 1) { - puts("Too much \"sourcing\" going on."); - (void)Fclose(fi); + printf("Too much \"sourcing\" going on.\n"); + Fclose(fi); return(1); } sstack[ssp].s_file = input; @@ -314,17 +351,16 @@ * Update the "sourcing" flag as appropriate. */ int -unstack(void) +unstack() { - if (ssp <= 0) { - puts("\"Source\" stack over-pop."); + printf("\"Source\" stack over-pop.\n"); sourcing = 0; return(1); } - (void)Fclose(input); + Fclose(input); if (cond != CANY) - puts("Unmatched \"if\""); + printf("Unmatched \"if\"\n"); ssp--; cond = sstack[ssp].s_cond; loading = sstack[ssp].s_loading; @@ -339,20 +375,17 @@ * This is nifty for the shell. */ void -alter(char *name) +alter(name) + char *name; { struct stat sb; struct timeval tv[2]; if (stat(name, &sb)) return; - (void) gettimeofday(&tv[0], (struct timezone *)0); - tv[0].tv_sec++; -#ifdef TIMESPEC_TO_TIMEVAL - TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec); -#else + tv[0].tv_sec = time((time_t *)0) + 1; tv[1].tv_sec = sb.st_mtime; -#endif + tv[0].tv_usec = tv[1].tv_usec = 0; (void)utimes(name, tv); } @@ -361,9 +394,10 @@ * return true if it is all blanks and tabs. */ int -blankline(char *linebuf) +blankline(linebuf) + char linebuf[]; { - char *cp; + register char *cp; for (cp = linebuf; *cp; cp++) if (*cp != ' ' && *cp != '\t') @@ -377,14 +411,16 @@ * before returning it. */ char * -nameof(struct message *mp, int reptype) +nameof(mp, reptype) + register struct message *mp; + int reptype; { - char *cp, *cp2; + register char *cp, *cp2; cp = skin(name1(mp, reptype)); if (reptype != 0 || charcount(cp, '!') < 2) return(cp); - cp2 = strrchr(cp, '!'); + cp2 = rindex(cp, '!'); cp2--; while (cp2 > cp && *cp2 != '!') cp2--; @@ -398,9 +434,10 @@ * Ignore it. */ char * -skip_comment(char *cp) +skip_comment(cp) + register char *cp; { - int nesting = 1; + register nesting = 1; for (; nesting > 0 && *cp; cp++) { switch (*cp) { @@ -416,7 +453,7 @@ break; } } - return(cp); + return cp; } /* @@ -424,20 +461,20 @@ * of "host-phrase." */ char * -skin(char *name) +skin(name) + char *name; { - char *nbuf, *bufend, *cp, *cp2; - int c, gotlt, lastsp; - - if (name == NULL) - return(NULL); - if (strchr(name, '(') == NULL && strchr(name, '<') == NULL - && strchr(name, ' ') == NULL) + register int c; + register char *cp, *cp2; + char *bufend; + int gotlt, lastsp; + char nbuf[BUFSIZ]; + + if (name == NOSTR) + return(NOSTR); + if (index(name, '(') == NOSTR && index(name, '<') == NOSTR + && index(name, ' ') == NOSTR) return(name); - - /* We assume that length(input) <= length(output) */ - if ((nbuf = (char *)malloc(strlen(name) + 1)) == NULL) - errx(1, "Out of memory"); gotlt = 0; lastsp = 0; bufend = nbuf; @@ -510,9 +547,9 @@ *cp2++ = ' '; } *cp2++ = c; - if (c == ',' && *cp == ' ' && !gotlt) { + if (c == ',' && !gotlt) { *cp2++ = ' '; - while (*++cp == ' ') + for (; *cp == ' '; cp++) ; lastsp = 0; bufend = cp2; @@ -521,9 +558,7 @@ } *cp2 = 0; - if ((cp = (char *)realloc(nbuf, strlen(nbuf) + 1)) != NULL) - nbuf = cp; - return(nbuf); + return(savestr(nbuf)); } /* @@ -534,21 +569,23 @@ * 2 -- get sender's name for Reply */ char * -name1(struct message *mp, int reptype) +name1(mp, reptype) + register struct message *mp; + int reptype; { char namebuf[LINESIZE]; char linebuf[LINESIZE]; - char *cp, *cp2; - FILE *ibuf; + register char *cp, *cp2; + register FILE *ibuf; int first = 1; - if ((cp = hfield("from", mp)) != NULL) - return(cp); - if (reptype == 0 && (cp = hfield("sender", mp)) != NULL) - return(cp); + if ((cp = hfield("from", mp)) != NOSTR) + return cp; + if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR) + return cp; ibuf = setinput(mp); - namebuf[0] = '\0'; - if (readline(ibuf, linebuf, LINESIZE, NULL) < 0) + namebuf[0] = 0; + if (readline(ibuf, linebuf, LINESIZE) < 0) return(savestr(namebuf)); newname: for (cp = linebuf; *cp && *cp != ' '; cp++) @@ -559,27 +596,29 @@ *cp && *cp != ' ' && *cp != '\t' && cp2 < namebuf + LINESIZE - 1;) *cp2++ = *cp++; *cp2 = '\0'; - if (readline(ibuf, linebuf, LINESIZE, NULL) < 0) + if (readline(ibuf, linebuf, LINESIZE) < 0) return(savestr(namebuf)); - if ((cp = strchr(linebuf, 'F')) == NULL) + if ((cp = index(linebuf, 'F')) == NULL) return(savestr(namebuf)); if (strncmp(cp, "From", 4) != 0) return(savestr(namebuf)); - while ((cp = strchr(cp, 'r')) != NULL) { + while ((cp = index(cp, 'r')) != NULL) { if (strncmp(cp, "remote", 6) == 0) { - if ((cp = strchr(cp, 'f')) == NULL) + if ((cp = index(cp, 'f')) == NULL) break; if (strncmp(cp, "from", 4) != 0) break; - if ((cp = strchr(cp, ' ')) == NULL) + if ((cp = index(cp, ' ')) == NULL) break; cp++; if (first) { - cp2 = namebuf; + strncpy(namebuf, cp, LINESIZE); first = 0; - } else - cp2 = strrchr(namebuf, '!') + 1; - istrcpy(cp2, cp, sizeof(namebuf) - (cp2 - namebuf) - 1); + } else { + cp2=rindex(namebuf, '!')+1; + strncpy(cp2, cp, (namebuf+LINESIZE)-cp2); + } + namebuf[LINESIZE-2]='\0'; strcat(namebuf, "!"); goto newname; } @@ -592,10 +631,12 @@ * Count the occurances of c in str */ int -charcount(char *str, int c) +charcount(str, c) + char *str; + int c; { - char *cp; - int i; + register char *cp; + register int i; for (i = 0, cp = str; *cp; cp++) if (*cp == c) @@ -604,71 +645,79 @@ } /* + * Are any of the characters in the two strings the same? + */ +int +anyof(s1, s2) + register char *s1, *s2; +{ + + while (*s1) + if (index(s2, *s1++)) + return 1; + return 0; +} + +/* * Convert c to upper case */ int -raise(int c) +raise(c) + register int c; { if (islower(c)) - return(toupper(c)); - return(c); + return toupper(c); + return c; } /* * Copy s1 to s2, return pointer to null in s2. */ char * -copy(char *s1, char *s2) +copy(s1, s2) + register char *s1, *s2; { while ((*s2++ = *s1++) != '\0') ; - return(s2 - 1); + return s2 - 1; } /* * See if the given header field is supposed to be ignored. */ int -isign(char *field, struct ignoretab ignore[2]) +isign(field, ignore) + char *field; + struct ignoretab ignore[2]; { - char realfld[LINESIZE]; + char realfld[BUFSIZ]; if (ignore == ignoreall) - return(1); + return 1; /* * Lower-case the string, so that "Status" and "status" * will hash to the same place. */ - istrcpy(realfld, field, sizeof(realfld)); + istrcpy(realfld, field, BUFSIZ); + realfld[BUFSIZ-1]='\0'; if (ignore[1].i_count > 0) - return(!member(realfld, ignore + 1)); + return (!member(realfld, ignore + 1)); else - return(member(realfld, ignore)); + return (member(realfld, ignore)); } int -member(char *realfield, struct ignoretab *table) +member(realfield, table) + register char *realfield; + struct ignoretab *table; { - struct ignore *igp; + register struct ignore *igp; for (igp = table->i_head[hash(realfield)]; igp != 0; igp = igp->i_link) if (*igp->i_field == *realfield && equal(igp->i_field, realfield)) - return(1); - return(0); -} - -void -clearnew(void) -{ - struct message *mp; - - for (mp = &message[0]; mp < &message[msgCount]; mp++) { - if (mp->m_flag & MNEW) { - mp->m_flag &= ~MNEW; - mp->m_flag |= MSTATUS; - } - } + return (1); + return (0); } diff -urN mailx-8.1.1.orig/changelog mailx-8.1.1/changelog --- mailx-8.1.1.orig/changelog 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/changelog 2003-03-26 13:03:40.000000000 -0800 @@ -0,0 +1,159 @@ +mailx (1:8.1.1-10.1.3) frozen unstable; urgency=high + + * More security fixes + * Don't allow to set interactive in mailrc (or interactively) + * Modify the variable-handling code to grok NULL values + + -- Wichert Akkerman Mon, 7 Aug 2000 17:22:57 -0700 + +mailx (1:8.1.1-10.1.2) frozen unstable; urgency=high + + * Another security problem: refuse to get the interactive variable + from the environment by explicitly setting it in the hashtable. + + -- Wichert Akkerman Mon, 7 Aug 2000 12:36:10 -0700 + +mailx (1:8.1.1-10.1.1) frozen unstable; urgency=high + + * NMU to fix RC bug. Now accepts both /var/mail and /var/spool/mail as + allowed places for setgid file manipulation. fixes:#64238 + + -- Paul Slootman Thu, 8 Jun 2000 19:51:14 +0200 + +mailx (1:8.1.1-10.1) stable frozen unstable; urgency=high + + * Security fix for a GID=mail shell. + + -- Daniel Jacobowitz Sun, 4 Jun 2000 22:45:19 -0700 + +mailx (1:8.1.1-10) frozen unstable; urgency=high + + * correct major security flaw, patch from Alvaro Martinez Echevarria + , bug#23880, bug#23901 + + * other potential buffer overflow, patch from Juan-Mariano de Goyeneche + , bug #22937 + + + -- Loic Prylli Sun, 28 Jun 1998 20:15:18 -0400 + +mailx (1:8.1.1-9) frozen unstable; urgency=high + + * recompile without the signal handling workarounds (lo + that eliminate critical bugs where message parts can be lost + (#20798) and (#20558) + + -- Loic Prylli Thu, 9 Apr 1998 02:11:26 +0200 + +mailx (1:8.1.1-8) frozen unstable; urgency=high + + * previous patch broke most file accesses, corrected safe_open (#20634) + * try to check every access to Fopen, change "a" into "w" for new files, + to suit behaviour of safe_open. + + -- Loic Prylli Sat, 4 Apr 1998 22:01:19 +0200 + +mailx (1:8.1.1-7) frozen; urgency=medium + + * security fix for tmp races patch from Martin Schulze (#20059) + + -- Loic Prylli Mon, 23 Mar 1998 22:52:35 +0100 + +mailx (1:8.1.1-6) unstable; urgency=low + + * convert to debhelper + * changelog now compressed (bug#15431) + * removed .orig and .rej from source (bug#18409) + + -- Loic Prylli Sat, 14 Feb 1998 14:34:22 +0100 + +mailx (1:8.1.1-5) unstable; urgency=low + + * apply David Brown patch so mailx choose the right window size + (#12197) + * correct Depends: in control file. + + -- Loic Prylli Sat, 15 Nov 1997 00:30:38 +0100 + +mailx (1:8.1.1-4) unstable; urgency=high + + * mailx was sending empty message, ignoring user input + add clearerr when EAGAIN occur in "IOSAFE" code (#14263) + + -- Loic Prylli Tue, 11 Nov 1997 20:22:35 +0100 + +mailx (1:8.1.1-3.1) unstable; urgency=low + + * Non-maintainer release. + * Libc6 compile. (#11705) + * Install missing symlink to manpage. (#7274) + + -- Martin Mitchell Wed, 29 Oct 1997 04:34:39 +1100 + +mailx (1:8.1.1-3) unstable; urgency=low + + * add dpkg --assert-working-epoch in preinst bug#6850 + * add writing of pid in mailbox locking file + * fix:mailx was not removing temporary lock files + + -- Loic Prylli Sat, 1 Feb 1997 11:44:04 +0100 + +mailx (1:8.1.1-2) unstable; urgency=low + + * correct bug #2733 (occur when no space left) dans quit.c + * detection of From_ lines with tring to match the date bug#2010 + * corrected garble output bug #2284 + + -- Loic Prylli Sat, 28 Dec 1996 15:02:22 +0100 + +mailx (1:8.1.1-1) unstable; urgency=medium + + * recreate completely starting from OpenBSD mail version (we loose a lot + of extension but we have a working program now) + * OpenBSD base version is the last one in december 96 + * rechange the numbering of version, so epoch 1+8.1 is from 4.4BSD, the + last upstream digit is to change each time we update to a new openbsd + version. + * fix the problem of longjmp inside signals inside stdio calls + * reincorporate a patch to be dot file locking+setgid safe + * some fix in signal handling + + -- Loic Prylli Mon, 23 Dec 1996 01:57:44 +0100 + +Mon Apr 29 17:21:42 1996 Sven Rudolph + + * releasing 8.5.5-1 + + * added symlink /usr/bin/Mail -> /usr/bin/mailx + +Thu Apr 25 23:55:36 1996 Sven Rudolph + + * set version number to 8.5.5 because it has to superseed 8.1 + + * switched back to mailx-5.5-kw (see mailx-5.5-kw.diff.README) + + * no POP support + +mailx 8.1 Debian 5 - 10/19/95 Sven Rudolph +* uses now BSD signal emulation (/usr/include/bsd/signal.h) +* added virtual package names in Depends: and Provides fields (Bug#1460) +* added Section: field +* created symlink for mailx manpage (Bug#1114) + +mailx 8.1 Debian 4 - 5/20/95 Carl Streeter +* Added diffs from Delman Lee : + + Hi! I got mailx-8.1-3 from the Linux Debian distribution, and have + added a "hold-pop" option to hold messages on the POP server after + retrieving them. (Also fixed a minor bug with mailx thinking that there + is mail even if the POP mailbox is empty. Code around stat() below.) + +mailx 8.1 Debian 3 - 4/18/95 Carl Streeter +* Fixed control file to depend on smail|sendmail. Updated to latest + guidelines + + + +Local variables: +mode: debian-changelog +End: diff -urN mailx-8.1.1.orig/cmd1.c mailx-8.1.1/cmd1.c --- mailx-8.1.1.orig/cmd1.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/cmd1.c 2003-03-26 13:03:39.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: cmd1.c,v 1.22 2001/11/21 20:41:55 millert Exp $ */ -/* $NetBSD: cmd1.c,v 1.9 1997/07/09 05:29:48 mikel Exp $ */ +/* $OpenBSD: cmd1.c,v 1.5 1996/06/08 19:48:11 christos Exp $ */ +/* $NetBSD: cmd1.c,v 1.5 1996/06/08 19:48:11 christos Exp $ */ /*- * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)cmd1.c 8.2 (Berkeley) 4/20/95"; +static char sccsid[] = "@(#)cmd1.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: cmd1.c,v 1.22 2001/11/21 20:41:55 millert Exp $"; +static char rcsid[] = "$OpenBSD: cmd1.c,v 1.5 1996/06/08 19:48:11 christos Exp $"; #endif #endif /* not lint */ @@ -57,16 +57,15 @@ */ static int screen; -static volatile sig_atomic_t gothdrint; int -headers(void *v) +headers(v) + void *v; { int *msgvec = v; - int n, mesg, flag, size; - struct message *mp; - struct sigaction act, oact; - sigset_t oset; + register int n, mesg, flag; + register struct message *mp; + int size; size = screensize(); n = msgvec[0]; @@ -83,15 +82,7 @@ mesg = mp - &message[0]; if (dot != &message[n-1]) dot = mp; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - act.sa_handler = hdrint; - if (sigaction(SIGINT, NULL, &oact) == 0 && - oact.sa_handler != SIG_IGN) { - (void)sigaction(SIGINT, &act, &oact); - (void)sigprocmask(SIG_UNBLOCK, &intset, &oset); - } - for (gothdrint = 0; !gothdrint && mp < &message[msgCount]; mp++) { + for (; mp < &message[msgCount]; mp++) { mesg++; if (mp->m_flag & MDELETED) continue; @@ -99,16 +90,8 @@ break; printhead(mesg); } - if (gothdrint) { - fflush(stdout); - fputs("\nInterrupt\n", stderr); - } - if (oact.sa_handler != SIG_IGN) { - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void)sigaction(SIGINT, &oact, NULL); - } if (flag == 0) { - puts("No more mail."); + printf("No more mail.\n"); return(1); } return(0); @@ -118,31 +101,33 @@ * Scroll to the next/previous screen */ int -scroll(void *v) +scroll(v) + void *v; { char *arg = v; - int size, maxscreen; + register int s, size; int cur[1]; cur[0] = 0; size = screensize(); - maxscreen = (msgCount - 1) / size; + s = screen; switch (*arg) { case 0: case '+': - if (screen >= maxscreen) { - puts("On last screenful of messages"); + s++; + if (s * size > msgCount) { + printf("On last screenful of messages\n"); return(0); } - screen++; + screen = s; break; case '-': - if (screen <= 0) { - puts("On first screenful of messages"); + if (--s < 0) { + printf("On first screenful of messages\n"); return(0); } - screen--; + screen = s; break; default: @@ -156,14 +141,14 @@ * Compute screen size. */ int -screensize(void) +screensize() { int s; char *cp; - if ((cp = value("screen")) != NULL && (s = atoi(cp)) > 0) - return(s); - return(screenheight - 4); + if ((cp = value("screen")) != NOSTR && (s = atoi(cp)) > 0) + return s; + return screenheight - 4; } /* @@ -171,7 +156,8 @@ * in the passed message list. */ int -from(void *v) +from(v) + void *v; { int *msgvec = v; register int *ip; @@ -188,7 +174,8 @@ * This is a slight improvement to the standard one. */ void -printhead(int mesg) +printhead(mesg) + int mesg; { struct message *mp; char headline[LINESIZE], wcount[LINESIZE], *subjline, dispc, curind; @@ -196,13 +183,10 @@ struct headline hl; int subjlen; char *name; - char *to, *from; - struct name *np; - char **ap; mp = &message[mesg-1]; - (void)readline(setinput(mp), headline, LINESIZE, NULL); - if ((subjline = hfield("subject", mp)) == NULL) + (void) readline(setinput(mp), headline, LINESIZE); + if ((subjline = hfield("subject", mp)) == NOSTR) subjline = hfield("subj", mp); /* * Bletch! @@ -220,32 +204,15 @@ if (mp->m_flag & MBOX) dispc = 'M'; parse(headline, &hl, pbuf); - (void)snprintf(wcount, sizeof(wcount), "%4d/%-5d", mp->m_lines, - mp->m_size); - subjlen = screenwidth - 44 - strlen(wcount); - from = nameof(mp, 0); - to = skin(hfield("to", mp)); - np = extract(from, GTO); - np = delname(np, myname); - if (altnames) - for (ap = altnames; *ap; ap++) - np = delname(np, *ap); - if (np) - /* not from me */ - name = value("show-rcpt") != NULL && to ? to : from; - else - /* from me - show TO */ - name = value("showto") != NULL && to ? to : from; - if (subjline == NULL || subjlen < 0) { /* pretty pathetic */ - subjline=""; - subjlen=0; - } - if (name == to) - printf("%c%c%3d TO %-14.14s %16.16s %s %.*s\n", - curind, dispc, mesg, name, hl.l_date, wcount, - subjlen, subjline); + sprintf(wcount, "%3d/%-5ld", mp->m_lines, mp->m_size); + subjlen = screenwidth - 50 - strlen(wcount); + name = value("show-rcpt") != NOSTR ? + skin(hfield("to", mp)) : nameof(mp, 0); + if (subjline == NOSTR || subjlen < 0) /* pretty pathetic */ + printf("%c%c%3d %-20.20s %16.16s %s\n", + curind, dispc, mesg, name, hl.l_date, wcount); else - printf("%c%c%3d %-17.17s %16.16s %s %.*s\n", + printf("%c%c%3d %-20.20s %16.16s %s \"%.*s\"\n", curind, dispc, mesg, name, hl.l_date, wcount, subjlen, subjline); } @@ -254,9 +221,10 @@ * Print out the value of dot. */ int -pdot(void *v) +pdot(v) + void *v; { - printf("%d\n", (int)(dot - &message[0] + 1)); + printf("%d\n", dot - &message[0] + 1); return(0); } @@ -264,163 +232,167 @@ * Print out all the possible commands. */ int -pcmdlist(void *v) +pcmdlist(v) + void *v; { extern const struct cmd cmdtab[]; - const struct cmd *cp; - int cc; + register const struct cmd *cp; + register int cc; - puts("Commands are:"); + printf("Commands are:\n"); for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) { cc += strlen(cp->c_name) + 2; if (cc > 72) { - putchar('\n'); + printf("\n"); cc = strlen(cp->c_name) + 2; } - if ((cp+1)->c_name != NULL) + if ((cp+1)->c_name != NOSTR) printf("%s, ", cp->c_name); else - puts(cp->c_name); + printf("%s\n", cp->c_name); } return(0); } /* - * Pipe message to command - */ -int -pipeit(void *ml, void *sl) -{ - int *msgvec = ml; - char *cmd = sl; - - return(type1(msgvec, cmd, 0, 0)); -} - -/* * Paginate messages, honor ignored fields. */ int -more(void *v) +more(v) + void *v; { int *msgvec = v; - return(type1(msgvec, NULL, 1, 1)); + return (type1(msgvec, 1, 1)); } /* * Paginate messages, even printing ignored fields. */ int -More(void *v) +More(v) + void *v; { int *msgvec = v; - return(type1(msgvec, NULL, 0, 1)); + return (type1(msgvec, 0, 1)); } /* * Type out messages, honor ignored fields. */ int -type(void *v) +type(v) + void *v; { int *msgvec = v; - return(type1(msgvec, NULL, 1, 0)); + return(type1(msgvec, 1, 0)); } /* * Type out messages, even printing ignored fields. */ int -Type(void *v) +Type(v) + void *v; { int *msgvec = v; - return(type1(msgvec, NULL, 0, 0)); + return(type1(msgvec, 0, 0)); } /* * Type out the messages requested. */ +jmp_buf pipestop; int -type1(int *msgvec, char *cmd, int doign, int page) +type1(msgvec, doign, page) + int *msgvec; + int doign, page; { - int nlines, *ip, restoreterm; + register *ip; struct message *mp; - struct termios tbuf; char *cp; + int nlines; FILE *obuf; +#if __GNUC__ + /* Avoid longjmp clobbering */ + (void) &cp; + (void) &obuf; +#endif obuf = stdout; - restoreterm = 0; - - /* - * start a pipe if needed. - */ - if (cmd) { - restoreterm = (tcgetattr(fileno(stdin), &tbuf) == 0); - obuf = Popen(cmd, "w"); - if (obuf == NULL) { - warn("%s", cmd); - obuf = stdout; - } - } else if (value("interactive") != NULL && - (page || (cp = value("crt")) != NULL)) { + if (setjmp(pipestop)) + goto close_pipe; + if (value("interactive") != NOSTR && + (page || (cp = value("crt")) != NOSTR)) { nlines = 0; if (!page) { for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) nlines += message[*ip - 1].m_lines; } if (page || nlines > (*cp ? atoi(cp) : realscreenheight)) { - restoreterm = (tcgetattr(fileno(stdin), &tbuf) == 0); - obuf = Popen(value("PAGER"), "w"); + cp = value("PAGER"); + if (cp == NULL || *cp == '\0') + cp = _PATH_MORE; + obuf = Popen(cp, "w"); if (obuf == NULL) { - warn("%s", cp); + perror(cp); obuf = stdout; - } + } else + signal(SIGPIPE, brokpipe); } } - - /* - * Send messages to the output. - */ for (ip = msgvec; *ip && ip - msgvec < msgCount; ip++) { mp = &message[*ip - 1]; touch(mp); dot = mp; - if (cmd == NULL && value("quiet") == NULL) + if (value("quiet") == NOSTR) fprintf(obuf, "Message %d:\n", *ip); - if (sendmessage(mp, obuf, doign ? ignore : 0, NULL) == -1) - break; + (void) send(mp, obuf, doign ? ignore : 0, NOSTR); } - +close_pipe: if (obuf != stdout) { - (void)Pclose(obuf); - if (restoreterm) - (void)tcsetattr(fileno(stdin), TCSADRAIN, &tbuf); + /* + * Ignore SIGPIPE so it can't cause a duplicate close. + */ + signal(SIGPIPE, SIG_IGN); + Pclose(obuf); + signal(SIGPIPE, SIG_DFL); } return(0); } /* + * Respond to a broken pipe signal -- + * probably caused by quitting more. + */ +void +brokpipe(signo) + int signo; +{ + longjmp(pipestop, 1); +} + +/* * Print the top so many lines of each desired message. * The number of lines is taken from the variable "toplines" * and defaults to 5. */ int -top(void * v) +top(v) + void *v; { int *msgvec = v; - int *ip; - struct message *mp; + register int *ip; + register struct message *mp; int c, topl, lines, lineb; char *valtop, linebuf[LINESIZE]; FILE *ibuf; topl = 5; valtop = value("toplines"); - if (valtop != NULL) { + if (valtop != NOSTR) { topl = atoi(valtop); if (topl < 0 || topl > 10000) topl = 5; @@ -430,14 +402,14 @@ mp = &message[*ip - 1]; touch(mp); dot = mp; - if (value("quiet") == NULL) + if (value("quiet") == NOSTR) printf("Message %d:\n", *ip); ibuf = setinput(mp); c = mp->m_lines; if (!lineb) - putchar('\n'); + printf("\n"); for (lines = 0; lines < c && lines <= topl; lines++) { - if (readline(ibuf, linebuf, sizeof(linebuf), NULL) < 0) + if (readline(ibuf, linebuf, LINESIZE) < 0) break; puts(linebuf); lineb = blankline(linebuf); @@ -451,10 +423,11 @@ * get mboxed. */ int -stouch(void *v) +stouch(v) + void *v; { int *msgvec = v; - int *ip; + register int *ip; for (ip = msgvec; *ip != 0; ip++) { dot = &message[*ip-1]; @@ -468,10 +441,11 @@ * Make sure all passed messages get mboxed. */ int -mboxit(void *v) +mboxit(v) + void *v; { int *msgvec = v; - int *ip; + register int *ip; for (ip = msgvec; *ip != 0; ip++) { dot = &message[*ip-1]; @@ -485,51 +459,18 @@ * List the folders the user currently has. */ int -folders(void *v) -{ - char *files = (char *)v; - char dirname[PATHSIZE]; - char cmd[BUFSIZ]; - - if (getfold(dirname, sizeof(dirname)) < 0) - istrcpy(dirname, "$HOME", sizeof(dirname)); - - snprintf(cmd, sizeof(cmd), "cd %s; %s %s", dirname, value("LISTER"), - files && *files ? files : ""); - - (void)run_command(value("SHELL"), 0, -1, -1, "-c", cmd, NULL); - return(0); -} - -/* - * Update the mail file with any new messages that have - * come in since we started reading mail. - */ -int -inc(void *v) -{ - int nmsg, mdot; - - nmsg = incfile(); - - if (nmsg == 0) { - puts("No new mail."); - } else if (nmsg > 0) { - mdot = newfileinfo(msgCount - nmsg); - dot = &message[mdot - 1]; - } else { - puts("\"inc\" command failed..."); - } - - return(0); -} - -/* - * User hit ^C while printing the headers. - */ -void -hdrint(int s) +folders(v) + void *v; { + char dirname[BUFSIZ]; + char *cmd; - gothdrint = 1; + if (getfold(dirname, BUFSIZ) < 0) { + printf("No value set for \"folder\"\n"); + return 1; + } + if ((cmd = value("LISTER")) == NOSTR) + cmd = "ls"; + (void) run_command(cmd, 0, -1, -1, dirname, NOSTR, NOSTR); + return 0; } diff -urN mailx-8.1.1.orig/cmd2.c mailx-8.1.1/cmd2.c --- mailx-8.1.1.orig/cmd2.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/cmd2.c 2003-03-26 13:03:39.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: cmd2.c,v 1.11 2001/11/21 20:41:55 millert Exp $ */ -/* $NetBSD: cmd2.c,v 1.7 1997/05/17 19:55:10 pk Exp $ */ +/* $OpenBSD: cmd2.c,v 1.5 1996/06/08 19:48:13 christos Exp $ */ +/* $NetBSD: cmd2.c,v 1.5 1996/06/08 19:48:13 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)cmd2.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)cmd2.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: cmd2.c,v 1.11 2001/11/21 20:41:55 millert Exp $"; +static char rcsid[] = "$OpenBSD: cmd2.c,v 1.5 1996/06/08 19:48:13 christos Exp $"; #endif #endif /* not lint */ @@ -51,7 +51,7 @@ * * More user commands. */ -static int igcomp(const void *, const void *); +static int igcomp __P((const void *, const void *)); /* * If any arguments were given, go to the next applicable argument @@ -59,24 +59,29 @@ * If given as first command with no arguments, print first message. */ int -next(void *v) +next(v) + void *v; { - struct message *mp; int *msgvec = v; - int *ip, *ip2, list[2], mdot; + register struct message *mp; + register int *ip, *ip2; + int list[2], mdot; if (*msgvec != NULL) { + /* - * If some messages were supplied, find the + * If some messages were supplied, find the * first applicable one following dot using * wrap around. */ + mdot = dot - &message[0] + 1; /* * Find the first message in the supplied * message list which follows dot. */ + for (ip = msgvec; *ip != NULL; ip++) if (*ip > mdot) break; @@ -94,7 +99,7 @@ if (*ip2 == NULL) ip2 = msgvec; } while (ip2 != ip); - puts("No messages applicable"); + printf("No messages applicable\n"); return(1); } @@ -102,6 +107,7 @@ * If this is the first command, select message 1. * Note that this must exist for us to get here at all. */ + if (!sawcom) goto hitit; @@ -109,11 +115,12 @@ * Just find the next good message after dot, no * wraparound. */ + for (mp = dot+1; mp < &message[msgCount]; mp++) if ((mp->m_flag & (MDELETED|MSAVED)) == 0) break; if (mp >= &message[msgCount]) { - puts("At EOF"); + printf("At EOF\n"); return(0); } dot = mp; @@ -121,6 +128,7 @@ /* * Print dot. */ + list[0] = dot - &message[0] + 1; list[1] = NULL; return(type(list)); @@ -131,22 +139,24 @@ * so we can discard when the user quits. */ int -save(void *v) +save(v) + void *v; { char *str = v; - return(save1(str, 1, "save", saveignore)); + return save1(str, 1, "save", saveignore); } /* * Copy a message to a file without affected its saved-ness */ int -copycmd(void *v) +copycmd(v) + void *v; { char *str = v; - return(save1(str, 0, "copy", saveignore)); + return save1(str, 0, "copy", saveignore); } /* @@ -154,15 +164,20 @@ * If mark is true, mark the message "saved." */ int -save1(char *str, int mark, char *cmd, struct ignoretab *ignore) +save1(str, mark, cmd, ignore) + char str[]; + int mark; + char *cmd; + struct ignoretab *ignore; { - struct message *mp; + register int *ip; + register struct message *mp; char *file, *disp; - int f, *msgvec, *ip; + int f, *msgvec; FILE *obuf; - msgvec = (int *)salloc((msgCount + 2) * sizeof(*msgvec)); - if ((file = snarf(str, &f)) == NULL) + msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); + if ((file = snarf(str, &f)) == NOSTR) return(1); if (!f) { *msgvec = first(0, MMNORM); @@ -174,7 +189,7 @@ } if (f && getmsglist(str, msgvec, 0) < 0) return(1); - if ((file = expand(file)) == NULL) + if ((file = expand(file)) == NOSTR) return(1); printf("\"%s\" ", file); fflush(stdout); @@ -183,15 +198,15 @@ else disp = "[New file]"; if ((obuf = Fopen(file, "a")) == NULL) { - warn(NULL); + perror(NOSTR); return(1); } for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { mp = &message[*ip - 1]; touch(mp); - if (sendmessage(mp, obuf, ignore, NULL) < 0) { - warn("%s", file); - (void)Fclose(obuf); + if (send(mp, obuf, ignore, NOSTR) < 0) { + perror(file); + Fclose(obuf); return(1); } if (mark) @@ -199,8 +214,8 @@ } fflush(obuf); if (ferror(obuf)) - warn("%s", file); - (void)Fclose(obuf); + perror(file); + Fclose(obuf); printf("%s\n", disp); return(0); } @@ -210,25 +225,29 @@ * file name, minus header and trailing blank line. */ int -swrite(void *v) +swrite(v) + void *v; { char *str = v; - return(save1(str, 1, "write", ignoreall)); + return save1(str, 1, "write", ignoreall); } /* * Snarf the file from the end of the command line and * return a pointer to it. If there is no file attached, - * just return NULL. Put a null in front of the file + * just return NOSTR. Put a null in front of the file * name so that the message list processing won't see it, * unless the file name is the only thing on the line, in * which case, return 0 in the reference flag variable. */ + char * -snarf(char *linebuf, int *flag) +snarf(linebuf, flag) + char linebuf[]; + int *flag; { - char *cp; + register char *cp; *flag = 1; cp = strlen(linebuf) + linebuf - 1; @@ -236,6 +255,7 @@ /* * Strip away trailing blanks. */ + while (cp > linebuf && isspace(*cp)) cp--; *++cp = 0; @@ -243,11 +263,12 @@ /* * Now search for the beginning of the file name. */ + while (cp > linebuf && !isspace(*cp)) cp--; if (*cp == '\0') { - puts("No file specified."); - return(NULL); + printf("No file specified.\n"); + return(NOSTR); } if (isspace(*cp)) *cp++ = 0; @@ -260,19 +281,20 @@ * Delete messages. */ int -delete(void *v) +delete(v) + void *v; { int *msgvec = v; - delm(msgvec); - return(0); + return 0; } /* * Delete messages, then type the new dot. */ int -deltype(void *v) +deltype(v) + void *v; { int *msgvec = v; int list[2]; @@ -286,9 +308,9 @@ list[1] = NULL; return(type(list)); } - puts("At EOF"); + printf("At EOF\n"); } else - puts("No more messages"); + printf("No more messages\n"); return(0); } @@ -298,10 +320,12 @@ * Internal interface. */ int -delm(int *msgvec) +delm(msgvec) + int *msgvec; { - struct message *mp; - int *ip, last; + register struct message *mp; + register *ip; + int last; last = NULL; for (ip = msgvec; *ip != NULL; ip++) { @@ -327,6 +351,7 @@ /* * Following can't happen -- it keeps lint happy */ + return(-1); } @@ -334,11 +359,12 @@ * Undelete the indicated messages. */ int -undeletecmd(void *v) +undeletecmd(v) + void *v; { int *msgvec = v; - int *ip; - struct message *mp; + register struct message *mp; + register *ip; for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { mp = &message[*ip - 1]; @@ -346,51 +372,53 @@ dot = mp; mp->m_flag &= ~MDELETED; } - return(0); + return 0; } /* * Interactively dump core on "core" */ int -core(void *v) +core(v) + void *v; { - pid_t pid; - extern int wait_status; + int pid; + extern union wait wait_status; switch (pid = vfork()) { case -1: - warn("vfork"); + perror("fork"); return(1); case 0: abort(); _exit(1); } - fputs("Okie dokie", stdout); + printf("Okie dokie"); fflush(stdout); wait_child(pid); - if (WIFSIGNALED(wait_status) && WCOREDUMP(wait_status)) - puts(" -- Core dumped."); + if (wait_status.w_coredump) + printf(" -- Core dumped.\n"); else - puts(" -- Can't dump core."); - return(0); + printf(" -- Can't dump core.\n"); + return 0; } /* * Clobber as many bytes of stack as the user requests. */ int -clobber(void *v) +clobber(v) + void *v; { char **argv = v; - int times; + register int times; if (argv[0] == 0) times = 1; else times = (atoi(argv[0]) + 511) / 512; clob1(times); - return(0); + return 0; } /* @@ -401,7 +429,7 @@ int n; { char buf[512]; - char *cp; + register char *cp; if (n <= 0) return; @@ -415,11 +443,12 @@ * If no arguments, print the current list of retained fields. */ int -retfield(void *v) +retfield(v) + void *v; { char **list = v; - return(ignore1(list, ignore + 1, "retained")); + return ignore1(list, ignore + 1, "retained"); } /* @@ -427,89 +456,96 @@ * If no arguments, print the current list of ignored fields. */ int -igfield(void *v) +igfield(v) + void *v; { char **list = v; - return(ignore1(list, ignore, "ignored")); + return ignore1(list, ignore, "ignored"); } int -saveretfield(void *v) +saveretfield(v) + void *v; { char **list = v; - return(ignore1(list, saveignore + 1, "retained")); + return ignore1(list, saveignore + 1, "retained"); } int -saveigfield(void *v) +saveigfield(v) + void *v; { char **list = v; - return(ignore1(list, saveignore, "ignored")); + return ignore1(list, saveignore, "ignored"); } int -ignore1(char **list, struct ignoretab *tab, char *which) +ignore1(list, tab, which) + char *list[]; + struct ignoretab *tab; + char *which; { - char field[LINESIZE]; + char field[BUFSIZ]; + register int h; + register struct ignore *igp; char **ap; - struct ignore *igp; - int h; - if (*list == NULL) - return(igshow(tab, which)); + if (*list == NOSTR) + return igshow(tab, which); for (ap = list; *ap != 0; ap++) { - istrcpy(field, *ap, sizeof(field)); + istrcpy(field, *ap, BUFSIZ); + field[BUFSIZ-1]='\0'; if (member(field, tab)) continue; h = hash(field); - igp = (struct ignore *)calloc(1, sizeof(struct ignore)); - if (igp == NULL) - errx(1, "Out of memory"); - igp->i_field = strdup(field); - if (igp->i_field == NULL) - errx(1, "Out of memory"); + igp = (struct ignore *) calloc(1, sizeof (struct ignore)); + igp->i_field = calloc((unsigned) strlen(field) + 1, + sizeof (char)); + strcpy(igp->i_field, field); igp->i_link = tab->i_head[h]; tab->i_head[h] = igp; tab->i_count++; } - return(0); + return 0; } /* * Print out all currently retained fields. */ int -igshow(struct ignoretab *tab, char *which) +igshow(tab, which) + struct ignoretab *tab; + char *which; { - int h; + register int h; struct ignore *igp; char **ap, **ring; if (tab->i_count == 0) { printf("No fields currently being %s.\n", which); - return(0); + return 0; } - ring = (char **)salloc((tab->i_count + 1) * sizeof(char *)); + ring = (char **) salloc((tab->i_count + 1) * sizeof (char *)); ap = ring; for (h = 0; h < HSHSIZE; h++) for (igp = tab->i_head[h]; igp != 0; igp = igp->i_link) *ap++ = igp->i_field; *ap = 0; - qsort(ring, tab->i_count, sizeof(char *), igcomp); + qsort(ring, tab->i_count, sizeof (char *), igcomp); for (ap = ring; *ap != 0; ap++) - puts(*ap); - return(0); + printf("%s\n", *ap); + return 0; } /* * Compare two names for sorting ignored field list. */ static int -igcomp(const void *l, const void *r) +igcomp(l, r) + const void *l, *r; { - - return(strcmp(*(char **)l, *(char **)r)); + return (strcmp(*(char **)l, *(char **)r)); } diff -urN mailx-8.1.1.orig/cmd3.c mailx-8.1.1/cmd3.c --- mailx-8.1.1.orig/cmd3.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/cmd3.c 2003-03-26 13:03:39.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: cmd3.c,v 1.19 2002/08/12 00:42:56 aaron Exp $ */ -/* $NetBSD: cmd3.c,v 1.8 1997/07/09 05:29:49 mikel Exp $ */ +/* $OpenBSD: cmd3.c,v 1.5 1996/06/08 19:48:14 christos Exp $ */ +/* $NetBSD: cmd3.c,v 1.5 1996/06/08 19:48:14 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95"; +static char sccsid[] = "@(#)cmd3.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: cmd3.c,v 1.19 2002/08/12 00:42:56 aaron Exp $"; +static char rcsid[] = "$OpenBSD: cmd3.c,v 1.5 1996/06/08 19:48:14 christos Exp $"; #endif #endif /* not lint */ @@ -50,31 +50,31 @@ * * Still more user commands. */ -static int diction(const void *, const void *); +static int diction __P((const void *, const void *)); /* * Process a shell escape by saving signals, ignoring signals, * and forking a sh -c */ int -shell(void *v) +shell(v) + void *v; { char *str = v; + sig_t sigint = signal(SIGINT, SIG_IGN); char *shell; char cmd[BUFSIZ]; - struct sigaction oact; - sigset_t oset; - (void)ignoresig(SIGINT, &oact, &oset); - (void)istrcpy(cmd, str, sizeof(cmd)); - if (bangexp(cmd, sizeof(cmd)) < 0) - return(1); - shell = value("SHELL"); - (void)run_command(shell, 0, 0, -1, "-c", cmd, NULL); - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void)sigaction(SIGINT, &oact, NULL); - puts("!"); - return(0); + (void) strncpy(cmd, str, BUFSIZ); + cmd[BUFSIZ-1]='\0'; + if (bangexp(cmd, BUFSIZ) < 0) + return 1; + if ((shell = value("SHELL")) == NOSTR) + shell = _PATH_CSHELL; + (void) run_command(shell, 0, -1, -1, "-c", cmd, NOSTR); + (void) signal(SIGINT, sigint); + printf("!\n"); + return 0; } /* @@ -82,32 +82,36 @@ */ /*ARGSUSED*/ int -dosh(void *v) +dosh(v) + void *v; { + sig_t sigint = signal(SIGINT, SIG_IGN); char *shell; - struct sigaction oact; - sigset_t oset; - shell = value("SHELL"); - (void)ignoresig(SIGINT, &oact, &oset); - (void)run_command(shell, 0, 0, -1, NULL, NULL, NULL); - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void)sigaction(SIGINT, &oact, NULL); + if ((shell = value("SHELL")) == NOSTR) + shell = _PATH_CSHELL; + (void) run_command(shell, 0, -1, -1, NOSTR, NOSTR, NOSTR); + (void) signal(SIGINT, sigint); putchar('\n'); - return(0); + return 0; } /* * Expand the shell escape by expanding unescaped !'s into the * last issued command where possible. */ + +char lastbang[128]; + int -bangexp(char *str, size_t strsize) +bangexp(str, size) + char *str; + int size; { char bangbuf[BUFSIZ]; - static char lastbang[BUFSIZ]; - char *cp, *cp2; - int n, changed = 0; + register char *cp, *cp2; + register int n; + int changed = 0; cp = str; cp2 = bangbuf; @@ -116,11 +120,11 @@ if (*cp == '!') { if (n < strlen(lastbang)) { overf: - puts("Command buffer overflow"); + printf("Command buffer overflow\n"); return(-1); } changed++; - istrcpy(cp2, lastbang, sizeof(bangbuf) - (cp2 - bangbuf)); + strcpy(cp2, lastbang); cp2 += strlen(lastbang); n -= strlen(lastbang); cp++; @@ -139,22 +143,34 @@ } *cp2 = 0; if (changed) { - (void)printf("!%s\n", bangbuf); - (void)fflush(stdout); + printf("!%s\n", bangbuf); + fflush(stdout); } - (void)istrcpy(str, bangbuf, strsize); - (void)istrcpy(lastbang, bangbuf, sizeof(lastbang)); + strncpy(str, bangbuf, size); + str[size-1]='\0'; + strncpy(lastbang, bangbuf, 128); + lastbang[127] = 0; return(0); } /* * Print out a nice help message from some file or another. */ + int -help(void *v) +help(v) + void *v; { + register c; + register FILE *f; - (void)run_command(value("PAGER"), 0, -1, -1, _PATH_HELP, NULL); + if ((f = Fopen(_PATH_HELP, "r")) == NULL) { + perror(_PATH_HELP); + return(1); + } + while ((c = getc(f)) != EOF) + putchar(c); + Fclose(f); return(0); } @@ -162,35 +178,33 @@ * Change user's working directory. */ int -schdir(void *v) +schdir(v) + void *v; { char **arglist = v; char *cp; - if (*arglist == NULL) { - if (homedir == NULL) - return(1); + if (*arglist == NOSTR) cp = homedir; - } else { - if ((cp = expand(*arglist)) == NULL) + else + if ((cp = expand(*arglist)) == NOSTR) return(1); - } if (chdir(cp) < 0) { - warn("%s", cp); + perror(cp); return(1); } - return(0); + return 0; } int -respond(void *v) +respond(v) + void *v; { int *msgvec = v; - - if (value("Replyall") == NULL) - return(_respond(msgvec)); + if (value("Replyall") == NOSTR) + return (_respond(msgvec)); else - return(_Respond(msgvec)); + return (_Respond(msgvec)); } /* @@ -208,20 +222,20 @@ struct header head; if (msgvec[1] != 0) { - puts("Sorry, can't reply to multiple messages at once"); + printf("Sorry, can't reply to multiple messages at once\n"); return(1); } mp = &message[msgvec[0] - 1]; touch(mp); dot = mp; - if ((rcv = skin(hfield("from", mp))) == NULL) + if ((rcv = skin(hfield("from", mp))) == NOSTR) rcv = skin(nameof(mp, 1)); - if ((replyto = skin(hfield("reply-to", mp))) != NULL) + if ((replyto = skin(hfield("reply-to", mp))) != NOSTR) np = extract(replyto, GTO); - else if ((cp = skin(hfield("to", mp))) != NULL) + else if ((cp = skin(hfield("to", mp))) != NOSTR) np = extract(cp, GTO); else - np = NULL; + np = NIL; np = elide(np); /* * Delete my name from the reply list, @@ -231,18 +245,18 @@ if (altnames) for (ap = altnames; *ap; ap++) np = delname(np, *ap); - if (np != NULL && replyto == NULL) + if (np != NIL && replyto == NOSTR) np = cat(np, extract(rcv, GTO)); - else if (np == NULL) { - if (replyto != NULL) - puts("Empty reply-to field -- replying to author"); + else if (np == NIL) { + if (replyto != NOSTR) + printf("Empty reply-to field -- replying to author\n"); np = extract(rcv, GTO); } head.h_to = np; - if ((head.h_subject = hfield("subject", mp)) == NULL) + if ((head.h_subject = hfield("subject", mp)) == NOSTR) head.h_subject = hfield("subj", mp); head.h_subject = reedit(head.h_subject); - if (replyto == NULL && (cp = skin(hfield("cc", mp))) != NULL) { + if (replyto == NOSTR && (cp = skin(hfield("cc", mp))) != NOSTR) { np = elide(extract(cp, GCC)); np = delname(np, myname); if (altnames != 0) @@ -250,9 +264,9 @@ np = delname(np, *ap); head.h_cc = np; } else - head.h_cc = NULL; - head.h_bcc = NULL; - head.h_smopts = NULL; + head.h_cc = NIL; + head.h_bcc = NIL; + head.h_smopts = NIL; mail1(&head, 1); return(0); } @@ -262,40 +276,21 @@ * it does not already. */ char * -reedit(char *subj) +reedit(subj) + register char *subj; { char *newsubj; - size_t len; - if (subj == NULL) - return(NULL); + if (subj == NOSTR) + return NOSTR; if ((subj[0] == 'r' || subj[0] == 'R') && (subj[1] == 'e' || subj[1] == 'E') && subj[2] == ':') - return(subj); - len = strlen(subj) + 5; - newsubj = salloc(len); - istrcpy(newsubj, "Re: ", len); - strcat(newsubj, subj); - return(newsubj); -} - -/* - * Mark new the named messages, so that they will be left in the system - * mailbox as unread. - */ -int -marknew(void *v) -{ - int *msgvec = v; - int *ip; - - for (ip = msgvec; *ip != NULL; ip++) { - dot = &message[*ip-1]; - dot->m_flag &= ~(MBOX|MREAD|MTOUCH); - dot->m_flag |= MNEW|MSTATUS; - } - return(0); + return subj; + newsubj = salloc(strlen(subj) + 5); + strcpy(newsubj, "Re: "); + strcpy(newsubj + 4, subj); + return newsubj; } /* @@ -303,14 +298,15 @@ * back to the system mailbox. */ int -preserve(void *v) +preserve(v) + void *v; { int *msgvec = v; - int *ip, mesg; - struct message *mp; + register struct message *mp; + register int *ip, mesg; if (edit) { - puts("Cannot \"preserve\" in edit mode"); + printf("Cannot \"preserve\" in edit mode\n"); return(1); } for (ip = msgvec; *ip != NULL; ip++) { @@ -327,10 +323,11 @@ * Mark all given messages as unread. */ int -unread(void *v) +unread(v) + void *v; { - int *msgvec = v; - int *ip; + int *msgvec = v; + register int *ip; for (ip = msgvec; *ip != NULL; ip++) { dot = &message[*ip-1]; @@ -344,16 +341,17 @@ * Print the size of each message. */ int -messize(void *v) +messize(v) + void *v; { int *msgvec = v; - struct message *mp; - int *ip, mesg; + register struct message *mp; + register int *ip, mesg; for (ip = msgvec; *ip != NULL; ip++) { mesg = *ip; mp = &message[mesg-1]; - printf("%d: %d/%d\n", mesg, mp->m_lines, mp->m_size); + printf("%d: %d/%ld\n", mesg, mp->m_lines, mp->m_size); } return(0); } @@ -363,9 +361,9 @@ * by returning an error. */ int -rexit(void *v) +rexit(v) + void *v; { - if (sourcing) return(1); exit(0); @@ -377,30 +375,31 @@ * of csh. */ int -set(void *v) +set(v) + void *v; { char **arglist = v; - struct var *vp; - char *cp, *cp2; + register struct var *vp; + register char *cp, *cp2; char varbuf[BUFSIZ], **ap, **p; int errs, h, s; - if (*arglist == NULL) { + if (*arglist == NOSTR) { for (h = 0, s = 1; h < HSHSIZE; h++) - for (vp = variables[h]; vp != NULL; vp = vp->v_link) + for (vp = variables[h]; vp != NOVAR; vp = vp->v_link) s++; - ap = (char **)salloc(s * sizeof(*ap)); + ap = (char **) salloc(s * sizeof *ap); for (h = 0, p = ap; h < HSHSIZE; h++) - for (vp = variables[h]; vp != NULL; vp = vp->v_link) + for (vp = variables[h]; vp != NOVAR; vp = vp->v_link) *p++ = vp->v_name; - *p = NULL; + *p = NOSTR; sort(ap); - for (p = ap; *p != NULL; p++) + for (p = ap; *p != NOSTR; p++) printf("%s\t%s\n", *p, value(*p)); return(0); } errs = 0; - for (ap = arglist; *ap != NULL; ap++) { + for (ap = arglist; *ap != NOSTR; ap++) { cp = *ap; cp2 = varbuf; while (*cp != '=' && *cp != '\0') @@ -411,7 +410,7 @@ else cp++; if (equal(varbuf, "")) { - puts("Non-null variable name required"); + printf("Non-null variable name required\n"); errs++; continue; } @@ -424,16 +423,17 @@ * Unset a bunch of variable values. */ int -unset(void *v) +unset(v) + void *v; { char **arglist = v; - struct var *vp, *vp2; + register struct var *vp, *vp2; int errs, h; char **ap; errs = 0; - for (ap = arglist; *ap != NULL; ap++) { - if ((vp2 = lookup(*ap)) == NULL) { + for (ap = arglist; *ap != NOSTR; ap++) { + if ((vp2 = lookup(*ap)) == NOVAR) { if (!sourcing) { printf("\"%s\": undefined variable\n", *ap); errs++; @@ -445,7 +445,7 @@ variables[h] = variables[h]->v_link; vfree(vp2->v_name); vfree(vp2->v_value); - (void)free(vp2); + free((char *)vp2); continue; } for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link) @@ -453,7 +453,7 @@ vp->v_link = vp2->v_link; vfree(vp2->v_name); vfree(vp2->v_value); - (void)free(vp2); + free((char *) vp2); } return(errs); } @@ -462,39 +462,40 @@ * Put add users to a group. */ int -group(void *v) +group(v) + void *v; { char **argv = v; - struct grouphead *gh; - struct group *gp; + register struct grouphead *gh; + register struct group *gp; + register int h; + int s; char **ap, *gname, **p; - int h, s; - if (*argv == NULL) { + if (*argv == NOSTR) { for (h = 0, s = 1; h < HSHSIZE; h++) - for (gh = groups[h]; gh != NULL; gh = gh->g_link) + for (gh = groups[h]; gh != NOGRP; gh = gh->g_link) s++; - ap = (char **)salloc(s * sizeof(*ap)); + ap = (char **) salloc(s * sizeof *ap); for (h = 0, p = ap; h < HSHSIZE; h++) - for (gh = groups[h]; gh != NULL; gh = gh->g_link) + for (gh = groups[h]; gh != NOGRP; gh = gh->g_link) *p++ = gh->g_name; - *p = NULL; + *p = NOSTR; sort(ap); - for (p = ap; *p != NULL; p++) + for (p = ap; *p != NOSTR; p++) printgroup(*p); return(0); } - if (argv[1] == NULL) { + if (argv[1] == NOSTR) { printgroup(*argv); return(0); } gname = *argv; h = hash(gname); - if ((gh = findgroup(gname)) == NULL) { - if ((gh = (struct grouphead *)calloc(1, sizeof(*gh))) == NULL) - errx(1, "Out of memory"); + if ((gh = findgroup(gname)) == NOGRP) { + gh = (struct grouphead *) calloc(sizeof *gh, 1); gh->g_name = vcopy(gname); - gh->g_list = NULL; + gh->g_list = NOGE; gh->g_link = groups[h]; groups[h] = gh; } @@ -505,9 +506,8 @@ * later anyway. */ - for (ap = argv+1; *ap != NULL; ap++) { - if ((gp = (struct group *)calloc(1, sizeof(*gp))) == NULL) - errx(1, "Out of memory"); + for (ap = argv+1; *ap != NOSTR; ap++) { + gp = (struct group *) calloc(sizeof *gp, 1); gp->ge_name = vcopy(*ap); gp->ge_link = gh->g_list; gh->g_list = gp; @@ -520,11 +520,12 @@ * order. */ void -sort(char **list) +sort(list) + char **list; { - char **ap; + register char **ap; - for (ap = list; *ap != NULL; ap++) + for (ap = list; *ap != NOSTR; ap++) ; if (ap-list < 2) return; @@ -536,21 +537,22 @@ * qsort. */ static int -diction(const void *a, const void *b) +diction(a, b) + const void *a, *b; { - return(strcmp(*(char **)a, *(char **)b)); } /* * The do nothing command for comments. */ + /*ARGSUSED*/ int -null(void *v) +null(v) + void *v; { - - return(0); + return 0; } /* @@ -558,51 +560,53 @@ * the current file. */ int -file(void *v) +file(v) + void *v; { char **argv = v; - if (argv[0] == NULL) { - newfileinfo(0); - clearnew(); - return(0); + if (argv[0] == NOSTR) { + newfileinfo(); + return 0; } if (setfile(*argv) < 0) - return(1); + return 1; announce(); - return(0); + return 0; } /* * Expand file names like echo */ int -echo(void *v) +echo(v) + void *v; { char **argv = v; - char **ap, *cp; + register char **ap; + register char *cp; - for (ap = argv; *ap != NULL; ap++) { + for (ap = argv; *ap != NOSTR; ap++) { cp = *ap; - if ((cp = expand(cp)) != NULL) { + if ((cp = expand(cp)) != NOSTR) { if (ap != argv) putchar(' '); - fputs(cp, stdout); + printf("%s", cp); } } putchar('\n'); - return(0); + return 0; } int -Respond(void *v) +Respond(v) + void *v; { int *msgvec = v; - - if (value("Replyall") == NULL) - return(_Respond(msgvec)); + if (value("Replyall") == NOSTR) + return (_Respond(msgvec)); else - return(_respond(msgvec)); + return (_respond(msgvec)); } /* @@ -611,33 +615,34 @@ * reply. */ int -_Respond(int *msgvec) +_Respond(msgvec) + int msgvec[]; { struct header head; struct message *mp; - int *ap; - char *cp; + register int *ap; + register char *cp; - head.h_to = NULL; + head.h_to = NIL; for (ap = msgvec; *ap != 0; ap++) { mp = &message[*ap - 1]; touch(mp); dot = mp; - if ((cp = skin(hfield("from", mp))) == NULL) + if ((cp = skin(hfield("from", mp))) == NOSTR) cp = skin(nameof(mp, 2)); head.h_to = cat(head.h_to, extract(cp, GTO)); } - if (head.h_to == NULL) - return(0); + if (head.h_to == NIL) + return 0; mp = &message[msgvec[0] - 1]; - if ((head.h_subject = hfield("subject", mp)) == NULL) + if ((head.h_subject = hfield("subject", mp)) == NOSTR) head.h_subject = hfield("subj", mp); head.h_subject = reedit(head.h_subject); - head.h_cc = NULL; - head.h_bcc = NULL; - head.h_smopts = NULL; + head.h_cc = NIL; + head.h_bcc = NIL; + head.h_smopts = NIL; mail1(&head, 1); - return(0); + return 0; } /* @@ -645,13 +650,14 @@ * .mailrc and do some things if sending, others if receiving. */ int -ifcmd(void *v) +ifcmd(v) + void *v; { char **argv = v; - char *cp; + register char *cp; if (cond != CANY) { - puts("Illegal nested \"if\""); + printf("Illegal nested \"if\"\n"); return(1); } cond = CANY; @@ -677,12 +683,13 @@ * flip over the conditional flag. */ int -elsecmd(void *v) +elsecmd(v) + void *v; { switch (cond) { case CANY: - puts("\"Else\" without matching \"if\""); + printf("\"Else\" without matching \"if\"\n"); return(1); case CSEND: @@ -694,7 +701,7 @@ break; default: - puts("mail's idea of conditions is screwed up"); + printf("Mail's idea of conditions is screwed up\n"); cond = CANY; break; } @@ -705,11 +712,12 @@ * End of if statement. Just set cond back to anything. */ int -endifcmd(void *v) +endifcmd(v) + void *v; { if (cond == CANY) { - puts("\"Endif\" without matching \"if\""); + printf("\"Endif\" without matching \"if\"\n"); return(1); } cond = CANY; @@ -720,11 +728,12 @@ * Set the list of alternate names. */ int -alternates(void *v) +alternates(v) + void *v; { char **namelist = v; - char **ap, **ap2; - int c; + register int c; + register char **ap, **ap2, *cp; c = argcount(namelist) + 1; if (c == 1) { @@ -732,16 +741,16 @@ return(0); for (ap = altnames; *ap; ap++) printf("%s ", *ap); - putchar('\n'); + printf("\n"); return(0); } if (altnames != 0) - (void)free(altnames); - if ((altnames = (char **)calloc(c, sizeof(char *))) == NULL) - errx(1, "Out of memory"); + free((char *) altnames); + altnames = (char **) calloc((unsigned) c, sizeof (char *)); for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) { - if ((*ap2 = strdup(*ap)) == NULL) - errx(1, "Out of memory"); + cp = (char *) calloc((unsigned) strlen(*ap) + 1, sizeof (char)); + strcpy(cp, *ap); + *ap2 = cp; } *ap2 = 0; return(0); diff -urN mailx-8.1.1.orig/cmdtab.c mailx-8.1.1/cmdtab.c --- mailx-8.1.1.orig/cmdtab.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/cmdtab.c 1996-06-14 01:26:57.000000000 -0700 @@ -1,5 +1,5 @@ -/* $OpenBSD: cmdtab.c,v 1.6 2001/11/21 15:26:39 millert Exp $ */ -/* $NetBSD: cmdtab.c,v 1.7 1996/12/28 07:10:59 tls Exp $ */ +/* $OpenBSD: cmdtab.c,v 1.6 1996/06/08 19:48:15 christos Exp $ */ +/* $NetBSD: cmdtab.c,v 1.6 1996/06/08 19:48:15 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)cmdtab.c 8.2 (Berkeley) 4/20/95"; +static char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: cmdtab.c,v 1.6 2001/11/21 15:26:39 millert Exp $"; +static char rcsid[] = "$OpenBSD: cmdtab.c,v 1.6 1996/06/08 19:48:15 christos Exp $"; #endif #endif /* not lint */ @@ -50,83 +50,75 @@ * * Define all of the command names and bindings. */ + const struct cmd cmdtab[] = { - /* msgmask msgflag */ - /* command function argtype result & mask */ - /* ------- -------- ------- ------- -------- */ - { "next", { next }, NDMLIST, 0, MMNDEL }, - { "alias", { group }, M|RAWLIST, 0, 1000 }, - { "print", { type }, MSGLIST, 0, MMNDEL }, - { "type", { type }, MSGLIST, 0, MMNDEL }, - { "Type", { Type }, MSGLIST, 0, MMNDEL }, - { "Print", { Type }, MSGLIST, 0, MMNDEL }, - { "visual", { visual }, I|MSGLIST, 0, MMNORM }, - { "top", { top }, MSGLIST, 0, MMNDEL }, - { "touch", { stouch }, W|MSGLIST, 0, MMNDEL }, - { "preserve", { preserve }, W|MSGLIST, 0, MMNDEL }, - { "delete", { delete }, W|P|MSGLIST, 0, MMNDEL }, - { "dp", { deltype }, W|MSGLIST, 0, MMNDEL }, - { "dt", { deltype }, W|MSGLIST, 0, MMNDEL }, - { "undelete", { undeletecmd }, P|MSGLIST, MDELETED,MMNDEL }, - { "unset", { unset }, M|RAWLIST, 1, 1000 }, - { "mail", { sendmail }, R|M|I|STRLIST, 0, 0 }, - { "mbox", { mboxit }, W|MSGLIST, 0, 0 }, - { "pipe", { pipeit }, MSGLIST|STRLIST,0, MMNDEL }, - { "|", { pipeit }, MSGLIST|STRLIST,0, MMNDEL }, - { "more", { more }, MSGLIST, 0, MMNDEL }, - { "page", { more }, MSGLIST, 0, MMNDEL }, - { "More", { More }, MSGLIST, 0, MMNDEL }, - { "Page", { More }, MSGLIST, 0, MMNDEL }, - { "unread", { unread }, MSGLIST, 0, MMNDEL }, - { "!", { shell }, I|STRLIST, 0, 0 }, - { "copy", { copycmd }, M|STRLIST, 0, 0 }, - { "chdir", { schdir }, M|RAWLIST, 0, 1 }, - { "cd", { schdir }, M|RAWLIST, 0, 1 }, - { "save", { save }, STRLIST, 0, 0 }, - { "source", { source }, M|RAWLIST, 1, 1 }, - { "set", { set }, M|RAWLIST, 0, 1000 }, - { "shell", { dosh }, I|NOLIST, 0, 0 }, - { "version", { pversion }, M|NOLIST, 0, 0 }, - { "group", { group }, M|RAWLIST, 0, 1000 }, - { "write", { swrite }, STRLIST, 0, 0 }, - { "from", { from }, MSGLIST, 0, MMNORM }, - { "file", { file }, T|M|RAWLIST, 0, 1 }, - { "folder", { file }, T|M|RAWLIST, 0, 1 }, - { "folders", { folders }, T|M|STRLIST, 0, 0 }, - { "?", { help }, M|NOLIST, 0, 0 }, - { "z", { scroll }, M|STRLIST, 0, 0 }, - { "headers", { headers }, MSGLIST, 0, MMNDEL }, - { "help", { help }, M|NOLIST, 0, 0 }, - { "=", { pdot }, NOLIST, 0, 0 }, - { "Reply", { Respond }, R|I|MSGLIST, 0, MMNDEL }, - { "Respond", { Respond }, R|I|MSGLIST, 0, MMNDEL }, - { "reply", { respond }, R|I|MSGLIST, 0, MMNDEL }, - { "respond", { respond }, R|I|MSGLIST, 0, MMNDEL }, - { "edit", { editor }, I|MSGLIST, 0, MMNORM }, - { "echo", { echo }, M|RAWLIST, 0, 1000 }, - { "quit", { quitcmd }, NOLIST, 0, 0 }, - { "list", { pcmdlist }, M|NOLIST, 0, 0 }, - { "xit", { rexit }, M|NOLIST, 0, 0 }, - { "exit", { rexit }, M|NOLIST, 0, 0 }, - { "size", { messize }, MSGLIST, 0, MMNDEL }, - { "hold", { preserve }, W|MSGLIST, 0, MMNDEL }, - { "if", { ifcmd }, F|M|RAWLIST, 1, 1 }, - { "else", { elsecmd }, F|M|RAWLIST, 0, 0 }, - { "endif", { endifcmd }, F|M|RAWLIST, 0, 0 }, - { "alternates", { alternates }, M|RAWLIST, 0, 1000 }, - { "ignore", { igfield }, M|RAWLIST, 0, 1000 }, - { "discard", { igfield }, M|RAWLIST, 0, 1000 }, - { "retain", { retfield }, M|RAWLIST, 0, 1000 }, - { "saveignore", { saveigfield }, M|RAWLIST, 0, 1000 }, - { "savediscard",{ saveigfield }, M|RAWLIST, 0, 1000 }, - { "saveretain", { saveretfield }, M|RAWLIST, 0, 1000 }, -#if 0 - { "Header", { Header }, STRLIST, 0, 1000 }, -#endif - { "core", { core }, M|NOLIST, 0, 0 }, - { "#", { null }, M|NOLIST, 0, 0 }, - { "clobber", { clobber }, M|RAWLIST, 0, 1 }, - { "inc", { inc }, T|NOLIST, 0, 0 }, - { "new", { marknew }, MSGLIST, 0, MMNDEL }, - { 0, { 0 }, 0, 0, 0 } + { "next", next, NDMLIST, 0, MMNDEL }, + { "alias", group, M|RAWLIST, 0, 1000 }, + { "print", type, MSGLIST, 0, MMNDEL }, + { "type", type, MSGLIST, 0, MMNDEL }, + { "Type", Type, MSGLIST, 0, MMNDEL }, + { "Print", Type, MSGLIST, 0, MMNDEL }, + { "visual", visual, I|MSGLIST, 0, MMNORM }, + { "top", top, MSGLIST, 0, MMNDEL }, + { "touch", stouch, W|MSGLIST, 0, MMNDEL }, + { "preserve", preserve, W|MSGLIST, 0, MMNDEL }, + { "delete", delete, W|P|MSGLIST, 0, MMNDEL }, + { "dp", deltype, W|MSGLIST, 0, MMNDEL }, + { "dt", deltype, W|MSGLIST, 0, MMNDEL }, + { "undelete", undeletecmd, P|MSGLIST, MDELETED,MMNDEL }, + { "unset", unset, M|RAWLIST, 1, 1000 }, + { "mail", sendmail, R|M|I|STRLIST, 0, 0 }, + { "mbox", mboxit, W|MSGLIST, 0, 0 }, + { "more", more, MSGLIST, 0, MMNDEL }, + { "page", more, MSGLIST, 0, MMNDEL }, + { "More", More, MSGLIST, 0, MMNDEL }, + { "Page", More, MSGLIST, 0, MMNDEL }, + { "unread", unread, MSGLIST, 0, MMNDEL }, + { "!", shell, I|STRLIST, 0, 0 }, + { "copy", copycmd, M|STRLIST, 0, 0 }, + { "chdir", schdir, M|RAWLIST, 0, 1 }, + { "cd", schdir, M|RAWLIST, 0, 1 }, + { "save", save, STRLIST, 0, 0 }, + { "source", source, M|RAWLIST, 1, 1 }, + { "set", set, M|RAWLIST, 0, 1000 }, + { "shell", dosh, I|NOLIST, 0, 0 }, + { "version", pversion, M|NOLIST, 0, 0 }, + { "group", group, M|RAWLIST, 0, 1000 }, + { "write", swrite, STRLIST, 0, 0 }, + { "from", from, MSGLIST, 0, MMNORM }, + { "file", file, T|M|RAWLIST, 0, 1 }, + { "folder", file, T|M|RAWLIST, 0, 1 }, + { "folders", folders, T|M|NOLIST, 0, 0 }, + { "?", help, M|NOLIST, 0, 0 }, + { "z", scroll, M|STRLIST, 0, 0 }, + { "headers", headers, MSGLIST, 0, MMNDEL }, + { "help", help, M|NOLIST, 0, 0 }, + { "=", pdot, NOLIST, 0, 0 }, + { "Reply", Respond, R|I|MSGLIST, 0, MMNDEL }, + { "Respond", Respond, R|I|MSGLIST, 0, MMNDEL }, + { "reply", respond, R|I|MSGLIST, 0, MMNDEL }, + { "respond", respond, R|I|MSGLIST, 0, MMNDEL }, + { "edit", editor, I|MSGLIST, 0, MMNORM }, + { "echo", echo, M|RAWLIST, 0, 1000 }, + { "quit", quitcmd, NOLIST, 0, 0 }, + { "list", pcmdlist, M|NOLIST, 0, 0 }, + { "xit", rexit, M|NOLIST, 0, 0 }, + { "exit", rexit, M|NOLIST, 0, 0 }, + { "size", messize, MSGLIST, 0, MMNDEL }, + { "hold", preserve, W|MSGLIST, 0, MMNDEL }, + { "if", ifcmd, F|M|RAWLIST, 1, 1 }, + { "else", elsecmd, F|M|RAWLIST, 0, 0 }, + { "endif", endifcmd, F|M|RAWLIST, 0, 0 }, + { "alternates", alternates, M|RAWLIST, 0, 1000 }, + { "ignore", igfield, M|RAWLIST, 0, 1000 }, + { "discard", igfield, M|RAWLIST, 0, 1000 }, + { "retain", retfield, M|RAWLIST, 0, 1000 }, + { "saveignore", saveigfield, M|RAWLIST, 0, 1000 }, + { "savediscard",saveigfield, M|RAWLIST, 0, 1000 }, + { "saveretain", saveretfield, M|RAWLIST, 0, 1000 }, +/* { "Header", Header, STRLIST, 0, 1000 }, */ + { "core", core, M|NOLIST, 0, 0 }, + { "#", null, M|NOLIST, 0, 0 }, + { "clobber", clobber, M|RAWLIST, 0, 1 }, + { 0, 0, 0, 0, 0 } }; diff -urN mailx-8.1.1.orig/collect.c mailx-8.1.1/collect.c --- mailx-8.1.1.orig/collect.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/collect.c 2003-03-26 13:03:39.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: collect.c,v 1.24 2002/04/08 20:27:17 millert Exp $ */ -/* $NetBSD: collect.c,v 1.9 1997/07/09 05:25:45 mikel Exp $ */ +/* $OpenBSD: collect.c,v 1.6 1996/06/08 19:48:16 christos Exp $ */ +/* $NetBSD: collect.c,v 1.6 1996/06/08 19:48:16 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)collect.c 8.2 (Berkeley) 4/19/94"; +static char sccsid[] = "@(#)collect.c 8.2 (Berkeley) 4/19/94"; #else -static const char rcsid[] = "$OpenBSD: collect.c,v 1.24 2002/04/08 20:27:17 millert Exp $"; +static char rcsid[] = "$OpenBSD: collect.c,v 1.6 1996/06/08 19:48:16 christos Exp $"; #endif #endif /* not lint */ @@ -52,6 +52,11 @@ #include "rcv.h" #include "extern.h" +#ifdef IOSAFE +/* to interact betzeen interrupt handlers and IO routines in fio.c */ +int got_interrupt; + +#endif /* * Read a message from standard output and return a read file to it * or NULL on error. @@ -62,37 +67,66 @@ * receipt of an interrupt signal, the partial message can be salted * away on dead.letter. */ + +static sig_t saveint; /* Previous SIGINT value */ +static sig_t savehup; /* Previous SIGHUP value */ +static sig_t savetstp; /* Previous SIGTSTP value */ +static sig_t savettou; /* Previous SIGTTOU value */ +static sig_t savettin; /* Previous SIGTTIN value */ static FILE *collf; /* File for saving away */ static int hadintr; /* Have seen one SIGINT so far */ +static jmp_buf colljmp; /* To get back to work */ +static int colljmp_p; /* whether to long jump */ +static jmp_buf collabort; /* To end collection with error */ + FILE * -collect(struct header *hp, int printheaders) +collect(hp, printheaders) + struct header *hp; + int printheaders; { FILE *fbuf; - int lc, cc, fd, c, t, lastlong, rc, sig; - int escape, eofcount, longline; + int lc, cc, escape, eofcount; + register int c, t; + char linebuf[LINESIZE], *cp; + extern char *tempMail; char getsub; - char linebuf[LINESIZE], tempname[PATHSIZE], *cp; + sigset_t oset, nset; +#if __GNUC__ + /* Avoid longjmp clobbering */ + (void) &escape; + (void) &eofcount; + (void) &getsub; +#endif collf = NULL; - eofcount = 0; - hadintr = 0; - lastlong = 0; - longline = 0; - if ((cp = value("escape")) != NULL) - escape = *cp; - else - escape = ESCAPE; - noreset++; + /* + * Start catching signals from here, but we're still die on interrupts + * until we're in the main loop. + */ + sigemptyset(&nset); + sigaddset(&nset, SIGINT); + sigaddset(&nset, SIGHUP); + sigprocmask(SIG_BLOCK, &nset, &oset); + if ((saveint = signal(SIGINT, SIG_IGN)) != SIG_IGN) + signal(SIGINT, collint); + if ((savehup = signal(SIGHUP, SIG_IGN)) != SIG_IGN) + signal(SIGHUP, collhup); + savetstp = signal(SIGTSTP, collstop); + savettou = signal(SIGTTOU, collstop); + savettin = signal(SIGTTIN, collstop); + if (setjmp(collabort) || setjmp(colljmp)) { + rm(tempMail); + goto err; + } + sigprocmask(SIG_SETMASK, &oset, NULL); - (void)snprintf(tempname, sizeof(tempname), - "%s/mail.RsXXXXXXXXXX", tmpdir); - if ((fd = mkstemp(tempname)) == -1 || - (collf = Fdopen(fd, "w+")) == NULL) { - warn("%s", tempname); + noreset++; + if ((collf = Fopen(tempMail, "w+")) == NULL) { + perror(tempMail); goto err; } - (void)rm(tempname); + unlink(tempMail); /* * If we are going to prompt for a subject, @@ -101,69 +135,68 @@ */ t = GTO|GSUBJECT|GCC|GNL; getsub = 0; - if (hp->h_subject == NULL && value("interactive") != NULL && - (value("ask") != NULL || value("asksub") != NULL)) + if (hp->h_subject == NOSTR && value("interactive") != NOSTR && + (value("ask") != NOSTR || value("asksub") != NOSTR)) t &= ~GNL, getsub++; if (printheaders) { puthead(hp, stdout, t); fflush(stdout); } - if (getsub && gethfromtty(hp, GSUBJECT) == -1) - goto err; + if ((cp = value("escape")) != NOSTR) + escape = *cp; + else + escape = ESCAPE; + eofcount = 0; + hadintr = 0; +#ifdef IOSAFE + got_interrupt = 0; +#endif - if (0) { + if (!setjmp(colljmp)) { + if (getsub) + grabh(hp, GSUBJECT); + } else { + /* + * Come here for printing the after-signal message. + * Duplicate messages won't be printed because + * the write is aborted if we get a SIGTTOU. + */ cont: - /* Come here for printing the after-suspend message. */ - if (isatty(0)) { - puts("(continue)"); + if (hadintr) { + fflush(stdout); + fprintf(stderr, + "\n(Interrupt -- one more to kill letter)\n"); + } else { + printf("(continue)\n"); fflush(stdout); } } for (;;) { - c = readline(stdin, linebuf, LINESIZE, &sig); - - /* Act on any signal caught during readline() ignoring 'c' */ - switch (sig) { - case 0: - break; - case SIGINT: - if (collabort()) - goto err; - continue; - case SIGHUP: - rewind(collf); - savedeadletter(collf); - /* - * Let's pretend nobody else wants to clean up, - * a true statement at this time. - */ - exit(1); - default: - /* Stopped due to job control */ - (void)kill(0, sig); - goto cont; - } - - /* No signal, check for error */ + colljmp_p = 1; + c = readline(stdin, linebuf, LINESIZE); +#ifdef IOSAFE + if (got_interrupt) { + got_interrupt = 0; + longjmp(colljmp,1); + } +#endif + colljmp_p = 0; if (c < 0) { - if (value("interactive") != NULL && - value("ignoreeof") != NULL && ++eofcount < 25) { - puts("Use \".\" to terminate letter"); + if (value("interactive") != NOSTR && + value("ignoreeof") != NOSTR && ++eofcount < 25) { + printf("Use \".\" to terminate letter\n"); continue; } break; } - lastlong = longline; - longline = (c == LINESIZE - 1); eofcount = 0; hadintr = 0; if (linebuf[0] == '.' && linebuf[1] == '\0' && - value("interactive") != NULL && !lastlong && - (value("dot") != NULL || value("ignoreeof") != NULL)) + value("interactive") != NOSTR && + (value("dot") != NOSTR || value("ignoreeof") != NOSTR)) break; - if (linebuf[0] != escape || value("interactive") == NULL || - lastlong) { - if (putline(collf, linebuf, !longline) < 0) + if (linebuf[0] != escape || value("interactive") == NOSTR) { + if (putline(collf, linebuf) < 0) goto err; continue; } @@ -175,12 +208,12 @@ * Otherwise, it's an error. */ if (c == escape) { - if (putline(collf, &linebuf[1], !longline) < 0) + if (putline(collf, &linebuf[1]) < 0) goto err; else break; } - puts("Unknown tilde escape."); + printf("Unknown tilde escape.\n"); break; case 'C': /* @@ -213,9 +246,8 @@ * Act like an interrupt happened. */ hadintr++; - collabort(); - fputs("Interrupt\n", stderr); - goto err; + collint(SIGINT); + exit(1); case 'h': /* * Grab a bunch of headers. @@ -250,8 +282,8 @@ hp->h_bcc = cat(hp->h_bcc, extract(&linebuf[2], GBCC)); break; case 'd': - linebuf[2] = '\0'; - strcat(linebuf, getdeadletter()); + strncpy(linebuf + 2, getdeadletter(), LINESIZE - 2); + linebuf[LINESIZE-1]='\0'; /* fall into . . . */ case 'r': case '<': @@ -264,35 +296,33 @@ while (isspace(*cp)) cp++; if (*cp == '\0') { - puts("Interpolate what file?"); + printf("Interpolate what file?\n"); break; } cp = expand(cp); - if (cp == NULL) + if (cp == NOSTR) break; if (isdir(cp)) { printf("%s: Directory\n", cp); break; } if ((fbuf = Fopen(cp, "r")) == NULL) { - warn("%s", cp); + perror(cp); break; } printf("\"%s\" ", cp); fflush(stdout); lc = 0; cc = 0; - while ((rc = readline(fbuf, linebuf, LINESIZE, NULL)) >= 0) { - if (rc != LINESIZE - 1) - lc++; - if ((t = putline(collf, linebuf, - rc != LINESIZE-1)) < 0) { - (void)Fclose(fbuf); + while (readline(fbuf, linebuf, LINESIZE) >= 0) { + lc++; + if ((t = putline(collf, linebuf)) < 0) { + Fclose(fbuf); goto err; } cc += t; } - (void)Fclose(fbuf); + Fclose(fbuf); printf("%d/%d\n", lc, cc); break; case 'w': @@ -303,10 +333,10 @@ while (*cp == ' ' || *cp == '\t') cp++; if (*cp == '\0') { - fputs("Write what file!?\n", stderr); + fprintf(stderr, "Write what file!?\n"); break; } - if ((cp = expand(cp)) == NULL) + if ((cp = expand(cp)) == NOSTR) break; rewind(collf); exwrite(cp, collf, 1); @@ -321,17 +351,17 @@ * standard list processing garbage. * If ~f is given, we don't shift over. */ - if (forward(linebuf + 2, collf, tempname, c) < 0) + if (forward(linebuf + 2, collf, c) < 0) goto err; goto cont; case '?': if ((fbuf = Fopen(_PATH_TILDE, "r")) == NULL) { - warn(_PATH_TILDE); + perror(_PATH_TILDE); break; } while ((t = getc(fbuf)) != EOF) - (void)putchar(t); - (void)Fclose(fbuf); + (void) putchar(t); + Fclose(fbuf); break; case 'p': /* @@ -339,10 +369,10 @@ * message without altering anything. */ rewind(collf); - puts("-------\nMessage contains:"); + printf("-------\nMessage contains:\n"); puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL); while ((t = getc(collf)) != EOF) - (void)putchar(t); + (void) putchar(t); goto cont; case '|': /* @@ -364,58 +394,62 @@ goto cont; } } - - if (value("interactive") != NULL) { - if (value("askcc") != NULL || value("askbcc") != NULL) { - if (value("askcc") != NULL) { - if (gethfromtty(hp, GCC) == -1) - goto err; - } - if (value("askbcc") != NULL) { - if (gethfromtty(hp, GBCC) == -1) - goto err; - } - } else { - puts("EOT"); - (void)fflush(stdout); - } - } goto out; err: if (collf != NULL) { - (void)Fclose(collf); + Fclose(collf); collf = NULL; } out: if (collf != NULL) rewind(collf); noreset--; - return(collf); + sigemptyset(&nset); + sigaddset(&nset, SIGINT); + sigaddset(&nset, SIGHUP); +#ifndef OLDBUG + sigprocmask(SIG_BLOCK, &nset, NULL); +#else + sigprocmask(SIG_BLOCK, &nset, &oset); +#endif + signal(SIGINT, saveint); + signal(SIGHUP, savehup); + signal(SIGTSTP, savetstp); + signal(SIGTTOU, savettou); + signal(SIGTTIN, savettin); + sigprocmask(SIG_SETMASK, &oset, NULL); + return collf; } /* * Write a file, ex-like if f set. */ int -exwrite(char *name, FILE *fp, int f) +exwrite(name, fp, f) + char name[]; + FILE *fp; + int f; { - FILE *of; - int c; - ssize_t cc, lc; + register FILE *of; + register int c; + long cc; + int lc; struct stat junk; if (f) { printf("\"%s\" ", name); fflush(stdout); } - if (stat(name, &junk) >= 0 && S_ISREG(junk.st_mode)) { + if (stat(name, &junk) >= 0 && (junk.st_mode & S_IFMT) == S_IFREG) { if (!f) fprintf(stderr, "%s: ", name); - fputs("File exists\n", stderr); + fprintf(stderr, "File exists\n"); return(-1); } + /* FIXME: Fopen with "w" will currently prevent writing to an existig file + (/dev/null), for now I am not sure this would even marginally useful to allow */ if ((of = Fopen(name, "w")) == NULL) { - warn(NULL); + perror(NOSTR); return(-1); } lc = 0; @@ -424,15 +458,15 @@ cc++; if (c == '\n') lc++; - (void)putc(c, of); + (void) putc(c, of); if (ferror(of)) { - warn("%s", name); - (void)Fclose(of); + perror(name); + Fclose(of); return(-1); } } - (void)Fclose(of); - printf("%d/%d\n", lc, cc); + Fclose(of); + printf("%d/%ld\n", lc, cc); fflush(stdout); return(0); } @@ -442,21 +476,19 @@ * On return, make the edit file the new temp file. */ void -mesedit(FILE *fp, int c) +mesedit(fp, c) + FILE *fp; + int c; { - FILE *nf; - struct sigaction oact; - sigset_t oset; + sig_t sigint = signal(SIGINT, SIG_IGN); + FILE *nf = run_editor(fp, (off_t)-1, c, 0); - (void)ignoresig(SIGINT, &oact, &oset); - nf = run_editor(fp, (off_t)-1, c, 0); if (nf != NULL) { fseek(nf, 0L, 2); collf = nf; - (void)Fclose(fp); + Fclose(fp); } - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void)sigaction(SIGINT, &oact, NULL); + (void) signal(SIGINT, sigint); } /* @@ -466,47 +498,44 @@ * Sh -c must return 0 to accept the new message. */ void -mespipe(FILE *fp, char *cmd) +mespipe(fp, cmd) + FILE *fp; + char cmd[]; { FILE *nf; - int fd; - char *shell, tempname[PATHSIZE]; - struct sigaction oact; - sigset_t oset; - - (void)ignoresig(SIGINT, &oact, &oset); - (void)snprintf(tempname, sizeof(tempname), - "%s/mail.ReXXXXXXXXXX", tmpdir); - if ((fd = mkstemp(tempname)) == -1 || - (nf = Fdopen(fd, "w+")) == NULL) { - warn("%s", tempname); + sig_t sigint = signal(SIGINT, SIG_IGN); + extern char *tempEdit; + char *shell; + + if ((nf = Fopen(tempEdit, "w+")) == NULL) { + perror(tempEdit); goto out; } - (void)rm(tempname); + (void) unlink(tempEdit); /* * stdin = current message. * stdout = new message. */ - shell = value("SHELL"); + if ((shell = value("SHELL")) == NOSTR) + shell = _PATH_CSHELL; if (run_command(shell, - 0, fileno(fp), fileno(nf), "-c", cmd, NULL) < 0) { - (void)Fclose(nf); + 0, fileno(fp), fileno(nf), "-c", cmd, NOSTR) < 0) { + (void) Fclose(nf); goto out; } if (fsize(nf) == 0) { fprintf(stderr, "No bytes from \"%s\" !?\n", cmd); - (void)Fclose(nf); + (void) Fclose(nf); goto out; } /* * Take new files. */ - (void)fseek(nf, 0L, 2); + (void) fseek(nf, 0L, 2); collf = nf; - (void)Fclose(fp); + (void) Fclose(fp); out: - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void)sigaction(SIGINT, &oact, NULL); + (void) signal(SIGINT, sigint); } /* @@ -518,80 +547,132 @@ * should shift over and 'f' if not. */ int -forward(char *ms, FILE *fp, char *fn, int f) +forward(ms, fp, f) + char ms[]; + FILE *fp; + int f; { - int *msgvec; + register int *msgvec; + extern char *tempMail; struct ignoretab *ig; char *tabst; - msgvec = (int *)salloc((msgCount+1) * sizeof(*msgvec)); - if (msgvec == NULL) + msgvec = (int *) salloc((msgCount+1) * sizeof *msgvec); + if (msgvec == (int *) NOSTR) return(0); if (getmsglist(ms, msgvec, 0) < 0) return(0); if (*msgvec == 0) { *msgvec = first(0, MMNORM); if (*msgvec == NULL) { - puts("No appropriate messages"); + printf("No appropriate messages\n"); return(0); } msgvec[1] = NULL; } if (f == 'f' || f == 'F') - tabst = NULL; - else if ((tabst = value("indentprefix")) == NULL) + tabst = NOSTR; + else if ((tabst = value("indentprefix")) == NOSTR) tabst = "\t"; ig = isupper(f) ? NULL : ignore; - fputs("Interpolating:", stdout); + printf("Interpolating:"); for (; *msgvec != 0; msgvec++) { struct message *mp = message + *msgvec - 1; touch(mp); printf(" %d", *msgvec); - if (sendmessage(mp, fp, ig, tabst) < 0) { - warn("%s", fn); + if (send(mp, fp, ig, tabst) < 0) { + perror(tempMail); return(-1); } } - putchar('\n'); + printf("\n"); return(0); } /* - * User aborted during message composition. - * Save the partial message in ~/dead.letter. + * Print (continue) when continued after ^Z. */ -int -collabort(void) +/*ARGSUSED*/ +void +collstop(s) + int s; +{ + sig_t old_action = signal(s, SIG_DFL); + sigset_t nset; + + sigemptyset(&nset); + sigaddset(&nset, s); + sigprocmask(SIG_UNBLOCK, &nset, NULL); + kill(0, s); + sigprocmask(SIG_BLOCK, &nset, NULL); + signal(s, old_action); + if (colljmp_p) { + colljmp_p = 0; + hadintr = 0; +#ifdef IOSAFE + got_interrupt = s; +#else + longjmp(colljmp, 1); +#endif + + } +} + + +/* + * On interrupt, come here to save the partial message in ~/dead.letter. + * Then jump out of the collection loop. + */ +/*ARGSUSED*/ +void +collint(s) + int s; { /* * the control flow is subtle, because we can be called from ~q. */ - if (hadintr == 0 && isatty(0)) { - if (value("ignore") != NULL) { + if (!hadintr) { + if (value("ignore") != NOSTR) { puts("@"); fflush(stdout); clearerr(stdin); - } else { - fflush(stdout); - fputs("\n(Interrupt -- one more to kill letter)\n", - stderr); - hadintr++; + return; } - return(0); + hadintr = 1; +#ifdef IOSAFE + got_interrupt = s; + return; +#else + longjmp(colljmp, 1); +#endif } - fflush(stdout); rewind(collf); - if (value("nosave") == NULL) + if (value("nosave") == NOSTR) savedeadletter(collf); - return(1); + longjmp(collabort, 1); } +/*ARGSUSED*/ void -savedeadletter(FILE *fp) +collhup(s) + int s; { - FILE *dbuf; - int c; + rewind(collf); + savedeadletter(collf); + /* + * Let's pretend nobody else wants to clean up, + * a true statement at this time. + */ + exit(1); +} + +void +savedeadletter(fp) + register FILE *fp; +{ + register FILE *dbuf; + register int c; char *cp; if (fsize(fp) == 0) @@ -599,23 +680,11 @@ cp = getdeadletter(); c = umask(077); dbuf = Fopen(cp, "a"); - (void)umask(c); + (void) umask(c); if (dbuf == NULL) return; while ((c = getc(fp)) != EOF) - (void)putc(c, dbuf); - (void)Fclose(dbuf); + (void) putc(c, dbuf); + Fclose(dbuf); rewind(fp); } - -int -gethfromtty(struct header *hp, int gflags) -{ - - hadintr = 0; - while (grabh(hp, gflags) != 0) { - if (collabort()) - return(-1); - } - return(0); -} diff -urN mailx-8.1.1.orig/debian/README.debian mailx-8.1.1/debian/README.debian --- mailx-8.1.1.orig/debian/README.debian 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/debian/README.debian 2003-03-26 13:03:40.000000000 -0800 @@ -0,0 +1,159 @@ +mailx for DEBIAN +---------------------- + +The history of this package is quite complicated. The changelog +includes a summary with the different maintainers. + +At the beginning of debian, I think this package was based on a BSD 5.5 mail version +from FreeBSD. + +There has been a lot on work on the package shipped with Debian +0.93R6, which was based a BSD 8.1 mail version from BSD4.4Lite. The +extensions includes support for dotfile locking, setgid support, POP +support, signal handling hacks. + +here is a README originally found: + + README for Berkely mailx version 8.1 with POP extension + + + + This is "mailx", a simple program for sending and receiving email. + + + + This is based on mailx version 8.1 (as distributed with BSD 4.4lite). + + + + It has been extended to support the post-office protocol (POP). Run + + "mail -p" and it will retrive your email from a POP server rather than + + from your local mail queue. See the manual page for more details. + + + + The POP support was written by Jonathan I. Kamens for version mailx 5.5 + + (as distributed with BSD 4.3.) + + + + The POP support was integrated into version 8.1 by Salvatore Valente + + for no particular reason. (It would have been simpler for me to + + simply use Jonathan's 5.5 source tree. There are no major differences + + between the two versions.) + + + + Have a nice day. + + -Salvatore Valente. + + 5/12/94 + + + + + + PORTING + + + + Before attempting to compile this for _any_ system, you should do two + + things: + + + + Edit CFLAGS in Makefile. + + Edit pathnames.h. + + + + These sources are _extremely_ BSDish. I have successfully built this + + for Linux, BSD 4.3, NetBSD, Ultrix, Aix, and SunOS. I have never + + successfully gotten it to build for Solaris or any System 5ish system. + + If you want to try, here are some issues you will face: + + + + It uses BSD signal() semantics. Use sigaction(). + + It uses BSD longjmp() semantics. Use siglongjmp(). + + It uses BSD sgtty. Use termios. + + It uses BSD signal mask functions. Use posix sigmask functions. + + + + There will probably be other hurdles too. Good luck. + + +With Debian1.1 a switch was done to a version base on a BSD5.5 mail +program, because of signal handling problems (which I think were due +to bad compilation options). So no more POP support. Some patches +from Ken Whang included, the corresponding +README was: + + mailx-5.5-kw 5/30/95 + + + + + + WHAT'S IN THIS PATCH + + + + There are a bunch of little features, common in System V and SunOS + + versions of mailx, that are missing from the NetBSD-based version + + distributed with Linux. This patch attempts to fill in some of what's + + missing. + + + + Changes from debian mailx-5.5 include: + + + + 5/4/95: + + + + -- interpret prompt variable + + -- interpret ~a and ~A tilde escapes + + -- updated tildehelp list + + -- changed mail.rc to ignore nothing (just my personal preference) + + -- accept From lines with times of the form hh:mm (formerly took only hh:mm:ss) + + + + 5/7/95: + + + + -- Save (S) command saves to mailbox named after author + + -- take startup commands from file named by environment variable MAILRC + + + + 5/30/95: + + + + -- -H switch for header summary only + + + + Still to be done: + + + + -- pipe ~p output through PAGER (see type1 in cmd1.c for an example) + + -- save (s) by default to MBOX (instead of "No file specified.") + + -- ~q should save to dead.letter, ~x is not known + + -- update man page + + -- allnet and showto ("showto" shows recipient instead of sender if sender + + is current user) + + + + Possibly difficult: + + + + -- interpret editheaders variable as in SunOS version + + + + Bugs: + + + + -- ~a,~A tilde escapes leave an extra trailing blank on each line + + -- to conform to original style, I should really be using char *cp + + instead of new variables sig and prompt to be looking up variables + + -- -H switch implementation is kind of gross. grep for "hdronly" in + + source files; much room for improvement! + + + + + + HOW TO INSTALL + + + + Apply Sal Valente's debian patch first, so: + + + + tar xvfz mailx-5.5.tar.gz + + cd mailx-5.5 + + zcat ../mailx-5.5.debian.diff.gz | patch -p1 + + zcat ../mailx-5.5-kw.diff.gz | patch -p1 + + make + + + + Or you may wish to just uncompress the diff file and pick and choose + + the changes that you like. + + + + + + AUTHOR + + + + Ken Whang + +This version has no provision for the debian mail policy (permission +on /var/mail+dotfile locking), so Loic Prylli + finally recreate a package based on the OpenBSD +mail with the minimum number of patches to make it suited for debian +(see changelog). There is no more POP support, nor the added +functionality from Ken Whang, but all these patches are archived, so +mail if you want them to be incorporated. + + +Loic Prylli , Mon, 23 Dec 1996 00:13:13 +0100 + + +Sat Apr 4 14:05:38 CEST 1998: +After a security patch to fix tmp races, a number of things broke. +Here is what I have tried to fix them: +The rationale is to have all file openings go through safe_open: +File opened in mode "w", "w+", are created with O_EXCL mode, + (should coincide with temporary files or new files) +Files with "a" "a+" et "r+" mode do not require the O_EXCL files. "a+" et "r+" do not creat the file. + + +Still to do: check creat calls + + + + diff -urN mailx-8.1.1.orig/debian/changelog mailx-8.1.1/debian/changelog --- mailx-8.1.1.orig/debian/changelog 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/debian/changelog 2003-03-26 13:03:40.000000000 -0800 @@ -0,0 +1,184 @@ +mailx (1:8.1.1-11) stable; urgency=medium + + * New maintainer. + * Upload to stable to fix problems introduced in the last security upgrade: + + Use the liblockfile library for mailbox locking (closes: #90446). + Patch backported from current sid version of mailx. + + Remove bashism from postinst (closes: #89642). + * Add Build-Depends field. + + -- Robert Luberda Fri, 30 Mar 2001 21:12:03 +0200 + +mailx (1:8.1.1-10.1.5) stable; urgency=high + + * Another non-maintainer upload + * If suidregister kept mail set mail setgid explain to the admin + that that is not a very good idea and offer to change it + + -- Wichert Akkerman Tue, 13 Mar 2001 15:59:55 +0100 + +mailx (1:8.1.1-10.1.4) stable; urgency=high + + * Another non-maintainer upload + * No longer install mailx setgid, the source is just too unsafe + + -- Wichert Akkerman Sat, 10 Mar 2001 00:13:22 +0100 + +mailx (1:8.1.1-10.1.3) frozen unstable; urgency=high + + * Fix the security fix: only accept a couple environment variables + instead of blindly using them all + + -- Wichert Akkerman Tue, 8 Aug 2000 11:42:02 -0700 + +mailx (1:8.1.1-10.1.2) frozen unstable; urgency=high + + * Another security problem: refuse to get the interactive variable + from the environment by explicitly setting it in the hashtable. + + -- Wichert Akkerman Mon, 7 Aug 2000 12:36:10 -0700 + +mailx (1:8.1.1-10.1.1) frozen unstable; urgency=high + + * NMU to fix RC bug. Now accepts both /var/mail and /var/spool/mail as + allowed places for setgid file manipulation. fixes:#64238 + + -- Paul Slootman Thu, 8 Jun 2000 19:51:14 +0200 + +mailx (1:8.1.1-10.1) stable frozen unstable; urgency=high + + * Security fix for a GID=mail shell. + + -- Daniel Jacobowitz Sun, 4 Jun 2000 22:45:19 -0700 + +mailx (1:8.1.1-10) frozen unstable; urgency=high + + * correct major security flaw, patch from Alvaro Martinez Echevarria + , bug#23880, bug#23901 + + * other potential buffer overflow, patch from Juan-Mariano de Goyeneche + , bug #22937 + + + -- Loic Prylli Sun, 28 Jun 1998 20:15:18 -0400 + +mailx (1:8.1.1-9) frozen unstable; urgency=high + + * recompile without the signal handling workarounds (lo + that eliminate critical bugs where message parts can be lost + (#20798) and (#20558) + + -- Loic Prylli Thu, 9 Apr 1998 02:11:26 +0200 + +mailx (1:8.1.1-8) frozen unstable; urgency=high + + * previous patch broke most file accesses, corrected safe_open (#20634) + * try to check every access to Fopen, change "a" into "w" for new files, + to suit behaviour of safe_open. + + -- Loic Prylli Sat, 4 Apr 1998 22:01:19 +0200 + +mailx (1:8.1.1-7) frozen; urgency=medium + + * security fix for tmp races patch from Martin Schulze (#20059) + + -- Loic Prylli Mon, 23 Mar 1998 22:52:35 +0100 + +mailx (1:8.1.1-6) unstable; urgency=low + + * convert to debhelper + * changelog now compressed (bug#15431) + * removed .orig and .rej from source (bug#18409) + + -- Loic Prylli Sat, 14 Feb 1998 14:34:22 +0100 + +mailx (1:8.1.1-5) unstable; urgency=low + + * apply David Brown patch so mailx choose the right window size + (#12197) + * correct Depends: in control file. + + -- Loic Prylli Sat, 15 Nov 1997 00:30:38 +0100 + +mailx (1:8.1.1-4) unstable; urgency=high + + * mailx was sending empty message, ignoring user input + add clearerr when EAGAIN occur in "IOSAFE" code (#14263) + + -- Loic Prylli Tue, 11 Nov 1997 20:22:35 +0100 + +mailx (1:8.1.1-3.1) unstable; urgency=low + + * Non-maintainer release. + * Libc6 compile. (#11705) + * Install missing symlink to manpage. (#7274) + + -- Martin Mitchell Wed, 29 Oct 1997 04:34:39 +1100 + +mailx (1:8.1.1-3) unstable; urgency=low + + * add dpkg --assert-working-epoch in preinst bug#6850 + * add writing of pid in mailbox locking file + * fix:mailx was not removing temporary lock files + + -- Loic Prylli Sat, 1 Feb 1997 11:44:04 +0100 + +mailx (1:8.1.1-2) unstable; urgency=low + + * correct bug #2733 (occur when no space left) dans quit.c + * detection of From_ lines with tring to match the date bug#2010 + * corrected garble output bug #2284 + + -- Loic Prylli Sat, 28 Dec 1996 15:02:22 +0100 + +mailx (1:8.1.1-1) unstable; urgency=medium + + * recreate completely starting from OpenBSD mail version (we loose a lot + of extension but we have a working program now) + * OpenBSD base version is the last one in december 96 + * rechange the numbering of version, so epoch 1+8.1 is from 4.4BSD, the + last upstream digit is to change each time we update to a new openbsd + version. + * fix the problem of longjmp inside signals inside stdio calls + * reincorporate a patch to be dot file locking+setgid safe + * some fix in signal handling + + -- Loic Prylli Mon, 23 Dec 1996 01:57:44 +0100 + +Mon Apr 29 17:21:42 1996 Sven Rudolph + + * releasing 8.5.5-1 + + * added symlink /usr/bin/Mail -> /usr/bin/mailx + +Thu Apr 25 23:55:36 1996 Sven Rudolph + + * set version number to 8.5.5 because it has to superseed 8.1 + + * switched back to mailx-5.5-kw (see mailx-5.5-kw.diff.README) + + * no POP support + +mailx 8.1 Debian 5 - 10/19/95 Sven Rudolph +* uses now BSD signal emulation (/usr/include/bsd/signal.h) +* added virtual package names in Depends: and Provides fields (Bug#1460) +* added Section: field +* created symlink for mailx manpage (Bug#1114) + +mailx 8.1 Debian 4 - 5/20/95 Carl Streeter +* Added diffs from Delman Lee : + + Hi! I got mailx-8.1-3 from the Linux Debian distribution, and have + added a "hold-pop" option to hold messages on the POP server after + retrieving them. (Also fixed a minor bug with mailx thinking that there + is mail even if the POP mailbox is empty. Code around stat() below.) + +mailx 8.1 Debian 3 - 4/18/95 Carl Streeter +* Fixed control file to depend on smail|sendmail. Updated to latest + guidelines + + + +Local variables: +mode: debian-changelog +End: diff -urN mailx-8.1.1.orig/debian/conffiles mailx-8.1.1/debian/conffiles --- mailx-8.1.1.orig/debian/conffiles 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/debian/conffiles 2003-03-26 13:03:40.000000000 -0800 @@ -0,0 +1 @@ +/etc/mail.rc diff -urN mailx-8.1.1.orig/debian/control mailx-8.1.1/debian/control --- mailx-8.1.1.orig/debian/control 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/debian/control 2003-03-26 13:03:41.000000000 -0800 @@ -0,0 +1,14 @@ +Source: mailx +Section: mail +Priority: important +Maintainer: Robert Luberda +Standards-Version: 2.1.1.0 +Build-Depends: debhelper (>= 2), groff, liblockfile-dev + +Package: mailx +Architecture: any +Depends: ${shlibs:Depends}, smail | mail-transport-agent +Provides: mail-reader +Description: A simple mail user agent. + mailx is the traditional command-line-mode mail user agent. + Even if you don't use it it may be required by other programmes. diff -urN mailx-8.1.1.orig/debian/copyright mailx-8.1.1/debian/copyright --- mailx-8.1.1.orig/debian/copyright 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/debian/copyright 2003-03-26 13:03:41.000000000 -0800 @@ -0,0 +1,45 @@ +This package was debianized by Loic Prylli lprylli@graville.fdn.fr on +Mon, 23 Dec 1996 00:13:13 +0100. + +It is now based on OpenBSD in directory src/usr.bin/mail on a lot of major ftp sites +See the debian.README (and changelog) for the complicated history of the debian package + +The changes from upstream involve: + - because of debian mailbox locking, some code needed to make mail setgid safe + - the original code do longjmp in the middle of IO when signals occur, + this breaks the Linux libc, so I rewrite some IO loops. + + +Copyright: + + Copyright (c) 1980, 1993 + The Regents of the University of California. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by the University of + California, Berkeley and its contributors. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + diff -urN mailx-8.1.1.orig/debian/dirs mailx-8.1.1/debian/dirs --- mailx-8.1.1.orig/debian/dirs 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/debian/dirs 2003-03-26 13:03:41.000000000 -0800 @@ -0,0 +1,4 @@ +usr/bin +usr/man/man1 +usr/lib +etc diff -urN mailx-8.1.1.orig/debian/postinst mailx-8.1.1/debian/postinst --- mailx-8.1.1.orig/debian/postinst 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/debian/postinst 2003-03-26 13:03:41.000000000 -0800 @@ -0,0 +1,43 @@ +#! /bin/sh + +set -e + +#DEBHELPER# + +[ "$1" = "configure" ] || exit 0 + +# We only need to ask about removing the setgid bit if the previous version +# of this package did not ask. This prevents us from asking the same question +# on every upgrade +dpkg --compare-versions "$2" ge "1:8.1.1-10.1.5" && exit 0 + +if [ -g /usr/bin/mail ] ; then + echo "Your /usr/bin/mail application is currently setgid mail." + echo "This is needed to properly lock your mailbox if you use mail" + echo "to read your email. However, mail is not written to be a secure" + echo "probably so local users might be able to use it to gain access" + echo "to email from other users." + echo + echo "It is therefore recommended to make mail non-setgid and use" + echo "another program like elm or mutt to read email." + echo + while : ; do + echo -n "Should I make this change [Y/n]? " + read a + if test -z "$a" -o "$a" = "Y" -o "$a" = "y" ; then + # Please note we don't check for suidregster presence, + # since mail can only still be setgid of suidregister + # did that. + suidregister -s mailx /usr/bin/mail root root 0755 + break + elif test "$a" = "N" -o "$a" = "n" ; then + break + fi + echo + echo "Illegal answer!" + echo + done +fi + +exit 0 + diff -urN mailx-8.1.1.orig/debian/preinst mailx-8.1.1/debian/preinst --- mailx-8.1.1.orig/debian/preinst 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/debian/preinst 2003-03-26 13:03:41.000000000 -0800 @@ -0,0 +1,8 @@ +#!/bin/sh + +set -e + +dpkg --assert-working-epoch 2>/dev/null || { + echo -e "\nYou must upgrade dpkg before installing this package.\n" + false +} diff -urN mailx-8.1.1.orig/debian/rules mailx-8.1.1/debian/rules --- mailx-8.1.1.orig/debian/rules 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/debian/rules 2003-03-26 13:03:41.000000000 -0800 @@ -0,0 +1,83 @@ +#!/usr/bin/make -f +# Sample debian.rules file - for GNU Hello (1.3). +# Copyright 1994,1995 by Ian Jackson. +# I hereby give you perpetual unlimited permission to copy, +# modify and relicense this file, provided that you do not remove +# my name from the file itself. (I assert my moral right of +# paternity under the Copyright, Designs and Patents Act 1988.) +# This file may have to be extensively modified +# + +package=mailx + +CFLAGS=-O2 +CC=gcc + +build: + dh_testdir + make CFLAGS="$(CFLAGS)" CC="$(CC)" + cd USD.doc && make + touch build + +clean: + dh_testdir + dh_testroot + -rm -f build + -make clean + -rm USD.doc/manual.ps + dh_clean + +binary-indep: build +# There are no architecture-independent files to be uploaded +# generated by this package. If there were any they would be +# made here. + +binary-arch: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + make install DESTDIR=`pwd`/debian/tmp + cd debian/tmp/usr/bin && ln -fs mail mailx + cd debian/tmp/usr/bin && ln -fs mail Mail +# if no debstd, uncomment following lines (taken from Martin Mitchell) +# install -d debian/tmp/usr/doc/mailx debian/tmp/DEBIAN +# gzip -9v debian/tmp/usr/man/man1/* +# cd debian/tmp/usr/man/man1 && ln -fs mail.1.gz mailx.1.gz +# cd debian/tmp/usr/man/man1 && ln -fs mail.1.gz Mail.1.gz +# cp debian/changelog debian/README.debian USD.doc/manual.ps debian/tmp/usr/doc/mailx +# gzip -9v debian/tmp/usr/doc/mailx/* +# cp debian/copyright debian/tmp/usr/doc/mailx +# cp debian/{control,conffiles,preinst} debian/tmp/DEBIAN +# dpkg-shlibdeps debian/tmp/usr/bin/mail +# Must have debmake installed for this to work. Otherwise please copy +# /usr/bin/debstd into the debian directory and change debstd to debian/debstd + cd debian/tmp/usr/man/man1 && ln -fs mail.1 mailx.1 + cd debian/tmp/usr/man/man1 && ln -fs mail.1 Mail.1 + dh_installdocs USD.doc/manual.ps +# dh_installexamples +# dh_installmenu +# dh_installcron +# dh_installmanpages + dh_installchangelogs + dh_strip + dh_compress + dh_fixperms + dh_suidregister /usr/bin/mail + dh_installdeb + dh_shlibdeps + dh_gencontrol +# dh_makeshlibs + dh_md5sums + dh_builddeb + +# Below here is fairly generic really + +binary: binary-indep binary-arch + + +.PHONY: binary binary-arch binary-indep clean + +# Local Variables: +# mode: makefile +# End variables diff -urN mailx-8.1.1.orig/def.h mailx-8.1.1/def.h --- mailx-8.1.1.orig/def.h 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/def.h 1996-06-14 01:26:58.000000000 -0700 @@ -1,6 +1,5 @@ -/* $OpenBSD: def.h,v 1.10 2002/02/16 21:27:48 millert Exp $ */ -/* $NetBSD: def.h,v 1.9 1996/12/28 07:11:00 tls Exp $ */ - +/* $OpenBSD: def.h,v 1.8 1996/06/08 19:48:18 christos Exp $ */ +/* $NetBSD: def.h,v 1.8 1996/06/08 19:48:18 christos Exp $ */ /* * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. @@ -33,8 +32,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)def.h 8.4 (Berkeley) 4/20/95 - * $OpenBSD: def.h,v 1.10 2002/02/16 21:27:48 millert Exp $ + * @(#)def.h 8.2 (Berkeley) 3/21/94 + * $NetBSD: def.h,v 1.8 1996/06/08 19:48:18 christos Exp $ */ /* @@ -43,21 +42,17 @@ * Author: Kurt Shoens (UCB) March 25, 1978 */ -#ifndef MAIL_DEF_H -#define MAIL_DEF_H - #include #include #include -#include -#include #include -#include -#include -#include #include #include +#include +#include +#include +#include #include "pathnames.h" #define APPEND /* New mail goes to end of mailbox */ @@ -69,21 +64,23 @@ #define LINESIZE BUFSIZ /* max readable line width */ #define STRINGSIZE ((unsigned) 128)/* Dynamic allocation units */ #define MAXARGC 1024 /* Maximum list of raw strings */ +#define NOSTR ((char *) 0) /* Null string pointer */ #define MAXEXP 25 /* Maximum expansion of aliases */ #define equal(a, b) (strcmp(a,b)==0)/* A nice function to string compare */ struct message { short m_flag; /* flags, see below */ - int m_offset; /* offset in block of message */ - int m_block; /* block number of this message */ - int m_size; /* Bytes in the message */ - int m_lines; /* Lines in the message */ + short m_block; /* block number of this message */ + short m_offset; /* offset in block of message */ + long m_size; /* Bytes in the message */ + short m_lines; /* Lines in the message */ }; /* * flag bits. */ + #define MUSED (1<<0) /* entry is used, but this bit isn't */ #define MDELETED (1<<1) /* entry has been deleted */ #define MSAVED (1<<2) /* entry has been saved */ @@ -110,42 +107,39 @@ */ struct cmd { char *c_name; /* Name of command */ - union { - int (*c_func0)(); - int (*c_func1)(void *); - int (*c_func2)(void *, void *); - } cfunc; /* Implementor of the command */ -#define c_func cfunc.c_func1 -#define c_func2 cfunc.c_func2 + int (*c_func) __P((void *));/* Implementor of the command */ short c_argtype; /* Type of arglist (see below) */ short c_msgflag; /* Required flags of messages */ short c_msgmask; /* Relevant flags of messages */ }; /* Yechh, can't initialize unions */ + #define c_minargs c_msgflag /* Minimum argcount for RAWLIST */ #define c_maxargs c_msgmask /* Max argcount for RAWLIST */ /* * Argument types. */ -#define MSGLIST 0x0001 /* Message list type */ -#define STRLIST 0x0002 /* A pure string */ -#define RAWLIST 0x0004 /* Shell string list */ -#define NOLIST 0x0008 /* Just plain 0 */ -#define NDMLIST 0x0010 /* Message list, no defaults */ - -#define P 0x0020 /* Autoprint dot after command */ -#define I 0x0040 /* Interactive command bit */ -#define M 0x0080 /* Legal from send mode bit */ -#define W 0x0100 /* Illegal when read only bit */ -#define F 0x0200 /* Is a conditional command */ -#define T 0x0400 /* Is a transparent command */ -#define R 0x0800 /* Cannot be called from collect */ + +#define MSGLIST 0 /* Message list type */ +#define STRLIST 1 /* A pure string */ +#define RAWLIST 2 /* Shell string list */ +#define NOLIST 3 /* Just plain 0 */ +#define NDMLIST 4 /* Message list, no defaults */ + +#define P 040 /* Autoprint dot after command */ +#define I 0100 /* Interactive command bit */ +#define M 0200 /* Legal from send mode bit */ +#define W 0400 /* Illegal when read only bit */ +#define F 01000 /* Is a conditional command */ +#define T 02000 /* Is a transparent command */ +#define R 04000 /* Cannot be called from collect */ /* * Oft-used mask values */ + #define MMNORM (MDELETED|MSAVED)/* Look at both save and delete bits */ #define MMNDEL MDELETED /* Look only at deleted bit */ @@ -153,6 +147,7 @@ * Structure used to return a break down of a head * line (hats off to Bill Joy!) */ + struct headline { char *l_from; /* The name of the sender */ char *l_tty; /* His tty string (if any) */ @@ -174,6 +169,7 @@ * Structure used to pass about the current * state of the user-typed message header. */ + struct header { struct name *h_to; /* Dynamic "To:" string */ char *h_subject; /* Subject string */ @@ -187,6 +183,7 @@ * the recipients of mail and aliases and all that * kind of stuff. */ + struct name { struct name *n_flink; /* Forward link in list. */ struct name *n_blink; /* Backward list link */ @@ -217,6 +214,12 @@ struct group *g_list; /* Users in group. */ }; +#define NIL ((struct name *) 0) /* The nil pointer for namelists */ +#define NONE ((struct cmd *) 0) /* The nil pointer to command tab */ +#define NOVAR ((struct var *) 0) /* The nil pointer to variables */ +#define NOGRP ((struct grouphead *) 0)/* The nil grouphead pointer */ +#define NOGE ((struct group *) 0) /* The nil group pointer */ + /* * Structure of the hash table of ignored header fields */ @@ -232,6 +235,7 @@ * Token values returned by the scanner used for argument lists. * Also, sizes of scanner-related things. */ + #define TEOL 0 /* End of the command line */ #define TNUMBER 1 /* A message number */ #define TDASH 2 /* A simple dash */ @@ -249,21 +253,27 @@ #define STRINGLEN 1024 /* Maximum length of string token */ /* - * Constants for conditional commands. - * These describe whether we should be executing stuff or not. + * Constants for conditional commands. These describe whether + * we should be executing stuff or not. */ + #define CANY 0 /* Execute in send or receive mode */ #define CRCV 1 /* Execute in receive mode only */ #define CSEND 2 /* Execute in send mode only */ /* + * Kludges to handle the change from setexit / reset to setjmp / longjmp + */ + +#define setexit() setjmp(srbuf) +#define reset(x) longjmp(srbuf, x) + +/* * Truncate a file to the last character written. This is * useful just before closing an old file that was opened * for read/write. */ -#define trunc(stream) do { \ +#define trunc(stream) { \ (void)fflush(stream); \ (void)ftruncate(fileno(stream), (off_t)ftell(stream)); \ -} while(0) - -#endif /* MAIL_DEF_H */ +} diff -urN mailx-8.1.1.orig/dotlock.c mailx-8.1.1/dotlock.c --- mailx-8.1.1.orig/dotlock.c 1969-12-31 16:00:00.000000000 -0800 +++ mailx-8.1.1/dotlock.c 2003-03-26 13:03:39.000000000 -0800 @@ -0,0 +1,236 @@ +/* $OpenBSD: dotlock.c,v 1.1 1996/06/08 19:48:19 christos Exp $ */ +/* $NetBSD: dotlock.c,v 1.1 1996/06/08 19:48:19 christos Exp $ */ + +/* + * Copyright (c) 1996 Christos Zoulas. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christos Zoulas. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef lint +static char rcsid[] = "$OpenBSD: dotlock.c,v 1.1 1996/06/08 19:48:19 christos Exp $"; +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" +#include "rcv.h" + +#ifndef O_SYNC +#define O_SYNC 0 +#endif + +/* + * Set the gid if the path is in the normal mail spool + */ +static int perhaps_setgid (name, gid) +char *name; +gid_t gid; +{ + char safelist[] = _PATH_MAILDIR; + char *safepath, *p = safelist; + int len; + + while ((safepath = strtok(p, ":"))) { + p = 0; + len = strlen(safepath); + if (strncmp (name, safepath, len) == 0 && name[len] == '/') + return (setgid (gid)); + } + return 0; +} + + +static int create_exclusive __P((const char *)); +/* + * Create a unique file. O_EXCL does not really work over NFS so we follow + * the following trick: [Inspired by S.R. van den Berg] + * + * - make a mostly unique filename and try to create it. + * - link the unique filename to our target + * - get the link count of the target + * - unlink the mostly unique filename + * - if the link count was 2, then we are ok; else we've failed. + */ +static int +create_exclusive(fname) + const char *fname; +{ + char path[MAXPATHLEN], hostname[MAXHOSTNAMELEN]; + char apid[40]; /* sufficient for storign 128 bits pids */ + const char *ptr; + struct timeval tv; + pid_t pid; + size_t ntries, cookie; + int fd, serrno, cc; + struct stat st; + + (void) gettimeofday(&tv, NULL); + (void) gethostname(hostname, MAXHOSTNAMELEN); + pid = getpid(); + + cookie = pid ^ tv.tv_usec; + + /* + * We generate a semi-unique filename, from hostname.(pid ^ usec) + */ + if ((ptr = strrchr(fname, '/')) == NULL) + ptr = fname; + else + ptr++; + + (void) snprintf(path, sizeof(path), "%.*s.%s.%x", + ptr - fname, fname, hostname, cookie); + + + /* + * We try to create the unique filename. + */ + for (ntries = 0; ntries < 5; ntries++) { + perhaps_setgid(path, effectivegid); + fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_SYNC, 0); + setgid(realgid); + if (fd != -1) { + sprintf(apid,"%d",getpid()); + write(fd, apid, strlen(apid)); + (void) close(fd); + break; + } + else if (errno == EEXIST) + continue; + else + return -1; + } + /* + * We link the path to the name + */ + perhaps_setgid(fname, effectivegid); + cc = link(path, fname); + setgid(realgid); + + if (cc == -1) + goto bad; + + /* + * Note that we stat our own exclusively created name, not the + * destination, since the destination can be affected by others. + */ + if (stat(path, &st) == -1) + goto bad; + + perhaps_setgid(fname, effectivegid); + (void) unlink(path); + setgid(realgid); + + /* + * If the number of links was two (one for the unique file and one + * for the lock), we've won the race + */ + if (st.st_nlink != 2) { + errno = EEXIST; + return -1; + } + return 0; + +bad: + serrno = errno; + (void) unlink(path); + errno = serrno; + return -1; +} + +int +dot_lock(fname, pollinterval, fp, msg) + const char *fname; /* Pathname to lock */ + int pollinterval; /* Interval to check for lock, -1 return */ + FILE *fp; /* File to print message */ + const char *msg; /* Message to print */ +{ + char path[MAXPATHLEN]; + sigset_t nset, oset; + int i; + + sigemptyset(&nset); + sigaddset(&nset, SIGHUP); + sigaddset(&nset, SIGINT); + sigaddset(&nset, SIGQUIT); + sigaddset(&nset, SIGTERM); + sigaddset(&nset, SIGTTIN); + sigaddset(&nset, SIGTTOU); + sigaddset(&nset, SIGTSTP); + sigaddset(&nset, SIGCHLD); + + (void) snprintf(path, sizeof(path), "%s.lock", fname); + + for (i=0;i<15;i++) { + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + if (create_exclusive(path) != -1) { + (void) sigprocmask(SIG_SETMASK, &oset, NULL); + return 0; + } + else + (void) sigprocmask(SIG_SETMASK, &oset, NULL); + + if (errno != EEXIST) + return -1; + + if (fp && msg) + (void) fputs(msg, fp); + + if (pollinterval) { + if (pollinterval == -1) { + errno = EEXIST; + return -1; + } + sleep(pollinterval); + } + } + fprintf(stderr,"%s seems a stale lock? Need to be removed by hand?\n",path); + return -1; +} + +void +dot_unlock(fname) + const char *fname; +{ + char path[MAXPATHLEN]; + + (void) snprintf(path, sizeof(path), "%s.lock", fname); + perhaps_setgid(path, effectivegid); + (void) unlink(path); + setgid(realgid); +} diff -urN mailx-8.1.1.orig/edit.c mailx-8.1.1/edit.c --- mailx-8.1.1.orig/edit.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/edit.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,4 +1,4 @@ -/* $OpenBSD: edit.c,v 1.11 2001/11/21 15:26:39 millert Exp $ */ +/* $OpenBSD: edit.c,v 1.5 1996/06/08 19:48:20 christos Exp $ */ /* $NetBSD: edit.c,v 1.5 1996/06/08 19:48:20 christos Exp $ */ /* @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)edit.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)edit.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: edit.c,v 1.11 2001/11/21 15:26:39 millert Exp $"; +static char rcsid[] = "$OpenBSD: edit.c,v 1.5 1996/06/08 19:48:20 christos Exp $"; #endif #endif /* not lint */ @@ -56,22 +56,24 @@ * Edit a message list. */ int -editor(void *v) +editor(v) + void *v; { int *msgvec = v; - return(edit1(msgvec, 'e')); + return edit1(msgvec, 'e'); } /* * Invoke the visual editor on a message list. */ int -visual(void *v) +visual(v) + void *v; { int *msgvec = v; - return(edit1(msgvec, 'v')); + return edit1(msgvec, 'v'); } /* @@ -80,25 +82,28 @@ * We get the editor from the stuff above. */ int -edit1(int *msgvec, int type) +edit1(msgvec, type) + int *msgvec; + int type; { - int c, i; + register int c; + int i; FILE *fp; - struct sigaction oact; - sigset_t oset; - struct message *mp; + register struct message *mp; off_t size; /* * Deal with each message to be edited . . . */ for (i = 0; msgvec[i] && i < msgCount; i++) { + sig_t sigint; + if (i > 0) { char buf[100]; char *p; printf("Edit message %d [ynq]? ", msgvec[i]); - if (fgets(buf, sizeof(buf), stdin) == 0) + if (fgets(buf, sizeof buf, stdin) == 0) break; for (p = buf; *p == ' ' || *p == '\t'; p++) ; @@ -109,10 +114,10 @@ } dot = mp = &message[msgvec[i] - 1]; touch(mp); - (void)ignoresig(SIGINT, &oact, &oset); + sigint = signal(SIGINT, SIG_IGN); fp = run_editor(setinput(mp), mp->m_size, type, readonly); if (fp != NULL) { - (void)fseek(otf, 0L, 2); + (void) fseek(otf, 0L, 2); size = ftell(otf); mp->m_block = blockof(size); mp->m_offset = offsetof(size); @@ -127,13 +132,12 @@ break; } if (ferror(otf)) - warn("/tmp"); - (void)Fclose(fp); + perror("/tmp"); + (void) Fclose(fp); } - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void)sigaction(SIGINT, &oact, NULL); + (void) signal(SIGINT, sigint); } - return(0); + return 0; } /* @@ -143,55 +147,56 @@ * "Type" is 'e' for _PATH_EX, 'v' for _PATH_VI. */ FILE * -run_editor(FILE *fp, off_t size, int type, int readonly) +run_editor(fp, size, type, readonly) + register FILE *fp; + off_t size; + int type, readonly; { - FILE *nf = NULL; - int t; + register FILE *nf = NULL; + register int t; time_t modtime; - char *edit, tempname[PATHSIZE]; + char *edit; struct stat statb; + extern char *tempEdit; - (void)snprintf(tempname, sizeof(tempname), - "%s/mail.ReXXXXXXXXXX", tmpdir); - if ((t = mkstemp(tempname)) == -1 || - (nf = Fdopen(t, "w")) == NULL) { - warn("%s", tempname); + if ((t = open(tempEdit, O_CREAT|O_WRONLY|O_EXCL, readonly ? 0400 : 0600)) < 0) { + perror(tempEdit); goto out; } - if (readonly && fchmod(t, 0400) == -1) { - warn("%s", tempname); - (void)rm(tempname); + if ((nf = Fdopen(t, "w")) == NULL) { + perror(tempEdit); + (void) unlink(tempEdit); goto out; } if (size >= 0) while (--size >= 0 && (t = getc(fp)) != EOF) - (void)putc(t, nf); + (void) putc(t, nf); else while ((t = getc(fp)) != EOF) - (void)putc(t, nf); - (void)fflush(nf); + (void) putc(t, nf); + (void) fflush(nf); if (fstat(fileno(nf), &statb) < 0) modtime = 0; else modtime = statb.st_mtime; if (ferror(nf)) { - (void)Fclose(nf); - warn("%s", tempname); - (void)rm(tempname); + (void) Fclose(nf); + perror(tempEdit); + (void) unlink(tempEdit); nf = NULL; goto out; } if (Fclose(nf) < 0) { - warn("%s", tempname); - (void)rm(tempname); + perror(tempEdit); + (void) unlink(tempEdit); nf = NULL; goto out; } nf = NULL; - if ((edit = value(type == 'e' ? "EDITOR" : "VISUAL")) == NULL) + if ((edit = value(type == 'e' ? "EDITOR" : "VISUAL")) == NOSTR) edit = type == 'e' ? _PATH_EX : _PATH_VI; - if (run_command(edit, 0, 0, -1, tempname, NULL, NULL) < 0) { - (void)rm(tempname); + if (run_command(edit, 0, -1, -1, tempEdit, NOSTR, NOSTR) < 0) { + (void) unlink(tempEdit); goto out; } /* @@ -199,26 +204,26 @@ * temporary and return. */ if (readonly) { - (void)rm(tempname); + (void) unlink(tempEdit); goto out; } - if (stat(tempname, &statb) < 0) { - warn("%s", tempname); + if (stat(tempEdit, &statb) < 0) { + perror(tempEdit); goto out; } if (modtime == statb.st_mtime) { - (void)rm(tempname); + (void) unlink(tempEdit); goto out; } /* * Now switch to new file. */ - if ((nf = Fopen(tempname, "a+")) == NULL) { - warn("%s", tempname); - (void)rm(tempname); + if ((nf = Fopen(tempEdit, "a+")) == NULL) { + perror(tempEdit); + (void) unlink(tempEdit); goto out; } - (void)rm(tempname); + (void) unlink(tempEdit); out: - return(nf); + return nf; } diff -urN mailx-8.1.1.orig/extern.h mailx-8.1.1/extern.h --- mailx-8.1.1.orig/extern.h 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/extern.h 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: extern.h,v 1.20 2001/11/28 01:26:35 millert Exp $ */ -/* $NetBSD: extern.h,v 1.7 1997/07/09 05:22:00 mikel Exp $ */ +/* $OpenBSD: extern.h,v 1.4 1996/06/08 19:48:21 christos Exp $ */ +/* $NetBSD: extern.h,v 1.4 1996/06/08 19:48:21 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -33,242 +33,233 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)extern.h 8.2 (Berkeley) 4/20/95 - * $OpenBSD: extern.h,v 1.20 2001/11/28 01:26:35 millert Exp $ + * @(#)extern.h 8.1 (Berkeley) 6/6/93 + * $NetBSD: extern.h,v 1.4 1996/06/08 19:48:21 christos Exp $ */ struct name; -struct name *cat(struct name *, struct name *); -struct name *delname(struct name *, char *); -struct name *elide(struct name *); -struct name *extract(char *, int); +struct name *cat __P((struct name *, struct name *)); +struct name *delname __P((struct name *, char [])); +struct name *elide __P((struct name *)); +struct name *extract __P((char [], int)); struct grouphead; -struct name *gexpand(struct name *, struct grouphead *, int, int); -struct name *nalloc(char *, int); +struct name *gexpand __P((struct name *, struct grouphead *, int, int)); +struct name *nalloc __P((char [], int)); struct header; -struct name *outof(struct name *, FILE *, struct header *); -struct name *put(struct name *, struct name *); -struct name *tailof(struct name *); -struct name *usermap(struct name *); -FILE *Fdopen(int, char *); -FILE *Fopen(char *, char *); -FILE *Popen(char *, char *); -FILE *collect(struct header *, int); -char *copy(char *, char *); -char *copyin(char *, char **); -char *detract(struct name *, int); -char *expand(char *); -char *getdeadletter(void); -char *getname(uid_t); +struct name *outof __P((struct name *, FILE *, struct header *)); +struct name *put __P((struct name *, struct name *)); +struct name *tailof __P((struct name *)); +struct name *usermap __P((struct name *)); +FILE *safe_fopen __P((char *, char *)); +FILE *Fdopen __P((int, char *)); +FILE *Fopen __P((char *, char *)); +FILE *Popen __P((char *, char *)); +FILE *collect __P((struct header *, int)); +char *copy __P((char *, char *)); +char *copyin __P((char *, char **)); +char *detract __P((struct name *, int)); +char *expand __P((char *)); +char *getdeadletter __P((void)); +char *getname __P((int)); struct message; -char *hfield(char *, struct message *); -FILE *infix(struct header *, FILE *); -char *ishfield(char *, char *, char *); -char *name1(struct message *, int); -char *nameof(struct message *, int); -char *nextword(char *, char *); -char *readtty(char *, char *); -char *reedit(char *); -FILE *run_editor(FILE *, off_t, int, int); -char *salloc(int); -char *savestr(char *); -FILE *setinput(struct message *); -char *skin(char *); -char *skip_comment(char *); -char *snarf(char *, int *); -char *username(void); -char *value(char *); -char *vcopy(char *); -char *yankword(char *, char *); -int Fclose(FILE *); -int More(void *); -int Pclose(FILE *); -int Respond(void *); -int Type(void *); -int _Respond(int *); -int _respond(int *); -void alter(char *); -int alternates(void *); -void announce(void); -int append(struct message *, FILE *); -int argcount(char **); -void assign(char *, char *); -int bangexp(char *, size_t); -int blankline(char *); -int charcount(char *, int); -int check(int, int); -void clearnew(void); -void clob1(int); -int clobber(void *); -void close_all_files(void); -int cmatch(char *, char *); -int collabort(void); -void commands(void); -int copycmd(void *); -int core(void *); -int count(struct name *); -int delete(void *); -int delm(int *); -int deltype(void *); -void demail(void); -void dointr(void); -int dosh(void *); -int dot_lock(const char *, int, FILE *, const char *); -void dot_unlock(const char *); -int echo(void *); -int edit1(int *, int); -int editor(void *); -int edstop(void); -int elsecmd(void *); -int endifcmd(void *); -int evalcol(int); -int execute(char *, int); -int exwrite(char *, FILE *, int); -void fail(char *, char *); -int file(void *); +char *hfield __P((char [], struct message *)); +FILE *infix __P((struct header *, FILE *)); +char *ishfield __P((char [], char[], char *)); +char *name1 __P((struct message *, int)); +char *nameof __P((struct message *, int)); +char *nextword __P((char *, char *)); +char *readtty __P((char [], char [])); +char *reedit __P((char *)); +FILE *run_editor __P((FILE *, off_t, int, int)); +char *salloc __P((int)); +char *savestr __P((char *)); +FILE *setinput __P((struct message *)); +char *skin __P((char *)); +char *skip_comment __P((char *)); +char *snarf __P((char [], int *)); +char *username __P((void)); +char *value __P((char [])); +char *vcopy __P((char [])); +char *yankword __P((char *, char [], int)); +int Fclose __P((FILE *)); +int More __P((void *)); +int Pclose __P((FILE *)); +int Respond __P((void *)); +int Type __P((void *)); +int _Respond __P((int [])); +int _respond __P((int *)); +void alter __P((char *)); +int alternates __P((void *)); +void announce __P((void)); +int anyof __P((char *, char *)); +int append __P((struct message *, FILE *)); +int argcount __P((char **)); +void assign __P((char [], char [])); +int bangexp __P((char *, int)); +int blankline __P((char [])); +void brokpipe __P((int)); +int charcount __P((char *, int)); +int check __P((int, int)); +void clob1 __P((int)); +int clobber __P((void *)); +void close_all_files __P((void)); +int cmatch __P((char *, char *)); +void collhup __P((int)); +void collint __P((int)); +void collstop __P((int)); +void commands __P((void)); +int copycmd __P((void *)); +int core __P((void *)); +int count __P((struct name *)); +int delete __P((void *)); +int delm __P((int [])); +int deltype __P((void *)); +void demail __P((void)); +int dosh __P((void *)); +int spool_lock __P((const char *)); +int spool_unlock __P((const char *)); +int echo __P((void *)); +int edit1 __P((int *, int)); +int editor __P((void *)); +void edstop __P((void)); +int elsecmd __P((void *)); +int endifcmd __P((void *)); +int evalcol __P((int)); +int execute __P((char [], int)); +int exwrite __P((char [], FILE *, int)); +void fail __P((char [], char [])); +int file __P((void *)); struct grouphead * - findgroup(char *); -void findmail(char *, char *, int); -void fioint(int); -int first(int, int); -void fixhead(struct header *, struct name *); -void fmt(char *, struct name *, FILE *, int); -int folders(void *); -int forward(char *, FILE *, char *, int); -void free_child(pid_t); -int from(void *); -off_t fsize(FILE *); -int getfold(char *, int); -int gethfield(FILE *, char *, int, char **); -int gethfromtty(struct header *, int); -int getmsglist(char *, int *, int); -int getrawlist(char *, char **, int); -uid_t getuserid(char *); -int grabh(struct header *, int); -int group(void *); -int hash(char *); -void hdrint(int); -int headers(void *); -int help(void *); -void holdsigs(void); -int ifcmd(void *); -int igfield(void *); + findgroup __P((char [])); +void findmail __P((char *, char *, int)); +int first __P((int, int)); +void fixhead __P((struct header *, struct name *)); +void fmt __P((char *, struct name *, FILE *, int)); +int folders __P((void *)); +int forward __P((char [], FILE *, int)); +void free_child __P((int)); +int from __P((void *)); +off_t fsize __P((FILE *)); +int getfold __P((char *, int)); +int gethfield __P((FILE *, char [], int, char **)); +int getmsglist __P((char *, int *, int)); +int getrawlist __P((char [], char **, int)); +int getuserid __P((char [])); +int grabh __P((struct header *, int)); +int group __P((void *)); +void hangup __P((int)); +int hash __P((char *)); +void hdrstop __P((int)); +int headers __P((void *)); +int help __P((void *)); +void holdsigs __P((void)); +int ifcmd __P((void *)); +int igfield __P((void *)); struct ignoretab; -int ignore1(char **, struct ignoretab *, char *); -int ignoresig(int, struct sigaction *, sigset_t *); -int igshow(struct ignoretab *, char *); -void intr(int); -int inc(void *); -int incfile(void); -int isdate(char *); -int isdir(char *); -int isfileaddr(char *); -int ishead(char *); -int isign(char *, struct ignoretab *); -int isprefix(char *, char *); -size_t istrlcpy(char *, const char *, size_t); +int ignore1 __P((char *[], struct ignoretab *, char *)); +int igshow __P((struct ignoretab *, char *)); +void intr __P((int)); +int isdate __P((char [])); +int isdir __P((char [])); +int isfileaddr __P((char *)); +int ishead __P((char [])); +int isign __P((char *, struct ignoretab [])); +int isprefix __P((char *, char *)); +void istrcpy __P((char *, char *, int)); const struct cmd * - lex(char *); -void load(char *); + lex __P((char [])); +void load __P((char *)); struct var * - lookup(char *); -int mail (struct name *, struct name *, struct name *, struct name *, - char *); -void mail1(struct header *, int); -void makemessage(FILE *, int); -void mark(int); -int markall(char *, int); -int marknew(void *); -int matchsender(char *, int); -int matchsubj(char *, int); -int mboxit(void *); -int member(char *, struct ignoretab *); -void mesedit(FILE *, int); -void mespipe(FILE *, char *); -int messize(void *); -int metamess(int, int); -int more(void *); -int newfileinfo(int); -int next(void *); -int null(void *); + lookup __P((char [])); +int mail __P((struct name *, + struct name *, struct name *, struct name *, char *)); +void mail1 __P((struct header *, int)); +void makemessage __P((FILE *)); +void mark __P((int)); +int markall __P((char [], int)); +int matchsender __P((char *, int)); +int matchsubj __P((char *, int)); +int mboxit __P((void *)); +int member __P((char *, struct ignoretab *)); +void mesedit __P((FILE *, int)); +void mespipe __P((FILE *, char [])); +int messize __P((void *)); +int metamess __P((int, int)); +int more __P((void *)); +int newfileinfo __P((void)); +int next __P((void *)); +int null __P((void *)); +void panic __P((const char *, ...)) + __attribute__((__format__(__printf__,1,2),__noreturn__)); struct headline; -void parse(char *, struct headline *, char *); -int pcmdlist(void *); -int pdot(void *); -int pipeit(void *, void *); -void prepare_child(sigset_t *, int, int); -int preserve(void *); -void prettyprint(struct name *); -void printgroup(char *); -void printhead(int); -int puthead(struct header *, FILE *, int); -int putline(FILE *, char *, int); -int pversion(void *); -int quit(void); -int quitcmd(void *); -int raise(int); -int readline(FILE *, char *, int, int *); -void register_file(FILE *, int, pid_t); -void regret(int); -void relsesigs(void); -int respond(void *); -int retfield(void *); -int rexit(void *); -int rm(char *); -int run_command(char *cmd, sigset_t *nset, int infd, int outfd, ...); -int save(void *); -int save1(char *, int, char *, struct ignoretab *); -void savedeadletter(FILE *); -int saveigfield(void *); -int savemail(char *, FILE *); -int saveretfield(void *); -int scan(char **); -void scaninit(void); -int schdir(void *); -int screensize(void); -int scroll(void *); -void sendint(int); -int sendmessage(struct message *, FILE *, struct ignoretab *, char *); -int sendmail(void *); -int set(void *); -int setfile(char *); -void setmsize(int); -void setptr(FILE *, off_t); -void setscreensize(void); -int shell(void *); -void sigchild(int); -void sort(char **); -int source(void *); -int spool_lock(void); -int spool_unlock(void); -void spreserve(void); -void sreset(void); -pid_t start_command(char *cmd, sigset_t *nset, int infd, int outfd, ...); -pid_t start_commandv(char *, sigset_t *, int, int, __gnuc_va_list); -int statusput(struct message *, FILE *, char *); -void stop(int); -int stouch(void *); -int swrite(void *); -void tinit(void); -int top(void *); -void touch(struct message *); -void ttyint(int); -void ttystop(int); -int type(void *); -int type1(int *, char *, int, int); -int undeletecmd(void *); -void unmark(int); -char **unpack(struct name *, struct name *); -int unread(void *); -void unregister_file(FILE *); -int unset(void *); -int unstack(void); -void vfree(char *); -int visual(void *); -int wait_child(pid_t); -int wait_command(int); -int writeback(FILE *); - -extern char *__progname; -extern char *tmpdir; -extern const struct cmd *com; /* command we are running */ +void parse __P((char [], struct headline *, char [])); +int pcmdlist __P((void *)); +int pdot __P((void *)); +void prepare_child __P((sigset_t *, int, int)); +int preserve __P((void *)); +void prettyprint __P((struct name *)); +void printgroup __P((char [])); +void printhead __P((int)); +int puthead __P((struct header *, FILE *, int)); +int putline __P((FILE *, char *)); +int pversion __P((void *)); +void quit __P((void)); +int quitcmd __P((void *)); +int raise __P((int)); +int readline __P((FILE *, char *, int)); +void register_file __P((FILE *, int, int)); +void regret __P((int)); +void relsesigs __P((void)); +int respond __P((void *)); +int retfield __P((void *)); +int rexit __P((void *)); +int rm __P((char *)); +int run_command __P((char *, sigset_t *, int, int, char *, char *, char *)); +int save __P((void *)); +int save1 __P((char [], int, char *, struct ignoretab *)); +void savedeadletter __P((FILE *)); +int saveigfield __P((void *)); +int savemail __P((char [], FILE *)); +int saveretfield __P((void *)); +int scan __P((char **)); +void scaninit __P((void)); +int schdir __P((void *)); +int screensize __P((void)); +int scroll __P((void *)); +int send __P((struct message *, FILE *, struct ignoretab *, char *)); +int sendmail __P((void *)); +int set __P((void *)); +int setfile __P((char *)); +void setmsize __P((int)); +void setptr __P((FILE *)); +void setscreensize __P((void)); +int shell __P((void *)); +void sigchild __P((int)); +void sort __P((char **)); +int source __P((void *)); +void spreserve __P((void)); +void sreset __P((void)); +int start_command __P((char *, sigset_t *, int, int, char *, char *, char *)); +void statusput __P((struct message *, FILE *, char *)); +void stop __P((int)); +int stouch __P((void *)); +int swrite __P((void *)); +void tinit __P((void)); +int top __P((void *)); +void touch __P((struct message *)); +void ttyint __P((int)); +void ttystop __P((int)); +int type __P((void *)); +int type1 __P((int *, int, int)); +int undeletecmd __P((void *)); +void unmark __P((int)); +char **unpack __P((struct name *)); +int unread __P((void *)); +void unregister_file __P((FILE *)); +int unset __P((void *)); +int unstack __P((void)); +void vfree __P((char *)); +int visual __P((void *)); +int wait_child __P((int)); +int wait_command __P((int)); +int writeback __P((FILE *)); diff -urN mailx-8.1.1.orig/fio.c mailx-8.1.1/fio.c --- mailx-8.1.1.orig/fio.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/fio.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: fio.c,v 1.22 2002/03/14 06:51:42 mpech Exp $ */ -/* $NetBSD: fio.c,v 1.8 1997/07/07 22:57:55 phil Exp $ */ +/* $OpenBSD: fio.c,v 1.5 1996/06/08 19:48:22 christos Exp $ */ +/* $NetBSD: fio.c,v 1.5 1996/06/08 19:48:22 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)fio.c 8.2 (Berkeley) 4/20/95"; +static char sccsid[] = "@(#)fio.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: fio.c,v 1.22 2002/03/14 06:51:42 mpech Exp $"; +static char rcsid[] = "$OpenBSD: fio.c,v 1.5 1996/06/08 19:48:22 christos Exp $"; #endif #endif /* not lint */ @@ -57,88 +57,62 @@ * File I/O. */ -static volatile sig_atomic_t fiosignal; - -/* - * Wrapper for read() to catch EINTR. - */ -ssize_t -myread(int fd, char *buf, int len) -{ - ssize_t nread; - - while ((nread = read(fd, buf, len)) == -1 && errno == EINTR) - ; - return(nread); -} - /* * Set up the input pointers while copying the mail file into /tmp. */ void -setptr(FILE *ibuf, off_t offset) +setptr(ibuf) + register FILE *ibuf; { - int c, count; - char *cp, *cp2; + extern char *tmpdir; + register int c, count; + register char *cp, *cp2; struct message this; FILE *mestmp; - int maybe, inhead, omsgCount; - char linebuf[LINESIZE], pathbuf[PATHSIZE]; + off_t offset; + int maybe, inhead; + char linebuf[LINESIZE]; /* Get temporary file. */ - (void)snprintf(pathbuf, sizeof(pathbuf), "%s/mail.XXXXXXXXXX", tmpdir); - if ((c = mkstemp(pathbuf)) == -1 || (mestmp = Fdopen(c, "r+")) == NULL) - err(1, "can't open %s", pathbuf); - (void)rm(pathbuf); - - if (offset == 0) { - msgCount = 0; - } else { - /* Seek into the file to get to the new messages */ - (void)fseek(ibuf, offset, 0); - /* - * We need to make "offset" a pointer to the end of - * the temp file that has the copy of the mail file. - * If any messages have been edited, this will be - * different from the offset into the mail file. - */ - (void)fseek(otf, 0L, SEEK_END); - offset = ftell(otf); + (void)snprintf(linebuf,LINESIZE,"%s/mail.XXXXXX", tmpdir); + if ((c = mkstemp(linebuf)) == -1 || + (mestmp = Fdopen(c, "r+")) == NULL) { + (void)fprintf(stderr, "mail: can't open %s\n", linebuf); + exit(1); } - omsgCount = msgCount; + (void)unlink(linebuf); + + msgCount = 0; maybe = 1; inhead = 0; + offset = 0; this.m_flag = MUSED|MNEW; this.m_size = 0; this.m_lines = 0; this.m_block = 0; this.m_offset = 0; for (;;) { - if (fgets(linebuf, sizeof(linebuf), ibuf) == NULL) { - if (append(&this, mestmp)) - err(1, "temporary file"); - makemessage(mestmp, omsgCount); + if (fgets(linebuf, LINESIZE, ibuf) == NULL) { + if (append(&this, mestmp)) { + perror("temporary file"); + exit(1); + } + makemessage(mestmp); return; } count = strlen(linebuf); - /* - * Transforms lines ending in to just . - * This allows mail to be able to read Eudora mailboxes - * that reside on a DOS partition. - */ - if (count >= 2 && linebuf[count-1] == '\n' && - linebuf[count - 2] == '\r') - linebuf[count - 2] = linebuf[--count]; - - (void)fwrite(linebuf, sizeof(*linebuf), count, otf); - if (ferror(otf)) - err(1, "/tmp"); - if (count) - linebuf[count - 1] = '\0'; + (void) fwrite(linebuf, sizeof *linebuf, count, otf); + if (ferror(otf)) { + perror("/tmp"); + exit(1); + } + linebuf[count - 1] = 0; if (maybe && linebuf[0] == 'F' && ishead(linebuf)) { msgCount++; - if (append(&this, mestmp)) - err(1, "temporary file"); + if (append(&this, mestmp)) { + perror("temporary file"); + exit(1); + } this.m_flag = MUSED|MNEW; this.m_size = 0; this.m_lines = 0; @@ -176,88 +150,83 @@ /* * Drop the passed line onto the passed output buffer. * If a write error occurs, return -1, else the count of - * characters written, including the newline if requested. + * characters written, including the newline. */ int -putline(FILE *obuf, char *linebuf, int outlf) +putline(obuf, linebuf) + FILE *obuf; + char *linebuf; { - int c; + register int c; c = strlen(linebuf); - (void)fwrite(linebuf, sizeof(*linebuf), c, obuf); - if (outlf) { - (void)putc('\n', obuf); - c++; - } + (void) fwrite(linebuf, sizeof *linebuf, c, obuf); + (void) putc('\n', obuf); if (ferror(obuf)) - return(-1); - return(c); + return (-1); + return (c + 1); } /* * Read up a line from the specified input into the line * buffer. Return the number of characters read. Do not - * include the newline (or carriage return) at the end. + * include the newline at the end. */ int -readline(FILE *ibuf, char *linebuf, int linesize, int *signo) +readline(ibuf, linebuf, linesize) + FILE *ibuf; + char *linebuf; + int linesize; { - struct sigaction act; - struct sigaction savetstp; - struct sigaction savettou; - struct sigaction savettin; - struct sigaction saveint; - struct sigaction savehup; - sigset_t oset; - int n; - - /* - * Setup signal handlers if the caller asked us to catch signals. - * Note that we do not restart system calls since we need the - * read to be interuptible. - */ - if (signo) { - fiosignal = 0; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - act.sa_handler = fioint; - if (sigaction(SIGINT, NULL, &saveint) == 0 && - saveint.sa_handler != SIG_IGN) { - (void)sigaction(SIGINT, &act, &saveint); - (void)sigprocmask(SIG_UNBLOCK, &intset, &oset); - } - if (sigaction(SIGHUP, NULL, &savehup) == 0 && - savehup.sa_handler != SIG_IGN) - (void)sigaction(SIGHUP, &act, &savehup); - (void)sigaction(SIGTSTP, &act, &savetstp); - (void)sigaction(SIGTTOU, &act, &savettou); - (void)sigaction(SIGTTIN, &act, &savettin); - } - + register int n,oldfl; + char *res; clearerr(ibuf); - if (fgets(linebuf, linesize, ibuf) == NULL) { - if (ferror(ibuf)) - clearerr(ibuf); - n = -1; - } else { - n = strlen(linebuf); - if (n > 0 && linebuf[n - 1] == '\n') - linebuf[--n] = '\0'; - if (n > 0 && linebuf[n - 1] == '\r') - linebuf[--n] = '\0'; - } - - if (signo) { - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void)sigaction(SIGINT, &saveint, NULL); - (void)sigaction(SIGHUP, &savehup, NULL); - (void)sigaction(SIGTSTP, &savetstp, NULL); - (void)sigaction(SIGTTOU, &savettou, NULL); - (void)sigaction(SIGTTIN, &savettin, NULL); - *signo = fiosignal; - } - - return(n); +#ifdef IOSAFE + /* we want to be able to get interrupts while waiting user-input + we cannot to safely inside a stdio call, so we first ensure there + is now data in the stdio buffer by doing the stdio call with the descriptor + in non-blocking state and then do a select. + Hope it is safe (the libc should not break on a EAGAIN) + lprylli@graville.fdn.fr*/ + n = 0; /* number of caracters already read */ + while (n < linesize - 1) { + errno = 0; + oldfl = fcntl(fileno(ibuf),F_GETFL); + fcntl(fileno(ibuf),F_SETFL,oldfl | O_NONBLOCK); + res = fgets(linebuf + n, linesize-n, ibuf); + fcntl(fileno(ibuf),F_SETFL,oldfl); + if (res != NULL) { + n = strlen(linebuf); + if (n > 0 && linebuf[n-1] == '\n') + break; + } else if (errno == EAGAIN || errno == EWOULDBLOCK) { + clearerr(ibuf); + } else { + /* probably EOF one the file descriptors */ + if (n > 0) + break; + else + return -1; + + }{ + extern int got_interrupt; + fd_set rds; + FD_ZERO(&rds); + FD_SET(fileno(ibuf),&rds); + select(fileno(ibuf)+1,&rds,NULL,NULL,NULL); + /* if an interrupt occur drops the current line and returns */ + if (got_interrupt) + return -1; + } + } +#else + if (fgets(linebuf, linesize, ibuf) == NULL) + return -1; +#endif + n = strlen(linebuf); + if (n > 0 && linebuf[n - 1] == '\n') + linebuf[--n] = '\0'; + return n; } /* @@ -265,13 +234,16 @@ * passed message pointer. */ FILE * -setinput(struct message *mp) +setinput(mp) + register struct message *mp; { fflush(otf); - if (fseek(itf, (long)positionof(mp->m_block, mp->m_offset), 0) < 0) - err(1, "fseek"); - return(itf); + if (fseek(itf, (long)positionof(mp->m_block, mp->m_offset), 0) < 0) { + perror("fseek"); + panic("temporary file seek"); + } + return (itf); } /* @@ -279,29 +251,24 @@ * a dynamically allocated message structure. */ void -makemessage(FILE *f, int omsgCount) +makemessage(f) + FILE *f; { - size_t size; - struct message *nmessage; + register size = (msgCount + 1) * sizeof (struct message); - size = (msgCount + 1) * sizeof(struct message); - nmessage = (struct message *)realloc(message, size); - if (nmessage == 0) - errx(1, "Insufficient memory for %d messages", - msgCount); - if (omsgCount == 0 || message == NULL) - dot = nmessage; - else - dot = nmessage + (dot - message); - message = nmessage; - size -= (omsgCount + 1) * sizeof(struct message); + if (message != 0) + free((char *) message); + if ((message = (struct message *) malloc((unsigned) size)) == 0) + panic("Insufficient memory for %d messages", msgCount); + dot = message; + size -= sizeof (struct message); fflush(f); - (void)lseek(fileno(f), (off_t)sizeof(*message), 0); - if (myread(fileno(f), (void *) &message[omsgCount], size) != size) - errx(1, "Message temporary file corrupted"); + (void) lseek(fileno(f), (off_t)sizeof *message, 0); + if (read(fileno(f), (char *) message, size) != size) + panic("Message temporary file corrupted"); message[msgCount].m_size = 0; message[msgCount].m_lines = 0; - (void)Fclose(f); + Fclose(f); } /* @@ -309,17 +276,19 @@ * If the write fails, return 1, else 0 */ int -append(struct message *mp, FILE *f) +append(mp, f) + struct message *mp; + FILE *f; { - - return(fwrite((char *) mp, sizeof(*mp), 1, f) != 1); + return fwrite((char *) mp, sizeof *mp, 1, f) != 1; } /* - * Delete or truncate a file, but only if the file is a plain file. + * Delete a file, but only if the file is a plain file. */ int -rm(char *name) +rm(name) + char *name; { struct stat sb; @@ -329,13 +298,7 @@ errno = EISDIR; return(-1); } - if (unlink(name) == -1) { - if (errno == EPERM) - return(truncate(name, 0)); - else - return(-1); - } - return(0); + return(unlink(name)); } static int sigdepth; /* depth of holdsigs() */ @@ -344,7 +307,7 @@ * Hold signals SIGHUP, SIGINT, and SIGQUIT. */ void -holdsigs(void) +holdsigs() { if (sigdepth++ == 0) { @@ -360,7 +323,7 @@ * Release signals SIGHUP, SIGINT, and SIGQUIT. */ void -relsesigs(void) +relsesigs() { if (--sigdepth == 0) @@ -368,42 +331,18 @@ } /* - * Unblock and ignore a signal - */ -int -ignoresig(int sig, struct sigaction *oact, sigset_t *oset) -{ - struct sigaction act; - sigset_t nset; - int error; - - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - act.sa_handler = SIG_IGN; - error = sigaction(sig, &act, oact); - - if (error == 0) { - sigemptyset(&nset); - sigaddset(&nset, sig); - (void)sigprocmask(SIG_UNBLOCK, &nset, oset); - } else if (oset != NULL) - (void)sigprocmask(SIG_BLOCK, NULL, oset); - - return(error); -} - -/* * Determine the size of the file possessed by * the passed buffer. */ off_t -fsize(FILE *iob) +fsize(iob) + FILE *iob; { struct stat sbuf; if (fstat(fileno(iob), &sbuf) < 0) - return(0); - return(sbuf.st_size); + return 0; + return sbuf.st_size; } /* @@ -418,16 +357,16 @@ * Return the file name as a dynamic string. */ char * -expand(char *name) +expand(name) + register char *name; { char xname[PATHSIZE]; char cmdbuf[PATHSIZE]; /* also used for file names */ - pid_t pid; - int l; - char *cp, *shell; + register int pid, l; + register char *cp, *shell; int pivec[2]; struct stat sbuf; - extern int wait_status; + extern union wait wait_status; /* * The order of evaluation is "%" and "#" expand into constants. @@ -437,120 +376,112 @@ */ switch (*name) { case '%': - findmail(name[1] ? name + 1 : myname, xname, sizeof(xname)); - return(savestr(xname)); + findmail(name[1] ? name + 1 : myname, xname, PATHSIZE); + return savestr(xname); case '#': if (name[1] != 0) break; if (prevfile[0] == 0) { - puts("No previous file"); - return(NULL); + printf("No previous file\n"); + return NOSTR; } - return(savestr(prevfile)); + return savestr(prevfile); case '&': - if (name[1] == 0 && (name = value("MBOX")) == NULL) + if (name[1] == 0 && (name = value("MBOX")) == NOSTR) name = "~/mbox"; /* fall through */ } - if (name[0] == '+' && getfold(cmdbuf, sizeof(cmdbuf)) >= 0) { - (void)snprintf(xname, sizeof(xname), "%s/%s", cmdbuf, name + 1); + if (name[0] == '+' && getfold(cmdbuf, PATHSIZE) >= 0) { + snprintf(xname, PATHSIZE, "%s/%s", cmdbuf, name + 1); name = savestr(xname); } /* catch the most common shell meta character */ - if (name[0] == '~' && homedir && (name[1] == '/' || name[1] == '\0')) { - (void)snprintf(xname, sizeof(xname), "%s%s", homedir, name + 1); + if (name[0] == '~' && (name[1] == '/' || name[1] == '\0')) { + snprintf(xname, PATHSIZE, "%s%s", homedir, name + 1); name = savestr(xname); } - if (strpbrk(name, "~{[*?$`'\"\\") == NULL) - return(name); - /* XXX - just use glob(3) and env expansion instead? */ + if (!anyof(name, "~{[*?$`'\"\\")) + return name; if (pipe(pivec) < 0) { - warn("pipe"); - return(name); + perror("pipe"); + return name; } - (void)snprintf(cmdbuf, sizeof(cmdbuf), "echo %s", name); - shell = value("SHELL"); - pid = start_command(shell, 0, -1, pivec[1], "-c", cmdbuf, NULL); + snprintf(cmdbuf, PATHSIZE, "echo %s", name); + if ((shell = value("SHELL")) == NOSTR) + shell = _PATH_CSHELL; + pid = start_command(shell, 0, -1, pivec[1], "-c", cmdbuf, NOSTR); if (pid < 0) { - (void)close(pivec[0]); - (void)close(pivec[1]); - return(NULL); - } - (void)close(pivec[1]); - l = myread(pivec[0], xname, PATHSIZE); - if (l < 0) - warn("read"); /* report error before errno changes */ - (void)close(pivec[0]); - if (wait_child(pid) < 0 && WIFSIGNALED(wait_status) && - WTERMSIG(wait_status) != SIGPIPE) { + close(pivec[0]); + close(pivec[1]); + return NOSTR; + } + close(pivec[1]); + l = read(pivec[0], xname, PATHSIZE); + if (l < 0) { + perror("read"); + close(pivec[0]); + return NOSTR; + } + close(pivec[0]); + if (wait_child(pid) < 0 && wait_status.w_termsig != SIGPIPE) { fprintf(stderr, "\"%s\": Expansion failed.\n", name); - return(NULL); + return NOSTR; } - if (l < 0) - return(NULL); if (l == 0) { fprintf(stderr, "\"%s\": No match.\n", name); - return(NULL); + return NOSTR; } if (l == PATHSIZE) { fprintf(stderr, "\"%s\": Expansion buffer overflow.\n", name); - return(NULL); + return NOSTR; } - xname[l] = '\0'; + xname[l] = 0; for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) ; cp[1] = '\0'; - if (strchr(xname, ' ') && stat(xname, &sbuf) < 0) { + if (index(xname, ' ') && stat(xname, &sbuf) < 0) { fprintf(stderr, "\"%s\": Ambiguous.\n", name); - return(NULL); + return NOSTR; } - return(savestr(xname)); + return savestr(xname); } /* * Determine the current folder directory name. */ int -getfold(char *name, int namelen) +getfold(name, size) + char *name; + int size; { char *folder; - if ((folder = value("folder")) == NULL) - return(-1); - if (*folder == '/') - istrcpy(name, folder, namelen); - else - (void)snprintf(name, namelen, "%s/%s", homedir ? homedir : ".", - folder); - return(0); + if ((folder = value("folder")) == NOSTR) + return (-1); + if (*folder == '/') { + strncpy(name, folder, size); + name[size-1]='\0'; + } else { + snprintf(name, size, "%s/%s", homedir, folder); + } + return (0); } /* * Return the name of the dead.letter file. */ char * -getdeadletter(void) +getdeadletter() { - char *cp; + register char *cp; - if ((cp = value("DEAD")) == NULL || (cp = expand(cp)) == NULL) + if ((cp = value("DEAD")) == NOSTR || (cp = expand(cp)) == NOSTR) cp = expand("~/dead.letter"); else if (*cp != '/') { char buf[PATHSIZE]; - (void)snprintf(buf, sizeof(buf), "~/%s", cp); + (void) snprintf(buf, PATHSIZE, "~/%s", cp); cp = expand(buf); } - return(cp); -} - -/* - * Signal handler used by readline() to catch SIGINT, SIGHUP, SIGTSTP, - * SIGTTOU, SIGTTIN. - */ -void -fioint(int s) -{ - - fiosignal = s; + return cp; } diff -urN mailx-8.1.1.orig/getname.c mailx-8.1.1/getname.c --- mailx-8.1.1.orig/getname.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/getname.c 1996-06-14 01:27:01.000000000 -0700 @@ -1,4 +1,4 @@ -/* $OpenBSD: getname.c,v 1.6 2002/10/07 22:45:37 vincent Exp $ */ +/* $OpenBSD: getname.c,v 1.4 1996/06/08 19:48:23 christos Exp $ */ /* $NetBSD: getname.c,v 1.4 1996/06/08 19:48:23 christos Exp $ */ /* @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)getname.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)getname.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: getname.c,v 1.6 2002/10/07 22:45:37 vincent Exp $"; +static char rcsid[] = "$OpenBSD: getname.c,v 1.4 1996/06/08 19:48:23 christos Exp $"; #endif #endif /* not lint */ @@ -46,31 +46,33 @@ #include #include "extern.h" -/* Getname / getuserid for those with hashed passwd data base. */ +/* Getname / getuserid for those with hashed passwd data base). */ /* - * Search the passwd file for a uid. Return name on success, NULL on failure + * Search the passwd file for a uid. Return name on success, NOSTR on failure */ char * -getname(uid_t uid) +getname(uid) + int uid; { struct passwd *pw; if ((pw = getpwuid(uid)) == NULL) - return(NULL); - return(pw->pw_name); + return NOSTR; + return pw->pw_name; } /* * Convert the passed name to a user id and return it. Return -1 * on error. */ -uid_t -getuserid(char *name) +int +getuserid(name) + char name[]; { struct passwd *pw; if ((pw = getpwnam(name)) == NULL) return -1; - return(pw->pw_uid); + return pw->pw_uid; } diff -urN mailx-8.1.1.orig/glob.h mailx-8.1.1/glob.h --- mailx-8.1.1.orig/glob.h 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/glob.h 2003-03-26 13:03:40.000000000 -0800 @@ -1,4 +1,4 @@ -/* $OpenBSD: glob.h,v 1.6 2001/11/21 15:26:39 millert Exp $ */ +/* $OpenBSD: glob.h,v 1.4 1996/06/08 19:48:25 christos Exp $ */ /* $NetBSD: glob.h,v 1.4 1996/06/08 19:48:25 christos Exp $ */ /* @@ -41,6 +41,7 @@ * A bunch of global variable declarations lie herein. * def.h must be included first. */ + int msgCount; /* Count of messages read in */ int rcvmode; /* True if receiving mail */ int sawcom; /* Set after first command */ @@ -82,8 +83,13 @@ int screenheight; /* Screen height, or best guess, for "header" command */ int realscreenheight; /* the real screen height */ -int uflag; /* Are we in -u mode? */ -sigset_t intset; /* Signal set that is just SIGINT */ +gid_t effectivegid; /* Saved from when we started up */ +gid_t realgid; /* Saved from when we started up */ + +#include + +jmp_buf srbuf; + /* * The pointers for the string allocation routines, @@ -91,6 +97,7 @@ * The first holds STRINGSIZE bytes, the next * twice as much, and so on. */ + #define NSPACE 25 /* Total number of string spaces */ struct strings { char *s_topFree; /* Beginning of this area */ diff -urN mailx-8.1.1.orig/head.c mailx-8.1.1/head.c --- mailx-8.1.1.orig/head.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/head.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: head.c,v 1.8 2002/06/14 21:35:00 todd Exp $ */ -/* $NetBSD: head.c,v 1.6 1996/12/28 07:11:03 tls Exp $ */ +/* $OpenBSD: head.c,v 1.5 1996/06/08 19:48:26 christos Exp $ */ +/* $NetBSD: head.c,v 1.5 1996/06/08 19:48:26 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)head.c 8.2 (Berkeley) 4/20/95"; +static char sccsid[] = "@(#)head.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: head.c,v 1.8 2002/06/14 21:35:00 todd Exp $"; +static char rcsid[] = "$OpenBSD: head.c,v 1.5 1996/06/08 19:48:26 christos Exp $"; #endif #endif /* not lint */ @@ -54,41 +54,46 @@ /* * See if the passed line buffer is a mail header. * Return true if yes. Note the extreme pains to - * accommodate all funny formats. + * accomodate all funny formats. */ int -ishead(char *linebuf) +ishead(linebuf) + char linebuf[]; { - char *cp; + register char *cp; struct headline hl; char parbuf[BUFSIZ]; cp = linebuf; if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' || *cp++ != ' ') - return(0); + return (0); parse(linebuf, &hl, parbuf); - if (hl.l_from == NULL || hl.l_date == NULL) { + if (hl.l_from == NOSTR || hl.l_date == NOSTR) { fail(linebuf, "No from or date field"); - return(0); + return (0); } + /* be very tolerant about the date */ +#if 0 if (!isdate(hl.l_date)) { fail(linebuf, "Date field not legal date"); - return(0); + return (0); } +#endif /* * I guess we got it! */ - return(1); + return (1); } /*ARGSUSED*/ void -fail(char *linebuf, char *reason) +fail(linebuf, reason) + char linebuf[], reason[]; { /* - if (value("debug") == NULL) + if (value("debug") == NOSTR) return; fprintf(stderr, "\"%s\"\nnot a header because %s\n", linebuf, reason); */ @@ -101,14 +106,17 @@ * structure. Actually, it scans. */ void -parse(char *line, struct headline *hl, char *pbuf) +parse(line, hl, pbuf) + char line[], pbuf[]; + register struct headline *hl; { - char *cp, *sp; + register char *cp; + char *sp; char word[LINESIZE]; - hl->l_from = NULL; - hl->l_tty = NULL; - hl->l_date = NULL; + hl->l_from = NOSTR; + hl->l_tty = NOSTR; + hl->l_date = NOSTR; cp = line; sp = pbuf; /* @@ -118,11 +126,11 @@ cp = nextword(cp, word); if (*word) hl->l_from = copyin(word, &sp); - if (cp != NULL && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') { + if (cp != NOSTR && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') { cp = nextword(cp, word); hl->l_tty = copyin(word, &sp); } - if (cp != NULL) + if (cp != NOSTR) hl->l_date = copyin(cp, &sp); } @@ -133,15 +141,18 @@ * the left string into it. */ char * -copyin(char *src, char **space) +copyin(src, space) + register char *src; + char **space; { - char *cp, *top; + register char *cp; + char *top; top = cp = *space; while ((*cp++ = *src++) != '\0') ; *space = cp; - return(top); + return (top); } /* @@ -157,43 +168,23 @@ * 'a' A lower case char * ' ' A space * '0' A digit - * 'O' A digit or space - * 'p' A punctuation char - * 'P' A punctuation char or space + * 'O' An optional digit or space * ':' A colon * 'N' A new line */ - -/* - * Yuck. If the mail file is created by Sys V (Solaris), - * there are no seconds in the time... - */ - -/* - * If the mail is created by another program such as imapd, it might - * have timezone as <-|+>nnnn (-0800 for instance) at the end. - */ - -static char *date_formats[] = { - "Aaa Aaa O0 00:00:00 0000", /* Mon Jan 01 23:59:59 2001 */ - "Aaa Aaa O0 00:00:00 AAA 0000", /* Mon Jan 01 23:59:59 PST 2001 */ - "Aaa Aaa O0 00:00:00 0000 p0000", /* Mon Jan 01 23:59:59 2001 -0800 */ - "Aaa Aaa O0 00:00 0000", /* Mon Jan 01 23:59 2001 */ - "Aaa Aaa O0 00:00 AAA 0000", /* Mon Jan 01 23:59 PST 2001 */ - "Aaa Aaa O0 00:00 0000 p0000", /* Mon Jan 01 23:59 2001 -0800 */ - "" -}; +char ctype[] = "Aaa Aaa O0 00:00:00 0000"; +char ctype_without_secs[] = "Aaa Aaa O0 00:00 0000"; +char tmztype[] = "Aaa Aaa O0 00:00:00 AAA 0000"; +char tmztype_without_secs[] = "Aaa Aaa O0 00:00 AAA 0000"; int -isdate(char *date) +isdate(date) + char date[]; { - int i; - for(i = 0; *date_formats[i]; i++) { - if (cmatch(date, date_formats[i])) - return 1; - } - return 0; + return cmatch(date, ctype_without_secs) || + cmatch(date, tmztype_without_secs) || + cmatch(date, ctype) || cmatch(date, tmztype); } /* @@ -201,68 +192,61 @@ * Return 1 if they match, 0 if they don't */ int -cmatch(char *cp, char *tp) +cmatch(cp, tp) + register char *cp, *tp; { while (*cp && *tp) switch (*tp++) { case 'a': if (!islower(*cp++)) - return(0); + return 0; break; case 'A': if (!isupper(*cp++)) - return(0); + return 0; break; case ' ': if (*cp++ != ' ') - return(0); + return 0; break; case '0': if (!isdigit(*cp++)) - return(0); + return 0; break; case 'O': if (*cp != ' ' && !isdigit(*cp)) - return(0); - cp++; - break; - case 'p': - if (!ispunct(*cp++)) - return(0); - break; - case 'P': - if (*cp != ' ' && !ispunct(*cp)) - return(0); + return 0; cp++; break; case ':': if (*cp++ != ':') - return(0); + return 0; break; case 'N': if (*cp++ != '\n') - return(0); + return 0; break; } if (*cp || *tp) - return(0); - return(1); + return 0; + return (1); } /* * Collect a liberal (space, tab delimited) word into the word buffer * passed. Also, return a pointer to the next word following that, - * or NULL if none follow. + * or NOSTR if none follow. */ char * -nextword(char *wp, char *wbuf) +nextword(wp, wbuf) + register char *wp, *wbuf; { - int c; + register c; - if (wp == NULL) { + if (wp == NOSTR) { *wbuf = 0; - return(NULL); + return (NOSTR); } while ((c = *wp++) && c != ' ' && c != '\t') { *wbuf++ = c; @@ -279,6 +263,6 @@ for (; c == ' ' || c == '\t'; c = *wp++) ; if (c == 0) - return(NULL); - return(wp - 1); + return (NOSTR); + return (wp - 1); } diff -urN mailx-8.1.1.orig/lex.c mailx-8.1.1/lex.c --- mailx-8.1.1.orig/lex.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/lex.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: lex.c,v 1.27 2001/11/21 20:41:55 millert Exp $ */ -/* $NetBSD: lex.c,v 1.10 1997/05/17 19:55:13 pk Exp $ */ +/* $OpenBSD: lex.c,v 1.7 1996/06/08 19:48:28 christos Exp $ */ +/* $NetBSD: lex.c,v 1.7 1996/06/08 19:48:28 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)lex.c 8.2 (Berkeley) 4/20/95"; +static char sccsid[] = "@(#)lex.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: lex.c,v 1.27 2001/11/21 20:41:55 millert Exp $"; +static char rcsid[] = "$OpenBSD: lex.c,v 1.7 1996/06/08 19:48:28 christos Exp $"; #endif #endif /* not lint */ @@ -55,8 +55,6 @@ char *prompt = "& "; -const struct cmd *com; /* command we are running */ - /* * Set up editing on the given file name. * If the first character of name is %, we are considered to be @@ -64,47 +62,49 @@ * signficance for mbox and so forth. */ int -setfile(char *name) +setfile(name) + char *name; { FILE *ibuf; - int i, fd; + int i; struct stat stb; char isedit = *name != '%'; char *who = name[1] ? name + 1 : myname; - char tempname[PATHSIZE]; static int shudclob; + extern char *tempMesg; + extern int errno; - if ((name = expand(name)) == NULL) - return(-1); + if ((name = expand(name)) == NOSTR) + return -1; if ((ibuf = Fopen(name, "r")) == NULL) { if (!isedit && errno == ENOENT) goto nomail; - warn("%s", name); + perror(name); return(-1); } if (fstat(fileno(ibuf), &stb) < 0) { - warn("fstat"); - (void)Fclose(ibuf); - return(-1); + perror("fstat"); + Fclose(ibuf); + return (-1); } switch (stb.st_mode & S_IFMT) { case S_IFDIR: - (void)Fclose(ibuf); + Fclose(ibuf); errno = EISDIR; - warn("%s", name); - return(-1); + perror(name); + return (-1); case S_IFREG: break; default: - (void)Fclose(ibuf); + Fclose(ibuf); errno = EINVAL; - warn("%s", name); - return(-1); + perror(name); + return (-1); } /* @@ -113,6 +113,7 @@ * while we are reading the new file, else we will ruin * the message[] data structure. */ + holdsigs(); if (shudclob) quit(); @@ -121,113 +122,85 @@ * Copy the messages into /tmp * and set pointers. */ + readonly = 0; - if ((i = open(name, O_WRONLY, 0)) < 0) + if ((i = open(name, 1)) < 0) readonly++; else - (void)close(i); + close(i); if (shudclob) { - (void)fclose(itf); - (void)fclose(otf); + fclose(itf); + fclose(otf); } shudclob = 1; edit = isedit; - istrcpy(prevfile, mailname, PATHSIZE); - if (name != mailname) - istrcpy(mailname, name, sizeof(mailname)); + strncpy(prevfile, mailname, PATHSIZE); + prevfile[PATHSIZE-1]='\0'; + if (name != mailname) { + strncpy(mailname, name, PATHSIZE); + mailname[PATHSIZE-1]='\0'; + } mailsize = fsize(ibuf); - (void)snprintf(tempname, sizeof(tempname), - "%s/mail.RxXXXXXXXXXX", tmpdir); - if ((fd = mkstemp(tempname)) == -1 || - (otf = fdopen(fd, "w")) == NULL) - err(1, "%s", tempname); - (void)fcntl(fileno(otf), F_SETFD, 1); - if ((itf = fopen(tempname, "r")) == NULL) - err(1, "%s", tempname); - (void)fcntl(fileno(itf), F_SETFD, 1); - (void)rm(tempname); - setptr(ibuf, 0); + if ((otf = safe_fopen(tempMesg, "w")) == NULL) { + perror(tempMesg); + exit(1); + } + (void) fcntl(fileno(otf), F_SETFD, 1); + if ((itf = safe_fopen(tempMesg, "r")) == NULL) { + perror(tempMesg); + exit(1); + } + (void) fcntl(fileno(itf), F_SETFD, 1); + rm(tempMesg); + setptr(ibuf); setmsize(msgCount); - /* - * New mail may have arrived while we were reading - * the mail file, so reset mailsize to be where - * we really are in the file... - */ - mailsize = ftell(ibuf); - (void)Fclose(ibuf); + Fclose(ibuf); relsesigs(); sawcom = 0; if (!edit && msgCount == 0) { nomail: fprintf(stderr, "No mail for %s\n", who); - return(-1); + return -1; } return(0); } -/* - * Incorporate any new mail that has arrived since we first - * started reading mail. - */ -int -incfile(void) -{ - int newsize; - int omsgCount = msgCount; - FILE *ibuf; - - ibuf = Fopen(mailname, "r"); - if (ibuf == NULL) - return(-1); - holdsigs(); - if (!spool_lock()) { - (void)Fclose(ibuf); - relsesigs(); - return(-1); - } - newsize = fsize(ibuf); - /* make sure mail box has grown and is non-empty */ - if (newsize == 0 || newsize <= mailsize) { - (void)Fclose(ibuf); - spool_unlock(); - relsesigs(); - return(newsize == mailsize ? 0 : -1); - } - setptr(ibuf, mailsize); - setmsize(msgCount); - mailsize = ftell(ibuf); - (void)Fclose(ibuf); - spool_unlock(); - relsesigs(); - return(msgCount - omsgCount); -} - - int *msgvec; -int reset_on_stop; /* reset prompt if stopped */ +int reset_on_stop; /* do a reset() if stopped */ /* * Interpret user commands one by one. If standard input is not a tty, * print no prompt. */ void -commands(void) +commands() { - int n, sig, *sigp; int eofloop = 0; + register int n; char linebuf[LINESIZE]; +#if __GNUC__ + /* Avoid longjmp clobbering */ + (void) &eofloop; +#endif - prompt: + if (!sourcing) { + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, intr); + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) + signal(SIGHUP, hangup); + signal(SIGTSTP, stop); + signal(SIGTTOU, stop); + signal(SIGTTIN, stop); + } + setexit(); for (;;) { /* * Print the prompt, if needed. Clear out * string space, and flush the output. */ - if (!sourcing && value("interactive") != NULL) { - if ((value("autoinc") != NULL) && (incfile() > 0)) - puts("New mail has arrived."); + if (!sourcing && value("interactive") != NOSTR) { reset_on_stop = 1; - printf("%s", prompt); + printf(prompt); } fflush(stdout); sreset(); @@ -236,24 +209,8 @@ * and handle end of file specially. */ n = 0; - sig = 0; - sigp = sourcing ? NULL : &sig; for (;;) { - if (readline(input, &linebuf[n], LINESIZE - n, sigp) < 0) { - if (sig) { - if (sig == SIGINT) - dointr(); - else if (sig == SIGHUP) - /* nothing to do? */ - exit(1); - else { - /* Stopped by job control */ - (void)kill(0, sig); - if (reset_on_stop) - reset_on_stop = 0; - } - goto prompt; - } + if (readline(input, &linebuf[n], LINESIZE - n) < 0) { if (n == 0) n = -1; break; @@ -274,10 +231,10 @@ unstack(); continue; } - if (value("interactive") != NULL && - value("ignoreeof") != NULL && + if (value("interactive") != NOSTR && + value("ignoreeof") != NOSTR && ++eofloop < 25) { - puts("Use \"quit\" to quit."); + printf("Use \"quit\" to quit.\n"); continue; } break; @@ -296,16 +253,18 @@ * Contxt is non-zero if called while composing mail. */ int -execute(char *linebuf, int contxt) +execute(linebuf, contxt) + char linebuf[]; + int contxt; { char word[LINESIZE]; char *arglist[MAXARGC]; - char *cp, *cp2; - int c, muvec[2]; + const struct cmd *com = NULL; + register char *cp, *cp2; + register int c; + int muvec[2]; int e = 1; - com = NULL; - /* * Strip the white space away from the beginning * of the command, then scan out a word, which @@ -314,18 +273,19 @@ * Handle ! escapes differently to get the correct * lexical conventions. */ + for (cp = linebuf; isspace(*cp); cp++) ; if (*cp == '!') { if (sourcing) { - puts("Can't \"!\" while sourcing"); + printf("Can't \"!\" while sourcing\n"); goto out; } shell(cp+1); return(0); } cp2 = word; - while (*cp && strchr(" \t0123456789$^.:/-+*'\"", *cp) == NULL) + while (*cp && index(" \t0123456789$^.:/-+*'\"", *cp) == NOSTR) *cp2++ = *cp++; *cp2 = '\0'; @@ -336,10 +296,11 @@ * however, we ignore blank lines to eliminate * confusion. */ + if (sourcing && *word == '\0') return(0); com = lex(word); - if (com == NULL) { + if (com == NONE) { printf("Unknown command: \"%s\"\n", word); goto out; } @@ -348,6 +309,7 @@ * See if we should execute the command -- if a conditional * we always execute it, otherwise, check the state of cond. */ + if ((com->c_argtype & F) == 0) if ((cond == CRCV && !rcvmode) || (cond == CSEND && rcvmode)) return(0); @@ -358,6 +320,7 @@ * If we are sourcing an interactive command, it's * an error. */ + if (!rcvmode && (com->c_argtype & M) == 0) { printf("May not execute \"%s\" while sending\n", com->c_name); @@ -378,60 +341,13 @@ goto out; } switch (com->c_argtype & ~(F|P|I|M|T|W|R)) { - case MSGLIST|STRLIST: - /* - * A message list defaulting to nearest forward - * legal message. - */ - if (msgvec == 0) { - puts("Illegal use of \"message list\""); - break; - } - /* - * remove leading blanks. - */ - while (isspace(*cp)) - cp++; - - if (isdigit(*cp) || *cp == ':') { - if ((c = getmsglist(cp, msgvec, com->c_msgflag)) < 0) - break; - /* position to next space - past the message list */ - while (!isspace(*cp)) - cp++; - /* position to next non-space */ - while (isspace(*cp)) - cp++; - } else { - c = 0; /* no message list */ - } - - if (c == 0) { - *msgvec = first(com->c_msgflag, - com->c_msgmask); - msgvec[1] = NULL; - } - if (*msgvec == NULL) { - puts("No applicable messages"); - break; - } - /* - * Just the straight string, with - * leading blanks removed. - */ - while (isspace(*cp)) - cp++; - - e = (*com->c_func2)(msgvec, cp); - break; - case MSGLIST: /* * A message list defaulting to nearest forward * legal message. */ if (msgvec == 0) { - puts("Illegal use of \"message list\""); + printf("Illegal use of \"message list\"\n"); break; } if ((c = getmsglist(cp, msgvec, com->c_msgflag)) < 0) @@ -442,7 +358,7 @@ msgvec[1] = NULL; } if (*msgvec == NULL) { - puts("No applicable messages"); + printf("No applicable messages\n"); break; } e = (*com->c_func)(msgvec); @@ -454,7 +370,7 @@ * if none exist. */ if (msgvec == 0) { - puts("Illegal use of \"message list\""); + printf("Illegal use of \"message list\"\n"); break; } if (getmsglist(cp, msgvec, com->c_msgflag) < 0) @@ -477,7 +393,7 @@ * A vector of strings, in shell style. */ if ((c = getrawlist(cp, arglist, - sizeof(arglist) / sizeof(*arglist))) < 0) + sizeof arglist / sizeof *arglist)) < 0) break; if (c < com->c_minargs) { printf("%s requires at least %d arg(s)\n", @@ -501,7 +417,7 @@ break; default: - errx(1, "Unknown argtype"); + panic("Unknown argtype"); } out: @@ -511,16 +427,16 @@ */ if (e) { if (e < 0) - return(1); + return 1; if (loading) - return(1); + return 1; if (sourcing) unstack(); - return(0); + return 0; } if (com == NULL) return(0); - if (value("autoprint") != NULL && com->c_argtype & P) + if (value("autoprint") != NOSTR && com->c_argtype & P) if ((dot->m_flag & MDELETED) == 0) { muvec[0] = dot - &message[0] + 1; muvec[1] = 0; @@ -536,14 +452,13 @@ * lists to message list functions. */ void -setmsize(int n) +setmsize(sz) + int sz; { - size_t msize; - msize = (n + 1) * sizeof(*msgvec); - if ((msgvec = realloc(msgvec, msize)) == NULL) - errx(1, "Out of memory"); - memset(msgvec, 0, msize); + if (msgvec != 0) + free((char *) msgvec); + msgvec = (int *) calloc((unsigned) (sz + 1), sizeof *msgvec); } /* @@ -552,17 +467,16 @@ */ const struct cmd * -lex(char *word) +lex(word) + char word[]; { extern const struct cmd cmdtab[]; - const struct cmd *cp; + register const struct cmd *cp; - if (word[0] == '#') - word = "#"; - for (cp = &cmdtab[0]; cp->c_name != NULL; cp++) + for (cp = &cmdtab[0]; cp->c_name != NOSTR; cp++) if (isprefix(word, cp->c_name)) return(cp); - return(NULL); + return(NONE); } /* @@ -570,9 +484,10 @@ * Return true if yep. */ int -isprefix(char *as1, char *as2) +isprefix(as1, as2) + char *as1, *as2; { - char *s1, *s2; + register char *s1, *s2; s1 = as1; s2 = as2; @@ -589,10 +504,13 @@ * Close all open files except 0, 1, 2, and the temporary. * Also, unstack all source files. */ + int inithdr; /* am printing startup headers */ +/*ARGSUSED*/ void -dointr(void) +intr(s) + int s; { noreset = 0; @@ -605,10 +523,46 @@ close_all_files(); if (image >= 0) { - (void)close(image); + close(image); image = -1; } - fputs("Interrupt\n", stderr); + fprintf(stderr, "Interrupt\n"); + reset(0); +} + +/* + * When we wake up after ^Z, reprint the prompt. + */ +void +stop(s) + int s; +{ + sig_t old_action = signal(s, SIG_DFL); + sigset_t nset; + + sigemptyset(&nset); + sigaddset(&nset, s); + sigprocmask(SIG_UNBLOCK, &nset, NULL); + kill(0, s); + sigprocmask(SIG_BLOCK, &nset, NULL); + signal(s, old_action); + if (reset_on_stop) { + reset_on_stop = 0; + reset(0); + } +} + +/* + * Branch here on hangup signal and simulate "exit". + */ +/*ARGSUSED*/ +void +hangup(s) + int s; +{ + + /* nothing to do? */ + exit(1); } /* @@ -616,15 +570,15 @@ * give the message count, and print a header listing. */ void -announce(void) +announce() { int vec[2], mdot; - mdot = newfileinfo(0); + mdot = newfileinfo(); vec[0] = mdot; vec[1] = 0; dot = &message[mdot - 1]; - if (msgCount > 0 && value("noheader") == NULL) { + if (msgCount > 0 && value("noheader") == NOSTR) { inithdr++; headers(vec); inithdr = 0; @@ -636,23 +590,23 @@ * Return a likely place to set dot. */ int -newfileinfo(int omsgCount) +newfileinfo() { - struct message *mp; - int u, n, mdot, d, s; - char fname[PATHSIZE], zname[PATHSIZE], *ename; + register struct message *mp; + register int u, n, mdot, d, s; + char fname[BUFSIZ], zname[BUFSIZ], *ename; - for (mp = &message[omsgCount]; mp < &message[msgCount]; mp++) + for (mp = &message[0]; mp < &message[msgCount]; mp++) if (mp->m_flag & MNEW) break; if (mp >= &message[msgCount]) - for (mp = &message[omsgCount]; mp < &message[msgCount]; mp++) + for (mp = &message[0]; mp < &message[msgCount]; mp++) if ((mp->m_flag & MREAD) == 0) break; if (mp < &message[msgCount]) mdot = mp - &message[0] + 1; else - mdot = omsgCount + 1; + mdot = 1; s = d = 0; for (mp = &message[0], n = 0, u = 0; mp < &message[msgCount]; mp++) { if (mp->m_flag & MNEW) @@ -665,17 +619,16 @@ s++; } ename = mailname; - if (getfold(fname, sizeof(fname)) >= 0) { + if (getfold(fname, BUFSIZ-1) >= 0) { strcat(fname, "/"); if (strncmp(fname, mailname, strlen(fname)) == 0) { - (void)snprintf(zname, sizeof(zname), "+%s", - mailname + strlen(fname)); + snprintf(zname, BUFSIZ, "+%s", mailname + strlen(fname)); ename = zname; } } printf("\"%s\": ", ename); if (msgCount == 1) - fputs("1 message", stdout); + printf("1 message"); else printf("%d messages", msgCount); if (n > 0) @@ -687,19 +640,21 @@ if (s > 0) printf(" %d saved", s); if (readonly) - fputs(" [Read only]", stdout); - putchar('\n'); + printf(" [Read only]"); + printf("\n"); return(mdot); } /* * Print the current version number. */ + /*ARGSUSED*/ int -pversion(void *v) +pversion(v) + void *v; { - extern const char version[]; + extern char *version; printf("Version %s\n", version); return(0); @@ -709,9 +664,10 @@ * Load a file of user definitions. */ void -load(char *name) +load(name) + char *name; { - FILE *in, *oldin; + register FILE *in, *oldin; if ((in = Fopen(name, "r")) == NULL) return; @@ -723,5 +679,5 @@ loading = 0; sourcing = 0; input = oldin; - (void)Fclose(in); + Fclose(in); } diff -urN mailx-8.1.1.orig/list.c mailx-8.1.1/list.c --- mailx-8.1.1.orig/list.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/list.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: list.c,v 1.12 2001/11/21 20:41:55 millert Exp $ */ -/* $NetBSD: list.c,v 1.7 1997/07/09 05:23:36 mikel Exp $ */ +/* $OpenBSD: list.c,v 1.4 1996/06/08 19:48:30 christos Exp $ */ +/* $NetBSD: list.c,v 1.4 1996/06/08 19:48:30 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)list.c 8.4 (Berkeley) 5/1/95"; +static char sccsid[] = "@(#)list.c 8.2 (Berkeley) 4/19/94"; #else -static const char rcsid[] = "$OpenBSD: list.c,v 1.12 2001/11/21 20:41:55 millert Exp $"; +static char rcsid[] = "$OpenBSD: list.c,v 1.4 1996/06/08 19:48:30 christos Exp $"; #endif #endif /* not lint */ @@ -46,8 +46,6 @@ #include #include "extern.h" -int matchto(char *, int); - /* * Mail -- a mail program * @@ -61,14 +59,16 @@ * Returns the count of messages picked up or -1 on error. */ int -getmsglist(char *buf, int *vector, int flags) +getmsglist(buf, vector, flags) + char *buf; + int *vector, flags; { - int *ip; - struct message *mp; + register int *ip; + register struct message *mp; if (msgCount == 0) { *vector = 0; - return(0); + return 0; } if (markall(buf, flags) < 0) return(-1); @@ -89,6 +89,7 @@ /* * Bit values for colon modifiers. */ + #define CMNEW 01 /* New messages */ #define CMOLD 02 /* Old messages */ #define CMUNREAD 04 /* Unread messages */ @@ -99,6 +100,7 @@ * The following table describes the letters which can follow * the colon and gives the corresponding modifier bit. */ + struct coltab { char co_char; /* What to find past : */ int co_bit; /* Associated modifier bit */ @@ -113,14 +115,16 @@ { 0, 0, 0, 0 } }; -static int lastcolmod; +static int lastcolmod; int -markall(char *buf, int f) +markall(buf, f) + char buf[]; + int f; { - char **np; - int i; - struct message *mp; + register char **np; + register int i; + register struct message *mp; char *namelist[NMLSIZE], *bufp; int tok, beg, mc, star, other, valdot, colmod, colresult; @@ -141,7 +145,7 @@ case TNUMBER: number: if (star) { - puts("No numbers mixed with *"); + printf("No numbers mixed with *\n"); return(-1); } mc++; @@ -168,14 +172,14 @@ case TPLUS: if (beg != 0) { - puts("Non-numeric second argument"); + printf("Non-numeric second argument\n"); return(-1); } i = valdot; do { i++; if (i > msgCount) { - puts("Referencing beyond EOF"); + printf("Referencing beyond EOF\n"); return(-1); } } while ((message[i - 1].m_flag & MDELETED) != f); @@ -188,7 +192,7 @@ do { i--; if (i <= 0) { - puts("Referencing before 1"); + printf("Referencing before 1\n"); return(-1); } } while ((message[i - 1].m_flag & MDELETED) != f); @@ -198,7 +202,7 @@ case TSTRING: if (beg != 0) { - puts("Non-numeric second argument"); + printf("Non-numeric second argument\n"); return(-1); } other++; @@ -210,11 +214,9 @@ return(-1); } colmod |= colresult; - } else { - if ((com->c_argtype & ~(F|P|I|M|T|W|R)) - != (MSGLIST|STRLIST)) - *np++ = savestr(lexstring); } + else + *np++ = savestr(lexstring); break; case TDOLLAR: @@ -227,19 +229,19 @@ case TSTAR: if (other) { - puts("Can't mix \"*\" with anything"); + printf("Can't mix \"*\" with anything\n"); return(-1); } star++; break; case TERROR: - return(-1); + return -1; } tok = scan(&bufp); } lastcolmod = colmod; - *np = NULL; + *np = NOSTR; mc = 0; if (star) { for (i = 0; i < msgCount; i++) @@ -248,7 +250,7 @@ mc++; } if (mc == 0) { - puts("No applicable messages."); + printf("No applicable messages.\n"); return(-1); } return(0); @@ -259,6 +261,7 @@ * so that we can unmark any whose sender was not selected * if any user names were given. */ + if ((np > namelist || colmod != 0) && mc == 0) for (i = 1; i <= msgCount; i++) if ((message[i-1].m_flag & MDELETED) == f) @@ -268,9 +271,10 @@ * If any names were given, go through and eliminate any * messages whose senders were not requested. */ + if (np > namelist) { for (i = 1; i <= msgCount; i++) { - for (mc = 0, np = &namelist[0]; *np != NULL; np++) + for (mc = 0, np = &namelist[0]; *np != NOSTR; np++) if (**np == '/') { if (matchsubj(*np, i)) { mc++; @@ -290,6 +294,7 @@ /* * Make sure we got some decent messages. */ + mc = 0; for (i = 1; i <= msgCount; i++) if (message[i-1].m_flag & MMARK) { @@ -299,9 +304,9 @@ if (mc == 0) { printf("No applicable messages from {%s", namelist[0]); - for (np = &namelist[1]; *np != NULL; np++) + for (np = &namelist[1]; *np != NOSTR; np++) printf(", %s", *np); - puts("}"); + printf("}\n"); return(-1); } } @@ -310,9 +315,10 @@ * If any colon modifiers were given, go through and * unmark any messages which do not satisfy the modifiers. */ + if (colmod != 0) { for (i = 1; i <= msgCount; i++) { - struct coltab *colp; + register struct coltab *colp; mp = &message[i - 1]; for (colp = &coltab[0]; colp->co_char; colp++) @@ -320,18 +326,19 @@ if ((mp->m_flag & colp->co_mask) != colp->co_equal) unmark(i); + } for (mp = &message[0]; mp < &message[msgCount]; mp++) if (mp->m_flag & MMARK) break; if (mp >= &message[msgCount]) { - struct coltab *colp; + register struct coltab *colp; - fputs("No messages satisfy", stdout); + printf("No messages satisfy"); for (colp = &coltab[0]; colp->co_char; colp++) if (colp->co_bit & colmod) printf(" :%c", colp->co_char); - putchar('\n'); + printf("\n"); return(-1); } } @@ -343,9 +350,10 @@ * value. */ int -evalcol(int col) +evalcol(col) + int col; { - struct coltab *colp; + register struct coltab *colp; if (col == 0) return(lastcolmod); @@ -361,9 +369,10 @@ * has to be undeleted. */ int -check(int mesg, int f) +check(mesg, f) + int mesg, f; { - struct message *mp; + register struct message *mp; if (mesg < 1 || mesg > msgCount) { printf("%d: Invalid message number\n", mesg); @@ -382,15 +391,14 @@ * for a RAWLIST. */ int -getrawlist(char *line, char **argv, int argc) +getrawlist(line, argv, argc) + char line[]; + char **argv; + int argc; { - char c, *cp, *cp2, quotec; + register char c, *cp, *cp2, quotec; int argn; - char *linebuf; - size_t linebufsize = BUFSIZ; - - if ((linebuf = (char *)malloc(linebufsize)) == NULL) - errx(1, "Out of memory"); + char linebuf[BUFSIZ]; argn = 0; cp = line; @@ -400,20 +408,13 @@ if (*cp == '\0') break; if (argn >= argc - 1) { - puts("Too many elements in the list; excess discarded."); + printf( + "Too many elements in the list; excess discarded.\n"); break; } cp2 = linebuf; quotec = '\0'; while ((c = *cp) != '\0') { - /* Alloc more space if necessary */ - if (cp2 - linebuf == linebufsize - 1) { - linebufsize += BUFSIZ; - linebuf = (char *)realloc(linebuf, linebufsize); - if (linebuf == NULL) - errx(1, "Out of memory"); - cp2 = linebuf + linebufsize - BUFSIZ - 1; - } cp++; if (quotec != '\0') { if (c == quotec) @@ -478,17 +479,17 @@ *cp2 = '\0'; argv[argn++] = savestr(linebuf); } - argv[argn] = NULL; - (void)free(linebuf); - return(argn); + argv[argn] = NOSTR; + return argn; } /* - * Scan out a single lexical item and return its token number, + * scan out a single lexical item and return its token number, * updating the string pointer passed **p. Also, store the value * of the number or string scanned in lexnumber or lexstring as * appropriate. In any event, store the scanned `thing' in lexstring. */ + struct lex { char l_char; char l_token; @@ -505,15 +506,17 @@ }; int -scan(char **sp) +scan(sp) + char **sp; { - char *cp, *cp2; - int c; - struct lex *lp; + register char *cp, *cp2; + register int c; + register struct lex *lp; int quotec; if (regretp >= 0) { - istrcpy(lexstring, string_stack[regretp], STRINGLEN); + strncpy(lexstring, string_stack[regretp], STRINGLEN); + lexstring[STRINGLEN-1]='\0'; lexnumber = numberstack[regretp]; return(regretstack[regretp--]); } @@ -524,6 +527,7 @@ /* * strip away leading white space. */ + while (c == ' ' || c == '\t') c = *cp++; @@ -531,6 +535,7 @@ * If no characters remain, we are at end of line, * so report that. */ + if (c == '\0') { *sp = --cp; return(TEOL); @@ -541,6 +546,7 @@ * the number and convert it on the fly. * Return TNUMBER when done. */ + if (isdigit(c)) { lexnumber = 0; while (isdigit(c)) { @@ -557,6 +563,7 @@ * Check for single character tokens; return such * if found. */ + for (lp = &singles[0]; lp->l_char != 0; lp++) if (c == lp->l_char) { lexstring[0] = c; @@ -572,6 +579,7 @@ * If the lead character is a " or ', save it * and scan until you get another. */ + quotec = 0; if (c == '\'' || c == '"') { quotec = c; @@ -590,7 +598,7 @@ } if (quotec && c == 0) { fprintf(stderr, "Missing %c\n", quotec); - return(TERROR); + return TERROR; } *sp = --cp; *cp2 = '\0'; @@ -601,11 +609,11 @@ * Unscan the named token by pushing it onto the regret stack. */ void -regret(int token) +regret(token) + int token; { - if (++regretp >= REGDEP) - errx(1, "Too many regrets"); + panic("Too many regrets"); regretstack[regretp] = token; lexstring[STRINGLEN-1] = '\0'; string_stack[regretp] = savestr(lexstring); @@ -616,9 +624,8 @@ * Reset all the scanner global variables. */ void -scaninit(void) +scaninit() { - regretp = -1; } @@ -627,21 +634,22 @@ * its message number. */ int -first(int f, int m) +first(f, m) + int f, m; { - struct message *mp; + register struct message *mp; if (msgCount == 0) - return(0); + return 0; f &= MDELETED; m &= MDELETED; for (mp = dot; mp < &message[msgCount]; mp++) if ((mp->m_flag & m) == f) - return(mp - message + 1); + return mp - message + 1; for (mp = dot-1; mp >= &message[0]; mp--) if ((mp->m_flag & m) == f) - return(mp - message + 1); - return(0); + return mp - message + 1; + return 0; } /* @@ -649,12 +657,14 @@ * if so. */ int -matchsender(char *str, int mesg) +matchsender(str, mesg) + char *str; + int mesg; { - char *cp, *cp2, *backup; + register char *cp, *cp2, *backup; if (!*str) /* null string matches nothing instead of everything */ - return(0); + return 0; backup = cp2 = nameof(&message[mesg - 1], 0); cp = str; while (*cp2) { @@ -669,83 +679,45 @@ } /* - * See if the passed name received the passed message number. Return true - * if so. - */ -static char *to_fields[] = { "to", "cc", "bcc", NULL }; - -int -matchto(char *str, int mesg) -{ - struct message *mp; - char *cp, *cp2, *backup, **to; - - str++; - - if (*str == 0) /* null string matches nothing instead of everything */ - return(0); - - mp = &message[mesg-1]; - - for (to = to_fields; *to; to++) { - cp = str; - cp2 = hfield(*to, mp); - if (cp2 != NULL) { - backup = cp2; - while (*cp2) { - if (*cp == 0) - return(1); - if (raise(*cp++) != raise(*cp2++)) { - cp2 = ++backup; - cp = str; - } - } - if (*cp == 0) - return(1); - } - } - return(0); -} - -/* * See if the given string matches inside the subject field of the * given message. For the purpose of the scan, we ignore case differences. * If it does, return true. The string search argument is assumed to * have the form "/search-string." If it is of the form "/," we use the * previous search string. */ -char lastscan[STRINGLEN]; +char lastscan[128]; int -matchsubj(char *str, int mesg) +matchsubj(str, mesg) + char *str; + int mesg; { - struct message *mp; - char *cp, *cp2, *backup; + register struct message *mp; + register char *cp, *cp2, *backup; str++; - if (*str == '\0') + if (strlen(str) == 0) { str = lastscan; - else - istrcpy(lastscan, str, sizeof(lastscan)); + } else { + strncpy(lastscan, str, 128); + lastscan[127]='\0'; + } mp = &message[mesg-1]; /* * Now look, ignoring case, for the word in the string. */ - if (value("searchheaders") && (cp = strchr(str, ':'))) { - /* Check for special case "/To:" */ - if (raise(str[0]) == 'T' && raise(str[1]) == 'O' && - str[2] == ':') - return(matchto(cp, mesg)); + + if (value("searchheaders") && (cp = index(str, ':'))) { *cp++ = '\0'; - cp2 = hfield(*str ? str : "subject", mp); + cp2 = hfield(str, mp); cp[-1] = ':'; str = cp; } else { cp = str; cp2 = hfield("subject", mp); } - if (cp2 == NULL) + if (cp2 == NOSTR) return(0); backup = cp2; while (*cp2) { @@ -763,13 +735,14 @@ * Mark the named message by setting its mark bit. */ void -mark(int mesg) +mark(mesg) + int mesg; { - int i; + register int i; i = mesg; if (i < 1 || i > msgCount) - errx(1, "Bad message number to mark"); + panic("Bad message number to mark"); message[i-1].m_flag |= MMARK; } @@ -777,13 +750,14 @@ * Unmark the named message. */ void -unmark(int mesg) +unmark(mesg) + int mesg; { - int i; + register int i; i = mesg; if (i < 1 || i > msgCount) - errx(1, "Bad message number to unmark"); + panic("Bad message number to unmark"); message[i-1].m_flag &= ~MMARK; } @@ -791,10 +765,11 @@ * Return the message number corresponding to the passed meta character. */ int -metamess(int meta, int f) +metamess(meta, f) + int meta, f; { - int c, m; - struct message *mp; + register int c, m; + register struct message *mp; c = meta; switch (c) { @@ -805,7 +780,7 @@ for (mp = &message[0]; mp < &message[msgCount]; mp++) if ((mp->m_flag & MDELETED) == f) return(mp - &message[0] + 1); - puts("No applicable messages"); + printf("No applicable messages\n"); return(-1); case '$': @@ -815,11 +790,11 @@ for (mp = &message[msgCount-1]; mp >= &message[0]; mp--) if ((mp->m_flag & MDELETED) == f) return(mp - &message[0] + 1); - puts("No applicable messages"); + printf("No applicable messages\n"); return(-1); case '.': - /* + /* * Current message. */ m = dot - &message[0] + 1; diff -urN mailx-8.1.1.orig/mail.1 mailx-8.1.1/mail.1 --- mailx-8.1.1.orig/mail.1 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/mail.1 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,4 @@ -.\" $OpenBSD: mail.1,v 1.35 2002/11/14 02:57:28 deraadt Exp $ -.\" +.\" $OpenBSD: mail.1,v 1.5 1994/06/29 05:09:32 deraadt Exp $ .\" Copyright (c) 1980, 1990, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -31,24 +30,21 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)mail.1 8.8 (Berkeley) 4/28/95 +.\" from: @(#)mail.1 8.2 (Berkeley) 12/30/93 .\" -.Dd April 28, 1995 +.Dd December 30, 1993 .Dt MAIL 1 -.Os +.Os BSD 4 .Sh NAME -.Nm mail , -.Nm mailx , -.Nm Mail +.Nm mail .Nd send and receive mail .Sh SYNOPSIS .Nm mail .Op Fl iInv .Op Fl s Ar subject -.Op Fl c Ar list -.Op Fl b Ar list -.Ar to-addr Op Ar ... -.Op Fl Ar sendmail-options Op Ar ... +.Op Fl c Ar cc-addr +.Op Fl b Ar bcc-addr +.Ar to-addr... .Nm mail .Op Fl iInNv .Fl f @@ -56,15 +52,14 @@ .Nm mail .Op Fl iInNv .Op Fl u Ar user -.Sh DESCRIPTION -.Nm mail -is an intelligent mail processing system which has +.Sh INTRODUCTION +.Nm Mail +is an intelligent mail processing system, which has a command syntax reminiscent of .Xr \&ed 1 with lines replaced by messages. .Pp -The options are as follows: -.Bl -tag -width Ds +.Bl -tag -width flag .It Fl v Verbose mode. The details of @@ -76,66 +71,46 @@ .Nm mail on noisy phone lines. .It Fl I -Forces -.Nm mail -to run in interactive mode, even when input is not a terminal. -In particular, the special -.Ic \&~ -command character, used when sending mail, is only available interactively. +Forces mail to run in interactive mode even when +input isn't a terminal. +In particular, the +.Sq Ic \&~ +special +character when sending mail is only active in interactive mode. .It Fl n Inhibits reading .Pa /etc/mail.rc upon startup. .It Fl N -Inhibits initial display of message headers +Inhibits the initial display of message headers when reading mail or editing a mail folder. -.It Fl s Ar subject +.It Fl s Specify subject on command line (only the first argument after the .Fl s flag is used as a subject; be careful to quote subjects -containing spaces). -.It Fl c Ar list +containing spaces.) +.It Fl c Send carbon copies to .Ar list of users. -.Ar list -should be a comma separated list of names. -.It Fl b Ar list +.It Fl b Send blind carbon copies to .Ar list . -.It Fl f Ar name -Read in the contents of your mailbox -(or the specified file -.Ar name ) -for processing; when you quit, +List should be a comma-separated list of names. +.It Fl f +Read in the contents of your +.Ar mbox +(or the specified file) +for processing; when you +.Ar quit , .Nm mail writes undeleted messages back to this file. -.It Fl u Ar user +.It Fl u Is equivalent to: .Pp -.Dl $ mail -f /var/mail/user -.Pp -except that locking is done. +.Dl mail -f /var/spool/mail/user .El -.Ss Startup actions -At startup time, -.Nm mail -will execute commands in the system command files -.Pa /usr/share/misc/mail.rc , -.Pa /usr/local/etc/mail.rc -and -.Pa /etc/mail.rc -in order unless explicitly told not to by using the -.Fl n -option. -Next, the commands in the user's personal command file -.Pa ~/.mailrc -are executed. -.Nm mail -then examines its command line options to determine whether the user -requested a new message to be sent or existing messages in a mailbox -to be examined. .Ss Sending mail To send a message to one or more people, .Nm mail @@ -143,56 +118,56 @@ whom the mail will be sent. You are then expected to type in your message, followed -by a control-D -.Pq Sq ^D +by an +.Sq Li control\-D at the beginning of a line. -The section below, +The section below .Ar Replying to or originating mail , describes some features of .Nm mail available to help you compose your letter. .Pp .Ss Reading mail -In normal usage, +In normal usage .Nm mail is given no arguments and checks your mail out of the post office, then prints out a one line header of each message found. -The current message is initially set to the first message (numbered 1) +The current message is initially the first message (numbered 1) and can be printed using the .Ic print command (which can be abbreviated -.Ic p ) . -Moving among the messages is much like moving between lines in -.Xr ed 1 ; -you may use -.Ic \&+ +.Ql Ic p ) . +You can move among the messages much as you move between lines in +.Xr \&ed 1 , +with the commands +.Ql Ic \&+ and -.Ic \&- -to shift forwards and backwards, or simply enter a message number to move -directly. +.Ql Ic \&\- +moving backwards and forwards, and +simple numbers. .Pp -.Ss Disposing of mail +.Ss Disposing of mail. After examining a message you can .Ic delete -.Pq Ic d -or +.Ql Ic d ) +the message or .Ic reply -.Pq Ic r +.Ql Ic r ) to it. Deletion causes the .Nm mail program to forget about the message. This is not irreversible; the message can be .Ic undeleted -.Pq Ic u +.Ql Ic u ) by giving its number, or the .Nm mail session can be aborted by giving the .Ic exit -.Pq Ic x +.Ql Ic x ) command. -Deleted messages, however, will usually disappear, never to be seen again. +Deleted messages will, however, usually disappear never to be seen again. .Pp .Ss Specifying messages Commands such as @@ -202,22 +177,22 @@ can be given a list of message numbers as arguments to apply to a number of messages at once. Thus -.Ic delete 1 2 +.Dq Li delete 1 2 deletes messages 1 and 2, while -.Ic delete 1\-5 +.Dq Li delete 1\-5 deletes messages 1 through 5. The special name -.Sq \&* -addresses all messages and -.Sq \&$ +.Ql Li \&* +addresses all messages, and +.Ql Li \&$ addresses the last message; thus the command .Ic top which prints the first few lines of a message could be used in -.Ic top \&* +.Dq Li top \&* to print the first few lines of all messages. .Pp -.Ss Replying to or originating mail +.Ss Replying to or originating mail. You can use the .Ic reply command to @@ -227,15 +202,15 @@ defines the contents of the message. While you are composing a message, .Nm mail -treats lines beginning with the tilde -.Pq Sq ~ -character specially. +treats lines beginning with the character +.Ql Ic \&~ +specially. For instance, typing -.Ic ~m +.Ql Ic \&~m (alone on a line) will place a copy -of the current message into the response, right shifting it by a single -tab-stop (see -.Va indentprefix +of the current message into the response right shifting it by a tabstop +(see +.Em indentprefix variable, below). Other escapes will set up subject fields, add and delete recipients to the message and allow you to escape to an editor to revise the @@ -243,22 +218,23 @@ (These options are given in the summary below.) .Pp -.Ss Ending a mail processing session +.Ss Ending a mail processing session. You can end a .Nm mail session with the .Ic quit -.Pq Ic q +.Ql Ic q ) command. Messages which have been examined go to your .Ar mbox file unless they have been deleted in which case they are discarded. -Unexamined messages go back to the post office (see the +Unexamined messages go back to the post office. +(See the .Fl f option above). .Pp -.Ss Personal and system wide distribution lists -It is also possible to create personal distribution lists so that, +.Ss Personal and systemwide distribution lists. +It is also possible to create a personal distribution lists so that, for instance, you can send mail to .Dq Li cohorts and have it go @@ -273,46 +249,46 @@ The current list of such aliases can be displayed with the .Ic alias command in -.Nm mail . +.Nm mail . System wide distribution lists can be created by editing -.Pa /etc/mail/aliases , -(see -.Xr aliases 5 +.Pa /etc/aliases , +see +.Xr aliases 5 and -.Xr sendmail 8 ) ; +.Xr sendmail 8 ; these are kept in a different syntax. In mail you send, personal aliases will be expanded in mail sent to others so that they will be able to .Ic reply to the recipients. -System wide aliases +System wide +.Ic aliases are not expanded when the mail is sent, but any reply returned to the machine will have the system wide alias expanded as all mail goes through -.Xr sendmail . +.Xr sendmail . .Pp .Ss Network mail (ARPA, UUCP, Berknet) See .Xr mailaddr 7 for a description of network addresses. .Pp -.Nm mail +.Nm Mail has a number of options which can be set in the .Pa .mailrc file to alter its behavior; thus -.Ic set askcc +.Dq Li set askcc enables the .Ar askcc feature. (These options are summarized below.) .Sh SUMMARY -(Adapted from the -.Dq Mail Reference Manual . ) +(Adapted from the `Mail Reference Manual') .Pp Each command is typed on a line by itself, and may take arguments following the command word. The command need not be typed in its -entirety -- the first command which matches the typed prefix is used. +entirety \- the first command which matches the typed prefix is used. For commands which take message lists as arguments, if no message list is given, then the next message forward which satisfies the command's requirements is used. @@ -321,7 +297,7 @@ good messages at all, .Nm mail types -.Dq Li \&No applicable messages +.Dq Li No applicable messages and aborts the command. .Bl -tag -width delete @@ -329,9 +305,9 @@ Print out the preceding message. If given a numeric argument -.Ar n , +.Ar n , goes to the -.Ar n Ns th +.Ar n Ns 'th previous message and prints it. .It Ic \&? Prints a brief summary of commands. @@ -364,7 +340,7 @@ command. .It Ic alias .Pq Ic a -With no arguments, prints out all currently defined aliases. +With no arguments, prints out all currently-defined aliases. With one argument, prints out that alias. With more than one argument, creates @@ -406,7 +382,7 @@ .Pq Ic d Takes a list of messages as argument and marks them all as deleted. Deleted messages will not be saved in -.Ar mbox , +.Ar mbox , nor will they be available for most other commands. .It Ic dp (also @@ -425,15 +401,15 @@ .Pf ( Ic ex or .Ic x ) -Effects an immediate return to the shell without +Effects an immediate return to the Shell without modifying the user's system mailbox, his .Ar mbox file, or his edit file in -.Fl f . +.Fl f . .It Ic file .Pq Ic fi The same as -.Ic folder . +.Ic folder . .It Ic folders List the names of the folders in your folder directory. .It Ic folder @@ -464,14 +440,13 @@ If a .Ql \&+ -argument is given, the next 18\-message group is printed; if +argument is given, then the next 18\-message group is printed, and if a .Ql \&\- argument is given, the previous 18\-message group is printed. .It Ic help A synonym for -.Ic \&? . -.ne li +.Ic \&? .It Ic hold .Pf ( Ic ho , also @@ -479,7 +454,7 @@ Takes a message list and marks each message therein to be saved in the user's system mailbox instead of in -.Ar mbox . +.Ar mbox . Does not override the .Ic delete command. @@ -501,13 +476,6 @@ .Ic ignore is executed with no arguments, it lists the current set of ignored fields. -.It Ic inc -Incorporate any new messages that have arrived while mail -is being read. -The new messages are added to the end of the message list, -and the current message is reset to be the first new mail message. -This does not renumber the existing message list, nor -does it cause any changes made so far to be saved. .It Ic mail .Pq Ic m Takes as argument login names and distribution group names and sends @@ -522,12 +490,9 @@ have the .Ic hold option set. -.It Ic more -.Pq Ic \mo -Takes a message list and invokes the pager on that list. .It Ic next .Pq Ic n -(like +like .Ic \&+ or .Tn CR ) @@ -536,7 +501,7 @@ .It Ic preserve .Pq Ic pre A synonym for -.Ic hold . +.Ic hold . .It Ic print .Pq Ic p Takes a message list and types out each message on the user's terminal. @@ -559,7 +524,7 @@ mailbox file with the .Fl f flag, then the edit file is rewritten. -A return to the shell is +A return to the Shell is effected, unless the rewrite of edit file fails, in which case the user can escape with the .Ic exit @@ -571,10 +536,10 @@ The default message must not be deleted. .It Ic respond A synonym for -.Ic reply . +.Ic reply . .It Ic retain Add the list of header fields named to the -.Ar retained list . +.Ar retained list Only the header fields in the retain list are shown on your terminal when you print a message. All other header fields are suppressed. @@ -603,10 +568,10 @@ (no space before or after =) or .Ar option . Quotation marks may be placed around any part of the assignment statement to -quote blanks or tabs, i.e., -.Ic set indentprefix="->" . +quote blanks or tabs, i.e. +.Dq Li "set indentprefix=\*q->\*q" .It Ic saveignore -.Ic saveignore +.Ic Saveignore is to .Ic save what @@ -614,15 +579,14 @@ is to .Ic print and -.Ic type . +.Ic type . Header fields thus marked are filtered out when saving a message by .Ic save or when automatically saving to -.Ar mbox . -.pl +1 +.Ar mbox . .It Ic saveretain -.Ic saveretain +.Ic Saveretain is to .Ic save what @@ -630,15 +594,15 @@ is to .Ic print and -.Ic type . +.Ic type . Header fields thus marked are the only ones saved with a message when saving by .Ic save or when automatically saving to -.Ar mbox . -.Ic saveretain +.Ar mbox . +.Ic Saveretain overrides -.Ic saveignore . +.Ic saveignore . .It Ic shell .Pq Ic sh Invokes an interactive version of the shell. @@ -659,7 +623,7 @@ .It Ic type .Pq Ic t A synonym for -.Ic print . +.Ic print . .It Ic unalias Takes a list of names defined by .Ic alias @@ -679,28 +643,27 @@ .It Ic unset Takes a list of option names and discards their remembered values; the inverse of -.Ic set . +.Ic set . .It Ic visual .Pq Ic v Takes a message list and invokes the display editor on each message. .It Ic write .Pq Ic w Similar to -.Ic save , +.Ic save , except that .Ic only the message body -.Pf ( Ar without -the header) -is saved. +.Pq Ar without +the header) is saved. Extremely useful for such tasks as sending and receiving source program text over the message system. .It Ic xit .Pq Ic x A synonym for -.Ic exit . +.Ic exit . .It Ic z -.Nm mail +.Nm Mail presents message headers in windowfuls as described under the .Ic headers command. @@ -710,16 +673,17 @@ .Ic \&z command. Also, you can move to the previous window by using -.Ic \&z\&\- . +.Ic \&z\&\- . .El -.Ss Tilde/escapes +.Ss Tilde/Escapes +.Pp Here is a summary of the tilde escapes, which are used when composing messages to perform special functions. Tilde escapes are only recognized at the beginning of lines. The name -.Dq tilde escape +.Dq Em tilde\ escape is somewhat of a misnomer since the actual escape character can be set by the option .Ic escape . @@ -733,7 +697,7 @@ Add the given names to the list of carbon copy recipients. .It Ic \&~d Read the file -.Pa dead.letter +.Dq Pa dead.letter from your home directory into the message. .It Ic \&~e Invoke the text editor on the message collected so far. @@ -748,7 +712,6 @@ or .Ic retain command) are not included. -.ne li .It Ic \&~F Ns Ar messages Identical to .Ic \&~f , @@ -760,7 +723,7 @@ .It Ic \&~m Ns Ar messages Read the named messages into the message being sent, indented by a tab or by the value of -.Va indentprefix . +.Ar indentprefix . If no messages are specified, read the current message. Message headers currently being ignored (by the @@ -777,7 +740,7 @@ fields. .It Ic \&~q Abort the message being sent, copying the message to -.Pa dead.letter +.Dq Pa dead.letter in your home directory if .Ic save is set. @@ -817,7 +780,7 @@ you have changed the escape character, then you should double that character in order to send it. .El -.Ss Mail options +.Ss Mail Options Options are controlled via .Ic set and @@ -834,24 +797,17 @@ to be appended to the end rather than prepended. This should always be set (perhaps in .Pa /etc/mail.rc ) . -.It Ar ask , asksub +.It Ar ask, asksub Causes .Nm mail to prompt you for the subject of each message you send. If you respond with simply a newline, no subject field will be sent. -.ne li .It Ar askcc Causes you to be prompted for additional carbon copy recipients at the end of each message. Responding with a newline indicates your satisfaction with the current list. -.It Ar autoinc -Causes new mail to be automatically incorporated when it arrives. -Setting this is similar to issuing the -.Ic inc -command at each prompt, except that the current message is not -reset when new mail arrives. .It Ar askbcc Causes you to be prompted for additional blind carbon copy recipients at the end of each message. @@ -861,8 +817,8 @@ Causes the .Ic delete command to behave like -.Ic dp ; -thus, after deleting a message, the next one will be typed +.Ic dp +\- thus, after deleting a message, the next one will be typed automatically. .It Ar debug Setting the binary option @@ -872,7 +828,7 @@ on the command line and causes .Nm mail to output all sorts of information useful for debugging -.Nm mail . +.Nm mail . .It Ar dot The binary option .Ar dot @@ -894,7 +850,7 @@ which makes .Nm mail refuse to accept a control-d as the end of a message. -.Ar ignoreeof +.Ar Ignoreeof also applies to .Nm mail command mode. @@ -915,7 +871,7 @@ (erase or delete) .Nm mail copies the partial letter to the file -.Pa dead.letter +.Dq Pa dead.letter in your home directory. Setting the binary option .Ar nosave @@ -929,39 +885,9 @@ .It Ar quiet Suppresses the printing of the version when first invoked. .It Ar searchheaders -If this option is set, then a message-list specifier in the form -.Dq /x:y -will expand to all messages containing the substring -.Dq y -in the header -field -.Dq x . -The string search is case insensitive. -If -.Dq x -is omitted, it will default to the -.Dq Subject -header field. -The form -.Dq /to:y -is a special case, and will expand -to all messages containing the substring -.Dq y -in the -.Dq To , -.Dq Cc -or -.Dq Bcc -header fields. -The check for -.Dq to -is case sensitive, so that -.Dq /To:y -can be used to limit the search for -.Dq y -to just the -.Dq To: -field. +If this option is set, then a message-list specifier in the form ``/x:y'' +will expand to all messages containing the substring ``y'' in the header +field ``x''. The string search is case insensitive. .It Ar verbose Setting the option .Ar verbose @@ -972,7 +898,7 @@ the actual delivery of messages is displayed on the user's terminal. .El -.Ss Option string values +.Ss Option String Values .Bl -tag -width Va .It Ev EDITOR Pathname of the text editor to use in the @@ -1010,7 +936,6 @@ command and .Ic \&~v escape. -.ne li .It Va crt The valued option .Va crt @@ -1030,8 +955,7 @@ .It Ar folder The name of the directory to use for storing folders of messages. -If this name begins with a -.Ql / , +If this name begins with a `/', .Nm mail considers it to be an absolute pathname; otherwise, the folder directory is found relative to your home directory. @@ -1048,10 +972,8 @@ mail. If not defined, then outgoing mail is not so saved. .It Ar indentprefix -String used by the -.Ic \&~m -tilde escape for indenting messages, in place of the normal tab character -.Pq Sq ^I +String used by the ``~m'' tilde escape for indenting messages, in place of +the normal tab character (^I). Be sure to quote the value if it contains spaces or tabs. .It Ar toplines @@ -1061,54 +983,44 @@ command; normally, the first five lines are printed. .El .Sh ENVIRONMENT -.Nm mail +.Nm Mail utilizes the -.Ev HOME , -.Ev LOGNAME , +.Ev HOME and .Ev USER environment variables. -.Pp -If the -.Ev MAIL -environment variable is set, its value is used as the path to the -user's mail spool. .Sh FILES -.Bl -tag -width /usr/share/misc/mail.*help -compact -.It Pa /var/mail/* -post office (unless overridden by the -.Ev MAIL -environment variable) +.Bl -tag -width /usr/lib/mail.*help -compact +.It Pa /var/spool/mail/* +Post office. .It ~/mbox -user's old mail +User's old mail. .It ~/.mailrc -file giving initial mail commands; can be overridden by setting the -.Ev MAILRC -environment variable +File giving initial mail commands. .It Pa /tmp/R* -temporary files -.It Pa /usr/share/misc/mail.*help -help files +Temporary files. +.It Pa /usr/lib/mail.*help +Help files. .It Pa /etc/mail.rc -system initialization file +System initialization file. .El .Sh SEE ALSO .Xr fmt 1 , -.Xr lockspool 1 , +.Xr newaliases 1 , .Xr vacation 1 , .Xr aliases 5 , .Xr mailaddr 7 , -.Xr mail.local 8 , -.Xr newaliases 8 , .Xr sendmail 8 +and .Rs -.%T "The Mail Reference Manual" +.%T "The Mail Reference Manual" . .Re .Sh HISTORY A .Nm mail -command appeared in -.At v3 . +command +appeared in +.At v6 . This man page is derived from .%T "The Mail Reference Manual" originally written by Kurt Shoens. @@ -1117,10 +1029,5 @@ Most are not useful to the general user. .Pp -Usually, -.Nm mail -and -.Nm mailx -are just links to -.Nm Mail , -which can be confusing. +.\" This bug is not the case in this particular distribution. +.\" Usually, .Nm mail is just a link to .Nm Mail, which can be confusing. diff -urN mailx-8.1.1.orig/main.c mailx-8.1.1/main.c --- mailx-8.1.1.orig/main.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/main.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: main.c,v 1.17 2001/11/21 15:28:25 millert Exp $ */ -/* $NetBSD: main.c,v 1.7 1997/05/13 06:15:57 mikel Exp $ */ +/* $OpenBSD: main.c,v 1.5 1996/06/08 19:48:31 christos Exp $ */ +/* $NetBSD: main.c,v 1.5 1996/06/08 19:48:31 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -35,53 +35,93 @@ */ #ifndef lint -static const char copyright[] = +static char copyright[] = "@(#) Copyright (c) 1980, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint #if 0 -static const char sccsid[] = "@(#)main.c 8.2 (Berkeley) 4/20/95"; +static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: main.c,v 1.17 2001/11/21 15:28:25 millert Exp $"; +static char rcsid[] = "$OpenBSD: main.c,v 1.5 1996/06/08 19:48:31 christos Exp $"; #endif #endif /* not lint */ +/* + * Most strcpy/sprintf functions have been changed to strncpy/snprintf to + * correct several buffer overruns (at least one ot them was exploitable). + * Sat Jun 20 04:58:09 CEST 1998 Alvaro Martinez Echevarria + */ + #include "rcv.h" #include #include #include "extern.h" -/* __dead void usage(void); */ -int main(int, char **); - /* * Mail -- a mail program * * Startup -- interface with user. */ +jmp_buf hdrjmp; + int -main(int argc, char **argv) +main(argc, argv) + int argc; + char *argv[]; { - int i; + register int i; struct name *to, *cc, *bcc, *smopts; char *subject; char *ef; + char* cmd; char nosrc = 0; - char *rc; - extern const char version[]; + sig_t prevint; + /* + * Absolutely the first thing we do is save our egid + * and set it to the rgid, so that we can safely run + * setgid. We use the sgid (saved set-gid) to allow ourselves + * to revert to the egid if we want (temporarily) to become + * priveliged. + */ + effectivegid = getegid(); + realgid = getgid(); + if (setgid (realgid) < 0) { + perror("setgid"); + exit(1); + } + /* * Set up a reasonable environment. * Figure out whether we are being run interactively, * start the SIGCHLD catcher, and so forth. */ - (void)signal(SIGCHLD, sigchild); - (void)signal(SIGPIPE, SIG_IGN); + (void) signal(SIGCHLD, sigchild); if (isatty(0)) assign("interactive", ""); + + /* + * Grab some stuff from the environment we might use + */ + + if (cmd = getenv("PAGER")) + assign("PAGER", cmd); + if (cmd = getenv("LISTER")) + assign("LISTER", cmd); + if (cmd = getenv("SHELL")) + assign("SHELL", cmd); + if (cmd = getenv("EDITOR")) + assign("EDITOR", cmd); + if (cmd = getenv("VISUAL")) + assign("VISUAL", cmd); + if (cmd = getenv("MBOX")) + assign("MBOX", cmd); + if (cmd = getenv("DEAD")) + assign("DEAD", cmd); + image = -1; /* * Now, determine how we are being used. @@ -90,13 +130,13 @@ * of users to mail to. Argp will be set to point to the * first of these users. */ - ef = NULL; - to = NULL; - cc = NULL; - bcc = NULL; - smopts = NULL; - subject = NULL; - while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != -1) { + ef = NOSTR; + to = NIL; + cc = NIL; + bcc = NIL; + smopts = NIL; + subject = NOSTR; + while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) { switch (i) { case 'T': /* @@ -104,19 +144,17 @@ * articles have been read/deleted for netnews. */ Tflag = optarg; - if ((i = creat(Tflag, 0600)) < 0) - err(1, "%s", Tflag); - (void)close(i); + if ((i = creat(Tflag, 0600)) < 0) { + perror(Tflag); + exit(1); + } + close(i); break; case 'u': /* * Next argument is person to pretend to be. */ - if (strlen(optarg) >= 33) - errx(1, "username `%s' too long", optarg); - unsetenv("MAIL"); myname = optarg; - uflag = 1; break; case 'i': /* @@ -186,9 +224,14 @@ */ bcc = cat(bcc, nalloc(optarg, GBCC)); break; - default: - usage(); - /*NOTREACHED*/ + case '?': + fputs("\ +Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\ + [- sendmail-options ...]\n\ + mail [-iInNv] -f [name]\n\ + mail [-iInNv] [-u user]\n", + stderr); + exit(1); } } for (i = optind; (argv[i]) && (*argv[i] != '-'); i++) @@ -198,19 +241,14 @@ /* * Check for inconsistent arguments. */ - if (to == NULL && (subject != NULL || cc != NULL || bcc != NULL)) - errx(1, "You must specify direct recipients with -s, -c, or -b"); - if (ef != NULL && to != NULL) - errx(1, "Cannot give -f and people to send to"); - /* - * Block SIGINT except where we install an explicit handler for it. - */ - sigemptyset(&intset); - sigaddset(&intset, SIGINT); - (void)sigprocmask(SIG_BLOCK, &intset, NULL); - /* - * Initialization. - */ + if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) { + fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr); + exit(1); + } + if (ef != NOSTR && to != NIL) { + fprintf(stderr, "Cannot give -f and people to send to.\n"); + exit(1); + } tinit(); setscreensize(); input = stdin; @@ -222,9 +260,7 @@ * Expand returns a savestr, but load only uses the file name * for fopen, so it's safe to do this. */ - if ((rc = getenv("MAILRC")) == 0) - rc = "~/.mailrc"; - load(expand(rc)); + load(expand("~/.mailrc")); if (!rcvmode) { mail(to, cc, bcc, smopts, subject); /* @@ -237,25 +273,44 @@ * Decide whether we are editing a mailbox or reading * the system mailbox, and open up the right stuff. */ - if (ef == NULL) + if (ef == NOSTR) ef = "%"; if (setfile(ef) < 0) exit(1); /* error already reported */ + if (setjmp(hdrjmp) == 0) { + extern char *version; - if (value("quiet") == NULL) - (void)printf("Mail version %s. Type ? for help.\n", - version); - announce(); - (void)fflush(stdout); + if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN) + signal(SIGINT, hdrstop); + if (value("quiet") == NOSTR) + printf("Mail version %s. Type ? for help.\n", + version); + announce(); + fflush(stdout); + signal(SIGINT, prevint); + } commands(); - (void)ignoresig(SIGHUP, NULL, NULL); - (void)ignoresig(SIGINT, NULL, NULL); - (void)ignoresig(SIGQUIT, NULL, NULL); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); quit(); exit(0); } /* + * Interrupt printing of the headers. + */ +void +hdrstop(signo) + int signo; +{ + + fflush(stdout); + fprintf(stderr, "\nInterrupt\n"); + longjmp(hdrjmp, 1); +} + +/* * Compute what the screen size for printing headers should be. * We use the following algorithm for the height: * If baud rate < 1200, use 9 @@ -264,7 +319,7 @@ * Width is either 80 or ws_col; */ void -setscreensize(void) +setscreensize() { struct termios tbuf; struct winsize ws; @@ -273,7 +328,7 @@ if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0) ws.ws_col = ws.ws_row = 0; if (tcgetattr(1, &tbuf) < 0) - ospeed = 9600; + ospeed = B9600; else ospeed = cfgetospeed(&tbuf); if (ospeed < B1200) @@ -289,15 +344,3 @@ if ((screenwidth = ws.ws_col) == 0) screenwidth = 80; } - -usage(void) -{ - - fprintf(stderr, "usage: %s [-iInv] [-s subject] [-c cc-addr] " - "[-b bcc-addr] to-addr ...\n", __progname); - fprintf(stderr, " %*s [- sendmail-options ...]\n", - (int)strlen(__progname), ""); - fprintf(stderr, " %s [-iInNv] -f [name]\n", __progname); - fprintf(stderr, " %s [-iInNv] [-u user]\n", __progname); - exit(1); -} diff -urN mailx-8.1.1.orig/misc/mail.help mailx-8.1.1/misc/mail.help --- mailx-8.1.1.orig/misc/mail.help 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/misc/mail.help 1996-06-21 21:26:58.000000000 -0700 @@ -1,37 +1,23 @@ -Mail Command Description -------------------------- -------------------------------------------- -t [message list] type message(s). -n goto and type next message. -e [message list] edit message(s). -f [message list] give head lines of messages. -d [message list] delete message(s). -s [message list] append message(s) to file. -u [message list] undelete message(s). -R [message list] reply to message sender(s). -r [message list] reply to message sender(s) and all recipients. -p [message list] print message list (pipe to lpr). -pre [message list] make messages go back to /var/mail. -m mail to specific recipient(s). -q quit, saving unresolved messages in mbox. -x quit, do not remove system mailbox. -h print out active message headers. -! shell escape. -| [msglist] command pipe message(s) to shell command. -pi [msglist] command pipe message(s) to shell command. + Mail Commands +t type messages +n goto and type next message +e edit messages +f give head lines of messages +d delete messages +s file append messages to file +u undelete messages +R reply to message senders +r reply to message senders and all recipients +pre make messages go back to /usr/spool/mail +m mail to specific users +q quit, saving unresolved messages in mbox +x quit, do not remove system mailbox +h print out active message headers +! shell escape cd [directory] chdir to directory or home if none given -fi switch to file (%=system inbox, %user=user's - system inbox). + searches in your folder - directory for the file. -set variable[=value] set Mail variable. -A [message list] consists of integers, ranges of same, :status, /subject, or -user names separated by spaces. If omitted, Mail uses the current message. -The pipe command doesn't accept user names or subject message list, since -that might conflict with the command string. +A consists of integers, ranges of same, or user names separated +by spaces. If omitted, Mail uses the last message typed. -A consists of recipient addresses or aliases separated by -spaces. Aliases are defined in .mailrc in your home directory. - - is a full or relative pathname, +folder, % (system inbox), %user -(specified user's syetem inbox), # (previous file), & (mbox file), or an -expression understood by ${SHELL:-/bin/sh} -c 'echo ...'. +A consists of user names or aliases separated by spaces. +Aliases are defined in .mailrc in your home directory. diff -urN mailx-8.1.1.orig/misc/mail.rc mailx-8.1.1/misc/mail.rc --- mailx-8.1.1.orig/misc/mail.rc 1996-06-21 21:26:59.000000000 -0700 +++ mailx-8.1.1/misc/mail.rc 2003-03-26 13:03:39.000000000 -0800 @@ -1,2 +1,2 @@ -set append dot save asksub +set ask askcc append dot save crt ignore Received Message-Id Resent-Message-Id Status Mail-From Return-Path Via diff -urN mailx-8.1.1.orig/misc/mail.tildehelp mailx-8.1.1/misc/mail.tildehelp --- mailx-8.1.1.orig/misc/mail.tildehelp 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/misc/mail.tildehelp 1996-06-21 21:26:59.000000000 -0700 @@ -1,22 +1,22 @@ ----------------------------------------------------------- The following ~ escapes are defined: -~~ Quote a single tilde. -~b users Add users to "blind" cc list. -~c users Add users to cc list. -~d Read in dead.letter. -~e Edit the message buffer. -~f messages Read in messages. -~F messages Same as ~f, but keep all header lines. -~h Prompt for to list, subject and cc list. -~r file Read a file into the message buffer. -~p Print (show) the message buffer. -~m messages Read in messages, right shifted by a tab. -~M messages Same as ~m, but keep all header lines. -~s subject Set subject. -~t users Add users to to list. -~v Invoke display editor on message. +~~ Quote a single tilde +~b users Add users to "blind" cc list +~c users Add users to cc list +~d Read in dead.letter +~e Edit the message buffer +~f messages Read in messages +~F messages Same as ~f, but keep all header lines +~h Prompt for to list, subject and cc list +~r file Read a file into the message buffer +~p Print the message buffer +~m messages Read in messages, right shifted by a tab +~M messages Same as ~m, but keep all header lines +~s subject Set subject +~t users Add users to to list +~v Invoke display editor on message ~w file Write message onto file. -~? Print this message. -~!command Invoke the shell. -~|command Pipe the message through the command and replace it. +~? Print this message +~!command Invoke the shell +~|command Pipe the message through the command ----------------------------------------------------------- diff -urN mailx-8.1.1.orig/names.c mailx-8.1.1/names.c --- mailx-8.1.1.orig/names.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/names.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,4 +1,4 @@ -/* $OpenBSD: names.c,v 1.16 2001/11/21 20:41:55 millert Exp $ */ +/* $OpenBSD: names.c,v 1.5 1996/06/08 19:48:32 christos Exp $ */ /* $NetBSD: names.c,v 1.5 1996/06/08 19:48:32 christos Exp $ */ /* @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)names.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)names.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: names.c,v 1.16 2001/11/21 20:41:55 millert Exp $"; +static char rcsid[] = "$OpenBSD: names.c,v 1.5 1996/06/08 19:48:32 christos Exp $"; #endif #endif /* not lint */ @@ -58,13 +58,15 @@ * name and return it. */ struct name * -nalloc(char *str, int ntype) -{ - struct name *np; - - np = (struct name *)salloc(sizeof(*np)); - np->n_flink = NULL; - np->n_blink = NULL; +nalloc(str, ntype) + char str[]; + int ntype; +{ + register struct name *np; + + np = (struct name *) salloc(sizeof *np); + np->n_flink = NIL; + np->n_blink = NIL; np->n_type = ntype; np->n_name = savestr(str); return(np); @@ -74,14 +76,15 @@ * Find the tail of a list and return it. */ struct name * -tailof(struct name *name) +tailof(name) + struct name *name; { - struct name *np; + register struct name *np; np = name; - if (np == NULL) - return(NULL); - while (np->n_flink != NULL) + if (np == NIL) + return(NIL); + while (np->n_flink != NIL) np = np->n_flink; return(np); } @@ -89,53 +92,55 @@ /* * Extract a list of names from a line, * and make a list of names from it. - * Return the list or NULL if none found. + * Return the list or NIL if none found. */ struct name * -extract(char *line, int ntype) -{ - char *cp; - struct name *top, *np, *t; - char *nbuf; - - if (line == NULL || *line == '\0') - return(NULL); - if ((nbuf = (char *)malloc(strlen(line) + 1)) == NULL) - errx(1, "Out of memory"); - top = NULL; - np = NULL; +extract(line, ntype) + char line[]; + int ntype; +{ + register char *cp; + register struct name *top, *np, *t; + char nbuf[BUFSIZ]; + + if (line == NOSTR || *line == '\0') + return NIL; + top = NIL; + np = NIL; cp = line; - while ((cp = yankword(cp, nbuf)) != NULL) { + while ((cp = yankword(cp, nbuf, BUFSIZ)) != NOSTR) { t = nalloc(nbuf, ntype); - if (top == NULL) + if (top == NIL) top = t; else np->n_flink = t; t->n_blink = np; np = t; } - (void)free(nbuf); - return(top); + return top; } /* * Turn a list of names into a string of the same names. */ char * -detract(struct name *np, int ntype) -{ - int s, comma; - char *cp, *top; - struct name *p; +detract(np, ntype) + register struct name *np; + int ntype; +{ + register int s; + register char *cp, *top; + register struct name *p; + register int comma; comma = ntype & GCOMMA; - if (np == NULL) - return(NULL); + if (np == NIL) + return(NOSTR); ntype &= ~GCOMMA; s = 0; if (debug && comma) - fputs("detract asked to insert commas\n", stderr); - for (p = np; p != NULL; p = p->n_flink) { + fprintf(stderr, "detract asked to insert commas\n"); + for (p = np; p != NIL; p = p->n_flink) { if (ntype && (p->n_type & GMASK) != ntype) continue; s += strlen(p->n_name) + 1; @@ -143,15 +148,15 @@ s++; } if (s == 0) - return(NULL); + return(NOSTR); s += 2; top = salloc(s); cp = top; - for (p = np; p != NULL; p = p->n_flink) { + for (p = np; p != NIL; p = p->n_flink) { if (ntype && (p->n_type & GMASK) != ntype) continue; cp = copy(p->n_name, cp); - if (comma && p->n_flink != NULL) + if (comma && p->n_flink != NIL) *cp++ = ','; *cp++ = ' '; } @@ -166,16 +171,19 @@ * Throw away things between ()'s, and take anything between <>. */ char * -yankword(char *ap, char *wbuf) +yankword(ap, wbuf, maxsize) + char *ap, wbuf[]; + int maxsize; { - char *cp, *cp2; + register char *cp, *cp2; + int used = 0; cp = ap; for (;;) { if (*cp == '\0') - return(NULL); + return NOSTR; if (*cp == '(') { - int nesting = 0; + register int nesting = 0; while (*cp != '\0') { switch (*cp++) { @@ -195,13 +203,14 @@ break; } if (*cp == '<') - for (cp2 = wbuf; *cp && (*cp2++ = *cp++) != '>';) + /* Pre-increment "used" so we leave room for the trailing zero */ + for (cp2 = wbuf; *cp && (++used < maxsize) && (*cp2++ = *cp++) != '>';) ; else - for (cp2 = wbuf; *cp && !strchr(" \t,(", *cp); *cp2++ = *cp++) + for (cp2 = wbuf; *cp && (++used < maxsize) && !index(" \t,(", *cp); *cp2++ = *cp++) ; *cp2 = '\0'; - return(cp); + return cp; } /* @@ -213,19 +222,24 @@ * program and removed. */ struct name * -outof(struct name *names, FILE *fo, struct header *hp) +outof(names, fo, hp) + struct name *names; + FILE *fo; + struct header *hp; { - int c, ispipe; - struct name *np, *top; + register int c; + register struct name *np, *top; time_t now; char *date, *fname; FILE *fout, *fin; + int ispipe; + extern char *tempEdit; top = names; np = names; - (void)time(&now); + (void) time(&now); date = ctime(&now); - while (np != NULL) { + while (np != NIL) { if (!isfileaddr(np->n_name) && np->n_name[0] != '|') { np = np->n_flink; continue; @@ -240,37 +254,33 @@ * See if we have copied the complete message out yet. * If not, do so. */ - if (image < 0) { - int fd; - char tempname[PATHSIZE]; - (void)snprintf(tempname, sizeof(tempname), - "%s/mail.ReXXXXXXXXXX", tmpdir); - if ((fd = mkstemp(tempname)) == -1 || - (fout = Fdopen(fd, "a")) == NULL) { - warn("%s", tempname); + if (image < 0) { + /* hopefully we always create the file, so I change the "a" to "w" the line below */ + if ((fout = Fopen(tempEdit, "w")) == NULL) { + perror(tempEdit); senderr++; goto cant; } - image = open(tempname, O_RDWR); - (void)rm(tempname); + image = open(tempEdit, 2); + (void) unlink(tempEdit); if (image < 0) { - warn("%s", tempname); + perror(tempEdit); senderr++; - (void)Fclose(fout); + (void) Fclose(fout); goto cant; } - (void)fcntl(image, F_SETFD, 1); + (void) fcntl(image, F_SETFD, 1); fprintf(fout, "From %s %s", myname, date); puthead(hp, fout, GTO|GSUBJECT|GCC|GNL); while ((c = getc(fo)) != EOF) - (void)putc(c, fout); + (void) putc(c, fout); rewind(fo); - (void)putc('\n', fout); - (void)fflush(fout); + (void) putc('\n', fout); + (void) fflush(fout); if (ferror(fout)) - warn("%s", tempname); - (void)Fclose(fout); + perror(tempEdit); + (void) Fclose(fout); } /* @@ -278,8 +288,9 @@ * or give it as the standard input to the desired * program as appropriate. */ + if (ispipe) { - pid_t pid; + int pid; char *shell; sigset_t nset; @@ -290,13 +301,14 @@ * share the same lseek location and trample * on one another. */ - shell = value("SHELL"); + if ((shell = value("SHELL")) == NOSTR) + shell = _PATH_CSHELL; sigemptyset(&nset); sigaddset(&nset, SIGHUP); sigaddset(&nset, SIGINT); sigaddset(&nset, SIGQUIT); pid = start_command(shell, &nset, - image, -1, "-c", fname, NULL); + image, -1, "-c", fname, NOSTR); if (pid < 0) { senderr++; goto cant; @@ -305,30 +317,28 @@ } else { int f; if ((fout = Fopen(fname, "a")) == NULL) { - warn("%s", fname); + perror(fname); senderr++; goto cant; } if ((f = dup(image)) < 0) { - warn("dup"); + perror("dup"); fin = NULL; } else fin = Fdopen(f, "r"); if (fin == NULL) { - fputs("Can't reopen image\n", stderr); - (void)Fclose(fout); + fprintf(stderr, "Can't reopen image\n"); + (void) Fclose(fout); senderr++; goto cant; } rewind(fin); while ((c = getc(fin)) != EOF) - (void)putc(c, fout); - if (ferror(fout)) { - senderr++; - warn("%s", fname); - } - (void)Fclose(fout); - (void)Fclose(fin); + (void) putc(c, fout); + if (ferror(fout)) + senderr++, perror(fname); + (void) Fclose(fout); + (void) Fclose(fin); } cant: /* @@ -340,7 +350,7 @@ np = np->n_flink; } if (image >= 0) { - (void)close(image); + (void) close(image); image = -1; } return(top); @@ -352,19 +362,20 @@ * be a filename. We cheat with .'s to allow path names like ./... */ int -isfileaddr(char *name) +isfileaddr(name) + char *name; { - char *cp; + register char *cp; if (*name == '+') - return(1); + return 1; for (cp = name; *cp; cp++) { if (*cp == '!' || *cp == '%' || *cp == '@') - return(0); + return 0; if (*cp == '/') - return(1); + return 1; } - return(0); + return 0; } /* @@ -373,17 +384,19 @@ * Changed after all these months of service to recursively * expand names (2/14/80). */ + struct name * -usermap(struct name *names) +usermap(names) + struct name *names; { - struct name *new, *np, *cp; + register struct name *new, *np, *cp; struct grouphead *gh; - int metoo; + register int metoo; - new = NULL; + new = NIL; np = names; - metoo = (value("metoo") != NULL); - while (np != NULL) { + metoo = (value("metoo") != NOSTR); + while (np != NIL) { if (np->n_name[0] == '\\') { cp = np->n_flink; new = put(new, np); @@ -392,7 +405,7 @@ } gh = findgroup(np->n_name); cp = np->n_flink; - if (gh != NULL) + if (gh != NOGRP) new = gexpand(new, gh, metoo, np->n_type); else new = put(new, np); @@ -406,8 +419,12 @@ * fixed level to keep things from going haywire. * Direct recursion is not expanded for convenience. */ + struct name * -gexpand(struct name *nlist, struct grouphead *gh, int metoo, int ntype) +gexpand(nlist, gh, metoo, ntype) + struct name *nlist; + struct grouphead *gh; + int metoo, ntype; { struct group *gp; struct grouphead *ngh; @@ -420,13 +437,13 @@ return(nlist); } depth++; - for (gp = gh->g_list; gp != NULL; gp = gp->ge_link) { + for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) { cp = gp->ge_name; if (*cp == '\\') goto quote; if (strcmp(cp, gh->g_name) == 0) goto quote; - if ((ngh = findgroup(cp)) != NULL) { + if ((ngh = findgroup(cp)) != NOGRP) { nlist = gexpand(nlist, ngh, metoo, ntype); continue; } @@ -436,7 +453,7 @@ * At this point should allow to expand * to self if only person in group */ - if (gp == gh->g_list && gp->ge_link == NULL) + if (gp == gh->g_list && gp->ge_link == NOGE) goto skip; if (!metoo && strcmp(cp, myname) == 0) np->n_type |= GDEL; @@ -451,13 +468,14 @@ * Concatenate the two passed name lists, return the result. */ struct name * -cat(struct name *n1, struct name *n2) +cat(n1, n2) + struct name *n1, *n2; { - struct name *tail; + register struct name *tail; - if (n1 == NULL) + if (n1 == NIL) return(n2); - if (n2 == NULL) + if (n2 == NIL) return(n1); tail = tailof(n1); tail->n_flink = n2; @@ -470,29 +488,31 @@ * Return an error if the name list won't fit. */ char ** -unpack(struct name *sm, struct name *np) +unpack(np) + struct name *np; { - char **ap, **top; + register char **ap, **top; + register struct name *n; int t, extra, metoo, verbose; - if ((t = count(np)) == 0) - errx(1, "No names to unpack"); - t += count(sm); - + n = np; + if ((t = count(n)) == 0) + panic("No names to unpack"); /* * Compute the number of extra arguments we will need. - * We need at least four extra -- one for "send-mail", one for the - * "-i" flag, one for the "--" to signal end of command line - * arguments, and one for the terminating 0 pointer. + * We need at least two extra -- one for "mail" and one for + * the terminating 0 pointer. Additional spots may be needed + * to pass along -f to the host mailer. */ - extra = 4; - metoo = value("metoo") != NULL; + extra = 2; + extra++; + metoo = value("metoo") != NOSTR; if (metoo) extra++; - verbose = value("verbose") != NULL; + verbose = value("verbose") != NOSTR; if (verbose) extra++; - top = (char **)salloc((t + extra) * sizeof(*top)); + top = (char **) salloc((t + extra) * sizeof *top); ap = top; *ap++ = "send-mail"; *ap++ = "-i"; @@ -500,14 +520,10 @@ *ap++ = "-m"; if (verbose) *ap++ = "-v"; - for (; sm != NULL; sm = sm->n_flink) - if ((sm->n_type & GDEL) == 0) - *ap++ = sm->n_name; - *ap++ = "--"; - for (; np != NULL; np = np->n_flink) - if ((np->n_type & GDEL) == 0) - *ap++ = np->n_name; - *ap = NULL; + for (; n != NIL; n = n->n_flink) + if ((n->n_type & GDEL) == 0) + *ap++ = n->n_name; + *ap = NOSTR; return(top); } @@ -517,23 +533,24 @@ * Return the head of the new list. */ struct name * -elide(struct name *names) +elide(names) + struct name *names; { - struct name *np, *t, *new; + register struct name *np, *t, *new; struct name *x; - if (names == NULL) - return(NULL); + if (names == NIL) + return(NIL); new = names; np = names; np = np->n_flink; - if (np != NULL) - np->n_blink = NULL; - new->n_flink = NULL; - while (np != NULL) { + if (np != NIL) + np->n_blink = NIL; + new->n_flink = NIL; + while (np != NIL) { t = new; while (strcasecmp(t->n_name, np->n_name) < 0) { - if (t->n_flink == NULL) + if (t->n_flink == NIL) break; t = t->n_flink; } @@ -542,12 +559,13 @@ * If we ran out of t's, put the new entry after * the current value of t. */ + if (strcasecmp(t->n_name, np->n_name) < 0) { t->n_flink = np; np->n_blink = t; t = np; np = np->n_flink; - t->n_flink = NULL; + t->n_flink = NIL; continue; } @@ -556,12 +574,13 @@ * current t. If at the front of the list, * the new guy becomes the new head of the list. */ + if (t == new) { t = np; np = np->n_flink; t->n_flink = new; new->n_blink = t; - t->n_blink = NULL; + t->n_blink = NIL; new = t; continue; } @@ -570,6 +589,7 @@ * The normal case -- we are inserting into the * middle of the list. */ + x = np; np = np->n_flink; x->n_flink = t; @@ -582,13 +602,14 @@ * Now the list headed up by new is sorted. * Go through it and remove duplicates. */ + np = new; - while (np != NULL) { + while (np != NIL) { t = np; - while (t->n_flink != NULL && + while (t->n_flink != NIL && strcasecmp(np->n_name, t->n_flink->n_name) == 0) t = t->n_flink; - if (t == np || t == NULL) { + if (t == np || t == NIL) { np = np->n_flink; continue; } @@ -597,8 +618,9 @@ * Now t points to the last entry with the same name * as np. Make np point beyond t. */ + np->n_flink = t->n_flink; - if (t->n_flink != NULL) + if (t->n_flink != NIL) t->n_flink->n_blink = np; np = np->n_flink; } @@ -610,11 +632,12 @@ * the list. */ struct name * -put(struct name *list, struct name *node) +put(list, node) + struct name *list, *node; { node->n_flink = list; - node->n_blink = NULL; - if (list != NULL) + node->n_blink = NIL; + if (list != NIL) list->n_blink = node; return(node); } @@ -624,61 +647,63 @@ * a name list and return it. */ int -count(struct name *np) +count(np) + register struct name *np; { - int c; + register int c; - for (c = 0; np != NULL; np = np->n_flink) + for (c = 0; np != NIL; np = np->n_flink) if ((np->n_type & GDEL) == 0) c++; - return(c); + return c; } /* * Delete the given name from a namelist. */ struct name * -delname(struct name *np, char *name) -{ - struct name *p; - - for (p = np; p != NULL; p = p->n_flink) - if ((strcasecmp(p->n_name, name) == 0) || - (value("allnet") && - strncasecmp(p->n_name, name, strlen(name)) == 0 && - *(p->n_name+strlen(name)) == '@')) { - if (p->n_blink == NULL) { - if (p->n_flink != NULL) - p->n_flink->n_blink = NULL; +delname(np, name) + register struct name *np; + char name[]; +{ + register struct name *p; + + for (p = np; p != NIL; p = p->n_flink) + if (strcasecmp(p->n_name, name) == 0) { + if (p->n_blink == NIL) { + if (p->n_flink != NIL) + p->n_flink->n_blink = NIL; np = p->n_flink; continue; } - if (p->n_flink == NULL) { - if (p->n_blink != NULL) - p->n_blink->n_flink = NULL; + if (p->n_flink == NIL) { + if (p->n_blink != NIL) + p->n_blink->n_flink = NIL; continue; } p->n_blink->n_flink = p->n_flink; p->n_flink->n_blink = p->n_blink; } - return(np); + return np; } /* * Pretty print a name list * Uncomment it if you need it. */ -#if 0 + +/* void -prettyprint(struct name *name) +prettyprint(name) + struct name *name; { - struct name *np; + register struct name *np; np = name; - while (np != NULL) { + while (np != NIL) { fprintf(stderr, "%s(%d) ", np->n_name, np->n_type); np = np->n_flink; } - putc('\n', stderr); + fprintf(stderr, "\n"); } -#endif +*/ diff -urN mailx-8.1.1.orig/pathnames.h mailx-8.1.1/pathnames.h --- mailx-8.1.1.orig/pathnames.h 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/pathnames.h 2003-03-26 13:03:39.000000000 -0800 @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.6 2001/10/04 04:23:26 pvalchev Exp $ */ +/* $OpenBSD: pathnames.h,v 1.4 1996/06/08 19:48:34 christos Exp $ */ /* $NetBSD: pathnames.h,v 1.4 1996/06/08 19:48:34 christos Exp $ */ /* @@ -37,17 +37,34 @@ * $NetBSD: pathnames.h,v 1.4 1996/06/08 19:48:34 christos Exp $ */ -#include +/* mail installed files */ +#define _PATH_HELP "/usr/lib/mail.help" +#define _PATH_TILDE "/usr/lib/mail.tildehelp" +#define _PATH_MASTER_RC "/etc/mail.rc" + +/* mail runtime files */ +#ifndef _PATH_MAILDIR +#define _PATH_MAILDIR "/var/mail:/var/spool/mail" +#endif /* executables */ +#ifndef _PATH_CSHELL +#define _PATH_CSHELL "/bin/csh" +#endif +#ifndef _PATH_MORE +#define _PATH_MORE "/bin/more" +#endif +#ifndef _PATH_EX #define _PATH_EX "/usr/bin/ex" -#define _PATH_MORE "/usr/bin/more" -#define _PATH_LS "/bin/ls" -#define _PATH_LOCKSPOOL "/usr/libexec/lockspool" +#endif +#ifndef _PATH_VI +#define _PATH_VI "/usr/bin/vi" +#endif +#ifndef _PATH_SENDMAIL +#define _PATH_SENDMAIL "/usr/sbin/sendmail" +#endif -/* directories & files */ -#define _PATH_MAILDIR "/var/mail" -#define _PATH_HELP "/usr/share/misc/mail.help" -#define _PATH_TILDE "/usr/share/misc/mail.tildehelp" -#define _PATH_MASTER_RC "/etc/mail.rc" -#define _PATH_LOCTMP "/tmp/local.XXXXXXXXXX" +/* directories */ +#ifndef _PATH_TMP +#define _PATH_TMP "/tmp/" +#endif diff -urN mailx-8.1.1.orig/popen.c mailx-8.1.1/popen.c --- mailx-8.1.1.orig/popen.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/popen.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: popen.c,v 1.32 2002/06/12 06:07:15 mpech Exp $ */ -/* $NetBSD: popen.c,v 1.6 1997/05/13 06:48:42 mikel Exp $ */ +/* $OpenBSD: popen.c,v 1.3 1996/06/26 21:22:34 dm Exp $ */ +/* $NetBSD: popen.c,v 1.4 1996/06/08 19:48:35 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: popen.c,v 1.32 2002/06/12 06:07:15 mpech Exp $"; +static char rcsid[] = "$OpenBSD: popen.c,v 1.3 1996/06/26 21:22:34 dm Exp $"; #endif #endif /* not lint */ @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include "extern.h" #define READ 0 @@ -55,127 +55,163 @@ struct fp { FILE *fp; int pipe; - pid_t pid; + int pid; struct fp *link; }; static struct fp *fp_head; struct child { - pid_t pid; + int pid; char done; char free; - int status; + union wait status; struct child *link; }; -static struct child *child, *child_freelist = NULL; +static struct child *child; +static struct child *findchild __P((int)); +static void delchild __P((struct child *)); +static int file_pid __P((FILE *)); -static struct child *findchild(pid_t, int); -static void delchild(struct child *); -static pid_t file_pid(FILE *); -static int handle_spool_locks(int); +FILE * +safe_fopen(file, mode) + char *file, *mode; +{ + int omode, fd; + + if (!strcmp(mode, "r")) { + omode = O_RDONLY; + } else if (!strcmp(mode, "w")) { + omode = O_WRONLY | O_CREAT | O_EXCL; + } else if (!strcmp(mode, "a")) { + omode = O_WRONLY | O_APPEND | O_CREAT; + } else if (!strcmp(mode, "a+")) { + omode = O_RDWR | O_APPEND; + } else if (!strcmp(mode, "r+")) { + omode = O_RDWR; + } else if (!strcmp(mode, "w+")) { + omode = O_RDWR | O_CREAT | O_EXCL; + } else { + fprintf(stderr, + "Internal error: bad stdio open mode %s\n", mode); + errno = EINVAL; + return NULL; + } + + if ((fd = open(file, omode, 0666)) < 0) + return NULL; + return fdopen(fd, mode); +} FILE * -Fopen(char *file, char *mode) +Fopen(file, mode) + char *file, *mode; { FILE *fp; - if ((fp = fopen(file, mode)) != NULL) { + if ((fp = safe_fopen(file, mode)) != NULL) { register_file(fp, 0, 0); - (void)fcntl(fileno(fp), F_SETFD, 1); + (void) fcntl(fileno(fp), F_SETFD, 1); } - return(fp); + return fp; } FILE * -Fdopen(int fd, char *mode) +Fdopen(fd, mode) + int fd; + char *mode; { FILE *fp; if ((fp = fdopen(fd, mode)) != NULL) { register_file(fp, 0, 0); - (void)fcntl(fileno(fp), F_SETFD, 1); + (void) fcntl(fileno(fp), F_SETFD, 1); } - return(fp); + return fp; } int -Fclose(FILE *fp) +Fclose(fp) + FILE *fp; { - unregister_file(fp); - return(fclose(fp)); + return fclose(fp); } FILE * -Popen(char *cmd, char *mode) +Popen(cmd, mode) + char *cmd; + char *mode; { int p[2]; int myside, hisside, fd0, fd1; - pid_t pid; + int pid; sigset_t nset; FILE *fp; if (pipe(p) < 0) - return(NULL); - (void)fcntl(p[READ], F_SETFD, 1); - (void)fcntl(p[WRITE], F_SETFD, 1); + return NULL; + (void) fcntl(p[READ], F_SETFD, 1); + (void) fcntl(p[WRITE], F_SETFD, 1); if (*mode == 'r') { myside = p[READ]; - hisside = fd0 = fd1 = p[WRITE]; + fd0 = -1; + hisside = fd1 = p[WRITE]; } else { myside = p[WRITE]; hisside = fd0 = p[READ]; fd1 = -1; } sigemptyset(&nset); - pid = start_command(value("SHELL"), &nset, fd0, fd1, "-c", cmd, NULL); - if (pid < 0) { - (void)close(p[READ]); - (void)close(p[WRITE]); - return(NULL); + if ((pid = start_command(cmd, &nset, fd0, fd1, NOSTR, NOSTR, NOSTR)) < 0) { + close(p[READ]); + close(p[WRITE]); + return NULL; } - (void)close(hisside); + (void) close(hisside); if ((fp = fdopen(myside, mode)) != NULL) register_file(fp, 1, pid); - return(fp); + return fp; } int -Pclose(FILE *ptr) +Pclose(ptr) + FILE *ptr; { int i; sigset_t nset, oset; i = file_pid(ptr); unregister_file(ptr); - (void)fclose(ptr); + (void) fclose(ptr); sigemptyset(&nset); sigaddset(&nset, SIGINT); sigaddset(&nset, SIGHUP); sigprocmask(SIG_BLOCK, &nset, &oset); i = wait_child(i); sigprocmask(SIG_SETMASK, &oset, NULL); - return(i); + return i; } void -close_all_files(void) +close_all_files() { while (fp_head) if (fp_head->pipe) - (void)Pclose(fp_head->fp); + (void) Pclose(fp_head->fp); else - (void)Fclose(fp_head->fp); + (void) Fclose(fp_head->fp); } void -register_file(FILE *fp, int pipe, pid_t pid) +register_file(fp, pipe, pid) + FILE *fp; + int pipe, pid; { struct fp *fpp; - if ((fpp = (struct fp *)malloc(sizeof(*fpp))) == NULL) - errx(1, "Out of memory"); + if ((fpp = (struct fp *) malloc(sizeof *fpp)) == NULL) + panic("Out of memory"); fpp->fp = fp; fpp->pipe = pipe; fpp->pid = pid; @@ -184,183 +220,165 @@ } void -unregister_file(FILE *fp) +unregister_file(fp) + FILE *fp; { struct fp **pp, *p; for (pp = &fp_head; (p = *pp) != NULL; pp = &p->link) if (p->fp == fp) { *pp = p->link; - (void)free(p); + free((char *) p); return; } - errx(1, "Invalid file pointer"); + panic("Invalid file pointer"); } -static pid_t -file_pid(FILE *fp) +static int +file_pid(fp) + FILE *fp; { struct fp *p; for (p = fp_head; p; p = p->link) if (p->fp == fp) - return(p->pid); - errx(1, "Invalid file pointer"); + return (p->pid); + panic("Invalid file pointer"); /*NOTREACHED*/ } /* * Run a command without a shell, with optional arguments and splicing - * of stdin (-1 means none) and stdout. The command name can be a sequence - * of words. + * of stdin and stdout. The command name can be a sequence of words. * Signals must be handled by the caller. - * "nset" contains the signals to ignore in the new process. - * SIGINT is enabled unless it's in "nset". + * "Mask" contains the signals to ignore in the new process. + * SIGINT is enabled unless it's in the mask. */ -pid_t -start_commandv(char *cmd, sigset_t *nset, int infd, int outfd, va_list args) +/*VARARGS4*/ +int +run_command(cmd, mask, infd, outfd, a0, a1, a2) + char *cmd; + sigset_t *mask; + int infd, outfd; + char *a0, *a1, *a2; { - pid_t pid; + int pid; - if ((pid = fork()) < 0) { - warn("fork"); - return(-1); + if ((pid = start_command(cmd, mask, infd, outfd, a0, a1, a2)) < 0) + return -1; + return wait_command(pid); +} + +/*VARARGS4*/ +int +start_command(cmd, mask, infd, outfd, a0, a1, a2) + char *cmd; + sigset_t *mask; + int infd, outfd; + char *a0, *a1, *a2; +{ + int pid; + + if ((pid = vfork()) < 0) { + perror("fork"); + return -1; } if (pid == 0) { char *argv[100]; - int i = getrawlist(cmd, argv, sizeof(argv)/ sizeof(*argv)); + int i = getrawlist(cmd, argv, sizeof argv / sizeof *argv); - while ((argv[i++] = va_arg(args, char *))) - ; - argv[i] = NULL; - prepare_child(nset, infd, outfd); + if ((argv[i++] = a0) != NOSTR && + (argv[i++] = a1) != NOSTR && + (argv[i++] = a2) != NOSTR) + argv[i] = NOSTR; + prepare_child(mask, infd, outfd); execvp(argv[0], argv); - warn("%s", argv[0]); + perror(argv[0]); _exit(1); } - return(pid); -} - -int -run_command(char *cmd, sigset_t *nset, int infd, int outfd, ...) -{ - pid_t pid; - va_list args; - - va_start(args, outfd); - pid = start_commandv(cmd, nset, infd, outfd, args); - va_end(args); - if (pid < 0) - return(-1); - return(wait_command(pid)); -} - -int -start_command(char *cmd, sigset_t *nset, int infd, int outfd, ...) -{ - va_list args; - int r; - - va_start(args, outfd); - r = start_commandv(cmd, nset, infd, outfd, args); - va_end(args); - return(r); + return pid; } void -prepare_child(sigset_t *nset, int infd, int outfd) +prepare_child(nset, infd, outfd) + sigset_t *nset; + int infd, outfd; { int i; - sigset_t eset; + sigset_t fset; /* * All file descriptors other than 0, 1, and 2 are supposed to be * close-on-exec. */ - if (infd > 0) { + if (infd >= 0) dup2(infd, 0); - } else if (infd != 0) { - /* we don't want the child stealing my stdin input */ - close(0); - open(_PATH_DEVNULL, O_RDONLY, 0); - } - if (outfd >= 0 && outfd != 1) + if (outfd >= 0) dup2(outfd, 1); - if (nset == NULL) - return; - if (nset != NULL) { - for (i = 1; i < NSIG; i++) + if (nset) { + for (i = 1; i <= NSIG; i++) if (sigismember(nset, i)) - (void)signal(i, SIG_IGN); + (void) signal(i, SIG_IGN); + if (!sigismember(nset, SIGINT)) + (void) signal(SIGINT, SIG_DFL); } - if (nset == NULL || !sigismember(nset, SIGINT)) - (void)signal(SIGINT, SIG_DFL); - sigemptyset(&eset); - (void)sigprocmask(SIG_SETMASK, &eset, NULL); + sigfillset(&fset); + (void) sigprocmask(SIG_UNBLOCK, &fset, NULL); } int -wait_command(pid_t pid) +wait_command(pid) + int pid; { if (wait_child(pid) < 0) { - puts("Fatal error in process."); - return(-1); + printf("Fatal error in process.\n"); + return -1; } - return(0); + return 0; } static struct child * -findchild(pid_t pid, int dont_alloc) +findchild(pid) + int pid; { - struct child **cpp; + register struct child **cpp; for (cpp = &child; *cpp != NULL && (*cpp)->pid != pid; cpp = &(*cpp)->link) ; if (*cpp == NULL) { - if (dont_alloc) - return(NULL); - if (child_freelist) { - *cpp = child_freelist; - child_freelist = (*cpp)->link; - } else { - *cpp = (struct child *)malloc(sizeof(struct child)); - if (*cpp == NULL) - errx(1, "Out of memory"); - } + *cpp = (struct child *) malloc(sizeof (struct child)); (*cpp)->pid = pid; (*cpp)->done = (*cpp)->free = 0; (*cpp)->link = NULL; } - return(*cpp); + return *cpp; } static void -delchild(struct child *cp) +delchild(cp) + register struct child *cp; { - struct child **cpp; + register struct child **cpp; for (cpp = &child; *cpp != cp; cpp = &(*cpp)->link) ; *cpp = cp->link; - cp->link = child_freelist; - child_freelist = cp; + free((char *) cp); } void -sigchild(int signo) +sigchild(signo) + int signo; { - pid_t pid; - int status; - struct child *cp; - int save_errno = errno; + int pid; + union wait status; + register struct child *cp; while ((pid = - waitpid((pid_t)-1, &status, WNOHANG)) > 0) { - cp = findchild(pid, 1); - if (!cp) - continue; + wait3((int *)&status, WNOHANG, (struct rusage *)0)) > 0) { + cp = findchild(pid); if (cp->free) delchild(cp); else { @@ -368,124 +386,132 @@ cp->status = status; } } - errno = save_errno; } -int wait_status; +union wait wait_status; /* * Wait for a specific child to die. */ int -wait_child(pid_t pid) +wait_child(pid) + int pid; { - struct child *cp; sigset_t nset, oset; - pid_t rv = 0; - + register struct child *cp = findchild(pid); sigemptyset(&nset); sigaddset(&nset, SIGCHLD); sigprocmask(SIG_BLOCK, &nset, &oset); - /* - * If we have not already waited on the pid (via sigchild) - * wait on it now. Otherwise, use the wait status stashed - * by sigchild. - */ - cp = findchild(pid, 1); - if (cp == NULL || !cp->done) - rv = waitpid(pid, &wait_status, 0); - else - wait_status = cp->status; - if (cp != NULL) - delchild(cp); + + while (!cp->done) + sigsuspend(&oset); + wait_status = cp->status; + delchild(cp); sigprocmask(SIG_SETMASK, &oset, NULL); - if (rv == -1 || (WIFEXITED(wait_status) && WEXITSTATUS(wait_status))) - return(-1); - else - return(0); + return wait_status.w_status ? -1 : 0; } /* * Mark a child as don't care. */ void -free_child(pid_t pid) +free_child(pid) + int pid; { - struct child *cp; sigset_t nset, oset; - + register struct child *cp = findchild(pid); sigemptyset(&nset); sigaddset(&nset, SIGCHLD); sigprocmask(SIG_BLOCK, &nset, &oset); - if ((cp = findchild(pid, 0)) != NULL) { - if (cp->done) - delchild(cp); - else - cp->free = 1; - } + + if (cp->done) + delchild(cp); + else + cp->free = 1; sigprocmask(SIG_SETMASK, &oset, NULL); } /* - * Lock(1)/unlock(0) mail spool using lockspool(1). + * Lock(1)/unlock(0) mail spool using liblockfile * Returns 1 for success, 0 for failure, -1 for bad usage. */ static int -handle_spool_locks(int action) +handle_spool_locks(mailname, action) + const char *mailname; + int action; { - static FILE *lockfp = NULL; - static pid_t lock_pid; + int retval; + char lockpath[PATHSIZE]; + + snprintf(lockpath, PATHSIZE - 1, "%s.lock", mailname); + lockpath[PATHSIZE - 1] = '\0'; if (action == 0) { /* Clear the lock */ - if (lockfp == NULL) { - fputs("handle_spool_locks: no spool lock to remove.\n", - stderr); - return(-1); - } - (void)Pclose(lockfp); - lockfp = NULL; + retval = lockfile_remove(lockpath); + if (retval == 0) + return(1); + else + warn("Cannot remove lockfile %s", lockpath); + } else if (action == 1) { - char *cmd; - char buf[sizeof(_PATH_LOCKSPOOL) + 32 + 1]; - /* XXX - lockspool requires root for user arg, we do not */ - if (uflag) { - snprintf(buf, sizeof(buf), "%s %s", _PATH_LOCKSPOOL, - myname); - cmd = buf; - } else - cmd = _PATH_LOCKSPOOL; - - /* Create the lock */ - lockfp = Popen(cmd, "r"); - if (lockfp == NULL) - return(0); - if (getc(lockfp) != '1') { - Pclose(lockfp); - lockfp = NULL; - return(0); - } - lock_pid = fp_head->pid; /* new entries added at head */ - } else { - (void)fprintf(stderr, "handle_spool_locks: unknown action %d\n", - action); - return(-1); + retval = lockfile_create(lockpath, 3, 0); + switch (retval) { + case L_SUCCESS: + return(1); + + case L_NAMELEN: + warnx( "Cannot create lockfile %s: %s", + lockpath, + "Recipient name too long." + ); + break; + + case L_TMPLOCK: + warnx( "Cannot create lockfile %s: %s", + lockpath, + "Error creating temporary lockfile" + ); + break; + + case L_TMPWRITE: + warnx( "Cannot create lockfile %s: %s", + lockpath, + "Failed to write pid into tmp lockfile." + ); + break; + + case L_MAXTRYS: + warnx( "Cannot create lockfile %s: %s", + lockpath, + "Failed after max tries." + ); + break; + + case L_ERROR: + default: + warn( "Cannot create lockfile %s", + lockpath + ); + break; + + } } - - return(1); + + return(0); } int -spool_lock(void) +spool_lock(mailname) + const char * mailname; { - - return(handle_spool_locks(1)); + return(handle_spool_locks(mailname, 1)); } int -spool_unlock(void) +spool_unlock(mailname) + const char * mailname; { - - return(handle_spool_locks(0)); + return(handle_spool_locks(mailname, 0)); } diff -urN mailx-8.1.1.orig/quit.c mailx-8.1.1/quit.c --- mailx-8.1.1.orig/quit.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/quit.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: quit.c,v 1.16 2001/11/21 15:26:39 millert Exp $ */ -/* $NetBSD: quit.c,v 1.6 1996/12/28 07:11:07 tls Exp $ */ +/* $OpenBSD: quit.c,v 1.5 1996/06/08 19:48:37 christos Exp $ */ +/* $NetBSD: quit.c,v 1.5 1996/06/08 19:48:37 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)quit.c 8.2 (Berkeley) 4/28/95"; +static char sccsid[] = "@(#)quit.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: quit.c,v 1.16 2001/11/21 15:26:39 millert Exp $"; +static char rcsid[] = "$OpenBSD: quit.c,v 1.5 1996/06/08 19:48:37 christos Exp $"; #endif #endif /* not lint */ @@ -56,15 +56,16 @@ * The "quit" command. */ int -quitcmd(void *v) +quitcmd(v) + void *v; { /* * If we are sourcing, then return 1 so execute() can handle it. * Otherwise, return -1 to abort command loop. */ if (sourcing) - return(1); - return(-1); + return 1; + return -1; } /* @@ -72,29 +73,31 @@ * Save all untouched messages back in the system mailbox. * Remove the system mailbox, if none saved there. */ -int -quit(void) +void +quit() { int mcount, p, modify, autohold, anystat, holdbit, nohold; FILE *ibuf = NULL, *obuf, *fbuf, *rbuf, *readstat = NULL, *abuf; - struct message *mp; - int c, fd; + register struct message *mp; + register int c; + extern char *tempQuit, *tempResid; struct stat minfo; - char *mbox, tempname[PATHSIZE]; + char *mbox; /* * If we are read only, we can't do anything, * so just return quickly. */ if (readonly) - return(0); - + return; /* * If editing (not reading system mail box), then do the work * in edstop() */ - if (edit) - return(edstop()); + if (edit) { + edstop(); + return; + } /* * See if there any messages to save in mbox. If no, we @@ -105,53 +108,55 @@ * If all the messages are to be preserved, just exit with * a message. */ - fbuf = Fopen(mailname, "r+"); + + fbuf = Fopen(mailname, "r"); if (fbuf == NULL) goto newmail; if (flock(fileno(fbuf), LOCK_EX) == -1) { - warn("Unable to lock mailbox"); - (void)Fclose(fbuf); - return(-1); +nolock: + perror("Unable to lock mailbox"); + Fclose(fbuf); + return; } - if (!spool_lock()) { + if (!spool_lock(mailname)) { (void)Fclose(fbuf); - return(-1); /* lockspool printed the error for us */ - } + return; /* lockspool printed error for us */ + } + rbuf = NULL; if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) { - puts("New mail has arrived."); - (void)snprintf(tempname, sizeof(tempname), - "%s/mail.RqXXXXXXXXXX", tmpdir); - if ((fd = mkstemp(tempname)) == -1 || - (rbuf = Fdopen(fd, "w")) == NULL) + printf("New mail has arrived.\n"); + rbuf = Fopen(tempResid, "w"); + if (rbuf == NULL || fbuf == NULL) goto newmail; #ifdef APPEND fseek(fbuf, (long)mailsize, 0); while ((c = getc(fbuf)) != EOF) - (void)putc(c, rbuf); + (void) putc(c, rbuf); #else p = minfo.st_size - mailsize; while (p-- > 0) { c = getc(fbuf); if (c == EOF) goto newmail; - (void)putc(c, rbuf); + (void) putc(c, rbuf); } #endif - (void)Fclose(rbuf); - if ((rbuf = Fopen(tempname, "r")) == NULL) + Fclose(rbuf); + if ((rbuf = Fopen(tempResid, "r")) == NULL) goto newmail; - (void)rm(tempname); + rm(tempResid); } /* * Adjust the message flags in each message. */ + anystat = 0; - autohold = value("hold") != NULL; + autohold = value("hold") != NOSTR; holdbit = autohold ? MPRESERVE : MBOX; nohold = MBOX|MSAVED|MDELETED|MPRESERVE; - if (value("keepsave") != NULL) + if (value("keepsave") != NOSTR) nohold &= ~MSAVED; for (mp = &message[0]; mp < &message[msgCount]; mp++) { if (mp->m_flag & MNEW) { @@ -166,9 +171,9 @@ mp->m_flag |= holdbit; } modify = 0; - if (Tflag != NULL) { + if (Tflag != NOSTR) { if ((readstat = Fopen(Tflag, "w")) == NULL) - Tflag = NULL; + Tflag = NOSTR; } for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) { if (mp->m_flag & MBOX) @@ -177,28 +182,28 @@ p++; if (mp->m_flag & MODIFY) modify++; - if (Tflag != NULL && (mp->m_flag & (MREAD|MDELETED)) != 0) { + if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) { char *id; - if ((id = hfield("article-id", mp)) != NULL) + if ((id = hfield("article-id", mp)) != NOSTR) fprintf(readstat, "%s\n", id); } } - if (Tflag != NULL) - (void)Fclose(readstat); + if (Tflag != NOSTR) + Fclose(readstat); if (p == msgCount && !modify && !anystat) { printf("Held %d message%s in %s\n", p, p == 1 ? "" : "s", mailname); - (void)Fclose(fbuf); - spool_unlock(); - return(0); + Fclose(fbuf); + spool_unlock(mailname); + return; } if (c == 0) { if (p != 0) { writeback(rbuf); - (void)Fclose(fbuf); - spool_unlock(); - return(0); + Fclose(fbuf); + spool_unlock(mailname); + return; } goto cream; } @@ -209,67 +214,67 @@ * If he has specified "append" don't copy his mailbox, * just copy saveable entries at the end. */ + mbox = expand("&"); mcount = c; - if (value("append") == NULL) { - (void)snprintf(tempname, sizeof(tempname), - "%s/mail.RmXXXXXXXXXX", tmpdir); - if ((fd = mkstemp(tempname)) == -1 || - (obuf = Fdopen(fd, "w")) == NULL) { - warn("%s", tempname); - (void)Fclose(fbuf); - spool_unlock(); - return(-1); + if (value("append") == NOSTR) { + if ((obuf = Fopen(tempQuit, "w")) == NULL) { + perror(tempQuit); + Fclose(fbuf); + spool_unlock(mailname); + return; + } + if ((ibuf = Fopen(tempQuit, "r")) == NULL) { + perror(tempQuit); + rm(tempQuit); + Fclose(obuf); + Fclose(fbuf); + spool_unlock(mailname); + return; } - if ((ibuf = Fopen(tempname, "r")) == NULL) { - warn("%s", tempname); - (void)rm(tempname); - (void)Fclose(obuf); - (void)Fclose(fbuf); - spool_unlock(); - return(-1); - } - (void)rm(tempname); + rm(tempQuit); if ((abuf = Fopen(mbox, "r")) != NULL) { while ((c = getc(abuf)) != EOF) - (void)putc(c, obuf); - (void)Fclose(abuf); + (void) putc(c, obuf); + Fclose(abuf); } if (ferror(obuf)) { - warn("%s", tempname); - (void)Fclose(ibuf); - (void)Fclose(obuf); - (void)Fclose(fbuf); - spool_unlock(); - return(-1); + perror(tempQuit); + Fclose(ibuf); + Fclose(obuf); + Fclose(fbuf); + spool_unlock(mailname); + return; } - (void)Fclose(obuf); - (void)close(creat(mbox, 0600)); + Fclose(obuf); + close(creat(mbox, 0600)); if ((obuf = Fopen(mbox, "r+")) == NULL) { - warn("%s", mbox); - (void)Fclose(ibuf); - (void)Fclose(fbuf); - spool_unlock(); - return(-1); + perror(mbox); + Fclose(ibuf); + Fclose(fbuf); + spool_unlock(mailname); + return; } - } else { + } + else { if ((obuf = Fopen(mbox, "a")) == NULL) { - warn("%s", mbox); - (void)Fclose(fbuf); - spool_unlock(); - return(-1); + perror(mbox); + Fclose(fbuf); + spool_unlock(mailname); + return; } fchmod(fileno(obuf), 0600); } for (mp = &message[0]; mp < &message[msgCount]; mp++) if (mp->m_flag & MBOX) - if (sendmessage(mp, obuf, saveignore, NULL) < 0) { - warn("%s", mbox); - (void)Fclose(ibuf); - (void)Fclose(obuf); - (void)Fclose(fbuf); - spool_unlock(); - return(-1); + if (send(mp, obuf, saveignore, NOSTR) < 0) { + perror(mbox); + if (ibuf) + Fclose(ibuf); + Fclose(obuf); + Fclose(fbuf); + spool_unlock(mailname); + return; } /* @@ -277,29 +282,30 @@ * to the end of the stuff we just saved. * If we are appending, this is unnecessary. */ - if (value("append") == NULL) { + + if (value("append") == NOSTR) { rewind(ibuf); c = getc(ibuf); while (c != EOF) { - (void)putc(c, obuf); + (void) putc(c, obuf); if (ferror(obuf)) break; c = getc(ibuf); } - (void)Fclose(ibuf); + Fclose(ibuf); fflush(obuf); } trunc(obuf); if (ferror(obuf)) { - warn("%s", mbox); - (void)Fclose(obuf); - (void)Fclose(fbuf); - spool_unlock(); - return(-1); + perror(mbox); + Fclose(obuf); + Fclose(fbuf); + spool_unlock(mailname); + return; } - (void)Fclose(obuf); + Fclose(obuf); if (mcount == 1) - puts("Saved 1 message in mbox"); + printf("Saved 1 message in mbox\n"); else printf("Saved %d messages in mbox\n", mcount); @@ -307,44 +313,45 @@ * Now we are ready to copy back preserved files to * the system mailbox, if any were requested. */ + if (p != 0) { writeback(rbuf); - (void)Fclose(fbuf); - spool_unlock(); - return(0); + Fclose(fbuf); + spool_unlock(mailname); + return; } /* - * Finally, remove his /var/mail file. + * Finally, remove his /usr/mail file. * If new mail has arrived, copy it back. */ + cream: if (rbuf != NULL) { abuf = Fopen(mailname, "r+"); if (abuf == NULL) goto newmail; while ((c = getc(rbuf)) != EOF) - (void)putc(c, abuf); - (void)Fclose(rbuf); + (void) putc(c, abuf); + Fclose(rbuf); trunc(abuf); - (void)Fclose(abuf); + Fclose(abuf); alter(mailname); - (void)Fclose(fbuf); - spool_unlock(); - return(0); + Fclose(fbuf); + spool_unlock(mailname); + return; } demail(); - (void)Fclose(fbuf); - spool_unlock(); - return(0);; + Fclose(fbuf); + spool_unlock(mailname); + return; newmail: - puts("Thou hast new mail."); + printf("Thou hast new mail.\n"); if (fbuf != NULL) { - (void)Fclose(fbuf); - spool_unlock(); + Fclose(fbuf); + spool_unlock(mailname); } - return(0); } /* @@ -354,46 +361,47 @@ * Incorporate the any new mail that we found. */ int -writeback(FILE *res) +writeback(res) + register FILE *res; { - struct message *mp; - int p, c; + register struct message *mp; + register int p, c; FILE *obuf; p = 0; if ((obuf = Fopen(mailname, "r+")) == NULL) { - warn("%s", mailname); + perror(mailname); return(-1); } #ifndef APPEND if (res != NULL) while ((c = getc(res)) != EOF) - (void)putc(c, obuf); + (void) putc(c, obuf); #endif for (mp = &message[0]; mp < &message[msgCount]; mp++) if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) { p++; - if (sendmessage(mp, obuf, NULL, NULL) < 0) { - warn("%s", mailname); - (void)Fclose(obuf); + if (send(mp, obuf, (struct ignoretab *)0, NOSTR) < 0) { + perror(mailname); + Fclose(obuf); return(-1); } } #ifdef APPEND if (res != NULL) while ((c = getc(res)) != EOF) - (void)putc(c, obuf); + (void) putc(c, obuf); #endif fflush(obuf); trunc(obuf); if (ferror(obuf)) { - warn("%s", mailname); - (void)Fclose(obuf); + perror(mailname); + Fclose(obuf); return(-1); } if (res != NULL) - (void)Fclose(res); - (void)Fclose(obuf); + Fclose(res); + Fclose(obuf); alter(mailname); if (p == 1) printf("Held 1 message in %s\n", mailname); @@ -406,21 +414,22 @@ * Terminate an editing session by attempting to write out the user's * file from the temporary. Save any new stuff appended to the file. */ -int -edstop(void) +void +edstop() { - int gotcha, c; - struct message *mp; + extern char *tmpdir; + register int gotcha, c; + register struct message *mp; FILE *obuf, *ibuf, *readstat = NULL; struct stat statb; - char tempname[PATHSIZE]; + char *tempname; if (readonly) - return(0); + return; holdsigs(); - if (Tflag != NULL) { + if (Tflag != NOSTR) { if ((readstat = Fopen(Tflag, "w")) == NULL) - Tflag = NULL; + Tflag = NOSTR; } for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) { if (mp->m_flag & MNEW) { @@ -429,57 +438,53 @@ } if (mp->m_flag & (MODIFY|MDELETED|MSTATUS)) gotcha++; - if (Tflag != NULL && (mp->m_flag & (MREAD|MDELETED)) != 0) { + if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) { char *id; - if ((id = hfield("article-id", mp)) != NULL) + if ((id = hfield("article-id", mp)) != NOSTR) fprintf(readstat, "%s\n", id); } } - if (Tflag != NULL) - (void)Fclose(readstat); - if (!gotcha || Tflag != NULL) + if (Tflag != NOSTR) + Fclose(readstat); + if (!gotcha || Tflag != NOSTR) goto done; ibuf = NULL; if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) { - int fd; + tempname = tempnam(tmpdir, "mbox"); - (void)snprintf(tempname, sizeof(tempname), "%s/mbox.XXXXXXXXXX", - tmpdir); - if ((fd = mkstemp(tempname)) == -1 || - (obuf = Fdopen(fd, "w")) == NULL) { - warn("%s", tempname); - if (fd != -1) - close(fd); + if ((obuf = Fopen(tempname, "w")) == NULL) { + perror(tempname); relsesigs(); - return(-1); + reset(0); } if ((ibuf = Fopen(mailname, "r")) == NULL) { - warn("%s", mailname); - (void)Fclose(obuf); - (void)rm(tempname); + perror(mailname); + Fclose(obuf); + rm(tempname); relsesigs(); - return(-1); + reset(0); } fseek(ibuf, (long)mailsize, 0); while ((c = getc(ibuf)) != EOF) - (void)putc(c, obuf); - (void)Fclose(ibuf); - (void)Fclose(obuf); + (void) putc(c, obuf); + Fclose(ibuf); + Fclose(obuf); if ((ibuf = Fopen(tempname, "r")) == NULL) { - warn("%s", tempname); - (void)rm(tempname); + perror(tempname); + rm(tempname); relsesigs(); - return(-1); + reset(0); } - (void)rm(tempname); + rm(tempname); + free(tempname); } printf("\"%s\" ", mailname); fflush(stdout); if ((obuf = Fopen(mailname, "r+")) == NULL) { - warn("%s", mailname); + perror(mailname); relsesigs(); - return(-1); + reset(0); } trunc(obuf); c = 0; @@ -487,33 +492,32 @@ if ((mp->m_flag & MDELETED) != 0) continue; c++; - if (sendmessage(mp, obuf, NULL, NULL) < 0) { - warn("%s", mailname); + if (send(mp, obuf, (struct ignoretab *) NULL, NOSTR) < 0) { + perror(mailname); relsesigs(); - return(-1); + reset(0); } } gotcha = (c == 0 && ibuf == NULL); if (ibuf != NULL) { while ((c = getc(ibuf)) != EOF) - (void)putc(c, obuf); - (void)Fclose(ibuf); + (void) putc(c, obuf); + Fclose(ibuf); } fflush(obuf); if (ferror(obuf)) { - warn("%s", mailname); + perror(mailname); relsesigs(); - return(-1); + reset(0); } - (void)Fclose(obuf); + Fclose(obuf); if (gotcha) { - (void)rm(mailname); - puts("removed"); + rm(mailname); + printf("removed\n"); } else - puts("complete"); + printf("complete\n"); fflush(stdout); done: relsesigs(); - return(0); } diff -urN mailx-8.1.1.orig/rcv.h mailx-8.1.1/rcv.h --- mailx-8.1.1.orig/rcv.h 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/rcv.h 1996-06-14 01:27:06.000000000 -0700 @@ -1,4 +1,4 @@ -/* $OpenBSD: rcv.h,v 1.2 1996/06/11 12:53:48 deraadt Exp $ */ +/* $OpenBSD: rcv.h,v 1.4 1996/06/08 19:48:38 christos Exp $ */ /* $NetBSD: rcv.h,v 1.4 1996/06/08 19:48:38 christos Exp $ */ /* diff -urN mailx-8.1.1.orig/send.c mailx-8.1.1/send.c --- mailx-8.1.1.orig/send.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/send.c 1996-06-14 01:27:08.000000000 -0700 @@ -1,4 +1,4 @@ -/* $OpenBSD: send.c,v 1.15 2001/11/28 01:26:35 millert Exp $ */ +/* $OpenBSD: send.c,v 1.6 1996/06/08 19:48:39 christos Exp $ */ /* $NetBSD: send.c,v 1.6 1996/06/08 19:48:39 christos Exp $ */ /* @@ -36,17 +36,15 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)send.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)send.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: send.c,v 1.15 2001/11/28 01:26:35 millert Exp $"; +static char rcsid[] = "$OpenBSD: send.c,v 1.6 1996/06/08 19:48:39 christos Exp $"; #endif #endif /* not lint */ #include "rcv.h" #include "extern.h" -static volatile sig_atomic_t sendsignal; /* Interrupted by a signal? */ - /* * Mail -- a mail program * @@ -61,33 +59,25 @@ * prefix is a string to prepend to each output line. */ int -sendmessage(struct message *mp, FILE *obuf, struct ignoretab *doign, - char *prefix) +send(mp, obuf, doign, prefix) + register struct message *mp; + FILE *obuf; + struct ignoretab *doign; + char *prefix; { - int count; - FILE *ibuf; + long count; + register FILE *ibuf; char line[LINESIZE]; int ishead, infld, ignoring = 0, dostat, firstline; - char *cp, *cp2; - int c = 0; + register char *cp, *cp2; + register int c = 0; int length; int prefixlen = 0; - int rval; - struct sigaction act, saveint; - sigset_t oset; - - sendsignal = 0; - rval = -1; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - act.sa_handler = sendint; - (void)sigaction(SIGINT, &act, &saveint); - (void)sigprocmask(SIG_UNBLOCK, &intset, &oset); /* * Compute the prefix string, without trailing whitespace */ - if (prefix != NULL) { + if (prefix != NOSTR) { cp2 = 0; for (cp = prefix; *cp; cp++) if (*cp != ' ' && *cp != '\t') @@ -104,11 +94,11 @@ * Process headers first */ while (count > 0 && ishead) { - if (fgets(line, sizeof(line), ibuf) == NULL) + if (fgets(line, LINESIZE, ibuf) == NULL) break; count -= length = strlen(line); if (firstline) { - /* + /* * First line is the From line, so no headers * there to worry about */ @@ -122,8 +112,7 @@ * fields */ if (dostat) { - if (statusput(mp, obuf, prefix) == -1) - goto out; + statusput(mp, obuf, prefix); dostat = 0; } ishead = 0; @@ -151,13 +140,12 @@ * there are no headers at all. */ if (dostat) { - if (statusput(mp, obuf, prefix) == -1) - goto out; + statusput(mp, obuf, prefix); dostat = 0; } if (doign != ignoreall) /* add blank line */ - (void)putc('\n', obuf); + (void) putc('\n', obuf); ishead = 0; ignoring = 0; } else { @@ -175,8 +163,7 @@ * and print the real Status: field */ if (dostat) { - if (statusput(mp, obuf, prefix) == -1) - goto out; + statusput(mp, obuf, prefix); dostat = 0; } ignoring = 1; @@ -192,32 +179,29 @@ * Strip trailing whitespace from prefix * if line is blank. */ - if (prefix != NULL) { + if (prefix != NOSTR) if (length > 1) fputs(prefix, obuf); else - (void)fwrite(prefix, sizeof(*prefix), + (void) fwrite(prefix, sizeof *prefix, prefixlen, obuf); - } - (void)fwrite(line, sizeof(*line), length, obuf); + (void) fwrite(line, sizeof *line, length, obuf); if (ferror(obuf)) - goto out; + return -1; } - if (sendsignal == SIGINT) - goto out; } /* * Copy out message body */ if (doign == ignoreall) count--; /* skip final blank line */ - while (count > 0) { - if (fgets(line, sizeof(line), ibuf) == NULL) { - c = 0; - break; - } - count -= c = strlen(line); - if (prefix != NULL) { + if (prefix != NOSTR) + while (count > 0) { + if (fgets(line, LINESIZE, ibuf) == NULL) { + c = 0; + break; + } + count -= c = strlen(line); /* * Strip trailing whitespace from prefix * if line is blank. @@ -225,53 +209,48 @@ if (c > 1) fputs(prefix, obuf); else - (void)fwrite(prefix, sizeof(*prefix), + (void) fwrite(prefix, sizeof *prefix, prefixlen, obuf); + (void) fwrite(line, sizeof *line, c, obuf); + if (ferror(obuf)) + return -1; + } + else + while (count > 0) { + c = count < LINESIZE ? count : LINESIZE; + if ((c = fread(line, sizeof *line, c, ibuf)) <= 0) + break; + count -= c; + if (fwrite(line, sizeof *line, c, obuf) != c) + return -1; } - /* - * We can't read the record file (or inbox for recipient) - * properly with 'From ' lines in the message body (from - * forwarded messages or sentences starting with "From "), - * so we will prepend those lines with a '>'. - */ - if (strncmp(line, "From ", 5) == 0) - (void)fwrite(">", 1, 1, obuf); /* '>' before 'From ' */ - (void)fwrite(line, sizeof(*line), c, obuf); - if (ferror(obuf) || sendsignal == SIGINT) - goto out; - } if (doign == ignoreall && c > 0 && line[c - 1] != '\n') /* no final blank line */ if ((c = getc(ibuf)) != EOF && putc(c, obuf) == EOF) - goto out; - rval = 0; -out: - sendsignal = 0; - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void)sigaction(SIGINT, &saveint, NULL); - return(rval); + return -1; + return 0; } /* * Output a reasonable looking status field. */ -int -statusput(struct message *mp, FILE *obuf, char *prefix) +void +statusput(mp, obuf, prefix) + register struct message *mp; + FILE *obuf; + char *prefix; { char statout[3]; - char *cp = statout; + register char *cp = statout; if (mp->m_flag & MREAD) *cp++ = 'R'; if ((mp->m_flag & MNEW) == 0) *cp++ = 'O'; *cp = 0; - if (statout[0]) { + if (statout[0]) fprintf(obuf, "%sStatus: %s\n", - prefix == NULL ? "" : prefix, statout); - return(ferror(obuf) ? -1 : 0); - } - return(0); + prefix == NOSTR ? "" : prefix, statout); } /* @@ -279,8 +258,9 @@ * which does all the dirty work. */ int -mail(struct name *to, struct name *cc, struct name *bcc, struct name *smopts, - char *subject) +mail(to, cc, bcc, smopts, subject) + struct name *to, *cc, *bcc, *smopts; + char *subject; { struct header head; @@ -299,16 +279,17 @@ * the mail routine below. */ int -sendmail(void *v) +sendmail(v) + void *v; { char *str = v; struct header head; head.h_to = extract(str, GTO); - head.h_subject = NULL; - head.h_cc = NULL; - head.h_bcc = NULL; - head.h_smopts = NULL; + head.h_subject = NOSTR; + head.h_cc = NIL; + head.h_bcc = NIL; + head.h_smopts = NIL; mail1(&head, 0); return(0); } @@ -318,10 +299,12 @@ * in the passed header. (Internal interface). */ void -mail1(struct header *hp, int printheaders) +mail1(hp, printheaders) + struct header *hp; + int printheaders; { char *cp; - pid_t pid; + int pid; char **namelist; struct name *to; FILE *mtf; @@ -332,12 +315,21 @@ */ if ((mtf = collect(hp, printheaders)) == NULL) return; - if (fsize(mtf) == 0) { - if (hp->h_subject == NULL) - puts("No message, no subject; hope that's ok"); + if (value("interactive") != NOSTR) + if (value("askcc") != NOSTR || value("askbcc") != NOSTR) { + if (value("askcc") != NOSTR) + grabh(hp, GCC); + if (value("askbcc") != NOSTR) + grabh(hp, GBCC); + } else { + printf("EOT\n"); + (void) fflush(stdout); + } + if (fsize(mtf) == 0) + if (hp->h_subject == NOSTR) + printf("No message, no subject; hope that's ok\n"); else - puts("Null message body; hope that's ok"); - } + printf("Null message body; hope that's ok\n"); /* * Now, take the user names from the combined * to and cc lists and do all the alias @@ -345,8 +337,8 @@ */ senderr = 0; to = usermap(cat(hp->h_bcc, cat(hp->h_to, hp->h_cc))); - if (to == NULL) { - puts("No recipients specified"); + if (to == NIL) { + printf("No recipients specified\n"); senderr++; } /* @@ -361,21 +353,21 @@ goto out; fixhead(hp, to); if ((mtf = infix(hp, mtf)) == NULL) { - fputs(". . . message lost, sorry.\n", stderr); + fprintf(stderr, ". . . message lost, sorry.\n"); return; } - namelist = unpack(hp->h_smopts, to); + namelist = unpack(cat(hp->h_smopts, to)); if (debug) { char **t; - fputs("Sendmail arguments:", stdout); - for (t = namelist; *t != NULL; t++) + printf("Sendmail arguments:"); + for (t = namelist; *t != NOSTR; t++) printf(" \"%s\"", *t); - putchar('\n'); + printf("\n"); goto out; } - if ((cp = value("record")) != NULL) - (void)savemail(expand(cp), mtf); + if ((cp = value("record")) != NOSTR) + (void) savemail(expand(cp), mtf); /* * Fork, set up the temporary mail file as standard * input for "mail", and exec with the user list we generated @@ -383,13 +375,12 @@ */ pid = fork(); if (pid == -1) { - warn("fork"); + perror("fork"); savedeadletter(mtf); goto out; } if (pid == 0) { sigset_t nset; - sigemptyset(&nset); sigaddset(&nset, SIGHUP); sigaddset(&nset, SIGINT); @@ -398,20 +389,20 @@ sigaddset(&nset, SIGTTIN); sigaddset(&nset, SIGTTOU); prepare_child(&nset, fileno(mtf), -1); - if ((cp = value("sendmail")) != NULL) + if ((cp = value("sendmail")) != NOSTR) cp = expand(cp); else cp = _PATH_SENDMAIL; execv(cp, namelist); - warn("%s", cp); + perror(cp); _exit(1); } - if (value("verbose") != NULL) - (void)wait_child(pid); + if (value("verbose") != NOSTR) + (void) wait_child(pid); else free_child(pid); out: - (void)Fclose(mtf); + (void) Fclose(mtf); } /* @@ -419,14 +410,16 @@ * the distribution list into the appropriate fields. */ void -fixhead(struct header *hp, struct name *tolist) -{ - struct name *np; - - hp->h_to = NULL; - hp->h_cc = NULL; - hp->h_bcc = NULL; - for (np = tolist; np != NULL; np = np->n_flink) +fixhead(hp, tolist) + struct header *hp; + struct name *tolist; +{ + register struct name *np; + + hp->h_to = NIL; + hp->h_cc = NIL; + hp->h_bcc = NIL; + for (np = tolist; np != NIL; np = np->n_flink) if ((np->n_type & GMASK) == GTO) hp->h_to = cat(hp->h_to, nalloc(np->n_name, np->n_type)); @@ -443,47 +436,45 @@ * and return the new file. */ FILE * -infix(struct header *hp, FILE *fi) -{ - FILE *nfo, *nfi; - int c, fd; - char tempname[PATHSIZE]; - - (void)snprintf(tempname, sizeof(tempname), - "%s/mail.RsXXXXXXXXXX", tmpdir); - if ((fd = mkstemp(tempname)) == -1 || - (nfo = Fdopen(fd, "w")) == NULL) { - warn("%s", tempname); +infix(hp, fi) + struct header *hp; + FILE *fi; +{ + extern char *tempMail; + register FILE *nfo, *nfi; + register int c; + + if ((nfo = Fopen(tempMail, "w")) == NULL) { + perror(tempMail); return(fi); } - if ((nfi = Fopen(tempname, "r")) == NULL) { - warn("%s", tempname); - (void)Fclose(nfo); - (void)rm(tempname); + if ((nfi = Fopen(tempMail, "r")) == NULL) { + perror(tempMail); + (void) Fclose(nfo); return(fi); } - (void)rm(tempname); - (void)puthead(hp, nfo, GTO|GSUBJECT|GCC|GBCC|GNL|GCOMMA); + (void) rm(tempMail); + (void) puthead(hp, nfo, GTO|GSUBJECT|GCC|GBCC|GNL|GCOMMA); c = getc(fi); while (c != EOF) { - (void)putc(c, nfo); + (void) putc(c, nfo); c = getc(fi); } if (ferror(fi)) { - warn("read"); + perror("read"); rewind(fi); return(fi); } - (void)fflush(nfo); + (void) fflush(nfo); if (ferror(nfo)) { - warn("%s", tempname); - (void)Fclose(nfo); - (void)Fclose(nfi); + perror(tempMail); + (void) Fclose(nfo); + (void) Fclose(nfi); rewind(fi); return(fi); } - (void)Fclose(nfo); - (void)Fclose(fi); + (void) Fclose(nfo); + (void) Fclose(fi); rewind(nfi); return(nfi); } @@ -493,21 +484,24 @@ * passed file buffer. */ int -puthead(struct header *hp, FILE *fo, int w) +puthead(hp, fo, w) + struct header *hp; + FILE *fo; + int w; { - int gotcha; + register int gotcha; gotcha = 0; - if (hp->h_to != NULL && w & GTO) + if (hp->h_to != NIL && w & GTO) fmt("To:", hp->h_to, fo, w&GCOMMA), gotcha++; - if (hp->h_subject != NULL && w & GSUBJECT) + if (hp->h_subject != NOSTR && w & GSUBJECT) fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++; - if (hp->h_cc != NULL && w & GCC) + if (hp->h_cc != NIL && w & GCC) fmt("Cc:", hp->h_cc, fo, w&GCOMMA), gotcha++; - if (hp->h_bcc != NULL && w & GBCC) + if (hp->h_bcc != NIL && w & GBCC) fmt("Bcc:", hp->h_bcc, fo, w&GCOMMA), gotcha++; if (gotcha && w & GNL) - (void)putc('\n', fo); + (void) putc('\n', fo); return(0); } @@ -515,16 +509,20 @@ * Format the given header line to not exceed 72 characters. */ void -fmt(char *str, struct name *np, FILE *fo, int comma) +fmt(str, np, fo, comma) + char *str; + register struct name *np; + FILE *fo; + int comma; { - int col, len; + register col, len; comma = comma ? 1 : 0; col = strlen(str); if (col) fputs(str, fo); - for (; np != NULL; np = np->n_flink) { - if (np->n_flink == NULL) + for (; np != NIL; np = np->n_flink) { + if (np->n_flink == NIL) comma = 0; len = strlen(np->n_name); col++; /* for the space */ @@ -544,44 +542,31 @@ /* * Save the outgoing mail on the passed file. */ + /*ARGSUSED*/ int -savemail(char *name, FILE *fi) +savemail(name, fi) + char name[]; + register FILE *fi; { - FILE *fo; + register FILE *fo; char buf[BUFSIZ]; + register i; time_t now; if ((fo = Fopen(name, "a")) == NULL) { - warn("%s", name); - return(-1); + perror(name); + return (-1); } - (void)time(&now); + (void) time(&now); fprintf(fo, "From %s %s", myname, ctime(&now)); - while (fgets(buf, sizeof(buf), fi) == buf) { - /* - * We can't read the record file (or inbox for recipient) - * in the message body (from forwarded messages or sentences - * starting with "From "), so we will prepend those lines with - * a '>'. - */ - if (strncmp(buf, "From ", 5) == 0) - (void)fwrite(">", 1, 1, fo); /* '>' before 'From ' */ - (void)fwrite(buf, 1, strlen(buf), fo); - } - (void)putc('\n', fo); - (void)fflush(fo); + while ((i = fread(buf, 1, sizeof buf, fi)) > 0) + (void) fwrite(buf, 1, i, fo); + (void) putc('\n', fo); + (void) fflush(fo); if (ferror(fo)) - warn("%s", name); - (void)Fclose(fo); + perror(name); + (void) Fclose(fo); rewind(fi); - return(0); -} - -/*ARGSUSED*/ -void -sendint(int s) -{ - - sendsignal = s; + return (0); } diff -urN mailx-8.1.1.orig/strings.c mailx-8.1.1/strings.c --- mailx-8.1.1.orig/strings.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/strings.c 1996-06-14 01:27:08.000000000 -0700 @@ -1,4 +1,4 @@ -/* $OpenBSD: strings.c,v 1.7 2001/11/21 15:26:39 millert Exp $ */ +/* $OpenBSD: strings.c,v 1.5 1996/06/08 19:48:40 christos Exp $ */ /* $NetBSD: strings.c,v 1.5 1996/06/08 19:48:40 christos Exp $ */ /* @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)strings.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)strings.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: strings.c,v 1.7 2001/11/21 15:26:39 millert Exp $"; +static char rcsid[] = "$OpenBSD: strings.c,v 1.5 1996/06/08 19:48:40 christos Exp $"; #endif #endif /* not lint */ @@ -60,32 +60,36 @@ * The string spaces are of exponentially increasing size, to satisfy * the occasional user with enormous string size requests. */ + char * -salloc(int size) +salloc(size) + int size; { - char *t; - int s; - struct strings *sp; + register char *t; + register int s; + register struct strings *sp; int index; s = size; - s += (sizeof(char *) - 1); - s &= ~(sizeof(char *) - 1); + s += (sizeof (char *) - 1); + s &= ~(sizeof (char *) - 1); index = 0; for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) { - if (sp->s_topFree == NULL && (STRINGSIZE << index) >= s) + if (sp->s_topFree == NOSTR && (STRINGSIZE << index) >= s) break; if (sp->s_nleft >= s) break; index++; } if (sp >= &stringdope[NSPACE]) - errx(1, "String too large"); - if (sp->s_topFree == NULL) { + panic("String too large"); + if (sp->s_topFree == NOSTR) { index = sp - &stringdope[0]; - sp->s_topFree = (char *)malloc(STRINGSIZE << index); - if (sp->s_topFree == NULL) - errx(1, "No room for space %d", index); + sp->s_topFree = malloc(STRINGSIZE << index); + if (sp->s_topFree == NOSTR) { + fprintf(stderr, "No room for space %d\n", index); + panic("Internal error"); + } sp->s_nextFree = sp->s_topFree; sp->s_nleft = STRINGSIZE << index; } @@ -101,16 +105,16 @@ * since last reset. */ void -sreset(void) +sreset() { - struct strings *sp; - int index; + register struct strings *sp; + register int index; if (noreset) return; index = 0; for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) { - if (sp->s_topFree == NULL) + if (sp->s_topFree == NOSTR) continue; sp->s_nextFree = sp->s_topFree; sp->s_nleft = STRINGSIZE << index; @@ -123,10 +127,10 @@ * Meant to be called in main, after initialization. */ void -spreserve(void) +spreserve() { - struct strings *sp; + register struct strings *sp; for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) - sp->s_topFree = NULL; + sp->s_topFree = NOSTR; } diff -urN mailx-8.1.1.orig/temp.c mailx-8.1.1/temp.c --- mailx-8.1.1.orig/temp.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/temp.c 1996-06-14 01:27:08.000000000 -0700 @@ -1,4 +1,4 @@ -/* $OpenBSD: temp.c,v 1.13 2002/01/24 23:01:19 millert Exp $ */ +/* $OpenBSD: temp.c,v 1.5 1996/06/08 19:48:42 christos Exp $ */ /* $NetBSD: temp.c,v 1.5 1996/06/08 19:48:42 christos Exp $ */ /* @@ -36,13 +36,14 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)temp.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)temp.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: temp.c,v 1.13 2002/01/24 23:01:19 millert Exp $"; +static char rcsid[] = "$OpenBSD: temp.c,v 1.5 1996/06/08 19:48:42 christos Exp $"; #endif #endif /* not lint */ #include "rcv.h" +#include #include "extern.h" /* @@ -51,47 +52,49 @@ * Give names to all the temporary files that we will need. */ -char *tmpdir; +char *tempMail; +char *tempQuit; +char *tempEdit; +char *tempResid; +char *tempMesg; +char *tmpdir; void -tinit(void) +tinit() { - char *cp; + register char *cp; - if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') + if ((tmpdir = getenv("TMPDIR")) == NULL) { tmpdir = _PATH_TMP; - if ((tmpdir = strdup(tmpdir)) == NULL) - errx(1, "Out of memory"); - - /* Strip trailing '/' if necessary */ - cp = tmpdir + strlen(tmpdir) - 1; - while (cp > tmpdir && *cp == '/') { - *cp = '\0'; - cp--; } + tempMail = tempnam (tmpdir, "Rs"); + tempResid = tempnam (tmpdir, "Rq"); + tempQuit = tempnam (tmpdir, "Rm"); + tempEdit = tempnam (tmpdir, "Re"); + tempMesg = tempnam (tmpdir, "Rx"); + /* * It's okay to call savestr in here because main will * do a spreserve() after us. */ - if (myname != NULL) { + if (myname != NOSTR) { if (getuserid(myname) < 0) { - errx(1, "\"%s\" is not a user of this system", myname); + printf("\"%s\" is not a user of this system\n", + myname); + exit(1); } } else { - if ((cp = username()) == NULL) { + if ((cp = username()) == NOSTR) { myname = "nobody"; if (rcvmode) exit(1); } else myname = savestr(cp); } - if ((cp = getenv("HOME")) == NULL || *cp == '\0' || - strlen(cp) >= PATHSIZE) - homedir = NULL; - else - homedir = savestr(cp); + if ((cp = getenv("HOME")) == NOSTR) + cp = "."; + homedir = savestr(cp); if (debug) - printf("user = %s, homedir = %s\n", myname, - homedir ? homedir : "NONE"); + printf("user = %s, homedir = %s\n", myname, homedir); } diff -urN mailx-8.1.1.orig/tty.c mailx-8.1.1/tty.c --- mailx-8.1.1.orig/tty.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/tty.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: tty.c,v 1.16 2001/11/28 01:04:34 millert Exp $ */ -/* $NetBSD: tty.c,v 1.7 1997/07/09 05:25:46 mikel Exp $ */ +/* $OpenBSD: tty.c,v 1.5 1996/06/08 19:48:43 christos Exp $ */ +/* $NetBSD: tty.c,v 1.5 1996/06/08 19:48:43 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)tty.c 8.2 (Berkeley) 4/20/95"; +static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: tty.c,v 1.16 2001/11/28 01:04:34 millert Exp $"; +static char rcsid[] = "$OpenBSD: tty.c,v 1.5 1996/06/08 19:48:43 christos Exp $"; #endif #endif /* not lint */ @@ -50,50 +50,54 @@ #include "rcv.h" #include "extern.h" -#include #include +#include +#include -static cc_t c_erase; /* Current erase char */ -static cc_t c_kill; /* Current kill char */ +static cc_t c_erase; /* Current erase char */ +static cc_t c_kill; /* Current kill char */ +static jmp_buf rewrite; /* Place to go when continued */ +static jmp_buf intjmp; /* Place to go when interrupted */ #ifndef TIOCSTI -static int ttyset; /* We must now do erase/kill */ +static int ttyset; /* We must now do erase/kill */ +#endif + +#ifdef IOSAFE +static int got_interrupt; #endif -static volatile sig_atomic_t ttysignal; /* Interrupted by a signal? */ /* * Read all relevant header fields. */ + int -grabh(struct header *hp, int gflags) +grabh(hp, gflags) + struct header *hp; + int gflags; { struct termios ttybuf; + sig_t saveint; #ifndef TIOCSTI - struct sigaction savequit; -#else -# ifdef TIOCEXT - int extproc; - int flag; -# endif /* TIOCEXT */ -#endif - struct sigaction savetstp; - struct sigaction savettou; - struct sigaction savettin; - struct sigaction act; - char *s; - int error; - - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - act.sa_handler = SIG_DFL; - (void)sigaction(SIGTSTP, &act, &savetstp); - (void)sigaction(SIGTTOU, &act, &savettou); - (void)sigaction(SIGTTIN, &act, &savettin); - error = 1; + sig_t savequit; +#endif + sig_t savetstp; + sig_t savettou; + sig_t savettin; + int errs; +#ifdef __GNUC__ + /* Avoid longjmp clobbering */ + (void) &saveint; +#endif + + savetstp = signal(SIGTSTP, SIG_DFL); + savettou = signal(SIGTTOU, SIG_DFL); + savettin = signal(SIGTTIN, SIG_DFL); + errs = 0; #ifndef TIOCSTI ttyset = 0; #endif if (tcgetattr(fileno(stdin), &ttybuf) < 0) { - warn("tcgetattr"); + perror("tcgetattr"); return(-1); } c_erase = ttybuf.c_cc[VERASE]; @@ -101,81 +105,66 @@ #ifndef TIOCSTI ttybuf.c_cc[VERASE] = 0; ttybuf.c_cc[VKILL] = 0; - act.sa_handler = SIG_IGN; - if (sigaction(SIGQUIT, &act, &savequit) == 0 && - savequit.sa_handler == SIG_DFL) - (void)sigaction(SIGQUIT, &savequit, NULL); + if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL) + signal(SIGINT, SIG_DFL); + if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL) + signal(SIGQUIT, SIG_DFL); #else -# ifdef TIOCEXT - extproc = ((ttybuf.c_lflag & EXTPROC) ? 1 : 0); - if (extproc) { - flag = 0; - if (ioctl(fileno(stdin), TIOCEXT, &flag) < 0) - warn("TIOCEXT: off"); - } -# endif /* TIOCEXT */ +#ifdef IOSAFE + got_interrupt = 0; +#endif + if (setjmp(intjmp)) { + /* avoid garbled output with C-c */ + printf("\n"); + fflush(stdout); + goto out; + } + saveint = signal(SIGINT, ttyint); #endif if (gflags & GTO) { #ifndef TIOCSTI - if (!ttyset && hp->h_to != NULL) + if (!ttyset && hp->h_to != NIL) ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf); #endif - s = readtty("To: ", detract(hp->h_to, 0)); - if (s == NULL) - goto out; - hp->h_to = extract(s, GTO); + hp->h_to = + extract(readtty("To: ", detract(hp->h_to, 0)), GTO); } if (gflags & GSUBJECT) { #ifndef TIOCSTI - if (!ttyset && hp->h_subject != NULL) + if (!ttyset && hp->h_subject != NOSTR) ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf); #endif - s = readtty("Subject: ", hp->h_subject); - if (s == NULL) - goto out; - hp->h_subject = s; + hp->h_subject = readtty("Subject: ", hp->h_subject); } if (gflags & GCC) { #ifndef TIOCSTI - if (!ttyset && hp->h_cc != NULL) + if (!ttyset && hp->h_cc != NIL) ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf); #endif - s = readtty("Cc: ", detract(hp->h_cc, 0)); - if (s == NULL) - goto out; - hp->h_cc = extract(s, GCC); + hp->h_cc = + extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC); } if (gflags & GBCC) { #ifndef TIOCSTI - if (!ttyset && hp->h_bcc != NULL) + if (!ttyset && hp->h_bcc != NIL) ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf); #endif - s = readtty("Bcc: ", detract(hp->h_bcc, 0)); - if (s == NULL) - goto out; - hp->h_bcc = extract(s, GBCC); + hp->h_bcc = + extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC); } - error = 0; out: - (void)sigaction(SIGTSTP, &savetstp, NULL); - (void)sigaction(SIGTTOU, &savettou, NULL); - (void)sigaction(SIGTTIN, &savettin, NULL); + signal(SIGTSTP, savetstp); + signal(SIGTTOU, savettou); + signal(SIGTTIN, savettin); #ifndef TIOCSTI ttybuf.c_cc[VERASE] = c_erase; ttybuf.c_cc[VKILL] = c_kill; if (ttyset) tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf); - (void)sigaction(SIGQUIT, &savequit, NULL); -#else -# ifdef TIOCEXT - if (extproc) { - flag = 1; - if (ioctl(fileno(stdin), TIOCEXT, &flag) < 0) - warn("TIOCEXT: on"); - } -# endif /* TIOCEXT */ + signal(SIGQUIT, savequit); #endif - return(error); + signal(SIGINT, saveint); + return(errs); } /* @@ -184,30 +173,35 @@ * be read. * */ + char * -readtty(char *pr, char *src) +readtty(pr, src) + char pr[], src[]; { - struct sigaction act, saveint; char ch, canonb[BUFSIZ]; - char *cp, *cp2; - sigset_t oset; int c; + char *cp, *cp2; +#if __GNUC__ + /* Avoid longjmp clobbering */ + (void) &c; + (void) &cp2; +#endif fputs(pr, stdout); fflush(stdout); - if (src != NULL && strlen(src) > BUFSIZ - 2) { - puts("too long to edit"); + if (src != NOSTR && strlen(src) > BUFSIZ - 2) { + printf("too long to edit\n"); return(src); } #ifndef TIOCSTI - if (src != NULL) - cp = copy(src, canonb); /* safe, bounds checked above */ + if (src != NOSTR) + cp = copy(src, canonb); else cp = copy("", canonb); fputs(canonb, stdout); fflush(stdout); #else - cp = src == NULL ? "" : src; + cp = src == NOSTR ? "" : src; while ((c = *cp++) != '\0') { if ((c_erase != _POSIX_VDISABLE && c == c_erase) || (c_kill != _POSIX_VDISABLE && c == c_kill)) { @@ -224,58 +218,46 @@ while (cp2 < canonb + BUFSIZ) *cp2++ = 0; cp2 = cp; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; /* Note: will not restart syscalls */ - act.sa_handler = ttyint; - (void)sigaction(SIGINT, &act, &saveint); - act.sa_handler = ttystop; - (void)sigaction(SIGTSTP, &act, NULL); - (void)sigaction(SIGTTOU, &act, NULL); - (void)sigaction(SIGTTIN, &act, NULL); - (void)sigprocmask(SIG_UNBLOCK, &intset, &oset); + if (setjmp(rewrite)) + goto redo; +#ifdef IOSAFE + got_interrupt = 0; +#endif + signal(SIGTSTP, ttystop); + signal(SIGTTOU, ttystop); + signal(SIGTTIN, ttystop); clearerr(stdin); while (cp2 < canonb + BUFSIZ) { +#ifdef IOSAFE + c = safegetc(stdin); + /* this is full of ACE but hopefully, interrupts will only occur in the above read */ + if (got_interrupt == SIGINT) + longjmp(intjmp,1); + else if (got_interrupt) + longjmp(rewrite,1); +#else c = getc(stdin); - switch (ttysignal) { - case SIGINT: - ttysignal = 0; - cp2 = NULL; - c = EOF; - /* FALLTHROUGH */ - case 0: - break; - default: - ttysignal = 0; - goto redo; - } +#endif if (c == EOF || c == '\n') - break; + break; *cp2++ = c; } - act.sa_handler = SIG_DFL; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void)sigaction(SIGTSTP, &act, NULL); - (void)sigaction(SIGTTOU, &act, NULL); - (void)sigaction(SIGTTIN, &act, NULL); - (void)sigaction(SIGINT, &saveint, NULL); - if (cp2 == NULL) - return(NULL); /* user hit ^C */ - *cp2 = '\0'; + *cp2 = 0; + signal(SIGTSTP, SIG_DFL); + signal(SIGTTOU, SIG_DFL); + signal(SIGTTIN, SIG_DFL); if (c == EOF && ferror(stdin)) { redo: - cp = strlen(canonb) > 0 ? canonb : NULL; + cp = strlen(canonb) > 0 ? canonb : NOSTR; clearerr(stdin); - /* XXX - make iterative, not recursive */ return(readtty(pr, cp)); } #ifndef TIOCSTI - if (cp == NULL || *cp == '\0') + if (cp == NOSTR || *cp == '\0') return(src); cp2 = cp; if (!ttyset) - return(strlen(canonb) > 0 ? savestr(canonb) : NULL); + return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR); while (*cp != '\0') { c = *cp++; if (c_erase != _POSIX_VDISABLE && c == c_erase) { @@ -303,7 +285,7 @@ *cp2 = '\0'; #endif if (equal("", canonb)) - return(""); + return(NOSTR); return(savestr(canonb)); } @@ -311,35 +293,63 @@ * Receipt continuation. */ void -ttystop(int s) +ttystop(s) + int s; { - struct sigaction act, oact; + sig_t old_action = signal(s, SIG_DFL); sigset_t nset; - int save_errno; - /* - * Save old handler and set to default. - * Unblock receipt of 's' and then resend it. - */ - save_errno = errno; - (void)sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - act.sa_handler = SIG_DFL; - (void)sigaction(s, &act, &oact); - (void)sigemptyset(&nset); - (void)sigaddset(&nset, s); - (void)sigprocmask(SIG_UNBLOCK, &nset, NULL); - (void)kill(0, s); - (void)sigprocmask(SIG_BLOCK, &nset, NULL); - (void)sigaction(s, &oact, NULL); - ttysignal = s; - errno = save_errno; + sigemptyset(&nset); + sigaddset(&nset, s); + sigprocmask(SIG_BLOCK, &nset, NULL); + kill(0, s); + sigprocmask(SIG_UNBLOCK, &nset, NULL); + signal(s, old_action); +#ifdef IOSAFE + got_interrupt = s; +#endif + longjmp(rewrite, 1); } /*ARGSUSED*/ void -ttyint(int s) +ttyint(s) + int s; { +#ifdef IOSAFE + got_interrupt = s; +#else + longjmp(intjmp, 1); +#endif +} - ttysignal = s; +#ifdef IOSAFE +/* it is very awful, but only way I see to be able to do a interruptable stdio call */ +int safegetc(FILE *ibuf) +{ + int oldfl; + int res; + while (1) { + errno = 0; + oldfl = fcntl(fileno(ibuf),F_GETFL); + fcntl(fileno(ibuf),F_SETFL,oldfl | O_NONBLOCK); + res = getc(ibuf); + fcntl(fileno(ibuf),F_SETFL,oldfl); + if (res != EOF) + return res; + else if (errno == EAGAIN || errno == EWOULDBLOCK) { + fd_set rds; + clearerr(ibuf); + FD_ZERO(&rds); + FD_SET(fileno(ibuf),&rds); + select(fileno(ibuf)+1,&rds,NULL,NULL,NULL); + /* if an interrupt occur drops the current line and returns */ + if (got_interrupt) + return EOF; + } else { + /* probably EOF one the file descriptors */ + return EOF; + } + } } +#endif diff -urN mailx-8.1.1.orig/v7.local.c mailx-8.1.1/v7.local.c --- mailx-8.1.1.orig/v7.local.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/v7.local.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,5 +1,5 @@ -/* $OpenBSD: v7.local.c,v 1.13 2001/11/21 15:26:39 millert Exp $ */ -/* $NetBSD: v7.local.c,v 1.8 1997/05/13 06:15:58 mikel Exp $ */ +/* $OpenBSD: v7.local.c,v 1.7 1996/06/08 19:48:44 christos Exp $ */ +/* $NetBSD: v7.local.c,v 1.7 1996/06/08 19:48:44 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)v7.local.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)v7.local.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: v7.local.c,v 1.13 2001/11/21 15:26:39 millert Exp $"; +static char rcsid[] = "$OpenBSD: v7.local.c,v 1.7 1996/06/08 19:48:44 christos Exp $"; #endif #endif /* not lint */ @@ -60,50 +60,52 @@ * mail is queued). */ void -findmail(char *user, char *buf, int buflen) +findmail(user, buf, size) + char *user, *buf; + int size; { char *mbox; - struct stat sb; - /* Ignore $MAIL if it is not owned by the invoking user */ - if ((mbox = getenv("MAIL")) && stat(mbox, &sb) == 0 && - sb.st_uid != getuid() && sb.st_uid != geteuid()) - mbox = NULL; - - if (mbox) - (void)istrcpy(buf, mbox, buflen); - else - (void)snprintf(buf, buflen, "%s/%s", _PATH_MAILDIR, user); + if (!(mbox = getenv("MAIL"))) { + char safelist[] = _PATH_MAILDIR; + char *safepath, *p = safelist; + while ((safepath = strtok(p, ":"))) { + p = 0; + (void)snprintf(buf, size, "%s/%s", safepath, user); + if (access(buf, F_OK) == 0) + break; + } + } else { + (void)strncpy(buf, mbox, size); + buf[size-1]='\0'; + } + } /* * Get rid of the queued mail. */ void -demail(void) +demail() { - if (value("keep") != NULL || rm(mailname) < 0) - (void)close(creat(mailname, 0600)); + if (value("keep") != NOSTR || rm(mailname) < 0) + close(creat(mailname, 0600)); } /* * Discover user login name. */ char * -username(void) +username() { char *np; uid_t uid; - if ((np = getenv("USER")) != NULL) - return(np); - if ((np = getenv("LOGNAME")) != NULL) - return(np); - if ((np = getname(uid = getuid())) != NULL) - return(np); - if ((np = getlogin()) != NULL) - return(np); - printf("Cannot associate a name with uid %u\n", (unsigned)uid); - return(NULL); + if ((np = getenv("USER")) != NOSTR) + return np; + if ((np = getname(uid = getuid())) != NOSTR) + return np; + printf("Cannot associate a name with uid %d\n", uid); + return NOSTR; } diff -urN mailx-8.1.1.orig/vars.c mailx-8.1.1/vars.c --- mailx-8.1.1.orig/vars.c 2003-03-26 12:58:12.000000000 -0800 +++ mailx-8.1.1/vars.c 2003-03-26 13:03:40.000000000 -0800 @@ -1,4 +1,4 @@ -/* $OpenBSD: vars.c,v 1.9 2002/08/12 00:42:56 aaron Exp $ */ +/* $OpenBSD: vars.c,v 1.4 1996/06/08 19:48:45 christos Exp $ */ /* $NetBSD: vars.c,v 1.4 1996/06/08 19:48:45 christos Exp $ */ /* @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)vars.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)vars.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: vars.c,v 1.9 2002/08/12 00:42:56 aaron Exp $"; +static char rcsid[] = "$OpenBSD: vars.c,v 1.4 1996/06/08 19:48:45 christos Exp $"; #endif #endif /* not lint */ @@ -55,16 +55,16 @@ * Assign a value to a variable. */ void -assign(char *name, char *value) +assign(name, value) + char name[], value[]; { - struct var *vp; - int h; + register struct var *vp; + register int h; h = hash(name); vp = lookup(name); - if (vp == NULL) { - if ((vp = (struct var *)calloc(1, sizeof(*vp))) == NULL) - errx(1, "Out of memory"); + if (vp == NOVAR) { + vp = (struct var *) calloc(sizeof *vp, 1); vp->v_name = vcopy(name); vp->v_link = variables[h]; variables[h] = vp; @@ -80,27 +80,34 @@ * Thus, we cannot free same! */ void -vfree(char *cp) +vfree(cp) + char *cp; { - - if (*cp) - (void)free(cp); + if (cp && *cp) + free(cp); } /* * Copy a variable value into permanent (ie, not collected after each * command) space. Do not bother to alloc space for "" */ + char * -vcopy(char *str) +vcopy(str) + char str[]; { char *new; + unsigned len; + if (str == NULL) + return NULL; if (*str == '\0') - return(""); - if ((new = strdup(str)) == NULL) - errx(1, "Out of memory"); - return(new); + return ""; + len = strlen(str) + 1; + if ((new = malloc(len)) == NULL) + panic("Out of memory"); + bcopy(str, new, (int) len); + return new; } /* @@ -109,70 +116,65 @@ */ char * -value(char *name) +value(name) + char name[]; { - struct var *vp; - char *env; + register struct var *vp; - if ((vp = lookup(name)) != NULL) - return(vp->v_value); - else if ((env = getenv(name))) - return(env); - /* not set, see if we can provide a default */ - else if (strcmp(name, "SHELL") == 0) - return(_PATH_CSHELL); - else if (strcmp(name, "LISTER") == 0) - return(_PATH_LS); - else if (strcmp(name, "PAGER") == 0) - return(_PATH_MORE); - else - return(NULL); + if ((vp = lookup(name)) == NOVAR) + return NULL; + return(vp->v_value); } /* * Locate a variable and return its variable * node. */ + struct var * -lookup(char *name) +lookup(name) + register char name[]; { - struct var *vp; + register struct var *vp; - for (vp = variables[hash(name)]; vp != NULL; vp = vp->v_link) + for (vp = variables[hash(name)]; vp != NOVAR; vp = vp->v_link) if (*vp->v_name == *name && equal(vp->v_name, name)) return(vp); - return(NULL); + return(NOVAR); } /* * Locate a group name and return it. */ + struct grouphead * -findgroup(char *name) +findgroup(name) + register char name[]; { - struct grouphead *gh; + register struct grouphead *gh; - for (gh = groups[hash(name)]; gh != NULL; gh = gh->g_link) + for (gh = groups[hash(name)]; gh != NOGRP; gh = gh->g_link) if (*gh->g_name == *name && equal(gh->g_name, name)) return(gh); - return(NULL); + return(NOGRP); } /* * Print a group out on stdout */ void -printgroup(char *name) +printgroup(name) + char name[]; { - struct grouphead *gh; - struct group *gp; + register struct grouphead *gh; + register struct group *gp; - if ((gh = findgroup(name)) == NULL) { + if ((gh = findgroup(name)) == NOGRP) { printf("\"%s\": not a group\n", name); return; } printf("%s\t", gh->g_name); - for (gp = gh->g_list; gp != NULL; gp = gp->ge_link) + for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) printf(" %s", gp->ge_name); putchar('\n'); } @@ -182,9 +184,10 @@ * the variable or group hash table. */ int -hash(char *name) +hash(name) + register char *name; { - int h = 0; + register h = 0; while (*name) { h <<= 2; @@ -192,5 +195,5 @@ } if (h < 0 && (h = -h) < 0) h = 0; - return(h % HSHSIZE); + return (h % HSHSIZE); } diff -urN mailx-8.1.1.orig/version.c mailx-8.1.1/version.c --- mailx-8.1.1.orig/version.c 2003-03-26 12:58:13.000000000 -0800 +++ mailx-8.1.1/version.c 1996-06-14 01:27:09.000000000 -0700 @@ -1,4 +1,4 @@ -/* $OpenBSD: version.c,v 1.5 2001/11/21 15:26:39 millert Exp $ */ +/* $OpenBSD: version.c,v 1.4 1996/06/08 19:48:46 christos Exp $ */ /* $NetBSD: version.c,v 1.4 1996/06/08 19:48:46 christos Exp $ */ /* @@ -36,9 +36,9 @@ #ifndef lint #if 0 -static const char sccsid[] = "@(#)version.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)version.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: version.c,v 1.5 2001/11/21 15:26:39 millert Exp $"; +static char rcsid[] = "$OpenBSD: version.c,v 1.4 1996/06/08 19:48:46 christos Exp $"; #endif #endif /* not lint */ @@ -46,4 +46,4 @@ * Just keep track of the date/sid of this version of Mail. * Load this file first to get a "total" Mail version. */ -const char version[] = "8.1.2 01/15/2001"; +char *version = "8.1 6/6/93";