⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 conf.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * written prior permission.  M.I.T. makes no representations about the
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Authors:  Many and varied...
 */

/* Non Apollo stuff removed by Don Lewis 11/15/93 */
#ifndef lint
static char  rcsid[] = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $";
#endif /* ! lint */

#ifdef apollo
# undef volatile
# include <apollo/base.h>

/* ARGSUSED */
int getloadavg( call_data )
     caddr_t	call_data;	/* pointer to (double) return value */
{
     double *avenrun = (double *) call_data;
     int i;
     status_$t      st;
     long loadav[3];
     proc1_$get_loadav(loadav, &st);
     *avenrun = loadav[0] / (double) (1 << 16);
     return 0;
}
#endif /* apollo */
/*
**  SM_GETLA -- get the current load average and set macro
**
**	Parameters:
**		e -- the envelope for the load average macro.
**
**	Returns:
**		The current load average as an integer.
**
**	Side Effects:
**		Sets the load average macro ({load_avg}) if
**		envelope e is not NULL.
*/

int
sm_getla(e)
	ENVELOPE *e;
{
	register int la;

	la = getla();
	if (e != NULL)
	{
		char labuf[8];

		snprintf(labuf, sizeof labuf, "%d", la);
		define(macid("{load_avg}", NULL), newstr(labuf), e);
	}
	return la;
}

/*
**  SHOULDQUEUE -- should this message be queued or sent?
**
**	Compares the message cost to the load average to decide.
**
**	Parameters:
**		pri -- the priority of the message in question.
**		ct -- the message creation time.
**
**	Returns:
**		TRUE -- if this message should be queued up for the
**			time being.
**		FALSE -- if the load is low enough to send this message.
**
**	Side Effects:
**		none.
*/

/* ARGSUSED1 */
bool
shouldqueue(pri, ct)
	long pri;
	time_t ct;
{
	bool rval;

	if (tTd(3, 30))
		dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ",
			CurrentLA, pri);
	if (CurrentLA < QueueLA)
	{
		if (tTd(3, 30))
			dprintf("FALSE (CurrentLA < QueueLA)\n");
		return FALSE;
	}
#if 0	/* this code is reported to cause oscillation around RefuseLA */
	if (CurrentLA >= RefuseLA && QueueLA < RefuseLA)
	{
		if (tTd(3, 30))
			dprintf("TRUE (CurrentLA >= RefuseLA)\n");
		return TRUE;
	}
#endif /* 0 */
	rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1));
	if (tTd(3, 30))
		dprintf("%s (by calculation)\n", rval ? "TRUE" : "FALSE");
	return rval;
}
/*
**  REFUSECONNECTIONS -- decide if connections should be refused
**
**	Parameters:
**		name -- daemon name (for error messages only)
**		e -- the current envelope.
**		d -- number of daemon
**
**	Returns:
**		TRUE if incoming SMTP connections should be refused
**			(for now).
**		FALSE if we should accept new work.
**
**	Side Effects:
**		Sets process title when it is rejecting connections.
*/

bool
refuseconnections(name, e, d)
	char *name;
	ENVELOPE *e;
	int d;
{
	time_t now;
	static time_t lastconn[MAXDAEMONS];
	static int conncnt[MAXDAEMONS];


#ifdef XLA
	if (!xla_smtp_ok())
		return TRUE;
#endif /* XLA */

	now = curtime();
	if (now != lastconn[d])
	{
		lastconn[d] = now;
		conncnt[d] = 0;
	}
	else if (conncnt[d]++ > ConnRateThrottle && ConnRateThrottle > 0)
	{
		/* sleep to flatten out connection load */
		sm_setproctitle(TRUE, e, "deferring connections on daemon %s: %d per second",
				name, ConnRateThrottle);
		if (LogLevel >= 9)
			sm_syslog(LOG_INFO, NOQID,
				"deferring connections on daemon %s: %d per second",
				name, ConnRateThrottle);
		(void) sleep(1);
	}

	CurrentLA = getla();
	if (RefuseLA > 0 && CurrentLA >= RefuseLA)
	{
		sm_setproctitle(TRUE, e, "rejecting connections on daemon %s: load average: %d",
				name, CurrentLA);
		if (LogLevel >= 9)
			sm_syslog(LOG_INFO, NOQID,
				"rejecting connections on daemon %s: load average: %d",
				name, CurrentLA);
		return TRUE;
	}

	if (MaxChildren > 0 && CurChildren >= MaxChildren)
	{
		proc_list_probe();
		if (CurChildren >= MaxChildren)
		{
			sm_setproctitle(TRUE, e, "rejecting connections on daemon %s: %d children, max %d",
					name, CurChildren, MaxChildren);
			if (LogLevel >= 9)
				sm_syslog(LOG_INFO, NOQID,
					"rejecting connections on daemon %s: %d children, max %d",
					name, CurChildren, MaxChildren);
			return TRUE;
		}
	}

	return FALSE;
}
/*
**  SETPROCTITLE -- set process title for ps
**
**	Parameters:
**		fmt -- a printf style format string.
**		a, b, c -- possible parameters to fmt.
**
**	Returns:
**		none.
**
**	Side Effects:
**		Clobbers argv of our main procedure so ps(1) will
**		display the title.
*/

