]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree.cpp
The IPV6 stuff compiles now, with compile-correct ipv6 code. I dont know if this...
[user/henk/code/inspircd.git] / src / modules / m_spanningtree.cpp
index 9957f88a6d55bce6497ae99f28da91c94be13b6b..0725d7b51767dab0ea2d9c40a8b27b7418242b6c 100644 (file)
@@ -30,6 +30,7 @@ using namespace std;
 #include "modules.h"
 #include "commands.h"
 #include "commands/cmd_whois.h"
+#include "commands/cmd_stats.h"
 #include "socket.h"
 #include "helperfuncs.h"
 #include "inspircd.h"
@@ -111,6 +112,9 @@ static Server* Srv;
 typedef nspace::hash_map<std::string, TreeServer*, nspace::hash<string>, irc::StrHashComp> server_hash;
 server_hash serverlist;
 
+typedef nspace::hash_map<std::string, userrec*> uid_hash;
+typedef nspace::hash_map<std::string, char*> sid_hash;
+
 /* More forward declarations */
 bool DoOneToOne(std::string prefix, std::string command, std::deque<std::string> &params, std::string target);
 bool DoOneToAllButSender(std::string prefix, std::string command, std::deque<std::string> &params, std::string omit);
@@ -135,6 +139,53 @@ extern std::vector<ZLine> pzlines;
 extern std::vector<QLine> pqlines;
 extern std::vector<ELine> pelines;
 
