/*
** This file is derived from inetd.c
** "@(#)from: inetd.c 8.4 (Berkeley) 4/13/94";
** as available in the OpenBSD source tree.
** It has been significantly modified to suit the needs as sendmail MCP.
*/
/*
* Copyright (c) 1983, 1991, 1993, 1994
* 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.
*
* 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 MCP_H
#define MCP_H 1
/* $Id: mcp.h,v 1.26 2007/09/29 02:10:07 ca Exp $ */
#include "sm/generic.h"
#include "sm/mcpdef.h"
#include "sm/servid.h"
#include "sm/sockcnf.h"
#ifndef SM_MCP_USE_CONF
# define SM_MCP_USE_CONF 1
#endif
/*
** Missing: counter for respawns: disable service if too often
** within a certain time period. For now it's a simple failure counter.
**
** Need parameter expansion, e.g., %p -> pid, to allow different names
** for different invocations of the same program (e.g., name of socket
** over which fd is passed).
**
** Enforce order to start programs; currently simply done by listing
** them in the right (reverse) order in the configuration file.
**
** Need way to signal all children to stop, e.g., send a signal
** to them or some data over a control socket. For now: pass TERM/INT/HUP
** to all children.
**
** Communication/control socket (same as socket to pass fd?)
** Also listen on that socket for feedback.
**
** Check names etc for "sanity", e.g., se_prg: only letter/digit/_?
**
** Specify a "working" directory into which to chdir before running?
*/
typedef struct servtab_S servtab_T, *servtab_P;
struct servtab_S
{
char const *se_prg; /* name of service */
char const *se_kw; /* keyword */
char const *se_title; /* title */
#if 0
char *se_proto; /* protocol used */
#endif
sockspec_T se_socket;
#define MCP_SOCKET_IS_TYPE(se, sock_type) \
((se)->se_socket.sckspc_type == (sock_type))
#define MCP_SOCKET_IS_UNIX(se) MCP_SOCKET_IS_TYPE(se, SOCK_TYPE_UNIX)
#define MCP_SOCKET_IS_INET(se) MCP_SOCKET_IS_TYPE(se, SOCK_TYPE_INET)
#define se_port se_socket.sock_inet.inetsckspc_port
#define se_addr se_socket.sock_inet.inetsckspc_addr
#if MCP_OLD_SOCKET
int se_port; /* port */
ipv4_T se_addr; /* address to bind(2) to */
#endif /* MCP_OLD_SOCKET */
int se_listen_len; /* backlog for listen(2) */
#define se_socket_name se_socket.sock_unix.unixsckspc_path
#define se_socket_umask se_socket.sock_unix.unixsckspc_umask
#define se_socket_user se_socket.sock_unix.unixsckspc_user
#define se_socket_group se_socket.sock_unix.unixsckspc_group
#if MCP_OLD_SOCKET
char *se_socket_name; /* local (UNIX) socket */
mode_t se_socket_umask; /* umask for socket creation */
char *se_socket_user; /* socket owner: user name */
char *se_socket_group; /* socket owner: group name */
#endif /* MCP_OLD_SOCKET */
int se_minchild; /* min number of children */
int se_maxchild; /* max number of children */
#if MTA_USE_CPML
int se_maxcpm; /* max connects per IP per minute */
#endif
int se_numchild; /* current number of children */
int se_failed; /* failure counter */
time_t se_lastfail;
pid_t *se_pids; /* array of child pids */
uint *se_ids; /* array of child ids */
char *se_pass_id; /* pass id to program (if not NULL) */
char *se_exsock; /* exchange socket */
char *se_user; /* user name to run as */
char *se_group; /* group name to run as */
#ifdef LOGIN_CAP
char *se_class; /* login class name to run with */
#endif
/* data for restart dependencies */
int se_nrestartdep;
char *se_restartdep[SM_MCP_MAXRESTARTDEP + 1];
char *se_restartdeps;
char *se_server; /* server program */
char *se_server_name; /* program without path */
char *se_workdir; /* working directory (chdir(2)) */
#define MAXARGV 64
char *se_args; /* program arguments (one string) */
char *se_argv[MAXARGV + 1]; /* program arguments */
int se_fd; /* open file descriptor */
int se_count; /* number started since se_time */
uint se_flags; /* see below */
#if 0
uint se_cflags; /* see below */
#else
bool se_logf_id; /* use id in logfile */
#endif
sm_sockaddr_T se_ctrladdr; /* bound address */
sockaddr_len_T se_ctrladdr_size;
struct timeval se_time; /* start of se_count */
servtab_P se_next; /* pointer to next entry */
};
/* flags for service */
#define SE_FL_DISABLED 0x0001 /* service is disabled */
#define SE_FL_WAIT 0x0002 /* wait for service to return */
#define SE_FL_PASS 0x0004 /* pass fd to service */
#define SE_FL_ACCEPT 0x0008 /* accept locally */
/* wait for request: start only when connection comes in */
#define SE_FL_W4REQ 0x0010
#define SE_FL_RESTART 0x0020 /* restart this service */
#define SE_FL_LEADER 0x0040 /* process that causes restart */
#define SE_FL_CHECKED 0x0100 /* looked at during merge */
#define SE_FL_LOGF_ID 0x0200 /* use id in logfile */
#define SE_FL_UNRECOVERABLE 0x0400 /* failed with unrecoverable error */
#define SE_SET_FLAG(sep, fl) (sep)->se_flags |= (fl)
#define SE_CLR_FLAG(sep, fl) (sep)->se_flags &= ~(fl)
#define SE_IS_FLAG(sep, fl) (((sep)->se_flags & (fl)) != 0)
#if 0
/* other configuration flags (separate, otherwise hard to handle in config) */
#define SE_CFL_LOGF_ID 0x0001 /* use id in logfile */
#define SE_SET_CFLAG(sep, fl) (sep)->se_cflags |= (fl)
#define SE_CLR_CFLAG(sep, fl) (sep)->se_cflags &= ~(fl)
#define SE_IS_CFLAG(sep, fl) (((sep)->se_cflags & (fl)) != 0)
#else /* 0 */
#endif /* 0 */
/*
** MCP context
** Note: the distinction between flags and status isn't very clean.
*/
typedef struct mcp_ctx_S mcp_ctx_T, *mcp_ctx_P;
struct mcp_ctx_S
{
uint mcp_status;
uint mcp_flags;
uint mcp_total_proc; /* sum of se_maxchild */
id_ctx_P mcp_id_ctx;
};
#define MCP_OPT_IS_SET(opt) ((opt) != NULL && *(opt) != SM_MCP_DEFAULT_CHAR)
void sm_exit(int _value);
void
#if SM_CHK_PRINTF
PRINTFLIKE(2, 3)
#endif
m_syslog(int _priority, const char *_fmt, ...);
#endif /* MCP_H */
syntax highlighted by Code2HTML, v. 0.9.1