summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src/control.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/control.c')
-rw-r--r--contrib/sendmail/src/control.c167
1 files changed, 108 insertions, 59 deletions
diff --git a/contrib/sendmail/src/control.c b/contrib/sendmail/src/control.c
index b30c63f..c319192 100644
--- a/contrib/sendmail/src/control.c
+++ b/contrib/sendmail/src/control.c
@@ -8,18 +8,20 @@
*
*/
-#ifndef lint
-static char id[] = "@(#)$Id: control.c,v 8.44.14.20 2001/05/03 17:24:03 gshapiro Exp $";
-#endif /* ! lint */
-
#include <sendmail.h>
+SM_RCSID("@(#)$Id: control.c,v 8.116 2001/12/13 21:51:38 gshapiro Exp $")
+
/* values for cmd_code */
-# define CMDERROR 0 /* bad command */
-# define CMDRESTART 1 /* restart daemon */
-# define CMDSHUTDOWN 2 /* end daemon */
-# define CMDHELP 3 /* help */
-# define CMDSTATUS 4 /* daemon status */
+#define CMDERROR 0 /* bad command */
+#define CMDRESTART 1 /* restart daemon */
+#define CMDSHUTDOWN 2 /* end daemon */
+#define CMDHELP 3 /* help */
+#define CMDSTATUS 4 /* daemon status */
+#define CMDMEMDUMP 5 /* dump memory, to find memory leaks */
+#if _FFR_CONTROL_MSTAT
+# define CMDMSTAT 6 /* daemon status, more info, tagged data */
+#endif /* _FFR_CONTROL_MSTAT */
struct cmd
{
@@ -33,13 +35,18 @@ static struct cmd CmdTab[] =
{ "restart", CMDRESTART },
{ "shutdown", CMDSHUTDOWN },
{ "status", CMDSTATUS },
+ { "memdump", CMDMEMDUMP },
+#if _FFR_CONTROL_MSTAT
+ { "mstat", CMDMSTAT },
+#endif /* _FFR_CONTROL_MSTAT */
{ NULL, CMDERROR }
};
+
int ControlSocket = -1;
- /*
+/*
** OPENCONTROLSOCKET -- create/open the daemon control named socket
**
** Creates and opens a named socket for external control over
@@ -55,13 +62,13 @@ int ControlSocket = -1;
int
opencontrolsocket()
{
-#if NETUNIX
+# if NETUNIX
int save_errno;
int rval;
long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_CREAT|SFF_MUSTOWN;
struct sockaddr_un controladdr;
- if (ControlSocketName == NULL)
+ if (ControlSocketName == NULL || *ControlSocketName == '\0')
return 0;
if (strlen(ControlSocketName) >= sizeof controladdr.sun_path)
@@ -87,8 +94,8 @@ opencontrolsocket()
(void) unlink(ControlSocketName);
memset(&controladdr, '\0', sizeof controladdr);
controladdr.sun_family = AF_UNIX;
- (void) strlcpy(controladdr.sun_path, ControlSocketName,
- sizeof controladdr.sun_path);
+ (void) sm_strlcpy(controladdr.sun_path, ControlSocketName,
+ sizeof controladdr.sun_path);
if (bind(ControlSocket, (struct sockaddr *) &controladdr,
sizeof controladdr) < 0)
@@ -115,11 +122,11 @@ opencontrolsocket()
sm_syslog(LOG_ALERT, NOQID,
"ownership change on %s to uid %d failed: %s",
ControlSocketName, (int) u,
- errstring(save_errno));
+ sm_errstring(save_errno));
message("050 ownership change on %s to uid %d failed: %s",
ControlSocketName, (int) u,
- errstring(save_errno));
- closecontrolsocket(TRUE);
+ sm_errstring(save_errno));
+ closecontrolsocket(true);
errno = save_errno;
return -1;
}
@@ -128,7 +135,7 @@ opencontrolsocket()
if (chmod(ControlSocketName, S_IRUSR|S_IWUSR) < 0)
{
save_errno = errno;
- closecontrolsocket(TRUE);
+ closecontrolsocket(true);
errno = save_errno;
return -1;
}
@@ -136,14 +143,14 @@ opencontrolsocket()
if (listen(ControlSocket, 8) < 0)
{
save_errno = errno;
- closecontrolsocket(TRUE);
+ closecontrolsocket(true);
errno = save_errno;
return -1;
}
-#endif /* NETUNIX */
+# endif /* NETUNIX */
return 0;
}
- /*
+/*
** CLOSECONTROLSOCKET -- close the daemon control named socket
**
** Close a named socket.
@@ -160,7 +167,7 @@ void
closecontrolsocket(fullclose)
bool fullclose;
{
-#if NETUNIX
+# if NETUNIX
long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_CREAT|SFF_MUSTOWN;
if (ControlSocket >= 0)
@@ -184,14 +191,14 @@ closecontrolsocket(fullclose)
{
sm_syslog(LOG_WARNING, NOQID,
"Could not remove control socket: %s",
- errstring(errno));
+ sm_errstring(errno));
return;
}
}
-#endif /* NETUNIX */
+# endif /* NETUNIX */
return;
}
- /*
+/*
** CLRCONTROL -- reset the control connection
**
** Parameters:
@@ -207,16 +214,13 @@ closecontrolsocket(fullclose)
void
clrcontrol()
{
-#if NETUNIX
+# if NETUNIX
if (ControlSocket >= 0)
(void) close(ControlSocket);
ControlSocket = -1;
-#endif /* NETUNIX */
+# endif /* NETUNIX */
}
-
-#ifndef NOT_SENDMAIL
-
- /*
+/*
** CONTROL_COMMAND -- read and process command from named socket
**
** Read and process the command from the opened socket.
@@ -232,6 +236,7 @@ clrcontrol()
static jmp_buf CtxControlTimeout;
+/* ARGSUSED0 */
static void
controltimeout(timeout)
time_t timeout;
@@ -252,17 +257,17 @@ control_command(sock, e)
ENVELOPE *e;
{
volatile int exitstat = EX_OK;
- FILE *s = NULL;
- EVENT *ev = NULL;
- FILE *traffic;
- FILE *oldout;
+ SM_FILE_T *s = NULL;
+ SM_EVENT *ev = NULL;
+ SM_FILE_T *traffic;
+ SM_FILE_T *oldout;
char *cmd;
char *p;
struct cmd *c;
char cmdbuf[MAXLINE];
char inp[MAXLINE];
- sm_setproctitle(FALSE, e, "control cmd read");
+ sm_setproctitle(false, e, "control cmd read");
if (TimeOuts.to_control > 0)
{
@@ -274,11 +279,12 @@ control_command(sock, e)
"timeout waiting for input during control command");
exit(EX_IOERR);
}
- ev = setevent(TimeOuts.to_control, controltimeout,
- TimeOuts.to_control);
+ ev = sm_setevent(TimeOuts.to_control, controltimeout,
+ TimeOuts.to_control);
}
- s = fdopen(sock, "r+");
+ s = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &sock,
+ SM_IO_RDWR, NULL);
if (s == NULL)
{
int save_errno = errno;
@@ -287,19 +293,20 @@ control_command(sock, e)
errno = save_errno;
exit(EX_IOERR);
}
- setbuf(s, NULL);
+ (void) sm_io_setvbuf(s, SM_TIME_DEFAULT, NULL,
+ SM_IO_NBF, SM_IO_BUFSIZ);
- if (fgets(inp, sizeof inp, s) == NULL)
+ if (sm_io_fgets(s, SM_TIME_DEFAULT, inp, sizeof inp) == NULL)
{
- (void) fclose(s);
+ (void) sm_io_close(s, SM_TIME_DEFAULT);
exit(EX_IOERR);
}
- (void) fflush(s);
+ (void) sm_io_flush(s, SM_TIME_DEFAULT);
/* clean up end of line */
- fixcrlf(inp, TRUE);
+ fixcrlf(inp, true);
- sm_setproctitle(FALSE, e, "control: %s", inp);
+ sm_setproctitle(false, e, "control: %s", inp);
/* break off command */
for (p = inp; isascii(*p) && isspace(*p); p++)
@@ -318,7 +325,7 @@ control_command(sock, e)
/* decode command */
for (c = CmdTab; c->cmd_name != NULL; c++)
{
- if (strcasecmp(c->cmd_name, cmdbuf) == 0)
+ if (sm_strcasecmp(c->cmd_name, cmdbuf) == 0)
break;
}
@@ -335,45 +342,87 @@ control_command(sock, e)
break;
case CMDRESTART: /* restart the daemon */
- fprintf(s, "OK\r\n");
+ (void) sm_io_fprintf(s, SM_TIME_DEFAULT, "OK\r\n");
exitstat = EX_RESTART;
break;
case CMDSHUTDOWN: /* kill the daemon */
- fprintf(s, "OK\r\n");
+ (void) sm_io_fprintf(s, SM_TIME_DEFAULT, "OK\r\n");
exitstat = EX_SHUTDOWN;
break;
case CMDSTATUS: /* daemon status */
proc_list_probe();
{
+ int qgrp;
long bsize;
long free;
- free = freediskspace(QueueDir, &bsize);
+ /* XXX need to deal with different partitions */
+ qgrp = e->e_qgrp;
+ if (!ISVALIDQGRP(qgrp))
+ qgrp = 0;
+ free = freediskspace(Queue[qgrp]->qg_qdir, &bsize);
/*
** Prevent overflow and don't lose
** precision (if bsize == 512)
*/
- free = (long)((double)free * ((double)bsize / 1024));
+ if (free > 0)
+ free = (long)((double) free *
+ ((double) bsize / 1024));
- fprintf(s, "%d/%d/%ld/%d\r\n",
- CurChildren, MaxChildren,
- free, sm_getla(NULL));
+ (void) sm_io_fprintf(s, SM_TIME_DEFAULT,
+ "%d/%d/%ld/%d\r\n",
+ CurChildren, MaxChildren,
+ free, getla());
}
- proc_list_display(s);
+ proc_list_display(s, "");
+ break;
+
+# if _FFR_CONTROL_MSTAT
+ case CMDMSTAT: /* daemon status, extended, tagged format */
+ proc_list_probe();
+ (void) sm_io_fprintf(s, SM_TIME_DEFAULT,
+ "C:%d\r\nM:%d\r\nL:%d\r\n",
+ CurChildren, MaxChildren,
+ getla());
+ printnqe(s, "Q:");
+ disk_status(s, "D:");
+ proc_list_display(s, "P:");
+ break;
+# endif /* _FFR_CONTROL_MSTAT */
+
+ case CMDMEMDUMP: /* daemon memory dump, to find memory leaks */
+# if SM_HEAP_CHECK
+ /* dump the heap, if we are checking for memory leaks */
+ if (sm_debug_active(&SmHeapCheck, 2))
+ {
+ sm_heap_report(s, sm_debug_level(&SmHeapCheck) - 1);
+ }
+ else
+ {
+ (void) sm_io_fprintf(s, SM_TIME_DEFAULT,
+ "Memory dump unavailable.\r\n");
+ (void) sm_io_fprintf(s, SM_TIME_DEFAULT,
+ "To fix, run sendmail with -dsm_check_heap.4\r\n");
+ }
+# else /* SM_HEAP_CHECK */
+ (void) sm_io_fprintf(s, SM_TIME_DEFAULT,
+ "Memory dump unavailable.\r\n");
+ (void) sm_io_fprintf(s, SM_TIME_DEFAULT,
+ "To fix, rebuild with -DSM_HEAP_CHECK\r\n");
+# endif /* SM_HEAP_CHECK */
break;
case CMDERROR: /* unknown command */
- fprintf(s, "Bad command (%s)\r\n", cmdbuf);
+ (void) sm_io_fprintf(s, SM_TIME_DEFAULT,
+ "Bad command (%s)\r\n", cmdbuf);
break;
}
- (void) fclose(s);
+ (void) sm_io_close(s, SM_TIME_DEFAULT);
if (ev != NULL)
- clrevent(ev);
+ sm_clrevent(ev);
exit(exitstat);
}
-#endif /* ! NOT_SENDMAIL */
-
OpenPOWER on IntegriCloud