/** send all users and their oper state/modes */ void TreeSocket::SendUsers(TreeServer* Current) { char data[MAXBUF]; std::deque<std::string> list; std::string dataline; for (user_hash::iterator u = this->ServerInstance->Users->clientlist->begin(); u != this->ServerInstance->Users->clientlist->end(); u++) { if (u->second->registered == REG_ALL) { TreeServer* theirserver = Utils->FindServer(u->second->server); if (theirserver) { snprintf(data,MAXBUF,":%s UID %s %lu %s %s %s %s %s %lu +%s :%s", theirserver->GetID().c_str(), /* Prefix: SID */ u->second->uuid.c_str(), /* 0: UUID */ (unsigned long)u->second->age, /* 1: TS */ u->second->nick.c_str(), /* 2: Nick */ u->second->host.c_str(), /* 3: Displayed Host */ u->second->dhost.c_str(), /* 4: Real host */ u->second->ident.c_str(), /* 5: Ident */ u->second->GetIPString(), /* 6: IP string */ (unsigned long)u->second->signon, /* 7: Signon time for WHOWAS */ u->second->FormatModes(true), /* 8...n: Modes and params */ u->second->fullname.c_str()); /* size-1: GECOS */ this->WriteLine(data); if (IS_OPER(u->second)) { snprintf(data,MAXBUF,":%s OPERTYPE %s", u->second->uuid.c_str(), u->second->oper.c_str()); this->WriteLine(data); } if (IS_AWAY(u->second)) { snprintf(data,MAXBUF,":%s AWAY :%s", u->second->uuid.c_str(), u->second->awaymsg.c_str()); this->WriteLine(data); } } 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++) { FOREACH_MOD_I(this->ServerInstance,I_OnSyncUserMetaData,OnSyncUserMetaData(u->second,(Module*)Utils->Creator,(void*)this,list[j])); } } } }
/** Send channel modes and topics */ void TreeSocket::SendChannelModes(TreeServer* Current) { char data[MAXBUF]; std::deque<std::string> list; std::string n = this->ServerInstance->Config->GetSID(); const char* sn = n.c_str(); for (chan_hash::iterator c = this->ServerInstance->chanlist->begin(); c != this->ServerInstance->chanlist->end(); c++) { SendFJoins(Current, c->second); if (!c->second->topic.empty()) { snprintf(data,MAXBUF,":%s FTOPIC %s %lu %s :%s", sn, c->second->name.c_str(), (unsigned long)c->second->topicset, c->second->setby.c_str(), c->second->topic.c_str()); this->WriteLine(data); } 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++) { FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannelMetaData,OnSyncChannelMetaData(c->second,(Module*)Utils->Creator,(void*)this,list[j])); } } }
std::string InspIRCd::GetServerDescription(const char* servername) { std::string description; FOREACH_MOD_I(this,I_OnGetServerDescription,OnGetServerDescription(servername,description)); if (!description.empty()) { return description; } else { // not a remote server that can be found, it must be me. return Config->ServerDesc; } }
/** This function is called when we want to send a netburst to a local * server. There is a set order we must do this, because for example * users require their servers to exist, and channels require their * users to exist. You get the idea. */ 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(), this->auth_fingerprint ? "SSL Fingerprint and " : "", this->auth_challenge ? "challenge-response" : "plaintext password"); this->CleanNegotiationInfo(); this->WriteLine(burst); /* send our version string */ this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" VERSION :"+this->ServerInstance->GetVersionString()); /* Send server tree */ this->SendServers(Utils->TreeRoot,s,1); /* Send users and their oper status */ this->SendUsers(s); /* Send everything else (channel modes, xlines etc) */ 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."); }