]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
m_spanningtree Move all server-to-server command handlers into handler classes
authorattilamolnar <attilamolnar@hush.com>
Mon, 15 Jul 2013 11:40:22 +0000 (13:40 +0200)
committerattilamolnar <attilamolnar@hush.com>
Sun, 18 Aug 2013 13:11:02 +0000 (15:11 +0200)
These commands are not registered in or called by the core. When looking for the handler of a command a new command table is searched first which contains all server-to-server commands. If a handler cannot be found in there, the core command table is consulted.

34 files changed:
src/modules/m_spanningtree/addline.cpp
src/modules/m_spanningtree/away.cpp
src/modules/m_spanningtree/commands.h
src/modules/m_spanningtree/delline.cpp
src/modules/m_spanningtree/encap.cpp
src/modules/m_spanningtree/fjoin.cpp
src/modules/m_spanningtree/fmode.cpp
src/modules/m_spanningtree/ftopic.cpp
src/modules/m_spanningtree/idle.cpp
src/modules/m_spanningtree/ijoin.cpp
src/modules/m_spanningtree/main.cpp
src/modules/m_spanningtree/main.h
src/modules/m_spanningtree/metadata.cpp
src/modules/m_spanningtree/misccommands.cpp [new file with mode: 0644]
src/modules/m_spanningtree/nick.cpp [new file with mode: 0644]
src/modules/m_spanningtree/nickcollide.cpp
src/modules/m_spanningtree/opertype.cpp
src/modules/m_spanningtree/ping.cpp
src/modules/m_spanningtree/pong.cpp
src/modules/m_spanningtree/postcommand.cpp
src/modules/m_spanningtree/push.cpp
src/modules/m_spanningtree/save.cpp
src/modules/m_spanningtree/server.cpp
src/modules/m_spanningtree/servercommand.cpp [new file with mode: 0644]
src/modules/m_spanningtree/servercommand.h [new file with mode: 0644]
src/modules/m_spanningtree/svsjoin.cpp
src/modules/m_spanningtree/svsnick.cpp
src/modules/m_spanningtree/svspart.cpp
src/modules/m_spanningtree/treesocket.h
src/modules/m_spanningtree/treesocket1.cpp
src/modules/m_spanningtree/treesocket2.cpp
src/modules/m_spanningtree/uid.cpp
src/modules/m_spanningtree/utils.h
src/modules/m_spanningtree/version.cpp

index 2ef76a351ce7e8fc2b1da52fffdd658363254619..2ee8401fa36c4126f9a7ec2face773bdb5b000e9 100644 (file)
 #include "inspircd.h"
 #include "xline.h"
 
-#include "treesocket.h"
 #include "treeserver.h"
 #include "utils.h"
+#include "commands.h"
 
-bool TreeSocket::AddLine(const std::string &prefix, parameterlist &params)
+CmdResult CommandAddLine::Handle(User* usr, std::vector<std::string>& params)
 {
-       if (params.size() < 6)
-       {
-               const std::string& servername = MyRoot->GetName();
-               ServerInstance->SNO->WriteToSnoMask('d', "%s sent me a malformed ADDLINE", servername.c_str());
-               return true;
-       }
-
        XLineFactory* xlf = ServerInstance->XLines->GetFactory(params[0]);
-
-       std::string setter = "<unknown>";
-       User* usr = ServerInstance->FindNick(prefix);
-       if (usr)
-               setter = usr->nick;
-       else
-       {
-               TreeServer* t = Utils->FindServer(prefix);
-               if (t)
-                       setter = t->GetName();
-       }
+       const std::string& setter = usr->nick;
 
        if (!xlf)
        {
                ServerInstance->SNO->WriteToSnoMask('d',"%s sent me an unknown ADDLINE type (%s).",setter.c_str(),params[0].c_str());
-               return true;
+               return CMD_FAILURE;
        }
 
        XLine* xl = NULL;
@@ -60,7 +43,7 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist &params)
        catch (ModuleException &e)
        {
                ServerInstance->SNO->WriteToSnoMask('d',"Unable to ADDLINE type %s from %s: %s", params[0].c_str(), setter.c_str(), e.GetReason());
-               return true;
+               return CMD_FAILURE;
        }
        xl->SetCreateTime(ConvToInt(params[3]));
        if (ServerInstance->XLines->AddLine(xl, NULL))
@@ -76,20 +59,19 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist &params)
                        ServerInstance->SNO->WriteToSnoMask('X',"%s added permanent %s%s on %s: %s",setter.c_str(),params[0].c_str(),params[0].length() == 1 ? "-line" : "",
                                        params[1].c_str(),params[5].c_str());
                }
-               params[5] = ":" + params[5];
 
-               User* u = ServerInstance->FindNick(prefix);
-               Utils->DoOneToAllButSender(prefix, "ADDLINE", params, u ? u->server : prefix);
-               TreeServer *remoteserver = Utils->FindServer(u ? u->server : prefix);
+               TreeServer* remoteserver = Utils->FindServer(usr->server);
 
                if (!remoteserver->bursting)
                {
                        ServerInstance->XLines->ApplyLines();
                }
+               return CMD_SUCCESS;
        }
        else
+       {
                delete xl;
-
-       return true;
+               return CMD_FAILURE;
+       }
 }
 
index ae60633bf50b351c12420f35dd27d98739f9ef2a..cf0c87ce46a45d46c8b47cefff740f720988ed32 100644 (file)
 
 #include "main.h"
 #include "utils.h"
-#include "treesocket.h"
+#include "commands.h"
 
-bool TreeSocket::Away(const std::string &prefix, parameterlist &params)
+CmdResult CommandAway::Handle(User* u, std::vector<std::string>& params)
 {
-       User* u = ServerInstance->FindNick(prefix);
-       if ((!u) || (IS_SERVER(u)))
-               return true;
+       if (IS_SERVER(u))
+               return CMD_INVALID;
        if (params.size())
        {
                FOREACH_MOD(OnSetAway, (u, params[params.size() - 1]));
@@ -38,14 +37,11 @@ bool TreeSocket::Away(const std::string &prefix, parameterlist &params)
                        u->awaytime = ServerInstance->Time();
 
                u->awaymsg = params[params.size() - 1];
-
-               params[params.size() - 1] = ":" + params[params.size() - 1];
        }
        else
        {
                FOREACH_MOD(OnSetAway, (u, ""));
                u->awaymsg.clear();
        }
-       Utils->DoOneToAllButSender(prefix,"AWAY",params,u->server);
-       return true;
+       return CMD_SUCCESS;
 }
index 44f26ae6c703b14609c826c1acbe6fc9c3b84147..a895c569b2510aa6933631de0d98f76f968bdd86 100644 (file)
@@ -39,50 +39,53 @@ class CommandRSQuit : public Command
                RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters);
 };
 
-class CommandSVSJoin : public Command
+class CommandSVSJoin : public ServerCommand
 {
  public:
-       CommandSVSJoin(Module* Creator) : Command(Creator, "SVSJOIN", 2) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
+       CommandSVSJoin(Module* Creator) : ServerCommand(Creator, "SVSJOIN", 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
        RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters);
 };
-class CommandSVSPart : public Command
+
+class CommandSVSPart : public ServerCommand
 {
  public:
-       CommandSVSPart(Module* Creator) : Command(Creator, "SVSPART", 2) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
+       CommandSVSPart(Module* Creator) : ServerCommand(Creator, "SVSPART", 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
        RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters);
 };
-class CommandSVSNick : public Command
+
+class CommandSVSNick : public ServerCommand
 {
  public:
-       CommandSVSNick(Module* Creator) : Command(Creator, "SVSNICK", 3) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
+       CommandSVSNick(Module* Creator) : ServerCommand(Creator, "SVSNICK", 3) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
        RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters);
 };
