static bool Channel_Mode PARAMS((CLIENT *Client, REQUEST *Req, CLIENT *Origin,
CHANNEL *Channel));
-static bool Add_Ban_Invite PARAMS((char what, CLIENT *Prefix, CLIENT *Client,
- CHANNEL *Channel, const char *Pattern));
-static bool Del_Ban_Invite PARAMS((char what, CLIENT *Prefix, CLIENT *Client,
- CHANNEL *Channel, const char *Pattern));
+static bool Add_To_List PARAMS((char what, CLIENT *Prefix, CLIENT *Client,
+ CHANNEL *Channel, const char *Pattern));
+static bool Del_From_List PARAMS((char what, CLIENT *Prefix, CLIENT *Client,
+ CHANNEL *Channel, const char *Pattern));
static bool Send_ListChange PARAMS((const bool IsAdd, const char ModeChar,
CLIENT *Prefix, CLIENT *Client,
/* Validate modes */
x[0] = '\0';
switch (*mode_ptr) {
+ case 'C': /* Only messages from clients sharing a channel */
case 'i': /* Invisible */
case 's': /* Server messages */
case 'w': /* Wallops messages */
ERR_RESTRICTED_MSG,
Client_ID(Origin));
break;
+ case 'R': /* Registered (not [un]settable by clients) */
+ if (Client_Type(Client) == CLIENT_SERVER)
+ x[0] = 'R';
+ else
+ ok = IRC_WriteStrClient(Origin,
+ ERR_NICKREGISTER_MSG,
+ Client_ID(Origin));
+ break;
case 'x': /* Cloak hostname */
if (Client_HasMode(Client, 'r'))
ok = IRC_WriteStrClient(Origin,
/* --- Channel lists --- */
case 'I': /* Invite lists */
case 'b': /* Ban lists */
+ case 'e': /* Channel exception lists */
if (Mode_Limit_Reached(Client, mode_arg_count++))
goto chan_exit;
if (arg_arg > mode_arg) {
/* modify list */
if (modeok) {
connected = set
- ? Add_Ban_Invite(*mode_ptr, Origin,
+ ? Add_To_List(*mode_ptr, Origin,
Client, Channel,
Req->argv[arg_arg])
- : Del_Ban_Invite(*mode_ptr, Origin,
+ : Del_From_List(*mode_ptr, Origin,
Client, Channel,
Req->argv[arg_arg]);
} else {
Req->argv[arg_arg][0] = '\0';
arg_arg++;
} else {
- if (*mode_ptr == 'I')
+ switch (*mode_ptr) {
+ case 'I':
Channel_ShowInvites(Origin, Channel);
- else
+ break;
+ case 'b':
Channel_ShowBans(Origin, Channel);
+ break;
+ case 'e':
+ Channel_ShowExcepts(Origin, Channel);
+ break;
+ }
}
break;
default:
/**
- * Add entries to channel ban and invite lists.
+ * Add entries to channel invite, ban and exception lists.
*
- * @param what Can be 'I' for invite or 'b' for ban list.
+ * @param what Can be 'I' for invite, 'b' for ban, and 'e' for exception list.
* @param Prefix The originator of the command.
* @param Client The sender of the command.
* @param Channel The channel of which the list should be modified.
* @return CONNECTED or DISCONNECTED.
*/
static bool
-Add_Ban_Invite(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
- const char *Pattern)
+Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
+ const char *Pattern)
{
const char *mask;
- struct list_head *list;
+ struct list_head *list = NULL;
+ long int current_count;
assert(Client != NULL);
assert(Channel != NULL);
assert(Pattern != NULL);
- assert(what == 'I' || what == 'b');
+ assert(what == 'I' || what == 'b' || what == 'e');
mask = Lists_MakeMask(Pattern);
+ current_count = Lists_Count(Channel_GetListInvites(Channel))
+ + Lists_Count(Channel_GetListExcepts(Channel))
+ + Lists_Count(Channel_GetListBans(Channel));
- if (what == 'I')
- list = Channel_GetListInvites(Channel);
- else
- list = Channel_GetListBans(Channel);
+ switch(what) {
+ case 'I':
+ list = Channel_GetListInvites(Channel);
+ break;
+ case 'b':
+ list = Channel_GetListBans(Channel);
+ break;
+ case 'e':
+ list = Channel_GetListExcepts(Channel);
+ break;
+ }
if (Lists_CheckDupeMask(list, mask))
return CONNECTED;
-
- if (what == 'I') {
- if (!Channel_AddInvite(Channel, mask, false))
- return CONNECTED;
- } else {
- if (!Channel_AddBan(Channel, mask))
- return CONNECTED;
+ if (Client_Type(Client) == CLIENT_USER &&
+ current_count >= MAX_HNDL_CHANNEL_LISTS)
+ return IRC_WriteStrClient(Client, ERR_LISTFULL_MSG,
+ Client_ID(Client),
+ Channel_Name(Channel), mask,
+ MAX_HNDL_CHANNEL_LISTS);
+
+ switch (what) {
+ case 'I':
+ if (!Channel_AddInvite(Channel, mask, false))
+ return CONNECTED;
+ break;
+ case 'b':
+ if (!Channel_AddBan(Channel, mask))
+ return CONNECTED;
+ break;
+ case 'e':
+ if (!Channel_AddExcept(Channel, mask))
+ return CONNECTED;
+ break;
}
return Send_ListChange(true, what, Prefix, Client, Channel, mask);
}
/**
- * Delete entries from channel ban and invite lists.
+ * Delete entries from channel invite, ban and exeption lists.
*
- * @param what Can be 'I' for invite or 'b' for ban list.
+ * @param what Can be 'I' for invite, 'b' for ban, and 'e' for exception list.
* @param Prefix The originator of the command.
* @param Client The sender of the command.
* @param Channel The channel of which the list should be modified.
* @return CONNECTED or DISCONNECTED.
*/
static bool
-Del_Ban_Invite(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
- const char *Pattern)
+Del_From_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
+ const char *Pattern)
{
const char *mask;
- struct list_head *list;
+ struct list_head *list = NULL;
assert(Client != NULL);
assert(Channel != NULL);
assert(Pattern != NULL);
- assert(what == 'I' || what == 'b');
+ assert(what == 'I' || what == 'b' || what == 'e');
mask = Lists_MakeMask(Pattern);
- if (what == 'I')
- list = Channel_GetListInvites(Channel);
- else
- list = Channel_GetListBans(Channel);
+ switch (what) {
+ case 'I':
+ list = Channel_GetListInvites(Channel);
+ break;
+ case 'b':
+ list = Channel_GetListBans(Channel);
+ break;
+ case 'e':
+ list = Channel_GetListExcepts(Channel);
+ break;
+ }
if (!Lists_CheckDupeMask(list, mask))
return CONNECTED;
/**
- * Send information about changed channel ban/invite lists to clients.
+ * Send information about changed channel invite/ban/exception lists to clients.
*
* @param IsAdd true if the list item has been added, false otherwise.
* @param ModeChar The mode to use (e. g. 'b' or 'I')