summaryrefslogtreecommitdiffstats
path: root/usr.bin/mail
diff options
context:
space:
mode:
authormikeh <mikeh@FreeBSD.org>2001-12-18 20:52:09 +0000
committermikeh <mikeh@FreeBSD.org>2001-12-18 20:52:09 +0000
commite4034fe298af9398dae0cac602d8a28ec6e51489 (patch)
tree89731abafbceb13b0e7b78a6e281339c99fbfef9 /usr.bin/mail
parent1750942f6f64d20cc8853d2d1a60a3daaeeb1110 (diff)
downloadFreeBSD-src-e4034fe298af9398dae0cac602d8a28ec6e51489.zip
FreeBSD-src-e4034fe298af9398dae0cac602d8a28ec6e51489.tar.gz
Sync with most of NetBSD's changes, including:
*) Sync with 4.4BSD-Lite2 *) Set usecs for utimes() *) Add 'inc' command and 'autoinc' option that check for new mail manually and automatically, respectively *) Use POSIX signal handling and tty semantics *) Handle long lines correctly when paging messages *) Add ability to explicitly search 'To:' line *) Various manpage cleanups *) Support overriding '~/.mailrc' with $MAILRC *) Support 'askbcc' and 'asksub' options *) Fix various bugs Reviewed by: ru (mail.1) Obtained from: NetBSD
Diffstat (limited to 'usr.bin/mail')
-rw-r--r--usr.bin/mail/aux.c6
-rw-r--r--usr.bin/mail/cmd1.c27
-rw-r--r--usr.bin/mail/cmd3.c10
-rw-r--r--usr.bin/mail/cmdtab.c1
-rw-r--r--usr.bin/mail/collect.c43
-rw-r--r--usr.bin/mail/def.h2
-rw-r--r--usr.bin/mail/extern.h23
-rw-r--r--usr.bin/mail/fio.c78
-rw-r--r--usr.bin/mail/head.c2
-rw-r--r--usr.bin/mail/lex.c66
-rw-r--r--usr.bin/mail/list.c50
-rw-r--r--usr.bin/mail/mail.1106
-rw-r--r--usr.bin/mail/main.c18
-rw-r--r--usr.bin/mail/names.c10
-rw-r--r--usr.bin/mail/popen.c52
-rw-r--r--usr.bin/mail/quit.c4
-rw-r--r--usr.bin/mail/send.c24
-rw-r--r--usr.bin/mail/tty.c74
18 files changed, 439 insertions, 157 deletions
diff --git a/usr.bin/mail/aux.c b/usr.bin/mail/aux.c
index d8c32b3..4db5b85 100644
--- a/usr.bin/mail/aux.c
+++ b/usr.bin/mail/aux.c
@@ -345,9 +345,9 @@ alter(name)
if (stat(name, &sb))
return;
- tv[0].tv_sec = time((time_t *)0) + 1;
- tv[1].tv_sec = sb.st_mtime;
- tv[0].tv_usec = tv[1].tv_usec = 0;
+ (void)gettimeofday(&tv[0], (struct timezone *)NULL);
+ tv[0].tv_sec++;
+ TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
(void)utimes(name, tv);
}
diff --git a/usr.bin/mail/cmd1.c b/usr.bin/mail/cmd1.c
index aa5ad53..8c51077 100644
--- a/usr.bin/mail/cmd1.c
+++ b/usr.bin/mail/cmd1.c
@@ -33,7 +33,7 @@
#ifndef lint
#if 0
-static char sccsid[] = "@(#)cmd1.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)cmd1.c 8.2 (Berkeley) 4/20/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
@@ -111,7 +111,7 @@ scroll(arg)
case 0:
case '+':
s++;
- if (s * size > msgCount) {
+ if (s * size >= msgCount) {
printf("On last screenful of messages\n");
return (0);
}
@@ -460,3 +460,26 @@ folders()
(void)run_command(cmd, 0, -1, -1, dirname, NULL, NULL);
return (0);
}
+
+/*
+ * Update the mail file with any new messages that have
+ * come in since we started reading mail.
+ */
+int
+inc(v)
+ void *v;
+{
+ int nmsg, mdot;
+
+ nmsg = incfile();
+
+ if (nmsg == 0)
+ printf("No new mail.\n");
+ else if (nmsg > 0) {
+ mdot = newfileinfo(msgCount - nmsg);
+ dot = &message[mdot - 1];
+ } else
+ printf("\"inc\" command failed...\n");
+
+ return (0);
+}
diff --git a/usr.bin/mail/cmd3.c b/usr.bin/mail/cmd3.c
index 4ead961..8d21dd4 100644
--- a/usr.bin/mail/cmd3.c
+++ b/usr.bin/mail/cmd3.c
@@ -33,7 +33,7 @@
#ifndef lint
#if 0
-static char sccsid[] = "@(#)cmd3.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
@@ -357,7 +357,7 @@ rexit(e)
{
if (sourcing)
return (1);
- exit(e);
+ exit(0);
/*NOTREACHED*/
}
@@ -423,7 +423,9 @@ unset(arglist)
errs = 0;
for (ap = arglist; *ap != NULL; ap++) {
if ((vp2 = lookup(*ap)) == NULL) {
- if (!sourcing) {
+ if (getenv(*ap))
+ unsetenv(*ap);
+ else if (!sourcing) {
printf("\"%s\": undefined variable\n", *ap);
errs++;
}
@@ -552,7 +554,7 @@ file(argv)
{
if (argv[0] == NULL) {
- newfileinfo();
+ newfileinfo(0);
return (0);
}
if (setfile(*argv) < 0)
diff --git a/usr.bin/mail/cmdtab.c b/usr.bin/mail/cmdtab.c
index d375b88..7c49205 100644
--- a/usr.bin/mail/cmdtab.c
+++ b/usr.bin/mail/cmdtab.c
@@ -120,5 +120,6 @@ const struct cmd cmdtab[] = {
{ "core", core, M|NOLIST, 0, 0 },
{ "#", null, M|NOLIST, 0, 0 },
{ "clobber", clobber, M|RAWLIST, 0, 1 },
+ { "inc", inc, T|NOLIST, 0, 0 },
{ 0, 0, 0, 0, 0 }
};
diff --git a/usr.bin/mail/collect.c b/usr.bin/mail/collect.c
index 12fac37..4c42c90 100644
--- a/usr.bin/mail/collect.c
+++ b/usr.bin/mail/collect.c
@@ -80,14 +80,19 @@ collect(hp, printheaders)
FILE *fbuf;
int lc, cc, escape, eofcount, fd, c, t;
char linebuf[LINESIZE], tempname[PATHSIZE], *cp, getsub;
- int omask;
+ sigset_t nset;
+ int longline, lastlong, rc; /* So we don't make 2 or more lines
+ out of a long input line. */
collf = NULL;
/*
* Start catching signals from here, but we're still die on interrupts
* until we're in the main loop.
*/
- omask = sigblock(sigmask(SIGINT) | sigmask(SIGHUP));
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, SIGINT);
+ (void)sigaddset(&nset, SIGHUP);
+ (void)sigprocmask(SIG_BLOCK, &nset, NULL);
if ((saveint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
(void)signal(SIGINT, collint);
if ((savehup = signal(SIGHUP, SIG_IGN)) != SIG_IGN)
@@ -99,7 +104,7 @@ collect(hp, printheaders)
(void)rm(tempname);
goto err;
}
- sigsetmask(omask & ~(sigmask(SIGINT) | sigmask(SIGHUP)));
+ (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
noreset++;
(void)snprintf(tempname, sizeof(tempname),
@@ -131,6 +136,8 @@ collect(hp, printheaders)
escape = ESCAPE;
eofcount = 0;
hadintr = 0;
+ lastlong = 0;
+ longline = 0;
if (!setjmp(colljmp)) {
if (getsub)
@@ -163,14 +170,17 @@ cont:
}
break;
}
+ lastlong = longline;
+ longline = c == LINESIZE - 1;
eofcount = 0;
hadintr = 0;
if (linebuf[0] == '.' && linebuf[1] == '\0' &&
- value("interactive") != NULL &&
+ value("interactive") != NULL && !lastlong &&
(value("dot") != NULL || value("ignoreeof") != NULL))
break;
- if (linebuf[0] != escape || value("interactive") == NULL) {
- if (putline(collf, linebuf) < 0)
+ if (linebuf[0] != escape || value("interactive") == NULL ||
+ lastlong) {
+ if (putline(collf, linebuf, !longline) < 0)
goto err;
continue;
}
@@ -182,7 +192,7 @@ cont:
* Otherwise, it's an error.
*/
if (c == escape) {
- if (putline(collf, &linebuf[1]) < 0)
+ if (putline(collf, &linebuf[1], !longline) < 0)
goto err;
else
break;
@@ -298,9 +308,11 @@ cont:
(void)fflush(stdout);
lc = 0;
cc = 0;
- while (readline(fbuf, linebuf, LINESIZE) >= 0) {
- lc++;
- if ((t = putline(collf, linebuf)) < 0) {
+ while ((rc = readline(fbuf, linebuf, LINESIZE)) >= 0) {
+ if (rc != LINESIZE - 1)
+ lc++;
+ if ((t = putline(collf, linebuf,
+ rc != LINESIZE - 1)) < 0) {
(void)Fclose(fbuf);
goto err;
}
@@ -388,13 +400,13 @@ out:
if (collf != NULL)
rewind(collf);
noreset--;
- (void)sigblock(sigmask(SIGINT) | sigmask(SIGHUP));
+ (void)sigprocmask(SIG_BLOCK, &nset, NULL);
(void)signal(SIGINT, saveint);
(void)signal(SIGHUP, savehup);
(void)signal(SIGTSTP, savetstp);
(void)signal(SIGTTOU, savettou);
(void)signal(SIGTTIN, savettin);
- (void)sigsetmask(omask);
+ (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
return (collf);
}
@@ -576,10 +588,13 @@ collstop(s)
int s;
{
sig_t old_action = signal(s, SIG_DFL);
+ sigset_t nset;
- (void)sigsetmask(sigblock(0) & ~sigmask(s));
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, s);
+ (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
(void)kill(0, s);
- (void)sigblock(sigmask(s));
+ (void)sigprocmask(SIG_BLOCK, &nset, NULL);
(void)signal(s, old_action);
if (colljmp_p) {
colljmp_p = 0;
diff --git a/usr.bin/mail/def.h b/usr.bin/mail/def.h
index 8b5e4ee..3ef4ed0 100644
--- a/usr.bin/mail/def.h
+++ b/usr.bin/mail/def.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)def.h 8.2 (Berkeley) 3/21/94
+ * @(#)def.h 8.4 (Berkeley) 4/20/95
*
* $FreeBSD$
*/
diff --git a/usr.bin/mail/extern.h b/usr.bin/mail/extern.h
index cbd622c..f012962 100644
--- a/usr.bin/mail/extern.h
+++ b/usr.bin/mail/extern.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)extern.h 8.1 (Berkeley) 6/6/93
+ * @(#)extern.h 8.2 (Berkeley) 4/20/95
*
* $FreeBSD$
*/
@@ -147,6 +147,8 @@ int igcomp __P((const void *, const void *));
int igfield __P((char *[]));
int ignore1 __P((char *[], struct ignoretab *, const char *));
int igshow __P((struct ignoretab *, const char *));
+int inc __P((void *));
+int incfile __P((void));
void intr __P((int));
int isdate __P((char []));
int isdir __P((char []));
@@ -163,7 +165,7 @@ struct var *
int mail __P((struct name *,
struct name *, struct name *, struct name *, char *, char *));
void mail1 __P((struct header *, int));
-void makemessage __P((FILE *));
+void makemessage __P((FILE *, int));
void mark __P((int));
int markall __P((char [], int));
int matchsender __P((char *, int));
@@ -175,19 +177,19 @@ void mespipe __P((FILE *, char []));
int messize __P((int *));
int metamess __P((int, int));
int more __P((int *));
-int newfileinfo __P((void));
+int newfileinfo __P((int));
int next __P((int *));
int null __P((int));
void parse __P((char [], struct headline *, char []));
int pcmdlist __P((void));
int pdot __P((void));
-void prepare_child __P((int, int, int));
+void prepare_child __P((sigset_t *, int, int));
int preserve __P((int *));
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 putline __P((FILE *, char *, int));
int pversion __P((int));
void quit __P((void));
int quitcmd __P((void));
@@ -199,7 +201,8 @@ int respond __P((int *));
int retfield __P((char *[]));
int rexit __P((int));
int rm __P((char *));
-int run_command __P((char *, int, int, int, char *, char *, char *));
+int run_command __P((char *, sigset_t *, int, int, char *, char *,
+ char *));
int save __P((char []));
int save1 __P((char [], int, const char *, struct ignoretab *));
void savedeadletter __P((FILE *));
@@ -211,12 +214,13 @@ void scaninit __P((void));
int schdir __P((char **));
int screensize __P((void));
int scroll __P((char []));
-int sendmessage __P((struct message *, FILE *, struct ignoretab *, char *));
+int sendmessage __P((struct message *, FILE *, struct ignoretab *,
+ char *));
int sendmail __P((char *));
int set __P((char **));
int setfile __P((char *));
void setmsize __P((int));
-void setptr __P((FILE *));
+void setptr __P((FILE *, off_t));
void setscreensize __P((void));
int shell __P((char *));
void sigchild __P((int));
@@ -224,7 +228,8 @@ void sort __P((char **));
int source __P((char **));
void spreserve __P((void));
void sreset __P((void));
-int start_command __P((char *, int, int, int, char *, char *, char *));
+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((int []));
diff --git a/usr.bin/mail/fio.c b/usr.bin/mail/fio.c
index c9dcb94..0c78e3e 100644
--- a/usr.bin/mail/fio.c
+++ b/usr.bin/mail/fio.c
@@ -33,7 +33,7 @@
#ifndef lint
#if 0
-static char sccsid[] = "@(#)fio.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)fio.c 8.2 (Berkeley) 4/20/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
@@ -60,16 +60,17 @@ extern int wait_status;
* Set up the input pointers while copying the mail file into /tmp.
*/
void
-setptr(ibuf)
+setptr(ibuf, offset)
FILE *ibuf;
+ off_t offset;
{
int c, count;
char *cp, *cp2;
struct message this;
FILE *mestmp;
- off_t offset;
int maybe, inhead;
char linebuf[LINESIZE], pathbuf[PATHSIZE];
+ int omsgCount;
/* Get temporary file. */
(void)snprintf(pathbuf, sizeof(pathbuf), "%s/mail.XXXXXXXXXX", tmpdir);
@@ -77,10 +78,23 @@ setptr(ibuf)
err(1, "can't open %s", pathbuf);
(void)rm(pathbuf);
- msgCount = 0;
+ if (offset == 0) {
+ msgCount = 0;
+ } else {
+ /* Seek into the file to get to the new messages */
+ (void)fseek(ibuf, offset, SEEK_SET);
+ /*
+ * 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);
+ }
+ omsgCount = msgCount;
maybe = 1;
inhead = 0;
- offset = 0;
this.m_flag = MUSED|MNEW;
this.m_size = 0;
this.m_lines = 0;
@@ -90,7 +104,7 @@ setptr(ibuf)
if (fgets(linebuf, sizeof(linebuf), ibuf) == NULL) {
if (append(&this, mestmp))
errx(1, "temporary file");
- makemessage(mestmp);
+ makemessage(mestmp, omsgCount);
return;
}
count = strlen(linebuf);
@@ -150,21 +164,25 @@ setptr(ibuf)
/*
* 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.
+ * characters written, including the newline if requested.
*/
int
-putline(obuf, linebuf)
+putline(obuf, linebuf, outlf)
FILE *obuf;
char *linebuf;
+ int outlf;
{
int c;
c = strlen(linebuf);
(void)fwrite(linebuf, sizeof(*linebuf), c, obuf);
- fprintf(obuf, "\n");
+ if (outlf) {
+ fprintf(obuf, "\n");
+ c++;
+ }
if (ferror(obuf))
return (-1);
- return (c + 1);
+ return (c);
}
/*
@@ -212,20 +230,27 @@ setinput(mp)
* a dynamically allocated message structure.
*/
void
-makemessage(f)
+makemessage(f, omsgCount)
FILE *f;
+ int omsgCount;
{
- int size = (msgCount + 1) * sizeof(struct message);
-
- if (message != 0)
- (void)free(message);
- if ((message = malloc((unsigned)size)) == NULL)
- err(1, "Out of memory");
- dot = message;
- size -= sizeof(struct message);
+ size_t size;
+ struct message *nmessage;
+
+ size = (msgCount + 1) * sizeof(struct message);
+ nmessage = (struct message *)realloc(message, size);
+ if (nmessage == NULL)
+ errx(1, "Insufficient memory for %d messages\n",
+ msgCount);
+ if (omsgCount == 0 || message == NULL)
+ dot = nmessage;
+ else
+ dot = nmessage + (dot - message);
+ message = nmessage;
+ size -= (omsgCount + 1) * sizeof(struct message);
(void)fflush(f);
(void)lseek(fileno(f), (off_t)sizeof(*message), 0);
- if (read(fileno(f), (char *)message, size) != size)
+ if (read(fileno(f), (char *)&message[omsgCount], size) != size)
errx(1, "Message temporary file corrupted");
message[msgCount].m_size = 0;
message[msgCount].m_lines = 0;
@@ -263,7 +288,7 @@ rm(name)
}
static int sigdepth; /* depth of holdsigs() */
-static int omask;
+static sigset_t nset, oset;
/*
* Hold signals SIGHUP, SIGINT, and SIGQUIT.
*/
@@ -271,8 +296,13 @@ void
holdsigs()
{
- if (sigdepth++ == 0)
- omask = sigblock(sigmask(SIGHUP)|sigmask(SIGINT)|sigmask(SIGQUIT));
+ if (sigdepth++ == 0) {
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, SIGHUP);
+ (void)sigaddset(&nset, SIGINT);
+ (void)sigaddset(&nset, SIGQUIT);
+ (void)sigprocmask(SIG_BLOCK, &nset, &oset);
+ }
}
/*
@@ -283,7 +313,7 @@ relsesigs()
{
if (--sigdepth == 0)
- (void)sigsetmask(omask);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
}
/*
diff --git a/usr.bin/mail/head.c b/usr.bin/mail/head.c
index 0f214d7..806ab6d 100644
--- a/usr.bin/mail/head.c
+++ b/usr.bin/mail/head.c
@@ -33,7 +33,7 @@
#ifndef lint
#if 0
-static char sccsid[] = "@(#)head.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)head.c 8.2 (Berkeley) 4/20/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
diff --git a/usr.bin/mail/lex.c b/usr.bin/mail/lex.c
index c0f2604..c7f674c 100644
--- a/usr.bin/mail/lex.c
+++ b/usr.bin/mail/lex.c
@@ -33,7 +33,7 @@
#ifndef lint
#if 0
-static char sccsid[] = "@(#)lex.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)lex.c 8.2 (Berkeley) 4/20/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
@@ -68,7 +68,7 @@ setfile(name)
FILE *ibuf;
int i, fd;
struct stat stb;
- char isedit = *name != '%';
+ char isedit = *name != '%' || getuserid(myname) != getuid();
char *who = name[1] ? name + 1 : myname;
char tempname[PATHSIZE];
static int shudclob;
@@ -136,8 +136,14 @@ setfile(name)
err(1, "%s", tempname);
(void)fcntl(fileno(itf), F_SETFD, 1);
(void)rm(tempname);
- setptr(ibuf);
+ setptr(ibuf, 0);
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);
relsesigs();
sawcom = 0;
@@ -149,6 +155,36 @@ nomail:
return (0);
}
+/*
+ * Incorporate any new mail that has arrived since we first
+ * started reading mail.
+ */
+int
+incfile()
+{
+ int newsize;
+ int omsgCount = msgCount;
+ FILE *ibuf;
+
+ ibuf = Fopen(mailname, "r");
+ if (ibuf == NULL)
+ return (-1);
+ holdsigs();
+ newsize = fsize(ibuf);
+ if (newsize == 0)
+ return (-1); /* mail box is now empty??? */
+ if (newsize < mailsize)
+ return (-1); /* mail box has shrunk??? */
+ if (newsize == mailsize)
+ return (0); /* no new mail */
+ setptr(ibuf, mailsize);
+ setmsize(msgCount);
+ mailsize = ftell(ibuf);
+ (void)Fclose(ibuf);
+ relsesigs();
+ return (msgCount - omsgCount);
+}
+
int *msgvec;
int reset_on_stop; /* do a reset() if stopped */
@@ -178,6 +214,8 @@ commands()
* string space, and flush the output.
*/
if (!sourcing && value("interactive") != NULL) {
+ if ((value("autoinc") != NULL) && (incfile() > 0))
+ printf("New mail has arrived.\n");
reset_on_stop = 1;
printf("%s", prompt);
}
@@ -411,6 +449,8 @@ out:
unstack();
return (0);
}
+ if (com == NULL)
+ return (0);
if (value("autoprint") != NULL && com->c_argtype & P)
if ((dot->m_flag & MDELETED) == 0) {
muvec[0] = dot - &message[0] + 1;
@@ -431,7 +471,7 @@ setmsize(sz)
int sz;
{
- if (msgvec != 0)
+ if (msgvec != NULL)
(void)free(msgvec);
msgvec = calloc((unsigned)(sz + 1), sizeof(*msgvec));
}
@@ -523,10 +563,13 @@ stop(s)
int s;
{
sig_t old_action = signal(s, SIG_DFL);
+ sigset_t nset;
- (void)sigsetmask(sigblock(0) & ~sigmask(s));
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, s);
+ (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
(void)kill(0, s);
- (void)sigblock(sigmask(s));
+ (void)sigprocmask(SIG_BLOCK, &nset, NULL);
(void)signal(s, old_action);
if (reset_on_stop) {
reset_on_stop = 0;
@@ -556,7 +599,7 @@ announce()
{
int vec[2], mdot;
- mdot = newfileinfo();
+ mdot = newfileinfo(0);
vec[0] = mdot;
vec[1] = 0;
dot = &message[mdot - 1];
@@ -572,23 +615,24 @@ announce()
* Return a likely place to set dot.
*/
int
-newfileinfo()
+newfileinfo(omsgCount)
+ int omsgCount;
{
struct message *mp;
int u, n, mdot, d, s;
char fname[PATHSIZE+1], zname[PATHSIZE+1], *ename;
- for (mp = &message[0]; mp < &message[msgCount]; mp++)
+ for (mp = &message[omsgCount]; mp < &message[msgCount]; mp++)
if (mp->m_flag & MNEW)
break;
if (mp >= &message[msgCount])
- for (mp = &message[0]; mp < &message[msgCount]; mp++)
+ for (mp = &message[omsgCount]; mp < &message[msgCount]; mp++)
if ((mp->m_flag & MREAD) == 0)
break;
if (mp < &message[msgCount])
mdot = mp - &message[0] + 1;
else
- mdot = 1;
+ mdot = omsgCount + 1;
s = d = 0;
for (mp = &message[0], n = 0, u = 0; mp < &message[msgCount]; mp++) {
if (mp->m_flag & MNEW)
diff --git a/usr.bin/mail/list.c b/usr.bin/mail/list.c
index 04b1586..1dbc587 100644
--- a/usr.bin/mail/list.c
+++ b/usr.bin/mail/list.c
@@ -33,7 +33,7 @@
#ifndef lint
#if 0
-static char sccsid[] = "@(#)list.c 8.2 (Berkeley) 4/19/94";
+static char sccsid[] = "@(#)list.c 8.4 (Berkeley) 5/1/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
@@ -687,6 +687,49 @@ matchsender(str, mesg)
}
/*
+ * See if the passed name received the passed message number. Return true
+ * if so.
+ */
+
+static char *to_fields[] = { "to", "cc", "bcc", NULL };
+
+int
+matchto(str, mesg)
+ char *str;
+ int mesg;
+{
+ struct message *mp;
+ char *cp, *cp2, *backup, **to;
+
+ str++;
+
+ /* null string matches nothing instead of everything */
+ if (*str == '\0')
+ return (0);
+
+ mp = &message[mesg - 1];
+
+ for (to = to_fields; *to != NULL; to++) {
+ cp = str;
+ cp2 = hfield(*to, mp);
+ if (cp2 != NULL) {
+ backup = cp2;
+ while (*cp2 != '\0') {
+ if (*cp == '\0')
+ return (1);
+ if (toupper(*cp++) != toupper(*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
@@ -715,8 +758,11 @@ matchsubj(str, mesg)
*/
if (value("searchheaders") && (cp = strchr(str, ':')) != NULL) {
+ /* Check for special case "/To:" */
+ if (strncasecmp(str, "To:", 3) == 0)
+ return (matchto(cp, mesg));
*cp++ = '\0';
- cp2 = hfield(str, mp);
+ cp2 = hfield(*str != '\0' ? str : "subject", mp);
cp[-1] = ':';
str = cp;
} else {
diff --git a/usr.bin/mail/mail.1 b/usr.bin/mail/mail.1
index e38be25..0b68435 100644
--- a/usr.bin/mail/mail.1
+++ b/usr.bin/mail/mail.1
@@ -29,14 +29,15 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)mail.1 8.2 (Berkeley) 12/30/93
+.\" @(#)mail.1 8.8 (Berkeley) 4/28/95
.\" $FreeBSD$
.\"
-.Dd December 30, 1993
+.Dd April 28, 1995
.Dt MAIL 1
.Os
.Sh NAME
-.Nm mail
+.Nm mail ,
+.Nm Mail
.Nd send and receive mail
.Sh SYNOPSIS
.Nm
@@ -174,7 +175,7 @@ and
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
@@ -219,7 +220,7 @@ which prints the first few lines of a message could be used in
.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
@@ -245,7 +246,7 @@ message or to a shell to run some commands.
(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
session with the
@@ -260,7 +261,7 @@ Unexamined messages go back to the post office.
.Fl f
option above).
.Pp
-.Ss Personal and system wide distribution lists.
+.Ss Personal and system wide distribution lists
It is also possible to create a personal distribution lists so that,
for instance, you can send mail to
.Dq Li cohorts
@@ -293,7 +294,7 @@ System wide
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 8 .
.Pp
.Ss Network mail (ARPA, UUCP, Berknet)
See
@@ -392,7 +393,7 @@ listed on the
list.
If the
.Ic alternates
-command is given with no argument, the current set of alternate
+command is given with no argument, the current set of alternative
names is displayed.
.It Ic chdir
.Pq Ic c
@@ -505,13 +506,17 @@ If
.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
+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
mail to those people.
-.It Ic more
-.Pq Ic \&mo
-Takes a list of messages and invokes the pager on that list.
.It Ic mbox
Indicate that a list of messages be sent to
.Ic mbox
@@ -522,10 +527,12 @@ action for messages if you do
have the
.Ic hold
option set.
+.It Ic more
+.Pq Ic \&mo
+Takes a list of messages and invokes the pager on that list.
.It Ic next
-.Pq Ic n
+.Ic ( n ,
like
-(
.Ic \&+
or
.Tn CR )
@@ -572,14 +579,14 @@ A synonym for
.Ic reply .
.It Ic retain
Add the list of header fields named to the
-.Ar retained list
-Only the header fields in the retain list
+.Em "retained list" .
+Only the header fields in the retained list
are shown on your terminal when you print a message.
All other header fields are suppressed.
The
-.Ic Type
+.Ic type
and
-.Ic Print
+.Ic print
commands can be used to print a message in its entirety.
If
.Ic retain
@@ -788,11 +795,11 @@ Cause the named string to become the current subject field.
.It Ic \&~\&t Ns Ar name ...
Add the given names to the direct recipient list.
.It Ic \&~\&v
-Invoke an alternate editor (defined by the
+Invoke an alternative editor (defined by the
.Ev VISUAL
option) on the
message collected so far.
-Usually, the alternate editor will be a
+Usually, the alternative editor will be a
screen editor.
After you quit the editor, you may resume appending
text to the end of your message.
@@ -838,17 +845,28 @@ to be appended to the end rather than prepended.
This should always be set (preferably in one of the system-wide
.Pa mail.rc
files).
-.It Ar ask
+.It Ar ask , asksub
Causes
.Nm
to prompt you for the subject of each message you send.
If
you respond with simply a newline, no subject field will be sent.
+.It Ar askbcc
+Causes you to be prompted for additional blind carbon copy recipients at the
+end of each message.
+Responding with a newline indicates your
+satisfaction with the current list.
.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 autoprint
Causes the
.Ic delete
@@ -921,9 +939,38 @@ commands.
.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 ``/x:y''
-will expand to all messages containing the substring ``y'' in the header
-field ``x''. The string search is case insensitive.
+If this option is set, then a message-list specifier in the form
+.Dq Li / Ns Ar x Ns Li : Ns Ar y
+will expand to all messages containing the substring
+.Dq Ar y
+in the header field
+.Dq Ar x .
+The string search is case insensitive.
+If
+.Dq Ar x
+is ommitted, it will default to the
+.Dq Li Subject
+header field.
+The form
+.Dq Li /to: Ns Ar y
+is a special case, and will expand
+to all messages containing the substring
+.Dq Ar y
+in the
+.Dq Li To ,
+.Dq Li Cc
+or
+.Dq Li Bcc
+header fields.
+The check for
+.Qq Li "to"
+is case sensitive, so that
+.Dq Li /to: Ns Ar y
+can be used to limit the search for
+.Dq Ar y
+to just the
+.Dq Li To:
+field.
.It Ar verbose
Setting the option
.Ar verbose
@@ -963,7 +1010,7 @@ If set, will be used to initialize the Reply-To field for outgoing
messages.
.It Ev SHELL
Pathname of the shell to use in the
-.Ic !\&
+.Ic \&!
command and the
.Ic \&~!
escape.
@@ -1040,6 +1087,9 @@ Post office.
User's old mail.
.It Pa ~/.mailrc
File giving initial mail commands.
+This can be overridden by setting the
+.Ev MAILRC
+environment variable.
.It Pa /tmp/R*
Temporary files.
.It Pa /usr/share/misc/mail.*help
@@ -1081,3 +1131,9 @@ Usually,
is just a link to
.Nm Mail ,
which can be confusing.
+.Pp
+The name of the
+.Ic alternates
+list is incorrect English (it should be
+.Dq alternatives ) ,
+but is retained for compatibility.
diff --git a/usr.bin/mail/main.c b/usr.bin/mail/main.c
index 3707903..a95c705 100644
--- a/usr.bin/mail/main.c
+++ b/usr.bin/mail/main.c
@@ -39,7 +39,7 @@ static char copyright[] =
#ifndef lint
#if 0
-static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 4/20/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
@@ -67,7 +67,7 @@ main(argc, argv)
int i;
struct name *to, *cc, *bcc, *smopts;
char *subject, *replyto;
- char *ef;
+ char *ef, *rc;
char nosrc = 0;
sig_t prevint;
@@ -228,7 +228,9 @@ Usage: %s [-EiInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
* Expand returns a savestr, but load only uses the file name
* for fopen, so it's safe to do this.
*/
- load(expand("~/.mailrc"));
+ if ((rc = getenv("MAILRC")) == NULL)
+ rc = "~/.mailrc";
+ load(expand(rc));
replyto = value("REPLYTO");
if (!rcvmode) {
@@ -290,16 +292,16 @@ hdrstop(signo)
void
setscreensize()
{
+ struct termios tbuf;
struct winsize ws;
- struct termios tio;
- speed_t speed = 0;
+ speed_t speed;
if (ioctl(1, TIOCGWINSZ, (char *)&ws) < 0)
ws.ws_col = ws.ws_row = 0;
- if (tcgetattr(1, &tio) != -1)
- speed = cfgetospeed(&tio);
- if (speed <= 0)
+ if (tcgetattr(1, &tbuf) < 0)
speed = B9600;
+ else
+ speed = cfgetospeed(&tbuf);
if (speed < B1200)
screenheight = 9;
else if (speed == B1200)
diff --git a/usr.bin/mail/names.c b/usr.bin/mail/names.c
index 8d4bb42..976bfa4 100644
--- a/usr.bin/mail/names.c
+++ b/usr.bin/mail/names.c
@@ -296,6 +296,7 @@ outof(names, fo, hp)
if (ispipe) {
int pid;
char *sh;
+ sigset_t nset;
/*
* XXX
@@ -306,9 +307,12 @@ outof(names, fo, hp)
*/
if ((sh = value("SHELL")) == NULL)
sh = _PATH_CSHELL;
- pid = start_command(sh,
- sigmask(SIGHUP)|sigmask(SIGINT)|sigmask(SIGQUIT),
- image, -1, "-c", fname, NULL);
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, SIGHUP);
+ (void)sigaddset(&nset, SIGINT);
+ (void)sigaddset(&nset, SIGQUIT);
+ pid = start_command(sh, &nset, image, -1, "-c", fname,
+ NULL);
if (pid < 0) {
senderr++;
goto cant;
diff --git a/usr.bin/mail/popen.c b/usr.bin/mail/popen.c
index e8ee364..bbb2c11 100644
--- a/usr.bin/mail/popen.c
+++ b/usr.bin/mail/popen.c
@@ -110,6 +110,7 @@ Popen(cmd, mode)
int p[2];
int myside, hisside, fd0, fd1;
int pid;
+ sigset_t nset;
FILE *fp;
if (pipe(p) < 0)
@@ -125,7 +126,8 @@ Popen(cmd, mode)
hisside = fd0 = p[READ];
fd1 = -1;
}
- if ((pid = start_command(cmd, 0, fd0, fd1, NULL, NULL, NULL)) < 0) {
+ (void)sigemptyset(&nset);
+ if ((pid = start_command(cmd, &nset, fd0, fd1, NULL, NULL, NULL)) < 0) {
(void)close(p[READ]);
(void)close(p[WRITE]);
return (NULL);
@@ -141,14 +143,17 @@ Pclose(ptr)
FILE *ptr;
{
int i;
- int omask;
+ sigset_t nset, oset;
i = file_pid(ptr);
unregister_file(ptr);
(void)fclose(ptr);
- omask = sigblock(sigmask(SIGINT)|sigmask(SIGHUP));
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, SIGINT);
+ (void)sigaddset(&nset, SIGHUP);
+ (void)sigprocmask(SIG_BLOCK, &nset, &oset);
i = wait_child(i);
- (void)sigsetmask(omask);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
return (i);
}
@@ -219,7 +224,8 @@ file_pid(fp)
int
run_command(cmd, mask, infd, outfd, a0, a1, a2)
char *cmd;
- int mask, infd, outfd;
+ sigset_t *mask;
+ int infd, outfd;
char *a0, *a1, *a2;
{
int pid;
@@ -233,7 +239,8 @@ run_command(cmd, mask, infd, outfd, a0, a1, a2)
int
start_command(cmd, mask, infd, outfd, a0, a1, a2)
char *cmd;
- int mask, infd, outfd;
+ sigset_t *mask;
+ int infd, outfd;
char *a0, *a1, *a2;
{
int pid;
@@ -259,10 +266,12 @@ start_command(cmd, mask, infd, outfd, a0, a1, a2)
}
void
-prepare_child(mask, infd, outfd)
- int mask, infd, outfd;
+prepare_child(nset, infd, outfd)
+ sigset_t *nset;
+ int infd, outfd;
{
int i;
+ sigset_t eset;
/*
* All file descriptors other than 0, 1, and 2 are supposed to be
@@ -272,12 +281,13 @@ prepare_child(mask, infd, outfd)
dup2(infd, 0);
if (outfd >= 0)
dup2(outfd, 1);
- for (i = 1; i <= NSIG; i++)
- if (mask & sigmask(i))
+ for (i = 1; i < NSIG; i++)
+ if (nset != NULL && sigismember(nset, i))
(void)signal(i, SIG_IGN);
- if ((mask & sigmask(SIGINT)) == 0)
+ if (nset == NULL || !sigismember(nset, SIGINT))
(void)signal(SIGINT, SIG_DFL);
- (void)sigsetmask(0);
+ (void)sigemptyset(&eset);
+ (void)sigprocmask(SIG_SETMASK, &eset, NULL);
}
int
@@ -353,14 +363,18 @@ int
wait_child(pid)
int pid;
{
- int mask = sigblock(sigmask(SIGCHLD));
+ sigset_t nset, oset;
struct child *cp = findchild(pid);
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, SIGCHLD);
+ (void)sigprocmask(SIG_BLOCK, &nset, &oset);
+
while (!cp->done)
- sigpause(mask);
+ (void)sigsuspend(&oset);
wait_status = cp->status;
delchild(cp);
- (void)sigsetmask(mask);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
return ((WIFEXITED(wait_status) && WEXITSTATUS(wait_status)) ? -1 : 0);
}
@@ -371,12 +385,16 @@ void
free_child(pid)
int pid;
{
- int mask = sigblock(sigmask(SIGCHLD));
+ sigset_t nset, oset;
struct child *cp = findchild(pid);
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, SIGCHLD);
+ (void)sigprocmask(SIG_BLOCK, &nset, &oset);
+
if (cp->done)
delchild(cp);
else
cp->free = 1;
- (void)sigsetmask(mask);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
}
diff --git a/usr.bin/mail/quit.c b/usr.bin/mail/quit.c
index 7831bb3..ea92dab 100644
--- a/usr.bin/mail/quit.c
+++ b/usr.bin/mail/quit.c
@@ -33,7 +33,7 @@
#ifndef lint
#if 0
-static char sccsid[] = "@(#)quit.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)quit.c 8.2 (Berkeley) 4/28/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
@@ -274,8 +274,8 @@ quit()
c = getc(ibuf);
}
(void)Fclose(ibuf);
- (void)fflush(obuf);
}
+ (void)fflush(obuf);
trunc(obuf);
if (ferror(obuf)) {
warn("%s", mbox);
diff --git a/usr.bin/mail/send.c b/usr.bin/mail/send.c
index 42dd65e..58f029a 100644
--- a/usr.bin/mail/send.c
+++ b/usr.bin/mail/send.c
@@ -315,9 +315,12 @@ mail1(hp, printheaders)
if ((mtf = collect(hp, printheaders)) == NULL)
return;
if (value("interactive") != NULL) {
- if (value("askcc") != NULL)
- grabh(hp, GCC);
- else {
+ if (value("askcc") != NULL || value("askbcc") != NULL) {
+ if (value("askcc") != NULL)
+ grabh(hp, GCC);
+ if (value("askbcc") != NULL)
+ grabh(hp, GBCC);
+ } else {
printf("EOT\n");
(void)fflush(stdout);
}
@@ -380,9 +383,15 @@ mail1(hp, printheaders)
goto out;
}
if (pid == 0) {
- prepare_child(sigmask(SIGHUP)|sigmask(SIGINT)|sigmask(SIGQUIT)|
- sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU),
- fileno(mtf), -1);
+ sigset_t nset;
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, SIGHUP);
+ (void)sigaddset(&nset, SIGINT);
+ (void)sigaddset(&nset, SIGQUIT);
+ (void)sigaddset(&nset, SIGTSTP);
+ (void)sigaddset(&nset, SIGTTIN);
+ (void)sigaddset(&nset, SIGTTOU);
+ prepare_child(&nset, fileno(mtf), -1);
if ((cp = value("sendmail")) != NULL)
cp = expand(cp);
else
@@ -414,6 +423,9 @@ fixhead(hp, tolist)
hp->h_cc = NULL;
hp->h_bcc = NULL;
for (np = tolist; np != NULL; np = np->n_flink)
+ /* Don't copy deleted addresses to the header */
+ if (np->n_type & GDEL)
+ continue;
if ((np->n_type & GMASK) == GTO)
hp->h_to =
cat(hp->h_to, nalloc(np->n_name, np->n_type));
diff --git a/usr.bin/mail/tty.c b/usr.bin/mail/tty.c
index 687ce59..c1e19d7 100644
--- a/usr.bin/mail/tty.c
+++ b/usr.bin/mail/tty.c
@@ -33,7 +33,7 @@
#ifndef lint
#if 0
-static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)tty.c 8.2 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$FreeBSD$";
@@ -48,8 +48,8 @@ static const char rcsid[] =
#include "rcv.h"
#include "extern.h"
-static int c_erase; /* Current erase char */
-static int 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
@@ -65,15 +65,19 @@ grabh(hp, gflags)
struct header *hp;
int gflags;
{
- struct termios tio;
+ struct termios ttybuf;
sig_t saveint;
-#ifndef TIOCSTI
- sig_t savequit;
-#endif
sig_t savetstp;
sig_t savettou;
sig_t savettin;
int errs;
+#ifndef TIOCSTI
+ sig_t savequit;
+#else
+# ifdef TIOCEXT
+ int extproc, flag;
+# endif /* TIOCEXT */
+#endif /* TIOCSTI */
savetstp = signal(SIGTSTP, SIG_DFL);
savettou = signal(SIGTTOU, SIG_DFL);
@@ -82,20 +86,28 @@ grabh(hp, gflags)
#ifndef TIOCSTI
ttyset = 0;
#endif
- if (tcgetattr(fileno(stdin), &tio) < 0) {
+ if (tcgetattr(fileno(stdin), &ttybuf) < 0) {
warn("tcgetattr(stdin)");
return (-1);
}
- c_erase = tio.c_cc[VERASE];
- c_kill = tio.c_cc[VKILL];
+ c_erase = ttybuf.c_cc[VERASE];
+ c_kill = ttybuf.c_cc[VKILL];
#ifndef TIOCSTI
- tio.c_cc[VERASE] = 0;
- tio.c_cc[VKILL] = 0;
+ ttybuf.c_cc[VERASE] = _POSIX_VDISABLE;
+ ttybuf.c_cc[VKILL] = _POSIX_VDISABLE;
if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL)
(void)signal(SIGINT, SIG_DFL);
if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL)
(void)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 */
if (setjmp(intjmp))
goto out;
saveint = signal(SIGINT, ttyint);
@@ -103,7 +115,7 @@ grabh(hp, gflags)
if (gflags & GTO) {
#ifndef TIOCSTI
if (!ttyset && hp->h_to != NULL)
- ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &tio);
+ ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
#endif
hp->h_to =
extract(readtty("To: ", detract(hp->h_to, 0)), GTO);
@@ -111,14 +123,14 @@ grabh(hp, gflags)
if (gflags & GSUBJECT) {
#ifndef TIOCSTI
if (!ttyset && hp->h_subject != NULL)
- ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &tio);
+ ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
#endif
hp->h_subject = readtty("Subject: ", hp->h_subject);
}
if (gflags & GCC) {
#ifndef TIOCSTI
if (!ttyset && hp->h_cc != NULL)
- ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &tio);
+ ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
#endif
hp->h_cc =
extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC);
@@ -126,7 +138,7 @@ grabh(hp, gflags)
if (gflags & GBCC) {
#ifndef TIOCSTI
if (!ttyset && hp->h_bcc != NULL)
- ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &tio);
+ ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
#endif
hp->h_bcc =
extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC);
@@ -136,11 +148,19 @@ out:
(void)signal(SIGTTOU, savettou);
(void)signal(SIGTTIN, savettin);
#ifndef TIOCSTI
- tio.c_cc[VERASE] = c_erase;
- tio.c_cc[VKILL] = c_kill;
+ ttybuf.c_cc[VERASE] = c_erase;
+ ttybuf.c_cc[VKILL] = c_kill;
if (ttyset)
- tcsetattr(fileno(stdin), TCSADRAIN, &tio);
+ tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
(void)signal(SIGQUIT, savequit);
+#else
+# ifdef TIOCEXT
+ if (extproc) {
+ flag = 1;
+ if (ioctl(fileno(stdin), TIOCEXT, &flag) < 0)
+ warn("TIOCEXT: on");
+ }
+# endif /* TIOCEXT */
#endif
(void)signal(SIGINT, saveint);
return (errs);
@@ -178,7 +198,8 @@ readtty(pr, src)
#else
cp = src == NULL ? "" : src;
while ((c = *cp++) != '\0') {
- if (c == c_erase || c == c_kill) {
+ if ((c_erase != _POSIX_VDISABLE && c == c_erase) ||
+ (c_kill != _POSIX_VDISABLE && c == c_kill)) {
ch = '\\';
ioctl(0, TIOCSTI, &ch);
}
@@ -222,7 +243,7 @@ redo:
return (strlen(canonb) > 0 ? savestr(canonb) : NULL);
while (*cp != '\0') {
c = *cp++;
- if (c == c_erase) {
+ if (c_erase != _POSIX_VDISABLE && c == c_erase) {
if (cp2 == canonb)
continue;
if (cp2[-1] == '\\') {
@@ -232,7 +253,7 @@ redo:
cp2--;
continue;
}
- if (c == c_kill) {
+ if (c_kill != _POSIX_VDISABLE && c == c_kill) {
if (cp2 == canonb)
continue;
if (cp2[-1] == '\\') {
@@ -259,10 +280,13 @@ ttystop(s)
int s;
{
sig_t old_action = signal(s, SIG_DFL);
+ sigset_t nset;
- (void)sigsetmask(sigblock(0) & ~sigmask(s));
- (void)kill(0, s);
- (void)sigblock(sigmask(s));
+ (void)sigemptyset(&nset);
+ (void)sigaddset(&nset, s);
+ (void)sigprocmask(SIG_BLOCK, &nset, NULL);
+ kill(0, s);
+ (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
(void)signal(s, old_action);
longjmp(rewrite, 1);
}
OpenPOWER on IntegriCloud