Sophie

Sophie

distrib > PLD > ra > i386 > media > dist-src > by-pkgid > 515a6da85eaef9f2b6af08ac92ce0f59 > files > 4

mailx-8.1.1-21.src.rpm

--- mailx-8.1.1.orig/aux.c
+++ mailx-8.1.1/aux.c
@@ -280,16 +280,22 @@
  * Copy a string, lowercasing it as we go.
  */
 void
-istrcpy(dest, src)
+istrcpy(dest, src, size)
 	register char *dest, *src;
+	int size;
 {
+	register char *max;
 
-	do {
-		if (isupper(*src))
+	max=dest+size-1;
+	while (dest<=max) {
+		if (isupper(*src)) {
 			*dest++ = tolower(*src);
-		else
+		} else {
 			*dest++ = *src;
-	} while (*src++ != 0);
+		}
+		if (*src++ == 0)
+                  break;
+	}
 }
 
 /*
@@ -606,10 +612,13 @@
 				break;
 			cp++;
 			if (first) {
-				strcpy(namebuf, cp);
+				strncpy(namebuf, cp, LINESIZE);
 				first = 0;
-			} else
-				strcpy(rindex(namebuf, '!')+1, cp);
+			} else {
+				cp2=rindex(namebuf, '!')+1;
+				strncpy(cp2, cp, (namebuf+LINESIZE)-cp2);
+			}
+			namebuf[LINESIZE-2]='\0';
 			strcat(namebuf, "!");
 			goto newname;
 		}
@@ -691,7 +700,8 @@
 	 * Lower-case the string, so that "Status" and "status"
 	 * will hash to the same place.
 	 */
-	istrcpy(realfld, field);
+	istrcpy(realfld, field, BUFSIZ);
+	realfld[BUFSIZ-1]='\0';
 	if (ignore[1].i_count > 0)
 		return (!member(realfld, ignore + 1));
 	else
--- mailx-8.1.1.orig/cmd1.c
+++ mailx-8.1.1/cmd1.c
@@ -465,7 +465,7 @@
 	char dirname[BUFSIZ];
 	char *cmd;
 
