Add channel::exemptchanops, and make +cCDTNG support it.

This commit is contained in:
B.Greenham 2010-03-01 02:43:55 -05:00
parent 2d465e2456
commit 5ad94b5000
10 changed files with 88 additions and 10 deletions

View File

@ -6,7 +6,6 @@ Todo list for ShadowIRCd 6.0
* kicknorejoin (+J in inspircd chmode)
* operoverride umode (+p), steal this from ircd-seven
* immune cmode (+M), steal this from ircd-seven too
* channel::exemptchanops config option
* host-on-operup: vhost that gets applied to you on oper-up. A surprising number of people want this.
* Anything else we think of between now and release. :P

View File

@ -333,6 +333,7 @@ exempt {
channel {
autochanmodes = "nt";
exemptchanops = "NT";
use_halfop = yes;
use_owner = yes;
use_invex = yes;

View File

@ -691,6 +691,12 @@ channel {
*/
autochanmodes = "nt";
/* exemptchanops: Channel modes that any form of channel ops (+aoh)
* will be exempt from. Even if the mode is set, it will not apply to the
* channel ops if it is listed in this option. Valid modes are cCDTNGK.
*/
exemptchanops = "NT";
/* halfop: Enable/disable channel mode +h, which adds halfop,
* a channel status below op that has op powers (kick, ban, mode, etc.)
* halfops can only kick/devoice/etc people who are +v or

View File

@ -222,6 +222,7 @@ struct config_file_entry
struct config_channel_entry
{
char * autochanmodes;
char * exemptchanops;
int use_halfop;
int use_owner;
int use_except;
@ -245,6 +246,14 @@ struct config_channel_entry
int host_in_topic;
int resv_forcepart;
int kick_no_rejoin_time;
int exempt_cmode_c;
int exempt_cmode_C;
int exempt_cmode_D;
int exempt_cmode_T;
int exempt_cmode_N;
int exempt_cmode_G;
int exempt_cmode_K;
};
struct config_server_hide

View File

@ -487,6 +487,7 @@ msg_channel(int p_or_n, const char *command,
int contor;
int caps = 0;
int len = 0;
struct membership *msptr = find_channel_membership(chptr, source_p);
if(MyClient(source_p))
{
@ -495,7 +496,7 @@ msg_channel(int p_or_n, const char *command,
source_p->localClient->last = rb_current_time();
}
if(chptr->mode.mode & MODE_NOCOLOR)
if(chptr->mode.mode & MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
{
rb_strlcpy(text2, text, BUFSIZE);
strip_colour(text2);
@ -516,7 +517,7 @@ msg_channel(int p_or_n, const char *command,
if(result == CAN_SEND_OPV ||
!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
{
if (strlen(text) > 10 && chptr->mode.mode & MODE_NOCAPS)
if (strlen(text) > 10 && chptr->mode.mode & MODE_NOCAPS && (!ConfigChannel.exempt_cmode_G || !is_any_op(msptr)))
{
for(contor=0; contor < strlen(text); contor++)
{
@ -531,14 +532,15 @@ msg_channel(int p_or_n, const char *command,
return;
}
}
if (p_or_n != PRIVMSG && chptr->mode.mode & MODE_NONOTICE)
if (p_or_n != PRIVMSG && chptr->mode.mode & MODE_NONOTICE && (!ConfigChannel.exempt_cmode_T || !is_any_op(msptr)))
{
sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
return;
}
if (p_or_n != NOTICE && chptr->mode.mode & MODE_NOACTION &&
!strncasecmp(text + 1, "ACTION", 6))
!strncasecmp(text + 1, "ACTION", 6) &&
(!ConfigChannel.exempt_cmode_D || !is_any_op(msptr)))
{
sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
@ -547,7 +549,7 @@ msg_channel(int p_or_n, const char *command,
if (p_or_n != NOTICE && *text == '\001' &&
strncasecmp(text + 1, "ACTION", 6))
{
if (chptr->mode.mode & MODE_NOCTCP)
if (chptr->mode.mode & MODE_NOCTCP && (!ConfigChannel.exempt_cmode_C || !is_any_op(msptr)))
{
sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);

View File

@ -128,7 +128,7 @@ part_one_client(struct Client *client_p, struct Client *source_p, char *name, ch
(source_p->localClient->firsttime +
ConfigFileEntry.anti_spam_exit_message_time) < rb_current_time()))))
{
if(chptr->mode.mode & MODE_NOCOLOR)
if(chptr->mode.mode & MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
{
rb_strlcpy(reason2, reason, BUFSIZE);
strip_colour(reason2);

View File

@ -332,6 +332,12 @@ static struct InfoStruct info_table[] = {
&ConfigChannel.autochanmodes,
"Channelmodes set on channel creation"
},
{
"exemptchanops",
OUTPUT_STRING,
&ConfigChannel.exemptchanops,
"Channelmodes that chanops are exempt from"
},
{
"nick_delay",
OUTPUT_DECIMAL,

View File

@ -1029,9 +1029,7 @@ find_nonickchange_channel(struct Client *client_p)
{
msptr = ptr->data;
chptr = msptr->chptr;
if (is_any_op(msptr))
continue;
if (chptr->mode.mode & MODE_NONICK)
if (chptr->mode.mode & MODE_NONICK && (!ConfigChannel.exempt_cmode_N || !is_any_op(msptr)))
return chptr;
}
return NULL;

View File

@ -2207,6 +2207,7 @@ static struct ConfEntry conf_general_table[] =
static struct ConfEntry conf_channel_table[] =
{
{ "autochanmodes", CF_QSTRING, NULL, 0, &ConfigChannel.autochanmodes },
{ "exemptchanops", CF_QSTRING, NULL, 0, &ConfigChannel.exemptchanops },
{ "default_split_user_count", CF_INT, NULL, 0, &ConfigChannel.default_split_user_count },
{ "default_split_server_count", CF_INT, NULL, 0, &ConfigChannel.default_split_server_count },
{ "burst_topicwho", CF_YESNO, NULL, 0, &ConfigChannel.burst_topicwho },
@ -2230,6 +2231,13 @@ static struct ConfEntry conf_channel_table[] =
{ "use_local_channels", CF_YESNO, NULL, 0, &ConfigChannel.use_local_channels },
{ "resv_forcepart", CF_YESNO, NULL, 0, &ConfigChannel.resv_forcepart },
{ "kick_no_rejoin_time", CF_INT, NULL, 0, &ConfigChannel.kick_no_rejoin_time },
{ "exempt_cmode_c", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_c },
{ "exempt_cmode_C", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_C },
{ "exempt_cmode_D", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_D },
{ "exempt_cmode_T", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_T },
{ "exempt_cmode_N", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_N },
{ "exempt_cmode_G", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_G },
{ "exempt_cmode_K", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_K },
{ "\0", 0, NULL, 0, NULL }
};

View File

@ -747,6 +747,7 @@ set_default_conf(void)
ConfigFileEntry.oper_snomask = SNO_GENERAL;
ConfigChannel.autochanmodes = rb_strdup("nt");
ConfigChannel.exemptchanops = rb_strdup("");
ConfigChannel.use_halfop = YES;
ConfigChannel.use_owner = YES;
ConfigChannel.use_except = YES;
@ -772,6 +773,14 @@ set_default_conf(void)
ConfigChannel.resv_forcepart = YES;
ConfigChannel.kick_no_rejoin_time = 30;
ConfigChannel.exempt_cmode_c = NO;
ConfigChannel.exempt_cmode_C = NO;
ConfigChannel.exempt_cmode_D = NO;
ConfigChannel.exempt_cmode_T = NO;
ConfigChannel.exempt_cmode_N = NO;
ConfigChannel.exempt_cmode_G = NO;
ConfigChannel.exempt_cmode_K = NO;
ConfigServerHide.flatten_links = 0;
ConfigServerHide.links_delay = 300;
ConfigServerHide.hidden = 0;
@ -866,6 +875,46 @@ validate_conf(void)
splitmode = 0;
splitchecking = 0;
}
/* Parse the exemptchanops option and set the internal variables
* that we will use. */
char * ech;
for(ech = ConfigChannel.exemptchanops; *ech; ech++)
{
if(*ech == 'c')
{
ConfigChannel.exempt_cmode_c = 1;
continue;
}
if(*ech == 'C')
{
ConfigChannel.exempt_cmode_C = 1;
continue;
}
if(*ech == 'D')
{
ConfigChannel.exempt_cmode_D = 1;
continue;
}
if(*ech == 'T')
{
ConfigChannel.exempt_cmode_T = 1;
continue;
}
if(*ech == 'N')
{
ConfigChannel.exempt_cmode_N = 1;
continue;
}
if(*ech == 'G')
{
ConfigChannel.exempt_cmode_G = 1;
continue;
}
if(*ech == 'K')
ConfigChannel.exempt_cmode_K = 1;
}
}
/* add_temp_kline()