+class UserManager : public classbase
+{
+       uid_hash uids;
+       sid_hash sids;
+ public:
+       UserManager()
+       {
+               uids.clear();
+               sids.clear();
+       }
+
+       std::string UserToUID(userrec* user)
+       {
+               return "";
+       }
+
+       std::string UIDToUser(const std::string &UID)
+       {
+               return "";
+       }
+
+       std::string CreateAndAdd(userrec* user)
+       {
+               return "";
+       }
+
+       std::string CreateAndAdd(const std::string &servername)
+       {
+               return "";
+       }
+
+       std::string ServerToSID(const std::string &servername)
+       {
+               return "";
+       }
+
+       std::string SIDToServer(const std::string &SID)
+       {
+               return "";
+       }
+
+       userrec* FindByID(const std::string &UID)
+       {
+               return NULL;
+       }
+};
+
 /* Each server in the tree is represented by one class of
  * type TreeServer. A locally connected TreeServer can
  * have a class of type TreeSocket associated with it, for
@@ -1509,9 +1560,9 @@ class TreeSocket : public InspSocket
                {
                        clientlist[tempnick]->modes[(*v)-65] = 1;
                }
-               inet_aton(params[6].c_str(),&clientlist[tempnick]->ip4);
+               insp_aton(params[6].c_str(),&clientlist[tempnick]->ip4);
 
-               WriteOpers("*** Client connecting at %s: %s!%s@%s [%s]",clientlist[tempnick]->server,clientlist[tempnick]->nick,clientlist[tempnick]->ident,clientlist[tempnick]->host, inet_ntoa(clientlist[tempnick]->ip4));
+               WriteOpers("*** Client connecting at %s: %s!%s@%s [%s]",clientlist[tempnick]->server,clientlist[tempnick]->nick,clientlist[tempnick]->ident,clientlist[tempnick]->host, insp_ntoa(clientlist[tempnick]->ip4));
 
                params[7] = ":" + params[7];
                DoOneToAllButSender(source,"NICK",params,source);
@@ -1716,7 +1767,7 @@ class TreeSocket : public InspSocket
                {
                        if (u->second->registered == REG_ALL)
                        {
-                               snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->FormatModes(),inet_ntoa(u->second->ip4),u->second->fullname);
+                               snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->FormatModes(),insp_ntoa(u->second->ip4),u->second->fullname);
                                this->WriteLine(data);
                                if (*u->second->oper)
                                {
@@ -1866,6 +1917,43 @@ class TreeSocket : public InspSocket
                return false;
        }
 
+       bool Stats(std::string prefix, std::deque<std::string> &params)
+       {
+               /* Get the reply to a STATS query if it matches this servername,
+                * and send it back as a load of PUSH queries
+                */
+               if (params.size() > 1)
+               {
+                       if (Srv->MatchText(Srv->GetServerName(), params[1]))
+                       {
+                               /* It's for our server */
+                               string_list results;
+                               userrec* source = Srv->FindNick(prefix);
+                               if (source)
+                               {
+                                       std::deque<std::string> par;
+                                       par.push_back(prefix);
+                                       par.push_back("");
+                                       DoStats(*(params[0].c_str()), source, results);
+                                       for (size_t i = 0; i < results.size(); i++)
+                                       {
+                                               par[1] = "::" + results[i];
+                                               DoOneToOne(Srv->GetServerName(), "PUSH",par, source->server);
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               /* Pass it on */
+                               userrec* source = Srv->FindNick(prefix);
+                               if (source)
+                                       DoOneToOne(prefix, "STATS", params, params[1]);
+                       }
+               }
+               return true;
+       }
+
+
        /* Because the core won't let users or even SERVERS set +o,
         * we use the OPERTYPE command to do this.
         */
@@ -2230,15 +2318,7 @@ class TreeSocket : public InspSocket
 
                if (IS_LOCAL(u))
                {
-                       // push the raw to the user
-                       if (Srv->IsUlined(prefix))
-                       {
-                               ::Write(u->fd,"%s",params[1].c_str());
-                       }
-                       else
-                       {
-                               log(DEBUG,"PUSH from non-ulined server dropped into the bit-bucket:  :%s PUSH %s :%s",prefix.c_str(),params[0].c_str(),params[1].c_str());
-                       }
+                       ::Write(u->fd,"%s",params[1].c_str());
                }
                else
                {
@@ -2680,6 +2760,10 @@ class TreeSocket : public InspSocket
                                {
                                        return this->ForceJoin(prefix,params);
                                }
+                               else if (command == "STATS")
+                               {
+                                       return this->Stats(prefix, params);
+                               }
                                else if (command == "SERVER")
                                {
                                        return this->RemoteServer(prefix,params);
@@ -2959,7 +3043,7 @@ class TreeSocket : public InspSocket
                        /* XXX: Fixme: blocks for a very short amount of time,
                         * we should cache these on rehash/startup
                         */
-                       if (CleanAndResolve(resolved_host,i->IPAddr.c_str(),true))
+                       if (CleanAndResolve(resolved_host,i->IPAddr.c_str(),true,1))
                        {
                                if (std::string(resolved_host) == ip)
                                {
@@ -3380,6 +3464,26 @@ class ModuleSpanningTree : public Module
                }
        }
 
+       int HandleStats(const char** parameters, int pcnt, userrec* user)
+       {
+               if (pcnt > 1)
+               {
+                       /* 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 = FindServerMask(parameters[1]);
+                       if (s)
+                       {
+                               params[1] = s->GetName();
+                               DoOneToOne(user->nick, "STATS", params, s->GetName());
+                       }
+                       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
@@ -3647,17 +3751,17 @@ class ModuleSpanningTree : public Module
                return 1;
        }
 
-       virtual int OnStats(char statschar, userrec* user)
+       virtual int OnStats(char statschar, userrec* user, string_list &results)
        {
                if (statschar == 'c')
                {
                        for (unsigned int i = 0; i < LinkBlocks.size(); i++)
                        {
-                               WriteServ(user->fd,"213 %s C *@%s * %s %d 0 %c%c%c",user->nick,(LinkBlocks[i].HiddenFromStats ? "<hidden>" : LinkBlocks[i].IPAddr).c_str(),LinkBlocks[i].Name.c_str(),LinkBlocks[i].Port,(LinkBlocks[i].EncryptionKey != "" ? 'e' : '-'),(LinkBlocks[i].AutoConnect ? 'a' : '-'),'s');
-                               WriteServ(user->fd,"244 %s H * * %s",user->nick,LinkBlocks[i].Name.c_str());
+                               results.push_back(Srv->GetServerName()+" 213 "+user->nick+" C *@"+(LinkBlocks[i].HiddenFromStats ? "<hidden>" : LinkBlocks[i].IPAddr)+" * "+LinkBlocks[i].Name.c_str()+" "+ConvToStr(LinkBlocks[i].Port)+" "+(LinkBlocks[i].EncryptionKey != "" ? 'e' : '-')+(LinkBlocks[i].AutoConnect ? 'a' : '-')+'s');
+                               results.push_back(Srv->GetServerName()+" 244 "+user->nick+" H * * "+LinkBlocks[i].Name.c_str());
                        }
-                       WriteServ(user->fd,"219 %s %c :End of /STATS report",user->nick,statschar);
-                       WriteOpers("*** Notice: Stats '%c' requested by %s (%s@%s)",statschar,user->nick,user->ident,user->host);
+                       results.push_back(Srv->GetServerName()+" 219 "+user->nick+" "+statschar+" :End of /STATS report");
+                       WriteOpers("*** Notice: %s '%c' requested by %s (%s@%s)",(!strcmp(user->server,Config->ServerName) ? "Stats" : "Remote stats"),statschar,user->nick,user->ident,user->host);
                        return 1;
                }
                return 0;
@@ -3673,6 +3777,10 @@ class ModuleSpanningTree : public Module
                {
                        return this->HandleConnect(parameters,pcnt,user);
                }
+               else if (command == "STATS")
+               {
+                       return this->HandleStats(parameters,pcnt,user);
+               }
                else if (command == "SQUIT")
                {
                        return this->HandleSquit(parameters,pcnt,user);
@@ -3947,7 +4055,7 @@ class ModuleSpanningTree : public Module
                        params.push_back(user->dhost);
                        params.push_back(user->ident);
                        params.push_back("+"+std::string(user->FormatModes()));
-                       params.push_back((char*)inet_ntoa(user->ip4));
+                       params.push_back((char*)insp_ntoa(user->ip4));
                        params.push_back(":"+std::string(user->fullname));
                        DoOneToMany(Srv->GetServerName(),"NICK",params);