X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Firc.c;h=1a0d725f92eca1069805e04bc8865d0f6b0cbecc;hb=588af510a35b5b28cb8c1063ac865f86c65d7a8a;hp=69dd61a797994886c63bf0426a6d4434192a993c;hpb=456e55921dddb4ae24bfc887b668c0e6407caace;p=ngircd-alex.git diff --git a/src/ngircd/irc.c b/src/ngircd/irc.c index 69dd61a7..1a0d725f 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 @@ -25,6 +25,7 @@ #include "conn-func.h" #include "conf.h" #include "channel.h" +#include "conn-encoding.h" #include "defines.h" #include "irc-write.h" #include "log.h" @@ -45,6 +46,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 ) { @@ -274,36 +304,52 @@ IRC_TRACE( CLIENT *Client, REQUEST *Req ) } /* IRC_TRACE */ +/** + * Handler for the IRC "HELP" command. + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. + */ GLOBAL bool -IRC_HELP( CLIENT *Client, REQUEST *Req ) +IRC_HELP(CLIENT *Client, REQUEST *Req) { COMMAND *cmd; - assert( Client != NULL ); - assert( Req != NULL ); + assert(Client != NULL); + assert(Req != NULL); /* Bad number of arguments? */ - if( Req->argc > 0 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command ); + if (Req->argc > 0) + return IRC_WriteStrClient(Client, ERR_NORECIPIENT_MSG, + Client_ID(Client), Req->command); - cmd = Parse_GetCommandStruct( ); - while( cmd->name ) - { - if( ! IRC_WriteStrClient( Client, "NOTICE %s :%s", Client_ID( Client ), cmd->name )) return DISCONNECTED; + cmd = Parse_GetCommandStruct(); + while(cmd->name) { + if (!IRC_WriteStrClient(Client, "NOTICE %s :%s", + Client_ID(Client), cmd->name)) + return DISCONNECTED; cmd++; } - - IRC_SetPenalty( Client, 2 ); + + IRC_SetPenalty(Client, 2); return CONNECTED; } /* IRC_HELP */ static char * -Option_String( CONN_ID Idx ) +#ifdef ZLIB +Option_String(CONN_ID Idx) +#else +Option_String(UNUSED CONN_ID Idx) +#endif { static char option_txt[8]; +#ifdef ZLIB UINT16 options; options = Conn_Options(Idx); +#endif strcpy(option_txt, "F"); /* No idea what this means, but the * original ircd sends it ... */ @@ -320,9 +366,11 @@ 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; + char *message = NULL; assert(Client != NULL); assert(Req != NULL); @@ -354,6 +402,13 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix); +#ifdef ICONV + if (Client_Conn(Client) > NONE) + message = Conn_EncodingFrom(Client_Conn(Client), Req->argv[1]); + else +#endif + message = Req->argv[1]; + /* handle msgtarget = msgto *("," msgto) */ currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget); ngt_UpperStr(Req->command); @@ -410,9 +465,9 @@ 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 && - strcasecmp(host, Client_HostnameCloaked(cl)) == 0) + if (strcasecmp(nick, Client_ID(cl)) == 0 && + strcasecmp(user, Client_User(cl)) == 0 && + strcasecmp(host, Client_HostnameDisplayed(cl)) == 0) break; else continue; @@ -420,7 +475,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) if (strcasecmp(user, Client_User(cl)) != 0) continue; if (host != NULL && strcasecmp(host, - Client_HostnameCloaked(cl)) != 0) + Client_HostnameDisplayed(cl)) != 0) continue; if (server != NULL && strcasecmp(server, Client_ID(Client_Introducer(cl))) != 0) @@ -439,11 +494,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 @@ -455,6 +510,34 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) Req->command = "PRIVMSG"; } #endif + if (Client_HasMode(cl, 'b') && + !Client_HasMode(from, 'R') && + !Client_HasMode(from, 'o') && + !(Client_Type(from) == CLIENT_SERVER) && + !(Client_Type(from) == CLIENT_SERVICE)) { + if (SendErrors && !IRC_WriteStrClient(from, + ERR_NONONREG_MSG, + Client_ID(from), Client_ID(cl))) + return DISCONNECTED; + goto send_next_target; + } + + 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')) { @@ -470,12 +553,12 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) } if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s", Req->command, Client_ID(cl), - Req->argv[1])) + message)) return DISCONNECTED; } else if (ForceType != CLIENT_SERVICE && (chan = Channel_Search(currentTarget))) { if (!Channel_Write(chan, from, Client, Req->command, - SendErrors, Req->argv[1])) + SendErrors, message)) return DISCONNECTED; } else if (ForceType != CLIENT_SERVICE /* $#: server/target mask, RFC 2812, sec. 3.3.1 */ @@ -483,7 +566,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) && strchr(currentTarget, '.')) { /* targetmask */ if (!Send_Message_Mask(from, Req->command, currentTarget, - Req->argv[1], SendErrors)) + message, SendErrors)) return DISCONNECTED; } else { if (!SendErrors) @@ -493,7 +576,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;