m_nick.c

来自「bahamut-1.8.6-release 支持中文呢称代码」· C语言 代码 · 共 751 行 · 第 1/2 页

C
751
字号
	    sendto_one(sptr, err_str(ERR_NICKNAMEINUSE),		       me.name, BadPtr(parv[0]) ? "*" : parv[0], nick);	    return 0;	}	/*	 * NICK was coming from a server connection. Means that the same	 * nick is registered for different users by different server.	 * This is either a race condition (two users coming online about	 * same time, or net reconnecting) or just two net fragments	 * becoming joined and having same nicks in use. We cannot have	 * TWO users with same nick--purge this NICK from the system with	 * a KILL... >;)	 *	 * Changed to something reasonable like IsServer(sptr) (true if	 * "NICK new", false if ":old NICK new") -orabidoo	 */     	if (IsServer(sptr))	{	    /*	     * A new NICK being introduced by a neighbouring server (e.g.	     * message type "NICK new" received)	     */	    if (!newts || !acptr->tsinfo || (newts == acptr->tsinfo))	    {		sendto_realops_lev(SKILL_LEV, "Nick collision on %s", parv[1]);		ircstp->is_kill++;		sendto_one(acptr, err_str(ERR_NICKCOLLISION),			   me.name, acptr->name, acptr->name);		sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)",				   me.name, acptr->name, me.name);		acptr->flags |= FLAGS_KILLED;		return exit_client(cptr, acptr, &me, "Nick collision");	    }	    else	    {		/* XXX This looks messed up to me XXX - Raist */		sameuser = (acptr->user) &&		    mycmp(acptr->user->username, parv[5]) == 0 &&		    mycmp(acptr->user->host, parv[6]) == 0;		if ((sameuser && newts < acptr->tsinfo) || 		    (!sameuser && newts > acptr->tsinfo))		{		    return 0;		}		else		{		    sendto_realops_lev(SKILL_LEV, "Nick collision on %s",parv[1]);		    ircstp->is_kill++;		    sendto_one(acptr, err_str(ERR_NICKCOLLISION),			       me.name, acptr->name, acptr->name);		    sendto_serv_butone(sptr, ":%s KILL %s :%s (Nick Collision)",				       me.name, acptr->name, me.name);		    acptr->flags |= FLAGS_KILLED;		    (void) exit_client(cptr, acptr, &me, "Nick collision");		    break;		}	    }	}	/*	 * * A NICK change has collided (e.g. message type * ":old NICK	 * new". This requires more complex cleanout. * Both clients must be	 * purged from this server, the "new" * must be killed from the	 * incoming connection, and "old" must * be purged from all outgoing	 * connections.	 */	if (!newts || !acptr->tsinfo || (newts == acptr->tsinfo) ||	    !sptr->user)	{	    sendto_realops_lev(SKILL_LEV, "Nick change collision: %s", parv[1]);	    ircstp->is_kill++;	    sendto_one(acptr, err_str(ERR_NICKCOLLISION),		       me.name, acptr->name, acptr->name);	    sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)",me.name,			       sptr->name, me.name);	    ircstp->is_kill++;	    sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)",me.name,			       acptr->name, me.name);	    acptr->flags |= FLAGS_KILLED;	    (void) exit_client(NULL, acptr, &me, "Nick collision(new)");	    sptr->flags |= FLAGS_KILLED;	    return exit_client(cptr, sptr, &me, "Nick collision(old)");	}	else	{	    /* XXX This looks messed up XXX */	    sameuser = mycmp(acptr->user->username, sptr->user->username) == 0		&& mycmp(acptr->user->host, sptr->user->host) == 0;	    if ((sameuser && newts < acptr->tsinfo) ||		(!sameuser && newts > acptr->tsinfo)) {		if (sameuser)		    sendto_realops_lev(SKILL_LEV, 				   "Nick change collision from %s to %s",				   sptr->name, acptr->name);		ircstp->is_kill++;		sendto_serv_butone(cptr, ":%s KILL %s :%s (Nick Collision)", me.name,				   sptr->name, me.name);		sptr->flags |= FLAGS_KILLED;		if (sameuser)		    return exit_client(cptr, sptr, &me, "Nick collision(old)");		else		    return exit_client(cptr, sptr, &me, "Nick collision(new)");	    } 	    else	    {		sendto_realops_lev(SKILL_LEV, "Nick collision on %s", acptr->name);				ircstp->is_kill++;		sendto_one(acptr, err_str(ERR_NICKCOLLISION),			   me.name, acptr->name, acptr->name);		sendto_serv_butone(sptr, ":%s KILL %s :%s (Nick Collision)",me.name,				   acptr->name, me.name);		acptr->flags |= FLAGS_KILLED;		(void) exit_client(cptr, acptr, &me, "Nick collision");	    }	}    } while (0);        if (IsServer(sptr))    {	uplink = find_server(parv[7], NULL);	if(!uplink)	{	    /* if we can't find the server this nick is on, 	     * complain loudly and ignore it. - lucas */	    sendto_realops("Remote nick %s on UNKNOWN server %s",			   nick, parv[7]);	    return 0;	}	sptr = make_client(cptr, uplink);		/* If this is on a U: lined server, it's a U: lined client. */	if(IsULine(uplink))	    sptr->flags|=FLAGS_ULINE;     	add_client_to_list(sptr);	if (parc > 2)	    sptr->hopcount = atoi(parv[2]);	if (newts)	{	    sptr->tsinfo = newts;	}	else	{	    newts = sptr->tsinfo = (ts_val) timeofday;	    ts_warn("Remote nick %s introduced without a TS", nick);	}	/* copy the nick in place */	(void) strcpy(sptr->name, nick);	(void) add_to_client_hash_table(nick, sptr);	if (parc >= 10)	{	    int *s, flag;	    char *m;       	    /* parse the usermodes -orabidoo */	    m = &parv[4][1];	    while (*m)	    {		for (s = user_modes; (flag = *s); s += 2)		    if (*m == *(s + 1))		    {			if ((flag == UMODE_o) || (flag == UMODE_O))			    Count.oper++;			sptr->umode |= flag & SEND_UMODES;			break;		    }		m++;	    }	    if (parc==10)	    {		return do_user(nick, cptr, sptr, parv[5], parv[6],			       parv[7], strtoul(parv[8], NULL, 0), 0, parv[9]);	    } else if (parc==11)	    {		return do_user(nick, cptr, sptr, parv[5], parv[6], parv[7],			       strtoul(parv[8], NULL, 0), 			       strtoul(parv[9], NULL, 0), parv[10]);	    }	}    }    else if (sptr->name[0])    {#ifdef DONT_CHECK_QLINE_REMOTE	if (MyConnect(sptr))	{#endif	    if ((ban = check_mask_simbanned(nick, SBAN_NICK)))	    {#ifndef DONT_CHECK_QLINE_REMOTE		if (!MyConnect(sptr))		    sendto_realops("Restricted nick %s from %s on %s", nick,				   (*sptr->name != 0 && !IsServer(sptr)) ?				   sptr->name : "<unregistered>",				   (sptr->user == NULL) ? ((IsServer(sptr)) ?							   parv[6] : me.name) :				   sptr->user->server);#endif				if (MyConnect(sptr) && (!IsServer(cptr)) && (!IsOper(cptr))		    && (!IsULine(sptr)))		{		    sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name,			       BadPtr(parv[0]) ? "*" : parv[0], nick,			       BadPtr(ban->reason) ? "Erroneous Nickname" :			       ban->reason);                    if (call_hooks(CHOOK_FORBID, cptr, nick, ban) != FLUSH_BUFFER)		        sendto_realops_lev(REJ_LEV,			    	           "Forbidding restricted nick %s from %s",				           nick, get_client_name(cptr, FALSE));		    return 0;		}	    }#ifdef DONT_CHECK_QLINE_REMOTE	}#endif	if (MyConnect(sptr))	{	    if (IsRegisteredUser(sptr))	    {	 		/* before we change their nick, make sure they're not banned		 * on any channels, and!! make sure they're not changing to		 * a banned nick -sed */		/* a little cleaner - lucas */	 		for (lp = sptr->user->channel; lp; lp = lp->next)		{		    if (can_send(sptr, lp->value.chptr, NULL))		    { 			sendto_one(sptr, err_str(ERR_BANNICKCHANGE), me.name,				   sptr->name, lp->value.chptr->chname);			return 0;		    }		    if (nick_is_banned(lp->value.chptr, nick, sptr) != NULL)		    {			sendto_one(sptr, err_str(ERR_BANONCHAN), me.name,				   sptr->name, nick, lp->value.chptr->chname);			return 0;		    }		}#ifdef ANTI_NICK_FLOOD		if ((sptr->last_nick_change + MAX_NICK_TIME) < NOW)		    sptr->number_of_nick_changes = 0;		sptr->last_nick_change = NOW;		sptr->number_of_nick_changes++;	 		if (sptr->number_of_nick_changes > MAX_NICK_CHANGES && 		    !IsAnOper(sptr))		{		    sendto_one(sptr,			       ":%s NOTICE %s :*** Notice -- Too many nick "			       "changes. Wait %d seconds before trying again.",			       me.name, sptr->name, MAX_NICK_TIME);		    return 0;		}#endif		/* If it changed nicks, -r it */		if ((sptr->umode & UMODE_r) && (mycmp(parv[0], nick) != 0))		{		    unsigned int oldumode;		    char mbuf[BUFSIZE];		    oldumode = sptr->umode;		    sptr->umode &= ~UMODE_r;		    send_umode(sptr, sptr, oldumode, ALL_UMODES, mbuf);		}                /* LOCAL NICKHANGE */                /*                 * Client just changing his/her nick. If he/she is on a                 * channel, send note of change to all clients on that channel.                 * Propagate notice to other servers.                 */                /* if the nickname is different, set the TS */                if (mycmp(parv[0], nick))                {                  sptr->tsinfo = newts ? newts : (ts_val) timeofday;                }		sendto_common_channels(sptr, ":%s NICK :%s", parv[0], 				       nick);		if (sptr->user)		{		    add_history(sptr, 1);					    sendto_serv_butone(cptr, ":%s NICK %s :%ld",				       parv[0], nick, sptr->tsinfo);		}	    }	}	else	{            /* REMOTE NICKCHANGE */            /*             * Client just changing his/her nick. If he/she is on a             * channel, send note of change to all clients on that channel.             * Propagate notice to other servers.             */            /* if the nickname is different, set the TS */            if (mycmp(parv[0], nick))            {              sptr->tsinfo = newts ? newts : (ts_val) timeofday;            }	    sendto_common_channels(sptr, ":%s NICK :%s", parv[0], nick);	    if (sptr->user)	    {		add_history(sptr, 1);				sendto_serv_butone(cptr, ":%s NICK %s :%ld",				   parv[0], nick, sptr->tsinfo);	    }	    /* If it changed nicks, -r it */	    if (mycmp(parv[0], nick))		sptr->umode &= ~UMODE_r;	}    }     else    {	/* Client setting NICK the first time */	if (MyConnect(sptr))	{	    if ((ban = check_mask_simbanned(nick, SBAN_NICK)))	    {		if (MyConnect(sptr) && (!IsServer(cptr)) && (!IsOper(cptr))		    && (!IsULine(sptr)))		{		    sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name,			       BadPtr(parv[0]) ? "*" : parv[0], nick,			       BadPtr(ban->reason) ? "Erroneous Nickname" :			       ban->reason);                    if (call_hooks(CHOOK_FORBID, cptr, nick, ban) != FLUSH_BUFFER)		        sendto_realops_lev(REJ_LEV,				           "Forbidding restricted nick %s from %s", nick,				           get_client_name(cptr, FALSE));		    return 0;		}	    }	}		strcpy(sptr->name, nick);	sptr->tsinfo = timeofday;	if (sptr->user)	{	    /* USER already received, now we have NICK */       	    if (register_user(cptr, sptr, nick, sptr->user->username)		== FLUSH_BUFFER)		return FLUSH_BUFFER;	}    }    /* Finally set new nick name. */    if (sptr->name[0])    {        del_from_client_hash_table(sptr->name, sptr);        samenick = mycmp(sptr->name, nick) ? 0 : 1;        if (IsPerson(sptr))        {            if (!samenick)                hash_check_watch(sptr, RPL_LOGOFF);#ifdef RWHO_PROBABILITY            probability_change(sptr->name, nick);#endif        }    }    strcpy(sptr->name, nick);    add_to_client_hash_table(nick, sptr);    if (IsPerson(sptr) && !samenick)	hash_check_watch(sptr, RPL_LOGON);    return 0;}

⌨️ 快捷键说明

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