X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Firc.c;h=9508ecc457b9037f389f4a5cd1bbf1b7cb6f17be;hp=69dd61a797994886c63bf0426a6d4434192a993c;hb=33a165721b79bf896a1895e79fa0809fd6f71174;hpb=456e55921dddb4ae24bfc887b668c0e6407caace diff --git a/src/ngircd/irc.c b/src/ngircd/irc.c index 69dd61a7..9508ecc4 100644 --- a/src/ngircd/irc.c +++ b/src/ngircd/irc.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2004 Alexander Barton + * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. * * 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 @@ -45,6 +45,35 @@ static bool Send_Message_Mask PARAMS((CLIENT *from, char *command, bool SendErrors)); +/** + * Check if a list limit is reached and inform client accordingly. + * + * @param From The client. + * @param Count Reply item count. + * @param Limit Reply limit. + * @param Name Name of the list. + * @return true if list limit has been reached; false otherwise. + */ +GLOBAL bool +IRC_CheckListTooBig(CLIENT *From, const int Count, const int Limit, + const char *Name) +{ + assert(From != NULL); + assert(Count >= 0); + assert(Limit > 0); + assert(Name != NULL); + + if (Count < Limit) + return false; + + (void)IRC_WriteStrClient(From, + "NOTICE %s :%s list limit (%d) reached!", + Client_ID(From), Name, Limit); + IRC_SetPenalty(From, 2); + return true; +} + + GLOBAL bool IRC_ERROR( CLIENT *Client, REQUEST *Req ) { @@ -320,6 +349,7 @@ static bool Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) { CLIENT *cl, *from; + CL2CHAN *cl2chan; CHANNEL *chan; char *currentTarget = Req->argv[0]; char *lastCurrentTarget = NULL; @@ -410,8 +440,8 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) Client_Type(cl) != CLIENT_SERVICE) continue; if (nick != NULL && host != NULL) { - if (strcmp(nick, Client_ID(cl)) == 0 && - strcmp(user, Client_User(cl)) == 0 && + if (strcasecmp(nick, Client_ID(cl)) == 0 && + strcasecmp(user, Client_User(cl)) == 0 && strcasecmp(host, Client_HostnameCloaked(cl)) == 0) break; else @@ -439,11 +469,11 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) #else if (Client_Type(cl) != ForceType) { #endif - if (!SendErrors) - return CONNECTED; - return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG, - Client_ID(from), - currentTarget); + if (SendErrors && !IRC_WriteStrClient( + from, ERR_NOSUCHNICK_MSG,Client_ID(from), + currentTarget)) + return DISCONNECTED; + goto send_next_target; } #ifndef STRICT_RFC @@ -456,6 +486,23 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) } #endif + if (Client_HasMode(cl, 'C')) { + cl2chan = Channel_FirstChannelOf(cl); + while (cl2chan) { + chan = Channel_GetChannel(cl2chan); + if (Channel_IsMemberOf(chan, from)) + break; + cl2chan = Channel_NextChannelOf(cl, cl2chan); + } + if (!cl2chan) { + if (SendErrors && !IRC_WriteStrClient( + from, ERR_NOTONSAMECHANNEL_MSG, + Client_ID(from), Client_ID(cl))) + return DISCONNECTED; + goto send_next_target; + } + } + if (SendErrors && (Client_Type(Client) != CLIENT_SERVER) && strchr(Client_Modes(cl), 'a')) { /* Target is away */ @@ -493,7 +540,10 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) return DISCONNECTED; } + send_next_target: currentTarget = strtok_r(NULL, ",", &lastCurrentTarget); + if (currentTarget) + Conn_SetPenalty(Client_Conn(Client), 1); } return CONNECTED;