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 &)
-{
- for (std::list<OperType *>::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it)
- delete *it;
+ File f(file, type == "executable");
+ this->LoadConf(f);
+ }
- config->MyOperTypes.clear();
- return true;
-}
+ FOREACH_MOD(I_OnReload, OnReload(this));
-static bool DoOperType(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue();
- Anope::string inherits = values[1].GetValue();
- Anope::string commands = values[2].GetValue();
- Anope::string privs = values[3].GetValue();
- Anope::string modes = values[4].GetValue();
-
- ValueItem vi(name);
- if (!ValidateNotEmpty(config, "opertype", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- OperType *ot = new OperType(name);
- ot->modes = modes;
-
- Anope::string tok;
- spacesepstream cmdstr(commands);
- while (cmdstr.GetToken(tok))
- ot->AddCommand(tok);
-
- spacesepstream privstr(privs);
- while (privstr.GetToken(tok))
- ot->AddPriv(tok);
-
- commasepstream inheritstr(inherits);
- while (inheritstr.GetToken(tok))
+ /* Check for modified values that aren't allowed to be modified */
+ if (Config)
{
- /* Strip leading ' ' after , */
- if (tok.length() > 1 && tok[0] == ' ')
- tok.erase(tok.begin());
- for (std::list<OperType *>::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it)
+ struct
{
- if ((*it)->GetName().equals_ci(tok))
- {
- Log() << "Inheriting commands and privs from " << (*it)->GetName() << " to " << ot->GetName();
- ot->Inherits(*it);
- break;
- }
- }
+ Anope::string block;
+ Anope::string name;
+ Anope::string def;
+ } noreload[] = {
+ {"serverinfo", "name", ""},
+ {"serverinfo", "description", ""},
+ {"serverinfo", "localhost", ""},
+ {"serverinfo", "id", ""},
+ {"serverinfo", "pid", ""},
+ {"networkinfo", "nicklen", "31"},
+ {"networkinfo", "userlen", "10"},
+ {"networkinfo", "hostlen", "64"},
+ {"networkinfo", "chanlen", "32"},
+ {"options", "passlen", "32"},
+ };
+
+ for (unsigned i = 0; i < sizeof(noreload) / sizeof(noreload[0]); ++i)
+ if (this->GetBlock(noreload[i].block)->Get<const Anope::string &>(noreload[i].name, noreload[i].def) != Config->GetBlock(noreload[i].block)->Get<const Anope::string &>(noreload[i].name, noreload[i].def))
+ throw ConfigException("<" + noreload[i].block + ":" + noreload[i].name + "> can not be modified once set");
}
- config->MyOperTypes.push_back(ot);
- return true;
-}
+ Block *options = this->GetBlock("options"), *mail = this->GetBlock("mail");
-static bool DoneOperTypes(ServerConfig *, const Anope::string &)
-{
- return true;
-}
+ ValidateNotZero("options", "releasetimeout", options->Get<time_t>("releasetimeout"));
+ ValidateNotEmpty("options", "enforceruser", options->Get<const Anope::string &>("enforceruser"));
+ ValidateNotEmpty("options", "enforcerhost", options->Get<const Anope::string &>("enforcerhost"));
+ ValidateNotEmpty("options", "guestnickprefix", options->Get<const Anope::string &>("guestnickprefix"));
+ spacesepstream(options->Get<const Anope::string &>("ulineservers")).GetTokens(this->Ulines);
-/*************************************************************************/
+ if (mail->Get<bool>("usemail"))
+ {
+ Anope::string check[] = { "sendmailpath", "sendfrom", "registration_subject", "registration_message", "emailchange_subject", "emailchange_message", "memo_subject", "memo_message" };
+ for (unsigned i = 0; i < sizeof(check) / sizeof(Anope::string); ++i)
+ ValidateNotEmpty("mail", check[i], mail->Get<const Anope::string &>(check[i]));
+ }
-static bool InitOpers(ServerConfig *config, const Anope::string &)
-{
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
+ this->ReadTimeout = options->Get<unsigned>("readtimeout");
+ this->UsePrivmsg = options->Get<bool>("useprivmsg");
+ this->StrictPrivmsg = options->Get<bool>("usestrictprivmsg") ? "/msg " : "/";
{
- NickCore *nc = it->second;
- nc->QueueUpdate();
- if (nc->o && nc->o->config)
- nc->o = NULL;
+ std::vector<Anope::string> defaults;
+ spacesepstream(this->GetModule("nickserv")->Get<const Anope::string &>("defaults")).GetTokens(defaults);
+ this->DefPrivmsg = std::find(defaults.begin(), defaults.end(), "msg") != defaults.end();
}
+ this->DefLanguage = options->Get<const Anope::string &>("defaultlanguage");
- for (unsigned i = 0; i < config->Opers.size(); ++i)
- delete config->Opers[i];
- config->Opers.clear();
+ for (int i = 0; i < this->CountBlock("uplink"); ++i)
+ {
+ Block *uplink = this->GetBlock("uplink", i);
- return true;
-}
+ const Anope::string &host = uplink->Get<const Anope::string &>("host");
+ bool ipv6 = uplink->Get<bool>("ipv6");
+ int port = uplink->Get<int>("port");
+ const Anope::string &password = uplink->Get<const Anope::string &>("password");
-static bool DoOper(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue();
- Anope::string type = values[1].GetValue();
- bool require_oper = values[2].GetBool();
- Anope::string password = values[3].GetValue();
- Anope::string certfp = values[4].GetValue();
- Anope::string host = values[5].GetValue();
- Anope::string vhost = values[6].GetValue();
-
- ValueItem vi(name);
- if (!ValidateNotEmpty(config, "oper", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- ValueItem vi2(type);
- if (!ValidateNotEmpty(config, "oper", "type", vi2))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- OperType *ot = NULL;
- for (std::list<OperType *>::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it)
- if ((*it)->GetName() == type)
- ot = *it;
- if (ot == NULL)
- throw ConfigException("Oper block for " + name + " has invalid oper type " + type);
-
- Oper *o = new Oper(name, ot);
- o->require_oper = require_oper;
- o->config = true;
- o->password = password;
- o->certfp = certfp;
- spacesepstream(host).GetTokens(o->hosts);
- o->vhost = vhost;
- config->Opers.push_back(o);
+ ValidateNotEmpty("uplink", "host", host);
+ ValidateNotEmpty("uplink", "password", password);
- return true;
-}
+ this->Uplinks.push_back(Uplink(host, port, password, ipv6));
+ }
-static bool DoneOpers(ServerConfig *config, const Anope::string &)
-{
- for (unsigned i = 0; i < config->Opers.size(); ++i)
+ for (int i = 0; i < this->CountBlock("module"); ++i)
{
- Oper *o = config->Opers[i];
+ Block *module = this->GetBlock("module", i);
- const NickAlias *na = NickAlias::Find(o->name);
- if (!na)
- // Nonexistant nick
- continue;
+ const Anope::string &modname = module->Get<const Anope::string &>("name");
- na->nc->o = o;
- Log() << "Tied oper " << na->nc->display << " to type " << o->ot->GetName();
+ ValidateNotEmpty("module", "name", modname);
+
+ this->ModulesAutoLoad.push_back(modname);
}
- return true;
-}
+ for (int i = 0; i < this->CountBlock("opertype"); ++i)
+ {
+ Block *opertype = this->GetBlock("opertype", i);
-/*************************************************************************/
+ const Anope::string &oname = opertype->Get<const Anope::string &>("name"),
+ &modes = opertype->Get<const Anope::string &>("modes"),
+ &inherits = opertype->Get<const Anope::string &>("inherits"),
+ &commands = opertype->Get<const Anope::string &>("commands"),
+ &privs = opertype->Get<const Anope::string &>("privs");
-static std::map<Anope::string, Anope::string> defines;
-static bool InitDefine(ServerConfig *config, const Anope::string &)
-{
- defines.clear();
- return true;
-}
+ ValidateNotEmpty("opertype", "name", oname);
-static bool DoDefine(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue(), value = values[1].GetValue();
- defines[name] = value;
- return true;
-}
+ OperType *ot = new OperType(oname);
+ ot->modes = modes;
-static bool DoneDefine(ServerConfig *config, const Anope::string &)
-{
- return true;
-}
+ spacesepstream cmdstr(commands);
+ for (Anope::string str; cmdstr.GetToken(str);)
+ ot->AddCommand(str);
-/*************************************************************************/
+ spacesepstream privstr(privs);
+ for (Anope::string str; cmdstr.GetToken(str);)
+ ot->AddPriv(str);
-static bool InitInclude(ServerConfig *config, const Anope::string &)
-{
- return true;
-}
+ commasepstream inheritstr(inherits);
+ for (Anope::string str; inheritstr.GetToken(str);)
+ {
+ /* Strip leading ' ' after , */
+ if (str.length() > 1 && str[0] == ' ')
+ str.erase(str.begin());
+ for (unsigned j = 0; j < this->MyOperTypes.size(); ++j)
+ {
+ OperType *ot2 = this->MyOperTypes[j];
-static bool DoInclude(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string type = values[0].GetValue();
- Anope::string file = values[1].GetValue();
+ if (ot2->GetName().equals_ci(str))
+ {
+ Log() << "Inheriting commands and privs from " << ot2->GetName() << " to " << ot->GetName();
+ ot->Inherits(ot2);
+ break;
+ }
+ }
+ }
- if (type != "file" && type != "executable")
- throw ConfigException("include:type must be either \"file\" or \"executable\"");
-
- ConfigurationFile f(file, type == "executable");
- config->LoadConf(f);
+ this->MyOperTypes.push_back(ot);
+ }
- return true;
-}
+ for (int i = 0; i < this->CountBlock("oper"); ++i)
+ {
+ Block *oper = this->GetBlock("oper", i);
-static bool DoneInclude(ServerConfig *config, const Anope::string &)
-{
- return true;
-}
+ const Anope::string &nname = oper->Get<const Anope::string &>("name"),
+ &type = oper->Get<const Anope::string &>("type"),
+ &password = oper->Get<const Anope::string &>("password"),
+ &certfp = oper->Get<const Anope::string &>("certfp"),
+ &host = oper->Get<const Anope::string &>("host"),
+ &vhost = oper->Get<const Anope::string &>("vhost");
+ bool require_oper = oper->Get<bool>("require_oper");
-/*************************************************************************/
+ ValidateNotEmpty("oper", "name", nname);
+ ValidateNotEmpty("oper", "type", type);
+
+ OperType *ot = NULL;
+ for (unsigned j = 0; j < this->MyOperTypes.size(); ++j)
+ if (this->MyOperTypes[j]->GetName() == type)
+ ot = this->MyOperTypes[j];
+ if (ot == NULL)
+ throw ConfigException("Oper block for " + nname + " has invalid oper type " + type);
-static bool InitModules(ServerConfig *, const Anope::string &)
-{
- return true;
-}
+ Oper *o = new Oper(nname, ot);
+ o->require_oper = require_oper;
+ o->config = true;
+ o->password = password;
+ o->certfp = certfp;
+ spacesepstream(host).GetTokens(o->hosts);
+ o->vhost = vhost;
-static bool DoModule(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- // First we validate that there was a name in the module block
- Anope::string module = values[0].GetValue();
- ValueItem vi(module);
- if (!ValidateNotEmpty(conf, "module", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- conf->ModulesAutoLoad.push_back(module);
- return true;
-}
+ this->Opers.push_back(o);
+ }
-static bool DoneModules(ServerConfig *config, const Anope::string &)
-{
- if (Config)
- {
- for (std::list<Anope::string>::iterator it = Config->ModulesAutoLoad.begin(); it != Config->ModulesAutoLoad.end(); ++it)
- if (std::find(config->ModulesAutoLoad.begin(), config->ModulesAutoLoad.end(), *it) == config->ModulesAutoLoad.end())
- ModuleManager::UnloadModule(ModuleManager::FindModule(*it), NULL);
- for (std::list<Anope::string>::iterator it = config->ModulesAutoLoad.begin(); it != config->ModulesAutoLoad.end(); ++it)
- if (std::find(Config->ModulesAutoLoad.begin(), Config->ModulesAutoLoad.end(), *it) == Config->ModulesAutoLoad.end())
- ModuleManager::LoadModule(*it, NULL);
+ for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ it->second->conf = false;
+ for (int i = 0; i < this->CountBlock("service"); ++i)
+ {
+ Block *service = this->GetBlock("service", i);
+
+ const Anope::string &nick = service->Get<const Anope::string &>("nick"),
+ &user = service->Get<const Anope::string &>("user"),
+ &host = service->Get<const Anope::string &>("host"),
+ &gecos = service->Get<const Anope::string &>("gecos"),
+ &modes = service->Get<const Anope::string &>("modes"),
+ &channels = service->Get<const Anope::string &>("channels");
+
+ ValidateNotEmpty("service", "nick", nick);
+ ValidateNotEmpty("service", "user", user);
+ ValidateNotEmpty("service", "host", host);
+ ValidateNotEmpty("service", "gecos", gecos);
+
+ BotInfo *bi = BotInfo::Find(nick, true);
+ if (!bi)
+ bi = new BotInfo(nick, user, host, gecos, modes);
+ bi->conf = true;
+
+ std::vector<Anope::string> oldchannels = bi->botchannels;
+ bi->botchannels.clear();
+ commasepstream sep(channels);
+ for (Anope::string token; sep.GetToken(token);)
+ {
+ bi->botchannels.push_back(token);
+ size_t ch = token.find('#');
+ Anope::string chname, want_modes;
+ if (ch == Anope::string::npos)
+ chname = token;
+ else
+ {
+ want_modes = token.substr(0, ch);
+ chname = token.substr(ch);
+ }
+ bi->Join(chname);
+ Channel *c = Channel::Find(chname);
+ if (!c)
+ continue; // Can't happen
+
+ /* Remove all existing modes */
+ ChanUserContainer *cu = c->FindUser(bi);
+ if (cu != NULL)
+ for (size_t j = 0; j < cu->status.Modes().length(); ++j)
+ c->RemoveMode(bi, ModeManager::FindChannelModeByChar(cu->status.Modes()[j]), bi->GetUID());
+ /* Set the new modes */
+ for (unsigned j = 0; j < want_modes.length(); ++j)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]);
+ if (cm == NULL)
+ cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j]));
+ if (cm && cm->type == MODE_STATUS)
+ c->SetMode(bi, cm, bi->GetUID());
+ }
+ }
+ for (unsigned k = 0; k < oldchannels.size(); ++k)
+ {
+ size_t ch = oldchannels[k].find('#');
+ Anope::string chname = oldchannels[k].substr(ch != Anope::string::npos ? ch : 0);
+
+ bool found = false;
+ for (unsigned j = 0; j < bi->botchannels.size(); ++j)
+ {
+ ch = bi->botchannels[j].find('#');
+ Anope::string ochname = bi->botchannels[j].substr(ch != Anope::string::npos ? ch : 0);
+
+ if (chname.equals_ci(ochname))
+ found = true;
+ }
+
+ if (found)
+ continue;
+
+ Channel *c = Channel::Find(chname);
+ if (c)
+ bi->Part(c);
+ }
+ }
+
+ for (int i = 0; i < this->CountBlock("log"); ++i)
+ {
+ Block *log = this->GetBlock("log", i);
+
+ int logage = log->Get<int>("logage");
+ bool rawio = log->Get<bool>("rawio");
+ bool debug = log->Get<bool>("debug");
+
+ LogInfo l(logage, rawio, debug);
+
+ spacesepstream(log->Get<const Anope::string &>("target")).GetTokens(l.targets);
+ spacesepstream(log->Get<const Anope::string &>("source")).GetTokens(l.sources);
+ spacesepstream(log->Get<const Anope::string &>("admin")).GetTokens(l.admin);
+ spacesepstream(log->Get<const Anope::string &>("override")).GetTokens(l.override);
+ spacesepstream(log->Get<const Anope::string &>("commands")).GetTokens(l.commands);
+ spacesepstream(log->Get<const Anope::string &>("servers")).GetTokens(l.servers);
+ spacesepstream(log->Get<const Anope::string &>("channels")).GetTokens(l.channels);
+ spacesepstream(log->Get<const Anope::string &>("users")).GetTokens(l.users);
+ spacesepstream(log->Get<const Anope::string &>("normal")).GetTokens(l.normal);
+
+ this->LogInfos.push_back(l);
}
- return true;
-}
-static bool InitLogs(ServerConfig *config, const Anope::string &)
-{
- config->LogInfos.clear();
- return true;
-}
+ for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ it->second->commands.clear();
+ for (int i = 0; i < this->CountBlock("command"); ++i)
+ {
+ Block *command = this->GetBlock("command", i);
-static bool DoLogs(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- //{"target", "source", "logage", "inhabit", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug"},
- Anope::string targets = values[0].GetValue();
- ValueItem vi(targets);
- if (!ValidateNotEmpty(config, "log", "target", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- Anope::string source = values[1].GetValue();
- int logage = values[2].GetInteger();
- Anope::string admin = values[3].GetValue();
- Anope::string override = values[4].GetValue();
- Anope::string commands = values[5].GetValue();
- Anope::string servers = values[6].GetValue();
- Anope::string channels = values[7].GetValue();
- Anope::string users = values[8].GetValue();
- Anope::string normal = values[9].GetValue();
- bool rawio = values[10].GetBool();
- bool ldebug = values[11].GetBool();
-
- LogInfo *l = new LogInfo(logage, rawio, ldebug);
- spacesepstream(targets).GetTokens(l->targets);
- spacesepstream(source).GetTokens(l->sources);
- spacesepstream(admin).GetTokens(l->admin);
- spacesepstream(override).GetTokens(l->override);
- spacesepstream(commands).GetTokens(l->commands);
- spacesepstream(servers).GetTokens(l->servers);
- spacesepstream(channels).GetTokens(l->channels);
- spacesepstream(users).GetTokens(l->users);
- spacesepstream(normal).GetTokens(l->normal);
-
- config->LogInfos.push_back(l);
+ const Anope::string &service = command->Get<const Anope::string &>("service"),
+ &nname = command->Get<const Anope::string &>("name"),
+ &cmd = command->Get<const Anope::string &>("command"),
+ &permission = command->Get<const Anope::string &>("permission"),
+ &group = command->Get<const Anope::string &>("group");
+ bool hide = command->Get<bool>("hide");
- return true;
-}
+ ValidateNotEmpty("command", "service", service);
+ ValidateNotEmpty("command", "name", nname);
+ ValidateNotEmpty("command", "command", cmd);
-static bool DoneLogs(ServerConfig *config, const Anope::string &)
-{
- Log() << "Loaded " << config->LogInfos.size() << " log blocks";
- return true;
-}
+ BotInfo *bi = BotInfo::Find(service, true);
+ if (!bi)
+ continue;
-/*************************************************************************/
+ CommandInfo &ci = bi->SetCommand(nname, cmd, permission);
+ ci.group = group;
+ ci.hide = hide;
+ }
-static bool InitCommands(ServerConfig *config, const Anope::string &)
-{
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ PrivilegeManager::ClearPrivileges();
+ for (int i = 0; i < this->CountBlock("privilege"); ++i)
{
- BotInfo *bi = it->second;
- if (bi)
- {
- bi->QueueUpdate();
- bi->commands.clear();
- }
+ Block *privilege = this->GetBlock("privilege", i);
+
+ const Anope::string &nname = privilege->Get<const Anope::string &>("name"),
+ &desc = privilege->Get<const Anope::string &>("desc");
+ int rank = privilege->Get<int>("rank");
+
+ PrivilegeManager::AddPrivilege(Privilege(nname, desc, rank));
}
- return true;
-}
-static bool DoCommands(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string service = values[0].GetValue();
- Anope::string name = values[1].GetValue();
- Anope::string command = values[2].GetValue();
- Anope::string permission = values[3].GetValue();
- Anope::string group = values[4].GetValue();
- bool hide = values[5].GetBool();
-
- ValueItem vi(service);
- if (!ValidateNotEmpty(config, "command", "service", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(name);
- if (!ValidateNotEmpty(config, "command", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(command);
- if (!ValidateNotEmpty(config, "command", "command", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- BotInfo *bi = BotInfo::Find(service);
- if (bi == NULL)
- throw ConfigException("Command " + name + " exists for nonexistant service " + service);
+ for (int i = 0; i < this->CountBlock("fantasy"); ++i)
+ {
+ Block *fantasy = this->GetBlock("fantasy", i);
- if (bi->commands.count(name))
- throw ConfigException("Command name " + name + " already exists on " + bi->nick);
+ const Anope::string &nname = fantasy->Get<const Anope::string &>("name"),
+ &service = fantasy->Get<const Anope::string &>("command"),
+ &permission = fantasy->Get<const Anope::string &>("permission"),
+ &group = fantasy->Get<const Anope::string &>("group");
+ bool hide = fantasy->Get<bool>("hide"),
+ prepend_channel = fantasy->Get<bool>("prepend_channel");
- CommandInfo &ci = bi->SetCommand(name, command, permission);
- ci.group = group;
- ci.hide = hide;
- return true;
-}
+ ValidateNotEmpty("fantasy", "name", nname);
+ ValidateNotEmpty("fantasy", "command", service);
-static bool DoneCommands(ServerConfig *config, const Anope::string &)
-{
- return true;
-}
+ CommandInfo &c = this->Fantasy[name];
+ c.name = service;
+ c.permission = permission;
+ c.group = group;
+ c.hide = hide;
+ c.prepend_channel = prepend_channel;
+ }
-/*************************************************************************/
+ for (int i = 0; i < this->CountBlock("command_group"); ++i)
+ {
+ Block *command_group = this->GetBlock("command_group", i);
-static bool InitPrivileges(ServerConfig *config, const Anope::string &)
-{
- PrivilegeManager::ClearPrivileges();
- return true;
-}
+ const Anope::string &nname = command_group->Get<const Anope::string &>("name"),
+ &description = command_group->Get<const Anope::string &>("description");
-static bool DoPrivileges(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue();
- Anope::string desc = values[1].GetValue();
- int rank = values[2].GetInteger();
+ CommandGroup gr;
+ gr.name = nname;
+ gr.description = description;
- ValueItem vi(name);
- if (!ValidateNotEmpty(config, "privilege", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+ this->CommandGroups.push_back(gr);
+ }
- PrivilegeManager::AddPrivilege(Privilege(name, desc, rank));
- return true;
-}
+ /* Below here can't throw */
-static bool DonePrivileges(ServerConfig *config, const Anope::string &)
-{
- Log(LOG_DEBUG) << "Loaded " << PrivilegeManager::GetPrivileges().size() << " privileges";
- return true;
-}
+ for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
+ {
+ NickCore *nc = it->second;
+ if (nc->o && nc->o->config)
+ nc->o = NULL;
+ }
+ for (unsigned i = 0; i < this->Opers.size(); ++i)
+ {
+ Oper *o = this->Opers[i];
-/*************************************************************************/
+ NickAlias *na = NickAlias::Find(o->name);
+ if (!na)
+ continue;
-static std::set<Anope::string> services;
-static bool InitServices(ServerConfig *config, const Anope::string &)
-{
- services.clear();
- return true;
-}
+ na->nc->o = o;
+ Log() << "Tied oper " << na->nc->display << " to type " << o->ot->GetName();
+ }
-static bool DoServices(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string nick = values[0].GetValue();
- Anope::string user = values[1].GetValue();
- Anope::string host = values[2].GetValue();
- Anope::string gecos = values[3].GetValue();
- Anope::string modes = values[4].GetValue();
- Anope::string channels = values[5].GetValue();
-
- ValueItem vi(nick);
- if (!ValidateNotEmpty(config, "service", "nick", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(user);
- if (!ValidateNotEmpty(config, "service", "user", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(host);
- if (!ValidateNotEmpty(config, "service", "host", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(gecos);
- if (!ValidateNotEmpty(config, "service", "gecos", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- services.insert(nick);
- BotInfo* bi = BotInfo::Find(nick);
- if (!bi)
- bi = new BotInfo(nick, user, host, gecos, modes);
- bi->conf = true;
-
- Anope::string token;
- commasepstream sep(channels);
- std::vector<Anope::string> oldchannels = bi->botchannels;
- bi->botchannels.clear();
- while (sep.GetToken(token))
+ if (options->Get<const Anope::string &>("casemap", "ascii") == "ascii")
+ Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>());
+ else if (options->Get<const Anope::string &>("casemap") == "rfc1459")
+ Anope::casemap = std::locale(std::locale(), new Anope::rfc1459_ctype<char>());
+ else
{
- bi->botchannels.push_back(token);
- size_t ch = token.find('#');
- Anope::string chname, want_modes;
- if (ch == Anope::string::npos)
- chname = token;
- else
+ try
{
- want_modes = token.substr(0, ch);
- chname = token.substr(ch);
+ Anope::casemap = std::locale(options->Get<const char *>("casemap"));
}
- bi->Join(chname);
- Channel *c = Channel::Find(chname);
- if (!c)
- continue; // Can't happen
-
- /* Remove all existing modes */
- ChanUserContainer *cu = c->FindUser(bi);
- if (cu != NULL)
- for (size_t i = 0; i < cu->status.Modes().length(); ++i)
- c->RemoveMode(bi, ModeManager::FindChannelModeByChar(cu->status.Modes()[i]), bi->GetUID());
- /* Set the new modes */
- for (unsigned j = 0; j < want_modes.length(); ++j)
+ catch (const std::runtime_error &)
{
- ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]);
- if (cm == NULL)
- cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j]));
- if (cm && cm->type == MODE_STATUS)
- c->SetMode(bi, cm, bi->GetUID());
+ Log() << "Unknown casemap " << options->Get<const Anope::string &>("casemap") << " - casemap not changed";
}
}
- for (unsigned i = 0; i < oldchannels.size(); ++i)
- {
- size_t ch = oldchannels[i].find('#');
- Anope::string chname = oldchannels[i].substr(ch != Anope::string::npos ? ch : 0);
-
- bool found = false;
- for (unsigned j = 0; j < bi->botchannels.size(); ++j)
- {
- ch = bi->botchannels[j].find('#');
- Anope::string ochname = bi->botchannels[j].substr(ch != Anope::string::npos ? ch : 0);
-
- if (chname.equals_ci(ochname))
- found = true;
- }
+ Anope::CaseMapRebuild();
- if (found)
- continue;
+ /* Check the user keys */
+ if (!options->Get<unsigned>("seed"))
+ Log() << "Configuration option options:seed should be set. It's for YOUR safety! Remember that!";
- Channel *c = Channel::Find(chname);
- if (c)
- bi->Part(c);
+#ifndef _WIN32
+ if (!options->Get<const Anope::string &>("user").empty())
+ {
+ errno = 0;
+ struct passwd *u = getpwnam(options->Get<const char *>("user"));
+ if (u == NULL)
+ Log() << "Unable to setuid to " << options->Get<const Anope::string &>("user") << ": " << Anope::LastError();
+ else if (setuid(u->pw_uid) == -1)
+ Log() << "Unable to setuid to " << options->Get<const Anope::string &>("user") << ": " << Anope::LastError();
+ else
+ Log() << "Successfully set user to " << options->Get<const Anope::string &>("user");
}
-
- return true;
-}
-
-static bool DoneServices(ServerConfig *config, const Anope::string &)
-{
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end;)
+ if (!options->Get<const Anope::string &>("group").empty())
{
- BotInfo *bi = it->second;
- ++it;
-
- if (bi->conf && services.count(bi->nick) == 0)
- delete bi;
+ errno = 0;
+ struct group *g = getgrnam(options->Get<const char *>("group"));
+ if (g == NULL)
+ Log() << "Unable to setgid to " << options->Get<const Anope::string &>("group") << ": " << Anope::LastError();
+ else if (setuid(g->gr_gid) == -1)
+ Log() << "Unable to setgid to " << options->Get<const Anope::string &>("group") << ": " << Anope::LastError();
+ else
+ Log() << "Successfully set group to " << options->Get<const Anope::string &>("group");
}
- services.clear();
- return true;
-}
-
-/*************************************************************************/
-
-static bool InitFantasy(ServerConfig *config, const Anope::string &)
-{
- config->Fantasy.clear();
- return true;
-}
-
-static bool DoFantasy(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue();
- Anope::string service = values[1].GetValue();
- Anope::string permission = values[2].GetValue();
- Anope::string group = values[3].GetValue();
- bool hide = values[4].GetBool();
- bool prepend_channel = values[5].GetBool();
-
- CommandInfo &c = config->Fantasy[name];
-
- c.name = service;
- c.permission = permission;
- c.group = group;
- c.hide = hide;
- c.prepend_channel = prepend_channel;
-
- return true;
-}
+#endif
-static bool DoneFantasy(ServerConfig *config, const Anope::string &)
-{
- return true;
+ /* Apply module chnages */
+ if (Config)
+ {
+ for (unsigned i = 0; i < Config->ModulesAutoLoad.size(); ++i)
+ if (std::find(this->ModulesAutoLoad.begin(), this->ModulesAutoLoad.end(), Config->ModulesAutoLoad[i]) == this->ModulesAutoLoad.end())
+ ModuleManager::UnloadModule(ModuleManager::FindModule(Config->ModulesAutoLoad[i]), NULL);
+ for (unsigned i = 0; i < this->ModulesAutoLoad.size(); ++i)
+ if (std::find(Config->ModulesAutoLoad.begin(), Config->ModulesAutoLoad.end(), this->ModulesAutoLoad[i]) == Config->ModulesAutoLoad.end())
+ ModuleManager::LoadModule(this->ModulesAutoLoad[i], NULL);
+ }
}
-/*************************************************************************/
-
-static bool InitCommandGroups(ServerConfig *config, const Anope::string &)
+Block *Conf::GetModule(Module *m)
{
- config->CommandGroups.clear();
- return true;
+ if (!m)
+ return NULL;
+
+ return GetModule(m->name);
}
-static bool DoCommandGroups(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+Block *Conf::GetModule(const Anope::string &mname)
{
- Anope::string name = values[0].GetValue();
- Anope::string description = values[1].GetValue();
+ std::map<Anope::string, Block *>::iterator it = modules.find(mname);
+ if (it != modules.end())
+ return it->second;
- if (name.empty() || description.empty())
- return true;
+ Block* &block = modules[mname];
+
+ /* Search for the block */
+ for (std::pair<block_map::iterator, block_map::iterator> iters = blocks.equal_range("module"); iters.first != iters.second; ++iters.first)
+ {
+ Block *b = &iters.first->second;
- CommandGroup gr;
- gr.name = name;
- gr.description = description;
+ if (b->Get<const Anope::string &>("name") == mname)
+ {
+ block = b;
+ break;
+ }
+ }
- config->CommandGroups.push_back(gr);
- return true;
+ return GetModule(mname);
}
-static bool DoneCommandGroups(ServerConfig *config, const Anope::string &)
+File::File(const Anope::string &n, bool e) : name(n), executable(e), fp(NULL)
{
- return true;
}
-/*************************************************************************/
-
-ConfigurationFile::ConfigurationFile(const Anope::string &n, bool e) : name(n), executable(e), fp(NULL)
-{
-}
-
-ConfigurationFile::~ConfigurationFile()
+File::~File()
{
this->Close();
}
-const Anope::string &ConfigurationFile::GetName() const
+const Anope::string &File::GetName() const
{
return this->name;
}
-bool ConfigurationFile::IsOpen() const
+bool File::IsOpen() const
{
return this->fp != NULL;
}
-bool ConfigurationFile::Open()
+bool File::Open()
{
this->Close();
this->fp = (this->executable ? popen(this->name.c_str(), "r") : fopen((Anope::ConfigDir + "/" + this->name).c_str(), "r"));
return this->fp != NULL;
}
-void ConfigurationFile::Close()
+void File::Close()
{
if (this->fp != NULL)
{
@@ -1050,12 +618,12 @@ void ConfigurationFile::Close()
}
}
-bool ConfigurationFile::End() const
+bool File::End() const
{
return !this->IsOpen() || feof(this->fp);
}
-Anope::string ConfigurationFile::Read()
+Anope::string File::Read()
{
Anope::string ret;
char buf[BUFSIZE];
@@ -1077,552 +645,50 @@ Anope::string ConfigurationFile::Read()
return ret;
}
-ConfigItems::ConfigItems(ServerConfig *conf)
+void Conf::LoadConf(File &file)
{
- // These tags can occur ONCE or not at all
- const Item Items[] = {
- /* The following comments are from CyberBotX to w00t as examples to use:
- *
- * The last argument, for validation, must use one of the functions with the following signature:
- * bool <function>(ServerConfig *, const char *, const char *, ValueItem &)
- * Examples are: NoValidation, ValidateNotEmpty, etc.
- *
- * If you want to create a directive using an integer:
- * int blarg;
- * {"tag", "value", "0", new ValueContainerInt(&conf->blarg), DT_INTEGER, <validation>},
- *
- * If you want to create a directive using an unsigned integer:
- * unsigned blarg;
- * {"tag", "value", "0", new ValueContainerUInt(&conf->blarg), DT_UINTEGER, <validation>},
- *
- * If you want to create a directive using a string:
- * Anope::string blarg;
- * {"tag", "value", "", new ValueContainerString(&conf->blarg), DT_STRING, <validation>},
- *
- * If you want to create a directive using a boolean:
- * bool blarg;
- * {"tag", "value", "no", new ValueContainerBool(&conf->blarg), DT_BOOLEAN, <validation>},
- *
- * If you want to create a directive using a character pointer specifically to hold a hostname (this will call ValidateHostname automatically):
- * char *blarg;
- * {"tag", "value", "", new ValueContainerChar(&conf->blarg), DT_HOSTNAME, <validation>},
- *
- * If you want to create a directive using a character pointer that specifically can not have spaces in it (this will call ValidateNoSpaces automatically):
- * char *blarg;
- * {"tag", "value", "", new ValueContainerChar(&conf->blarg), DT_NOSPACES, <validation>},
- *
- * If you want to create a directive using a character pointer specifically to hold an IP address (this will call ValidateIP automatically):
- * char *blarg;
- * {"tag", "value", "", new ValueContainerChar(&conf->blarg), DT_IPADDRESS, <validation>},
- *
- * If you want to create a directive using a time (a time_t variable converted from a string):
- * time_t blarg;
- * {"tag", "value", "", new ValueContainterTime(&conf->blarg), DT_TIME, <validation>},
- *
- * For the second-to-last argument, you can or (|) in the following values:
- * DT_NORELOAD - The variable can't be changed on a reload of the configuration
- * DT_ALLOW_WILD - Allows wildcards/CIDR in DT_IPADDRESS
- * DT_ALLOW_NEWLINE - Allows new line characters in DT_STRING
- *
- * We may need to add some other validation functions to handle certain things, we can handle that later.
- * Any questions about these, w00t, feel free to ask. */
- {"serverinfo", "name", "", new ValueContainerString(&conf->ServerName), DT_HOSTNAME | DT_NORELOAD, ValidateNotEmpty},
- {"serverinfo", "description", "", new ValueContainerString(&conf->ServerDesc), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
- {"serverinfo", "localhost", "", new ValueContainerString(&conf->LocalHost), DT_HOSTNAME | DT_NORELOAD, NoValidation},
- {"serverinfo", "id", "", new ValueContainerString(&conf->Numeric), DT_NOSPACES | DT_NORELOAD, NoValidation},
- {"serverinfo", "pid", "data/services.pid", new ValueContainerString(&conf->PIDFilename), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
- {"serverinfo", "motd", "conf/services.motd", new ValueContainerString(&conf->MOTDFilename), DT_STRING, ValidateNotEmpty},
- {"networkinfo", "networkname", "", new ValueContainerString(&conf->NetworkName), DT_STRING, ValidateNotEmpty},
- {"networkinfo", "nicklen", "31", new ValueContainerUInt(&conf->NickLen), DT_UINTEGER | DT_NORELOAD, ValidateNickLen},
- {"networkinfo", "userlen", "10", new ValueContainerUInt(&conf->UserLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"networkinfo", "hostlen", "64", new ValueContainerUInt(&conf->HostLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"networkinfo", "chanlen", "32", new ValueContainerUInt(&conf->ChanLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"networkinfo", "modelistsize", "0", new ValueContainerUInt(&conf->ListSize), DT_UINTEGER, NoValidation},
- {"options", "user", "", new ValueContainerString(&conf->User), DT_STRING, NoValidation},
- {"options", "group", "", new ValueContainerString(&conf->Group), DT_STRING, NoValidation},
- {"options", "casemap", "ascii", new ValueContainerString(&conf->CaseMap), DT_STRING, NoValidation},
- {"options", "passlen", "32", new ValueContainerUInt(&conf->PassLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"options", "seed", "0", new ValueContainerLUInt(&conf->Seed), DT_LUINTEGER, NoValidation},
- {"options", "nobackupokay", "no", new ValueContainerBool(&conf->NoBackupOkay), DT_BOOLEAN, NoValidation},
- {"options", "strictpasswords", "no", new ValueContainerBool(&conf->StrictPasswords), DT_BOOLEAN, NoValidation},
- {"options", "badpasslimit", "0", new ValueContainerUInt(&conf->BadPassLimit), DT_UINTEGER, NoValidation},
- {"options", "badpasstimeout", "0", new ValueContainerTime(&conf->BadPassTimeout), DT_TIME, NoValidation},
- {"options", "updatetimeout", "0", new ValueContainerTime(&conf->UpdateTimeout), DT_TIME, ValidateNotZero},
- {"options", "expiretimeout", "0", new ValueContainerTime(&conf->ExpireTimeout), DT_TIME, ValidateNotZero},
- {"options", "readtimeout", "0", new ValueContainerTime(&conf->ReadTimeout), DT_TIME, ValidateNotZero},
- {"options", "warningtimeout", "0", new ValueContainerTime(&conf->WarningTimeout), DT_TIME, ValidateNotZero},
- {"options", "timeoutcheck", "0", new ValueContainerTime(&conf->TimeoutCheck), DT_TIME, NoValidation},
- {"options", "keepbackups", "0", new ValueContainerInt(&conf->KeepBackups), DT_INTEGER, NoValidation},
- {"options", "forceforbidreason", "no", new ValueContainerBool(&conf->ForceForbidReason), DT_BOOLEAN, NoValidation},
- {"options", "useprivmsg", "no", new ValueContainerBool(&conf->UsePrivmsg), DT_BOOLEAN, NoValidation},
- {"options", "usestrictprivmsg", "no", new ValueContainerBool(&conf->UseStrictPrivMsg), DT_BOOLEAN, NoValidation},
- {"options", "hidestatso", "no", new ValueContainerBool(&conf->HideStatsO), DT_BOOLEAN, NoValidation},
- {"options", "nickregdelay", "0", new ValueContainerUInt(&conf->NickRegDelay), DT_UINTEGER, NoValidation},
- {"options", "restrictopernicks", "no", new ValueContainerBool(&conf->RestrictOperNicks), DT_BOOLEAN, NoValidation},
- {"options", "newscount", "3", new ValueContainerUInt(&conf->NewsCount), DT_UINTEGER, NoValidation},
- {"options", "ulineservers", "", new ValueContainerString(&UlineServers), DT_STRING, NoValidation},
- {"options", "botmodes", "", new ValueContainerString(&conf->BotModes), DT_STRING, NoValidation},
- {"options", "retrywait", "60", new ValueContainerInt(&conf->RetryWait), DT_INTEGER, ValidateNotZero},
- {"options", "hideprivilegedcommands", "yes", new ValueContainerBool(&conf->HidePrivilegedCommands), DT_BOOLEAN, NoValidation},
- {"options", "nonicknameownership", "no", new ValueContainerBool(&conf->NoNicknameOwnership), DT_BOOLEAN | DT_NORELOAD, NoValidation},
- {"options", "regexengine", "", new ValueContainerString(&conf->RegexEngine), DT_STRING, NoValidation},
- {"nickserv", "name", "", new ValueContainerString(&conf->NickServ), DT_STRING, NoValidation},
- {"nickserv", "registration", "none", new ValueContainerString(&conf->NSRegistration), DT_STRING, ValidateNickServ},
- {"nickserv", "unregistered_notice", "", new ValueContainerString(&conf->NSUnregisteredNotice), DT_STRING, NoValidation},
- {"nickserv", "forceemail", "no", new ValueContainerBool(&conf->NSForceEmail), DT_BOOLEAN, ValidateEmailReg},
- {"nickserv", "confirmemailchanges", "no", new ValueContainerBool(&conf->NSConfirmEmailChanges), DT_BOOLEAN, NoValidation},
- {"nickserv", "defaults", "secure memo_signon memo_receive", new ValueContainerString(&NSDefaults), DT_STRING, NoValidation},
- {"nickserv", "languages", "", new ValueContainerString(&conf->Languages), DT_STRING, NoValidation},
- {"nickserv", "defaultlanguage", "0", new ValueContainerString(&conf->NSDefLanguage), DT_STRING, NoValidation},
- {"nickserv", "regdelay", "0", new ValueContainerTime(&conf->NSRegDelay), DT_TIME, NoValidation},
- {"nickserv", "resenddelay", "0", new ValueContainerTime(&conf->NSResendDelay), DT_TIME, NoValidation},
- {"nickserv", "expire", "21d", new ValueContainerTime(&conf->NSExpire), DT_TIME, NoValidation},
- {"nickserv", "suspendexpire", "0", new ValueContainerTime(&conf->NSSuspendExpire), DT_TIME, NoValidation},
- {"nickserv", "unconfirmedexpire", "0", new ValueContainerTime(&conf->NSUnconfirmedExpire), DT_TIME, ValidateEmailReg},
- {"nickserv", "maxaliases", "0", new ValueContainerUInt(&conf->NSMaxAliases), DT_UINTEGER, NoValidation},
- {"nickserv", "accessmax", "0", new ValueContainerUInt(&conf->NSAccessMax), DT_UINTEGER, ValidateNickServ},
- {"nickserv", "enforceruser", "", new ValueContainerString(&conf->NSEnforcerUser), DT_STRING, ValidateNickServ},
- {"nickserv", "enforcerhost", "", new ValueContainerString(&conf->NSEnforcerHost), DT_STRING, ValidateNickServ},
- {"nickserv", "releasetimeout", "0", new ValueContainerTime(&conf->NSReleaseTimeout), DT_TIME, ValidateNickServ},
- {"nickserv", "allowkillimmed", "no", new ValueContainerBool(&conf->NSAllowKillImmed), DT_BOOLEAN | DT_NORELOAD, NoValidation},
- {"nickserv", "nogroupchange", "no", new ValueContainerBool(&conf->NSNoGroupChange), DT_BOOLEAN, NoValidation},
- {"nickserv", "listmax", "0", new ValueContainerUInt(&conf->NSListMax), DT_UINTEGER, ValidateNickServ},
- {"nickserv", "guestnickprefix", "", new ValueContainerString(&conf->NSGuestNickPrefix), DT_STRING, ValidateNickServ},
- {"nickserv", "secureadmins", "no", new ValueContainerBool(&conf->NSSecureAdmins), DT_BOOLEAN, NoValidation},
- {"nickserv", "strictprivileges", "no", new ValueContainerBool(&conf->NSStrictPrivileges), DT_BOOLEAN, NoValidation},
- {"nickserv", "modeonid", "no", new ValueContainerBool(&conf->NSModeOnID), DT_BOOLEAN, NoValidation},
- {"nickserv", "addaccessonreg", "no", new ValueContainerBool(&conf->NSAddAccessOnReg), DT_BOOLEAN, NoValidation},
- {"nickserv", "ajoinmax", "10", new ValueContainerUInt(&conf->AJoinMax), DT_UINTEGER, NoValidation},
- {"nickserv", "killquick", "20", new ValueContainerTime(&conf->NSKillQuick), DT_TIME, NoValidation},
- {"nickserv", "kill", "60", new ValueContainerTime(&conf->NSKill), DT_TIME, NoValidation},
- {"nickserv", "modesonid", "", new ValueContainerString(&conf->NSModesOnID), DT_STRING, NoValidation},
- {"nickserv", "restoreonrecover", "yes", new ValueContainerBool(&conf->NSRestoreOnRecover), DT_BOOLEAN, NoValidation},
- {"nickserv", "sasl", "yes", new ValueContainerBool(&conf->NSSASL), DT_BOOLEAN, NoValidation},
- {"nickserv", "hidenetsplitquit", "no", new ValueContainerBool(&conf->NSHideNetSplitQuit), DT_BOOLEAN, NoValidation},
- {"mail", "usemail", "no", new ValueContainerBool(&conf->UseMail), DT_BOOLEAN, ValidateEmailReg},
- {"mail", "sendmailpath", "", new ValueContainerString(&conf->SendMailPath), DT_STRING, ValidateMail},
- {"mail", "sendfrom", "", new ValueContainerString(&conf->SendFrom), DT_STRING, ValidateMail},
- {"mail", "restrict", "no", new ValueContainerBool(&conf->RestrictMail), DT_BOOLEAN, NoValidation},
- {"mail", "delay", "0", new ValueContainerTime(&conf->MailDelay), DT_TIME, NoValidation},
- {"mail", "dontquoteaddresses", "no", new ValueContainerBool(&conf->DontQuoteAddresses), DT_BOOLEAN, NoValidation},
- {"mail", "registration_subject", "", new ValueContainerString(&conf->MailRegistrationSubject), DT_STRING, ValidateMail},
- {"mail", "registration_message", "", new ValueContainerString(&conf->MailRegistrationMessage), DT_STRING | DT_ALLOW_NEWLINE, ValidateMail},
- {"mail", "reset_subject", "", new ValueContainerString(&conf->MailResetSubject), DT_STRING, ValidateMail},
- {"mail", "reset_message", "", new ValueContainerString(&conf->MailResetMessage), DT_STRING | DT_ALLOW_NEWLINE, ValidateMail},
- {"mail", "emailchange_subject", "", new ValueContainerString(&conf->MailEmailchangeSubject), DT_STRING, ValidateMail},
- {"mail", "emailchange_message", "", new ValueContainerString(&conf->MailEmailchangeMessage), DT_STRING | DT_ALLOW_NEWLINE, ValidateMail},
- {"mail", "memo_subject", "", new ValueContainerString(&conf->MailMemoSubject), DT_STRING, ValidateMail},
- {"mail", "memo_message", "", new ValueContainerString(&conf->MailMemoMessage), DT_STRING | DT_ALLOW_NEWLINE, ValidateMail},
- {"chanserv", "name", "", new ValueContainerString(&conf->ChanServ), DT_STRING, NoValidation},
- {"chanserv", "defaults", "keeptopic secure securefounder signkick", new ValueContainerString(&CSDefaults), DT_STRING, ValidateChanServ},
- {"chanserv", "maxregistered", "0", new ValueContainerUInt(&conf->CSMaxReg), DT_UINTEGER, ValidateChanServ},
- {"chanserv", "expire", "14d", new ValueContainerTime(&conf->CSExpire), DT_TIME, ValidateChanServ},
- {"chanserv", "suspendexpire", "0", new ValueContainerTime(&conf->CSSuspendExpire), DT_TIME, NoValidation},
- {"chanserv", "forbidexpire", "0", new ValueContainerTime(&conf->CSForbidExpire), DT_TIME, NoValidation},
- {"chanserv", "defbantype", "2", new ValueContainerInt(&conf->CSDefBantype), DT_INTEGER, ValidateChanServ},
- {"chanserv", "accessmax", "0", new ValueContainerUInt(&conf->CSAccessMax), DT_UINTEGER, ValidateChanServ},
- {"chanserv", "autokickmax", "0", new ValueContainerUInt(&conf->CSAutokickMax), DT_UINTEGER, ValidateChanServ},
- {"chanserv", "autokickreason", "User has been banned from the channel", new ValueContainerString(&conf->CSAutokickReason), DT_STRING, ValidateChanServ},
- {"chanserv", "inhabit", "0", new ValueContainerTime(&conf->CSInhabit), DT_TIME, ValidateChanServ},
- {"chanserv", "listmax", "0", new ValueContainerUInt(&conf->CSListMax), DT_UINTEGER, ValidateChanServ},
- {"chanserv", "opersonly", "no", new ValueContainerBool(&conf->CSOpersOnly), DT_BOOLEAN, ValidateChanServ},
- {"chanserv", "mlock", "+nrt", new ValueContainerString(&conf->MLock), DT_STRING | DT_ALLOW_EMPTY, NoValidation},
- {"chanserv", "nomlock", "", new ValueContainerString(&conf->NoMLock), DT_STRING, NoValidation},
- {"chanserv", "require", "", new ValueContainerString(&conf->CSRequire), DT_STRING, NoValidation},
- {"chanserv", "use_server_side_mlock", "yes", new ValueContainerBool(&conf->UseServerSideMLock), DT_BOOLEAN, NoValidation},
- {"chanserv", "use_server_side_topiclock", "yes", new ValueContainerBool(&conf->UseServerSideTopicLock), DT_BOOLEAN, NoValidation},
- {"chanserv", "reasonmax", "200", new ValueContainerUInt(&conf->CSReasonMax), DT_UINTEGER, NoValidation},
- {"memoserv", "name", "", new ValueContainerString(&conf->MemoServ), DT_STRING, NoValidation},
- {"memoserv", "maxmemos", "0", new ValueContainerUInt(&conf->MSMaxMemos), DT_UINTEGER, NoValidation},
- {"memoserv", "senddelay", "0", new ValueContainerTime(&conf->MSSendDelay), DT_TIME, NoValidation},
- {"memoserv", "notifyall", "no", new ValueContainerBool(&conf->MSNotifyAll), DT_BOOLEAN, NoValidation},
- {"memoserv", "memoreceipt", "0", new ValueContainerUInt(&conf->MSMemoReceipt), DT_UINTEGER, NoValidation},
- {"hostserv", "name", "", new ValueContainerString(&conf->HostServ), DT_STRING, NoValidation},
- {"hostserv", "vhost_chars", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJMLMNOPQRSTUVWXYZ0123456789.-", new ValueContainerString(&conf->VhostChars), DT_STRING, NoValidation},
- {"hostserv", "allow_undotted_vhosts", "false", new ValueContainerBool(&conf->VhostUndotted), DT_BOOLEAN, NoValidation},
- {"hostserv", "disallow_start_or_end", "", new ValueContainerString(&conf->VhostDisallowBE), DT_STRING, NoValidation},
- {"botserv", "name", "", new ValueContainerString(&conf->BotServ), DT_STRING, NoValidation},
- {"botserv", "defaults", "", new ValueContainerString(&BSDefaults), DT_STRING, NoValidation},
- {"botserv", "minusers", "0", new ValueContainerUInt(&conf->BSMinUsers), DT_UINTEGER, ValidateBotServ},
- {"botserv", "badwordsmax", "0", new ValueContainerUInt(&conf->BSBadWordsMax), DT_UINTEGER, ValidateBotServ},
- {"botserv", "keepdata", "0", new ValueContainerTime(&conf->BSKeepData), DT_TIME, ValidateBotServ},
- {"botserv", "smartjoin", "no", new ValueContainerBool(&conf->BSSmartJoin), DT_BOOLEAN, NoValidation},
- {"botserv", "gentlebadwordreason", "no", new ValueContainerBool(&conf->BSGentleBWReason), DT_BOOLEAN, NoValidation},
- {"botserv", "casesensitive", "no", new ValueContainerBool(&conf->BSCaseSensitive), DT_BOOLEAN, NoValidation},
- {"botserv", "fantasycharacter", "!", new ValueContainerString(&conf->BSFantasyCharacter), DT_STRING | DT_ALLOW_EMPTY, NoValidation},
- {"operserv", "name", "", new ValueContainerString(&conf->OperServ), DT_STRING, NoValidation},
- {"operserv", "superadmin", "no", new ValueContainerBool(&conf->SuperAdmin), DT_BOOLEAN, NoValidation},
- {"operserv", "autokillexpiry", "0", new ValueContainerTime(&conf->AutokillExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "chankillexpiry", "0", new ValueContainerTime(&conf->ChankillExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "snlineexpiry", "0", new ValueContainerTime(&conf->SNLineExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "sqlineexpiry", "0", new ValueContainerTime(&conf->SQLineExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "akillonadd", "no", new ValueContainerBool(&conf->AkillOnAdd), DT_BOOLEAN, NoValidation},
- {"operserv", "killonsnline", "no", new ValueContainerBool(&conf->KillonSNline), DT_BOOLEAN, NoValidation},
- {"operserv", "killonsqline", "no", new ValueContainerBool(&conf->KillonSQline), DT_BOOLEAN, NoValidation},
- {"operserv", "limitsessions", "no", new ValueContainerBool(&conf->LimitSessions), DT_BOOLEAN, NoValidation},
- {"operserv", "defaultsessionlimit", "0", new ValueContainerUInt(&conf->DefSessionLimit), DT_UINTEGER, NoValidation},
- {"operserv", "maxsessionlimit", "0", new ValueContainerUInt(&conf->MaxSessionLimit), DT_UINTEGER, ValidateOperServ},
- {"operserv", "exceptionexpiry", "0", new ValueContainerTime(&conf->ExceptionExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "sessionlimitexceeded", "", new ValueContainerString(&conf->SessionLimitExceeded), DT_STRING, NoValidation},
- {"operserv", "sessionlimitdetailsloc", "", new ValueContainerString(&conf->SessionLimitDetailsLoc), DT_STRING, NoValidation},
- {"operserv", "maxsessionkill", "0", new ValueContainerUInt(&conf->MaxSessionKill), DT_UINTEGER, NoValidation},
- {"operserv", "sessionautokillexpiry", "0", new ValueContainerTime(&conf->SessionAutoKillExpiry), DT_TIME, NoValidation},
- {"operserv", "session_ipv4_cidr", "32", new ValueContainerUInt(&conf->SessionIPv4CIDR), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"operserv", "session_ipv6_cidr", "128", new ValueContainerUInt(&conf->SessionIPv6CIDR), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"operserv", "addakiller", "no", new ValueContainerBool(&conf->AddAkiller), DT_BOOLEAN, NoValidation},
- {"operserv", "akillids", "no", new ValueContainerBool(&conf->AkillIds), DT_BOOLEAN, NoValidation},
- {"operserv", "opersonly", "no", new ValueContainerBool(&conf->OSOpersOnly), DT_BOOLEAN, NoValidation},
- {"global", "name", "", new ValueContainerString(&conf->Global), DT_STRING, NoValidation},
- {"global", "globaloncycle", "no", new ValueContainerBool(&conf->GlobalOnCycle), DT_BOOLEAN, NoValidation},
- {"global", "globaloncycledown", "", new ValueContainerString(&conf->GlobalOnCycleMessage), DT_STRING, ValidateGlobalOnCycle},
- {"global", "globaloncycleup", "", new ValueContainerString(&conf->GlobalOnCycleUP), DT_STRING, ValidateGlobalOnCycle},
- {"global", "anonymousglobal", "no", new ValueContainerBool(&conf->AnonymousGlobal), DT_BOOLEAN, NoValidation},
- {"", "", "", NULL, DT_NOTHING, NoValidation}
- };
-
- /* These tags can occur multiple times, and therefore they have special code to read them
- * which is different to the code for reading the singular tags listed above. */
- MultiItem MultiItems[] = {
- /* Include must be first so we can pull in the extra files before processing
- * anything else! */
- {"include",
- {"type", "name", ""},
- {"", "", ""},
- {DT_STRING, DT_STRING},
- InitInclude, DoInclude, DoneInclude},
- {"define",
- {"name", "value", ""},
- {"", "", ""},
- {DT_STRING, DT_STRING},
- InitDefine, DoDefine, DoneDefine},
- {"uplink",
- {"host", "ipv6", "port", "password", ""},
- {"", "no", "0", "", ""},
- {DT_HOSTNAME | DT_NORELOAD, DT_BOOLEAN | DT_NORELOAD, DT_UINTEGER | DT_NORELOAD, DT_NOSPACES | DT_NORELOAD},
- InitUplinks, DoUplink, DoneUplinks},
- {"module",
- {"name", ""},
- {"", ""},
- {DT_STRING},
- InitModules, DoModule, DoneModules},
- {"opertype",
- {"name", "inherits", "commands", "privs", "modes", ""},
- {"", "", "", "", "", ""},
- {DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING},
- InitOperTypes, DoOperType, DoneOperTypes},
- {"oper",
- {"name", "type", "require_oper", "password", "certfp", "host", "vhost", ""},
- {"", "", "yes", "", "", "", "", ""},
- {DT_STRING, DT_STRING, DT_BOOLEAN, DT_STRING, DT_STRING, DT_STRING, DT_STRING},
- InitOpers, DoOper, DoneOpers},
- {"service",
- {"nick", "user", "host", "gecos", "modes", "channels", ""},
- {"", "", "", "", "", "", ""},
- {DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING},
- InitServices, DoServices, DoneServices},
- {"log",
- {"target", "source", "logage", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug", ""},
- {"", "", "7", "", "", "", "", "", "", "", "no", "no", ""},
- {DT_STRING, DT_STRING, DT_INTEGER, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN, DT_BOOLEAN},
- InitLogs, DoLogs, DoneLogs},
- {"command",
- {"service", "name", "command", "permission", "group", "hide", ""},
- {"", "", "", "", "", "no", ""},
- {DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN},
- InitCommands, DoCommands, DoneCommands},
- {"privilege",
- {"name", "desc", "rank", ""},
- {"", "", "", ""},
- {DT_STRING, DT_STRING, DT_INTEGER, DT_STRING},
- InitPrivileges, DoPrivileges, DonePrivileges},
- {"fantasy",
- {"name", "command", "permission", "group", "hide", "prepend_channel", ""},
- {"", "", "", "", "no", "yes", ""},
- {DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN, DT_BOOLEAN},
- InitFantasy, DoFantasy, DoneFantasy},
- {"command_group",
- {"name", "description", ""},
- {"", "", ""},
- {DT_STRING, DT_STRING},
- InitCommandGroups, DoCommandGroups, DoneCommandGroups},
- {"",
- {""},
- {""},
- {0},
- NULL, NULL, NULL}
- };
-
- this->Values = new Item[sizeof(Items) / sizeof(Item)];
- for (unsigned i = 0; i < sizeof(Items) / sizeof(Item); ++i)
- this->Values[i] = Items[i];
-
- this->MultiValues = new MultiItem[sizeof(MultiItems) / sizeof(MultiItem)];
- for (unsigned i = 0; i < sizeof(MultiItems) / sizeof(MultiItem); ++i)
- this->MultiValues[i] = MultiItems[i];
-}
-
-ConfigItems::~ConfigItems()
-{
- for (unsigned i = 0; !this->Values[i].tag.empty(); ++i)
- delete this->Values[i].val;
- delete [] this->Values;
- delete [] this->MultiValues;
-}
-
-void ServerConfig::Read()
-{
- // These tags MUST occur and must ONLY occur once in the config file
- static const Anope::string Once[] = {"serverinfo", "networkinfo", "options", ""};
-
- this->LoadConf(ServicesConf);
-
- ConfigItems configitems(this);
-
- /* Read the multiple-tag items (class tags, connect tags, etc)
- * and call the callbacks associated with them. We have three
- * callbacks for these, a 'start', 'item' and 'end' callback. */
- for (int Index = 0; !configitems.MultiValues[Index].tag.empty(); ++Index)
- {
- configitems.MultiValues[Index].init_function(this, configitems.MultiValues[Index].tag);
- int number_of_tags = ConfValueEnum(config_data, configitems.MultiValues[Index].tag);
- for (int tagnum = 0; tagnum < number_of_tags; ++tagnum)
- {
- ValueList vl;
- vl.clear();
- for (int valuenum = 0; !configitems.MultiValues[Index].items[valuenum].empty(); ++valuenum)
- {
- int dt = configitems.MultiValues[Index].datatype[valuenum];
- bool allow_newlines = dt & DT_ALLOW_NEWLINE, allow_wild = dt & DT_ALLOW_WILD, noreload = dt & DT_NORELOAD, allow_empty = dt & DT_ALLOW_EMPTY;
- dt &= ~DT_ALLOW_NEWLINE;
- dt &= ~DT_ALLOW_WILD;
- dt &= ~DT_NORELOAD;
- dt &= ~DT_ALLOW_EMPTY;
-
- ConfigDataHash &hash = (noreload && Config ? Config->config_data : this->config_data);
- Anope::string item;
- bool has_value = ConfValue(hash, configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum], configitems.MultiValues[Index].items_default[valuenum], tagnum, item, allow_newlines);
- if (defines.count(item) > 0)
- item = defines[item];
-
- if (has_value && item.empty() && !allow_empty)
- throw ConfigException("Item without value: " + configitems.MultiValues[Index].tag + ":" + configitems.MultiValues[Index].items[valuenum]);
-
- switch (dt)
- {
- case DT_NOSPACES:
- {
- if (has_value)
- vl.push_back(ValueItem(item));
- else
- vl.push_back(ValueItem());
- ValidateNoSpaces(vl[vl.size() - 1].GetValue(), configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum]);
- break;
- }
- case DT_HOSTNAME:
- {
- if (has_value)
- vl.push_back(ValueItem(item));
- else
- vl.push_back(ValueItem());
- ValidateHostname(vl[vl.size() - 1].GetValue(), configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum]);
- break;
- }
- case DT_IPADDRESS:
- {
- if (has_value)
- vl.push_back(ValueItem(item));
- else
- vl.push_back(ValueItem());
- ValidateIP(vl[vl.size() - 1].GetValue(), configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum], allow_wild);
- break;
- }
- case DT_STRING:
- {
- if (has_value)
- vl.push_back(ValueItem(item));
- else
- vl.push_back(ValueItem());
- break;
- }
- case DT_INTEGER:
- case DT_UINTEGER:
- case DT_LUINTEGER:
- {
- int titem = 0;
- if (ConfValueInteger(hash, configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum], configitems.MultiValues[Index].items_default[valuenum], tagnum, titem))
- vl.push_back(ValueItem(titem));
- else
- vl.push_back(ValueItem(0));
- break;
- }
- case DT_TIME:
- {
- if (has_value)
- {
-#ifdef _WIN32
- long time = static_cast<long>(Anope::DoTime(item));
-#else
- time_t time = Anope::DoTime(item);
-#endif
- vl.push_back(ValueItem(time));
- }
- else
- vl.push_back(ValueItem(0));
- break;
- }
- case DT_BOOLEAN:
- {
- bool titem = ConfValueBool(hash, configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum], configitems.MultiValues[Index].items_default[valuenum], tagnum);
- vl.push_back(ValueItem(titem));
- }
- }
- }
- configitems.MultiValues[Index].validation_function(this, configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items, vl, configitems.MultiValues[Index].datatype);
- }
- configitems.MultiValues[Index].finish_function(this, configitems.MultiValues[Index].tag);
- }
-
- // Read the values of all the tags which occur once or not at all, and call their callbacks.
- for (int Index = 0; !configitems.Values[Index].tag.empty(); ++Index)
- {
- Anope::string item;
- int dt = configitems.Values[Index].datatype;
- bool allow_newlines = dt & DT_ALLOW_NEWLINE, allow_wild = dt & DT_ALLOW_WILD, noreload = dt & DT_NORELOAD, allow_empty = dt & DT_ALLOW_EMPTY;
- dt &= ~DT_ALLOW_NEWLINE;
- dt &= ~DT_ALLOW_WILD;
- dt &= ~DT_NORELOAD;
- dt &= ~DT_ALLOW_EMPTY;
-
- ConfigDataHash &hash = (noreload && Config ? Config->config_data : this->config_data);
- bool has_value = ConfValue(hash, configitems.Values[Index].tag, configitems.Values[Index].value, configitems.Values[Index].default_value, 0, item, allow_newlines);
- if (defines.count(item) > 0)
- item = defines[item];
-
- if (has_value && item.empty() && !allow_empty)
- throw ConfigException("Item without value: " + configitems.Values[Index].tag + ":" + configitems.Values[Index].value);
-
- ValueItem vi(item);
-
- if (!configitems.Values[Index].validation_function(this, configitems.Values[Index].tag, configitems.Values[Index].value, vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your logfiles for more information.");
-
- switch (dt)
- {
- case DT_NOSPACES:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(configitems.Values[Index].val);
- ValidateNoSpaces(vi.GetValue(), configitems.Values[Index].tag, configitems.Values[Index].value);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_HOSTNAME:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(configitems.Values[Index].val);
- ValidateHostname(vi.GetValue(), configitems.Values[Index].tag, configitems.Values[Index].value);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_IPADDRESS:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(configitems.Values[Index].val);
- ValidateIP(vi.GetValue(), configitems.Values[Index].tag, configitems.Values[Index].value, allow_wild);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_STRING:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(configitems.Values[Index].val);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_INTEGER:
- {
- int val = vi.GetInteger();
- ValueContainerInt *vci = anope_dynamic_static_cast<ValueContainerInt *>(configitems.Values[Index].val);
- vci->Set(&val, sizeof(int));
- break;
- }
- case DT_UINTEGER:
- {
- unsigned val = vi.GetInteger();
- ValueContainerUInt *vci = anope_dynamic_static_cast<ValueContainerUInt *>(configitems.Values[Index].val);
- vci->Set(&val, sizeof(unsigned));
- break;
- }
- case DT_LUINTEGER:
- {
- unsigned long val = vi.GetInteger();
- ValueContainerLUInt *vci = anope_dynamic_static_cast<ValueContainerLUInt *>(configitems.Values[Index].val);
- vci->Set(&val, sizeof(unsigned long));
- break;
- }
- case DT_TIME:
- {
- time_t time = Anope::DoTime(vi.GetValue());
- ValueContainerTime *vci = anope_dynamic_static_cast<ValueContainerTime *>(configitems.Values[Index].val);
- vci->Set(&time, sizeof(time_t));
- break;
- }
- case DT_BOOLEAN:
- {
- bool val = vi.GetBool();
- ValueContainerBool *vcb = anope_dynamic_static_cast<ValueContainerBool *>(configitems.Values[Index].val);
- vcb->Set(&val, sizeof(bool));
- break;
- }
- default:
- break;
- }
- }
-
- Log(LOG_DEBUG) << "End config " << ServicesConf.GetName();
- for (int Index = 0; !Once[Index].empty(); ++Index)
- CheckOnce(Once[Index]);
- Log() << "Done reading configuration file " << ServicesConf.GetName();
-}
-
-void ServerConfig::LoadConf(ConfigurationFile &file)
-{
- Anope::string section, wordbuffer, itemname;
- int linenumber = 0;
- bool in_word = false, in_quote = false, in_ml_comment = false;
- KeyValList sectiondata;
if (!file.Open())
- {
throw ConfigException("File " + file.GetName() + " could not be opened.");
- }
+
+ Anope::string itemname, wordbuffer;
+ std::stack<Block *> block_stack;
+ int linenumber = 0;
+ bool in_word = false, in_quote = false, in_comment = false;
+
Log(LOG_DEBUG) << "Start to read conf " << file.GetName();
// Start reading characters...
while (!file.End())
{
Anope::string line = file.Read();
++linenumber;
- unsigned c = 0, len = line.length();
- for (; c < len; ++c)
+
+ for (unsigned c = 0, len = line.length(); c < len; ++c)
{
char ch = line[c];
if (in_quote)
{
- /* Strip leading white spaces from multi line comments */
+ /* Strip leading white spaces from multi line quotes */
if (c == 0)
{
+ wordbuffer += "\n";
while (c < len && isspace(line[c]))
++c;
ch = line[c];
}
+
/* Allow \" in quotes */
if (ch == '\\' && c + 1 < len && line[c + 1] == '"')
wordbuffer += line[++c];
else if (ch == '"')
in_quote = in_word = false;
- else
+ else if (ch)
wordbuffer += ch;
}
- else if (in_ml_comment)
+ else if (in_comment)
{
if (ch == '*' && c + 1 < len && line[c + 1] == '/')
{
- in_ml_comment = false;
+ in_comment = false;
++c;
}
continue;
@@ -1632,7 +698,7 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
else if (ch == '/' && c + 1 < len && line[c + 1] == '*')
{
// Multiline (or less than one line) comment
- in_ml_comment = true;
+ in_comment = true;
++c;
continue;
}
@@ -1641,7 +707,7 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
else if (ch == '"')
{
// Quotes are valid only in the value position
- if (section.empty() || itemname.empty())
+ if (block_stack.empty() || itemname.empty())
{
file.Close();
throw ConfigException("Unexpected quoted string: " + file.GetName() + ":" + stringify(linenumber));
@@ -1655,36 +721,45 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
}
else if (ch == '=')
{
- if (section.empty())
+ if (block_stack.empty())
{
file.Close();
throw ConfigException("Config item outside of section (or stray '='): " + file.GetName() + ":" + stringify(linenumber));
}
- if (!itemname.empty())
+
+ if (!itemname.empty() || wordbuffer.empty())
{
file.Close();
throw ConfigException("Stray '=' sign or item without value: " + file.GetName() + ":" + stringify(linenumber));
}
- if (in_word)
- in_word = false;
+
+ in_word = false;
itemname = wordbuffer;
wordbuffer.clear();
}
else if (ch == '{')
{
- if (!section.empty())
- {
- file.Close();
- throw ConfigException("Section inside another section: " + file.GetName() + ":" + stringify(linenumber));
- }
if (wordbuffer.empty())
{
- file.Close();
- throw ConfigException("Section without a name or unexpected '{': " + file.GetName() + ":" + stringify(linenumber));
+ block_stack.push(NULL);
+ // Commented or unnamed section
+ continue;
}
- if (in_word)
+
+ if (!block_stack.empty() && !block_stack.top())
+ {
+ // Named block inside of a commented block
in_word = false;
- section = wordbuffer;
+ wordbuffer.clear();
+ block_stack.push(NULL);
+ continue;
+ }
+
+ Block *b = block_stack.empty() ? this : block_stack.top();
+ block_map::iterator it = b->blocks.insert(std::make_pair(wordbuffer, Configuration::Block(wordbuffer)));
+ block_stack.push(&it->second);
+
+ in_word = false;
wordbuffer.clear();
continue;
}
@@ -1720,30 +795,59 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
wordbuffer += "\n";
continue;
}
+
in_word = false;
if (!itemname.empty())
{
- Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << section << "' '" << itemname << "' set to '" << wordbuffer << "'";
- sectiondata.push_back(KeyVal(itemname, wordbuffer));
+ if (block_stack.empty())
+ {
+ file.Close();
+ throw ConfigException("Stray ';' outside of block: " + file.GetName() + ":" + stringify(linenumber));
+ }
+
+ Block *b = block_stack.top();
+
+ if (b)
+ Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << b->name << "' '" << itemname << "' set to '" << wordbuffer << "'";
+
+ if (itemname.empty())
+ {
+ file.Close();
+ throw ConfigException("Item without a name: " + file.GetName() + ":" + stringify(linenumber));
+ }
+
+ /* Check defines */
+ for (int i = 0; i < this->CountBlock("define"); ++i)
+ {
+ Block *define = this->GetBlock("define", i);
+
+ const Anope::string &dname = define->Get<const Anope::string &>("name");
+
+ if (dname == wordbuffer)
+ wordbuffer = define->Get<const Anope::string &>("value");
+ }
+
+ if (b)
+ b->items[itemname] = wordbuffer;
+
wordbuffer.clear();
itemname.clear();
}
if (ch == '}')
{
- if (section.empty())
+ if (block_stack.empty())
{
file.Close();
throw ConfigException("Stray '}': " + file.GetName() + ":" + stringify(linenumber));
}
- this->config_data.insert(std::pair<Anope::string, KeyValList>(section, sectiondata));
- section.clear();
- sectiondata.clear();
+
+ block_stack.pop();
}
}
}
}
- if (in_ml_comment)
+ if (in_comment)
{
file.Close();
throw ConfigException("Unterminated multiline comment at end of file: " + file.GetName());
@@ -1758,212 +862,7 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
file.Close();
throw ConfigException("Unexpected garbage at end of file: " + file.GetName());
}
- if (!section.empty())
- {
- file.Close();
- throw ConfigException("Unterminated section at end of file: " + file.GetName());
- }
file.Close();
}
-bool ServerConfig::ConfValue(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, int index, Anope::string &result, bool allow_linefeeds)
-{
- return ConfValue(target, tag, var, "", index, result, allow_linefeeds);
-}
-
-bool ServerConfig::ConfValue(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, const Anope::string &default_value, int index, Anope::string &result, bool allow_linefeeds)
-{
- ConfigDataHash::size_type pos = index;
- if (pos < target.count(tag))
- {
- ConfigDataHash::iterator iter = target.find(tag);
-
- for (int i = 0; i < index; ++i)
- ++iter;
-
- KeyValList::iterator j = iter->second.begin(), jend = iter->second.end();
- for (; j != jend; ++j)
- {
- if (j->first.equals_ci(var))
- {
- if (!allow_linefeeds && j->second.find('\n') != Anope::string::npos)
- {
- Log(LOG_DEBUG) << "Value of <" << tag << ":" << var << "> contains a linefeed, and linefeeds in this value are not permitted -- stripped to spaces.";
- j->second.replace_all_cs("\n", " ");
- }
- else
- {
- result = j->second;
- return true;
- }
- }
- }
- if (!default_value.empty())
- {
- result = default_value;
- return true;
- }
- }
- else if (!pos)
- {
- if (!default_value.empty())
- {
- result = default_value;
- return true;
- }
- }
- return false;
-}
-
-bool ServerConfig::ConfValueInteger(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, int index, int &result)
-{
- return ConfValueInteger(target, tag, var, "", index, result);
-}
-
-bool ServerConfig::ConfValueInteger(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, const Anope::string &default_value, int index, int &result)
-{
- Anope::string value;
- std::istringstream stream;
- bool r = ConfValue(target, tag, var, default_value, index, value);
- stream.str(value.str());
- if (!(stream >> result))
- return false;
- else
- {
- if (!value.empty())
- {
- if (value.substr(0, 2).equals_ci("0x"))
- {
- char *endptr;
-
- value.erase(0, 2);
- result = strtol(value.c_str(), &endptr, 16);
-
- /* No digits found */
- if (endptr == value.c_str())
- return false;
- }
- else
- {
- char denominator = *(value.end() - 1);
- switch (toupper(denominator))
- {
- case 'K':
- // Kilobytes -> bytes
- result = result * 1024;
- break;
- case 'M':
- // Megabytes -> bytes
- result = result * 1048576;
- break;
- case 'G':
- // Gigabytes -> bytes
- result = result * 1073741824;
- }
- }
- }
- }
- return r;
-}
-
-bool ServerConfig::ConfValueBool(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, int index)
-{
- return ConfValueBool(target, tag, var, "", index);
-}
-
-bool ServerConfig::ConfValueBool(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, const Anope::string &default_value, int index)
-{
- Anope::string result;
- if (!ConfValue(target, tag, var, default_value, index, result))
- return false;
-
- return result.equals_ci("yes") || result.equals_ci("true") || result.equals_ci("1");
-}
-
-int ServerConfig::ConfValueEnum(const ConfigDataHash &target, const Anope::string &tag)
-{
- return target.count(tag);
-}
-
-int ServerConfig::ConfVarEnum(ConfigDataHash &target, const Anope::string &tag, int index)
-{
- ConfigDataHash::size_type pos = index;
-
- if (pos < target.count(tag))
- {
- ConfigDataHash::const_iterator iter = target.find(tag);
-
- for (int i = 0; i < index; ++i)
- ++iter;
-
- return iter->second.size();
- }
-
- return 0;
-}
-
-ValueItem::ValueItem() { }
-
-ValueItem::ValueItem(int value) : v("")
-{
- std::stringstream n;
- n << value;
- v = n.str();
-}
-
-ValueItem::ValueItem(long value) : v("")
-{
- std::stringstream n;
- n << value;
- v = n.str();
-}
-
-ValueItem::ValueItem(bool value) : v("")
-{
- std::stringstream n;
- n << value;
- v = n.str();
-}
-
-ValueItem::ValueItem(const Anope::string &value) : v(value) { }
-
-void ValueItem::Set(const Anope::string &value)
-{
- v = value;
-}
-
-void ValueItem::Set(int value)
-{
- std::stringstream n;
- n << value;
- v = n.str();
-}
-
-int ValueItem::GetInteger() const
-{
- if (v.empty() || !v.is_number_only())
- return 0;
- try
- {
- return convertTo<int>(v);
- }
- catch (const ConvertException &)
- {
- Log() << "Unable to convert configuration value " << this->v << " to an integer. Value too large?";
- }
-
- return 0;
-}
-
-const char *ValueItem::GetString() const
-{
- return v.c_str();
-}
-
-bool ValueItem::GetBool() const
-{
- return GetInteger() || v == "yes" || v == "true";
-}
-
-
diff --git a/src/configreader.cpp b/src/configreader.cpp
deleted file mode 100644
index ca5a64a60..000000000
--- a/src/configreader.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Configuration file handling.
- *
- * (C) 2003-2013 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- */
-
-/* Taken from:
- * +------------------------------------+
- * | Inspire Internet Relay Chat Daemon |
- * +------------------------------------+
- *
- * InspIRCd: (C) 2002-2011 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
- *
- * This program is free but copyrighted software; see
- * the file COPYING for details.
- *
- * ---------------------------------------------------
- */
-
-#include "services.h"
-#include "config.h"
-
-ConfigReader::ConfigReader() : conf(Config), error(CONF_NO_ERROR)
-{
-}
-
-ConfigReader::ConfigReader(const Anope::string &filename) : conf(Config), error(CONF_NO_ERROR)
-{
-}
-
-ConfigReader::ConfigReader(ServerConfig *c) : conf(c), error(CONF_NO_ERROR)
-{
-}
-
-ConfigReader::~ConfigReader()
-{
-}
-
-Anope::string ConfigReader::ReadValue(const Anope::string &tag, const Anope::string &name, const Anope::string &default_value, int index, bool allow_linefeeds)
-{
- /* Don't need to strlcpy() tag and name anymore, ReadConf() takes const char* */
- Anope::string result;
-
- if (!conf->ConfValue(conf->config_data, tag, name, default_value, index, result, allow_linefeeds))
- this->error = CONF_VALUE_NOT_FOUND;
-
- return result;
-}
-
-Anope::string ConfigReader::ReadValue(const Anope::string &tag, const Anope::string &name, int index, bool allow_linefeeds)
-{
- return ReadValue(tag, name, "", index, allow_linefeeds);
-}
-
-bool ConfigReader::ReadFlag(const Anope::string &tag, const Anope::string &name, const Anope::string &default_value, int index)
-{
- return conf->ConfValueBool(conf->config_data, tag, name, default_value, index);
-}
-
-bool ConfigReader::ReadFlag(const Anope::string &tag, const Anope::string &name, int index)
-{
- return ReadFlag(tag, name, "", index);
-}
-
-int ConfigReader::ReadInteger(const Anope::string &tag, const Anope::string &name, const Anope::string &default_value, int index, bool need_positive)
-{
- int result;
-
- if (!conf->ConfValueInteger(conf->config_data, tag, name, default_value, index, result))
- {
- this->error = CONF_VALUE_NOT_FOUND;
- return 0;
- }
-
- if (need_positive && result < 0)
- {
- this->error = CONF_INT_NEGATIVE;
- return 0;
- }
-
- return result;
-}
-
-int ConfigReader::ReadInteger(const Anope::string &tag, const Anope::string &name, int index, bool need_positive)
-{
- return ReadInteger(tag, name, "", index, need_positive);
-}
-
-long ConfigReader::GetError()
-{
- long olderr = this->error;
- this->error = 0;
- return olderr;
-}
-
-int ConfigReader::Enumerate(const Anope::string &tag) const
-{
- return conf->ConfValueEnum(conf->config_data, tag);
-}
-
-int ConfigReader::EnumerateValues(const Anope::string &tag, int index)
-{
- return conf->ConfVarEnum(conf->config_data, tag, index);
-}
-
-bool ConfigReader::Verify()
-{
- return this->readerror;
-}
diff --git a/src/init.cpp b/src/init.cpp
index b0812fedc..27f0a8689 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -120,8 +120,8 @@ void Anope::HandleSignal()
try
{
- ServerConfig *new_config = new ServerConfig();
- delete Config;
+ Configuration::Conf *new_config = new Configuration::Conf();
+ delete new_config;
Config = new_config;
}
catch (const ConfigException &ex)
@@ -197,14 +197,14 @@ static void InitSignals()
static void remove_pidfile()
{
- remove(Config->PIDFilename.c_str());
+ remove(Config->GetBlock("serverinfo")->Get<const char *>("pid"));
}
/* Create our PID file and write the PID to it. */
static void write_pidfile()
{
- FILE *pidfile = fopen(Config->PIDFilename.c_str(), "w");
+ FILE *pidfile = fopen(Config->GetBlock("serverinfo")->Get<const char *>("pid"), "w");
if (pidfile)
{
#ifdef _WIN32
@@ -216,7 +216,7 @@ static void write_pidfile()
atexit(remove_pidfile);
}
else
- throw CoreException("Can not write to PID file " + Config->PIDFilename);
+ throw CoreException("Can not write to PID file " + Config->GetBlock("serverinfo")->Get<const Anope::string &>("pid"));
}
void Anope::Init(int ac, char **av)
@@ -303,7 +303,7 @@ void Anope::Init(int ac, char **av)
{
if (arg.empty())
throw CoreException("The --config option requires a file name");
- ServicesConf = ConfigurationFile(arg, false);
+ ServicesConf = Configuration::File(arg, false);
}
if (GetCommandLineArgument("confdir", 0, arg))
@@ -413,7 +413,7 @@ void Anope::Init(int ac, char **av)
/* Read configuration file; exit if there are problems. */
try
{
- Config = new ServerConfig();
+ Config = new Configuration::Conf();
}
catch (const ConfigException &ex)
{
@@ -429,7 +429,8 @@ void Anope::Init(int ac, char **av)
write_pidfile();
/* Create me */
- Me = new Server(NULL, Config->ServerName, 0, Config->ServerDesc, Config->Numeric);
+ Configuration::Block *block = Config->GetBlock("serverinfo");
+ Me = new Server(NULL, block->Get<const Anope::string &>("name"), 0, block->Get<const Anope::string &>("description"), block->Get<const Anope::string &>("id"));
for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
{
it->second->server = Me;
@@ -445,12 +446,13 @@ void Anope::Init(int ac, char **av)
Language::InitLanguages();
/* Initialize random number generator */
- srand(Config->Seed);
+ block = Config->GetBlock("options");
+ srand(block->Get<unsigned>("seed"));
/* load modules */
Log() << "Loading modules...";
- for (std::list<Anope::string>::iterator it = Config->ModulesAutoLoad.begin(), it_end = Config->ModulesAutoLoad.end(); it != it_end; ++it)
- ModuleManager::LoadModule(*it, NULL);
+ for (int i = 0; i < Config->CountBlock("module"); ++i)
+ ModuleManager::LoadModule(Config->GetBlock("module", i)->Get<const Anope::string &>("name"), NULL);
Module *protocol = ModuleManager::FindFirstOf(PROTOCOL);
if (protocol == NULL)
diff --git a/src/language.cpp b/src/language.cpp
index ec2e0e39b..80f4477c2 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -37,7 +37,7 @@ void Language::InitLanguages()
setlocale(LC_ALL, "");
- spacesepstream sep(Config->Languages);
+ spacesepstream sep(Config->GetBlock("options")->Get<const Anope::string &>("languages"));
Anope::string language;
while (sep.GetToken(language))
{
@@ -58,7 +58,7 @@ void Language::InitLanguages()
const char *Language::Translate(const char *string)
{
- return Translate(Config->NSDefLanguage.c_str(), string);
+ return Translate("", string);
}
const char *Language::Translate(User *u, const char *string)
@@ -66,12 +66,12 @@ const char *Language::Translate(User *u, const char *string)
if (u && u->Account())
return Translate(u->Account(), string);
else
- return Translate(string);
+ return Translate("", string);
}
const char *Language::Translate(const NickCore *nc, const char *string)
{
- return Translate(nc ? nc->language.c_str() : Config->NSDefLanguage.c_str(), string);
+ return Translate(nc ? nc->language.c_str() : "", string);
}
#if GETTEXT_FOUND
@@ -81,8 +81,11 @@ extern "C" int _nl_msg_cat_cntr;
const char *Language::Translate(const char *lang, const char *string)
{
- if (!string || !*string || !lang || !*lang)
- return string ? string : "";
+ if (!string || !*string)
+ return "";
+
+ if (!lang || !*lang)
+ lang = Config->DefLanguage.c_str();
++_nl_msg_cat_cntr;
#ifdef _WIN32
diff --git a/src/logger.cpp b/src/logger.cpp
index f738cb2e1..d071b7cc3 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -21,7 +21,6 @@
#include "servers.h"
#include "uplink.h"
#include "protocol.h"
-#include "global.h"
#ifndef _WIN32
#include <sys/time.h>
@@ -149,8 +148,8 @@ Log::~Log()
if (Config)
for (unsigned i = 0; i < Config->LogInfos.size(); ++i)
- if (Config->LogInfos[i]->HasType(this->type, this->category))
- Config->LogInfos[i]->ProcessMessage(this);
+ if (Config->LogInfos[i].HasType(this->type, this->category))
+ Config->LogInfos[i].ProcessMessage(this);
FOREACH_MOD(I_OnLog, OnLog(this));
}
diff --git a/src/mail.cpp b/src/mail.cpp
index 851fe6d4e..3b2b1272f 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -14,7 +14,7 @@
#include "mail.h"
#include "config.h"
-Mail::Message::Message(const Anope::string &sf, const Anope::string &mailto, const Anope::string &a, const Anope::string &s, const Anope::string &m) : Thread(), sendmail_path(Config->SendMailPath), send_from(sf), mail_to(mailto), addr(a), subject(s), message(m), dont_quote_addresses(Config->DontQuoteAddresses), success(false)
+Mail::Message::Message(const Anope::string &sf, const Anope::string &mailto, const Anope::string &a, const Anope::string &s, const Anope::string &m) : Thread(), sendmail_path(Config->GetBlock("mail")->Get<const Anope::string &>("sendmailpath")), send_from(sf), mail_to(mailto), addr(a), subject(s), message(m), dont_quote_addresses(Config->GetBlock("mail")->Get<bool>("dontquoteaddresses")), success(false)
{
}
@@ -55,31 +55,33 @@ bool Mail::Send(User *u, NickCore *nc, const BotInfo *service, const Anope::stri
{
if (!nc || !service || subject.empty() || message.empty())
return false;
+
+ Configuration::Block *b = Config->GetBlock("mail");
if (!u)
{
- if (!Config->UseMail)
+ if (!b->Get<bool>("usemail") || b->Get<const Anope::string &>("sendfrom").empty())
return false;
else if (nc->email.empty())
return false;
nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<const Anope::string &>("sendfrom"), nc->display, nc->email, subject, message);
t->Start();
return true;
}
else
{
- if (!Config->UseMail)
+ if (!b->Get<bool>("usemail") || b->Get<const Anope::string &>("sendfrom").empty())
u->SendMessage(service, _("Services have been configured to not send mail."));
- else if (Anope::CurTime - u->lastmail < Config->MailDelay)
- u->SendMessage(service, _("Please wait \002%d\002 seconds and retry."), Config->MailDelay - (Anope::CurTime - u->lastmail));
+ else if (Anope::CurTime - u->lastmail < b->Get<time_t>("delay"))
+ u->SendMessage(service, _("Please wait \002%d\002 seconds and retry."), b->Get<time_t>("delay") - (Anope::CurTime - u->lastmail));
else if (nc->email.empty())
u->SendMessage(service, _("E-mail for \002%s\002 is invalid."), nc->display.c_str());
else
{
u->lastmail = nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<const Anope::string &>("sendfrom"), nc->display, nc->email, subject, message);
t->Start();
return true;
}
@@ -90,11 +92,12 @@ bool Mail::Send(User *u, NickCore *nc, const BotInfo *service, const Anope::stri
bool Mail::Send(NickCore *nc, const Anope::string &subject, const Anope::string &message)
{
- if (!Config->UseMail || !nc || nc->email.empty() || subject.empty() || message.empty())
+ Configuration::Block *b = Config->GetBlock("mail");
+ if (!b->Get<bool>("usemail") || b->Get<const Anope::string &>("sendfrom").empty() || !nc || nc->email.empty() || subject.empty() || message.empty())
return false;
nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<const Anope::string &>("sendfrom"), nc->display, nc->email, subject, message);
t->Start();
return true;
diff --git a/src/main.cpp b/src/main.cpp
index 059650df0..12fc1335c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -144,12 +144,12 @@ int main(int ac, char **av, char **envp)
}
catch (const SocketException &ex)
{
- Log(LOG_TERMINAL) << "Unable to connect to uplink #" << Anope::CurrentUplink << " (" << Config->Uplinks[Anope::CurrentUplink]->host << ":" << Config->Uplinks[Anope::CurrentUplink]->port << "): " << ex.GetReason();
+ Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << "): " << ex.GetReason();
}
/* Set up timers */
time_t last_check = Anope::CurTime;
- UpdateTimer updateTimer(Config->UpdateTimeout);
+ UpdateTimer updateTimer(Config->GetBlock("options")->Get<time_t>("updatetimeout"));
/*** Main loop. ***/
while (!Anope::Quitting)
@@ -157,7 +157,7 @@ int main(int ac, char **av, char **envp)
Log(LOG_DEBUG_2) << "Top of main loop";
/* Process timers */
- if (Anope::CurTime - last_check >= Config->TimeoutCheck)
+ if (Anope::CurTime - last_check >= Config->GetBlock("options")->Get<time_t>("timeoutcheck"))
{
TimerManager::TickTimers(Anope::CurTime);
last_check = Anope::CurTime;
diff --git a/src/messages.cpp b/src/messages.cpp
index c9ffd3c59..9bbfb42c0 100644
--- a/src/messages.cpp
+++ b/src/messages.cpp
@@ -126,9 +126,6 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co
const ChannelStatus &status = it->first;
User *u = it->second;
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
-
/* Add the user to the channel */
ChanUserContainer *cc = c->JoinUser(u);
@@ -141,14 +138,8 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co
*/
c->SetCorrectModes(u, true, true);
- /* Check to see if modules want the user to join, if they do
- * check to see if they are allowed to join (CheckKick will kick/ban them
- * if they aren't).
- */
- if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u))
- continue;
-
- FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
+ if (c->ci)
+ c->ci->CheckKick(u);
}
/* Channel is done syncing */
@@ -234,10 +225,10 @@ void MOTD::Run(MessageSource &source, const std::vector<Anope::string> &params)
if (s != Me)
return;
- FILE *f = fopen(Config->MOTDFilename.c_str(), "r");
+ FILE *f = fopen(Config->GetBlock("serverinfo")->Get<const char *>("motd"), "r");
if (f)
{
- IRCD->SendNumeric(375, source.GetSource(), ":- %s Message of the Day", Config->ServerName.c_str());
+ IRCD->SendNumeric(375, source.GetSource(), ":- %s Message of the Day", s->GetName().c_str());
char buf[BUFSIZE];
while (fgets(buf, sizeof(buf), f))
{
@@ -304,16 +295,16 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
{
Anope::string servername(receiver.begin() + s + 1, receiver.end());
botname = botname.substr(0, s);
- if (!servername.equals_ci(Config->ServerName))
+ if (!servername.equals_ci(Me->GetName()))
return;
}
- else if (Config->UseStrictPrivMsg)
+ else if (Config->GetBlock("options")->Get<bool>("usestrictprivmsg"))
{
const BotInfo *bi = BotInfo::Find(receiver);
if (!bi)
return;
Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick;
- u->SendMessage(bi, _("\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."), bi->nick.c_str(), bi->nick.c_str(), Config->ServerName.c_str(), bi->nick.c_str());
+ u->SendMessage(bi, _("\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."), bi->nick.c_str(), bi->nick.c_str(), Me->GetName().c_str(), bi->nick.c_str());
return;
}
@@ -338,7 +329,7 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
else if (message.substr(0, 9).equals_ci("\1VERSION\1"))
{
Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
- IRCD->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
+ IRCD->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Me->GetName().c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
}
return;
}
@@ -357,16 +348,7 @@ void Quit::Run(MessageSource &source, const std::vector<Anope::string> &params)
Log(user, "quit") << "quit (Reason: " << (!reason.empty() ? reason : "no reason") << ")";
- NickAlias *na = NickAlias::Find(user->nick);
- if (na && !na->nc->HasExt("SUSPENDED") && (user->IsRecognized() || user->IsIdentified(true)))
- {
- na->last_seen = Anope::CurTime;
- na->last_quit = reason;
- }
- FOREACH_MOD(I_OnUserQuit, OnUserQuit(user, reason));
user->Quit(reason);
-
- return;
}
void SQuit::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -382,8 +364,6 @@ void SQuit::Run(MessageSource &source, const std::vector<Anope::string> &params)
FOREACH_MOD(I_OnServerQuit, OnServerQuit(s));
s->Delete(s->GetName() + " " + s->GetUplink()->GetName());
-
- return;
}
void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -396,7 +376,7 @@ void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
if (u->HasMode("OPER"))
{
IRCD->SendNumeric(211, source.GetSource(), "Server SendBuf SentBytes SentMsgs RecvBuf RecvBytes RecvMsgs ConnTime");
- IRCD->SendNumeric(211, source.GetSource(), "%s %d %d %d %d %d %d %ld", Config->Uplinks[Anope::CurrentUplink]->host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - Anope::StartTime));
+ IRCD->SendNumeric(211, source.GetSource(), "%s %d %d %d %d %d %d %ld", Config->Uplinks[Anope::CurrentUplink].host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - Anope::StartTime));
}
IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]);
@@ -404,7 +384,7 @@ void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
case 'o':
case 'O':
/* Check whether the user is an operator */
- if (!u->HasMode("OPER") && Config->HideStatsO)
+ if (!u->HasMode("OPER") && Config->GetBlock("options")->Get<bool>("hidestatso"))
IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]);
else
{
@@ -444,7 +424,7 @@ void Time::Run(MessageSource &source, const std::vector<Anope::string> &params)
struct tm *tm = localtime(&t);
char buf[64];
strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y %Z", tm);
- IRCD->SendNumeric(391, source.GetSource(), "%s :%s", Config->ServerName.c_str(), buf);
+ IRCD->SendNumeric(391, source.GetSource(), "%s :%s", Me->GetName().c_str(), buf);
return;
}
@@ -460,7 +440,7 @@ void Topic::Run(MessageSource &source, const std::vector<Anope::string> &params)
void Version::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
- IRCD->SendNumeric(351, source.GetSource(), "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
+ IRCD->SendNumeric(351, source.GetSource(), "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Me->GetName().c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
return;
}
@@ -474,7 +454,7 @@ void Whois::Run(MessageSource &source, const std::vector<Anope::string> &params)
IRCD->SendNumeric(311, source.GetSource(), "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str());
if (bi)
IRCD->SendNumeric(307, source.GetSource(), "%s :is a registered nick", bi->nick.c_str());
- IRCD->SendNumeric(312, source.GetSource(), "%s %s :%s", u->nick.c_str(), Config->ServerName.c_str(), Config->ServerDesc.c_str());
+ IRCD->SendNumeric(312, source.GetSource(), "%s %s :%s", u->nick.c_str(), Me->GetName().c_str(), Config->GetBlock("serverinfo")->Get<const char *>("description"));
if (bi)
IRCD->SendNumeric(317, source.GetSource(), "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(bi->signon));
IRCD->SendNumeric(318, source.GetSource(), "%s :End of /WHOIS list.", params[0].c_str());
diff --git a/src/misc.cpp b/src/misc.cpp
index 20a53e7cc..86328b6b3 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -43,10 +43,18 @@ NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(tr
if (t == Anope::string::npos)
{
- unsigned num = convertTo<unsigned>(token, error, false);
- if (error.empty())
- numbers.insert(num);
- else
+ try
+ {
+ unsigned num = convertTo<unsigned>(token, error, false);
+ if (error.empty())
+ numbers.insert(num);
+ }
+ catch (const ConvertException &)
+ {
+ error = "1";
+ }
+
+ if (!error.empty())
{
if (!this->InvalidRange(list))
{
@@ -58,14 +66,20 @@ NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(tr
else
{
Anope::string error2;
- unsigned num1 = convertTo<unsigned>(token.substr(0, t), error, false);
- unsigned num2 = convertTo<unsigned>(token.substr(t + 1), error2, false);
- if (error.empty() && error2.empty())
+ try
{
- for (unsigned i = num1; i <= num2; ++i)
- numbers.insert(i);
+ unsigned num1 = convertTo<unsigned>(token.substr(0, t), error, false);
+ unsigned num2 = convertTo<unsigned>(token.substr(t + 1), error2, false);
+ if (error.empty() && error2.empty())
+ for (unsigned i = num1; i <= num2; ++i)
+ numbers.insert(i);
}
- else
+ catch (const ConvertException &)
+ {
+ error = "1";
+ }
+
+ if (!error.empty() || !error2.empty())
{
if (!this->InvalidRange(list))
{
@@ -232,7 +246,7 @@ bool Anope::IsFile(const Anope::string &filename)
time_t Anope::DoTime(const Anope::string &s)
{
if (s.empty())
- return -1;
+ return 0;
int amount = 0;
Anope::string end;
@@ -257,7 +271,7 @@ time_t Anope::DoTime(const Anope::string &s)
case 'y':
return amount * 86400 * 365;
default:
- return -1;
+ break;
}
}
}
@@ -368,7 +382,7 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case
if (r == NULL || r->GetExpression() != stripped_mask)
{
- ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine);
+ ServiceReference<RegexProvider> provider("Regex", Config->GetBlock("options")->Get<const Anope::string &>("regexengine"));
if (provider)
{
try
diff --git a/src/modes.cpp b/src/modes.cpp
index 6cdeb6565..9481f570e 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -31,12 +31,13 @@ static std::vector<ChannelModeStatus *> ChannelModesByStatus;
/* Number of generic modes we support */
unsigned ModeManager::GenericChannelModes = 0, ModeManager::GenericUserModes = 0;
-/* Default channel mode lock */
-std::list<std::pair<Anope::string, Anope::string> > ModeManager::ModeLockOn;
-std::list<Anope::string> ModeManager::ModeLockOff;
+ChannelStatus::ChannelStatus()
+{
+}
-/* Default modes bots have on channels */
-ChannelStatus ModeManager::DefaultBotModes;
+ChannelStatus::ChannelStatus(const Anope::string &m) : modes(m)
+{
+}
void ChannelStatus::AddMode(char c)
{
@@ -75,7 +76,7 @@ Anope::string ChannelStatus::BuildModePrefixList() const
for (size_t i = 0; i < modes.length(); ++i)
{
- ChannelMode *cm = ModeManager::FindChannelModeByName(modes[i]);
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
if (cm != NULL && cm->type == MODE_STATUS)
{
ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
@@ -117,9 +118,9 @@ ChannelMode::~ChannelMode()
bool ChannelMode::CanSet(User *u) const
{
- if (Config->NoMLock.find(this->mchar) != Anope::string::npos || Config->CSRequire.find(this->mchar) != Anope::string::npos)
- return false;
- return true;
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCanSet, OnCanSet(u, this));
+ return MOD_RESULT == EVENT_ALLOW;
}
ChannelModeList::ChannelModeList(const Anope::string &cm, char mch) : ChannelMode(cm, mch)
@@ -358,9 +359,6 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
ChannelModesByName[cm->name] = cm;
- /* Apply this mode to the new default mlock if its used */
- UpdateDefaultMLock(Config);
-
FOREACH_MOD(I_OnChannelModeAdd, OnChannelModeAdd(cm));
return true;
@@ -621,66 +619,6 @@ void ModeManager::StackerDel(Mode *m)
}
}
-void ModeManager::UpdateDefaultMLock(ServerConfig *config)
-{
- ModeLockOn.clear();
- ModeLockOff.clear();
-
- Anope::string modes;
- spacesepstream sep(config->MLock);
- sep.GetToken(modes);
-
- int adding = -1;
- for (unsigned i = 0, end_mode = modes.length(); i < end_mode; ++i)
- {
- if (modes[i] == '+')
- adding = 1;
- else if (modes[i] == '-')
- adding = 0;
- else if (adding != -1)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
-
- if (cm && cm->type != MODE_STATUS)
- {
- Anope::string param;
- if (adding == 1 && cm->type != MODE_REGULAR && !sep.GetToken(param)) // MODE_LIST OR MODE_PARAM
- {
- Log() << "Warning: Got default mlock mode " << cm->mchar << " with no param?";
- continue;
- }
-
- if (cm->type != MODE_LIST) // Only MODE_LIST can have duplicates
- {
- for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = ModeLockOn.begin(), it_end = ModeLockOn.end(); it != it_end; ++it)
- if (it->first == cm->name)
- {
- ModeLockOn.erase(it);
- break;
- }
-
- for (std::list<Anope::string>::iterator it = ModeLockOff.begin(), it_end = ModeLockOff.end(); it != it_end; ++it)
- if (*it == cm->name)
- {
- ModeLockOff.erase(it);
- break;
- }
- }
-
- if (adding)
- ModeLockOn.push_back(std::make_pair(cm->name, param));
- else
- ModeLockOff.push_back(cm->name);
- }
- }
- }
-
- /* Set Bot Modes */
- DefaultBotModes.Clear();
- for (unsigned i = 0; i < config->BotModes.length(); ++i)
- DefaultBotModes.AddMode(config->BotModes[i]);
-}
-
Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0)
{
Anope::string n, u, h;
diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp
index 82691822f..211304cae 100644
--- a/src/modulemanager.cpp
+++ b/src/modulemanager.cpp
@@ -229,10 +229,9 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
/* If the module is hooked to the reload event it wants to initialize its config here */
if (std::find(EventHandlers[I_OnReload].begin(), EventHandlers[I_OnReload].end(), m) != EventHandlers[I_OnReload].end())
{
- ConfigReader reader;
try
{
- m->OnReload(Config, reader);
+ m->OnReload(Config);
}
catch (const ConfigException &ex)
{
diff --git a/src/nickalias.cpp b/src/nickalias.cpp
index 5e6960cc6..0de2f6d0a 100644
--- a/src/nickalias.cpp
+++ b/src/nickalias.cpp
@@ -139,7 +139,8 @@ class CoreExport NickServRelease : public User, public Timer
* @param na The nick
* @param delay The delay before the nick is released
*/
- NickServRelease(NickAlias *na, time_t delay) : User(na->nick, Config->NSEnforcerUser, Config->NSEnforcerHost, "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Timer(delay), nick(na->nick)
+ NickServRelease(NickAlias *na, time_t delay) : User(na->nick, Config->GetBlock("options")->Get<const Anope::string &>("enforceruser"),
+ Config->GetBlock("options")->Get<const Anope::string &>("enforcerhost"), "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Timer(delay), nick(na->nick)
{
/* Erase the current release timer and use the new one */
std::map<Anope::string, NickServRelease *>::iterator nit = NickServReleases.find(this->nick);
@@ -176,12 +177,12 @@ void NickAlias::OnCancel(User *)
this->Extend("HELD");
this->Shrink("COLLIDED");
- new NickServHeld(this, Config->NSReleaseTimeout);
+ new NickServHeld(this, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
if (IRCD->CanSVSHold)
- IRCD->SendSVSHold(this->nick);
+ IRCD->SendSVSHold(this->nick, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
else
- new NickServRelease(this, Config->NSReleaseTimeout);
+ new NickServRelease(this, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
}
}
diff --git a/src/nickcore.cpp b/src/nickcore.cpp
index dcd324846..e2b47e953 100644
--- a/src/nickcore.cpp
+++ b/src/nickcore.cpp
@@ -25,19 +25,16 @@ NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore"),
this->o = NULL;
this->channelcount = 0;
this->lastmail = 0;
- this->memos.memomax = Config->MSMaxMemos;
- this->language = Config->NSDefLanguage;
+ this->memos.memomax = 0;
this->display = coredisplay;
- /* Set default nick core flags */
- for (std::set<Anope::string>::const_iterator it = Config->NSDefFlags.begin(), it_end = Config->NSDefFlags.end(); it != it_end; ++it)
- this->ExtendMetadata(*it);
-
size_t old = NickCoreList->size();
(*NickCoreList)[this->display] = this;
if (old == NickCoreList->size())
Log(LOG_DEBUG) << "Duplicate account " << coredisplay << " in nickcore table?";
+
+ FOREACH_MOD(I_OnNickCoreCreate, OnNickCoreCreate(this));
}
NickCore::~NickCore()
@@ -174,6 +171,11 @@ Anope::string NickCore::GetAccess(unsigned entry) const
return this->access[entry];
}
+unsigned NickCore::GetAccessCount() const
+{
+ return this->access.size();
+}
+
bool NickCore::FindAccess(const Anope::string &entry)
{
for (unsigned i = 0, end = this->access.size(); i < end; ++i)
diff --git a/src/opertype.cpp b/src/opertype.cpp
index eb73c20f4..0db17464d 100644
--- a/src/opertype.cpp
+++ b/src/opertype.cpp
@@ -27,9 +27,9 @@ Oper *Oper::Find(const Anope::string &name)
OperType *OperType::Find(const Anope::string &name)
{
- for (std::list<OperType *>::iterator it = Config->MyOperTypes.begin(), it_end = Config->MyOperTypes.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i)
{
- OperType *ot = *it;
+ OperType *ot = Config->MyOperTypes[i];
if (ot->GetName() == name)
return ot;
diff --git a/src/protocol.cpp b/src/protocol.cpp
index a66bf8227..14739d24b 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -67,14 +67,6 @@ void IRCDProto::SendKickInternal(const BotInfo *bi, const Channel *c, const User
UplinkSocket::Message(bi) << "KICK " << c->name << " " << u->GetUID();
}
-void IRCDProto::SendMessageInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf)
-{
- if (Config->NSDefFlags.count("msg"))
- SendPrivmsgInternal(bi, dest, buf);
- else
- SendNoticeInternal(bi, dest, buf);
-}
-
void IRCDProto::SendNoticeInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &msg)
{
UplinkSocket::Message(bi) << "NOTICE " << dest << " :" << msg;
@@ -176,16 +168,6 @@ void IRCDProto::SendKick(const BotInfo *bi, const Channel *chan, const User *use
SendKickInternal(bi, chan, user, buf);
}
-void IRCDProto::SendMessage(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...)
-{
- va_list args;
- char buf[BUFSIZE] = "";
- va_start(args, fmt);
- vsnprintf(buf, BUFSIZE - 1, fmt, args);
- va_end(args);
- SendMessageInternal(bi, dest, buf);
-}
-
void IRCDProto::SendNotice(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...)
{
va_list args;
@@ -339,7 +321,7 @@ bool IRCDProto::IsNickValid(const Anope::string &nick)
bool IRCDProto::IsChannelValid(const Anope::string &chan)
{
- if (chan.empty() || chan[0] != '#' || chan.length() > Config->ChanLen)
+ if (chan.empty() || chan[0] != '#' || chan.length() > Config->GetBlock("networkinfo")->Get<unsigned>("chanlen"))
return false;
return true;
@@ -347,7 +329,7 @@ bool IRCDProto::IsChannelValid(const Anope::string &chan)
bool IRCDProto::IsIdentValid(const Anope::string &ident)
{
- if (ident.empty() || ident.length() > Config->UserLen)
+ if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("chanlen"))
return false;
for (unsigned i = 0; i < ident.length(); ++i)
@@ -364,12 +346,15 @@ bool IRCDProto::IsIdentValid(const Anope::string &ident)
bool IRCDProto::IsHostValid(const Anope::string &host)
{
- if (host.empty() || host.length() > Config->HostLen)
+ if (host.empty() || host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
return false;
- if (Config->VhostDisallowBE.find_first_of(host[0]) != Anope::string::npos)
+ const Anope::string &vhostdisablebe = Config->GetBlock("networkinfo")->Get<const Anope::string &>("disallow_start_or_end"),
+ vhostchars = Config->GetBlock("networkinfo")->Get<const Anope::string &>("vhost_chars");
+
+ if (vhostdisablebe.find_first_of(host[0]) != Anope::string::npos)
return false;
- else if (Config->VhostDisallowBE.find_first_of(host[host.length() - 1]) != Anope::string::npos)
+ else if (vhostdisablebe.find_first_of(host[host.length() - 1]) != Anope::string::npos)
return false;
int dots = 0;
@@ -377,11 +362,11 @@ bool IRCDProto::IsHostValid(const Anope::string &host)
{
if (host[i] == '.')
++dots;
- if (Config->VhostChars.find_first_of(host[i]) == Anope::string::npos)
+ if (vhostchars.find_first_of(host[i]) == Anope::string::npos)
return false;
}
- return Config->VhostUndotted || dots > 0;
+ return dots > 0 || Config->GetBlock("networkinfo")->Get<bool>("allow_undotted_vhosts");
}
void IRCDProto::SendOper(User *u)
@@ -392,7 +377,7 @@ void IRCDProto::SendOper(User *u)
unsigned IRCDProto::GetMaxListFor(Channel *c)
{
- return c->HasMode("LBAN") ? 0 : Config->ListSize;
+ return c->HasMode("LBAN") ? 0 : Config->GetBlock("networkinfo")->Get<int>("modelistsize");
}
MessageSource::MessageSource(const Anope::string &src) : source(src), u(NULL), s(NULL)
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index 48d039be3..12655533b 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -276,22 +276,12 @@ ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInf
this->repeattimes = 0;
this->banexpire = 0;
this->bi = NULL;
-
- this->last_topic_setter = Config->ChanServ;
- this->last_topic_time = Anope::CurTime;
+ this->last_topic_time = 0;
this->name = chname;
- /* Set default channel flags */
- for (std::set<Anope::string>::const_iterator it = Config->CSDefFlags.begin(), it_end = Config->CSDefFlags.end(); it != it_end; ++it)
- this->ExtendMetadata(*it);
-
- /* Set default bot flags */
- for (std::set<Anope::string>::const_iterator it = Config->BSDefFlags.begin(), it_end = Config->BSDefFlags.end(); it != it_end; ++it)
- this->ExtendMetadata(*it);
-
- this->bantype = Config->CSDefBantype;
- this->memos.memomax = Config->MSMaxMemos;
+ this->bantype = 2;
+ this->memos.memomax = 0;
this->last_used = this->time_registered = Anope::CurTime;
for (int i = 0; i < TTB_SIZE; ++i)
@@ -357,6 +347,8 @@ ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"),
l->ci = this;
this->log_settings->push_back(l);
}
+
+ FOREACH_MOD(I_OnCreateChan, OnCreateChan(this));
}
ChannelInfo::~ChannelInfo()
@@ -474,11 +466,10 @@ Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
BotInfo *bi = BotInfo::Find(sbi);
if (*ci->bi != bi)
{
- if (ci->bi)
+ if (bi)
+ bi->Assign(NULL, ci);
+ else if (ci->bi)
ci->bi->UnAssign(NULL, ci);
- ci->bi = bi;
- if (ci->bi)
- ci->bi->Assign(NULL, ci);
}
{
Anope::string ttb, tok;
@@ -1035,23 +1026,6 @@ bool ChannelInfo::CheckKick(User *user)
Log(LOG_DEBUG) << "Autokicking " << user->nick << " (" << mask << ") from " << this->name;
- /* If the channel isn't syncing and doesn't have any users, join ChanServ
- * Note that the user AND POSSIBLY the botserv bot exist here
- * ChanServ always enforces channels like this to keep people from deleting bots etc
- * that are holding channels.
- */
- if (this->c->users.size() == (this->bi && this->c->FindUser(this->bi) ? 2 : 1) && !this->c->HasExt("INHABIT") && !this->c->HasExt("SYNCING"))
- {
- /* Set +ntsi to prevent rejoin */
- c->SetMode(NULL, "NOEXTERNAL");
- c->SetMode(NULL, "TOPIC");
- c->SetMode(NULL, "SECRET");
- c->SetMode(NULL, "INVITE");
-
- /* Join ChanServ and set a timer for this channel to part ChanServ later */
- this->c->Hold();
- }
-
this->c->SetMode(NULL, "BAN", mask);
this->c->Kick(NULL, user, "%s", reason.c_str());
diff --git a/src/servers.cpp b/src/servers.cpp
index 28ff7bf17..2f87d66e4 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -127,21 +127,12 @@ Server::~Server()
if (Servers::Capab.count("NOQUIT") > 0 || Servers::Capab.count("QS") > 0)
{
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
{
User *u = it->second;
- ++it;
if (u->server == this)
{
- NickAlias *na = NickAlias::Find(u->nick);
- if (na && !na->nc->HasExt("SUSPENDED") && (u->IsRecognized() || u->IsIdentified()))
- {
- na->last_seen = Anope::CurTime;
- if (!Config->NSHideNetSplitQuit)
- na->last_quit = this->quit_reason;
- }
-
u->Quit(this->quit_reason);
u->server = NULL;
}
@@ -201,6 +192,11 @@ const Anope::string &Server::GetSID() const
return this->name;
}
+const Anope::string &Server::GetQuitReason() const
+{
+ return this->quit_reason;
+}
+
const std::vector<Server *> &Server::GetLinks() const
{
return this->links;
@@ -313,8 +309,8 @@ bool Server::IsULined() const
if (this == Me)
return true;
- for (std::list<Anope::string>::const_iterator it = Config->Ulines.begin(), it_end = Config->Ulines.end(); it != it_end; ++it)
- if (it->equals_ci(this->GetName()))
+ for (unsigned i = 0; i < Config->Ulines.size(); ++i)
+ if (Config->Ulines[i].equals_ci(this->GetName()))
return true;
return false;
}
@@ -326,7 +322,7 @@ bool Server::IsJuped() const
void Server::Notice(const BotInfo *source, const Anope::string &message)
{
- if (Config->NSDefFlags.count("MSG"))
+ if (Config->UsePrivmsg && Config->DefPrivmsg)
IRCD->SendGlobalPrivmsg(source, this, message);
else
IRCD->SendGlobalNotice(source, this, message);
@@ -370,13 +366,13 @@ const Anope::string Servers::TS6_UID_Retrieve()
static Anope::string current_uid = "AAAAAA";
- while (User::Find(Config->Numeric + current_uid) != NULL)
+ while (User::Find(Me->GetSID() + current_uid) != NULL)
{
int current_len = current_uid.length() - 1;
while (current_len >= 0 && nextID(current_uid[current_len--]) == 'A');
}
- return Config->Numeric + current_uid;
+ return Me->GetSID() + current_uid;
}
const Anope::string Servers::TS6_SID_Retrieve()
@@ -384,13 +380,9 @@ const Anope::string Servers::TS6_SID_Retrieve()
if (!IRCD || !IRCD->RequiresID)
return "";
- static Anope::string current_sid;
+ static Anope::string current_sid = Config->GetBlock("options")->Get<const Anope::string &>("id");
if (current_sid.empty())
- {
- current_sid = Config->Numeric;
- if (current_sid.empty())
- current_sid = "00A";
- }
+ current_sid = "00A";
while (Server::Find(current_sid) != NULL)
{
diff --git a/src/uplink.cpp b/src/uplink.cpp
index f8841c58f..ff90ee53c 100644
--- a/src/uplink.cpp
+++ b/src/uplink.cpp
@@ -31,7 +31,7 @@ class ReconnectTimer : public Timer
}
catch (const SocketException &ex)
{
- Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink]->host << ":" << Config->Uplinks[Anope::CurrentUplink]->port << "): " << ex.GetReason();
+ Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << "): " << ex.GetReason();
}
}
};
@@ -41,19 +41,19 @@ void Uplink::Connect()
if (static_cast<unsigned>(++Anope::CurrentUplink) >= Config->Uplinks.size())
Anope::CurrentUplink = 0;
- ServerConfig::Uplink *u = Config->Uplinks[Anope::CurrentUplink];
+ Configuration::Uplink &u = Config->Uplinks[Anope::CurrentUplink];
new UplinkSocket();
- if (!Config->LocalHost.empty())
- UplinkSock->Bind(Config->LocalHost);
+ if (!Config->GetBlock("serverinfo")->Get<const Anope::string &>("localhost").empty())
+ UplinkSock->Bind(Config->GetBlock("serverinfo")->Get<const Anope::string &>("localhost"));
FOREACH_MOD(I_OnPreServerConnect, OnPreServerConnect());
- Anope::string ip = Anope::Resolve(u->host, u->ipv6 ? AF_INET6 : AF_INET);
- Log(LOG_TERMINAL) << "Attempting to connect to uplink #" << (Anope::CurrentUplink + 1) << " " << u->host << " (" << ip << "), port " << u->port;
- UplinkSock->Connect(ip, u->port);
+ Anope::string ip = Anope::Resolve(u.host, u.ipv6 ? AF_INET6 : AF_INET);
+ Log(LOG_TERMINAL) << "Attempting to connect to uplink #" << (Anope::CurrentUplink + 1) << " " << u.host << " (" << ip << "), port " << u.port;
+ UplinkSock->Connect(ip, u.port);
}
-UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink]->ipv6), ConnectionSocket(), BufferedSocket()
+UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink].ipv6), ConnectionSocket(), BufferedSocket()
{
UplinkSock = this;
}
@@ -107,9 +107,7 @@ UplinkSocket::~UplinkSocket()
}
else if (!Anope::Quitting)
{
- int retry = Config->RetryWait;
- if (retry <= 0)
- retry = 60;
+ time_t retry = Config->GetBlock("options")->Get<time_t>("retrywait");
Log() << "Disconnected, retrying in " << retry << " seconds";
new ReconnectTimer(retry);
@@ -129,14 +127,14 @@ bool UplinkSocket::ProcessRead()
void UplinkSocket::OnConnect()
{
- Log(LOG_TERMINAL) << "Successfully connected to uplink #" << (Anope::CurrentUplink + 1) << " " << Config->Uplinks[Anope::CurrentUplink]->host << ":" << Config->Uplinks[Anope::CurrentUplink]->port;
+ Log(LOG_TERMINAL) << "Successfully connected to uplink #" << (Anope::CurrentUplink + 1) << " " << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port;
IRCD->SendConnect();
FOREACH_MOD(I_OnServerConnect, OnServerConnect());
}
void UplinkSocket::OnError(const Anope::string &error)
{
- Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink]->host << ":" << Config->Uplinks[Anope::CurrentUplink]->port << ")" << (!error.empty() ? (": " + error) : "");
+ Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << ")" << (!error.empty() ? (": " + error) : "");
}
UplinkSocket::Message::Message() : server(NULL), user(NULL)
diff --git a/src/users.cpp b/src/users.cpp
index 691653055..26d5b31c5 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -279,10 +279,9 @@ void User::SendMessage(const BotInfo *source, const Anope::string &msg)
* - The user is registered and has set /ns set msg on
*/
sepstream sep(translated_message, '\n');
- Anope::string tok;
- while (sep.GetToken(tok))
+ for (Anope::string tok; sep.GetToken(tok);)
{
- if (Config->UsePrivmsg && ((!this->nc && Config->NSDefFlags.count("msg")) || (this->nc && this->nc->HasExt("MSG"))))
+ if (Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasExt("MSG"))))
IRCD->SendPrivmsg(source, this->GetUID(), "%s", tok.c_str());
else
IRCD->SendNotice(source, this->GetUID(), "%s", tok.c_str());
@@ -291,17 +290,16 @@ void User::SendMessage(const BotInfo *source, const Anope::string &msg)
/** Collides a nick.
*
- * First, it marks the nick (if the user is on a registered nick, we don't use it without but it could be)
- * as COLLIDED, this is checked in NickAlias::OnCancel.
+ * First, it marks the nick as COLLIDED, this is checked in NickAlias::OnCancel.
*
* Then it does one of two things.
*
* 1. This will force change the users nick to the guest nick. This gets processed by the IRCd and comes
- * back to call do_nick. do_nick changes the nick of the use to the new one, then calls NickAlias::OnCancel
+ * back as a nick change, which calls NickAlias::OnCancel
* with the users old nick's nickalias (if there is one).
*
- * 2. Calls User::Kill, which will either delete the user immediatly or kill them, wait for the QUIT,
- * then delete the user then. Users destructor then calls NickAlias::OnCancel
+ * 2. Calls User::Kill, which kills the user and deletes the user at the end of the I/O loop.
+ * Users destructor then calls NickAlias::OnCancel
*
* NickAlias::OnCancel checks for NS_COLLIDED, it then does one of two things.
*
@@ -309,40 +307,13 @@ void User::SendMessage(const BotInfo *source, const Anope::string &msg)
*
* 2. We create a new client with SendClientIntroduction(). Note that is it important that this is called either after the
* user has been removed from our internal list of user or after the users nick has been updated completely internally.
- * This is beacuse SendClientIntroduction will destroy any users we think are currently on the nickname (which causes a
- * lot of problems, eg, deleting the user which recalls OnCancel), whether they really are or not. We then create a
- * release timer for this new client that waits and later on sends a QUIT for the client. Release timers are never used
- * for SVSHolds. Ever.
+ * We then create a release timer for this new client that waits and later on sends a QUIT for the client. Release timers
+ * are never used for SVSHolds. Ever.
*
*
* Note that now for the timers we only store the users name, not the NickAlias* pointer. We never remove timers when
* a user changes nick or a nick is deleted, the timers must assume that either of these may have happend.
*
- * Storing NickAlias* pointers caused quite a problem, some of which are:
- *
- * Having a valid timer alive that calls User::Collide would either:
- *
- * 1. Kill the user, causing users destructor to cancel all timers for the nick (as it should, it has no way of knowing
- * if we are in a timer or not) which would delete the currently active timer while it was running, causing TimerManager
- * to explode.
- *
- * 2. Force a user off of their nick, this would call NickAlias::Cancel before updating the user internally (to cancel the
- * current nicks timers, granted we could have easially saved this and called it after) which could possibly try to
- * introduce an enforcer nick. We would then check to see if the nick is already in use (it is, internally) and send
- * a kill for that nick. That may in turn delete the user immediatly, calling users destructor, which would attempt to
- * delete the timer, causing TimerManager to explode.
- *
- * Additionally, if we marked the timer as "in use" so that calling the ClearTimer function wouldn't delete them, users
- * destructor would then call NickAlias::OnCancel, which would (at this point, it was unsetting GUESTED after introducing
- * the new client) introduce the same new client again, without actually deleting the originial user, causing an infinite
- * loop.
- *
- * This is why we remove NS_GUESTED first in NickAlias::OnCancel before introducing a new client, although this should
- * not happen anymore. If I must emphasize this again, users need to be GONE from the internal list before calling
- * NickAlias::OnCancel. NickAlias::OnCancel intentionally reffers to this->nick, not the user passed to it. They *can*
- * (but not always) be different, depending if the user changed nicks or disconnected.
- *
- *
* Adam
*/
void User::Collide(NickAlias *na)
@@ -352,16 +323,18 @@ void User::Collide(NickAlias *na)
if (IRCD->CanSVSNick)
{
+ const Anope::string &guestprefix = Config->GetBlock("options")->Get<const Anope::string &>("guestnickprefix");
+
Anope::string guestnick;
int i = 0;
do
{
- guestnick = Config->NSGuestNickPrefix + stringify(static_cast<uint16_t>(rand()));
+ guestnick = guestprefix + stringify(static_cast<uint16_t>(rand()));
} while (User::Find(guestnick) && i++ < 10);
if (i == 11)
- this->Kill(Config->NickServ, "Services nickname-enforcer kill");
+ this->Kill(NickServ ? NickServ->nick : "", "Services nickname-enforcer kill");
else
{
if (NickServ)
@@ -370,7 +343,7 @@ void User::Collide(NickAlias *na)
}
}
else
- this->Kill(Config->NickServ, "Services nickname-enforcer kill");
+ this->Kill(NickServ ? NickServ->nick : "", "Services nickname-enforcer kill");
}
void User::Identify(NickAlias *na)
@@ -395,7 +368,7 @@ void User::Identify(NickAlias *na)
IRCD->SendLogin(this);
const NickAlias *this_na = NickAlias::Find(this->nick);
- if (!Config->NoNicknameOwnership && this_na && this_na->nc == *na->nc && na->nc->HasExt("UNCONFIRMED") == false)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && this_na && this_na->nc == *na->nc && na->nc->HasExt("UNCONFIRMED") == false)
this->SetMode(NickServ, "REGISTERED");
FOREACH_MOD(I_OnNickIdentify, OnNickIdentify(this));
@@ -738,8 +711,7 @@ bool User::IsProtected() const
void User::Kill(const Anope::string &source, const Anope::string &reason)
{
- Anope::string real_source = source.empty() ? Config->ServerName : source;
- Anope::string real_reason = real_source + " (" + reason + ")";
+ Anope::string real_reason = (source.empty() ? Me->GetName() : source) + " (" + reason + ")";
IRCD->SendSVSKill(BotInfo::Find(source), this, "%s", real_reason.c_str());
}
@@ -754,12 +726,7 @@ void User::KillInternal(const Anope::string &source, const Anope::string &reason
Log(this, "killed") << "was killed by " << source << " (Reason: " << reason << ")";
- NickAlias *na = NickAlias::Find(this->nick);
- if (na && !na->nc->HasExt("SUSPENDED") && (this->IsRecognized() || this->IsIdentified(true)))
- {
- na->last_seen = Anope::CurTime;
- na->last_quit = reason;
- }
+ this->Quit(reason);
this->quit = true;
quitting_users.push_back(this);
@@ -773,6 +740,8 @@ void User::Quit(const Anope::string &reason)
return;
}
+ FOREACH_MOD(I_OnUserQuit, OnUserQuit(this, reason));
+
this->quit = true;
quitting_users.push_back(this);
}
@@ -813,16 +782,16 @@ Anope::string User::Mask() const
bool User::BadPassword()
{
- if (!Config->BadPassLimit)
+ if (!Config->GetBlock("options")->Get<int>("badpasslimit"))
return false;
- if (Config->BadPassTimeout > 0 && this->invalid_pw_time > 0 && this->invalid_pw_time < Anope::CurTime - Config->BadPassTimeout)
+ if (Config->GetBlock("options")->Get<time_t>("badpasstimeout") > 0 && this->invalid_pw_time > 0 && this->invalid_pw_time < Anope::CurTime - Config->GetBlock("options")->Get<time_t>("badpasstimeout"))
this->invalid_pw_count = 0;
++this->invalid_pw_count;
this->invalid_pw_time = Anope::CurTime;
- if (this->invalid_pw_count >= Config->BadPassLimit)
+ if (this->invalid_pw_count >= Config->GetBlock("options")->Get<int>("badpasslimit"))
{
- this->Kill(Config->ServerName, "Too many invalid passwords");
+ this->Kill(Me->GetName(), "Too many invalid passwords");
return true;
}
diff --git a/src/xline.cpp b/src/xline.cpp
index 67f976d9a..0ba3d6557 100644
--- a/src/xline.cpp
+++ b/src/xline.cpp
@@ -25,11 +25,11 @@ Serialize::Checker<std::multimap<Anope::string, XLine *, ci::less> > XLineManage
void XLine::InitRegex()
{
- if (!Config->RegexEngine.empty() && this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/')
+ if (this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/' && !Config->GetBlock("options")->Get<const Anope::string &>("regexengine").empty())
{
Anope::string stripped_mask = this->mask.substr(1, this->mask.length() - 2);
- ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine);
+ ServiceReference<RegexProvider> provider("Regex", Config->GetBlock("options")->Get<const Anope::string &>("regexengine"));
if (provider)
{
try
@@ -44,7 +44,7 @@ void XLine::InitRegex()
}
}
-XLine::XLine(const Anope::string &ma, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(Config->OperServ), created(0), expires(0), reason(r), id(uid)
+XLine::XLine(const Anope::string &ma, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(OperServ ? OperServ->nick : ""), created(0), expires(0), reason(r), id(uid)
{
regex = NULL;
manager = NULL;
@@ -118,8 +118,6 @@ Anope::string XLine::GetReal() const
Anope::string XLine::GetReason() const
{
Anope::string r = this->reason;
- if (Config->AddAkiller && !this->by.empty())
- r = "[" + this->by + "] " + r;
if (!this->id.empty())
r += " (ID: " + this->id + ")";
return r;