} /* 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
*
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;
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;
}
break;
case 'l': /* Member limit */
+ if (Mode_Limit_Reached(Client, mode_arg_count++))
+ goto chan_exit;
if (!set) {
if (modeok)
x[0] = *mode_ptr;
/* --- 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) {
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,