-class CommandMetadata : public Command
+
+class CommandMetadata : public ServerCommand
 {
  public:
-       CommandMetadata(Module* Creator) : Command(Creator, "METADATA", 2) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandMetadata(Module* Creator) : ServerCommand(Creator, "METADATA", 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
 };
-class CommandUID : public Command
+
+class CommandUID : public ServerCommand
 {
  public:
-       CommandUID(Module* Creator) : Command(Creator, "UID", 10) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandUID(Module* Creator) : ServerCommand(Creator, "UID", 10) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
 };
-class CommandOpertype : public Command
+
+class CommandOpertype : public ServerCommand
 {
  public:
-       CommandOpertype(Module* Creator) : Command(Creator, "OPERTYPE", 1) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandOpertype(Module* Creator) : ServerCommand(Creator, "OPERTYPE", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
 };
+
 class TreeSocket;
-class CommandFJoin : public Command
+class CommandFJoin : public ServerCommand
 {
        /** Remove all modes from a channel, including statusmodes (+qaovh etc), simplemodes, parameter modes.
         * This does not update the timestamp of the target channel, this must be done seperately.
@@ -91,59 +94,174 @@ class CommandFJoin : public Command
        static void ApplyModeStack(User* srcuser, Channel* c, irc::modestacker& stack);
        bool ProcessModeUUIDPair(const std::string& item, TreeSocket* src_socket, Channel* chan, irc::modestacker* modestack);
  public:
-       CommandFJoin(Module* Creator) : Command(Creator, "FJOIN", 3) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandFJoin(Module* Creator) : ServerCommand(Creator, "FJOIN", 3) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
+};
+
+class CommandFMode : public ServerCommand
+{
+ public:
+       CommandFMode(Module* Creator) : ServerCommand(Creator, "FMODE", 3) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
+};
+
+class CommandFTopic : public ServerCommand
+{
+ public:
+       CommandFTopic(Module* Creator) : ServerCommand(Creator, "FTOPIC", 5) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
+};
+
+class CommandFHost : public ServerCommand
+{
+ public:
+       CommandFHost(Module* Creator) : ServerCommand(Creator, "FHOST", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
+};
+
+class CommandFIdent : public ServerCommand
+{
+ public:
+       CommandFIdent(Module* Creator) : ServerCommand(Creator, "FIDENT", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
+};
+
+class CommandFName : public ServerCommand
+{
+ public:
+       CommandFName(Module* Creator) : ServerCommand(Creator, "FNAME", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
+};
+
+class CommandIJoin : public ServerCommand
+{
+ public:
+       CommandIJoin(Module* Creator) : ServerCommand(Creator, "IJOIN", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& params);
+};
+
+class CommandResync : public ServerCommand
+{
+ public:
+       CommandResync(Module* Creator) : ServerCommand(Creator, "RESYNC", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+};
+
+class CommandAway : public ServerCommand
+{
+ public:
+       CommandAway(Module* Creator) : ServerCommand(Creator, "AWAY", 0, 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
 };
-class CommandFMode : public Command
+
+class CommandAddLine : public ServerCommand
+{
+ public:
+       CommandAddLine(Module* Creator) : ServerCommand(Creator, "ADDLINE", 6, 6) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+};
+
+class CommandDelLine : public ServerCommand
+{
+ public:
+       CommandDelLine(Module* Creator) : ServerCommand(Creator, "DELLINE", 2, 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+};
+
+class CommandEncap : public ServerCommand
+{
+ public:
+       CommandEncap(Module* Creator) : ServerCommand(Creator, "ENCAP", 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters);
+};
+
+class CommandIdle : public ServerCommand
+{
+ public:
+       CommandIdle(Module* Creator) : ServerCommand(Creator, "IDLE", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_UNICAST(parameters[0]); }
+};
+
+class CommandNick : public ServerCommand
+{
+ public:
+       CommandNick(Module* Creator) : ServerCommand(Creator, "NICK", 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+};
+
+class CommandPing : public ServerCommand
+{
+ public:
+       CommandPing(Module* Creator) : ServerCommand(Creator, "PING", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_UNICAST(parameters[0]); }
+};
+
+class CommandPong : public ServerCommand
 {
  public:
-       CommandFMode(Module* Creator) : Command(Creator, "FMODE", 3) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandPong(Module* Creator) : ServerCommand(Creator, "PONG", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_UNICAST(parameters[0]); }
 };
-class CommandFTopic : public Command
+
+class CommandPush : public ServerCommand
 {
  public:
-       CommandFTopic(Module* Creator) : Command(Creator, "FTOPIC", 5) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandPush(Module* Creator) : ServerCommand(Creator, "PUSH", 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_UNICAST(parameters[0]); }
 };
-class CommandFHost : public Command
+
+class CommandSave : public ServerCommand
 {
  public:
-       CommandFHost(Module* Creator) : Command(Creator, "FHOST", 1) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandSave(Module* Creator) : ServerCommand(Creator, "SAVE", 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
 };
-class CommandFIdent : public Command
+
+class CommandServer : public ServerCommand
 {
  public:
-       CommandFIdent(Module* Creator) : Command(Creator, "FIDENT", 1) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandServer(Module* Creator) : ServerCommand(Creator, "SERVER", 5) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
 };
-class CommandFName : public Command
+
+class CommandSQuit : public ServerCommand
+{
+ public:
+       CommandSQuit(Module* Creator) : ServerCommand(Creator, "SQUIT", 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+};
+
+class CommandSNONotice : public ServerCommand
+{
+ public:
+       CommandSNONotice(Module* Creator) : ServerCommand(Creator, "SNONOTICE", 2) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
+};
+
+class CommandVersion : public ServerCommand
 {
  public:
-       CommandFName(Module* Creator) : Command(Creator, "FNAME", 1) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult Handle (const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandVersion(Module* Creator) : ServerCommand(Creator, "VERSION", 1) { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
 };
 
-class CommandIJoin : public SplitCommand
+class CommandBurst : public ServerCommand
 {
  public:
-       CommandIJoin(Module* Creator) : SplitCommand(Creator, "IJOIN", 1) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult HandleRemote(const std::vector<std::string>& parameters, RemoteUser* user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_BROADCAST; }
+       CommandBurst(Module* Creator) : ServerCommand(Creator, "BURST") { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
 };
 
-class CommandResync : public SplitCommand
+class CommandEndBurst : public ServerCommand
 {
  public:
-       CommandResync(Module* Creator) : SplitCommand(Creator, "RESYNC", 1) { flags_needed = FLAG_SERVERONLY; }
-       CmdResult HandleServer(const std::vector<std::string>& parameters, FakeUser* user);
+       CommandEndBurst(Module* Creator) : ServerCommand(Creator, "ENDBURST") { }
+       CmdResult Handle(User* user, std::vector<std::string>& parameters);
 };
 
 class SpanningTreeCommands
@@ -165,5 +283,21 @@ class SpanningTreeCommands
        CommandFHost fhost;
        CommandFIdent fident;
        CommandFName fname;
+       CommandAway away;
+       CommandAddLine addline;
+       CommandDelLine delline;
+       CommandEncap encap;
+       CommandIdle idle;
+       CommandNick nick;
+       CommandPing ping;
+       CommandPong pong;
+       CommandPush push;
+       CommandSave save;
+       CommandServer server;
+       CommandSQuit squit;
+       CommandSNONotice snonotice;
+       CommandVersion version;
+       CommandBurst burst;
+       CommandEndBurst endburst;
        SpanningTreeCommands(ModuleSpanningTree* module);
 };
index 6ac70283c42e4335ce5ba613c0273be251c66cf4..c4ed1691bfa0299857fa732c0848d18352a854b8 100644 (file)
 #include "inspircd.h"
 #include "xline.h"
 
-#include "treesocket.h"
-#include "treeserver.h"
-#include "utils.h"
+#include "commands.h"
 
-bool TreeSocket::DelLine(const std::string &prefix, parameterlist &params)
+CmdResult CommandDelLine::Handle(User* user, std::vector<std::string>& params)
 {
-       if (params.size() < 2)
-               return true;
-
-       std::string setter = "<unknown>";
-
-       User* user = ServerInstance->FindNick(prefix);
-       if (user)
-               setter = user->nick;
-       else
-       {
-               TreeServer* t = Utils->FindServer(prefix);
-               if (t)
-                       setter = t->GetName();
-       }
-
+       const std::string& setter = user->nick;
 
        /* NOTE: No check needed on 'user', this function safely handles NULL */
        if (ServerInstance->XLines->DelLine(params[1].c_str(), params[0], user))
        {
                ServerInstance->SNO->WriteToSnoMask('X',"%s removed %s%s on %s", setter.c_str(),
                                params[0].c_str(), params[0].length() == 1 ? "-line" : "", params[1].c_str());
-               Utils->DoOneToAllButSender(prefix,"DELLINE", params, prefix);
+               return CMD_SUCCESS;
        }
-       return true;
+       return CMD_FAILURE;
 }
 
index fedadedb5d9ce60970e98c613969e9fe3fa3d35d..12ab2b664cf939b43019a07315ee2e0c77c34073 100644 (file)
 
 
 #include "inspircd.h"
-#include "xline.h"
 
-#include "treesocket.h"
-#include "utils.h"
+#include "commands.h"
 
 /** ENCAP */
-void TreeSocket::Encap(User* who, parameterlist &params)
+CmdResult CommandEncap::Handle(User* user, std::vector<std::string>& params)
 {
-       if (params.size() > 1)
+       if (ServerInstance->Config->GetSID() == params[0] || InspIRCd::Match(ServerInstance->Config->ServerName, params[0]))
        {
-               if (ServerInstance->Config->GetSID() == params[0] || InspIRCd::Match(ServerInstance->Config->ServerName, params[0]))
-               {
-                       parameterlist plist(params.begin() + 2, params.end());
-                       ServerInstance->Parser->CallHandler(params[1], plist, who);
-                       // discard return value, ENCAP shall succeed even if the command does not exist
-               }
-
-               params[params.size() - 1] = ":" + params[params.size() - 1];
-
-               if (params[0].find_first_of("*?") != std::string::npos)
-               {
-                       Utils->DoOneToAllButSender(who->uuid, "ENCAP", params, who->server);
-               }
-               else
-                       Utils->DoOneToOne(who->uuid, "ENCAP", params, params[0]);
+               parameterlist plist(params.begin() + 2, params.end());
+               ServerInstance->Parser->CallHandler(params[1], plist, user);
+               // Discard return value, ENCAP shall succeed even if the command does not exist
        }
+       return CMD_SUCCESS;
 }
 
+RouteDescriptor CommandEncap::GetRouting(User* user, const std::vector<std::string>& params)
+{
+       if (params[0].find_first_of("*?") != std::string::npos)
+               return ROUTE_BROADCAST;
+       return ROUTE_UNICAST(params[0]);
+}
index 21327581a55bca8f85553ae4bc2a0b29fe455c6d..831d52c1d8517ada894db56db273b068aef2e9aa 100644 (file)
@@ -26,7 +26,7 @@
 #include "treesocket.h"
 
 /** FJOIN, almost identical to TS6 SJOIN, except for nicklist handling. */
-CmdResult CommandFJoin::Handle(const std::vector<std::string>& params, User *srcuser)
+CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params)
 {
        /* 1.1+ FJOIN works as follows:
         *
index 7e02df6a76da07d866a5902e9eed8c574d327c39..16af5ccc08ff720811545eedc98ecc6ed1ebdace 100644 (file)
@@ -22,7 +22,7 @@
 #include "commands.h"
 
 /** FMODE command - server mode with timestamp checks */
-CmdResult CommandFMode::Handle(const std::vector<std::string>& params, User *who)
+CmdResult CommandFMode::Handle(User* who, std::vector<std::string>& params)
 {
        time_t TS = ConvToInt(params[1]);
        if (!TS)
index 69d3af56520c7e72f3601799b28073e49bbfd056..0a4a95f9ec9dbc1c3a9244e5680583516b1b2888 100644 (file)
@@ -22,7 +22,7 @@
 #include "commands.h"
 
 /** FTOPIC command */
-CmdResult CommandFTopic::Handle(const std::vector<std::string>& params, User *user)
+CmdResult CommandFTopic::Handle(User* user, std::vector<std::string>& params)
 {
        Channel* c = ServerInstance->FindChan(params[0]);
        if (!c)
index 2c95eaad140aaf0b53f5e50da2c481683f2c4e65..57692ddf53c8790b43cb5b8ef3f07706bd76571c 100644 (file)
 
 #include "inspircd.h"
 #include "utils.h"
-#include "treesocket.h"
+#include "commands.h"
 
-bool TreeSocket::Whois(const std::string &prefix, parameterlist &params)
+CmdResult CommandIdle::Handle(User* issuer, std::vector<std::string>& params)
 {
-       if (params.size() < 1)
-               return true;
-
        /* If this is a request, this user did the /whois
         * If this is a reply, this user's information is in params[1] and params[2]
         */
-       User* issuer = ServerInstance->FindUUID(prefix);
-       if ((!issuer) || (IS_SERVER(issuer)))
-               return true;
+       if (IS_SERVER(issuer))
+               return CMD_FAILURE;
 
        /* If this is a request, this is the user whose idle information was requested
         * If this is a reply, this user did the /whois
         */
        User* target = ServerInstance->FindUUID(params[0]);
        if ((!target) || (IS_SERVER(target)))
-               return true;
+               return CMD_FAILURE;
 
        LocalUser* localtarget = IS_LOCAL(target);
        if (!localtarget)
        {
                // Forward to target's server
-               Utils->DoOneToOne(prefix, "IDLE", params, target->server);
-               return true;
+               return CMD_SUCCESS;
        }
 
        if (params.size() >= 2)
@@ -63,11 +58,11 @@ bool TreeSocket::Whois(const std::string &prefix, parameterlist &params)
                        idle = ((unsigned int) (ServerInstance->Time() - localtarget->idle_lastmsg));
 
                parameterlist reply;
-               reply.push_back(prefix);
+               reply.push_back(issuer->uuid);
                reply.push_back(ConvToStr(target->signon));
                reply.push_back(ConvToStr(idle));
                Utils->DoOneToOne(params[0], "IDLE", reply, issuer->server);
        }
 
-       return true;
+       return CMD_SUCCESS;
 }
index 8185216d37915f1fe19b0d437bba4c90246f0242..8342e9d2404c870d2a2886ff457e718bcfff65bf 100644 (file)
@@ -23,7 +23,7 @@
 #include "treeserver.h"
 #include "treesocket.h"
 
-CmdResult CommandIJoin::HandleRemote(const std::vector<std::string>& params, RemoteUser* user)
+CmdResult CommandIJoin::Handle(User* user, std::vector<std::string>& params)
 {
        Channel* chan = ServerInstance->FindChan(params[0]);
        if (!chan)
@@ -63,7 +63,7 @@ CmdResult CommandIJoin::HandleRemote(const std::vector<std::string>& params, Rem
        return CMD_SUCCESS;
 }
 
-CmdResult CommandResync::HandleServer(const std::vector<std::string>& params, FakeUser* user)
+CmdResult CommandResync::Handle(User* user, std::vector<std::string>& params)
 {
        ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Resyncing " + params[0]);
        Channel* chan = ServerInstance->FindChan(params[0]);
index 7bbe5fbad02850dacfbe207bf4d1812fc18802d4..8f17129a33cea93eff5eca9be8711012cbd2d3f6 100644 (file)
@@ -44,7 +44,11 @@ SpanningTreeCommands::SpanningTreeCommands(ModuleSpanningTree* module)
        : rconnect(module), rsquit(module),
        svsjoin(module), svspart(module), svsnick(module), metadata(module),
        uid(module), opertype(module), fjoin(module), ijoin(module), resync(module),
-       fmode(module), ftopic(module), fhost(module), fident(module), fname(module)
+       fmode(module), ftopic(module), fhost(module), fident(module), fname(module),
+       away(module), addline(module), delline(module), encap(module), idle(module),
+       nick(module), ping(module), pong(module), push(module), save(module),
+       server(module), squit(module), snonotice(module), version(module),
+       burst(module), endburst(module)
 {
 }
 
@@ -57,20 +61,6 @@ void ModuleSpanningTree::init()
        commands = new SpanningTreeCommands(this);
        ServerInstance->Modules->AddService(commands->rconnect);
        ServerInstance->Modules->AddService(commands->rsquit);
-       ServerInstance->Modules->AddService(commands->svsjoin);
-       ServerInstance->Modules->AddService(commands->svspart);
-       ServerInstance->Modules->AddService(commands->svsnick);
-       ServerInstance->Modules->AddService(commands->metadata);
-       ServerInstance->Modules->AddService(commands->uid);
-       ServerInstance->Modules->AddService(commands->opertype);
-       ServerInstance->Modules->AddService(commands->fjoin);
-       ServerInstance->Modules->AddService(commands->ijoin);
-       ServerInstance->Modules->AddService(commands->resync);
-       ServerInstance->Modules->AddService(commands->fmode);
-       ServerInstance->Modules->AddService(commands->ftopic);
-       ServerInstance->Modules->AddService(commands->fhost);
-       ServerInstance->Modules->AddService(commands->fident);
-       ServerInstance->Modules->AddService(commands->fname);
 
        delete ServerInstance->PI;
        ServerInstance->PI = new SpanningTreeProtocolInterface(Utils);
index 07b0762e5724abf47b6c5a20e597c0b76c2b5a5d..8b1f8e72f67a43efed7796b68e374f8855886016 100644 (file)
@@ -24,8 +24,9 @@
 #pragma once
 
 #include "inspircd.h"
-
 #include "modules/dns.h"
+#include "servercommand.h"
+
 /** If you make a change which breaks the protocol, increment this.
  * If you  completely change the protocol, completely change the number.
  *
@@ -57,6 +58,8 @@ class ModuleSpanningTree : public Module
  public:
        dynamic_reference<DNS::Manager> DNS;
 
+       ServerCommandManager CmdManager;
+
        /** Set to true if inside a spanningtree call, to prevent sending
         * xlines and other things back to their source
         */
index 8ce41d87f1f5012ac12660bf42d091c5ea89ffe3..cf386cf21f6527dc4302a892af7137cad0717412 100644 (file)
@@ -21,7 +21,7 @@
 #include "inspircd.h"
 #include "commands.h"
 
-CmdResult CommandMetadata::Handle(const std::vector<std::string>& params, User *srcuser)
+CmdResult CommandMetadata::Handle(User* srcuser, std::vector<std::string>& params)
 {
        if (params[0] == "*")
        {
diff --git a/src/modules/m_spanningtree/misccommands.cpp b/src/modules/m_spanningtree/misccommands.cpp
new file mode 100644 (file)
index 0000000..6e66c68
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com>
+ *   Copyright (C) 2007-2008, 2012 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
+ *
+ * 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 "main.h"
+#include "commands.h"
+#include "treeserver.h"
+
+CmdResult CommandSNONotice::Handle(User* user, std::vector<std::string>& params)
+{
+       ServerInstance->SNO->WriteToSnoMask(params[0][0], "From " + user->nick + ": " + params[1]);
+       return CMD_SUCCESS;
+}
+
+CmdResult CommandBurst::Handle(User* user, std::vector<std::string>& params)
+{
+       if (!IS_SERVER(user))
+               return CMD_INVALID;
+
+       TreeServer* server = Utils->FindServer(user->server);
+       server->bursting = true;
+       return CMD_SUCCESS;
+}
+
+CmdResult CommandEndBurst::Handle(User* user, std::vector<std::string>& params)
+{
+       if (!IS_SERVER(user))
+               return CMD_INVALID;
+
+       TreeServer* server = Utils->FindServer(user->server);
+       server->FinishBurst();
+       return CMD_SUCCESS;
+}
diff --git a/src/modules/m_spanningtree/nick.cpp b/src/modules/m_spanningtree/nick.cpp
new file mode 100644 (file)
index 0000000..5de12b5
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com>
+ *   Copyright (C) 2007-2008, 2012 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
+ *
+ * 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 "main.h"
+#include "utils.h"
+#include "commands.h"
+
+CmdResult CommandNick::Handle(User* user, std::vector<std::string>& params)
+{
+       if (IS_SERVER(user))
+               return CMD_INVALID;
+
+       if ((isdigit(params[0][0])) && (params[0] != user->uuid))
+               return CMD_INVALID;
+
+       /* Update timestamp on user when they change nicks */
+       user->age = ConvToInt(params[1]);
+
+       /*
+        * On nick messages, check that the nick doesn't already exist here.
+        * If it does, perform collision logic.
+        */
+       User* x = ServerInstance->FindNickOnly(params[0]);
+       if ((x) && (x != user))
+       {
+               /* x is local, who is remote */
+               int collideret = Utils->DoCollision(x, Utils->FindServer(user->server), user->age, user->ident, user->GetIPString(), user->uuid);
+               if (collideret != 1)
+               {
+                       /*
+                        * Remote client lost, or both lost, parsing or passing on this
+                        * nickchange would be pointless, as the incoming client's server will
+                        * soon receive SAVE to change its nick to its UID. :) -- w00t
+                        */
+                       return CMD_FAILURE;
+               }
+       }
+       user->ForceNickChange(params[0]);
+       return CMD_SUCCESS;
+}
index 3d29e402a7ffc0470edc53220d16334da7c5706a..39490e953b28d3684376712b3ab23d5a106a98e7 100644 (file)
@@ -21,6 +21,7 @@
 #include "inspircd.h"
 
 #include "treesocket.h"
+#include "treeserver.h"
 #include "utils.h"
 
 /*
@@ -29,7 +30,7 @@
  * Returns 1 if colliding local client, 2 if colliding remote, 3 if colliding both.
  * Sends SAVEs as appropriate and forces nickchanges too.
  */
-int TreeSocket::DoCollision(User *u, time_t remotets, const std::string &remoteident, const std::string &remoteip, const std::string &remoteuid)
+int SpanningTreeUtilities::DoCollision(User* u, TreeServer* server, time_t remotets, const std::string& remoteident, const std::string& remoteip, const std::string& remoteuid)
 {
        /*
         * Under old protocol rules, we would have had to kill both clients.
@@ -107,7 +108,7 @@ int TreeSocket::DoCollision(User *u, time_t remotets, const std::string &remotei
                parameterlist params;
                params.push_back(u->uuid);
                params.push_back(ConvToStr(u->age));
-               Utils->DoOneToMany(ServerInstance->Config->GetSID(),"SAVE",params);
+               this->DoOneToMany(ServerInstance->Config->GetSID(),"SAVE",params);
 
                u->ForceNickChange(u->uuid);
 
@@ -122,7 +123,8 @@ int TreeSocket::DoCollision(User *u, time_t remotets, const std::string &remotei
                 * the UID or halt the propagation of the nick change command,
                 * so other servers don't need to see the SAVE
                 */
-               WriteLine(":"+ServerInstance->Config->GetSID()+" SAVE "+remoteuid+" "+ ConvToStr(remotets));
+               TreeSocket* sock = server->GetRoute()->GetSocket();
+               sock->WriteLine(":"+ServerInstance->Config->GetSID()+" SAVE "+remoteuid+" "+ ConvToStr(remotets));
 
                if (remote)
                {
index 83544850369c97be66396a80ef65b6050e497e9e..c3f9b633cf33da570d5b5491781d9794f4acb41e 100644 (file)
@@ -26,7 +26,7 @@
 /** Because the core won't let users or even SERVERS set +o,
  * we use the OPERTYPE command to do this.
  */
-CmdResult CommandOpertype::Handle(const std::vector<std::string>& params, User *u)
+CmdResult CommandOpertype::Handle(User* u, std::vector<std::string>& params)
 {
        const std::string& opertype = params[0];
        if (!u->IsOper())
index 92eee2666b68c1863dfd297e497fce785e51eb94..537efe96466488af37948961335f9ae38d6c42ca 100644 (file)
 #include "inspircd.h"
 
 #include "utils.h"
-#include "treesocket.h"
+#include "treeserver.h"
+#include "commands.h"
+#include "utils.h"
 
-bool TreeSocket::LocalPing(const std::string &prefix, parameterlist &params)
+CmdResult CommandPing::Handle(User* user, std::vector<std::string>& params)
 {
-       if (params.size() < 1)
-               return true;
-
-       const std::string& forwardto = params[0];
-       if (forwardto == ServerInstance->Config->GetSID())
+       if (params[0] == ServerInstance->Config->GetSID())
        {
                // PING for us, reply with a PONG
-               std::string reply = ":" + forwardto + " PONG " + prefix;
+               parameterlist reply;
+               reply.push_back(user->uuid);
                if (params.size() >= 2)
                        // If there is a second parameter, append it
-                       reply.append(" :").append(params[1]);
+                       reply.push_back(params[1]);
 
-               this->WriteLine(reply);
-       }
-       else
-       {
-               // not for us, pass it on :)
-               Utils->DoOneToOne(prefix,"PING",params,forwardto);
+               Utils->DoOneToOne(params[0], "PONG", reply, user->server);
        }
-       return true;
+       return CMD_SUCCESS;
 }
 
 
index 034f1f8914256d44025b8dfe52ba3019d35a1a38..006d51a101c7fc00dd333935ccde2e8f2ca667ae 100644 (file)
 
 #include "utils.h"
 #include "treeserver.h"
-#include "treesocket.h"
+#include "commands.h"
+#include "utils.h"
 
-bool TreeSocket::LocalPong(const std::string &prefix, parameterlist &params)
+CmdResult CommandPong::Handle(User* user, std::vector<std::string>& params)
 {
-       if (params.size() < 1)
-               return true;
-
-       const std::string& forwardto = params[0];
-       if (forwardto == ServerInstance->Config->GetSID())
+       TreeServer* server = Utils->FindServer(user->server);
+       if (server->bursting)
        {
-               // PONG for us
-               TreeServer* ServerSource = Utils->FindServer(prefix);
-               if (ServerSource)
-               {
-                       long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000);
-                       ServerSource->rtt = ts - ServerSource->LastPingMsec;
-                       ServerSource->SetPingFlag();
-               }
+               ServerInstance->SNO->WriteGlobalSno('l', "Server \002%s\002 has not finished burst, forcing end of burst (send ENDBURST!)", server->GetName().c_str());
+               server->FinishBurst();
        }
-       else
+
+       if (params[0] == ServerInstance->Config->GetSID())
        {
-               // not for us, pass it on :)
-               Utils->DoOneToOne(prefix,"PONG",params,forwardto);
+               // PONG for us
+               long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000);
+               server->rtt = ts - server->LastPingMsec;
+               server->SetPingFlag();
        }
-       return true;
+       return CMD_SUCCESS;
 }
 
index 7a681856a0987465021371eff870d706e801ec73..3fb3d5b0703cdbe586031758093645f26d202d5a 100644 (file)
@@ -29,7 +29,7 @@ void ModuleSpanningTree::OnPostCommand(Command* command, const std::vector<std::
                Utils->RouteCommand(NULL, command, parameters, user);
 }
 
-void SpanningTreeUtilities::RouteCommand(TreeServer* origin, Command* thiscmd, const parameterlist& parameters, User* user)
+void SpanningTreeUtilities::RouteCommand(TreeServer* origin, CommandBase* thiscmd, const parameterlist& parameters, User* user)
 {
        const std::string& command = thiscmd->name;
        RouteDescriptor routing = thiscmd->GetRouting(user, parameters);
index 05b5d68dea49879228cabae8f00709a26c95fbb0..a265e0d2e99bf18e66824423940fc17e49feb6ce 100644 (file)
 #include "inspircd.h"
 
 #include "utils.h"
-#include "treesocket.h"
+#include "commands.h"
 
-bool TreeSocket::Push(const std::string &prefix, parameterlist &params)
+CmdResult CommandPush::Handle(User* user, std::vector<std::string>& params)
 {
-       if (params.size() < 2)
-               return true;
        User* u = ServerInstance->FindNick(params[0]);
        if (!u)
-               return true;
+               return CMD_FAILURE;
        if (IS_LOCAL(u))
        {
                u->Write(params[1]);
        }
-       else
-       {
-               // continue the raw onwards
-               params[1] = ":" + params[1];
-               Utils->DoOneToOne(prefix,"PUSH",params,u->server);
-       }
-       return true;
+       return CMD_SUCCESS;
 }
 
index 42d909be7b03b0e62774979e30cb4ae12b3a2e8c..8f0eced7333af7fb2495c4a4f670bf913354ebf6 100644 (file)
 
 #include "utils.h"
 #include "treesocket.h"
+#include "commands.h"
 
 /**
  * SAVE command - force nick change to UID on timestamp match
  */
-bool TreeSocket::ForceNick(const std::string &prefix, parameterlist &params)
+CmdResult CommandSave::Handle(User* user, std::vector<std::string>& params)
 {
-       if (params.size() < 2)
-               return true;
-
        User* u = ServerInstance->FindNick(params[0]);
+       if ((!u) || (IS_SERVER(u)))
+               return CMD_FAILURE;
+
        time_t ts = atol(params[1].c_str());
 
-       if ((u) && (!IS_SERVER(u)) && (u->age == ts))
+       if (u->age == ts)
        {
-               Utils->DoOneToAllButSender(prefix,"SAVE",params,prefix);
-
                if (!u->ForceNickChange(u->uuid))
                {
                        ServerInstance->Users->QuitUser(u, "Nickname collision");
                }
        }
 
-       return true;
+       return CMD_SUCCESS;
 }
 
index aebc165688a9146b9009f3a1d4af47ca39206da7..fcd326974c84130525b208e997cec12212f9aac0 100644 (file)
 
 #include "inspircd.h"
 
+#include "main.h"
 #include "utils.h"
 #include "link.h"
 #include "treeserver.h"
 #include "treesocket.h"
+#include "commands.h"
 
 /*
  * Some server somewhere in the network introducing another server.
  *     -- w
  */
-bool TreeSocket::RemoteServer(const std::string &prefix, parameterlist &params)
+CmdResult CommandServer::Handle(User* user, std::vector<std::string>& params)
 {
-       if (params.size() < 5)
-       {
-               SendError("Protocol error - Not enough parameters for SERVER command");
-               return false;
-       }
-
        std::string servername = params[0];
        // password is not used for a remote server
        // hopcount is not used (ever)
        std::string sid = params[3];
        std::string description = params[4];
-       TreeServer* ParentOfThis = Utils->FindServer(prefix);
+       TreeServer* ParentOfThis = Utils->FindServer(user->server);
+       TreeSocket* socket = ParentOfThis->GetRoute()->GetSocket();
+
+       if (!IS_SERVER(user))
+               return CMD_FAILURE;
 
-       if (!ParentOfThis)
-       {
-               this->SendError("Protocol error - Introduced remote server from unknown server "+prefix);
-               return false;
-       }
        if (!InspIRCd::IsSID(sid))
        {
-               this->SendError("Invalid format server ID: "+sid+"!");
-               return false;
+               socket->SendError("Invalid format server ID: "+sid+"!");
+               return CMD_FAILURE;
        }
        TreeServer* CheckDupe = Utils->FindServer(servername);
        if (CheckDupe)
        {
-               this->SendError("Server "+servername+" already exists!");
+               socket->SendError("Server "+servername+" already exists!");
                ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+CheckDupe->GetName()+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, already exists. Closing link with " + ParentOfThis->GetName());
-               return false;
+               return CMD_FAILURE;
        }
        CheckDupe = Utils->FindServer(sid);
        if (CheckDupe)
        {
-               this->SendError("Server ID "+sid+" already exists! You may want to specify the server ID for the server manually with <server:id> so they do not conflict.");
+               socket->SendError("Server ID "+sid+" already exists! You may want to specify the server ID for the server manually with <server:id> so they do not conflict.");
                ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+servername+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, server ID already exists on the network. Closing link with " + ParentOfThis->GetName());
-               return false;
+               return CMD_FAILURE;
        }
 
 
@@ -75,10 +70,8 @@ bool TreeSocket::RemoteServer(const std::string &prefix, parameterlist &params)
        TreeServer *Node = new TreeServer(servername, description, sid, ParentOfThis,NULL, lnk ? lnk->Hidden : false);
 
        ParentOfThis->AddChild(Node);
-       params[4] = ":" + params[4];
-       Utils->DoOneToAllButSender(prefix,"SERVER",params,prefix);
        ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+ParentOfThis->GetName()+"\002 introduced server \002"+servername+"\002 ("+description+")");
-       return true;
+       return CMD_SUCCESS;
 }
 
 
diff --git a/src/modules/m_spanningtree/servercommand.cpp b/src/modules/m_spanningtree/servercommand.cpp
new file mode 100644 (file)
index 0000000..fe5a38a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com>
+ *
+ * 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 "main.h"
+#include "servercommand.h"
+
+ServerCommand::ServerCommand(Module* Creator, const std::string& Name, unsigned int MinParams, unsigned int MaxParams)
+       : CommandBase(Creator, Name, MinParams, MaxParams)
+{
+       ModuleSpanningTree* st = static_cast<ModuleSpanningTree*>(Creator);
+       st->CmdManager.AddCommand(this);
+}
+
+RouteDescriptor ServerCommand::GetRouting(User* user, const std::vector<std::string>& parameters)
+{
+       // Broadcast server-to-server commands unless overridden
+       return ROUTE_BROADCAST;
+}
+
+ServerCommand* ServerCommandManager::GetHandler(const std::string& command) const
+{
+       ServerCommandMap::const_iterator it = commands.find(command);
+       if (it != commands.end())
+               return it->second;
+       return NULL;
+}
+
+bool ServerCommandManager::AddCommand(ServerCommand* cmd)
+{
+       return commands.insert(std::make_pair(cmd->name, cmd)).second;
+}
diff --git a/src/modules/m_spanningtree/servercommand.h b/src/modules/m_spanningtree/servercommand.h
new file mode 100644 (file)
index 0000000..4311dd7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com>
+ *
+ * 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/>.
+ */
+
+
+#pragma once
+
+class ServerCommand : public CommandBase
+{
+ public:
+       ServerCommand(Module* Creator, const std::string& Name, unsigned int MinPara = 0, unsigned int MaxPara = 0);
+
+       virtual CmdResult Handle(User* user, std::vector<std::string>& parameters) = 0;
+       virtual RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters);
+};
+
+class ServerCommandManager
+{
+       typedef TR1NS::unordered_map<std::string, ServerCommand*> ServerCommandMap;
+       ServerCommandMap commands;
+
+ public:
+       ServerCommand* GetHandler(const std::string& command) const;
+       bool AddCommand(ServerCommand* cmd);
+};
index 032633416851e0dd4a5a71d0f84911985ce4cbcd..552e08dd37fc53bfec859f353c4fdb413ccfa0a4 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "commands.h"
 
-CmdResult CommandSVSJoin::Handle(const std::vector<std::string>& parameters, User *user)
+CmdResult CommandSVSJoin::Handle(User* user, std::vector<std::string>& parameters)
 {
        // Check for valid channel name
        if (!ServerInstance->IsChannel(parameters[1]))
index 6490626afb4ba0e1e44abcc556fad0cc34aac75f..a504afbd7b25faacf61c9c49fda3f071c0dbca4e 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "commands.h"
 
-CmdResult CommandSVSNick::Handle(const std::vector<std::string>& parameters, User *user)
+CmdResult CommandSVSNick::Handle(User* user, std::vector<std::string>& parameters)
 {
        User* u = ServerInstance->FindNick(parameters[0]);
 
index b966da2820297ec58b16749849f2135160ddb362..f86afa367a9e4695aa29dbe92d08d2d72958ae02 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "commands.h"
 
-CmdResult CommandSVSPart::Handle(const std::vector<std::string>& parameters, User *user)
+CmdResult CommandSVSPart::Handle(User* user, std::vector<std::string>& parameters)
 {
        User* u = ServerInstance->FindUUID(parameters[0]);
        if (!u)
index 88204319cff5888269c026623974208b53f4d9d6..47bdef8842976ffdff10a15dee36edb10257c6ee 100644 (file)
@@ -208,9 +208,6 @@ class TreeSocket : public BufferedSocket
         */
        void Squit(TreeServer* Current, const std::string &reason);
 
-       /* Used on nick collision ... XXX ugly function HACK */
-       int DoCollision(User *u, time_t remotets, const std::string &remoteident, const std::string &remoteip, const std::string &remoteuid);
-
        /** Send one or more FJOINs for a channel of users.
         * If the length of a single line is more than 480-NICKMAX
         * in length, it is split over multiple lines.
@@ -245,48 +242,6 @@ class TreeSocket : public BufferedSocket
        /** Handle ERROR command */
        void Error(parameterlist &params);
 
-       /** Remote AWAY */
-       bool Away(const std::string &prefix, parameterlist &params);
-
-       /** SAVE to resolve nick collisions without killing */
-       bool ForceNick(const std::string &prefix, parameterlist &params);
-
-       /** ENCAP command
-        */
-       void Encap(User* who, parameterlist &params);
-
-       /** PONG
-        */
-       bool LocalPong(const std::string &prefix, parameterlist &params);
-
-       /** VERSION
-        */
-       bool ServerVersion(const std::string &prefix, parameterlist &params);
-
-       /** ADDLINE
-        */
-       bool AddLine(const std::string &prefix, parameterlist &params);
-
-       /** DELLINE
-        */
-       bool DelLine(const std::string &prefix, parameterlist &params);
-
-       /** WHOIS
-        */
-       bool Whois(const std::string &prefix, parameterlist &params);
-
-       /** PUSH
-        */
-       bool Push(const std::string &prefix, parameterlist &params);
-
-       /** PING
-        */
-       bool LocalPing(const std::string &prefix, parameterlist &params);
-
-       /** <- (remote) <- SERVER
-        */
-       bool RemoteServer(const std::string &prefix, parameterlist &params);
-
        /** (local) -> SERVER
         */
        bool Outbound_Reply_Server(parameterlist &params);
index e2afe6421391a32dea7d15a37c07950e6b06d4b0..8dbdb3839ebe43a5db3eb4e6052cf3ca371b9f1a 100644 (file)
@@ -29,6 +29,7 @@
 #include "treeserver.h"
 #include "link.h"
 #include "treesocket.h"
+#include "commands.h"
 
 /** Because most of the I/O gubbins are encapsulated within
  * BufferedSocket, we just call the superclass constructor for
@@ -167,22 +168,21 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason)
 {
        bool LocalSquit = false;
 
-       if ((Current) && (Current != Utils->TreeRoot))
+       if (Current != Utils->TreeRoot)
        {
                DelServerEvent(Utils->Creator, Current->GetName());
 
-               if (!Current->GetSocket() || Current->GetSocket()->Introduced())
-               {
-                       parameterlist params;
-                       params.push_back(Current->GetID());
-                       params.push_back(":"+reason);
-                       Utils->DoOneToAllButSender(Current->GetParent()->GetID(),"SQUIT",params,Current->GetName());
-               }
-
                if (Current->GetParent() == Utils->TreeRoot)
                {
                        ServerInstance->SNO->WriteGlobalSno('l', "Server \002"+Current->GetName()+"\002 split: "+reason);
                        LocalSquit = true;
+                       if (Current->GetSocket()->Introduced())
+                       {
+                               parameterlist params;
+                               params.push_back(Current->GetID());
+                               params.push_back(":"+reason);
+                               Utils->DoOneToMany(Utils->TreeRoot->GetID(), "SQUIT", params);
+                       }
                }
                else
                {
@@ -204,8 +204,20 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason)
                        Close();
                }
        }
-       else
+}
+
+CmdResult CommandSQuit::Handle(User* user, std::vector<std::string>& params)
+{
+       TreeServer* quitting = Utils->FindServer(params[0]);
+       if (!quitting)
+       {
                ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Squit from unknown server");
+               return CMD_FAILURE;
+       }
+
+       TreeSocket* sock = Utils->FindServer(user->server)->GetRoute()->GetSocket();
+       sock->Squit(quitting, params[1]);
+       return CMD_SUCCESS;
 }
 
 /** This function is called when we receive data from a remote
index 4995f6cb7df57e9c6637e4505955d0f69a27ebc5..66826ff3b9e3fa0392e6b766a64b63a9d3fdf5e7 100644 (file)
@@ -310,156 +310,13 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command,
                        return;
        }
 
-       // TODO move all this into Commands
-       if (command == "MAP")
+       ServerCommand* scmd = Utils->Creator->CmdManager.GetHandler(command);
+       CommandBase* cmdbase = scmd;
+       Command* cmd;
+       if (!scmd)
        {
-               Utils->Creator->HandleMap(params, who);
-       }
-       else if (command == "SERVER")
-       {
-               this->RemoteServer(prefix,params);
-       }
-       else if (command == "ERROR")
-       {
-               this->Error(params);
-       }
-       else if (command == "AWAY")
-       {
-               this->Away(prefix,params);
-       }
-       else if (command == "PING")
-       {
-               this->LocalPing(prefix,params);
-       }
-       else if (command == "PONG")
-       {
-               TreeServer *s = Utils->FindServer(prefix);
-               if (s && s->bursting)
-               {
-                       ServerInstance->SNO->WriteGlobalSno('l',"Server \002%s\002 has not finished burst, forcing end of burst (send ENDBURST!)", prefix.c_str());
-                       s->FinishBurst();
-               }
-               this->LocalPong(prefix,params);
-       }
-       else if (command == "VERSION")
-       {
-               this->ServerVersion(prefix,params);
-       }
-       else if (command == "ADDLINE")
-       {
-               this->AddLine(prefix,params);
-       }
-       else if (command == "DELLINE")
-       {
-               this->DelLine(prefix,params);
-       }
-       else if (command == "SAVE")
-       {
-               this->ForceNick(prefix,params);
-       }
-       else if (command == "IDLE")
-       {
-               this->Whois(prefix,params);
-       }
-       else if (command == "PUSH")
-       {
-               this->Push(prefix,params);
-       }
-       else if (command == "SQUIT")
-       {
-               if (params.size() == 2)
-               {
-                       this->Squit(Utils->FindServer(params[0]),params[1]);
-               }
-       }
-       else if (command == "SNONOTICE")
-       {
-               if (params.size() >= 2)
-               {
-                       ServerInstance->SNO->WriteToSnoMask(params[0][0], "From " + who->nick + ": "+ params[1]);
-                       params[1] = ":" + params[1];
-                       Utils->DoOneToAllButSender(prefix, command, params, prefix);
-               }
-       }
-       else if (command == "BURST")
-       {
-               // Set prefix server as bursting
-               TreeServer* ServerSource = Utils->FindServer(prefix);
-               if (!ServerSource)
-               {
-                       ServerInstance->SNO->WriteGlobalSno('l', "WTF: Got BURST from a non-server(?): %s", prefix.c_str());
-                       return;
-               }
-
-               ServerSource->bursting = true;
-               Utils->DoOneToAllButSender(prefix, command, params, prefix);
-       }
-       else if (command == "ENDBURST")
-       {
-               TreeServer* ServerSource = Utils->FindServer(prefix);
-               if (!ServerSource)
-               {
-                       ServerInstance->SNO->WriteGlobalSno('l', "WTF: Got ENDBURST from a non-server(?): %s", prefix.c_str());
-                       return;
-               }
-
-               ServerSource->FinishBurst();
-               Utils->DoOneToAllButSender(prefix, command, params, prefix);
-       }
-       else if (command == "ENCAP")
-       {
-               this->Encap(who, params);
-       }
-       else if (command == "NICK")
-       {
-               if (params.size() != 2)
-               {
-                       SendError("Protocol violation: Wrong number of parameters for NICK message");
-                       return;
-               }
-
-               if (IS_SERVER(who))
-               {
-                       SendError("Protocol violation: Server changing nick");
-                       return;
-               }
-
-               if ((isdigit(params[0][0])) && (params[0] != who->uuid))
-               {
-                       SendError("Protocol violation: User changing nick to an invalid UID - " + params[0]);
-                       return;
-               }
-
-               /* Update timestamp on user when they change nicks */
-               who->age = ConvToInt(params[1]);
-
-               /*
-                * On nick messages, check that the nick doesnt already exist here.
-                * If it does, perform collision logic.
-                */
-               User* x = ServerInstance->FindNickOnly(params[0]);
-               if ((x) && (x != who))
-               {
-                       int collideret = 0;
-                       /* x is local, who is remote */
-                       collideret = this->DoCollision(x, who->age, who->ident, who->GetIPString(), who->uuid);
-                       if (collideret != 1)
-                       {
-                               /*
-                                * Remote client lost, or both lost, parsing or passing on this
-                                * nickchange would be pointless, as the incoming client's server will
-                                * soon recieve SVSNICK to change its nick to its UID. :) -- w00t
-                                */
-                               return;
-                       }
-               }
-               who->ForceNickChange(params[0]);
-               Utils->DoOneToAllButSender(prefix, command, params, prefix);
-       }
-       else
-       {
-               Command* cmd = ServerInstance->Parser->GetHandler(command);
-
+               // Not a special server-to-server command
+               cmd = ServerInstance->Parser->GetHandler(command);
                if (!cmd)
                {
                        irc::stringjoiner pmlist(params);
@@ -468,36 +325,41 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command,
                        SendError("Unrecognised command '" + command + "' -- possibly loaded mismatched modules");
                        return;
                }
+               cmdbase = cmd;
+       }
 
-               if (params.size() < cmd->min_params)
-               {
-                       irc::stringjoiner pmlist(params);
-                       ServerInstance->Logs->Log(MODNAME, LOG_SPARSE, "Insufficient parameters for S2S command :%s %s %s",
-                               who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str());
-                       SendError("Insufficient parameters for command '" + command + "'");
-                       return;
-               }
+       if (params.size() < cmdbase->min_params)
+       {
+               irc::stringjoiner pmlist(params);
+               ServerInstance->Logs->Log(MODNAME, LOG_SPARSE, "Insufficient parameters for S2S command :%s %s %s",
+                       who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str());
+               SendError("Insufficient parameters for command '" + command + "'");
+               return;
+       }
 
-               if ((!params.empty()) && (params.back().empty()) && (!cmd->allow_empty_last_param))
-               {
-                       // the last param is empty and the command handler doesn't allow that, check if there will be enough params if we drop the last
-                       if (params.size()-1 < cmd->min_params)
-                               return;
-                       params.pop_back();
-               }
+       if ((!params.empty()) && (params.back().empty()) && (!cmdbase->allow_empty_last_param))
+       {
+               // the last param is empty and the command handler doesn't allow that, check if there will be enough params if we drop the last
+               if (params.size()-1 < cmdbase->min_params)
+                       return;
+               params.pop_back();
+       }
 
-               CmdResult res = cmd->Handle(params, who);
+       CmdResult res;
+       if (scmd)
+               res = scmd->Handle(who, params);
+       else
+               res = cmd->Handle(params, who);
 
-               if (res == CMD_INVALID)
-               {
-                       irc::stringjoiner pmlist(params);
-                       ServerInstance->Logs->Log(MODNAME, LOG_SPARSE, "Error handling S2S command :%s %s %s",
-                               who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str());
-                       SendError("Error handling '" + command + "' -- possibly loaded mismatched modules");
-               }
-               else if (res == CMD_SUCCESS)
-                       Utils->RouteCommand(route_back_again, cmd, params, who);
+       if (res == CMD_INVALID)
+       {
+               irc::stringjoiner pmlist(params);
+               ServerInstance->Logs->Log(MODNAME, LOG_SPARSE, "Error handling S2S command :%s %s %s",
+                       who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str());
+               SendError("Error handling '" + command + "' -- possibly loaded mismatched modules");
        }
+       else if (res == CMD_SUCCESS)
+               Utils->RouteCommand(route_back_again, cmdbase, params, who);
 }
 
 void TreeSocket::OnTimeout()
index a24d44e533f454e68b2d495854a3d4a825d44ab3..da75eebec27f3b78244e28a9a8726d405cc9ec24 100644 (file)
@@ -25,7 +25,7 @@
 #include "utils.h"
 #include "treeserver.h"
 
-CmdResult CommandUID::Handle(const parameterlist &params, User* serversrc)
+CmdResult CommandUID::Handle(User* serversrc, std::vector<std::string>& params)
 {
        /** Do we have enough parameters:
         *      0    1    2    3    4    5        6        7     8        9       (n-1)
@@ -50,7 +50,6 @@ CmdResult CommandUID::Handle(const parameterlist &params, User* serversrc)
                return CMD_INVALID;
        if (modestr[0] != '+')
                return CMD_INVALID;
-       TreeSocket* sock = remoteserver->GetRoute()->GetSocket();
 
        /* check for collision */
        user_hash::iterator iter = ServerInstance->Users->clientlist->find(params[2]);
@@ -60,17 +59,13 @@ CmdResult CommandUID::Handle(const parameterlist &params, User* serversrc)
                /*
                 * Nick collision.
                 */
-               int collide = sock->DoCollision(iter->second, age_t, params[5], params[6], params[0]);
+               int collide = Utils->DoCollision(iter->second, remoteserver, age_t, params[5], params[6], params[0]);
                ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "*** Collision on %s, collide=%d", params[2].c_str(), collide);
 
                if (collide != 1)
                {
-                       /* remote client lost, make sure we change their nick for the hash too
-                        *
-                        * This alters the line that will be sent to other servers, which
-                        * commands normally shouldn't do; hence the required const_cast.
-                        */
-                       const_cast<parameterlist&>(params)[2] = params[0];
+                       // Remote client lost, make sure we change their nick for the hash too
+                       params[2] = params[0];
                }
        }
 
@@ -152,7 +147,7 @@ CmdResult CommandUID::Handle(const parameterlist &params, User* serversrc)
        return CMD_SUCCESS;
 }
 
-CmdResult CommandFHost::Handle(const parameterlist &params, User* src)
+CmdResult CommandFHost::Handle(User* src, std::vector<std::string>& params)
 {
        if (IS_SERVER(src))
                return CMD_FAILURE;
@@ -160,7 +155,7 @@ CmdResult CommandFHost::Handle(const parameterlist &params, User* src)
        return CMD_SUCCESS;
 }
 
-CmdResult CommandFIdent::Handle(const parameterlist &params, User* src)
+CmdResult CommandFIdent::Handle(User* src, std::vector<std::string>& params)
 {
        if (IS_SERVER(src))
                return CMD_FAILURE;
@@ -168,7 +163,7 @@ CmdResult CommandFIdent::Handle(const parameterlist &params, User* src)
        return CMD_SUCCESS;
 }
 
-CmdResult CommandFName::Handle(const parameterlist &params, User* src)
+CmdResult CommandFName::Handle(User* src, std::vector<std::string>& params)
 {
        if (IS_SERVER(src))
                return CMD_FAILURE;
index bf81ef47fe0ff009d4fcddf926eb57856cc7e337..f65b07c436c755d5fd0384a137aff3fb925bb87d 100644 (file)
@@ -126,7 +126,7 @@ class SpanningTreeUtilities : public classbase
         */
        ~SpanningTreeUtilities();
 
-       void RouteCommand(TreeServer*, Command*, const parameterlist&, User*);
+       void RouteCommand(TreeServer* origin, CommandBase* cmd, const parameterlist& parameters, User* user);
 
        /** Send a message from this server to one other local or remote
         */
@@ -144,6 +144,10 @@ class SpanningTreeUtilities : public classbase
         */
        void ReadConfiguration();
 
+       /** Handle nick collision
+        */
+       int DoCollision(User* u, TreeServer* server, time_t remotets, const std::string& remoteident, const std::string& remoteip, const std::string& remoteuid);
+
        /** Compile a list of servers which contain members of channel c
         */
        void GetListOfServersForChannel(Channel* c, TreeServerList &list, char status, const CUList &exempt_list);
index 63bf6c419908af3d51107ad7201b9acfabf2d220..9a07103596e6ca5b2b178f7cc6ec78d2e323c81f 100644 (file)
 #include "main.h"
 #include "utils.h"
 #include "treeserver.h"
-#include "treesocket.h"
+#include "commands.h"
 
-bool TreeSocket::ServerVersion(const std::string &prefix, parameterlist &params)
+CmdResult CommandVersion::Handle(User* user, std::vector<std::string>& params)
 {
-       if (params.size() < 1)
-               return true;
-
-       TreeServer* ServerSource = Utils->FindServer(prefix);
+       TreeServer* ServerSource = Utils->FindServer(user->server);
 
        if (ServerSource)
        {
                ServerSource->SetVersion(params[0]);
        }
-       params[0] = ":" + params[0];
-       Utils->DoOneToAllButSender(prefix,"VERSION",params,prefix);
-       return true;
+       return CMD_SUCCESS;
 }