]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/configreader.cpp
Implement <options:invitebypassmodes>, optionally circumvent +blk if invited on join...
[user/henk/code/inspircd.git] / src / configreader.cpp
index 19f5cc21cd8df5cff0389890eb377689dbab68a9..424f3ad68a1292c233f96e778f7adfd1ac0d92e8 100644 (file)
@@ -11,7 +11,7 @@
  * ---------------------------------------------------
  */
 
-/* $Core: libIRCDconfigreader */
+/* $Core */
 /* $CopyInstall: conf/inspircd.quotes.example $(CONPATH) */
 /* $CopyInstall: conf/inspircd.rules.example $(CONPATH) */
 /* $CopyInstall: conf/inspircd.motd.example $(CONPATH) */
@@ -19,7 +19,8 @@
 /* $CopyInstall: conf/inspircd.helpop.example $(CONPATH) */
 /* $CopyInstall: conf/inspircd.censor.example $(CONPATH) */
 /* $CopyInstall: conf/inspircd.filter.example $(CONPATH) */
-/* $CopyInstall: docs/inspircd.conf.example $(CONPATH) */
+/* $CopyInstall: conf/inspircd.conf.example $(CONPATH) */
+/* $CopyInstall: conf/modules.conf.example $(CONPATH) */
 
 #include "inspircd.h"
 #include <fstream>
@@ -43,7 +44,7 @@ ServerConfig::ServerConfig(InspIRCd* Instance) : ServerInstance(Instance)
        WhoWasGroupSize = WhoWasMaxGroups = WhoWasMaxKeep = 0;
        log_file = NULL;
        NoUserDns = forcedebug = OperSpyWhois = nofork = HideBans = HideSplits = UndernetMsgPrefix = false;
-       CycleHosts = writelog = AllowHalfop = true;
+       CycleHosts = writelog = AllowHalfop = InvBypassModes = true;
        dns_timeout = DieDelay = 5;
        MaxTargets = 20;
        NetBufferSize = 10240;
@@ -53,6 +54,8 @@ ServerConfig::ServerConfig(InspIRCd* Instance) : ServerInstance(Instance)
        debugging = 0;
        MaxChans = 20;
        OperMaxChans = 30;
+       c_ipv4_range = 32;
+       c_ipv6_range = 128;
        maxbans.clear();
        DNSServerValidator = &ValidateDnsServer;
 }
@@ -79,7 +82,6 @@ bool ServerConfig::AddIOHook(Module* iomod, BufferedSocket* is)
        else
        {
                throw ModuleException("BufferedSocket derived class already hooked by another module");
-               return false;
        }
 }
 
@@ -125,7 +127,7 @@ void ServerConfig::Update005()
 void ServerConfig::Send005(User* user)
 {
        for (std::vector<std::string>::iterator line = ServerInstance->Config->isupport.begin(); line != ServerInstance->Config->isupport.end(); line++)
-               user->WriteNumeric(005, "%s %s", user->nick.c_str(), line->c_str());
+               user->WriteNumeric(RPL_ISUPPORT, "%s %s", user->nick.c_str(), line->c_str());
 }
 
 bool ServerConfig::CheckOnce(const char* tag, ConfigDataHash &newconf)
@@ -133,15 +135,9 @@ bool ServerConfig::CheckOnce(const char* tag, ConfigDataHash &newconf)
        int count = ConfValueEnum(newconf, tag);
 
        if (count > 1)
-       {
                throw CoreException("You have more than one <"+std::string(tag)+"> tag, this is not permitted.");
-               return false;
-       }
        if (count < 1)
-       {
                throw CoreException("You have not defined a <"+std::string(tag)+"> tag, this is required.");
-               return false;
-       }
        return true;
 }
 
@@ -296,6 +292,28 @@ bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance)
        return true;
 }
 
