summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2020-03-12 17:27:11 +0000
committerSadie Powell <sadie@witchery.services>2020-03-12 17:51:03 +0000
commit1efc234a54bd66714f9743ca7d1f3d5c0be3628e (patch)
treeb352bf8c30f8fea17f6be2b17d0a74fe97fa61da
parent906e44f687185f6507cba95ec1b565de4936eb03 (diff)
Implement support for the SERVLIST command.
-rw-r--r--include/moduledefs.h2
-rw-r--r--include/usermanager.h11
-rw-r--r--src/coremods/core_info/cmd_servlist.cpp59
-rw-r--r--src/coremods/core_info/core_info.cpp4
-rw-r--r--src/coremods/core_info/core_info.h10
-rw-r--r--src/usermanager.cpp1
-rw-r--r--src/users.cpp6
7 files changed, 83 insertions, 10 deletions
diff --git a/include/moduledefs.h b/include/moduledefs.h
index 9f54e3eeb..a706a8883 100644
--- a/include/moduledefs.h
+++ b/include/moduledefs.h
@@ -22,7 +22,7 @@
class Module;
/** The version of the InspIRCd ABI which is presently in use. */
-#define MODULE_ABI 3011UL
+#define MODULE_ABI 3012UL
/** Stringifies the value of a symbol. */
#define MODULE_STRINGIFY_SYM1(DEF) MODULE_STRINGIFY_SYM2(DEF)
diff --git a/include/usermanager.h b/include/usermanager.h
index ad09d968c..2a18393ab 100644
--- a/include/usermanager.h
+++ b/include/usermanager.h
@@ -46,6 +46,9 @@ class CoreExport UserManager : public fakederef<UserManager>
*/
typedef std::vector<User*> OperList;
+ /** A list containing users who are on a U-lined servers. */
+ typedef std::vector<User*> ULineList;
+
/** A list holding local users
*/
typedef insp::intrusive_list<LocalUser> LocalList;
@@ -89,14 +92,14 @@ class CoreExport UserManager : public fakederef<UserManager>
*/
OperList all_opers;
+ /** A list of users on U-lined servers. */
+ ULineList all_ulines;
+
/** Number of unregistered users online right now.
* (Unregistered means before USER/NICK/dns)
*/
unsigned int unregistered_count;
- /** The number of users on U-lined servers. */
- unsigned int uline_count;
-
/** Perform background user events for all local users such as PING checks, registration timeouts,
* penalty management and recvq processing for users who have data in their recvq due to throttling.
*/
@@ -175,7 +178,7 @@ class CoreExport UserManager : public fakederef<UserManager>
/** Return a count of users on a u-lined servers.
* @return The number of users on u-lined servers.
*/
- unsigned int ULineCount() const { return this->uline_count; }
+ unsigned int ULineCount() const { return this->all_ulines.size(); }
/** Return a count of local registered users
* @return The number of registered local users
diff --git a/src/coremods/core_info/cmd_servlist.cpp b/src/coremods/core_info/cmd_servlist.cpp
new file mode 100644
index 000000000..f400124d2
--- /dev/null
+++ b/src/coremods/core_info/cmd_servlist.cpp
@@ -0,0 +1,59 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2020 Sadie Powell <sadie@witchery.services>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "core_info.h"
+
+enum
+{
+ // From RFC 2812.
+ RPL_SERVLIST = 234,
+ RPL_SERVLISTEND = 235
+};
+
+CommandServList::CommandServList(Module* parent)
+ : SplitCommand(parent, "SERVLIST")
+ , invisiblemode(parent, "invisible")
+{
+ allow_empty_last_param = false;
+ syntax = "[<mask>]";
+}
+
+CmdResult CommandServList::HandleLocal(LocalUser* user, const Params& parameters)
+{
+ const std::string& mask = parameters.empty() ? "*" : parameters[0];
+ for (UserManager::ULineList::const_iterator iter = ServerInstance->Users.all_ulines.begin(); iter != ServerInstance->Users.all_ulines.end(); ++iter)
+ {
+ User* uline = *iter;
+ if (uline->IsModeSet(invisiblemode) || !InspIRCd::Match(uline->nick, mask))
+ continue;
+
+ Numeric::Numeric numeric(RPL_SERVLIST);
+ numeric
+ .push(uline->nick)
+ .push(uline->server->GetName())
+ .push(mask)
+ .push(0)
+ .push(0)
+ .push(uline->GetRealName());
+ user->WriteNumeric(numeric);
+ }
+ user->WriteNumeric(RPL_SERVLISTEND, mask, 0, "End of service listing");
+ return CMD_SUCCESS;
+}
diff --git a/src/coremods/core_info/core_info.cpp b/src/coremods/core_info/core_info.cpp
index 507e43250..b172372e5 100644
--- a/src/coremods/core_info/core_info.cpp
+++ b/src/coremods/core_info/core_info.cpp
@@ -46,6 +46,7 @@ class CoreModInfo : public Module
CommandInfo cmdinfo;
CommandModules cmdmodules;
CommandMotd cmdmotd;
+ CommandServList cmdservlist;
CommandTime cmdtime;
CommandVersion cmdversion;
Numeric::Numeric numeric004;
@@ -91,6 +92,7 @@ class CoreModInfo : public Module
, cmdinfo(this)
, cmdmodules(this)
, cmdmotd(this)
+ , cmdservlist(this)
, cmdtime(this)
, cmdversion(this)
, numeric004(RPL_MYINFO)
@@ -176,7 +178,7 @@ class CoreModInfo : public Module
Version GetVersion() CXX11_OVERRIDE
{
- return Version("Provides the ADMIN, COMMANDS, INFO, MODULES, MOTD, TIME, and VERSION commands", VF_VENDOR|VF_CORE);
+ return Version("Provides the ADMIN, COMMANDS, INFO, MODULES, MOTD, TIME, SERVLIST, and VERSION commands", VF_VENDOR|VF_CORE);
}
};
diff --git a/src/coremods/core_info/core_info.h b/src/coremods/core_info/core_info.h
index 08aab4cd1..ecd4f78e7 100644
--- a/src/coremods/core_info/core_info.h
+++ b/src/coremods/core_info/core_info.h
@@ -137,6 +137,16 @@ class CommandMotd : public ServerTargetCommand
CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE;
};
+class CommandServList : public SplitCommand
+{
+ private:
+ UserModeReference invisiblemode;
+
+ public:
+ CommandServList(Module* parent);
+ CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE;
+};
+
/** Handle /TIME.
*/
class CommandTime : public ServerTargetCommand
diff --git a/src/usermanager.cpp b/src/usermanager.cpp
index 9c8bde1e2..812f43113 100644
--- a/src/usermanager.cpp
+++ b/src/usermanager.cpp
@@ -119,7 +119,6 @@ namespace
UserManager::UserManager()
: already_sent_id(0)
, unregistered_count(0)
- , uline_count(0)
{
}
diff --git a/src/users.cpp b/src/users.cpp
index 0c95ecc0b..2571d15f2 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -91,7 +91,7 @@ User::User(const std::string& uid, Server* srv, UserType type)
ServerInstance->Logs->Log("USERS", LOG_DEBUG, "New UUID for user: %s", uuid.c_str());
if (srv->IsULine())
- ServerInstance->Users->uline_count++;
+ ServerInstance->Users.all_ulines.push_back(this);
// Do not insert FakeUsers into the uuidlist so FindUUID() won't return them which is the desired behavior
if (type != USERTYPE_SERVER)
@@ -354,8 +354,8 @@ CullResult User::cull()
if (client_sa.family() != AF_UNSPEC)
ServerInstance->Users->RemoveCloneCounts(this);
- if (server->IsULine() && ServerInstance->Users->uline_count)
- ServerInstance->Users->uline_count--;
+ if (server->IsULine())
+ stdalgo::erase(ServerInstance->Users->all_ulines, this);
return Extensible::cull();
}