]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - src/chmode.c
Should just specify the name here.
[irc/rqf/shadowircd.git] / src / chmode.c
index cb2e2242613aa65b768e947013466bdb80ca7ef2..e0aaf665895816ed73ea414f7c2842121c7aa32b 100644 (file)
@@ -42,6 +42,7 @@
 #include "s_newconf.h"
 #include "logger.h"
 #include "chmode.h"
+#include "irc_dictionary.h";
 
 /* bitmasks for error returns, so we send once per call */
 #define SM_ERR_NOTS             0x00000001     /* No TS on channel */
@@ -501,6 +502,8 @@ chm_simple(struct Client *source_p, struct Channel *chptr,
 {
 
        int override = 0;
+       struct Metadata *md;
+       struct DictionaryIter iter;
        
        if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
        {
@@ -540,6 +543,18 @@ chm_simple(struct Client *source_p, struct Channel *chptr,
        }
        else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type))
        {
+               /* cleanup metadata when the related mode is removed */
+               if(c == 'J')
+               {
+                       DICTIONARY_FOREACH(md, &iter, chptr->metadata)
+                       {
+                               if(!strcmp(md->name, "KICKNOREJOIN"))  
+                                       channel_metadata_delete(chptr, md->name, 0);
+                       }
+               }
+               if(c == 'K')
+                       channel_metadata_delete(chptr, "NOREPEAT", 0);
+
                chptr->mode.mode &= ~mode_type;
 
                mode_changes[mode_count].letter = c;
@@ -783,7 +798,12 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
                                mode_type != CHFL_QUIET)
                {
                        if(IsOverride(source_p))
-                               override = 1;
+                       {
+                               sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+                                               "%s is overriding modes on %s: (%s list)",
+                                               get_oper_name(source_p), chptr->chname,
+                                               mode_type == CHFL_INVEX ? "invex" : "exempt");
+                       }
                        else
                        {
 
@@ -967,8 +987,11 @@ chm_owner(struct Client *source_p, struct Channel *chptr,
                if(targ_p == source_p)
                {
                        no_override_deop = 1;
+                       /* Don't reject modes from remote. It desyncs, and this is perfectly
+                        * legitimate from a remote override oper.
                        if(!override)
                                return;
+                       */
                }
 
                mode_changes[mode_count].letter = c;
@@ -1068,8 +1091,11 @@ chm_op(struct Client *source_p, struct Channel *chptr,
                if(targ_p == source_p)
                {
                        no_override_deop = 1;
+                       /* Don't reject modes from remote. It desyncs, and this is perfectly
+                        * legitimate from a remote override oper.
                        if(!override)
                                return;
+                       */
                }
 
                mode_changes[mode_count].letter = c;
@@ -1178,8 +1204,11 @@ chm_halfop(struct Client *source_p, struct Channel *chptr,
                if(targ_p == source_p)
                {
                        no_override_deop = 1;
+                       /* Don't reject modes from remote. It desyncs, and this is perfectly
+                        * legitimate from a remote override oper.
                        if(!override)
                                return;
+                       */
                }
 
                mode_changes[mode_count].letter = c;
@@ -2052,7 +2081,9 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
                                  source_p->name, source_p->username,
                                  source_p->host, chptr->chname);
 
-       for (override = 0; override < (IsOverride(source_p) ? 2 : 1); ++override)
+       mlen = 0;
+
+       for (override = 0; override < (IsOverride(source_p) && alevel != CHFL_CHANOP ? 2 : 1); ++override)
        {
                int was_on_chan = 0;
 
@@ -2079,6 +2110,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
                        for(i = 0; i < mode_count; i++)
                        {
                                if(mode_changes[i].letter == 0 || mode_changes[i].mems != flags)
+                                       continue;
 
                                if(mode_changes[i].override != override)
                                        continue;
@@ -2097,15 +2129,15 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
                                 * bufsize (4 == +/-,modechar,two spaces) send now.
                                 */
                                if(mode_changes[i].arg != NULL &&
-                                               ((paracount == MAXMODEPARAMSSERV) ||
-                                                ((cur_len + paralen + arglen + 4) > (BUFSIZE - 3))))
+                                  ((paracount == MAXMODEPARAMSSERV) ||
+                                   ((cur_len + paralen + arglen + 4) > (BUFSIZE - 3))))
                                {
                                        *mbuf = '\0';
 
                                        if(cur_len > mlen)
                                        {
                                                sendto_channel_local(flags, chptr, "%s%s %s",
-                                                               cmdbuf, modebuf, parabuf);
+                                                                    cmdbuf, modebuf, parabuf);
                                                if(override)
                                                        sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
                                                                        "%s is overriding modes on %s: %s %s",
@@ -2142,16 +2174,30 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
                                }
                        }
 
-                       if(override)
+                       if(paralen && parabuf[paralen - 1] == ' ')
+                               parabuf[paralen - 1] = '\0';
+
+                       *mbuf = '\0';
+                       if(cur_len > mlen)
                        {
-                               if(!was_on_chan)
-                                       remove_user_from_channel(find_channel_membership(chptr, source_p));
-                               else if (!no_override_deop)
-                                       msptr->flags &= ~CHFL_CHANOP;
+                               sendto_channel_local(flags, chptr, "%s%s %s", cmdbuf, modebuf, parabuf);
+                               if(override)
+                                       sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+                                                       "%s is overriding modes on %s: %s %s",
+                                                       get_oper_name(source_p), chptr->chname,
+                                                       modebuf, parabuf);
                        }
+               }
+               if(override)
+               {
+                       if(!was_on_chan)
+                               remove_user_from_channel(find_channel_membership(chptr, source_p));
+                       else if (!no_override_deop)
+                               msptr->flags &= ~CHFL_CHANOP;
+               }
        }
+
        /* only propagate modes originating locally, or if we're hubbing */
        if(MyClient(source_p) || rb_dlink_list_length(&serv_list) > 1)
                send_cap_mode_changes(client_p, source_p, chptr, mode_changes, mode_count);
-       }
 }