]> jfr.im git - irc/rqf/shadowircd.git/commitdiff
Add channel::exemptchanops, and make +cCDTNG support it.
authorB.Greenham <redacted>
Mon, 1 Mar 2010 07:43:55 +0000 (02:43 -0500)
committerB.Greenham <redacted>
Mon, 1 Mar 2010 07:43:55 +0000 (02:43 -0500)
TODO-SHADOW
doc/example.conf
doc/reference.conf
include/s_conf.h
modules/core/m_message.c
modules/core/m_part.c
modules/m_info.c
src/channel.c
src/newconf.c
src/s_conf.c

index c6748a69f6fdb603ab16988a56461531e7def284..79c8d2ea01d845e0904331d8f3c73a13da83b2b3 100644 (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
 
index f736d17e6b003955f30be27513a84c4b1032cf62..1c5c75fce73541551257817795a6f919b7e45a23 100755 (executable)
@@ -333,6 +333,7 @@ exempt {
 
 channel {
        autochanmodes = "nt";
+       exemptchanops = "NT";
        use_halfop = yes;
        use_owner = yes;
        use_invex = yes;
index cf7d45a968ed434ffb904236f710475391fc15c4..636800d23e22f0b1412d6851944491b5c702363d 100755 (executable)
@@ -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
index c07896cc21624e0fd03755483b61362bc8bd1bf5..6e18c42da8771521699d9ec2240164382b6b7397 100644 (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
index 1ac0cfb4bd9d728698ca92f313f0dab4beb08b36..343aef733157fdd676b8111a318a6298e81a4037 100644 (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);
index 61c585b7c2ce540b9cf1b0b515f08ee511b36b33..3159a3f7c0ded6c9ab7d80d1f78afe5d6d7c6d2c 100644 (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);
index a8ce27f6f04e6b4e1bd248465196d5c0c247506d..36cf629084ae55b98038a8eaf5a2e8e0c1b84a49 100644 (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,
index fab6c920b000dcb023918b90526d377952a0736d..89c271bae8307539d607a229f09db8dda225b638 100644 (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;
index 31969a53052f740e0bfa78d44612da64f60b02a6..a13841a5f7f6b800959a7bfafc0ad8e0357bd082 100644 (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 }
 };
 
index 5eb07d552d6a873e801b110a73ec498fdbf561c4..66d407cef8ba768d5aa33d5e3ac59316b76af9c2 100644 (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()