summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-10-14 19:18:04 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-10-14 19:18:04 +0000
commitf087d825a88760d251b8f80b5d50bc98b40fa2ae (patch)
treebbd5e06dc1d62bc5e338d1eeaa9ca47e45c95707
parentaf8692ea3b8ad6bf602ad4cee669a6d9d217c7a2 (diff)
Split up spanningtree some more, the filenames should be more intuitive so that developers know where to find stuff (more of this is coming soon)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@8187 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--src/modules/m_spanningtree/main.cpp447
-rw-r--r--src/modules/m_spanningtree/override_admin.cpp59
-rw-r--r--src/modules/m_spanningtree/override_map.cpp162
-rw-r--r--src/modules/m_spanningtree/override_modules.cpp57
-rw-r--r--src/modules/m_spanningtree/override_motd.cpp59
-rw-r--r--src/modules/m_spanningtree/override_squit.cpp66
-rw-r--r--src/modules/m_spanningtree/override_stats.cpp99
-rw-r--r--src/modules/m_spanningtree/override_time.cpp59
-rw-r--r--src/modules/m_spanningtree/override_whois.cpp57
-rw-r--r--src/modules/m_spanningtree/postcommand.cpp80
-rw-r--r--src/modules/m_spanningtree/precommand.cpp100
11 files changed, 798 insertions, 447 deletions
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index fdd57c4ef..4a31d7007 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -167,307 +167,6 @@ std::string ModuleSpanningTree::TimeToStr(time_t secs)
+ ConvToStr(secs) + "s");
}
-const std::string ModuleSpanningTree::MapOperInfo(TreeServer* Current)
-{
- time_t secs_up = ServerInstance->Time() - Current->age;
- return (" [Up: " + TimeToStr(secs_up) + " Lag: "+ConvToStr(Current->rtt)+"ms]");
-}
-
-// WARNING: NOT THREAD SAFE - DONT GET ANY SMART IDEAS.
-void ModuleSpanningTree::ShowMap(TreeServer* Current, userrec* user, int depth, char matrix[128][128], float &totusers, float &totservers)
-{
- if (line < 128)
- {
- for (int t = 0; t < depth; t++)
- {
- matrix[line][t] = ' ';
- }
- // For Aligning, we need to work out exactly how deep this thing is, and produce
- // a 'Spacer' String to compensate.
- char spacer[40];
- memset(spacer,' ',40);
- if ((40 - Current->GetName().length() - depth) > 1) {
- spacer[40 - Current->GetName().length() - depth] = '\0';
- }
- else
- {
- spacer[5] = '\0';
- }
- float percent;
- char text[128];
- /* Neat and tidy default values, as we're dealing with a matrix not a simple string */
- memset(text, 0, 128);
-
- if (ServerInstance->clientlist->size() == 0) {
- // If there are no users, WHO THE HELL DID THE /MAP?!?!?!
- percent = 0;
- }
- else
- {
- percent = ((float)Current->GetUserCount() / (float)ServerInstance->clientlist->size()) * 100;
- }
- const std::string operdata = IS_OPER(user) ? MapOperInfo(Current) : "";
- snprintf(text, 126, "%s %s%5d [%5.2f%%]%s", Current->GetName().c_str(), spacer, Current->GetUserCount(), percent, operdata.c_str());
- totusers += Current->GetUserCount();
- totservers++;
- strlcpy(&matrix[line][depth],text,126);
- line++;
- for (unsigned int q = 0; q < Current->ChildCount(); q++)
- {
- if ((Current->GetChild(q)->Hidden) || ((Utils->HideULines) && (ServerInstance->ULine(Current->GetChild(q)->GetName().c_str()))))
- {
- if (*user->oper)
- {
- ShowMap(Current->GetChild(q),user,(Utils->FlatLinks && (!*user->oper)) ? depth : depth+2,matrix,totusers,totservers);
- }
- }
- else
- {
- ShowMap(Current->GetChild(q),user,(Utils->FlatLinks && (!*user->oper)) ? depth : depth+2,matrix,totusers,totservers);
- }
- }
- }
-}
-
-int ModuleSpanningTree::HandleMotd(const char** parameters, int pcnt, userrec* user)
-{
- if (pcnt > 0)
- {
- if (match(ServerInstance->Config->ServerName, parameters[0]))
- return 0;
-
- /* Remote MOTD, the server is within the 1st parameter */
- std::deque<std::string> params;
- params.push_back(parameters[0]);
- /* Send it out remotely, generate no reply yet */
- TreeServer* s = Utils->FindServerMask(parameters[0]);
- if (s)
- {
- params[0] = s->GetName();
- Utils->DoOneToOne(user->uuid, "MOTD", params, s->GetName());
- }
- else
- user->WriteServ( "402 %s %s :No such server", user->nick, parameters[0]);
- return 1;
- }
- return 0;
-}
-
-int ModuleSpanningTree::HandleAdmin(const char** parameters, int pcnt, userrec* user)
-{
- if (pcnt > 0)
- {
- if (match(ServerInstance->Config->ServerName, parameters[0]))
- return 0;
-
- /* Remote ADMIN, the server is within the 1st parameter */
- std::deque<std::string> params;
- params.push_back(parameters[0]);
- /* Send it out remotely, generate no reply yet */
- TreeServer* s = Utils->FindServerMask(parameters[0]);
- if (s)
- {
- params[0] = s->GetName();
- Utils->DoOneToOne(user->uuid, "ADMIN", params, s->GetName());
- }
- else
- user->WriteServ( "402 %s %s :No such server", user->nick, parameters[0]);
- return 1;
- }
- return 0;
-}
-
-int ModuleSpanningTree::HandleModules(const char** parameters, int pcnt, userrec* user)
-{
- if (pcnt > 0)
- {
- if (match(ServerInstance->Config->ServerName, parameters[0]))
- return 0;
-
- std::deque<std::string> params;
- params.push_back(parameters[0]);
- TreeServer* s = Utils->FindServerMask(parameters[0]);
- if (s)
- {
- params[0] = s->GetName();
- Utils->DoOneToOne(user->uuid, "MODULES", params, s->GetName());
- }
- else
- user->WriteServ( "402 %s %s :No such server", user->nick, parameters[0]);
- return 1;
- }
- return 0;
-}
-
-int ModuleSpanningTree::HandleStats(const char** parameters, int pcnt, userrec* user)
-{
- if (pcnt > 1)
- {
- if (match(ServerInstance->Config->ServerName, parameters[1]))
- return 0;
-
- /* Remote STATS, the server is within the 2nd parameter */
- std::deque<std::string> params;
- params.push_back(parameters[0]);
- params.push_back(parameters[1]);
- /* Send it out remotely, generate no reply yet */
-
- TreeServer* s = Utils->FindServerMask(parameters[1]);
- if (s)
- {
- params[1] = s->GetName();
- Utils->DoOneToOne(user->uuid, "STATS", params, s->GetName());
- }
- else
- {
- user->WriteServ( "402 %s %s :No such server", user->nick, parameters[1]);
- }
- return 1;
- }
- return 0;
-}
-
-// Ok, prepare to be confused.
-// After much mulling over how to approach this, it struck me that
-// the 'usual' way of doing a /MAP isnt the best way. Instead of
-// keeping track of a ton of ascii characters, and line by line
-// under recursion working out where to place them using multiplications
-// and divisons, we instead render the map onto a backplane of characters
-// (a character matrix), then draw the branches as a series of "L" shapes
-// from the nodes. This is not only friendlier on CPU it uses less stack.
-void ModuleSpanningTree::HandleMap(const char** parameters, int pcnt, userrec* user)
-{
- // This array represents a virtual screen which we will
- // "scratch" draw to, as the console device of an irc
- // client does not provide for a proper terminal.
- float totusers = 0;
- float totservers = 0;
- char matrix[128][128];
- for (unsigned int t = 0; t < 128; t++)
- {
- matrix[t][0] = '\0';
- }
- line = 0;
- // The only recursive bit is called here.
- ShowMap(Utils->TreeRoot,user,0,matrix,totusers,totservers);
- // Process each line one by one. The algorithm has a limit of
- // 128 servers (which is far more than a spanning tree should have
- // anyway, so we're ok). This limit can be raised simply by making
- // the character matrix deeper, 128 rows taking 10k of memory.
- for (int l = 1; l < line; l++)
- {
- // scan across the line looking for the start of the
- // servername (the recursive part of the algorithm has placed
- // the servers at indented positions depending on what they
- // are related to)
- int first_nonspace = 0;
- while (matrix[l][first_nonspace] == ' ')
- {
- first_nonspace++;
- }
- first_nonspace--;
- // Draw the `- (corner) section: this may be overwritten by
- // another L shape passing along the same vertical pane, becoming
- // a |- (branch) section instead.
- matrix[l][first_nonspace] = '-';
- matrix[l][first_nonspace-1] = '`';
- int l2 = l - 1;
- // Draw upwards until we hit the parent server, causing possibly
- // other corners (`-) to become branches (|-)
- while ((matrix[l2][first_nonspace-1] == ' ') || (matrix[l2][first_nonspace-1] == '`'))
- {
- matrix[l2][first_nonspace-1] = '|';
- l2--;
- }
- }
- // dump the whole lot to the user. This is the easy bit, honest.
- for (int t = 0; t < line; t++)
- {
- user->WriteServ("006 %s :%s",user->nick,&matrix[t][0]);
- }
- float avg_users = totusers / totservers;
- user->WriteServ("270 %s :%.0f server%s and %.0f user%s, average %.2f users per server",user->nick,totservers,(totservers > 1 ? "s" : ""),totusers,(totusers > 1 ? "s" : ""),avg_users);
- user->WriteServ("007 %s :End of /MAP",user->nick);
- return;
-}
-
-int ModuleSpanningTree::HandleSquit(const char** parameters, int pcnt, userrec* user)
-{
- TreeServer* s = Utils->FindServerMask(parameters[0]);
- if (s)
- {
- if (s == Utils->TreeRoot)
- {
- user->WriteServ("NOTICE %s :*** SQUIT: Foolish mortal, you cannot make a server SQUIT itself! (%s matches local server name)",user->nick,parameters[0]);
- return 1;
- }
- TreeSocket* sock = s->GetSocket();
- if (sock)
- {
- ServerInstance->SNO->WriteToSnoMask('l',"SQUIT: Server \002%s\002 removed from network by %s",parameters[0],user->nick);
- sock->Squit(s,std::string("Server quit by ") + user->GetFullRealHost());
- ServerInstance->SE->DelFd(sock);
- sock->Close();
- }
- else
- {
- if (IS_LOCAL(user))
- user->WriteServ("NOTICE %s :*** WARNING: Using SQUIT to split remote servers is deprecated. Please use RSQUIT instead.",user->nick);
- }
- }
- else
- {
- user->WriteServ("NOTICE %s :*** SQUIT: The server \002%s\002 does not exist on the network.",user->nick,parameters[0]);
- }
- return 1;
-}
-
-int ModuleSpanningTree::HandleTime(const char** parameters, int pcnt, userrec* user)
-{
- if ((IS_LOCAL(user)) && (pcnt))
- {
- TreeServer* found = Utils->FindServerMask(parameters[0]);
- if (found)
- {
- // we dont' override for local server
- if (found == Utils->TreeRoot)
- return 0;
-
- std::deque<std::string> params;
- params.push_back(found->GetName());
- params.push_back(user->uuid);
- Utils->DoOneToOne(ServerInstance->Config->GetSID(),"TIME",params,found->GetName());
- }
- else
- {
- user->WriteServ("402 %s %s :No such server",user->nick,parameters[0]);
- }
- }
- return 1;
-}
-
-int ModuleSpanningTree::HandleRemoteWhois(const char** parameters, int pcnt, userrec* user)
-{
- if ((IS_LOCAL(user)) && (pcnt > 1))
- {
- userrec* remote = ServerInstance->FindNick(parameters[1]);
- if ((remote) && (remote->GetFd() < 0))
- {
- std::deque<std::string> params;
- params.push_back(parameters[1]);
- Utils->DoOneToOne(user->uuid,"IDLE",params,remote->server);
- return 1;
- }
- else if (!remote)
- {
- user->WriteServ("401 %s %s :No such nick/channel",user->nick, parameters[1]);
- user->WriteServ("318 %s %s :End of /WHOIS list.",user->nick, parameters[1]);
- return 1;
- }
- }
- return 0;
-}
-
void ModuleSpanningTree::DoPingChecks(time_t curtime)
{
for (unsigned int j = 0; j < Utils->TreeRoot->ChildCount(); j++)
@@ -705,152 +404,6 @@ void ModuleSpanningTree::BroadcastTimeSync()
}
}
-int ModuleSpanningTree::OnStats(char statschar, userrec* user, string_list &results)
-{
- if ((statschar == 'c') || (statschar == 'n'))
- {
- for (unsigned int i = 0; i < Utils->LinkBlocks.size(); i++)
- {
- results.push_back(std::string(ServerInstance->Config->ServerName)+" 213 "+user->nick+" "+statschar+" *@"+(Utils->LinkBlocks[i].HiddenFromStats ? "<hidden>" : Utils->LinkBlocks[i].IPAddr)+" * "+Utils->LinkBlocks[i].Name.c_str()+" "+ConvToStr(Utils->LinkBlocks[i].Port)+" "+(Utils->LinkBlocks[i].Hook.empty() ? "plaintext" : Utils->LinkBlocks[i].Hook)+" "+(Utils->LinkBlocks[i].AutoConnect ? 'a' : '-')+'s');
- if (statschar == 'c')
- results.push_back(std::string(ServerInstance->Config->ServerName)+" 244 "+user->nick+" H * * "+Utils->LinkBlocks[i].Name.c_str());
- }
- results.push_back(std::string(ServerInstance->Config->ServerName)+" 219 "+user->nick+" "+statschar+" :End of /STATS report");
- ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)",(!strcmp(user->server,ServerInstance->Config->ServerName) ? "Stats" : "Remote stats"),statschar,user->nick,user->ident,user->host);
- return 1;
- }
-
- if (statschar == 'p')
- {
- /* show all server ports, after showing client ports. -- w00t */
-
- for (unsigned int i = 0; i < Utils->Bindings.size(); i++)
- {
- std::string ip = Utils->Bindings[i]->IP;
- if (ip.empty())
- ip = "*";
-
- std::string transport("plaintext");
- if (Utils->Bindings[i]->GetHook())
- transport = InspSocketNameRequest(this, Utils->Bindings[i]->GetHook()).Send();
-
- results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr(Utils->Bindings[i]->port)+
- " (server, " + transport + ")");
- }
- }
- return 0;
-}
-
-int ModuleSpanningTree::OnPreCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, bool validated, const std::string &original_line)
-{
- /* If the command doesnt appear to be valid, we dont want to mess with it. */
- if (!validated)
- return 0;
-
- if (command == "CONNECT")
- {
- return this->HandleConnect(parameters,pcnt,user);
- }
- else if (command == "STATS")
- {
- return this->HandleStats(parameters,pcnt,user);
- }
- else if (command == "MOTD")
- {
- return this->HandleMotd(parameters,pcnt,user);
- }
- else if (command == "ADMIN")
- {
- return this->HandleAdmin(parameters,pcnt,user);
- }
- else if (command == "SQUIT")
- {
- return this->HandleSquit(parameters,pcnt,user);
- }
- else if (command == "MAP")
- {
- this->HandleMap(parameters,pcnt,user);
- return 1;
- }
- else if ((command == "TIME") && (pcnt > 0))
- {
- return this->HandleTime(parameters,pcnt,user);
- }
- else if (command == "LUSERS")
- {
- this->HandleLusers(parameters,pcnt,user);
- return 1;
- }
- else if (command == "LINKS")
- {
- this->HandleLinks(parameters,pcnt,user);
- return 1;
- }
- else if (command == "WHOIS")
- {
- if (pcnt > 1)
- {
- // remote whois
- return this->HandleRemoteWhois(parameters,pcnt,user);
- }
- }
- else if ((command == "VERSION") && (pcnt > 0))
- {
- this->HandleVersion(parameters,pcnt,user);
- return 1;
- }
- else if ((command == "MODULES") && (pcnt > 0))
- {
- return this->HandleModules(parameters,pcnt,user);
- }
- return 0;
-}
-
-void ModuleSpanningTree::OnPostCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, CmdResult result, const std::string &original_line)
-{
- if ((result == CMD_SUCCESS) && (ServerInstance->IsValidModuleCommand(command, pcnt, user)))
- {
- /* Safe, we know its non-null because IsValidModuleCommand returned true */
- command_t* thiscmd = ServerInstance->Parser->GetHandler(command);
- // this bit of code cleverly routes all module commands
- // to all remote severs *automatically* so that modules
- // can just handle commands locally, without having
- // to have any special provision in place for remote
- // commands and linking protocols.
- std::deque<std::string> params;
- params.clear();
- int n_translate = thiscmd->translation.size();
- TranslateType translate_to;
-
- /* To make sure that parameters with spaces, or empty
- * parameters, etc, are always sent properly, *always*
- * prefix the last parameter with a :. This also removes
- * an extra strchr() */
- for (int j = 0; j < pcnt; j++)
- {
- std::string target;
-
- /* Map all items to UUIDs where neccessary */
- if (j < n_translate)
- {
- /* We have a translation mapping for this index */
- translate_to = thiscmd->translation[j] != TR_END ? thiscmd->translation[j] : TR_TEXT;
- }
- else
- translate_to = TR_TEXT;
-
- ServerInstance->Log(DEBUG,"TRANSLATION: %s - type is %d", parameters[j], translate_to);
- ServerInstance->Parser->TranslateUIDs(translate_to, parameters[j], target);
-
- if (j == (pcnt - 1))
- params.push_back(":" + target);
- else
- params.push_back(target);
- }
- Utils->DoOneToMany(user->uuid, command, params);
- }
-}
-
void ModuleSpanningTree::OnGetServerDescription(const std::string &servername,std::string &description)
{
TreeServer* s = Utils->FindServer(servername);
diff --git a/src/modules/m_spanningtree/override_admin.cpp b/src/modules/m_spanningtree/override_admin.cpp
new file mode 100644
index 000000000..86ea216f2
--- /dev/null
+++ b/src/modules/m_spanningtree/override_admin.cpp
@@ -0,0 +1,59 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+int ModuleSpanningTree::HandleAdmin(const char** parameters, int pcnt, userrec* user)
+{
+ if (pcnt > 0)
+ {
+ if (match(ServerInstance->Config->ServerName, parameters[0]))
+ return 0;
+
+ /* Remote ADMIN, the server is within the 1st parameter */
+ std::deque<std::string> params;
+ params.push_back(parameters[0]);
+ /* Send it out remotely, generate no reply yet */
+ TreeServer* s = Utils->FindServerMask(parameters[0]);
+ if (s)
+ {
+ params[0] = s->GetName();
+ Utils->DoOneToOne(user->uuid, "ADMIN", params, s->GetName());
+ }
+ else
+ user->WriteServ( "402 %s %s :No such server", user->nick, parameters[0]);
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/src/modules/m_spanningtree/override_map.cpp b/src/modules/m_spanningtree/override_map.cpp
new file mode 100644
index 000000000..a6bff8aba
--- /dev/null
+++ b/src/modules/m_spanningtree/override_map.cpp
@@ -0,0 +1,162 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+const std::string ModuleSpanningTree::MapOperInfo(TreeServer* Current)
+{
+ time_t secs_up = ServerInstance->Time() - Current->age;
+ return (" [Up: " + TimeToStr(secs_up) + " Lag: "+ConvToStr(Current->rtt)+"ms]");
+}
+
+// WARNING: NOT THREAD SAFE - DONT GET ANY SMART IDEAS.
+void ModuleSpanningTree::ShowMap(TreeServer* Current, userrec* user, int depth, char matrix[128][128], float &totusers, float &totservers)
+{
+ if (line < 128)
+ {
+ for (int t = 0; t < depth; t++)
+ {
+ matrix[line][t] = ' ';
+ }
+ // For Aligning, we need to work out exactly how deep this thing is, and produce
+ // a 'Spacer' String to compensate.
+ char spacer[40];
+ memset(spacer,' ',40);
+ if ((40 - Current->GetName().length() - depth) > 1) {
+ spacer[40 - Current->GetName().length() - depth] = '\0';
+ }
+ else
+ {
+ spacer[5] = '\0';
+ }
+ float percent;
+ char text[128];
+ /* Neat and tidy default values, as we're dealing with a matrix not a simple string */
+ memset(text, 0, 128);
+
+ if (ServerInstance->clientlist->size() == 0) {
+ // If there are no users, WHO THE HELL DID THE /MAP?!?!?!
+ percent = 0;
+ }
+ else
+ {
+ percent = ((float)Current->GetUserCount() / (float)ServerInstance->clientlist->size()) * 100;
+ }
+ const std::string operdata = IS_OPER(user) ? MapOperInfo(Current) : "";
+ snprintf(text, 126, "%s %s%5d [%5.2f%%]%s", Current->GetName().c_str(), spacer, Current->GetUserCount(), percent, operdata.c_str());
+ totusers += Current->GetUserCount();
+ totservers++;
+ strlcpy(&matrix[line][depth],text,126);
+ line++;
+ for (unsigned int q = 0; q < Current->ChildCount(); q++)
+ {
+ if ((Current->GetChild(q)->Hidden) || ((Utils->HideULines) && (ServerInstance->ULine(Current->GetChild(q)->GetName().c_str()))))
+ {
+ if (*user->oper)
+ {
+ ShowMap(Current->GetChild(q),user,(Utils->FlatLinks && (!*user->oper)) ? depth : depth+2,matrix,totusers,totservers);
+ }
+ }
+ else
+ {
+ ShowMap(Current->GetChild(q),user,(Utils->FlatLinks && (!*user->oper)) ? depth : depth+2,matrix,totusers,totservers);
+ }
+ }
+ }
+}
+
+
+// Ok, prepare to be confused.
+// After much mulling over how to approach this, it struck me that
+// the 'usual' way of doing a /MAP isnt the best way. Instead of
+// keeping track of a ton of ascii characters, and line by line
+// under recursion working out where to place them using multiplications
+// and divisons, we instead render the map onto a backplane of characters
+// (a character matrix), then draw the branches as a series of "L" shapes
+// from the nodes. This is not only friendlier on CPU it uses less stack.
+void ModuleSpanningTree::HandleMap(const char** parameters, int pcnt, userrec* user)
+{
+ // This array represents a virtual screen which we will
+ // "scratch" draw to, as the console device of an irc
+ // client does not provide for a proper terminal.
+ float totusers = 0;
+ float totservers = 0;
+ char matrix[128][128];
+ for (unsigned int t = 0; t < 128; t++)
+ {
+ matrix[t][0] = '\0';
+ }
+ line = 0;
+ // The only recursive bit is called here.
+ ShowMap(Utils->TreeRoot,user,0,matrix,totusers,totservers);
+ // Process each line one by one. The algorithm has a limit of
+ // 128 servers (which is far more than a spanning tree should have
+ // anyway, so we're ok). This limit can be raised simply by making
+ // the character matrix deeper, 128 rows taking 10k of memory.
+ for (int l = 1; l < line; l++)
+ {
+ // scan across the line looking for the start of the
+ // servername (the recursive part of the algorithm has placed
+ // the servers at indented positions depending on what they
+ // are related to)
+ int first_nonspace = 0;
+ while (matrix[l][first_nonspace] == ' ')
+ {
+ first_nonspace++;
+ }
+ first_nonspace--;
+ // Draw the `- (corner) section: this may be overwritten by
+ // another L shape passing along the same vertical pane, becoming
+ // a |- (branch) section instead.
+ matrix[l][first_nonspace] = '-';
+ matrix[l][first_nonspace-1] = '`';
+ int l2 = l - 1;
+ // Draw upwards until we hit the parent server, causing possibly
+ // other corners (`-) to become branches (|-)
+ while ((matrix[l2][first_nonspace-1] == ' ') || (matrix[l2][first_nonspace-1] == '`'))
+ {
+ matrix[l2][first_nonspace-1] = '|';
+ l2--;
+ }
+ }
+ // dump the whole lot to the user. This is the easy bit, honest.
+ for (int t = 0; t < line; t++)
+ {
+ user->WriteServ("006 %s :%s",user->nick,&matrix[t][0]);
+ }
+ float avg_users = totusers / totservers;
+ user->WriteServ("270 %s :%.0f server%s and %.0f user%s, average %.2f users per server",user->nick,totservers,(totservers > 1 ? "s" : ""),totusers,(totusers > 1 ? "s" : ""),avg_users);
+ user->WriteServ("007 %s :End of /MAP",user->nick);
+ return;
+}
+
diff --git a/src/modules/m_spanningtree/override_modules.cpp b/src/modules/m_spanningtree/override_modules.cpp
new file mode 100644
index 000000000..2e2a4dd86
--- /dev/null
+++ b/src/modules/m_spanningtree/override_modules.cpp
@@ -0,0 +1,57 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+int ModuleSpanningTree::HandleModules(const char** parameters, int pcnt, userrec* user)
+{
+ if (pcnt > 0)
+ {
+ if (match(ServerInstance->Config->ServerName, parameters[0]))
+ return 0;
+
+ std::deque<std::string> params;
+ params.push_back(parameters[0]);
+ TreeServer* s = Utils->FindServerMask(parameters[0]);
+ if (s)
+ {
+ params[0] = s->GetName();
+ Utils->DoOneToOne(user->uuid, "MODULES", params, s->GetName());
+ }
+ else
+ user->WriteServ( "402 %s %s :No such server", user->nick, parameters[0]);
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/src/modules/m_spanningtree/override_motd.cpp b/src/modules/m_spanningtree/override_motd.cpp
new file mode 100644
index 000000000..ce9f5b5e1
--- /dev/null
+++ b/src/modules/m_spanningtree/override_motd.cpp
@@ -0,0 +1,59 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+int ModuleSpanningTree::HandleMotd(const char** parameters, int pcnt, userrec* user)
+{
+ if (pcnt > 0)
+ {
+ if (match(ServerInstance->Config->ServerName, parameters[0]))
+ return 0;
+
+ /* Remote MOTD, the server is within the 1st parameter */
+ std::deque<std::string> params;
+ params.push_back(parameters[0]);
+ /* Send it out remotely, generate no reply yet */
+ TreeServer* s = Utils->FindServerMask(parameters[0]);
+ if (s)
+ {
+ params[0] = s->GetName();
+ Utils->DoOneToOne(user->uuid, "MOTD", params, s->GetName());
+ }
+ else
+ user->WriteServ( "402 %s %s :No such server", user->nick, parameters[0]);
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/src/modules/m_spanningtree/override_squit.cpp b/src/modules/m_spanningtree/override_squit.cpp
new file mode 100644
index 000000000..11f5be135
--- /dev/null
+++ b/src/modules/m_spanningtree/override_squit.cpp
@@ -0,0 +1,66 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+int ModuleSpanningTree::HandleSquit(const char** parameters, int pcnt, userrec* user)
+{
+ TreeServer* s = Utils->FindServerMask(parameters[0]);
+ if (s)
+ {
+ if (s == Utils->TreeRoot)
+ {
+ user->WriteServ("NOTICE %s :*** SQUIT: Foolish mortal, you cannot make a server SQUIT itself! (%s matches local server name)",user->nick,parameters[0]);
+ return 1;
+ }
+ TreeSocket* sock = s->GetSocket();
+ if (sock)
+ {
+ ServerInstance->SNO->WriteToSnoMask('l',"SQUIT: Server \002%s\002 removed from network by %s",parameters[0],user->nick);
+ sock->Squit(s,std::string("Server quit by ") + user->GetFullRealHost());
+ ServerInstance->SE->DelFd(sock);
+ sock->Close();
+ }
+ else
+ {
+ if (IS_LOCAL(user))
+ user->WriteServ("NOTICE %s :*** WARNING: Using SQUIT to split remote servers is deprecated. Please use RSQUIT instead.",user->nick);
+ }
+ }
+ else
+ {
+ user->WriteServ("NOTICE %s :*** SQUIT: The server \002%s\002 does not exist on the network.",user->nick,parameters[0]);
+ }
+ return 1;
+}
+
diff --git a/src/modules/m_spanningtree/override_stats.cpp b/src/modules/m_spanningtree/override_stats.cpp
new file mode 100644
index 000000000..2e32cc72e
--- /dev/null
+++ b/src/modules/m_spanningtree/override_stats.cpp
@@ -0,0 +1,99 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+int ModuleSpanningTree::HandleStats(const char** parameters, int pcnt, userrec* user)
+{
+ if (pcnt > 1)
+ {
+ if (match(ServerInstance->Config->ServerName, parameters[1]))
+ return 0;
+
+ /* Remote STATS, the server is within the 2nd parameter */
+ std::deque<std::string> params;
+ params.push_back(parameters[0]);
+ params.push_back(parameters[1]);
+ /* Send it out remotely, generate no reply yet */
+
+ TreeServer* s = Utils->FindServerMask(parameters[1]);
+ if (s)
+ {
+ params[1] = s->GetName();
+ Utils->DoOneToOne(user->uuid, "STATS", params, s->GetName());
+ }
+ else
+ {
+ user->WriteServ( "402 %s %s :No such server", user->nick, parameters[1]);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int ModuleSpanningTree::OnStats(char statschar, userrec* user, string_list &results)
+{
+ if ((statschar == 'c') || (statschar == 'n'))
+ {
+ for (unsigned int i = 0; i < Utils->LinkBlocks.size(); i++)
+ {
+ results.push_back(std::string(ServerInstance->Config->ServerName)+" 213 "+user->nick+" "+statschar+" *@"+(Utils->LinkBlocks[i].HiddenFromStats ? "<hidden>" : Utils->LinkBlocks[i].IPAddr)+" * "+Utils->LinkBlocks[i].Name.c_str()+" "+ConvToStr(Utils->LinkBlocks[i].Port)+" "+(Utils->LinkBlocks[i].Hook.empty() ? "plaintext" : Utils->LinkBlocks[i].Hook)+" "+(Utils->LinkBlocks[i].AutoConnect ? 'a': '-')+'s');
+ if (statschar == 'c')
+ results.push_back(std::string(ServerInstance->Config->ServerName)+" 244 "+user->nick+" H * * "+Utils->LinkBlocks[i].Name.c_str());
+ }
+ results.push_back(std::string(ServerInstance->Config->ServerName)+" 219 "+user->nick+" "+statschar+" :End of /STATS report");
+ ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)",(!strcmp(user->server,ServerInstance->Config->ServerName) ? "Stats" : "Remote stats"),statschar,user->nick,user->ident,user->host);
+ return 1;
+ }
+
+ if (statschar == 'p')
+ {
+ /* show all server ports, after showing client ports. -- w00t */
+
+ for (unsigned int i = 0; i < Utils->Bindings.size(); i++)
+ {
+ std::string ip = Utils->Bindings[i]->IP;
+ if (ip.empty())
+ ip = "*";
+
+ std::string transport("plaintext");
+ if (Utils->Bindings[i]->GetHook())
+ transport = InspSocketNameRequest(this, Utils->Bindings[i]->GetHook()).Send();
+
+ results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr(Utils->Bindings[i]->port)+
+ " (server, " + transport + ")");
+ }
+ }
+ return 0;
+}
+
diff --git a/src/modules/m_spanningtree/override_time.cpp b/src/modules/m_spanningtree/override_time.cpp
new file mode 100644
index 000000000..9fa4b15b6
--- /dev/null
+++ b/src/modules/m_spanningtree/override_time.cpp
@@ -0,0 +1,59 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+int ModuleSpanningTree::HandleTime(const char** parameters, int pcnt, userrec* user)
+{
+ if ((IS_LOCAL(user)) && (pcnt))
+ {
+ TreeServer* found = Utils->FindServerMask(parameters[0]);
+ if (found)
+ {
+ // we dont' override for local server
+ if (found == Utils->TreeRoot)
+ return 0;
+
+ std::deque<std::string> params;
+ params.push_back(found->GetName());
+ params.push_back(user->uuid);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(),"TIME",params,found->GetName());
+ }
+ else
+ {
+ user->WriteServ("402 %s %s :No such server",user->nick,parameters[0]);
+ }
+ }
+ return 1;
+}
+
diff --git a/src/modules/m_spanningtree/override_whois.cpp b/src/modules/m_spanningtree/override_whois.cpp
new file mode 100644
index 000000000..15488e71c
--- /dev/null
+++ b/src/modules/m_spanningtree/override_whois.cpp
@@ -0,0 +1,57 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+int ModuleSpanningTree::HandleRemoteWhois(const char** parameters, int pcnt, userrec* user)
+{
+ if ((IS_LOCAL(user)) && (pcnt > 1))
+ {
+ userrec* remote = ServerInstance->FindNick(parameters[1]);
+ if ((remote) && (remote->GetFd() < 0))
+ {
+ std::deque<std::string> params;
+ params.push_back(parameters[1]);
+ Utils->DoOneToOne(user->uuid,"IDLE",params,remote->server);
+ return 1;
+ }
+ else if (!remote)
+ {
+ user->WriteServ("401 %s %s :No such nick/channel",user->nick, parameters[1]);
+ user->WriteServ("318 %s %s :End of /WHOIS list.",user->nick, parameters[1]);
+ return 1;
+ }
+ }
+ return 0;
+}
+
diff --git a/src/modules/m_spanningtree/postcommand.cpp b/src/modules/m_spanningtree/postcommand.cpp
new file mode 100644
index 000000000..44476c8c7
--- /dev/null
+++ b/src/modules/m_spanningtree/postcommand.cpp
@@ -0,0 +1,80 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+void ModuleSpanningTree::OnPostCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, CmdResult result, const std::string &original_line)
+{
+ if ((result == CMD_SUCCESS) && (ServerInstance->IsValidModuleCommand(command, pcnt, user)))
+ {
+ /* Safe, we know its non-null because IsValidModuleCommand returned true */
+ command_t* thiscmd = ServerInstance->Parser->GetHandler(command);
+ // this bit of code cleverly routes all module commands
+ // to all remote severs *automatically* so that modules
+ // can just handle commands locally, without having
+ // to have any special provision in place for remote
+ // commands and linking protocols.
+ std::deque<std::string> params;
+ params.clear();
+ int n_translate = thiscmd->translation.size();
+ TranslateType translate_to;
+
+ /* To make sure that parameters with spaces, or empty
+ * parameters, etc, are always sent properly, *always*
+ * prefix the last parameter with a :. This also removes
+ * an extra strchr() */
+ for (int j = 0; j < pcnt; j++)
+ {
+ std::string target;
+
+ /* Map all items to UUIDs where neccessary */
+ if (j < n_translate)
+ {
+ /* We have a translation mapping for this index */
+ translate_to = thiscmd->translation[j] != TR_END ? thiscmd->translation[j] : TR_TEXT;
+ }
+ else
+ translate_to = TR_TEXT;
+
+ ServerInstance->Log(DEBUG,"TRANSLATION: %s - type is %d", parameters[j], translate_to);
+ ServerInstance->Parser->TranslateUIDs(translate_to, parameters[j], target);
+
+ if (j == (pcnt - 1))
+ params.push_back(":" + target);
+ else
+ params.push_back(target);
+ }
+ Utils->DoOneToMany(user->uuid, command, params);
+ }
+}
+
diff --git a/src/modules/m_spanningtree/precommand.cpp b/src/modules/m_spanningtree/precommand.cpp
new file mode 100644
index 000000000..3fc8febc0
--- /dev/null
+++ b/src/modules/m_spanningtree/precommand.cpp
@@ -0,0 +1,100 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* $ModDesc: Provides a spanning tree server link protocol */
+
+#include "inspircd.h"
+#include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
+#include "socket.h"
+#include "wildcard.h"
+#include "xline.h"
+#include "transport.h"
+
+#include "m_spanningtree/timesynctimer.h"
+#include "m_spanningtree/resolvers.h"
+#include "m_spanningtree/main.h"
+#include "m_spanningtree/utils.h"
+#include "m_spanningtree/treeserver.h"
+#include "m_spanningtree/link.h"
+#include "m_spanningtree/treesocket.h"
+#include "m_spanningtree/rconnect.h"
+#include "m_spanningtree/rsquit.h"
+
+/* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h */
+
+int ModuleSpanningTree::OnPreCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, bool validated, const std::string &original_line)
+{
+ /* If the command doesnt appear to be valid, we dont want to mess with it. */
+ if (!validated)
+ return 0;
+
+ if (command == "CONNECT")
+ {
+ return this->HandleConnect(parameters,pcnt,user);
+ }
+ else if (command == "STATS")
+ {
+ return this->HandleStats(parameters,pcnt,user);
+ }
+ else if (command == "MOTD")
+ {
+ return this->HandleMotd(parameters,pcnt,user);
+ }
+ else if (command == "ADMIN")
+ {
+ return this->HandleAdmin(parameters,pcnt,user);
+ }
+ else if (command == "SQUIT")
+ {
+ return this->HandleSquit(parameters,pcnt,user);
+ }
+ else if (command == "MAP")
+ {
+ this->HandleMap(parameters,pcnt,user);
+ return 1;
+ }
+ else if ((command == "TIME") && (pcnt > 0))
+ {
+ return this->HandleTime(parameters,pcnt,user);
+ }
+ else if (command == "LUSERS")
+ {
+ this->HandleLusers(parameters,pcnt,user);
+ return 1;
+ }
+ else if (command == "LINKS")
+ {
+ this->HandleLinks(parameters,pcnt,user);
+ return 1;
+ }
+ else if (command == "WHOIS")
+ {
+ if (pcnt > 1)
+ {
+ // remote whois
+ return this->HandleRemoteWhois(parameters,pcnt,user);
+ }
+ }
+ else if ((command == "VERSION") && (pcnt > 0))
+ {
+ this->HandleVersion(parameters,pcnt,user);
+ return 1;
+ }
+ else if ((command == "MODULES") && (pcnt > 0))
+ {
+ return this->HandleModules(parameters,pcnt,user);
+ }
+ return 0;
+}
+