From Anon Ymous:
- Remove all longjmp(3) calls from signal handlers. Instead, we post to an internal signal queue and check that periodically. All signal related code is now in sig.c, except for the SIGCHLD handler which remains in popen.c as it is intimately tied to routines there. - Handle SIGPIPE in type1() regardless of mime support, or else the handler in execute() will prevent our error code from being returned resulting in 'sawcom' not being set on the first command as it should. This only affected the initial behavior of the "next" command without mime support. - Add the 'T' flag to many commands in cmdtab.c that should not look like the first command. E.g., start mail on a mailbox with multiple messages, run "set foo", then "next", and watch the second message get displayed rather than the first as is the case without the first "set" command. - Add file descriptor and file handle leak detection. Enabled by DEBUG_FILE_LEAK. This will likely disappear in the future. - Fix a long standing (since import in 1993) longjmp() bug in edstop(): the jmpbuf was invalid when quit() is called at the end of main. - Fix a long standing bug (since import in 1993) in snarf() where it didn't strip whitespace correctly if the line consisted only of whitespace. - Lint cleanup. - New Feature: "Header" command. This allows miscellaneous header fields to be added to the header, e.g., "X-Organization:" or "Reply-To:" fields. - New Feature: "page-also" variable. This allows the specification of additional commands to page. It is more flexible than "crt". - Document the "pager-off" variable: if set, it disables paging entirely.
This commit is contained in:
parent
889c434e54
commit
ca13337dfe
|
@ -1,20 +1,30 @@
|
|||
# $NetBSD: Makefile,v 1.30 2007/05/28 12:06:28 tls Exp $
|
||||
# $NetBSD: Makefile,v 1.31 2009/04/10 13:08:24 christos Exp $
|
||||
# @(#)Makefile 8.3 (Berkeley) 4/20/95
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
USE_FORT?= yes # data-driven bugs?
|
||||
|
||||
USE_EDITLINE=yes
|
||||
MIME_SUPPORT=yes # currently requires USE_EDITLINE
|
||||
CHARSET_SUPPORT=yes # requires MIME_SUPPORT
|
||||
THREAD_SUPPORT=yes # EXPERIMENTAL
|
||||
USE_EDITLINE?=yes
|
||||
MIME_SUPPORT?=yes # currently requires USE_EDITLINE
|
||||
CHARSET_SUPPORT?=yes # requires MIME_SUPPORT
|
||||
THREAD_SUPPORT?=yes # EXPERIMENTAL
|
||||
|
||||
# Work around some problems in -current.
|
||||
# See the source code for more info.
|
||||
#
|
||||
CPPFLAGS+= -DBROKEN_EXEC_TTY_RESTORE # broken since 4.99.10
|
||||
CPPFLAGS+= -DBROKEN_CLONE_STAT # see PRs 37878 and 37550
|
||||
|
||||
# Debugging options (most should go away - please leave for now).
|
||||
#
|
||||
#CPPFLAGS+= -DDEBUG_FILE_LEAK
|
||||
|
||||
PROG= mail
|
||||
SRCS= version.c support.c cmd1.c cmd2.c cmd3.c cmd4.c cmdtab.c collect.c \
|
||||
dotlock.c edit.c fio.c format.c getname.c head.c v7.local.c lex.c \
|
||||
list.c main.c names.c popen.c quit.c send.c strings.c temp.c tty.c \
|
||||
vars.c
|
||||
list.c main.c names.c popen.c quit.c send.c sig.c strings.c temp.c \
|
||||
tty.c vars.c
|
||||
LINKS= ${BINDIR}/mail ${BINDIR}/Mail ${BINDIR}/mail ${BINDIR}/mailx
|
||||
MLINKS= mail.1 Mail.1 mail.1 mailx.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cmd1.c,v 1.29 2007/10/29 23:20:37 christos Exp $ */
|
||||
/* $NetBSD: cmd1.c,v 1.30 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)cmd1.c 8.2 (Berkeley) 4/20/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: cmd1.c,v 1.29 2007/10/29 23:20:37 christos Exp $");
|
||||
__RCSID("$NetBSD: cmd1.c,v 1.30 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -46,6 +46,7 @@ __RCSID("$NetBSD: cmd1.c,v 1.29 2007/10/29 23:20:37 christos Exp $");
|
|||
#ifdef MIME_SUPPORT
|
||||
#include "mime.h"
|
||||
#endif
|
||||
#include "sig.h"
|
||||
#include "thread.h"
|
||||
|
||||
|
||||
|
@ -88,6 +89,7 @@ printhead(int mesg)
|
|||
if (screenwidth > 0)
|
||||
msgline[screenwidth] = '\0';
|
||||
(void)printf("%s\n", msgline);
|
||||
sig_check();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -97,11 +99,13 @@ printhead(int mesg)
|
|||
PUBLIC int
|
||||
headers(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int n, flag;
|
||||
int *msgvec;
|
||||
int n;
|
||||
int flag;
|
||||
struct message *mp;
|
||||
int size;
|
||||
|
||||
msgvec = v;
|
||||
size = screensize();
|
||||
n = msgvec[0];
|
||||
if (n != 0)
|
||||
|
@ -140,10 +144,12 @@ headers(void *v)
|
|||
PUBLIC int
|
||||
scroll(void *v)
|
||||
{
|
||||
char *arg = v;
|
||||
int s, size;
|
||||
char *arg;
|
||||
int s;
|
||||
int size;
|
||||
int cur[1];
|
||||
|
||||
arg = v;
|
||||
cur[0] = 0;
|
||||
size = screensize();
|
||||
s = screen;
|
||||
|
@ -180,9 +186,10 @@ scroll(void *v)
|
|||
PUBLIC int
|
||||
from(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
int *ip;
|
||||
|
||||
msgvec = v;
|
||||
for (ip = msgvec; *ip != 0; ip++)
|
||||
printhead(*ip);
|
||||
if (--ip >= msgvec)
|
||||
|
@ -214,10 +221,11 @@ PUBLIC int
|
|||
pcmdlist(void *v __unused)
|
||||
{
|
||||
const struct cmd *cp;
|
||||
int cc;
|
||||
size_t cc;
|
||||
|
||||
(void)printf("Commands are:\n");
|
||||
for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) {
|
||||
cc = 0;
|
||||
for (cp = cmdtab; cp->c_name != NULL; cp++) {
|
||||
cc += strlen(cp->c_name) + 2;
|
||||
if (cc > 72) {
|
||||
(void)printf("\n");
|
||||
|
@ -227,6 +235,7 @@ pcmdlist(void *v __unused)
|
|||
(void)printf("%s, ", cp->c_name);
|
||||
else
|
||||
(void)printf("%s\n", cp->c_name);
|
||||
sig_check();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -236,6 +245,7 @@ PUBLIC char *
|
|||
sget_msgnum(struct message *mp, struct message *parent)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (parent == NULL || parent == mp) {
|
||||
(void)sasprintf(&p, "%d", mp->m_index);
|
||||
return p;
|
||||
|
@ -249,6 +259,7 @@ sget_msgnum(struct message *mp, struct message *parent)
|
|||
PUBLIC void
|
||||
show_msgnum(FILE *obuf, struct message *mp, struct message *parent)
|
||||
{
|
||||
|
||||
if (value(ENAME_QUIET) == NULL)
|
||||
(void)fprintf(obuf, "Message %s:\n", sget_msgnum(mp, parent));
|
||||
}
|
||||
|
@ -278,6 +289,7 @@ type1_core(struct message *mp, void *v)
|
|||
#else
|
||||
(void)sendmessage(mp, args->obuf, args->igtab, NULL, NULL);
|
||||
#endif
|
||||
sig_check();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -289,8 +301,9 @@ static jmp_buf pipestop;
|
|||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
brokpipe(int signo __unused)
|
||||
cmd1_brokpipe(int signo __unused)
|
||||
{
|
||||
|
||||
longjmp(pipestop, 1);
|
||||
}
|
||||
|
||||
|
@ -311,25 +324,27 @@ type1(int *msgvec, int doign, int mime_decode)
|
|||
* starting values. Note it is the variable that is volatile,
|
||||
* not what it is pointing at!
|
||||
*/
|
||||
FILE *volatile obuf; /* avoid longjmp clobbering? */
|
||||
FILE *volatile obuf; /* avoid longjmp clobbering */
|
||||
sig_t volatile oldsigpipe; /* avoid longjmp clobbering? */
|
||||
#ifdef MIME_SUPPORT
|
||||
sig_t volatile oldsigpipe; /* XXX - is volatile needed? */
|
||||
struct mime_info *volatile mip; /* avoid longjmp clobbering - needed */
|
||||
struct mime_info *volatile mip; /* avoid longjmp clobbering? */
|
||||
|
||||
mip = NULL;
|
||||
#endif
|
||||
|
||||
if ((obuf = last_registered_file(0)) == NULL)
|
||||
obuf = stdout;
|
||||
|
||||
#ifdef MIME_SUPPORT
|
||||
mip = NULL;
|
||||
|
||||
oldsigpipe = signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
/*
|
||||
* Even without MIME_SUPPORT, we need to handle SIGPIPE here
|
||||
* or else the handler in execute() will grab things and our
|
||||
* exit code will never be seen.
|
||||
*/
|
||||
sig_check();
|
||||
oldsigpipe = sig_signal(SIGPIPE, cmd1_brokpipe);
|
||||
if (setjmp(pipestop))
|
||||
goto close_pipe;
|
||||
|
||||
(void)signal(SIGPIPE, brokpipe);
|
||||
#endif
|
||||
msgCount = get_msgCount();
|
||||
|
||||
recursive = do_recursion();
|
||||
|
@ -349,17 +364,22 @@ type1(int *msgvec, int doign, int mime_decode)
|
|||
#endif
|
||||
(void)thread_recursion(mp, type1_core, &args);
|
||||
}
|
||||
#ifdef MIME_SUPPORT
|
||||
close_pipe:
|
||||
#ifdef MIME_SUPPORT
|
||||
if (mip != NULL) {
|
||||
struct sigaction osa;
|
||||
sigset_t oset;
|
||||
|
||||
/*
|
||||
* Ignore SIGPIPE so it can't cause a duplicate close.
|
||||
*/
|
||||
(void)signal(SIGPIPE, SIG_IGN);
|
||||
(void)sig_ignore(SIGPIPE, &osa, &oset);
|
||||
mime_decode_close(mip);
|
||||
(void)signal(SIGPIPE, oldsigpipe);
|
||||
(void)sig_restore(SIGPIPE, &osa, &oset);
|
||||
}
|
||||
#endif
|
||||
(void)sig_signal(SIGPIPE, oldsigpipe);
|
||||
sig_check();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -367,6 +387,7 @@ close_pipe:
|
|||
static int
|
||||
de_mime(void)
|
||||
{
|
||||
|
||||
return value(ENAME_MIME_DECODE_MSG) != NULL;
|
||||
}
|
||||
|
||||
|
@ -376,7 +397,9 @@ de_mime(void)
|
|||
PUBLIC int
|
||||
view(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
|
||||
msgvec = v;
|
||||
return type1(msgvec, 1, !de_mime());
|
||||
}
|
||||
|
||||
|
@ -386,8 +409,9 @@ view(void *v)
|
|||
PUBLIC int
|
||||
View(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
|
||||
msgvec = v;
|
||||
return type1(msgvec, 0, !de_mime());
|
||||
}
|
||||
#endif /* MIME_SUPPORT */
|
||||
|
@ -398,8 +422,9 @@ View(void *v)
|
|||
PUBLIC int
|
||||
type(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
|
||||
msgvec = v;
|
||||
return type1(msgvec, 1, de_mime());
|
||||
}
|
||||
|
||||
|
@ -409,8 +434,9 @@ type(void *v)
|
|||
PUBLIC int
|
||||
Type(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
|
||||
msgvec = v;
|
||||
return type1(msgvec, 0, de_mime());
|
||||
}
|
||||
|
||||
|
@ -420,9 +446,11 @@ Type(void *v)
|
|||
PUBLIC int
|
||||
pipecmd(void *v)
|
||||
{
|
||||
char *cmd = v;
|
||||
FILE *volatile obuf; /* void longjmp clobbering - we want
|
||||
the current value not start value */
|
||||
char *cmd;
|
||||
FILE *volatile obuf; /* void longjmp clobbering */
|
||||
sig_t volatile oldsigpipe; /* XXX - is volatile needed? */
|
||||
|
||||
cmd = v;
|
||||
if (dot == NULL) {
|
||||
warn("pipcmd: no current message");
|
||||
return 1;
|
||||
|
@ -432,30 +460,36 @@ pipecmd(void *v)
|
|||
if (setjmp(pipestop))
|
||||
goto close_pipe;
|
||||
|
||||
sig_check();
|
||||
obuf = Popen(cmd, "w");
|
||||
if (obuf == NULL) {
|
||||
warn("pipecmd: Popen failed: %s", cmd);
|
||||
return 1;
|
||||
} else
|
||||
(void)signal(SIGPIPE, brokpipe);
|
||||
}
|
||||
|
||||
oldsigpipe = sig_signal(SIGPIPE, cmd1_brokpipe);
|
||||
|
||||
(void)sendmessage(dot, obuf, ignoreall, NULL, NULL);
|
||||
close_pipe:
|
||||
sig_check();
|
||||
if (obuf != stdout) {
|
||||
struct sigaction osa;
|
||||
sigset_t oset;
|
||||
/*
|
||||
* Ignore SIGPIPE so it can't cause a duplicate close.
|
||||
*/
|
||||
(void)signal(SIGPIPE, SIG_IGN);
|
||||
(void)sig_ignore(SIGPIPE, &osa, &oset);
|
||||
(void)Pclose(obuf);
|
||||
(void)signal(SIGPIPE, SIG_DFL);
|
||||
(void)sig_restore(SIGPIPE, &osa, &oset);
|
||||
}
|
||||
(void)sig_signal(SIGPIPE, oldsigpipe);
|
||||
sig_check();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct top_core_args_s {
|
||||
int lineb;
|
||||
int topl;
|
||||
size_t topl;
|
||||
struct message *parent;
|
||||
};
|
||||
static int
|
||||
|
@ -464,8 +498,8 @@ top_core(struct message *mp, void *v)
|
|||
char buffer[LINESIZE];
|
||||
struct top_core_args_s *args;
|
||||
FILE *ibuf;
|
||||
int lines;
|
||||
int c;
|
||||
size_t lines;
|
||||
size_t c;
|
||||
|
||||
args = v;
|
||||
touch(mp);
|
||||
|
@ -475,11 +509,13 @@ top_core(struct message *mp, void *v)
|
|||
ibuf = setinput(mp);
|
||||
c = mp->m_lines;
|
||||
for (lines = 0; lines < c && lines <= args->topl; lines++) {
|
||||
if (mail_readline(ibuf, buffer, sizeof(buffer)) < 0)
|
||||
sig_check();
|
||||
if (readline(ibuf, buffer, (int)sizeof(buffer), 0) < 0)
|
||||
break;
|
||||
(void)puts(buffer);
|
||||
args->lineb = blankline(buffer);
|
||||
}
|
||||
sig_check();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -494,11 +530,12 @@ top(void *v)
|
|||
struct top_core_args_s args;
|
||||
int recursive;
|
||||
int msgCount;
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
int *ip;
|
||||
int topl;
|
||||
char *valtop;
|
||||
|
||||
msgvec = v;
|
||||
topl = 5;
|
||||
valtop = value(ENAME_TOPLINES);
|
||||
if (valtop != NULL) {
|
||||
|
@ -528,12 +565,14 @@ top(void *v)
|
|||
PUBLIC int
|
||||
stouch(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
int *ip;
|
||||
|
||||
for (ip = msgvec; *ip != 0; ip++)
|
||||
msgvec = v;
|
||||
for (ip = msgvec; *ip != 0; ip++) {
|
||||
sig_check();
|
||||
dot = set_m_flag(*ip, ~(MPRESERVE | MTOUCH), MTOUCH);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -543,13 +582,15 @@ stouch(void *v)
|
|||
PUBLIC int
|
||||
mboxit(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
int *ip;
|
||||
|
||||
for (ip = msgvec; *ip != 0; ip++)
|
||||
msgvec = v;
|
||||
for (ip = msgvec; *ip != 0; ip++) {
|
||||
sig_check();
|
||||
dot = set_m_flag(*ip,
|
||||
~(MPRESERVE | MTOUCH | MBOX), MTOUCH | MBOX);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -569,7 +610,7 @@ folders(void *v __unused)
|
|||
}
|
||||
if ((cmd = value(ENAME_LISTER)) == NULL)
|
||||
cmd = "ls";
|
||||
(void)run_command(cmd, 0, -1, -1, dirname, NULL);
|
||||
(void)run_command(cmd, NULL, -1, -1, dirname, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -581,7 +622,8 @@ folders(void *v __unused)
|
|||
PUBLIC int
|
||||
inc(void *v __unused)
|
||||
{
|
||||
int nmsg, mdot;
|
||||
int nmsg;
|
||||
int mdot;
|
||||
|
||||
nmsg = incfile();
|
||||
|
||||
|
@ -595,6 +637,5 @@ inc(void *v __unused)
|
|||
} else {
|
||||
(void)printf("\"inc\" command failed...\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cmd2.c,v 1.23 2007/10/27 15:14:50 christos Exp $ */
|
||||
/* $NetBSD: cmd2.c,v 1.24 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)cmd2.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: cmd2.c,v 1.23 2007/10/27 15:14:50 christos Exp $");
|
||||
__RCSID("$NetBSD: cmd2.c,v 1.24 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -60,11 +60,12 @@ __RCSID("$NetBSD: cmd2.c,v 1.23 2007/10/27 15:14:50 christos Exp $");
|
|||
PUBLIC int
|
||||
next(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
struct message *mp;
|
||||
int *ip, *ip2;
|
||||
int list[2], mdot;
|
||||
|
||||
msgvec = v;
|
||||
if (*msgvec != 0) {
|
||||
|
||||
/*
|
||||
|
@ -151,15 +152,13 @@ snarf(char linebuf[], int *flag, const char *string)
|
|||
/*
|
||||
* Strip away trailing blanks.
|
||||
*/
|
||||
|
||||
while (cp > linebuf && isspace((unsigned char)*cp))
|
||||
while (cp >= linebuf && isspace((unsigned char)*cp))
|
||||
cp--;
|
||||
*++cp = 0;
|
||||
*++cp = '\0';
|
||||
|
||||
/*
|
||||
* Now search for the beginning of the file name.
|
||||
*/
|
||||
|
||||
while (cp > linebuf && !isspace((unsigned char)*cp))
|
||||
cp--;
|
||||
if (*cp == '\0') {
|
||||
|
@ -167,7 +166,7 @@ snarf(char linebuf[], int *flag, const char *string)
|
|||
return NULL;
|
||||
}
|
||||
if (isspace((unsigned char)*cp))
|
||||
*cp++ = 0;
|
||||
*cp++ = '\0';
|
||||
else
|
||||
*flag = 0;
|
||||
return cp;
|
||||
|
@ -182,8 +181,8 @@ static int
|
|||
save1_core(struct message *mp, void *v)
|
||||
{
|
||||
struct save1_core_args_s *args;
|
||||
args = v;
|
||||
|
||||
args = v;
|
||||
touch(mp);
|
||||
|
||||
if (sendmessage(mp, args->obuf, args->igtab, NULL, NULL) < 0)
|
||||
|
@ -264,8 +263,9 @@ save1(char str[], int markmsg, const char *cmd, struct ignoretab *igtab)
|
|||
PUBLIC int
|
||||
save(void *v)
|
||||
{
|
||||
char *str = v;
|
||||
char *str;
|
||||
|
||||
str = v;
|
||||
return save1(str, 1, "save", saveignore);
|
||||
}
|
||||
|
||||
|
@ -277,8 +277,9 @@ save(void *v)
|
|||
PUBLIC int
|
||||
Save(void *v)
|
||||
{
|
||||
char *str = v;
|
||||
char *str;
|
||||
|
||||
str = v;
|
||||
return save1(str, 1, "Save", NULL);
|
||||
}
|
||||
|
||||
|
@ -288,8 +289,9 @@ Save(void *v)
|
|||
PUBLIC int
|
||||
copycmd(void *v)
|
||||
{
|
||||
char *str = v;
|
||||
char *str;
|
||||
|
||||
str = v;
|
||||
return save1(str, 0, "copy", saveignore);
|
||||
}
|
||||
|
||||
|
@ -300,8 +302,9 @@ copycmd(void *v)
|
|||
PUBLIC int
|
||||
swrite(void *v)
|
||||
{
|
||||
char *str = v;
|
||||
char *str;
|
||||
|
||||
str = v;
|
||||
return save1(str, 1, "write", ignoreall);
|
||||
}
|
||||
|
||||
|
@ -349,7 +352,9 @@ delm(int *msgvec)
|
|||
PUBLIC int
|
||||
delete(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
|
||||
msgvec = v;
|
||||
(void)delm(msgvec);
|
||||
return 0;
|
||||
}
|
||||
|
@ -360,10 +365,11 @@ delete(void *v)
|
|||
PUBLIC int
|
||||
deltype(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
int list[2];
|
||||
int lastdot;
|
||||
|
||||
msgvec = v;
|
||||
lastdot = get_msgnum(dot);
|
||||
if (delm(msgvec) >= 0) {
|
||||
list[0] = get_msgnum(dot);
|
||||
|
@ -449,9 +455,10 @@ clob1(int n)
|
|||
PUBLIC int
|
||||
clobber(void *v)
|
||||
{
|
||||
char **argv = v;
|
||||
char **argv;
|
||||
int times;
|
||||
|
||||
argv = v;
|
||||
if (argv[0] == 0)
|
||||
times = 1;
|
||||
else
|
||||
|
@ -519,8 +526,9 @@ ignore1(char *list[], struct ignoretab *tab, const char *which)
|
|||
PUBLIC int
|
||||
retfield(void *v)
|
||||
{
|
||||
char **list = v;
|
||||
char **list;
|
||||
|
||||
list = v;
|
||||
return ignore1(list, ignore + 1, "retained");
|
||||
}
|
||||
|
||||
|
@ -531,8 +539,9 @@ retfield(void *v)
|
|||
PUBLIC int
|
||||
igfield(void *v)
|
||||
{
|
||||
char **list = v;
|
||||
char **list;
|
||||
|
||||
list = v;
|
||||
return ignore1(list, ignore, "ignored");
|
||||
}
|
||||
|
||||
|
@ -543,8 +552,9 @@ igfield(void *v)
|
|||
PUBLIC int
|
||||
saveretfield(void *v)
|
||||
{
|
||||
char **list = v;
|
||||
char **list;
|
||||
|
||||
list = v;
|
||||
return ignore1(list, saveignore + 1, "retained");
|
||||
}
|
||||
|
||||
|
@ -555,8 +565,9 @@ saveretfield(void *v)
|
|||
PUBLIC int
|
||||
saveigfield(void *v)
|
||||
{
|
||||
char **list = v;
|
||||
char **list;
|
||||
|
||||
list = v;
|
||||
return ignore1(list, saveignore, "ignored");
|
||||
}
|
||||
|
||||
|
@ -595,7 +606,7 @@ check_dirname(char *filename)
|
|||
if (access(canon_name, W_OK|X_OK) == -1) {
|
||||
warnx("access: %s is not writable", canon_name);
|
||||
canon_name = NULL;
|
||||
/* goto done; */
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
if (fname != filename)
|
||||
|
@ -604,7 +615,6 @@ check_dirname(char *filename)
|
|||
return canon_name ? savestr(canon_name) : NULL;
|
||||
}
|
||||
|
||||
|
||||
struct detach1_core_args_s {
|
||||
struct message *parent;
|
||||
struct ignoretab *igtab;
|
||||
|
@ -683,6 +693,7 @@ detach1(void *v, int do_unnamed)
|
|||
for (ip = msgvec; *ip && ip - msgvec < msgCount; ip++) {
|
||||
struct detach1_core_args_s args;
|
||||
struct message *mp;
|
||||
|
||||
mp = get_message(*ip);
|
||||
dot = mp;
|
||||
args.parent = recursive ? mp : NULL;
|
||||
|
@ -699,6 +710,7 @@ detach1(void *v, int do_unnamed)
|
|||
PUBLIC int
|
||||
detach(void *v)
|
||||
{
|
||||
|
||||
return detach1(v, 0);
|
||||
}
|
||||
|
||||
|
@ -708,6 +720,7 @@ detach(void *v)
|
|||
PUBLIC int
|
||||
Detach(void *v)
|
||||
{
|
||||
|
||||
return detach1(v, 1);
|
||||
}
|
||||
#endif /* MIME_SUPPORT */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cmd3.c,v 1.39 2007/10/30 16:08:11 christos Exp $ */
|
||||
/* $NetBSD: cmd3.c,v 1.40 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: cmd3.c,v 1.39 2007/10/30 16:08:11 christos Exp $");
|
||||
__RCSID("$NetBSD: cmd3.c,v 1.40 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -43,6 +43,7 @@ __RCSID("$NetBSD: cmd3.c,v 1.39 2007/10/30 16:08:11 christos Exp $");
|
|||
#include <util.h>
|
||||
#include "extern.h"
|
||||
#include "mime.h"
|
||||
#include "sig.h"
|
||||
#include "thread.h"
|
||||
|
||||
/*
|
||||
|
@ -59,6 +60,7 @@ __RCSID("$NetBSD: cmd3.c,v 1.39 2007/10/30 16:08:11 christos Exp $");
|
|||
static int
|
||||
diction(const void *a, const void *b)
|
||||
{
|
||||
|
||||
return strcmp(*(const char *const *)a, *(const char *const *)b);
|
||||
}
|
||||
|
||||
|
@ -73,9 +75,9 @@ sort(const char **list)
|
|||
|
||||
for (ap = list; *ap != NULL; ap++)
|
||||
continue;
|
||||
if (ap-list < 2)
|
||||
if (ap - list < 2)
|
||||
return;
|
||||
qsort(list, (size_t)(ap-list), sizeof(*list), diction);
|
||||
qsort(list, (size_t)(ap - list), sizeof(*list), diction);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -88,16 +90,17 @@ bangexp(char *str)
|
|||
static char lastbang[128];
|
||||
char bangbuf[LINESIZE];
|
||||
char *cp, *cp2;
|
||||
int n;
|
||||
int changed = 0;
|
||||
ssize_t n;
|
||||
int changed;
|
||||
|
||||
changed = 0;
|
||||
cp = str;
|
||||
cp2 = bangbuf;
|
||||
n = sizeof(bangbuf); /* bytes left in bangbuf */
|
||||
while (*cp) {
|
||||
if (*cp == '!') {
|
||||
if (n < (int)strlen(lastbang)) {
|
||||
overf:
|
||||
overf:
|
||||
(void)printf("Command buffer overflow\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -136,19 +139,24 @@ overf:
|
|||
PUBLIC int
|
||||
shell(void *v)
|
||||
{
|
||||
char *str = v;
|
||||
sig_t sigint = signal(SIGINT, SIG_IGN);
|
||||
struct sigaction osa;
|
||||
sigset_t oset;
|
||||
char *str;
|
||||
const char *shellcmd;
|
||||
char cmd[LINESIZE];
|
||||
|
||||
str = v;
|
||||
sig_check();
|
||||
(void)sig_ignore(SIGINT, &osa, &oset);
|
||||
(void)strcpy(cmd, str);
|
||||
if (bangexp(cmd) < 0)
|
||||
return 1;
|
||||
if ((shellcmd = value(ENAME_SHELL)) == NULL)
|
||||
shellcmd = _PATH_CSHELL;
|
||||
(void)run_command(shellcmd, 0, 0, 1, "-c", cmd, NULL);
|
||||
(void)signal(SIGINT, sigint);
|
||||
(void)run_command(shellcmd, NULL, 0, 1, "-c", cmd, NULL);
|
||||
(void)sig_restore(SIGINT, &osa, &oset);
|
||||
(void)printf("!\n");
|
||||
sig_check();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -159,14 +167,18 @@ shell(void *v)
|
|||
PUBLIC int
|
||||
dosh(void *v __unused)
|
||||
{
|
||||
sig_t sigint = signal(SIGINT, SIG_IGN);
|
||||
struct sigaction osa;
|
||||
sigset_t oset;
|
||||
const char *shellcmd;
|
||||
|
||||
sig_check();
|
||||
(void)sig_ignore(SIGINT, &osa, &oset);
|
||||
if ((shellcmd = value(ENAME_SHELL)) == NULL)
|
||||
shellcmd = _PATH_CSHELL;
|
||||
(void)run_command(shellcmd, 0, 0, 1, NULL);
|
||||
(void)signal(SIGINT, sigint);
|
||||
(void)run_command(shellcmd, NULL, 0, 1, NULL);
|
||||
(void)sig_restore(SIGINT, &osa, &oset);
|
||||
(void)putchar('\n');
|
||||
sig_check();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -178,6 +190,7 @@ dosh(void *v __unused)
|
|||
PUBLIC int
|
||||
help(void *v __unused)
|
||||
{
|
||||
|
||||
cathelp(_PATH_HELP);
|
||||
return 0;
|
||||
}
|
||||
|
@ -188,9 +201,10 @@ help(void *v __unused)
|
|||
PUBLIC int
|
||||
schdir(void *v)
|
||||
{
|
||||
char **arglist = v;
|
||||
char **arglist;
|
||||
const char *cp;
|
||||
|
||||
arglist = v;
|
||||
if (*arglist == NULL)
|
||||
cp = homedir;
|
||||
else
|
||||
|
@ -210,9 +224,11 @@ static struct name *
|
|||
set_smopts(struct message *mp)
|
||||
{
|
||||
char *cp;
|
||||
struct name *np = NULL;
|
||||
char *reply_as_recipient = value(ENAME_REPLYASRECIPIENT);
|
||||
struct name *np;
|
||||
char *reply_as_recipient;
|
||||
|
||||
np = NULL;
|
||||
reply_as_recipient = value(ENAME_REPLYASRECIPIENT);
|
||||
if (reply_as_recipient &&
|
||||
(cp = skin(hfield("to", mp))) != NULL &&
|
||||
extract(cp, GTO)->n_flink == NULL) { /* check for one recipient */
|
||||
|
@ -540,12 +556,13 @@ bounce_one(int msgno, const char **smargs, struct name *h_to)
|
|||
PUBLIC int
|
||||
bounce(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
int *ip;
|
||||
const char **smargs;
|
||||
struct header hdr;
|
||||
int rval;
|
||||
|
||||
msgvec = v;
|
||||
if (bouncetab[0].i_count == 0) {
|
||||
/* setup the bounce tab */
|
||||
add_ignore("Status", bouncetab);
|
||||
|
@ -576,9 +593,10 @@ bounce(void *v)
|
|||
PUBLIC int
|
||||
preserve(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
int *ip;
|
||||
|
||||
msgvec = v;
|
||||
if (edit) {
|
||||
(void)printf("Cannot \"preserve\" in edit mode\n");
|
||||
return 1;
|
||||
|
@ -595,9 +613,10 @@ preserve(void *v)
|
|||
PUBLIC int
|
||||
unread(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
int *ip;
|
||||
|
||||
msgvec = v;
|
||||
for (ip = msgvec; *ip != 0; ip++)
|
||||
dot = set_m_flag(*ip, ~(MREAD | MTOUCH | MSTATUS), MSTATUS);
|
||||
|
||||
|
@ -610,9 +629,10 @@ unread(void *v)
|
|||
PUBLIC int
|
||||
markread(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
int *ip;
|
||||
|
||||
msgvec = v;
|
||||
for (ip = msgvec; *ip != 0; ip++)
|
||||
dot = set_m_flag(*ip,
|
||||
~(MNEW | MTOUCH | MREAD | MSTATUS), MREAD | MSTATUS);
|
||||
|
@ -626,10 +646,11 @@ markread(void *v)
|
|||
PUBLIC int
|
||||
messize(void *v)
|
||||
{
|
||||
int *msgvec = v;
|
||||
int *msgvec;
|
||||
struct message *mp;
|
||||
int *ip, mesg;
|
||||
|
||||
msgvec = v;
|
||||
for (ip = msgvec; *ip != 0; ip++) {
|
||||
mesg = *ip;
|
||||
mp = get_message(mesg);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cmd4.c,v 1.4 2008/04/28 20:24:14 martin Exp $ */
|
||||
/* $NetBSD: cmd4.c,v 1.5 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -35,7 +35,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: cmd4.c,v 1.4 2008/04/28 20:24:14 martin Exp $");
|
||||
__RCSID("$NetBSD: cmd4.c,v 1.5 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -55,6 +55,7 @@ void showname(struct name *);
|
|||
void
|
||||
showname(struct name *np)
|
||||
{
|
||||
|
||||
for (/*EMPTY*/; np; np = np->n_flink)
|
||||
(void)printf("np: %p np->n_type: %d np->n_name: '%s' (%p)\n",
|
||||
np, np->n_type, np->n_name, np->n_name);
|
||||
|
@ -64,6 +65,7 @@ __unused
|
|||
static void
|
||||
showsmopts(struct smopts_s *sp)
|
||||
{
|
||||
|
||||
(void)printf("%s (%p)\n", sp->s_name, sp);
|
||||
showname(sp->s_smopts);
|
||||
}
|
||||
|
@ -74,6 +76,7 @@ static int
|
|||
hashcase(const char *key)
|
||||
{
|
||||
char *lckey;
|
||||
|
||||
lckey = salloc(strlen(key) + 1);
|
||||
istrcpy(lckey, key);
|
||||
return hash(lckey);
|
||||
|
@ -128,18 +131,19 @@ static void
|
|||
printsmoptstbl(void)
|
||||
{
|
||||
struct smopts_s *sp;
|
||||
const char **argv, **ap;
|
||||
const char **argv;
|
||||
const char **ap;
|
||||
int h;
|
||||
int cnt;
|
||||
|
||||
cnt = 1;
|
||||
for (h = 0; h < (int)sizeofarray(smoptstbl); h++ )
|
||||
for (h = 0; h < (int)__arraycount(smoptstbl); h++ )
|
||||
for (sp = smoptstbl[h]; sp && sp->s_name != NULL; sp = sp->s_link)
|
||||
cnt++;
|
||||
|
||||
argv = salloc(cnt * sizeof(*argv));
|
||||
ap = argv;
|
||||
for (h = 0; h < (int)sizeofarray(smoptstbl); h++ )
|
||||
for (h = 0; h < (int)__arraycount(smoptstbl); h++ )
|
||||
for (sp = smoptstbl[h]; sp && sp->s_name != NULL; sp = sp->s_link)
|
||||
*ap++ = sp->s_name;
|
||||
*ap = NULL;
|
||||
|
@ -180,7 +184,8 @@ static void
|
|||
smopts_core(const char *sname, char **argv)
|
||||
{
|
||||
struct smopts_s *sp;
|
||||
struct name *np, *t;
|
||||
struct name *np;
|
||||
struct name *t;
|
||||
int h;
|
||||
char **ap;
|
||||
|
||||
|
@ -217,8 +222,9 @@ PUBLIC int
|
|||
smoptscmd(void *v)
|
||||
{
|
||||
struct name *np;
|
||||
char **argv = v;
|
||||
char **argv;
|
||||
|
||||
argv = v;
|
||||
if (*argv == NULL) {
|
||||
printsmoptstbl();
|
||||
return 0;
|
||||
|
@ -240,6 +246,7 @@ static void
|
|||
free_name(struct name *np)
|
||||
{
|
||||
struct name *next_np;
|
||||
|
||||
for (/*EMPTY*/; np; np = next_np) {
|
||||
next_np = np->n_flink;
|
||||
free(next_np);
|
||||
|
@ -269,11 +276,112 @@ PUBLIC int
|
|||
unsmoptscmd(void *v)
|
||||
{
|
||||
struct name *np;
|
||||
char **argv, **ap;
|
||||
char **ap;
|
||||
|
||||
argv = v;
|
||||
for (ap = argv; *ap != NULL; ap++)
|
||||
for (ap = v; *ap != NULL; ap++)
|
||||
for (np = name_expand(*ap, GTO); np; np = np->n_flink)
|
||||
delsmopts(np->n_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct name *
|
||||
alloc_Header(char *str)
|
||||
{
|
||||
struct name *np;
|
||||
|
||||
/*
|
||||
* Don't use salloc() routines here as these strings must persist.
|
||||
*/
|
||||
np = ecalloc(1, sizeof(*np));
|
||||
np->n_name = estrdup(str);
|
||||
np->n_type = GMISC;
|
||||
return np;
|
||||
}
|
||||
|
||||
static int
|
||||
free_Header(char *str)
|
||||
{
|
||||
struct name *np;
|
||||
struct name *next_np;
|
||||
size_t len;
|
||||
|
||||
len = strlen(str);
|
||||
for (np = extra_headers; np != NULL; np = next_np) {
|
||||
next_np = np->n_flink;
|
||||
if (strncasecmp(np->n_name, str, len) == 0) {
|
||||
if (np == extra_headers) {
|
||||
extra_headers = np->n_flink;
|
||||
if (extra_headers)
|
||||
extra_headers->n_blink = NULL;
|
||||
}
|
||||
else {
|
||||
struct name *bp;
|
||||
struct name *fp;
|
||||
|
||||
bp = np->n_blink;
|
||||
fp = np->n_flink;
|
||||
if (bp)
|
||||
bp->n_flink = fp;
|
||||
if (fp)
|
||||
fp->n_blink = bp;
|
||||
}
|
||||
if (np->n_name)
|
||||
free(np->n_name);
|
||||
free(np);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Takes a string and includes it in the header.
|
||||
*/
|
||||
PUBLIC int
|
||||
Header(void *v)
|
||||
{
|
||||
struct name *np;
|
||||
char *str;
|
||||
char *p;
|
||||
|
||||
str = v;
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
(void)strip_WSP(str); /* strip trailing whitespace */
|
||||
|
||||
if (str[0] == '\0') { /* Show the extra headers */
|
||||
for (np = extra_headers; np != NULL; np = np->n_flink)
|
||||
(void)printf("%s\n", np->n_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for a valid header line: find the end of its name.
|
||||
*/
|
||||
for (p = str; *p != '\0' && *p != ':' && !is_WSP(*p); p++)
|
||||
continue;
|
||||
|
||||
if (p[0] == ':' && p[1] == '\0') /* free headers of this type */
|
||||
return free_Header(str);
|
||||
|
||||
/*
|
||||
* Check for a valid header name.
|
||||
*/
|
||||
if (*p != ':' || !is_WSP(p[1])) {
|
||||
(void)printf("invalid header string: `%s'\n", str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
np = alloc_Header(str);
|
||||
if (extra_headers == NULL)
|
||||
extra_headers = np;
|
||||
else {
|
||||
struct name *tp;
|
||||
|
||||
for (tp = extra_headers; tp->n_flink; tp = tp->n_flink)
|
||||
continue;
|
||||
tp->n_flink = np;
|
||||
np->n_blink = tp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cmdtab.c,v 1.20 2007/10/30 02:28:31 christos Exp $ */
|
||||
/* $NetBSD: cmdtab.c,v 1.21 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)cmdtab.c 8.2 (Berkeley) 4/20/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: cmdtab.c,v 1.20 2007/10/30 02:28:31 christos Exp $");
|
||||
__RCSID("$NetBSD: cmdtab.c,v 1.21 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -62,7 +62,7 @@ __RCSID("$NetBSD: cmdtab.c,v 1.20 2007/10/30 02:28:31 christos Exp $");
|
|||
/* R - in left comment means recursive */
|
||||
const struct cmd cmdtab[] = {
|
||||
{ "next", next, C, CMP(n) NDMLIST, 0, MMNDEL },
|
||||
{ "alias", group, S, CMP(A) M|RAWLIST, 0, 1000 },
|
||||
{ "alias", group, S, CMP(A) T|M|RAWLIST, 0, 1000 },
|
||||
/* R */ { "print", type, C, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
/* R */ { "Print", Type, C, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
/* R */ { "type", type, C, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
|
@ -75,7 +75,7 @@ const struct cmd cmdtab[] = {
|
|||
/* R */ { "dp", deltype, C, CMP(n) W|MSGLIST, 0, MMNDEL },
|
||||
/* R */ { "dt", deltype, C, CMP(n) W|MSGLIST, 0, MMNDEL },
|
||||
/* R */ { "undelete", undeletecmd, 0, CMP(n) P|MSGLIST, MDELETED, MMNDEL },
|
||||
{ "unset", unset, 0, CMP(S) M|RAWLIST, 1, 1000 },
|
||||
{ "unset", unset, 0, CMP(S) T|M|RAWLIST, 1, 1000 },
|
||||
{ "mail", sendmail, 0, CMP(A) R|M|I|STRLIST, 0, 0 },
|
||||
/* R */ { "mbox", mboxit, 0, CMP(n) W|MSGLIST, 0, MMNDEL },
|
||||
/* R */ { "more", type, A, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
|
@ -86,21 +86,21 @@ const struct cmd cmdtab[] = {
|
|||
/* R */ { "view", view, A, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
/* R */ { "View", View, A, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
#endif
|
||||
{ "unalias", unalias, 0, CMP(A) M|RAWLIST, 1, 1000 },
|
||||
{ "unalias", unalias, 0, CMP(A) T|M|RAWLIST, 1, 1000 },
|
||||
/* R */ { "unread", unread, 0, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
{ "!", shell, 0, CMP(xF) I|STRLIST, 0, 0 },
|
||||
{ "!", shell, 0, CMP(xF) T|I|STRLIST, 0, 0 },
|
||||
{ "|", pipecmd, 0, CMP(xF) I|STRLIST, 0, 0 },
|
||||
/* R */ { "copy", copycmd, 0, CMP(F) M|STRLIST, 0, 0 },
|
||||
{ "chdir", schdir, 0, CMP(F) M|RAWLIST, 0, 1 },
|
||||
{ "cd", schdir, 0, CMP(F) M|RAWLIST, 0, 1 },
|
||||
{ "chdir", schdir, 0, CMP(F) T|M|RAWLIST, 0, 1 },
|
||||
{ "cd", schdir, 0, CMP(F) T|M|RAWLIST, 0, 1 },
|
||||
/* R */ { "save", save, 0, CMP(F) STRLIST, 0, 0 },
|
||||
/* R */ { "Save", Save, 0, CMP(F) STRLIST, 0, 0 },
|
||||
{ "source", source, 0, CMP(F) M|RAWLIST, 1, 1 },
|
||||
{ "set", set, S, CMP(sF) M|RAWLIST, 0, 1000 },
|
||||
{ "shell", dosh, 0, CMP(n) I|NOLIST, 0, 0 },
|
||||
{ "show", show, S, CMP(S) M|RAWLIST, 0, 1000 },
|
||||
{ "version", pversion, S, CMP(n) M|NOLIST, 0, 0 },
|
||||
{ "group", group, S, CMP(a) M|RAWLIST, 0, 1000 },
|
||||
{ "source", source, 0, CMP(F) T|M|RAWLIST, 1, 1 },
|
||||
{ "set", set, S, CMP(sF) T|M|RAWLIST, 0, 1000 },
|
||||
{ "shell", dosh, 0, CMP(n) T|I|NOLIST, 0, 0 },
|
||||
{ "show", show, S, CMP(S) T|M|RAWLIST, 0, 1000 },
|
||||
{ "version", pversion, S, CMP(n) T|M|NOLIST, 0, 0 },
|
||||
{ "group", group, S, CMP(a) T|M|RAWLIST, 0, 1000 },
|
||||
/* R */ { "write", swrite, 0, CMP(F) STRLIST, 0, 0 },
|
||||
{ "from", from, S, CMP(n) MSGLIST, 0, MMNORM },
|
||||
{ "file", file, 0, CMP(f) T|M|RAWLIST, 0, 1 },
|
||||
|
@ -110,42 +110,42 @@ const struct cmd cmdtab[] = {
|
|||
{ "forward", forward, 0, CMP(n) R|I|MSGLIST, 0, 0 },
|
||||
#endif
|
||||
{ "bounce", bounce, 0, CMP(n) R|I|MSGLIST, 0, 0 },
|
||||
{ "?", help, S, CMP(n) M|NOLIST, 0, 0 },
|
||||
{ "?", help, S, CMP(n) T|M|NOLIST, 0, 0 },
|
||||
{ "z", scroll, S, CMP(n) M|STRLIST, 0, 0 },
|
||||
{ "headers", headers, S, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
{ "help", help, S, CMP(n) M|NOLIST, 0, 0 },
|
||||
{ "=", pdot, S, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
{ "headers", headers, S, CMP(n) T|MSGLIST, 0, MMNDEL },
|
||||
{ "help", help, S, CMP(n) T|M|NOLIST, 0, 0 },
|
||||
{ "=", pdot, S, CMP(n) T|MSGLIST, 0, MMNDEL },
|
||||
{ "Reply", Respond, 0, CMP(n) R|I|MSGLIST, 0, MMNDEL },
|
||||
{ "Respond", Respond, 0, CMP(n) R|I|MSGLIST, 0, MMNDEL },
|
||||
{ "reply", respond, 0, CMP(n) R|I|MSGLIST, 0, MMNDEL },
|
||||
{ "respond", respond, 0, CMP(n) R|I|MSGLIST, 0, MMNDEL },
|
||||
{ "edit", editor, 0, CMP(n) I|MSGLIST, 0, MMNORM },
|
||||
{ "echo", echo, S, CMP(F) M|RAWLIST, 0, 1000 },
|
||||
{ "echo", echo, S, CMP(F) T|M|RAWLIST, 0, 1000 },
|
||||
{ "quit", quitcmd, 0, CMP(n) NOLIST, 0, 0 },
|
||||
{ "list", pcmdlist, S, CMP(n) M|NOLIST, 0, 0 },
|
||||
{ "list", pcmdlist, S, CMP(n) T|M|NOLIST, 0, 0 },
|
||||
{ "xit", rexit, 0, CMP(n) M|NOLIST, 0, 0 },
|
||||
{ "exit", rexit, 0, CMP(n) M|NOLIST, 0, 0 },
|
||||
{ "size", messize, S, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
{ "size", messize, S, CMP(n) T|MSGLIST, 0, MMNDEL },
|
||||
/* R */ { "hold", preserve, 0, CMP(n) W|MSGLIST, 0, MMNDEL },
|
||||
{ "if", ifcmd, 0, CMP(F) F|M|RAWLIST, 1, 1 },
|
||||
{ "ifdef", ifdefcmd, 0, CMP(F) F|M|RAWLIST, 1, 1 },
|
||||
{ "ifndef", ifndefcmd, 0, CMP(F) F|M|RAWLIST, 1, 1 },
|
||||
{ "else", elsecmd, 0, CMP(F) F|M|RAWLIST, 0, 0 },
|
||||
{ "endif", endifcmd, 0, CMP(F) F|M|RAWLIST, 0, 0 },
|
||||
{ "alternates", alternates, S, CMP(n) M|RAWLIST, 0, 1000 },
|
||||
{ "ignore", igfield, S, CMP(n) M|RAWLIST, 0, 1000 },
|
||||
{ "discard", igfield, S, CMP(n) M|RAWLIST, 0, 1000 },
|
||||
{ "retain", retfield, S, CMP(n) M|RAWLIST, 0, 1000 },
|
||||
{ "saveignore", saveigfield, S, CMP(n) M|RAWLIST, 0, 1000 },
|
||||
{ "savediscard",saveigfield, S, CMP(n) M|RAWLIST, 0, 1000 },
|
||||
{ "saveretain", saveretfield, S, CMP(n) M|RAWLIST, 0, 1000 },
|
||||
/* { "Header", Header, S, CMP(n) STRLIST, 0, 1000 }, */
|
||||
{ "core", core, 0, CMP(F) M|NOLIST, 0, 0 },
|
||||
{ "#", null, 0, CMP(n) M|NOLIST, 0, 0 },
|
||||
{ "clobber", clobber, 0, CMP(n) M|RAWLIST, 0, 1 },
|
||||
{ "if", ifcmd, 0, CMP(F) T|F|M|RAWLIST, 1, 1 },
|
||||
{ "ifdef", ifdefcmd, 0, CMP(F) T|F|M|RAWLIST, 1, 1 },
|
||||
{ "ifndef", ifndefcmd, 0, CMP(F) T|F|M|RAWLIST, 1, 1 },
|
||||
{ "else", elsecmd, 0, CMP(F) T|F|M|RAWLIST, 0, 0 },
|
||||
{ "endif", endifcmd, 0, CMP(F) T|F|M|RAWLIST, 0, 0 },
|
||||
{ "alternates", alternates, S, CMP(n) T|M|RAWLIST, 0, 1000 },
|
||||
{ "ignore", igfield, S, CMP(n) T|M|RAWLIST, 0, 1000 },
|
||||
{ "discard", igfield, S, CMP(n) T|M|RAWLIST, 0, 1000 },
|
||||
{ "retain", retfield, S, CMP(n) T|M|RAWLIST, 0, 1000 },
|
||||
{ "saveignore", saveigfield, S, CMP(n) T|M|RAWLIST, 0, 1000 },
|
||||
{ "savediscard",saveigfield, S, CMP(n) T|M|RAWLIST, 0, 1000 },
|
||||
{ "saveretain", saveretfield, S, CMP(n) T|M|RAWLIST, 0, 1000 },
|
||||
{ "Header", Header, S, CMP(n) T|M|STRLIST, 0, 1000 },
|
||||
{ "core", core, 0, CMP(F) T|M|NOLIST, 0, 0 },
|
||||
{ "#", null, 0, CMP(n) T|M|NOLIST, 0, 0 },
|
||||
{ "clobber", clobber, 0, CMP(n) T|M|RAWLIST, 0, 1 },
|
||||
{ "inc", inc, S, CMP(n) T|NOLIST, 0, 0 },
|
||||
{ "smopts", smoptscmd, S, CMP(m) M|RAWLIST, 0, 1000 },
|
||||
{ "unsmopts", unsmoptscmd, S, CMP(M) M|RAWLIST, 1, 1000 },
|
||||
{ "smopts", smoptscmd, S, CMP(m) T|M|RAWLIST, 0, 1000 },
|
||||
{ "unsmopts", unsmoptscmd, S, CMP(M) T|M|RAWLIST, 1, 1000 },
|
||||
/* R */ { "mkread", markread, 0, CMP(n) MSGLIST, 0, MMNDEL },
|
||||
#ifdef MIME_SUPPORT
|
||||
/* R */ { "detach", detach, S, CMP(F) STRLIST, 0, 0 },
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: collect.c,v 1.42 2007/10/29 23:20:38 christos Exp $ */
|
||||
/* $NetBSD: collect.c,v 1.43 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)collect.c 8.2 (Berkeley) 4/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: collect.c,v 1.42 2007/10/29 23:20:38 christos Exp $");
|
||||
__RCSID("$NetBSD: collect.c,v 1.43 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -54,6 +54,7 @@ __RCSID("$NetBSD: collect.c,v 1.42 2007/10/29 23:20:38 christos Exp $");
|
|||
#ifdef MIME_SUPPORT
|
||||
#include "mime.h"
|
||||
#endif
|
||||
#include "sig.h"
|
||||
#include "thread.h"
|
||||
|
||||
|
||||
|
@ -67,19 +68,12 @@ __RCSID("$NetBSD: collect.c,v 1.42 2007/10/29 23:20:38 christos Exp $");
|
|||
* receipt of an interrupt signal, the partial message can be salted
|
||||
* away on dead.letter.
|
||||
*/
|
||||
|
||||
static sig_t saveint; /* Previous SIGINT value */
|
||||
static sig_t savehup; /* Previous SIGHUP value */
|
||||
static sig_t savetstp; /* Previous SIGTSTP value */
|
||||
static sig_t savettou; /* Previous SIGTTOU value */
|
||||
static sig_t savettin; /* Previous SIGTTIN value */
|
||||
static FILE *collf; /* File for saving away */
|
||||
static int hadintr; /* Have seen one SIGINT so far */
|
||||
|
||||
static jmp_buf colljmp; /* To get back to work */
|
||||
static int colljmp_p; /* whether to long jump */
|
||||
static jmp_buf collabort; /* To end collection with error */
|
||||
|
||||
static jmp_buf abort_jmpbuf; /* To end collection with error */
|
||||
static jmp_buf reset_jmpbuf; /* To get back to work */
|
||||
static int reset_on_stop; /* To do job control longjmp. */
|
||||
|
||||
/*
|
||||
* Write a file, ex-like if f set.
|
||||
|
@ -133,15 +127,20 @@ exwrite(const char name[], FILE *fp, int f)
|
|||
static void
|
||||
mesedit(FILE *fp, int c)
|
||||
{
|
||||
sig_t sigint = signal(SIGINT, SIG_IGN);
|
||||
FILE *nf = run_editor(fp, (off_t)-1, c, 0);
|
||||
struct sigaction osa;
|
||||
sigset_t oset;
|
||||
FILE *nf;
|
||||
|
||||
sig_check();
|
||||
(void)sig_ignore(SIGINT, &osa, &oset);
|
||||
nf = run_editor(fp, (off_t)-1, c, 0);
|
||||
if (nf != NULL) {
|
||||
(void)fseek(nf, 0L, 2);
|
||||
collf = nf;
|
||||
(void)Fclose(fp);
|
||||
}
|
||||
(void)signal(SIGINT, sigint);
|
||||
(void)sig_restore(SIGINT, &osa, &oset);
|
||||
sig_check();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -154,11 +153,15 @@ static void
|
|||
mespipe(FILE *fp, char cmd[])
|
||||
{
|
||||
FILE *nf;
|
||||
sig_t sigint = signal(SIGINT, SIG_IGN);
|
||||
struct sigaction osa;
|
||||
sigset_t oset;
|
||||
const char *shellcmd;
|
||||
int fd;
|
||||
char tempname[PATHSIZE];
|
||||
|
||||
sig_check();
|
||||
(void)sig_ignore(SIGINT, &osa, &oset);
|
||||
|
||||
(void)snprintf(tempname, sizeof(tempname),
|
||||
"%s/mail.ReXXXXXXXXXX", tmpdir);
|
||||
if ((fd = mkstemp(tempname)) == -1 ||
|
||||
|
@ -176,7 +179,7 @@ mespipe(FILE *fp, char cmd[])
|
|||
if ((shellcmd = value(ENAME_SHELL)) == NULL)
|
||||
shellcmd = _PATH_CSHELL;
|
||||
if (run_command(shellcmd,
|
||||
0, fileno(fp), fileno(nf), "-c", cmd, NULL) < 0) {
|
||||
NULL, fileno(fp), fileno(nf), "-c", cmd, NULL) < 0) {
|
||||
(void)Fclose(nf);
|
||||
goto out;
|
||||
}
|
||||
|
@ -191,8 +194,9 @@ mespipe(FILE *fp, char cmd[])
|
|||
(void)fseek(nf, 0L, 2);
|
||||
collf = nf;
|
||||
(void)Fclose(fp);
|
||||
out:
|
||||
(void)signal(SIGINT, sigint);
|
||||
out:
|
||||
(void)sig_restore(SIGINT, &osa, &oset);
|
||||
sig_check();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -267,29 +271,6 @@ interpolate(char ms[], FILE *fp, char *fn, int f)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print (continue) when continued after ^Z.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
collstop(int s)
|
||||
{
|
||||
sig_t old_action = signal(s, SIG_DFL);
|
||||
sigset_t nset;
|
||||
|
||||
(void)sigemptyset(&nset);
|
||||
(void)sigaddset(&nset, s);
|
||||
(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
|
||||
(void)kill(0, s);
|
||||
(void)sigprocmask(SIG_BLOCK, &nset, NULL);
|
||||
(void)signal(s, old_action);
|
||||
if (colljmp_p) {
|
||||
colljmp_p = 0;
|
||||
hadintr = 0;
|
||||
longjmp(colljmp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Append the contents of the file to the end of the deadletter file.
|
||||
*/
|
||||
|
@ -309,6 +290,7 @@ savedeadletter(FILE *fp)
|
|||
(void)umask(m);
|
||||
if (dbuf == NULL)
|
||||
return;
|
||||
(void)printf("Saving message body to `%s'.\n", cp);
|
||||
while ((c = getc(fp)) != EOF)
|
||||
(void)putc(c, dbuf);
|
||||
(void)Fclose(dbuf);
|
||||
|
@ -319,10 +301,10 @@ savedeadletter(FILE *fp)
|
|||
* On interrupt, come here to save the partial message in ~/dead.letter.
|
||||
* Then jump out of the collection loop.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
collint(int s __unused)
|
||||
coll_int(int signo)
|
||||
{
|
||||
|
||||
/*
|
||||
* the control flow is subtle, because we can be called from ~q.
|
||||
*/
|
||||
|
@ -334,30 +316,50 @@ collint(int s __unused)
|
|||
return;
|
||||
}
|
||||
hadintr = 1;
|
||||
longjmp(colljmp, 1);
|
||||
longjmp(reset_jmpbuf, signo);
|
||||
}
|
||||
rewind(collf);
|
||||
if (value(ENAME_NOSAVE) == NULL)
|
||||
savedeadletter(collf);
|
||||
longjmp(collabort, 1);
|
||||
longjmp(abort_jmpbuf, signo);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
collhup(int s __unused)
|
||||
coll_hup(int signo __unused)
|
||||
{
|
||||
|
||||
rewind(collf);
|
||||
savedeadletter(collf);
|
||||
/*
|
||||
* Let's pretend nobody else wants to clean up,
|
||||
* a true statement at this time.
|
||||
*/
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print (continue) when continued after ^Z.
|
||||
*/
|
||||
static void
|
||||
coll_stop(int signo)
|
||||
{
|
||||
|
||||
if (reset_on_stop) {
|
||||
reset_on_stop = 0;
|
||||
hadintr = 0;
|
||||
longjmp(reset_jmpbuf, signo);
|
||||
}
|
||||
}
|
||||
|
||||
PUBLIC FILE *
|
||||
collect(struct header *hp, int printheaders)
|
||||
{
|
||||
volatile sig_t old_sigint;
|
||||
volatile sig_t old_sighup;
|
||||
volatile sig_t old_sigtstp;
|
||||
volatile sig_t old_sigttin;
|
||||
volatile sig_t old_sigttou;
|
||||
FILE *fbuf;
|
||||
int lc, cc;
|
||||
int c, fd, t;
|
||||
|
@ -365,11 +367,10 @@ collect(struct header *hp, int printheaders)
|
|||
const char *cp;
|
||||
char tempname[PATHSIZE];
|
||||
char mailtempname[PATHSIZE];
|
||||
int lastlong, rc; /* So we don't make 2 or more lines
|
||||
out of a long input line. */
|
||||
int eofcount;
|
||||
int longline;
|
||||
sigset_t nset;
|
||||
int lastlong, rc; /* So we don't make 2 or more lines
|
||||
out of a long input line. */
|
||||
|
||||
/* The following are declared volatile to avoid longjmp clobbering. */
|
||||
char volatile getsub;
|
||||
|
@ -377,26 +378,20 @@ collect(struct header *hp, int printheaders)
|
|||
|
||||
(void)memset(mailtempname, 0, sizeof(mailtempname));
|
||||
collf = NULL;
|
||||
/*
|
||||
* Start catching signals from here, but we're still die on interrupts
|
||||
* until we're in the main loop.
|
||||
*/
|
||||
(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)
|
||||
(void)signal(SIGHUP, collhup);
|
||||
savetstp = signal(SIGTSTP, collstop);
|
||||
savettou = signal(SIGTTOU, collstop);
|
||||
savettin = signal(SIGTTIN, collstop);
|
||||
if (setjmp(collabort) || setjmp(colljmp)) {
|
||||
|
||||
if (setjmp(abort_jmpbuf) || setjmp(reset_jmpbuf)) {
|
||||
(void)rm(mailtempname);
|
||||
goto err;
|
||||
}
|
||||
(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
|
||||
sig_check();
|
||||
|
||||
sig_hold();
|
||||
old_sigint = sig_signal(SIGINT, coll_int);
|
||||
old_sighup = sig_signal(SIGHUP, coll_hup);
|
||||
old_sigtstp = sig_signal(SIGTSTP, coll_stop);
|
||||
old_sigttin = sig_signal(SIGTTIN, coll_stop);
|
||||
old_sigttou = sig_signal(SIGTTOU, coll_stop);
|
||||
sig_release();
|
||||
|
||||
noreset++;
|
||||
(void)snprintf(mailtempname, sizeof(mailtempname),
|
||||
|
@ -415,11 +410,13 @@ collect(struct header *hp, int printheaders)
|
|||
* refrain from printing a newline after
|
||||
* the headers (since some people mind).
|
||||
*/
|
||||
t = GTO|GSUBJECT|GCC|GNL|GSMOPTS;
|
||||
t = GTO | GSUBJECT | GCC | GNL | GSMOPTS;
|
||||
getsub = 0;
|
||||
if (hp->h_subject == NULL && value(ENAME_INTERACTIVE) != NULL &&
|
||||
(value(ENAME_ASK) != NULL || value(ENAME_ASKSUB) != NULL))
|
||||
t &= ~GNL, getsub++;
|
||||
(value(ENAME_ASK) != NULL || value(ENAME_ASKSUB) != NULL)) {
|
||||
t &= ~GNL;
|
||||
getsub++;
|
||||
}
|
||||
if (printheaders) {
|
||||
(void)puthead(hp, stdout, t);
|
||||
(void)fflush(stdout);
|
||||
|
@ -428,8 +425,8 @@ collect(struct header *hp, int printheaders)
|
|||
escape = *cp;
|
||||
else
|
||||
escape = ESCAPE;
|
||||
hadintr = 0; /* static - no longjmp problem */
|
||||
if (!setjmp(colljmp)) {
|
||||
hadintr = 0;
|
||||
if (setjmp(reset_jmpbuf) == 0) {
|
||||
if (getsub)
|
||||
(void)grabh(hp, GSUBJECT);
|
||||
} else {
|
||||
|
@ -438,7 +435,7 @@ collect(struct header *hp, int printheaders)
|
|||
* Duplicate messages won't be printed because
|
||||
* the write is aborted if we get a SIGTTOU.
|
||||
*/
|
||||
cont:
|
||||
cont:
|
||||
if (hadintr) {
|
||||
(void)fflush(stdout);
|
||||
(void)fprintf(stderr,
|
||||
|
@ -451,12 +448,13 @@ cont:
|
|||
eofcount = 0; /* reset after possible longjmp */
|
||||
longline = 0; /* reset after possible longjmp */
|
||||
for (;;) {
|
||||
colljmp_p = 1;
|
||||
c = mail_readline(stdin, linebuf, LINESIZE);
|
||||
colljmp_p = 0;
|
||||
#ifdef USE_EDITLINE
|
||||
reset_on_stop = 1;
|
||||
c = readline(stdin, linebuf, LINESIZE, reset_on_stop);
|
||||
reset_on_stop = 0;
|
||||
|
||||
if (c < 0) {
|
||||
char *p;
|
||||
|
||||
if (value(ENAME_INTERACTIVE) != NULL &&
|
||||
(p = value(ENAME_IGNOREEOF)) != NULL &&
|
||||
++eofcount < (*p == 0 ? 25 : atoi(p))) {
|
||||
|
@ -465,18 +463,8 @@ cont:
|
|||
}
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (c < 0) {
|
||||
if (value(ENAME_INTERACTIVE) != NULL &&
|
||||
value(ENAME_IGNOREEOF) != NULL && ++eofcount < 25) {
|
||||
(void)printf("Use \".\" to terminate letter\n");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
lastlong = longline;
|
||||
longline = c == LINESIZE-1;
|
||||
longline = c == LINESIZE - 1;
|
||||
eofcount = 0;
|
||||
hadintr = 0;
|
||||
if (linebuf[0] == '.' && linebuf[1] == '\0' &&
|
||||
|
@ -540,7 +528,7 @@ cont:
|
|||
* Act like an interrupt happened.
|
||||
*/
|
||||
hadintr++;
|
||||
collint(SIGINT);
|
||||
coll_int(SIGINT);
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
|
||||
|
@ -551,7 +539,7 @@ cont:
|
|||
/*
|
||||
* Grab a bunch of headers.
|
||||
*/
|
||||
(void)grabh(hp, GTO|GSUBJECT|GCC|GBCC|GSMOPTS);
|
||||
(void)grabh(hp, GTO | GSUBJECT | GCC | GBCC | GSMOPTS);
|
||||
goto cont;
|
||||
case 't':
|
||||
/*
|
||||
|
@ -651,7 +639,7 @@ cont:
|
|||
if ((shellcmd = value(ENAME_SHELL)) == NULL)
|
||||
shellcmd = _PATH_CSHELL;
|
||||
|
||||
rc2 = run_command(shellcmd, 0, nullfd, fileno(fbuf), "-c", cp + 1, NULL);
|
||||
rc2 = run_command(shellcmd, NULL, nullfd, fileno(fbuf), "-c", cp + 1, NULL);
|
||||
|
||||
(void)close(nullfd);
|
||||
|
||||
|
@ -680,7 +668,7 @@ cont:
|
|||
(void)fflush(stdout);
|
||||
lc = 0;
|
||||
cc = 0;
|
||||
while ((rc = mail_readline(fbuf, linebuf, LINESIZE)) >= 0) {
|
||||
while ((rc = readline(fbuf, linebuf, LINESIZE, 0)) >= 0) {
|
||||
if (rc != LINESIZE-1) lc++;
|
||||
if ((t = putline(collf, linebuf,
|
||||
rc != LINESIZE-1)) < 0) {
|
||||
|
@ -729,7 +717,8 @@ cont:
|
|||
*/
|
||||
rewind(collf);
|
||||
(void)printf("-------\nMessage contains:\n");
|
||||
(void)puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL);
|
||||
(void)puthead(hp, stdout,
|
||||
GTO | GSUBJECT | GCC | GBCC | GSMOPTS | GNL);
|
||||
while ((t = getc(collf)) != EOF)
|
||||
(void)putchar(t);
|
||||
goto cont;
|
||||
|
@ -754,21 +743,24 @@ cont:
|
|||
}
|
||||
}
|
||||
goto out;
|
||||
err:
|
||||
err:
|
||||
if (collf != NULL) {
|
||||
(void)Fclose(collf);
|
||||
collf = NULL;
|
||||
}
|
||||
out:
|
||||
out:
|
||||
if (collf != NULL)
|
||||
rewind(collf);
|
||||
noreset--;
|
||||
(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)sigprocmask(SIG_UNBLOCK, &nset, NULL);
|
||||
|
||||
sig_hold();
|
||||
(void)sig_signal(SIGINT, old_sigint);
|
||||
(void)sig_signal(SIGHUP, old_sighup);
|
||||
(void)sig_signal(SIGTSTP, old_sigtstp);
|
||||
(void)sig_signal(SIGTTIN, old_sigttin);
|
||||
(void)sig_signal(SIGTTOU, old_sigttou);
|
||||
sig_release();
|
||||
|
||||
sig_check();
|
||||
return collf;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: complete.c,v 1.18 2009/02/11 19:22:22 christos Exp $ */
|
||||
/* $NetBSD: complete.c,v 1.19 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2000,2005,2006 The NetBSD Foundation, Inc.
|
||||
|
@ -34,11 +34,10 @@
|
|||
*/
|
||||
|
||||
#ifdef USE_EDITLINE
|
||||
#undef NO_EDITCOMPLETE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: complete.c,v 1.18 2009/02/11 19:22:22 christos Exp $");
|
||||
__RCSID("$NetBSD: complete.c,v 1.19 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
|
@ -66,6 +65,7 @@ __RCSID("$NetBSD: complete.c,v 1.18 2009/02/11 19:22:22 christos Exp $");
|
|||
#ifdef MIME_SUPPORT
|
||||
#include "mime.h"
|
||||
#endif
|
||||
#include "sig.h"
|
||||
#ifdef THREAD_SUPPORT
|
||||
#include "thread.h"
|
||||
#endif
|
||||
|
@ -738,6 +738,7 @@ static int
|
|||
is_emacs_mode(EditLine *el)
|
||||
{
|
||||
char *mode;
|
||||
|
||||
if (el_get(el, EL_EDITOR, &mode) == -1)
|
||||
return 0;
|
||||
return equal(mode, "emacs");
|
||||
|
@ -747,6 +748,7 @@ static int
|
|||
emacs_ctrl_d(EditLine *el, const LineInfo *lf, int ch)
|
||||
{
|
||||
static char delunder[3] = { CTRL('f'), CTRL('h'), '\0' };
|
||||
|
||||
if (ch == CTRL('d') && is_emacs_mode(el)) { /* CTRL-D is special */
|
||||
if (lf->buffer == lf->lastchar)
|
||||
return CC_EOF;
|
||||
|
@ -882,7 +884,7 @@ split_word(int *cmpltype, const char *cmplarray, LineInfo *li)
|
|||
}
|
||||
|
||||
/* check for 'continuation' completes (which are uppercase) */
|
||||
arraylen = strlen(cmplarray);
|
||||
arraylen = (int)strlen(cmplarray);
|
||||
if (cursorc >= arraylen &&
|
||||
arraylen > 0 &&
|
||||
isupper((unsigned char)cmplarray[arraylen - 1]))
|
||||
|
@ -1068,12 +1070,10 @@ mime_enc_complete(EditLine *el, int ch)
|
|||
* Initializes of all editline and completion data strutures.
|
||||
*
|
||||
* my_gets()
|
||||
* Returns the next line of input as a NULL termnated string without
|
||||
* the trailing newline.
|
||||
*
|
||||
* my_getline()
|
||||
* Same as my_gets(), but strips leading and trailing whitespace
|
||||
* and returns an empty line if it gets a SIGINT.
|
||||
* Displays prompt, calls el_gets() and deals with history.
|
||||
* Returns the next line of input as a NULL termnated string
|
||||
* without the trailing newline, or NULL if el_gets() sees is an
|
||||
* error or signal.
|
||||
*/
|
||||
|
||||
static const char *el_prompt;
|
||||
|
@ -1085,30 +1085,68 @@ show_prompt(EditLine *e __unused)
|
|||
return el_prompt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the current INTR character to fp in a friendly form.
|
||||
*/
|
||||
static void
|
||||
echo_INTR(void *p)
|
||||
{
|
||||
struct termios ttybuf;
|
||||
char buf[5];
|
||||
FILE *fp;
|
||||
|
||||
fp = p;
|
||||
if (tcgetattr(fileno(stdin), &ttybuf) == -1)
|
||||
warn("tcgetattr");
|
||||
else {
|
||||
(void)vis(buf, ttybuf.c_cc[VINTR], VIS_SAFE | VIS_NOSLASH, 0);
|
||||
(void)fprintf(fp, "%s", buf);
|
||||
(void)fflush(fp);
|
||||
}
|
||||
}
|
||||
|
||||
static sig_t old_sigint;
|
||||
static void
|
||||
comp_intr(int signo)
|
||||
{
|
||||
|
||||
echo_INTR(stdout);
|
||||
old_sigint(signo);
|
||||
}
|
||||
|
||||
PUBLIC char *
|
||||
my_gets(el_mode_t *em, const char *prompt, char *string)
|
||||
{
|
||||
int cnt;
|
||||
static char line[LINE_MAX];
|
||||
size_t len;
|
||||
int cnt;
|
||||
const char *buf;
|
||||
HistEvent ev;
|
||||
static char line[LINE_MAX];
|
||||
|
||||
sig_check();
|
||||
|
||||
el_prompt = prompt;
|
||||
|
||||
if (string)
|
||||
el_push(em->el, string);
|
||||
|
||||
/*
|
||||
* Let el_gets() deal with flow control. Also, make sure we
|
||||
* output a ^C when we get a SIGINT as el_gets() doesn't echo
|
||||
* one.
|
||||
*/
|
||||
old_sigint = sig_signal(SIGINT, comp_intr);
|
||||
buf = el_gets(em->el, &cnt);
|
||||
(void)sig_signal(SIGINT, old_sigint);
|
||||
|
||||
if (buf == NULL || cnt <= 0) {
|
||||
if (cnt == 0)
|
||||
(void)putc('\n', stdout);
|
||||
if (buf == NULL) {
|
||||
sig_check();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(cnt > 0);
|
||||
if (buf[cnt - 1] == '\n')
|
||||
cnt--; /* trash the trailing LF */
|
||||
|
||||
len = MIN(sizeof(line) - 1, (size_t)cnt);
|
||||
(void)memcpy(line, buf, len);
|
||||
line[cnt] = '\0';
|
||||
|
@ -1116,56 +1154,15 @@ my_gets(el_mode_t *em, const char *prompt, char *string)
|
|||
/* enter non-empty lines into history */
|
||||
if (em->hist) {
|
||||
const char *p;
|
||||
|
||||
p = skip_WSP(line);
|
||||
if (*p && history(em->hist, &ev, H_ENTER, line) == 0)
|
||||
(void)printf("Failed history entry: %s", line);
|
||||
}
|
||||
sig_check();
|
||||
return line;
|
||||
}
|
||||
|
||||
#ifdef MIME_SUPPORT
|
||||
/* XXX - do we really want this here? */
|
||||
|
||||
static jmp_buf intjmp;
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
sigint(int signum __unused)
|
||||
{
|
||||
siglongjmp(intjmp, 1);
|
||||
}
|
||||
|
||||
PUBLIC char *
|
||||
my_getline(el_mode_t *em, const char *prompt, const char *str)
|
||||
{
|
||||
sig_t saveint;
|
||||
char *cp;
|
||||
char *line;
|
||||
|
||||
saveint = signal(SIGINT, sigint);
|
||||
if (sigsetjmp(intjmp, 1)) {
|
||||
(void)signal(SIGINT, saveint);
|
||||
(void)putc('\n', stdout);
|
||||
return __UNCONST("");
|
||||
}
|
||||
|
||||
line = my_gets(em, prompt, __UNCONST(str));
|
||||
/* LINTED */
|
||||
line = line ? savestr(line) : __UNCONST("");
|
||||
|
||||
(void)signal(SIGINT, saveint);
|
||||
|
||||
/* strip trailing white space */
|
||||
for (cp = line + strlen(line) - 1;
|
||||
cp >= line && is_WSP(*cp); cp--)
|
||||
*cp = '\0';
|
||||
|
||||
/* skip leading white space */
|
||||
cp = skip_WSP(line);
|
||||
|
||||
return cp;
|
||||
}
|
||||
#endif /* MIME_SUPPORT */
|
||||
|
||||
static el_mode_t
|
||||
init_el_mode(
|
||||
const char *el_editor,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: complete.h,v 1.5 2008/04/28 20:24:14 martin Exp $ */
|
||||
/* $NetBSD: complete.h,v 1.6 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -50,7 +50,6 @@ struct el_modes_s {
|
|||
extern struct el_modes_s elm;
|
||||
|
||||
char *my_gets(el_mode_t *, const char *, char *);
|
||||
char *my_getline(el_mode_t *, const char *, const char *);
|
||||
void init_editline(void);
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: def.h,v 1.26 2007/10/27 15:14:50 christos Exp $ */
|
||||
/* $NetBSD: def.h,v 1.27 2009/04/10 13:08:24 christos Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
|
@ -28,7 +28,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)def.h 8.4 (Berkeley) 4/20/95
|
||||
* $NetBSD: def.h,v 1.26 2007/10/27 15:14:50 christos Exp $
|
||||
* $NetBSD: def.h,v 1.27 2009/04/10 13:08:24 christos Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -54,6 +54,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -61,6 +62,8 @@
|
|||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <vis.h>
|
||||
|
||||
#include "pathnames.h"
|
||||
|
||||
#define APPEND /* New mail goes to end of mailbox */
|
||||
|
@ -111,6 +114,7 @@
|
|||
#define ENAME_METOO "metoo"
|
||||
#define ENAME_NOHEADER "noheader"
|
||||
#define ENAME_NOSAVE "nosave"
|
||||
#define ENAME_PAGE_ALSO "page-also"
|
||||
#define ENAME_PAGER "PAGER"
|
||||
#define ENAME_PAGER_OFF "pager-off"
|
||||
#define ENAME_PROMPT "prompt"
|
||||
|
@ -131,7 +135,6 @@
|
|||
#define ENAME_VERBOSE "verbose"
|
||||
#define ENAME_VISUAL "VISUAL"
|
||||
|
||||
#define sizeofarray(a) (sizeof(a)/sizeof(*a))
|
||||
#define equal(a, b) (strcmp(a,b)==0)/* A nice function to string compare */
|
||||
|
||||
struct message {
|
||||
|
@ -249,7 +252,7 @@ struct headline {
|
|||
#ifdef MIME_SUPPORT
|
||||
#define GMIME 0x040 /* mime flag */
|
||||
#endif
|
||||
#define GMASK (GTO|GSUBJECT|GCC|GBCC|GSMOPTS)
|
||||
#define GMASK (GTO | GSUBJECT | GCC | GBCC | GSMOPTS)
|
||||
/* Mask of places from whence */
|
||||
|
||||
#define GNL 0x100 /* Print blank line after */
|
||||
|
@ -318,14 +321,14 @@ struct attachment {
|
|||
*/
|
||||
|
||||
struct header {
|
||||
struct name *h_to; /* Dynamic "To:" string */
|
||||
char *h_subject; /* Subject string */
|
||||
struct name *h_cc; /* Carbon copies string */
|
||||
struct name *h_bcc; /* Blind carbon copies */
|
||||
struct name *h_smopts; /* Sendmail options */
|
||||
char *h_in_reply_to;
|
||||
struct name *h_references;
|
||||
char *h_extra; /* extra lines to output */
|
||||
struct name *h_to; /* Dynamic "To:" string */
|
||||
char *h_subject; /* Subject string */
|
||||
struct name *h_cc; /* Carbon copies string */
|
||||
struct name *h_bcc; /* Blind carbon copies */
|
||||
struct name *h_smopts; /* Sendmail options */
|
||||
char *h_in_reply_to; /* In-Reply-To: field */
|
||||
struct name *h_references; /* References: field */
|
||||
struct name *h_extra; /* extra header fields */
|
||||
#ifdef MIME_SUPPORT
|
||||
char *h_mime_boundary; /* MIME multipart boundary string */
|
||||
struct Content h_Content; /* MIME content for message */
|
||||
|
@ -406,13 +409,6 @@ enum mailmode_e {
|
|||
mm_hdrsonly /* headers only mode */
|
||||
};
|
||||
|
||||
/*
|
||||
* Kludges to handle the change from setexit / reset to setjmp / longjmp
|
||||
*/
|
||||
|
||||
#define setexit() (void)setjmp(srbuf)
|
||||
#define reset(x) longjmp(srbuf, x)
|
||||
|
||||
/*
|
||||
* Truncate a file to the last character written. This is
|
||||
* useful just before closing an old file that was opened
|
||||
|
@ -438,7 +434,7 @@ is_WSP(int c)
|
|||
return c == ' ' || c == '\t';
|
||||
}
|
||||
|
||||
static inline char*
|
||||
static inline char *
|
||||
skip_WSP(const char *cp)
|
||||
{
|
||||
while (is_WSP(*cp))
|
||||
|
@ -446,7 +442,7 @@ skip_WSP(const char *cp)
|
|||
return __UNCONST(cp);
|
||||
}
|
||||
|
||||
static inline char*
|
||||
static inline char *
|
||||
skip_space(char *p)
|
||||
{
|
||||
while (isspace((unsigned char)*p))
|
||||
|
@ -454,4 +450,19 @@ skip_space(char *p)
|
|||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* strip trailing white space
|
||||
*/
|
||||
static inline char *
|
||||
strip_WSP(char *line)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
cp = line + strlen(line) - 1;
|
||||
while (cp >= line && is_WSP(*cp))
|
||||
cp--;
|
||||
*++cp = '\0';
|
||||
return cp;
|
||||
}
|
||||
|
||||
#endif /* __DEF_H__ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dotlock.c,v 1.9 2007/10/29 23:20:38 christos Exp $ */
|
||||
/* $NetBSD: dotlock.c,v 1.10 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
|
||||
|
@ -31,11 +31,12 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: dotlock.c,v 1.9 2007/10/29 23:20:38 christos Exp $");
|
||||
__RCSID("$NetBSD: dotlock.c,v 1.10 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif
|
||||
|
||||
#include "rcv.h"
|
||||
#include "extern.h"
|
||||
#include "sig.h"
|
||||
|
||||
#ifndef O_SYNC
|
||||
#define O_SYNC 0
|
||||
|
@ -139,6 +140,7 @@ dot_lock(const char *fname, int pollinterval, FILE *fp, const char *msg)
|
|||
{
|
||||
char path[MAXPATHLEN];
|
||||
sigset_t nset, oset;
|
||||
int retval;
|
||||
|
||||
(void)sigemptyset(&nset);
|
||||
(void)sigaddset(&nset, SIGHUP);
|
||||
|
@ -152,17 +154,20 @@ dot_lock(const char *fname, int pollinterval, FILE *fp, const char *msg)
|
|||
|
||||
(void)snprintf(path, sizeof(path), "%s.lock", fname);
|
||||
|
||||
retval = -1;
|
||||
for (;;) {
|
||||
sig_check();
|
||||
(void)sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
if (create_exclusive(path) != -1) {
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
return 0;
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
if (fp && msg)
|
||||
(void)fputs(msg, fp);
|
||||
|
@ -170,11 +175,13 @@ dot_lock(const char *fname, int pollinterval, FILE *fp, const char *msg)
|
|||
if (pollinterval) {
|
||||
if (pollinterval == -1) {
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
(void)sleep((unsigned int)pollinterval);
|
||||
}
|
||||
}
|
||||
sig_check();
|
||||
return retval;
|
||||
}
|
||||
|
||||
PUBLIC void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: edit.c,v 1.24 2007/10/29 23:20:38 christos Exp $ */
|
||||
/* $NetBSD: edit.c,v 1.25 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,13 +34,14 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)edit.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: edit.c,v 1.24 2007/10/29 23:20:38 christos Exp $");
|
||||
__RCSID("$NetBSD: edit.c,v 1.25 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include "rcv.h"
|
||||
#include "extern.h"
|
||||
#include "thread.h"
|
||||
#include "sig.h"
|
||||
|
||||
/*
|
||||
* Mail -- a mail program
|
||||
|
@ -107,10 +108,10 @@ run_editor(FILE *fp, off_t size, int editortype, int readonlyflag)
|
|||
goto out;
|
||||
}
|
||||
nf = NULL;
|
||||
if ((editcmd =
|
||||
value(editortype == 'e' ? ENAME_EDITOR : ENAME_VISUAL)) == NULL)
|
||||
editcmd = value(editortype == 'e' ? ENAME_EDITOR : ENAME_VISUAL);
|
||||
if (editcmd == NULL)
|
||||
editcmd = editortype == 'e' ? _PATH_EX : _PATH_VI;
|
||||
if (run_command(editcmd, 0, 0, -1, tempname, NULL) < 0) {
|
||||
if (run_command(editcmd, NULL, 0, -1, tempname, NULL) < 0) {
|
||||
(void)unlink(tempname);
|
||||
goto out;
|
||||
}
|
||||
|
@ -163,14 +164,15 @@ edit1(int *msgvec, int editortype)
|
|||
*/
|
||||
msgCount = get_msgCount();
|
||||
for (i = 0; msgvec[i] && i < msgCount; i++) {
|
||||
sig_t sigint;
|
||||
sigset_t oset;
|
||||
struct sigaction osa;
|
||||
|
||||
if (i > 0) {
|
||||
char buf[100];
|
||||
char *p;
|
||||
|
||||
(void)printf("Edit message %d [ynq]? ", msgvec[i]);
|
||||
if (fgets(buf, sizeof(buf), stdin) == 0)
|
||||
if (fgets(buf, (int)sizeof(buf), stdin) == 0)
|
||||
break;
|
||||
p = skip_WSP(buf);
|
||||
if (*p == 'q')
|
||||
|
@ -180,7 +182,8 @@ edit1(int *msgvec, int editortype)
|
|||
}
|
||||
dot = mp = get_message(msgvec[i]);
|
||||
touch(mp);
|
||||
sigint = signal(SIGINT, SIG_IGN);
|
||||
sig_check();
|
||||
(void)sig_ignore(SIGINT, &osa, &oset);
|
||||
fp = run_editor(setinput(mp), mp->m_size, editortype,
|
||||
readonly);
|
||||
if (fp != NULL) {
|
||||
|
@ -213,7 +216,8 @@ edit1(int *msgvec, int editortype)
|
|||
warn("/tmp");
|
||||
(void)Fclose(fp);
|
||||
}
|
||||
(void)signal(SIGINT, sigint);
|
||||
(void)sig_restore(SIGINT, &osa, &oset);
|
||||
sig_check();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: extern.h,v 1.30 2007/10/27 15:14:50 christos Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.31 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -29,7 +29,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)extern.h 8.2 (Berkeley) 4/20/95
|
||||
* $NetBSD: extern.h,v 1.30 2007/10/27 15:14:50 christos Exp $
|
||||
* $NetBSD: extern.h,v 1.31 2009/04/10 13:08:24 christos Exp $
|
||||
*/
|
||||
|
||||
#ifndef __EXTERN_H__
|
||||
|
@ -126,6 +126,7 @@ void sort(const char **);
|
|||
struct smopts_s *findsmopts(const char *, int);
|
||||
int smoptscmd(void *);
|
||||
int unsmoptscmd(void *);
|
||||
int Header(void *);
|
||||
|
||||
/*
|
||||
* from cmdtab.c
|
||||
|
@ -158,10 +159,11 @@ const char *expand(const char *);
|
|||
off_t fsize(FILE *);
|
||||
const char *getdeadletter(void);
|
||||
int getfold(char *, size_t);
|
||||
void holdsigs(void);
|
||||
int mail_readline(FILE *, char *, int);
|
||||
#ifdef USE_EDITLINE
|
||||
#define readline xreadline /* readline() is defined in libedit */
|
||||
#endif
|
||||
int readline(FILE *, char *, int, int);
|
||||
int putline(FILE *, const char *, int);
|
||||
void relsesigs(void);
|
||||
int rm(char *);
|
||||
FILE * setinput(const struct message *);
|
||||
void setptr(FILE *, off_t);
|
||||
|
@ -201,7 +203,7 @@ int first(int, int);
|
|||
int get_Hflag(char **);
|
||||
int getmsglist(char *, int *, int);
|
||||
int getrawlist(const char [], char **, int);
|
||||
int show_headers_and_exit(int) __attribute__((__noreturn__));
|
||||
int show_headers_and_exit(int) __dead;
|
||||
|
||||
/*
|
||||
* from main.c
|
||||
|
@ -253,7 +255,7 @@ void flush_files(FILE *, int);
|
|||
/*
|
||||
* from quit.c
|
||||
*/
|
||||
void quit(void);
|
||||
void quit(jmp_buf);
|
||||
int quitcmd(void *);
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fio.c,v 1.31 2007/10/29 23:20:38 christos Exp $ */
|
||||
/* $NetBSD: fio.c,v 1.32 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,13 +34,14 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)fio.c 8.2 (Berkeley) 4/20/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: fio.c,v 1.31 2007/10/29 23:20:38 christos Exp $");
|
||||
__RCSID("$NetBSD: fio.c,v 1.32 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include "rcv.h"
|
||||
#include "extern.h"
|
||||
#include "thread.h"
|
||||
#include "sig.h"
|
||||
|
||||
/*
|
||||
* Mail -- a mail program
|
||||
|
@ -215,10 +216,8 @@ setptr(FILE *ibuf, off_t offset)
|
|||
|
||||
for (;;) {
|
||||
if (fgets(linebuf, LINESIZE, ibuf) == NULL) {
|
||||
if (append(&this, mestmp)) {
|
||||
warn("temporary file");
|
||||
exit(1);
|
||||
}
|
||||
if (append(&this, mestmp))
|
||||
err(EXIT_FAILURE, "temporary file");
|
||||
makemessage(mestmp, omsgCount, nmsgCount);
|
||||
return;
|
||||
}
|
||||
|
@ -234,18 +233,14 @@ setptr(FILE *ibuf, off_t offset)
|
|||
len--;
|
||||
}
|
||||
(void)fwrite(linebuf, sizeof(*linebuf), len, otf);
|
||||
if (ferror(otf)) {
|
||||
warn("/tmp");
|
||||
exit(1);
|
||||
}
|
||||
if (ferror(otf))
|
||||
err(EXIT_FAILURE, "/tmp");
|
||||
if(len)
|
||||
linebuf[len - 1] = 0;
|
||||
if (maybe && linebuf[0] == 'F' && ishead(linebuf)) {
|
||||
nmsgCount++;
|
||||
if (append(&this, mestmp)) {
|
||||
warn("temporary file");
|
||||
exit(1);
|
||||
}
|
||||
if (append(&this, mestmp))
|
||||
err(EXIT_FAILURE, "temporary file");
|
||||
message_init(&this, offset, MUSED|MNEW);
|
||||
inhead = 1;
|
||||
} else if (linebuf[0] == 0) {
|
||||
|
@ -274,7 +269,7 @@ setptr(FILE *ibuf, off_t offset)
|
|||
this.m_lines++;
|
||||
if (!inhead) {
|
||||
int lines_plus_wraps = 1;
|
||||
size_t linelen = strlen(linebuf);
|
||||
int linelen = (int)strlen(linebuf);
|
||||
|
||||
if (screenwidth && (int)linelen > screenwidth) {
|
||||
lines_plus_wraps = linelen / screenwidth;
|
||||
|
@ -305,7 +300,7 @@ putline(FILE *obuf, const char *linebuf, int outlf)
|
|||
}
|
||||
if (ferror(obuf))
|
||||
return -1;
|
||||
return c;
|
||||
return (int)c;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -314,16 +309,34 @@ putline(FILE *obuf, const char *linebuf, int outlf)
|
|||
* include the newline at the end.
|
||||
*/
|
||||
PUBLIC int
|
||||
mail_readline(FILE *ibuf, char *linebuf, int linesize)
|
||||
readline(FILE *ibuf, char *linebuf, int linesize, int no_restart)
|
||||
{
|
||||
struct sigaction osa_sigtstp;
|
||||
struct sigaction osa_sigttin;
|
||||
struct sigaction osa_sigttou;
|
||||
int n;
|
||||
|
||||
clearerr(ibuf);
|
||||
|
||||
sig_check();
|
||||
if (no_restart) {
|
||||
(void)sig_setflags(SIGTSTP, 0, &osa_sigtstp);
|
||||
(void)sig_setflags(SIGTTIN, 0, &osa_sigttin);
|
||||
(void)sig_setflags(SIGTTOU, 0, &osa_sigttou);
|
||||
}
|
||||
if (fgets(linebuf, linesize, ibuf) == NULL)
|
||||
return -1;
|
||||
n = strlen(linebuf);
|
||||
if (n > 0 && linebuf[n - 1] == '\n')
|
||||
linebuf[--n] = '\0';
|
||||
n = -1;
|
||||
else {
|
||||
n = (int)strlen(linebuf);
|
||||
if (n > 0 && linebuf[n - 1] == '\n')
|
||||
linebuf[--n] = '\0';
|
||||
}
|
||||
if (no_restart) {
|
||||
(void)sigaction(SIGTSTP, &osa_sigtstp, NULL);
|
||||
(void)sigaction(SIGTTIN, &osa_sigttin, NULL);
|
||||
(void)sigaction(SIGTTOU, &osa_sigttou, NULL);
|
||||
}
|
||||
sig_check();
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -358,35 +371,6 @@ rm(char *name)
|
|||
return unlink(name);
|
||||
}
|
||||
|
||||
static int sigdepth; /* depth of holdsigs() */
|
||||
static sigset_t nset, oset;
|
||||
/*
|
||||
* Hold signals SIGHUP, SIGINT, and SIGQUIT.
|
||||
*/
|
||||
PUBLIC void
|
||||
holdsigs(void)
|
||||
{
|
||||
|
||||
if (sigdepth++ == 0) {
|
||||
(void)sigemptyset(&nset);
|
||||
(void)sigaddset(&nset, SIGHUP);
|
||||
(void)sigaddset(&nset, SIGINT);
|
||||
(void)sigaddset(&nset, SIGQUIT);
|
||||
(void)sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Release signals SIGHUP, SIGINT, and SIGQUIT.
|
||||
*/
|
||||
PUBLIC void
|
||||
relsesigs(void)
|
||||
{
|
||||
|
||||
if (--sigdepth == 0)
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the size of the file possessed by
|
||||
* the passed buffer.
|
||||
|
@ -434,7 +418,8 @@ expand(const char *name)
|
|||
{
|
||||
char xname[PATHSIZE];
|
||||
char cmdbuf[PATHSIZE]; /* also used for file names */
|
||||
int pid, l;
|
||||
pid_t pid;
|
||||
ssize_t l;
|
||||
char *cp;
|
||||
const char *shellcmd;
|
||||
int pivec[2];
|
||||
|
@ -481,7 +466,7 @@ expand(const char *name)
|
|||
(void)snprintf(cmdbuf, sizeof(cmdbuf), "echo %s", name);
|
||||
if ((shellcmd = value(ENAME_SHELL)) == NULL)
|
||||
shellcmd = _PATH_CSHELL;
|
||||
pid = start_command(shellcmd, 0, -1, pivec[1], "-c", cmdbuf, NULL);
|
||||
pid = start_command(shellcmd, NULL, -1, pivec[1], "-c", cmdbuf, NULL);
|
||||
if (pid < 0) {
|
||||
(void)close(pivec[0]);
|
||||
(void)close(pivec[1]);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: format.c,v 1.13 2008/04/28 20:24:14 martin Exp $ */
|
||||
/* $NetBSD: format.c,v 1.14 2009/04/10 13:08:24 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef __lint__
|
||||
__RCSID("$NetBSD: format.c,v 1.13 2008/04/28 20:24:14 martin Exp $");
|
||||
__RCSID("$NetBSD: format.c,v 1.14 2009/04/10 13:08:24 christos Exp $");
|
||||
#endif /* not __lint__ */
|
||||
|
||||
#include <time.h>
|
||||
|
@ -796,7 +796,7 @@ dateof(struct tm *tm, struct message *mp, int use_hl_date)
|
|||
*/
|
||||
tm->tm_isdst = -1; /* let mktime(3) determine tm_isdst */
|
||||
headline[0] = '\0';
|
||||
(void)mail_readline(setinput(mp), headline, sizeof(headline));
|
||||
(void)readline(setinput(mp), headline, (int)sizeof(headline), 0);
|
||||
parse(headline, &hl, pbuf);
|
||||
if (hl.l_date == NULL)
|
||||
warnx("invalid headline: `%s'", headline);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: glob.h,v 1.11 2007/10/30 02:28:31 christos Exp $ */
|
||||
/* $NetBSD: glob.h,v 1.12 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -29,7 +29,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)glob.h 8.1 (Berkeley) 6/6/93
|
||||
* $NetBSD: glob.h,v 1.11 2007/10/30 02:28:31 christos Exp $
|
||||
* $NetBSD: glob.h,v 1.12 2009/04/10 13:08:25 christos Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -90,8 +90,6 @@ EXTERN int wait_status; /* wait status set by wait_child() */
|
|||
EXTERN int cond; /* Current state of conditional exc. */
|
||||
EXTERN struct cond_stack_s *cond_stack; /* stack for if/else/endif condition */
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
EXTERN jmp_buf srbuf;
|
||||
EXTERN struct name *extra_headers; /* extra header lines */
|
||||
|
||||
#endif /* __GLOB_H__ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lex.c,v 1.36 2007/12/17 22:06:00 christos Exp $ */
|
||||
/* $NetBSD: lex.c,v 1.37 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,19 +34,20 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)lex.c 8.2 (Berkeley) 4/20/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: lex.c,v 1.36 2007/12/17 22:06:00 christos Exp $");
|
||||
__RCSID("$NetBSD: lex.c,v 1.37 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <util.h>
|
||||
|
||||
#include "rcv.h"
|
||||
#include <util.h>
|
||||
#include "extern.h"
|
||||
#ifdef USE_EDITLINE
|
||||
#include "complete.h"
|
||||
#endif
|
||||
#include "format.h"
|
||||
#include "sig.h"
|
||||
#include "thread.h"
|
||||
|
||||
/*
|
||||
|
@ -57,8 +58,88 @@ __RCSID("$NetBSD: lex.c,v 1.36 2007/12/17 22:06:00 christos Exp $");
|
|||
|
||||
static const char *prompt = DEFAULT_PROMPT;
|
||||
static int *msgvec;
|
||||
static int reset_on_stop; /* do a reset() if stopped */
|
||||
static int inithdr; /* Am printing startup headers. */
|
||||
static jmp_buf jmpbuf; /* The reset jmpbuf */
|
||||
static int reset_on_stop; /* To do job control longjmp. */
|
||||
|
||||
#ifdef DEBUG_FILE_LEAK
|
||||
struct glue {
|
||||
struct glue *next;
|
||||
int niobs;
|
||||
FILE *iobs;
|
||||
};
|
||||
extern struct glue __sglue;
|
||||
|
||||
static int open_fd_cnt;
|
||||
static int open_fp_cnt;
|
||||
|
||||
static int
|
||||
file_count(void)
|
||||
{
|
||||
struct glue *gp;
|
||||
FILE *fp;
|
||||
int n;
|
||||
int cnt;
|
||||
|
||||
cnt = 0;
|
||||
for (gp = &__sglue; gp; gp = gp->next) {
|
||||
for (fp = gp->iobs, n = gp->niobs; --n >= 0; fp++)
|
||||
if (fp->_flags)
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static int
|
||||
fds_count(void)
|
||||
{
|
||||
int maxfd;
|
||||
int cnt;
|
||||
int fd;
|
||||
|
||||
maxfd = fcntl(0, F_MAXFD);
|
||||
if (maxfd == -1) {
|
||||
warn("fcntl");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
for (fd = 0; fd <= maxfd; fd++) {
|
||||
struct stat sb;
|
||||
|
||||
if (fstat(fd, &sb) != -1)
|
||||
cnt++;
|
||||
else if (errno != EBADF
|
||||
#ifdef BROKEN_CLONE_STAT /* see PRs 37878 and 37550 */
|
||||
&& errno != EOPNOTSUPP
|
||||
#endif
|
||||
)
|
||||
warn("fstat(%d): errno=%d", fd, errno);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static void
|
||||
file_leak_init(void)
|
||||
{
|
||||
open_fd_cnt = fds_count();
|
||||
open_fp_cnt = file_count();
|
||||
}
|
||||
|
||||
static void
|
||||
file_leak_check(void)
|
||||
{
|
||||
if (open_fp_cnt != file_count() ||
|
||||
open_fd_cnt != fds_count()) {
|
||||
(void)printf("FILE LEAK WARNING: "
|
||||
"fp-count: %d (%d) "
|
||||
"fd-count: %d (%d) max-fd: %d\n",
|
||||
file_count(), open_fp_cnt,
|
||||
fds_count(), open_fd_cnt,
|
||||
fcntl(0, F_MAXFD));
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG_FILE_LEAK */
|
||||
|
||||
/*
|
||||
* Set the size of the message vector used to construct argument
|
||||
|
@ -129,9 +210,10 @@ setfile(const char *name)
|
|||
* the message[] data structure.
|
||||
*/
|
||||
|
||||
holdsigs();
|
||||
sig_check();
|
||||
sig_hold();
|
||||
if (shudclob)
|
||||
quit();
|
||||
quit(jmpbuf);
|
||||
|
||||
/*
|
||||
* Copy the messages into /tmp
|
||||
|
@ -172,7 +254,8 @@ setfile(const char *name)
|
|||
*/
|
||||
mailsize = ftell(ibuf);
|
||||
(void)Fclose(ibuf);
|
||||
relsesigs();
|
||||
sig_release();
|
||||
sig_check();
|
||||
sawcom = 0;
|
||||
if (!edit && get_abs_msgCount() == 0) {
|
||||
nomail:
|
||||
|
@ -199,7 +282,8 @@ incfile(void)
|
|||
ibuf = Fopen(mailname, "r");
|
||||
if (ibuf == NULL)
|
||||
return -1;
|
||||
holdsigs();
|
||||
sig_check();
|
||||
sig_hold();
|
||||
newsize = fsize(ibuf);
|
||||
if (newsize == 0 || /* mail box is now empty??? */
|
||||
newsize < mailsize) { /* mail box has shrunk??? */
|
||||
|
@ -216,7 +300,8 @@ incfile(void)
|
|||
rval = get_abs_msgCount() - omsgCount;
|
||||
done:
|
||||
(void)Fclose(ibuf);
|
||||
relsesigs();
|
||||
sig_release();
|
||||
sig_check();
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -244,29 +329,6 @@ comment_char(char *line)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* When we wake up after ^Z, reprint the prompt.
|
||||
*/
|
||||
static void
|
||||
stop(int s)
|
||||
{
|
||||
sig_t old_action = signal(s, SIG_DFL);
|
||||
sigset_t nset;
|
||||
|
||||
(void)sigemptyset(&nset);
|
||||
(void)sigaddset(&nset, s);
|
||||
(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
|
||||
(void)kill(0, s);
|
||||
(void)sigprocmask(SIG_BLOCK, &nset, NULL);
|
||||
(void)signal(s, old_action);
|
||||
if (reset_on_stop) {
|
||||
reset_on_stop = 0;
|
||||
reset(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Signal handler is hooked by setup_piping().
|
||||
* Respond to a broken pipe signal --
|
||||
|
@ -276,9 +338,10 @@ static jmp_buf pipestop;
|
|||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
brokpipe(int signo __unused)
|
||||
lex_brokpipe(int signo)
|
||||
{
|
||||
longjmp(pipestop, 1);
|
||||
|
||||
longjmp(pipestop, signo);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -331,19 +394,51 @@ shellpr(char *cp)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
do_paging(const char *cmd, int c_pipe)
|
||||
{
|
||||
char *cp, *p;
|
||||
|
||||
if (value(ENAME_PAGER_OFF) != NULL)
|
||||
return 0;
|
||||
|
||||
if (c_pipe & C_PIPE_PAGER)
|
||||
return 1;
|
||||
|
||||
if (c_pipe & C_PIPE_CRT && value(ENAME_CRT) != NULL)
|
||||
return 1;
|
||||
|
||||
if ((cp = value(ENAME_PAGE_ALSO)) == NULL)
|
||||
return 0;
|
||||
|
||||
if ((p = strcasestr(cp, cmd)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (p != cp && p[-1] != ',' && !is_WSP(p[-1]))
|
||||
return 0;
|
||||
|
||||
p += strlen(cmd);
|
||||
|
||||
return (*p == '\0' || *p == ',' || is_WSP(*p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup any pipe or redirection that the command line indicates.
|
||||
* If none, then setup the pager unless "pager-off" is defined.
|
||||
*/
|
||||
static FILE *fp_stop = NULL;
|
||||
static int oldfd1 = -1;
|
||||
static sig_t old_sigpipe;
|
||||
|
||||
static int
|
||||
setup_piping(char *cmdline, int c_pipe)
|
||||
setup_piping(const char *cmd, char *cmdline, int c_pipe)
|
||||
{
|
||||
FILE *fout;
|
||||
FILE *last_file;
|
||||
char *cp;
|
||||
|
||||
sig_check();
|
||||
|
||||
last_file = last_registered_file(0);
|
||||
|
||||
fout = NULL;
|
||||
|
@ -374,8 +469,7 @@ setup_piping(char *cmdline, int c_pipe)
|
|||
}
|
||||
|
||||
}
|
||||
else if (value(ENAME_PAGER_OFF) == NULL && (c_pipe & C_PIPE_PAGER ||
|
||||
(c_pipe & C_PIPE_CRT && value(ENAME_CRT) != NULL))) {
|
||||
else if (do_paging(cmd, c_pipe)) {
|
||||
const char *pager;
|
||||
pager = value(ENAME_PAGER);
|
||||
if (pager == NULL || *pager == '\0')
|
||||
|
@ -388,7 +482,7 @@ setup_piping(char *cmdline, int c_pipe)
|
|||
}
|
||||
|
||||
if (fout) {
|
||||
(void)signal(SIGPIPE, brokpipe);
|
||||
old_sigpipe = sig_signal(SIGPIPE, lex_brokpipe);
|
||||
(void)fflush(stdout);
|
||||
if ((oldfd1 = dup(STDOUT_FILENO)) == -1)
|
||||
err(EXIT_FAILURE, "dup failed");
|
||||
|
@ -405,19 +499,26 @@ setup_piping(char *cmdline, int c_pipe)
|
|||
static void
|
||||
close_piping(void)
|
||||
{
|
||||
sigset_t oset;
|
||||
struct sigaction osa;
|
||||
|
||||
if (oldfd1 != -1) {
|
||||
(void)fflush(stdout);
|
||||
if (fileno(stdout) != oldfd1 &&
|
||||
dup2(oldfd1, STDOUT_FILENO) == -1)
|
||||
err(EXIT_FAILURE, "dup2 failed");
|
||||
|
||||
(void)signal(SIGPIPE, SIG_IGN);
|
||||
(void)sig_ignore(SIGPIPE, &osa, &oset);
|
||||
|
||||
close_top_files(fp_stop);
|
||||
fp_stop = NULL;
|
||||
(void)close(oldfd1);
|
||||
oldfd1 = -1;
|
||||
(void)signal(SIGPIPE, SIG_DFL);
|
||||
|
||||
(void)sig_signal(SIGPIPE, old_sigpipe);
|
||||
(void)sig_restore(SIGPIPE, &osa, &oset);
|
||||
}
|
||||
sig_check();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -486,6 +587,7 @@ execute(char linebuf[], enum execute_contxt_e contxt)
|
|||
char *arglist[MAXARGC];
|
||||
const struct cmd *com = NULL;
|
||||
char *volatile cp;
|
||||
int retval;
|
||||
int c;
|
||||
int e = 1;
|
||||
|
||||
|
@ -563,10 +665,12 @@ execute(char linebuf[], enum execute_contxt_e contxt)
|
|||
}
|
||||
|
||||
if (!sourcing && com->c_pipe && value(ENAME_INTERACTIVE) != NULL) {
|
||||
|
||||
sig_check();
|
||||
if (setjmp(pipestop))
|
||||
goto out;
|
||||
|
||||
if (setup_piping(cp, com->c_pipe) == -1)
|
||||
if (setup_piping(com->c_name, cp, com->c_pipe) == -1)
|
||||
goto out;
|
||||
}
|
||||
switch (com->c_argtype & ARGTYPE_MASK) {
|
||||
|
@ -619,8 +723,7 @@ execute(char linebuf[], enum execute_contxt_e contxt)
|
|||
/*
|
||||
* A vector of strings, in shell style.
|
||||
*/
|
||||
if ((c = getrawlist(cp, arglist,
|
||||
sizeof(arglist) / sizeof(*arglist))) < 0)
|
||||
if ((c = getrawlist(cp, arglist, (int)__arraycount(arglist))) < 0)
|
||||
break;
|
||||
if (c < com->c_minargs) {
|
||||
(void)printf("%s requires at least %d arg(s)\n",
|
||||
|
@ -654,39 +757,38 @@ out:
|
|||
* Exit the current source file on
|
||||
* error.
|
||||
*/
|
||||
retval = 0;
|
||||
if (e) {
|
||||
if (e < 0)
|
||||
return 1;
|
||||
if (loading)
|
||||
return 1;
|
||||
if (sourcing)
|
||||
retval = 1;
|
||||
else if (loading)
|
||||
retval = 1;
|
||||
else if (sourcing)
|
||||
(void)unstack();
|
||||
return 0;
|
||||
}
|
||||
if (com == NULL)
|
||||
return 0;
|
||||
if (contxt != ec_autoprint && com->c_argtype & P &&
|
||||
value(ENAME_AUTOPRINT) != NULL && (dot->m_flag & MDELETED) == 0)
|
||||
(void)execute(__UNCONST("print ."), ec_autoprint);
|
||||
if (!sourcing && (com->c_argtype & T) == 0)
|
||||
sawcom = 1;
|
||||
return 0;
|
||||
else if (com != NULL) {
|
||||
if (contxt != ec_autoprint && com->c_argtype & P &&
|
||||
value(ENAME_AUTOPRINT) != NULL &&
|
||||
(dot->m_flag & MDELETED) == 0)
|
||||
(void)execute(__UNCONST("print ."), ec_autoprint);
|
||||
if (!sourcing && (com->c_argtype & T) == 0)
|
||||
sawcom = 1;
|
||||
}
|
||||
sig_check();
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following gets called on receipt of an interrupt. This is
|
||||
* to abort printout of a command, mainly.
|
||||
* Dispatching here when command() is inactive crashes rcv.
|
||||
* Dispatching here when commands() is inactive crashes rcv.
|
||||
* Close all open files except 0, 1, 2, and the temporary.
|
||||
* Also, unstack all source files.
|
||||
*/
|
||||
static int inithdr; /* am printing startup headers */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
intr(int s __unused)
|
||||
lex_intr(int signo)
|
||||
{
|
||||
|
||||
noreset = 0;
|
||||
if (!inithdr)
|
||||
sawcom++;
|
||||
|
@ -702,7 +804,7 @@ intr(int s __unused)
|
|||
image = -1;
|
||||
}
|
||||
(void)fprintf(stderr, "Interrupt\n");
|
||||
reset(0);
|
||||
longjmp(jmpbuf, signo);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -710,10 +812,27 @@ intr(int s __unused)
|
|||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
hangup(int s __unused)
|
||||
lex_hangup(int s __unused)
|
||||
{
|
||||
|
||||
/* nothing to do? */
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* When we wake up after ^Z, reprint the prompt.
|
||||
*
|
||||
* NOTE: EditLine deals with the prompt and job control, so with it
|
||||
* this does nothing, i.e., reset_on_stop == 0.
|
||||
*/
|
||||
static void
|
||||
lex_stop(int signo)
|
||||
{
|
||||
|
||||
if (reset_on_stop) {
|
||||
reset_on_stop = 0;
|
||||
longjmp(jmpbuf, signo);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -727,18 +846,27 @@ commands(void)
|
|||
char linebuf[LINESIZE];
|
||||
int eofloop;
|
||||
|
||||
#ifdef DEBUG_FILE_LEAK
|
||||
file_leak_init();
|
||||
#endif
|
||||
|
||||
if (!sourcing) {
|
||||
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
|
||||
(void)signal(SIGINT, intr);
|
||||
if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
|
||||
(void)signal(SIGHUP, hangup);
|
||||
(void)signal(SIGTSTP, stop);
|
||||
(void)signal(SIGTTOU, stop);
|
||||
(void)signal(SIGTTIN, stop);
|
||||
sig_check();
|
||||
|
||||
sig_hold();
|
||||
(void)sig_signal(SIGINT, lex_intr);
|
||||
(void)sig_signal(SIGHUP, lex_hangup);
|
||||
(void)sig_signal(SIGTSTP, lex_stop);
|
||||
(void)sig_signal(SIGTTOU, lex_stop);
|
||||
(void)sig_signal(SIGTTIN, lex_stop);
|
||||
sig_release();
|
||||
}
|
||||
setexit(); /* defined as (void)setjmp(srbuf) in def.h */
|
||||
|
||||
(void)setjmp(jmpbuf); /* "reset" location if we got an interrupt */
|
||||
|
||||
eofloop = 0; /* initialize this after a possible longjmp */
|
||||
for (;;) {
|
||||
sig_check();
|
||||
(void)fflush(stdout);
|
||||
sreset();
|
||||
/*
|
||||
|
@ -751,82 +879,83 @@ commands(void)
|
|||
prompt = smsgprintf(prompt, dot);
|
||||
if ((value(ENAME_AUTOINC) != NULL) && (incfile() > 0))
|
||||
(void)printf("New mail has arrived.\n");
|
||||
reset_on_stop = 1;
|
||||
|
||||
#ifndef USE_EDITLINE
|
||||
reset_on_stop = 1; /* enable job control longjmp */
|
||||
(void)printf("%s", prompt);
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_FILE_LEAK
|
||||
file_leak_check();
|
||||
#endif
|
||||
/*
|
||||
* Read a line of commands from the current input
|
||||
* and handle end of file specially.
|
||||
*/
|
||||
n = 0;
|
||||
for (;;) {
|
||||
sig_check();
|
||||
#ifdef USE_EDITLINE
|
||||
if (!sourcing) {
|
||||
char *line;
|
||||
if ((line = my_gets(&elm.command, prompt, NULL)) == NULL) {
|
||||
|
||||
line = my_gets(&elm.command, prompt, NULL);
|
||||
if (line == NULL) {
|
||||
if (n == 0)
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
(void)strlcpy(linebuf, line, sizeof(linebuf));
|
||||
setscreensize(); /* so we can resize a window */
|
||||
}
|
||||
else {
|
||||
if (mail_readline(input, &linebuf[n], LINESIZE - n) < 0) {
|
||||
if (readline(input, &linebuf[n], LINESIZE - n, 0) < 0) {
|
||||
if (n == 0)
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else /* USE_EDITLINE */
|
||||
if (mail_readline(input, &linebuf[n], LINESIZE - n) < 0) {
|
||||
if (readline(input, &linebuf[n], LINESIZE - n, reset_on_stop) < 0) {
|
||||
if (n == 0)
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
#endif /* USE_EDITLINE */
|
||||
if (!sourcing)
|
||||
setscreensize(); /* so we can resize window */
|
||||
|
||||
if (sourcing) { /* allow comments in source files */
|
||||
char *ptr;
|
||||
if ((ptr = comment_char(linebuf)) != NULL)
|
||||
*ptr = '\0';
|
||||
}
|
||||
if ((n = strlen(linebuf)) == 0)
|
||||
if ((n = (int)strlen(linebuf)) == 0)
|
||||
break;
|
||||
n--;
|
||||
if (linebuf[n] != '\\')
|
||||
break;
|
||||
linebuf[n++] = ' ';
|
||||
}
|
||||
reset_on_stop = 0;
|
||||
#ifndef USE_EDITLINE
|
||||
sig_check();
|
||||
reset_on_stop = 0; /* disable job control longjmp */
|
||||
#endif
|
||||
if (n < 0) {
|
||||
/* eof */
|
||||
char *p;
|
||||
|
||||
/* eof */
|
||||
if (loading)
|
||||
break;
|
||||
if (sourcing) {
|
||||
(void)unstack();
|
||||
continue;
|
||||
}
|
||||
#ifdef USE_EDITLINE
|
||||
{
|
||||
char *p;
|
||||
if (value(ENAME_INTERACTIVE) != NULL &&
|
||||
(p = value(ENAME_IGNOREEOF)) != NULL &&
|
||||
++eofloop < (*p == '\0' ? 25 : atoi(p))) {
|
||||
(void)printf("Use \"quit\" to quit.\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (value(ENAME_INTERACTIVE) != NULL &&
|
||||
value(ENAME_IGNOREEOF) != NULL &&
|
||||
++eofloop < 25) {
|
||||
(p = value(ENAME_IGNOREEOF)) != NULL &&
|
||||
++eofloop < (*p == '\0' ? 25 : atoi(p))) {
|
||||
(void)printf("Use \"quit\" to quit.\n");
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
eofloop = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: list.c,v 1.24 2008/12/07 19:21:00 christos Exp $ */
|
||||
/* $NetBSD: list.c,v 1.25 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)list.c 8.4 (Berkeley) 5/1/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: list.c,v 1.24 2008/12/07 19:21:00 christos Exp $");
|
||||
__RCSID("$NetBSD: list.c,v 1.25 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -727,7 +727,7 @@ matchfrom(int (*cmpfn)(void *, char *, size_t),
|
|||
#ifdef __lint__
|
||||
fieldname = fieldname;
|
||||
#endif
|
||||
(void)mail_readline(setinput(mp), headline, sizeof(headline));
|
||||
(void)readline(setinput(mp), headline, (int)sizeof(headline), 0);
|
||||
field = savestr(headline);
|
||||
if (strncmp(field, "From ", 5) != 0)
|
||||
return 1;
|
||||
|
@ -1286,7 +1286,7 @@ getmsglist(char *buf, int *vector, int flags)
|
|||
if (mp->m_flag & MMARK)
|
||||
*ip++ = get_msgnum(mp);
|
||||
*ip = 0;
|
||||
return ip - vector;
|
||||
return (int)(ip - vector);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1320,6 +1320,10 @@ show_headers_and_exit(int flags)
|
|||
{
|
||||
struct message *mp;
|
||||
|
||||
/* We are exiting anyway, so use the default signal handler. */
|
||||
if (signal(SIGINT, SIG_DFL) == SIG_IGN)
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
|
||||
flags &= CMMASK;
|
||||
for (mp = get_message(1); mp; mp = next_message(mp))
|
||||
if (flags == 0 || !ignore_message(mp->m_flag, flags))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: mail.1,v 1.55 2009/03/23 17:02:06 joerg Exp $
|
||||
.\" $NetBSD: mail.1,v 1.56 2009/04/10 13:08:25 christos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
|
@ -29,7 +29,7 @@
|
|||
.\"
|
||||
.\" @(#)mail.1 8.8 (Berkeley) 4/28/95
|
||||
.\"
|
||||
.Dd December 7, 2008
|
||||
.Dd February 18, 2009
|
||||
.Dt MAIL 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -43,9 +43,10 @@
|
|||
.Op Fl a Ar file
|
||||
.Op Fl b Ar bcc-addr
|
||||
.Op Fl c Ar cc-addr
|
||||
.Op Fl r Ar rcfile
|
||||
.Op Fl s Ar subject
|
||||
.Ar to-addr ...
|
||||
.Op Ar sendmail-flags
|
||||
.Op - Ar sendmail-flags
|
||||
.Nm
|
||||
.Op Fl EIiNnv
|
||||
.Op Fl H Ns Op colon-modifier
|
||||
|
@ -118,6 +119,13 @@ when reading mail or editing a mail folder.
|
|||
Inhibits reading
|
||||
.Pa /etc/mail.rc
|
||||
upon startup.
|
||||
.It Fl r
|
||||
Specify an alternate user rcfile to load.
|
||||
This overrides the value specified in the environment variable
|
||||
.Ev MAILRC
|
||||
which in turn overrides the default
|
||||
.Pa ~/.mailrc
|
||||
file.
|
||||
.It Fl s
|
||||
Specify subject on command line
|
||||
(only the first argument after the
|
||||
|
@ -499,6 +507,33 @@ but also saves MIME parts that don't have a filename associated with
|
|||
them.
|
||||
For the unnamed parts, a filename is suggested containing the message
|
||||
and part numbers, and the subtype.
|
||||
.It Ic Header
|
||||
.Pq Ic H
|
||||
Specify or show additional header fields.
|
||||
This is intended for adding extra header fields like
|
||||
.Dq Reply-To:
|
||||
or
|
||||
.Dq X-Organization:
|
||||
to the header.
|
||||
For example:
|
||||
.Bd -literal -offset 0
|
||||
Header X-Mailer: NetBSD mail(1) 9.1
|
||||
.Ed
|
||||
.Pp
|
||||
would add the
|
||||
.Dq X-Mailer: NetBSD mail(1) 9.1
|
||||
line to the message header.
|
||||
Without any arguments, the extra header fields are displayed.
|
||||
With only a header name (including the
|
||||
.Sq \&: ) ,
|
||||
it will delete all extra header fields with that name.
|
||||
Note: Although some syntax checking is done on the header line, care
|
||||
should be taken to ensure that it complies with RFC 2821 and 2822.
|
||||
Also, the extra header lines are not currently displayed by the
|
||||
.Ic \&~h
|
||||
tilde command when sending mail (use
|
||||
.Ic \&~:Header
|
||||
to see them).
|
||||
.It Ic More
|
||||
.Pq Ic M
|
||||
Like
|
||||
|
@ -1292,7 +1327,7 @@ Message headers currently being ignored (by the
|
|||
or
|
||||
.Ic retain
|
||||
command) are not included.
|
||||
.It Ic \&~F Ns Ar messages
|
||||
.It Ic \&~
|
||||
Identical to
|
||||
.Ic \&~f ,
|
||||
except all message headers are included.
|
||||
|
@ -1428,6 +1463,8 @@ and
|
|||
.Ic Type
|
||||
commands.
|
||||
Normally these commands do not invoke the pager.
|
||||
(See
|
||||
.Va page-also . )
|
||||
.It Ar debug
|
||||
Setting the binary option
|
||||
.Ar debug
|
||||
|
@ -1572,6 +1609,17 @@ in your home directory.
|
|||
Setting the binary option
|
||||
.Ar nosave
|
||||
prevents this.
|
||||
.It Ar page-also
|
||||
A comma or whitespace delimited list of additional commands to page.
|
||||
The comparisons are case insensitive, so if
|
||||
.Ic view
|
||||
is in the list, both
|
||||
.Ic view
|
||||
and
|
||||
.Ic View
|
||||
will page.
|
||||
.It Ar pager-off
|
||||
If set, disable the pager on all commands.
|
||||
.It Ar quiet
|
||||
Suppresses the printing of the version when first invoked.
|
||||
.It Ar recursive-commands
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: main.c,v 1.29 2008/07/21 14:19:24 lukem Exp $ */
|
||||
/* $NetBSD: main.c,v 1.30 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1993\
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 4/20/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: main.c,v 1.29 2008/07/21 14:19:24 lukem Exp $");
|
||||
__RCSID("$NetBSD: main.c,v 1.30 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -50,6 +50,7 @@ __RCSID("$NetBSD: main.c,v 1.29 2008/07/21 14:19:24 lukem Exp $");
|
|||
#include <util.h>
|
||||
|
||||
#include "extern.h"
|
||||
#include "sig.h"
|
||||
|
||||
#ifdef USE_EDITLINE
|
||||
#include "complete.h"
|
||||
|
@ -68,19 +69,26 @@ __RCSID("$NetBSD: main.c,v 1.29 2008/07/21 14:19:24 lukem Exp $");
|
|||
* Startup -- interface with user.
|
||||
*/
|
||||
|
||||
static jmp_buf hdrjmp;
|
||||
|
||||
/*
|
||||
* Interrupt printing of the headers.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
__dead
|
||||
static void
|
||||
hdrstop(int signo __unused)
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fflush(stdout);
|
||||
(void)fprintf(stderr, "\nInterrupt\n");
|
||||
longjmp(hdrjmp, 1);
|
||||
#ifdef MIME_SUPPORT
|
||||
(void)fputs("\
|
||||
Usage: mail [-EiInv] [-r rcfile] [-s subject] [-a file] [-c cc-addr]\n\
|
||||
[-b bcc-addr] to-addr ... [- sendmail-options ...]\n\
|
||||
mail [-EiInNv] [-H[colon-modifier]] -f [name]\n\
|
||||
mail [-EiInNv] [-H[colon-modifier]] [-u user]\n",
|
||||
stderr);
|
||||
#else /* MIME_SUPPORT */
|
||||
(void)fputs("\
|
||||
Usage: mail [-EiInv] [-r rcfile] [-s subject] [-c cc-addr] [-b bcc-addr]\n\
|
||||
to-addr ... [- sendmail-options ...]\n\
|
||||
mail [-EiInNv] [-H[colon-modifier]] -f [name]\n\
|
||||
mail [-EiInNv] [-H[colon-modifier]] [-u user]\n",
|
||||
stderr);
|
||||
#endif /* MIME_SUPPORT */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -168,7 +176,8 @@ lexpand(char *str, int ntype)
|
|||
PUBLIC int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
jmp_buf jmpbuf;
|
||||
struct sigaction sa;
|
||||
struct name *to, *cc, *bcc, *smopts;
|
||||
#ifdef MIME_SUPPORT
|
||||
struct name *attach_optargs;
|
||||
|
@ -177,9 +186,9 @@ main(int argc, char *argv[])
|
|||
char *subject;
|
||||
const char *ef;
|
||||
char nosrc = 0;
|
||||
sig_t prevint;
|
||||
const char *rc;
|
||||
int volatile Hflag;
|
||||
int Hflag;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* For portability, call setprogname() early, before
|
||||
|
@ -191,11 +200,17 @@ main(int argc, char *argv[])
|
|||
* Set up a reasonable environment.
|
||||
* Figure out whether we are being run interactively,
|
||||
* start the SIGCHLD catcher, and so forth.
|
||||
* (Other signals are setup later by sig_setup().)
|
||||
*/
|
||||
(void)signal(SIGCHLD, sigchild);
|
||||
(void)sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sa.sa_handler = sigchild;
|
||||
(void)sigaction(SIGCHLD, &sa, NULL);
|
||||
|
||||
if (isatty(0))
|
||||
assign(ENAME_INTERACTIVE, "");
|
||||
image = -1;
|
||||
|
||||
/*
|
||||
* Now, determine how we are being used.
|
||||
* We successively pick off - flags.
|
||||
|
@ -203,6 +218,7 @@ main(int argc, char *argv[])
|
|||
* of users to mail to. Argp will be set to point to the
|
||||
* first of these users.
|
||||
*/
|
||||
rc = NULL;
|
||||
ef = NULL;
|
||||
to = NULL;
|
||||
cc = NULL;
|
||||
|
@ -213,9 +229,9 @@ main(int argc, char *argv[])
|
|||
#ifdef MIME_SUPPORT
|
||||
attach_optargs = NULL;
|
||||
attach_end = NULL;
|
||||
while ((i = getopt(argc, argv, ":~EH:INT:a:b:c:dfins:u:v")) != -1)
|
||||
while ((i = getopt(argc, argv, ":~EH:INT:a:b:c:dfinr:s:u:v")) != -1)
|
||||
#else
|
||||
while ((i = getopt(argc, argv, ":~EH:INT:b:c:dfins:u:v")) != -1)
|
||||
while ((i = getopt(argc, argv, ":~EH:INT:b:c:dfinr:s:u:v")) != -1)
|
||||
#endif
|
||||
{
|
||||
switch (i) {
|
||||
|
@ -262,6 +278,9 @@ main(int argc, char *argv[])
|
|||
case 'd':
|
||||
debug++;
|
||||
break;
|
||||
case 'r':
|
||||
rc = optarg;
|
||||
break;
|
||||
case 's':
|
||||
/*
|
||||
* Give a subject field for sending from
|
||||
|
@ -356,23 +375,8 @@ main(int argc, char *argv[])
|
|||
(void)fprintf(stderr,
|
||||
"%s: unknown option -- %c\n", getprogname(),
|
||||
optopt);
|
||||
#ifdef MIME_SUPPORT
|
||||
(void)fputs("\
|
||||
Usage: mail [-EiInv] [-s subject] [-a file] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
|
||||
[- sendmail-options ...]\n\
|
||||
mail [-EiInNv] [-H[colon-modifier]] -f [name]\n\
|
||||
mail [-EiInNv] [-H[colon-modifier]] [-u user]\n",
|
||||
stderr);
|
||||
#else /* MIME_SUPPORT */
|
||||
(void)fputs("\
|
||||
Usage: mail [-EiInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
|
||||
[- sendmail-options ...]\n\
|
||||
mail [-EiInNv] [-H[colon-modifier]] -f [name]\n\
|
||||
mail [-EiInNv] [-H[colon-modifier]] [-u user]\n",
|
||||
stderr);
|
||||
#endif /* MIME_SUPPORT */
|
||||
|
||||
exit(1);
|
||||
usage(); /* print usage message and die */
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
|
||||
|
@ -405,7 +409,7 @@ Usage: mail [-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.
|
||||
*/
|
||||
if ((rc = getenv("MAILRC")) == 0)
|
||||
if (rc == NULL && (rc = getenv("MAILRC")) == NULL)
|
||||
rc = "~/.mailrc";
|
||||
load(expand(rc));
|
||||
setscreensize(); /* do this after loading the rcfile */
|
||||
|
@ -420,6 +424,8 @@ Usage: mail [-EiInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
|
|||
init_editline();
|
||||
#endif
|
||||
|
||||
sig_setup();
|
||||
|
||||
switch (mailmode) {
|
||||
case mm_sending:
|
||||
(void)mail(to, cc, bcc, smopts, subject,
|
||||
|
@ -441,23 +447,25 @@ Usage: mail [-EiInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
|
|||
ef = "%";
|
||||
if (setfile(ef) < 0)
|
||||
exit(1); /* error already reported */
|
||||
if (setjmp(hdrjmp) == 0) {
|
||||
if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
|
||||
(void)signal(SIGINT, hdrstop);
|
||||
if (value(ENAME_QUIET) == NULL)
|
||||
(void)printf("Mail version %s. Type ? for help.\n",
|
||||
version);
|
||||
if (mailmode == mm_hdrsonly)
|
||||
show_headers_and_exit(Hflag); /* NORETURN */
|
||||
announce();
|
||||
(void)fflush(stdout);
|
||||
(void)signal(SIGINT, prevint);
|
||||
if (value(ENAME_QUIET) == NULL)
|
||||
(void)printf("Mail version %s. Type ? for help.\n",
|
||||
version);
|
||||
if (mailmode == mm_hdrsonly)
|
||||
show_headers_and_exit(Hflag); /* NORETURN */
|
||||
announce();
|
||||
(void)fflush(stdout);
|
||||
|
||||
if (setjmp(jmpbuf) != 0) {
|
||||
/* Return here if quit() fails below. */
|
||||
(void)printf("Use 'exit' to quit without saving changes.\n");
|
||||
}
|
||||
commands();
|
||||
|
||||
/* Ignore these signals from now on! */
|
||||
(void)signal(SIGHUP, SIG_IGN);
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
(void)signal(SIGQUIT, SIG_IGN);
|
||||
quit();
|
||||
quit(jmpbuf);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mime_attach.c,v 1.11 2009/03/11 01:10:05 christos Exp $ */
|
||||
/* $NetBSD: mime_attach.c,v 1.12 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef __lint__
|
||||
__RCSID("$NetBSD: mime_attach.c,v 1.11 2009/03/11 01:10:05 christos Exp $");
|
||||
__RCSID("$NetBSD: mime_attach.c,v 1.12 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif /* not __lint__ */
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -41,7 +41,6 @@ __RCSID("$NetBSD: mime_attach.c,v 1.11 2009/03/11 01:10:05 christos Exp $");
|
|||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#include <magic.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -60,6 +59,7 @@ __RCSID("$NetBSD: mime_attach.c,v 1.11 2009/03/11 01:10:05 christos Exp $");
|
|||
#include "mime_child.h"
|
||||
#endif
|
||||
#include "glob.h"
|
||||
#include "sig.h"
|
||||
|
||||
#if 0
|
||||
/*
|
||||
|
@ -373,7 +373,7 @@ content_type_by_name(char *filename)
|
|||
}
|
||||
cp = magic_file(magic, filename);
|
||||
if (cp == NULL) {
|
||||
warnx("magic_file: %s", magic_error(magic));
|
||||
warnx("magic_load: %s", magic_error(magic));
|
||||
return NULL;
|
||||
}
|
||||
if (filename &&
|
||||
|
@ -787,9 +787,15 @@ get_line(el_mode_t *em, const char *pr, const char *str, int i)
|
|||
* seems to handle it badly.
|
||||
*/
|
||||
(void)easprintf(&prompt, "#%-7d %s: ", i, pr);
|
||||
line = my_getline(em, prompt, __UNCONST(str));
|
||||
/* LINTED */
|
||||
line = line ? savestr(line) : __UNCONST("");
|
||||
line = my_gets(em, prompt, __UNCONST(str));
|
||||
if (line != NULL) {
|
||||
(void)strip_WSP(line); /* strip trailing whitespace */
|
||||
line = skip_WSP(line); /* skip leading white space */
|
||||
line = savestr(line); /* XXX - do we need this? */
|
||||
}
|
||||
else {
|
||||
line = __UNCONST("");
|
||||
}
|
||||
free(prompt);
|
||||
|
||||
return line;
|
||||
|
@ -800,8 +806,8 @@ sget_line(el_mode_t *em, const char *pr, const char **str, int i)
|
|||
{
|
||||
char *line;
|
||||
line = get_line(em, pr, *str, i);
|
||||
if (strcmp(line, *str) != 0)
|
||||
*str = savestr(line);
|
||||
if (line != NULL && strcmp(line, *str) != 0)
|
||||
*str = line;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -949,14 +955,14 @@ edit_attachlist(struct attachment *alist)
|
|||
* Hook used by the '~@' escape to attach files.
|
||||
*/
|
||||
PUBLIC struct attachment*
|
||||
mime_attach_files(struct attachment *attach, char *linebuf)
|
||||
mime_attach_files(struct attachment * volatile attach, char *linebuf)
|
||||
{
|
||||
struct attachment *ap;
|
||||
char *argv[MAXARGC];
|
||||
int argc;
|
||||
int attach_num;
|
||||
|
||||
argc = getrawlist(linebuf, argv, sizeofarray(argv));
|
||||
argc = getrawlist(linebuf, argv, (int)__arraycount(argv));
|
||||
attach_num = 1;
|
||||
for (ap = attach; ap && ap->a_flink; ap = ap->a_flink)
|
||||
attach_num++;
|
||||
|
@ -1004,7 +1010,8 @@ mime_attach_optargs(struct name *optargs)
|
|||
int i;
|
||||
|
||||
if (expand_optargs != NULL)
|
||||
argc = getrawlist(np->n_name, argv, sizeofarray(argv));
|
||||
argc = getrawlist(np->n_name,
|
||||
argv, (int)__arraycount(argv));
|
||||
else {
|
||||
if (np->n_name == '\0')
|
||||
argc = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mime_codecs.c,v 1.8 2009/01/18 01:29:57 lukem Exp $ */
|
||||
/* $NetBSD: mime_codecs.c,v 1.9 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -52,7 +52,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef __lint__
|
||||
__RCSID("$NetBSD: mime_codecs.c,v 1.8 2009/01/18 01:29:57 lukem Exp $");
|
||||
__RCSID("$NetBSD: mime_codecs.c,v 1.9 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif /* not __lint__ */
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -276,7 +276,7 @@ mime_bintob64(char *b64, const char *bin, size_t cnt)
|
|||
static const char b64table[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
const unsigned char *p = (const unsigned char*)bin;
|
||||
int i;
|
||||
ssize_t i;
|
||||
|
||||
for (i = cnt; i > 0; i -= 3) {
|
||||
unsigned a = p[0];
|
||||
|
@ -314,7 +314,7 @@ mime_fB64_encode(FILE *fi, FILE *fo, void *cookie __unused)
|
|||
{
|
||||
static char b64[MIME_BASE64_LINE_MAX];
|
||||
static char mem[3 * (MIME_BASE64_LINE_MAX / 4)];
|
||||
int cnt;
|
||||
size_t cnt;
|
||||
char *cp;
|
||||
size_t limit;
|
||||
#ifdef __lint__
|
||||
|
@ -530,9 +530,9 @@ mime_fQP_decode(FILE *fi, FILE *fo, void *cookie __unused)
|
|||
cookie = cookie;
|
||||
#endif
|
||||
while ((line = fgetln(fi, &len)) != NULL) {
|
||||
int c;
|
||||
char *p;
|
||||
char *end;
|
||||
|
||||
end = line + len;
|
||||
for (p = line; p < end; p++) {
|
||||
if (*p == '=') {
|
||||
|
@ -540,11 +540,13 @@ mime_fQP_decode(FILE *fi, FILE *fo, void *cookie __unused)
|
|||
while (p < end && is_WSP(*p))
|
||||
p++;
|
||||
if (*p != '\n' && p + 1 < end) {
|
||||
int c;
|
||||
char buf[3];
|
||||
|
||||
buf[0] = *p++;
|
||||
buf[1] = *p;
|
||||
buf[2] = '\0';
|
||||
c = strtol(buf, NULL, 16);
|
||||
c = (int)strtol(buf, NULL, 16);
|
||||
(void)fputc(c, fo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mime_decode.c,v 1.14 2009/01/18 01:29:57 lukem Exp $ */
|
||||
/* $NetBSD: mime_decode.c,v 1.15 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -34,14 +34,13 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef __lint__
|
||||
__RCSID("$NetBSD: mime_decode.c,v 1.14 2009/01/18 01:29:57 lukem Exp $");
|
||||
__RCSID("$NetBSD: mime_decode.c,v 1.15 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif /* not __lint__ */
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mime_detach.c,v 1.3 2008/04/28 20:24:14 martin Exp $ */
|
||||
/* $NetBSD: mime_detach.c,v 1.4 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef __lint__
|
||||
__RCSID("$NetBSD: mime_detach.c,v 1.3 2008/04/28 20:24:14 martin Exp $");
|
||||
__RCSID("$NetBSD: mime_detach.c,v 1.4 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif /* not __lint__ */
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -54,6 +54,7 @@ __RCSID("$NetBSD: mime_detach.c,v 1.3 2008/04/28 20:24:14 martin Exp $");
|
|||
#include "mime_codecs.h"
|
||||
#include "mime_detach.h"
|
||||
#endif
|
||||
#include "sig.h"
|
||||
|
||||
|
||||
static struct {
|
||||
|
@ -95,8 +96,12 @@ detach_get_fname(char *prompt, char *pathname)
|
|||
{
|
||||
if (!detach_ctl.batch) {
|
||||
char *fname;
|
||||
|
||||
fname = my_gets(&elm.filec, prompt, pathname);
|
||||
fname = skip_WSP(fname); /* XXX - do this? */
|
||||
if (fname == NULL) /* ignore this attachment */
|
||||
return NULL;
|
||||
(void)strip_WSP(fname);
|
||||
fname = skip_WSP(fname);
|
||||
if (*fname == '\0') /* ignore this attachment */
|
||||
return NULL;
|
||||
pathname = savestr(fname); /* save this or it gets trashed */
|
||||
|
@ -130,7 +135,12 @@ detach_open_core(char *fname, const char *partstr)
|
|||
(void)sasprintf(&p, "%-7s overwrite: Always/Never/once/next/rename (ANonr)[n]? ",
|
||||
partstr, fname);
|
||||
p = my_gets(&elm.string, p, NULL);
|
||||
if (p == NULL)
|
||||
goto start;
|
||||
|
||||
(void)strip_WSP(p);
|
||||
p = skip_WSP(p);
|
||||
|
||||
switch (*p) {
|
||||
case 'A': detach_ctl.overwrite = 1;
|
||||
detach_ctl.batch = 1;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mime_header.c,v 1.7 2009/01/18 01:29:57 lukem Exp $ */
|
||||
/* $NetBSD: mime_header.c,v 1.8 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -39,9 +39,10 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef __lint__
|
||||
__RCSID("$NetBSD: mime_header.c,v 1.7 2009/01/18 01:29:57 lukem Exp $");
|
||||
__RCSID("$NetBSD: mime_header.c,v 1.8 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif /* not __lint__ */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -91,16 +92,17 @@ mime_QPh_decode(char *outbuf, size_t outlen, const char *inbuf, size_t inlen)
|
|||
if (*p == '=') {
|
||||
p++;
|
||||
if (p + 1 < inend) {
|
||||
int c;
|
||||
size_t c;
|
||||
char *bufend;
|
||||
char buf[3];
|
||||
|
||||
buf[0] = *p++;
|
||||
buf[1] = *p;
|
||||
buf[2] = '\0';
|
||||
c = strtol(buf, &bufend, 16);
|
||||
if (bufend != &buf[2])
|
||||
return -1;
|
||||
*q++ = c;
|
||||
*q++ = (char)c;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
@ -181,8 +183,11 @@ decode_word(const char **ibuf, char **obuf, char *oend, const char *to_cs)
|
|||
if (iend > *ibuf + 75)
|
||||
return -1;
|
||||
|
||||
if (oend < *obuf + 1) {
|
||||
assert(/*CONSTCOND*/ 0); /* We have a coding error! */
|
||||
return -1;
|
||||
}
|
||||
dstend = to_cs ? decword : *obuf;
|
||||
/* XXX: what if oend <= *obuf, or decword == "" ? */
|
||||
dstlen = (to_cs ? sizeof(decword) : (size_t)(oend - *obuf)) - 1;
|
||||
|
||||
if (enctype == 'B' || enctype == 'b')
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: popen.c,v 1.24 2007/10/30 02:28:31 christos Exp $ */
|
||||
/* $NetBSD: popen.c,v 1.25 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: popen.c,v 1.24 2007/10/30 02:28:31 christos Exp $");
|
||||
__RCSID("$NetBSD: popen.c,v 1.25 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -46,6 +46,7 @@ __RCSID("$NetBSD: popen.c,v 1.24 2007/10/30 02:28:31 christos Exp $");
|
|||
|
||||
#include "rcv.h"
|
||||
#include "extern.h"
|
||||
#include "sig.h"
|
||||
|
||||
#define READ 0
|
||||
#define WRITE 1
|
||||
|
@ -146,6 +147,10 @@ Fdopen(int fd, const char *mode)
|
|||
PUBLIC int
|
||||
Fclose(FILE *fp)
|
||||
{
|
||||
|
||||
if (fp == NULL)
|
||||
return 0;
|
||||
|
||||
unregister_file(fp);
|
||||
return fclose(fp);
|
||||
}
|
||||
|
@ -169,17 +174,17 @@ prepare_child(sigset_t *nset, int infd, int outfd)
|
|||
}
|
||||
if (outfd >= 0 && outfd != 1)
|
||||
(void)dup2(outfd, 1);
|
||||
if (nset == NULL)
|
||||
return;
|
||||
|
||||
if (nset != NULL) {
|
||||
for (i = 1; i < NSIG; i++)
|
||||
for (i = 1; i < NSIG; i++) {
|
||||
if (sigismember(nset, i))
|
||||
(void)signal(i, SIG_IGN);
|
||||
}
|
||||
if (!sigismember(nset, SIGINT))
|
||||
(void)signal(SIGINT, SIG_DFL);
|
||||
(void)sigemptyset(&eset);
|
||||
(void)sigprocmask(SIG_SETMASK, &eset, NULL);
|
||||
}
|
||||
if (nset == NULL || !sigismember(nset, SIGINT))
|
||||
(void)signal(SIGINT, SIG_DFL);
|
||||
(void)sigemptyset(&eset);
|
||||
(void)sigprocmask(SIG_SETMASK, &eset, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -196,15 +201,18 @@ start_commandv(const char *cmd, sigset_t *nset, int infd, int outfd,
|
|||
{
|
||||
pid_t pid;
|
||||
|
||||
sig_check();
|
||||
if ((pid = fork()) < 0) {
|
||||
warn("fork");
|
||||
return -1;
|
||||
}
|
||||
if (pid == 0) {
|
||||
char *argv[100];
|
||||
int i = getrawlist(cmd, argv, sizeof(argv)/ sizeof(*argv));
|
||||
size_t i;
|
||||
|
||||
while ((argv[i++] = va_arg(args, char *)) != NULL)
|
||||
i = getrawlist(cmd, argv, (int)__arraycount(argv));
|
||||
while (i < __arraycount(argv) - 1 &&
|
||||
(argv[i++] = va_arg(args, char *)) != NULL)
|
||||
continue;
|
||||
argv[i] = NULL;
|
||||
prepare_child(nset, infd, outfd);
|
||||
|
@ -350,6 +358,9 @@ Pclose(FILE *ptr)
|
|||
int i;
|
||||
sigset_t nset, oset;
|
||||
|
||||
if (ptr == NULL)
|
||||
return 0;
|
||||
|
||||
i = file_pid(ptr);
|
||||
unregister_file(ptr);
|
||||
(void)fclose(ptr);
|
||||
|
@ -429,13 +440,48 @@ run_command(const char *cmd, sigset_t *nset, int infd, int outfd, ...)
|
|||
{
|
||||
pid_t pid;
|
||||
va_list args;
|
||||
int rval;
|
||||
|
||||
#ifdef BROKEN_EXEC_TTY_RESTORE
|
||||
struct termios ttybuf;
|
||||
int tcrval;
|
||||
/*
|
||||
* XXX - grab the tty settings as currently they can get
|
||||
* trashed by emacs-21 when suspending with bash-3.2.25 as the
|
||||
* shell.
|
||||
*
|
||||
* 1) from the mail editor, start "emacs -nw" (21.4)
|
||||
* 2) suspend emacs to the shell (bash 3.2.25)
|
||||
* 3) resume emacs
|
||||
* 4) exit emacs back to the mail editor
|
||||
* 5) discover the tty is screwed: the mail editor is no
|
||||
* longer receiving characters
|
||||
*
|
||||
* - This occurs on both i386 and amd64.
|
||||
* - This did _NOT_ occur before 4.99.10.
|
||||
* - This does _NOT_ occur if the editor is vi(1) or if the shell
|
||||
* is /bin/sh.
|
||||
* - This _DOES_ happen with the old mail(1) from 2006-01-01 (long
|
||||
* before my changes).
|
||||
*
|
||||
* This is the commit that introduced this "feature":
|
||||
* http://mail-index.netbsd.org/source-changes/2007/02/09/0020.html
|
||||
*/
|
||||
if ((tcrval = tcgetattr(fileno(stdin), &ttybuf)) == -1)
|
||||
warn("tcgetattr");
|
||||
#endif
|
||||
va_start(args, outfd);
|
||||
pid = start_commandv(cmd, nset, infd, outfd, args);
|
||||
va_end(args);
|
||||
if (pid < 0)
|
||||
return -1;
|
||||
return wait_command(pid);
|
||||
rval = wait_command(pid);
|
||||
#ifdef BROKEN_EXEC_TTY_RESTORE
|
||||
if (tcrval != -1 && tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf) == -1)
|
||||
warn("tcsetattr");
|
||||
#endif
|
||||
return rval;
|
||||
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
|
@ -445,15 +491,15 @@ sigchild(int signo __unused)
|
|||
pid_t pid;
|
||||
int status;
|
||||
struct child *cp;
|
||||
int save_errno = errno;
|
||||
int save_errno;
|
||||
|
||||
while ((pid =
|
||||
waitpid((pid_t)-1, &status, WNOHANG)) > 0) {
|
||||
cp = findchild(pid, 1);
|
||||
save_errno = errno;
|
||||
while ((pid = waitpid((pid_t)-1, &status, WNOHANG)) > 0) {
|
||||
cp = findchild(pid, 1); /* async-signal-safe: we don't alloc */
|
||||
if (!cp)
|
||||
continue;
|
||||
if (cp->free)
|
||||
delchild(cp);
|
||||
delchild(cp); /* async-signal-safe: list changes */
|
||||
else {
|
||||
cp->done = 1;
|
||||
cp->status = status;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: quit.c,v 1.26 2006/11/28 18:45:32 christos Exp $ */
|
||||
/* $NetBSD: quit.c,v 1.27 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,13 +34,14 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)quit.c 8.2 (Berkeley) 4/28/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: quit.c,v 1.26 2006/11/28 18:45:32 christos Exp $");
|
||||
__RCSID("$NetBSD: quit.c,v 1.27 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include "rcv.h"
|
||||
#include "extern.h"
|
||||
#include "thread.h"
|
||||
#include "sig.h"
|
||||
|
||||
/*
|
||||
* Rcv -- receive mail rationally.
|
||||
|
@ -132,18 +133,22 @@ writeback(FILE *res)
|
|||
* file from the temporary. Save any new stuff appended to the file.
|
||||
*/
|
||||
static void
|
||||
edstop(void)
|
||||
edstop(jmp_buf jmpbuf)
|
||||
{
|
||||
int gotcha, c;
|
||||
struct message *mp;
|
||||
FILE *obuf, *ibuf, *readstat = NULL;
|
||||
FILE *obuf;
|
||||
FILE *ibuf;
|
||||
FILE *readstat;
|
||||
struct stat statb;
|
||||
char tempname[PATHSIZE];
|
||||
int fd;
|
||||
|
||||
sig_check();
|
||||
if (readonly)
|
||||
return;
|
||||
holdsigs();
|
||||
|
||||
readstat = NULL;
|
||||
if (Tflag != NULL) {
|
||||
if ((readstat = Fopen(Tflag, "w")) == NULL)
|
||||
Tflag = NULL;
|
||||
|
@ -175,15 +180,15 @@ edstop(void)
|
|||
warn("%s", tempname);
|
||||
if (fd != -1)
|
||||
(void)close(fd);
|
||||
relsesigs();
|
||||
reset(0);
|
||||
sig_release();
|
||||
longjmp(jmpbuf, -11);
|
||||
}
|
||||
if ((ibuf = Fopen(mailname, "r")) == NULL) {
|
||||
warn("%s", mailname);
|
||||
(void)Fclose(obuf);
|
||||
(void)rm(tempname);
|
||||
relsesigs();
|
||||
reset(0);
|
||||
sig_release();
|
||||
longjmp(jmpbuf, -1);
|
||||
}
|
||||
(void)fseek(ibuf, (long)mailsize, 0);
|
||||
while ((c = getc(ibuf)) != EOF)
|
||||
|
@ -194,16 +199,16 @@ edstop(void)
|
|||
(void)Fclose(obuf);
|
||||
(void)Fclose(ibuf);
|
||||
(void)rm(tempname);
|
||||
relsesigs();
|
||||
reset(0);
|
||||
sig_release();
|
||||
longjmp(jmpbuf, -1);
|
||||
}
|
||||
(void)Fclose(ibuf);
|
||||
(void)Fclose(obuf);
|
||||
if ((ibuf = Fopen(tempname, "r")) == NULL) {
|
||||
warn("%s", tempname);
|
||||
(void)rm(tempname);
|
||||
relsesigs();
|
||||
reset(0);
|
||||
sig_release();
|
||||
longjmp(jmpbuf, -1);
|
||||
}
|
||||
(void)rm(tempname);
|
||||
}
|
||||
|
@ -211,8 +216,8 @@ edstop(void)
|
|||
(void)fflush(stdout);
|
||||
if ((obuf = Fopen(mailname, "r+")) == NULL) {
|
||||
warn("%s", mailname);
|
||||
relsesigs();
|
||||
reset(0);
|
||||
sig_release();
|
||||
longjmp(jmpbuf, -1);
|
||||
}
|
||||
trunc(obuf);
|
||||
c = 0;
|
||||
|
@ -222,8 +227,8 @@ edstop(void)
|
|||
c++;
|
||||
if (sendmessage(mp, obuf, NULL, NULL, NULL) < 0) {
|
||||
warn("%s", mailname);
|
||||
relsesigs();
|
||||
reset(0);
|
||||
sig_release();
|
||||
longjmp(jmpbuf, -1);
|
||||
}
|
||||
}
|
||||
gotcha = (c == 0 && ibuf == NULL);
|
||||
|
@ -235,8 +240,8 @@ edstop(void)
|
|||
(void)fflush(obuf);
|
||||
if (ferror(obuf)) {
|
||||
warn("%s", mailname);
|
||||
relsesigs();
|
||||
reset(0);
|
||||
sig_release();
|
||||
longjmp(jmpbuf, -1);
|
||||
}
|
||||
(void)Fclose(obuf);
|
||||
if (gotcha) {
|
||||
|
@ -247,7 +252,8 @@ edstop(void)
|
|||
(void)fflush(stdout);
|
||||
|
||||
done:
|
||||
relsesigs();
|
||||
sig_release();
|
||||
sig_check();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -256,20 +262,21 @@ done:
|
|||
* Remove the system mailbox, if none saved there.
|
||||
*/
|
||||
PUBLIC void
|
||||
quit(void)
|
||||
quit(jmp_buf jmpbuf)
|
||||
{
|
||||
int mcount, p, modify, autohold, anystat, holdbit, nohold;
|
||||
FILE *ibuf = NULL, *obuf, *fbuf, *rbuf, *readstat = NULL, *abuf;
|
||||
_Bool append;
|
||||
FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf;
|
||||
struct message *mp;
|
||||
int c, fd;
|
||||
struct stat minfo;
|
||||
const char *mbox;
|
||||
char tempname[PATHSIZE];
|
||||
|
||||
#ifdef __GNUC__
|
||||
obuf = NULL; /* XXX gcc -Wuninitialized */
|
||||
#ifdef __GNUC__ /* XXX gcc -Wuninitialized */
|
||||
ibuf = NULL;
|
||||
readstat = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we are read only, we can't do anything,
|
||||
* so just return quickly.
|
||||
|
@ -286,7 +293,7 @@ quit(void)
|
|||
* in edstop()
|
||||
*/
|
||||
if (edit) {
|
||||
edstop();
|
||||
edstop(jmpbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -418,7 +425,8 @@ nolock:
|
|||
|
||||
mbox = expand("&");
|
||||
mcount = c;
|
||||
if (value(ENAME_APPEND) == NULL) {
|
||||
append = value(ENAME_APPEND) != NULL;
|
||||
if (!append) {
|
||||
(void)snprintf(tempname, sizeof(tempname),
|
||||
"%s/mail.RmXXXXXXXXXX", tmpdir);
|
||||
if ((fd = mkstemp(tempname)) == -1 ||
|
||||
|
@ -476,7 +484,8 @@ nolock:
|
|||
if (mp->m_flag & MBOX)
|
||||
if (sendmessage(mp, obuf, saveignore, NULL, NULL) < 0) {
|
||||
warn("%s", mbox);
|
||||
(void)Fclose(ibuf);
|
||||
if (!append)
|
||||
(void)Fclose(ibuf);
|
||||
(void)Fclose(obuf);
|
||||
(void)Fclose(fbuf);
|
||||
dot_unlock(mailname);
|
||||
|
@ -489,7 +498,7 @@ nolock:
|
|||
* If we are appending, this is unnecessary.
|
||||
*/
|
||||
|
||||
if (value(ENAME_APPEND) == NULL) {
|
||||
if (!append) {
|
||||
rewind(ibuf);
|
||||
c = getc(ibuf);
|
||||
while (c != EOF) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: send.c,v 1.33 2009/01/25 14:07:18 lukem Exp $ */
|
||||
/* $NetBSD: send.c,v 1.34 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,16 +34,18 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)send.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: send.c,v 1.33 2009/01/25 14:07:18 lukem Exp $");
|
||||
__RCSID("$NetBSD: send.c,v 1.34 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "rcv.h"
|
||||
#include "extern.h"
|
||||
#ifdef MIME_SUPPORT
|
||||
#include "mime.h"
|
||||
#endif
|
||||
|
||||
#include "sig.h"
|
||||
|
||||
/*
|
||||
* Mail -- a mail program
|
||||
|
@ -125,9 +127,11 @@ sendmessage(struct message *mp, FILE *obuf, struct ignoretab *doign,
|
|||
char *cp;
|
||||
size_t prefixlen;
|
||||
size_t linelen;
|
||||
int rval;
|
||||
|
||||
ignoring = 0;
|
||||
prefixlen = 0;
|
||||
rval = -1;
|
||||
|
||||
/*
|
||||
* Compute the prefix string, without trailing whitespace
|
||||
|
@ -145,6 +149,8 @@ sendmessage(struct message *mp, FILE *obuf, struct ignoretab *doign,
|
|||
dostat = doign == 0 || !isign("status", doign);
|
||||
infld = 0;
|
||||
firstline = 1;
|
||||
|
||||
sig_check();
|
||||
/*
|
||||
* Process headers first
|
||||
*/
|
||||
|
@ -153,7 +159,8 @@ sendmessage(struct message *mp, FILE *obuf, struct ignoretab *doign,
|
|||
obuf = mime_decode_header(mip);
|
||||
#endif
|
||||
while (len > 0 && isheadflag) {
|
||||
if (fgets(line, sizeof(line), ibuf) == NULL)
|
||||
sig_check();
|
||||
if (fgets(line, (int)sizeof(line), ibuf) == NULL)
|
||||
break;
|
||||
len -= linelen = strlen(line);
|
||||
if (firstline) {
|
||||
|
@ -254,26 +261,32 @@ sendmessage(struct message *mp, FILE *obuf, struct ignoretab *doign,
|
|||
}
|
||||
(void)fwrite(line, sizeof(*line), linelen, obuf);
|
||||
if (ferror(obuf))
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
sig_check();
|
||||
|
||||
/*
|
||||
* Copy out message body
|
||||
*/
|
||||
#ifdef MIME_SUPPORT
|
||||
if (mip) {
|
||||
obuf = mime_decode_body(mip);
|
||||
if (obuf == NULL) /* XXX - early out */
|
||||
return 0;
|
||||
sig_check();
|
||||
if (obuf == NULL) { /* XXX - early out */
|
||||
rval = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (doign == ignoreall)
|
||||
len--; /* skip final blank line */
|
||||
|
||||
linelen = 0; /* needed for in case len == 0 */
|
||||
if (prefix != NULL)
|
||||
if (prefix != NULL) {
|
||||
while (len > 0) {
|
||||
if (fgets(line, sizeof(line), ibuf) == NULL) {
|
||||
sig_check();
|
||||
if (fgets(line, (int)sizeof(line), ibuf) == NULL) {
|
||||
linelen = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -289,24 +302,33 @@ sendmessage(struct message *mp, FILE *obuf, struct ignoretab *doign,
|
|||
prefixlen, obuf);
|
||||
(void)fwrite(line, sizeof(*line), linelen, obuf);
|
||||
if (ferror(obuf))
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
}
|
||||
else {
|
||||
while (len > 0) {
|
||||
sig_check();
|
||||
linelen = (size_t)len < sizeof(line) ? (size_t)len : sizeof(line);
|
||||
if ((linelen = fread(line, sizeof(*line), linelen, ibuf)) == 0)
|
||||
if ((linelen = fread(line, sizeof(*line), linelen, ibuf)) == 0) {
|
||||
break;
|
||||
}
|
||||
len -= linelen;
|
||||
if (fwrite(line, sizeof(*line), linelen, obuf) != linelen)
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
sig_check();
|
||||
if (doign == ignoreall && linelen > 0 && line[linelen - 1] != '\n') {
|
||||
int c;
|
||||
|
||||
/* no final blank line */
|
||||
if ((c = getc(ibuf)) != EOF && putc(c, obuf) == EOF)
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
return 0;
|
||||
rval = 0;
|
||||
out:
|
||||
sig_check();
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -340,9 +362,10 @@ fixhead(struct header *hp, struct name *tolist)
|
|||
* Format the given header line to not exceed 72 characters.
|
||||
*/
|
||||
static void
|
||||
fmt(const char *str, struct name *np, FILE *fo, int comma)
|
||||
fmt(const char *str, struct name *np, FILE *fo, size_t comma)
|
||||
{
|
||||
int col, len;
|
||||
size_t col;
|
||||
size_t len;
|
||||
|
||||
comma = comma ? 1 : 0;
|
||||
col = strlen(str);
|
||||
|
@ -366,6 +389,51 @@ fmt(const char *str, struct name *np, FILE *fo, int comma)
|
|||
(void)putc('\n', fo);
|
||||
}
|
||||
|
||||
/*
|
||||
* Formatting for extra_header lines: try to wrap them before 72
|
||||
* characters.
|
||||
*
|
||||
* XXX - should this allow for quoting?
|
||||
*/
|
||||
static void
|
||||
fmt2(const char *str, FILE *fo)
|
||||
{
|
||||
const char *p;
|
||||
size_t col;
|
||||
|
||||
col = 0;
|
||||
p = strchr(str, ':');
|
||||
assert(p != NULL); /* this is a coding error */
|
||||
|
||||
while (str <= p) { /* output the header name */
|
||||
(void)putc(*str, fo);
|
||||
str++;
|
||||
col++;
|
||||
}
|
||||
assert(is_WSP(*str)); /* this is a coding error */
|
||||
|
||||
(void)putc(' ', fo); /* output a single space after the ':' */
|
||||
str = skip_WSP(str);
|
||||
|
||||
while (*str != '\0') {
|
||||
if (p <= str) {
|
||||
p = strpbrk(str, " \t");
|
||||
if (p == NULL)
|
||||
p = str + strlen(str);
|
||||
if (col + (p - str) > 72 && col > 4) {
|
||||
(void)fputs("\n ", fo);
|
||||
col = 4;
|
||||
str = skip_WSP(str);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
(void)putc(*str, fo);
|
||||
str++;
|
||||
col++;
|
||||
}
|
||||
(void)putc('\n', fo);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump the to, subject, cc header on the
|
||||
* passed file buffer.
|
||||
|
@ -373,23 +441,29 @@ fmt(const char *str, struct name *np, FILE *fo, int comma)
|
|||
PUBLIC int
|
||||
puthead(struct header *hp, FILE *fo, int w)
|
||||
{
|
||||
struct name *np;
|
||||
int gotcha;
|
||||
|
||||
gotcha = 0;
|
||||
if (hp->h_to != NULL && w & GTO)
|
||||
fmt("To:", hp->h_to, fo, w&GCOMMA), gotcha++;
|
||||
fmt("To:", hp->h_to, fo, w & GCOMMA), gotcha++;
|
||||
if (hp->h_subject != NULL && w & GSUBJECT)
|
||||
(void)fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++;
|
||||
if (hp->h_smopts != NULL && w & GSMOPTS)
|
||||
(void)fprintf(fo, "(sendmail options: %s)\n", detract(hp->h_smopts, GSMOPTS)), gotcha++;
|
||||
if (hp->h_cc != NULL && w & GCC)
|
||||
fmt("Cc:", hp->h_cc, fo, w&GCOMMA), gotcha++;
|
||||
fmt("Cc:", hp->h_cc, fo, w & GCOMMA), gotcha++;
|
||||
if (hp->h_bcc != NULL && w & GBCC)
|
||||
fmt("Bcc:", hp->h_bcc, fo, w&GCOMMA), gotcha++;
|
||||
fmt("Bcc:", hp->h_bcc, fo, w & GCOMMA), gotcha++;
|
||||
if (hp->h_in_reply_to != NULL && w & GMISC)
|
||||
(void)fprintf(fo, "In-Reply-To: %s\n", hp->h_in_reply_to), gotcha++;
|
||||
if (hp->h_references != NULL && w & GMISC)
|
||||
fmt("References:", hp->h_references, fo, w&GCOMMA), gotcha++;
|
||||
fmt("References:", hp->h_references, fo, w & GCOMMA), gotcha++;
|
||||
if (hp->h_extra != NULL && w & GMISC) {
|
||||
for (np = hp->h_extra; np != NULL; np = np->n_flink)
|
||||
fmt2(np->n_name, fo);
|
||||
gotcha++;
|
||||
}
|
||||
if (hp->h_smopts != NULL && w & GSMOPTS)
|
||||
(void)fprintf(fo, "(sendmail options: %s)\n", detract(hp->h_smopts, GSMOPTS)), gotcha++;
|
||||
#ifdef MIME_SUPPORT
|
||||
if (w & GMIME && (hp->h_attach || value(ENAME_MIME_ENCODE_MSG)))
|
||||
mime_putheader(fo, hp), gotcha++;
|
||||
|
@ -426,11 +500,12 @@ infix(struct header *hp, FILE *fi)
|
|||
return fi;
|
||||
}
|
||||
(void)rm(tempname);
|
||||
(void)puthead(hp, nfo,
|
||||
GTO | GSUBJECT | GCC | GBCC | GMISC | GNL | GCOMMA
|
||||
#ifdef MIME_SUPPORT
|
||||
(void)puthead(hp, nfo, GTO|GSUBJECT|GCC|GBCC|GMISC|GMIME|GNL|GCOMMA);
|
||||
#else
|
||||
(void)puthead(hp, nfo, GTO|GSUBJECT|GCC|GBCC|GMISC|GNL|GCOMMA);
|
||||
| GMIME
|
||||
#endif
|
||||
);
|
||||
|
||||
c = getc(fi);
|
||||
while (c != EOF) {
|
||||
|
@ -576,6 +651,28 @@ mail2(FILE *mtf, const char **namelist)
|
|||
}
|
||||
}
|
||||
|
||||
static struct name *
|
||||
ncopy(struct name *np)
|
||||
{
|
||||
struct name *rv;
|
||||
struct name *lp;
|
||||
struct name *tp;
|
||||
|
||||
rv = NULL;
|
||||
for (/*EMPTY*/; np; np = np->n_flink) {
|
||||
tp = nalloc(np->n_name, np->n_type);
|
||||
if (rv == NULL)
|
||||
rv = tp;
|
||||
else {
|
||||
/*LINTED*/
|
||||
lp->n_flink = tp;
|
||||
tp->n_blink = lp;
|
||||
}
|
||||
lp = tp;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mail a message on standard input to the people indicated
|
||||
* in the passed header. (Internal interface).
|
||||
|
@ -594,6 +691,12 @@ mail1(struct header *hp, int printheaders)
|
|||
if ((mtf = collect(hp, printheaders)) == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Grab any extra header lines. Do this after collect() so
|
||||
* that we can add header lines while collecting.
|
||||
*/
|
||||
hp->h_extra = ncopy(extra_headers);
|
||||
|
||||
if (value(ENAME_INTERACTIVE) != NULL) {
|
||||
if (value(ENAME_ASKCC) != NULL || value(ENAME_ASKBCC) != NULL) {
|
||||
if (value(ENAME_ASKCC) != NULL)
|
||||
|
|
|
@ -0,0 +1,424 @@
|
|||
/* $NetBSD: sig.c,v 1.1 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: sig.c,v 1.1 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <util.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include "rcv.h"
|
||||
#include "extern.h"
|
||||
#include "sig.h"
|
||||
|
||||
/*
|
||||
* Mail -- a mail program
|
||||
*
|
||||
* Signal routines.
|
||||
*/
|
||||
|
||||
static sig_t sigarray[NSIG];
|
||||
|
||||
typedef struct q_entry_s {
|
||||
int qe_signo;
|
||||
sig_t qe_handler;
|
||||
struct q_entry_s *qe_next;
|
||||
} q_entry_t;
|
||||
|
||||
static struct {
|
||||
q_entry_t *qe_first;
|
||||
q_entry_t **qe_last;
|
||||
} sigqueue = { NULL, &sigqueue.qe_first };
|
||||
#define SIGQUEUE_INIT(p) do {\
|
||||
(p)->qe_first = NULL;\
|
||||
(p)->qe_last = &((p)->qe_first);\
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
/*
|
||||
* The routines alloc_entry() and free_entry() manage the queue
|
||||
* elements.
|
||||
*
|
||||
* Currently, they just assign one element per signo from a fix array
|
||||
* as we don't support POSIX signal queues. We leave them as this may
|
||||
* change in the future and the modifications will be isolated.
|
||||
*/
|
||||
static q_entry_t *
|
||||
alloc_entry(int signo)
|
||||
{
|
||||
static q_entry_t entries[NSIG];
|
||||
q_entry_t *e;
|
||||
|
||||
/*
|
||||
* We currently only post one signal per signal number, so
|
||||
* there is no need to make this complicated.
|
||||
*/
|
||||
e = &entries[signo];
|
||||
if (e->qe_signo != 0)
|
||||
return NULL;
|
||||
|
||||
e->qe_signo = signo;
|
||||
e->qe_handler = sigarray[signo];
|
||||
e->qe_next = NULL;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static void
|
||||
free_entry(q_entry_t *e)
|
||||
{
|
||||
|
||||
e->qe_signo = 0;
|
||||
e->qe_handler = NULL;
|
||||
e->qe_next = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to post a signal to the sigqueue.
|
||||
*/
|
||||
static void
|
||||
sig_post(int signo)
|
||||
{
|
||||
q_entry_t *e;
|
||||
|
||||
if (sigarray[signo] == SIG_DFL || sigarray[signo] == SIG_IGN)
|
||||
return;
|
||||
|
||||
e = alloc_entry(signo);
|
||||
if (e != NULL) {
|
||||
*sigqueue.qe_last = e;
|
||||
sigqueue.qe_last = &e->qe_next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the sigqueue for any pending signals. If any are found,
|
||||
* preform the required actions and remove them from the queue.
|
||||
*/
|
||||
PUBLIC void
|
||||
sig_check(void)
|
||||
{
|
||||
q_entry_t *e;
|
||||
sigset_t nset;
|
||||
sigset_t oset;
|
||||
void (*handler)(int);
|
||||
int signo;
|
||||
|
||||
(void)sigfillset(&nset);
|
||||
(void)sigprocmask(SIG_SETMASK, &nset, &oset);
|
||||
|
||||
while ((e = sigqueue.qe_first) != NULL) {
|
||||
signo = e->qe_signo;
|
||||
handler = e->qe_handler;
|
||||
|
||||
/*
|
||||
* Remove the entry from the queue and free it.
|
||||
*/
|
||||
sigqueue.qe_first = e->qe_next;
|
||||
if (sigqueue.qe_first == NULL)
|
||||
sigqueue.qe_last = &sigqueue.qe_first;
|
||||
free_entry(e);
|
||||
|
||||
if (handler == SIG_DFL || handler == SIG_IGN) {
|
||||
assert(/*CONSTCOND*/ 0); /* These should not get posted. */
|
||||
}
|
||||
else {
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
handler(signo);
|
||||
(void)sigprocmask(SIG_SETMASK, &nset, NULL);
|
||||
}
|
||||
}
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
|
||||
PUBLIC sig_t
|
||||
sig_signal(int signo, sig_t handler)
|
||||
{
|
||||
sig_t old_handler;
|
||||
sigset_t nset;
|
||||
sigset_t oset;
|
||||
|
||||
assert(signo > 0 && signo < NSIG);
|
||||
|
||||
(void)sigemptyset(&nset);
|
||||
(void)sigaddset(&nset, signo);
|
||||
(void)sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
|
||||
old_handler = sigarray[signo];
|
||||
sigarray[signo] = handler;
|
||||
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
|
||||
return old_handler;
|
||||
}
|
||||
|
||||
static void
|
||||
do_default_handler(int signo, int flags)
|
||||
{
|
||||
struct sigaction nsa;
|
||||
struct sigaction osa;
|
||||
sigset_t nset;
|
||||
sigset_t oset;
|
||||
int save_errno;
|
||||
|
||||
save_errno = errno;
|
||||
(void)sigemptyset(&nsa.sa_mask);
|
||||
nsa.sa_flags = flags;
|
||||
nsa.sa_handler = SIG_DFL;
|
||||
(void)sigaction(signo, &nsa, &osa);
|
||||
|
||||
(void)sigemptyset(&nset);
|
||||
(void)sigaddset(&nset, signo);
|
||||
(void)sigprocmask(SIG_UNBLOCK, &nset, &oset);
|
||||
|
||||
(void)kill(0, signo);
|
||||
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
(void)sigaction(signo, &osa, NULL);
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Our generic signal handler.
|
||||
*/
|
||||
static void
|
||||
sig_handler(int signo)
|
||||
{
|
||||
sigset_t nset;
|
||||
sigset_t oset;
|
||||
|
||||
(void)sigfillset(&nset);
|
||||
(void)sigprocmask(SIG_SETMASK, &nset, &oset);
|
||||
|
||||
assert (signo > 0 && signo < NSIG); /* Should be guaranteed. */
|
||||
|
||||
sig_post(signo);
|
||||
|
||||
switch (signo) {
|
||||
case SIGCONT:
|
||||
assert(/*CONSTCOND*/ 0); /* We should not be seeing these. */
|
||||
do_default_handler(signo, 0);
|
||||
break;
|
||||
|
||||
case SIGTSTP:
|
||||
case SIGTTIN:
|
||||
case SIGTTOU:
|
||||
do_default_handler(signo, 0);
|
||||
break;
|
||||
|
||||
case SIGINT:
|
||||
case SIGHUP:
|
||||
case SIGQUIT:
|
||||
case SIGPIPE:
|
||||
default:
|
||||
if (sigarray[signo] == SIG_DFL)
|
||||
do_default_handler(signo, SA_RESTART);
|
||||
break;
|
||||
}
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the signal handlers.
|
||||
*/
|
||||
PUBLIC void
|
||||
sig_setup(void)
|
||||
{
|
||||
sigset_t nset;
|
||||
sigset_t oset;
|
||||
struct sigaction sa;
|
||||
struct sigaction osa;
|
||||
|
||||
/* Block all signals while setting things. */
|
||||
(void)sigfillset(&nset);
|
||||
(void)sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
|
||||
/*
|
||||
* Flow Control - SIGTSTP, SIGTTIN, SIGTTOU, SIGCONT:
|
||||
*
|
||||
* We grab SIGTSTP, SIGTTIN, and SIGTTOU so that we post the
|
||||
* signals before suspending so that they are available when
|
||||
* we resume. If we were to use SIGCONT instead, they will
|
||||
* not get posted until SIGCONT is unblocked, even though the
|
||||
* process has resumed.
|
||||
*
|
||||
* NOTE: We default these to SA_RESTART here, but we need to
|
||||
* change this in certain cases, e.g., when reading from a
|
||||
* tty.
|
||||
*/
|
||||
(void)sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sa.sa_handler = sig_handler;
|
||||
(void)sigaction(SIGTSTP, &sa, NULL);
|
||||
(void)sigaction(SIGTTIN, &sa, NULL);
|
||||
(void)sigaction(SIGTTOU, &sa, NULL);
|
||||
|
||||
/*
|
||||
* SIGHUP, SIGINT, and SIGQUIT:
|
||||
*
|
||||
* SIGHUP and SIGINT are trapped unless they are being
|
||||
* ignored.
|
||||
*
|
||||
* Currently, we let the default handler deal with SIGQUIT.
|
||||
*/
|
||||
(void)sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = sig_handler;
|
||||
|
||||
if (sigaction(SIGHUP, &sa, &osa) != -1 && osa.sa_handler == SIG_IGN)
|
||||
(void)signal(SIGHUP, SIG_IGN);
|
||||
|
||||
if (sigaction(SIGINT, &sa, &osa) != -1 && osa.sa_handler == SIG_IGN)
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
#if 0
|
||||
if (signal(SIGQUIT, SIG_DFL) == SIG_IGN)
|
||||
(void)signal(SIGQUIT, SIG_IGN);
|
||||
#endif
|
||||
/*
|
||||
* SIGCHLD and SIGPIPE:
|
||||
*
|
||||
* SIGCHLD is setup early in main. The handler lives in
|
||||
* popen.c as it uses internals of that module.
|
||||
*
|
||||
* SIGPIPE is grabbed here. It is only used in
|
||||
* lex.c:setup_piping(), cmd1.c:type1(), and cmd1.c:pipecmd().
|
||||
*/
|
||||
(void)sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = sig_handler;
|
||||
(void)sigaction(SIGPIPE, &sa, NULL);
|
||||
|
||||
/*
|
||||
* Make sure our structures are initialized.
|
||||
* XXX: This should be unnecessary.
|
||||
*/
|
||||
(void)memset(sigarray, 0, sizeof(sigarray));
|
||||
SIGQUEUE_INIT(&sigqueue);
|
||||
|
||||
/* Restore the signal mask. */
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
|
||||
static struct { /* data shared by sig_hold() and sig_release() */
|
||||
int depth; /* depth of sig_hold() */
|
||||
sigset_t oset; /* old signal mask saved by sig_hold() */
|
||||
} hold;
|
||||
|
||||
/*
|
||||
* Hold signals SIGHUP, SIGINT, and SIGQUIT.
|
||||
*/
|
||||
PUBLIC void
|
||||
sig_hold(void)
|
||||
{
|
||||
sigset_t nset;
|
||||
|
||||
if (hold.depth++ == 0) {
|
||||
(void)sigemptyset(&nset);
|
||||
(void)sigaddset(&nset, SIGHUP);
|
||||
(void)sigaddset(&nset, SIGINT);
|
||||
(void)sigaddset(&nset, SIGQUIT);
|
||||
(void)sigprocmask(SIG_BLOCK, &nset, &hold.oset);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Release signals SIGHUP, SIGINT, and SIGQUIT.
|
||||
*/
|
||||
PUBLIC void
|
||||
sig_release(void)
|
||||
{
|
||||
|
||||
if (--hold.depth == 0)
|
||||
(void)sigprocmask(SIG_SETMASK, &hold.oset, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unblock and ignore a signal.
|
||||
*/
|
||||
PUBLIC int
|
||||
sig_ignore(int sig, struct sigaction *osa, sigset_t *oset)
|
||||
{
|
||||
struct sigaction act;
|
||||
sigset_t nset;
|
||||
int error;
|
||||
|
||||
(void)sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = SA_RESTART;
|
||||
act.sa_handler = SIG_IGN;
|
||||
error = sigaction(sig, &act, osa);
|
||||
|
||||
if (error != -1) {
|
||||
(void)sigemptyset(&nset);
|
||||
(void)sigaddset(&nset, sig);
|
||||
(void)sigprocmask(SIG_UNBLOCK, &nset, oset);
|
||||
} else if (oset != NULL)
|
||||
(void)sigprocmask(SIG_UNBLOCK, NULL, oset);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore a signal and the current signal mask.
|
||||
*/
|
||||
PUBLIC int
|
||||
sig_restore(int sig, struct sigaction *osa, sigset_t *oset)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = 0;
|
||||
if (oset)
|
||||
error = sigprocmask(SIG_SETMASK, oset, NULL);
|
||||
if (osa)
|
||||
error = sigaction(sig, osa, NULL);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the current flags and (optionally) return the old sigaction
|
||||
* structure so we can restore things later. This is used to turn
|
||||
* SA_RESTART on or off.
|
||||
*/
|
||||
PUBLIC int
|
||||
sig_setflags(int signo, int flags, struct sigaction *osa)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
if (sigaction(signo, NULL, &sa) == -1)
|
||||
return -1;
|
||||
if (osa)
|
||||
*osa = sa;
|
||||
sa.sa_flags = flags;
|
||||
return sigaction(signo, &sa, NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* $NetBSD: sig.h,v 1.1 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SIG_H__
|
||||
#define __SIG_H__
|
||||
|
||||
int sig_ignore(int, struct sigaction *, sigset_t *);
|
||||
int sig_restore(int, struct sigaction *, sigset_t *);
|
||||
int sig_setflags(int, int, struct sigaction *);
|
||||
|
||||
void sig_hold(void);
|
||||
void sig_release(void); /* XXX: should this be named sig_relse()? */
|
||||
|
||||
void sig_check(void);
|
||||
void sig_setup(void);
|
||||
sig_t sig_signal(int, sig_t);
|
||||
|
||||
#endif /* __SIG_H__ */
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: strings.c,v 1.16 2007/10/29 23:20:39 christos Exp $ */
|
||||
/* $NetBSD: strings.c,v 1.17 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)strings.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: strings.c,v 1.16 2007/10/29 23:20:39 christos Exp $");
|
||||
__RCSID("$NetBSD: strings.c,v 1.17 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -61,7 +61,7 @@ __RCSID("$NetBSD: strings.c,v 1.16 2007/10/29 23:20:39 christos Exp $");
|
|||
static struct strings {
|
||||
char *s_topFree; /* Beginning of this area */
|
||||
char *s_nextFree; /* Next alloctable place here */
|
||||
unsigned s_nleft; /* Number of bytes left here */
|
||||
size_t s_nleft; /* Number of bytes left here */
|
||||
} stringdope[NSPACE];
|
||||
|
||||
/*
|
||||
|
@ -71,7 +71,6 @@ static struct strings {
|
|||
* The string spaces are of exponentially increasing size, to satisfy
|
||||
* the occasional user with enormous string size requests.
|
||||
*/
|
||||
|
||||
PUBLIC void *
|
||||
salloc(size_t size)
|
||||
{
|
||||
|
@ -94,7 +93,7 @@ salloc(size_t size)
|
|||
if (sp >= &stringdope[NSPACE])
|
||||
errx(1, "String too large");
|
||||
if (sp->s_topFree == NULL) {
|
||||
idx = sp - &stringdope[0];
|
||||
idx = (int)(sp - &stringdope[0]);
|
||||
sp->s_topFree = malloc(STRINGSIZE << idx);
|
||||
if (sp->s_topFree == NULL)
|
||||
errx(1, "No room for space %d", idx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: support.c,v 1.21 2008/04/24 01:27:07 christos Exp $ */
|
||||
/* $NetBSD: support.c,v 1.22 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)aux.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: support.c,v 1.21 2008/04/24 01:27:07 christos Exp $");
|
||||
__RCSID("$NetBSD: support.c,v 1.22 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -169,7 +169,7 @@ argcount(char **argv)
|
|||
|
||||
for (ap = argv; *ap++ != NULL; /*EMPTY*/)
|
||||
continue;
|
||||
return ap - argv - 1;
|
||||
return (int)(ap - argv - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -211,7 +211,7 @@ gethfield(FILE *f, char linebuf[], int rem, char **colon)
|
|||
for (;;) {
|
||||
if (--rem < 0)
|
||||
return -1;
|
||||
if ((c = mail_readline(f, linebuf, LINESIZE)) <= 0)
|
||||
if ((c = readline(f, linebuf, LINESIZE, 0)) <= 0)
|
||||
return -1;
|
||||
for (cp = linebuf;
|
||||
isprint((unsigned char)*cp) && *cp != ' ' && *cp != ':';
|
||||
|
@ -234,11 +234,11 @@ gethfield(FILE *f, char linebuf[], int rem, char **colon)
|
|||
(void)ungetc(c = getc(f), f);
|
||||
if (!is_WSP(c))
|
||||
break;
|
||||
if ((c = mail_readline(f, line2, LINESIZE)) < 0)
|
||||
if ((c = readline(f, line2, LINESIZE, 0)) < 0)
|
||||
break;
|
||||
rem--;
|
||||
cp2 = skip_WSP(line2);
|
||||
c -= cp2 - line2;
|
||||
c -= (int)(cp2 - line2);
|
||||
if (cp + c >= linebuf + LINESIZE - 2)
|
||||
break;
|
||||
*cp++ = ' ';
|
||||
|
@ -271,9 +271,9 @@ hfield(const char field[], const struct message *mp)
|
|||
#endif
|
||||
|
||||
ibuf = setinput(mp);
|
||||
if ((lc = mp->m_lines - 1) < 0)
|
||||
if ((lc = (int)(mp->m_lines - 1)) < 0)
|
||||
return NULL;
|
||||
if (mail_readline(ibuf, linebuf, LINESIZE) < 0)
|
||||
if (readline(ibuf, linebuf, LINESIZE, 0) < 0)
|
||||
return NULL;
|
||||
while (lc > 0) {
|
||||
if ((lc = gethfield(ibuf, linebuf, lc, &colon)) < 0)
|
||||
|
@ -571,7 +571,7 @@ name1(struct message *mp, int reptype)
|
|||
return cp;
|
||||
ibuf = setinput(mp);
|
||||
namebuf[0] = '\0';
|
||||
if (mail_readline(ibuf, linebuf, LINESIZE) < 0)
|
||||
if (readline(ibuf, linebuf, LINESIZE, 0) < 0)
|
||||
return savestr(namebuf);
|
||||
newname:
|
||||
for (cp = linebuf; *cp && *cp != ' '; cp++)
|
||||
|
@ -582,7 +582,7 @@ name1(struct message *mp, int reptype)
|
|||
/*EMPTY*/)
|
||||
*cp2++ = *cp++;
|
||||
*cp2 = '\0';
|
||||
if (mail_readline(ibuf, linebuf, LINESIZE) < 0)
|
||||
if (readline(ibuf, linebuf, LINESIZE, 0) < 0)
|
||||
return savestr(namebuf);
|
||||
if ((cp = strchr(linebuf, 'F')) == NULL)
|
||||
return savestr(namebuf);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: thread.c,v 1.7 2009/01/18 01:29:57 lukem Exp $ */
|
||||
/* $NetBSD: thread.c,v 1.8 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef __lint__
|
||||
__RCSID("$NetBSD: thread.c,v 1.7 2009/01/18 01:29:57 lukem Exp $");
|
||||
__RCSID("$NetBSD: thread.c,v 1.8 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif /* not __lint__ */
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -780,7 +780,7 @@ link_array(struct key_sort_s *marray, size_t mcount)
|
|||
struct message *lastmp;
|
||||
lastmp = NULL;
|
||||
for (i = 0; i < mcount; i++) {
|
||||
marray[i].mp->m_index = i + 1;
|
||||
marray[i].mp->m_index = (int)i + 1;
|
||||
marray[i].mp->m_blink = lastmp;
|
||||
marray[i].mp->m_flink = NULL;
|
||||
if (lastmp)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tty.c,v 1.27 2006/11/28 18:45:32 christos Exp $ */
|
||||
/* $NetBSD: tty.c,v 1.28 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)tty.c 8.2 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: tty.c,v 1.27 2006/11/28 18:45:32 christos Exp $");
|
||||
__RCSID("$NetBSD: tty.c,v 1.28 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -47,77 +47,55 @@ __RCSID("$NetBSD: tty.c,v 1.27 2006/11/28 18:45:32 christos Exp $");
|
|||
#include "rcv.h"
|
||||
#include "extern.h"
|
||||
#ifdef USE_EDITLINE
|
||||
#include "complete.h"
|
||||
# include "complete.h"
|
||||
#endif
|
||||
#include "sig.h"
|
||||
|
||||
#if !defined(USE_EDITLINE) || !defined(TIOCSTI)
|
||||
static jmp_buf tty_jmpbuf; /* Place to go when interrupted */
|
||||
|
||||
#ifndef USE_EDITLINE
|
||||
static cc_t c_erase; /* Current erase char */
|
||||
static cc_t c_kill; /* Current kill char */
|
||||
#endif
|
||||
#ifndef USE_EDITLINE
|
||||
static jmp_buf rewrite; /* Place to go when continued */
|
||||
#endif
|
||||
static jmp_buf intjmp; /* Place to go when interrupted */
|
||||
#ifndef TIOCSTI
|
||||
# ifndef TIOCSTI
|
||||
static int ttyset; /* We must now do erase/kill */
|
||||
#endif
|
||||
|
||||
# endif
|
||||
#endif /* USE_EDITLINE */
|
||||
|
||||
/*
|
||||
* Read up a header from standard input.
|
||||
* The source string has the preliminary contents to
|
||||
* be read.
|
||||
*
|
||||
* Returns: an salloc'ed copy of the line read if successful, or NULL
|
||||
* if no characters were read or if an error occurred.
|
||||
*
|
||||
*/
|
||||
#ifdef USE_EDITLINE
|
||||
static char *
|
||||
readtty(const char pr[], char src[])
|
||||
readtty(const char *pr, char *src)
|
||||
{
|
||||
char *line;
|
||||
|
||||
line = my_gets(&elm.string, pr, src);
|
||||
#if 0
|
||||
sig_check();
|
||||
if (line == NULL)
|
||||
(void)putc('\n', stdout);
|
||||
|
||||
return line ? savestr(line) : __UNCONST("");
|
||||
#else
|
||||
if (line)
|
||||
return savestr(line);
|
||||
else
|
||||
return __UNCONST("");
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* USE_EDITLINE */
|
||||
|
||||
/*
|
||||
* Receipt continuation.
|
||||
*/
|
||||
static void
|
||||
ttystop(int s)
|
||||
{
|
||||
sig_t old_action = signal(s, SIG_DFL);
|
||||
sigset_t nset;
|
||||
|
||||
(void)sigemptyset(&nset);
|
||||
(void)sigaddset(&nset, s);
|
||||
(void)sigprocmask(SIG_BLOCK, &nset, NULL);
|
||||
(void)kill(0, s);
|
||||
(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
|
||||
(void)signal(s, old_action);
|
||||
longjmp(rewrite, 1);
|
||||
}
|
||||
#else /* not USE_EDITLINE */
|
||||
|
||||
static char *
|
||||
readtty(const char pr[], char src[])
|
||||
readtty(const char *pr, char *src)
|
||||
{
|
||||
/* XXX - watch for potential setjmp/longjmp clobbering!
|
||||
* Currently there appear to be none.
|
||||
*/
|
||||
char canonb[LINESIZE];
|
||||
int c;
|
||||
char *cp, *cp2;
|
||||
int c;
|
||||
#ifdef TIOCSTI
|
||||
char ch;
|
||||
static char empty[] = "";
|
||||
#endif
|
||||
|
||||
(void)fputs(pr, stdout);
|
||||
(void)fflush(stdout);
|
||||
if (src != NULL && strlen(src) > sizeof(canonb) - 2) {
|
||||
|
@ -128,11 +106,12 @@ readtty(const char pr[], char src[])
|
|||
if (src != NULL)
|
||||
cp = copy(src, canonb);
|
||||
else
|
||||
cp = copy("", canonb);
|
||||
cp = copy(__UNCONST(""), canonb);
|
||||
c = *cp;
|
||||
(void)fputs(canonb, stdout);
|
||||
(void)fflush(stdout);
|
||||
#else
|
||||
cp = src == NULL ? empty : src;
|
||||
cp = src == NULL ? __UNCONST("") : src;
|
||||
while ((c = *cp++) != '\0') {
|
||||
if ((c_erase != _POSIX_VDISABLE && c == c_erase) ||
|
||||
(c_kill != _POSIX_VDISABLE && c == c_kill)) {
|
||||
|
@ -143,30 +122,25 @@ readtty(const char pr[], char src[])
|
|||
(void)ioctl(0, TIOCSTI, &ch);
|
||||
}
|
||||
cp = canonb;
|
||||
*cp = 0;
|
||||
*cp = '\0';
|
||||
#endif
|
||||
cp2 = cp;
|
||||
while (cp2 < canonb + sizeof(canonb))
|
||||
*cp2++ = 0;
|
||||
cp2 = cp;
|
||||
if (setjmp(rewrite))
|
||||
goto redo;
|
||||
(void)signal(SIGTSTP, ttystop);
|
||||
(void)signal(SIGTTOU, ttystop);
|
||||
(void)signal(SIGTTIN, ttystop);
|
||||
clearerr(stdin);
|
||||
while (cp2 < canonb + sizeof(canonb)) {
|
||||
cp2 = cp;
|
||||
while (cp2 < canonb + sizeof(canonb) - 1) {
|
||||
c = getc(stdin);
|
||||
if (c == EOF || c == '\n')
|
||||
sig_check();
|
||||
if (c == EOF) {
|
||||
if (feof(stdin))
|
||||
(void)putc('\n', stdout);
|
||||
break;
|
||||
}
|
||||
if (c == '\n')
|
||||
break;
|
||||
*cp2++ = c;
|
||||
}
|
||||
*cp2 = 0;
|
||||
(void)signal(SIGTSTP, SIG_DFL);
|
||||
(void)signal(SIGTTOU, SIG_DFL);
|
||||
(void)signal(SIGTTIN, SIG_DFL);
|
||||
*cp2 = '\0';
|
||||
|
||||
if (c == EOF && ferror(stdin)) {
|
||||
redo:
|
||||
cp = strlen(canonb) > 0 ? canonb : NULL;
|
||||
clearerr(stdin);
|
||||
return readtty(pr, cp);
|
||||
|
@ -174,9 +148,13 @@ redo:
|
|||
#ifndef TIOCSTI
|
||||
if (cp == NULL || *cp == '\0')
|
||||
return src;
|
||||
cp2 = cp;
|
||||
if (!ttyset)
|
||||
if (ttyset == 0)
|
||||
return strlen(canonb) > 0 ? savestr(canonb) : NULL;
|
||||
|
||||
/*
|
||||
* Do erase and kill.
|
||||
*/
|
||||
cp2 = cp;
|
||||
while (*cp != '\0') {
|
||||
c = *cp++;
|
||||
if (c_erase != _POSIX_VDISABLE && c == c_erase) {
|
||||
|
@ -203,173 +181,193 @@ redo:
|
|||
}
|
||||
*cp2 = '\0';
|
||||
#endif
|
||||
if (equal("", canonb))
|
||||
return NULL;
|
||||
if (canonb[0] == '\0')
|
||||
return __UNCONST("");
|
||||
return savestr(canonb);
|
||||
}
|
||||
#endif /* USE_EDITLINE */
|
||||
|
||||
#ifdef USE_EDITLINE
|
||||
# define save_erase_and_kill(t) 0
|
||||
#else
|
||||
static int
|
||||
save_erase_and_kill(struct termios *t)
|
||||
{
|
||||
|
||||
# ifndef TIOCSTI
|
||||
ttyset = 0;
|
||||
#endif
|
||||
if (tcgetattr(fileno(stdin), t) == -1) {
|
||||
warn("tcgetattr");
|
||||
return -1;
|
||||
}
|
||||
c_erase = t->c_cc[VERASE];
|
||||
c_kill = t->c_cc[VKILL];
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_EDITLINE) || defined(TIOCSTI)
|
||||
# define disable_erase_and_kill(t)
|
||||
#else
|
||||
static void
|
||||
disable_erase_and_kill(struct termios *t)
|
||||
{
|
||||
|
||||
if (ttyset == 0) {
|
||||
ttyset = 1;
|
||||
t->c_cc[VERASE] = _POSIX_VDISABLE;
|
||||
t->c_cc[VKILL] = _POSIX_VDISABLE;
|
||||
(void)tcsetattr(fileno(stdin), TCSADRAIN, t);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_EDITLINE) || defined(TIOCSTI)
|
||||
# define restore_erase_and_kill(t)
|
||||
#else
|
||||
static void
|
||||
restore_erase_and_kill(struct termios *t)
|
||||
{
|
||||
|
||||
if (ttyset != 0) {
|
||||
ttyset = 0;
|
||||
t->c_cc[VERASE] = c_erase;
|
||||
t->c_cc[VKILL] = c_kill;
|
||||
(void)tcsetattr(fileno(stdin), TCSADRAIN, t);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do a shell-like extraction of a line
|
||||
* and make a list of name from it.
|
||||
* Return the list or NULL if none found.
|
||||
*/
|
||||
static struct name *
|
||||
shextract(char *line, int ntype)
|
||||
{
|
||||
struct name *begin, *np, *t;
|
||||
char *argv[MAXARGC];
|
||||
size_t argc, i;
|
||||
|
||||
begin = NULL;
|
||||
if (line) {
|
||||
np = NULL;
|
||||
argc = getrawlist(line, argv, (int)__arraycount(argv));
|
||||
for (i = 0; i < argc; i++) {
|
||||
t = nalloc(argv[i], ntype);
|
||||
if (begin == NULL)
|
||||
begin = t;
|
||||
else
|
||||
np->n_flink = t;
|
||||
t->n_blink = np;
|
||||
np = t;
|
||||
}
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ttyint(int s __unused)
|
||||
tty_sigint(int signo __unused)
|
||||
{
|
||||
longjmp(intjmp, 1);
|
||||
|
||||
longjmp(tty_jmpbuf, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read all relevant header fields.
|
||||
* Returns 0 on success; 1 if there was an error or signal.
|
||||
*/
|
||||
PUBLIC int
|
||||
grabh(struct header *hp, int gflags)
|
||||
{
|
||||
struct termios ttybuf;
|
||||
|
||||
/* The following are declared volatile to avoid longjmp
|
||||
* clobbering, though they seem safe without it! */
|
||||
sig_t volatile saveint;
|
||||
sig_t volatile savetstp;
|
||||
sig_t volatile savettou;
|
||||
sig_t volatile savettin;
|
||||
#ifndef TIOCSTI
|
||||
sig_t volatile savequit;
|
||||
#else
|
||||
# ifdef TIOCEXT
|
||||
int volatile extproc;
|
||||
# endif /* TIOCEXT */
|
||||
#endif /* TIOCSTI */
|
||||
sig_t volatile old_sigint;
|
||||
int retval;
|
||||
#ifndef USE_EDITLINE
|
||||
struct termios ttybuf;
|
||||
# if defined(TIOCSTI) && defined(TIOCEXT)
|
||||
int extproc;
|
||||
# endif
|
||||
|
||||
savetstp = signal(SIGTSTP, SIG_DFL);
|
||||
savettou = signal(SIGTTOU, SIG_DFL);
|
||||
savettin = signal(SIGTTIN, SIG_DFL);
|
||||
#ifndef TIOCSTI
|
||||
ttyset = 0;
|
||||
#endif
|
||||
if (tcgetattr(fileno(stdin), &ttybuf) < 0) {
|
||||
warn("tcgetattr");
|
||||
if (save_erase_and_kill(&ttybuf))
|
||||
return -1;
|
||||
}
|
||||
#if !defined(USE_EDITLINE) || !defined(TIOCSTI)
|
||||
c_erase = ttybuf.c_cc[VERASE];
|
||||
c_kill = ttybuf.c_cc[VKILL];
|
||||
#endif
|
||||
#ifndef TIOCSTI
|
||||
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
|
||||
|
||||
# if defined(TIOCSTI) && defined(TIOCEXT)
|
||||
extproc = ((ttybuf.c_lflag & EXTPROC) ? 1 : 0);
|
||||
if (extproc) {
|
||||
int flag;
|
||||
|
||||
flag = 0;
|
||||
if (ioctl(fileno(stdin), TIOCEXT, &flag) < 0)
|
||||
if (ioctl(fileno(stdin), TIOCEXT, &flag) == -1)
|
||||
warn("TIOCEXT: off");
|
||||
}
|
||||
# endif /* TIOCEXT */
|
||||
saveint = signal(SIGINT, ttyint); /* must precede setjmp to be saved */
|
||||
if ((retval = setjmp(intjmp)) != 0) {
|
||||
(void)fputc('\n', stdout);
|
||||
# endif
|
||||
#endif /* USE_EDITLINE */
|
||||
|
||||
sig_check();
|
||||
old_sigint = sig_signal(SIGINT, tty_sigint);
|
||||
|
||||
/* return here if we detect a SIGINT */
|
||||
if ((retval = setjmp(tty_jmpbuf)) != 0) {
|
||||
(void)putc('\n', stdout);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do this irrespective of whether the initial string is empty.
|
||||
* Otherwise, the editing is inconsistent.
|
||||
*/
|
||||
disable_erase_and_kill(&ttybuf);
|
||||
|
||||
if (gflags & GTO) {
|
||||
#ifndef TIOCSTI
|
||||
if (!ttyset && hp->h_to != NULL)
|
||||
ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
|
||||
#endif
|
||||
hp->h_to =
|
||||
extract(readtty("To: ", detract(hp->h_to, 0)), GTO);
|
||||
extract(readtty("To: ", detract(hp->h_to, 0)), GTO);
|
||||
}
|
||||
if (gflags & GSUBJECT) {
|
||||
#ifndef TIOCSTI
|
||||
if (!ttyset && hp->h_subject != NULL)
|
||||
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, &ttybuf);
|
||||
#endif
|
||||
hp->h_cc =
|
||||
extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC);
|
||||
extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC);
|
||||
}
|
||||
if (gflags & GBCC) {
|
||||
#ifndef TIOCSTI
|
||||
if (!ttyset && hp->h_bcc != NULL)
|
||||
ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
|
||||
#endif
|
||||
hp->h_bcc =
|
||||
extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC);
|
||||
extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC);
|
||||
}
|
||||
if (gflags & GSMOPTS) {
|
||||
char *smopts;
|
||||
#ifndef TIOCSTI
|
||||
if (!ttyset && hp->h_smopts != NULL)
|
||||
ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
|
||||
#endif
|
||||
smopts = readtty("Smopts: ", detract(hp->h_smopts, GSMOPTS));
|
||||
|
||||
/* Parse smopts with getrawlist() rather than expand()
|
||||
* to get a shell-like expansion.
|
||||
*/
|
||||
hp->h_smopts = NULL;
|
||||
if (smopts) {
|
||||
struct name *np, *t;
|
||||
char *argv[MAXARGC];
|
||||
int argc, i;
|
||||
|
||||
np = NULL;
|
||||
argc = getrawlist(smopts, argv, sizeof(argv)/sizeof(*argv));
|
||||
for (i = 0; i < argc; i++) {
|
||||
t = nalloc(argv[i], GSMOPTS);
|
||||
if (hp->h_smopts == NULL)
|
||||
hp->h_smopts = t;
|
||||
else
|
||||
np->n_flink = t;
|
||||
t->n_blink = np;
|
||||
np = t;
|
||||
}
|
||||
}
|
||||
hp->h_smopts =
|
||||
shextract(readtty("Smopts: ", detract(hp->h_smopts, 0)),
|
||||
GSMOPTS);
|
||||
}
|
||||
#ifdef MIME_SUPPORT
|
||||
if (gflags & GSMOPTS) { /* XXX - Use a new flag for this? */
|
||||
if (hp->h_attach) {
|
||||
struct attachment *ap;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
for (ap = hp->h_attach; ap; ap = ap->a_flink)
|
||||
i++;
|
||||
(void)printf("Attachment%s: %d\n", i > 1 ? "s" : "", i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef TIOCSTI
|
||||
out:
|
||||
#endif
|
||||
(void)signal(SIGTSTP, savetstp);
|
||||
(void)signal(SIGTTOU, savettou);
|
||||
(void)signal(SIGTTIN, savettin);
|
||||
#ifndef TIOCSTI
|
||||
ttybuf.c_cc[VERASE] = c_erase;
|
||||
ttybuf.c_cc[VKILL] = c_kill;
|
||||
if (ttyset)
|
||||
tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
|
||||
(void)signal(SIGQUIT, savequit);
|
||||
#else
|
||||
# ifdef TIOCEXT
|
||||
out:
|
||||
restore_erase_and_kill(&ttybuf);
|
||||
|
||||
#ifndef USE_EDITLINE
|
||||
# if defined(TIOCSTI) && defined(TIOCEXT)
|
||||
if (extproc) {
|
||||
int flag;
|
||||
flag = 1;
|
||||
if (ioctl(fileno(stdin), TIOCEXT, &flag) < 0)
|
||||
if (ioctl(fileno(stdin), TIOCEXT, &flag) == -1)
|
||||
warn("TIOCEXT: on");
|
||||
}
|
||||
# endif /* TIOCEXT */
|
||||
# endif
|
||||
#endif
|
||||
(void)signal(SIGINT, saveint);
|
||||
(void)sig_signal(SIGINT, old_sigint);
|
||||
sig_check();
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: version.c,v 1.12 2007/02/15 17:18:15 christos Exp $ */
|
||||
/* $NetBSD: version.c,v 1.13 2009/04/10 13:08:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)version.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: version.c,v 1.12 2007/02/15 17:18:15 christos Exp $");
|
||||
__RCSID("$NetBSD: version.c,v 1.13 2009/04/10 13:08:25 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -45,4 +45,4 @@ __RCSID("$NetBSD: version.c,v 1.12 2007/02/15 17:18:15 christos Exp $");
|
|||
* Just keep track of the date/sid of this version of Mail.
|
||||
* Load this file first to get a "total" Mail version.
|
||||
*/
|
||||
const char *version = "9.0beta 2007-02-15";
|
||||
const char *version = "9.1alpha 2009-02-25";
|
||||
|
|
Loading…
Reference in New Issue