-
-/*
- * slocal.c -- asynchronously filter and deliver new mail
+/* slocal.c -- asynchronously filter and deliver new mail
*
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
#include <h/tws.h>
#include <h/mts.h>
#include <h/utils.h>
+#include "../sbr/lock_file.h"
+#include "../sbr/m_mktemp.h"
#include <pwd.h>
#include <sys/ioctl.h>
main (int argc, char **argv)
{
int fd, status;
- FILE *fp = stdin;
+ FILE *fp;
char *cp, *mdlvr = NULL, buf[BUFSIZ];
char mailbox[BUFSIZ], tmpfil[BUFSIZ];
char **argp, **arguments;
-#ifdef LOCALE
- setlocale(LC_ALL, "");
-#endif
- invo_name = r1bindex (*argv, '/');
+ if (nmh_init(argv[0], 0 /* use context_foil() */)) { return 1; }
- /* foil search of user profile/context */
- if (context_foil (NULL) == -1)
- done (1);
-
- mts_init (invo_name);
+ mts_init ();
arguments = getarguments (invo_name, argc, argv, 0);
argp = arguments;
if (addr == NULL)
addr = getusername ();
- if (user == NULL)
- user = (cp = strchr(addr, '.')) ? ++cp : addr;
+ if (user == NULL) {
+ user = getusername ();
+ }
if ((pw = getpwnam (user)) == NULL)
adios (NULL, "no such local user as %s", user);
if (chdir (pw->pw_dir) == -1)
- chdir ("/");
+ if (chdir ("/") < 0) {
+ advise ("/", "chdir");
+ }
umask (0077);
if (geteuid() == 0) {
- setgid (pw->pw_gid);
+ if (setgid (pw->pw_gid) != 0) {
+ adios ("setgid", "unable to set group to %ld", (long) pw->pw_gid);
+ }
initgroups (pw->pw_name, pw->pw_gid);
- setuid (pw->pw_uid);
+ if (setuid (pw->pw_uid) != 0) {
+ adios ("setuid", "unable to set user to %ld", (long) pw->pw_uid);
+ }
}
-
+
if (info == NULL)
info = "";
thing would be to delay this unlink() until later if debug == 1, but I'll
leave that for someone who cares about the temp-file-accessing
functionality (they'll have to watch out for cases where we adios()). */
- unlink (tmpfil);
+ (void) m_unlink (tmpfil);
if (!(fp = fdopen (fd, "r+")))
adios (NULL, "unable to access temporary file");
int i, accept, status=1, won, vecp, next;
char *field, *pattern, *action, *result, *string;
char buffer[BUFSIZ], tmpbuf[BUFSIZ];
- char *cp, *vec[NVEC];
+ char *vec[NVEC];
struct stat st;
struct pair *p;
FILE *fp;
if (*buffer == '#' || *buffer == '\n')
continue;
- /* zap trailing newline */
- if ((cp = strchr(buffer, '\n')))
- *cp = 0;
+ trim_suffix_c(buffer, '\n');
/* split buffer into fields */
vecp = split (buffer, vec);
* do this - else fall through
*/
if (!next)
- continue; /* else fall */
+ continue;
+ /* FALLTHRU */
case '?':
/*
* consider delivered if action is successful.
*/
if (won)
- continue; /* else fall */
+ continue;
+ /* FALLTHRU */
case 'A':
case 'a':
if (won)
continue;
break;
- } /* else fall */
+ }
+ /* FALLTHRU */
default:
/* parse message and build lookup table */
case 'q':
/* deliver to quoted pipe */
if (strcasecmp (action, "qpipe"))
- continue; /* else fall */
+ continue;
+ /* FALLTHRU */
case '^':
expand (tmpbuf, string, fd);
if (split (tmpbuf, vec) < 1)
case 'p':
/* deliver to pipe */
if (strcasecmp (action, "pipe"))
- continue; /* else fall */
+ continue;
+ /* FALLTHRU */
case '|':
vec[2] = "sh";
vec[3] = "-c";
}
/* deliver to nmh folder */
else if (strcasecmp (action, "folder"))
- continue; /* else fall */
+ continue;
+ /* FALLTHRU */
case '+':
status = usr_folder (fd, string);
break;
}
/* mbox format */
else if (strcasecmp (action, "mbox"))
- continue; /* else fall */
+ continue;
+ /* FALLTHRU */
case '>':
/* mbox format */
int i, state;
int fd1;
char *cp, *dp, *lp;
- char name[NAMESZ], field[BUFSIZ];
+ char name[NAMESZ], field[NMH_BUFSIZ];
struct pair *p, *q;
FILE *in;
m_getfld_state_t gstate = 0;
switch (state = m_getfld (&gstate, name, field, &fieldsz, in)) {
case FLD:
case FLDPLUS:
- lp = add (field, NULL);
+ lp = mh_xstrdup(field);
while (state == FLDPLUS) {
fieldsz = sizeof field;
state = m_getfld (&gstate, name, field, &fieldsz, in);
}
}
if (p->p_name == NULL && i < NVEC) {
- p->p_name = getcpy (name);
+ p->p_name = mh_xstrdup(name);
p->p_value = lp;
p->p_flags = P_NIL;
p++, i++;
case LENERR:
case FMTERR:
- advise (NULL, "format error in message");
+ inform("format error in message");
break;
default:
- advise (NULL, "internal error in m_getfld");
+ inform("internal error in m_getfld");
fclose (in);
return -1;
}
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);
static int
usr_file (int fd, char *mailbox, int mbx_style)
{
- int md, mapping;
+ int md;
- if (verbose)
- verbose_printf ("delivering to file \"%s\"", mailbox);
-
- if (mbx_style == MBOX_FORMAT) {
- if (verbose)
- verbose_printf (" (mbox style)");
- mapping = 0;
- } else {
- if (verbose)
- verbose_printf (" (mmdf style)");
- mapping = 1;
+ if (verbose) {
+ verbose_printf("delivering to file \"%s\" (%s style)", mailbox,
+ mbx_style == MBOX_FORMAT ? "mbox" : "mmdf");
}
/* open and lock the file */
return -1;
}
- lseek (fd, (off_t) 0, SEEK_SET);
+ lseek(fd, 0, SEEK_SET);
/* append message to file */
- if (mbx_copy (mailbox, mbx_style, md, fd, mapping, NULL, verbose) == -1) {
+ if (mbx_copy (mailbox, mbx_style, md, fd, NULL) == -1) {
if (verbose)
adorn ("", "error writing to:");
return -1;
if (verbose && !suppress)
verbose_printf ("delivering to pipe \"%s\"", cmd);
- lseek (fd, (off_t) 0, SEEK_SET);
+ lseek(fd, 0, SEEK_SET);
for (i = 0; (child_id = fork()) == -1 && i < 5; i++)
sleep (5);
/* child process */
if (fd != 0)
dup2 (fd, 0);
- freopen ("/dev/null", "w", stdout);
- freopen ("/dev/null", "w", stderr);
+ if (freopen ("/dev/null", "w", stdout) == NULL) {
+ advise ("stdout", "freopen");
+ }
+ if (freopen ("/dev/null", "w", stderr) == NULL) {
+ advise ("stderr", "freopen");
+ }
if (fd != 3)
dup2 (fd, 3);
closefds (4);
setpgid ((pid_t) 0, getpid ()); /* put in own process group */
*environ = NULL;
- m_putenv ("USER", pw->pw_name);
- m_putenv ("HOME", pw->pw_dir);
- m_putenv ("SHELL", pw->pw_shell);
+ setenv("USER", pw->pw_name, 1);
+ setenv("HOME", pw->pw_dir, 1);
+ setenv("SHELL", pw->pw_shell, 1);
execvp (pgm, vec);
_exit (-1);
pidstatus (status, stdout, ", failed");
}
return (status == 0 ? 0 : -1);
- } else {
- /*
- * Ruthlessly kill the child and anything
- * else in its process group.
- */
- killpg(child_id, SIGKILL);
- if (verbose)
- verbose_printf (", timed-out; terminated\n");
- return -1;
}
+ /*
+ * Ruthlessly kill the child and anything
+ * else in its process group.
+ */
+ killpg(child_id, SIGKILL);
+ if (verbose)
+ verbose_printf (", timed-out; terminated\n");
+ return -1;
}
}
char buffer[BUFSIZ];
if (envelope == NULL) {
- *sender = getcpy ("");
+ *sender = mh_xstrdup("");
return;
}
- i = strlen ("From ");
+ i = LEN("From ");
strncpy (buffer, envelope + i, sizeof(buffer));
if ((cp = strchr(buffer, '\n'))) {
*cp = 0;
*cp = 0;
else
break;
- *sender = getcpy (buffer);
+ *sender = mh_xstrdup(buffer);
}
if (write (fd1, buffer, i) != i) {
you_lose:
close (fd1);
- unlink (tmpfil);
+ (void) m_unlink (tmpfil);
return -1;
}
if (i == -1)
goto you_lose;
- lseek (fd1, (off_t) 0, SEEK_SET);
+ lseek(fd1, 0, SEEK_SET);
return fd1;
}
* and massage the headers. Save
* a copy of the "From " line for later.
*/
- i = strlen ("From ");
while (fgets (buffer, sizeof(buffer), qfp)) {
if (first) {
first = 0;
- if (!strncmp (buffer, "From ", i)) {
+ if (has_prefix(buffer, "From ")) {
/* get copy of envelope information ("From " line) */
- envelope = getcpy (buffer);
+ envelope = mh_xstrdup(buffer);
/* Put the delivery date in message */
fputs (ddate, ffp);
return -1;
}
fclose (qfp);
- lseek (fd1, (off_t) 0, SEEK_SET);
+ lseek(fd1, 0, SEEK_SET);
return fd1;
*sp = ' ';
/* now return a copy */
- return getcpy(bp);
+ return mh_xstrdup(bp);
}
/*
va_list ap;
va_start(ap, fmt);
- vfprintf (stdout, fmt, ap);
+ vprintf(fmt, ap);
va_end(ap);
fflush (stdout); /* now flush output */
char *s;
eindex = errno; /* save the errno */
- fprintf (stdout, ", ");
+ printf(", ");
va_start(ap, fmt);
- vfprintf (stdout, fmt, ap);
+ vprintf(fmt, ap);
va_end(ap);
if (what) {
if (*what)
- fprintf (stdout, " %s: ", what);
+ printf(" %s: ", what);
if ((s = strerror (eindex)))
- fprintf (stdout, "%s", s);
+ fputs(s, stdout);
else
- fprintf (stdout, "Error %d", eindex);
+ printf("Error %d", eindex);
}
- fputc ('\n', stdout);
+ putchar('\n');
fflush (stdout);
}
suppress_duplicates (int fd, char *file)
{
int fd1, lockfd, state, result;
- char *cp, buf[BUFSIZ], name[NAMESZ];
+ char *cp, buf[NMH_BUFSIZ], name[NAMESZ];
datum key, value;
DBM *db;
FILE *in;
rewind (in);
for (;;) {
+ int failed_to_lock = 0;
int bufsz = sizeof buf;
state = m_getfld (&gstate, name, buf, &bufsz, in);
switch (state) {
continue;
}
- cp = add (buf, NULL);
+ cp = mh_xstrdup(buf);
while (state == FLDPLUS) {
bufsz = sizeof buf;
state = m_getfld (&gstate, name, buf, &bufsz, in);
* This will fail if your Maildelivery file doesn't
* exist.
*/
- if ((lockfd = lkopendata(file, O_RDWR, 0)) == -1) {
+ if ((lockfd = lkopendata(file, O_RDWR, 0, &failed_to_lock))
+ == -1) {
advise (file, "unable to perform file locking on");
free (cp);
fclose (in);