#include "configparser.h"
#include <iostream>
+ServerLimits::ServerLimits(ConfigTag* tag)
+ : NickMax(tag->getInt("maxnick", 32))
+ , ChanMax(tag->getInt("maxchan", 64))
+ , MaxModes(tag->getInt("maxmodes", 20))
+ , IdentMax(tag->getInt("maxident", 11))
+ , MaxQuit(tag->getInt("maxquit", 255))
+ , MaxTopic(tag->getInt("maxtopic", 307))
+ , MaxKick(tag->getInt("maxkick", 255))
+ , MaxGecos(tag->getInt("maxgecos", 128))
+ , MaxAway(tag->getInt("maxaway", 200))
+ , MaxLine(tag->getInt("maxline", 512))
+ , MaxHost(tag->getInt("maxhost", 64))
+{
+}
+
+static ConfigTag* CreateEmptyTag()
+{
+ std::vector<KeyVal>* items;
+ return ConfigTag::create("empty", "<auto>", 0, items);
+}
+
ServerConfig::ServerConfig()
+ : EmptyTag(CreateEmptyTag())
+ , Limits(EmptyTag)
+ , NoSnoticeStack(false)
{
- RawLog = HideBans = HideSplits = UndernetMsgPrefix = false;
- WildcardIPv6 = CycleHosts = InvBypassModes = true;
+ RawLog = HideBans = HideSplits = false;
+ WildcardIPv6 = true;
dns_timeout = 5;
MaxTargets = 20;
NetBufferSize = 10240;
- SoftLimit = ServerInstance->SE->GetMaxFds();
MaxConn = SOMAXCONN;
MaxChans = 20;
OperMaxChans = 30;
c_ipv6_range = 128;
}
-template<typename T, typename V>
-static void range(T& value, V min, V max, V def, const char* msg)
+ServerConfig::~ServerConfig()
{
- if (value >= (T)min && value <= (T)max)
- return;
- ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "WARNING: %s value of %ld is not between %ld and %ld; set to %ld.",
- msg, (long)value, (long)min, (long)max, (long)def);
- value = def;
+ delete EmptyTag;
}
static void ValidHost(const std::string& p, const std::string& msg)
std::string thiscmd;
/* Enable everything first */
- for (Commandtable::iterator x = ServerInstance->Parser->cmdlist.begin(); x != ServerInstance->Parser->cmdlist.end(); x++)
+ const CommandParser::CommandMap& commands = ServerInstance->Parser.GetCommands();
+ for (CommandParser::CommandMap::const_iterator x = commands.begin(); x != commands.end(); ++x)
x->second->Disable(false);
/* Now disable all the ones which the user wants disabled */
while (dcmds >> thiscmd)
{
- Commandtable::iterator cm = ServerInstance->Parser->cmdlist.find(thiscmd);
- if (cm != ServerInstance->Parser->cmdlist.end())
- {
- cm->second->Disable(true);
- }
+ Command* handler = ServerInstance->Parser.GetHandler(thiscmd);
+ if (handler)
+ handler->Disable(true);
}
return true;
}
std::string name = tag->getString("name");
if (name.empty())
throw CoreException("<type:name> is missing from tag at " + tag->getTagLocation());
- if (oper_blocks.find(" " + name) != oper_blocks.end())
+ if (OperTypes.find(name) != OperTypes.end())
throw CoreException("Duplicate type block with name " + name + " at " + tag->getTagLocation());
OperInfo* ifo = new OperInfo;
- oper_blocks[" " + name] = ifo;
+ OperTypes[name] = ifo;
ifo->name = name;
ifo->type_block = tag;
throw CoreException("<oper:name> missing from tag at " + tag->getTagLocation());
std::string type = tag->getString("type");
- OperIndex::iterator tblk = oper_blocks.find(" " + type);
- if (tblk == oper_blocks.end())
+ OperIndex::iterator tblk = OperTypes.find(type);
+ if (tblk == OperTypes.end())
throw CoreException("Oper block " + name + " has missing type " + type);
if (oper_blocks.find(name) != oper_blocks.end())
throw CoreException("Duplicate oper block with name " + name + " at " + tag->getTagLocation());
for(ClassVector::iterator i = current->Classes.begin(); i != current->Classes.end(); ++i)
{
ConnectClass* c = *i;
- if (c->name.substr(0, 8) != "unnamed-")
+ if (c->name.compare(0, 8, "unnamed-", 8))
{
oldBlocksByMask["n" + c->name] = c;
}
me->maxchans = tag->getInt("maxchans", me->maxchans);
me->maxconnwarn = tag->getBool("maxconnwarn", me->maxconnwarn);
me->limit = tag->getInt("limit", me->limit);
- me->nouserdns = tag->getBool("nouserdns", me->nouserdns);
+ me->resolvehostnames = tag->getBool("resolvehostnames", me->resolvehostnames);
ClassMap::iterator oldMask = oldBlocksByMask.find(typeMask);
if (oldMask != oldBlocksByMask.end())
static const DeprecatedConfig ChangedConfig[] = {
{ "bind", "transport", "", "has been moved to <bind:ssl> as of 2.0" },
{ "die", "value", "", "you need to reread your config" },
+ { "gnutls", "starttls", "", "has been replaced with m_starttls as of 2.2" },
{ "link", "autoconnect", "", "2.0+ does not use this attribute - define <autoconnect> tags instead" },
{ "link", "transport", "", "has been moved to <link:ssl> as of 2.0" },
{ "module", "name", "m_chanprotect.so", "has been replaced with m_customprefix as of 2.2" },
{ "module", "name", "m_halfop.so", "has been replaced with m_customprefix as of 2.2" },
- { "performance", "nouserdns", "", "has been moved to <connect:nouserdns> as of 2.2" }
+ { "options", "cyclehosts", "", "has been replaced with m_hostcycle as of 2.2" },
+ { "performance", "nouserdns", "", "has been moved to <connect:resolvehostnames> as of 2.2" }
};
void ServerConfig::Fill()
ConfigTag* security = ConfValue("security");
if (sid.empty())
{
- ServerName = ConfValue("server")->getString("name");
- sid = ConfValue("server")->getString("id");
+ ServerName = ConfValue("server")->getString("name", "irc.example.com");
ValidHost(ServerName, "<server:name>");
+
+ sid = ConfValue("server")->getString("id");
if (!sid.empty() && !InspIRCd::IsSID(sid))
throw CoreException(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.");
}
std::string nsid = ConfValue("server")->getString("id");
if (!nsid.empty() && nsid != sid)
throw CoreException("You must restart to change the server id");
-
- if (Limits.MaxLine != static_cast<size_t>(ConfValue("limits")->getInt("maxline", 512)))
- throw CoreException("You must restart to change the maximum line length");
-
}
- diepass = ConfValue("power")->getString("diepass");
- restartpass = ConfValue("power")->getString("restartpass");
- powerhash = ConfValue("power")->getString("hash");
- PrefixQuit = options->getString("prefixquit");
- SuffixQuit = options->getString("suffixquit");
- FixedQuit = options->getString("fixedquit");
- PrefixPart = options->getString("prefixpart");
- SuffixPart = options->getString("suffixpart");
- FixedPart = options->getString("fixedpart");
- SoftLimit = ConfValue("performance")->getInt("softlimit", ServerInstance->SE->GetMaxFds());
+ SoftLimit = ConfValue("performance")->getInt("softlimit", (SocketEngine::GetMaxFds() > 0 ? SocketEngine::GetMaxFds() : LONG_MAX), 10);
+ CCOnConnect = ConfValue("performance")->getBool("clonesonconnect", true);
MaxConn = ConfValue("performance")->getInt("somaxconn", SOMAXCONN);
- MoronBanner = options->getString("moronbanner", "You're banned!");
+ XLineMessage = options->getString("xlinemessage", options->getString("moronbanner", "You're banned!"));
ServerDesc = ConfValue("server")->getString("description", "Configure Me");
Network = ConfValue("server")->getString("network", "Network");
- AdminName = ConfValue("admin")->getString("name", "");
- AdminEmail = ConfValue("admin")->getString("email", "null@example.com");
- AdminNick = ConfValue("admin")->getString("nick", "admin");
- ModPath = ConfValue("path")->getString("moduledir", MOD_PATH);
- NetBufferSize = ConfValue("performance")->getInt("netbuffersize", 10240);
+ NetBufferSize = ConfValue("performance")->getInt("netbuffersize", 10240, 1024, 65534);
dns_timeout = ConfValue("dns")->getInt("timeout", 5);
DisabledCommands = ConfValue("disabled")->getString("commands", "");
DisabledDontExist = ConfValue("disabled")->getBool("fakenonexistant");
UserStats = security->getString("userstats");
- CustomVersion = security->getString("customversion", Network + " IRCd");
+ CustomVersion = security->getString("customversion");
HideSplits = security->getBool("hidesplits");
HideBans = security->getBool("hidebans");
HideWhoisServer = security->getString("hidewhois");
RestrictBannedUsers = security->getBool("restrictbannedusers", true);
GenericOper = security->getBool("genericoper");
SyntaxHints = options->getBool("syntaxhints");
- CycleHosts = options->getBool("cyclehosts");
CycleHostsFromUser = options->getBool("cyclehostsfromuser");
- UndernetMsgPrefix = options->getBool("ircumsgprefix");
FullHostInTopic = options->getBool("hostintopic");
- MaxTargets = security->getInt("maxtargets", 20);
- DefaultModes = options->getString("defaultmodes", "nt");
+ MaxTargets = security->getInt("maxtargets", 20, 1, 31);
+ DefaultModes = options->getString("defaultmodes", "not");
PID = ConfValue("pid")->getString("file");
MaxChans = ConfValue("channels")->getInt("users", 20);
- OperMaxChans = ConfValue("channels")->getInt("opers", 60);
+ OperMaxChans = ConfValue("channels")->getInt("opers");
c_ipv4_range = ConfValue("cidr")->getInt("ipv4clone", 32);
c_ipv6_range = ConfValue("cidr")->getInt("ipv6clone", 128);
- Limits.NickMax = ConfValue("limits")->getInt("maxnick", 32);
- Limits.ChanMax = ConfValue("limits")->getInt("maxchan", 64);
- Limits.MaxModes = ConfValue("limits")->getInt("maxmodes", 20);
- Limits.IdentMax = ConfValue("limits")->getInt("maxident", 11);
- Limits.MaxQuit = ConfValue("limits")->getInt("maxquit", 255);
- Limits.MaxTopic = ConfValue("limits")->getInt("maxtopic", 307);
- Limits.MaxKick = ConfValue("limits")->getInt("maxkick", 255);
- Limits.MaxGecos = ConfValue("limits")->getInt("maxgecos", 128);
- Limits.MaxAway = ConfValue("limits")->getInt("maxaway", 200);
- Limits.MaxLine = ConfValue("limits")->getInt("maxline", 512);
- InvBypassModes = options->getBool("invitebypassmodes", true);
+ Limits = ServerLimits(ConfValue("limits"));
+ Paths.Config = ConfValue("path")->getString("configdir", INSPIRCD_CONFIG_PATH);
+ Paths.Data = ConfValue("path")->getString("datadir", INSPIRCD_DATA_PATH);
+ Paths.Log = ConfValue("path")->getString("logdir", INSPIRCD_LOG_PATH);
+ Paths.Module = ConfValue("path")->getString("moduledir", INSPIRCD_MODULE_PATH);
NoSnoticeStack = options->getBool("nosnoticestack", false);
- range(SoftLimit, 10, ServerInstance->SE->GetMaxFds(), ServerInstance->SE->GetMaxFds(), "<performance:softlimit>");
- if (ConfValue("performance")->getBool("limitsomaxconn", true))
- range(MaxConn, 0, SOMAXCONN, SOMAXCONN, "<performance:somaxconn>");
- range(MaxTargets, 1, 31, 20, "<security:maxtargets>");
- range(NetBufferSize, 1024, 65534, 10240, "<performance:netbuffersize>");
+ if (Network.find(' ') != std::string::npos)
+ throw CoreException(Network + " is not a valid network name. A network name must not contain spaces.");
std::string defbind = options->getString("defaultbind");
if (assign(defbind) == "ipv4")
if (socktest < 0)
WildcardIPv6 = false;
else
- ServerInstance->SE->Close(socktest);
- }
- ConfigTagList tags = ConfTags("uline");
- for(ConfigIter i = tags.first; i != tags.second; ++i)
- {
- ConfigTag* tag = i->second;
- std::string server;
- if (!tag->readString("server", server))
- throw CoreException("<uline> tag missing server at " + tag->getTagLocation());
- ulines[assign(server)] = tag->getBool("silent");
+ SocketEngine::Close(socktest);
}
ReadXLine(this, "badip", "ipmask", ServerInstance->XLines->GetFactory("Z"));
DisabledCModes[*p - 'A'] = 1;
}
- memset(HideModeLists, 0, sizeof(HideModeLists));
- modes = ConfValue("security")->getString("hidemodes");
- for (std::string::const_iterator p = modes.begin(); p != modes.end(); ++p)
- HideModeLists[(unsigned char) *p] = true;
-
std::string v = security->getString("announceinvites");
if (v == "ops")
catch (CoreException& err)
{
valid = false;
- errstr << err.GetReason();
+ errstr << err.GetReason() << std::endl;
}
}
{
errstr << ' ' << ChangedConfig[index].key << "=\"" << ChangedConfig[index].value << "\"";
}
- errstr << "> - " << ChangedConfig[index].reason << " (at " << i->second->getTagLocation() << ")\n";
+ errstr << "> - " << ChangedConfig[index].reason << " (at " << i->second->getTagLocation() << ")" << std::endl;
}
}
}
if (valid)
ServerInstance->WritePID(this->PID);
- if (old)
+ ConfigTagList binds = ConfTags("bind");
+ if (binds.first == binds.second)
+ errstr << "Possible configuration error: you have not defined any <bind> blocks." << std::endl
+ << "You will need to do this if you want clients to be able to connect!" << std::endl;
+
+ if (old && valid)
{
// On first run, ports are bound later on
FailedPortList pl;
User* user = useruid.empty() ? NULL : ServerInstance->FindNick(useruid);
if (!valid)
+ {
ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "There were errors in your configuration file:");
+ Classes.clear();
+ }
while (errstr.good())
{
ConfigTag *tag = (*it)->config;
// Make sure our connection class allows motd colors
if(!tag->getBool("allowmotdcolors"))
- continue;
+ continue;
ConfigFileCache::iterator file = this->Files.find(tag->getString("motd", "motd"));
if (file != this->Files.end())
- InspIRCd::ProcessColors(file->second);
-
- file = this->Files.find(tag->getString("rules", "rules"));
- if (file != this->Files.end())
- InspIRCd::ProcessColors(file->second);
+ InspIRCd::ProcessColors(file->second);
}
/* No old configuration -> initial boot, nothing more to do here */
void ServerConfig::ApplyModules(User* user)
{
- const std::vector<std::string> v = ServerInstance->Modules->GetAllModuleNames(0);
std::vector<std::string> added_modules;
- std::set<std::string> removed_modules(v.begin(), v.end());
+ ModuleManager::ModuleMap removed_modules = ServerInstance->Modules->GetModules();
ConfigTagList tags = ConfTags("module");
for(ConfigIter i = tags.first; i != tags.second; ++i)
std::string name;
if (tag->readString("name", name))
{
+ name = ModuleManager::ExpandModName(name);
// if this module is already loaded, the erase will succeed, so we need do nothing
// otherwise, we need to add the module (which will be done later)
if (removed_modules.erase(name) == 0)
}
}
- if (ConfValue("options")->getBool("allowhalfop") && removed_modules.erase("m_halfop.so") == 0)
- added_modules.push_back("m_halfop.so");
-
- for (std::set<std::string>::iterator removing = removed_modules.begin(); removing != removed_modules.end(); removing++)
+ for (ModuleManager::ModuleMap::iterator i = removed_modules.begin(); i != removed_modules.end(); ++i)
{
- // Don't remove cmd_*.so, just remove m_*.so
- if (removing->c_str()[0] == 'c')
+ const std::string& modname = i->first;
+ // Don't remove core_*.so, just remove m_*.so
+ if (modname.c_str()[0] == 'c')
continue;
- Module* m = ServerInstance->Modules->Find(*removing);
- if (m && ServerInstance->Modules->Unload(m))
+ if (ServerInstance->Modules->Unload(i->second))
{
- ServerInstance->SNO->WriteGlobalSno('a', "*** REHASH UNLOADED MODULE: %s",removing->c_str());
+ ServerInstance->SNO->WriteGlobalSno('a', "*** REHASH UNLOADED MODULE: %s", modname.c_str());
if (user)
- user->WriteNumeric(RPL_UNLOADEDMODULE, "%s %s :Module %s successfully unloaded.",user->nick.c_str(), removing->c_str(), removing->c_str());
+ user->WriteNumeric(RPL_UNLOADEDMODULE, "%s :Module %s successfully unloaded.", modname.c_str(), modname.c_str());
else
- ServerInstance->SNO->WriteGlobalSno('a', "Module %s successfully unloaded.", removing->c_str());
+ ServerInstance->SNO->WriteGlobalSno('a', "Module %s successfully unloaded.", modname.c_str());
}
else
{
if (user)
- user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s %s :Failed to unload module %s: %s",user->nick.c_str(), removing->c_str(), removing->c_str(), ServerInstance->Modules->LastError().c_str());
+ user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s :Failed to unload module %s: %s", modname.c_str(), modname.c_str(), ServerInstance->Modules->LastError().c_str());
else
- ServerInstance->SNO->WriteGlobalSno('a', "Failed to unload module %s: %s", removing->c_str(), ServerInstance->Modules->LastError().c_str());
+ ServerInstance->SNO->WriteGlobalSno('a', "Failed to unload module %s: %s", modname.c_str(), ServerInstance->Modules->LastError().c_str());
}
}
{
ServerInstance->SNO->WriteGlobalSno('a', "*** REHASH LOADED MODULE: %s",adding->c_str());
if (user)
- user->WriteNumeric(RPL_LOADEDMODULE, "%s %s :Module %s successfully loaded.",user->nick.c_str(), adding->c_str(), adding->c_str());
+ user->WriteNumeric(RPL_LOADEDMODULE, "%s :Module %s successfully loaded.", adding->c_str(), adding->c_str());
else
ServerInstance->SNO->WriteGlobalSno('a', "Module %s successfully loaded.", adding->c_str());
}
else
{
if (user)
- user->WriteNumeric(ERR_CANTLOADMODULE, "%s %s :Failed to load module %s: %s",user->nick.c_str(), adding->c_str(), adding->c_str(), ServerInstance->Modules->LastError().c_str());
+ user->WriteNumeric(ERR_CANTLOADMODULE, "%s :Failed to load module %s: %s", adding->c_str(), adding->c_str(), ServerInstance->Modules->LastError().c_str());
else
ServerInstance->SNO->WriteGlobalSno('a', "Failed to load module %s: %s", adding->c_str(), ServerInstance->Modules->LastError().c_str());
}
}
}
-bool ServerConfig::StartsWithWindowsDriveLetter(const std::string &path)
-{
- return (path.length() > 2 && isalpha(path[0]) && path[1] == ':');
-}
-
ConfigTag* ServerConfig::ConfValue(const std::string &tag)
{
ConfigTagList found = config_data.equal_range(tag);
if (found.first == found.second)
- return NULL;
+ return EmptyTag;
ConfigTag* rv = found.first->second;
found.first++;
if (found.first != found.second)
return config_data.equal_range(tag);
}
-bool ServerConfig::FileExists(const char* file)
-{
- struct stat sb;
- if (stat(file, &sb) == -1)
- return false;
-
- if ((sb.st_mode & S_IFDIR) > 0)
- return false;
-
- return !access(file, F_OK);
-}
-
std::string ServerConfig::Escape(const std::string& str, bool xml)
{
std::string escaped;
return escaped;
}
-const char* ServerConfig::CleanFilename(const char* name)
-{
- const char* p = name + strlen(name);
- while ((p != name) && (*p != '/') && (*p != '\\')) p--;
- return (p != name ? ++p : p);
-}
-
void ConfigReaderThread::Run()
{
Config->Read();
* XXX: The order of these is IMPORTANT, do not reorder them without testing
* thoroughly!!!
*/
+ ServerInstance->Users.RehashCloneCounts();
ServerInstance->XLines->CheckELines();
ServerInstance->XLines->ApplyLines();
- ModeReference ban(NULL, "ban");
+ ChanModeReference ban(NULL, "ban");
static_cast<ListModeBase*>(*ban)->DoRehash();
Config->ApplyDisabledCommands(Config->DisabledCommands);
User* user = ServerInstance->FindNick(TheUserUID);
- FOREACH_MOD(I_OnRehash, OnRehash(user));
+
+ ConfigStatus status(user);
+ const ModuleManager::ModuleMap& mods = ServerInstance->Modules->GetModules();
+ for (ModuleManager::ModuleMap::const_iterator i = mods.begin(); i != mods.end(); ++i)
+ i->second->ReadConfig(status);
+
+ // The description of this server may have changed - update it for WHOIS etc.
+ ServerInstance->FakeClient->server->description = Config->ServerDesc;
+
ServerInstance->ISupport.Build();
ServerInstance->Logs->CloseLogs();