From 5ad94b5000b15576521af8a5efc730d57058c839 Mon Sep 17 00:00:00 2001 From: "B.Greenham" Date: Mon, 1 Mar 2010 02:43:55 -0500 Subject: [PATCH] Add channel::exemptchanops, and make +cCDTNG support it. --- TODO-SHADOW | 1 - doc/example.conf | 1 + doc/reference.conf | 6 +++++ include/s_conf.h | 9 ++++++++ modules/core/m_message.c | 12 ++++++---- modules/core/m_part.c | 2 +- modules/m_info.c | 6 +++++ src/channel.c | 4 +--- src/newconf.c | 8 +++++++ src/s_conf.c | 49 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 88 insertions(+), 10 deletions(-) diff --git a/TODO-SHADOW b/TODO-SHADOW index c6748a6..79c8d2e 100644 --- a/TODO-SHADOW +++ b/TODO-SHADOW @@ -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 diff --git a/doc/example.conf b/doc/example.conf index f736d17..1c5c75f 100755 --- a/doc/example.conf +++ b/doc/example.conf @@ -333,6 +333,7 @@ exempt { channel { autochanmodes = "nt"; + exemptchanops = "NT"; use_halfop = yes; use_owner = yes; use_invex = yes; diff --git a/doc/reference.conf b/doc/reference.conf index cf7d45a..636800d 100755 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -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 diff --git a/include/s_conf.h b/include/s_conf.h index c07896c..6e18c42 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -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 diff --git a/modules/core/m_message.c b/modules/core/m_message.c index 1ac0cfb..343aef7 100644 --- a/modules/core/m_message.c +++ b/modules/core/m_message.c @@ -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); diff --git a/modules/core/m_part.c b/modules/core/m_part.c index 61c585b..3159a3f 100644 --- a/modules/core/m_part.c +++ b/modules/core/m_part.c @@ -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); diff --git a/modules/m_info.c b/modules/m_info.c index a8ce27f..36cf629 100644 --- a/modules/m_info.c +++ b/modules/m_info.c @@ -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, diff --git a/src/channel.c b/src/channel.c index fab6c92..89c271b 100644 --- a/src/channel.c +++ b/src/channel.c @@ -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; diff --git a/src/newconf.c b/src/newconf.c index 31969a5..a13841a 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -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 } }; diff --git a/src/s_conf.c b/src/s_conf.c index 5eb07d5..66d407c 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -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()