X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree%2Fmain.cpp;h=2e743689c090115d8691e4b2952c6129e9b7d826;hb=17a80c5a8ef43675bf0d6937f35c950d7348f9ee;hp=dd6282a631bd4febf7c0abda7333dafa79a48200;hpb=144f168729eb58262660afa4fb0a27445290f7f7;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index dd6282a63..2e743689c 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -36,7 +36,7 @@ ModuleSpanningTree::ModuleSpanningTree(InspIRCd* Me) : Module(Me), max_local(0), max_global(0) { - ServerInstance->UseInterface("InspSocketHook"); + ServerInstance->Modules->UseInterface("BufferedSocketHook"); Utils = new SpanningTreeUtilities(Me, this); command_rconnect = new cmd_rconnect(ServerInstance, this, Utils); ServerInstance->AddCommand(command_rconnect); @@ -54,7 +54,7 @@ ModuleSpanningTree::ModuleSpanningTree(InspIRCd* Me) ServerInstance->Timers->AddTimer(RefreshTimer); } -void ModuleSpanningTree::ShowLinks(TreeServer* Current, userrec* user, int hops) +void ModuleSpanningTree::ShowLinks(TreeServer* Current, User* user, int hops) { std::string Parent = Utils->TreeRoot->GetName(); if (Current->GetParent()) @@ -98,14 +98,14 @@ int ModuleSpanningTree::CountServs() return Utils->serverlist.size(); } -void ModuleSpanningTree::HandleLinks(const char** parameters, int pcnt, userrec* user) +void ModuleSpanningTree::HandleLinks(const char** parameters, int pcnt, User* user) { ShowLinks(Utils->TreeRoot,user,0); user->WriteServ("365 %s * :End of /LINKS list.",user->nick); return; } -void ModuleSpanningTree::HandleLusers(const char** parameters, int pcnt, userrec* user) +void ModuleSpanningTree::HandleLusers(const char** parameters, int pcnt, User* user) { unsigned int n_users = ServerInstance->UserCount(); @@ -134,8 +134,8 @@ void ModuleSpanningTree::HandleLusers(const char** parameters, int pcnt, userrec } } user->WriteServ("251 %s :There are %d users and %d invisible on %d servers",user->nick, - n_users-ServerInstance->InvisibleUserCount(), - ServerInstance->InvisibleUserCount(), + n_users-ServerInstance->ModeCount('i'), + ServerInstance->ModeCount('i'), ulined_count ? this->CountServs() - ulined_count : this->CountServs()); if (ServerInstance->OperCount()) @@ -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 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 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 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 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 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 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++) @@ -480,7 +179,7 @@ void ModuleSpanningTree::DoPingChecks(time_t curtime) { if (serv->AnsweredLastPing()) { - sock->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" PING "+serv->GetName()); + sock->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" PING "+serv->GetID()); serv->SetNextPingTime(curtime + Utils->PingFreq); serv->LastPing = curtime; timeval t; @@ -600,7 +299,7 @@ void ModuleSpanningTree::AutoConnectServers(time_t curtime) } } -int ModuleSpanningTree::HandleVersion(const char** parameters, int pcnt, userrec* user) +int ModuleSpanningTree::HandleVersion(const char** parameters, int pcnt, User* user) { // we've already checked if pcnt > 0, so this is safe TreeServer* found = Utils->FindServerMask(parameters[0]); @@ -627,8 +326,17 @@ int ModuleSpanningTree::HandleVersion(const char** parameters, int pcnt, userrec * If the user is NULL, then the notice is sent locally via WriteToSnoMask with snomask 'l', * and remotely via SNONOTICE with mask 'l'. */ -void ModuleSpanningTree::RemoteMessage(userrec* user, const char* format, ...) -{ +void ModuleSpanningTree::RemoteMessage(User* user, const char* format, ...) +{ + /* This could cause an infinite loop, because DoOneToMany() will, on error, + * call TreeSocket::OnError(), which in turn will call this function to + * notify everyone of the error. So, drop any messages that are generated + * during the sending of another message. -Special */ + static bool SendingRemoteMessage = false; + if (SendingRemoteMessage) + return; + SendingRemoteMessage = true; + std::deque params; char text[MAXBUF]; va_list argsPtr; @@ -657,9 +365,11 @@ void ModuleSpanningTree::RemoteMessage(userrec* user, const char* format, ...) Utils->DoOneToMany(ServerInstance->Config->GetSID(), "PUSH", params); } } + + SendingRemoteMessage = false; } -int ModuleSpanningTree::HandleConnect(const char** parameters, int pcnt, userrec* user) +int ModuleSpanningTree::HandleConnect(const char** parameters, int pcnt, User* user) { for (std::vector::iterator x = Utils->LinkBlocks.begin(); x < Utils->LinkBlocks.end(); x++) { @@ -668,18 +378,18 @@ int ModuleSpanningTree::HandleConnect(const char** parameters, int pcnt, userrec TreeServer* CheckDupe = Utils->FindServer(x->Name.c_str()); if (!CheckDupe) { - RemoteMessage(user, "*** CONNECT: Connecting to server: \002%s\002 (%s:%d)",user->nick,x->Name.c_str(),(x->HiddenFromStats ? "" : x->IPAddr.c_str()),x->Port); + RemoteMessage(user, "*** CONNECT: Connecting to server: \002%s\002 (%s:%d)",x->Name.c_str(),(x->HiddenFromStats ? "" : x->IPAddr.c_str()),x->Port); ConnectServer(&(*x)); return 1; } else { - RemoteMessage(user, "*** CONNECT: Server \002%s\002 already exists on the network and is connected via \002%s\002",user->nick,x->Name.c_str(),CheckDupe->GetParent()->GetName().c_str()); + RemoteMessage(user, "*** CONNECT: Server \002%s\002 already exists on the network and is connected via \002%s\002",x->Name.c_str(),CheckDupe->GetParent()->GetName().c_str()); return 1; } } } - RemoteMessage(user, "NOTICE %s :*** CONNECT: No server matching \002%s\002 could be found in the config file.",user->nick,parameters[0]); + RemoteMessage(user, "*** CONNECT: No server matching \002%s\002 could be found in the config file.",parameters[0]); return 1; } @@ -690,149 +400,7 @@ void ModuleSpanningTree::BroadcastTimeSync() std::deque params; params.push_back(ConvToStr(ServerInstance->Time(false))); params.push_back("FORCE"); - Utils->DoOneToMany(Utils->TreeRoot->GetName(), "TIMESET", params); - } -} - -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 ? "" : 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 params; - params.clear(); - int n_translate = thiscmd->translation.size(); - TranslateType translate_to; - - 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 (strchr(parameters[j],' ')) - params.push_back(":" + target); - else - params.push_back(target); - } - Utils->DoOneToMany(user->uuid, command, params); + Utils->DoOneToMany(ServerInstance->Config->GetSID(), "TIMESET", params); } } @@ -845,7 +413,7 @@ void ModuleSpanningTree::OnGetServerDescription(const std::string &servername,st } } -void ModuleSpanningTree::OnUserInvite(userrec* source,userrec* dest,chanrec* channel) +void ModuleSpanningTree::OnUserInvite(User* source,User* dest,Channel* channel) { if (IS_LOCAL(source)) { @@ -856,7 +424,7 @@ void ModuleSpanningTree::OnUserInvite(userrec* source,userrec* dest,chanrec* cha } } -void ModuleSpanningTree::OnPostLocalTopicChange(userrec* user, chanrec* chan, const std::string &topic) +void ModuleSpanningTree::OnPostLocalTopicChange(User* user, Channel* chan, const std::string &topic) { std::deque params; params.push_back(chan->name); @@ -864,7 +432,7 @@ void ModuleSpanningTree::OnPostLocalTopicChange(userrec* user, chanrec* chan, co Utils->DoOneToMany(user->uuid,"TOPIC",params); } -void ModuleSpanningTree::OnWallops(userrec* user, const std::string &text) +void ModuleSpanningTree::OnWallops(User* user, const std::string &text) { if (IS_LOCAL(user)) { @@ -874,11 +442,11 @@ void ModuleSpanningTree::OnWallops(userrec* user, const std::string &text) } } -void ModuleSpanningTree::OnUserNotice(userrec* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list) +void ModuleSpanningTree::OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list) { if (target_type == TYPE_USER) { - userrec* d = (userrec*)dest; + User* d = (User*)dest; if ((d->GetFd() < 0) && (IS_LOCAL(user))) { std::deque params; @@ -892,7 +460,7 @@ void ModuleSpanningTree::OnUserNotice(userrec* user, void* dest, int target_type { if (IS_LOCAL(user)) { - chanrec *c = (chanrec*)dest; + Channel *c = (Channel*)dest; if (c) { std::string cname = c->name; @@ -922,13 +490,13 @@ void ModuleSpanningTree::OnUserNotice(userrec* user, void* dest, int target_type } } -void ModuleSpanningTree::OnUserMessage(userrec* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list) +void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list) { if (target_type == TYPE_USER) { // route private messages which are targetted at clients only to the server // which needs to receive them - userrec* d = (userrec*)dest; + User* d = (User*)dest; if ((d->GetFd() < 0) && (IS_LOCAL(user))) { std::deque params; @@ -942,7 +510,7 @@ void ModuleSpanningTree::OnUserMessage(userrec* user, void* dest, int target_typ { if (IS_LOCAL(user)) { - chanrec *c = (chanrec*)dest; + Channel *c = (Channel*)dest; if (c) { std::string cname = c->name; @@ -978,7 +546,7 @@ void ModuleSpanningTree::OnBackgroundTimer(time_t curtime) DoPingChecks(curtime); } -void ModuleSpanningTree::OnUserJoin(userrec* user, chanrec* channel, bool &silent) +void ModuleSpanningTree::OnUserJoin(User* user, Channel* channel, bool &silent) { // Only do this for local users if (IS_LOCAL(user)) @@ -1008,7 +576,7 @@ void ModuleSpanningTree::OnUserJoin(userrec* user, chanrec* channel, bool &silen } } -void ModuleSpanningTree::OnChangeHost(userrec* user, const std::string &newhost) +void ModuleSpanningTree::OnChangeHost(User* user, const std::string &newhost) { // only occurs for local clients if (user->registered != REG_ALL) @@ -1018,7 +586,7 @@ void ModuleSpanningTree::OnChangeHost(userrec* user, const std::string &newhost) Utils->DoOneToMany(user->uuid,"FHOST",params); } -void ModuleSpanningTree::OnChangeName(userrec* user, const std::string &gecos) +void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos) { // only occurs for local clients if (user->registered != REG_ALL) @@ -1028,7 +596,7 @@ void ModuleSpanningTree::OnChangeName(userrec* user, const std::string &gecos) Utils->DoOneToMany(user->uuid,"FNAME",params); } -void ModuleSpanningTree::OnUserPart(userrec* user, chanrec* channel, const std::string &partmessage, bool &silent) +void ModuleSpanningTree::OnUserPart(User* user, Channel* channel, const std::string &partmessage, bool &silent) { if (IS_LOCAL(user)) { @@ -1040,21 +608,20 @@ void ModuleSpanningTree::OnUserPart(userrec* user, chanrec* channel, const std:: } } -void ModuleSpanningTree::OnUserConnect(userrec* user) +void ModuleSpanningTree::OnUserConnect(User* user) { - char agestr[MAXBUF]; if (IS_LOCAL(user)) { std::deque params; - snprintf(agestr,MAXBUF,"%lu",(unsigned long)user->age); params.push_back(user->uuid); - params.push_back(agestr); + params.push_back(ConvToStr(user->age)); params.push_back(user->nick); params.push_back(user->host); params.push_back(user->dhost); params.push_back(user->ident); params.push_back("+"+std::string(user->FormatModes())); params.push_back(user->GetIPString()); + params.push_back(ConvToStr(user->signon)); params.push_back(":"+std::string(user->fullname)); Utils->DoOneToMany(ServerInstance->Config->GetSID(), "UID", params); // User is Local, change needs to be reflected! @@ -1066,7 +633,7 @@ void ModuleSpanningTree::OnUserConnect(userrec* user) } } -void ModuleSpanningTree::OnUserQuit(userrec* user, const std::string &reason, const std::string &oper_message) +void ModuleSpanningTree::OnUserQuit(User* user, const std::string &reason, const std::string &oper_message) { if ((IS_LOCAL(user)) && (user->registered == REG_ALL)) { @@ -1089,17 +656,24 @@ void ModuleSpanningTree::OnUserQuit(userrec* user, const std::string &reason, co } } -void ModuleSpanningTree::OnUserPostNick(userrec* user, const std::string &oldnick) +void ModuleSpanningTree::OnUserPostNick(User* user, const std::string &oldnick) { if (IS_LOCAL(user)) { std::deque params; params.push_back(user->nick); + + /** IMPORTANT: We don't update the TS if the oldnick is just a case change of the newnick! + */ + if (irc::string(user->nick) != assign(oldnick)) + user->age = ServerInstance->Time(true); + + params.push_back(ConvToStr(user->age)); Utils->DoOneToMany(user->uuid,"NICK",params); } } -void ModuleSpanningTree::OnUserKick(userrec* source, userrec* user, chanrec* chan, const std::string &reason, bool &silent) +void ModuleSpanningTree::OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent) { if ((source) && (IS_LOCAL(source))) { @@ -1119,7 +693,7 @@ void ModuleSpanningTree::OnUserKick(userrec* source, userrec* user, chanrec* cha } } -void ModuleSpanningTree::OnRemoteKill(userrec* source, userrec* dest, const std::string &reason, const std::string &operreason) +void ModuleSpanningTree::OnRemoteKill(User* source, User* dest, const std::string &reason, const std::string &operreason) { std::deque params; params.push_back(":"+reason); @@ -1131,7 +705,7 @@ void ModuleSpanningTree::OnRemoteKill(userrec* source, userrec* dest, const std: Utils->DoOneToMany(source->uuid,"KILL",params); } -void ModuleSpanningTree::OnRehash(userrec* user, const std::string ¶meter) +void ModuleSpanningTree::OnRehash(User* user, const std::string ¶meter) { if (!parameter.empty()) { @@ -1152,7 +726,7 @@ void ModuleSpanningTree::OnRehash(userrec* user, const std::string ¶meter) // note: the protocol does not allow direct umode +o except // via NICK with 8 params. sending OPERTYPE infers +o modechange // locally. -void ModuleSpanningTree::OnOper(userrec* user, const std::string &opertype) +void ModuleSpanningTree::OnOper(User* user, const std::string &opertype) { if (IS_LOCAL(user)) { @@ -1162,86 +736,56 @@ void ModuleSpanningTree::OnOper(userrec* user, const std::string &opertype) } } -void ModuleSpanningTree::OnLine(userrec* source, const std::string &host, bool adding, char linetype, long duration, const std::string &reason) +void ModuleSpanningTree::OnAddLine(XLine* line, User* user) { - if (!source) + if (!user) { /* Server-set lines */ char data[MAXBUF]; - snprintf(data,MAXBUF,"%c %s %s %lu %lu :%s", linetype, host.c_str(), ServerInstance->Config->ServerName, (unsigned long)ServerInstance->Time(false), - (unsigned long)duration, reason.c_str()); + snprintf(data,MAXBUF,"%s %s %s %lu %lu :%s", line->type.c_str(), line->Displayable(), ServerInstance->Config->ServerName, line->set_time, + line->duration, line->reason); std::deque params; params.push_back(data); Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ADDLINE", params); } else { - if (IS_LOCAL(source)) + /** XXX: This is WRONG and needs fixing. + * We need to implement a DELLINE + */ + if (user && IS_LOCAL(user)) { char type[8]; - snprintf(type,8,"%cLINE",linetype); - std::string stype = type; - if (adding) - { - char sduration[MAXBUF]; - snprintf(sduration,MAXBUF,"%ld",duration); - std::deque params; - params.push_back(host); - params.push_back(sduration); - params.push_back(":"+reason); - Utils->DoOneToMany(source->uuid,stype,params); - } - else - { - std::deque params; - params.push_back(host); - Utils->DoOneToMany(source->uuid,stype,params); - } + snprintf(type,8,"%sLINE",line->type.c_str()); + std::string stype(type); + char sduration[MAXBUF]; + snprintf(sduration,MAXBUF,"%ld",line->duration); + std::deque params; + params.push_back(line->Displayable()); + params.push_back(ConvToStr(line->duration)); + params.push_back(std::string(":")+line->reason); + Utils->DoOneToMany(user->uuid,stype,params); } } } -void ModuleSpanningTree::OnAddGLine(long duration, userrec* source, const std::string &reason, const std::string &hostmask) -{ - OnLine(source,hostmask,true,'G',duration,reason); -} - -void ModuleSpanningTree::OnAddZLine(long duration, userrec* source, const std::string &reason, const std::string &ipmask) -{ - OnLine(source,ipmask,true,'Z',duration,reason); -} - -void ModuleSpanningTree::OnAddQLine(long duration, userrec* source, const std::string &reason, const std::string &nickmask) -{ - OnLine(source,nickmask,true,'Q',duration,reason); -} - -void ModuleSpanningTree::OnAddELine(long duration, userrec* source, const std::string &reason, const std::string &hostmask) -{ - OnLine(source,hostmask,true,'E',duration,reason); -} - -void ModuleSpanningTree::OnDelGLine(userrec* source, const std::string &hostmask) -{ - OnLine(source,hostmask,false,'G',0,""); -} - -void ModuleSpanningTree::OnDelZLine(userrec* source, const std::string &ipmask) -{ - OnLine(source,ipmask,false,'Z',0,""); -} - -void ModuleSpanningTree::OnDelQLine(userrec* source, const std::string &nickmask) +void ModuleSpanningTree::OnDelLine(XLine* line, User* user) { - OnLine(source,nickmask,false,'Q',0,""); -} - -void ModuleSpanningTree::OnDelELine(userrec* source, const std::string &hostmask) -{ - OnLine(source,hostmask,false,'E',0,""); + if (user && IS_LOCAL(user)) + { + /** XXX: This is WRONG and needs fixing. + * We need to implement a DELLINE + */ + char type[8]; + snprintf(type,8,"%sLINE",line->type.c_str()); + std::string stype(type); + std::deque params; + params.push_back(line->Displayable()); + Utils->DoOneToMany(user->uuid,stype,params); + } } -void ModuleSpanningTree::OnMode(userrec* user, void* dest, int target_type, const std::string &text) +void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::string &text) { if ((IS_LOCAL(user)) && (user->registered == REG_ALL)) { @@ -1253,14 +797,14 @@ void ModuleSpanningTree::OnMode(userrec* user, void* dest, int target_type, cons if (target_type == TYPE_USER) { - userrec* u = (userrec*)dest; + User* u = (User*)dest; params.push_back(u->uuid); params.push_back(output_text); command = "MODE"; } else { - chanrec* c = (chanrec*)dest; + Channel* c = (Channel*)dest; params.push_back(c->name); params.push_back(ConvToStr(c->age)); params.push_back(output_text); @@ -1271,7 +815,7 @@ void ModuleSpanningTree::OnMode(userrec* user, void* dest, int target_type, cons } } -void ModuleSpanningTree::OnSetAway(userrec* user) +void ModuleSpanningTree::OnSetAway(User* user) { if (IS_LOCAL(user)) { @@ -1281,7 +825,7 @@ void ModuleSpanningTree::OnSetAway(userrec* user) } } -void ModuleSpanningTree::OnCancelAway(userrec* user) +void ModuleSpanningTree::OnCancelAway(User* user) { if (IS_LOCAL(user)) { @@ -1302,12 +846,12 @@ void ModuleSpanningTree::ProtoSendMode(void* opaque, int target_type, void* targ { if (target_type == TYPE_USER) { - userrec* u = (userrec*)target; + User* u = (User*)target; s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" FMODE "+u->uuid+" "+ConvToStr(u->age)+" "+output_text); } else { - chanrec* c = (chanrec*)target; + Channel* c = (Channel*)target; s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" FMODE "+c->name+" "+ConvToStr(c->age)+" "+output_text); } } @@ -1320,12 +864,12 @@ void ModuleSpanningTree::ProtoSendMetaData(void* opaque, int target_type, void* { if (target_type == TYPE_USER) { - userrec* u = (userrec*)target; + User* u = (User*)target; s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" METADATA "+u->uuid+" "+extname+" :"+extdata); } else if (target_type == TYPE_CHANNEL) { - chanrec* c = (chanrec*)target; + Channel* c = (Channel*)target; s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" METADATA "+c->name+" "+extname+" :"+extdata); } } @@ -1358,7 +902,7 @@ void ModuleSpanningTree::OnEvent(Event* event) { if (params->size() < 2) return; - // Insert the TS value of the object, either userrec or chanrec + // Insert the TS value of the object, either User or Channel time_t ourTS = 0; std::string output_text; @@ -1366,7 +910,7 @@ void ModuleSpanningTree::OnEvent(Event* event) for (size_t n = 0; n < params->size(); n++) ServerInstance->Parser->TranslateUIDs(TR_NICK, (*params)[n], (*params)[n]); - userrec* a = ServerInstance->FindNick((*params)[0]); + User* a = ServerInstance->FindNick((*params)[0]); if (a) { ourTS = a->age; @@ -1375,7 +919,7 @@ void ModuleSpanningTree::OnEvent(Event* event) } else { - chanrec* a = ServerInstance->FindChan((*params)[0]); + Channel* a = ServerInstance->FindChan((*params)[0]); if (a) { ourTS = a->age; @@ -1422,7 +966,7 @@ void ModuleSpanningTree::OnEvent(Event* event) if (params->size() < 2) return; - userrec *a = ServerInstance->FindNick((*params)[0]); + User *a = ServerInstance->FindNick((*params)[0]); if (!a) return; @@ -1442,7 +986,7 @@ ModuleSpanningTree::~ModuleSpanningTree() ServerInstance->Timers->DelTimer(RefreshTimer); - ServerInstance->DoneWithInterface("InspSocketHook"); + ServerInstance->Modules->DoneWithInterface("BufferedSocketHook"); } Version ModuleSpanningTree::GetVersion() @@ -1456,8 +1000,7 @@ void ModuleSpanningTree::Implements(char* List) List[I_OnWallops] = List[I_OnUserNotice] = List[I_OnUserMessage] = List[I_OnBackgroundTimer] = 1; List[I_OnUserJoin] = List[I_OnChangeHost] = List[I_OnChangeName] = List[I_OnUserPart] = List[I_OnUserConnect] = 1; List[I_OnUserQuit] = List[I_OnUserPostNick] = List[I_OnUserKick] = List[I_OnRemoteKill] = List[I_OnRehash] = 1; - List[I_OnOper] = List[I_OnAddGLine] = List[I_OnAddZLine] = List[I_OnAddQLine] = List[I_OnAddELine] = 1; - List[I_OnDelGLine] = List[I_OnDelZLine] = List[I_OnDelQLine] = List[I_OnDelELine] = List[I_ProtoSendMode] = List[I_OnMode] = 1; + List[I_OnOper] = List[I_OnAddLine] = List[I_OnDelLine] = List[I_ProtoSendMode] = List[I_OnMode] = 1; List[I_OnStats] = List[I_ProtoSendMetaData] = List[I_OnEvent] = List[I_OnSetAway] = List[I_OnCancelAway] = List[I_OnPostCommand] = 1; } @@ -1474,4 +1017,3 @@ Priority ModuleSpanningTree::Prioritize() } MODULE_INIT(ModuleSpanningTree) -