summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2021-02-25 20:06:46 +0000
committerSadie Powell <sadie@witchery.services>2021-02-25 20:10:34 +0000
commit0db24252fd119cafee34f1bfa023763fcdd7ebf5 (patch)
treec71033314cc0d94c226eb087b1e535709019878c
parent61225fa14fe0c8335cbfec7a9764cfc3f31936bc (diff)
Implement support for multi-prefix on WHOIS.
-rw-r--r--include/modules/whois.h16
-rw-r--r--src/coremods/core_whois.cpp16
-rw-r--r--src/modules/m_namesx.cpp47
3 files changed, 63 insertions, 16 deletions
diff --git a/include/modules/whois.h b/include/modules/whois.h
index f158f82cc..c081a2b6a 100644
--- a/include/modules/whois.h
+++ b/include/modules/whois.h
@@ -28,6 +28,22 @@ namespace Whois
class Context;
}
+enum
+{
+ // From RFC 1459.
+ RPL_WHOISUSER = 311,
+ RPL_WHOISOPERATOR = 313,
+ RPL_WHOISIDLE = 317,
+ RPL_WHOISCHANNELS = 319,
+
+ // From UnrealIRCd.
+ RPL_WHOISHOST = 378,
+ RPL_WHOISMODES = 379,
+
+ // InspIRCd-specific.
+ RPL_CHANNELSMSG = 651
+};
+
class Whois::EventListener : public Events::ModuleEventListener
{
public:
diff --git a/src/coremods/core_whois.cpp b/src/coremods/core_whois.cpp
index bd0502998..c1c4777ef 100644
--- a/src/coremods/core_whois.cpp
+++ b/src/coremods/core_whois.cpp
@@ -30,22 +30,6 @@
#include "inspircd.h"
#include "modules/whois.h"
-enum
-{
- // From RFC 1459.
- RPL_WHOISUSER = 311,
- RPL_WHOISOPERATOR = 313,
- RPL_WHOISIDLE = 317,
- RPL_WHOISCHANNELS = 319,
-
- // From UnrealIRCd.
- RPL_WHOISHOST = 378,
- RPL_WHOISMODES = 379,
-
- // InspIRCd-specific.
- RPL_CHANNELSMSG = 651
-};
-
enum SplitWhoisState
{
// Don't split private/secret channels into a separate RPL_WHOISCHANNELS numeric.
diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp
index 4f93da21a..ed983b32d 100644
--- a/src/modules/m_namesx.cpp
+++ b/src/modules/m_namesx.cpp
@@ -27,11 +27,13 @@
#include "modules/cap.h"
#include "modules/names.h"
#include "modules/who.h"
+#include "modules/whois.h"
class ModuleNamesX
: public Module
, public Names::EventListener
, public Who::EventListener
+ , public Whois::LineEventListener
{
private:
Cap::Capability cap;
@@ -40,6 +42,7 @@ class ModuleNamesX
ModuleNamesX()
: Names::EventListener(this)
, Who::EventListener(this)
+ , Whois::LineEventListener(this)
, cap(this, "multi-prefix")
{
}
@@ -104,6 +107,50 @@ class ModuleNamesX
numeric.GetParams()[flag_index].append(prefixes, 1, std::string::npos);
return MOD_RES_PASSTHRU;
}
+
+ ModResult OnWhoisLine(Whois::Context& whois, Numeric::Numeric& numeric) CXX11_OVERRIDE
+ {
+ if (numeric.GetNumeric() != RPL_WHOISCHANNELS || !cap.get(whois.GetSource()))
+ return MOD_RES_PASSTHRU;
+
+ // :testnet.inspircd.org 319 test Sadie :#test ~#inspircd
+ if (numeric.GetParams().size() < 2 || numeric.GetParams().back().empty())
+ return MOD_RES_PASSTHRU;
+
+ std::stringstream newchannels;
+ irc::spacesepstream channelstream(numeric.GetParams().back());
+ for (std::string channel; channelstream.GetToken(channel); )
+ {
+ size_t hashpos = channel.find('#');
+ if (!hashpos || hashpos == std::string::npos)
+ {
+ // The entry is malformed or the user has no privs.
+ newchannels << channel << ' ';
+ continue;
+ }
+
+ Channel* chan = ServerInstance->FindChan(channel.substr(hashpos));
+ if (!chan)
+ {
+ // Should never happen.
+ newchannels << channel << ' ';
+ continue;
+ }
+
+ Membership* memb = chan->GetUser(whois.GetTarget());
+ if (!memb)
+ {
+ // Should never happen.
+ newchannels << channel << ' ';
+ continue;
+ }
+
+ newchannels << memb->GetAllPrefixChars() << chan->name << ' ';
+ }
+
+ numeric.GetParams().back() = newchannels.str();
+ return MOD_RES_PASSTHRU;
+ }
};
MODULE_INIT(ModuleNamesX)