summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-05-05 01:55:04 -0400
committerAdam <Adam@anope.org>2013-05-05 01:55:04 -0400
commit1d0bb9b26b7ad58ab0bf979ac046f4511b3bf12b (patch)
tree4486f0784bdf050fd7eb225c0cb9df352ce1f45a /src
parent781defb7076ddfddf723ca08cd0a518b6657b64f (diff)
Rework the config file reader to be much more flexible and move many configuration directives to the actual modules they are used in.
Diffstat (limited to 'src')
-rw-r--r--src/bots.cpp68
-rw-r--r--src/channels.cpp97
-rw-r--r--src/command.cpp6
-rw-r--r--src/config.cpp2119
-rw-r--r--src/configreader.cpp116
-rw-r--r--src/init.cpp24
-rw-r--r--src/language.cpp15
-rw-r--r--src/logger.cpp5
-rw-r--r--src/mail.cpp21
-rw-r--r--src/main.cpp6
-rw-r--r--src/messages.cpp46
-rw-r--r--src/misc.cpp40
-rw-r--r--src/modes.cpp82
-rw-r--r--src/modulemanager.cpp3
-rw-r--r--src/nickalias.cpp9
-rw-r--r--src/nickcore.cpp14
-rw-r--r--src/opertype.cpp4
-rw-r--r--src/protocol.cpp37
-rw-r--r--src/regchannel.cpp42
-rw-r--r--src/servers.cpp34
-rw-r--r--src/uplink.cpp24
-rw-r--r--src/users.cpp75
-rw-r--r--src/xline.cpp8
23 files changed, 714 insertions, 2181 deletions
diff --git a/src/bots.cpp b/src/bots.cpp
index f1a96eacf..fcbedeeb3 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -23,7 +23,7 @@ Serialize::Checker<botinfo_map> BotListByNick("BotInfo"), BotListByUID("BotInfo"
BotInfo *BotServ = NULL, *ChanServ = NULL, *Global = NULL, *HostServ = NULL, *MemoServ = NULL, *NickServ = NULL, *OperServ = NULL;
-BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Serializable("BotInfo"), botmodes(bmodes)
+BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Serializable("BotInfo"), channels("ChannelInfo"), botmodes(bmodes)
{
this->lastmsg = this->created = Anope::CurTime;
this->introduced = false;
@@ -58,15 +58,10 @@ BotInfo::~BotInfo()
IRCD->SendSQLineDel(&x);
}
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
+ for (std::set<ChannelInfo *>::iterator it = this->channels->begin(), it_end = this->channels->end(); it != it_end; ++it)
{
- ChannelInfo *ci = it->second;
-
- if (ci->bi == this)
- {
- ci->QueueUpdate();
- ci->bi = NULL;
- }
+ ChannelInfo *ci = *it;
+ this->UnAssign(NULL, ci);
}
BotListByNick->erase(this->nick);
@@ -129,21 +124,15 @@ void BotInfo::SetNewNick(const Anope::string &newnick)
(*BotListByNick)[this->nick] = this;
}
-void BotInfo::RejoinAll()
+const std::set<ChannelInfo *> &BotInfo::GetChannels() const
{
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- {
- const ChannelInfo *ci = it->second;
-
- if (ci->bi == this && ci->c && ci->c->users.size() >= Config->BSMinUsers)
- this->Join(ci->c);
- }
+ return this->channels;
}
void BotInfo::Assign(User *u, ChannelInfo *ci)
{
EventReturn MOD_RESULT = EVENT_CONTINUE;
- FOREACH_RESULT(I_OnBotAssign, OnBotAssign(u, ci, this));
+ FOREACH_RESULT(I_OnPreBotAssign, OnPreBotAssign(u, ci, this));
if (MOD_RESULT == EVENT_STOP)
return;
@@ -151,8 +140,10 @@ void BotInfo::Assign(User *u, ChannelInfo *ci)
ci->bi->UnAssign(u, ci);
ci->bi = this;
- if (Me->IsSynced() && ci->c && ci->c->users.size() >= Config->BSMinUsers)
- this->Join(ci->c, &ModeManager::DefaultBotModes);
+ this->channels->insert(ci);
+
+ ChannelStatus status;
+ FOREACH_MOD(I_OnBotAssign, OnBotAssign(u, ci, this));
}
void BotInfo::UnAssign(User *u, ChannelInfo *ci)
@@ -171,19 +162,12 @@ void BotInfo::UnAssign(User *u, ChannelInfo *ci)
}
ci->bi = NULL;
+ this->channels->erase(ci);
}
unsigned BotInfo::GetChannelCount() const
{
- unsigned count = 0;
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- {
- const ChannelInfo *ci = it->second;
-
- if (ci->bi == this)
- ++count;
- }
- return count;
+ return this->channels->size();
}
void BotInfo::Join(Channel *c, ChannelStatus *status)
@@ -191,35 +175,9 @@ void BotInfo::Join(Channel *c, ChannelStatus *status)
if (c->FindUser(this) != NULL)
return;
- if (Config && IRCD && Config->BSSmartJoin)
- {
- std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = c->GetModeList("BAN");
-
- /* We check for bans */
- for (; bans.first != bans.second; ++bans.first)
- {
- Entry ban("BAN", bans.first->second);
- if (ban.Matches(this))
- c->RemoveMode(NULL, "BAN", ban.GetMask());
- }
-
- Anope::string Limit;
- unsigned limit = 0;
- if (c->GetParam("LIMIT", Limit) && Limit.is_pos_number_only())
- limit = convertTo<unsigned>(Limit);
-
- /* Should we be invited? */
- if (c->HasMode("INVITE") || (limit && c->users.size() >= limit))
- IRCD->SendNotice(this, "@" + c->name, "%s invited %s into the channel.", this->nick.c_str(), this->nick.c_str());
-
- ModeManager::ProcessModes();
- }
-
c->JoinUser(this);
if (IRCD)
IRCD->SendJoin(this, c, status);
-
- FOREACH_MOD(I_OnBotJoin, OnBotJoin(c, this));
}
void BotInfo::Join(const Anope::string &chname, ChannelStatus *status)
diff --git a/src/channels.cpp b/src/channels.cpp
index 4d08661ef..5001869da 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -89,17 +89,7 @@ void Channel::Reset()
void Channel::Sync()
{
- if (!this->HasMode("PERM") && (this->users.empty() || (this->users.size() == 1 && this->ci && this->ci->bi && *this->ci->bi == this->users.begin()->second->user)))
- {
- this->Hold();
- }
- if (this->ci)
- {
- this->CheckModes();
-
- if (Me && Me->IsSynced())
- this->ci->RestoreTopic();
- }
+ FOREACH_MOD(I_OnChannelSync, OnChannelSync(this));
}
void Channel::CheckModes()
@@ -168,6 +158,8 @@ ChanUserContainer* Channel::JoinUser(User *user)
if (user->server && user->server->IsSynced())
Log(user, this, "join");
+ FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(user, this));
+
ChanUserContainer *cuc = new ChanUserContainer(user, this);
user->chans[this] = cuc;
this->users[user] = cuc;
@@ -401,16 +393,8 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A
FOREACH_RESULT(I_OnChannelModeUnset, OnChannelModeUnset(this, setter, cm->name, param));
if (enforce_mlock && MOD_RESULT != EVENT_STOP)
- {
- /* Reset modes on bots if we're supposed to */
- if (this->ci && this->ci->bi && this->ci->bi == bi)
- {
- if (ModeManager::DefaultBotModes.HasMode(cm->mchar))
- this->SetMode(bi, cm, bi->GetUID());
- }
-
this->SetCorrectModes(u, false, false);
- }
+
return;
}
@@ -790,22 +774,19 @@ void Channel::KickInternal(MessageSource &source, const Anope::string &nick, con
Anope::string chname = this->name;
- if (target->FindChannel(this))
+ ChanUserContainer *cu = target->FindChannel(this);
+ if (cu == NULL)
{
- FOREACH_MOD(I_OnUserKicked, OnUserKicked(this, target, source, reason));
- if (bi)
- this->Extend("INHABIT");
- this->DeleteUser(target);
- }
- else
Log() << "Channel::KickInternal got kick for user " << target->nick << " from " << source.GetSource() << " who isn't on channel " << this->name;
-
- /* Bots get rejoined */
- if (bi)
- {
- bi->Join(this, &ModeManager::DefaultBotModes);
- this->Shrink("INHABIT");
+ return;
}
+
+ Anope::string this_name = this->name;
+ ChannelStatus status = cu->status;
+
+ FOREACH_MOD(I_OnPreUserKicked, OnPreUserKicked(source, cu, reason));
+ this->DeleteUser(target); /* This can delete this; */
+ FOREACH_MOD(I_OnUserKicked, OnUserKicked(source, target, this_name, status, reason));
}
bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...)
@@ -873,54 +854,6 @@ void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtop
this->ci->CheckTopic();
}
-void Channel::Hold()
-{
- /** A timer used to keep the BotServ bot/ChanServ in the channel
- * after kicking the last user in a channel
- */
- class ChanServTimer : public Timer
- {
- private:
- Reference<Channel> c;
-
- public:
- /** Constructor
- * @param chan The channel
- */
- ChanServTimer(Channel *chan) : Timer(Config->CSInhabit), c(chan)
- {
- if (!ChanServ || !c)
- return;
- c->Extend("INHABIT");
- if (!c->ci || !c->ci->bi)
- ChanServ->Join(c);
- else if (!c->FindUser(c->ci->bi))
- c->ci->bi->Join(c);
- }
-
- /** Called when the delay is up
- * @param The current time
- */
- void Tick(time_t) anope_override
- {
- if (!c)
- return;
-
- c->Shrink("INHABIT");
-
- if (!c->ci || !c->ci->bi)
- {
- if (ChanServ)
- ChanServ->Part(c);
- }
- else if (c->users.size() == 1 || c->users.size() < Config->BSMinUsers)
- c->ci->bi->Part(c);
- }
- };
-
- new ChanServTimer(this);
-}
-
void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
{
if (user == NULL)
@@ -980,6 +913,8 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
}
}
}
+
+ FOREACH_MOD(I_OnSetCorrectModes, OnSetCorrectModes(user, this, u_access, give_modes));
}
bool Channel::Unban(User *u, bool full)
diff --git a/src/command.cpp b/src/command.cpp
index dc095fdd8..db4bb9996 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -191,7 +191,7 @@ void Command::OnSyntaxError(CommandSource &source, const Anope::string &subcomma
this->SendSyntax(source);
bool has_help = source.service->commands.find("HELP") != source.service->commands.end();
if (has_help)
- source.Reply(MORE_INFO, Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str());
+ source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
}
void RunCommand(CommandSource &source, const Anope::string &message)
@@ -216,7 +216,7 @@ void RunCommand(CommandSource &source, const Anope::string &message)
if (it == source.service->commands.end())
{
if (has_help)
- source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ source.Reply(_("Unknown command \002%s\002. \"%s %s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
else
source.Reply(_("Unknown command \002%s\002."), message.c_str());
return;
@@ -227,7 +227,7 @@ void RunCommand(CommandSource &source, const Anope::string &message)
if (!c)
{
if (has_help)
- source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
else
source.Reply(_("Unknown command \002%s\002."), message.c_str());
Log(source.service) << "Command " << it->first << " exists on me, but its service " << info.name << " was not found!";
diff --git a/src/config.cpp b/src/config.cpp
index bc01a1589..38e072de8 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -25,1020 +25,588 @@
#include <grp.h>
#endif
-/*************************************************************************/
+using namespace Configuration;
-ConfigurationFile ServicesConf("services.conf", false); // Services configuration file name
-ServerConfig *Config = NULL;
+File ServicesConf("services.conf", false); // Services configuration file name
+Conf *Config = NULL;
-static Anope::string UlineServers;
-static Anope::string BSDefaults;
-static Anope::string CSDefaults;
-static Anope::string NSDefaults;
-
-/*************************************************************************/
-
-ServerConfig::ServerConfig()
+Block::Block(const Anope::string &n) : name(n)
{
- this->Read();
-
- if (NSDefaults.empty())
- {
- this->NSDefFlags.insert("SECURE");
- this->NSDefFlags.insert("MEMO_SIGNON");
- this->NSDefFlags.insert("MEMO_RECEIVE");
- }
- else if (!NSDefaults.equals_ci("none"))
- {
- spacesepstream options(NSDefaults);
- Anope::string option;
- while (options.GetToken(option))
- {
- if (option.equals_ci("msg"))
- {
- if (!this->UsePrivmsg)
- Log() << "msg in <nickserv:defaults> can only be used when options:useprivmsg is set";
- else
- this->NSDefFlags.insert(option.upper());
- }
- else
- this->NSDefFlags.insert(option.upper());
- }
- }
-
- if (this->CSDefBantype < 0 || this->CSDefBantype > 3)
- {
- throw ConfigException("Value of CSDefBantype must be between 0 and 3 included");
- }
-
- if (CSDefaults.empty())
- {
- this->CSDefFlags.insert("KEEPTOPIC");
- this->CSDefFlags.insert("SECURE");
- this->CSDefFlags.insert("SECUREFOUNDER");
- this->CSDefFlags.insert("SIGNKICK");
- }
- else if (!CSDefaults.equals_ci("none"))
- {
- spacesepstream options(CSDefaults);
- Anope::string option;
- while (options.GetToken(option))
- this->CSDefFlags.insert(option.upper());
- }
-
- if (UseStrictPrivMsg)
- UseStrictPrivMsgString = "/";
- else
- UseStrictPrivMsgString ="/msg ";
-
-
- if (!BSDefaults.empty())
- {
- spacesepstream options(BSDefaults);
- Anope::string option;
- while (options.GetToken(option))
- this->BSDefFlags.insert("BS_" + option.upper());
- }
-
- /* Ulines */
- if (!UlineServers.empty())
- {
- this->Ulines.clear();
-
- spacesepstream ulines(UlineServers);
- Anope::string uline;
- while (ulines.GetToken(uline))
- this->Ulines.push_back(uline);
- }
-
- if (this->LimitSessions)
- {
- if (this->MaxSessionKill && !this->SessionAutoKillExpiry)
- this->SessionAutoKillExpiry = 1800; /* 30 minutes */
- }
-
- /* Check the user keys */
- if (this->Seed == 0)
- Log() << "Configuration option options:seed should be set. It's for YOUR safety! Remember that!";
-
- ModeManager::UpdateDefaultMLock(this);
-
- if (this->CaseMap == "ascii")
- Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>());
- else if (this->CaseMap == "rfc1459")
- Anope::casemap = std::locale(std::locale(), new Anope::rfc1459_ctype<char>());
- else
- {
- try
- {
- Anope::casemap = std::locale(this->CaseMap.c_str());
- }
- catch (const std::runtime_error &)
- {
- Log() << "Unknown casemap " << this->CaseMap << " - casemap not changed";
- }
- }
- Anope::CaseMapRebuild();
-
- if (this->SessionIPv4CIDR > 32 || this->SessionIPv6CIDR > 128)
- throw ConfigException("Session CIDR value out of range");
-
- ConfigReader reader(this);
- FOREACH_MOD(I_OnReload, OnReload(this, reader));
-
-#ifndef _WIN32
- if (!this->User.empty())
- {
- errno = 0;
- struct passwd *u = getpwnam(this->User.c_str());
- if (u == NULL)
- Log() << "Unable to setuid to " << this->User << ": " << Anope::LastError();
- else if (setuid(u->pw_uid) == -1)
- Log() << "Unable to setuid to " << this->User << ": " << Anope::LastError();
- else
- Log() << "Successfully set user to " << this->User;
- }
- if (!this->Group.empty())
- {
- errno = 0;
- struct group *g = getgrnam(this->Group.c_str());
- if (g == NULL)
- Log() << "Unable to setgid to " << this->Group << ": " << Anope::LastError();
- else if (setuid(g->gr_gid) == -1)
- Log() << "Unable to setgid to " << this->Group << ": " << Anope::LastError();
- else
- Log() << "Successfully set group to " << this->Group;
- }
-#endif
}
-bool ServerConfig::CheckOnce(const Anope::string &tag)
+const Anope::string &Block::GetName() const
{
- int count = ConfValueEnum(config_data, tag);
- if (count > 1)
- throw ConfigException("You have more than one <" + tag + "> tag, this is not permitted.");
- if (count < 1)
- throw ConfigException("You have not defined a <" + tag + "> tag, this is required.");
- return true;
+ return name;
}
-bool NoValidation(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &)
+int Block::CountBlock(const Anope::string &bname)
{
- return true;
-}
-
-void ServerConfig::ValidateNoSpaces(const Anope::string &p, const Anope::string &tag, const Anope::string &val) const
-{
- for (Anope::string::const_iterator ptr = p.begin(), end = p.end(); ptr != end; ++ptr)
- if (*ptr == ' ')
- throw ConfigException("The value of <" + tag + ":" + val + "> cannot contain spaces");
+ if (!this)
+ return 0;
+
+ return blocks.count(bname);
}
-/* NOTE: Before anyone asks why we're not using inet_pton for this, it is because inet_pton and friends do not return so much detail,
- * even in LastError(). They just return 'yes' or 'no' to an address without such detail as to whats WRONG with the address.
- * Because ircd users arent as technical as they used to be (;)) we are going to give more of a useful error message.
- */
-void ServerConfig::ValidateIP(const Anope::string &p, const Anope::string &tag, const Anope::string &val, bool wild) const
+Block* Block::GetBlock(const Anope::string &bname, int num)
{
- int num_dots = 0, num_seps = 0;
- bool not_numbers = false, not_hex = false;
-
- if (!p.empty())
- {
- if (p[0] == '.')
- throw ConfigException("The value of <" + tag + ":" + val + "> is not an IP address");
-
- for (Anope::string::const_iterator ptr = p.begin(), end = p.end(); ptr != end; ++ptr)
- {
- if (wild && (*ptr == '*' || *ptr == '?' || *ptr == '/'))
- continue;
-
- if (*ptr != ':' && *ptr != '.' && (*ptr < '0' || *ptr > '9'))
- {
- not_numbers = true;
- if (toupper(*ptr) < 'A' || toupper(*ptr) > 'F')
- not_hex = true;
- }
- switch (*ptr)
- {
- case ' ':
- throw ConfigException("The value of <" + tag + ":" + val + "> is not an IP address");
- case '.':
- ++num_dots;
- break;
- case ':':
- ++num_seps;
- }
- }
- if (num_dots > 3)
- throw ConfigException("The value of <" + tag + ":" + val + "> is an IPv4 address with too many fields!");
-
- if (num_seps > 8)
- throw ConfigException("The value of <" + tag + ":" + val + "> is an IPv6 address with too many fields!");
-
- if (!num_seps && num_dots < 3 && !wild)
- throw ConfigException("The value of <" + tag + ":" + val + "> looks to be a malformed IPv4 address");
-
- if (!num_seps && num_dots == 3 && not_numbers)
- throw ConfigException("The value of <" + tag + ":" + val + "> contains non-numeric characters in an IPv4 address");
-
- if (num_seps && not_hex)
- throw ConfigException("The value of <" + tag + ":" + val + "> contains non-hexdecimal characters in an IPv6 address");
+ if (!this)
+ return NULL;
+
+ std::pair<block_map::iterator, block_map::iterator> it = blocks.equal_range(bname);
- if (num_seps && num_dots != 3 && num_dots && !wild)
- throw ConfigException("The value of <" + tag + ":" + val + "> is a malformed IPv6 4in6 address");
- }
+ for (int i = 0; it.first != it.second; ++it.first, ++i)
+ if (i == num)
+ return &it.first->second;
+ return NULL;
}
-void ServerConfig::ValidateHostname(const Anope::string &p, const Anope::string &tag, const Anope::string &val) const
+bool Block::Set(const Anope::string &tag, const Anope::string &value)
{
- if (p.equals_ci("localhost"))
- return;
-
- int num_dots = 0, num_seps = 0;
- if (!p.empty())
- {
- if (p[0] == '.')
- throw ConfigException("The value of <" + tag + ":" + val + "> is not a valid hostname");
- for (unsigned i = 0, end = p.length(); i < end; ++i)
- {
- switch (p[i])
- {
- case ' ':
- throw ConfigException("The value of <" + tag + ":" + val + "> is not a valid hostname");
- case '.':
- ++num_dots;
- break;
- case ':':
- ++num_seps;
- break;
- }
- }
- if (!num_dots && !num_seps)
- throw ConfigException("The value of <" + tag + ":" + val + "> is not a valid hostname");
- }
-}
+ if (!this)
+ return false;
-static bool ValidateNotEmpty(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data)
-{
- if (data.GetValue().empty())
- throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty!");
+ items[tag] = value;
return true;
}
-static bool ValidateNotZero(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+const Block::item_map* Block::GetItems() const
{
- if (!data.GetInteger() && Anope::DoTime(data.GetValue()) <= 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero!");
- return true;
+ if (this)
+ return &items;
+ else
+ return NULL;
}
-static bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<> const Anope::string& Block::Get(const Anope::string &tag, const Anope::string& def) const
{
- if (!config->NSRegistration.equals_ci("none") && !config->NSRegistration.equals_ci("disable"))
- {
- if (value.equals_ci("unconfirmedexpire"))
- {
- if (!data.GetInteger() && Anope::DoTime(data.GetValue()) <= 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero when e-mail or admin registration is enabled!");
- }
- else
- {
- if (!data.GetBool())
- throw ConfigException("The value for <" + tag + ":" + value + "> must be set to yes when e-mail or admin registrations is enabled!");
- }
- }
- return true;
-}
+ if (!this)
+ return def;
-static bool ValidatePort(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data)
-{
- int port = data.GetInteger();
- if (!port)
- return true;
- if (port < 1 || port > 65535)
- throw ConfigException("The value for <" + tag + ":" + value + "> is not a value port, it must be between 1 and 65535!");
- return true;
-}
+ Anope::map<Anope::string>::const_iterator it = items.find(tag);
+ if (it != items.end())
+ return it->second;
-static bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data)
-{
- int bantype = data.GetInteger();
- if (bantype < 0 || bantype > 3)
- throw ConfigException("The value for <chanserv:defbantype> must be between 0 and 3!");
- return true;
+ return def;
}
-static bool ValidateNickServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<> time_t Block::Get(const Anope::string &tag, const Anope::string &def) const
{
- if (!config->NickServ.empty())
- {
- if (value.equals_ci("releasetimeout") || value.equals_ci("accessmax") || value.equals_ci("listmax"))
- return ValidateNotZero(config, tag, value, data);
- else if (value.equals_ci("enforceruser") || value.equals_ci("enforcerhost"))
- return ValidateNotEmpty(config, tag, value, data);
- else if (value.equals_ci("guestnickprefix"))
- {
- ValidateNotEmpty(config, tag, value, data);
- if (data.GetValue().length() > 21)
- throw ConfigException("The value for <nickserv:guestnickprefix> cannot exceed 21 characters in length!");
- }
- else if (value.equals_ci("registration"))
- if (!data.GetValue().equals_ci("none") && !data.GetValue().equals_ci("mail") && !data.GetValue().equals_ci("admin") && !data.GetValue().equals_ci("disable"))
- throw ConfigException("The value for <nickserv:registration> must be one of \"none\", \"mail\", \"admin\", or \"disable\"");
- }
- return true;
+ return Anope::DoTime(Get<const Anope::string &>(tag, def));
}
-static bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<> const char* Block::Get(const Anope::string &tag, const Anope::string &def) const
{
- if (!config->ChanServ.empty())
- {
- if ((value.equals_ci("decription") || value.equals_ci("autokickreason")) && data.GetValue().empty())
- throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when ChanServ is enabled!");
- else if (value.equals_ci("defbantype"))
- return ValidateBantype(config, tag, value, data);
- else if (value.equals_ci("accessmax") || value.equals_ci("autokickmax") || value.equals_ci("inhabit") || value.equals_ci("listmax"))
- return ValidateNotZero(config, tag, value, data);
- }
- return true;
+ return this->Get<const Anope::string &>(tag, def).c_str();
}
-static bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<> bool Block::Get(const Anope::string &tag, const Anope::string &def) const
{
- if (!config->BotServ.empty())
- {
- if (value.equals_ci("badwordsmax") || value.equals_ci("keepdata"))
- {
- if (!data.GetInteger() && Anope::DoTime(data.GetValue()) <= 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero when BotServ is enabled!");
- }
- else if (value.equals_ci("minusers"))
- {
- if (data.GetInteger() < 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be greater than or equal to zero!");
- }
- }
- return true;
+ const Anope::string &str = Get<const Anope::string &>(tag, def);
+ return str.equals_ci("yes") || str.equals_ci("on") || str.equals_ci("true");
}
-static bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+static void ValidateNotEmpty(const Anope::string &block, const Anope::string &name, const Anope::string &value)
{
- if (config->LimitSessions)
- {
- if (value.equals_ci("maxsessionlimit") || value.equals_ci("exceptionexpiry"))
- {
- if (!data.GetInteger() && Anope::DoTime(data.GetValue()) <= 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero when session limiting is enabled!");
- }
- }
- return true;
+ if (value.empty())
+ throw ConfigException("The value for <" + block + ":" + name + "> cannot be empty!");
}
-static bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<typename T> static void ValidateNotZero(const Anope::string &block, const Anope::string &name, T value)
{
- if (!config->OperServ.empty())
- {
- if (value.equals_ci("autokillexpiry") || value.equals_ci("chankillexpiry") || value.equals_ci("snlineexpiry") || value.equals_ci("sqlineexpiry"))
- return ValidateNotZero(config, tag, value, data);
- else if (value.equals_ci("maxsessionlimit") || value.equals_ci("exceptionexpiry"))
- return ValidateLimitSessions(config, tag, value, data);
- }
- return true;
+ if (!value)
+ throw ConfigException("The value for <" + block + ":" + name + "> cannot be zero!");
}
-static bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data)
+Conf::Conf() : Block("")
{
- int nicklen = data.GetInteger();
- if (!nicklen)
- {
- Log() << "You have not defined the <networkinfo:nicklen> directive. It is strongly";
- Log() << "adviced that you do configure this correctly in your services.conf";
- data.Set(31);
- }
- else if (nicklen < 1)
- {
- Log() << "<networkinfo:nicklen> has an invalid value; setting to 31";
- data.Set(31);
- }
- return true;
-}
+ ReadTimeout = 0;
+ UsePrivmsg = DefPrivmsg = false;
-static bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
-{
- if (config->UseMail)
- {
- Anope::string check[] = { "sendmailpath", "sendfrom", "registration_subject", "registration_message", "emailchange_subject", "emailchange_message", "memo_subject", "memo_message", "" };
- for (int i = 0; !check[i].empty(); ++i)
- if (value.equals_ci(check[i]))
- if (data.GetValue().empty())
- throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when e-mail is enabled!");
- }
- return true;
-}
+ this->LoadConf(ServicesConf);
-static bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
-{
- if (config->GlobalOnCycle)
+ for (int i = 0; i < this->CountBlock("include"); ++i)
{
- if (data.GetValue().empty())
- {
- Log() << "<" << tag << ":" << value << "> was undefined, disabling <options:globaloncycle>";
- config->GlobalOnCycle = false;
- }
- }
- return true;
-}
+ Block *include = this->GetBlock("include", i);
-static bool InitUplinks(ServerConfig *config, const Anope::string &)
-{
- if (!config->Uplinks.empty())
- {
- std::vector<ServerConfig::Uplink *>::iterator curr_uplink = config->Uplinks.begin(), end_uplink = config->Uplinks.end();
- for (; curr_uplink != end_uplink; ++curr_uplink)
- delete *curr_uplink;
- }
- config->Uplinks.clear();
- return true;
-}
+ const Anope::string &type = include->Get<const Anope::string &>("type"),
+ &file = include->Get<const Anope::string &>("name");
-static bool DoUplink(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- // Validation variables
- Anope::string host = values[0].GetValue(), password = values[3].GetValue();
- int port = values[2].GetInteger();
- bool ipv6 = values[1].GetBool();
- ValueItem vi_host(host), vi_port(port), vi_password(password);
- // Validate the host to make sure it is not empty
- if (!ValidateNotEmpty(config, "uplink", "host", vi_host))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- // Validate the port to make sure it is a valid port
- if (!ValidatePort(config, "uplink", "port", vi_port))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- // Validate the password to make sure it is not empty
- if (!ValidateNotEmpty(config, "uplink", "password", vi_password))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- // If we get here, all the values are valid, we'll add it to the Uplinks list
- config->Uplinks.push_back(new ServerConfig::Uplink(host, port, password, ipv6));
- return true;
-}
-
-static bool DoneUplinks(ServerConfig *config, const Anope::string &)
-{
- if (config->Uplinks.empty())
- throw ConfigException("You must define at least one uplink block!");
- return true;
-}
-
-static bool InitOperTypes(ServerConfig *config, const Anope::string &)
-{