]> jfr.im git - solanum.git/blobdiff - ircd/chmode.c
extensions/helpops: implement DEHELPER command
[solanum.git] / ircd / chmode.c
index 4cf3cb5c698a35f8a6650671610d5d91f92b99af..127494ee5bb25bf1e44eae3f2811d3cdced7753d 100644 (file)
@@ -43,6 +43,7 @@
 #include "logger.h"
 #include "chmode.h"
 #include "s_assert.h"
+#include "parse.h"
 
 /* bitmasks for error returns, so we send once per call */
 #define SM_ERR_NOTS             0x00000001     /* No TS on channel */
@@ -179,22 +180,20 @@ cflag_orphan(char c_)
 }
 
 int
-get_channel_access(struct Client *source_p, struct membership *msptr, int dir)
+get_channel_access(struct Client *source_p, struct Channel *chptr, struct membership *msptr, int dir, const char *modestr)
 {
        hook_data_channel_approval moduledata;
 
        if(!MyClient(source_p))
                return CHFL_CHANOP;
 
-       if (msptr == NULL)
-               return CHFL_PEON;
-
        moduledata.client = source_p;
-       moduledata.chptr = msptr->chptr;
+       moduledata.chptr = chptr;
        moduledata.msptr = msptr;
        moduledata.target = NULL;
-       moduledata.approved = is_chanop(msptr) ? CHFL_CHANOP : CHFL_PEON;
+       moduledata.approved = (msptr != NULL && is_chanop(msptr)) ? CHFL_CHANOP : CHFL_PEON;
        moduledata.dir = dir;
+       moduledata.modestr = modestr;
 
        call_hook(h_get_channel_access, &moduledata);
 
@@ -519,7 +518,7 @@ check_forward(struct Client *source_p, struct Channel *chptr,
        if(MyClient(source_p) && !(targptr->mode.mode & MODE_FREETARGET))
        {
                if((msptr = find_channel_membership(targptr, source_p)) == NULL ||
-                       get_channel_access(source_p, msptr, MODE_QUERY) != CHFL_CHANOP)
+                       get_channel_access(source_p, targptr, msptr, MODE_QUERY, NULL) != CHFL_CHANOP)
                {
                        sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                                   me.name, source_p->name, targptr->chname);
@@ -659,6 +658,53 @@ chm_orphaned(struct Client *source_p, struct Channel *chptr,
        }
 }
 
+void
+chm_hidden(struct Client *source_p, struct Channel *chptr,
+         int alevel, int parc, int *parn,
+         const char **parv, int *errors, int dir, char c, long mode_type)
+{
+       if(!IsOper(source_p) && !IsServer(source_p))
+       {
+               if(!(*errors & SM_ERR_NOPRIVS))
+                       sendto_one_numeric(source_p, ERR_NOPRIVILEGES, form_str(ERR_NOPRIVILEGES));
+               *errors |= SM_ERR_NOPRIVS;
+               return;
+       }
+       if(MyClient(source_p) && !IsOperAdmin(source_p))
+       {
+               if(!(*errors & SM_ERR_NOPRIVS))
+                       sendto_one(source_p, form_str(ERR_NOPRIVS), me.name,
+                                       source_p->name, "admin");
+               *errors |= SM_ERR_NOPRIVS;
+               return;
+       }
+
+       if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE))
+               return;
+
+       /* setting + */
+       if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type))
+       {
+               chptr->mode.mode |= mode_type;
+
+               mode_changes[mode_count].letter = c;
+               mode_changes[mode_count].dir = MODE_ADD;
+               mode_changes[mode_count].id = NULL;
+               mode_changes[mode_count].mems = ONLY_OPERS;
+               mode_changes[mode_count++].arg = NULL;
+       }
+       else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type))
+       {
+               chptr->mode.mode &= ~mode_type;
+
+               mode_changes[mode_count].letter = c;
+               mode_changes[mode_count].dir = MODE_DEL;
+               mode_changes[mode_count].mems = ONLY_OPERS;
+               mode_changes[mode_count].id = NULL;
+               mode_changes[mode_count++].arg = NULL;
+       }
+}
+
 void
 chm_staff(struct Client *source_p, struct Channel *chptr,
          int alevel, int parc, int *parn,
@@ -1642,6 +1688,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
        char c;
        struct Client *fakesource_p;
        int reauthorized = 0;   /* if we change from MODE_QUERY to MODE_ADD/MODE_DEL, then reauth once, ugly but it works */
+       int flags_list[3] = { ALL_MEMBERS, ONLY_CHANOPS, ONLY_OPERS };
 
        mask_pos = 0;
        removed_mask_pos = 0;
@@ -1655,7 +1702,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
        else
                fakesource_p = source_p;
 
-       alevel = get_channel_access(source_p, msptr, dir);
+       alevel = get_channel_access(source_p, chptr, msptr, dir, reconstruct_parv(parc, parv));
 
        for(; (c = *ml) != 0; ml++)
        {
@@ -1665,7 +1712,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
                        dir = MODE_ADD;
                        if (!reauthorized)
                        {
-                               alevel = get_channel_access(source_p, msptr, dir);
+                               alevel = get_channel_access(source_p, chptr, msptr, dir, reconstruct_parv(parc, parv));
                                reauthorized = 1;
                        }
                        break;
@@ -1673,7 +1720,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
                        dir = MODE_DEL;
                        if (!reauthorized)
                        {
-                               alevel = get_channel_access(source_p, msptr, dir);
+                               alevel = get_channel_access(source_p, chptr, msptr, dir, reconstruct_parv(parc, parv));
                                reauthorized = 1;
                        }
                        break;
@@ -1700,7 +1747,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
                                  source_p->name, source_p->username,
                                  source_p->host, chptr->chname);
 
-       for(j = 0, flags = ALL_MEMBERS; j < 2; j++, flags = ONLY_CHANOPS)
+       for(j = 0, flags = flags_list[0]; j < 3; j++, flags = flags_list[j])
        {
                cur_len = mlen;
                mbuf = modebuf + mlen;