#define SPT_NONE	0	/* don't use it at all */
#define SPT_REUSEARGV	1	/* cover argv with title information */
#define SPT_BUILTIN	2	/* use libc builtin */
#define SPT_PSTAT	3	/* use pstat(PSTAT_SETCMD, ...) */
#define SPT_PSSTRINGS	4	/* use PS_STRINGS->... */
#define SPT_SYSMIPS	5	/* use sysmips() supported by NEWS-OS 6 */
#define SPT_SCO		6	/* write kernel u. area */
#define SPT_CHANGEARGV	7	/* write our own strings into argv[] */

#ifndef SPT_TYPE
# define SPT_TYPE	SPT_REUSEARGV
#endif /* ! SPT_TYPE */


#if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN

# if SPT_TYPE == SPT_PSTAT
#  include <sys/pstat.h>
# endif /* SPT_TYPE == SPT_PSTAT */
# if SPT_TYPE == SPT_PSSTRINGS
#  include <machine/vmparam.h>
#  include <sys/exec.h>
#  ifndef PS_STRINGS	/* hmmmm....  apparently not available after all */
#   undef SPT_TYPE
#   define SPT_TYPE	SPT_REUSEARGV
#  else /* ! PS_STRINGS */
#   ifndef NKPDE			/* FreeBSD 2.0 */
#    define NKPDE 63
typedef unsigned int	*pt_entry_t;
#   endif /* ! NKPDE */
#  endif /* ! PS_STRINGS */
# endif /* SPT_TYPE == SPT_PSSTRINGS */

# if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
#  define SETPROC_STATIC	static
# else /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
#  define SETPROC_STATIC
# endif /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */

# if SPT_TYPE == SPT_SYSMIPS
#  include <sys/sysmips.h>
#  include <sys/sysnews.h>
# endif /* SPT_TYPE == SPT_SYSMIPS */

# if SPT_TYPE == SPT_SCO
#  include <sys/immu.h>
#  include <sys/dir.h>
#  include <sys/user.h>
#  include <sys/fs/s5param.h>
#  if PSARGSZ > MAXLINE
#   define SPT_BUFSIZE	PSARGSZ
#  endif /* PSARGSZ > MAXLINE */
# endif /* SPT_TYPE == SPT_SCO */

# ifndef SPT_PADCHAR
#  define SPT_PADCHAR	' '
# endif /* ! SPT_PADCHAR */

#endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */

#ifndef SPT_BUFSIZE
# define SPT_BUFSIZE	MAXLINE
#endif /* ! SPT_BUFSIZE */

/*
**  Pointers for setproctitle.
**	This allows "ps" listings to give more useful information.
*/

static char	**Argv = NULL;		/* pointer to argument vector */
static char	*LastArgv = NULL;	/* end of argv */
#if SPT_TYPE != SPT_BUILTIN
static void	setproctitle __P((const char *, ...));
#endif /* SPT_TYPE != SPT_BUILTIN */

void
initsetproctitle(argc, argv, envp)
	int argc;
	char **argv;
	char **envp;
{
	register int i, envpsize = 0;
	extern char **environ;

	/*
	**  Move the environment so setproctitle can use the space at
	**  the top of memory.
	*/

	for (i = 0; envp[i] != NULL; i++)
		envpsize += strlen(envp[i]) + 1;
	environ = (char **) xalloc(sizeof (char *) * (i + 1));
	for (i = 0; envp[i] != NULL; i++)
		environ[i] = newstr(envp[i]);
	environ[i] = NULL;

	/*
	**  Save start and extent of argv for setproctitle.
	*/

	Argv = argv;

	/*
	**  Determine how much space we can use for setproctitle.
	**  Use all contiguous argv and envp pointers starting at argv[0]
	*/
	for (i = 0; i < argc; i++)
	{
		if (i == 0 || LastArgv + 1 == argv[i])
			LastArgv = argv[i] + strlen(argv[i]);
	}
	for (i = 0; LastArgv != NULL && envp[i] != NULL; i++)
	{
		if (LastArgv + 1 == envp[i])
			LastArgv = envp[i] + strlen(envp[i]);
	}
}

#if SPT_TYPE != SPT_BUILTIN

/*VARARGS1*/
static void
# ifdef __STDC__
setproctitle(const char *fmt, ...)
# else /* __STDC__ */
setproctitle(fmt, va_alist)
	const char *fmt;
	va_dcl
