X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Fngircd%2Firc-mode.c;h=50b0db0476cf4eab116d8192606843ac0c351fe2;hb=25dd193e9b49b38db39cf549f94df4ba11812fe9;hp=df464a7dba7efca0058cdede4d18ec8090a7eeea;hpb=2a4bf67aaceebd3567dcd0ac1db2b9027560f574;p=ngircd-alex.git diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index df464a7d..50b0db04 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -1,19 +1,21 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2011 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. - * - * IRC commands for mode changes (MODE, AWAY, ...) */ - #include "portab.h" +/** + * @file + * IRC commands for mode changes (like MODE, AWAY, etc.) + */ + #include "imp.h" #include #include @@ -202,7 +204,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ) case 'x': /* Cloak hostname */ if (Client_HasMode(Client, 'r')) - IRC_WriteStrClient(Origin, + ok = IRC_WriteStrClient(Origin, ERR_RESTRICTED_MSG, Client_ID(Origin)); else @@ -294,8 +296,17 @@ Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel) if (the_args[0]) strlcat(the_modes, the_args, sizeof(the_modes)); - return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG, - Client_ID(Origin), Channel_Name(Channel), the_modes); + if (!IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG, + Client_ID(Origin), Channel_Name(Channel), + the_modes)) + return DISCONNECTED; +#ifndef STRICT_RFC + if (!IRC_WriteStrClient(Origin, RPL_CREATIONTIME_MSG, + Client_ID(Origin), Channel_Name(Channel), + Channel_CreationTime(Channel))) + return DISCONNECTED; +#endif + return CONNECTED; } @@ -307,8 +318,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) { char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr; - bool connected, set, skiponce, retval, onchannel; - bool modeok = true, use_servermode = false; + bool connected, set, skiponce, retval, onchannel, modeok, use_servermode; int mode_arg, arg_arg; CLIENT *client; long l; @@ -322,28 +332,13 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) if (Req->argc <= 1) return Channel_Mode_Answer_Request(Origin, Channel); - /* Is the user allowed to change modes? */ - if (Client_Type(Client) == CLIENT_USER) { - /* Is the originating user on that channel? */ - onchannel = Channel_IsMemberOf(Channel, Origin); - modeok = false; - /* channel operator? */ - if (onchannel && - strchr(Channel_UserModes(Channel, Origin), 'o')) { - modeok = true; - } else if (Conf_OperCanMode) { - /* IRC-Operators can use MODE as well */ - if (Client_OperByMe(Origin)) { - modeok = true; - if (Conf_OperServerMode) - use_servermode = true; /* Change Origin to Server */ - } - } + Channel_CheckAdminRights(Channel, Client, Origin, + &onchannel, &modeok, &use_servermode); - if (!onchannel && !modeok) - return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG, - Client_ID(Origin), Channel_Name(Channel)); - } + if (!onchannel && !modeok) + return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG, + Client_ID(Origin), + Channel_Name(Channel)); mode_arg = 1; mode_ptr = Req->argv[mode_arg]; @@ -506,6 +501,23 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) goto chan_exit; } break; + case 'O': /* IRC operators only */ + if (modeok) { + /* Only IRC operators are allowed to + * set the 'O' channel mode! */ + if (set && !(Client_OperByMe(Client) + || Client_Type(Client) == CLIENT_SERVER)) + connected = IRC_WriteStrClient(Origin, + ERR_NOPRIVILEGES_MSG, + Client_ID(Origin)); + else + x[0] = 'O'; + } else + connected = IRC_WriteStrClient(Origin, + ERR_CHANOPRIVSNEEDED_MSG, + Client_ID(Origin), + Channel_Name(Channel)); + break; case 'P': /* Persistent channel */ if (modeok) { /* Only IRC operators are allowed to