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
This commit is contained in:
parent
fdb33f08ef
commit
856f23ed35
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=88150
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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 @@ collect(hp, printheaders)
|
||||
}
|
||||
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 @@ collect(hp, printheaders)
|
||||
* 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 @@ collect(hp, printheaders)
|
||||
(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 @@ collect(hp, printheaders)
|
||||
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;
|
||||
|
@ -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$
|
||||
*/
|
||||
|
@ -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 []));
|
||||
|
@ -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);
|
||||
size_t size;
|
||||
struct message *nmessage;
|
||||
|
||||
if (message != 0)
|
||||
(void)free(message);
|
||||
if ((message = malloc((unsigned)size)) == NULL)
|
||||
err(1, "Out of memory");
|
||||
dot = message;
|
||||
size -= sizeof(struct message);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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$";
|
||||
|
@ -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 @@ setfile(name)
|
||||
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 @@ execute(linebuf, contxt)
|
||||
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)
|
||||
|
@ -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$";
|
||||
@ -686,6 +686,49 @@ matchsender(str, mesg)
|
||||
return (*cp == '\0');
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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 @@ grabh(hp, gflags)
|
||||
(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 @@ readtty(pr, src)
|
||||
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 @@ readtty(pr, src)
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user