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

📄 xla.c

📁 早期freebsd实现
💻 C
字号:
/* * (C) Copyright 1993-94, Herve Schauer Consultants * * This module written by Christophe.Wolfhugel@hsc-sec.fr * is to be used under the same conditions and terms (and absence * or warranties) than the other modules of the Sendmail package. * * ABSOLUTELY NO WARRANTY. USE AT YOUR OWN RISKS. * * Version: 940417, applied a patch from Paul Graham <pjg@acsu.buffalo.edu> *                  (lockfile syntax in xla.c did not reflect anymore the *                  new one used by sendmail, now fine). * */#ifdef XLA#ifndef MAXLARULES# define MAXLARULES	20#endif# include "sendmail.h"typedef struct {		short	queue;		/* # of connexions to have queueing */		short	reject;		/* # of conn. to reject */		short	num;		/* # of increments this process */		char	*mask;		/* Mask (domain) */        } XLARULE;char	*XlaFname;			/* Work file name */char	XlaHostName[1024];		/* Temporary */int	XlaNext;			/* # of XlaRules */pid_t	XlaPid;				/* Pid updating the tables */XLARULE	XlaRules[MAXLARULES];		/* The rules themselves */short   XlaCtr[MAXLARULES];		/* Counter (for work file only) */extern	bool	lockfile();/*** XLAMATCH -- Matches a fnmatch like expression.****	Parameters:**		mask -- mask to match the string too;**		name -- string.**** Mask can either be a plain string or a simplified fnmatch like mask:**	*.string     or  string.*** No other alternatives are accepted.****	Returns:**		none.****	Side Effects:**		none.*/boolXlaMatch(mask, name)	char *mask, *name;{	int l1, l2;	l1 = strlen(mask);  l2 = strlen(name);	if (l1 == 1 && mask[0] == '*') return(TRUE);	if (mask[0] == '*' && mask[1] == '.') {		if (l2 < (l1 - 2)) return(FALSE);		if (strcasecmp(&mask[2], name) == 0) return(TRUE);		if (strcasecmp(&mask[1], name + l2 - l1 + 1) == 0) return(TRUE);		return(FALSE);	}	if (l1 < 3) return(FALSE);	if (mask[l1 -1] == '*') {		if (l2 < l1 - 1) return(FALSE);		if (strncasecmp(mask, name, l1 - 1) == 0) return(TRUE);		return(FALSE);	}	if (strcasecmp(mask, name) == 0) return(TRUE);	return(FALSE);}/*** XLAZERO -- Zeroes the used variables**** 	Just initializes some variables, called once at sendmail**	startup.****	Parameters:**		none.****	Returns:**		none.****	Side Effects:**		none.*/xla_zero(){	if (tTd(59, 1)) {		printf("xla_zero\n");	}	XlaFname = NULL;	XlaNext  = 0;	XlaPid   = 0;	memset((char *) &XlaRules[0], 0, sizeof(XLARULE) * MAXLARULES);}/***  XLAINIT -- initialized extended load average stuff****  This routine handles the L lines appearing in the configuration**  file.****  L/etc/sendmail.la     indicates the working file**  Lmask   #1   #2	  Xtended LA to apply to mask**	#1 = Queueing # of connections**	#2 = Reject connections.****	Parameters:**		line -- the cf file line to parse.****	Returns:**		none.****	Side Effects:**		Builds several internal tables.*/xla_init(line)	char *line;{	char *s;	if (tTd(59, 1)) {		printf("xla_init line: %s\n", line);	}	if (XlaFname == NULL && *line == '/') {	/* Work file name */                XlaFname = newstr(line);		if (tTd(59, 10))			printf("xla_init: fname = %s\n", XlaFname);		return;	}	if (XlaNext == MAXLARULES) {		syserr("too many xla rules defined (%d max)", MAXLARULES);		return;	}	s = strtok(line, " \t");	if (s == NULL) {		syserr("xla: line unparseable");		return;	}	XlaRules[XlaNext].mask = newstr(s);	s = strtok(NULL, " \t");	if (s == NULL) {		syserr("xla: line unparseable");		return;	}	XlaRules[XlaNext].queue = atoi(s);	s = strtok(NULL, " \t");	if (s == NULL) {		syserr("xla: line unparseable");		return;	}	XlaRules[XlaNext].reject = atoi(s);	if (tTd(59, 10))		printf("xla_init: rule #%d = %s q=%d r=%d\n", XlaNext, 			XlaRules[XlaNext].mask,			XlaRules[XlaNext].queue, XlaRules[XlaNext].reject);	XlaNext++;}/***  XLACREATEFILE -- Create the working file****	Tries to create the working file, called each time sendmail is**	invoked with the -bd option.****	Parameters:**		none.****	Returns:**		none.****	Side Effects:**		Creates the working file (sendmail.la) and zeroes it.*/xla_create_file(){	int	fd, i;	if (tTd(59, 1))		printf("xla_create_file:\n");	if (XlaFname == NULL) return;	fd = open(XlaFname, O_RDWR|O_CREAT, 0644);	if (fd == -1) {		XlaFname = NULL;		syserr("xla_create_file: open failed");		return;	}	if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {		close(fd);		XlaFname = NULL;		syserr("xla_create_file: can't set lock");		return;	}	if (ftruncate(fd, 0) == -1) {		close(fd);		XlaFname = NULL;		syserr("xla_create_file: can't truncate XlaFname");		return;	}	if (write(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {		XlaFname == NULL;		syserr("xla_create_file: can't write XlaFname");	}	close(fd);}/***  XLASMTPOK -- Checks if all slots are in use****	Check is there are still some slots available for an SMTP**	connection.****	Parameters:**		none.****	Returns:**		TRUE -- slots are available;**		FALSE -- no more slots.****	Side Effects:**		Reads a file, uses a lock and updates sendmail.la if a slot**		is free for use.*/boolxla_smtp_ok(){	int	fd, i;	if (tTd(59, 1))		printf("xla_smtp_ok:\n");	if (XlaFname == NULL) return(TRUE);	fd = open(XlaFname, O_RDWR, 0644);	if (fd == -1) {		XlaFname = NULL;		syserr("xla_smtp_ok: open failed");		return(TRUE);	}	if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {		close(fd);		XlaFname = NULL;		syserr("xla_smtp_ok: can't set lock");		return(TRUE);	}	if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {		close(fd);                XlaFname = NULL;                syserr("xla_smtp_ok: can't read XlaFname");                return(TRUE);	}	close(fd);	for (i = 0; i < XlaNext; i++) {		if (XlaCtr[i] < XlaRules[i].reject)			return(TRUE);	}	return(FALSE);}/***  XLAHOSTOK -- Can we accept a connection from this host****	Check the quota for the indicated host****	Parameters:**		name -- host name or IP# (string)****	Returns:**		TRUE -- we can accept the connection;**		FALSE -- we must refuse the connection.1****	Side Effects:**		Reads and writes a file, uses a lock and still updates**		sendmail.la is a slot gets assigned.*/boolxla_host_ok(name)	char *name;{	int	fd, i;	if (tTd(59, 1))		printf("xla_host_ok:\n");	if (XlaFname == NULL) return(TRUE);	fd = open(XlaFname, O_RDWR, 0644);	if (fd == -1) {		XlaFname = NULL;		syserr("xla_host_ok: open failed");		return(TRUE);	}	XlaPid = getpid();	if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {		close(fd);		XlaFname = NULL;		syserr("xla_host_ok: can't set lock");		return(TRUE);	}	if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {		close(fd);                XlaFname = NULL;                syserr("xla_smtp_ok: can't read XlaFname");                return(TRUE);	}	strncpy(XlaHostName, name, sizeof(XlaHostName) -1);	XlaHostName[sizeof(XlaHostName) -1] = 0;	i = strlen(name) - 1;	if (i >= 0 && XlaHostName[i] == '.') XlaHostName[i] = 0;	for (i = 0; i < XlaNext; i++) {		if (XlaMatch(XlaRules[i].mask, XlaHostName)) {			if (XlaCtr[i] < XlaRules[i].reject) {				if (XlaRules[i].num++ == 0) {					XlaCtr[i]++;					lseek(fd, i*sizeof(XlaCtr[i]), SEEK_SET);					if (write(fd, &XlaCtr[i], sizeof(XlaCtr[i])) !=  sizeof(XlaCtr[i]))						XlaFname = NULL;				}				close(fd);				return(TRUE);			}			close(fd);			return(FALSE);		}	}	close(fd);	return(TRUE);}/***  XLANOQUEUEOK -- Can we sent this message to the remote host****	Check if we can send to the remote host****	Parameters:**		name -- host name or IP# (string)****	Returns:**		TRUE -- we can send the message to the remote site;**		FALSE -- we can't connect the remote host, queue.****	Side Effects:**		Reads and writes a file, uses a lock.**		And still updates the sendmail.la file.*/boolxla_noqueue_ok(name)	char *name;{	int	fd, i;	if (tTd(59, 1))		printf("xla_noqueue_ok:\n");        if (XlaFname == NULL) return(TRUE);	fd = open(XlaFname, O_RDWR, 0644);	if (fd == -1) {		XlaFname = NULL;		syserr("xla_noqueue_ok: open failed");		return(TRUE);	}	if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {		close(fd);		XlaFname = NULL;		syserr("xla_noqueue_ok: can't set lock");		return(TRUE);	}	XlaPid = getpid();        if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {                close(fd);                XlaFname = NULL;                syserr("xla_noqueue_ok: can't read XlaFname");                return(TRUE);        }	strncpy(XlaHostName, name, sizeof(XlaHostName) -1);	XlaHostName[sizeof(XlaHostName) -1] = 0;	i = strlen(name) - 1;	if (i >= 0 && XlaHostName[i] == '.') XlaHostName[i] = 0;	for (i = 0; i < XlaNext; i++) {		if (XlaMatch(XlaRules[i].mask, XlaHostName)) {			if (XlaCtr[i] < XlaRules[i].queue) {				if (XlaRules[i].num++ == 0) {					XlaCtr[i]++;                                	lseek(fd, i*sizeof(XlaCtr[i]), SEEK_SET);                                	if (write(fd, &XlaCtr[i], sizeof(XlaCtr[i])) !=  sizeof(XlaCtr[i]))                                        	XlaFname = NULL;				}				close(fd);				return(TRUE);			}			close(fd);			return(FALSE);		}	}	close(fd);	return(TRUE);}/***  XLAHOSTEND -- Notice that a connection is terminated.****	Updates the counters to reflect the end of an SMTP session**	(in or outgoing).****	Parameters:**		name -- host name or IP# (string)****	Returns:**		none.****	Side Effects:**		Reads and writes a file, uses a lock.**		And still updates sendmail.la.*/xla_host_end(name)	char	*name;{	int	fd, i;	if (tTd(59, 1))		printf("xla_host_end:\n");	if (XlaFname == NULL || XlaPid != getpid()) return;	fd = open(XlaFname, O_RDWR, 0644);	if (fd == -1) {		XlaFname = NULL;		syserr("xla_host_end: open failed");		return;	}	if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {                close(fd);                XlaFname = NULL;		syserr("xla_host_end: can't set lock");		return;	}        if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {                close(fd);                XlaFname = NULL;                syserr("xla_host_end: can't read XlaFname");                return(TRUE);	}	strncpy(XlaHostName, name, sizeof(XlaHostName) -1);	XlaHostName[sizeof(XlaHostName) -1] = 0;	i = strlen(name) - 1;	if (i >= 0 && XlaHostName[i] == '.') XlaHostName[i] = 0;	for (i = 0; i < XlaNext; i++) {		if (XlaMatch(XlaRules[i].mask, XlaHostName)) {			if (XlaRules[i].num > 0 && XlaRules[i].num-- == 1) {				if (XlaCtr[i]) XlaCtr[i]--;                                lseek(fd, i*sizeof(XlaCtr[i]), SEEK_SET);                                if (write(fd, &XlaCtr[i], sizeof(XlaCtr[i]))                                        !=  sizeof(XlaCtr[i]))                                        XlaFname = NULL;			}			close(fd);			return;		}	}	close(fd);}/***  XLAALLEND -- Mark all connections as closed.****	Generally due to an emergency exit.****	Parameters:**		name -- host name or IP# (string)****	Returns:**		none.****	Side Effects:**		Reads and writes a file, uses a lock.**		And guess what: updates sendmail.la.*/xla_all_end(){	int	fd, i;	if (tTd(59, 1))		printf("xla_all_end:\n");	if (XlaFname == NULL || XlaPid != getpid()) return;	fd = open(XlaFname, O_RDWR, 0644);        if (fd == -1) {                XlaFname = NULL;		syserr("xla_all_end: open failed");                return;        }        if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {                close(fd);                XlaFname = NULL;                syserr("xla_all_end: can't set lock");                return;        }        if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {                close(fd);                XlaFname = NULL;                syserr("xla_all_end: can't read XlaFname");                return(TRUE);        }	for (i = 0; i < XlaNext; i++) {		if (XlaCtr[i] > 0 && XlaRules[i].num > 0) {			XlaCtr[i]--; XlaRules[i].num = 0;		}	}	lseek(fd, 0, SEEK_SET);	if (write(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {		XlaFname = NULL;	}	close(fd);}#endif /* XLA */

⌨️ 快捷键说明

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