summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/configreader.h63
-rw-r--r--src/configreader.cpp137
2 files changed, 135 insertions, 65 deletions
diff --git a/include/configreader.h b/include/configreader.h
index 179827eed..069e6321d 100644
--- a/include/configreader.h
+++ b/include/configreader.h
@@ -58,7 +58,12 @@ class ValueItem
v = value;
}
- void Set(const std::string &value)
+ void Set(char* value)
+ {
+ v = value;
+ }
+
+ void Set(const char* value)
{
v = value;
}
@@ -70,13 +75,61 @@ class ValueItem
v = n.str();
}
- int GetInteger() { return atoi(v.c_str()); };
+ int GetInteger()
+ {
+ return atoi(v.c_str());
+ }
+
+ char* GetString()
+ {
+ return (char*)v.c_str();
+ }
+
+ bool GetBool()
+ {
+ return (GetInteger() || v == "yes" || v == "true");
+ }
+};
+
+class ValueContainerBase
+{
+ public:
+ ValueContainerBase()
+ {
+ }
+
+ virtual ~ValueContainerBase()
+ {
+ }
+};
- const char* GetString() { return v.c_str(); };
+template<typename T> class ValueContainer : public ValueContainerBase
+{
+ T val;
+
+ public:
- bool GetBool() { return GetInteger(); };
+ ValueContainer()
+ {
+ val = NULL;
+ }
+
+ ValueContainer(T Val)
+ {
+ val = Val;
+ }
+
+ void Set(T newval, size_t s)
+ {
+ memcpy(val, newval, s);
+ }
};
+typedef ValueContainer<bool*> ValueContainerBool;
+typedef ValueContainer<unsigned int*> ValueContainerUInt;
+typedef ValueContainer<char*> ValueContainerChar;
+typedef ValueContainer<int*> ValueContainerInt;
+
typedef std::deque<ValueItem> ValueList;
/** A callback for validating a single value
@@ -96,7 +149,7 @@ struct InitialConfig
{
char* tag;
char* value;
- void* val;
+ ValueContainerBase* val;
ConfigDataType datatype;
Validator validation_function;
};
diff --git a/src/configreader.cpp b/src/configreader.cpp
index 37153afdd..c6227fc33 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -222,7 +222,7 @@ bool ValidateDnsServer(ServerConfig* conf, const char* tag, const char* value, V
if ((nameserver == "nameserver") && (!found_server))
{
resolv >> nameserver;
- data.Set(nameserver);
+ data.Set(nameserver.c_str());
found_server = true;
conf->GetInstance()->Log(DEFAULT,"<dns:server> set to '%s' as first resolver in /etc/resolv.conf.",nameserver.c_str());
}
@@ -256,7 +256,8 @@ bool ValidateServerName(ServerConfig* conf, const char* tag, const char* value,
if (!strchr(data.GetString(),'.'))
{
conf->GetInstance()->Log(DEFAULT,"WARNING: <server:name> '%s' is not a fully-qualified domain name. Changed to '%s%c'",data.GetString(),data.GetString(),'.');
- data.Set(std::string(data.GetString()) + ".");
+ std::string moo = std::string(data.GetString()).append(".");
+ data.Set(moo.c_str());
}
return true;
}
@@ -535,43 +536,42 @@ void ServerConfig::Read(bool bail, userrec* user)
/* These tags can occur ONCE or not at all */
static InitialConfig Values[] = {
- {"options", "softlimit", &this->SoftLimit, DT_INTEGER, ValidateSoftLimit},
- {"options", "somaxconn", &this->MaxConn, DT_INTEGER, ValidateMaxConn},
- {"server", "name", &this->ServerName, DT_CHARPTR, ValidateServerName},
- {"server", "description", &this->ServerDesc, DT_CHARPTR, NoValidation},
- {"server", "network", &this->Network, DT_CHARPTR, NoValidation},
- {"admin", "name", &this->AdminName, DT_CHARPTR, NoValidation},
- {"admin", "email", &this->AdminEmail, DT_CHARPTR, NoValidation},
- {"admin", "nick", &this->AdminNick, DT_CHARPTR, NoValidation},
- {"files", "motd", &this->motd, DT_CHARPTR, ValidateMotd},
- {"files", "rules", &this->rules, DT_CHARPTR, ValidateRules},
- {"power", "diepass", &this->diepass, DT_CHARPTR, NoValidation},
- {"power", "pause", &this->DieDelay, DT_INTEGER, NoValidation},
- {"power", "restartpass", &this->restartpass, DT_CHARPTR, NoValidation},
- {"options", "prefixquit", &this->PrefixQuit, DT_CHARPTR, NoValidation},
- {"die", "value", &this->DieValue, DT_CHARPTR, NoValidation},
- {"options", "loglevel", &debug, DT_CHARPTR, ValidateLogLevel},
- {"options", "netbuffersize", &this->NetBufferSize, DT_INTEGER, ValidateNetBufferSize},
- {"options", "maxwho", &this->MaxWhoResults, DT_INTEGER, ValidateMaxWho},
- {"options", "allowhalfop", &this->AllowHalfop, DT_BOOLEAN, NoValidation},
- {"dns", "server", &this->DNSServer, DT_CHARPTR, ValidateDnsServer},
- {"dns", "timeout", &this->dns_timeout, DT_INTEGER, ValidateDnsTimeout},
- {"options", "moduledir", &this->ModPath, DT_CHARPTR, ValidateModPath},
- {"disabled", "commands", &this->DisabledCommands, DT_CHARPTR, NoValidation},
- {"options", "userstats", &this->UserStats, DT_CHARPTR, NoValidation},
- {"options", "customversion", &this->CustomVersion, DT_CHARPTR, NoValidation},
- {"options", "hidesplits", &this->HideSplits, DT_BOOLEAN, NoValidation},
- {"options", "hidebans", &this->HideBans, DT_BOOLEAN, NoValidation},
- {"options", "hidewhois", &this->HideWhoisServer, DT_CHARPTR, NoValidation},
- {"options", "operspywhois", &this->OperSpyWhois, DT_BOOLEAN, NoValidation},
- {"options", "tempdir", &this->TempDir, DT_CHARPTR, ValidateTempDir},
- {"options", "nouserdns", &this->NoUserDns, DT_BOOLEAN, NoValidation},
- {"options", "syntaxhints", &this->SyntaxHints, DT_BOOLEAN, NoValidation},
- {"options", "cyclehosts", &this->CycleHosts, DT_BOOLEAN, NoValidation},
- {"pid", "file", &this->PID, DT_CHARPTR, NoValidation},
- {"whowas", "groupsize", &this->WhoWasGroupSize, DT_INTEGER, NoValidation},
- {"whowas", "maxgroups", &this->WhoWasMaxGroups, DT_INTEGER, NoValidation},
- {"whowas", "maxkeep", &maxkeep, DT_CHARPTR, ValidateWhoWas},
+ {"options", "softlimit", new ValueContainerUInt (&this->SoftLimit), DT_INTEGER, ValidateSoftLimit},
+ {"options", "somaxconn", new ValueContainerInt (&this->MaxConn), DT_INTEGER, ValidateMaxConn},
+ {"server", "name", new ValueContainerChar (this->ServerName), DT_CHARPTR, ValidateServerName},
+ {"server", "description", new ValueContainerChar (this->ServerDesc), DT_CHARPTR, NoValidation},
+ {"server", "network", new ValueContainerChar (this->Network), DT_CHARPTR, NoValidation},
+ {"admin", "name", new ValueContainerChar (this->AdminName), DT_CHARPTR, NoValidation},
+ {"admin", "email", new ValueContainerChar (this->AdminEmail), DT_CHARPTR, NoValidation},
+ {"admin", "nick", 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, NoValidation},
+ {"power", "pause", new ValueContainerInt (&this->DieDelay), DT_INTEGER, NoValidation},
+ {"power", "restartpass", new ValueContainerChar (this->restartpass), DT_CHARPTR, NoValidation},
+ {"options", "prefixquit", new ValueContainerChar (this->PrefixQuit), DT_CHARPTR, NoValidation},
+ {"options", "loglevel", new ValueContainerChar (debug), DT_CHARPTR, ValidateLogLevel},
+ {"options", "netbuffersize", new ValueContainerInt (&this->NetBufferSize), DT_INTEGER, ValidateNetBufferSize},
+ {"options", "maxwho", new ValueContainerInt (&this->MaxWhoResults), DT_INTEGER, ValidateMaxWho},
+ {"options", "allowhalfop", new ValueContainerBool (&this->AllowHalfop), DT_BOOLEAN, NoValidation},
+ {"dns", "server", new ValueContainerChar (this->DNSServer), DT_CHARPTR, ValidateDnsServer},
+ {"dns", "timeout", new ValueContainerInt (&this->dns_timeout), DT_INTEGER, ValidateDnsTimeout},
+ {"options", "moduledir", new ValueContainerChar (this->ModPath), DT_CHARPTR, ValidateModPath},
+ {"disabled", "commands", new ValueContainerChar (this->DisabledCommands), DT_CHARPTR, NoValidation},
+ {"options", "userstats", new ValueContainerChar (this->UserStats), DT_CHARPTR, NoValidation},
+ {"options", "customversion", new ValueContainerChar (this->CustomVersion), DT_CHARPTR, NoValidation},
+ {"options", "hidesplits", new ValueContainerBool (&this->HideSplits), DT_BOOLEAN, NoValidation},
+ {"options", "hidebans", new ValueContainerBool (&this->HideBans), DT_BOOLEAN, NoValidation},
+ {"options", "hidewhois", new ValueContainerChar (this->HideWhoisServer), DT_CHARPTR, NoValidation},
+ {"options", "operspywhois", new ValueContainerBool (&this->OperSpyWhois), DT_BOOLEAN, NoValidation},
+ {"options", "tempdir", new ValueContainerChar (this->TempDir), DT_CHARPTR, ValidateTempDir},
+ {"options", "nouserdns", new ValueContainerBool (&this->NoUserDns), DT_BOOLEAN, NoValidation},
+ {"options", "syntaxhints", new ValueContainerBool (&this->SyntaxHints), DT_BOOLEAN, NoValidation},
+ {"options", "cyclehosts", new ValueContainerBool (&this->CycleHosts), DT_BOOLEAN, NoValidation},
+ {"pid", "file", new ValueContainerChar (this->PID), DT_CHARPTR, NoValidation},
+ {"whowas", "groupsize", new ValueContainerInt (&this->WhoWasGroupSize), DT_INTEGER, NoValidation},
+ {"whowas", "maxgroups", new ValueContainerInt (&this->WhoWasMaxGroups), DT_INTEGER, NoValidation},
+ {"whowas", "maxkeep", new ValueContainerChar (maxkeep), DT_CHARPTR, ValidateWhoWas},
{NULL}
};
@@ -695,7 +695,7 @@ void ServerConfig::Read(bool bail, userrec* user)
/* Check we dont have more than one of singular tags, or any of them missing
*/
for (int Index = 0; Once[Index]; Index++)
- if (!CheckOnce(Once[Index],bail,user))
+ if (!CheckOnce(Once[Index], bail, user))
return;
/* Read the values of all the tags which occur once or not at all, and call their callbacks.
@@ -711,17 +711,32 @@ void ServerConfig::Read(bool bail, userrec* user)
switch (Values[Index].datatype)
{
case DT_CHARPTR:
- strlcpy((char*)Values[Index].val, vi.GetString(), MAXBUF);
+ {
+ ValueContainerChar* vcc = (ValueContainerChar*)Values[Index].val;
+ vcc->Set(vi.GetString(), strlen(vi.GetString()));
+ }
break;
case DT_INTEGER:
- *((int*)Values[Index].val) = vi.GetInteger();
+ {
+ int val = vi.GetInteger();
+ ValueContainerInt* vci = (ValueContainerInt*)Values[Index].val;
+ vci->Set(&val, sizeof(int));
+ }
break;
case DT_BOOLEAN:
- *((bool*)(Values[Index].val)) = vi.GetBool();
+ {
+ bool val = vi.GetBool();
+ ValueContainerBool* vcb = (ValueContainerBool*)Values[Index].val;
+ vcb->Set(&val, sizeof(bool));
+ }
break;
default:
+ /* You don't want to know what happens if someones bad code sends us here. */
break;
}
+
+ /* We're done with this now */
+ delete Values[Index].val;
}
/* Read the multiple-tag items (class tags, connect tags, etc)
@@ -745,7 +760,6 @@ void ServerConfig::Read(bool bail, userrec* user)
{
char item[MAXBUF];
ConfValue(this->config_data, MultiValues[Index].tag, MultiValues[Index].items[valuenum], tagnum, item, MAXBUF);
- ServerInstance->Log(DEBUG,"Data type DT_CHARPTR multi-item <%s:%s>[%d] = '%s'", MultiValues[Index].tag, MultiValues[Index].items[valuenum],tagnum, item);
vl.push_back(ValueItem(item));
}
break;
@@ -753,22 +767,21 @@ void ServerConfig::Read(bool bail, userrec* user)
{
int item;
ConfValueInteger(this->config_data, MultiValues[Index].tag, MultiValues[Index].items[valuenum], tagnum, item);
- ServerInstance->Log(DEBUG,"Data type DT_INTEGER multi-item <%s:%s>[%d] = '%d'", MultiValues[Index].tag, MultiValues[Index].items[valuenum],tagnum, item);
vl.push_back(ValueItem(item));
}
break;
case DT_BOOLEAN:
{
bool item = ConfValueBool(this->config_data, MultiValues[Index].tag, MultiValues[Index].items[valuenum], tagnum);
- ServerInstance->Log(DEBUG,"Data type DT_BOOLEAN multi-item <%s:%s>[%d] = '%d'", MultiValues[Index].tag, MultiValues[Index].items[valuenum],tagnum, item);
vl.push_back(ValueItem(item));
}
break;
default:
+ /* Someone was smoking craq if we got here, and we're all gonna die. */
break;
}
}
- ServerInstance->Log(DEBUG,"Call validation function for multi-value <%s>", MultiValues[Index].tag);
+
MultiValues[Index].validation_function(this, MultiValues[Index].tag, (char**)MultiValues[Index].items, vl, MultiValues[Index].datatype);
}
@@ -800,6 +813,7 @@ void ServerConfig::Read(bool bail, userrec* user)
}
if (!removed_modules.empty())
+ {
for (std::vector<std::string>::iterator removing = removed_modules.begin(); removing != removed_modules.end(); removing++)
{
if (ServerInstance->UnloadModule(removing->c_str()))
@@ -817,23 +831,26 @@ void ServerConfig::Read(bool bail, userrec* user)
user->WriteServ("972 %s %s :Failed to unload module %s: %s",user->nick, removing->c_str(), removing->c_str(), ServerInstance->ModuleError());
}
}
+ }
if (!added_modules.empty())
- for (std::vector<std::string>::iterator adding = added_modules.begin(); adding != added_modules.end(); adding++)
{
- if (ServerInstance->LoadModule(adding->c_str()))
- {
- ServerInstance->WriteOpers("*** REHASH LOADED MODULE: %s",adding->c_str());
-
- if (user)
- user->WriteServ("975 %s %s :Module %s successfully loaded.",user->nick, adding->c_str(), adding->c_str());
-
- add++;
- }
- else
+ for (std::vector<std::string>::iterator adding = added_modules.begin(); adding != added_modules.end(); adding++)
{
- if (user)
- user->WriteServ("974 %s %s :Failed to load module %s: %s",user->nick, adding->c_str(), adding->c_str(), ServerInstance->ModuleError());
+ if (ServerInstance->LoadModule(adding->c_str()))
+ {
+ ServerInstance->WriteOpers("*** REHASH LOADED MODULE: %s",adding->c_str());
+
+ if (user)
+ user->WriteServ("975 %s %s :Module %s successfully loaded.",user->nick, adding->c_str(), adding->c_str());
+
+ add++;
+ }
+ else
+ {
+ if (user)
+ user->WriteServ("974 %s %s :Failed to load module %s: %s",user->nick, adding->c_str(), adding->c_str(), ServerInstance->ModuleError());
+ }
}
}