**
*/
-
#include <h/mh.h>
#include <h/rcvmail.h>
#include <h/signals.h>
#include <h/tws.h>
#include <h/utils.h>
-
#include <pwd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <locale.h>
+#include <sysexits.h>
#ifdef INITGROUPS_HEADER
#include INITGROUPS_HEADER
#define VERBSW 8
{ "verbose", 0 },
#define NVERBSW 9
- { "noverbose", 0 },
+ { "noverbose", 2 },
#define DEBUGSW 10
{ "debug", 0 },
#define VERSIONSW 11
- { "version", 0 },
+ { "Version", 0 },
#define HELPSW 12
{ "help", 0 },
{ NULL, 0 }
static char ddate[BUFSIZ]; /* record the delivery date */
struct tws *now;
-static jmp_buf myctx;
+volatile sig_atomic_t eflag = 0; /* flag to indecate interrupt */
+static volatile pid_t child_id;
/* flags for pair->p_flags */
#define P_NIL 0x00
static void verbose_printf(char *fmt, ...);
static void adorn(char *, char *, ...);
static void debug_printf(char *fmt, ...);
-static char *trim(char *);
+static char *trimstr(char *);
int
char mailbox[BUFSIZ], tmpfil[BUFSIZ];
char **argp, **arguments;
-#ifdef LOCALE
setlocale(LC_ALL, "");
-#endif
invo_name = mhbasename(*argv);
- /* foil search of user profile/context */
- if (context_foil(NULL) == -1) {
- done(1);
- }
arguments = getarguments(invo_name, argc, argv, 0);
argp = arguments;
switch (smatch(++cp, switches)) {
case AMBIGSW:
ambigsw(cp, switches);
- done(1);
+ exit(EX_USAGE);
case UNKWNSW:
- adios(NULL, "-%s unknown", cp);
+ adios(EX_USAGE, NULL, "-%s unknown", cp);
case HELPSW:
snprintf(buf, sizeof(buf), "%s [switches] [address info sender]", invo_name);
print_help(buf, switches, 0);
- done(1);
+ exit(argc == 2 ? EX_OK : EX_USAGE);
case VERSIONSW:
print_version(invo_name);
- done(1);
+ exit(argc == 2 ? EX_OK : EX_USAGE);
case ADDRSW:
if (!(addr = *argp++)) {
/* allow -xyz arguments */
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
}
continue;
case INFOSW:
if (!(info = *argp++)) {
/* allow -xyz arguments */
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
}
continue;
case USERSW:
if (!(user = *argp++)) {
/* allow -xyz arguments */
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
}
continue;
case FILESW:
if (!(file = *argp++) || *file == '-') {
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
}
continue;
case SENDERSW:
if (!(sender = *argp++)) {
/* allow -xyz arguments */
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
}
continue;
case MAILBOXSW:
if (!(mbox = *argp++) || *mbox == '-') {
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
}
continue;
case HOMESW:
if (!(home = *argp++) || *home == '-') {
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
}
continue;
case MAILSW:
if (!(cp = *argp++) || *cp == '-') {
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
}
if (mdlvr) {
- adios(NULL, "only one maildelivery file at a time!");
+ adios(EX_USAGE, NULL, "only one maildelivery file at a time!");
}
mdlvr = cp;
continue;
user = (cp = strchr(addr, '.')) ? ++cp : addr;
}
if (!(pw = getpwnam(user))) {
- adios(NULL, "no such local user as %s", user);
+ adios(EX_NOUSER, NULL, "no such local user as %s", user);
}
if (chdir(pw->pw_dir) == -1) {
/* Record the delivery time */
if (!(now = dlocaltimenow())) {
- adios(NULL, "unable to ascertain local time");
+ adios(EX_OSERR, NULL, "unable to ascertain local time");
}
- snprintf(ddate, sizeof(ddate), "Delivery-Date: %s\n", dtimenow(0));
+ snprintf(ddate, sizeof(ddate), "Delivery-Date: %s\n", dtimenow());
/*
** Copy the message to a temporary file
/* getting message from file */
if ((tempfd = open(file, O_RDONLY)) == -1) {
- adios(file, "unable to open");
+ adios(EX_IOERR, file, "unable to open");
}
if (debug) {
debug_printf("retrieving message from file \"%s\"\n",
file);
}
if ((fd = copy_message(tempfd, tmpfil, 1)) == -1) {
- adios(NULL, "unable to create temporary file");
+ adios(EX_CANTCREAT, NULL, "unable to create temporary file");
}
close(tempfd);
} else {
debug_printf("retrieving message from stdin\n");
}
if ((fd = copy_message(fileno(stdin), tmpfil, 1)) == -1) {
- adios(NULL, "unable to create temporary file");
+ adios(EX_CANTCREAT, NULL, "unable to create temporary file");
}
}
unlink(tmpfil);
if (!(fp = fdopen(fd, "r+"))) {
- adios(NULL, "unable to access temporary file");
+ adios(EX_IOERR, NULL, "unable to access temporary file");
}
/* If no sender given, extract it from envelope information. */
}
if (debug) {
- debug_printf("addr=\"%s\"\n", trim(addr));
- debug_printf("user=\"%s\"\n", trim(user));
- debug_printf("info=\"%s\"\n", trim(info));
- debug_printf("sender=\"%s\"\n", trim(sender));
+ debug_printf("addr=\"%s\"\n", trimstr(addr));
+ debug_printf("user=\"%s\"\n", trimstr(user));
+ debug_printf("info=\"%s\"\n", trimstr(info));
+ debug_printf("sender=\"%s\"\n", trimstr(sender));
debug_printf("envelope=\"%s\"\n",
- envelope ? trim(envelope) : "");
- debug_printf("mbox=\"%s\"\n", trim(mbox));
- debug_printf("home=\"%s\"\n", trim(home));
- debug_printf("ddate=\"%s\"\n", trim(ddate));
+ envelope ? trimstr(envelope) : "");
+ debug_printf("mbox=\"%s\"\n", trimstr(mbox));
+ debug_printf("home=\"%s\"\n", trimstr(home));
+ debug_printf("ddate=\"%s\"\n", trimstr(ddate));
debug_printf("now=%02d:%02d\n\n", now->tw_hour, now->tw_min);
}
/* deliver the message */
status = localmail(fd, mdlvr);
- done(status != -1 ? RCV_MOK : RCV_MBX);
- return 1;
+ return (status != -1 ? RCV_MOK : RCV_MBX);
}
if (debug) {
for (i = 0; vec[i]; i++) {
debug_printf("vec[%d]: \"%s\"\n",
- i, trim(vec[i]));
+ i, trimstr(vec[i]));
}
}
static int
parse(int fd)
{
- int i, state;
- int fd1;
+ enum state state;
+ struct field f = {{0}};
+ int i, fd1;
char *cp, *dp, *lp;
- char name[NAMESZ], field[BUFSIZ];
struct pair *p, *q;
FILE *in;
/* add special entries to lookup table */
if ((p = lookup(hdrs, "source"))) {
- p->p_value = getcpy(sender);
+ p->p_value = mh_xstrdup(sender);
}
if ((p = lookup(hdrs, "addr"))) {
- p->p_value = getcpy(addr);
+ p->p_value = mh_xstrdup(addr);
}
/*
** Scan the headers of the message and build a lookup table.
*/
- for (i = 0, state = FLD;;) {
- switch (state = m_getfld(state, name, field, sizeof(field),
- in)) {
- case FLD:
- case FLDEOF:
- case FLDPLUS:
- lp = getcpy(field);
- while (state == FLDPLUS) {
- state = m_getfld(state, name, field,
- sizeof(field), in);
- lp = add(field, lp);
- }
+ for (i = 0, state = FLD2;;) {
+ switch (state = m_getfld2(state, &f, in)) {
+ case LENERR2:
+ state = FLD2;
+ /* FALL */
+
+ case FLD2:
+ lp = mh_xstrdup(f.value);
for (p = hdrs; p->p_name; p++) {
- if (mh_strcasecmp(p->p_name, name)!=0) {
+ if (mh_strcasecmp(p->p_name, f.name)!=0) {
if (!(p->p_flags & P_HID)) {
if ((cp = p->p_value)) {
if (p->p_flags & P_ADR) {
}
p->p_value = add(lp, cp);
}
- free(lp);
+ mh_free0(&lp);
break;
}
}
if (!p->p_name && i < NVEC) {
- p->p_name = getcpy(name);
+ p->p_name = mh_xstrdup(f.name);
p->p_value = lp;
p->p_flags = P_NIL;
p++, i++;
p->p_name = NULL;
}
- if (state != FLDEOF) {
- continue;
- }
- break;
+ continue;
- case BODY:
- case BODYEOF:
- case FILEEOF:
+ case BODY2:
+ case FILEEOF2:
break;
- case LENERR:
- case FMTERR:
+ case FMTERR2:
+ case IOERR2:
advise(NULL, "format error in message");
break;
if (!(q = lookup(hdrs, "reply-to")) || !q->p_value) {
q = lookup(hdrs, "from");
}
- p->p_value = getcpy(q ? q->p_value : "");
+ p->p_value = mh_xstrdup(q ? q->p_value : "");
p->p_flags &= ~P_CHK;
if (debug) {
debug_printf("vars[%d]: name=\"%s\" value=\"%s\"\n",
- p - vars, p->p_name, trim(p->p_value));
+ p - vars, p->p_name, trimstr(p->p_value));
}
}
if (debug) {
for (p = hdrs; p->p_name; p++) {
debug_printf("hdrs[%d]: name=\"%s\" value=\"%s\"\n",
p - hdrs, p->p_name,
- p->p_value ? trim(p->p_value) : "");
+ p->p_value ? trimstr(p->p_value) : "");
}
}
return 0;
return;
}
if ((p = lookup(vars, "sender"))) {
- p->p_value = getcpy(sender);
+ p->p_value = mh_xstrdup(sender);
}
if ((p = lookup(vars, "address"))) {
- p->p_value = getcpy(addr);
+ p->p_value = mh_xstrdup(addr);
}
if ((p = lookup(vars, "size"))) {
snprintf(buffer, sizeof(buffer), "%d",
fstat(fd, &st) != -1 ? (int) st.st_size : 0);
- p->p_value = getcpy(buffer);
+ p->p_value = mh_xstrdup(buffer);
}
if ((p = lookup(vars, "info"))) {
- p->p_value = getcpy(info);
+ p->p_value = mh_xstrdup(info);
}
if (debug) {
for (p = vars; p->p_name; p++) {
debug_printf("vars[%d]: name=\"%s\" value=\"%s\"\n",
- p - vars, p->p_name, trim(p->p_value));
+ p - vars, p->p_name, trimstr(p->p_value));
}
}
}
static int
usr_pipe(int fd, char *cmd, char *pgm, char **vec, int suppress)
{
- pid_t child_id;
int bytes, seconds, status, n;
struct stat st;
char *path;
m_putenv("PATH", path);
execvp(pgm, vec);
- _exit(-1);
+ _exit(EX_OSERR);
default:
/* parent process */
- if (setjmp(myctx)) {
- /*
- ** Ruthlessly kill the child and anything
- ** else in its process group.
- */
- kill(-child_id, SIGKILL);
- if (verbose)
- verbose_printf(", timed-out; terminated\n");
- return -1;
- }
SIGNAL(SIGALRM, alrmser);
bytes = fstat(fd, &st) != -1 ? (int) st.st_size : 100;
status = pidwait(child_id, 0);
alarm(0);
+ if (eflag) {
+ if (verbose) {
+ verbose_printf(", timed-out; terminated\n");
+ }
+ return -1;
+ }
+
if (verbose) {
if (!status) {
verbose_printf(", success.\n");
static void
alrmser(int i)
{
- longjmp(myctx, DONE);
+ eflag = 1;
+ kill(-child_id, SIGKILL);
}
unsigned char buffer[BUFSIZ];
if (!envelope) {
- *sender = getcpy("");
+ *sender = mh_xstrdup("");
return;
}
i = strlen("From ");
strncpy(buffer, envelope + i, sizeof(buffer));
+ buffer[sizeof buffer -1] = '\0'; /* ensure termination */
if ((cp = strchr(buffer, '\n'))) {
*cp = '\0';
cp -= 24;
} else {
break;
}
- *sender = getcpy(buffer);
+ *sender = mh_xstrdup(buffer);
}
** get copy of envelope information
** ("From " line)
*/
- envelope = getcpy(buffer);
+ envelope = mh_xstrdup(buffer);
/* Put the delivery date in message */
fputs(ddate, ffp);
** Trim strings for pretty printing of debugging output
*/
static char *
-trim(char *cp)
+trimstr(char *cp)
{
char buffer[BUFSIZ*4];
unsigned char *bp, *sp;
*sp = ' ';
}
}
- return getcpy(bp);
+ return mh_xstrdup(bp);
}
/*