diff --git a/src/modules/m_spanningtree/admin.cpp b/src/modules/m_spanningtree/admin.cpp index e9e5d811e..eba629186 100644 --- a/src/modules/m_spanningtree/admin.cpp +++ b/src/modules/m_spanningtree/admin.cpp @@ -34,21 +34,13 @@ bool TreeSocket::Admin(const std::string &prefix, std::deque ¶m if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0])) { /* It's for our server */ - string_list results; User* source = this->ServerInstance->FindNick(prefix); if (source) { - std::deque par; - par.push_back(prefix); - par.push_back(""); - par[1] = std::string("::")+ServerInstance->Config->ServerName+" 256 "+source->nick+" :Administrative info for "+ServerInstance->Config->ServerName; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); - par[1] = std::string("::")+ServerInstance->Config->ServerName+" 257 "+source->nick+" :Name - "+ServerInstance->Config->AdminName; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); - par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :Nickname - "+ServerInstance->Config->AdminNick; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); - par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :E-Mail - "+ServerInstance->Config->AdminEmail; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 256 "+source->nick+" :Administrative info for "+ServerInstance->Config->ServerName); + ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 257 "+source->nick+" :Name - "+ServerInstance->Config->AdminName); + ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :Nickname - "+ServerInstance->Config->AdminNick); + ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :E-Mail - "+ServerInstance->Config->AdminEmail); } } else diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp index ca619b63c..5aa6d005b 100644 --- a/src/modules/m_spanningtree/capab.cpp +++ b/src/modules/m_spanningtree/capab.cpp @@ -35,11 +35,11 @@ std::string TreeSocket::MyCapabilities() std::vector modlist = this->ServerInstance->Modules->GetAllModuleNames(VF_COMMON); std::string capabilities; sort(modlist.begin(),modlist.end()); - for (unsigned int i = 0; i < modlist.size(); i++) + for (std::vector::const_iterator i = modlist.begin(); i != modlist.end(); ++i) { - if (i) + if (i != modlist.begin()) capabilities = capabilities + ","; - capabilities = capabilities + modlist[i]; + capabilities = capabilities + *i; } return capabilities; } diff --git a/src/modules/m_spanningtree/encap.cpp b/src/modules/m_spanningtree/encap.cpp index 8c70965a6..98985d431 100644 --- a/src/modules/m_spanningtree/encap.cpp +++ b/src/modules/m_spanningtree/encap.cpp @@ -26,14 +26,11 @@ /* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */ - - -/** remote MOTD. leet, huh? */ bool TreeSocket::Encap(const std::string &prefix, std::deque ¶ms) { if (params.size() > 1) { - if (InspIRCd::Match(ServerInstance->Config->GetSID(), params[0])) + if (ServerInstance->Config->GetSID() == params[0] || InspIRCd::Match(ServerInstance->Config->ServerName, params[0])) { Event event((char*) ¶ms, (Module*)this->Utils->Creator, "encap_received"); event.Send(ServerInstance); @@ -41,12 +38,21 @@ bool TreeSocket::Encap(const std::string &prefix, std::deque ¶m params[params.size() - 1] = ":" + params[params.size() - 1]; - if (params[0].find('*') != std::string::npos) + if (params[0].find_first_of("*?") != std::string::npos) { Utils->DoOneToAllButSender(prefix, "ENCAP", params, prefix); } else - Utils->DoOneToOne(prefix, "ENCAP", params, params[0]); + { + /* Only forward when the route to the target is not the same as the sender. + * This occurs with 1.2.9 and older servers, as they broadcast ENCAP even when + * it is targetted to a single server only. + * If we were the only target of this ENCAP, it won't be propagated. + */ + TreeServer* routeserver = Utils->BestRouteTo(params[0]); + if ((routeserver) && (routeserver->GetSocket() != this)) + Utils->DoOneToOne(prefix, "ENCAP", params, params[0]); + } } return true; } diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index fbaee127c..d33bf6ee0 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -43,7 +43,7 @@ /* $ModDep: m_spanningtree/cachetimer.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 m_spanningtree/protocolinterface.h */ ModuleSpanningTree::ModuleSpanningTree(InspIRCd* Me) - : Module(Me), max_local(0), max_global(0) + : Module(Me), max_local(0), max_global(0), loopCall(false) { ServerInstance->Modules->UseInterface("BufferedSocketHook"); Utils = new SpanningTreeUtilities(ServerInstance, this); @@ -67,7 +67,6 @@ ModuleSpanningTree::ModuleSpanningTree(InspIRCd* Me) delete ServerInstance->PI; ServerInstance->PI = new SpanningTreeProtocolInterface(this, Utils, ServerInstance); - loopCall = false; for (std::vector::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); i++) { @@ -486,110 +485,47 @@ void ModuleSpanningTree::OnWallops(User* user, const std::string &text) } } -void ModuleSpanningTree::OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list) +void ModuleSpanningTree::LocalMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list, const std::string& message_type) { - /* Server origin */ - if (user == NULL) - return; - if (target_type == TYPE_USER) { User* d = (User*)dest; - if ((d->GetFd() < 0) && (IS_LOCAL(user))) + if (IS_REMOTE(d)) { std::deque params; - params.clear(); params.push_back(d->uuid); params.push_back(":"+text); - Utils->DoOneToOne(user->uuid,"NOTICE",params,d->server); + Utils->DoOneToOne(user->uuid, message_type, params, d->server); } } else if (target_type == TYPE_CHANNEL) { - if (IS_LOCAL(user)) + Channel *c = (Channel*)dest; + if (c) { - Channel *c = (Channel*)dest; - if (c) - { - std::string cname = c->name; - if (status) - cname = status + cname; - TreeServerList list; - Utils->GetListOfServersForChannel(c,list,status,exempt_list); - for (TreeServerList::iterator i = list.begin(); i != list.end(); i++) - { - TreeSocket* Sock = i->second->GetSocket(); - if (Sock) - Sock->WriteLine(":"+std::string(user->uuid)+" NOTICE "+cname+" :"+text); - } - } + Utils->SendChannelMessage(user->uuid, c, text, status, exempt_list, message_type); } } else if (target_type == TYPE_SERVER) { - if (IS_LOCAL(user)) - { - char* target = (char*)dest; - std::deque par; - par.push_back(target); - par.push_back(":"+text); - Utils->DoOneToMany(user->uuid,"NOTICE",par); - } + char* target = (char*)dest; + std::deque par; + par.push_back(target); + par.push_back(":"+text); + Utils->DoOneToMany(user->uuid, message_type, par); } } +void ModuleSpanningTree::OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list) +{ + if ((user) && (IS_LOCAL(user))) + LocalMessage(user, dest, target_type, text, status, exempt_list, "NOTICE"); +} + void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list) { - /* Server origin */ - if (user == NULL) - return; - - if (target_type == TYPE_USER) - { - // route private messages which are targetted at clients only to the server - // which needs to receive them - User* d = (User*)dest; - if ((d->GetFd() < 0) && (IS_LOCAL(user))) - { - std::deque params; - params.clear(); - params.push_back(d->uuid); - params.push_back(":"+text); - Utils->DoOneToOne(user->uuid,"PRIVMSG",params,d->server); - } - } - else if (target_type == TYPE_CHANNEL) - { - if (IS_LOCAL(user)) - { - Channel *c = (Channel*)dest; - if (c) - { - std::string cname = c->name; - if (status) - cname = status + cname; - TreeServerList list; - Utils->GetListOfServersForChannel(c,list,status,exempt_list); - for (TreeServerList::iterator i = list.begin(); i != list.end(); i++) - { - TreeSocket* Sock = i->second->GetSocket(); - if (Sock) - Sock->WriteLine(":"+std::string(user->uuid)+" PRIVMSG "+cname+" :"+text); - } - } - } - } - else if (target_type == TYPE_SERVER) - { - if (IS_LOCAL(user)) - { - char* target = (char*)dest; - std::deque par; - par.push_back(target); - par.push_back(":"+text); - Utils->DoOneToMany(user->uuid,"PRIVMSG",par); - } - } + if ((user) && (IS_LOCAL(user))) + LocalMessage(user, dest, target_type, text, status, exempt_list, "PRIVMSG"); } void ModuleSpanningTree::OnBackgroundTimer(time_t curtime) @@ -611,7 +547,7 @@ void ModuleSpanningTree::OnUserJoin(User* user, Channel* channel, bool sync, boo params.push_back(channel->name); params.push_back(ConvToStr(channel->age)); params.push_back(std::string("+") + channel->ChanModes(true)); - params.push_back(ServerInstance->Modes->ModeString(user, channel, false)+","+std::string(user->uuid)); + params.push_back(ServerInstance->Modes->ModeString(user, channel, false) + "," + user->uuid); Utils->DoOneToMany(ServerInstance->Config->GetSID(),"FJOIN",params); } } @@ -638,7 +574,7 @@ void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos) Utils->DoOneToMany(user->uuid,"FNAME",params); } -void ModuleSpanningTree::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent) +void ModuleSpanningTree::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent) { if (IS_LOCAL(user)) { @@ -660,8 +596,8 @@ void ModuleSpanningTree::OnUserQuit(User* user, const std::string &reason, const { params.push_back(":"+oper_message); Utils->DoOneToMany(user->uuid,"OPERQUIT",params); + params.clear(); } - params.clear(); params.push_back(":"+reason); Utils->DoOneToMany(user->uuid,"QUIT",params); } @@ -789,22 +725,17 @@ void ModuleSpanningTree::OnAddLine(User* user, XLine *x) if (!x->IsBurstable() || loopCall) return; - char data[MAXBUF]; - snprintf(data,MAXBUF,"%s %s %s %lu %lu :%s", x->type.c_str(), x->Displayable(), - ServerInstance->Config->ServerName, (unsigned long)x->set_time, (unsigned long)x->duration, x->reason); std::deque params; - params.push_back(data); + params.push_back(x->type); + params.push_back(x->Displayable()); + params.push_back(ServerInstance->Config->ServerName); + params.push_back(ConvToStr(x->set_time)); + params.push_back(ConvToStr(x->duration)); + params.push_back(":" + std::string(x->reason)); - if (!user) - { - /* Server-set lines */ - Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ADDLINE", params); - } - else if (IS_LOCAL(user)) - { - /* User-set lines */ - Utils->DoOneToMany(user->uuid, "ADDLINE", params); - } + /* Server-set lines doesn't have a setter user */ + const std::string& source = user ? user->uuid : ServerInstance->Config->GetSID(); + Utils->DoOneToMany(source, "ADDLINE", params); } void ModuleSpanningTree::OnDelLine(User* user, XLine *x) @@ -812,21 +743,13 @@ void ModuleSpanningTree::OnDelLine(User* user, XLine *x) if (!x->IsBurstable() || loopCall) return; - char data[MAXBUF]; - snprintf(data,MAXBUF,"%s %s", x->type.c_str(), x->Displayable()); std::deque params; - params.push_back(data); + params.push_back(x->type); + params.push_back(x->Displayable()); - if (!user) - { - /* Server-unset lines */ - Utils->DoOneToMany(ServerInstance->Config->GetSID(), "DELLINE", params); - } - else if (IS_LOCAL(user)) - { - /* User-unset lines */ - Utils->DoOneToMany(user->uuid, "DELLINE", params); - } + /* Server-set lines doesn't have a setter user */ + const std::string& source = user ? user->uuid : ServerInstance->Config->GetSID(); + Utils->DoOneToMany(source, "DELLINE", params); } void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::deque &text, const std::deque &translate) @@ -834,7 +757,6 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s if ((IS_LOCAL(user)) && (user->registered == REG_ALL)) { std::deque params; - std::string command; std::string output_text; ServerInstance->Parser->TranslateUIDs(translate, text, output_text); @@ -844,7 +766,7 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s User* u = (User*)dest; params.push_back(u->uuid); params.push_back(output_text); - command = "MODE"; + Utils->DoOneToMany(user->uuid, "MODE", params); } else { @@ -852,10 +774,8 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s params.push_back(c->name); params.push_back(ConvToStr(c->age)); params.push_back(output_text); - command = "FMODE"; + Utils->DoOneToMany(user->uuid, "FMODE", params); } - - Utils->DoOneToMany(user->uuid, command, params); } } @@ -863,18 +783,10 @@ int ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg) { if (IS_LOCAL(user)) { - if (awaymsg.empty()) - { - std::deque params; - params.clear(); - Utils->DoOneToMany(user->uuid,"AWAY",params); - } - else - { - std::deque params; + std::deque params; + if (!awaymsg.empty()) params.push_back(":" + awaymsg); - Utils->DoOneToMany(user->uuid,"AWAY",params); - } + Utils->DoOneToMany(user->uuid,"AWAY",params); } return 0; diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index 9be1ee631..3d62146ac 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -58,6 +58,7 @@ class ModuleSpanningTree : public Module SpanningTreeUtilities* Utils; void RedoConfig(Module* mod, const std::string &name); + void LocalMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list, const std::string& message_type); public: CacheRefreshTimer *RefreshTimer; diff --git a/src/modules/m_spanningtree/metadata.cpp b/src/modules/m_spanningtree/metadata.cpp index 1cd061a20..706317334 100644 --- a/src/modules/m_spanningtree/metadata.cpp +++ b/src/modules/m_spanningtree/metadata.cpp @@ -48,7 +48,7 @@ bool TreeSocket::MetaData(const std::string &prefix, std::deque &pa FOREACH_MOD_I(this->ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(TYPE_CHANNEL,c,params[1],params[2])); } } - else if (*(params[0].c_str()) != '#') + else { User* u = this->ServerInstance->FindNick(params[0]); if (u) diff --git a/src/modules/m_spanningtree/modules.cpp b/src/modules/m_spanningtree/modules.cpp index e92c81e2a..5457d0051 100644 --- a/src/modules/m_spanningtree/modules.cpp +++ b/src/modules/m_spanningtree/modules.cpp @@ -41,41 +41,35 @@ bool TreeSocket::Modules(const std::string &prefix, std::deque &par } char strbuf[MAXBUF]; - std::deque par; - par.push_back(prefix); - par.push_back(""); User* source = this->ServerInstance->FindNick(prefix); if (!source) return true; std::vector module_names = ServerInstance->Modules->GetAllModuleNames(0); - - for (unsigned int i = 0; i < module_names.size(); i++) + for (std::vector::const_iterator i = module_names.begin(); i != module_names.end(); ++i) { - Module* m = ServerInstance->Modules->Find(module_names[i]); + Module* m = ServerInstance->Modules->Find(*i); Version V = m->GetVersion(); if (IS_OPER(source)) { - std::string flags("Svsc"); + std::string flags("Svsc"); int pos = 0; for (int mult = 1; mult <= VF_SERVICEPROVIDER; mult *= 2, ++pos) if (!(V.Flags & mult)) flags[pos] = '-'; - snprintf(strbuf, MAXBUF, "::%s 702 %s :0x%08lx %s %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(),(unsigned long)m, module_names[i].c_str(), flags.c_str(), V.version.c_str()); + snprintf(strbuf, MAXBUF, "::%s 702 %s :0x%08lx %s %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(),(unsigned long)m, i->c_str(), flags.c_str(), V.version.c_str()); } else { - snprintf(strbuf, MAXBUF, "::%s 702 %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(), module_names[i].c_str()); + snprintf(strbuf, MAXBUF, "::%s 702 %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(), i->c_str()); } - par[1] = strbuf; - Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", par, source->server); + ServerInstance->PI->PushToClient(source, std::string(strbuf)); } snprintf(strbuf, MAXBUF, "::%s 703 %s :End of MODULES list", ServerInstance->Config->ServerName, source->nick.c_str()); - par[1] = strbuf; - Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", par, source->server); + ServerInstance->PI->PushToClient(source, std::string(strbuf)); return true; } diff --git a/src/modules/m_spanningtree/motd.cpp b/src/modules/m_spanningtree/motd.cpp index acd83cf71..2bf2ae2d3 100644 --- a/src/modules/m_spanningtree/motd.cpp +++ b/src/modules/m_spanningtree/motd.cpp @@ -36,33 +36,24 @@ bool TreeSocket::Motd(const std::string &prefix, std::deque ¶ms if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0])) { /* It's for our server */ - string_list results; User* source = this->ServerInstance->FindNick(prefix); if (source) { - std::deque par; - par.push_back(prefix); - par.push_back(""); - if (!ServerInstance->Config->MOTD.size()) { - par[1] = std::string("::")+ServerInstance->Config->ServerName+" 422 "+source->nick+" :Message of the day file is missing."; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 422 "+source->nick+" :Message of the day file is missing."); return true; } - par[1] = std::string("::")+ServerInstance->Config->ServerName+" 375 "+source->nick+" :"+ServerInstance->Config->ServerName+" message of the day"; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 375 "+source->nick+" :"+ServerInstance->Config->ServerName+" message of the day"); - for (unsigned int i = 0; i < ServerInstance->Config->MOTD.size(); i++) + std::string lineprefix = std::string("::") + ServerInstance->Config->ServerName + " 372 " + source->nick + " :- "; + for (file_cache::const_iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); ++i) { - par[1] = std::string("::")+ServerInstance->Config->ServerName+" 372 "+source->nick+" :- "+ServerInstance->Config->MOTD[i]; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + ServerInstance->PI->PushToClient(source, lineprefix + *i); } - - par[1] = std::string("::")+ServerInstance->Config->ServerName+" 376 "+source->nick+" :End of message of the day."; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 376 "+source->nick+" :End of message of the day."); } } else @@ -75,4 +66,3 @@ bool TreeSocket::Motd(const std::string &prefix, std::deque ¶ms } return true; } - diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp index f7006bcae..997f040f1 100644 --- a/src/modules/m_spanningtree/netburst.cpp +++ b/src/modules/m_spanningtree/netburst.cpp @@ -36,15 +36,12 @@ */ void TreeSocket::DoBurst(TreeServer* s) { - std::string name = s->GetName(); - std::string burst = ":" + this->ServerInstance->Config->GetSID() + " BURST " +ConvToStr(ServerInstance->Time()); - std::string endburst = ":" + this->ServerInstance->Config->GetSID() + " ENDBURST"; this->ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s%s).", - name.c_str(), + s->GetName().c_str(), this->auth_fingerprint ? "SSL Fingerprint and " : "", this->auth_challenge ? "challenge-response" : "plaintext password"); this->CleanNegotiationInfo(); - this->WriteLine(burst); + this->WriteLine(":" + ServerInstance->Config->GetSID() + " BURST " + ConvToStr(ServerInstance->Time())); /* send our version string */ this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" VERSION :"+this->ServerInstance->GetVersionString()); /* Send server tree */ @@ -55,8 +52,8 @@ void TreeSocket::DoBurst(TreeServer* s) this->SendChannelModes(s); this->SendXLines(s); FOREACH_MOD_I(this->ServerInstance,I_OnSyncOtherMetaData,OnSyncOtherMetaData((Module*)Utils->Creator,(void*)this)); - this->WriteLine(endburst); - this->ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+name+"\2."); + this->WriteLine(":" + ServerInstance->Config->GetSID() + " ENDBURST"); + this->ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+s->GetName()+"\2."); } /** Recursively send the server tree with distances as hops. @@ -229,9 +226,9 @@ void TreeSocket::SendChannelModes(TreeServer* Current) FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannel,OnSyncChannel(c->second,(Module*)Utils->Creator,(void*)this)); list.clear(); c->second->GetExtList(list); - for (unsigned int j = 0; j < list.size(); j++) + for (std::deque::const_iterator i = list.begin(); i != list.end(); ++i) { - FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannelMetaData,OnSyncChannelMetaData(c->second,(Module*)Utils->Creator,(void*)this,list[j])); + FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannelMetaData,OnSyncChannelMetaData(c->second,(Module*)Utils->Creator,(void*)this,*i)); } } } @@ -277,9 +274,9 @@ void TreeSocket::SendUsers(TreeServer* Current) FOREACH_MOD_I(this->ServerInstance,I_OnSyncUser,OnSyncUser(u->second,(Module*)Utils->Creator,(void*)this)); list.clear(); u->second->GetExtList(list); - for (unsigned int j = 0; j < list.size(); j++) + for (std::deque::const_iterator i = list.begin(); i != list.end(); ++i) { - FOREACH_MOD_I(this->ServerInstance,I_OnSyncUserMetaData,OnSyncUserMetaData(u->second,(Module*)Utils->Creator,(void*)this,list[j])); + FOREACH_MOD_I(this->ServerInstance,I_OnSyncUserMetaData,OnSyncUserMetaData(u->second,(Module*)Utils->Creator,(void*)this,*i)); } } } diff --git a/src/modules/m_spanningtree/override_stats.cpp b/src/modules/m_spanningtree/override_stats.cpp index 3a30bf3b3..43eed4670 100644 --- a/src/modules/m_spanningtree/override_stats.cpp +++ b/src/modules/m_spanningtree/override_stats.cpp @@ -78,18 +78,17 @@ int ModuleSpanningTree::OnStats(char statschar, User* user, string_list &results if (statschar == 'p') { /* show all server ports, after showing client ports. -- w00t */ - - for (unsigned int i = 0; i < Utils->Bindings.size(); i++) + for (std::vector::const_iterator i = Utils->Bindings.begin(); i != Utils->Bindings.end(); ++i) { - std::string ip = Utils->Bindings[i]->GetIP(); + std::string ip = (*i)->GetIP(); if (ip.empty()) ip = "*"; std::string transport("plaintext"); - if (Utils->Bindings[i]->GetIOHook()) - transport = BufferedSocketNameRequest(this, Utils->Bindings[i]->GetIOHook()).Send(); + if ((*i)->GetIOHook()) + transport = BufferedSocketNameRequest(this, (*i)->GetIOHook()).Send(); - results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr(Utils->Bindings[i]->GetPort())+ + results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr((*i)->GetPort())+ " (server, " + transport + ")"); } } diff --git a/src/modules/m_spanningtree/postcommand.cpp b/src/modules/m_spanningtree/postcommand.cpp index 0c80af2c9..f3da162ec 100644 --- a/src/modules/m_spanningtree/postcommand.cpp +++ b/src/modules/m_spanningtree/postcommand.cpp @@ -45,7 +45,6 @@ void ModuleSpanningTree::OnPostCommand(const std::string &command, const std::ve // to have any special provision in place for remote // commands and linking protocols. std::deque params; - params.clear(); unsigned int n_translate = thiscmd->translation.size(); TranslateType translate_to; diff --git a/src/modules/m_spanningtree/protocolinterface.cpp b/src/modules/m_spanningtree/protocolinterface.cpp index 6e68e2a52..243711453 100644 --- a/src/modules/m_spanningtree/protocolinterface.cpp +++ b/src/modules/m_spanningtree/protocolinterface.cpp @@ -48,7 +48,14 @@ void SpanningTreeProtocolInterface::GetServerList(ProtoServerList &sl) void SpanningTreeProtocolInterface::SendEncapsulatedData(parameterlist &encap) { - Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ENCAP", encap); + if (encap.size() < 2) + return; + + const std::string& target = encap[0]; + if (target.find_first_of("*?") == std::string::npos) + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "ENCAP", encap, target); + else + Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ENCAP", encap); } void SpanningTreeProtocolInterface::SendMetaData(void* target, TargetTypeFlags type, const std::string &key, const std::string &data) @@ -63,12 +70,10 @@ void SpanningTreeProtocolInterface::SendMetaData(void* target, TargetTypeFlags t case TYPE_CHANNEL: params.push_back(((Channel*)target)->name); break; + case TYPE_OTHER: case TYPE_SERVER: params.push_back("*"); break; - default: - throw CoreException("I don't know how to handle TYPE_OTHER."); - break; } params.push_back(key); params.push_back(":" + data); @@ -144,57 +149,32 @@ void SpanningTreeProtocolInterface::PushToClient(User* target, const std::string Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", p, target->server); } -void SpanningTreeProtocolInterface::SendChannel(Channel* target, char status, const std::string &text) -{ - std::string cname = target->name; - if (status) - cname = status + cname; - TreeServerList list; - CUList exempt_list; - Utils->GetListOfServersForChannel(target,list,status,exempt_list); - for (TreeServerList::iterator i = list.begin(); i != list.end(); i++) - { - TreeSocket* Sock = i->second->GetSocket(); - if (Sock) - Sock->WriteLine(text); - } -} - - void SpanningTreeProtocolInterface::SendChannelPrivmsg(Channel* target, char status, const std::string &text) { - SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" PRIVMSG "+target->name+" :"+text); + CUList exempt_list; + Utils->SendChannelMessage(ServerInstance->Config->GetSID(), target, text, status, exempt_list, "PRIVMSG"); } void SpanningTreeProtocolInterface::SendChannelNotice(Channel* target, char status, const std::string &text) { - SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" NOTICE "+target->name+" :"+text); + CUList exempt_list; + Utils->SendChannelMessage(ServerInstance->Config->GetSID(), target, text, status, exempt_list, "NOTICE"); } void SpanningTreeProtocolInterface::SendUserPrivmsg(User* target, const std::string &text) { - TreeServer* serv = Utils->FindServer(target->server); - if (serv) - { - TreeSocket* sock = serv->GetSocket(); - if (sock) - { - sock->WriteLine(":" + ServerInstance->Config->GetSID() + " PRIVMSG " + target->nick + " :"+text); - } - } + parameterlist p; + p.push_back(target->uuid); + p.push_back(":" + text); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PRIVMSG", p, target->server); } void SpanningTreeProtocolInterface::SendUserNotice(User* target, const std::string &text) { - TreeServer* serv = Utils->FindServer(target->server); - if (serv) - { - TreeSocket* sock = serv->GetSocket(); - if (sock) - { - sock->WriteLine(":" + ServerInstance->Config->GetSID() + " NOTICE " + target->nick + " :"+text); - } - } + parameterlist p; + p.push_back(target->uuid); + p.push_back(":" + text); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "NOTICE", p, target->server); } void SpanningTreeProtocolInterface::Introduce(User* user) diff --git a/src/modules/m_spanningtree/protocolinterface.h b/src/modules/m_spanningtree/protocolinterface.h index cfebf27d5..c3477db18 100644 --- a/src/modules/m_spanningtree/protocolinterface.h +++ b/src/modules/m_spanningtree/protocolinterface.h @@ -27,7 +27,6 @@ class SpanningTreeProtocolInterface : public ProtocolInterface { SpanningTreeUtilities* Utils; ModuleSpanningTree* Module; - void SendChannel(Channel* target, char status, const std::string &text); public: SpanningTreeProtocolInterface(ModuleSpanningTree* mod, SpanningTreeUtilities* util, InspIRCd* Instance) : ProtocolInterface(Instance), Utils(util), Module(mod) { } virtual ~SpanningTreeProtocolInterface() { } diff --git a/src/modules/m_spanningtree/rsquit.cpp b/src/modules/m_spanningtree/rsquit.cpp index 2a7ea912b..91b41a81f 100644 --- a/src/modules/m_spanningtree/rsquit.cpp +++ b/src/modules/m_spanningtree/rsquit.cpp @@ -53,7 +53,11 @@ CmdResult CommandRSQuit::Handle (const std::vector& parameters, Use if (server_target == Utils->TreeRoot) { - NoticeUser(user, "*** RSQUIT: Foolish mortal, you cannot make a server SQUIT itself! ("+parameters[0]+" matches local server name)"); + std::string msg = ":"+std::string(ServerInstance->Config->ServerName)+" NOTICE "+user->nick+" :*** RSQUIT: Foolish mortal, you cannot make a server SQUIT itself! ("+parameters[0]+" matches local server name)"; + if (IS_LOCAL(user)) + user->Write(msg); + else + ServerInstance->PI->PushToClient(user, ":" + msg); return CMD_FAILURE; } @@ -76,20 +80,3 @@ CmdResult CommandRSQuit::Handle (const std::vector& parameters, Use return CMD_SUCCESS; } - -// XXX use protocol interface instead of rolling our own :) -void CommandRSQuit::NoticeUser(User* user, const std::string &msg) -{ - if (IS_LOCAL(user)) - { - user->WriteServ("NOTICE %s :%s",user->nick.c_str(),msg.c_str()); - } - else - { - std::deque params; - params.push_back(user->nick); - params.push_back("NOTICE "+ConvToStr(user->nick)+" :"+msg); - Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", params, user->server); - } -} - diff --git a/src/modules/m_spanningtree/rsquit.h b/src/modules/m_spanningtree/rsquit.h index a7b5208f9..5a522330a 100644 --- a/src/modules/m_spanningtree/rsquit.h +++ b/src/modules/m_spanningtree/rsquit.h @@ -20,7 +20,7 @@ #ifndef __RSQUIT_H__ #define __RSQUIT_H__ -/** Handle /RCONNECT +/** Handle /RSQUIT */ class CommandRSQuit : public Command { @@ -29,7 +29,6 @@ class CommandRSQuit : public Command public: CommandRSQuit (InspIRCd* Instance, Module* Callback, SpanningTreeUtilities* Util); CmdResult Handle (const std::vector& parameters, User *user); - void NoticeUser(User* user, const std::string &msg); }; #endif diff --git a/src/modules/m_spanningtree/stats.cpp b/src/modules/m_spanningtree/stats.cpp index 130c07a25..ec9d1013b 100644 --- a/src/modules/m_spanningtree/stats.cpp +++ b/src/modules/m_spanningtree/stats.cpp @@ -47,14 +47,10 @@ bool TreeSocket::Stats(const std::string &prefix, std::deque ¶m User* source = this->ServerInstance->FindNick(prefix); if (source) { - std::deque par; - par.push_back(prefix); - par.push_back(""); DoStats(this->ServerInstance, *(params[0].c_str()), source, results); - for (size_t i = 0; i < results.size(); i++) + for (string_list::const_iterator i = results.begin(); i != results.end(); ++i) { - par[1] = "::" + results[i]; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + ServerInstance->PI->PushToClient(source, "::" + *i); } } } diff --git a/src/modules/m_spanningtree/svsjoin.cpp b/src/modules/m_spanningtree/svsjoin.cpp index 6fb913ac5..20bf5c6a9 100644 --- a/src/modules/m_spanningtree/svsjoin.cpp +++ b/src/modules/m_spanningtree/svsjoin.cpp @@ -50,7 +50,18 @@ bool TreeSocket::ServiceJoin(const std::string &prefix, std::deque /* only join if it's local, otherwise just pass it on! */ if (IS_LOCAL(u)) Channel::JoinUser(this->ServerInstance, u, params[1].c_str(), false, "", false, ServerInstance->Time()); - Utils->DoOneToAllButSender(prefix,"SVSJOIN",params,prefix); + else + { + /* Only forward when the route to the target is not the same as the sender. + * This occurs with 1.2.9 and older servers, as they broadcast SVSJOIN/SVSPART, + * so we can end up here with a user who is reachable via the sender. + * If that's the case, just drop the command. + */ + TreeServer* routeserver = Utils->BestRouteTo(u->server); + if ((routeserver) && (routeserver->GetSocket() != this)) + Utils->DoOneToOne(prefix,"SVSJOIN",params,u->server); + } + return true; } diff --git a/src/modules/m_spanningtree/svspart.cpp b/src/modules/m_spanningtree/svspart.cpp index bcd4eb8b4..59d9869f0 100644 --- a/src/modules/m_spanningtree/svspart.cpp +++ b/src/modules/m_spanningtree/svspart.cpp @@ -37,21 +37,30 @@ bool TreeSocket::ServicePart(const std::string &prefix, std::deque if (params.size() < 2) return true; - std::string reason = "Services forced part"; - - if (params.size() == 3) - reason = params[2]; - User* u = this->ServerInstance->FindNick(params[0]); Channel* c = this->ServerInstance->FindChan(params[1]); - if (u) + if (u && c) { /* only part if it's local, otherwise just pass it on! */ if (IS_LOCAL(u)) + { + std::string reason; + reason = (params.size() == 3) ? params[2] : "Services forced part"; if (!c->PartUser(u, reason)) delete c; - Utils->DoOneToAllButSender(prefix,"SVSPART",params,prefix); + } + else + { + /* Only forward when the route to the target is not the same as the sender. + * This occurs with 1.2.9 and older servers, as they broadcast SVSJOIN/SVSPART, + * so we can end up here with a user who is reachable via the sender. + * If that's the case, just drop the command. + */ + TreeServer* routeserver = Utils->BestRouteTo(u->server); + if ((routeserver) && (routeserver->GetSocket() != this)) + Utils->DoOneToOne(prefix,"SVSPART",params,u->server); + } } return true; diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index 340b9fb64..7942c12b5 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -38,7 +38,7 @@ bool TreeSocket::ParseUID(const std::string &source, std::deque &pa */ if (params.size() < 10) { - this->SendError("Invalid client introduction (wanted 10 or more parameters, got " + (params.empty() ? "0" : ConvToStr(params.size())) + "!)"); + this->SendError("Invalid client introduction (wanted 10 or more parameters, got " + ConvToStr(params.size()) + "!)"); return false; } diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp index a7eb62e35..d5c6b5157 100644 --- a/src/modules/m_spanningtree/utils.cpp +++ b/src/modules/m_spanningtree/utils.cpp @@ -169,9 +169,9 @@ SpanningTreeUtilities::SpanningTreeUtilities(InspIRCd* Instance, ModuleSpanningT SpanningTreeUtilities::~SpanningTreeUtilities() { - for (unsigned int i = 0; i < Bindings.size(); i++) + for (std::vector::iterator i = Bindings.begin(); i != Bindings.end(); ++i) { - delete Bindings[i]; + delete *i; } while (TreeRoot->ChildCount()) @@ -300,10 +300,9 @@ bool SpanningTreeUtilities::DoOneToAllButSender(const std::string &prefix, const { TreeServer* omitroute = this->BestRouteTo(omit); std::string FullLine = ":" + prefix + " " + command; - unsigned int words = params.size(); - for (unsigned int x = 0; x < words; x++) + for (std::deque::const_iterator i = params.begin(); i != params.end(); ++i) { - FullLine = FullLine + " " + params[x]; + FullLine = FullLine + " " + *i; } unsigned int items = this->TreeRoot->ChildCount(); for (unsigned int x = 0; x < items; x++) @@ -326,10 +325,9 @@ bool SpanningTreeUtilities::DoOneToAllButSender(const std::string &prefix, const bool SpanningTreeUtilities::DoOneToMany(const std::string &prefix, const std::string &command, std::deque ¶ms) { std::string FullLine = ":" + prefix + " " + command; - unsigned int words = params.size(); - for (unsigned int x = 0; x < words; x++) + for (std::deque::const_iterator i = params.begin(); i != params.end(); ++i) { - FullLine = FullLine + " " + params[x]; + FullLine = FullLine + " " + *i; } unsigned int items = this->TreeRoot->ChildCount(); for (unsigned int x = 0; x < items; x++) @@ -365,10 +363,9 @@ bool SpanningTreeUtilities::DoOneToOne(const std::string &prefix, const std::str if (Route) { std::string FullLine = ":" + prefix + " " + command; - unsigned int words = params.size(); - for (unsigned int x = 0; x < words; x++) + for (std::deque::const_iterator i = params.begin(); i != params.end(); ++i) { - FullLine = FullLine + " " + params[x]; + FullLine = FullLine + " " + *i; } if (Route && Route->GetSocket()) { @@ -472,9 +469,9 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) if (rebind) { - for (unsigned int i = 0; i < Bindings.size(); i++) + for (std::vector::iterator i = Bindings.begin(); i != Bindings.end(); ++i) { - delete Bindings[i]; + delete *i; } ServerInstance->BufferedSocketCull(); Bindings.clear(); @@ -687,3 +684,20 @@ Link* SpanningTreeUtilities::FindLink(const std::string& name) } return NULL; } + +void SpanningTreeUtilities::SendChannelMessage(const std::string& prefix, Channel* target, const std::string &text, char status, const CUList& exempt_list, const std::string& message_type) +{ + std::string raw = ":" + prefix + " " + message_type + " "; + if (status) + raw.append(1, status); + raw += target->name + " :" + text; + + TreeServerList list; + this->GetListOfServersForChannel(target, list, status, exempt_list); + for (TreeServerList::iterator i = list.begin(); i != list.end(); ++i) + { + TreeSocket* Sock = i->second->GetSocket(); + if (Sock) + Sock->WriteLine(raw); + } +} diff --git a/src/modules/m_spanningtree/utils.h b/src/modules/m_spanningtree/utils.h index 10ab66a0e..ec81c6a93 100644 --- a/src/modules/m_spanningtree/utils.h +++ b/src/modules/m_spanningtree/utils.h @@ -222,6 +222,10 @@ class SpanningTreeUtilities : public classbase /** Refresh the IP cache used for allowing inbound connections */ void RefreshIPCache(); + + /** Sends a PRIVMSG or a NOTICE to a channel obeying an exempt list and an optional prefix + */ + void SendChannelMessage(const std::string& prefix, Channel* target, const std::string &text, char status, const CUList& exempt_list, const std::string& message_type); }; #endif