summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c586
1 files changed, 476 insertions, 110 deletions
diff --git a/src/util.c b/src/util.c
index 2e5aebe..0cb8992 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,39 +1,17 @@
/*
- * Copyright (c) 1983, 1995-1997 Eric P. Allman
+ * Copyright (c) 1998 Sendmail, Inc. 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.
*
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
*
- * 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.
*/
#ifndef lint
-static char sccsid[] = "@(#)util.c 8.137 (Berkeley) 10/22/97";
+static char sccsid[] = "@(#)util.c 8.168 (Berkeley) 1/21/1999";
#endif /* not lint */
# include "sendmail.h"
@@ -80,6 +58,298 @@ stripquotes(s)
} while (c != '\0');
}
/*
+** ADDQUOTES -- Adds quotes & quote bits to a string.
+**
+** Runs through a string and adds characters and quote bits.
+**
+** Parameters:
+** s -- the string to modify.
+**
+** Returns:
+** pointer to quoted string.
+**
+** Side Effects:
+** none.
+**
+*/
+
+char *
+addquotes(s)
+ char *s;
+{
+ int len = 0;
+ char c;
+ char *p = s, *q, *r;
+
+ if (s == NULL)
+ return NULL;
+
+ /* Find length of quoted string */
+ while ((c = *p++) != '\0')
+ {
+ len++;
+ if (c == '\\' || c == '"')
+ len++;
+ }
+
+ q = r = xalloc(len + 3);
+ p = s;
+
+ /* add leading quote */
+ *q++ = '"';
+ while ((c = *p++) != '\0')
+ {
+ /* quote \ or " */
+ if (c == '\\' || c == '"')
+ *q++ = '\\';
+ *q++ = c;
+ }
+ *q++ = '"';
+ *q = '\0';
+ return r;
+}
+ /*
+** RFC822_STRING -- Checks string for proper RFC822 string quoting.
+**
+** Runs through a string and verifies RFC822 special characters
+** are only found inside comments, quoted strings, or backslash
+** escaped. Also verified balanced quotes and parenthesis.
+**
+** Parameters:
+** s -- the string to modify.
+**
+** Returns:
+** TRUE -- if the string is RFC822 compliant.
+** FALSE -- if the string is not RFC822 compliant.
+**
+** Side Effects:
+** none.
+**
+*/
+
+bool
+rfc822_string(s)
+ char *s;
+{
+ bool quoted = FALSE;
+ int commentlev = 0;
+ char *c = s;
+
+ if (s == NULL)
+ return FALSE;
+
+ while (*c != '\0')
+ {
+ /* escaped character */
+ if (*c == '\\')
+ {
+ c++;
+ if (*c == '\0')
+ return FALSE;
+ }
+ else if (commentlev == 0 && *c == '"')
+ quoted = !quoted;
+ else if (!quoted)
+ {
+ if (*c == ')')
+ {
+ /* unbalanced ')' */
+ if (commentlev == 0)
+ return FALSE;
+ else
+ commentlev--;
+ }
+ else if (*c == '(')
+ commentlev++;
+ else if (commentlev == 0 &&
+ strchr(MustQuoteChars, *c) != NULL)
+ return FALSE;
+ }
+ c++;
+ }
+ /* unbalanced '"' or '(' */
+ if (quoted || commentlev != 0)
+ return FALSE;
+ else
+ return TRUE;
+}
+ /*
+** SHORTEN_RFC822_STRING -- Truncate and rebalance an RFC822 string
+**
+** Arbitratily shorten (in place) an RFC822 string and rebalance
+** comments and quotes.
+**
+** Parameters:
+** string -- the string to shorten
+** length -- the maximum size, 0 if no maximum
+**
+** Returns:
+** TRUE if string is changed, FALSE otherwise
+**
+** Side Effects:
+** Changes string in place, possibly resulting
+** in a shorter string.
+*/
+
+bool
+shorten_rfc822_string(string, length)
+ char *string;
+ size_t length;
+{
+ bool backslash = FALSE;
+ bool modified = FALSE;
+ bool quoted = FALSE;
+ 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.
+ */
+ slen = strlen(string);
+ if (length == 0 || slen < length)
+ length = slen;
+
+ while (*ptr != '\0')
+ {
+ if (backslash)
+ {
+ backslash = FALSE;
+ goto increment;
+ }
+
+ if (*ptr == '\\')
+ backslash = TRUE;
+ else if (*ptr == '(')
+ {
+ if (!quoted)
+ parencount++;
+ }
+ else if (*ptr == ')')
+ {
+ 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) +
+ parencount +
+ (quoted ? 1 : 0)))
+ {
+ /* Not enough, backtrack */
+ if (*ptr == '\\')
+ backslash = FALSE;
+ else if (*ptr == '(' && !quoted)
+ parencount--;
+ else if (*ptr == '"' && parencount == 0)
+ quoted = FALSE;
+ break;
+ }
+ ptr++;
+ }
+
+ /* Rebalance */
+ while (parencount-- > 0)
+ {
+ if (*ptr != ')')
+ {
+ modified = TRUE;
+ *ptr = ')';
+ }
+ ptr++;
+ }
+ if (quoted)
+ {
+ if (*ptr != '"')
+ {
+ modified = TRUE;
+ *ptr = '"';
+ }
+ ptr++;
+ }
+ if (*ptr != '\0')
+ {
+ modified = TRUE;
+ *ptr = '\0';
+ }
+ return modified;
+}
+ /*
+** FIND_CHARACTER -- find an unquoted character in an RFC822 string
+**
+** Find an unquoted, non-commented character in an RFC822
+** string and return a pointer to its location in the
+** string.
+**
+** Parameters:
+** string -- the string to search
+** character -- the character to find
+**
+** Returns:
+** pointer to the character, or
+** a pointer to the end of the line if character is not found
+*/
+
+char *
+find_character(string, character)
+ char *string;
+ char character;
+{
+ bool backslash = FALSE;
+ bool quoted = FALSE;
+ int parencount = 0;
+
+ while (string != NULL && *string != '\0')
+ {
+ if (backslash)
+ {
+ backslash = FALSE;
+ if (!quoted && character == '\\' && *string == '\\')
+ break;
+ string++;
+ continue;
+ }
+ switch (*string)
+ {
+ 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)
+ break;
+ string++;
+ }
+
+ /* Return pointer to the character */
+ return string;
+}
+ /*
** XALLOC -- Allocate memory and bitch wildly on failure.
**
** THIS IS A CLUDGE. This should be made to give a proper
@@ -286,10 +556,14 @@ xputs(s)
c = *s++ & 0377;
goto printchar;
}
- if (c == MACROEXPAND)
+ if (c == MACROEXPAND || c == MACRODEXPAND)
{
printf("%s$", TermEscape.te_rv_on);
+ if (c == MACRODEXPAND)
+ putchar('&');
shiftout = TRUE;
+ if (*s == '\0')
+ continue;
if (strchr("=~&?", *s) != NULL)
putchar(*s++);
if (bitset(0200, *s))
@@ -538,6 +812,7 @@ putxline(l, len, mci, pxflags)
{
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) ||
@@ -572,6 +847,8 @@ putxline(l, len, mci, pxflags)
bitnset(M_XDOT, mci->mci_mailer->m_flags))
{
(void) putc('.', mci->mci_out);
+ if (!bitset(MCIF_INHEADER, mci->mci_flags))
+ mci->mci_contentlen++;
if (TrafficLogFile != NULL)
(void) putc('.', TrafficLogFile);
}
@@ -581,14 +858,26 @@ putxline(l, len, mci, pxflags)
bitnset(M_ESCFROM, mci->mci_mailer->m_flags))
{
(void) putc('>', mci->mci_out);
+ if (!bitset(MCIF_INHEADER, mci->mci_flags))
+ mci->mci_contentlen++;
if (TrafficLogFile != NULL)
(void) putc('>', TrafficLogFile);
}
while (l < q)
+ {
(void) putc(*l++, mci->mci_out);
+ if (!bitset(MCIF_INHEADER, mci->mci_flags))
+ mci->mci_contentlen++;
+ }
(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++;
if (TrafficLogFile != NULL)
{
for (l = l_base; l < q; l++)
@@ -604,6 +893,8 @@ putxline(l, len, mci, pxflags)
bitnset(M_XDOT, mci->mci_mailer->m_flags))
{
(void) putc('.', mci->mci_out);
+ if (!bitset(MCIF_INHEADER, mci->mci_flags))
+ mci->mci_contentlen++;
if (TrafficLogFile != NULL)
(void) putc('.', TrafficLogFile);
}
@@ -613,6 +904,8 @@ putxline(l, len, mci, pxflags)
bitnset(M_ESCFROM, mci->mci_mailer->m_flags))
{
(void) putc('>', mci->mci_out);
+ if (!bitset(MCIF_INHEADER, mci->mci_flags))
+ mci->mci_contentlen++;
if (TrafficLogFile != NULL)
(void) putc('>', TrafficLogFile);
}
@@ -621,16 +914,22 @@ putxline(l, len, mci, pxflags)
if (TrafficLogFile != NULL)
(void) putc(*l, TrafficLogFile);
(void) putc(*l, mci->mci_out);
+ if (!bitset(MCIF_INHEADER, mci->mci_flags))
+ mci->mci_contentlen++;
}
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 (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 (TrafficLogFile != NULL)
(void) putc(' ', TrafficLogFile);
}
@@ -715,7 +1014,7 @@ xfclose(fp, a, b)
*/
static jmp_buf CtxReadTimeout;
-static void readtimeout();
+static void readtimeout __P((time_t));
char *
sfgets(buf, siz, fp, timeout, during)
@@ -727,6 +1026,7 @@ sfgets(buf, siz, fp, timeout, during)
{
register EVENT *ev = NULL;
register char *p;
+ int save_errno;
if (fp == NULL)
{
@@ -744,7 +1044,6 @@ sfgets(buf, siz, fp, timeout, during)
"timeout waiting for input from %.100s during %s",
CurHostName ? CurHostName : "local",
during);
- errno = 0;
buf[0] = '\0';
#if XDEBUG
checkfd012(during);
@@ -752,6 +1051,7 @@ sfgets(buf, siz, fp, timeout, during)
if (TrafficLogFile != NULL)
fprintf(TrafficLogFile, "%05d <<< [TIMEOUT]\n",
(int) getpid());
+ errno = 0;
return (NULL);
}
ev = setevent(timeout, readtimeout, 0);
@@ -759,6 +1059,7 @@ sfgets(buf, siz, fp, timeout, during)
/* try to read */
p = NULL;
+ errno = 0;
while (!feof(fp) && !ferror(fp))
{
errno = 0;
@@ -767,6 +1068,7 @@ sfgets(buf, siz, fp, timeout, during)
break;
clearerr(fp);
}
+ save_errno = errno;
/* clear the event if it has not sprung */
clrevent(ev);
@@ -778,6 +1080,7 @@ sfgets(buf, siz, fp, timeout, during)
buf[0] = '\0';
if (TrafficLogFile != NULL)
fprintf(TrafficLogFile, "%05d <<< [EOF]\n", (int) getpid());
+ errno = save_errno;
return (NULL);
}
if (TrafficLogFile != NULL)
@@ -801,6 +1104,7 @@ sfgets(buf, siz, fp, timeout, during)
return (buf);
}
+/* ARGSUSED */
static void
readtimeout(timeout)
time_t timeout;
@@ -1192,20 +1496,29 @@ dumpfd(fd, printclosed, logit)
{
register char *p;
char *hp;
- char *fmtstr;
#ifdef S_IFSOCK
SOCKADDR sa;
#endif
auto SOCKADDR_LEN_T slen;
int i;
+#if STAT64 > 0
+ struct stat64 st;
+#else
struct stat st;
+#endif
char buf[200];
p = buf;
snprintf(p, SPACELEFT(buf, p), "%3d: ", fd);
p += strlen(p);
- if (fstat(fd, &st) < 0)
+ if (
+#if STAT64 > 0
+ fstat64(fd, &st)
+#else
+ fstat(fd, &st)
+#endif
+ < 0)
{
if (errno != EBADF)
{
@@ -1299,13 +1612,24 @@ dumpfd(fd, printclosed, logit)
default:
defprint:
+ 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);
+ 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);
if (sizeof st.st_size > sizeof (long))
- fmtstr = "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%qd";
+ snprintf(p, SPACELEFT(buf, p), "size=%s",
+ quad_to_string(st.st_size));
else
- fmtstr = "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%ld";
- snprintf(p, SPACELEFT(buf, p), fmtstr,
- major(st.st_dev), minor(st.st_dev), st.st_ino,
- st.st_nlink, st.st_uid, st.st_gid, st.st_size);
+ snprintf(p, SPACELEFT(buf, p), "size=%lu",
+ (unsigned long) st.st_size);
break;
}
@@ -1317,55 +1641,6 @@ printit:
printf("%s\n", buf);
}
/*
-** SHORTENSTRING -- return short version of a string
-**
-** If the string is already short, just return it. If it is too
-** long, return the head and tail of the string.
-**
-** Parameters:
-** s -- the string to shorten.
-** m -- the max length of the string.
-**
-** Returns:
-** Either s or a short version of s.
-*/
-
-#ifndef MAXSHORTSTR
-# define MAXSHORTSTR 203
-#endif
-
-char *
-shortenstring(s, m)
- register const char *s;
- int m;
-{
- int l;
- static char buf[MAXSHORTSTR + 1];
-
- l = strlen(s);
- if (l < m)
- return (char *) s;
- if (m > MAXSHORTSTR)
- m = MAXSHORTSTR;
- else if (m < 10)
- {
- if (m < 5)
- {
- strncpy(buf, s, m);
- buf[m] = '\0';
- return buf;
- }
- strncpy(buf, s, m - 3);
- strcpy(buf + m - 3, "...");
- return buf;
- }
- m = (m - 3) / 2;
- strncpy(buf, s, m);
- strcpy(buf + m, "...");
- strcpy(buf + m + 3, s + l - m);
- return buf;
-}
- /*
** SHORTEN_HOSTNAME -- strip local domain information off of hostname.
**
** Parameters:
@@ -1481,9 +1756,9 @@ prog_open(argv, pfd, e)
/* run as default user */
endpwent();
- if (setgid(DefGid) < 0)
+ if (setgid(DefGid) < 0 && geteuid() == 0)
syserr("prog_open: setgid(%ld) failed", (long) DefGid);
- if (setuid(DefUid) < 0)
+ if (setuid(DefUid) < 0 && geteuid() == 0)
syserr("prog_open: setuid(%ld) failed", (long) DefUid);
/* run in some directory */
@@ -1686,7 +1961,7 @@ denlstring(s, strict, logattacks)
sm_syslog(LOG_NOTICE, CurEnv->e_id,
"POSSIBLE ATTACK from %.100s: newline in string \"%s\"",
RealHostName == NULL ? "[UNKNOWN]" : RealHostName,
- shortenstring(bp, 203));
+ shortenstring(bp, MAXSHORTSTR));
}
return bp;
@@ -1751,7 +2026,13 @@ path_is_dir(pathname, createflag)
** none
*/
-static pid_t *ProcListVec = NULL;
+struct procs
+{
+ pid_t proc_pid;
+ char *proc_task;
+};
+
+static struct procs *ProcListVec = NULL;
static int ProcListSize = 0;
#define NO_PID ((pid_t) 0)
@@ -1760,15 +2041,15 @@ static int ProcListSize = 0;
#endif
void
-proc_list_add(pid)
+proc_list_add(pid, task)
pid_t pid;
+ char *task;
{
int i;
- extern void proc_list_probe __P((void));
for (i = 0; i < ProcListSize; i++)
{
- if (ProcListVec[i] == NO_PID)
+ if (ProcListVec[i].proc_pid == NO_PID)
break;
}
if (i >= ProcListSize)
@@ -1779,29 +2060,66 @@ proc_list_add(pid)
/* now scan again */
for (i = 0; i < ProcListSize; i++)
{
- if (ProcListVec[i] == NO_PID)
+ if (ProcListVec[i].proc_pid == NO_PID)
break;
}
}
if (i >= ProcListSize)
{
/* grow process list */
- pid_t *npv;
+ struct procs *npv;
- npv = (pid_t *) xalloc(sizeof (pid_t) * (ProcListSize + PROC_LIST_SEG));
+ npv = (struct procs *) xalloc(sizeof (struct procs) * (ProcListSize + PROC_LIST_SEG));
if (ProcListSize > 0)
{
- bcopy(ProcListVec, npv, ProcListSize * sizeof (pid_t));
+ bcopy(ProcListVec, npv, ProcListSize *
+ sizeof (struct procs));
free(ProcListVec);
}
for (i = ProcListSize; i < ProcListSize + PROC_LIST_SEG; i++)
- npv[i] = NO_PID;
+ {
+ npv[i].proc_pid = NO_PID;
+ npv[i].proc_task = NULL;
+ }
i = ProcListSize;
ProcListSize += PROC_LIST_SEG;
ProcListVec = npv;
}
- ProcListVec[i] = pid;
- CurChildren++;
+ ProcListVec[i].proc_pid = pid;
+ ProcListVec[i].proc_task = newstr(task);
+
+ /* if process adding itself, it's not a child */
+ if (pid != getpid())
+ CurChildren++;
+}
+ /*
+** PROC_LIST_SET -- set pid task in process list
+**
+** Parameters:
+** pid -- pid to set
+** task -- task of pid
+**
+** Returns:
+** none.
+*/
+
+void
+proc_list_set(pid, task)
+ pid_t pid;
+ char *task;
+{
+ int i;
+
+ for (i = 0; i < ProcListSize; i++)
+ {
+ if (ProcListVec[i].proc_pid == pid)
+ {
+ if (ProcListVec[i].proc_task != NULL)
+ free(ProcListVec[i].proc_task);
+ ProcListVec[i].proc_task = newstr(task);
+ break;
+ }
+ }
}
/*
** PROC_LIST_DROP -- drop pid from process list
@@ -1821,9 +2139,14 @@ proc_list_drop(pid)
for (i = 0; i < ProcListSize; i++)
{
- if (ProcListVec[i] == pid)
+ if (ProcListVec[i].proc_pid == pid)
{
- ProcListVec[i] = NO_PID;
+ ProcListVec[i].proc_pid = NO_PID;
+ if (ProcListVec[i].proc_task != NULL)
+ {
+ free(ProcListVec[i].proc_task);
+ ProcListVec[i].proc_task = NULL;
+ }
break;
}
}
@@ -1845,8 +2168,16 @@ proc_list_clear()
{
int i;
- for (i = 0; i < ProcListSize; i++)
- ProcListVec[i] = NO_PID;
+ /* start from 1 since 0 is the daemon itself */
+ 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;
}
/*
@@ -1864,17 +2195,23 @@ proc_list_probe()
{
int i;
- for (i = 0; i < ProcListSize; i++)
+ /* start from 1 since 0 is the daemon itself */
+ for (i = 1; i < ProcListSize; i++)
{
- if (ProcListVec[i] == NO_PID)
+ if (ProcListVec[i].proc_pid == NO_PID)
continue;
- if (kill(ProcListVec[i], 0) < 0)
+ if (kill(ProcListVec[i].proc_pid, 0) < 0)
{
if (LogLevel > 3)
sm_syslog(LOG_DEBUG, CurEnv->e_id,
"proc_list_probe: lost pid %d",
- ProcListVec[i]);
- ProcListVec[i] = NO_PID;
+ (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--;
}
}
@@ -1882,6 +2219,35 @@ proc_list_probe()
CurChildren = 0;
}
/*
+** PROC_LIST_DISPLAY -- display the process list
+**
+** Parameters:
+** out -- output file pointer
+**
+** Returns:
+** none.
+*/
+
+void
+proc_list_display(out)
+ FILE *out;
+{
+ int i;
+
+ for (i = 0; i < ProcListSize; i++)
+ {
+ if (ProcListVec[i].proc_pid == NO_PID)
+ continue;
+
+ fprintf(out, "%d %s%s\n", (int) ProcListVec[i].proc_pid,
+ ProcListVec[i].proc_task != NULL ?
+ ProcListVec[i].proc_task : "(unknown)",
+ (OpMode == MD_SMTP ||
+ OpMode == MD_DAEMON ||
+ OpMode == MD_ARPAFTP) ? "\r" : "");
+ }
+}
+ /*
** SM_STRCASECMP -- 8-bit clean version of strcasecmp
**
** Thank you, vendors, for making this all necessary.