X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree.cpp;h=0725d7b51767dab0ea2d9c40a8b27b7418242b6c;hb=4488e477136ea3daa60a744bac272cc37a604136;hp=9957f88a6d55bce6497ae99f28da91c94be13b6b;hpb=83be005aa1f65eb9b33a6bec176e5c44076087cc;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index 9957f88a6..0725d7b51 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -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, irc::StrHashComp> server_hash; server_hash serverlist; +typedef nspace::hash_map uid_hash; +typedef nspace::hash_map sid_hash; + /* More forward declarations */ bool DoOneToOne(std::string prefix, std::string command, std::deque ¶ms, std::string target); bool DoOneToAllButSender(std::string prefix, std::string command, std::deque ¶ms, std::string omit); @@ -135,6 +139,53 @@ extern std::vector pzlines; extern std::vector pqlines; extern std::vector 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 ¶ms) + { + /* 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 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 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 ? "" : 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 ? "" : 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);