From e65d8b2f3dfdb40858259b3bb48ef6998c31e62f Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 17 Aug 2010 19:27:37 -0400 Subject: Rewrote the config reader to better handle invalid configs. This prevents Anope from exploding when /os reload has errors. --- src/actions.cpp | 8 +- src/bots.cpp | 20 +- src/botserv.cpp | 32 +- src/channels.cpp | 18 +- src/chanserv.cpp | 28 +- src/commands.cpp | 4 +- src/config.cpp | 1183 ++++++++++++++++++++++--------------------------- src/configreader.cpp | 40 +- src/hostserv.cpp | 8 +- src/init.cpp | 59 ++- src/language.cpp | 14 +- src/log.cpp | 8 +- src/mail.cpp | 16 +- src/main.cpp | 38 +- src/memoserv.cpp | 50 +-- src/messages.cpp | 92 ++-- src/misc.cpp | 26 +- src/modes.cpp | 12 +- src/modulemanager.cpp | 8 +- src/modules.cpp | 12 +- src/nickalias.cpp | 8 +- src/nickcore.cpp | 4 +- src/nickserv.cpp | 24 +- src/operserv.cpp | 42 +- src/protocol.cpp | 12 +- src/regchannel.cpp | 10 +- src/send.cpp | 2 +- src/servers.cpp | 8 +- src/sessions.cpp | 26 +- src/users.cpp | 24 +- 30 files changed, 873 insertions(+), 963 deletions(-) (limited to 'src') diff --git a/src/actions.cpp b/src/actions.cpp index 17c0a2898..bdc5a041d 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -23,14 +23,14 @@ bool bad_password(User *u) { time_t now = time(NULL); - if (!u || !Config.BadPassLimit) + if (!u || !Config->BadPassLimit) return false; - if (Config.BadPassTimeout > 0 && u->invalid_pw_time > 0 && u->invalid_pw_time < now - Config.BadPassTimeout) + if (Config->BadPassTimeout > 0 && u->invalid_pw_time > 0 && u->invalid_pw_time < now - Config->BadPassTimeout) u->invalid_pw_count = 0; ++u->invalid_pw_count; u->invalid_pw_time = now; - if (u->invalid_pw_count >= Config.BadPassLimit) + if (u->invalid_pw_count >= Config->BadPassLimit) { kill_user("", u->nick, "Too many invalid passwords"); return true; @@ -53,7 +53,7 @@ void kill_user(const Anope::string &source, const Anope::string &user, const Ano if (user.empty()) return; - Anope::string real_source = source.empty() ? Config.ServerName : source; + Anope::string real_source = source.empty() ? Config->ServerName : source; Anope::string buf = real_source + " (" + reason + ")"; diff --git a/src/bots.cpp b/src/bots.cpp index c07b358da..cb7a370c1 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -30,19 +30,19 @@ BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const A this->chancount = 0; this->lastmsg = this->created = time(NULL); - if (!Config.s_ChanServ.empty() && nnick.equals_ci(Config.s_ChanServ)) + if (!Config->s_ChanServ.empty() && nnick.equals_ci(Config->s_ChanServ)) ChanServ = this; - else if (!Config.s_BotServ.empty() && nnick.equals_ci(Config.s_BotServ)) + else if (!Config->s_BotServ.empty() && nnick.equals_ci(Config->s_BotServ)) BotServ = this; - else if (!Config.s_HostServ.empty() && nnick.equals_ci(Config.s_HostServ)) + else if (!Config->s_HostServ.empty() && nnick.equals_ci(Config->s_HostServ)) HostServ = this; - else if (!Config.s_OperServ.empty() && nnick.equals_ci(Config.s_OperServ)) + else if (!Config->s_OperServ.empty() && nnick.equals_ci(Config->s_OperServ)) OperServ = this; - else if (!Config.s_MemoServ.empty() && nnick.equals_ci(Config.s_MemoServ)) + else if (!Config->s_MemoServ.empty() && nnick.equals_ci(Config->s_MemoServ)) MemoServ = this; - else if (!Config.s_NickServ.empty() && nnick.equals_ci(Config.s_NickServ)) + else if (!Config->s_NickServ.empty() && nnick.equals_ci(Config->s_NickServ)) NickServ = this; - else if (!Config.s_GlobalNoticer.empty() && nnick.equals_ci(Config.s_GlobalNoticer)) + else if (!Config->s_GlobalNoticer.empty() && nnick.equals_ci(Config->s_GlobalNoticer)) Global = this; BotListByNick[this->nick] = this; @@ -94,7 +94,7 @@ void BotInfo::RejoinAll() { ChannelInfo *ci = it->second; - if (ci->bi == this && ci->c && ci->c->users.size() >= Config.BSMinUsers) + if (ci->bi == this && ci->c && ci->c->users.size() >= Config->BSMinUsers) this->Join(ci->c); } } @@ -112,7 +112,7 @@ void BotInfo::Assign(User *u, ChannelInfo *ci) ++this->chancount; ci->bi = this; - if (ci->c && ci->c->users.size() >= Config.BSMinUsers) + if (ci->c && ci->c->users.size() >= Config->BSMinUsers) this->Join(ci->c); } @@ -138,7 +138,7 @@ void BotInfo::UnAssign(User *u, ChannelInfo *ci) void BotInfo::Join(Channel *c) { - if (Config.BSSmartJoin) + if (Config->BSSmartJoin) { /* We check for bans */ if (c->bans && c->bans->count) diff --git a/src/botserv.cpp b/src/botserv.cpp index 381223681..ee6f08f29 100644 --- a/src/botserv.cpp +++ b/src/botserv.cpp @@ -26,7 +26,7 @@ E void moduleAddBotServCmds(); void moduleAddBotServCmds() { - ModuleManager::LoadModuleList(Config.BotServCoreModules); + ModuleManager::LoadModuleList(Config->BotServCoreModules); } /*************************************************************************/ @@ -61,7 +61,7 @@ void get_botserv_stats(long *nrec, long *memuse) void bs_init() { - if (!Config.s_BotServ.empty()) + if (!Config->s_BotServ.empty()) moduleAddBotServCmds(); } @@ -198,25 +198,25 @@ void botchanmsgs(User *u, ChannelInfo *ci, const Anope::string &buf) { BadWord *bw = ci->GetBadWord(i); - if (bw->type == BW_ANY && ((Config.BSCaseSensitive && nbuf.find(bw->word) != Anope::string::npos) || (!Config.BSCaseSensitive && nbuf.find_ci(bw->word) != Anope::string::npos))) + if (bw->type == BW_ANY && ((Config->BSCaseSensitive && nbuf.find(bw->word) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) != Anope::string::npos))) mustkick = true; else if (bw->type == BW_SINGLE) { size_t len = bw->word.length(); - if ((Config.BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config.BSCaseSensitive && bw->word.equals_ci(nbuf))) + if ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf))) mustkick = true; - else if (nbuf.find(' ') == len && ((Config.BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config.BSCaseSensitive && bw->word.equals_ci(nbuf)))) + else if (nbuf.find(' ') == len && ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf)))) mustkick = true; else { - if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((Config.BSCaseSensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!Config.BSCaseSensitive && nbuf.find_ci(bw->word) == nbuf.length() - len))) + if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((Config->BSCaseSensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) == nbuf.length() - len))) mustkick = true; else { Anope::string wordbuf = " " + bw->word + " "; - if ((Config.BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config.BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) + if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) mustkick = true; } } @@ -225,13 +225,13 @@ void botchanmsgs(User *u, ChannelInfo *ci, const Anope::string &buf) { size_t len = bw->word.length(); - if ((Config.BSCaseSensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!Config.BSCaseSensitive && nbuf.substr(0, len).equals_ci(bw->word))) + if ((Config->BSCaseSensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(0, len).equals_ci(bw->word))) mustkick = true; else { Anope::string wordbuf = " " + bw->word; - if ((Config.BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config.BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) + if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) mustkick = true; } } @@ -239,13 +239,13 @@ void botchanmsgs(User *u, ChannelInfo *ci, const Anope::string &buf) { size_t len = bw->word.length(); - if ((Config.BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!Config.BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word))) + if ((Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word))) mustkick = true; else { Anope::string wordbuf = bw->word + " "; - if ((Config.BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config.BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) + if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) mustkick = true; } } @@ -253,7 +253,7 @@ void botchanmsgs(User *u, ChannelInfo *ci, const Anope::string &buf) if (mustkick) { check_ban(ci, u, TTB_BADWORDS); - if (Config.BSGentleBWReason) + if (Config->BSGentleBWReason) bot_kick(ci, u, BOT_REASON_BADWORD_GENTLE); else bot_kick(ci, u, BOT_REASON_BADWORD, bw->word.c_str()); @@ -320,12 +320,12 @@ void botchanmsgs(User *u, ChannelInfo *ci, const Anope::string &buf) return; /* Fantaisist commands */ - if (ci->botflags.HasFlag(BS_FANTASY) && buf[0] == Config.BSFantasyCharacter[0] && !was_action) + if (ci->botflags.HasFlag(BS_FANTASY) && buf[0] == Config->BSFantasyCharacter[0] && !was_action) { spacesepstream sep(buf); Anope::string token; - if (sep.GetToken(token) && token[0] == Config.BSFantasyCharacter[0]) + if (sep.GetToken(token) && token[0] == Config->BSFantasyCharacter[0]) { /* Strip off the fantasy character */ token.erase(token.begin()); @@ -396,7 +396,7 @@ static BanData *get_ban_data(Channel *c, User *u) for (bd = c->bd; bd; bd = next) { - if (now - bd->last_use > Config.BSKeepData) + if (now - bd->last_use > Config->BSKeepData) { if (bd->next) bd->next->prev = bd->prev; @@ -452,7 +452,7 @@ static UserData *get_user_data(Channel *c, User *u) time_t now = time(NULL); /* Checks whether data is obsolete */ - if (now - uc->ud.last_use > Config.BSKeepData) + if (now - uc->ud.last_use > Config->BSKeepData) { /* We should not free and realloc, but reset to 0 instead. */ diff --git a/src/channels.cpp b/src/channels.cpp index 9392b70cd..a10a4e675 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -109,9 +109,9 @@ void Channel::JoinUser(User *user) if (this->ci && check_access(user, this->ci, CA_MEMO) && this->ci->memos.memos.size() > 0) { if (this->ci->memos.memos.size() == 1) - notice_lang(Config.s_MemoServ, user, MEMO_X_ONE_NOTICE, this->ci->memos.memos.size(), this->ci->name.c_str()); + notice_lang(Config->s_MemoServ, user, MEMO_X_ONE_NOTICE, this->ci->memos.memos.size(), this->ci->name.c_str()); else - notice_lang(Config.s_MemoServ, user, MEMO_X_MANY_NOTICE, this->ci->memos.memos.size(), this->ci->name.c_str()); + notice_lang(Config->s_MemoServ, user, MEMO_X_MANY_NOTICE, this->ci->memos.memos.size(), this->ci->name.c_str()); } /* Added channelname to entrymsg - 30.03.2004, Certus */ /* Also, don't send the entrymsg when bursting -GD */ @@ -119,7 +119,7 @@ void Channel::JoinUser(User *user) user->SendMessage(whosends(this->ci)->nick, "[%s] %s", this->name.c_str(), this->ci->entry_message.c_str()); } - if (!Config.s_BotServ.empty() && this->ci && this->ci->bi) + if (!Config->s_BotServ.empty() && this->ci && this->ci->bi) { /** * We let the bot join even if it was an ignored user, as if we don't, @@ -129,7 +129,7 @@ void Channel::JoinUser(User *user) * But don't join the bot if the channel is persistant - Adam * But join persistant channels when syncing with our uplink- DP **/ - if ((!Me->IsSynced() || !this->ci->HasFlag(CI_PERSIST)) && this->users.size() >= Config.BSMinUsers && !this->FindUser(this->ci->bi)) + if ((!Me->IsSynced() || !this->ci->HasFlag(CI_PERSIST)) && this->users.size() >= Config->BSMinUsers && !this->FindUser(this->ci->bi)) this->ci->bi->Join(this); /* Only display the greet if the main uplink we're connected * to has synced, or we'll get greet-floods when the net @@ -193,7 +193,7 @@ void Channel::DeleteUser(User *user) /* check for BSMinUsers and part the BotServ bot from the channel * Use <= because the bot is included in this->users.size() */ - if (!Config.s_BotServ.empty() && this->ci && this->ci->bi && this->users.size() <= Config.BSMinUsers && this->FindUser(this->ci->bi)) + if (!Config->s_BotServ.empty() && this->ci && this->ci->bi && this->users.size() <= Config->BSMinUsers && this->FindUser(this->ci->bi)) this->ci->bi->Part(this->ci->c); else if (this->users.empty()) delete this; @@ -278,7 +278,7 @@ void Channel::SetModeInternal(ChannelMode *cm, const Anope::string ¶m, bool } BotInfo *bi = NULL; - if (!Config.s_BotServ.empty()) + if (!Config->s_BotServ.empty()) bi = findbot(param); User *u = bi ? bi : finduser(param); @@ -404,7 +404,7 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const Anope::string ¶m, bo } BotInfo *bi = NULL; - if (!Config.s_BotServ.empty()) + if (!Config->s_BotServ.empty()) bi = findbot(param); User *u = bi ? bi : finduser(param); @@ -460,7 +460,7 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const Anope::string ¶m, bo if (ci) { ci->UnsetFlag(CI_PERSIST); - if (!Config.s_BotServ.empty() && ci->bi && this->FindUser(ci->bi)) + if (!Config->s_BotServ.empty() && ci->bi && this->FindUser(ci->bi)) this->ci->bi->Part(this); } } @@ -865,7 +865,7 @@ void ChanSetInternalModes(Channel *c, int ac, const char **av) void Channel::KickInternal(const Anope::string &source, const Anope::string &nick, const Anope::string &reason) { BotInfo *bi = NULL; - if (!Config.s_BotServ.empty() && this->ci) + if (!Config->s_BotServ.empty() && this->ci) bi = findbot(nick); User *user = bi ? bi : finduser(nick); if (!user) diff --git a/src/chanserv.cpp b/src/chanserv.cpp index b0d6f4b16..03760b9b6 100644 --- a/src/chanserv.cpp +++ b/src/chanserv.cpp @@ -110,7 +110,7 @@ int levelinfo_maxwidth = 0; void moduleAddChanServCmds() { - ModuleManager::LoadModuleList(Config.ChanServCoreModules); + ModuleManager::LoadModuleList(Config->ChanServCoreModules); } /*************************************************************************/ @@ -263,7 +263,7 @@ void check_modes(Channel *c) if (c->server_modecount >= 3 && c->chanserv_modecount >= 3) { ircdproto->SendGlobops(NULL, "Warning: unable to set modes on channel %s. Are your servers' U:lines configured correctly?", c->name.c_str()); - Alog() << Config.s_ChanServ << ": Bouncy modes on channel " << c->name; + Alog() << Config->s_ChanServ << ": Bouncy modes on channel " << c->name; c->bouncy_modes = 1; return; } @@ -355,7 +355,7 @@ int check_valid_admin(User *user, Channel *chan, int servermode) if (servermode && !check_access(user, chan->ci, CA_AUTOPROTECT)) { - notice_lang(Config.s_ChanServ, user, CHAN_IS_REGISTERED, Config.s_ChanServ.c_str()); + notice_lang(Config->s_ChanServ, user, CHAN_IS_REGISTERED, Config->s_ChanServ.c_str()); chan->RemoveMode(NULL, CMODE_PROTECT, user->nick); return 0; } @@ -391,7 +391,7 @@ int check_valid_op(User *user, Channel *chan, int servermode) if (servermode && !check_access(user, chan->ci, CA_AUTOOP)) { - notice_lang(Config.s_ChanServ, user, CHAN_IS_REGISTERED, Config.s_ChanServ.c_str()); + notice_lang(Config->s_ChanServ, user, CHAN_IS_REGISTERED, Config->s_ChanServ.c_str()); if (owner) chan->RemoveMode(NULL, CMODE_OWNER, user->nick); @@ -479,7 +479,7 @@ void restore_topic(const Anope::string &chan) if (ircd->join2set && whosends(ci) == ChanServ) { ChanServ->Join(chan); - c->SetMode(NULL, CMODE_OP, Config.s_ChanServ); + c->SetMode(NULL, CMODE_OP, Config->s_ChanServ); } ircdproto->SendTopic(whosends(ci), c, c->topic_setter, c->topic); if (ircd->join2set && whosends(ci) == ChanServ) @@ -513,7 +513,7 @@ int check_topiclock(Channel *c, time_t topic_time) { c->topic.clear(); /* Bot assigned & Symbiosis ON?, the bot will set the topic - doc */ - /* Altough whosends() also checks for Config.BSMinUsers -GD */ + /* Altough whosends() also checks for Config->BSMinUsers -GD */ c->topic_setter = whosends(ci)->nick; } @@ -538,7 +538,7 @@ int check_topiclock(Channel *c, time_t topic_time) if (ircd->join2set && whosends(ci) == ChanServ) { ChanServ->Join(c); - c->SetMode(NULL, CMODE_OP, Config.s_ChanServ); + c->SetMode(NULL, CMODE_OP, Config->s_ChanServ); } ircdproto->SendTopic(whosends(ci), c, c->topic_setter, c->topic); @@ -554,7 +554,7 @@ int check_topiclock(Channel *c, time_t topic_time) void expire_chans() { - if (!Config.CSExpire) + if (!Config->CSExpire) return; time_t now = time(NULL); @@ -564,7 +564,7 @@ void expire_chans() ChannelInfo *ci = it->second; ++it; - if (!ci->c && now - ci->last_used >= Config.CSExpire && !ci->HasFlag(CI_FORBIDDEN) && !ci->HasFlag(CI_NO_EXPIRE) && !ci->HasFlag(CI_SUSPENDED)) + if (!ci->c && now - ci->last_used >= Config->CSExpire && !ci->HasFlag(CI_FORBIDDEN) && !ci->HasFlag(CI_NO_EXPIRE) && !ci->HasFlag(CI_SUSPENDED)) { EventReturn MOD_RESULT; FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci)); @@ -597,15 +597,15 @@ void cs_remove_nick(const NickCore *nc) if (ci->successor) { NickCore *nc2 = ci->successor; - if (!nc2->IsServicesOper() && Config.CSMaxReg && nc2->channelcount >= Config.CSMaxReg) + if (!nc2->IsServicesOper() && Config->CSMaxReg && nc2->channelcount >= Config->CSMaxReg) { - Alog() << Config.s_ChanServ << ": Successor (" << nc2->display << " ) of " << ci->name << " owns too many channels, deleting channel", + Alog() << Config->s_ChanServ << ": Successor (" << nc2->display << " ) of " << ci->name << " owns too many channels, deleting channel", delete ci; continue; } else { - Alog() << Config.s_ChanServ << ": Transferring foundership of " << ci->name << " from deleted nick " << nc->display << " to successor " << nc2->display; + Alog() << Config->s_ChanServ << ": Transferring foundership of " << ci->name << " from deleted nick " << nc->display << " to successor " << nc2->display; ci->founder = nc2; ci->successor = NULL; ++nc2->channelcount; @@ -613,7 +613,7 @@ void cs_remove_nick(const NickCore *nc) } else { - Alog() << Config.s_ChanServ << ": Deleting channel " << ci->name << "owned by deleted nick " << nc->display; + Alog() << Config->s_ChanServ << ": Deleting channel " << ci->name << "owned by deleted nick " << nc->display; if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) { @@ -963,7 +963,7 @@ void stick_all(ChannelInfo *ci) } } -ChanServTimer::ChanServTimer(Channel *chan) : Timer(Config.CSInhabit), c(chan) +ChanServTimer::ChanServTimer(Channel *chan) : Timer(Config->CSInhabit), c(chan) { if (c->ci) c->ci->SetFlag(CI_INHABIT); diff --git a/src/commands.cpp b/src/commands.cpp index 2647ea952..26ca76e65 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -57,7 +57,7 @@ void mod_run_cmd(BotInfo *bi, User *u, Command *c, const Anope::string &command, // Command requires registered users only if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified()) { - notice_lang(bi->nick, u, NICK_IDENTIFY_REQUIRED, Config.s_NickServ.c_str()); + notice_lang(bi->nick, u, NICK_IDENTIFY_REQUIRED, Config->s_NickServ.c_str()); Alog() << "Access denied for unregistered user " << u->nick << " with service " << bi->nick << " and command " << command; return; } @@ -164,7 +164,7 @@ void mod_help_cmd(BotInfo *bi, User *u, const Anope::string &cmd) Anope::string subcommand = tokens.StreamEnd() ? "" : tokens.GetRemaining(); - if (!c || (Config.HidePrivilegedCommands && !c->permission.empty() && (!u->Account() || !u->Account()->HasCommand(c->permission))) || !c->OnHelp(u, subcommand)) + if (!c || (Config->HidePrivilegedCommands && !c->permission.empty() && (!u->Account() || !u->Account()->HasCommand(c->permission))) || !c->OnHelp(u, subcommand)) notice_lang(bi->nick, u, NO_HELP_AVAILABLE, cmd.c_str()); else { diff --git a/src/config.cpp b/src/config.cpp index 7853196ad..0dfc9702e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -16,7 +16,7 @@ /*************************************************************************/ Anope::string services_conf = "services.conf"; // Services configuration file name -ServerConfig Config; +ServerConfig *Config = NULL; static Anope::string Modules; static Anope::string EncModules; @@ -40,14 +40,319 @@ static Anope::string NSDefaults; /*************************************************************************/ -ServerConfig::ServerConfig() : include_stack(), errstr(""), newconfig(), config_data() +ServerConfig::ServerConfig() : errstr(""), config_data() { - this->ClearStack(); -} + this->Read(); -void ServerConfig::ClearStack() -{ - include_stack.clear(); + if (!temp_nsuserhost.empty()) + { + size_t at = temp_nsuserhost.find('@'); + if (at == Anope::string::npos) + { + this->NSEnforcerUser = temp_nsuserhost; + this->NSEnforcerHost = this->ServiceHost; + } + else + { + this->NSEnforcerUser = temp_nsuserhost.substr(0, at); + this->NSEnforcerHost = temp_nsuserhost.substr(at + 1); + } + } + + if (NSDefaults.empty()) + { + this->NSDefFlags.SetFlag(NI_SECURE); + this->NSDefFlags.SetFlag(NI_MEMO_SIGNON); + this->NSDefFlags.SetFlag(NI_MEMO_RECEIVE); + } + else if (!NSDefaults.equals_ci("none")) + { + spacesepstream options(NSDefaults); + Anope::string option; + while (options.GetToken(option)) + { + if (option.equals_ci("kill")) + this->NSDefFlags.SetFlag(NI_KILLPROTECT); + else if (option.equals_ci("killquick")) + this->NSDefFlags.SetFlag(NI_KILL_QUICK); + else if (option.equals_ci("secure")) + this->NSDefFlags.SetFlag(NI_SECURE); + else if (option.equals_ci("private")) + this->NSDefFlags.SetFlag(NI_PRIVATE); + else if (option.equals_ci("msg")) + { + if (!this->UsePrivmsg) + Alog() << "msg in can only be used when UsePrivmsg is set"; + else + this->NSDefFlags.SetFlag(NI_MSG); + } + else if (option.equals_ci("hideemail")) + this->NSDefFlags.SetFlag(NI_HIDE_EMAIL); + else if (option.equals_ci("hideusermask")) + this->NSDefFlags.SetFlag(NI_HIDE_MASK); + else if (option.equals_ci("hidequit")) + this->NSDefFlags.SetFlag(NI_HIDE_QUIT); + else if (option.equals_ci("memosignon")) + this->NSDefFlags.SetFlag(NI_MEMO_SIGNON); + else if (option.equals_ci("memoreceive")) + this->NSDefFlags.SetFlag(NI_MEMO_RECEIVE); + else if (option.equals_ci("autoop")) + this->NSDefFlags.SetFlag(NI_AUTOOP); + } + } + + if ((this->NSDefLanguage = langlist[this->NSDefLanguage]) < 0) + this->NSDefLanguage = DEF_LANGUAGE; + + if (this->CSDefBantype < 0 || this->CSDefBantype > 3) + { + throw ConfigException("Value of CSDefBantype must be between 0 and 3 included"); + } + + if (CSDefaults.empty()) + { + this->CSDefFlags.SetFlag(CI_KEEPTOPIC); + this->CSDefFlags.SetFlag(CI_SECURE); + this->CSDefFlags.SetFlag(CI_SECUREFOUNDER); + this->CSDefFlags.SetFlag(CI_SIGNKICK); + } + else if (!CSDefaults.equals_ci("none")) + { + spacesepstream options(CSDefaults); + Anope::string option; + while (options.GetToken(option)) + { + if (option.equals_ci("keeptopic")) + this->CSDefFlags.SetFlag(CI_KEEPTOPIC); + else if (option.equals_ci("topiclock")) + this->CSDefFlags.SetFlag(CI_TOPICLOCK); + else if (option.equals_ci("private")) + this->CSDefFlags.SetFlag(CI_PRIVATE); + else if (option.equals_ci("restricted")) + this->CSDefFlags.SetFlag(CI_RESTRICTED); + else if (option.equals_ci("secure")) + this->CSDefFlags.SetFlag(CI_SECURE); + else if (option.equals_ci("secureops")) + this->CSDefFlags.SetFlag(CI_SECUREOPS); + else if (option.equals_ci("securefounder")) + this->CSDefFlags.SetFlag(CI_SECUREFOUNDER); + else if (option.equals_ci("signkick")) + this->CSDefFlags.SetFlag(CI_SIGNKICK); + else if (option.equals_ci("signkicklevel")) + this->CSDefFlags.SetFlag(CI_SIGNKICK_LEVEL); + else if (option.equals_ci("opnotice")) + this->CSDefFlags.SetFlag(CI_OPNOTICE); + else if (option.equals_ci("xop")) + this->CSDefFlags.SetFlag(CI_XOP); + else if (option.equals_ci("peace")) + this->CSDefFlags.SetFlag(CI_PEACE); + else if (option.equals_ci("persist")) + this->CSDefFlags.SetFlag(CI_PERSIST); + } + } + + if (!BSDefaults.empty()) + { + spacesepstream options(BSDefaults); + Anope::string option; + while (options.GetToken(option)) + { + if (option.equals_ci("dontkickops")) + this->BSDefFlags.SetFlag(BS_DONTKICKOPS); + else if (option.equals_ci("dontkickvoices")) + this->BSDefFlags.SetFlag(BS_DONTKICKVOICES); + else if (option.equals_ci("greet")) + this->BSDefFlags.SetFlag(BS_GREET); + else if (option.equals_ci("fantasy")) + this->BSDefFlags.SetFlag(BS_FANTASY); + else if (option.equals_ci("symbiosis")) + this->BSDefFlags.SetFlag(BS_SYMBIOSIS); + } + } + + this->WallOper = this->WallBadOS = this->WallOSGlobal = this->WallOSMode = this->WallOSClearmodes = this->WallOSKick = this->WallOSAkill = this->WallOSSNLine = this->WallOSSQLine = + this->WallOSSZLine = this->WallOSNoOp = this->WallOSJupe = this->WallAkillExpire = this->WallSNLineExpire = this->WallSQLineExpire = this->WallSZLineExpire = this->WallExceptionExpire = + this->WallGetpass = this->WallSetpass = this->WallForbid = this->WallDrop = false; + if (!OSNotifications.empty()) + { + spacesepstream notifications(OSNotifications); + Anope::string notice; + while (notifications.GetToken(notice)) + { + if (notice.equals_ci("oper")) + this->WallOper = true; + else if (notice.equals_ci("bados")) + this->WallBadOS = true; + else if (notice.equals_ci("osglobal")) + this->WallOSGlobal = true; + else if (notice.equals_ci("osmode")) + this->WallOSMode = true; + else if (notice.equals_ci("osclearmodes")) + this->WallOSClearmodes = true; + else if (notice.equals_ci("oskick")) + this->WallOSKick = true; + else if (notice.equals_ci("osakill")) + this->WallOSAkill = true; + else if (notice.equals_ci("ossnline")) + this->WallOSSNLine = true; + else if (notice.equals_ci("ossqline")) + this->WallOSSQLine = true; + else if (notice.equals_ci("osszline")) + this->WallOSSZLine = true; + else if (notice.equals_ci("osnoop")) + this->WallOSNoOp = true; + else if (notice.equals_ci("osjupe")) + this->WallOSJupe = true; + else if (notice.equals_ci("akillexpire")) + this->WallAkillExpire = true; + else if (notice.equals_ci("snlineexpire")) + this->WallSNLineExpire = true; + else if (notice.equals_ci("sqlineexpire")) + this->WallSQLineExpire = true; + else if (notice.equals_ci("szlineexpire")) + this->WallSZLineExpire = true; + else if (notice.equals_ci("exceptionexpire")) + this->WallExceptionExpire = true; + else if (notice.equals_ci("getpass")) + this->WallGetpass = true; + else if (notice.equals_ci("setpass")) + this->WallSetpass = true; + else if (notice.equals_ci("forbid")) + this->WallForbid = true; + else if (notice.equals_ci("drop")) + this->WallDrop = true; + } + } + + /* Ulines */ + if (!UlineServers.empty()) + { + this->Ulines.clear(); + + spacesepstream ulines(UlineServers); + Anope::string uline; + while (ulines.GetToken(uline)) + this->Ulines.push_back(uline); + } + + /* Modules Autoload building... :P */ + this->ModulesAutoLoad = BuildStringList(Modules); + this->EncModuleList = BuildStringList(EncModules); + this->DBModuleList = BuildStringList(DBModules); + this->HostServCoreModules = BuildStringList(HostCoreModules); + this->MemoServCoreModules = BuildStringList(MemoCoreModules); + this->BotServCoreModules = BuildStringList(BotCoreModules); + this->OperServCoreModules = BuildStringList(OperCoreModules); + this->ChanServCoreModules = BuildStringList(ChanCoreModules); + this->NickServCoreModules = BuildStringList(NickCoreModules); + + if (this->LimitSessions) + { + if (this->MaxSessionKill && !this->SessionAutoKillExpiry) + this->SessionAutoKillExpiry = 1800; /* 30 minutes */ + } + + if (!this->s_BotServ.empty()) + { + if (this->BSFantasyCharacter.empty()) + this->BSFantasyCharacter = "!"; + if (this->BSFantasyCharacter.length() > 1) + printf("*** this->BSFantasyCharacter is more than 1 character long. Only the first\n*** character ('%c') will be used. The others will be ignored.\n", this->BSFantasyCharacter[0]); + } + + /* Check the user keys */ + if (this->UserKey1 == this->UserKey2 || this->UserKey1 == this->UserKey3 || this->UserKey3 == this->UserKey2) + Alog() << "Every UserKey must be different. It's for YOUR safety! Remember that!"; + + /** + * Check all DEFCON dependiencies... + **/ + if (this->DefConLevel) + { + /* Build DefCon's */ + DefCon.resize(6); + DefCon[5].reset(); + for (unsigned int level = 1; level < 5; ++level) + { + DefCon[level] = 0; + Anope::string *levelDefinition = NULL; + switch (level) + { + case 1: + levelDefinition = &DefCon1; + break; + case 2: + levelDefinition = &DefCon2; + break; + case 3: + levelDefinition = &DefCon3; + break; + case 4: + levelDefinition = &DefCon4; + } + spacesepstream operations(*levelDefinition); + Anope::string operation; + while (operations.GetToken(operation)) + { + if (operation.equals_ci("nonewchannels")) + AddDefCon(level, DEFCON_NO_NEW_CHANNELS); + else if (operation.equals_ci("nonewnicks")) + AddDefCon(level, DEFCON_NO_NEW_NICKS); + else if (operation.equals_ci("nomlockchanges")) + AddDefCon(level, DEFCON_NO_MLOCK_CHANGE); + else if (operation.equals_ci("forcechanmodes")) + AddDefCon(level, DEFCON_FORCE_CHAN_MODES); + else if (operation.equals_ci("reducedsessions")) + AddDefCon(level, DEFCON_REDUCE_SESSION); + else if (operation.equals_ci("nonewclients")) + AddDefCon(level, DEFCON_NO_NEW_CLIENTS); + else if (operation.equals_ci("operonly")) + AddDefCon(level, DEFCON_OPER_ONLY); + else if (operation.equals_ci("silentoperonly")) + AddDefCon(level, DEFCON_SILENT_OPER_ONLY); + else if (operation.equals_ci("akillnewclients")) + AddDefCon(level, DEFCON_AKILL_NEW_CLIENTS); + else if (operation.equals_ci("nonewmemos")) + AddDefCon(level, DEFCON_NO_NEW_MEMOS); + } + } + + /* Check any defcon needed settings */ + for (int defconCount = 1; defconCount <= 5; ++defconCount) + { + if (CheckDefCon(defconCount, DEFCON_REDUCE_SESSION)) + { + if (!this->DefConSessionLimit) + { + throw ConfigException("this->DefConSessionLimit missing"); + } + } + if (CheckDefCon(defconCount, DEFCON_AKILL_NEW_CLIENTS)) + { + if (!this->DefConAKILL) + { + throw ConfigException("this->DefConAKILL missing"); + } + if (this->DefConAkillReason.empty()) + { + throw ConfigException("this->DefConAkillReason missing"); + } + } + if (CheckDefCon(defconCount, DEFCON_FORCE_CHAN_MODES)) + { + if (this->DefConChanModes.empty()) + { + throw ConfigException("this->DefConChanModes missing"); + } + } + } + } + + SetDefaultMLock(this); + + /* Disable the log channel if its defined in the conf, but not enabled */ + if (this->LogChannel.empty() && LogChan) + LogChan = false; } bool ServerConfig::CheckOnce(const Anope::string &tag) @@ -171,9 +476,9 @@ bool ValidateNotZero(ServerConfig *, const Anope::string &tag, const Anope::stri return true; } -bool ValidateEmailReg(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { - if (Config.NSEmailReg) + if (config->NSEmailReg) { if (value.equals_ci("preregexpire")) { @@ -224,9 +529,9 @@ bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string return true; } -bool ValidateBotServ(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { - if (!Config.s_BotServ.empty()) + if (!config->s_BotServ.empty()) { if (value.equals_ci("description")) { @@ -247,9 +552,9 @@ bool ValidateBotServ(ServerConfig *, const Anope::string &tag, const Anope::stri return true; } -bool ValidateHostServ(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +bool ValidateHostServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { - if (!Config.s_HostServ.empty()) + if (!config->s_HostServ.empty()) { if (value.equals_ci("description")) { @@ -260,9 +565,9 @@ bool ValidateHostServ(ServerConfig *, const Anope::string &tag, const Anope::str return true; } -bool ValidateLimitSessions(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { - if (Config.LimitSessions) + if (config->LimitSessions) { if (value.equals_ci("maxsessionlimit") || value.equals_ci("exceptionexpiry")) { @@ -273,7 +578,7 @@ bool ValidateLimitSessions(ServerConfig *, const Anope::string &tag, const Anope return true; } -bool ValidateDefCon(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +bool ValidateDefCon(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { if (value.equals_ci("defaultlevel")) { @@ -283,14 +588,14 @@ bool ValidateDefCon(ServerConfig *, const Anope::string &tag, const Anope::strin if (level > 5) throw ConfigException("The value for must be between 1 through 5 if you wish to use DefCon or 0 if you wish to disable it!"); } - else if (Config.DefConLevel) + else if (config->DefConLevel) { if ((value.substr(0, 5).equals_ci("level") && isdigit(value[5])) || value.equals_ci("chanmodes") || value.equals_ci("akillreason")) { if (data.GetValue().empty()) throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when DefCon is enabled!"); } - else if (value.equals_ci("message") && Config.GlobalOnDefconMore) + else if (value.equals_ci("message") && config->GlobalOnDefconMore) { if (data.GetValue().empty()) throw ConfigException("The value for cannot be empty when globalondefconmore is enabled!"); @@ -321,9 +626,9 @@ bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string return true; } -bool ValidateMail(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { - if (Config.UseMail) + if (config->UseMail) { if (value.equals_ci("sendmailpath") || value.equals_ci("sendfrom")) { @@ -334,88 +639,69 @@ bool ValidateMail(ServerConfig *, const Anope::string &tag, const Anope::string return true; } -bool ValidateGlobalOnCycle(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { - if (Config.GlobalOnCycle) + if (config->GlobalOnCycle) { if (data.GetValue().empty()) { Alog() << "<" << tag << ":" << value << "> was undefined, disabling "; - Config.GlobalOnCycle = false; + config->GlobalOnCycle = false; } } return true; } -void ServerConfig::ReportConfigError(const Anope::string &errormessage, bool bail) -{ - Alog() << "There were errors in your configuration file: " << errormessage; - if (bail) - { - // TODO -- Need a way to stop loading in a safe way -- CyberBotX - //ServerInstance->Exit(EXIT_STATUS_CONFIG); - } -} - -bool InitUplinks(ServerConfig *, const Anope::string &, bool bail) +bool InitUplinks(ServerConfig *config, const Anope::string &) { - // If bail is false, we were reloading, don't clear anything - if (!bail) - return true; - if (!Config.Uplinks.empty()) + if (!config->Uplinks.empty()) { - std::list::iterator curr_uplink = Config.Uplinks.begin(), end_uplink = Config.Uplinks.end(); + std::list::iterator curr_uplink = config->Uplinks.begin(), end_uplink = config->Uplinks.end(); for (; curr_uplink != end_uplink; ++curr_uplink) delete *curr_uplink; } - Config.Uplinks.clear(); + config->Uplinks.clear(); return true; } -bool DoUplink(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *, bool bail) +bool DoUplink(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *) { - // If bail is false, we were reloading, don't even try to add another uplink - if (!bail) - return true; // 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(conf, "uplink", "host", vi_host)) + 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(conf, "uplink", "port", vi_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(conf, "uplink", "password", vi_password)) + 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 Uplink(host, port, password, ipv6)); + config->Uplinks.push_back(new Uplink(host, port, password, ipv6)); return true; } -bool DoneUplinks(ServerConfig *, const Anope::string &, bool bail) +bool DoneUplinks(ServerConfig *config, const Anope::string &) { - // If bail is false, we were reloading, ignore this check - if (!bail) - return true; - if (Config.Uplinks.empty()) + if (config->Uplinks.empty()) throw ConfigException("You must define at least one uplink block!"); return true; } -static bool InitOperTypes(ServerConfig *, const Anope::string &, bool) +static bool InitOperTypes(ServerConfig *config, const Anope::string &) { - for (std::list::iterator it = Config.MyOperTypes.begin(), it_end = Config.MyOperTypes.end(); it != it_end; ++it) + for (std::list::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it) delete *it; - Config.MyOperTypes.clear(); + config->MyOperTypes.clear(); return true; } -static bool DoOperType(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *, bool) +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(); @@ -423,7 +709,7 @@ static bool DoOperType(ServerConfig *conf, const Anope::string &, const Anope::s Anope::string privs = values[3].GetValue(); ValueItem vi(name); - if (!ValidateNotEmpty(conf, "opertype", "name", vi)) + 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); @@ -443,7 +729,7 @@ static bool DoOperType(ServerConfig *conf, const Anope::string &, const Anope::s /* Strip leading ' ' after , */ if (tok.length() > 1 && tok[0] == ' ') tok.erase(tok.begin()); - for (std::list::iterator it = Config.MyOperTypes.begin(), it_end = Config.MyOperTypes.end(); it != it_end; ++it) + for (std::list::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it) { if ((*it)->GetName().equals_ci(tok)) { @@ -454,47 +740,47 @@ static bool DoOperType(ServerConfig *conf, const Anope::string &, const Anope::s } } - Config.MyOperTypes.push_back(ot); + config->MyOperTypes.push_back(ot); return true; } -static bool DoneOperTypes(ServerConfig *, const Anope::string &, bool) +static bool DoneOperTypes(ServerConfig *, const Anope::string &) { return true; } /*************************************************************************/ -static bool InitOpers(ServerConfig *, const Anope::string &, bool) +static bool InitOpers(ServerConfig *config, const Anope::string &) { for (nickcore_map::const_iterator it = NickCoreList.begin(), it_end = NickCoreList.end(); it != it_end; ++it) it->second->ot = NULL; - Config.Opers.clear(); + config->Opers.clear(); return true; } -static bool DoOper(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *, bool) +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(); ValueItem vi(name); - if (!ValidateNotEmpty(conf, "oper", "name", vi)) + 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(conf, "oper", "type", vi2)) + 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."); - Config.Opers.push_back(std::make_pair(name, type)); + config->Opers.push_back(std::make_pair(name, type)); return true; } -static bool DoneOpers(ServerConfig *, const Anope::string &, bool) +static bool DoneOpers(ServerConfig *config, const Anope::string &) { - for (std::list >::iterator it = Config.Opers.begin(), it_end = Config.Opers.end(); it != it_end; ++it) + for (std::list >::iterator it = config->Opers.begin(), it_end = config->Opers.end(); it != it_end; ++it) { Anope::string nick = it->first, type = it->second; @@ -504,10 +790,9 @@ static bool DoneOpers(ServerConfig *, const Anope::string &, bool) continue; if (!na->nc) - // Nick with no core (wtf?) - abort(); + throw CoreException("Nick with no core?"); - for (std::list::iterator tit = Config.MyOperTypes.begin(), tit_end = Config.MyOperTypes.end(); tit != tit_end; ++tit) + for (std::list::iterator tit = config->MyOperTypes.begin(), tit_end = config->MyOperTypes.end(); tit != tit_end; ++tit) { OperType *ot = *tit; if (ot->GetName().equals_ci(type)) @@ -522,13 +807,13 @@ static bool DoneOpers(ServerConfig *, const Anope::string &, bool) /*************************************************************************/ -bool InitModules(ServerConfig *, const Anope::string &, bool) +bool InitModules(ServerConfig *, const Anope::string &) { Modules.clear(); return true; } -bool DoModule(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *, bool) +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(); @@ -543,12 +828,12 @@ bool DoModule(ServerConfig *conf, const Anope::string &, const Anope::string *, return true; } -bool DoneModules(ServerConfig *, const Anope::string &, bool) +bool DoneModules(ServerConfig *, const Anope::string &) { return true; } -int ServerConfig::Read(bool bail) +void ServerConfig::Read() { errstr.clear(); // These tags MUST occur and must ONLY occur once in the config file @@ -608,164 +893,164 @@ int ServerConfig::Read(bool bail) * * 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(&Config.ServerName), DT_HOSTNAME | DT_NORELOAD, ValidateNotEmpty}, - {"serverinfo", "description", "", new ValueContainerString(&Config.ServerDesc), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"serverinfo", "localhost", "", new ValueContainerString(&Config.LocalHost), DT_HOSTNAME | DT_NORELOAD, NoValidation}, - {"serverinfo", "type", "", new ValueContainerString(&Config.IRCDModule), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"serverinfo", "id", "", new ValueContainerString(&Config.Numeric), DT_NOSPACES | DT_NORELOAD, NoValidation}, - {"serverinfo", "ident", "", new ValueContainerString(&Config.ServiceUser), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"serverinfo", "hostname", "", new ValueContainerString(&Config.ServiceHost), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"serverinfo", "pid", "services.pid", new ValueContainerString(&Config.PIDFilename), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"serverinfo", "motd", "services.motd", new ValueContainerString(&Config.MOTDFilename), DT_STRING, ValidateNotEmpty}, - {"networkinfo", "logchannel", "", new ValueContainerString(&Config.LogChannel), DT_STRING, NoValidation}, - {"networkinfo", "logbot", "no", new ValueContainerBool(&Config.LogBot), DT_BOOLEAN, NoValidation}, - {"networkinfo", "networkname", "", new ValueContainerString(&Config.NetworkName), DT_STRING, ValidateNotEmpty}, - {"networkinfo", "nicklen", "0", new ValueContainerUInt(&Config.NickLen), DT_UINTEGER | DT_NORELOAD, ValidateNickLen}, - {"networkinfo", "userlen", "10", new ValueContainerUInt(&Config.UserLen), DT_UINTEGER | DT_NORELOAD, NoValidation}, - {"networkinfo", "hostlen", "64", new ValueContainerUInt(&Config.HostLen), DT_UINTEGER | DT_NORELOAD, NoValidation}, + {"serverinfo", "name", "", new ValueContainerString(&this->ServerName), DT_HOSTNAME | DT_NORELOAD, ValidateNotEmpty}, + {"serverinfo", "description", "", new ValueContainerString(&this->ServerDesc), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"serverinfo", "localhost", "", new ValueContainerString(&this->LocalHost), DT_HOSTNAME | DT_NORELOAD, NoValidation}, + {"serverinfo", "type", "", new ValueContainerString(&this->IRCDModule), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"serverinfo", "id", "", new ValueContainerString(&this->Numeric), DT_NOSPACES | DT_NORELOAD, NoValidation}, + {"serverinfo", "ident", "", new ValueContainerString(&this->ServiceUser), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"serverinfo", "hostname", "", new ValueContainerString(&this->ServiceHost), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"serverinfo", "pid", "services.pid", new ValueContainerString(&this->PIDFilename), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"serverinfo", "motd", "services.motd", new ValueContainerString(&this->MOTDFilename), DT_STRING, ValidateNotEmpty}, + {"networkinfo", "logchannel", "", new ValueContainerString(&this->LogChannel), DT_STRING, NoValidation}, + {"networkinfo", "logbot", "no", new ValueContainerBool(&this->LogBot), DT_BOOLEAN, NoValidation}, + {"networkinfo", "networkname", "", new ValueContainerString(&this->NetworkName), DT_STRING, ValidateNotEmpty}, + {"networkinfo", "nicklen", "0", new ValueContainerUInt(&this->NickLen), DT_UINTEGER | DT_NORELOAD, ValidateNickLen}, + {"networkinfo", "userlen", "10", new ValueContainerUInt(&this->UserLen), DT_UINTEGER | DT_NORELOAD, NoValidation}, + {"networkinfo", "hostlen", "64", new ValueContainerUInt(&this->HostLen), DT_UINTEGER | DT_NORELOAD, NoValidation}, {"options", "encryption", "", new ValueContainerString(&EncModules), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"options", "passlen", "32", new ValueContainerUInt(&Config.PassLen), DT_UINTEGER | DT_NORELOAD, NoValidation}, + {"options", "passlen", "32", new ValueContainerUInt(&this->PassLen), DT_UINTEGER | DT_NORELOAD, NoValidation}, {"options", "database", "", new ValueContainerString(&DBModules), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"options", "socketengine", "", new ValueContainerString(&Config.SocketEngine), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"options", "userkey1", "0", new ValueContainerLUInt(&Config.UserKey1), DT_LUINTEGER, NoValidation}, - {"options", "userkey2", "0", new ValueContainerLUInt(&Config.UserKey2), DT_LUINTEGER, NoValidation}, - {"options", "userkey3", "0", new ValueContainerLUInt(&Config.UserKey3), DT_LUINTEGER, NoValidation}, - {"options", "nobackupokay", "no", new ValueContainerBool(&Config.NoBackupOkay), DT_BOOLEAN, NoValidation}, - {"options", "strictpasswords", "no", new ValueContainerBool(&Config.StrictPasswords), DT_BOOLEAN, NoValidation}, - {"options", "badpasslimit", "0", new ValueContainerUInt(&Config.BadPassLimit), DT_UINTEGER, NoValidation}, - {"options", "badpasstimeout", "0", new ValueContainerTime(&Config.BadPassTimeout), DT_TIME, NoValidation}, - {"options", "updatetimeout", "0", new ValueContainerTime(&Config.UpdateTimeout), DT_TIME, ValidateNotZero}, - {"options", "expiretimeout", "0", new ValueContainerTime(&Config.ExpireTimeout), DT_TIME, ValidateNotZero}, - {"options", "readtimeout", "0", new ValueContainerTime(&Config.ReadTimeout), DT_TIME, ValidateNotZero}, - {"options", "warningtimeout", "0", new ValueContainerTime(&Config.WarningTimeout), DT_TIME, ValidateNotZero}, - {"options", "timeoutcheck", "0", new ValueContainerTime(&Config.TimeoutCheck), DT_TIME, NoValidation}, - {"options", "keeplogs", "0", new ValueContainerInt(&Config.KeepLogs), DT_INTEGER, NoValidation}, - {"options", "keepbackups", "0", new ValueContainerInt(&Config.KeepBackups), DT_INTEGER, NoValidation}, - {"options", "forceforbidreason", "no", new ValueContainerBool(&Config.ForceForbidReason), DT_BOOLEAN, NoValidation}, - {"options", "useprivmsg", "no", new ValueContainerBool(&Config.UsePrivmsg), DT_BOOLEAN, NoValidation}, - {"options", "usestrictprivmsg", "no", new ValueContainerBool(&Config.UseStrictPrivMsg), DT_BOOLEAN, NoValidation}, - {"options", "dumpcore", "yes", new ValueContainerBool(&Config.DumpCore), DT_BOOLEAN | DT_NORELOAD, NoValidation}, - {"options", "logusers", "no", new ValueContainerBool(&Config.LogUsers), DT_BOOLEAN, NoValidation}, - {"options", "hidestatso", "no", new ValueContainerBool(&Config.HideStatsO), DT_BOOLEAN, NoValidation}, - {"options", "globaloncycle", "no", new ValueContainerBool(&Config.GlobalOnCycle), DT_BOOLEAN, NoValidation}, - {"options", "globaloncycledown", "", new ValueContainerString(&Config.GlobalOnCycleMessage), DT_STRING, ValidateGlobalOnCycle}, - {"options", "globaloncycleup", "", new ValueContainerString(&Config.GlobalOnCycleUP), DT_STRING, ValidateGlobalOnCycle}, - {"options", "anonymousglobal", "no", new ValueContainerBool(&Config.AnonymousGlobal), DT_BOOLEAN, NoValidation}, - {"options", "nickregdelay", "0", new ValueContainerUInt(&Config.NickRegDelay), DT_UINTEGER, NoValidation}, - {"options", "restrictopernicks", "no", new ValueContainerBool(&Config.RestrictOperNicks), DT_BOOLEAN, NoValidation}, - {"options", "newscount", "3", new ValueContainerUInt(&Config.NewsCount), DT_UINTEGER, NoValidation}, + {"options", "socketengine", "", new ValueContainerString(&this->SocketEngine), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"options", "userkey1", "0", new ValueContainerLUInt(&this->UserKey1), DT_LUINTEGER, NoValidation}, + {"options", "userkey2", "0", new ValueContainerLUInt(&this->UserKey2), DT_LUINTEGER, NoValidation}, + {"options", "userkey3", "0", new ValueContainerLUInt(&this->UserKey3), DT_LUINTEGER, NoValidation}, + {"options", "nobackupokay", "no", new ValueContainerBool(&this->NoBackupOkay), DT_BOOLEAN, NoValidation}, + {"options", "strictpasswords", "no", new ValueContainerBool(&this->StrictPasswords), DT_BOOLEAN, NoValidation}, + {"options", "badpasslimit", "0", new ValueContainerUInt(&this->BadPassLimit), DT_UINTEGER, NoValidation}, + {"options", "badpasstimeout", "0", new ValueContainerTime(&this->BadPassTimeout), DT_TIME, NoValidation}, + {"options", "updatetimeout", "0", new ValueContainerTime(&this->UpdateTimeout), DT_TIME, ValidateNotZero}, + {"options", "expiretimeout", "0", new ValueContainerTime(&this->ExpireTimeout), DT_TIME, ValidateNotZero}, + {"options", "readtimeout", "0", new ValueContainerTime(&this->ReadTimeout), DT_TIME, ValidateNotZero}, + {"options", "warningtimeout", "0", new ValueContainerTime(&this->WarningTimeout), DT_TIME, ValidateNotZero}, + {"options", "timeoutcheck", "0", new ValueContainerTime(&this->TimeoutCheck), DT_TIME, NoValidation}, + {"options", "keeplogs", "0", new ValueContainerInt(&this->KeepLogs), DT_INTEGER, NoValidation}, + {"options", "keepbackups", "0", new ValueContainerInt(&this->KeepBackups), DT_INTEGER, NoValidation}, + {"options", "forceforbidreason", "no", new ValueContainerBool(&this->ForceForbidReason), DT_BOOLEAN, NoValidation}, + {"options", "useprivmsg", "no", new ValueContainerBool(&this->UsePrivmsg), DT_BOOLEAN, NoValidation}, + {"options", "usestrictprivmsg", "no", new ValueContainerBool(&this->UseStrictPrivMsg), DT_BOOLEAN, NoValidation}, + {"options", "dumpcore", "yes", new ValueContainerBool(&this->DumpCore), DT_BOOLEAN | DT_NORELOAD, NoValidation}, + {"options", "logusers", "no", new ValueContainerBool(&this->LogUsers), DT_BOOLEAN, NoValidation}, + {"options", "hidestatso", "no", new ValueContainerBool(&this->HideStatsO), DT_BOOLEAN, NoValidation}, + {"options", "globaloncycle", "no", new ValueContainerBool(&this->GlobalOnCycle), DT_BOOLEAN, NoValidation}, + {"options", "globaloncycledown", "", new ValueContainerString(&this->GlobalOnCycleMessage), DT_STRING, ValidateGlobalOnCycle}, + {"options", "globaloncycleup", "", new ValueContainerString(&this->GlobalOnCycleUP), DT_STRING, ValidateGlobalOnCycle}, + {"options", "anonymousglobal", "no", new ValueContainerBool(&this->AnonymousGlobal), DT_BOOLEAN, NoValidation}, + {"options", "nickregdelay", "0", new ValueContainerUInt(&this->NickRegDelay), DT_UINTEGER, NoValidation}, + {"options", "restrictopernicks", "no", new ValueContainerBool(&this->RestrictOperNicks), DT_BOOLEAN, NoValidation}, + {"options", "newscount", "3", new ValueContainerUInt(&this->NewsCount), DT_UINTEGER, NoValidation}, {"options", "ulineservers", "", new ValueContainerString(&UlineServers), DT_STRING, NoValidation}, {"options", "enablelogchannel", "no", new ValueContainerBool(&LogChan), DT_BOOLEAN, NoValidation}, - {"options", "mlock", "+nrt", new ValueContainerString(&Config.MLock), DT_STRING, NoValidation}, - {"options", "botmodes", "", new ValueContainerString(&Config.BotModes), DT_STRING, NoValidation}, - {"options", "maxretries", "10", new ValueContainerUInt(&Config.MaxRetries), DT_UINTEGER, NoValidation}, - {"options", "retrywait", "60", new ValueContainerInt(&Config.RetryWait), DT_INTEGER, ValidateNotZero}, - {"options", "hideprivilegedcommands", "no", new ValueContainerBool(&Config.HidePrivilegedCommands), DT_BOOLEAN, ValidateEmailReg}, - {"nickserv", "nick", "NickServ", new ValueContainerString(&Config.s_NickServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"nickserv", "description", "Nickname Registration Service", new ValueContainerString(&Config.desc_NickServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"nickserv", "emailregistration", "no", new ValueContainerBool(&Config.NSEmailReg), DT_BOOLEAN, NoValidation}, + {"options", "mlock", "+nrt", new ValueContainerString(&this->MLock), DT_STRING, NoValidation}, + {"options", "botmodes", "", new ValueContainerString(&this->BotModes), DT_STRING, NoValidation}, + {"options", "maxretries", "10", new ValueContainerUInt(&this->MaxRetries), DT_UINTEGER, NoValidation}, + {"options", "retrywait", "60", new ValueContainerInt(&this->RetryWait), DT_INTEGER, ValidateNotZero}, + {"options", "hideprivilegedcommands", "no", new ValueContainerBool(&this->HidePrivilegedCommands), DT_BOOLEAN, NoValidation}, + {"nickserv", "nick", "NickServ", new ValueContainerString(&this->s_NickServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"nickserv", "description", "Nickname Registration Service", new ValueContainerString(&this->desc_NickServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"nickserv", "emailregistration", "no", new ValueContainerBool(&this->NSEmailReg), DT_BOOLEAN, NoValidation}, {"nickserv", "modules", "", new ValueContainerString(&NickCoreModules), DT_STRING, NoValidation}, - {"nickserv", "forceemail", "no", new ValueContainerBool(&Config.NSForceEmail), DT_BOOLEAN, ValidateEmailReg}, + {"nickserv", "forceemail", "no", new ValueContainerBool(&this->NSForceEmail), DT_BOOLEAN, ValidateEmailReg}, {"nickserv", "defaults", "secure memosignon memoreceive", new ValueContainerString(&NSDefaults), DT_STRING, NoValidation}, - {"nickserv", "defaultlanguage", "0", new ValueContainerUInt(&Config.NSDefLanguage), DT_UINTEGER, ValidateLanguage}, - {"nickserv", "regdelay", "0", new ValueContainerTime(&Config.NSRegDelay), DT_TIME, NoValidation}, - {"nickserv", "resenddelay", "0", new ValueContainerTime(&Config.NSResendDelay), DT_TIME, NoValidation}, - {"nickserv", "expire", "21d", new ValueContainerTime(&Config.NSExpire), DT_TIME, NoValidation}, - {"nickserv", "preregexpire", "0", new ValueContainerTime(&Config.NSRExpire), DT_TIME, ValidateEmailReg}, - {"nickserv", "maxaliases", "0", new ValueContainerInt(&Config.NSMaxAliases), DT_INTEGER, NoValidation}, - {"nickserv", "accessmax", "0", new ValueContainerUInt(&Config.NSAccessMax), DT_UINTEGER, ValidateNotZero}, + {"nickserv", "defaultlanguage", "0", new ValueContainerUInt(&this->NSDefLanguage), DT_UINTEGER, ValidateLanguage}, + {"nickserv", "regdelay", "0", new ValueContainerTime(&this->NSRegDelay), DT_TIME, NoValidation}, + {"nickserv", "resenddelay", "0", new ValueContainerTime(&this->NSResendDelay), DT_TIME, NoValidation}, + {"nickserv", "expire", "21d", new ValueContainerTime(&this->NSExpire), DT_TIME, NoValidation}, + {"nickserv", "preregexpire", "0", new ValueContainerTime(&this->NSRExpire), DT_TIME, ValidateEmailReg}, + {"nickserv", "maxaliases", "0", new ValueContainerInt(&this->NSMaxAliases), DT_INTEGER, NoValidation}, + {"nickserv", "accessmax", "0", new ValueContainerUInt(&this->NSAccessMax), DT_UINTEGER, ValidateNotZero}, {"nickserv", "enforceruser", "", new ValueContainerString(&temp_nsuserhost), DT_STRING, ValidateNotEmpty}, - {"nickserv", "releasetimeout", "0", new ValueContainerTime(&Config.NSReleaseTimeout), DT_TIME, ValidateNotZero}, - {"nickserv", "allowkillimmed", "no", new ValueContainerBool(&Config.NSAllowKillImmed), DT_BOOLEAN | DT_NORELOAD, NoValidation}, - {"nickserv", "nogroupchange", "no", new ValueContainerBool(&Config.NSNoGroupChange), DT_BOOLEAN, NoValidation}, - {"nickserv", "listopersonly", "no", new ValueContainerBool(&Config.NSListOpersOnly), DT_BOOLEAN, NoValidation}, - {"nickserv", "listmax", "0", new ValueContainerUInt(&Config.NSListMax), DT_UINTEGER, ValidateNotZero}, - {"nickserv", "guestnickprefix", "", new ValueContainerString(&Config.NSGuestNickPrefix), DT_STRING, ValidateGuestPrefix}, - {"nickserv", "secureadmins", "no", new ValueContainerBool(&Config.NSSecureAdmins), DT_BOOLEAN, NoValidation}, - {"nickserv", "strictprivileges", "no", new ValueContainerBool(&Config.NSStrictPrivileges), DT_BOOLEAN, NoValidation}, - {"nickserv", "modeonid", "no", new ValueContainerBool(&Config.NSModeOnID), DT_BOOLEAN, NoValidation}, - {"nickserv", "addaccessonreg", "no", new ValueContainerBool(&Config.NSAddAccessOnReg), DT_BOOLEAN, NoValidation}, - {"mail", "usemail", "no", new ValueContainerBool(&Config.UseMail), DT_BOOLEAN, ValidateEmailReg}, - {"mail", "sendmailpath", "", new ValueContainerString(&Config.SendMailPath), DT_STRING, ValidateMail}, - {"mail", "sendfrom", "", new ValueContainerString(&Config.SendFrom), DT_STRING, ValidateMail}, - {"mail", "restrict", "no", new ValueContainerBool(&Config.RestrictMail), DT_BOOLEAN, NoValidation}, - {"mail", "delay", "0", new ValueContainerTime(&Config.MailDelay), DT_TIME, NoValidation}, - {"mail", "dontquoteaddresses", "no", new ValueContainerBool(&Config.DontQuoteAddresses), DT_BOOLEAN, NoValidation}, - {"chanserv", "nick", "ChanServ", new ValueContainerString(&Config.s_ChanServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, - {"chanserv", "description", "Channel Registration Service", new ValueContainerString(&Config.desc_ChanServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"nickserv", "releasetimeout", "0", new ValueContainerTime(&this->NSReleaseTimeout), DT_TIME, ValidateNotZero}, + {"nickserv", "allowkillimmed", "no", new ValueContainerBool(&this->NSAllowKillImmed), DT_BOOLEAN | DT_NORELOAD, NoValidation}, + {"nickserv", "nogroupchange", "no", new ValueContainerBool(&this->NSNoGroupChange), DT_BOOLEAN, NoValidation}, + {"nickserv", "listopersonly", "no", new ValueContainerBool(&this->NSListOpersOnly), DT_BOOLEAN, NoValidation}, + {"nickserv", "listmax", "0", new ValueContainerUInt(&this->NSListMax), DT_UINTEGER, ValidateNotZero}, + {"nickserv", "guestnickprefix", "", new ValueContainerString(&this->NSGuestNickPrefix), DT_STRING, ValidateGuestPrefix}, + {"nickserv", "secureadmins", "no", new ValueContainerBool(&this->NSSecureAdmins), DT_BOOLEAN, NoValidation}, + {"nickserv", "strictprivileges", "no", new ValueContainerBool(&this->NSStrictPrivileges), DT_BOOLEAN, NoValidation}, + {"nickserv", "modeonid", "no", new ValueContainerBool(&this->NSModeOnID), DT_BOOLEAN, NoValidation}, + {"nickserv", "addaccessonreg", "no", new ValueContainerBool(&this->NSAddAccessOnReg), DT_BOOLEAN, NoValidation}, + {"mail", "usemail", "no", new ValueContainerBool(&this->UseMail), DT_BOOLEAN, ValidateEmailReg}, + {"mail", "sendmailpath", "", new ValueContainerString(&this->SendMailPath), DT_STRING, ValidateMail}, + {"mail", "sendfrom", "", new ValueContainerString(&this->SendFrom), DT_STRING, ValidateMail}, + {"mail", "restrict", "no", new ValueContainerBool(&this->RestrictMail), DT_BOOLEAN, NoValidation}, + {"mail", "delay", "0", new ValueContainerTime(&this->MailDelay), DT_TIME, NoValidation}, + {"mail", "dontquoteaddresses", "no", new ValueContainerBool(&this->DontQuoteAddresses), DT_BOOLEAN, NoValidation}, + {"chanserv", "nick", "ChanServ", new ValueContainerString(&this->s_ChanServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, + {"chanserv", "description", "Channel Registration Service", new ValueContainerString(&this->desc_ChanServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty}, {"chanserv", "modules", "", new ValueContainerString(&ChanCoreModules), DT_STRING, NoValidation}, {"chanserv", "defaults", "keeptopic secure securefounder signkick", new ValueContainerString(&CSDefaults), DT_STRING, NoValidation}, - {"chanserv", "maxregistered", "0", new ValueContainerUInt(&Config.CSMaxReg), DT_UINTEGER, NoValidation}, - {"chanserv", "expire", "14d", new ValueContainerTime(&Config.CSExpire), DT_TIME, NoValidation}, - {"chanserv", "defbantype", "2", new ValueContainerInt(&Config.CSDefBantype), DT_INTEGER, ValidateBantype}, - {"chanserv", "accessmax", "0", new ValueContainerUInt(&Config.CSAccessMax), DT_UINTEGER, ValidateNotZero}, - {"chanserv", "autokickmax", "0", new ValueContainerUInt(&Config.CSAutokickMax), DT_UINTEGER, ValidateNotZero}, - {"chanserv", "autokickreason", "User has been banned from the channel", new ValueContainerString(&Config.CSAutokickReason), DT_STRING, ValidateNotEmpty}, - {"chanserv", "inhabit", "0", new ValueContainerTime(&Config.CSInhabit), DT_TIME, ValidateNotZero}, - {"chanserv", "listopersonly", "no", new ValueContainerBool(&