summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2021-02-25 06:47:34 +0000
committerSadie Powell <sadie@witchery.services>2021-02-25 06:47:34 +0000
commit61225fa14fe0c8335cbfec7a9764cfc3f31936bc (patch)
tree418806aa12a092e2ccb86ba43a20db24b87dba7e
parent5860247c3bf664daac1234f47f68ed30402fe13d (diff)
Allow a statusmsg to have multiple statuses and pick the lowest.
This is pretty much useless but other implementations support it so we have to also support it for compatibility.
-rw-r--r--include/numerics.h1
-rw-r--r--src/coremods/core_message.cpp21
-rw-r--r--src/modules/m_ircv3_ctctags.cpp21
3 files changed, 33 insertions, 10 deletions
diff --git a/include/numerics.h b/include/numerics.h
index 98abf2bbe..a50b7c518 100644
--- a/include/numerics.h
+++ b/include/numerics.h
@@ -114,6 +114,7 @@ enum
ERR_TOOMANYCHANNELS = 405,
ERR_WASNOSUCHNICK = 406,
ERR_NOSUCHSERVICE = 408, // From RFC 2812.
+ ERR_NORECIPIENT = 411,
ERR_NOTEXTTOSEND = 412,
ERR_UNKNOWNCOMMAND = 421,
ERR_NOMOTD = 422,
diff --git a/src/coremods/core_message.cpp b/src/coremods/core_message.cpp
index 75abd6900..94eefee22 100644
--- a/src/coremods/core_message.cpp
+++ b/src/coremods/core_message.cpp
@@ -298,15 +298,26 @@ class CommandMessage : public Command
if (parameters[0][0] == '$')
return HandleServerTarget(user, parameters);
- // If the message begins with a status character then look it up.
+ // If the message begins with one or more status characters then look them up.
const char* target = parameters[0].c_str();
- PrefixMode* pmh = ServerInstance->Modes->FindPrefix(target[0]);
- if (pmh)
- target++;
+ PrefixMode* targetpfx = NULL;
+ for (PrefixMode* pfx; (pfx = ServerInstance->Modes->FindPrefix(target[0])); ++target)
+ {
+ // We want the lowest ranked prefix specified.
+ if (!targetpfx || pfx->GetPrefixRank() < targetpfx->GetPrefixRank())
+ targetpfx = pfx;
+ }
+
+ if (!target[0])
+ {
+ // The target consisted solely of prefix modes.
+ user->WriteNumeric(ERR_NORECIPIENT, "No recipient given");
+ return CMD_FAILURE;
+ }
// The target is a channel name.
if (*target == '#')
- return HandleChannelTarget(user, parameters, target, pmh);
+ return HandleChannelTarget(user, parameters, target, targetpfx);
// The target is a nickname.
return HandleUserTarget(user, parameters);
diff --git a/src/modules/m_ircv3_ctctags.cpp b/src/modules/m_ircv3_ctctags.cpp
index 285657987..6ef1ed30d 100644
--- a/src/modules/m_ircv3_ctctags.cpp
+++ b/src/modules/m_ircv3_ctctags.cpp
@@ -234,15 +234,26 @@ class CommandTagMsg : public Command
if (parameters[0][0] == '$')
return HandleServerTarget(user, parameters);
- // If the message begins with a status character then look it up.
+ // If the message begins with one or more status characters then look them up.
const char* target = parameters[0].c_str();
- PrefixMode* pmh = ServerInstance->Modes->FindPrefix(target[0]);
- if (pmh)
- target++;
+ PrefixMode* targetpfx = NULL;
+ for (PrefixMode* pfx; (pfx = ServerInstance->Modes->FindPrefix(target[0])); ++target)
+ {
+ // We want the lowest ranked prefix specified.
+ if (!targetpfx || pfx->GetPrefixRank() < targetpfx->GetPrefixRank())
+ targetpfx = pfx;
+ }
+
+ if (!target[0])
+ {
+ // The target consisted solely of prefix modes.
+ user->WriteNumeric(ERR_NORECIPIENT, "No recipient given");
+ return CMD_FAILURE;
+ }
// The target is a channel name.
if (*target == '#')
- return HandleChannelTarget(user, parameters, target, pmh);
+ return HandleChannelTarget(user, parameters, target, targetpfx);
// The target is a nickname.
return HandleUserTarget(user, parameters);