Initial support for 'noisy' oper-override of channel modes, using omode-type code. Supports simple modes at present.
This commit is contained in:
parent
08e35f665f
commit
eccd1c58d2
|
@ -114,6 +114,7 @@ struct ChModeChange
|
||||||
int caps;
|
int caps;
|
||||||
int nocaps;
|
int nocaps;
|
||||||
int mems;
|
int mems;
|
||||||
|
int override;
|
||||||
struct Client *client;
|
struct Client *client;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
177
src/chmode.c
177
src/chmode.c
|
@ -498,13 +498,21 @@ chm_simple(struct Client *source_p, struct Channel *chptr,
|
||||||
int alevel, int parc, int *parn,
|
int alevel, int parc, int *parn,
|
||||||
const char **parv, int *errors, int dir, char c, long mode_type)
|
const char **parv, int *errors, int dir, char c, long mode_type)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int override = 0;
|
||||||
|
|
||||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||||
{
|
{
|
||||||
if(!(*errors & SM_ERR_NOOPS))
|
if (IsOverride(source_p))
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
override = 1;
|
||||||
me.name, source_p->name, chptr->chname);
|
else
|
||||||
*errors |= SM_ERR_NOOPS;
|
{
|
||||||
return;
|
if(!(*errors & SM_ERR_NOOPS))
|
||||||
|
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||||
|
me.name, source_p->name, chptr->chname);
|
||||||
|
*errors |= SM_ERR_NOOPS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE))
|
if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE))
|
||||||
|
@ -526,6 +534,7 @@ chm_simple(struct Client *source_p, struct Channel *chptr,
|
||||||
mode_changes[mode_count].nocaps = 0;
|
mode_changes[mode_count].nocaps = 0;
|
||||||
mode_changes[mode_count].id = NULL;
|
mode_changes[mode_count].id = NULL;
|
||||||
mode_changes[mode_count].mems = ALL_MEMBERS;
|
mode_changes[mode_count].mems = ALL_MEMBERS;
|
||||||
|
mode_changes[mode_count].override = override;
|
||||||
mode_changes[mode_count++].arg = NULL;
|
mode_changes[mode_count++].arg = NULL;
|
||||||
}
|
}
|
||||||
else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type))
|
else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type))
|
||||||
|
@ -538,6 +547,7 @@ chm_simple(struct Client *source_p, struct Channel *chptr,
|
||||||
mode_changes[mode_count].nocaps = 0;
|
mode_changes[mode_count].nocaps = 0;
|
||||||
mode_changes[mode_count].mems = ALL_MEMBERS;
|
mode_changes[mode_count].mems = ALL_MEMBERS;
|
||||||
mode_changes[mode_count].id = NULL;
|
mode_changes[mode_count].id = NULL;
|
||||||
|
mode_changes[mode_count].override = override;
|
||||||
mode_changes[mode_count++].arg = NULL;
|
mode_changes[mode_count++].arg = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1813,12 +1823,13 @@ void
|
||||||
set_channel_mode(struct Client *client_p, struct Client *source_p,
|
set_channel_mode(struct Client *client_p, struct Client *source_p,
|
||||||
struct Channel *chptr, struct membership *msptr, int parc, const char *parv[])
|
struct Channel *chptr, struct membership *msptr, int parc, const char *parv[])
|
||||||
{
|
{
|
||||||
|
static char cmdbuf[BUFSIZE];
|
||||||
static char modebuf[BUFSIZE];
|
static char modebuf[BUFSIZE];
|
||||||
static char parabuf[BUFSIZE];
|
static char parabuf[BUFSIZE];
|
||||||
char *mbuf;
|
char *mbuf;
|
||||||
char *pbuf;
|
char *pbuf;
|
||||||
int cur_len, mlen, paralen, paracount, arglen, len;
|
int cur_len, mlen, paralen, paracount, arglen, len;
|
||||||
int i, j, flags;
|
int i, j, flags, override;
|
||||||
int dir = MODE_ADD;
|
int dir = MODE_ADD;
|
||||||
int parn = 1;
|
int parn = 1;
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
@ -1867,87 +1878,103 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(IsServer(source_p))
|
if(IsServer(source_p))
|
||||||
mlen = rb_sprintf(modebuf, ":%s MODE %s ", fakesource_p->name, chptr->chname);
|
rb_sprintf(cmdbuf, ":%s MODE %s ", fakesource_p->name, chptr->chname);
|
||||||
else
|
else
|
||||||
mlen = rb_sprintf(modebuf, ":%s!%s@%s MODE %s ",
|
rb_sprintf(cmdbuf, ":%s!%s@%s MODE %s ",
|
||||||
source_p->name, source_p->username,
|
source_p->name, source_p->username,
|
||||||
source_p->host, chptr->chname);
|
source_p->host, chptr->chname);
|
||||||
|
|
||||||
for(j = 0, flags = ALL_MEMBERS; j < 2; j++, flags = ONLY_CHANOPS)
|
for (override = 0; override < (IsOverride(source_p) ? 2 : 1); ++override)
|
||||||
{
|
{
|
||||||
cur_len = mlen;
|
int was_on_chan = 0;
|
||||||
mbuf = modebuf + mlen;
|
if(override)
|
||||||
pbuf = parabuf;
|
|
||||||
parabuf[0] = '\0';
|
|
||||||
paracount = paralen = 0;
|
|
||||||
dir = MODE_QUERY;
|
|
||||||
|
|
||||||
for(i = 0; i < mode_count; i++)
|
|
||||||
{
|
{
|
||||||
if(mode_changes[i].letter == 0 || mode_changes[i].mems != flags)
|
if(msptr)
|
||||||
continue;
|
was_on_chan = 1;
|
||||||
|
|
||||||
if(mode_changes[i].arg != NULL)
|
|
||||||
{
|
|
||||||
arglen = strlen(mode_changes[i].arg);
|
|
||||||
|
|
||||||
if(arglen > MODEBUFLEN - 5)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
arglen = 0;
|
add_user_to_channel(chptr, source_p, 0);
|
||||||
|
|
||||||
/* if we're creeping over MAXMODEPARAMSSERV, or over
|
|
||||||
* bufsize (4 == +/-,modechar,two spaces) send now.
|
|
||||||
*/
|
|
||||||
if(mode_changes[i].arg != NULL &&
|
|
||||||
((paracount == MAXMODEPARAMSSERV) ||
|
|
||||||
((cur_len + paralen + arglen + 4) > (BUFSIZE - 3))))
|
|
||||||
{
|
|
||||||
*mbuf = '\0';
|
|
||||||
|
|
||||||
if(cur_len > mlen)
|
|
||||||
sendto_channel_local(flags, chptr, "%s %s", modebuf,
|
|
||||||
parabuf);
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
paracount = paralen = 0;
|
|
||||||
cur_len = mlen;
|
|
||||||
mbuf = modebuf + mlen;
|
|
||||||
pbuf = parabuf;
|
|
||||||
parabuf[0] = '\0';
|
|
||||||
dir = MODE_QUERY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dir != mode_changes[i].dir)
|
|
||||||
{
|
|
||||||
*mbuf++ = (mode_changes[i].dir == MODE_ADD) ? '+' : '-';
|
|
||||||
cur_len++;
|
|
||||||
dir = mode_changes[i].dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
*mbuf++ = mode_changes[i].letter;
|
|
||||||
cur_len++;
|
|
||||||
|
|
||||||
if(mode_changes[i].arg != NULL)
|
|
||||||
{
|
|
||||||
paracount++;
|
|
||||||
len = rb_sprintf(pbuf, "%s ", mode_changes[i].arg);
|
|
||||||
pbuf += len;
|
|
||||||
paralen += len;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(paralen && parabuf[paralen - 1] == ' ')
|
for(j = 0, flags = ALL_MEMBERS; j < 2; j++, flags = ONLY_CHANOPS)
|
||||||
parabuf[paralen - 1] = '\0';
|
{
|
||||||
|
cur_len = mlen;
|
||||||
|
mbuf = modebuf + mlen;
|
||||||
|
pbuf = parabuf;
|
||||||
|
parabuf[0] = '\0';
|
||||||
|
paracount = paralen = 0;
|
||||||
|
dir = MODE_QUERY;
|
||||||
|
|
||||||
*mbuf = '\0';
|
for(i = 0; i < mode_count; i++)
|
||||||
if(cur_len > mlen)
|
{
|
||||||
sendto_channel_local(flags, chptr, "%s %s", modebuf, parabuf);
|
if(mode_changes[i].letter == 0 || mode_changes[i].mems != flags)
|
||||||
|
|
||||||
|
if(mode_changes[i].override != override)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(mode_changes[i].arg != NULL)
|
||||||
|
{
|
||||||
|
arglen = strlen(mode_changes[i].arg);
|
||||||
|
|
||||||
|
if(arglen > MODEBUFLEN - 5)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
arglen = 0;
|
||||||
|
|
||||||
|
/* if we're creeping over MAXMODEPARAMSSERV, or over
|
||||||
|
* bufsize (4 == +/-,modechar,two spaces) send now.
|
||||||
|
*/
|
||||||
|
if(mode_changes[i].arg != NULL &&
|
||||||
|
((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);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
paracount = paralen = 0;
|
||||||
|
cur_len = mlen;
|
||||||
|
mbuf = modebuf + mlen;
|
||||||
|
pbuf = parabuf;
|
||||||
|
parabuf[0] = '\0';
|
||||||
|
dir = MODE_QUERY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dir != mode_changes[i].dir)
|
||||||
|
{
|
||||||
|
*mbuf++ = (mode_changes[i].dir == MODE_ADD) ? '+' : '-';
|
||||||
|
cur_len++;
|
||||||
|
dir = mode_changes[i].dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
*mbuf++ = mode_changes[i].letter;
|
||||||
|
cur_len++;
|
||||||
|
|
||||||
|
if(mode_changes[i].arg != NULL)
|
||||||
|
{
|
||||||
|
paracount++;
|
||||||
|
len = rb_sprintf(pbuf, "%s ", mode_changes[i].arg);
|
||||||
|
pbuf += len;
|
||||||
|
paralen += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(override && !was_on_chan)
|
||||||
|
remove_user_from_channel(find_channel_membership(chptr, source_p));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only propagate modes originating locally, or if we're hubbing */
|
/* only propagate modes originating locally, or if we're hubbing */
|
||||||
if(MyClient(source_p) || rb_dlink_list_length(&serv_list) > 1)
|
if(MyClient(source_p) || rb_dlink_list_length(&serv_list) > 1)
|
||||||
send_cap_mode_changes(client_p, source_p, chptr, mode_changes, mode_count);
|
send_cap_mode_changes(client_p, source_p, chptr, mode_changes, mode_count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue