summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/util.c')
-rw-r--r--contrib/sendmail/src/util.c565
1 files changed, 339 insertions, 226 deletions
diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c
index 0cb8992..fa0f74a 100644
--- a/contrib/sendmail/src/util.c
+++ b/contrib/sendmail/src/util.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 1998 Sendmail, Inc. All rights reserved.
+ * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
@@ -11,11 +12,15 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)util.c 8.168 (Berkeley) 1/21/1999";
-#endif /* not lint */
+static char id[] = "@(#)$Id: util.c,v 8.225.2.1.2.8 2000/07/03 18:28:56 geir Exp $";
+#endif /* ! lint */
+
+#include <sendmail.h>
+#include <sysexits.h>
+
+
+static void readtimeout __P((time_t));
-# include "sendmail.h"
-# include <sysexits.h>
/*
** STRIPQUOTES -- Strip quotes & quote bits from a string.
**
@@ -30,9 +35,6 @@ static char sccsid[] = "@(#)util.c 8.168 (Berkeley) 1/21/1999";
**
** Side Effects:
** none.
-**
-** Called By:
-** deliver
*/
void
@@ -91,7 +93,7 @@ addquotes(s)
if (c == '\\' || c == '"')
len++;
}
-
+
q = r = xalloc(len + 3);
p = s;
@@ -176,7 +178,7 @@ rfc822_string(s)
/*
** SHORTEN_RFC822_STRING -- Truncate and rebalance an RFC822 string
**
-** Arbitratily shorten (in place) an RFC822 string and rebalance
+** Arbitrarily shorten (in place) an RFC822 string and rebalance
** comments and quotes.
**
** Parameters:
@@ -202,7 +204,7 @@ shorten_rfc822_string(string, length)
size_t slen;
int parencount = 0;
char *ptr = string;
-
+
/*
** If have to rebalance an already short enough string,
** need to do it within allocated space.
@@ -231,14 +233,14 @@ shorten_rfc822_string(string, length)
if (--parencount < 0)
parencount = 0;
}
-
+
/* Inside a comment, quotes don't matter */
if (parencount <= 0 && *ptr == '"')
quoted = !quoted;
increment:
/* Check for sufficient space for next character */
- if (length - (ptr - string) <= ((backslash ? 1 : 0) +
+ if (length - (ptr - string) <= (size_t) ((backslash ? 1 : 0) +
parencount +
(quoted ? 1 : 0)))
{
@@ -299,12 +301,12 @@ increment:
char *
find_character(string, character)
char *string;
- char character;
+ int character;
{
bool backslash = FALSE;
bool quoted = FALSE;
int parencount = 0;
-
+
while (string != NULL && *string != '\0')
{
if (backslash)
@@ -320,25 +322,25 @@ find_character(string, character)
case '\\':
backslash = TRUE;
break;
-
+
case '(':
if (!quoted)
parencount++;
break;
-
+
case ')':
if (--parencount < 0)
parencount = 0;
break;
}
-
+
/* Inside a comment, nothing matters */
if (parencount > 0)
{
string++;
continue;
}
-
+
if (*string == '"')
quoted = !quoted;
else if (*string == character && !quoted)
@@ -381,7 +383,7 @@ xalloc(sz)
syserr("!Out of memory!!");
/* exit(EX_UNAVAILABLE); */
}
- return (p);
+ return p;
}
/*
** COPYPLIST -- copy list of pointers.
@@ -416,7 +418,7 @@ copyplist(list, copycont)
vp++;
newvp = (char **) xalloc((int) (vp - list) * sizeof *vp);
- bcopy((char *) list, (char *) newvp, (int) (vp - list) * sizeof *vp);
+ memmove((char *) newvp, (char *) list, (int) (vp - list) * sizeof *vp);
if (copycont)
{
@@ -424,13 +426,13 @@ copyplist(list, copycont)
*vp = newstr(*vp);
}
- return (newvp);
+ return newvp;
}
/*
** COPYQUEUE -- copy address queue.
**
** This routine is the equivalent of newstr for address queues
-** addresses marked with QDONTSEND aren't copied
+** addresses marked as QS_IS_DEAD() aren't copied
**
** Parameters:
** addr -- list of address structures to copy.
@@ -452,9 +454,9 @@ copyqueue(addr)
while (addr != NULL)
{
- if (!bitset(QDONTSEND, addr->q_flags))
+ if (!QS_IS_DEAD(addr->q_state))
{
- newaddr = (ADDRESS *) xalloc(sizeof(ADDRESS));
+ newaddr = (ADDRESS *) xalloc(sizeof *newaddr);
STRUCTCOPY(*addr, *newaddr);
*tail = newaddr;
tail = &newaddr->q_next;
@@ -462,10 +464,81 @@ copyqueue(addr)
addr = addr->q_next;
}
*tail = NULL;
-
+
return ret;
}
/*
+** LOG_SENDMAIL_PID -- record sendmail pid and command line.
+**
+** Parameters:
+** e -- the current envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** writes pidfile.
+*/
+
+void
+log_sendmail_pid(e)
+ ENVELOPE *e;
+{
+ long sff;
+ FILE *pidf;
+ char pidpath[MAXPATHLEN + 1];
+
+ /* write the pid to the log file for posterity */
+ sff = SFF_NOLINK|SFF_ROOTOK|SFF_REGONLY|SFF_CREAT;
+ if (TrustedUid != 0 && RealUid == TrustedUid)
+ sff |= SFF_OPENASROOT;
+ expand(PidFile, pidpath, sizeof pidpath, e);
+ pidf = safefopen(pidpath, O_WRONLY|O_TRUNC, 0644, sff);
+ if (pidf == NULL)
+ {
+ sm_syslog(LOG_ERR, NOQID, "unable to write %s", pidpath);
+ }
+ else
+ {
+ extern char *CommandLineArgs;
+
+ /* write the process id on line 1 */
+ fprintf(pidf, "%ld\n", (long) getpid());
+
+ /* line 2 contains all command line flags */
+ fprintf(pidf, "%s\n", CommandLineArgs);
+
+ /* flush and close */
+ (void) fclose(pidf);
+ }
+}
+ /*
+** SET_DELIVERY_MODE -- set and record the delivery mode
+**
+** Parameters:
+** mode -- delivery mode
+** e -- the current envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** sets $&{deliveryMode} macro
+*/
+
+void
+set_delivery_mode(mode, e)
+ int mode;
+ ENVELOPE *e;
+{
+ char buf[2];
+
+ e->e_sendmode = (char)mode;
+ buf[0] = (char)mode;
+ buf[1] = '\0';
+ define(macid("{deliveryMode}", NULL), newstr(buf), e);
+}
+ /*
** PRINTAV -- print argument vector.
**
** Parameters:
@@ -485,7 +558,7 @@ printav(av)
while (*av != NULL)
{
if (tTd(0, 44))
- printf("\n\t%08lx=", (u_long) *av);
+ dprintf("\n\t%08lx=", (u_long) *av);
else
(void) putchar(' ');
xputs(*av++);
@@ -507,9 +580,9 @@ printav(av)
char
lower(c)
- register char c;
+ register int c;
{
- return((isascii(c) && isupper(c)) ? tolower(c) : c);
+ return ((isascii(c) && isupper(c)) ? tolower(c) : c);
}
/*
** XPUTS -- put string doing control escapes.
@@ -560,12 +633,12 @@ xputs(s)
{
printf("%s$", TermEscape.te_rv_on);
if (c == MACRODEXPAND)
- putchar('&');
+ (void) putchar('&');
shiftout = TRUE;
if (*s == '\0')
continue;
if (strchr("=~&?", *s) != NULL)
- putchar(*s++);
+ (void) putchar(*s++);
if (bitset(0200, *s))
printf("{%s}", macname(*s++ & 0377));
else
@@ -601,7 +674,7 @@ xputs(s)
printchar:
if (isprint(c))
{
- putchar(c);
+ (void) putchar(c);
continue;
}
@@ -652,9 +725,6 @@ xputs(s)
**
** Side Effects:
** String pointed to by p is translated to lower case.
-**
-** Called By:
-** parse
*/
void
@@ -677,7 +747,7 @@ makelower(p)
**
** Parameters:
** p -- name to build.
-** login -- the login name of this user (for &).
+** user -- the login name of this user (for &).
** buf -- place to put the result.
** buflen -- length of buf.
**
@@ -689,9 +759,9 @@ makelower(p)
*/
void
-buildfname(gecos, login, buf, buflen)
+buildfname(gecos, user, buf, buflen)
register char *gecos;
- char *login;
+ char *user;
char *buf;
int buflen;
{
@@ -707,13 +777,13 @@ buildfname(gecos, login, buf, buflen)
if (bp >= &buf[buflen - 1])
{
/* buffer overflow -- just use login name */
- snprintf(buf, buflen, "%s", login);
+ snprintf(buf, buflen, "%s", user);
return;
}
if (*p == '&')
{
/* interpolate full name */
- snprintf(bp, buflen - (bp - buf), "%s", login);
+ snprintf(bp, buflen - (bp - buf), "%s", user);
*bp = toupper(*bp);
bp += strlen(bp);
}
@@ -810,9 +880,9 @@ putxline(l, len, mci, pxflags)
register MCI *mci;
int pxflags;
{
+ bool dead = FALSE;
register char *p, *end;
int slop = 0;
- size_t eol_len = strlen(mci->mci_mailer->m_eol);
/* strip out 0200 bits -- these can look like TELNET protocol */
if (bitset(MCIF_7BIT, mci->mci_flags) ||
@@ -846,9 +916,8 @@ putxline(l, len, mci, pxflags)
if (l[0] == '.' && slop == 0 &&
bitnset(M_XDOT, mci->mci_mailer->m_flags))
{
- (void) putc('.', mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen++;
+ if (putc('.', mci->mci_out) == EOF)
+ dead = TRUE;
if (TrafficLogFile != NULL)
(void) putc('.', TrafficLogFile);
}
@@ -857,44 +926,61 @@ putxline(l, len, mci, pxflags)
strncmp(l, "From ", 5) == 0 &&
bitnset(M_ESCFROM, mci->mci_mailer->m_flags))
{
- (void) putc('>', mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen++;
+ if (putc('>', mci->mci_out) == EOF)
+ dead = TRUE;
if (TrafficLogFile != NULL)
(void) putc('>', TrafficLogFile);
}
+ if (dead)
+ break;
+
while (l < q)
{
- (void) putc(*l++, mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen++;
+ if (putc((unsigned char) *l++, mci->mci_out) ==
+ EOF)
+ {
+ dead = TRUE;
+ break;
+ }
+
+ /* record progress for DATA timeout */
+ DataProgress = TRUE;
+ }
+ if (dead)
+ break;
+
+ if (putc('!', mci->mci_out) == EOF ||
+ fputs(mci->mci_mailer->m_eol,
+ mci->mci_out) == EOF ||
+ putc(' ', mci->mci_out) == EOF)
+ {
+ dead = TRUE;
+ break;
}
- (void) putc('!', mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen++;
- fputs(mci->mci_mailer->m_eol, mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen += eol_len;
- (void) putc(' ', mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen++;
+
+ /* record progress for DATA timeout */
+ DataProgress = TRUE;
+
if (TrafficLogFile != NULL)
{
for (l = l_base; l < q; l++)
- (void) putc(*l, TrafficLogFile);
+ (void) putc((unsigned char)*l,
+ TrafficLogFile);
fprintf(TrafficLogFile, "!\n%05d >>> ",
(int) getpid());
}
slop = 1;
}
+ if (dead)
+ break;
+
/* output last part */
if (l[0] == '.' && slop == 0 &&
bitnset(M_XDOT, mci->mci_mailer->m_flags))
{
- (void) putc('.', mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen++;
+ if (putc('.', mci->mci_out) == EOF)
+ break;
if (TrafficLogFile != NULL)
(void) putc('.', TrafficLogFile);
}
@@ -903,37 +989,45 @@ putxline(l, len, mci, pxflags)
strncmp(l, "From ", 5) == 0 &&
bitnset(M_ESCFROM, mci->mci_mailer->m_flags))
{
- (void) putc('>', mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen++;
+ if (putc('>', mci->mci_out) == EOF)
+ break;
if (TrafficLogFile != NULL)
(void) putc('>', TrafficLogFile);
}
for ( ; l < p; ++l)
{
if (TrafficLogFile != NULL)
- (void) putc(*l, TrafficLogFile);
- (void) putc(*l, mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen++;
+ (void) putc((unsigned char)*l, TrafficLogFile);
+ if (putc((unsigned char) *l, mci->mci_out) == EOF)
+ {
+ dead = TRUE;
+ break;
+ }
+
+ /* record progress for DATA timeout */
+ DataProgress = TRUE;
}
+ if (dead)
+ break;
+
if (TrafficLogFile != NULL)
(void) putc('\n', TrafficLogFile);
- fputs(mci->mci_mailer->m_eol, mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen += eol_len;
+ if (fputs(mci->mci_mailer->m_eol, mci->mci_out) == EOF)
+ break;
if (l < end && *l == '\n')
{
if (*++l != ' ' && *l != '\t' && *l != '\0' &&
bitset(PXLF_HEADER, pxflags))
{
- (void) putc(' ', mci->mci_out);
- if (!bitset(MCIF_INHEADER, mci->mci_flags))
- mci->mci_contentlen++;
+ if (putc(' ', mci->mci_out) == EOF)
+ break;
if (TrafficLogFile != NULL)
(void) putc(' ', TrafficLogFile);
}
}
+
+ /* record progress for DATA timeout */
+ DataProgress = TRUE;
} while (l < end);
}
/*
@@ -957,42 +1051,14 @@ xunlink(f)
if (LogLevel > 98)
sm_syslog(LOG_DEBUG, CurEnv->e_id,
- "unlink %s",
- f);
+ "unlink %s",
+ f);
i = unlink(f);
if (i < 0 && LogLevel > 97)
sm_syslog(LOG_DEBUG, CurEnv->e_id,
- "%s: unlink-fail %d",
- f, errno);
-}
- /*
-** XFCLOSE -- close a file, doing logging as appropriate.
-**
-** Parameters:
-** fp -- file pointer for the file to close
-** a, b -- miscellaneous crud to print for debugging
-**
-** Returns:
-** none.
-**
-** Side Effects:
-** fp is closed.
-*/
-
-void
-xfclose(fp, a, b)
- FILE *fp;
- char *a, *b;
-{
- if (tTd(53, 99))
- printf("xfclose(%lx) %s %s\n", (u_long) fp, a, b);
-#if XDEBUG
- if (fileno(fp) == 1)
- syserr("xfclose(%s %s): fd = 1", a, b);
-#endif
- if (fclose(fp) < 0 && tTd(53, 99))
- printf("xfclose FAILURE: %s\n", errstring(errno));
+ "%s: unlink-fail %d",
+ f, errno);
}
/*
** SFGETS -- "safe" fgets -- times out and ignores random interrupts.
@@ -1013,8 +1079,8 @@ xfclose(fp, a, b)
** none.
*/
+
static jmp_buf CtxReadTimeout;
-static void readtimeout __P((time_t));
char *
sfgets(buf, siz, fp, timeout, during)
@@ -1041,18 +1107,18 @@ sfgets(buf, siz, fp, timeout, during)
{
if (LogLevel > 1)
sm_syslog(LOG_NOTICE, CurEnv->e_id,
- "timeout waiting for input from %.100s during %s",
- CurHostName ? CurHostName : "local",
- during);
+ "timeout waiting for input from %.100s during %s",
+ CurHostName ? CurHostName : "local",
+ during);
buf[0] = '\0';
#if XDEBUG
checkfd012(during);
-#endif
+#endif /* XDEBUG */
if (TrafficLogFile != NULL)
fprintf(TrafficLogFile, "%05d <<< [TIMEOUT]\n",
(int) getpid());
errno = 0;
- return (NULL);
+ return NULL;
}
ev = setevent(timeout, readtimeout, 0);
}
@@ -1081,7 +1147,7 @@ sfgets(buf, siz, fp, timeout, during)
if (TrafficLogFile != NULL)
fprintf(TrafficLogFile, "%05d <<< [EOF]\n", (int) getpid());
errno = save_errno;
- return (NULL);
+ return NULL;
}
if (TrafficLogFile != NULL)
fprintf(TrafficLogFile, "%05d <<< %s", (int) getpid(), buf);
@@ -1101,7 +1167,7 @@ sfgets(buf, siz, fp, timeout, during)
}
}
}
- return (buf);
+ return buf;
}
/* ARGSUSED */
@@ -1165,7 +1231,7 @@ fgetfolded(buf, n, f)
else
nn += MEMCHUNKSIZE;
nbp = xalloc(nn);
- bcopy(bp, nbp, p - bp);
+ memmove(nbp, bp, p - bp);
p = &nbp[p - bp];
if (bp != buf)
free(bp);
@@ -1184,11 +1250,11 @@ fgetfolded(buf, n, f)
}
}
if (p == bp)
- return (NULL);
+ return NULL;
if (p[-1] == '\n')
p--;
*p = '\0';
- return (bp);
+ return bp;
}
/*
** CURTIME -- return current time.
@@ -1209,7 +1275,7 @@ curtime()
auto time_t t;
(void) time(&t);
- return (t);
+ return t;
}
/*
** ATOBOOL -- convert a string representation to boolean.
@@ -1232,8 +1298,8 @@ atobool(s)
register char *s;
{
if (s == NULL || *s == '\0' || strchr("tTyY", *s) != NULL)
- return (TRUE);
- return (FALSE);
+ return TRUE;
+ return FALSE;
}
/*
** ATOOCT -- convert a string representation to octal.
@@ -1257,7 +1323,7 @@ atooct(s)
while (*s >= '0' && *s <= '7')
i = (i << 3) | (*s++ - '0');
- return (i);
+ return i;
}
/*
** BITINTERSECT -- tell if two bitmaps intersect
@@ -1275,15 +1341,15 @@ atooct(s)
bool
bitintersect(a, b)
- BITMAP a;
- BITMAP b;
+ BITMAP256 a;
+ BITMAP256 b;
{
int i;
for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
if ((a[i] & b[i]) != 0)
- return (TRUE);
- return (FALSE);
+ return TRUE;
+ return FALSE;
}
/*
** BITZEROP -- tell if a bitmap is all zero
@@ -1301,14 +1367,14 @@ bitintersect(a, b)
bool
bitzerop(map)
- BITMAP map;
+ BITMAP256 map;
{
int i;
for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
if (map[i] != 0)
- return (FALSE);
- return (TRUE);
+ return FALSE;
+ return TRUE;
}
/*
** STRCONTAINEDIN -- tell if one string is contained in another
@@ -1393,7 +1459,7 @@ checkfdopen(fd, where)
syserr("checkfdopen(%d): %s not open as expected!", fd, where);
printopenfds(TRUE);
}
-#endif
+#endif /* XDEBUG */
}
/*
** CHECKFDS -- check for new or missing file descriptors
@@ -1416,7 +1482,7 @@ checkfds(where)
register int fd;
bool printhdr = TRUE;
int save_errno = errno;
- static BITMAP baseline;
+ static BITMAP256 baseline;
extern int DtableSize;
if (DtableSize > 256)
@@ -1447,8 +1513,8 @@ checkfds(where)
if (printhdr)
{
sm_syslog(LOG_DEBUG, CurEnv->e_id,
- "%s: changed fds:",
- where);
+ "%s: changed fds:",
+ where);
printhdr = FALSE;
}
dumpfd(fd, TRUE, TRUE);
@@ -1466,7 +1532,9 @@ checkfds(where)
** none.
*/
-#include <arpa/inet.h>
+#if NETINET || NETINET6
+# include <arpa/inet.h>
+#endif /* NETINET || NETINET6 */
void
printopenfds(logit)
@@ -1498,14 +1566,14 @@ dumpfd(fd, printclosed, logit)
char *hp;
#ifdef S_IFSOCK
SOCKADDR sa;
-#endif
+#endif /* S_IFSOCK */
auto SOCKADDR_LEN_T slen;
int i;
#if STAT64 > 0
struct stat64 st;
-#else
+#else /* STAT64 > 0 */
struct stat st;
-#endif
+#endif /* STAT64 > 0 */
char buf[200];
p = buf;
@@ -1515,9 +1583,9 @@ dumpfd(fd, printclosed, logit)
if (
#if STAT64 > 0
fstat64(fd, &st)
-#else
+#else /* STAT64 > 0 */
fstat(fd, &st)
-#endif
+#endif /* STAT64 > 0 */
< 0)
{
if (errno != EBADF)
@@ -1541,7 +1609,7 @@ dumpfd(fd, printclosed, logit)
p += strlen(p);
}
- snprintf(p, SPACELEFT(buf, p), "mode=%o: ", st.st_mode);
+ snprintf(p, SPACELEFT(buf, p), "mode=%o: ", (int) st.st_mode);
p += strlen(p);
switch (st.st_mode & S_IFMT)
{
@@ -1549,15 +1617,29 @@ dumpfd(fd, printclosed, logit)
case S_IFSOCK:
snprintf(p, SPACELEFT(buf, p), "SOCK ");
p += strlen(p);
+ memset(&sa, '\0', sizeof sa);
slen = sizeof sa;
if (getsockname(fd, &sa.sa, &slen) < 0)
- snprintf(p, SPACELEFT(buf, p), "(%s)", errstring(errno));
+ snprintf(p, SPACELEFT(buf, p), "(%s)",
+ errstring(errno));
else
{
hp = hostnamebyanyaddr(&sa);
- if (sa.sa.sa_family == AF_INET)
+ if (hp == NULL)
+ {
+ /* EMPTY */
+ /* do nothing */
+ }
+# if NETINET
+ else if (sa.sa.sa_family == AF_INET)
+ snprintf(p, SPACELEFT(buf, p), "%s/%d",
+ hp, ntohs(sa.sin.sin_port));
+# endif /* NETINET */
+# if NETINET6
+ else if (sa.sa.sa_family == AF_INET6)
snprintf(p, SPACELEFT(buf, p), "%s/%d",
- hp, ntohs(sa.sin.sin_port));
+ hp, ntohs(sa.sin6.sin6_port));
+# endif /* NETINET6 */
else
snprintf(p, SPACELEFT(buf, p), "%s", hp);
}
@@ -1570,14 +1652,26 @@ dumpfd(fd, printclosed, logit)
else
{
hp = hostnamebyanyaddr(&sa);
- if (sa.sa.sa_family == AF_INET)
+ if (hp == NULL)
+ {
+ /* EMPTY */
+ /* do nothing */
+ }
+# if NETINET
+ else if (sa.sa.sa_family == AF_INET)
snprintf(p, SPACELEFT(buf, p), "%s/%d",
- hp, ntohs(sa.sin.sin_port));
+ hp, ntohs(sa.sin.sin_port));
+# endif /* NETINET */
+# if NETINET6
+ else if (sa.sa.sa_family == AF_INET6)
+ snprintf(p, SPACELEFT(buf, p), "%s/%d",
+ hp, ntohs(sa.sin6.sin6_port));
+# endif /* NETINET6 */
else
snprintf(p, SPACELEFT(buf, p), "%s", hp);
}
break;
-#endif
+#endif /* S_IFSOCK */
case S_IFCHR:
snprintf(p, SPACELEFT(buf, p), "CHR: ");
@@ -1594,36 +1688,40 @@ dumpfd(fd, printclosed, logit)
snprintf(p, SPACELEFT(buf, p), "FIFO: ");
p += strlen(p);
goto defprint;
-#endif
+#endif /* defined(S_IFIFO) && (!defined(S_IFSOCK) || S_IFIFO != S_IFSOCK) */
#ifdef S_IFDIR
case S_IFDIR:
snprintf(p, SPACELEFT(buf, p), "DIR: ");
p += strlen(p);
goto defprint;
-#endif
+#endif /* S_IFDIR */
#ifdef S_IFLNK
case S_IFLNK:
snprintf(p, SPACELEFT(buf, p), "LNK: ");
p += strlen(p);
goto defprint;
-#endif
+#endif /* S_IFLNK */
default:
defprint:
+ /*CONSTCOND*/
if (sizeof st.st_ino > sizeof (long))
snprintf(p, SPACELEFT(buf, p),
"dev=%d/%d, ino=%s, nlink=%d, u/gid=%d/%d, ",
major(st.st_dev), minor(st.st_dev),
quad_to_string(st.st_ino),
- st.st_nlink, st.st_uid, st.st_gid);
+ (int) st.st_nlink, (int) st.st_uid,
+ (int) st.st_gid);
else
snprintf(p, SPACELEFT(buf, p),
- "dev=%d/%d, ino=%lu, nlink=%d, u/gid=%d/%d, ",
- major(st.st_dev), minor(st.st_dev),
- (unsigned long) st.st_ino,
- st.st_nlink, st.st_uid, st.st_gid);
+ "dev=%d/%d, ino=%lu, nlink=%d, u/gid=%d/%d, ",
+ major(st.st_dev), minor(st.st_dev),
+ (unsigned long) st.st_ino,
+ (int) st.st_nlink, (int) st.st_uid,
+ (int) st.st_gid);
+ /*CONSTCOND*/
if (sizeof st.st_size > sizeof (long))
snprintf(p, SPACELEFT(buf, p), "size=%s",
quad_to_string(st.st_size));
@@ -1636,7 +1734,7 @@ defprint:
printit:
if (logit)
sm_syslog(LOG_DEBUG, CurEnv ? CurEnv->e_id : NULL,
- "%.800s", buf);
+ "%.800s", buf);
else
printf("%s\n", buf);
}
@@ -1701,7 +1799,7 @@ prog_open(argv, pfd, e)
{
int pid;
int i;
- int saveerrno;
+ int save_errno;
int fdv[2];
char *p, *q;
char buf[MAXLINE + 1];
@@ -1716,34 +1814,37 @@ prog_open(argv, pfd, e)
if (pid < 0)
{
syserr("%s: cannot fork", argv[0]);
- close(fdv[0]);
- close(fdv[1]);
+ (void) close(fdv[0]);
+ (void) close(fdv[1]);
return -1;
}
if (pid > 0)
{
/* parent */
- close(fdv[1]);
+ (void) close(fdv[1]);
*pfd = fdv[0];
return pid;
}
/* child -- close stdin */
- close(0);
+ (void) close(0);
/* stdout goes back to parent */
- close(fdv[0]);
+ (void) close(fdv[0]);
if (dup2(fdv[1], 1) < 0)
{
syserr("%s: cannot dup2 for stdout", argv[0]);
_exit(EX_OSERR);
}
- close(fdv[1]);
+ (void) close(fdv[1]);
/* stderr goes to transcript if available */
if (e->e_xfp != NULL)
{
- if (dup2(fileno(e->e_xfp), 2) < 0)
+ int xfd;
+
+ xfd = fileno(e->e_xfp);
+ if (xfd >= 0 && dup2(xfd, 2) < 0)
{
syserr("%s: cannot dup2 for stderr", argv[0]);
_exit(EX_OSERR);
@@ -1752,14 +1853,36 @@ prog_open(argv, pfd, e)
/* this process has no right to the queue file */
if (e->e_lockfp != NULL)
- close(fileno(e->e_lockfp));
+ (void) close(fileno(e->e_lockfp));
+
+ /* chroot to the program mailer directory, if defined */
+ if (ProgMailer != NULL && ProgMailer->m_rootdir != NULL)
+ {
+ expand(ProgMailer->m_rootdir, buf, sizeof buf, e);
+ if (chroot(buf) < 0)
+ {
+ syserr("prog_open: cannot chroot(%s)", buf);
+ exit(EX_TEMPFAIL);
+ }
+ if (chdir("/") < 0)
+ {
+ syserr("prog_open: cannot chdir(/)");
+ exit(EX_TEMPFAIL);
+ }
+ }
/* run as default user */
endpwent();
if (setgid(DefGid) < 0 && geteuid() == 0)
+ {
syserr("prog_open: setgid(%ld) failed", (long) DefGid);
+ exit(EX_TEMPFAIL);
+ }
if (setuid(DefUid) < 0 && geteuid() == 0)
+ {
syserr("prog_open: setuid(%ld) failed", (long) DefUid);
+ exit(EX_TEMPFAIL);
+ }
/* run in some directory */
if (ProgMailer != NULL)
@@ -1790,22 +1913,22 @@ prog_open(argv, pfd, e)
register int j;
if ((j = fcntl(i, F_GETFD, 0)) != -1)
- (void) fcntl(i, F_SETFD, j | 1);
+ (void) fcntl(i, F_SETFD, j | FD_CLOEXEC);
}
/* now exec the process */
- execve(argv[0], (ARGV_T) argv, (ARGV_T) UserEnviron);
+ (void) execve(argv[0], (ARGV_T) argv, (ARGV_T) UserEnviron);
/* woops! failed */
- saveerrno = errno;
+ save_errno = errno;
syserr("%s: cannot exec", argv[0]);
- if (transienterror(saveerrno))
+ if (transienterror(save_errno))
_exit(EX_OSERR);
_exit(EX_CONFIG);
return -1; /* avoid compiler warning on IRIX */
}
/*
-** GET_COLUMN -- look up a Column in a line buffer
+** GET_COLUMN -- look up a Column in a line buffer
**
** Parameters:
** line -- the raw text line to search.
@@ -1824,7 +1947,7 @@ char *
get_column(line, col, delim, buf, buflen)
char line[];
int col;
- char delim;
+ int delim;
char buf[];
int buflen;
{
@@ -1832,24 +1955,24 @@ get_column(line, col, delim, buf, buflen)
char *begin, *end;
int i;
char delimbuf[4];
-
- if (delim == '\0')
- strcpy(delimbuf, "\n\t ");
+
+ if ((char)delim == '\0')
+ (void) strlcpy(delimbuf, "\n\t ", sizeof delimbuf);
else
{
- delimbuf[0] = delim;
+ delimbuf[0] = (char)delim;
delimbuf[1] = '\0';
}
p = line;
if (*p == '\0')
return NULL; /* line empty */
- if (*p == delim && col == 0)
+ if (*p == (char)delim && col == 0)
return NULL; /* first column empty */
begin = line;
- if (col == 0 && delim == '\0')
+ if (col == 0 && (char)delim == '\0')
{
while (*begin != '\0' && isascii(*begin) && isspace(*begin))
begin++;
@@ -1860,13 +1983,13 @@ get_column(line, col, delim, buf, buflen)
if ((begin = strpbrk(begin, delimbuf)) == NULL)
return NULL; /* no such column */
begin++;
- if (delim == '\0')
+ if ((char)delim == '\0')
{
while (*begin != '\0' && isascii(*begin) && isspace(*begin))
begin++;
}
}
-
+
end = strpbrk(begin, delimbuf);
if (end == NULL)
i = strlen(begin);
@@ -1874,8 +1997,7 @@ get_column(line, col, delim, buf, buflen)
i = end - begin;
if (i >= buflen)
i = buflen - 1;
- strncpy(buf, begin, i);
- buf[i] = '\0';
+ (void) strlcpy(buf, begin, i + 1);
return buf;
}
/*
@@ -1899,6 +2021,9 @@ cleanstrcpy(t, f, l)
/* check for newlines and log if necessary */
(void) denlstring(f, TRUE, TRUE);
+ if (l <= 0)
+ syserr("!cleanstrcpy: length == 0");
+
l--;
while (l > 0 && *f != '\0')
{
@@ -1912,6 +2037,7 @@ cleanstrcpy(t, f, l)
}
*t = '\0';
}
+
/*
** DENLSTRING -- convert newlines in a string to spaces
**
@@ -1952,16 +2078,16 @@ denlstring(s, strict, logattacks)
bp = xalloc(l);
bl = l;
}
- strcpy(bp, s);
+ (void) strlcpy(bp, s, l);
for (p = bp; (p = strchr(p, '\n')) != NULL; )
*p++ = ' ';
if (logattacks)
{
sm_syslog(LOG_NOTICE, CurEnv->e_id,
- "POSSIBLE ATTACK from %.100s: newline in string \"%s\"",
- RealHostName == NULL ? "[UNKNOWN]" : RealHostName,
- shortenstring(bp, MAXSHORTSTR));
+ "POSSIBLE ATTACK from %.100s: newline in string \"%s\"",
+ RealHostName == NULL ? "[UNKNOWN]" : RealHostName,
+ shortenstring(bp, MAXSHORTSTR));
}
return bp;
@@ -1991,9 +2117,9 @@ path_is_dir(pathname, createflag)
#if HASLSTAT
if (lstat(pathname, &statbuf) < 0)
-#else
+#else /* HASLSTAT */
if (stat(pathname, &statbuf) < 0)
-#endif
+#endif /* HASLSTAT */
{
if (errno != ENOENT || !createflag)
return FALSE;
@@ -2021,29 +2147,21 @@ path_is_dir(pathname, createflag)
**
** Parameters:
** pid -- pid to add to list.
+** task -- task of pid.
+** type -- type of process.
**
** Returns:
** none
*/
-struct procs
-{
- pid_t proc_pid;
- char *proc_task;
-};
-
-static struct procs *ProcListVec = NULL;
-static int ProcListSize = 0;
-
-#define NO_PID ((pid_t) 0)
-#ifndef PROC_LIST_SEG
-# define PROC_LIST_SEG 32 /* number of pids to alloc at a time */
-#endif
+static struct procs *ProcListVec = NULL;
+static int ProcListSize = 0;
void
-proc_list_add(pid, task)
+proc_list_add(pid, task, type)
pid_t pid;
char *task;
+ int type;
{
int i;
@@ -2069,24 +2187,29 @@ proc_list_add(pid, task)
/* grow process list */
struct procs *npv;
- npv = (struct procs *) xalloc(sizeof (struct procs) * (ProcListSize + PROC_LIST_SEG));
+ npv = (struct procs *) xalloc((sizeof *npv) *
+ (ProcListSize + PROC_LIST_SEG));
if (ProcListSize > 0)
{
- bcopy(ProcListVec, npv, ProcListSize *
- sizeof (struct procs));
+ memmove(npv, ProcListVec,
+ ProcListSize * sizeof (struct procs));
free(ProcListVec);
}
for (i = ProcListSize; i < ProcListSize + PROC_LIST_SEG; i++)
{
npv[i].proc_pid = NO_PID;
npv[i].proc_task = NULL;
+ npv[i].proc_type = PROC_NONE;
}
i = ProcListSize;
ProcListSize += PROC_LIST_SEG;
ProcListVec = npv;
}
ProcListVec[i].proc_pid = pid;
+ if (ProcListVec[i].proc_task != NULL)
+ free(ProcListVec[i].proc_task);
ProcListVec[i].proc_task = newstr(task);
+ ProcListVec[i].proc_type = type;
/* if process adding itself, it's not a child */
if (pid != getpid())
@@ -2128,30 +2251,30 @@ proc_list_set(pid, task)
** pid -- pid to drop
**
** Returns:
-** none.
+** type of process
*/
-void
+int
proc_list_drop(pid)
pid_t pid;
{
int i;
+ int type = PROC_NONE;
for (i = 0; i < ProcListSize; i++)
{
if (ProcListVec[i].proc_pid == pid)
{
ProcListVec[i].proc_pid = NO_PID;
- if (ProcListVec[i].proc_task != NULL)
- {
- free(ProcListVec[i].proc_task);
- ProcListVec[i].proc_task = NULL;
- }
+ type = ProcListVec[i].proc_type;
break;
}
}
if (CurChildren > 0)
CurChildren--;
+
+
+ return type;
}
/*
** PROC_LIST_CLEAR -- clear the process list
@@ -2172,11 +2295,6 @@ proc_list_clear()
for (i = 1; i < ProcListSize; i++)
{
ProcListVec[i].proc_pid = NO_PID;
- if (ProcListVec[i].proc_task != NULL)
- {
- free(ProcListVec[i].proc_task);
- ProcListVec[i].proc_task = NULL;
- }
}
CurChildren = 0;
}
@@ -2204,14 +2322,9 @@ proc_list_probe()
{
if (LogLevel > 3)
sm_syslog(LOG_DEBUG, CurEnv->e_id,
- "proc_list_probe: lost pid %d",
- (int) ProcListVec[i].proc_pid);
+ "proc_list_probe: lost pid %d",
+ (int) ProcListVec[i].proc_pid);
ProcListVec[i].proc_pid = NO_PID;
- if (ProcListVec[i].proc_task != NULL)
- {
- free(ProcListVec[i].proc_task);
- ProcListVec[i].proc_task = NULL;
- }
CurChildren--;
}
}
@@ -2288,7 +2401,7 @@ proc_list_display(out)
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
+#endif /* defined(LIBC_SCCS) && !defined(lint) */
/*
* This array is designed for mapping upper and lower case letter
@@ -2340,7 +2453,7 @@ sm_strcasecmp(s1, s2)
while (cm[*us1] == cm[*us2++])
if (*us1++ == '\0')
- return (0);
+ return 0;
return (cm[*us1] - cm[*--us2]);
}
@@ -2361,5 +2474,5 @@ sm_strncasecmp(s1, s2, n)
break;
} while (--n != 0);
}
- return (0);
+ return 0;
}
OpenPOWER on IntegriCloud