-	if (getfold(dirname) < 0) {
+	if (getfold(dirname, BUFSIZ) < 0) {
 		printf("No value set for \"folder\"\n");
 		return 1;
 	}
--- mailx-8.1.1.orig/cmd2.c
+++ mailx-8.1.1/cmd2.c
@@ -496,7 +496,8 @@
 	if (*list == NOSTR)
 		return igshow(tab, which);
 	for (ap = list; *ap != 0; ap++) {
-		istrcpy(field, *ap);
+		istrcpy(field, *ap, BUFSIZ);
+		field[BUFSIZ-1]='\0';
 		if (member(field, tab))
 			continue;
 		h = hash(field);
--- mailx-8.1.1.orig/cmd3.c
+++ mailx-8.1.1/cmd3.c
@@ -65,8 +65,9 @@
 	char *shell;
 	char cmd[BUFSIZ];
 
-	(void) strcpy(cmd, str);
-	if (bangexp(cmd) < 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;
@@ -103,8 +104,9 @@
 char	lastbang[128];
 
 int
-bangexp(str)
+bangexp(str, size)
 	char *str;
+	int size;
 {
 	char bangbuf[BUFSIZ];
 	register char *cp, *cp2;
@@ -144,7 +146,8 @@
 		printf("!%s\n", bangbuf);
 		fflush(stdout);
 	}
-	strcpy(str, bangbuf);
+	strncpy(str, bangbuf, size);
+	str[size-1]='\0';
 	strncpy(lastbang, bangbuf, 128);
 	lastbang[127] = 0;
 	return(0);
--- mailx-8.1.1.orig/collect.c
+++ mailx-8.1.1/collect.c
@@ -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.
@@ -143,6 +148,9 @@
 		escape = ESCAPE;
 	eofcount = 0;
 	hadintr = 0;
+#ifdef IOSAFE
+        got_interrupt = 0;
+#endif
 
 	if (!setjmp(colljmp)) {
 		if (getsub)
@@ -166,6 +174,12 @@
 	for (;;) {
 		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") != NOSTR &&
@@ -268,7 +282,8 @@
 			hp->h_bcc = cat(hp->h_bcc, extract(&linebuf[2], GBCC));
 			break;
 		case 'd':
-			strcpy(linebuf + 2, getdeadletter());
+			strncpy(linebuf + 2, getdeadletter(), LINESIZE - 2);
+			linebuf[LINESIZE-1]='\0';
 			/* fall into . . . */
 		case 'r':
 		case '<':
@@ -392,7 +407,11 @@
 	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);
@@ -427,6 +446,8 @@
 		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) {
 		perror(NOSTR);
 		return(-1);
@@ -589,10 +610,16 @@
 	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.
@@ -613,7 +640,12 @@
 			return;
 		}
 		hadintr = 1;
+#ifdef IOSAFE
+                got_interrupt = s;
+                return;
+#else
 		longjmp(colljmp, 1);
+#endif
 	}
 	rewind(collf);
 	if (value("nosave") == NOSTR)
--- mailx-8.1.1.orig/dotlock.c
+++ mailx-8.1.1/dotlock.c
@@ -48,11 +48,33 @@
 #include <signal.h>
 
 #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
@@ -69,11 +91,12 @@
 	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;
+	int fd, serrno, cc;
 	struct stat st;
 
 	(void) gettimeofday(&tv, NULL);
@@ -93,12 +116,17 @@
 	(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;
 		}
@@ -107,11 +135,14 @@
 		else
 			return -1;
 	}
-
 	/*
 	 * We link the path to the name
 	 */
-	if (link(path, fname) == -1)
+        perhaps_setgid(fname, effectivegid);
+        cc = link(path, fname);
+        setgid(realgid);
+   
+	if (cc == -1)
 		goto bad;
 
 	/*
@@ -121,7 +152,9 @@
 	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
@@ -149,6 +182,7 @@
 {
 	char path[MAXPATHLEN];
 	sigset_t nset, oset;
+        int i;
 
 	sigemptyset(&nset);
 	sigaddset(&nset, SIGHUP);
@@ -162,7 +196,7 @@
 
 	(void) snprintf(path, sizeof(path), "%s.lock", fname);
 
-	for (;;) {
+	for (i=0;i<15;i++) {
 		(void) sigprocmask(SIG_BLOCK, &nset, &oset);
 		if (create_exclusive(path) != -1) {
 			(void) sigprocmask(SIG_SETMASK, &oset, NULL);
@@ -185,6 +219,8 @@
 			sleep(pollinterval);
 		}
 	}
+        fprintf(stderr,"%s seems a stale lock? Need to be removed by hand?\n",path);
+        return -1;
 }
 
 void
@@ -194,5 +230,7 @@
 	char path[MAXPATHLEN];
 
 	(void) snprintf(path, sizeof(path), "%s.lock", fname);
+        perhaps_setgid(path, effectivegid);
 	(void) unlink(path);
+        setgid(realgid);
 }
--- mailx-8.1.1.orig/edit.c
+++ mailx-8.1.1/edit.c
@@ -159,7 +159,7 @@
 	struct stat statb;
 	extern char *tempEdit;
 
-	if ((t = creat(tempEdit, readonly ? 0400 : 0600)) < 0) {
+	if ((t = open(tempEdit, O_CREAT|O_WRONLY|O_EXCL, readonly ? 0400 : 0600)) < 0) {
 		perror(tempEdit);
 		goto out;
 	}
--- mailx-8.1.1.orig/extern.h
+++ mailx-8.1.1/extern.h
@@ -50,6 +50,7 @@
 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 *));
@@ -79,7 +80,7 @@
 char	*username __P((void));
 char	*value __P((char []));
 char	*vcopy __P((char []));
-char	*yankword __P((char *, char []));
+char	*yankword __P((char *, char [], int));
 int	 Fclose __P((FILE *));
 int	 More __P((void *));
 int	 Pclose __P((FILE *));
@@ -94,7 +95,7 @@
 int	 append __P((struct message *, FILE *));
 int	 argcount __P((char **));
 void	 assign __P((char [], char []));
-int	 bangexp __P((char *));
+int	 bangexp __P((char *, int));
 int	 blankline __P((char []));
 void	 brokpipe __P((int));
 int	 charcount __P((char *, int));
@@ -130,7 +131,7 @@
 int	 file __P((void *));
 struct grouphead *
 	 findgroup __P((char []));
-void	 findmail __P((char *, 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));
@@ -139,7 +140,7 @@
 void	 free_child __P((int));
 int	 from __P((void *));
 off_t	 fsize __P((FILE *));
-int	 getfold __P((char *));
+int	 getfold __P((char *, int));
 int	 gethfield __P((FILE *, char [], int, char **));
 int	 getmsglist __P((char *, int *, int));
 int	 getrawlist __P((char [], char **, int));
@@ -164,7 +165,7 @@
 int	 ishead __P((char []));
 int	 isign __P((char *, struct ignoretab []));
 int	 isprefix __P((char *, char *));
-void	 istrcpy __P((char *, char *));
+void	 istrcpy __P((char *, char *, int));
 const struct cmd *
 	 lex __P((char []));
 void	 load __P((char *));
--- mailx-8.1.1.orig/fio.c
+++ mailx-8.1.1/fio.c
@@ -74,7 +74,7 @@
 	char linebuf[LINESIZE];
 
 	/* Get temporary file. */
-	(void)sprintf(linebuf, "%s/mail.XXXXXX", tmpdir);
+	(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);
@@ -178,14 +178,54 @@
 	char *linebuf;
 	int linesize;
 {
-	register int n;
-
+	register int n,oldfl;
+        char *res;
 	clearerr(ibuf);
-	if (fgets(linebuf, linesize, ibuf) == NULL)
-		return -1;
+#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';
+          linebuf[--n] = '\0';
 	return n;
 }
 
@@ -336,7 +376,7 @@
 	 */
 	switch (*name) {
 	case '%':
-		findmail(name[1] ? name + 1 : myname, xname);
+		findmail(name[1] ? name + 1 : myname, xname, PATHSIZE);
 		return savestr(xname);
 	case '#':
 		if (name[1] != 0)
@@ -351,13 +391,13 @@
 			name = "~/mbox";
 		/* fall through */
 	}
-	if (name[0] == '+' && getfold(cmdbuf) >= 0) {
-		sprintf(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] == '~' && (name[1] == '/' || name[1] == '\0')) {
-		sprintf(xname, "%s%s", homedir, name + 1);
+		snprintf(xname, PATHSIZE, "%s%s", homedir, name + 1);
 		name = savestr(xname);
 	}
 	if (!anyof(name, "~{[*?$`'\"\\"))
@@ -366,7 +406,7 @@
 		perror("pipe");
 		return name;
 	}
