/*
* 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 <assert.h>
#include <stdio.h>
case 'x': /* Cloak hostname */
if (Client_HasMode(Client, 'r'))
- IRC_WriteStrClient(Origin,
+ ok = IRC_WriteStrClient(Origin,
ERR_RESTRICTED_MSG,
Client_ID(Origin));
else
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;
}
{
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;
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];
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