#include "irc-mode.h"
+static void Announce_Client_Hostname PARAMS((CLIENT *Origin, CLIENT *Client));
+
static bool Client_Mode PARAMS((CLIENT *Client, REQUEST *Req, CLIENT *Origin,
CLIENT *Target));
static bool Channel_Mode PARAMS((CLIENT *Client, REQUEST *Req, CLIENT *Origin,
/* Mode request: let's answer it :-) */
if (Req->argc == 1)
return IRC_WriteStrClient(Origin, RPL_UMODEIS_MSG,
- Client_ID(Origin),
+ Client_ID(Target),
Client_Modes(Target));
mode_arg = 1;
/* Validate modes */
x[0] = '\0';
switch (*mode_ptr) {
+ case 'b': /* Block private msgs */
case 'C': /* Only messages from clients sharing a channel */
case 'i': /* Invisible */
case 's': /* Server messages */
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
break;
+ case 'q': /* KICK-protected user */
+ if (!set || Client_Type(Client) == CLIENT_SERVER
+ || Client_OperByMe(Origin))
+ x[0] = 'q';
+ else
+ ok = IRC_WriteStrClient(Origin,
+ ERR_NOPRIVILEGES_MSG,
+ Client_ID(Origin));
+ break;
case 'r': /* Restricted (only settable) */
if (set || Client_Type(Client) == CLIENT_SERVER)
x[0] = 'r';
Client_ID(Target),
the_modes);
if (send_RPL_HOSTHIDDEN_MSG)
- IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG,
- Client_ID(Client),
- Client_HostnameCloaked(Client));
+ Announce_Client_Hostname(Origin, Client);
}
LogDebug("%s \"%s\": Mode change, now \"%s\".",
Client_TypeText(Target), Client_Mask(Target),
} /* Client_Mode */
+/**
+ * Announce changed client hostname in the network.
+ *
+ * @param Client The client of which the hostname changed.
+ */
+static void
+Announce_Client_Hostname(CLIENT *Origin, CLIENT *Client)
+{
+ assert(Client != NULL);
+
+ /* Inform the client itself */
+ IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG, Client_ID(Client),
+ Client_HostnameDisplayed(Client));
+
+ /* Inform other servers in the network */
+ IRC_WriteStrServersPrefixFlag(Origin, Client_ThisServer(), 'M',
+ "METADATA %s host :%s", Client_ID(Client),
+ Client_HostnameDisplayed(Client));
+}
+
+
static bool
Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
{
goto chan_exit;
}
case 'i': /* Invite only */
+ case 'V': /* Invite disallow */
case 'M': /* Only identified nicks can write */
case 'm': /* Moderated */
case 'n': /* Only members can write */
+ case 'Q': /* No kicks */
case 't': /* Topic locked */
if(is_oper || is_machine || is_owner ||
is_admin || is_op || is_halfop)
/* --- Channel user modes --- */
case 'q': /* Owner */
case 'a': /* Channel admin */
- if(!is_oper && !is_machine && !is_owner) {
+ if(!is_oper && !is_machine && !is_owner && !is_admin) {
connected = IRC_WriteStrClient(Origin,
- ERR_CHANOPRIVSNEEDED_MSG,
+ ERR_CHANOPPRIVTOOLOW_MSG,
Client_ID(Origin),
Channel_Name(Channel));
goto chan_exit;