-	sprintf(cmdbuf, "echo %s", name);
+	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);
@@ -376,21 +416,22 @@
 		return NOSTR;
 	}
 	close(pivec[1]);
-	l = read(pivec[0], xname, BUFSIZ);
+	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 NOSTR;
 	}
-	if (l < 0) {
-		perror("read");
-		return NOSTR;
-	}
 	if (l == 0) {
 		fprintf(stderr, "\"%s\": No match.\n", name);
 		return NOSTR;
 	}
-	if (l == BUFSIZ) {
+	if (l == PATHSIZE) {
 		fprintf(stderr, "\"%s\": Expansion buffer overflow.\n", name);
 		return NOSTR;
 	}
@@ -409,17 +450,20 @@
  * Determine the current folder directory name.
  */
 int
-getfold(name)
+getfold(name, size)
 	char *name;
+	int size;
 {
 	char *folder;
 
 	if ((folder = value("folder")) == NOSTR)
 		return (-1);
-	if (*folder == '/')
-		strcpy(name, folder);
-	else
-		sprintf(name, "%s/%s", homedir, folder);
+	if (*folder == '/') {
+		strncpy(name, folder, size);
+		name[size-1]='\0';
+	} else {
+		snprintf(name, size, "%s/%s", homedir, folder);
+	}
 	return (0);
 }
 
@@ -436,7 +480,7 @@
 	else if (*cp != '/') {
 		char buf[PATHSIZE];
 
-		(void) sprintf(buf, "~/%s", cp);
+		(void) snprintf(buf, PATHSIZE, "~/%s", cp);
 		cp = expand(buf);
 	}
 	return cp;
--- mailx-8.1.1.orig/glob.h
+++ mailx-8.1.1/glob.h
@@ -83,6 +83,8 @@
 int	screenheight;			/* Screen height, or best guess,
 					   for "header" command */
 int	realscreenheight;		/* the real screen height */
+gid_t   effectivegid;                   /* Saved from when we started up */
+gid_t   realgid;                        /* Saved from when we started up */
 
 #include <setjmp.h>
 
--- mailx-8.1.1.orig/head.c
+++ mailx-8.1.1/head.c
@@ -73,10 +73,13 @@
 		fail(linebuf, "No from or date field");
 		return (0);
 	}
