]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/configreader.cpp
Move stuff around a bit:
[user/henk/code/inspircd.git] / src / configreader.cpp
index a8c0abe89056b4ed9fc11f5d47ab81ffa3285360..341414e0d5f8759bca70bfc69aa21108745e1b19 100644 (file)
@@ -32,7 +32,7 @@
 ServerConfig::ServerConfig()
 {
        RawLog = HideBans = HideSplits = UndernetMsgPrefix = false;
-       WildcardIPv6 = CycleHosts = InvBypassModes = true;
+       WildcardIPv6 = InvBypassModes = true;
        dns_timeout = 5;
        MaxTargets = 20;
        NetBufferSize = 10240;
@@ -44,16 +44,6 @@ ServerConfig::ServerConfig()
        c_ipv6_range = 128;
 }
 
-template<typename T, typename V>
-static void range(T& value, V min, V max, V def, const char* msg)
-{
-       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;
-}
-
 static void ValidHost(const std::string& p, const std::string& msg)
 {
        int num_dots = 0;
@@ -133,11 +123,11 @@ void ServerConfig::CrossCheckOperClassType()
                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;
 
@@ -162,8 +152,8 @@ void ServerConfig::CrossCheckOperClassType()
                        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());
@@ -309,7 +299,7 @@ void ServerConfig::CrossCheckConnectBlocks(ServerConfig* current)
                        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())
@@ -349,7 +339,8 @@ static const DeprecatedConfig ChangedConfig[] = {
        { "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()
@@ -358,19 +349,21 @@ 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.");
        }
        else
        {
                if (ServerName != ConfValue("server")->getString("name"))
-                       throw CoreException("You must restart to change the server name or SID");
+                       throw CoreException("You must restart to change the server name");
+
                std::string nsid = ConfValue("server")->getString("id");
                if (!nsid.empty() && nsid != sid)
-                       throw CoreException("You must restart to change the server name or SID");
+                       throw CoreException("You must restart to change the server id");
        }
        diepass = ConfValue("power")->getString("diepass");
        restartpass = ConfValue("power")->getString("restartpass");
@@ -381,21 +374,21 @@ void ServerConfig::Fill()
        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", ServerInstance->SE->GetMaxFds(), 10, ServerInstance->SE->GetMaxFds());
+       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");
@@ -403,12 +396,11 @@ void ServerConfig::Fill()
        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);
@@ -423,14 +415,16 @@ void ServerConfig::Fill()
        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);
+       Paths.Config = ConfValue("path")->getString("configdir", CONFIG_PATH);
+       Paths.Data = ConfValue("path")->getString("datadir", DATA_PATH);
+       Paths.Log = ConfValue("path")->getString("logdir", LOG_PATH);
+       Paths.Module = ConfValue("path")->getString("moduledir", MOD_PATH);
        InvBypassModes = options->getBool("invitebypassmodes", true);
        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")
@@ -457,6 +451,10 @@ void ServerConfig::Fill()
                std::string server;
                if (!tag->readString("server", server))
                        throw CoreException("<uline> tag missing server at " + tag->getTagLocation());
+
+               if (ServerName == server)
+                       throw CoreException("Servers should not uline themselves (at " + tag->getTagLocation() + ")");
+
                ulines[assign(server)] = tag->getBool("silent");
        }
 
@@ -523,7 +521,7 @@ void ServerConfig::Read()
        catch (CoreException& err)
        {
                valid = false;
-               errstr << err.GetReason();
+               errstr << err.GetReason() << std::endl;
        }
 }
 
@@ -561,7 +559,7 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid)
                                        {
                                                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;
                                }
                        }
                }
@@ -584,6 +582,11 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid)
        if (valid)
                ServerInstance->WritePID(this->PID);
 
+       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)
        {
                // On first run, ports are bound later on
@@ -670,9 +673,8 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid)
 
 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)
@@ -688,30 +690,27 @@ void ServerConfig::ApplyModules(User* user)
                }
        }
 
-       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)
        {
+               const std::string& modname = i->first;
                // Don't remove cmd_*.so, just remove m_*.so
-               if (removing->c_str()[0] == 'c')
+               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());
                }
        }
 
@@ -721,25 +720,20 @@ void ServerConfig::ApplyModules(User* user)
                {
                        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);
@@ -758,30 +752,28 @@ ConfigTagList ServerConfig::ConfTags(const std::string& tag)
        return config_data.equal_range(tag);
 }
 
-bool ServerConfig::FileExists(const char* file)
+std::string ServerConfig::Escape(const std::string& str, bool xml)
 {
-       struct stat sb;
-       if (stat(file, &sb) == -1)
-               return false;
-
-       if ((sb.st_mode & S_IFDIR) > 0)
-               return false;
-
-       FILE *input = fopen(file, "r");
-       if (input == NULL)
-               return false;
-       else
+       std::string escaped;
+       for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)
        {
-               fclose(input);
-               return true;
+               switch (*it)
+               {
+                       case '"':
+                               escaped += xml ? "&quot;" : "\"";
+                               break;
+                       case '&':
+                               escaped += xml ? "&amp;" : "&";
+                               break;
+                       case '\\':
+                               escaped += xml ? "\\" : "\\\\";
+                               break;
+                       default:
+                               escaped += *it;
+                               break;
+               }
        }
-}
-
-const char* ServerConfig::CleanFilename(const char* name)
-{
-       const char* p = name + strlen(name);
-       while ((p != name) && (*p != '/') && (*p != '\\')) p--;
-       return (p != name ? ++p : p);
+       return escaped;
 }
 
 void ConfigReaderThread::Run()
@@ -807,11 +799,16 @@ void ConfigReaderThread::Finish()
                 */
                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);
+
                ServerInstance->ISupport.Build();
 
                ServerInstance->Logs->CloseLogs();