]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-mode.c
Don't enforce MAX_HNDL_MODES_ARG on server and service links
[ngircd-alex.git] / src / ngircd / irc-mode.c
index 01f87621a6d670df9b7973528d3892b3672caee4..82e6a5aef0fb405d23b4bdc61f14174ffc39e9f3 100644 (file)
@@ -102,6 +102,27 @@ IRC_MODE( CLIENT *Client, REQUEST *Req )
 } /* IRC_MODE */
 
 
+/**
+ * Check if the "mode limit" for a client has been reached.
+ *
+ * This limit doesn't apply for servers or services!
+ *
+ * @param Client The client to check.
+ * @param Count The number of modes already handled.
+ * @return true if the limit has been reached.
+ */
+static bool
+Mode_Limit_Reached(CLIENT *Client, int Count)
+{
+       if (Client_Type(Client) == CLIENT_SERVER
+           || Client_Type(Client) == CLIENT_SERVICE)
+               return false;
+       if (Count < MAX_HNDL_MODES_ARG)
+               return false;
+       return true;
+}
+
+
 /**
  * Handle client mode requests
  *
@@ -375,7 +396,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, modeok, use_servermode;
-       int mode_arg, arg_arg;
+       int mode_arg, arg_arg, mode_arg_count = 0;
        CLIENT *client;
        long l;
        size_t len;
@@ -491,6 +512,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
                                        Client_ID(Origin), Channel_Name(Channel));
                        break;
                case 'k': /* Channel key */
+                       if (Mode_Limit_Reached(Client, mode_arg_count++))
+                               goto chan_exit;
                        if (!set) {
                                if (modeok)
                                        x[0] = *mode_ptr;
@@ -525,6 +548,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
                        }
                        break;
                case 'l': /* Member limit */
+                       if (Mode_Limit_Reached(Client, mode_arg_count++))
+                               goto chan_exit;
                        if (!set) {
                                if (modeok)
                                        x[0] = *mode_ptr;
@@ -635,6 +660,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
                /* --- Channel lists --- */
                case 'I': /* Invite lists */
                case 'b': /* Ban lists */
+                       if (Mode_Limit_Reached(Client, mode_arg_count++))
+                               goto chan_exit;
                        if (arg_arg > mode_arg) {
                                /* modify list */
                                if (modeok) {
@@ -667,9 +694,9 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
                                    set ? '+' : '-', *mode_ptr,
                                    Client_ID(Origin), Channel_Name(Channel));
                                connected = IRC_WriteStrClient(Origin,
-                                       ERR_UMODEUNKNOWNFLAG2_MSG,
-                                       Client_ID(Origin),
-                                       set ? '+' : '-', *mode_ptr);
+                                       ERR_UNKNOWNMODE_MSG,
+                                       Client_ID(Origin), *mode_ptr,
+                                       Channel_Name(Channel));
                                x[0] = '\0';
                        } else {
                                Log(LOG_DEBUG,