#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 */
}
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);
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);
}
}
+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,
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;
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++)
{
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;
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;
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;