# endif /* __STDC__ */
{
# if SPT_TYPE != SPT_NONE
	register int i;
	register char *p;
	SETPROC_STATIC char buf[SPT_BUFSIZE];
	VA_LOCAL_DECL
#  if SPT_TYPE == SPT_PSTAT
	union pstun pst;
#  endif /* SPT_TYPE == SPT_PSTAT */
#  if SPT_TYPE == SPT_SCO
	off_t seek_off;
	static int kmem = -1;
	static int kmempid = -1;
	struct user u;
#  endif /* SPT_TYPE == SPT_SCO */

	p = buf;

	/* print sendmail: heading for grep */
	(void) strlcpy(p, "sendmail: ", SPACELEFT(buf, p));
	p += strlen(p);

	/* print the argument string */
	VA_START(fmt);
	(void) vsnprintf(p, SPACELEFT(buf, p), fmt, ap);
	VA_END;

	i = strlen(buf);

#  if SPT_TYPE == SPT_PSTAT
	pst.pst_command = buf;
	pstat(PSTAT_SETCMD, pst, i, 0, 0);
#  endif /* SPT_TYPE == SPT_PSTAT */
#  if SPT_TYPE == SPT_PSSTRINGS
	PS_STRINGS->ps_nargvstr = 1;
	PS_STRINGS->ps_argvstr = buf;
#  endif /* SPT_TYPE == SPT_PSSTRINGS */
#  if SPT_TYPE == SPT_SYSMIPS
	sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
#  endif /* SPT_TYPE == SPT_SYSMIPS */
#  if SPT_TYPE == SPT_SCO
	if (kmem < 0 || kmempid != getpid())
	{
		if (kmem >= 0)
			close(kmem);
		kmem = open(_PATH_KMEM, O_RDWR, 0);
		if (kmem < 0)
			return;
		(void) fcntl(kmem, F_SETFD, FD_CLOEXEC);
		kmempid = getpid();
	}
	buf[PSARGSZ - 1] = '\0';
	seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
	if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
		(void) write(kmem, buf, PSARGSZ);
#  endif /* SPT_TYPE == SPT_SCO */
#  if SPT_TYPE == SPT_REUSEARGV
	if (LastArgv == NULL)
		return;

	if (i > LastArgv - Argv[0] - 2)
	{
		i = LastArgv - Argv[0] - 2;
		buf[i] = '\0';
	}
	(void) strlcpy(Argv[0], buf, i + 1);
	p = &Argv[0][i];
	while (p < LastArgv)
		*p++ = SPT_PADCHAR;
	Argv[1] = NULL;
#  endif /* SPT_TYPE == SPT_REUSEARGV */
#  if SPT_TYPE == SPT_CHANGEARGV
	Argv[0] = buf;
	Argv[1] = 0;
#  endif /* SPT_TYPE == SPT_CHANGEARGV */
# endif /* SPT_TYPE != SPT_NONE */
}

#endif /* SPT_TYPE != SPT_BUILTIN */
/*
**  SM_SETPROCTITLE -- set process task and set process title for ps
**
**	Possibly set process status and call setproctitle() to
**	change the ps display.
**
**	Parameters:
**		status -- whether or not to store as process status
**		e -- the current envelope.
**		fmt -- a printf style format string.
**		a, b, c -- possible parameters to fmt.
**
**	Returns:
**		none.
*/

/*VARARGS2*/
void
#ifdef __STDC__
sm_setproctitle(bool status, ENVELOPE *e, const char *fmt, ...)
#else /* __STDC__ */
sm_setproctitle(status, e, fmt, va_alist)
	bool status;
	ENVELOPE *e;
	const char *fmt;
	va_dcl
#endif /* __STDC__ */
{
	char buf[SPT_BUFSIZE];
	VA_LOCAL_DECL

	/* print the argument string */
	VA_START(fmt);
	(void) vsnprintf(buf, sizeof buf, fmt, ap);
	VA_END;

	if (status)
		proc_list_set(getpid(), buf);

	if (ProcTitlePrefix != NULL)
	{
		char prefix[SPT_BUFSIZE];

		expand(ProcTitlePrefix, prefix, sizeof prefix, e);
		setproctitle("%s: %s", prefix, buf);
	}
	else
		setproctitle("%s", buf);
}
/*
**  WAITFOR -- wait for a particular process id.
**
**	Parameters:
**		pid -- process id to wait for.
**
**	Returns:
**		status of pid.
**		-1 if pid never shows up.
**
**	Side Effects:
**		none.
*/

int
waitfor(pid)
	pid_t pid;
{
# ifdef WAITUNION
	union wait st;
# else /* WAITUNION */
	auto int st;
# endif /* WAITUNION */
	pid_t i;
# if defined(ISC_UNIX) || defined(_SCO_unix_)
	int savesig;
# endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */

	do
	{
		errno = 0;
# if defined(ISC_UNIX) || defined(_SCO_unix_)
		savesig = releasesignal(SIGCHLD);
# endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
		i = wait(&st);
# if defined(ISC_UNIX) || defined(_SCO_unix_)
		if (savesig > 0)
			blocksignal(SIGCHLD);
# endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
		if (i > 0)
			(void) proc_list_drop(i);
	} while ((i >= 0 || errno == EINTR) && i != pid);
	if (i < 0)
		return -1;
# ifdef WAITUNION
	return st.w_status;
# else /* WAITUNION */
	return st;
# endif /* WAITUNION */
}
/*
**  REAPCHILD -- pick up the body of my child, lest it become a zombie
**
**	Parameters:
**		sig -- the signal that got us here (unused).

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -