]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Implement support for the SERVLIST command.
authorSadie Powell <sadie@witchery.services>
Thu, 12 Mar 2020 17:27:11 +0000 (17:27 +0000)
committerSadie Powell <sadie@witchery.services>
Thu, 12 Mar 2020 17:51:03 +0000 (17:51 +0000)
include/moduledefs.h
include/usermanager.h
src/coremods/core_info/cmd_servlist.cpp [new file with mode: 0644]
src/coremods/core_info/core_info.cpp
src/coremods/core_info/core_info.h
src/usermanager.cpp
src/users.cpp

index 9f54e3eeb6953217b43eb56f568486bf3de2650a..a706a88832eeddc21fc9e16a88b5c6988d04e485 100644 (file)
@@ -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)
index ad09d968c29674283f628cb4f73020ac41eacc58..2a18393abc63aef3ec43c05f0b0c62b539108ba8 100644 (file)
@@ -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 (file)
index 0000000..f400124
--- /dev/null
@@ -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;
+}
index 507e4325077b5742e8e35a460df5787a1388708d..b172372e57bebcfaf53df2db51b0b96fa676b544 100644 (file)
@@ -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);
        }
 };
 
index 08aab4cd1cc8ba06f71e95ea216f246c8248560a..ecd4f78e77fb400250fa08b5564d5b300f160ffd 100644 (file)
@@ -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
index 9c8bde1e2c279fd3aafb6df715841444058c07fb..812f43113308c504dae4f59eebc448bc1fe86d44 100644 (file)
@@ -119,7 +119,6 @@ namespace
 UserManager::UserManager()
        : already_sent_id(0)
        , unregistered_count(0)
-       , uline_count(0)
 {
 }
 
index 0c95ecc0bc84214d5e5128855ffcb8cd3c13e27b..2571d15f2590f78da83ce8dd64c7ebce86dce859 100644 (file)
@@ -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();
 }