+bool ValidateDisabledUModes(ServerConfig* conf, const char*, const char*, ValueItem &data)
+{
+       memset(conf->DisabledUModes, 0, sizeof(conf->DisabledUModes));
+       for (const unsigned char* p = (const unsigned char*)data.GetString(); *p; ++p)
+       {
+               if (*p < 'A' || *p > ('A' + 64)) throw CoreException(std::string("Invalid usermode ")+(char)*p+" was found.");
+               conf->DisabledUModes[*p - 'A'] = 1;
+       }
+       return true;
+}
+
+bool ValidateDisabledCModes(ServerConfig* conf, const char*, const char*, ValueItem &data)
+{
+       memset(conf->DisabledCModes, 0, sizeof(conf->DisabledCModes));
+       for (const unsigned char* p = (const unsigned char*)data.GetString(); *p; ++p)
+       {
+               if (*p < 'A' || *p > ('A' + 64)) throw CoreException(std::string("Invalid chanmode ")+(char)*p+" was found.");
+               conf->DisabledCModes[*p - 'A'] = 1;
+       }
+       return true;
+}
+
 bool ValidateDnsServer(ServerConfig* conf, const char*, const char*, ValueItem &data)
 {
        if (!*(data.GetString()))
@@ -350,7 +368,8 @@ bool ValidateServerName(ServerConfig* conf, const char*, const char*, ValueItem
 
 bool ValidateNetBufferSize(ServerConfig* conf, const char*, const char*, ValueItem &data)
 {
-       if ((!data.GetInteger()) || (data.GetInteger() > 65535) || (data.GetInteger() < 1024))
+       // 65534 not 65535 because of null terminator
+       if ((!data.GetInteger()) || (data.GetInteger() > 65534) || (data.GetInteger() < 1024))
        {
                conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"No NetBufferSize specified or size out of range, setting to default of 10240.");
                data.Set(10240);
@@ -389,7 +408,7 @@ bool ValidateRules(ServerConfig* conf, const char*, const char*, ValueItem &data
 
 bool ValidateModeLists(ServerConfig* conf, const char*, const char*, ValueItem &data)
 {
-       memset(conf->HideModeLists, 0, 256);
+       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;
@@ -397,7 +416,7 @@ bool ValidateModeLists(ServerConfig* conf, const char*, const char*, ValueItem &
 
 bool ValidateExemptChanOps(ServerConfig* conf, const char*, const char*, ValueItem &data)
 {
-       memset(conf->ExemptChanOps, 0, 256);
+       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;
@@ -760,6 +779,8 @@ void ServerConfig::Read(bool bail, User* user)
        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 */
        errstr.clear();
 
        include_stack.clear();
@@ -820,6 +841,8 @@ void ServerConfig::Read(bool bail, User* user)
                {"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},
                {"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},
@@ -844,6 +867,8 @@ void ServerConfig::Read(bool bail, User* user)
                {"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},
@@ -853,6 +878,7 @@ void ServerConfig::Read(bool bail, User* user)
                {"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}
        };
 
@@ -1248,7 +1274,7 @@ void ServerConfig::Read(bool bail, User* user)
                        int j = 1;
                        for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++)
                        {
-                               user->WriteServ("NOTICE %s :*** %d.   IP: %s     Port: %lu", user->nick.c_str(), j, i->first.empty() ? "<all>" : i->first.c_str(), (unsigned long)i->second);
+                               user->WriteServ("NOTICE %s :*** %d.   Address: %s        Reason: %s", user->nick.c_str(), j, i->first.empty() ? "<all>" : i->first.c_str(), i->second.c_str());
                        }
                        ServerInstance->Threads->Mutex(false);
                }
@@ -1263,14 +1289,14 @@ void ServerConfig::Read(bool bail, User* user)
                                        ServerInstance->SNO->WriteToSnoMask('A', "*** REHASH UNLOADED MODULE: %s",removing->c_str());
 
                                        if (user)
-                                               user->WriteNumeric(973, "%s %s :Module %s successfully unloaded.",user->nick.c_str(), removing->c_str(), removing->c_str());
+                                               user->WriteNumeric(RPL_UNLOADEDMODULE, "%s %s :Module %s successfully unloaded.",user->nick.c_str(), removing->c_str(), removing->c_str());
 
                                        rem++;
                                }
                                else
                                {
                                        if (user)
-                                               user->WriteNumeric(972, "%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 %s :Failed to unload module %s: %s",user->nick.c_str(), removing->c_str(), removing->c_str(), ServerInstance->Modules->LastError().c_str());
                                }
                        }
                }
@@ -1284,14 +1310,14 @@ void ServerConfig::Read(bool bail, User* user)
                                        ServerInstance->SNO->WriteToSnoMask('A', "*** REHASH LOADED MODULE: %s",adding->c_str());
 
                                        if (user)
-                                               user->WriteNumeric(975, "%s %s :Module %s successfully loaded.",user->nick.c_str(), adding->c_str(), adding->c_str());
+                                               user->WriteNumeric(RPL_LOADEDMODULE, "%s %s :Module %s successfully loaded.",user->nick.c_str(), adding->c_str(), adding->c_str());
 
                                        add++;
                                }
                                else
                                {
                                        if (user)
-                                               user->WriteNumeric(974, "%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 %s :Failed to load module %s: %s",user->nick.c_str(), adding->c_str(), adding->c_str(), ServerInstance->Modules->LastError().c_str());
                                }
                        }
                }
@@ -1302,12 +1328,14 @@ void ServerConfig::Read(bool bail, User* user)
 
        }
 
-       /** Note: This is safe, the method checks for user == NULL */
-       ServerInstance->Threads->Mutex(true);
-       ServerInstance->Parser->SetupCommandTable(user);
-       ServerInstance->Threads->Mutex(false);
-
-       if (!bail)
+       if (bail)
+       {
+               /** Note: This is safe, the method checks for user == NULL */
+               ServerInstance->Threads->Mutex(true);
+               ServerInstance->Parser->SetupCommandTable(user);
+               ServerInstance->Threads->Mutex(false);
+       }
+       else
        {
                if (user)
                        user->WriteServ("NOTICE %s :*** Successfully rehashed server.", user->nick.c_str());
@@ -2071,7 +2099,7 @@ bool ServerConfig::DirValid(const char* dirandfile)
 
 std::string ServerConfig::GetFullProgDir()
 {
-       char buffer[4096];
+       char buffer[PATH_MAX];
 #ifdef WINDOWS
        /* Windows has specific api calls to get the exe path that never fail.
         * For once, windows has something of use, compared to the POSIX code
@@ -2085,7 +2113,7 @@ std::string ServerConfig::GetFullProgDir()
        }
 #else
        // Get the current working directory
-       if (getcwd(buffer, 4096))
+       if (getcwd(buffer, PATH_MAX))
        {
                std::string remainder = this->argv[0];