From b860ad5ffac21b14e916555b53cde304df08c304 Mon Sep 17 00:00:00 2001 From: Ed Kellett Date: Mon, 30 Nov 2020 09:24:32 +0000 Subject: [PATCH] chmode: end the grace period more intelligently (#84) We were ending the flood grace period for any channel mode command other than `MODE #foo [bq]` by means of a hardcoded check. I've moved that to after we parse the mode string, so we can correctly identify all requests to change modes and end the grace period on exactly those. It would have been entirely possible to move the check even further down and flood_endgrace on only mode commands that *actually* change modes, but I don't like the idea of making it sensitive to external conditions. --- ircd/chmode.c | 19 +++++++++++++++---- modules/core/m_mode.c | 7 ------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/ircd/chmode.c b/ircd/chmode.c index ae3268eb..5eb384a9 100644 --- a/ircd/chmode.c +++ b/ircd/chmode.c @@ -42,6 +42,7 @@ #include "s_assert.h" #include "parse.h" #include "msgbuf.h" +#include "packet.h" /* bitmasks for error returns, so we send once per call */ #define SM_ERR_NOTS 0x00000001 /* No TS on channel */ @@ -1363,7 +1364,8 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, int cur_len, mlen, paralen, paracount, arglen, len; int i, j, flags; int dir = MODE_ADD; - int access_dir = MODE_QUERY; + bool changes = false; + bool privileged_query = false; int parn = 1; int errors = 0; int alevel; @@ -1452,10 +1454,10 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, *mbuf++ = c; - if (effective_dir != MODE_QUERY && access_dir == MODE_QUERY) - access_dir = effective_dir; + if (effective_dir != MODE_QUERY) + changes = true; if (effective_dir == MODE_QUERY && cm->flags & CHM_OPS_QUERY) - access_dir = MODE_OP_QUERY; + privileged_query = true; ms->cm = cm; ms->dir = effective_dir; @@ -1481,6 +1483,12 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, /* XXX we could reject excess params here */ } + /* Finish the flood grace period if we were asked to do anything */ + if (changes && MyClient(source_p) && !IsFloodDone(source_p)) + { + flood_endgrace(source_p); + } + mend = ms; if (parn > 1) @@ -1492,6 +1500,9 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, { *mbuf = '\0'; } + int access_dir = privileged_query ? MODE_OP_QUERY : + changes ? MODE_ADD : + MODE_QUERY; alevel = get_channel_access(source_p, chptr, msptr, access_dir, modebuf); for (ms = modesets; ms < mend; ms++) diff --git a/modules/core/m_mode.c b/modules/core/m_mode.c index 61f0ee3b..ab054fd8 100644 --- a/modules/core/m_mode.c +++ b/modules/core/m_mode.c @@ -138,13 +138,6 @@ m_mode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p { msptr = find_channel_membership(chptr, source_p); - /* Finish the flood grace period... */ - if(MyClient(source_p) && !IsFloodDone(source_p)) - { - if(!((parc == 3) && (parv[2][0] == 'b' || parv[2][0] == 'q') && (parv[2][1] == '\0'))) - flood_endgrace(source_p); - } - set_channel_mode(client_p, source_p, chptr, msptr, parc - n, parv + n); } }