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

📄 m_tkl.c

📁 Unreal irc 服务器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		"no reason"	/*8  reason */	};	struct tm *t;	if (parc == 1)	{		tkl_stats(sptr, 0, NULL);		sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');		return 0;	}	mask = parv[1];	if (*mask == '-')	{		whattodo = 1;		mask++;	}	else if (*mask == '+')	{		whattodo = 0;		mask++;	}	if (strchr(mask, '!'))	{		sendto_one(sptr, ":%s NOTICE %s :[error] Cannot have '!' in masks.", me.name,		    sptr->name);		return 0;	}	if (*mask == ':')	{		sendto_one(sptr, ":%s NOTICE %s :[error] Mask cannot start with a ':'.", me.name,			sptr->name);		return 0;	}	if (strchr(mask, ' '))		return 0;	/* Check if its a hostmask and legal .. */	p = strchr(mask, '@');	if (p) {		if ((p == mask) || !p[1])		{			sendnotice(sptr, "Error: no user@host specified");			return 0;		}		usermask = strtok(mask, "@");		hostmask = strtok(NULL, "");		if (BadPtr(hostmask)) {			if (BadPtr(usermask)) {				return 0;			}			hostmask = usermask;			usermask = "*";		}		if (*hostmask == ':')		{			sendnotice(sptr, "[error] For (weird) technical reasons you cannot start the host with a ':', sorry");			return 0;		}		if (((*type == 'z') || (*type == 'Z')) && !whattodo)		{			/* It's a (G)ZLINE, make sure the user isn't specyfing a HOST.			 * Just a warning in 3.2.3, but an error in 3.2.4.			 */			if (strcmp(usermask, "*"))			{				sendnotice(sptr, "ERROR: (g)zlines must be placed at \037*\037@ipmask, not \037user\037@ipmask. This is "				                 "because (g)zlines are processed BEFORE dns and ident lookups are done. "				                 "If you want to use usermasks, use a KLINE/GLINE instead.");				return -1;			}			for (p=hostmask; *p; p++)				if (isalpha(*p))				{					sendnotice(sptr, "ERROR: (g)zlines must be placed at *@\037IPMASK\037, not *@\037HOSTMASK\037 "					                 "(so for example *@192.168.* is ok, but *@*.aol.com is not). "					                 "This is because (g)zlines are processed BEFORE dns and ident lookups are done. "					                 "If you want to use hostmasks instead of ipmasks, use a KLINE/GLINE instead.");					return -1;				}		}		/* set 'p' right for later... */		p = hostmask-1;	}	else	{		/* It's seemingly a nick .. let's see if we can find the user */		if ((acptr = find_person(mask, NULL)))		{			usermask = "*";			if ((*type == 'z') || (*type == 'Z'))			{				/* Fill in IP */				hostmask = GetIP(acptr);				if (!hostmask)				{					sendnotice(sptr, "Could not get IP for user '%s'", acptr->name);					return 0;				}			} else {				/* Fill in host */				hostmask = acptr->user->realhost;			}			p = hostmask - 1;		}		else		{			sendto_one(sptr, rpl_str(ERR_NOSUCHNICK), me.name, sptr->name, mask);			return 0;		}	}		if (!whattodo)	{		char c;				if (!strchr(usermask, '*') && !strchr(usermask, '?'))		{			/* Allow things like clone@*, dsfsf@*, etc.. */		} else {			/* Check hostmask. */						/* STEP 1: Must at least contain 4 non-wildcard/non-dot characters */			p++;			i = 0;			while (*p)			{				if (*p != '*' && *p != '.' && *p != '?')					i++;				p++;			}			if (i < 4)			{				sendto_one(sptr,				    ":%s NOTICE %s :*** [error] Too broad mask",				    me.name, sptr->name);				return 0;			}			/* STEP 2: Check CIDR.. allow x.x/16, but not /15, /14, etc... */			c = tolower(*type);			if (c == 'k' || c == 'z' || *type == 'G' || *type == 's')			{				struct irc_netmask tmp;				if ((tmp.type = parse_netmask(hostmask, &tmp)) != HM_HOST)				{					if (tmp.bits < 16)					{						sendto_one(sptr,						    ":%s NOTICE %s :*** [error] Too broad mask",						    me.name, sptr->name);						return 0;					}				}			}		}	}	tkl_check_expire(NULL);	secs = 0;	if (whattodo == 0 && (parc > 3))	{		secs = atime(parv[2]);		if (secs < 0)		{			sendto_one(sptr,			    ":%s NOTICE %s :*** [error] The time you specified is out of range!",			    me.name, sptr->name);			return 0;		}	}	tkllayer[1] = whattodo == 0 ? "+" : "-";	tkllayer[2] = type;	tkllayer[3] = usermask;	tkllayer[4] = hostmask;	tkllayer[5] =	    make_nick_user_host(sptr->name, sptr->user->username, GetHost(sptr));	if (whattodo == 0)	{		if (secs == 0)		{			if (DEFAULT_BANTIME && (parc <= 3))				ircsprintf(mo, "%li", DEFAULT_BANTIME + TStime());			else				ircsprintf(mo, "%li", secs); /* "0" */		}		else			ircsprintf(mo, "%li", secs + TStime());		ircsprintf(mo2, "%li", TStime());		tkllayer[6] = mo;		tkllayer[7] = mo2;		if (parc > 3) {			tkllayer[8] = parv[3];		} else if (parc > 2) {			tkllayer[8] = parv[2];		}		/* Blerghhh... */		i = atol(mo);		t = gmtime(&i);		if (!t)		{			sendto_one(sptr,				":%s NOTICE %s :*** [error] The time you specified is out of range",				me.name, sptr->name);			return 0;		}				/* call the tkl layer .. */		m_tkl(&me, &me, 9, tkllayer);	}	else	{		/* call the tkl layer .. */		m_tkl(&me, &me, 6, tkllayer);	}	return 0;}int spamfilter_usage(aClient *sptr){	sendnotice(sptr, "Use: /spamfilter [add|del|remove|+|-] [type] [action] [tkltime] [tklreason] [regex]");	sendnotice(sptr, "See '/helpop ?spamfilter' for more information.");	return 0;}DLLFUNC int m_spamfilter(aClient *cptr, aClient *sptr, int parc, char *parv[]){int  whattodo = 0;	/* 0 = add  1 = del */char mo[32], mo2[32];char *p;char *tkllayer[11] = {	me.name,	/*  0 server.name */	NULL,		/*  1 +|- */	"F",		/*  2 F   */	NULL,		/*  3 usermask (targets) */	NULL,		/*  4 hostmask (action) */	NULL,		/*  5 setby */	"0",		/*  6 expire_at */	"0",		/*  7 set_at */	"",			/*  8 tkl time */	"",			/*  9 tkl reason */	""			/* 10 regex */};int targets = 0, action = 0;char targetbuf[64], actionbuf[2];char reason[512];int n;	if (IsServer(sptr))		return 0;	if (!OPCanTKL(sptr) || !IsOper(sptr))	{		sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, sptr->name);		return 0;	}	if (parc == 1)	{		tkl_stats(sptr, TKL_SPAMF, NULL);		tkl_stats(sptr, TKL_SPAMF|TKL_GLOBAL, NULL);		sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'F');		return 0;	}	if ((parc < 7) || BadPtr(parv[4]))		return spamfilter_usage(sptr);	/* parv[1]: [add|del|+|-]	 * parv[2]: type	 * parv[3]: action	 * parv[4]: tkl time	 * parv[5]: tkl reason (or block reason..)	 * parv[6]: regex	 */	if (!strcasecmp(parv[1], "add") || !strcmp(parv[1], "+"))		whattodo = 0;	else if (!strcasecmp(parv[1], "del") || !strcmp(parv[1], "-") || !strcasecmp(parv[1], "remove"))		whattodo = 1;	else	{		sendto_one(sptr, ":%s NOTICE %s :1st parameter invalid", me.name, sptr->name);		return spamfilter_usage(sptr);	}	targets = spamfilter_gettargets(parv[2], sptr);	if (!targets)		return spamfilter_usage(sptr);	strncpyzt(targetbuf, spamfilter_target_inttostring(targets), sizeof(targetbuf));	action = banact_stringtoval(parv[3]);	if (!action)	{		sendto_one(sptr, ":%s NOTICE %s :Invalid 'action' field (%s)", me.name, sptr->name, parv[3]);		return spamfilter_usage(sptr);	}	actionbuf[0] = banact_valtochar(action);	actionbuf[1] = '\0';	/* now check the regex... */	p = unreal_checkregex(parv[6],0,1);	if (p)	{		sendto_one(sptr, ":%s NOTICE %s :Error in regex '%s': %s",			me.name, sptr->name, parv[6], p);		return 0;	}	tkllayer[1] = whattodo ? "-" : "+";	tkllayer[3] = targetbuf;	tkllayer[4] = actionbuf;	tkllayer[5] = make_nick_user_host(sptr->name, sptr->user->username, GetHost(sptr));	if (parv[4][0] == '-')	{		ircsprintf(mo, "%li", SPAMFILTER_BAN_TIME);		tkllayer[8] = mo;	}	else		tkllayer[8] = parv[4];	if (parv[5][0] == '-')		strlcpy(reason, unreal_encodespace(SPAMFILTER_BAN_REASON), sizeof(reason));	else		strlcpy(reason, parv[5], sizeof(reason));	tkllayer[9] = reason;	tkllayer[10] = parv[6];	/* SPAMFILTER LENGTH CHECK.	 * We try to limit it here so '/stats f' output shows ok, output of that is:	 * :servername 229 destname F <target> <action> <num> <num> <num> <reason> <setby> :<regex>	 * : ^NICKLEN       ^ NICKLEN                                       ^check   ^check   ^check	 * And for the other fields (and spacing/etc) we count on max 40 characters.	 * We also do >500 instead of >510, since that looks cleaner ;).. so actually we count	 * on 50 characters for the rest... -- Syzop	 */	n = strlen(reason) + strlen(parv[6]) + strlen(tkllayer[5]) + (NICKLEN * 2) + 40;	if ((n > 500) && (whattodo == 0))	{		sendnotice(sptr, "Sorry, spamfilter too long. You'll either have to trim down the "		                 "reason or the regex (exceeded by %d bytes)", n - 500);		return 0;	}		if (whattodo == 0)	{		ircsprintf(mo2, "%li", TStime());		tkllayer[7] = mo2;	}		m_tkl(&me, &me, 11, tkllayer);	return 0;}/** tkl hash method. * NOTE1: the input value 'c' is assumed to be in range a-z or A-Z! * NOTE2: don't blindly change the hashmethod, some things depend on *        'z'/'Z' getting the same bucket. */int _tkl_hash(unsigned int c){#ifdef DEBUGMODE	if ((c >= 'a') && (c <= 'z'))		return c-'a';	else if ((c >= 'A') && (c <= 'Z'))		return c-'A';	else {		sendto_realops("[BUG] tkl_hash() called with out of range parameter (c = '%c') !!!", c);		ircd_log(LOG_ERROR, "[BUG] tkl_hash() called with out of range parameter (c = '%c') !!!", c);		return 0;	}#else	return (isupper(c) ? c-'A' : c-'a');#endif}/** tkl type to tkl character. * NOTE: type is assumed to be valid. */char _tkl_typetochar(int type){	if (type & TKL_GLOBAL)	{		if (type & TKL_KILL)			return 'G';		if (type & TKL_ZAP)			return 'Z';		if (type & TKL_SHUN)			return 's';		if (type & TKL_KILL)			return 'G';		if (type & TKL_SPAMF)			return 'F';		if (type & TKL_NICK)			return 'Q';	} else {		if (type & TKL_ZAP)			return 'z';		if (type & TKL_KILL)			return 'k';		if (type & TKL_SPAMF)			return 'f';		if (type & TKL_NICK)			return 'q';	}	sendto_realops("[BUG]: tkl_typetochar(): unknown type 0x%x !!!", type);	ircd_log(LOG_ERROR, "[BUG] tkl_typetochar(): unknown type 0x%x !!!", type);	return 0;}/* *  type =  TKL_* *	usermask@hostmask *	reason *	setby = whom set it *	expire_at = when to expire - 0 if not to expire *	set_at    = was set at *  spamf_tkl_duration = duration of *line placed by spamfilter [1] *  spamf_tkl_reason = escaped reason field for *lines placed by spamfilter [1] * *  [1]: only relevant for spamfilters, else ignored (eg 0, NULL).*/aTKline *_tkl_add_line(int type, char *usermask, char *hostmask, char *reason, char *setby,                  TS expire_at, TS set_at, TS spamf_tkl_duration, char *spamf_tkl_reason){	aTKline *nl;	int index;	/* Pre-allocate etc check for spamfilters that fail to compile.	 * This could happen if for example TRE supports a feature on server X, but not	 * on server Y!	 */	if (type & TKL_SPAMF)	{		char *myerr = unreal_checkregex(reason, 0, 0);		if (myerr)		{			sendto_realops("[TKL ERROR] ERROR: Spamfilter was added but did not compile. ERROR='%s', Spamfilter='%s'",				myerr, reason);			return NULL;		}	}	nl = (aTKline *) MyMallocEx(sizeof(aTKline));	if (!nl)		return NULL;	nl->type = type;	nl->expire_at = expire_at;	nl->set_at = set_at;	strncpyzt(nl->usermask, usermask, sizeof(nl->usermask));	nl->hostmask = strdup(hostmask);	nl->reason = strdup(reason);	nl->setby = strdup(setby);	if (type & TKL_SPAMF)	{		/* Need to set some additional flags like 'targets' and 'action'.. */		nl->subtype = spamfilter_gettargets(usermask, NULL);		nl->ptr.spamf = unreal_buildspamfilter(reason);		nl->ptr.spamf->action = banact_chartoval(*hostmask);		nl->expire_at = 0; /* temporary spamfilters are NOT supported! (makes no sense) */		if (!spamf_tkl_reason)		{			/* no exttkl support, use default values... */			nl->ptr.spamf->tkl_duration = SPAMFILTER_BAN_TIME;			nl->ptr.spamf->tkl_reason = strdup(unreal_encodespace(SPAMFILTER_BAN_REASON));		} else {			nl->ptr.spamf->tkl_duration = spamf_tkl_duration;			nl->ptr.spamf->tkl_reason = strdup(spamf_tkl_reason); /* already encoded */		}		if (nl->subtype & SPAMF_USER)			loop.do_bancheck_spamf_user = 1;		if (nl->subtype & SPAMF_AWAY)			loop.do_bancheck_spamf_away = 1;	}	else if (type & TKL_KILL || type & TKL_ZAP || type & TKL_SHUN)

⌨️ 快捷键说明

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