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

📄 m_nick.c

📁 Unreal irc 服务器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *   IRC - Internet Relay Chat, src/modules/m_nick.c *   (C) 1999-2005 The UnrealIRCd Team * *   See file AUTHORS in IRC package for additional names of *   the programmers. * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 1, or (at your option) *   any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "config.h"#include "struct.h"#include "common.h"#include "sys.h"#include "numeric.h"#include "msg.h"#include "proto.h"#include "channel.h"#include <time.h>#include <sys/stat.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef _WIN32#include <io.h>#endif#include <fcntl.h>#include "h.h"#ifdef STRIPBADWORDS#include "badwords.h"#endif#ifdef _WIN32#include "version.h"#endifDLLFUNC CMD_FUNC(m_nick);DLLFUNC int _register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char *umode, char *virthost, char *ip);#define MSG_NICK 	"NICK"	#define TOK_NICK 	"&"	ModuleHeader MOD_HEADER(m_nick)  = {	"m_nick",	"$Id: m_nick.c,v 1.1.4.5 2006/12/22 21:10:33 syzop Exp $",	"command /nick", 	"3.2-b8-1",	NULL     };DLLFUNC int MOD_TEST(m_nick)(ModuleInfo *modinfo){	MARK_AS_OFFICIAL_MODULE(modinfo);	EfunctionAdd(modinfo->handle, EFUNC_REGISTER_USER, _register_user);	return MOD_SUCCESS;}DLLFUNC int MOD_INIT(m_nick)(ModuleInfo *modinfo){	CommandAdd(modinfo->handle, MSG_NICK, TOK_NICK, m_nick, MAXPARA, M_USER|M_SERVER|M_UNREGISTERED);	MARK_AS_OFFICIAL_MODULE(modinfo);	return MOD_SUCCESS;}DLLFUNC int MOD_LOAD(m_nick)(int module_load){	return MOD_SUCCESS;}DLLFUNC int MOD_UNLOAD(m_nick)(int module_unload){	return MOD_SUCCESS;}static char buf[BUFSIZE];static char spamfilter_user[NICKLEN + USERLEN + HOSTLEN + REALLEN + 64];/*** m_nick**	parv[0] = sender prefix**	parv[1] = nickname**  if from new client  -taz**	parv[2] = nick password**  if from server:**      parv[2] = hopcount**      parv[3] = timestamp**      parv[4] = username**      parv[5] = hostname**      parv[6] = servername**  if NICK version 1:**      parv[7] = servicestamp**	parv[8] = info**  if NICK version 2:**	parv[7] = servicestamp**      parv[8] = umodes**	parv[9] = virthost, * if none**	parv[10] = info**  if NICKIP:**      parv[10] = ip**      parv[11] = info*/DLLFUNC CMD_FUNC(m_nick){	aTKline *tklban;	int ishold;	aClient *acptr, *serv = NULL;	aClient *acptrs;	char nick[NICKLEN + 2], *s;	Membership *mp;	time_t lastnick = (time_t) 0;	int  differ = 1, update_watch = 1;	unsigned char newusr = 0, removemoder = 1;	/*	 * If the user didn't specify a nickname, complain	 */	if (parc < 2)	{		sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),		    me.name, parv[0]);		return 0;	}	strncpyzt(nick, parv[1], NICKLEN + 1);	if (MyConnect(sptr) && sptr->user && !IsAnOper(sptr))	{		if ((sptr->user->flood.nick_c >= NICK_COUNT) && 		    (TStime() - sptr->user->flood.nick_t < NICK_PERIOD))		{			/* Throttle... */			sendto_one(sptr, err_str(ERR_NCHANGETOOFAST), me.name, sptr->name, nick,				(int)(NICK_PERIOD - (TStime() - sptr->user->flood.nick_t)));			return 0;		}	}	/* For a local clients, do proper nickname checking via do_nick_name()	 * and reject the nick if it returns false.	 * For remote clients, do a quick check by using do_remote_nick_name(),	 * if this returned false then reject and kill it. -- Syzop	 */	if ((IsServer(cptr) && !do_remote_nick_name(nick)) ||	    (!IsServer(cptr) && !do_nick_name(nick)))	{		sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME),		    me.name, parv[0], parv[1], "Illegal characters");		if (IsServer(cptr))		{			ircstp->is_kill++;			sendto_failops("Bad Nick: %s From: %s %s",			    parv[1], parv[0], get_client_name(cptr, FALSE));			sendto_one(cptr, ":%s KILL %s :%s (%s <- %s[%s])",			    me.name, parv[1], me.name, parv[1],			    nick, cptr->name);			if (sptr != cptr)			{	/* bad nick change */				sendto_serv_butone(cptr,				    ":%s KILL %s :%s (%s <- %s!%s@%s)",				    me.name, parv[0], me.name,				    get_client_name(cptr, FALSE),				    parv[0],				    sptr->user ? sptr->username : "",				    sptr->user ? sptr->user->server :				    cptr->name);				sptr->flags |= FLAGS_KILLED;				return exit_client(cptr, sptr, &me, "BadNick");			}		}		return 0;	}	/* Kill quarantined opers early... */	if (IsServer(cptr) && (sptr->from->flags & FLAGS_QUARANTINE) &&	    (parc >= 11) && strchr(parv[8], 'o'))	{		ircstp->is_kill++;		/* Send kill to uplink only, hasn't been broadcasted to the rest, anyway */		sendto_one(cptr, ":%s KILL %s :%s (Quarantined: no global oper privileges allowed)",			me.name, parv[1], me.name);		sendto_realops("QUARANTINE: Oper %s on server %s killed, due to quarantine",			parv[1], sptr->name);		/* (nothing to exit_client or to free, since user was never added) */		return 0;	}	/*	   ** Protocol 4 doesn't send the server as prefix, so it is possible	   ** the server doesn't exist (a lagged net.burst), in which case	   ** we simply need to ignore the NICK. Also when we got that server	   ** name (again) but from another direction. --Run	 */	/*	   ** We should really only deal with this for msgs from servers.	   ** -- Aeto	 */	if (IsServer(cptr) &&	    (parc > 7	    && (!(serv = (aClient *)find_server_b64_or_real(parv[6]))	    || serv->from != cptr->from)))	{		sendto_realops("Cannot find server %s (%s)", parv[6],		    backupbuf);		return 0;	}	/*	   ** Check against nick name collisions.	   **	   ** Put this 'if' here so that the nesting goes nicely on the screen :)	   ** We check against server name list before determining if the nickname	   ** is present in the nicklist (due to the way the below for loop is	   ** constructed). -avalon	 */	/* I managed to fuck this up i guess --stskeeps */	if ((acptr = find_server(nick, NULL)))	{		if (MyConnect(sptr))		{#ifdef GUEST			if (IsUnknown(sptr))			{				RunHook4(HOOKTYPE_GUEST, cptr, sptr, parc, parv);				return 0;			}#endif			sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name,			    BadPtr(parv[0]) ? "*" : parv[0], nick);			return 0;	/* NICK message ignored */		}	}	/*	   ** Check for a Q-lined nickname. If we find it, and it's our	   ** client, just reject it. -Lefler	   ** Allow opers to use Q-lined nicknames. -Russell	 */	if (!stricmp("ircd", nick))	{		sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name,		    BadPtr(parv[0]) ? "*" : parv[0], nick,		    "Reserved for internal IRCd purposes");		return 0;	}	if (!stricmp("irc", nick))	{		sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name,		    BadPtr(parv[0]) ? "*" : parv[0], nick,		    "Reserved for internal IRCd purposes");		return 0;	}	if (MyClient(sptr)) /* local client changin nick afterwards.. */	{		int xx;		spamfilter_build_user_string(spamfilter_user, nick, sptr);		xx = dospamfilter(sptr, spamfilter_user, SPAMF_USER, NULL, 0, NULL);		if (xx < 0)			return xx;	}	if (!IsULine(sptr) && (tklban = find_qline(sptr, nick, &ishold)))	{		if (IsServer(sptr) && !ishold) /* server introducing new client */		{			acptrs =			    (aClient *)find_server_b64_or_real(sptr->user ==			    NULL ? (char *)parv[6] : (char *)sptr->user->			    server);			/* (NEW: no unregistered q:line msgs anymore during linking) */			if (!acptrs || (acptrs->serv && acptrs->serv->flags.synced))				sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s", nick,				    (*sptr->name != 0				    && !IsServer(sptr) ? sptr->name : "<unregistered>"),				    acptrs ? acptrs->name : "unknown server");		}				if (IsServer(cptr) && IsPerson(sptr) && !ishold) /* remote user changing nick */		{			sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s", nick,				sptr->name, sptr->srvptr ? sptr->srvptr->name : "<unknown>");		}		if (!IsServer(cptr)) /* local */		{			if (ishold)			{				sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME),				    me.name, BadPtr(parv[0]) ? "*" : parv[0],				    nick, tklban->reason);				return 0;			}			if (!IsOper(cptr))			{				sptr->since += 4; /* lag them up */				sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME),				    me.name, BadPtr(parv[0]) ? "*" : parv[0],				    nick, tklban->reason);				sendto_snomask(SNO_QLINE, "Forbidding Q-lined nick %s from %s.",				    nick, get_client_name(cptr, FALSE));				return 0;	/* NICK message ignored */			}		}	}	/*	   ** acptr already has result from previous find_server()	 */	if (acptr)	{		/*		   ** We have a nickname trying to use the same name as		   ** a server. Send out a nick collision KILL to remove		   ** the nickname. As long as only a KILL is sent out,		   ** there is no danger of the server being disconnected.		   ** Ultimate way to jupiter a nick ? >;-). -avalon		 */		sendto_failops("Nick collision on %s(%s <- %s)",		    sptr->name, acptr->from->name,		    get_client_name(cptr, FALSE));		ircstp->is_kill++;		sendto_one(cptr, ":%s KILL %s :%s (%s <- %s)",		    me.name, sptr->name, me.name, acptr->from->name,		    /* NOTE: Cannot use get_client_name		       ** twice here, it returns static		       ** string pointer--the other info		       ** would be lost		     */		    get_client_name(cptr, FALSE));		sptr->flags |= FLAGS_KILLED;		return exit_client(cptr, sptr, &me, "Nick/Server collision");	}	if (MyClient(cptr) && !IsOper(cptr))		cptr->since += 3;	/* Nick-flood prot. -Donwulff */	if (!(acptr = find_client(nick, NULL)))		goto nickkilldone;	/* No collisions, all clear... */	/*	   ** If the older one is "non-person", the new entry is just	   ** allowed to overwrite it. Just silently drop non-person,	   ** and proceed with the nick. This should take care of the	   ** "dormant nick" way of generating collisions...	 */	/* Moved before Lost User Field to fix some bugs... -- Barubary */	if (IsUnknown(acptr) && MyConnect(acptr))	{		/* This may help - copying code below */		if (acptr == cptr)			return 0;		acptr->flags |= FLAGS_KILLED;		exit_client(NULL, acptr, &me, "Overridden");		goto nickkilldone;	}	/* A sanity check in the user field... */	if (acptr->user == NULL)	{		/* This is a Bad Thing */		sendto_failops("Lost user field for %s in change from %s",		    acptr->name, get_client_name(cptr, FALSE));		ircstp->is_kill++;		sendto_one(acptr, ":%s KILL %s :%s (Lost user field!)",		    me.name, acptr->name, me.name);		acptr->flags |= FLAGS_KILLED;		/* Here's the previous versions' desynch.  If the old one is		   messed up, trash the old one and accept the new one.		   Remember - at this point there is a new nick coming in!		   Handle appropriately. -- Barubary */		exit_client(NULL, acptr, &me, "Lost user field");		goto nickkilldone;	}	/*	   ** If acptr == sptr, then we have a client doing a nick	   ** change between *equivalent* nicknames as far as server	   ** is concerned (user is changing the case of his/her	   ** nickname or somesuch)	 */	if (acptr == sptr) {		if (strcmp(acptr->name, nick) != 0)		{			/* Allows change of case in his/her nick */			removemoder = 0; /* don't set the user -r */			goto nickkilldone;	/* -- go and process change */		} else			/*			 ** This is just ':old NICK old' type thing.			 ** Just forget the whole thing here. There is			 ** no point forwarding it to anywhere,			 ** especially since servers prior to this			 ** version would treat it as nick collision.			 */			return 0;	/* NICK Message ignored */	}	/*	   ** Note: From this point forward it can be assumed that	   ** acptr != sptr (point to different client structures).	 */	/*	   ** Decide, we really have a nick collision and deal with it	 */	if (!IsServer(cptr))	{		/*		   ** NICK is coming from local client connection. Just		   ** send error reply and ignore the command.

⌨️ 快捷键说明

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