- conf->ReadFile(conf->MOTD, data.GetString());
- return true;
-}
-
-bool ValidateNotEmpty(ServerConfig*, const char* tag, const char* val, ValueItem &data)
-{
- if (!*data.GetString())
- throw CoreException(std::string("The value for <")+tag+":"+val+"> cannot be empty!");
- return true;
-}
-
-bool ValidateRules(ServerConfig* conf, const char*, const char*, ValueItem &data)
-{
- conf->ReadFile(conf->RULES, data.GetString());
- return true;
-}
-
-bool ValidateModeLists(ServerConfig* conf, const char*, const char*, ValueItem &data)
-{
- memset(conf->HideModeLists, 0, sizeof(conf->HideModeLists));
- for (const unsigned char* x = (const unsigned char*)data.GetString(); *x; ++x)
- conf->HideModeLists[*x] = true;
- return true;
-}
-
-bool ValidateExemptChanOps(ServerConfig* conf, const char*, const char*, ValueItem &data)
-{
- memset(conf->ExemptChanOps, 0, sizeof(conf->ExemptChanOps));
- for (const unsigned char* x = (const unsigned char*)data.GetString(); *x; ++x)
- conf->ExemptChanOps[*x] = true;
- return true;
-}
-
-bool ValidateInvite(ServerConfig* conf, const char*, const char*, ValueItem &data)
-{
- std::string v = data.GetString();
-
- if (v == "ops")
- conf->AnnounceInvites = ServerConfig::INVITE_ANNOUNCE_OPS;
- else if (v == "all")
- conf->AnnounceInvites = ServerConfig::INVITE_ANNOUNCE_ALL;
- else if (v == "dynamic")
- conf->AnnounceInvites = ServerConfig::INVITE_ANNOUNCE_DYNAMIC;
- else
- conf->AnnounceInvites = ServerConfig::INVITE_ANNOUNCE_NONE;
-
- return true;
-}
-
-bool ValidateSID(ServerConfig* conf, const char*, const char*, ValueItem &data)
-{
- conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Validating server id");
-
- const char *sid = data.GetString();
-
- if (*sid && !conf->GetInstance()->IsSID(sid))
- {
- throw CoreException(std::string(sid) + " is not a valid server ID. A server ID must be 3 characters long, with the first character a digit and the next two characters a digit or letter.");
- }
-
- strlcpy(conf->sid, sid, 5);
-
- return true;
-}
-
-bool ValidateWhoWas(ServerConfig* conf, const char*, const char*, ValueItem &data)
-{
- conf->WhoWasMaxKeep = conf->GetInstance()->Duration(data.GetString());
-
- if (conf->WhoWasGroupSize < 0)
- conf->WhoWasGroupSize = 0;
-
- if (conf->WhoWasMaxGroups < 0)
- conf->WhoWasMaxGroups = 0;
-
- if (conf->WhoWasMaxKeep < 3600)
- {
- conf->WhoWasMaxKeep = 3600;
- conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"WARNING: <whowas:maxkeep> value less than 3600, setting to default 3600");
- }
-
- Command* whowas_command = conf->GetInstance()->Parser->GetHandler("WHOWAS");
- if (whowas_command)
- {
- std::deque<classbase*> params;
- whowas_command->HandleInternal(WHOWAS_PRUNE, params);
- }
-
- return true;
-}
-
-/* Callback called before processing the first <connect> tag
- */
-bool InitConnect(ServerConfig* conf, const char*)
-{
- conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Reading connect classes... class list is:");
-
- for (ClassVector::iterator i = conf->Classes.begin(); i != conf->Classes.end() ; )
- {
- ConnectClass* c = *i;
-
- /*
- * only delete a class with refcount 0.
- * this is needed to avoid trampling on a wild pointer (User::MyClass)!
- * it's also the most simple way to do it, given that we're looking at threads..
- * -- w00t
- */
- if (c->RefCount == 0)
- {
- conf->GetInstance()->Logs->Log("CONFIG",DEFAULT, "Removing connect class, refcount is 0!");
-
- /* This was causing a crash, because we'd set i to .begin() just here, but then the for loop's increment would
- * set it to .begin() + 1. Which if it was already the last thing in the list, wasn't good.
- * Now the increment is in the else { } below.
- */
- conf->Classes.erase(i);
- i = conf->Classes.begin(); // start over so we don't trample on a bad iterator
- }
- else
- {
- /* also mark all existing classes disabled, if they still exist in the conf, they will be reenabled. */
- c->SetDisabled(true);
- i++;
- }
- }
-
- return true;
-}
-
-/* Callback called to process a single <connect> tag
- */
-bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*)
-{
- ConnectClass c;
- const char* allow = values[0].GetString(); /* Yeah, there are a lot of values. Live with it. */
- const char* deny = values[1].GetString();
- const char* password = values[2].GetString();
- int timeout = values[3].GetInteger();
- int pingfreq = values[4].GetInteger();
- int sendq = values[5].GetInteger();
- int recvq = values[6].GetInteger();
- int localmax = values[7].GetInteger();
- int globalmax = values[8].GetInteger();
- int port = values[9].GetInteger();
- const char* name = values[10].GetString();
- const char* parent = values[11].GetString();
- int maxchans = values[12].GetInteger();
- unsigned long limit = values[13].GetInteger();
- const char* hashtype = values[14].GetString();
-
- conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Adding a connect class!");
-
- ConnectClass *cc = NULL;
-
- if (*parent)
- {
- /* Find 'parent' and inherit a new class from it,
- * then overwrite any values that are set here
- */
- ClassVector::iterator item = conf->Classes.begin();
- for (; item != conf->Classes.end(); ++item)
- {
- cc = *item;
- conf->GetInstance()->Logs->Log("CONFIG",DEBUG,"Class: %s", cc->GetName().c_str());
- if (cc->GetName() == parent)
- {
- cc = new ConnectClass(name, cc);
- cc->Update(timeout, *allow ? allow : deny, pingfreq, password, sendq, recvq, localmax, globalmax, maxchans, port, limit);
- conf->Classes.push_back(cc);
- break;
- }
- }
- if (item == conf->Classes.end())
- throw CoreException("Class name '" + std::string(name) + "' is configured to inherit from class '" + std::string(parent) + "' which cannot be found.");
- }
- else
- {
- if (*allow)
- {
- /* Find existing class by mask, the mask should be unique */
- for (ClassVector::iterator item = conf->Classes.begin(); item != conf->Classes.end(); ++item)
- {
- if ((*item)->GetHost() == allow && !(*item)->GetDisabled())
- {
- (*item)->Update(timeout, allow, pingfreq, password, sendq, recvq, localmax, globalmax, maxchans, port, limit);
- return true;
- }
- }
- cc = new ConnectClass(name, timeout, allow, pingfreq, password, hashtype, sendq, recvq, localmax, globalmax, maxchans);
- cc->limit = limit;
- cc->SetPort(port);
- conf->Classes.push_back(cc);
- }
- else
- {
- /* Find existing class by mask, the mask should be unique */
- for (ClassVector::iterator item = conf->Classes.begin(); item != conf->Classes.end(); ++item)
- {
- if ((*item)->GetHost() == deny && !(*item)->GetDisabled())
- {
- (*item)->Update(name, deny);
- (*item)->SetPort(port);
- return true;
- }
- }
- cc = new ConnectClass(name, deny);
- cc->SetPort(port);
- conf->Classes.push_back(cc);
- }
- }
-
- return true;
-}
-
-/* Callback called when there are no more <connect> tags
- */
-bool DoneConnect(ServerConfig *conf, const char*)
-{
- conf->GetInstance()->Logs->Log("CONFIG",DEFAULT, "Done adding connect classes!");
- return true;
-}
-
-/* Callback called before processing the first <uline> tag
- */
-bool InitULine(ServerConfig* conf, const char*)
-{
- conf->ulines.clear();
- return true;
-}
-
-/* Callback called to process a single <uline> tag
- */
-bool DoULine(ServerConfig* conf, const char*, char**, ValueList &values, int*)
-{
- const char* server = values[0].GetString();
- const bool silent = values[1].GetBool();
- conf->ulines[server] = silent;
- return true;
-}
-
-/* Callback called when there are no more <uline> tags
- */
-bool DoneULine(ServerConfig*, const char*)
-{
- return true;
-}
-
-/* Callback called before processing the first <module> tag
- */
-bool InitModule(ServerConfig* conf, const char*)
-{
- old_module_names = conf->GetInstance()->Modules->GetAllModuleNames(0);
- new_module_names.clear();
- added_modules.clear();
- removed_modules.clear();
- return true;
-}
-
-/* Callback called to process a single <module> tag
- */
-bool DoModule(ServerConfig*, const char*, char**, ValueList &values, int*)
-{
- const char* modname = values[0].GetString();
- new_module_names.push_back(modname);
- return true;
-}
-
-/* Callback called when there are no more <module> tags
- */
-bool DoneModule(ServerConfig*, const char*)
-{
- // now create a list of new modules that are due to be loaded
- // and a seperate list of modules which are due to be unloaded
- for (std::vector<std::string>::iterator _new = new_module_names.begin(); _new != new_module_names.end(); _new++)
- {
- bool added = true;
-
- for (std::vector<std::string>::iterator old = old_module_names.begin(); old != old_module_names.end(); old++)
- {
- if (*old == *_new)
- added = false;
- }
-
- if (added)
- added_modules.push_back(*_new);
- }
-
- for (std::vector<std::string>::iterator oldm = old_module_names.begin(); oldm != old_module_names.end(); oldm++)
- {
- bool removed = true;
- for (std::vector<std::string>::iterator newm = new_module_names.begin(); newm != new_module_names.end(); newm++)
- {
- if (*newm == *oldm)
- removed = false;
- }
-
- if (removed)
- removed_modules.push_back(*oldm);
- }
- return true;
-}
-
-/* Callback called before processing the first <banlist> tag
- */
-bool InitMaxBans(ServerConfig* conf, const char*)
-{
- conf->maxbans.clear();
- return true;
-}
-
-/* Callback called to process a single <banlist> tag
- */
-bool DoMaxBans(ServerConfig* conf, const char*, char**, ValueList &values, int*)
-{
- const char* channel = values[0].GetString();
- int limit = values[1].GetInteger();
- conf->maxbans[channel] = limit;
- return true;
-}
-
-/* Callback called when there are no more <banlist> tags.
- */
-bool DoneMaxBans(ServerConfig*, const char*)
-{
- return true;
-}
-
-void ServerConfig::ReportConfigError(const std::string &errormessage, bool bail, const std::string &useruid)
-{
- ServerInstance->Logs->Log("CONFIG",DEFAULT, "There were errors in your configuration file: %s", errormessage.c_str());
- if (bail)
- {
- /* Unneeded because of the ServerInstance->Log() aboive? */
- printf("There were errors in your configuration:\n%s\n\n",errormessage.c_str());
- ServerInstance->Exit(EXIT_STATUS_CONFIG);
- }
- else
- {
- std::string errors = errormessage;
- std::string::size_type start;
- unsigned int prefixlen;
- start = 0;
- /* ":ServerInstance->Config->ServerName NOTICE user->nick :" */
- if (!useruid.empty())
- {
- User* user = ServerInstance->FindNick(useruid);
- if (user)
- {
- prefixlen = strlen(this->ServerName) + user->nick.length() + 11;
- user->WriteServ("NOTICE %s :There were errors in the configuration file:",user->nick.c_str());
- while (start < errors.length())
- {
- user->WriteServ("NOTICE %s :%s",user->nick.c_str(), errors.substr(start, 510 - prefixlen).c_str());
- start += 510 - prefixlen;
- }
- }
- }
- else
- {
- ServerInstance->SNO->WriteToSnoMask('A', "There were errors in the configuration file:");
- while (start < errors.length())
- {
- ServerInstance->SNO->WriteToSnoMask('A', errors.substr(start, 360));
- start += 360;
- }
- }
- return;
- }
-}
-
-void ServerConfig::Read(bool bail, const std::string &useruid)
-{
- int rem = 0, add = 0; /* Number of modules added, number of modules removed */
-
- static char maxkeep[MAXBUF]; /* Temporary buffer for WhoWasMaxKeep value */
- static char hidemodes[MAXBUF]; /* Modes to not allow listing from users below halfop */
- static char exemptchanops[MAXBUF]; /* Exempt channel ops from these modes */
- static char announceinvites[MAXBUF]; /* options:announceinvites setting */
- static char disabledumodes[MAXBUF]; /* Disabled usermodes */
- static char disabledcmodes[MAXBUF]; /* Disabled chanmodes */
- /* std::ostringstream::clear() does not clear the string itself, only the error flags. */
- this->errstr = new std::ostringstream(std::stringstream::in | std::stringstream::out);
-
- include_stack.clear();
-
- /* These tags MUST occur and must ONLY occur once in the config file */
- static const char* Once[] = { "server", "admin", "files", "power", "options", NULL };
-
- Deprecated ChangedConfig[] = {
- {"options", "hidelinks", "has been moved to <security:hidelinks> as of 1.2a3"},
- {"options", "hidewhois", "has been moved to <security:hidewhois> as of 1.2a3"},
- {"options", "userstats", "has been moved to <security:userstats> as of 1.2a3"},
- {"options", "customversion", "has been moved to <security:customversion> as of 1.2a3"},
- {"options", "hidesplits", "has been moved to <security:hidesplits> as of 1.2a3"},
- {"options", "hidebans", "has been moved to <security:hidebans> as of 1.2a3"},
- {"options", "hidekills", "has been moved to <security:hidekills> as of 1.2a3"},
- {"options", "operspywhois", "has been moved to <security:operspywhois> as of 1.2a3"},
- {"options", "announceinvites", "has been moved to <security:announceinvites> as of 1.2a3"},
- {"options", "hidemodes", "has been moved to <security:hidemodes> as of 1.2a3"},
- {"options", "maxtargets", "has been moved to <security:maxtargets> as of 1.2a3"},
- {"options", "nouserdns", "has been moved to <performance:nouserdns> as of 1.2a3"},
- {"options", "maxwho", "has been moved to <performance:maxwho> as of 1.2a3"},
- {"options", "softlimit", "has been moved to <performance:softlimit> as of 1.2a3"},
- {"options", "somaxconn", "has been moved to <performance:somaxconn> as of 1.2a3"},
- {"options", "netbuffersize", "has been moved to <performance:netbuffersize> as of 1.2a3"},
- {"options", "maxwho", "has been moved to <performance:maxwho> as of 1.2a3"},
- {"options", "loglevel", "1.2 does not use the loglevel value. Please define <log> tags instead."},
- {NULL, NULL, NULL}
- };
-
- /* These tags can occur ONCE or not at all */
- InitialConfig Values[] = {
- {"performance", "softlimit", "0", new ValueContainerUInt (&this->SoftLimit), DT_INTEGER, ValidateSoftLimit},
- {"performance", "somaxconn", SOMAXCONN_S, new ValueContainerInt (&this->MaxConn), DT_INTEGER, ValidateMaxConn},
- {"options", "moronbanner", "Youre banned!", new ValueContainerChar (this->MoronBanner), DT_CHARPTR, NoValidation},
- {"server", "name", "", new ValueContainerChar (this->ServerName), DT_HOSTNAME|DT_BOOTONLY, ValidateServerName},
- {"server", "description", "Configure Me", new ValueContainerChar (this->ServerDesc), DT_CHARPTR, NoValidation},
- {"server", "network", "Network", new ValueContainerChar (this->Network), DT_NOSPACES, NoValidation},
- {"server", "id", "", new ValueContainerChar (this->sid), DT_CHARPTR|DT_BOOTONLY, ValidateSID},
- {"admin", "name", "", new ValueContainerChar (this->AdminName), DT_CHARPTR, NoValidation},
- {"admin", "email", "Mis@configu.red", new ValueContainerChar (this->AdminEmail), DT_CHARPTR, NoValidation},
- {"admin", "nick", "Misconfigured", new ValueContainerChar (this->AdminNick), DT_CHARPTR, NoValidation},
- {"files", "motd", "", new ValueContainerChar (this->motd), DT_CHARPTR, ValidateMotd},
- {"files", "rules", "", new ValueContainerChar (this->rules), DT_CHARPTR, ValidateRules},
- {"power", "diepass", "", new ValueContainerChar (this->diepass), DT_CHARPTR, ValidateNotEmpty},
- {"power", "pause", "", new ValueContainerInt (&this->DieDelay), DT_INTEGER, NoValidation},
- {"power", "hash", "", new ValueContainerChar (this->powerhash), DT_CHARPTR, NoValidation},
- {"power", "restartpass", "", new ValueContainerChar (this->restartpass), DT_CHARPTR, ValidateNotEmpty},
- {"options", "prefixquit", "", new ValueContainerChar (this->PrefixQuit), DT_CHARPTR, NoValidation},
- {"options", "suffixquit", "", new ValueContainerChar (this->SuffixQuit), DT_CHARPTR, NoValidation},
- {"options", "fixedquit", "", new ValueContainerChar (this->FixedQuit), DT_CHARPTR, NoValidation},
- {"options", "prefixpart", "", new ValueContainerChar (this->PrefixPart), DT_CHARPTR, NoValidation},
- {"options", "suffixpart", "", new ValueContainerChar (this->SuffixPart), DT_CHARPTR, NoValidation},
- {"options", "fixedpart", "", new ValueContainerChar (this->FixedPart), DT_CHARPTR, NoValidation},
- {"performance", "netbuffersize","10240", new ValueContainerInt (&this->NetBufferSize), DT_INTEGER, ValidateNetBufferSize},
- {"performance", "maxwho", "128", new ValueContainerInt (&this->MaxWhoResults), DT_INTEGER, ValidateMaxWho},
- {"options", "allowhalfop", "0", new ValueContainerBool (&this->AllowHalfop), DT_BOOLEAN, ValidateHalfOp},
- {"dns", "server", "", new ValueContainerChar (this->DNSServer), DT_IPADDRESS,DNSServerValidator},
- {"dns", "timeout", "5", new ValueContainerInt (&this->dns_timeout), DT_INTEGER, NoValidation},
- {"options", "moduledir", MOD_PATH, new ValueContainerChar (this->ModPath), DT_CHARPTR, NoValidation},
- {"disabled", "commands", "", new ValueContainerChar (this->DisabledCommands), DT_CHARPTR, NoValidation},
- {"disabled", "usermodes", "", new ValueContainerChar (disabledumodes), DT_CHARPTR, ValidateDisabledUModes},
- {"disabled", "chanmodes", "", new ValueContainerChar (disabledcmodes), DT_CHARPTR, ValidateDisabledCModes},
- {"disabled", "fakenonexistant", "0", new ValueContainerBool (&this->DisabledDontExist), DT_BOOLEAN, NoValidation},
-
- {"security", "runasuser", "", new ValueContainerChar(this->SetUser), DT_CHARPTR, NoValidation},
- {"security", "runasgroup", "", new ValueContainerChar(this->SetGroup), DT_CHARPTR, NoValidation},
- {"security", "userstats", "", new ValueContainerChar (this->UserStats), DT_CHARPTR, NoValidation},
- {"security", "customversion","", new ValueContainerChar (this->CustomVersion), DT_CHARPTR, NoValidation},
- {"security", "hidesplits", "0", new ValueContainerBool (&this->HideSplits), DT_BOOLEAN, NoValidation},
- {"security", "hidebans", "0", new ValueContainerBool (&this->HideBans), DT_BOOLEAN, NoValidation},
- {"security", "hidewhois", "", new ValueContainerChar (this->HideWhoisServer), DT_NOSPACES, NoValidation},
- {"security", "hidekills", "", new ValueContainerChar (this->HideKillsServer), DT_NOSPACES, NoValidation},
- {"security", "operspywhois", "0", new ValueContainerBool (&this->OperSpyWhois), DT_BOOLEAN, NoValidation},
- {"security", "restrictbannedusers", "1", new ValueContainerBool (&this->RestrictBannedUsers), DT_BOOLEAN, NoValidation},
- {"security", "genericoper", "0", new ValueContainerBool (&this->GenericOper), DT_BOOLEAN, NoValidation},
- {"performance", "nouserdns", "0", new ValueContainerBool (&this->NoUserDns), DT_BOOLEAN, NoValidation},
- {"options", "syntaxhints", "0", new ValueContainerBool (&this->SyntaxHints), DT_BOOLEAN, NoValidation},
- {"options", "cyclehosts", "0", new ValueContainerBool (&this->CycleHosts), DT_BOOLEAN, NoValidation},
- {"options", "ircumsgprefix","0", new ValueContainerBool (&this->UndernetMsgPrefix), DT_BOOLEAN, NoValidation},
- {"security", "announceinvites", "1", new ValueContainerChar (announceinvites), DT_CHARPTR, ValidateInvite},
- {"options", "hostintopic", "1", new ValueContainerBool (&this->FullHostInTopic), DT_BOOLEAN, NoValidation},
- {"security", "hidemodes", "", new ValueContainerChar (hidemodes), DT_CHARPTR, ValidateModeLists},
- {"options", "exemptchanops","", new ValueContainerChar (exemptchanops), DT_CHARPTR, ValidateExemptChanOps},
- {"security", "maxtargets", "20", new ValueContainerUInt (&this->MaxTargets), DT_INTEGER, ValidateMaxTargets},
- {"options", "defaultmodes", "nt", new ValueContainerChar (this->DefaultModes), DT_CHARPTR, NoValidation},
- {"pid", "file", "", new ValueContainerChar (this->PID), DT_CHARPTR, NoValidation},
- {"whowas", "groupsize", "10", new ValueContainerInt (&this->WhoWasGroupSize), DT_INTEGER, NoValidation},
- {"whowas", "maxgroups", "10240", new ValueContainerInt (&this->WhoWasMaxGroups), DT_INTEGER, NoValidation},
- {"whowas", "maxkeep", "3600", new ValueContainerChar (maxkeep), DT_CHARPTR, ValidateWhoWas},
- {"die", "value", "", new ValueContainerChar (this->DieValue), DT_CHARPTR, NoValidation},
- {"channels", "users", "20", new ValueContainerUInt (&this->MaxChans), DT_INTEGER, NoValidation},
- {"channels", "opers", "60", new ValueContainerUInt (&this->OperMaxChans), DT_INTEGER, NoValidation},
- {"cidr", "ipv4clone", "32", new ValueContainerInt (&this->c_ipv4_range), DT_INTEGER, NoValidation},
- {"cidr", "ipv6clone", "128", new ValueContainerInt (&this->c_ipv6_range), DT_INTEGER, NoValidation},
- {"limits", "maxnick", "32", new ValueContainerST (&this->Limits.NickMax), DT_INTEGER, NoValidation},
- {"limits", "maxchan", "64", new ValueContainerST (&this->Limits.ChanMax), DT_INTEGER, NoValidation},
- {"limits", "maxmodes", "20", new ValueContainerST (&this->Limits.MaxModes), DT_INTEGER, NoValidation},
- {"limits", "maxident", "11", new ValueContainerST (&this->Limits.IdentMax), DT_INTEGER, NoValidation},
- {"limits", "maxquit", "255", new ValueContainerST (&this->Limits.MaxQuit), DT_INTEGER, NoValidation},
- {"limits", "maxtopic", "307", new ValueContainerST (&this->Limits.MaxTopic), DT_INTEGER, NoValidation},
- {"limits", "maxkick", "255", new ValueContainerST (&this->Limits.MaxKick), DT_INTEGER, NoValidation},
- {"limits", "maxgecos", "128", new ValueContainerST (&this->Limits.MaxGecos), DT_INTEGER, NoValidation},
- {"limits", "maxaway", "200", new ValueContainerST (&this->Limits.MaxAway), DT_INTEGER, NoValidation},
- {"options", "invitebypassmodes", "1", new ValueContainerBool (&this->InvBypassModes), DT_BOOLEAN, NoValidation},
- {NULL, NULL, NULL, NULL, DT_NOTHING, NoValidation}
- };
-
-
- /* These tags can occur multiple times, and therefore they have special code to read them
- * which is different to the code for reading the singular tags listed above.
- */
- MultiConfig MultiValues[] = {
-
- {"connect",
- {"allow", "deny", "password", "timeout", "pingfreq",
- "sendq", "recvq", "localmax", "globalmax", "port",
- "name", "parent", "maxchans", "limit", "hash",
- NULL},
- {"", "", "", "", "120",
- "", "", "3", "3", "0",
- "", "", "0", "0", "",
- NULL},
- {DT_IPADDRESS|DT_ALLOW_WILD, DT_IPADDRESS|DT_ALLOW_WILD, DT_CHARPTR, DT_INTEGER, DT_INTEGER,
- DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER,
- DT_NOSPACES, DT_NOSPACES, DT_INTEGER, DT_INTEGER, DT_CHARPTR},
- InitConnect, DoConnect, DoneConnect},
-
- {"uline",
- {"server", "silent", NULL},
- {"", "0", NULL},
- {DT_HOSTNAME, DT_BOOLEAN},
- InitULine,DoULine,DoneULine},
-
- {"banlist",
- {"chan", "limit", NULL},
- {"", "", NULL},
- {DT_CHARPTR, DT_INTEGER},
- InitMaxBans, DoMaxBans, DoneMaxBans},
-
- {"module",
- {"name", NULL},
- {"", NULL},
- {DT_CHARPTR},
- InitModule, DoModule, DoneModule},
-
- {"badip",
- {"reason", "ipmask", NULL},
- {"No reason", "", NULL},
- {DT_CHARPTR, DT_IPADDRESS|DT_ALLOW_WILD},
- InitXLine, DoZLine, DoneConfItem},
-
- {"badnick",
- {"reason", "nick", NULL},
- {"No reason", "", NULL},
- {DT_CHARPTR, DT_CHARPTR},
- InitXLine, DoQLine, DoneConfItem},
-
- {"badhost",
- {"reason", "host", NULL},
- {"No reason", "", NULL},
- {DT_CHARPTR, DT_CHARPTR},
- InitXLine, DoKLine, DoneConfItem},
-
- {"exception",
- {"reason", "host", NULL},
- {"No reason", "", NULL},
- {DT_CHARPTR, DT_CHARPTR},
- InitXLine, DoELine, DoneELine},
-
- {"type",
- {"name", "classes", NULL},
- {"", "", NULL},
- {DT_NOSPACES, DT_CHARPTR},
- InitTypes, DoType, DoneClassesAndTypes},
-
- {"class",
- {"name", "commands", "usermodes", "chanmodes", "privs", NULL},
- {"", "", "", "", "", NULL},
- {DT_NOSPACES, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR},
- InitClasses, DoClass, DoneClassesAndTypes},
-
- {NULL,
- {NULL},
- {NULL},
- {0},
- NULL, NULL, NULL}
- };
-
- /* Load and parse the config file, if there are any errors then explode */
-
- /* Make a copy here so if it fails then we can carry on running with an unaffected config */
- newconfig.clear();
-
- if (!this->DoInclude(newconfig, ServerInstance->ConfigFileName, *errstr))
- {
- ReportConfigError(errstr->str(), bail, useruid);
- delete errstr;
- return;
- }
-
- delete errstr;