]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-mode.c
Generate "METADATA host" commands on "MODE +/-x"
[ngircd-alex.git] / src / ngircd / irc-mode.c
index 90f638d811219282b34af51c8cf8369e7548e4f7..1cf19afc2bf437f19a2887509e12851c932a7951 100644 (file)
@@ -36,6 +36,8 @@
 #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,
@@ -215,6 +217,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                /* 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 */
@@ -257,6 +260,15 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                                                        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';
@@ -357,9 +369,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                                                  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),
@@ -371,6 +381,27 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *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_HostnameCloaked(Client));
+
+       /* Inform other servers in the network */
+       IRC_WriteStrServersPrefixFlag(Origin, Client_ThisServer(), 'M',
+                                     "METADATA %s host :%s", Client_ID(Client),
+                                     Client_HostnameCloaked(Client));
+}
+
+
 static bool
 Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
 {
@@ -566,9 +597,11 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, 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)
@@ -697,9 +730,9 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
                /* --- 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;