static ModuleSpanningTree* TreeProtocolModule;
extern ServerConfig* Config;
-
+extern InspIRCd* ServerInstance;
extern std::vector<Module*> modules;
extern std::vector<ircd_module*> factory;
extern int MODCOUNT;
bool DoOneToOne(std::string prefix, std::string command, std::deque<std::string> ¶ms, std::string target);
bool DoOneToAllButSender(std::string prefix, std::string command, std::deque<std::string> ¶ms, std::string omit);
bool DoOneToMany(std::string prefix, std::string command, std::deque<std::string> ¶ms);
-bool DoOneToAllButSenderRaw(std::string data, std::string omit, std::string prefix, std::string command, std::deque<std::string> ¶ms);
+bool DoOneToAllButSenderRaw(std::string data, std::string omit, std::string prefix, irc::string command, std::deque<std::string> ¶ms);
void ReadConfiguration(bool rebind);
/* Flatten links and /MAP for non-opers */
}
/* FMODE command */
- bool ForceMode(std::string source, std::deque<std::string> params)
+ bool ForceMode(std::string source, std::deque<std::string> ¶ms)
{
- userrec* who = new userrec;
- who->fd = FD_MAGIC_NUMBER;
if (params.size() < 2)
return true;
- char* modelist[255];
+ userrec* who = new userrec();
+ who->fd = FD_MAGIC_NUMBER;
+ char* modelist[64];
+ memset(&modelist,0,sizeof(modelist));
for (unsigned int q = 0; q < params.size(); q++)
{
modelist[q] = (char*)params[q].c_str();
}
/* FTOPIC command */
- bool ForceTopic(std::string source, std::deque<std::string> params)
+ bool ForceTopic(std::string source, std::deque<std::string> ¶ms)
{
if (params.size() != 4)
return true;
}
/* FJOIN, similar to unreal SJOIN */
- bool ForceJoin(std::string source, std::deque<std::string> params)
+ bool ForceJoin(std::string source, std::deque<std::string> ¶ms)
{
if (params.size() < 3)
return true;
char first[MAXBUF];
char modestring[MAXBUF];
char* mode_users[127];
+ memset(&mode_users,0,sizeof(mode_users));
mode_users[0] = first;
mode_users[1] = modestring;
strcpy(mode_users[1],"+");
}
/* NICK command */
- bool IntroduceClient(std::string source, std::deque<std::string> params)
+ bool IntroduceClient(std::string source, std::deque<std::string> ¶ms)
{
if (params.size() < 8)
return true;
void SendXLines(TreeServer* Current)
{
char data[MAXBUF];
- const char* sn = Srv->GetServerName().c_str();
+ std::string n = Srv->GetServerName();
+ const char* sn = n.c_str();
+ int iterations = 0;
/* Yes, these arent too nice looking, but they get the job done */
- for (std::vector<ZLine>::iterator i = zlines.begin(); i != zlines.end(); i++)
+ for (std::vector<ZLine>::iterator i = zlines.begin(); i != zlines.end(); i++, iterations++)
{
snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s",sn,i->ipaddr,i->source,(unsigned long)i->set_time,(unsigned long)i->duration,i->reason);
this->WriteLine(data);
+ if ((iterations % 10) == 0)
+ {
+ ServerInstance->DoOneIteration(false);
+ }
}
- for (std::vector<QLine>::iterator i = qlines.begin(); i != qlines.end(); i++)
+ for (std::vector<QLine>::iterator i = qlines.begin(); i != qlines.end(); i++, iterations++)
{
snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s",sn,i->nick,i->source,(unsigned long)i->set_time,(unsigned long)i->duration,i->reason);
this->WriteLine(data);
+ if ((iterations % 10) == 0)
+ {
+ ServerInstance->DoOneIteration(false);
+ }
}
- for (std::vector<GLine>::iterator i = glines.begin(); i != glines.end(); i++)
+ for (std::vector<GLine>::iterator i = glines.begin(); i != glines.end(); i++, iterations++)
{
snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s",sn,i->hostmask,i->source,(unsigned long)i->set_time,(unsigned long)i->duration,i->reason);
this->WriteLine(data);
+ if ((iterations % 10) == 0)
+ {
+ ServerInstance->DoOneIteration(false);
+ }
}
- for (std::vector<ELine>::iterator i = elines.begin(); i != elines.end(); i++)
+ for (std::vector<ELine>::iterator i = elines.begin(); i != elines.end(); i++, iterations++)
{
snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s",sn,i->hostmask,i->source,(unsigned long)i->set_time,(unsigned long)i->duration,i->reason);
this->WriteLine(data);
+ if ((iterations % 10) == 0)
+ {
+ ServerInstance->DoOneIteration(false);
+ }
}
- for (std::vector<ZLine>::iterator i = pzlines.begin(); i != pzlines.end(); i++)
+ for (std::vector<ZLine>::iterator i = pzlines.begin(); i != pzlines.end(); i++, iterations++)
{
snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s",sn,i->ipaddr,i->source,(unsigned long)i->set_time,(unsigned long)i->duration,i->reason);
this->WriteLine(data);
+ if ((iterations % 10) == 0)
+ {
+ ServerInstance->DoOneIteration(false);
+ }
}
- for (std::vector<QLine>::iterator i = pqlines.begin(); i != pqlines.end(); i++)
+ for (std::vector<QLine>::iterator i = pqlines.begin(); i != pqlines.end(); i++, iterations++)
{
snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s",sn,i->nick,i->source,(unsigned long)i->set_time,(unsigned long)i->duration,i->reason);
this->WriteLine(data);
+ if ((iterations % 10) == 0)
+ {
+ ServerInstance->DoOneIteration(false);
+ }
}
- for (std::vector<GLine>::iterator i = pglines.begin(); i != pglines.end(); i++)
+ for (std::vector<GLine>::iterator i = pglines.begin(); i != pglines.end(); i++, iterations++)
{
snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s",sn,i->hostmask,i->source,(unsigned long)i->set_time,(unsigned long)i->duration,i->reason);
this->WriteLine(data);
+ if ((iterations % 10) == 0)
+ {
+ ServerInstance->DoOneIteration(false);
+ }
}
- for (std::vector<ELine>::iterator i = pelines.begin(); i != pelines.end(); i++)
+ for (std::vector<ELine>::iterator i = pelines.begin(); i != pelines.end(); i++, iterations++)
{
snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s",sn,i->hostmask,i->source,(unsigned long)i->set_time,(unsigned long)i->duration,i->reason);
this->WriteLine(data);
+ if ((iterations % 10) == 0)
+ {
+ ServerInstance->DoOneIteration(false);
+ }
}
}
{
char data[MAXBUF];
std::deque<std::string> list;
- const char* sn = Srv->GetServerName().c_str();
- for (chan_hash::iterator c = chanlist.begin(); c != chanlist.end(); c++)
+ int iterations = 0;
+ std::string n = Srv->GetServerName();
+ const char* sn = n.c_str();
+ for (chan_hash::iterator c = chanlist.begin(); c != chanlist.end(); c++, iterations++)
{
SendFJoins(Current, c->second);
snprintf(data,MAXBUF,":%s FMODE %s +%s",sn,c->second->name,chanmodes(c->second,true));
{
char data[MAXBUF];
std::deque<std::string> list;
- for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
+ int iterations = 0;
+ for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++, iterations++)
{
if (u->second->registered == 7)
{
*/
void DoBurst(TreeServer* s)
{
+ /* The calls here to ServerInstance->DoOneIteration(false); yield the processing
+ * back to the core so that a large burst is split into at least 6 sections
+ * (possibly more)
+ */
+ std::string burst = "BURST";
+ std::string endburst = "ENDBURST";
Srv->SendOpers("*** Bursting to \2"+s->GetName()+"\2.");
- this->WriteLine("BURST");
+ this->WriteLine(burst);
+ ServerInstance->DoOneIteration(false);
/* send our version string */
this->WriteLine(":"+Srv->GetServerName()+" VERSION :"+Srv->GetVersion());
/* Send server tree */
this->SendServers(TreeRoot,s,1);
+ ServerInstance->DoOneIteration(false);
/* Send users and their oper status */
this->SendUsers(s);
+ ServerInstance->DoOneIteration(false);
/* Send everything else (channel modes, xlines etc) */
this->SendChannelModes(s);
+ ServerInstance->DoOneIteration(false);
this->SendXLines(s);
+ ServerInstance->DoOneIteration(false);
FOREACH_MOD(I_OnSyncOtherMetaData,OnSyncOtherMetaData((Module*)TreeProtocolModule,(void*)this));
- this->WriteLine("ENDBURST");
+ ServerInstance->DoOneIteration(false);
+ this->WriteLine(endburst);
Srv->SendOpers("*** Finished bursting to \2"+s->GetName()+"\2.");
}
*/
virtual bool OnDataReady()
{
- log(DEBUG,"TreeSocket::OnDataReady");
+ int iterations = 0;
char* data = this->Read();
/* Check that the data read is a valid pointer and it has some content */
if (data && *data)
{
- log(DEBUG,"got some data");
this->in_buffer.append(data);
/* While there is at least one new line in the buffer,
* do something useful (we hope!) with it.
*/
while (in_buffer.find("\n") != std::string::npos)
{
+ iterations++;
+ if ((iterations % 10) == 0)
+ {
+ ServerInstance->DoOneIteration(false);
+ }
std::string ret = in_buffer.substr(0,in_buffer.find("\n")-1);
in_buffer = in_buffer.substr(in_buffer.find("\n")+1,in_buffer.length()-in_buffer.find("\n"));
if (ret.find("\r") != std::string::npos)
if ((nbytes > 0) && (nbytes < 1024))
{
log(DEBUG,"m_spanningtree: decrypt %d bytes",nbytes);
- ctx_in->Decrypt(out, result, nbytes, 1);
+ ctx_in->Decrypt(out, result, nbytes, 0);
for (int t = 0; t < nbytes; t++)
if (result[t] == '\7') result[t] = 0;
ret = result;
return false;
}
}
+ return true;
}
/* EAGAIN returns an empty but non-NULL string, so this
* evaluates to TRUE for EAGAIN but to FALSE for EOF.
*/
- return (data != NULL);
+ return (data && !*data);
}
int WriteLine(std::string line)
}
}
unsigned int ll = line.length();
- ctx_out->Encrypt(line.c_str(), result, ll, 1);
+ ctx_out->Encrypt(line.c_str(), result, ll, 0);
to64frombits((unsigned char*)result64,(unsigned char*)result,ll);
line = result64;
//int from64tobits(char *out, const char *in, int maxlen);
void Split(std::string line, bool stripcolon, std::deque<std::string> &n)
{
+ // we don't do anything with a line > 2048
+ if (line.length() > 2048)
+ return;
if (!strchr(line.c_str(),' '))
{
n.push_back(line);
return;
}
std::stringstream s(line);
- std::string param = "";
+ int count = 0;
+ char param[1024];
+ char* pptr = param;
n.clear();
int item = 0;
while (!s.eof())
{
- char c;
+ char c = 0;
s.get(c);
if (c == ' ')
{
n.push_back(param);
- param = "";
+ *param = count = 0;
item++;
}
else
{
if (!s.eof())
{
- param = param + c;
+ *pptr++ = c;
+ count++;
}
- if ((param == ":") && (item > 0))
+ if ((*param == ':') && (count == 1) && (item > 0))
{
- param = "";
+ *param = 0;
while (!s.eof())
{
s.get(c);
if (!s.eof())
{
- param = param + c;
+ *pptr++ = c;
+ count++;
}
}
n.push_back(param);
- param = "";
+ *param = count = 0;
}
}
}
- if (param != "")
+ if (*param)
{
n.push_back(param);
}
std::deque<std::string> params;
this->Split(line,true,params);
- std::string command = "";
+ irc::string command = "";
std::string prefix = "";
if (((params[0].c_str())[0] == ':') && (params.size() > 1))
{
prefix = params[0];
- command = params[1];
+ command = params[1].c_str();
char* pref = (char*)prefix.c_str();
prefix = ++pref;
params.pop_front();
else
{
prefix = "";
- command = params[0];
+ command = params[0].c_str();
params.pop_front();
}
{
this->bursting = false;
apply_lines(APPLY_ZLINES|APPLY_GLINES|APPLY_QLINES);
+ std::string sourceserv = this->myhost;
+ if (this->InboundServerName != "")
+ {
+ sourceserv = this->InboundServerName;
+ }
+ WriteOpers("*** Received end of netburst from \2%s\2",sourceserv.c_str());
return true;
}
else
{
strparams[q] = (char*)params[q].c_str();
}
- Srv->CallCommandHandler(command, strparams, params.size(), who);
+ if (!Srv->CallCommandHandler(command.c_str(), strparams, params.size(), who))
+ {
+ this->WriteLine("ERROR :Unrecognised command -- possibly loaded mismatched modules");
+ return false;
+ }
}
else
{
return;
}
-bool DoOneToAllButSenderRaw(std::string data, std::string omit, std::string prefix, std::string command, std::deque<std::string> ¶ms)
+bool DoOneToAllButSenderRaw(std::string data, std::string omit, std::string prefix, irc::string command, std::deque<std::string> ¶ms)
{
TreeServer* omitroute = BestRouteTo(omit);
if ((command == "NOTICE") || (command == "PRIVMSG"))
std::deque<std::string> par;
par.push_back(params[0]);
par.push_back(":"+params[1]);
- DoOneToOne(prefix,command,par,d->server);
+ DoOneToOne(prefix,command.c_str(),par,d->server);
return true;
}
}