From: Alexander Barton Date: Fri, 2 Aug 2013 22:29:12 +0000 (+0200) Subject: Merge remote-tracking branch 'fgsch/certfp' X-Git-Tag: rel-21-rc1~72 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=commitdiff_plain;h=69ce65bacb0155be5fb9159a3dfc5c8e3390cc0d;hp=bf8e03c46652100547755322a797f0bf8e2da586 Merge remote-tracking branch 'fgsch/certfp' * fgsch/certfp: Simplify MOTD handling Add certificate fingerprint support --- diff --git a/doc/Commands.txt b/doc/Commands.txt index 7765d3a4..c43b50e3 100644 --- a/doc/Commands.txt +++ b/doc/Commands.txt @@ -97,8 +97,8 @@ Connection Handling Commands clients using UTF-8, which should be the default today. References: - - - - doc/Protocol.txt + - IRC+, + - IRC+, doc/Protocol.txt - NICK NICK @@ -129,7 +129,8 @@ Connection Handling Commands - RFC 1459, 4.1.1 "Password message" (old client and server protocol) - RFC 2812, 3.1.1 "Password message" (client protocol) - RFC 2813, 4.1.1 "Password message" (server protocol) - - doc/Protocol.txt + - IRC+, + - IRC+, doc/Protocol.txt - PING PING [] @@ -211,7 +212,8 @@ Connection Handling Commands unauthorized clients to fake their identity; it is an arbitrary string. References: - - doc/Protocol.txt, II.4: "Update webchat/proxy client information" + - IRC+, + - IRC+, doc/Protocol.txt General Commands @@ -225,6 +227,9 @@ General Commands . If is omitted, the away status is removed. + References: + - RFC 2812, 4.1 "Away" + - HELP HELP [] . @@ -241,15 +246,46 @@ General Commands ngIRCd replies using "NOTICE" commands like ircd 2.10/2.11; other implementations are using numerics 704, 705, and 706. - - MODE - MODE (user) - MODE [] + MODE [{+|-}[] [{+|-}[] [...]]] + MODE [{+|-}[] [ [ [...]]] [{+|-}[] [ [ [...]]] [...]]] + . + Set and get user and channel modes. + . + When no mode parameters are given, the currently set user or channel + modes are returned. Otherwise the modes are adjusted accordingly + and the changes will be reported back to the client. + . + All user and chnnel "modes" are indicated by single case-sensitive + characters. . - The MODE command is dual-purpose. It can be used to set both (user) and - modes. + Please note that a user can only get and set his own modes, and not + all user "levels" are allowed to change all channel modes ... . - See doc/Modes.txt for more information. + The mode parameters can become quite complex, especially when dealing + with channel modes that require additional arguments: + . + {+|-} -- set or unset one or more modes. + + - -- set some modes and unset others. + + -- set (at least) two modes with arguments. + . + Some examples: + . + MODE nick +i -- set user to "invisible". + MODE #chan +tn -- set "topic lock" and "no external messages". + MODE #chan -t +l 50 -- remove "topic lock", set "user limit" to 50. + MODE #chan +ov nick1 nick2 -- set "channel op" and "voice" mode + to nick1 and nick2 in channel #chan. + . + A complete list of all modes supported by ngIRCd can be found online + here: . + + References: + - RFC 2811, 4. "Channel Modes" + - RFC 2812, 3.1.5 "User mode message" + - RFC 2812, 3.2.3 "Channel mode message" + - + - doc/Modes.txt - NOTICE NOTICE [,[,...]] @@ -443,10 +479,19 @@ Status and Informational Commands - RFC 2812, 3.4.6 "Time message" - TRACE - TRACE [] + TRACE [] + . + Find the route to a specific server and send information about its + peers. Each server that processes this command reports back to the + sender about it: the replies from pass-through servers form a chain + which shows the route to the destination. . - Trace a path across the IRC network of the current server, or if given - of a specific , in a similar method to traceroute. + can be a server name, the nickname of a client connected to + a specific server, or a mask matching a server name in the network. + The server of the current connection is used when is omitted. + + References: + - RFC 2812, 3.4.8 "Trace message" - USERHOST USERHOST [ [...]] @@ -539,13 +584,19 @@ Channel Commands - RFC 2812, 3.2.7 "Invite message" - JOIN - JOIN [] + JOIN {[,[,...]] [[,[,...]]] | 0} . - Makes the client join the (comma-separated list), specifying - the passwords, if needed, in the comma-separated list. - A is only needed, if the mode "+k" is set. + Makes the client join the (comma-separated list), specifying + the channel keys ("passwords"). A is only needed if the + has the mode "+k" set. . If the channel(s) do not exist, then they will be created. + . + Using "JOIN 0" parts all channels at once. + + References: + - RFC 2812, 3.2.1 "Join message" (client protocol) + - RFC 2813, 4.2.1 "Join message" (server protocol) - KICK KICK [,[,...]] [,[,...]] [] @@ -562,62 +613,99 @@ Channel Commands - RFC 2812, 3.2.8 "Kick command" - LIST - LIST [ []] + LIST [[,[,...]] []] + . + List all visible (comma-seperated list). . - List all visible (comma-seperated list) on the current - server. If is given, the command will be forwarded to for evaluation. + References: + - RFC 2812, 3.2.6 "List message" + - PART - PART [] + PART [,[,...]] [] . - Leave (comma-separated list), optional with a - . + Leave (comma-separated list), optionally with sending a + to all the other channel members. + + References: + - RFC 2812, 3.2.2 "Part message" - TOPIC - TOPIC + TOPIC [] . - Set a for . + Cchange or view the topic of a channel. . - Only operators are able to set a . + The topic for channel is returned if there is no + given. If the parameter is present, the topic for that + channel will be changed, if this action is allowed for the user + requesting it. If the parameter is an empty string, the + topic for that channel will be removed. + + References: + - RFC 2812, 3.2.4 "Topic message" Administrative Commands ~~~~~~~~~~~~~~~~~~~~~~~ - CONNECT - CONNECT [ [ [ ]]] + CONNECT [ [ [ ]]] + . + Instructs the current server, or if specified, + to connect to the server named , which must be configured + in the server configuration file. . - Instructs the current server, or if specified, - to connect to . + To use this command, the user must be an IRC Operator. To establish + a connection on a , you must have remote IRC operator + privileges. . - To connect you need to have remote oper status. - If is omitted, it uses the server port of the configuration. - If and is given, it uses those passwords instead - of the ones in the configuration. + If , and are given, these values override + the ones specified in the server configuration file. + + References: + - RFC 2812, 3.4.7 "Connect message" - DIE DIE . Instructs the server to shut down. + . + To use this command, the user must be an IRC Operator. + + References: + - RFC 2812, 4.3 "Die message" - DISCONNECT - DISCONNECT [] + DISCONNECT . - Disconnects the current server, or if specified. - To disconnect a you need to have remote oper status. + Disconnect and disable a locally linked server. + . + To use this command, the user must be an IRC Operator. + + References: + - This command is not specified in the IRC RFCs, it is an extension + of ngIRCd. - GLINE - GLINE : + GLINE [ :] + . + This command provides timed G-Lines (network-wide bans). . - This command provides timed G-Lines (Network-wide bans). If a client matches a G-Line, it cannot connect to any server on - the IRC network. If you put 0 as , it makes the G-Line - permanent. + the IRC network for seconds. When is 0, it make + the G-Line permanent. + . + If no and no is given, the G-Line is removed. . - To remove a G-Line, type "GLINE ". - To list the G-Lines, type "STATS g". + To use this command, the user must be an IRC Operator. + . + "STATS g" can be used to list all currently active G-Lines. + + References: + - This command is not specified in the IRC RFCs, it is an extension + of ngIRCd. - KILL KILL @@ -627,40 +715,78 @@ Administrative Commands . This command is used internally between servers, too, for example to disconnect duplicate 's after a "net split". + . + To use this command, the user must be an IRC Operator. References: - RFC 2812, 3.7.1 "Kill message" - KLINE - KLINE : + KLINE [ :] + . + This command provides timed K-Lines (server-local bans). . - This command provides timed K-Lines (Server-local bans). - If a client matches a K-Line, it cannot connect to the issued server. - If you put 0 as , it makes the K-Line permanent. + If a client matches a K-Line, it cannot connect to this server for + seconds. When is 0, it makes the K-Line permanent. . - To remove a K-Line, type "KLINE ". - To list the K-Lines, type "STATS k". + If no and no is given, the K-Line is removed. + . + To use this command, the user must be an IRC Operator. + . + "STATS k" can be used to list all currently active K-Lines. + + References: + - This command is not specified in the IRC RFCs, it is an extension + of ngIRCd. - OPER - OPER + OPER + . + Authenticates a user named as an IRC operator on the current + server/network. + . + This operator must be configured in the server configuration. . - Authenticates as an IRC operator on the current server/network. + Please note that is NOT related to a nickname at all! + + References: + - RFC 2812, 3.1.4 "Oper message" - REHASH REHASH . Causes the server to re-read and re-process its configuration file(s). + . + While rehashing, no new connections are accepted, but all already + established connections stay connected. + . + To use this command, the user must be an IRC Operator. + + References: + - RFC 2812, 4.2 "Rehash message" - RESTART RESTART . Restart the server. + . + While restarting, all connections are reset and no new connections + are accepted. + . + To use this command, the user must be an IRC Operator. + + References: + - RFC 2812, 4.4 "Restart message" - WALLOPS WALLOPS . Sends to all users with user mode "+w". + . + To use this command, the user must be an IRC Operator. + References: + - RFC 2812, 4.7 "Operwall message" IRC Service Commands ~~~~~~~~~~~~~~~~~~~~ @@ -740,7 +866,11 @@ Server Protocol Commands CHANINFO is used by servers to inform each other about a channel: its modes, channel key, user limits and its topic. . - See doc/Protocol.txt for more information. + The CHANINFO command is allowed on server-links only. + + References: + - IRC+, + - IRC+, doc/Protocol.txt - ERROR ERROR [ [<> [...]]] @@ -765,17 +895,49 @@ Server Protocol Commands information of clients, like the hostname, the info text ("real name"), or the user name. . - See doc/Protocol.txt for more information. + The METADATA command is allowed on server-links only. + + References: + - IRC+, + - IRC+, doc/Protocol.txt - NJOIN + NJOIN [][,[][,...]] + . + The NJOIN command is used on setver-links to add users with + and to a while peering. + . + The NJOIN command is allowed on server-links only. + + References: + - RFC 2813, 4.2.2 "Njoin message" - SERVER + SERVER + SERVER + SERVER + . + The first form registers the local connection as a new server in the + network, the second (RFC 1459) and third (RFC 2812) form announce a + new remote server in the network. + . + The SERVER command is allowed on unregistered or server-links only. + + References: + - RFC 1459, 4.1.4 "Server message" + - RFC 2813, 4.1.2 "Server message" - SQUIT - SQUIT + SQUIT . Disconnects an IRC Server from the network. + . + This command is used on server-links, but can be used by IRC Operators + to forcefully disconnect servers from the network, too. + References: + - RFC 2812, 3.1.8 "Squit" + - RFC 2813, 4.1.6 "Server quit message" Dummy Commands ~~~~~~~~~~~~~~ @@ -804,5 +966,19 @@ Dummy Commands - RFC 2812, 4.6 "Users" - GET + GET [...] + . + Fake HTTP GET command. When received, the connection is shut down + immediately again to protect against crazy web browsers ... + + References: + - ngIRCd GIT commit 33e8c2480649 - POST + POST [...] + . + Fake HTTP POST command. When received, the connection is shut down + immediately again to protect against crazy web browsers ... + + References: + - ngIRCd GIT commit 33e8c2480649 diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c index 41947a8a..c6836401 100644 --- a/src/ngircd/irc-channel.c +++ b/src/ngircd/irc-channel.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) * * 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 @@ -33,13 +33,13 @@ #include "parse.h" #include "irc.h" #include "irc-info.h" +#include "irc-macros.h" #include "irc-write.h" #include "conf.h" #include "exp.h" #include "irc-channel.h" - /** * Part from all channels. * @@ -67,7 +67,6 @@ part_from_all_channels(CLIENT* client, CLIENT *target) return CONNECTED; } /* part_from_all_channels */ - /** * Check weather a local client is allowed to join an already existing * channel or not. @@ -149,7 +148,6 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, return true; } /* join_allowed */ - /** * Set user channel modes. * @@ -174,7 +172,6 @@ join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags) Channel_UserModeAdd(chan, target, 'o'); } /* join_set_channelmodes */ - /** * Forward JOIN command to a specific server * @@ -211,7 +208,6 @@ cb_join_forward(CLIENT *To, CLIENT *Prefix, void *Data) Client_ID(Prefix)); } /* cb_join_forward */ - /** * Forward JOIN command to all servers * @@ -256,7 +252,6 @@ join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan, } } /* join_forward */ - /** * Aknowledge user JOIN request and send "channel info" numerics. * @@ -299,15 +294,12 @@ join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan, Channel_Name(chan)); } /* join_send_topic */ - /** * Handler for the IRC "JOIN" command. * - * See RFC 2812, 3.2.1 "Join message"; RFC 2813, 4.2.1 "Join message". - * - * @param Client The client from which this command has been received - * @param Req Request structure with prefix and all parameters - * @returns CONNECTED or DISCONNECTED + * @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_JOIN( CLIENT *Client, REQUEST *Req ) @@ -319,20 +311,9 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req ) assert (Client != NULL); assert (Req != NULL); - /* Bad number of arguments? */ - if (Req->argc < 1 || Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); - - /* Who is the sender? */ - if (Client_Type(Client) == CLIENT_SERVER) - target = Client_Search(Req->prefix); - else - target = Client; - - if (!target) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, - Client_ID(Client), Req->prefix); + _IRC_ARGC_GE_OR_RETURN_(Client, Req, 1) + _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) + _IRC_GET_SENDER_OR_RETURN_(target, Req, Client) /* Is argument "0"? */ if (Req->argc == 1 && !strncmp("0", Req->argv[0], 2)) @@ -443,15 +424,12 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req ) return CONNECTED; } /* IRC_JOIN */ - /** * Handler for the IRC "PART" command. * - * See RFC 2812, 3.2.2: "Part message". - * - * @param Client The client from which this command has been received - * @param Req Request structure with prefix and all parameters - * @returns CONNECTED or DISCONNECTED + * @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_PART(CLIENT * Client, REQUEST * Req) @@ -462,18 +440,9 @@ IRC_PART(CLIENT * Client, REQUEST * Req) assert(Client != NULL); assert(Req != NULL); - if (Req->argc < 1 || Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); - - /* Get the sender */ - if (Client_Type(Client) == CLIENT_SERVER) - target = Client_Search(Req->prefix); - else - target = Client; - if (!target) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, - Client_ID(Client), Req->prefix); + _IRC_ARGC_GE_OR_RETURN_(Client, Req, 1) + _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) + _IRC_GET_SENDER_OR_RETURN_(target, Req, Client) /* Loop over all the given channel names */ chan = strtok(Req->argv[0], ","); @@ -496,15 +465,12 @@ IRC_PART(CLIENT * Client, REQUEST * Req) return CONNECTED; } /* IRC_PART */ - /** * Handler for the IRC "TOPIC" command. * - * See RFC 2812, 3.2.4 "Topic message". - * - * @param Client The client from which this command has been received - * @param Req Request structure with prefix and all parameters - * @returns CONNECTED or DISCONNECTED + * @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_TOPIC( CLIENT *Client, REQUEST *Req ) @@ -517,18 +483,11 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if (Req->argc < 1 || Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); - - if (Client_Type(Client) == CLIENT_SERVER) - from = Client_Search(Req->prefix); - else - from = Client; + IRC_SetPenalty(Client, 1); - if (!from) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, - Client_ID(Client), Req->prefix); + _IRC_ARGC_GE_OR_RETURN_(Client, Req, 1) + _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) chan = Channel_Search(Req->argv[0]); if (!chan) @@ -606,15 +565,9 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) return CONNECTED; } /* IRC_TOPIC */ - /** * Handler for the IRC "LIST" command. * - * See RFC 2812, 3.2.6 "List message". - * - * This implementation handles the local case as well as the forwarding of the - * LIST command to other servers in the IRC network. - * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @return CONNECTED or DISCONNECTED. @@ -630,26 +583,16 @@ IRC_LIST( CLIENT *Client, REQUEST *Req ) assert(Client != NULL); assert(Req != NULL); - /* Bad number of prameters? */ - if (Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + IRC_SetPenalty(Client, 2); + + _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) if (Req->argc > 0) pattern = strtok(Req->argv[0], ","); else pattern = "*"; - /* Get sender from prefix, if any */ - if (Client_Type(Client) == CLIENT_SERVER) - from = Client_Search(Req->prefix); - else - from = Client; - - if (!from) - return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG, - Client_ID(Client), Req->prefix); - if (Req->argc == 2) { /* Forward to other server? */ target = Client_Search(Req->argv[1]); @@ -703,20 +646,15 @@ IRC_LIST( CLIENT *Client, REQUEST *Req ) pattern = NULL; } - IRC_SetPenalty(from, 2); return IRC_WriteStrClient(from, RPL_LISTEND_MSG, Client_ID(from)); } /* IRC_LIST */ - /** - * Handler for the IRC+ command "CHANINFO". - * - * See doc/Protocol.txt, section II.3: - * "Exchange channel-modes, topics, and persistent channels". + * Handler for the IRC+ "CHANINFO" command. * - * @param Client The client from which this command has been received - * @param Req Request structure with prefix and all parameters - * @returns CONNECTED or DISCONNECTED + * @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_CHANINFO( CLIENT *Client, REQUEST *Req ) @@ -735,68 +673,71 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req ) Client_ID(Client), Req->command); /* Compatibility kludge */ - if( Req->argc == 5 ) arg_topic = 4; - else if( Req->argc == 3 ) arg_topic = 2; - else arg_topic = -1; + if (Req->argc == 5) + arg_topic = 4; + else if(Req->argc == 3) + arg_topic = 2; + else + arg_topic = -1; - /* Search origin */ - from = Client_Search( Req->prefix ); - if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) /* Search or create channel */ chan = Channel_Search( Req->argv[0] ); - if( ! chan ) chan = Channel_Create( Req->argv[0] ); - if( ! chan ) return CONNECTED; - - if( Req->argv[1][0] == '+' ) - { - ptr = Channel_Modes( chan ); - if( ! *ptr ) - { - /* OK, this channel doesn't have modes jet, set the received ones: */ - Channel_SetModes( chan, &Req->argv[1][1] ); - - if( Req->argc == 5 ) - { - if( strchr( Channel_Modes( chan ), 'k' )) Channel_SetKey( chan, Req->argv[2] ); - if( strchr( Channel_Modes( chan ), 'l' )) Channel_SetMaxUsers( chan, atol( Req->argv[3] )); - } - else - { + if (!chan) + chan = Channel_Create( Req->argv[0] ); + if (!chan) + return CONNECTED; + + if (Req->argv[1][0] == '+') { + ptr = Channel_Modes(chan); + if (!*ptr) { + /* OK, this channel doesn't have modes jet, + * set the received ones: */ + Channel_SetModes(chan, &Req->argv[1][1]); + + if(Req->argc == 5) { + if(strchr(Channel_Modes(chan), 'k')) + Channel_SetKey(chan, Req->argv[2]); + if(strchr(Channel_Modes(chan), 'l')) + Channel_SetMaxUsers(chan, atol(Req->argv[3])); + } else { /* Delete modes which we never want to inherit */ - Channel_ModeDel( chan, 'l' ); - Channel_ModeDel( chan, 'k' ); + Channel_ModeDel(chan, 'l'); + Channel_ModeDel(chan, 'k'); } - strcpy( modes_add, "" ); - ptr = Channel_Modes( chan ); - while( *ptr ) - { - if( *ptr == 'l' ) - { - snprintf( l, sizeof( l ), " %lu", Channel_MaxUsers( chan )); - strlcat( modes_add, l, sizeof( modes_add )); + strcpy(modes_add, ""); + ptr = Channel_Modes(chan); + while (*ptr) { + if (*ptr == 'l') { + snprintf(l, sizeof(l), " %lu", + Channel_MaxUsers(chan)); + strlcat(modes_add, l, + sizeof(modes_add)); } - if( *ptr == 'k' ) - { - strlcat( modes_add, " ", sizeof( modes_add )); - strlcat( modes_add, Channel_Key( chan ), sizeof( modes_add )); + if (*ptr == 'k') { + strlcat(modes_add, " ", + sizeof(modes_add)); + strlcat(modes_add, Channel_Key(chan), + sizeof(modes_add)); } ptr++; } /* Inform members of this channel */ - IRC_WriteStrChannelPrefix( Client, chan, from, false, "MODE %s +%s%s", Req->argv[0], Channel_Modes( chan ), modes_add ); + IRC_WriteStrChannelPrefix(Client, chan, from, false, + "MODE %s +%s%s", Req->argv[0], + Channel_Modes(chan), modes_add); } } - else Log( LOG_WARNING, "CHANINFO: invalid MODE format ignored!" ); + else + Log(LOG_WARNING, "CHANINFO: invalid MODE format ignored!"); - if( arg_topic > 0 ) - { + if (arg_topic > 0) { /* We got a topic */ ptr = Channel_Topic( chan ); - if(( ! *ptr ) && ( Req->argv[arg_topic][0] )) - { + if (!*ptr && Req->argv[arg_topic][0]) { /* OK, there is no topic jet */ Channel_SetTopic(chan, Client, Req->argv[arg_topic]); IRC_WriteStrChannelPrefix(Client, chan, from, false, @@ -805,12 +746,23 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req ) } /* Forward CHANINFO to other serevrs */ - if( Req->argc == 5 ) IRC_WriteStrServersPrefixFlag( Client, from, 'C', "CHANINFO %s %s %s %s :%s", Req->argv[0], Req->argv[1], Req->argv[2], Req->argv[3], Req->argv[4] ); - else if( Req->argc == 3 ) IRC_WriteStrServersPrefixFlag( Client, from, 'C', "CHANINFO %s %s :%s", Req->argv[0], Req->argv[1], Req->argv[2] ); - else IRC_WriteStrServersPrefixFlag( Client, from, 'C', "CHANINFO %s %s", Req->argv[0], Req->argv[1] ); + if (Req->argc == 5) + IRC_WriteStrServersPrefixFlag(Client, from, 'C', + "CHANINFO %s %s %s %s :%s", + Req->argv[0], Req->argv[1], + Req->argv[2], Req->argv[3], + Req->argv[4]); + else if (Req->argc == 3) + IRC_WriteStrServersPrefixFlag(Client, from, 'C', + "CHANINFO %s %s :%s", + Req->argv[0], Req->argv[1], + Req->argv[2]); + else + IRC_WriteStrServersPrefixFlag(Client, from, 'C', + "CHANINFO %s %s", + Req->argv[0], Req->argv[1]); return CONNECTED; } /* IRC_CHANINFO */ - /* -eof- */ diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index 765de394..a51369f0 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2013 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 "defines.h" #include "conn.h" #include "channel.h" +#include "irc-macros.h" #include "irc-write.h" #include "lists.h" #include "log.h" @@ -35,7 +36,6 @@ #include "exp.h" #include "irc-mode.h" - static bool Client_Mode PARAMS((CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target)); static bool Channel_Mode PARAMS((CLIENT *Client, REQUEST *Req, CLIENT *Origin, @@ -50,16 +50,15 @@ static bool Send_ListChange PARAMS((const bool IsAdd, const char ModeChar, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask)); - /** * Handler for the IRC "MODE" command. * - * See RFC 2812 section 3.1.5 ("user mode message") and section 3.2.3 - * ("channel mode message"), and RFC 2811 section 4 ("channel modes"). + * This function detects whether user or channel modes should be modified + * and calls the apropriate sub-functions. * - * @param Client The client from which this command has been received. - * @param Req Request structure with prefix and all parameters. - * @returns CONNECTED or DISCONNECTED. + * @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_MODE( CLIENT *Client, REQUEST *Req ) @@ -70,20 +69,8 @@ IRC_MODE( CLIENT *Client, REQUEST *Req ) assert(Client != NULL); assert(Req != NULL); - /* No parameters? */ - if (Req->argc < 1) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); - - /* Origin for answers */ - if (Client_Type(Client) == CLIENT_SERVER) { - origin = Client_Search(Req->prefix); - if (!origin) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, - Client_ID(Client), - Req->prefix); - } else - origin = Client; + _IRC_ARGC_GE_OR_RETURN_(Client, Req, 1) + _IRC_GET_SENDER_OR_RETURN_(origin, Req, Client) /* Channel or user mode? */ cl = NULL; chan = NULL; @@ -102,7 +89,6 @@ IRC_MODE( CLIENT *Client, REQUEST *Req ) Client_ID(Client), Req->argv[0]); } /* IRC_MODE */ - /** * Check if the "mode limit" for a client has been reached. * @@ -123,15 +109,14 @@ Mode_Limit_Reached(CLIENT *Client, int Count) return true; } - /** * Handle client mode requests * - * @param Client The client from which this command has been received. - * @param Req Request structure with prefix and all parameters. - * @param Origin The originator of the MODE command (prefix). - * @param Target The target (client) of this MODE command. - * @returns CONNECTED or DISCONNECTED. + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @param Origin The originator of the MODE command (prefix). + * @param Target The target (client) of this MODE command. + * @return CONNECTED or DISCONNECTED. */ static bool Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ) @@ -386,7 +371,13 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ) return ok; } /* Client_Mode */ - +/* + * Reply to a channel mode request. + * + * @param Origin The originator of the MODE command (prefix). + * @param Channel The channel of which the modes should be sent. + * @return CONNECTED or DISCONNECTED. + */ static bool Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel) { @@ -432,9 +423,14 @@ Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel) return CONNECTED; } - /** * Handle channel mode and channel-user mode changes + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @param Origin The originator of the MODE command (prefix). + * @param Channel The target channel of this MODE command. + * @return CONNECTED or DISCONNECTED. */ static bool Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) @@ -941,31 +937,37 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) return connected; } /* Channel_Mode */ - +/** + * Handler for the IRC "AWAY" 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_AWAY( CLIENT *Client, REQUEST *Req ) { - assert( Client != NULL ); - assert( Req != NULL ); - - if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); - - if(( Req->argc == 1 ) && (Req->argv[0][0] )) - { - Client_SetAway( Client, Req->argv[0] ); - Client_ModeAdd( Client, 'a' ); - IRC_WriteStrServersPrefix( Client, Client, "MODE %s :+a", Client_ID( Client )); - return IRC_WriteStrClient( Client, RPL_NOWAWAY_MSG, Client_ID( Client )); - } - else - { - Client_ModeDel( Client, 'a' ); - IRC_WriteStrServersPrefix( Client, Client, "MODE %s :-a", Client_ID( Client )); - return IRC_WriteStrClient( Client, RPL_UNAWAY_MSG, Client_ID( Client )); + assert (Client != NULL); + assert (Req != NULL); + + _IRC_ARGC_LE_OR_RETURN_(Client, Req, 1) + + if (Req->argc == 1 && Req->argv[0][0]) { + Client_SetAway(Client, Req->argv[0]); + Client_ModeAdd(Client, 'a'); + IRC_WriteStrServersPrefix(Client, Client, "MODE %s :+a", + Client_ID( Client)); + return IRC_WriteStrClient(Client, RPL_NOWAWAY_MSG, + Client_ID( Client)); + } else { + Client_ModeDel(Client, 'a'); + IRC_WriteStrServersPrefix(Client, Client, "MODE %s :-a", + Client_ID( Client)); + return IRC_WriteStrClient(Client, RPL_UNAWAY_MSG, + Client_ID( Client)); } } /* IRC_AWAY */ - /** * Add entries to channel invite, ban and exception lists. * @@ -1032,7 +1034,6 @@ Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, return Send_ListChange(true, what, Prefix, Client, Channel, mask); } - /** * Delete entries from channel invite, ban and exeption lists. * @@ -1076,7 +1077,6 @@ Del_From_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, return Send_ListChange(false, what, Prefix, Client, Channel, mask); } - /** * Send information about changed channel invite/ban/exception lists to clients. * @@ -1114,5 +1114,4 @@ Send_ListChange(const bool IsAdd, const char ModeChar, CLIENT *Prefix, return ok; } /* Send_ListChange */ - /* -eof- */ diff --git a/src/ngircd/irc-oper.c b/src/ngircd/irc-oper.c index 237107f6..80b9f9a4 100644 --- a/src/ngircd/irc-oper.c +++ b/src/ngircd/irc-oper.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2013 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 @@ -28,6 +28,7 @@ #include "conf.h" #include "channel.h" #include "class.h" +#include "irc-macros.h" #include "irc-write.h" #include "log.h" #include "match.h" @@ -55,8 +56,6 @@ Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg) /** * Handler for the IRC "OPER" command. * - * See RFC 2812, 3.1.4 "Oper message". - * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @return CONNECTED or DISCONNECTED. @@ -70,9 +69,7 @@ IRC_OPER( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if (Req->argc != 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 2) len = array_length(&Conf_Opers, sizeof(*op)); op = array_start(&Conf_Opers); @@ -98,8 +95,8 @@ IRC_OPER( CLIENT *Client, REQUEST *Req ) if (!Client_OperByMe(Client)) Log(LOG_NOTICE|LOG_snotice, - "Got valid OPER from \"%s\", user is an IRC operator now.", - Client_Mask(Client)); + "Got valid OPER for \"%s\" from \"%s\", user is an IRC operator now.", + Req->argv[0], Client_Mask(Client)); Client_SetOperByMe(Client, true); return IRC_WriteStrClient(Client, RPL_YOUREOPER_MSG, Client_ID(Client)); @@ -108,8 +105,6 @@ IRC_OPER( CLIENT *Client, REQUEST *Req ) /** * Handler for the IRC "DIE" command. * - * See RFC 2812, 4.3 "Die message". - * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @return CONNECTED or DISCONNECTED. @@ -128,14 +123,11 @@ IRC_DIE(CLIENT * Client, REQUEST * Req) if (!Op_Check(Client, Req)) return Op_NoPrivileges(Client, Req); - /* Bad number of parameters? */ #ifdef STRICT_RFC - if (Req->argc != 0) + _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 0) #else - if (Req->argc > 1) + _IRC_ARGC_LE_OR_RETURN_(Client, Req, 1) #endif - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); /* Is a message given? */ if (Req->argc > 0) { @@ -159,8 +151,6 @@ IRC_DIE(CLIENT * Client, REQUEST * Req) /** * Handler for the IRC "REHASH" command. * - * See RFC 2812, 4.2 "Rehash message". - * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @return CONNECTED or DISCONNECTED. @@ -176,10 +166,7 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req ) if (!Op_Check(Client, Req)) return Op_NoPrivileges(Client, Req); - /* Bad number of parameters? */ - if (Req->argc != 0) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command ); + _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 0) Log(LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...", Client_Mask(Client)); @@ -193,8 +180,6 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req ) /** * Handler for the IRC "RESTART" command. * - * See RFC 2812, 4.4 "Restart message". - * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @return CONNECTED or DISCONNECTED. @@ -225,8 +210,6 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req ) /** * Handler for the IRC "CONNECT" command. * - * See RFC 2812, 3.4.7 "Connect message". - * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @return CONNECTED or DISCONNECTED. @@ -377,8 +360,6 @@ IRC_DISCONNECT(CLIENT * Client, REQUEST * Req) /** * Handler for the IRC "WALLOPS" command. * - * See RFC 2812, 4.7 "Operwall message". - * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @return CONNECTED or DISCONNECTED. @@ -391,9 +372,7 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if (Req->argc != 1) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 1) switch (Client_Type(Client)) { case CLIENT_USER: diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c index 0a9e930d..a8b82c96 100644 --- a/src/ngircd/irc-server.c +++ b/src/ngircd/irc-server.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2007 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2013 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 @@ -29,7 +29,6 @@ #include "conn-zip.h" #include "conf.h" #include "channel.h" -#include "irc-write.h" #include "lists.h" #include "log.h" #include "messages.h" @@ -37,15 +36,19 @@ #include "numeric.h" #include "ngircd.h" #include "irc-info.h" +#include "irc-macros.h" +#include "irc-write.h" #include "op.h" #include "exp.h" #include "irc-server.h" - /** - * Handler for the IRC command "SERVER". - * See RFC 2813 section 4.1.2. + * Handler for the IRC "SERVER" 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_SERVER( CLIENT *Client, REQUEST *Req ) @@ -214,7 +217,13 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) Client_ID(Client), Req->command); } /* IRC_SERVER */ - +/* + * Handler for the IRC "NJOIN" 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_NJOIN( CLIENT *Client, REQUEST *Req ) { @@ -226,7 +235,7 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 2) strlcpy( nick_in, Req->argv[1], sizeof( nick_in )); strcpy( nick_out, "" ); @@ -288,15 +297,19 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req ) } /* forward to other servers */ - if( nick_out[0] != '\0' ) IRC_WriteStrServersPrefix( Client, Client_ThisServer( ), "NJOIN %s :%s", Req->argv[0], nick_out ); + if (nick_out[0] != '\0') + IRC_WriteStrServersPrefix(Client, Client_ThisServer(), + "NJOIN %s :%s", Req->argv[0], nick_out); return CONNECTED; } /* IRC_NJOIN */ - /** - * Handler for the IRC command "SQUIT". - * See RFC 2813 section 4.1.2 and RFC 2812 section 3.1.8. + * Handler for the IRC "SQUIT" 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_SQUIT(CLIENT * Client, REQUEST * Req) @@ -313,10 +326,7 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req) && !Client_HasMode(Client, 'o')) return Op_NoPrivileges(Client, Req); - /* Bad number of arguments? */ - if (Req->argc != 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 2) if (Client_Type(Client) == CLIENT_SERVER && Req->prefix) { from = Client_Search(Req->prefix);