+        /* be very tolerant about the date */
+#if 0
 	if (!isdate(hl.l_date)) {
 		fail(linebuf, "Date field not legal date");
 		return (0);
 	}
+#endif
 	/*
 	 * I guess we got it!
 	 */
--- mailx-8.1.1.orig/lex.c
+++ mailx-8.1.1/lex.c
@@ -134,16 +134,19 @@
 	}
 	shudclob = 1;
 	edit = isedit;
-	strcpy(prevfile, mailname);
-	if (name != mailname)
-		strcpy(mailname, name);
+	strncpy(prevfile, mailname, PATHSIZE);
+	prevfile[PATHSIZE-1]='\0';
+	if (name != mailname) {
+		strncpy(mailname, name, PATHSIZE);
+		mailname[PATHSIZE-1]='\0';
+	}
 	mailsize = fsize(ibuf);
-	if ((otf = fopen(tempMesg, "w")) == NULL) {
+	if ((otf = safe_fopen(tempMesg, "w")) == NULL) {
 		perror(tempMesg);
 		exit(1);
 	}
 	(void) fcntl(fileno(otf), F_SETFD, 1);
-	if ((itf = fopen(tempMesg, "r")) == NULL) {
+	if ((itf = safe_fopen(tempMesg, "r")) == NULL) {
 		perror(tempMesg);
 		exit(1);
 	}
@@ -616,10 +619,10 @@
 			s++;
 	}
 	ename = mailname;
-	if (getfold(fname) >= 0) {
+	if (getfold(fname, BUFSIZ-1) >= 0) {
 		strcat(fname, "/");
 		if (strncmp(fname, mailname, strlen(fname)) == 0) {
-			sprintf(zname, "+%s", mailname + strlen(fname));
+			snprintf(zname, BUFSIZ, "+%s", mailname + strlen(fname));
 			ename = zname;
 		}
 	}
--- mailx-8.1.1.orig/list.c
+++ mailx-8.1.1/list.c
@@ -515,7 +515,8 @@
 	int quotec;
 
 	if (regretp >= 0) {
-		strcpy(lexstring, string_stack[regretp]);
+		strncpy(lexstring, string_stack[regretp], STRINGLEN);
+		lexstring[STRINGLEN-1]='\0';
 		lexnumber = numberstack[regretp];
 		return(regretstack[regretp--]);
 	}
@@ -695,10 +696,12 @@
 	register char *cp, *cp2, *backup;
 
 	str++;
-	if (strlen(str) == 0)
+	if (strlen(str) == 0) {
 		str = lastscan;
-	else
-		strcpy(lastscan, str);
+	} else {
+		strncpy(lastscan, str, 128);
+		lastscan[127]='\0';
+	}
 	mp = &message[mesg-1];
 	
 	/*
--- mailx-8.1.1.orig/main.c
+++ mailx-8.1.1/main.c
@@ -48,6 +48,12 @@
 #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 <alvaro@lander.es>
+ */
+
 #include "rcv.h"
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -70,9 +76,24 @@
 	struct name *to, *cc, *bcc, *smopts;
 	char *subject;
 	char *ef;
+	char* cmd;
 	char nosrc = 0;
 	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,
@@ -81,6 +102,26 @@
 	(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.
@@ -287,12 +328,12 @@
 	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 < 1200)
+	if (ospeed < B1200)
 		screenheight = 9;
-	else if (ospeed == 1200)
+	else if (ospeed == B1200)
 		screenheight = 14;
 	else if (ws.ws_row != 0)
 		screenheight = ws.ws_row;
--- mailx-8.1.1.orig/names.c
+++ mailx-8.1.1/names.c
@@ -108,7 +108,7 @@
 	top = NIL;
 	np = NIL;
 	cp = line;
-	while ((cp = yankword(cp, nbuf)) != NOSTR) {
+	while ((cp = yankword(cp, nbuf, BUFSIZ)) != NOSTR) {
 		t = nalloc(nbuf, ntype);
 		if (top == NIL)
 			top = t;
@@ -171,10 +171,12 @@
  * Throw away things between ()'s, and take anything between <>.
  */
 char *
-yankword(ap, wbuf)
+yankword(ap, wbuf, maxsize)
 	char *ap, wbuf[];
+	int maxsize;
 {
 	register char *cp, *cp2;
+	int used = 0;
 
 	cp = ap;
 	for (;;) {
@@ -201,10 +203,11 @@
 			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 && !index(" \t,(", *cp); *cp2++ = *cp++)
+		for (cp2 = wbuf; *cp && (++used < maxsize) && !index(" \t,(", *cp); *cp2++ = *cp++)
 			;
 	*cp2 = '\0';
 	return cp;
@@ -253,7 +256,8 @@
 		 */
 
 		if (image < 0) {
-			if ((fout = Fopen(tempEdit, "a")) == NULL) {
+                  /* 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;
--- mailx-8.1.1.orig/quit.c
+++ mailx-8.1.1/quit.c
@@ -266,7 +266,8 @@
 		if (mp->m_flag & MBOX)
 			if (send(mp, obuf, saveignore, NOSTR) < 0) {
 				perror(mbox);
-				Fclose(ibuf);
+				if (ibuf)
+                                  Fclose(ibuf);
 				Fclose(obuf);
 				Fclose(fbuf);
 				dot_unlock(mailname);
--- mailx-8.1.1.orig/tty.c
+++ mailx-8.1.1/tty.c
@@ -50,6 +50,8 @@
 
 #include "rcv.h"
 #include "extern.h"
+#include <errno.h>
+#include <fcntl.h>
 #include <sys/ioctl.h>
 
 static	cc_t	c_erase;		/* Current erase char */
@@ -60,6 +62,10 @@
 static	int	ttyset;			/* We must now do erase/kill */
 #endif
 
+#ifdef IOSAFE 
+static int got_interrupt;
+#endif
+
 /*
  * Read all relevant header fields.
  */
@@ -104,8 +110,15 @@
 	if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL)
 		signal(SIGQUIT, SIG_DFL);
 #else
-	if (setjmp(intjmp))
+#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) {
@@ -207,14 +220,26 @@
 	cp2 = cp;
 	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);
+#endif
 		if (c == EOF || c == '\n')
-			break;
+                  break;
 		*cp2++ = c;
 	}
 	*cp2 = 0;
@@ -280,6 +305,9 @@
 	kill(0, s);
 	sigprocmask(SIG_UNBLOCK, &nset, NULL);
 	signal(s, old_action);
+#ifdef IOSAFE
+        got_interrupt = s;
+#endif
 	longjmp(rewrite, 1);
 }
 
@@ -288,5 +316,40 @@
 ttyint(s)
 	int s;
 {
+#ifdef IOSAFE
+  got_interrupt = s;
+#else
 	longjmp(intjmp, 1);
+#endif
+}
+
+#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
--- mailx-8.1.1.orig/v7.local.c
+++ mailx-8.1.1/v7.local.c
@@ -60,15 +60,26 @@
  * mail is queued).
  */
 void
-findmail(user, buf)
+findmail(user, buf, size)
 	char *user, *buf;
+	int size;
 {
 	char *mbox;
 
-	if (!(mbox = getenv("MAIL")))
-		(void)sprintf(buf, "%s/%s", _PATH_MAILDIR, user);
-	else
-		(void)strcpy(buf, mbox);
+	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';
+	}
+
 }
 
 /*
--- mailx-8.1.1.orig/vars.c
+++ mailx-8.1.1/vars.c
@@ -83,7 +83,7 @@
 vfree(cp)
 	char *cp;
 {
-	if (*cp)
+	if (cp && *cp)
 		free(cp);
 }
 
@@ -99,6 +99,8 @@
 	char *new;
 	unsigned len;
 
+	if (str == NULL)
+		return NULL;
 	if (*str == '\0')
 		return "";
 	len = strlen(str) + 1;
@@ -120,7 +122,7 @@
 	register struct var *vp;
 
 	if ((vp = lookup(name)) == NOVAR)
-		return(getenv(name));
+		return NULL;
 	return(vp->v_value);
 }
 
--- mailx-8.1.1.orig/popen.c
+++ mailx-8.1.1/popen.c
@@ -45,6 +45,7 @@
 #include "rcv.h"
 #include <sys/wait.h>
 #include <fcntl.h>
+#include <errno.h>
 #include "extern.h"
 
 #define READ 0
@@ -71,12 +72,42 @@
 static int file_pid __P((FILE *));
 
 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(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);
 	}